summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore30
-rw-r--r--COPYING4
-rw-r--r--CREDITS26
-rw-r--r--Documentation/00-INDEX4
-rw-r--r--Documentation/Changes10
-rw-r--r--Documentation/CodingStyle24
-rw-r--r--Documentation/DMA-API.txt2
-rw-r--r--Documentation/DMA-ISA-LPC.txt151
-rw-r--r--Documentation/DocBook/journal-api.tmpl4
-rw-r--r--Documentation/DocBook/kernel-hacking.tmpl310
-rw-r--r--Documentation/DocBook/libata.tmpl1072
-rw-r--r--Documentation/DocBook/usb.tmpl2
-rw-r--r--Documentation/MSI-HOWTO.txt2
-rw-r--r--Documentation/RCU/RTFP.txt36
-rw-r--r--Documentation/RCU/UP.txt79
-rw-r--r--Documentation/RCU/checklist.txt23
-rw-r--r--Documentation/RCU/rcu.txt48
-rw-r--r--Documentation/RCU/rcuref.txt74
-rw-r--r--Documentation/RCU/whatisRCU.txt902
-rw-r--r--Documentation/SubmittingPatches86
-rw-r--r--Documentation/acpi-hotkey.txt2
-rw-r--r--Documentation/aoe/mkshelf.sh6
-rw-r--r--Documentation/applying-patches.txt439
-rw-r--r--Documentation/block/biodoc.txt113
-rw-r--r--Documentation/cciss.txt4
-rw-r--r--Documentation/connector/cn_test.c194
-rw-r--r--Documentation/connector/connector.txt177
-rw-r--r--Documentation/cpu-freq/cpufreq-stats.txt2
-rw-r--r--Documentation/cpusets.txt2
-rw-r--r--Documentation/crypto/descore-readme.txt2
-rw-r--r--Documentation/dell_rbu.txt50
-rw-r--r--Documentation/device-mapper/snapshot.txt73
-rw-r--r--Documentation/dontdiff1
-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/intel810.txt56
-rw-r--r--Documentation/fb/modedb.txt73
-rw-r--r--Documentation/feature-removal-schedule.txt26
-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/relayfs.txt2
-rw-r--r--Documentation/filesystems/v9fs.txt95
-rw-r--r--Documentation/filesystems/vfs.txt435
-rw-r--r--Documentation/firmware_class/firmware_sample_driver.c8
-rw-r--r--Documentation/ia64/mca.txt194
-rw-r--r--Documentation/ibm-acpi.txt376
-rw-r--r--Documentation/input/appletouch.txt84
-rw-r--r--Documentation/input/yealink.txt203
-rw-r--r--Documentation/ioctl/cdrom.txt2
-rw-r--r--Documentation/kbuild/makefiles.txt14
-rw-r--r--Documentation/kdump/kdump.txt27
-rw-r--r--Documentation/kernel-parameters.txt504
-rw-r--r--Documentation/keys-request-key.txt161
-rw-r--r--Documentation/keys.txt92
-rw-r--r--Documentation/mono.txt2
-rw-r--r--Documentation/networking/bonding.txt9
-rw-r--r--Documentation/networking/ip-sysctl.txt10
-rw-r--r--Documentation/networking/wan-router.txt4
-rw-r--r--Documentation/oops-tracing.txt25
-rw-r--r--Documentation/pci.txt2
-rw-r--r--Documentation/pm.txt6
-rw-r--r--Documentation/powerpc/eeh-pci-error-recovery.txt2
-rw-r--r--Documentation/s390/s390dbf.txt2
-rw-r--r--Documentation/scsi/00-INDEX2
-rw-r--r--Documentation/scsi/ibmmca.txt2
-rw-r--r--Documentation/scsi/scsi_eh.txt479
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt126
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl10
-rw-r--r--Documentation/sparse.txt6
-rw-r--r--Documentation/sysrq.txt2
-rw-r--r--Documentation/uml/UserModeLinux-HOWTO.txt2
-rw-r--r--Documentation/usb/URB.txt74
-rw-r--r--Documentation/usb/gadget_serial.txt2
-rw-r--r--Documentation/usb/proc_usb_info.txt13
-rw-r--r--Documentation/video4linux/CARDLIST.bttv4
-rw-r--r--Documentation/video4linux/CARDLIST.saa71343
-rw-r--r--Documentation/video4linux/CARDLIST.tuner1
-rw-r--r--Documentation/video4linux/Zoran2
-rw-r--r--Documentation/x86_64/boot-options.txt5
-rw-r--r--Kbuild49
-rw-r--r--MAINTAINERS122
-rw-r--r--Makefile88
-rw-r--r--README9
-rw-r--r--REPORTING-BUGS14
-rw-r--r--arch/alpha/Makefile11
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c9
-rw-r--r--arch/alpha/kernel/entry.S3
-rw-r--r--arch/alpha/kernel/head.S2
-rw-r--r--arch/alpha/kernel/module.c8
-rw-r--r--arch/alpha/kernel/osf_sys.c12
-rw-r--r--arch/alpha/kernel/pci-noop.c2
-rw-r--r--arch/alpha/kernel/pci_iommu.c2
-rw-r--r--arch/alpha/kernel/process.c4
-rw-r--r--arch/alpha/kernel/smp.c172
-rw-r--r--arch/alpha/kernel/sys_dp264.c41
-rw-r--r--arch/alpha/kernel/sys_marvel.c5
-rw-r--r--arch/alpha/kernel/traps.c15
-rw-r--r--arch/alpha/lib/dbg_stackcheck.S2
-rw-r--r--arch/alpha/lib/dbg_stackkill.S2
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/Makefile13
-rw-r--r--arch/arm/boot/compressed/head.S3
-rw-r--r--arch/arm/boot/compressed/ofw-shark.c2
-rw-r--r--arch/arm/common/gic.c2
-rw-r--r--arch/arm/common/locomo.c102
-rw-r--r--arch/arm/common/scoop.c22
-rw-r--r--arch/arm/configs/collie_defconfig888
-rw-r--r--arch/arm/configs/corgi_defconfig1523
-rw-r--r--arch/arm/configs/enp2611_defconfig182
-rw-r--r--arch/arm/configs/ixdp2400_defconfig182
-rw-r--r--arch/arm/configs/ixdp2401_defconfig182
-rw-r--r--arch/arm/configs/ixdp2800_defconfig182
-rw-r--r--arch/arm/configs/ixdp2801_defconfig182
-rw-r--r--arch/arm/configs/ixp4xx_defconfig577
-rw-r--r--arch/arm/configs/mp1000_defconfig897
-rw-r--r--arch/arm/configs/poodle_defconfig1015
-rw-r--r--arch/arm/configs/s3c2410_defconfig218
-rw-r--r--arch/arm/configs/spitz_defconfig1401
-rw-r--r--arch/arm/kernel/armksyms.c4
-rw-r--r--arch/arm/kernel/calls.S7
-rw-r--r--arch/arm/kernel/entry-armv.S2
-rw-r--r--arch/arm/kernel/entry-common.S15
-rw-r--r--arch/arm/kernel/entry-header.S2
-rw-r--r--arch/arm/kernel/head.S2
-rw-r--r--arch/arm/kernel/io.c6
-rw-r--r--arch/arm/kernel/iwmmxt.S2
-rw-r--r--arch/arm/kernel/module.c1
-rw-r--r--arch/arm/kernel/semaphore.c2
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/traps.c9
-rw-r--r--arch/arm/kernel/vmlinux.lds.S23
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/copy_page.S2
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S2
-rw-r--r--arch/arm/lib/getuser.S2
-rw-r--r--arch/arm/lib/putuser.S2
-rw-r--r--arch/arm/lib/sha1.S206
-rw-r--r--arch/arm/mach-aaec2000/Makefile2
-rw-r--r--arch/arm/mach-aaec2000/aaed2000.c50
-rw-r--r--arch/arm/mach-aaec2000/clock.c110
-rw-r--r--arch/arm/mach-aaec2000/clock.h23
-rw-r--r--arch/arm/mach-aaec2000/core.c135
-rw-r--r--arch/arm/mach-aaec2000/core.h11
-rw-r--r--arch/arm/mach-clps711x/Kconfig11
-rw-r--r--arch/arm/mach-clps711x/Makefile1
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c12
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c7
-rw-r--r--arch/arm/mach-clps711x/ceiva.c12
-rw-r--r--arch/arm/mach-clps711x/edb7211-mm.c30
-rw-r--r--arch/arm/mach-clps711x/fortunet.c2
-rw-r--r--arch/arm/mach-clps711x/mm.c8
-rw-r--r--arch/arm/mach-clps711x/mp1000-mach.c49
-rw-r--r--arch/arm/mach-clps711x/mp1000-mm.c47
-rw-r--r--arch/arm/mach-clps711x/mp1000-seprom.c195
-rw-r--r--arch/arm/mach-clps711x/p720t.c14
-rw-r--r--arch/arm/mach-clps7500/core.c27
-rw-r--r--arch/arm/mach-ebsa110/core.c40
-rw-r--r--arch/arm/mach-ebsa110/io.c1
-rw-r--r--arch/arm/mach-epxa10db/arch.c2
-rw-r--r--arch/arm/mach-epxa10db/mm.c37
-rw-r--r--arch/arm/mach-footbridge/common.c57
-rw-r--r--arch/arm/mach-footbridge/isa.c2
-rw-r--r--arch/arm/mach-h720x/common.c7
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c2
-rw-r--r--arch/arm/mach-imx/generic.c31
-rw-r--r--arch/arm/mach-imx/leds-mx1ads.c1
-rw-r--r--arch/arm/mach-imx/mx1ads.c40
-rw-r--r--arch/arm/mach-integrator/impd1.c15
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c79
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c67
-rw-r--r--arch/arm/mach-iop3xx/common.c1
-rw-r--r--arch/arm/mach-iop3xx/iop321-setup.c18
-rw-r--r--arch/arm/mach-iop3xx/iop321-time.c1
-rw-r--r--arch/arm/mach-iop3xx/iop331-setup.c18
-rw-r--r--arch/arm/mach-iop3xx/iop331-time.c1
-rw-r--r--arch/arm/mach-iop3xx/iq31244-mm.c11
-rw-r--r--arch/arm/mach-iop3xx/iq80321-mm.c11
-rw-r--r--arch/arm/mach-iop3xx/iq80331-mm.c1
-rw-r--r--arch/arm/mach-iop3xx/iq80332-mm.c1
-rw-r--r--arch/arm/mach-ixp2000/core.c21
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c2
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c2
-rw-r--r--arch/arm/mach-ixp2000/pci.c1
-rw-r--r--arch/arm/mach-ixp4xx/common.c13
-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.c8
-rw-r--r--arch/arm/mach-l7200/core.c21
-rw-r--r--arch/arm/mach-lh7a40x/arch-kev7a400.c13
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c86
-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.c21
-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.c13
-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.c76
-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/Kconfig49
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/corgi.c123
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c216
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c68
-rw-r--r--arch/arm/mach-pxa/generic.c106
-rw-r--r--arch/arm/mach-pxa/idp.c21
-rw-r--r--arch/arm/mach-pxa/lubbock.c33
-rw-r--r--arch/arm/mach-pxa/mainstone.c32
-rw-r--r--arch/arm/mach-pxa/poodle.c113
-rw-r--r--arch/arm/mach-pxa/pxa25x.c2
-rw-r--r--arch/arm/mach-pxa/pxa27x.c2
-rw-r--r--arch/arm/mach-pxa/sharpsl.h34
-rw-r--r--arch/arm/mach-pxa/sleep.S7
-rw-r--r--arch/arm/mach-pxa/spitz.c378
-rw-r--r--arch/arm/mach-pxa/standby.S2
-rw-r--r--arch/arm/mach-rpc/riscpc.c21
-rw-r--r--arch/arm/mach-s3c2410/Kconfig1
-rw-r--r--arch/arm/mach-s3c2410/clock.c5
-rw-r--r--arch/arm/mach-s3c2410/cpu.h2
-rw-r--r--arch/arm/mach-s3c2410/devs.c35
-rw-r--r--arch/arm/mach-s3c2410/gpio.c22
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c55
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c57
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-nexcoder.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c75
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c7
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c4
-rw-r--r--arch/arm/mach-s3c2410/time.c1
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c1
-rw-r--r--arch/arm/mach-sa1100/assabet.c14
-rw-r--r--arch/arm/mach-sa1100/badge4.c20
-rw-r--r--arch/arm/mach-sa1100/cerf.c8
-rw-r--r--arch/arm/mach-sa1100/collie.c25
-rw-r--r--arch/arm/mach-sa1100/generic.c26
-rw-r--r--arch/arm/mach-sa1100/generic.h3
-rw-r--r--arch/arm/mach-sa1100/h3600.c20
-rw-r--r--arch/arm/mach-sa1100/hackkit.c8
-rw-r--r--arch/arm/mach-sa1100/jornada720.c20
-rw-r--r--arch/arm/mach-sa1100/lart.c14
-rw-r--r--arch/arm/mach-sa1100/neponset.c14
-rw-r--r--arch/arm/mach-sa1100/simpad.c16
-rw-r--r--arch/arm/mach-shark/core.c9
-rw-r--r--arch/arm/mach-versatile/core.c127
-rw-r--r--arch/arm/mach-versatile/pci.c1
-rw-r--r--arch/arm/mm/Kconfig8
-rw-r--r--arch/arm/mm/abort-ev6.S5
-rw-r--r--arch/arm/mm/alignment.c55
-rw-r--r--arch/arm/mm/cache-v6.S9
-rw-r--r--arch/arm/mm/consistent.c8
-rw-r--r--arch/arm/mm/copypage-v3.S2
-rw-r--r--arch/arm/mm/copypage-v4wb.S2
-rw-r--r--arch/arm/mm/copypage-v4wt.S2
-rw-r--r--arch/arm/mm/fault.c12
-rw-r--r--arch/arm/mm/flush.c52
-rw-r--r--arch/arm/mm/init.c480
-rw-r--r--arch/arm/mm/ioremap.c1
-rw-r--r--arch/arm/mm/mm-armv.c172
-rw-r--r--arch/arm/mm/proc-arm1020.S4
-rw-r--r--arch/arm/mm/proc-arm1020e.S4
-rw-r--r--arch/arm/mm/proc-arm1022.S4
-rw-r--r--arch/arm/mm/proc-arm1026.S4
-rw-r--r--arch/arm/mm/proc-arm6_7.S4
-rw-r--r--arch/arm/mm/proc-arm720.S4
-rw-r--r--arch/arm/mm/proc-arm920.S2
-rw-r--r--arch/arm/mm/proc-arm922.S2
-rw-r--r--arch/arm/mm/proc-arm925.S2
-rw-r--r--arch/arm/mm/proc-arm926.S2
-rw-r--r--arch/arm/mm/proc-macros.S2
-rw-r--r--arch/arm/mm/proc-sa110.S4
-rw-r--r--arch/arm/mm/proc-sa1100.S4
-rw-r--r--arch/arm/mm/proc-v6.S13
-rw-r--r--arch/arm/mm/proc-xscale.S2
-rw-r--r--arch/arm/mm/tlb-v3.S2
-rw-r--r--arch/arm/mm/tlb-v4.S2
-rw-r--r--arch/arm/mm/tlb-v4wb.S2
-rw-r--r--arch/arm/mm/tlb-v4wbi.S2
-rw-r--r--arch/arm/mm/tlb-v6.S2
-rw-r--r--arch/arm/nwfpe/entry26.S2
-rw-r--r--arch/arm/nwfpe/fpa11.c5
-rw-r--r--arch/arm/nwfpe/fpa11.h20
-rw-r--r--arch/arm/nwfpe/fpa11_cprt.c3
-rw-r--r--arch/arm/nwfpe/fpopcode.h6
-rw-r--r--arch/arm/nwfpe/softfloat.h3
-rw-r--r--arch/arm/oprofile/Makefile4
-rw-r--r--arch/arm/oprofile/common.c185
-rw-r--r--arch/arm/oprofile/init.c33
-rw-r--r--arch/arm/oprofile/op_arm_model.h4
-rw-r--r--arch/arm/plat-omap/common.c1
-rw-r--r--arch/arm/plat-omap/cpu-omap.c1
-rw-r--r--arch/arm/plat-omap/sram.c6
-rw-r--r--arch/arm/plat-omap/usb.c1
-rw-r--r--arch/arm/tools/mach-types90
-rw-r--r--arch/arm/vfp/entry.S2
-rw-r--r--arch/arm26/Makefile10
-rw-r--r--arch/arm26/boot/compressed/hw-bse.c74
-rw-r--r--arch/arm26/kernel/entry.S2
-rw-r--r--arch/arm26/lib/copy_page.S2
-rw-r--r--arch/arm26/lib/csumpartialcopyuser.S2
-rw-r--r--arch/arm26/lib/getuser.S2
-rw-r--r--arch/arm26/lib/putuser.S2
-rw-r--r--arch/arm26/mm/proc-funcs.S2
-rw-r--r--arch/arm26/nwfpe/entry.S2
-rw-r--r--arch/cris/Makefile10
-rw-r--r--arch/cris/arch-v10/kernel/entry.S2
-rw-r--r--arch/cris/arch-v32/drivers/pci/dma.c2
-rw-r--r--arch/cris/arch-v32/kernel/entry.S2
-rw-r--r--arch/cris/arch-v32/kernel/smp.c2
-rw-r--r--arch/frv/kernel/asm-offsets.c1
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c2
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c2
-rw-r--r--arch/frv/mm/dma-alloc.c2
-rw-r--r--arch/h8300/Makefile8
-rw-r--r--arch/i386/Kconfig6
-rw-r--r--arch/i386/Makefile9
-rw-r--r--arch/i386/boot/video.S7
-rw-r--r--arch/i386/defconfig4
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/acpi/Makefile2
-rw-r--r--arch/i386/kernel/acpi/boot.c560
-rw-r--r--arch/i386/kernel/acpi/earlyquirk.c40
-rw-r--r--arch/i386/kernel/acpi/sleep.c35
-rw-r--r--arch/i386/kernel/acpi/wakeup.S6
-rw-r--r--arch/i386/kernel/apic.c1
-rw-r--r--arch/i386/kernel/cpu/amd.c16
-rw-r--r--arch/i386/kernel/cpu/common.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c57
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c30
-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/cpu/mcheck/k7.c1
-rw-r--r--arch/i386/kernel/cpu/mcheck/non-fatal.c1
-rw-r--r--arch/i386/kernel/cpu/mcheck/p4.c1
-rw-r--r--arch/i386/kernel/cpu/mcheck/p5.c1
-rw-r--r--arch/i386/kernel/cpu/mcheck/p6.c1
-rw-r--r--arch/i386/kernel/cpu/mcheck/winchip.c1
-rw-r--r--arch/i386/kernel/crash.c2
-rw-r--r--arch/i386/kernel/entry.S4
-rw-r--r--arch/i386/kernel/head.S2
-rw-r--r--arch/i386/kernel/i8259.c3
-rw-r--r--arch/i386/kernel/io_apic.c16
-rw-r--r--arch/i386/kernel/mpparse.c39
-rw-r--r--arch/i386/kernel/nmi.c1
-rw-r--r--arch/i386/kernel/pci-dma.c2
-rw-r--r--arch/i386/kernel/process.c2
-rw-r--r--arch/i386/kernel/ptrace.c22
-rw-r--r--arch/i386/kernel/reboot.c7
-rw-r--r--arch/i386/kernel/setup.c36
-rw-r--r--arch/i386/kernel/sigframe.h8
-rw-r--r--arch/i386/kernel/signal.c6
-rw-r--r--arch/i386/kernel/smp.c1
-rw-r--r--arch/i386/kernel/smpboot.c6
-rw-r--r--arch/i386/kernel/srat.c8
-rw-r--r--arch/i386/kernel/time.c3
-rw-r--r--arch/i386/kernel/timers/timer_pit.c1
-rw-r--r--arch/i386/kernel/traps.c6
-rw-r--r--arch/i386/kernel/vmlinux.lds.S11
-rw-r--r--arch/i386/kernel/vsyscall-sigreturn.S2
-rw-r--r--arch/i386/kernel/vsyscall.lds.S2
-rw-r--r--arch/i386/lib/Makefile1
-rw-r--r--arch/i386/lib/dec_and_lock.c42
-rw-r--r--arch/i386/mach-default/setup.c1
-rw-r--r--arch/i386/mach-es7000/es7000plat.c4
-rw-r--r--arch/i386/mach-visws/setup.c1
-rw-r--r--arch/i386/mach-visws/visws_apic.c1
-rw-r--r--arch/i386/mach-voyager/setup.c1
-rw-r--r--arch/i386/mach-voyager/voyager_basic.c1
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c2
-rw-r--r--arch/i386/mach-voyager/voyager_thread.c2
-rw-r--r--arch/i386/oprofile/nmi_timer_int.c2
-rw-r--r--arch/i386/pci/Makefile2
-rw-r--r--arch/i386/pci/acpi.c18
-rw-r--r--arch/i386/pci/i386.c6
-rw-r--r--arch/i386/pci/irq.c5
-rw-r--r--arch/i386/pci/mmconfig.c7
-rw-r--r--arch/i386/power/cpu.c17
-rw-r--r--arch/i386/power/swsusp.S2
-rw-r--r--arch/ia64/Kconfig41
-rw-r--r--arch/ia64/Makefile19
-rw-r--r--arch/ia64/configs/bigsur_defconfig6
-rw-r--r--arch/ia64/configs/sn2_defconfig8
-rw-r--r--arch/ia64/configs/tiger_defconfig8
-rw-r--r--arch/ia64/configs/zx1_defconfig8
-rw-r--r--arch/ia64/defconfig9
-rw-r--r--arch/ia64/hp/common/hwsw_iommu.c2
-rw-r--r--arch/ia64/hp/common/sba_iommu.c2
-rw-r--r--arch/ia64/hp/sim/boot/boot_head.S31
-rw-r--r--arch/ia64/hp/sim/simscsi.c29
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c6
-rw-r--r--arch/ia64/ia32/ia32_entry.S2
-rw-r--r--arch/ia64/ia32/sys_ia32.c2
-rw-r--r--arch/ia64/kernel/acpi-ext.c37
-rw-r--r--arch/ia64/kernel/acpi.c330
-rw-r--r--arch/ia64/kernel/asm-offsets.c41
-rw-r--r--arch/ia64/kernel/entry.S31
-rw-r--r--arch/ia64/kernel/fsys.S2
-rw-r--r--arch/ia64/kernel/gate.S2
-rw-r--r--arch/ia64/kernel/head.S2
-rw-r--r--arch/ia64/kernel/iosapic.c24
-rw-r--r--arch/ia64/kernel/ivt.S3
-rw-r--r--arch/ia64/kernel/mca.c835
-rw-r--r--arch/ia64/kernel/mca_asm.S1432
-rw-r--r--arch/ia64/kernel/mca_drv.c160
-rw-r--r--arch/ia64/kernel/mca_drv.h2
-rw-r--r--arch/ia64/kernel/mca_drv_asm.S48
-rw-r--r--arch/ia64/kernel/minstate.h88
-rw-r--r--arch/ia64/kernel/palinfo.c115
-rw-r--r--arch/ia64/kernel/perfmon.c12
-rw-r--r--arch/ia64/kernel/salinfo.c62
-rw-r--r--arch/ia64/kernel/setup.c4
-rw-r--r--arch/ia64/kernel/topology.c2
-rw-r--r--arch/ia64/kernel/unwind.c22
-rw-r--r--arch/ia64/lib/Makefile1
-rw-r--r--arch/ia64/lib/dec_and_lock.c42
-rw-r--r--arch/ia64/lib/memcpy_mck.S3
-rw-r--r--arch/ia64/lib/swiotlb.c6
-rw-r--r--arch/ia64/mm/fault.c6
-rw-r--r--arch/ia64/mm/init.c15
-rw-r--r--arch/ia64/pci/pci.c2
-rw-r--r--arch/ia64/sn/kernel/irq.c2
-rw-r--r--arch/ia64/sn/kernel/setup.c32
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_proc_fs.c2
-rw-r--r--arch/ia64/sn/kernel/xpc.h2
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c4
-rw-r--r--arch/ia64/sn/kernel/xpnet.c6
-rw-r--r--arch/ia64/sn/pci/pci_dma.c2
-rw-r--r--arch/m32r/Kconfig9
-rw-r--r--arch/m32r/Makefile2
-rw-r--r--arch/m32r/kernel/asm-offsets.c1
-rw-r--r--arch/m32r/kernel/entry.S9
-rw-r--r--arch/m32r/kernel/smp.c60
-rw-r--r--arch/m32r/kernel/traps.c33
-rw-r--r--arch/m32r/lib/usercopy.c16
-rw-r--r--arch/m68k/Makefile9
-rw-r--r--arch/m68k/amiga/amisound.c2
-rw-r--r--arch/m68k/fpsp040/skeleton.S2
-rw-r--r--arch/m68k/ifpsp060/iskeleton.S2
-rw-r--r--arch/m68k/kernel/entry.S2
-rw-r--r--arch/m68k/kernel/head.S2
-rw-r--r--arch/m68k/mac/macboing.c3
-rw-r--r--arch/m68k/math-emu/fp_emu.h2
-rw-r--r--arch/m68knommu/Makefile10
-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/head-de2.S135
-rw-r--r--arch/m68knommu/platform/68328/timers.c106
-rw-r--r--arch/m68knommu/platform/68360/head-ram.S408
-rw-r--r--arch/m68knommu/platform/68360/head-rom.S420
-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/Kconfig11
-rw-r--r--arch/mips/Makefile35
-rw-r--r--arch/mips/configs/tb0287_defconfig1041
-rw-r--r--arch/mips/kernel/asm-offsets.c (renamed from arch/mips/kernel/offset.c)0
-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/kernel/irixsig.c17
-rw-r--r--arch/mips/kernel/r2300_fpu.S2
-rw-r--r--arch/mips/kernel/r2300_switch.S2
-rw-r--r--arch/mips/kernel/r4k_fpu.S2
-rw-r--r--arch/mips/kernel/r4k_switch.S2
-rw-r--r--arch/mips/kernel/r6000_fpu.S2
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/syscall.c2
-rw-r--r--arch/mips/kernel/sysirix.c12
-rw-r--r--arch/mips/lib-32/memset.S2
-rw-r--r--arch/mips/lib-64/memset.S2
-rw-r--r--arch/mips/lib/Makefile2
-rw-r--r--arch/mips/lib/dec_and_lock.c55
-rw-r--r--arch/mips/lib/memcpy.S2
-rw-r--r--arch/mips/lib/strlen_user.S2
-rw-r--r--arch/mips/lib/strncpy_user.S2
-rw-r--r--arch/mips/lib/strnlen_user.S2
-rw-r--r--arch/mips/mm/dma-coherent.c4
-rw-r--r--arch/mips/mm/dma-ip27.c4
-rw-r--r--arch/mips/mm/dma-ip32.c4
-rw-r--r--arch/mips/mm/dma-noncoherent.c4
-rw-r--r--arch/mips/pci/Makefile1
-rw-r--r--arch/mips/pci/fixup-tb0226.c33
-rw-r--r--arch/mips/pci/fixup-tb0287.c65
-rw-r--r--arch/parisc/Makefile10
-rw-r--r--arch/parisc/hpux/gate.S2
-rw-r--r--arch/parisc/hpux/wrappers.S2
-rw-r--r--arch/parisc/kernel/entry.S2
-rw-r--r--arch/parisc/kernel/head.S2
-rw-r--r--arch/parisc/kernel/pci-dma.c6
-rw-r--r--arch/parisc/kernel/process.c2
-rw-r--r--arch/parisc/kernel/ptrace.c2
-rw-r--r--arch/parisc/kernel/signal.c2
-rw-r--r--arch/parisc/kernel/syscall.S2
-rw-r--r--arch/parisc/lib/Makefile2
-rw-r--r--arch/parisc/lib/bitops.c4
-rw-r--r--arch/parisc/lib/debuglocks.c277
-rw-r--r--arch/parisc/lib/fixup.S2
-rw-r--r--arch/ppc/8xx_io/cs4218.h2
-rw-r--r--arch/ppc/8xx_io/cs4218_tdm.c6
-rw-r--r--arch/ppc/Kconfig23
-rw-r--r--arch/ppc/Makefile28
-rw-r--r--arch/ppc/boot/common/ns16550.c8
-rw-r--r--arch/ppc/boot/common/util.S2
-rw-r--r--arch/ppc/boot/ld.script2
-rw-r--r--arch/ppc/kernel/cpu_setup_6xx.S3
-rw-r--r--arch/ppc/kernel/cpu_setup_power4.S3
-rw-r--r--arch/ppc/kernel/cputable.c5
-rw-r--r--arch/ppc/kernel/dma-mapping.c10
-rw-r--r--arch/ppc/kernel/entry.S2
-rw-r--r--arch/ppc/kernel/fpu.S2
-rw-r--r--arch/ppc/kernel/head.S30
-rw-r--r--arch/ppc/kernel/head_44x.S2
-rw-r--r--arch/ppc/kernel/head_4xx.S3
-rw-r--r--arch/ppc/kernel/head_8xx.S2
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S2
-rw-r--r--arch/ppc/kernel/idle.c6
-rw-r--r--arch/ppc/kernel/idle_6xx.S2
-rw-r--r--arch/ppc/kernel/idle_power4.S2
-rw-r--r--arch/ppc/kernel/misc.S2
-rw-r--r--arch/ppc/kernel/pci.c1
-rw-r--r--arch/ppc/kernel/perfmon.c7
-rw-r--r--arch/ppc/kernel/smp.c44
-rw-r--r--arch/ppc/kernel/swsusp.S2
-rw-r--r--arch/ppc/kernel/syscalls.c4
-rw-r--r--arch/ppc/kernel/temp.c1
-rw-r--r--arch/ppc/kernel/time.c1
-rw-r--r--arch/ppc/kernel/traps.c24
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S4
-rw-r--r--arch/ppc/lib/Makefile3
-rw-r--r--arch/ppc/lib/dec_and_lock.c46
-rw-r--r--arch/ppc/mm/fault.c6
-rw-r--r--arch/ppc/mm/hashtable.S2
-rw-r--r--arch/ppc/mm/pgtable.c4
-rw-r--r--arch/ppc/platforms/4xx/bamboo.c1
-rw-r--r--arch/ppc/platforms/4xx/ebony.c14
-rw-r--r--arch/ppc/platforms/4xx/luan.c1
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c1
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c1
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c1
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.c1
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c1
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c1
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.c1
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c1
-rw-r--r--arch/ppc/platforms/chestnut.c1
-rw-r--r--arch/ppc/platforms/chrp_setup.c1
-rw-r--r--arch/ppc/platforms/chrp_time.c1
-rw-r--r--arch/ppc/platforms/gemini_setup.c1
-rw-r--r--arch/ppc/platforms/hdpu.c2
-rw-r--r--arch/ppc/platforms/mvme5100.c1
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c7
-rw-r--r--arch/ppc/platforms/pmac_feature.c4
-rw-r--r--arch/ppc/platforms/pmac_setup.c11
-rw-r--r--arch/ppc/platforms/pmac_sleep.S4
-rw-r--r--arch/ppc/platforms/pmac_smp.c85
-rw-r--r--arch/ppc/platforms/pmac_time.c2
-rw-r--r--arch/ppc/platforms/powerpmc250.c1
-rw-r--r--arch/ppc/platforms/pplus.c1
-rw-r--r--arch/ppc/platforms/prpmc750.c1
-rw-r--r--arch/ppc/platforms/prpmc800.c1
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c2
-rw-r--r--arch/ppc/platforms/sandpoint.c1
-rw-r--r--arch/ppc/syslib/Makefile3
-rw-r--r--arch/ppc/syslib/cpc700_pic.c12
-rw-r--r--arch/ppc/syslib/i8259.c13
-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/mpc8xx_devices.c224
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c61
-rw-r--r--arch/ppc/syslib/mv64x60.c6
-rw-r--r--arch/ppc/syslib/of_device.c6
-rw-r--r--arch/ppc/syslib/open_pic.c1
-rw-r--r--arch/ppc/syslib/open_pic2.c15
-rw-r--r--arch/ppc/syslib/ppc403_pic.c11
-rw-r--r--arch/ppc/syslib/ppc4xx_setup.c1
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c8
-rw-r--r--arch/ppc/syslib/prep_nvram.c1
-rw-r--r--arch/ppc/syslib/qspan_pci.c2
-rw-r--r--arch/ppc/syslib/xilinx_pic.c13
-rw-r--r--arch/ppc64/Kconfig4
-rw-r--r--arch/ppc64/Makefile45
-rw-r--r--arch/ppc64/boot/Makefile53
-rw-r--r--arch/ppc64/boot/main.c31
-rw-r--r--arch/ppc64/configs/bpa_defconfig79
-rw-r--r--arch/ppc64/configs/g5_defconfig124
-rw-r--r--arch/ppc64/configs/iSeries_defconfig78
-rw-r--r--arch/ppc64/configs/maple_defconfig67
-rw-r--r--arch/ppc64/configs/pSeries_defconfig95
-rw-r--r--arch/ppc64/defconfig100
-rw-r--r--arch/ppc64/kernel/asm-offsets.c1
-rw-r--r--arch/ppc64/kernel/bpa_iic.c28
-rw-r--r--arch/ppc64/kernel/bpa_iommu.c8
-rw-r--r--arch/ppc64/kernel/cpu_setup_power4.S3
-rw-r--r--arch/ppc64/kernel/dma.c2
-rw-r--r--arch/ppc64/kernel/eeh.c86
-rw-r--r--arch/ppc64/kernel/entry.S20
-rw-r--r--arch/ppc64/kernel/head.S8
-rw-r--r--arch/ppc64/kernel/iSeries_VpdInfo.c5
-rw-r--r--arch/ppc64/kernel/iSeries_htab.c2
-rw-r--r--arch/ppc64/kernel/iSeries_pci.c2
-rw-r--r--arch/ppc64/kernel/idle_power4.S2
-rw-r--r--arch/ppc64/kernel/iomap.c32
-rw-r--r--arch/ppc64/kernel/iommu.c5
-rw-r--r--arch/ppc64/kernel/kprobes.c8
-rw-r--r--arch/ppc64/kernel/machine_kexec.c1
-rw-r--r--arch/ppc64/kernel/maple_pci.c60
-rw-r--r--arch/ppc64/kernel/misc.S8
-rw-r--r--arch/ppc64/kernel/module.c13
-rw-r--r--arch/ppc64/kernel/mpic.c4
-rw-r--r--arch/ppc64/kernel/of_device.c7
-rw-r--r--arch/ppc64/kernel/pSeries_iommu.c219
-rw-r--r--arch/ppc64/kernel/pSeries_pci.c4
-rw-r--r--arch/ppc64/kernel/pSeries_setup.c10
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c13
-rw-r--r--arch/ppc64/kernel/pci.c483
-rw-r--r--arch/ppc64/kernel/pci.h1
-rw-r--r--arch/ppc64/kernel/pci_direct_iommu.c2
-rw-r--r--arch/ppc64/kernel/pci_dn.c47
-rw-r--r--arch/ppc64/kernel/pci_iommu.c4
-rw-r--r--arch/ppc64/kernel/pmac_feature.c8
-rw-r--r--arch/ppc64/kernel/pmac_pci.c66
-rw-r--r--arch/ppc64/kernel/pmac_setup.c34
-rw-r--r--arch/ppc64/kernel/pmac_time.c4
-rw-r--r--arch/ppc64/kernel/pmc.c2
-rw-r--r--arch/ppc64/kernel/process.c34
-rw-r--r--arch/ppc64/kernel/prom.c1
-rw-r--r--arch/ppc64/kernel/prom_init.c3
-rw-r--r--arch/ppc64/kernel/ptrace.c29
-rw-r--r--arch/ppc64/kernel/ptrace32.c34
-rw-r--r--arch/ppc64/kernel/ras.c2
-rw-r--r--arch/ppc64/kernel/rtas_pci.c39
-rw-r--r--arch/ppc64/kernel/setup.c18
-rw-r--r--arch/ppc64/kernel/signal.c9
-rw-r--r--arch/ppc64/kernel/signal32.c8
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c55
-rw-r--r--arch/ppc64/kernel/syscalls.c4
-rw-r--r--arch/ppc64/kernel/time.c2
-rw-r--r--arch/ppc64/kernel/u3_iommu.c4
-rw-r--r--arch/ppc64/kernel/udbg.c6
-rw-r--r--arch/ppc64/kernel/vdso.c15
-rw-r--r--arch/ppc64/kernel/vdso32/cacheflush.S2
-rw-r--r--arch/ppc64/kernel/vdso32/datapage.S2
-rw-r--r--arch/ppc64/kernel/vdso32/gettimeofday.S4
-rw-r--r--arch/ppc64/kernel/vdso64/cacheflush.S2
-rw-r--r--arch/ppc64/kernel/vdso64/datapage.S2
-rw-r--r--arch/ppc64/kernel/vdso64/gettimeofday.S2
-rw-r--r--arch/ppc64/kernel/vio.c2
-rw-r--r--arch/ppc64/kernel/xics.c44
-rw-r--r--arch/ppc64/lib/Makefile2
-rw-r--r--arch/ppc64/lib/dec_and_lock.c55
-rw-r--r--arch/ppc64/lib/locks.c14
-rw-r--r--arch/ppc64/mm/fault.c32
-rw-r--r--arch/ppc64/mm/hash_low.S2
-rw-r--r--arch/ppc64/mm/hash_native.c6
-rw-r--r--arch/ppc64/mm/hugetlbpage.c7
-rw-r--r--arch/ppc64/mm/init.c7
-rw-r--r--arch/ppc64/mm/slb_low.S2
-rw-r--r--arch/ppc64/mm/tlb.c4
-rw-r--r--arch/ppc64/xmon/privinst.h1
-rw-r--r--arch/ppc64/xmon/xmon.c20
-rw-r--r--arch/s390/Makefile12
-rw-r--r--arch/s390/defconfig36
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/compat_linux.c2
-rw-r--r--arch/s390/kernel/compat_signal.c6
-rw-r--r--arch/s390/kernel/entry.S4
-rw-r--r--arch/s390/kernel/entry64.S4
-rw-r--r--arch/s390/kernel/head.S2
-rw-r--r--arch/s390/kernel/head64.S2
-rw-r--r--arch/s390/kernel/reipl_diag.c39
-rw-r--r--arch/s390/kernel/setup.c5
-rw-r--r--arch/s390/kernel/signal.c4
-rw-r--r--arch/s390/kernel/smp.c3
-rw-r--r--arch/s390/lib/spinlock.c12
-rw-r--r--arch/s390/lib/uaccess.S2
-rw-r--r--arch/s390/lib/uaccess64.S2
-rw-r--r--arch/sh/Makefile13
-rw-r--r--arch/sh/boards/adx/irq_maskreg.c14
-rw-r--r--arch/sh/boards/bigsur/io.c8
-rw-r--r--arch/sh/boards/bigsur/irq.c28
-rw-r--r--arch/sh/boards/cqreek/irq.c14
-rw-r--r--arch/sh/boards/harp/irq.c14
-rw-r--r--arch/sh/boards/overdrive/irq.c14
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/irq.c14
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/irq.c14
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/mach.c2
-rw-r--r--arch/sh/boards/renesas/systemh/irq.c14
-rw-r--r--arch/sh/boards/superh/microdev/irq.c14
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/io.c8
-rw-r--r--arch/sh/cchips/voyagergx/consistent.c2
-rw-r--r--arch/sh/cchips/voyagergx/irq.c14
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c2
-rw-r--r--arch/sh/kernel/cpu/irq_imask.c14
-rw-r--r--arch/sh/kernel/cpu/irq_ipr.c28
-rw-r--r--arch/sh/kernel/cpu/sh4/irq_intc2.c14
-rw-r--r--arch/sh/kernel/smp.c3
-rw-r--r--arch/sh/mm/consistent.c2
-rw-r--r--arch/sh64/Makefile8
-rw-r--r--arch/sh64/kernel/irq_intc.c14
-rw-r--r--arch/sparc/Kconfig56
-rw-r--r--arch/sparc/Makefile12
-rw-r--r--arch/sparc/kernel/entry.S2
-rw-r--r--arch/sparc/kernel/module.c9
-rw-r--r--arch/sparc/kernel/sclow.S2
-rw-r--r--arch/sparc/kernel/setup.c2
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c41
-rw-r--r--arch/sparc/kernel/time.c2
-rw-r--r--arch/sparc/lib/Makefile2
-rw-r--r--arch/sparc/lib/atomic32.c2
-rw-r--r--arch/sparc/lib/debuglocks.c202
-rw-r--r--arch/sparc/lib/mul.S2
-rw-r--r--arch/sparc/lib/rem.S2
-rw-r--r--arch/sparc/lib/sdiv.S2
-rw-r--r--arch/sparc/lib/udiv.S2
-rw-r--r--arch/sparc/lib/umul.S2
-rw-r--r--arch/sparc/lib/urem.S2
-rw-r--r--arch/sparc/mm/hypersparc.S2
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc/mm/swift.S2
-rw-r--r--arch/sparc/mm/tsunami.S2
-rw-r--r--arch/sparc/mm/viking.S2
-rw-r--r--arch/sparc64/Kconfig.debug14
-rw-r--r--arch/sparc64/kernel/asm-offsets.c1
-rw-r--r--arch/sparc64/kernel/cpu.c4
-rw-r--r--arch/sparc64/kernel/devices.c22
-rw-r--r--arch/sparc64/kernel/dtlb_backend.S13
-rw-r--r--arch/sparc64/kernel/dtlb_base.S18
-rw-r--r--arch/sparc64/kernel/dtlb_prot.S12
-rw-r--r--arch/sparc64/kernel/entry.S263
-rw-r--r--arch/sparc64/kernel/etrap.S51
-rw-r--r--arch/sparc64/kernel/head.S748
-rw-r--r--arch/sparc64/kernel/irq.c1
-rw-r--r--arch/sparc64/kernel/itlb_base.S26
-rw-r--r--arch/sparc64/kernel/ktlb.S194
-rw-r--r--arch/sparc64/kernel/pci.c127
-rw-r--r--arch/sparc64/kernel/pci_iommu.c363
-rw-r--r--arch/sparc64/kernel/pci_psycho.c78
-rw-r--r--arch/sparc64/kernel/pci_sabre.c75
-rw-r--r--arch/sparc64/kernel/pci_schizo.c107
-rw-r--r--arch/sparc64/kernel/power.c64
-rw-r--r--arch/sparc64/kernel/process.c5
-rw-r--r--arch/sparc64/kernel/ptrace.c21
-rw-r--r--arch/sparc64/kernel/rtrap.S30
-rw-r--r--arch/sparc64/kernel/setup.c58
-rw-r--r--arch/sparc64/kernel/smp.c28
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c17
-rw-r--r--arch/sparc64/kernel/sys32.S170
-rw-r--r--arch/sparc64/kernel/trampoline.S31
-rw-r--r--arch/sparc64/kernel/traps.c100
-rw-r--r--arch/sparc64/kernel/una_asm.S67
-rw-r--r--arch/sparc64/kernel/unaligned.c101
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c5
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S3
-rw-r--r--arch/sparc64/kernel/winfixup.S33
-rw-r--r--arch/sparc64/lib/Makefile5
-rw-r--r--arch/sparc64/lib/VISsave.S8
-rw-r--r--arch/sparc64/lib/debuglocks.c366
-rw-r--r--arch/sparc64/lib/dec_and_lock.S80
-rw-r--r--arch/sparc64/lib/mb.S73
-rw-r--r--arch/sparc64/lib/strncpy_from_user.S16
-rw-r--r--arch/sparc64/lib/user_fixup.c63
-rw-r--r--arch/sparc64/mm/Makefile2
-rw-r--r--arch/sparc64/mm/extable.c80
-rw-r--r--arch/sparc64/mm/fault.c69
-rw-r--r--arch/sparc64/mm/init.c868
-rw-r--r--arch/sparc64/mm/ultra.S112
-rw-r--r--arch/sparc64/prom/Makefile4
-rw-r--r--arch/sparc64/prom/console.c2
-rw-r--r--arch/sparc64/prom/devops.c2
-rw-r--r--arch/sparc64/prom/init.c5
-rw-r--r--arch/sparc64/prom/map.S72
-rw-r--r--arch/sparc64/prom/memory.c152
-rw-r--r--arch/sparc64/prom/misc.c46
-rw-r--r--arch/sparc64/prom/p1275.c2
-rw-r--r--arch/sparc64/prom/printf.c2
-rw-r--r--arch/sparc64/prom/tree.c50
-rw-r--r--arch/sparc64/solaris/ioctl.c15
-rw-r--r--arch/sparc64/solaris/socksys.c2
-rw-r--r--arch/sparc64/solaris/timod.c31
-rw-r--r--arch/um/Kconfig.i3864
-rw-r--r--arch/um/Makefile87
-rw-r--r--arch/um/Makefile-i38622
-rw-r--r--arch/um/Makefile-skas2
-rw-r--r--arch/um/Makefile-x86_6422
-rw-r--r--arch/um/drivers/Makefile2
-rw-r--r--arch/um/drivers/chan_kern.c60
-rw-r--r--arch/um/drivers/cow.h39
-rw-r--r--arch/um/drivers/cow_user.c1
-rw-r--r--arch/um/drivers/mcast_user.c12
-rw-r--r--arch/um/drivers/mconsole_kern.c52
-rw-r--r--arch/um/drivers/mconsole_user.c7
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/drivers/pty.c3
-rw-r--r--arch/um/drivers/ubd_kern.c556
-rw-r--r--arch/um/drivers/xterm.c6
-rw-r--r--arch/um/include/aio.h18
-rw-r--r--arch/um/include/common-offsets.h8
-rw-r--r--arch/um/include/mconsole.h1
-rw-r--r--arch/um/include/mem.h12
-rw-r--r--arch/um/include/mem_user.h15
-rw-r--r--arch/um/include/os.h14
-rw-r--r--arch/um/include/registers.h12
-rw-r--r--arch/um/include/skas_ptregs.h6
-rw-r--r--arch/um/include/sysdep-i386/sc.h44
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h10
-rw-r--r--arch/um/include/sysdep-i386/thread.h11
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h8
-rw-r--r--arch/um/include/sysdep-x86_64/sc.h45
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h5
-rw-r--r--arch/um/include/sysdep-x86_64/thread.h10
-rw-r--r--arch/um/include/task.h9
-rw-r--r--arch/um/include/user.h4
-rw-r--r--arch/um/kernel/Makefile16
-rw-r--r--arch/um/kernel/asm-offsets.c1
-rw-r--r--arch/um/kernel/dyn.lds.S37
-rw-r--r--arch/um/kernel/helper.c12
-rw-r--r--arch/um/kernel/init_task.c5
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/ksyms.c5
-rw-r--r--arch/um/kernel/mem.c18
-rw-r--r--arch/um/kernel/mem_user.c273
-rw-r--r--arch/um/kernel/physmem.c35
-rw-r--r--arch/um/kernel/process_kern.c24
-rw-r--r--arch/um/kernel/sigio_user.c2
-rw-r--r--arch/um/kernel/skas/Makefile2
-rw-r--r--arch/um/kernel/skas/include/mode_kern-skas.h2
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h18
-rw-r--r--arch/um/kernel/skas/process_kern.c7
-rw-r--r--arch/um/kernel/skas/util/Makefile5
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c49
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c66
-rw-r--r--arch/um/kernel/sysrq.c8
-rw-r--r--arch/um/kernel/tempfile.c82
-rw-r--r--arch/um/kernel/tlb.c14
-rw-r--r--arch/um/kernel/trap_kern.c27
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h2
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h18
-rw-r--r--arch/um/kernel/tt/mem_user.c1
-rw-r--r--arch/um/kernel/tt/process_kern.c8
-rw-r--r--arch/um/kernel/tt/uaccess_user.c11
-rw-r--r--arch/um/kernel/um_arch.c7
-rw-r--r--arch/um/kernel/umid.c41
-rw-r--r--arch/um/kernel/uml.lds.S14
-rw-r--r--arch/um/kernel/user_util.c18
-rw-r--r--arch/um/os-Linux/Makefile8
-rw-r--r--arch/um/os-Linux/aio.c211
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c8
-rw-r--r--arch/um/os-Linux/elf_aux.c8
-rw-r--r--arch/um/os-Linux/file.c82
-rw-r--r--arch/um/os-Linux/mem.c161
-rw-r--r--arch/um/os-Linux/process.c1
-rw-r--r--arch/um/os-Linux/start_up.c120
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c19
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c19
-rw-r--r--arch/um/os-Linux/tt.c14
-rw-r--r--arch/um/os-Linux/util/Makefile4
-rw-r--r--arch/um/os-Linux/util/mk_user_constants.c23
-rw-r--r--arch/um/scripts/Makefile.rules9
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/kernel-offsets.c4
-rw-r--r--arch/um/sys-i386/ldt.c1
-rw-r--r--arch/um/sys-i386/sysrq.c13
-rw-r--r--arch/um/sys-i386/user-offsets.c71
-rw-r--r--arch/um/sys-i386/util/Makefile5
-rw-r--r--arch/um/sys-i386/util/mk_sc.c51
-rw-r--r--arch/um/sys-i386/util/mk_thread.c22
-rw-r--r--arch/um/sys-x86_64/Makefile2
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c2
-rw-r--r--arch/um/sys-x86_64/stub_segv.c37
-rw-r--r--arch/um/sys-x86_64/user-offsets.c117
-rw-r--r--arch/um/sys-x86_64/util/Makefile8
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c47
-rw-r--r--arch/um/sys-x86_64/util/mk_thread.c20
-rw-r--r--arch/um/util/Makefile5
-rw-r--r--arch/um/util/mk_constants.c32
-rw-r--r--arch/um/util/mk_task.c30
-rw-r--r--arch/v850/Makefile14
-rw-r--r--arch/v850/kernel/asm-offsets.c (renamed from arch/v850/kernel/asm-consts.c)0
-rw-r--r--arch/v850/kernel/entry.S2
-rw-r--r--arch/v850/kernel/irq.c14
-rw-r--r--arch/v850/kernel/setup.c14
-rw-r--r--arch/v850/kernel/sim.c14
-rw-r--r--arch/x86_64/Kconfig9
-rw-r--r--arch/x86_64/Makefile10
-rw-r--r--arch/x86_64/boot/Makefile2
-rw-r--r--arch/x86_64/boot/compressed/misc.c6
-rw-r--r--arch/x86_64/defconfig69
-rw-r--r--arch/x86_64/ia32/ia32_binfmt.c5
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c17
-rw-r--r--arch/x86_64/ia32/ia32_signal.c6
-rw-r--r--arch/x86_64/ia32/ia32entry.S53
-rw-r--r--arch/x86_64/ia32/sys_ia32.c2
-rw-r--r--arch/x86_64/ia32/syscall32.c6
-rw-r--r--arch/x86_64/ia32/vsyscall-syscall.S2
-rw-r--r--arch/x86_64/ia32/vsyscall-sysenter.S2
-rw-r--r--arch/x86_64/kernel/Makefile3
-rw-r--r--arch/x86_64/kernel/acpi/Makefile4
-rw-r--r--arch/x86_64/kernel/acpi/sleep.c18
-rw-r--r--arch/x86_64/kernel/aperture.c2
-rw-r--r--arch/x86_64/kernel/apic.c42
-rw-r--r--arch/x86_64/kernel/asm-offsets.c1
-rw-r--r--arch/x86_64/kernel/crash.c1
-rw-r--r--arch/x86_64/kernel/e820.c21
-rw-r--r--arch/x86_64/kernel/early_printk.c46
-rw-r--r--arch/x86_64/kernel/entry.S224
-rw-r--r--arch/x86_64/kernel/genapic.c22
-rw-r--r--arch/x86_64/kernel/genapic_cluster.c4
-rw-r--r--arch/x86_64/kernel/genapic_flat.c22
-rw-r--r--arch/x86_64/kernel/head.S40
-rw-r--r--arch/x86_64/kernel/i8259.c23
-rw-r--r--arch/x86_64/kernel/init_task.c2
-rw-r--r--arch/x86_64/kernel/io_apic.c33
-rw-r--r--arch/x86_64/kernel/irq.c1
-rw-r--r--arch/x86_64/kernel/kprobes.c8
-rw-r--r--arch/x86_64/kernel/mce.c54
-rw-r--r--arch/x86_64/kernel/mpparse.c19
-rw-r--r--arch/x86_64/kernel/msr.c279
-rw-r--r--arch/x86_64/kernel/nmi.c13
-rw-r--r--arch/x86_64/kernel/pci-gart.c12
-rw-r--r--arch/x86_64/kernel/pci-nommu.c2
-rw-r--r--arch/x86_64/kernel/process.c38
-rw-r--r--arch/x86_64/kernel/setup.c113
-rw-r--r--arch/x86_64/kernel/setup64.c7
-rw-r--r--arch/x86_64/kernel/smp.c129
-rw-r--r--arch/x86_64/kernel/smpboot.c72
-rw-r--r--arch/x86_64/kernel/suspend.c144
-rw-r--r--arch/x86_64/kernel/suspend_asm.S19
-rw-r--r--arch/x86_64/kernel/time.c5
-rw-r--r--arch/x86_64/kernel/traps.c57
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S19
-rw-r--r--arch/x86_64/kernel/vsyscall.c8
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c4
-rw-r--r--arch/x86_64/lib/Makefile2
-rw-r--r--arch/x86_64/lib/copy_user.S2
-rw-r--r--arch/x86_64/lib/dec_and_lock.c40
-rw-r--r--arch/x86_64/lib/getuser.S2
-rw-r--r--arch/x86_64/lib/putuser.S2
-rw-r--r--arch/x86_64/mm/fault.c10
-rw-r--r--arch/x86_64/mm/init.c79
-rw-r--r--arch/x86_64/mm/k8topology.c13
-rw-r--r--arch/x86_64/mm/numa.c19
-rw-r--r--arch/x86_64/mm/pageattr.c2
-rw-r--r--arch/x86_64/mm/srat.c68
-rw-r--r--arch/x86_64/pci/Makefile2
-rw-r--r--arch/x86_64/pci/Makefile-BUS2
-rw-r--r--arch/x86_64/pci/k8-bus.c10
-rw-r--r--arch/x86_64/pci/mmconfig.c7
-rw-r--r--arch/xtensa/Kconfig4
-rw-r--r--arch/xtensa/Makefile10
-rw-r--r--arch/xtensa/kernel/align.S2
-rw-r--r--arch/xtensa/kernel/entry.S2
-rw-r--r--arch/xtensa/kernel/pci-dma.c2
-rw-r--r--arch/xtensa/kernel/pci.c4
-rw-r--r--arch/xtensa/kernel/platform.c2
-rw-r--r--arch/xtensa/kernel/process.c4
-rw-r--r--arch/xtensa/kernel/setup.c2
-rw-r--r--arch/xtensa/kernel/signal.c2
-rw-r--r--arch/xtensa/kernel/time.c2
-rw-r--r--arch/xtensa/kernel/vectors.S2
-rw-r--r--arch/xtensa/mm/init.c2
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile4
-rw-r--r--drivers/acorn/block/fd1772.c12
-rw-r--r--drivers/acorn/char/pcf8583.c3
-rw-r--r--drivers/acpi/Kconfig84
-rw-r--r--drivers/acpi/Makefile14
-rw-r--r--drivers/acpi/ac.c138
-rw-r--r--drivers/acpi/acpi_memhotplug.c176
-rw-r--r--drivers/acpi/asus_acpi.c690
-rw-r--r--drivers/acpi/battery.c400
-rw-r--r--drivers/acpi/blacklist.c122
-rw-r--r--drivers/acpi/bus.c310
-rw-r--r--drivers/acpi/button.c274
-rw-r--r--drivers/acpi/container.c128
-rw-r--r--drivers/acpi/debug.c115
-rw-r--r--drivers/acpi/dispatcher/dsfield.c346
-rw-r--r--drivers/acpi/dispatcher/dsinit.c141
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c404
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c424
-rw-r--r--drivers/acpi/dispatcher/dsobject.c330
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c723
-rw-r--r--drivers/acpi/dispatcher/dsutils.c421
-rw-r--r--drivers/acpi/dispatcher/dswexec.c519
-rw-r--r--drivers/acpi/dispatcher/dswload.c522
-rw-r--r--drivers/acpi/dispatcher/dswscope.c139
-rw-r--r--drivers/acpi/dispatcher/dswstate.c668
-rw-r--r--drivers/acpi/ec.c1028
-rw-r--r--drivers/acpi/event.c83
-rw-r--r--drivers/acpi/events/evevent.c168
-rw-r--r--drivers/acpi/events/evgpe.c427
-rw-r--r--drivers/acpi/events/evgpeblk.c767
-rw-r--r--drivers/acpi/events/evmisc.c293
-rw-r--r--drivers/acpi/events/evregion.c582
-rw-r--r--drivers/acpi/events/evrgnini.c315
-rw-r--r--drivers/acpi/events/evsci.c77
-rw-r--r--drivers/acpi/events/evxface.c444
-rw-r--r--drivers/acpi/events/evxfevnt.c465
-rw-r--r--drivers/acpi/events/evxfregn.c114
-rw-r--r--drivers/acpi/executer/exconfig.c351
-rw-r--r--drivers/acpi/executer/exconvrt.c311
-rw-r--r--drivers/acpi/executer/excreate.c342
-rw-r--r--drivers/acpi/executer/exdump.c793
-rw-r--r--drivers/acpi/executer/exfield.c253
-rw-r--r--drivers/acpi/executer/exfldio.c644
-rw-r--r--drivers/acpi/executer/exmisc.c358
-rw-r--r--drivers/acpi/executer/exmutex.c160
-rw-r--r--drivers/acpi/executer/exnames.c236
-rw-r--r--drivers/acpi/executer/exoparg1.c574
-rw-r--r--drivers/acpi/executer/exoparg2.c317
-rw-r--r--drivers/acpi/executer/exoparg3.c167
-rw-r--r--drivers/acpi/executer/exoparg6.c127
-rw-r--r--drivers/acpi/executer/exprep.c381
-rw-r--r--drivers/acpi/executer/exregion.c280
-rw-r--r--drivers/acpi/executer/exresnte.c172
-rw-r--r--drivers/acpi/executer/exresolv.c284
-rw-r--r--drivers/acpi/executer/exresop.c398
-rw-r--r--drivers/acpi/executer/exstore.c417
-rw-r--r--drivers/acpi/executer/exstoren.c125
-rw-r--r--drivers/acpi/executer/exstorob.c86
-rw-r--r--drivers/acpi/executer/exsystem.c183
-rw-r--r--drivers/acpi/executer/exutils.c173
-rw-r--r--drivers/acpi/fan.c142
-rw-r--r--drivers/acpi/glue.c17
-rw-r--r--drivers/acpi/hardware/hwacpi.c116
-rw-r--r--drivers/acpi/hardware/hwgpe.c203
-rw-r--r--drivers/acpi/hardware/hwregs.c600
-rw-r--r--drivers/acpi/hardware/hwsleep.c415
-rw-r--r--drivers/acpi/hardware/hwtimer.c77
-rw-r--r--drivers/acpi/hotkey.c233
-rw-r--r--drivers/acpi/ibm_acpi.c1598
-rw-r--r--drivers/acpi/motherboard.c108
-rw-r--r--drivers/acpi/namespace/nsaccess.c355
-rw-r--r--drivers/acpi/namespace/nsalloc.c350
-rw-r--r--drivers/acpi/namespace/nsdump.c461
-rw-r--r--drivers/acpi/namespace/nsdumpdv.c74
-rw-r--r--drivers/acpi/namespace/nseval.c274
-rw-r--r--drivers/acpi/namespace/nsinit.c257
-rw-r--r--drivers/acpi/namespace/nsload.c264
-rw-r--r--drivers/acpi/namespace/nsnames.c118
-rw-r--r--drivers/acpi/namespace/nsobject.c209
-rw-r--r--drivers/acpi/namespace/nsparse.c84
-rw-r--r--drivers/acpi/namespace/nssearch.c205
-rw-r--r--drivers/acpi/namespace/nsutils.c502
-rw-r--r--drivers/acpi/namespace/nswalk.c105
-rw-r--r--drivers/acpi/namespace/nsxfeval.c430
-rw-r--r--drivers/acpi/namespace/nsxfname.c173
-rw-r--r--drivers/acpi/namespace/nsxfobj.c91
-rw-r--r--drivers/acpi/numa.c125
-rw-r--r--drivers/acpi/osl.c695
-rw-r--r--drivers/acpi/parser/Makefile2
-rw-r--r--drivers/acpi/parser/psargs.c376
-rw-r--r--drivers/acpi/parser/psloop.c874
-rw-r--r--drivers/acpi/parser/psopcode.c739
-rw-r--r--drivers/acpi/parser/psparse.c1080
-rw-r--r--drivers/acpi/parser/psscope.c130
-rw-r--r--drivers/acpi/parser/pstree.c92
-rw-r--r--drivers/acpi/parser/psutils.c134
-rw-r--r--drivers/acpi/parser/pswalk.c26
-rw-r--r--drivers/acpi/parser/psxface.c251
-rw-r--r--drivers/acpi/pci_bind.c220
-rw-r--r--drivers/acpi/pci_irq.c275
-rw-r--r--drivers/acpi/pci_link.c482
-rw-r--r--drivers/acpi/pci_root.c130
-rw-r--r--drivers/acpi/power.c271
-rw-r--r--drivers/acpi/processor_core.c437
-rw-r--r--drivers/acpi/processor_idle.c315
-rw-r--r--drivers/acpi/processor_perflib.c297
-rw-r--r--drivers/acpi/processor_thermal.c153
-rw-r--r--drivers/acpi/processor_throttling.c133
-rw-r--r--drivers/acpi/resources/rsaddr.c873
-rw-r--r--drivers/acpi/resources/rscalc.c314
-rw-r--r--drivers/acpi/resources/rscreate.c297
-rw-r--r--drivers/acpi/resources/rsdump.c847
-rw-r--r--drivers/acpi/resources/rsio.c172
-rw-r--r--drivers/acpi/resources/rsirq.c251
-rw-r--r--drivers/acpi/resources/rslist.c279
-rw-r--r--drivers/acpi/resources/rsmemory.c218
-rw-r--r--drivers/acpi/resources/rsmisc.c230
-rw-r--r--drivers/acpi/resources/rsutils.c159
-rw-r--r--drivers/acpi/resources/rsxface.c182
-rw-r--r--drivers/acpi/scan.c437
-rw-r--r--drivers/acpi/sleep/main.c8
-rw-r--r--drivers/acpi/sleep/poweroff.c6
-rw-r--r--drivers/acpi/sleep/proc.c271
-rw-r--r--drivers/acpi/sleep/wakeup.c115
-rw-r--r--drivers/acpi/system.c76
-rw-r--r--drivers/acpi/tables.c434
-rw-r--r--drivers/acpi/tables/tbconvrt.c408
-rw-r--r--drivers/acpi/tables/tbget.c275
-rw-r--r--drivers/acpi/tables/tbgetall.c189
-rw-r--r--drivers/acpi/tables/tbinstal.c264
-rw-r--r--drivers/acpi/tables/tbrsdt.c231
-rw-r--r--drivers/acpi/tables/tbutils.c178
-rw-r--r--drivers/acpi/tables/tbxface.c253
-rw-r--r--drivers/acpi/tables/tbxfroot.c513
-rw-r--r--drivers/acpi/thermal.c801
-rw-r--r--drivers/acpi/toshiba_acpi.c174
-rw-r--r--drivers/acpi/utilities/Makefile2
-rw-r--r--drivers/acpi/utilities/utalloc.c713
-rw-r--r--drivers/acpi/utilities/utcache.c305
-rw-r--r--drivers/acpi/utilities/utcopy.c592
-rw-r--r--drivers/acpi/utilities/utdebug.c400
-rw-r--r--drivers/acpi/utilities/utdelete.c431
-rw-r--r--drivers/acpi/utilities/uteval.c396
-rw-r--r--drivers/acpi/utilities/utglobal.c653
-rw-r--r--drivers/acpi/utilities/utinit.c135
-rw-r--r--drivers/acpi/utilities/utmath.c144
-rw-r--r--drivers/acpi/utilities/utmisc.c1175
-rw-r--r--drivers/acpi/utilities/utmutex.c354
-rw-r--r--drivers/acpi/utilities/utobject.c354
-rw-r--r--drivers/acpi/utilities/utstate.c333
-rw-r--r--drivers/acpi/utilities/utxface.c278
-rw-r--r--drivers/acpi/utils.c195
-rw-r--r--drivers/acpi/video.c1076
-rw-r--r--drivers/atm/ambassador.c2
-rw-r--r--drivers/atm/firestream.c5
-rw-r--r--drivers/atm/fore200e.c10
-rw-r--r--drivers/atm/idt77105.c6
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/base/attribute_container.c5
-rw-r--r--drivers/base/class.c23
-rw-r--r--drivers/base/dd.c3
-rw-r--r--drivers/base/dmapool.c4
-rw-r--r--drivers/base/firmware_class.c9
-rw-r--r--drivers/base/map.c3
-rw-r--r--drivers/base/platform.c3
-rw-r--r--drivers/block/acsi.c2
-rw-r--r--drivers/block/acsi_slm.c2
-rw-r--r--drivers/block/aoe/aoe.h12
-rw-r--r--drivers/block/as-iosched.c327
-rw-r--r--drivers/block/ataflop.c14
-rw-r--r--drivers/block/cciss.c643
-rw-r--r--drivers/block/cciss.h10
-rw-r--r--drivers/block/cciss_cmd.h8
-rw-r--r--drivers/block/cciss_scsi.c69
-rw-r--r--drivers/block/cfq-iosched.c375
-rw-r--r--drivers/block/deadline-iosched.c130
-rw-r--r--drivers/block/elevator.c345
-rw-r--r--drivers/block/floppy.c4
-rw-r--r--drivers/block/ll_rw_blk.c231
-rw-r--r--drivers/block/loop.c2
-rw-r--r--drivers/block/noop-iosched.c48
-rw-r--r--drivers/block/paride/pcd.c3
-rw-r--r--drivers/block/paride/pf.c25
-rw-r--r--drivers/block/paride/pg.c3
-rw-r--r--drivers/block/paride/pt.c3
-rw-r--r--drivers/block/pktcdvd.c89
-rw-r--r--drivers/block/ps2esdi.c3
-rw-r--r--drivers/block/rd.c2
-rw-r--r--drivers/block/scsi_ioctl.c10
-rw-r--r--drivers/block/swim3.c9
-rw-r--r--drivers/block/swim_iop.c3
-rw-r--r--drivers/block/sx8.c51
-rw-r--r--drivers/block/ub.c306
-rw-r--r--drivers/block/umem.c11
-rw-r--r--drivers/block/xd.c21
-rw-r--r--drivers/block/z2ram.c2
-rw-r--r--drivers/bluetooth/bpa10x.c2
-rw-r--r--drivers/bluetooth/hci_usb.c21
-rw-r--r--drivers/bluetooth/hci_usb.h5
-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.c18
-rw-r--r--drivers/cdrom/sjcd.c2
-rw-r--r--drivers/cdrom/sonycd535.c3
-rw-r--r--drivers/char/.gitignore3
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/backend.c7
-rw-r--r--drivers/char/agp/generic.c33
-rw-r--r--drivers/char/agp/hp-agp.c2
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/applicom.c24
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/drm/drmP.h4
-rw-r--r--drivers/char/drm/drm_drv.c2
-rw-r--r--drivers/char/drm/drm_proc.c2
-rw-r--r--drivers/char/drm/drm_stub.c2
-rw-r--r--drivers/char/drm/drm_vm.c3
-rw-r--r--drivers/char/drm/mga_dma.c22
-rw-r--r--drivers/char/drm/mga_drv.h2
-rw-r--r--drivers/char/drm/mga_state.c2
-rw-r--r--drivers/char/drm/radeon_cp.c11
-rw-r--r--drivers/char/epca.c84
-rw-r--r--drivers/char/epca.h12
-rw-r--r--drivers/char/ftape/lowlevel/fdc-io.c6
-rw-r--r--drivers/char/hangcheck-timer.c3
-rw-r--r--drivers/char/hpet.c13
-rw-r--r--drivers/char/hvc_console.c6
-rw-r--r--drivers/char/hw_random.c5
-rw-r--r--drivers/char/ip2/i2lib.c6
-rw-r--r--drivers/char/ip2main.c3
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c5
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c6
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c27
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c6
-rw-r--r--drivers/char/istallion.c2
-rw-r--r--drivers/char/keyboard.c114
-rw-r--r--drivers/char/lcd.c7
-rw-r--r--drivers/char/lp.c3
-rw-r--r--drivers/char/mbcs.c3
-rw-r--r--drivers/char/mxser.c12
-rw-r--r--drivers/char/n_r3964.c92
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/nvram.c110
-rw-r--r--drivers/char/pcmcia/synclink_cs.c16
-rw-r--r--drivers/char/pty.c5
-rw-r--r--drivers/char/s3c2410-rtc.c1
-rw-r--r--drivers/char/synclink.c29
-rw-r--r--drivers/char/synclinkmp.c41
-rw-r--r--drivers/char/tpm/Kconfig2
-rw-r--r--drivers/char/tty_io.c87
-rw-r--r--drivers/char/vt.c38
-rw-r--r--drivers/char/watchdog/Kconfig102
-rw-r--r--drivers/char/watchdog/Makefile8
-rw-r--r--drivers/char/watchdog/i6300esb.c527
-rw-r--r--drivers/char/watchdog/ibmasr.c405
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c436
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c252
-rw-r--r--drivers/char/watchdog/pcwd_pci.c281
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c2
-rw-r--r--drivers/char/watchdog/sbc8360.c414
-rw-r--r--drivers/char/watchdog/w83977f_wdt.c543
-rw-r--r--drivers/connector/Kconfig13
-rw-r--r--drivers/connector/Makefile3
-rw-r--r--drivers/connector/cn_queue.c179
-rw-r--r--drivers/connector/connector.c488
-rw-r--r--drivers/cpufreq/cpufreq.c6
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c6
-rw-r--r--drivers/firmware/dell_rbu.c361
-rw-r--r--drivers/hwmon/Kconfig16
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/hdaps.c616
-rw-r--r--drivers/hwmon/sis5595.c5
-rw-r--r--drivers/hwmon/smsc47m1.c4
-rw-r--r--drivers/hwmon/via686a.c5
-rw-r--r--drivers/hwmon/w83627hf.c14
-rw-r--r--drivers/i2c/busses/Kconfig28
-rw-r--r--drivers/i2c/busses/Makefile2
-rw-r--r--drivers/i2c/busses/i2c-keywest.c1
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c5
-rw-r--r--drivers/i2c/busses/i2c-pmac-smu.c316
-rw-r--r--drivers/i2c/busses/i2c-pxa.c1026
-rw-r--r--drivers/ide/ide-io.c14
-rw-r--r--drivers/ide/ide-iops.c41
-rw-r--r--drivers/ide/ide-tape.c3
-rw-r--r--drivers/ide/ide-taskfile.c1
-rw-r--r--drivers/ide/ide-timing.h25
-rw-r--r--drivers/ide/legacy/ide-cs.c12
-rw-r--r--drivers/ide/pci/cmd64x.c2
-rw-r--r--drivers/ide/pci/hpt34x.c2
-rw-r--r--drivers/ide/pci/hpt366.c8
-rw-r--r--drivers/ieee1394/amdtp.c1
-rw-r--r--drivers/ieee1394/csr1212.h1
-rw-r--r--drivers/ieee1394/dv1394.c1
-rw-r--r--drivers/ieee1394/eth1394.c14
-rw-r--r--drivers/ieee1394/eth1394.h6
-rw-r--r--drivers/ieee1394/hosts.c3
-rw-r--r--drivers/ieee1394/hosts.h8
-rw-r--r--drivers/ieee1394/ieee1394_core.c32
-rw-r--r--drivers/ieee1394/nodemgr.c23
-rw-r--r--drivers/ieee1394/ohci1394.c10
-rw-r--r--drivers/ieee1394/raw1394.c103
-rw-r--r--drivers/ieee1394/sbp2.c115
-rw-r--r--drivers/ieee1394/video1394.c3
-rw-r--r--drivers/infiniband/Kconfig25
-rw-r--r--drivers/infiniband/core/Makefile5
-rw-r--r--drivers/infiniband/core/cm.c5
-rw-r--r--drivers/infiniband/core/mad.c2
-rw-r--r--drivers/infiniband/core/mad_rmpp.c19
-rw-r--r--drivers/infiniband/core/sa_query.c36
-rw-r--r--drivers/infiniband/core/ucm.c287
-rw-r--r--drivers/infiniband/core/ucm.h11
-rw-r--r--drivers/infiniband/core/user_mad.c5
-rw-r--r--drivers/infiniband/core/uverbs.h27
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c275
-rw-r--r--drivers/infiniband/core/uverbs_main.c125
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c39
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c53
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c21
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c94
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c8
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c25
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c13
-rw-r--r--drivers/input/evdev.c4
-rw-r--r--drivers/input/input.c1
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c32
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c1
-rw-r--r--drivers/input/keyboard/Kconfig13
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/atkbd.c10
-rw-r--r--drivers/input/keyboard/spitzkbd.c478
-rw-r--r--drivers/input/keyboard/sunkbd.c2
-rw-r--r--drivers/input/misc/uinput.c4
-rw-r--r--drivers/input/mouse/Makefile2
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/input/mouse/logips2pp.c13
-rw-r--r--drivers/input/mouse/psmouse-base.c132
-rw-r--r--drivers/input/mouse/psmouse.h52
-rw-r--r--drivers/input/mouse/trackpoint.c304
-rw-r--r--drivers/input/mouse/trackpoint.h147
-rw-r--r--drivers/input/serio/i8042-io.h6
-rw-r--r--drivers/input/serio/i8042-ip22io.h2
-rw-r--r--drivers/input/serio/i8042-jazzio.h2
-rw-r--r--drivers/input/serio/i8042-sparcio.h12
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h72
-rw-r--r--drivers/input/serio/i8042.c199
-rw-r--r--drivers/input/touchscreen/Kconfig6
-rw-r--r--drivers/input/touchscreen/corgi_ts.c70
-rw-r--r--drivers/isdn/divert/divert_procfs.c6
-rw-r--r--drivers/isdn/hardware/eicon/diva_didd.c6
-rw-r--r--drivers/isdn/hardware/eicon/divasproc.c2
-rw-r--r--drivers/isdn/hisax/hfc_pci.c1
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c2
-rw-r--r--drivers/isdn/hisax/st5481.h4
-rw-r--r--drivers/isdn/hisax/st5481_b.c20
-rw-r--r--drivers/isdn/hisax/st5481_d.c26
-rw-r--r--drivers/isdn/hisax/st5481_init.c4
-rw-r--r--drivers/isdn/hisax/st5481_usb.c68
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c2
-rw-r--r--drivers/isdn/i4l/isdn_bsdcomp.c14
-rw-r--r--drivers/isdn/i4l/isdn_common.c3
-rw-r--r--drivers/isdn/sc/init.c4
-rw-r--r--drivers/macintosh/smu.c1032
-rw-r--r--drivers/macintosh/therm_adt746x.c2
-rw-r--r--drivers/macintosh/therm_pm72.c2
-rw-r--r--drivers/macintosh/therm_windtunnel.c2
-rw-r--r--drivers/md/bitmap.c185
-rw-r--r--drivers/md/dm-crypt.c4
-rw-r--r--drivers/md/dm-exception-store.c9
-rw-r--r--drivers/md/dm-io.c2
-rw-r--r--drivers/md/dm-ioctl.c9
-rw-r--r--drivers/md/dm-mpath.c16
-rw-r--r--drivers/md/dm-raid1.c14
-rw-r--r--drivers/md/linear.c100
-rw-r--r--drivers/md/md.c239
-rw-r--r--drivers/md/multipath.c7
-rw-r--r--drivers/md/raid0.c5
-rw-r--r--drivers/md/raid1.c238
-rw-r--r--drivers/md/raid10.c50
-rw-r--r--drivers/md/raid5.c138
-rw-r--r--drivers/md/raid6.h4
-rw-r--r--drivers/md/raid6algos.c1
-rw-r--r--drivers/md/raid6altivec.uc18
-rw-r--r--drivers/md/raid6main.c138
-rw-r--r--drivers/md/raid6test/Makefile27
-rw-r--r--drivers/media/Makefile5
-rw-r--r--drivers/media/common/ir-common.c68
-rw-r--r--drivers/media/common/saa7146_core.c6
-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/tda10021.c4
-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/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-aztech.c2
-rw-r--r--drivers/media/radio/radio-cadet.c4
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c2
-rw-r--r--drivers/media/radio/radio-terratec.c2
-rw-r--r--drivers/media/radio/radio-typhoon.c2
-rw-r--r--drivers/media/radio/radio-zoltrix.c2
-rw-r--r--drivers/media/video/Kconfig16
-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.c81
-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.h3
-rw-r--r--drivers/media/video/cpia.c2
-rw-r--r--drivers/media/video/cpia_usb.c30
-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.c52
-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/stradis.c32
-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.c9
-rw-r--r--drivers/media/video/vpx3220.c32
-rw-r--r--drivers/media/video/zoran_driver.c2
-rw-r--r--drivers/media/video/zr36120.c6
-rw-r--r--drivers/message/fusion/Kconfig17
-rw-r--r--drivers/message/fusion/Makefile1
-rw-r--r--drivers/message/fusion/mptbase.c963
-rw-r--r--drivers/message/fusion/mptbase.h56
-rw-r--r--drivers/message/fusion/mptctl.c4
-rw-r--r--drivers/message/fusion/mptfc.c2
-rw-r--r--drivers/message/fusion/mptlan.c7
-rw-r--r--drivers/message/fusion/mptsas.c1239
-rw-r--r--drivers/message/fusion/mptscsih.c463
-rw-r--r--drivers/message/fusion/mptscsih.h7
-rw-r--r--drivers/message/fusion/mptspi.c2
-rw-r--r--drivers/message/i2o/config-osm.c5
-rw-r--r--drivers/mfd/Kconfig9
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/ucb1x00-assabet.c73
-rw-r--r--drivers/mfd/ucb1x00-core.c663
-rw-r--r--drivers/mfd/ucb1x00-ts.c399
-rw-r--r--drivers/mfd/ucb1x00.h254
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c23
-rw-r--r--drivers/mmc/mmc.c12
-rw-r--r--drivers/mmc/mmci.c3
-rw-r--r--drivers/mmc/pxamci.c4
-rw-r--r--drivers/mmc/wbsd.c460
-rw-r--r--drivers/mmc/wbsd.h23
-rw-r--r--drivers/mtd/devices/docecc.c8
-rw-r--r--drivers/mtd/devices/mtdram.c3
-rw-r--r--drivers/mtd/ftl.c11
-rw-r--r--drivers/mtd/maps/bast-flash.c1
-rw-r--r--drivers/mtd/maps/ixp2000.c1
-rw-r--r--drivers/mtd/maps/ixp4xx.c3
-rw-r--r--drivers/mtd/maps/omap_nor.c1
-rw-r--r--drivers/mtd/maps/sa1100-flash.c2
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c2
-rw-r--r--drivers/mtd/maps/uclinux.c13
-rw-r--r--drivers/mtd/nand/s3c2410.c1
-rw-r--r--drivers/mtd/nand/sharpsl.c10
-rw-r--r--drivers/net/8139cp.c51
-rw-r--r--drivers/net/8139too.c5
-rw-r--r--drivers/net/8390.c2
-rw-r--r--drivers/net/Kconfig56
-rw-r--r--drivers/net/Makefile5
-rw-r--r--drivers/net/arcnet/com90io.c4
-rw-r--r--drivers/net/arm/am79c961a.c23
-rw-r--r--drivers/net/atari_bionet.c2
-rw-r--r--drivers/net/atari_pamsnet.c2
-rw-r--r--drivers/net/au1000_eth.c13
-rw-r--r--drivers/net/b44.c136
-rw-r--r--drivers/net/b44.h2
-rw-r--r--drivers/net/bmac.c2
-rw-r--r--drivers/net/bnx2.c9
-rw-r--r--drivers/net/bnx2.h1
-rw-r--r--drivers/net/bonding/bond_main.c358
-rw-r--r--drivers/net/bonding/bonding.h4
-rw-r--r--drivers/net/bsd_comp.c28
-rw-r--r--drivers/net/cassini.c5237
-rw-r--r--drivers/net/cassini.h4425
-rw-r--r--drivers/net/cris/eth_v10.c6
-rw-r--r--drivers/net/cs89x0.c34
-rw-r--r--drivers/net/cs89x0.h2
-rw-r--r--drivers/net/declance.c37
-rw-r--r--drivers/net/e100.c232
-rw-r--r--drivers/net/e1000/e1000.h74
-rw-r--r--drivers/net/e1000/e1000_ethtool.c95
-rw-r--r--drivers/net/e1000/e1000_hw.c220
-rw-r--r--drivers/net/e1000/e1000_hw.h96
-rw-r--r--drivers/net/e1000/e1000_main.c1079
-rw-r--r--drivers/net/e1000/e1000_param.c10
-rw-r--r--drivers/net/epic100.c4
-rw-r--r--drivers/net/fec.c478
-rw-r--r--drivers/net/fec.h7
-rw-r--r--drivers/net/forcedeth.c310
-rw-r--r--drivers/net/gianfar.c412
-rw-r--r--drivers/net/gianfar.h30
-rw-r--r--drivers/net/gianfar_ethtool.c100
-rw-r--r--drivers/net/gianfar_mii.c219
-rw-r--r--drivers/net/gianfar_mii.h45
-rw-r--r--drivers/net/gianfar_phy.c661
-rw-r--r--drivers/net/gianfar_phy.h213
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/Kconfig1
-rw-r--r--drivers/net/hamradio/baycom_epp.c17
-rw-r--r--drivers/net/hamradio/bpqether.c11
-rw-r--r--drivers/net/hamradio/dmascc.c10
-rw-r--r--drivers/net/hamradio/hdlcdrv.c16
-rw-r--r--drivers/net/hamradio/mkiss.c184
-rw-r--r--drivers/net/hamradio/mkiss.h62
-rw-r--r--drivers/net/hamradio/scc.c2
-rw-r--r--drivers/net/hamradio/yam.c30
-rw-r--r--drivers/net/hp100.c48
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.c31
-rw-r--r--drivers/net/ibmveth.c6
-rw-r--r--drivers/net/irda/Kconfig10
-rw-r--r--drivers/net/irda/Makefile1
-rw-r--r--drivers/net/irda/irda-usb.c13
-rw-r--r--drivers/net/irda/pxaficp_ir.c871
-rw-r--r--drivers/net/irda/stir4200.c7
-rw-r--r--drivers/net/irda/vlsi_ir.c4
-rw-r--r--drivers/net/irda/vlsi_ir.h6
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c8
-rw-r--r--drivers/net/ixgb/ixgb_main.c5
-rw-r--r--drivers/net/lance.c4
-rw-r--r--drivers/net/lne390.c2
-rw-r--r--drivers/net/mii.c15
-rw-r--r--drivers/net/mipsnet.c371
-rw-r--r--drivers/net/mipsnet.h127
-rw-r--r--drivers/net/mv643xx_eth.c2
-rw-r--r--drivers/net/myri_sbus.c2
-rw-r--r--drivers/net/myri_sbus.h2
-rw-r--r--drivers/net/ne.c15
-rw-r--r--drivers/net/ne2k-pci.c2
-rw-r--r--drivers/net/ns83820.c5
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c2
-rw-r--r--drivers/net/pcnet32.c278
-rw-r--r--drivers/net/phy/Kconfig8
-rw-r--r--drivers/net/phy/phy.c8
-rw-r--r--drivers/net/phy/phy_device.c3
-rw-r--r--drivers/net/ppp_generic.c23
-rw-r--r--drivers/net/pppoe.c4
-rw-r--r--drivers/net/r8169.c9
-rw-r--r--drivers/net/rionet.c574
-rw-r--r--drivers/net/s2io-regs.h11
-rw-r--r--drivers/net/s2io.c800
-rw-r--r--drivers/net/s2io.h50
-rw-r--r--drivers/net/sb1250-mac.c1384
-rw-r--r--drivers/net/sgiseeq.c37
-rw-r--r--drivers/net/sk98lin/skge.c20
-rw-r--r--drivers/net/skge.c338
-rw-r--r--drivers/net/skge.h4
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/starfire.c46
-rw-r--r--drivers/net/sunbmac.c3
-rw-r--r--drivers/net/sunbmac.h2
-rw-r--r--drivers/net/sundance.c49
-rw-r--r--drivers/net/sungem.c36
-rw-r--r--drivers/net/sungem.h3
-rw-r--r--drivers/net/sunhme.c43
-rw-r--r--drivers/net/tg3.c225
-rw-r--r--drivers/net/tg3.h1
-rw-r--r--drivers/net/tokenring/ibmtr.c14
-rw-r--r--drivers/net/tokenring/olympic.c2
-rw-r--r--drivers/net/tokenring/tms380tr.c3
-rw-r--r--drivers/net/tulip/21142.c2
-rw-r--r--drivers/net/tulip/de2104x.c5
-rw-r--r--drivers/net/tulip/de4x5.c4
-rw-r--r--drivers/net/tulip/xircom_cb.c2
-rw-r--r--drivers/net/typhoon.c7
-rw-r--r--drivers/net/via-rhine.c38
-rw-r--r--drivers/net/wan/cosa.c6
-rw-r--r--drivers/net/wan/cycx_drv.c7
-rw-r--r--drivers/net/wan/cycx_main.c2
-rw-r--r--drivers/net/wan/cycx_x25.c5
-rw-r--r--drivers/net/wan/dscc4.c23
-rw-r--r--drivers/net/wan/farsync.c27
-rw-r--r--drivers/net/wan/hdlc_cisco.c2
-rw-r--r--drivers/net/wan/hdlc_fr.c2
-rw-r--r--drivers/net/wan/lmc/lmc_debug.c10
-rw-r--r--drivers/net/wan/lmc/lmc_media.c8
-rw-r--r--drivers/net/wan/pc300.h16
-rw-r--r--drivers/net/wan/pc300_drv.c87
-rw-r--r--drivers/net/wan/pc300_tty.c18
-rw-r--r--drivers/net/wan/sdla.c20
-rw-r--r--drivers/net/wan/sdla_fr.c4
-rw-r--r--drivers/net/wan/sdla_x25.c8
-rw-r--r--drivers/net/wan/sdladrv.c16
-rw-r--r--drivers/net/wan/sdlamain.c23
-rw-r--r--drivers/net/wan/syncppp.c12
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/airo.c42
-rw-r--r--drivers/net/wireless/airport.c19
-rw-r--r--drivers/net/wireless/atmel.c24
-rw-r--r--drivers/net/wireless/hermes.c11
-rw-r--r--drivers/net/wireless/hermes.h111
-rw-r--r--drivers/net/wireless/hostap/hostap.c6
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c43
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c28
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c80
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h6
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c50
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c22
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c23
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c21
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c11
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h2
-rw-r--r--drivers/net/wireless/ipw2100.c24
-rw-r--r--drivers/net/wireless/ipw2100.h2
-rw-r--r--drivers/net/wireless/ipw2200.c27
-rw-r--r--drivers/net/wireless/ipw2200.h4
-rw-r--r--drivers/net/wireless/netwave_cs.c185
-rw-r--r--drivers/net/wireless/orinoco.c246
-rw-r--r--drivers/net/wireless/orinoco.h16
-rw-r--r--drivers/net/wireless/orinoco_cs.c111
-rw-r--r--drivers/net/wireless/orinoco_nortel.c20
-rw-r--r--drivers/net/wireless/orinoco_pci.c18
-rw-r--r--drivers/net/wireless/orinoco_plx.c18
-rw-r--r--drivers/net/wireless/orinoco_tmd.c18
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c10
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c10
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h2
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c5
-rw-r--r--drivers/net/wireless/ray_cs.c46
-rw-r--r--drivers/net/wireless/spectrum_cs.c79
-rw-r--r--drivers/net/wireless/strip.c4
-rw-r--r--drivers/net/wireless/wavelan.c8
-rw-r--r--drivers/net/wireless/wavelan.p.h4
-rw-r--r--drivers/net/wireless/wavelan_cs.c8
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h4
-rw-r--r--drivers/net/wireless/wl3501.h2
-rw-r--r--drivers/parisc/ccio-dma.c2
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parisc/lasi.c1
-rw-r--r--drivers/parisc/led.c5
-rw-r--r--drivers/parisc/sba_iommu.c2
-rw-r--r--drivers/parport/ieee1284.c7
-rw-r--r--drivers/parport/ieee1284_ops.c10
-rw-r--r--drivers/parport/parport_pc.c5
-rw-r--r--drivers/pci/.gitignore4
-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.c55
-rw-r--r--drivers/pci/hotplug/Kconfig4
-rw-r--r--drivers/pci/hotplug/Makefile7
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c2
-rw-r--r--drivers/pci/hotplug/pciehp.h2
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c4
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c8
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c299
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c4
-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/hotplug/shpchp_ctrl.c3
-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-sysfs.c12
-rw-r--r--drivers/pci/pci.c114
-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.c82
-rw-r--r--drivers/pci/proc.c12
-rw-r--r--drivers/pci/quirks.c118
-rw-r--r--drivers/pci/setup-bus.c6
-rw-r--r--drivers/pci/setup-res.c7
-rw-r--r--drivers/pcmcia/Kconfig9
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/cardbus.c5
-rw-r--r--drivers/pcmcia/cs.c12
-rw-r--r--drivers/pcmcia/cs_internal.h4
-rw-r--r--drivers/pcmcia/ds.c34
-rw-r--r--drivers/pcmcia/omap_cf.c372
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c12
-rw-r--r--drivers/pcmcia/pcmcia_resource.c11
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c10
-rw-r--r--drivers/pcmcia/sa1111_generic.c2
-rw-r--r--drivers/pcmcia/soc_common.c14
-rw-r--r--drivers/pcmcia/ti113x.h118
-rw-r--r--drivers/pcmcia/yenta_socket.c122
-rw-r--r--drivers/pnp/Kconfig2
-rw-r--r--drivers/pnp/pnpacpi/Kconfig2
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c75
-rw-r--r--drivers/s390/cio/blacklist.c4
-rw-r--r--drivers/s390/cio/ccwgroup.c2
-rw-r--r--drivers/s390/cio/device.c2
-rw-r--r--drivers/s390/crypto/z90main.c3
-rw-r--r--drivers/s390/net/ctcmain.c41
-rw-r--r--drivers/s390/net/fsm.c2
-rw-r--r--drivers/s390/net/fsm.h2
-rw-r--r--drivers/s390/net/qeth.h51
-rw-r--r--drivers/s390/net/qeth_fs.h12
-rw-r--r--drivers/s390/net/qeth_main.c591
-rw-r--r--drivers/s390/net/qeth_mpc.c6
-rw-r--r--drivers/s390/net/qeth_mpc.h15
-rw-r--r--drivers/s390/net/qeth_sys.c41
-rw-r--r--drivers/s390/scsi/Makefile2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c186
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c10
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c995
-rw-r--r--drivers/s390/scsi/zfcp_def.h307
-rw-r--r--drivers/s390/scsi/zfcp_erp.c135
-rw-r--r--drivers/s390/scsi/zfcp_ext.h30
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c769
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h54
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c30
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c297
-rw-r--r--drivers/s390/scsi/zfcp_sysfs_adapter.c14
-rw-r--r--drivers/sbus/char/aurora.c3
-rw-r--r--drivers/sbus/char/bbc_envctrl.c3
-rw-r--r--drivers/sbus/char/bpp.c3
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/envctrl.c4
-rw-r--r--drivers/sbus/char/vfc_i2c.c3
-rw-r--r--drivers/scsi/3w-9xxx.c83
-rw-r--r--drivers/scsi/3w-9xxx.h17
-rw-r--r--drivers/scsi/53c7xx.c4
-rw-r--r--drivers/scsi/Kconfig34
-rw-r--r--drivers/scsi/Makefile4
-rw-r--r--drivers/scsi/NCR5380.c2
-rw-r--r--drivers/scsi/aacraid/aachba.c283
-rw-r--r--drivers/scsi/aacraid/aacraid.h19
-rw-r--r--drivers/scsi/aacraid/comminit.c17
-rw-r--r--drivers/scsi/aacraid/commsup.c581
-rw-r--r--drivers/scsi/aacraid/linit.c14
-rw-r--r--drivers/scsi/ahci.c57
-rw-r--r--drivers/scsi/aic7xxx/aic7770_osm.c3
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c8
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c3
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c17
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c11
-rw-r--r--drivers/scsi/ata_piix.c29
-rw-r--r--drivers/scsi/atp870u.c6
-rw-r--r--drivers/scsi/atp870u.h5
-rw-r--r--drivers/scsi/ch.c29
-rw-r--r--drivers/scsi/cpqfcTSinit.c3
-rw-r--r--drivers/scsi/eata.c2
-rw-r--r--drivers/scsi/fd_mcs.c2
-rw-r--r--drivers/scsi/hosts.c40
-rw-r--r--drivers/scsi/ibmmca.c3
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c10
-rw-r--r--drivers/scsi/libata-core.c988
-rw-r--r--drivers/scsi/libata-scsi.c730
-rw-r--r--drivers/scsi/libata.h19
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c22
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h17
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c2
-rw-r--r--drivers/scsi/megaraid.c70
-rw-r--r--drivers/scsi/megaraid/Kconfig.megaraid9
-rw-r--r--drivers/scsi/megaraid/Makefile1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c2806
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h1142
-rw-r--r--drivers/scsi/mesh.c29
-rw-r--r--drivers/scsi/osst.c19
-rw-r--r--drivers/scsi/pdc_adma.c739
-rw-r--r--drivers/scsi/pluto.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_rscn.c4
-rw-r--r--drivers/scsi/qlogicpti.c39
-rw-r--r--drivers/scsi/sata_mv.c1147
-rw-r--r--drivers/scsi/sata_nv.c22
-rw-r--r--drivers/scsi/sata_promise.c26
-rw-r--r--drivers/scsi/sata_qstor.c8
-rw-r--r--drivers/scsi/sata_sil.c6
-rw-r--r--drivers/scsi/sata_sil24.c875
-rw-r--r--drivers/scsi/sata_sis.c100
-rw-r--r--drivers/scsi/sata_svw.c4
-rw-r--r--drivers/scsi/sata_sx4.c29
-rw-r--r--drivers/scsi/sata_uli.c18
-rw-r--r--drivers/scsi/sata_via.c4
-rw-r--r--drivers/scsi/sata_vsc.c14
-rw-r--r--drivers/scsi/scsi.c13
-rw-r--r--drivers/scsi/scsi_devinfo.c2
-rw-r--r--drivers/scsi/scsi_error.c80
-rw-r--r--drivers/scsi/scsi_ioctl.c5
-rw-r--r--drivers/scsi/scsi_lib.c141
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/scsi_scan.c204
-rw-r--r--drivers/scsi/scsi_sysfs.c39
-rw-r--r--drivers/scsi/scsi_transport_fc.c13
-rw-r--r--drivers/scsi/scsi_transport_sas.c819
-rw-r--r--drivers/scsi/sd.c1
-rw-r--r--drivers/scsi/sg.c11
-rw-r--r--drivers/scsi/sr.c1
-rw-r--r--drivers/scsi/st.c7
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/serial/8250.c4
-rw-r--r--drivers/serial/8250_accent.c2
-rw-r--r--drivers/serial/8250_acpi.c20
-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/8250_pci.c26
-rw-r--r--drivers/serial/8250_pnp.c4
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/amba-pl010.c3
-rw-r--r--drivers/serial/amba-pl011.c3
-rw-r--r--drivers/serial/clps711x.c13
-rw-r--r--drivers/serial/imx.c50
-rw-r--r--drivers/serial/ioc4_serial.c12
-rw-r--r--drivers/serial/mcfserial.c13
-rw-r--r--drivers/serial/mpc52xx_uart.c2
-rw-r--r--drivers/serial/pxa.c27
-rw-r--r--drivers/serial/s3c2410.c24
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/serial_cs.c1
-rw-r--r--drivers/serial/serial_lh7a40x.c2
-rw-r--r--drivers/serial/serial_txx9.c118
-rw-r--r--drivers/serial/sh-sci.c2
-rw-r--r--drivers/serial/sunsab.c1
-rw-r--r--drivers/serial/sunsu.c4
-rw-r--r--drivers/serial/sunzilog.c5
-rw-r--r--drivers/tc/zs.c2
-rw-r--r--drivers/telephony/ixj.c116
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/class/Kconfig21
-rw-r--r--drivers/usb/class/audio.c12
-rw-r--r--drivers/usb/class/usblp.c9
-rw-r--r--drivers/usb/core/Makefile4
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/core/devio.c118
-rw-r--r--drivers/usb/core/hcd-pci.c37
-rw-r--r--drivers/usb/core/hcd.c5
-rw-r--r--drivers/usb/core/hcd.h16
-rw-r--r--drivers/usb/core/hub.c126
-rw-r--r--drivers/usb/core/hub.h7
-rw-r--r--drivers/usb/core/inode.c11
-rw-r--r--drivers/usb/core/message.c12
-rw-r--r--drivers/usb/core/urb.c30
-rw-r--r--drivers/usb/core/usb.c43
-rw-r--r--drivers/usb/core/usb.h8
-rw-r--r--drivers/usb/gadget/dummy_hcd.c8
-rw-r--r--drivers/usb/gadget/ether.c55
-rw-r--r--drivers/usb/gadget/file_storage.c33
-rw-r--r--drivers/usb/gadget/gadget_chips.h55
-rw-r--r--drivers/usb/gadget/goku_udc.c6
-rw-r--r--drivers/usb/gadget/inode.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c12
-rw-r--r--drivers/usb/gadget/net2280.c6
-rw-r--r--drivers/usb/gadget/omap_udc.c6
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c8
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h2
-rw-r--r--drivers/usb/gadget/serial.c67
-rw-r--r--drivers/usb/gadget/zero.c56
-rw-r--r--drivers/usb/host/ehci-hcd.c34
-rw-r--r--drivers/usb/host/ehci-hub.c27
-rw-r--r--drivers/usb/host/ehci-mem.c6
-rw-r--r--drivers/usb/host/ehci-q.c13
-rw-r--r--drivers/usb/host/ehci-sched.c18
-rw-r--r--drivers/usb/host/ehci.h3
-rw-r--r--drivers/usb/host/hc_crisv10.c4
-rw-r--r--drivers/usb/host/isp116x-hcd.c93
-rw-r--r--drivers/usb/host/ohci-dbg.c9
-rw-r--r--drivers/usb/host/ohci-hcd.c16
-rw-r--r--drivers/usb/host/ohci-hub.c22
-rw-r--r--drivers/usb/host/ohci-lh7a404.c2
-rw-r--r--drivers/usb/host/ohci-mem.c4
-rw-r--r--drivers/usb/host/ohci-omap.c1
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c24
-rw-r--r--drivers/usb/host/ohci-pxa27x.c48
-rw-r--r--drivers/usb/host/ohci-s3c2410.c5
-rw-r--r--drivers/usb/host/ohci.h1
-rw-r--r--drivers/usb/host/sl811-hcd.c18
-rw-r--r--drivers/usb/host/uhci-hcd.c62
-rw-r--r--drivers/usb/host/uhci-hcd.h11
-rw-r--r--drivers/usb/host/uhci-hub.c11
-rw-r--r--drivers/usb/host/uhci-q.c4
-rw-r--r--drivers/usb/input/Kconfig34
-rw-r--r--drivers/usb/input/Makefile2
-rw-r--r--drivers/usb/input/appletouch.c469
-rw-r--r--drivers/usb/input/hid-core.c84
-rw-r--r--drivers/usb/input/hid-debug.h34
-rw-r--r--drivers/usb/input/hid-input.c66
-rw-r--r--drivers/usb/input/hid.h9
-rw-r--r--drivers/usb/input/hiddev.c1
-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/media/stv680.c26
-rw-r--r--drivers/usb/media/vicam.c4
-rw-r--r--drivers/usb/misc/auerswald.c3
-rw-r--r--drivers/usb/misc/ldusb.c6
-rw-r--r--drivers/usb/misc/sisusbvga/Kconfig42
-rw-r--r--drivers/usb/misc/sisusbvga/Makefile4
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c467
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h73
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1658
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1047
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.h830
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_struct.h169
-rw-r--r--drivers/usb/misc/usbtest.c2
-rw-r--r--drivers/usb/misc/uss720.c393
-rw-r--r--drivers/usb/mon/Makefile2
-rw-r--r--drivers/usb/mon/mon_dma.c55
-rw-r--r--drivers/usb/mon/mon_text.c37
-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.c7
-rw-r--r--drivers/usb/net/net1080.c622
-rw-r--r--drivers/usb/net/pegasus.c30
-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.c3
-rw-r--r--drivers/usb/serial/airprime.c3
-rw-r--r--drivers/usb/serial/cp2101.c5
-rw-r--r--drivers/usb/serial/cypress_m8.c254
-rw-r--r--drivers/usb/serial/ftdi_sio.c66
-rw-r--r--drivers/usb/serial/ftdi_sio.h54
-rw-r--r--drivers/usb/serial/generic.c2
-rw-r--r--drivers/usb/serial/keyspan.c8
-rw-r--r--drivers/usb/serial/option.c214
-rw-r--r--drivers/usb/serial/pl2303.c10
-rw-r--r--drivers/usb/serial/pl2303.h4
-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.c28
-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.h54
-rw-r--r--drivers/usb/storage/usb.c90
-rw-r--r--drivers/usb/storage/usb.h1
-rw-r--r--drivers/video/Kconfig81
-rw-r--r--drivers/video/Makefile7
-rw-r--r--drivers/video/amba-clcd.c1
-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.c36
-rw-r--r--drivers/video/aty/radeon_pm.c14
-rw-r--r--drivers/video/aty/radeonfb.h2
-rw-r--r--drivers/video/aty/xlinit.c11
-rw-r--r--drivers/video/backlight/corgi_bl.c33
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/console/Makefile4
-rw-r--r--drivers/video/console/bitblit.c148
-rw-r--r--drivers/video/console/fbcon.c203
-rw-r--r--drivers/video/console/fbcon.h5
-rw-r--r--drivers/video/console/font_10x18.c4
-rw-r--r--drivers/video/console/font_6x11.c4
-rw-r--r--drivers/video/console/font_7x14.c4
-rw-r--r--drivers/video/console/font_8x16.c4
-rw-r--r--drivers/video/console/font_8x8.c4
-rw-r--r--drivers/video/console/font_acorn_8x8.c4
-rw-r--r--drivers/video/console/font_mini_4x6.c4
-rw-r--r--drivers/video/console/font_pearl_8x8.c4
-rw-r--r--drivers/video/console/font_sun12x22.c4
-rw-r--r--drivers/video/console/font_sun8x16.c4
-rw-r--r--drivers/video/console/fonts.c9
-rw-r--r--drivers/video/console/vgacon.c78
-rw-r--r--drivers/video/cyblafb.c1457
-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/fbsysfs.c8
-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.c223
-rw-r--r--drivers/video/i810/i810_main.h16
-rw-r--r--drivers/video/imxfb.c3
-rw-r--r--drivers/video/intelfb/intelfb.h1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c38
-rw-r--r--drivers/video/intelfb/intelfbhw.c4
-rw-r--r--drivers/video/logo/.gitignore7
-rw-r--r--drivers/video/matrox/matroxfb_base.c13
-rw-r--r--drivers/video/matrox/matroxfb_misc.c30
-rw-r--r--drivers/video/modedb.c62
-rw-r--r--drivers/video/nvidia/nv_i2c.c19
-rw-r--r--drivers/video/nvidia/nv_local.h4
-rw-r--r--drivers/video/nvidia/nv_of.c3
-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.c17
-rw-r--r--drivers/video/offb.c2
-rw-r--r--drivers/video/p9100.c4
-rw-r--r--drivers/video/pm3fb.c3
-rw-r--r--drivers/video/pxafb.c140
-rw-r--r--drivers/video/pxafb.h11
-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/sa1100fb.c2
-rw-r--r--drivers/video/savage/savagefb-i2c.c19
-rw-r--r--drivers/video/savage/savagefb.h11
-rw-r--r--drivers/video/savage/savagefb_driver.c147
-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/video/vgastate.c15
-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.c301
-rw-r--r--drivers/w1/w1.h22
-rw-r--r--drivers/w1/w1_ds2433.c331
-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.c708
-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.c255
-rw-r--r--fs/9p/fid.h60
-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.c458
-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.c223
-rw-r--r--fs/9p/vfs_file.c321
-rw-r--r--fs/9p/vfs_inode.c1365
-rw-r--r--fs/9p/vfs_super.c265
-rw-r--r--fs/Kconfig27
-rw-r--r--fs/Makefile2
-rw-r--r--fs/affs/inode.c1
-rw-r--r--fs/afs/file.c4
-rw-r--r--fs/aio.c117
-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.c23
-rw-r--r--fs/bfs/file.c23
-rw-r--r--fs/bfs/inode.c146
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/bio.c16
-rw-r--r--fs/buffer.c7
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/connect.c8
-rw-r--r--fs/compat.c10
-rw-r--r--fs/compat_ioctl.c7
-rw-r--r--fs/cramfs/uncompress.c1
-rw-r--r--fs/dcache.c21
-rw-r--r--fs/dquot.c2
-rw-r--r--fs/eventpoll.c48
-rw-r--r--fs/exec.c30
-rw-r--r--fs/ext2/ialloc.c22
-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/balloc.c6
-rw-r--r--fs/ext3/ialloc.c26
-rw-r--r--fs/ext3/inode.c4
-rw-r--r--fs/ext3/resize.c6
-rw-r--r--fs/ext3/super.c11
-rw-r--r--fs/ext3/xattr.h11
-rw-r--r--fs/ext3/xattr_security.c22
-rw-r--r--fs/fat/file.c37
-rw-r--r--fs/fat/inode.c28
-rw-r--r--fs/fcntl.c60
-rw-r--r--fs/file.c383
-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.c988
-rw-r--r--fs/fuse/file.c559
-rw-r--r--fs/fuse/fuse_i.h451
-rw-r--r--fs/fuse/inode.c591
-rw-r--r--fs/hfs/inode.c2
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hfsplus/super.c1
-rw-r--r--fs/hostfs/hostfs_kern.c8
-rw-r--r--fs/hpfs/inode.c1
-rw-r--r--fs/inode.c14
-rw-r--r--fs/inotify.c1
-rw-r--r--fs/jbd/journal.c2
-rw-r--r--fs/jbd/transaction.c5
-rw-r--r--fs/jffs/inode-v23.c1
-rw-r--r--fs/jffs/intrep.c22
-rw-r--r--fs/jfs/acl.c24
-rw-r--r--fs/jfs/inode.c25
-rw-r--r--fs/jfs/jfs_acl.h12
-rw-r--r--fs/jfs/jfs_dmap.c2
-rw-r--r--fs/jfs/jfs_metapage.c4
-rw-r--r--fs/jfs/jfs_txnmgr.c15
-rw-r--r--fs/jfs/jfs_txnmgr.h1
-rw-r--r--fs/jfs/jfs_xattr.h14
-rw-r--r--fs/jfs/namei.c85
-rw-r--r--fs/jfs/xattr.c94
-rw-r--r--fs/lockd/clntproc.c3
-rw-r--r--fs/lockd/host.c4
-rw-r--r--fs/locks.c59
-rw-r--r--fs/mbcache.c6
-rw-r--r--fs/minix/inode.c1
-rw-r--r--fs/mpage.c2
-rw-r--r--fs/namei.c129
-rw-r--r--fs/namespace.c4
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/nfs/delegation.c6
-rw-r--r--fs/nfs/delegation.h16
-rw-r--r--fs/nfs/dir.c67
-rw-r--r--fs/nfs/file.c34
-rw-r--r--fs/nfs/inode.c211
-rw-r--r--fs/nfs/nfs2xdr.c1
-rw-r--r--fs/nfs/nfs3proc.c95
-rw-r--r--fs/nfs/nfs3xdr.c1
-rw-r--r--fs/nfs/nfs4_fs.h53
-rw-r--r--fs/nfs/nfs4proc.c747
-rw-r--r--fs/nfs/nfs4state.c181
-rw-r--r--fs/nfs/nfs4xdr.c305
-rw-r--r--fs/nfs/proc.c44
-rw-r--r--fs/nfs/read.c6
-rw-r--r--fs/nfs/write.c2
-rw-r--r--fs/nfs_common/nfsacl.c70
-rw-r--r--fs/nfsd/nfs4proc.c24
-rw-r--r--fs/nfsd/nfs4state.c90
-rw-r--r--fs/ntfs/ChangeLog84
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/aops.c394
-rw-r--r--fs/ntfs/attrib.c125
-rw-r--r--fs/ntfs/attrib.h2
-rw-r--r--fs/ntfs/bitmap.c5
-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.c228
-rw-r--r--fs/ntfs/layout.h8
-rw-r--r--fs/ntfs/lcnalloc.c48
-rw-r--r--fs/ntfs/lcnalloc.h28
-rw-r--r--fs/ntfs/logfile.c279
-rw-r--r--fs/ntfs/logfile.h10
-rw-r--r--fs/ntfs/malloc.h50
-rw-r--r--fs/ntfs/mft.c7
-rw-r--r--fs/ntfs/runlist.c543
-rw-r--r--fs/ntfs/runlist.h3
-rw-r--r--fs/ntfs/super.c30
-rw-r--r--fs/ntfs/unistr.c5
-rw-r--r--fs/open.c196
-rw-r--r--fs/partitions/check.c2
-rw-r--r--fs/pipe.c6
-rw-r--r--fs/posix_acl.c6
-rw-r--r--fs/proc/array.c8
-rw-r--r--fs/proc/base.c131
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/nommu.c1
-rw-r--r--fs/qnx4/inode.c1
-rw-r--r--fs/read_write.c3
-rw-r--r--fs/reiserfs/file.c11
-rw-r--r--fs/reiserfs/fix_node.c2
-rw-r--r--fs/reiserfs/inode.c20
-rw-r--r--fs/reiserfs/journal.c3
-rw-r--r--fs/reiserfs/super.c3
-rw-r--r--fs/reiserfs/xattr.c2
-rw-r--r--fs/relayfs/buffers.c2
-rw-r--r--fs/select.c23
-rw-r--r--fs/smbfs/inode.c1
-rw-r--r--fs/smbfs/proc.c3
-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/Kconfig45
-rw-r--r--fs/xfs/Makefile-linux-2.615
-rw-r--r--fs/xfs/linux-2.6/kmem.c12
-rw-r--r--fs/xfs/linux-2.6/kmem.h11
-rw-r--r--fs/xfs/linux-2.6/time.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c12
-rw-r--r--fs/xfs/quota/Makefile-linux-2.68
-rw-r--r--fs/xfs/support/ktrace.c2
-rw-r--r--fs/xfs/xfs_arch.h22
-rw-r--r--fs/xfs/xfs_bmap_btree.c8
-rw-r--r--fs/xfs/xfs_bmap_btree.h12
-rw-r--r--fs/xfs/xfs_dir_leaf.h6
-rw-r--r--fs/xfs/xfs_inode_item.c4
-rw-r--r--fs/xfs/xfs_log_priv.h10
-rw-r--r--include/acpi/acconfig.h29
-rw-r--r--include/acpi/acdebug.h259
-rw-r--r--include/acpi/acdisasm.h322
-rw-r--r--include/acpi/acdispat.h405
-rw-r--r--include/acpi/acevents.h241
-rw-r--r--include/acpi/acexcep.h34
-rw-r--r--include/acpi/acglobal.h271
-rw-r--r--include/acpi/achware.h107
-rw-r--r--include/acpi/acinterp.h626
-rw-r--r--include/acpi/aclocal.h722
-rw-r--r--include/acpi/acmacros.h145
-rw-r--r--include/acpi/acnames.h13
-rw-r--r--include/acpi/acnamesp.h357
-rw-r--r--include/acpi/acobject.h390
-rw-r--r--include/acpi/acopcode.h6
-rw-r--r--include/acpi/acoutput.h10
-rw-r--r--include/acpi/acparser.h255
-rw-r--r--include/acpi/acpi.h35
-rw-r--r--include/acpi/acpi_bus.h334
-rw-r--r--include/acpi/acpi_drivers.h40
-rw-r--r--include/acpi/acpiosxf.h264
-rw-r--r--include/acpi/acpixf.h408
-rw-r--r--include/acpi/acresrc.h309
-rw-r--r--include/acpi/acstruct.h221
-rw-r--r--include/acpi/actables.h121
-rw-r--r--include/acpi/actbl.h282
-rw-r--r--include/acpi/actbl1.h141
-rw-r--r--include/acpi/actbl2.h260
-rw-r--r--include/acpi/actbl71.h148
-rw-r--r--include/acpi/actypes.h807
-rw-r--r--include/acpi/acutils.h718
-rw-r--r--include/acpi/amlcode.h172
-rw-r--r--include/acpi/amlresrc.h380
-rw-r--r--include/acpi/container.h3
-rw-r--r--include/acpi/pdc_intel.h4
-rw-r--r--include/acpi/platform/acenv.h70
-rw-r--r--include/acpi/platform/acgcc.h10
-rw-r--r--include/acpi/platform/aclinux.h15
-rw-r--r--include/acpi/processor.h238
-rw-r--r--include/asm-alpha/atomic.h14
-rw-r--r--include/asm-alpha/barrier.h34
-rw-r--r--include/asm-alpha/compiler.h5
-rw-r--r--include/asm-alpha/dma-mapping.h2
-rw-r--r--include/asm-alpha/futex.h2
-rw-r--r--include/asm-alpha/pci.h13
-rw-r--r--include/asm-alpha/pgtable.h7
-rw-r--r--include/asm-alpha/spinlock.h96
-rw-r--r--include/asm-alpha/spinlock_types.h20
-rw-r--r--include/asm-alpha/system.h31
-rw-r--r--include/asm-arm/arch-aaec2000/aaec2000.h56
-rw-r--r--include/asm-arm/arch-aaec2000/aaed2000.h40
-rw-r--r--include/asm-arm/arch-aaec2000/hardware.h3
-rw-r--r--include/asm-arm/arch-aaec2000/io.h2
-rw-r--r--include/asm-arm/arch-aaec2000/memory.h4
-rw-r--r--include/asm-arm/arch-cl7500/io.h2
-rw-r--r--include/asm-arm/arch-clps711x/hardware.h117
-rw-r--r--include/asm-arm/arch-clps711x/io.h2
-rw-r--r--include/asm-arm/arch-clps711x/mp1000-seprom.h77
-rw-r--r--include/asm-arm/arch-ebsa285/io.h2
-rw-r--r--include/asm-arm/arch-epxa10db/io.h2
-rw-r--r--include/asm-arm/arch-h720x/io.h2
-rw-r--r--include/asm-arm/arch-h720x/system.h8
-rw-r--r--include/asm-arm/arch-imx/imx-regs.h48
-rw-r--r--include/asm-arm/arch-imx/io.h2
-rw-r--r--include/asm-arm/arch-integrator/hardware.h9
-rw-r--r--include/asm-arm/arch-integrator/io.h8
-rw-r--r--include/asm-arm/arch-iop3xx/io.h2
-rw-r--r--include/asm-arm/arch-iop3xx/memory.h2
-rw-r--r--include/asm-arm/arch-ixp2000/io.h2
-rw-r--r--include/asm-arm/arch-ixp2000/ixp2000-regs.h45
-rw-r--r--include/asm-arm/arch-ixp2000/platform.h16
-rw-r--r--include/asm-arm/arch-ixp4xx/entry-macro.S9
-rw-r--r--include/asm-arm/arch-ixp4xx/hardware.h2
-rw-r--r--include/asm-arm/arch-ixp4xx/platform.h2
-rw-r--r--include/asm-arm/arch-l7200/io.h2
-rw-r--r--include/asm-arm/arch-lh7a40x/io.h2
-rw-r--r--include/asm-arm/arch-lh7a40x/memory.h4
-rw-r--r--include/asm-arm/arch-omap/io.h2
-rw-r--r--include/asm-arm/arch-omap/memory.h1
-rw-r--r--include/asm-arm/arch-pxa/akita.h30
-rw-r--r--include/asm-arm/arch-pxa/corgi.h12
-rw-r--r--include/asm-arm/arch-pxa/hardware.h16
-rw-r--r--include/asm-arm/arch-pxa/i2c.h70
-rw-r--r--include/asm-arm/arch-pxa/io.h2
-rw-r--r--include/asm-arm/arch-pxa/irda.h17
-rw-r--r--include/asm-arm/arch-pxa/memory.h4
-rw-r--r--include/asm-arm/arch-pxa/mmc.h1
-rw-r--r--include/asm-arm/arch-pxa/poodle.h25
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h51
-rw-r--r--include/asm-arm/arch-pxa/pxafb.h2
-rw-r--r--include/asm-arm/arch-pxa/sharpsl.h32
-rw-r--r--include/asm-arm/arch-pxa/spitz.h158
-rw-r--r--include/asm-arm/arch-pxa/uncompress.h1
-rw-r--r--include/asm-arm/arch-rpc/hardware.h4
-rw-r--r--include/asm-arm/arch-rpc/io.h2
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-map.h10
-rw-r--r--include/asm-arm/arch-s3c2410/fb.h70
-rw-r--r--include/asm-arm/arch-s3c2410/hardware.h7
-rw-r--r--include/asm-arm/arch-s3c2410/io.h60
-rw-r--r--include/asm-arm/arch-s3c2410/regs-clock.h21
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpio.h6
-rw-r--r--include/asm-arm/arch-s3c2410/regs-lcd.h17
-rw-r--r--include/asm-arm/arch-sa1100/hardware.h25
-rw-r--r--include/asm-arm/arch-sa1100/io.h8
-rw-r--r--include/asm-arm/arch-sa1100/memory.h4
-rw-r--r--include/asm-arm/arch-sa1100/system.h1
-rw-r--r--include/asm-arm/arch-shark/io.h2
-rw-r--r--include/asm-arm/arch-versatile/io.h6
-rw-r--r--include/asm-arm/bitops.h1
-rw-r--r--include/asm-arm/cacheflush.h7
-rw-r--r--include/asm-arm/dma-mapping.h4
-rw-r--r--include/asm-arm/elf.h2
-rw-r--r--include/asm-arm/futex.h2
-rw-r--r--include/asm-arm/hardware/arm_twd.h16
-rw-r--r--include/asm-arm/hardware/scoop.h2
-rw-r--r--include/asm-arm/io.h7
-rw-r--r--include/asm-arm/locks.h4
-rw-r--r--include/asm-arm/mach/arch.h8
-rw-r--r--include/asm-arm/mach/map.h5
-rw-r--r--include/asm-arm/memory.h15
-rw-r--r--include/asm-arm/pci.h13
-rw-r--r--include/asm-arm/pgtable.h5
-rw-r--r--include/asm-arm/setup.h4
-rw-r--r--include/asm-arm/signal.h1
-rw-r--r--include/asm-arm/spinlock.h50
-rw-r--r--include/asm-arm/spinlock_types.h20
-rw-r--r--include/asm-arm/unistd.h3
-rw-r--r--include/asm-arm26/futex.h2
-rw-r--r--include/asm-arm26/hardirq.h2
-rw-r--r--include/asm-arm26/pgtable.h5
-rw-r--r--include/asm-cris/dma-mapping.h4
-rw-r--r--include/asm-cris/futex.h2
-rw-r--r--include/asm-frv/dma-mapping.h2
-rw-r--r--include/asm-frv/futex.h2
-rw-r--r--include/asm-frv/pci.h2
-rw-r--r--include/asm-frv/pgtable.h3
-rw-r--r--include/asm-generic/dma-mapping-broken.h2
-rw-r--r--include/asm-generic/dma-mapping.h4
-rw-r--r--include/asm-generic/pci.h13
-rw-r--r--include/asm-generic/pgtable.h13
-rw-r--r--include/asm-generic/tlb.h6
-rw-r--r--include/asm-generic/vmlinux.lds.h38
-rw-r--r--include/asm-h8300/futex.h2
-rw-r--r--include/asm-h8300/pgtable.h2
-rw-r--r--include/asm-i386/acpi.h20
-rw-r--r--include/asm-i386/apic.h2
-rw-r--r--include/asm-i386/div64.h2
-rw-r--r--include/asm-i386/dma-mapping.h2
-rw-r--r--include/asm-i386/fixmap.h2
-rw-r--r--include/asm-i386/futex.h2
-rw-r--r--include/asm-i386/hw_irq.h2
-rw-r--r--include/asm-i386/io_apic.h4
-rw-r--r--include/asm-i386/mach-default/mach_reboot.h10
-rw-r--r--include/asm-i386/mmzone.h2
-rw-r--r--include/asm-i386/mpspec.h4
-rw-r--r--include/asm-i386/numa.h3
-rw-r--r--include/asm-i386/pgtable.h3
-rw-r--r--include/asm-i386/processor.h4
-rw-r--r--include/asm-i386/spinlock.h200
-rw-r--r--include/asm-i386/spinlock_types.h20
-rw-r--r--include/asm-i386/thread_info.h2
-rw-r--r--include/asm-i386/topology.h2
-rw-r--r--include/asm-i386/unistd.h12
-rw-r--r--include/asm-ia64/acpi-ext.h1
-rw-r--r--include/asm-ia64/futex.h2
-rw-r--r--include/asm-ia64/iosapic.h4
-rw-r--r--include/asm-ia64/irq.h4
-rw-r--r--include/asm-ia64/machvec.h2
-rw-r--r--include/asm-ia64/mca.h107
-rw-r--r--include/asm-ia64/mca_asm.h125
-rw-r--r--include/asm-ia64/pci.h13
-rw-r--r--include/asm-ia64/pgtable.h4
-rw-r--r--include/asm-ia64/ptrace.h6
-rw-r--r--include/asm-ia64/sn/sn_feature_sets.h57
-rw-r--r--include/asm-ia64/sn/sn_sal.h36
-rw-r--r--include/asm-ia64/spinlock.h69
-rw-r--r--include/asm-ia64/spinlock_types.h21
-rw-r--r--include/asm-ia64/system.h1
-rw-r--r--include/asm-ia64/thread_info.h11
-rw-r--r--include/asm-ia64/uaccess.h12
-rw-r--r--include/asm-ia64/unwind.h7
-rw-r--r--include/asm-m32r/dma-mapping.h2
-rw-r--r--include/asm-m32r/futex.h2
-rw-r--r--include/asm-m32r/io.h2
-rw-r--r--include/asm-m32r/pgtable.h3
-rw-r--r--include/asm-m32r/spinlock.h127
-rw-r--r--include/asm-m32r/spinlock_types.h23
-rw-r--r--include/asm-m32r/uaccess.h10
-rw-r--r--include/asm-m68k/futex.h2
-rw-r--r--include/asm-m68k/pgtable.h3
-rw-r--r--include/asm-m68knommu/bitops.h2
-rw-r--r--include/asm-m68knommu/cacheflush.h29
-rw-r--r--include/asm-m68knommu/checksum.h7
-rw-r--r--include/asm-m68knommu/coldfire.h6
-rw-r--r--include/asm-m68knommu/futex.h2
-rw-r--r--include/asm-m68knommu/m523xsim.h46
-rw-r--r--include/asm-m68knommu/m527xsim.h21
-rw-r--r--include/asm-m68knommu/m528xsim.h112
-rw-r--r--include/asm-m68knommu/mcfcache.h25
-rw-r--r--include/asm-m68knommu/mcfdma.h2
-rw-r--r--include/asm-m68knommu/mcfsim.h6
-rw-r--r--include/asm-m68knommu/mcfuart.h2
-rw-r--r--include/asm-m68knommu/pgtable.h2
-rw-r--r--include/asm-m68knommu/scatterlist.h6
-rw-r--r--include/asm-m68knommu/system.h54
-rw-r--r--include/asm-mips/asmmacro-32.h2
-rw-r--r--include/asm-mips/asmmacro-64.h2
-rw-r--r--include/asm-mips/dma-mapping.h4
-rw-r--r--include/asm-mips/irq.h3
-rw-r--r--include/asm-mips/pgtable.h14
-rw-r--r--include/asm-mips/sgi/hpc3.h40
-rw-r--r--include/asm-mips/sim.h2
-rw-r--r--include/asm-mips/spinlock.h75
-rw-r--r--include/asm-mips/spinlock_types.h20
-rw-r--r--include/asm-mips/stackframe.h2
-rw-r--r--include/asm-mips/vr41xx/tb0287.h43
-rw-r--r--include/asm-parisc/assembly.h2
-rw-r--r--include/asm-parisc/atomic.h12
-rw-r--r--include/asm-parisc/bitops.h2
-rw-r--r--include/asm-parisc/cacheflush.h1
-rw-r--r--include/asm-parisc/dma-mapping.h8
-rw-r--r--include/asm-parisc/futex.h2
-rw-r--r--include/asm-parisc/pci.h13
-rw-r--r--include/asm-parisc/pgtable.h3
-rw-r--r--include/asm-parisc/processor.h1
-rw-r--r--include/asm-parisc/spinlock.h163
-rw-r--r--include/asm-parisc/spinlock_types.h21
-rw-r--r--include/asm-parisc/system.h24
-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.h14
-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.h49
-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/cputable.h1
-rw-r--r--include/asm-ppc/dma-mapping.h4
-rw-r--r--include/asm-ppc/futex.h2
-rw-r--r--include/asm-ppc/io.h20
-rw-r--r--include/asm-ppc/irq.h14
-rw-r--r--include/asm-ppc/macio.h1
-rw-r--r--include/asm-ppc/mpc8xx.h16
-rw-r--r--include/asm-ppc/mv64x60.h12
-rw-r--r--include/asm-ppc/of_device.h5
-rw-r--r--include/asm-ppc/pci.h13
-rw-r--r--include/asm-ppc/pgtable.h11
-rw-r--r--include/asm-ppc/ppc_sys.h2
-rw-r--r--include/asm-ppc/ptrace.h7
-rw-r--r--include/asm-ppc/reg.h6
-rw-r--r--include/asm-ppc/segment.h1
-rw-r--r--include/asm-ppc/setup.h14
-rw-r--r--include/asm-ppc/smp.h6
-rw-r--r--include/asm-ppc/spinlock.h91
-rw-r--r--include/asm-ppc/spinlock_types.h20
-rw-r--r--include/asm-ppc/system.h1
-rw-r--r--include/asm-ppc/timex.h40
-rw-r--r--include/asm-ppc/tlbflush.h2
-rw-r--r--include/asm-ppc/topology.h6
-rw-r--r--include/asm-ppc64/dma-mapping.h4
-rw-r--r--include/asm-ppc64/eeh.h39
-rw-r--r--include/asm-ppc64/hvcall.h6
-rw-r--r--include/asm-ppc64/io.h42
-rw-r--r--include/asm-ppc64/iommu.h2
-rw-r--r--include/asm-ppc64/machdep.h5
-rw-r--r--include/asm-ppc64/msgbuf.h27
-rw-r--r--include/asm-ppc64/param.h31
-rw-r--r--include/asm-ppc64/pci-bridge.h50
-rw-r--r--include/asm-ppc64/pci.h13
-rw-r--r--include/asm-ppc64/plpar_wrappers.h9
-rw-r--r--include/asm-ppc64/processor.h1
-rw-r--r--include/asm-ppc64/prom.h19
-rw-r--r--include/asm-ppc64/ptrace-common.h92
-rw-r--r--include/asm-ppc64/ptrace.h128
-rw-r--r--include/asm-ppc64/segment.h6
-rw-r--r--include/asm-ppc64/setup.h6
-rw-r--r--include/asm-ppc64/smu.h365
-rw-r--r--include/asm-ppc64/spinlock.h191
-rw-r--r--include/asm-ppc64/spinlock_types.h20
-rw-r--r--include/asm-ppc64/system.h3
-rw-r--r--include/asm-ppc64/timex.h26
-rw-r--r--include/asm-ppc64/tlbflush.h1
-rw-r--r--include/asm-ppc64/uaccess.h6
-rw-r--r--include/asm-ppc64/user.h58
-rw-r--r--include/asm-s390/futex.h2
-rw-r--r--include/asm-s390/sigcontext.h2
-rw-r--r--include/asm-s390/signal.h2
-rw-r--r--include/asm-s390/spinlock.h63
-rw-r--r--include/asm-s390/spinlock_types.h21
-rw-r--r--include/asm-sh/dma-mapping.h4
-rw-r--r--include/asm-sh/futex.h2
-rw-r--r--include/asm-sh/irq.h4
-rw-r--r--include/asm-sh/machvec.h2
-rw-r--r--include/asm-sh/pgtable.h3
-rw-r--r--include/asm-sh/spinlock.h61
-rw-r--r--include/asm-sh/spinlock_types.h22
-rw-r--r--include/asm-sh64/dma-mapping.h2
-rw-r--r--include/asm-sh64/futex.h2
-rw-r--r--include/asm-sh64/pgtable.h3
-rw-r--r--include/asm-sparc/btfixup.h24
-rw-r--r--include/asm-sparc/cache.h18
-rw-r--r--include/asm-sparc/cypress.h8
-rw-r--r--include/asm-sparc/delay.h2
-rw-r--r--include/asm-sparc/dma-mapping.h2
-rw-r--r--include/asm-sparc/dma.h2
-rw-r--r--include/asm-sparc/futex.h2
-rw-r--r--include/asm-sparc/iommu.h4
-rw-r--r--include/asm-sparc/kdebug.h2
-rw-r--r--include/asm-sparc/mbus.h4
-rw-r--r--include/asm-sparc/msi.h2
-rw-r--r--include/asm-sparc/mxcc.h8
-rw-r--r--include/asm-sparc/obio.h30
-rw-r--r--include/asm-sparc/pci.h6
-rw-r--r--include/asm-sparc/pgtable.h46
-rw-r--r--include/asm-sparc/pgtsrmmu.h30
-rw-r--r--include/asm-sparc/processor.h2
-rw-r--r--include/asm-sparc/psr.h6
-rw-r--r--include/asm-sparc/ptrace.h4
-rw-r--r--include/asm-sparc/sbi.h10
-rw-r--r--include/asm-sparc/sbus.h6
-rw-r--r--include/asm-sparc/smp.h26
-rw-r--r--include/asm-sparc/smpprim.h8
-rw-r--r--include/asm-sparc/spinlock.h140
-rw-r--r--include/asm-sparc/spinlock_types.h20
-rw-r--r--include/asm-sparc/system.h2
-rw-r--r--include/asm-sparc/traps.h2
-rw-r--r--include/asm-sparc64/cacheflush.h12
-rw-r--r--include/asm-sparc64/cpudata.h10
-rw-r--r--include/asm-sparc64/dma-mapping.h2
-rw-r--r--include/asm-sparc64/futex.h2
-rw-r--r--include/asm-sparc64/head.h9
-rw-r--r--include/asm-sparc64/ide.h1
-rw-r--r--include/asm-sparc64/openprom.h4
-rw-r--r--include/asm-sparc64/oplib.h66
-rw-r--r--include/asm-sparc64/page.h24
-rw-r--r--include/asm-sparc64/pbm.h30
-rw-r--r--include/asm-sparc64/pci.h2
-rw-r--r--include/asm-sparc64/pgalloc.h1
-rw-r--r--include/asm-sparc64/pgtable.h34
-rw-r--r--include/asm-sparc64/spinlock.h160
-rw-r--r--include/asm-sparc64/spinlock_types.h20
-rw-r--r--include/asm-sparc64/system.h49
-rw-r--r--include/asm-sparc64/uaccess.h24
-rw-r--r--include/asm-um/dma-mapping.h2
-rw-r--r--include/asm-um/futex.h51
-rw-r--r--include/asm-um/page.h5
-rw-r--r--include/asm-um/pgtable.h17
-rw-r--r--include/asm-um/processor-generic.h24
-rw-r--r--include/asm-um/processor-i386.h15
-rw-r--r--include/asm-um/processor-x86_64.h14
-rw-r--r--include/asm-um/spinlock_types.h6
-rw-r--r--include/asm-um/system-i386.h2
-rw-r--r--include/asm-um/uaccess.h2
-rw-r--r--include/asm-v850/futex.h2
-rw-r--r--include/asm-x86_64/acpi.h27
-rw-r--r--include/asm-x86_64/apic.h3
-rw-r--r--include/asm-x86_64/apicdef.h1
-rw-r--r--include/asm-x86_64/bug.h10
-rw-r--r--include/asm-x86_64/calling.h23
-rw-r--r--include/asm-x86_64/current.h2
-rw-r--r--include/asm-x86_64/desc.h4
-rw-r--r--include/asm-x86_64/dma-mapping.h7
-rw-r--r--include/asm-x86_64/dwarf2.h8
-rw-r--r--include/asm-x86_64/fixmap.h2
-rw-r--r--include/asm-x86_64/hardirq.h9
-rw-r--r--include/asm-x86_64/hw_irq.h18
-rw-r--r--include/asm-x86_64/io.h14
-rw-r--r--include/asm-x86_64/io_apic.h2
-rw-r--r--include/asm-x86_64/ipi.h23
-rw-r--r--include/asm-x86_64/irq.h4
-rw-r--r--include/asm-x86_64/kdebug.h4
-rw-r--r--include/asm-x86_64/local.h4
-rw-r--r--include/asm-x86_64/mmzone.h4
-rw-r--r--include/asm-x86_64/mpspec.h2
-rw-r--r--include/asm-x86_64/msr.h50
-rw-r--r--include/asm-x86_64/numa.h3
-rw-r--r--include/asm-x86_64/page.h4
-rw-r--r--include/asm-x86_64/pda.h14
-rw-r--r--include/asm-x86_64/pgalloc.h8
-rw-r--r--include/asm-x86_64/pgtable.h11
-rw-r--r--include/asm-x86_64/processor.h12
-rw-r--r--include/asm-x86_64/proto.h6
-rw-r--r--include/asm-x86_64/signal.h10
-rw-r--r--include/asm-x86_64/smp.h3
-rw-r--r--include/asm-x86_64/spinlock.h164
-rw-r--r--include/asm-x86_64/spinlock_types.h20
-rw-r--r--include/asm-x86_64/swiotlb.h2
-rw-r--r--include/asm-x86_64/system.h8
-rw-r--r--include/asm-x86_64/timex.h1
-rw-r--r--include/asm-x86_64/tlbflush.h4
-rw-r--r--include/asm-x86_64/topology.h3
-rw-r--r--include/asm-x86_64/vsyscall.h1
-rw-r--r--include/asm-xtensa/atomic.h2
-rw-r--r--include/asm-xtensa/bitops.h2
-rw-r--r--include/asm-xtensa/dma-mapping.h2
-rw-r--r--include/asm-xtensa/hardirq.h1
-rw-r--r--include/asm-xtensa/pgtable.h6
-rw-r--r--include/asm-xtensa/ptrace.h2
-rw-r--r--include/asm-xtensa/semaphore.h49
-rw-r--r--include/asm-xtensa/system.h16
-rw-r--r--include/asm-xtensa/uaccess.h2
-rw-r--r--include/linux/acct.h4
-rw-r--r--include/linux/acpi.h45
-rw-r--r--include/linux/aio.h41
-rw-r--r--include/linux/ata.h41
-rw-r--r--include/linux/atmdev.h12
-rw-r--r--include/linux/audit.h36
-rw-r--r--include/linux/bfs_fs.h59
-rw-r--r--include/linux/bio.h15
-rw-r--r--include/linux/bit_spinlock.h77
-rw-r--r--include/linux/blkdev.h52
-rw-r--r--include/linux/bootmem.h32
-rw-r--r--include/linux/buffer_head.h4
-rw-r--r--include/linux/byteorder/generic.h4
-rw-r--r--include/linux/chio.h2
-rw-r--r--include/linux/connector.h167
-rw-r--r--include/linux/cpumask.h10
-rw-r--r--include/linux/cpuset.h5
-rw-r--r--include/linux/crc16.h30
-rw-r--r--include/linux/cyclomx.h2
-rw-r--r--include/linux/cycx_drv.h1
-rw-r--r--include/linux/dccp.h62
-rw-r--r--include/linux/device.h5
-rw-r--r--include/linux/dmapool.h3
-rw-r--r--include/linux/dmi.h2
-rw-r--r--include/linux/elevator.h22
-rw-r--r--include/linux/fb.h30
-rw-r--r--include/linux/file.h30
-rw-r--r--include/linux/font.h10
-rw-r--r--include/linux/fs.h8
-rw-r--r--include/linux/fuse.h259
-rw-r--r--include/linux/genhd.h2
-rw-r--r--include/linux/gfp.h53
-rw-r--r--include/linux/hugetlb.h3
-rw-r--r--include/linux/i2c-pxa.h48
-rw-r--r--include/linux/i2c.h5
-rw-r--r--include/linux/i2o.h4
-rw-r--r--include/linux/ibmtr.h4
-rw-r--r--include/linux/idr.h3
-rw-r--r--include/linux/if_arp.h1
-rw-r--r--include/linux/if_ether.h2
-rw-r--r--include/linux/if_vlan.h8
-rw-r--r--include/linux/in6.h52
-rw-r--r--include/linux/inetdevice.h12
-rw-r--r--include/linux/init_task.h18
-rw-r--r--include/linux/input.h8
-rw-r--r--include/linux/interrupt.h7
-rw-r--r--include/linux/ipv6.h22
-rw-r--r--include/linux/jbd.h7
-rw-r--r--include/linux/jiffies.h40
-rw-r--r--include/linux/joystick.h24
-rw-r--r--include/linux/kernel.h4
-rw-r--r--include/linux/key-ui.h87
-rw-r--r--include/linux/key.h78
-rw-r--r--include/linux/kfifo.h4
-rw-r--r--include/linux/kobject.h2
-rw-r--r--include/linux/libata.h114
-rw-r--r--include/linux/list.h39
-rw-r--r--include/linux/loop.h2
-rw-r--r--include/linux/mbcache.h2
-rw-r--r--include/linux/mempolicy.h1
-rw-r--r--include/linux/mempool.h9
-rw-r--r--include/linux/mii.h1
-rw-r--r--include/linux/mm.h12
-rw-r--r--include/linux/mmc/host.h10
-rw-r--r--include/linux/mmc/mmc.h4
-rw-r--r--include/linux/mmzone.h2
-rw-r--r--include/linux/mod_devicetable.h7
-rw-r--r--include/linux/namei.h8
-rw-r--r--include/linux/netdevice.h95
-rw-r--r--include/linux/netfilter/nfnetlink.h12
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h15
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h47
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_pptp.h325
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h114
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_protocol.h3
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tuple.h11
-rw-r--r--include/linux/netfilter_ipv4/ip_nat.h4
-rw-r--r--include/linux/netfilter_ipv4/ip_nat_core.h12
-rw-r--r--include/linux/netfilter_ipv4/ip_nat_pptp.h11
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h3
-rw-r--r--include/linux/netlink.h4
-rw-r--r--include/linux/netpoll.h2
-rw-r--r--include/linux/nfs_fs.h28
-rw-r--r--include/linux/nfs_xdr.h65
-rw-r--r--include/linux/nfsd/xdr4.h15
-rw-r--r--include/linux/pagemap.h15
-rw-r--r--include/linux/pci.h519
-rw-r--r--include/linux/pci_ids.h73
-rw-r--r--include/linux/pci_regs.h448
-rw-r--r--include/linux/pktcdvd.h3
-rw-r--r--include/linux/posix_acl.h6
-rw-r--r--include/linux/radix-tree.h4
-rw-r--r--include/linux/raid/bitmap.h15
-rw-r--r--include/linux/raid/linear.h4
-rw-r--r--include/linux/raid/md_k.h81
-rw-r--r--include/linux/raid/md_p.h16
-rw-r--r--include/linux/raid/raid1.h13
-rw-r--r--include/linux/raid/raid5.h14
-rw-r--r--include/linux/rcupdate.h5
-rw-r--r--include/linux/rcuref.h220
-rw-r--r--include/linux/reboot.h4
-rw-r--r--include/linux/reiserfs_fs.h8
-rw-r--r--include/linux/sched.h34
-rw-r--r--include/linux/sdladrv.h4
-rw-r--r--include/linux/security.h193
-rw-r--r--include/linux/serial_8250.h15
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/skbuff.h45
-rw-r--r--include/linux/slab.h20
-rw-r--r--include/linux/spinlock.h627
-rw-r--r--include/linux/spinlock_api_smp.h57
-rw-r--r--include/linux/spinlock_api_up.h80
-rw-r--r--include/linux/spinlock_types.h67
-rw-r--r--include/linux/spinlock_types_up.h51
-rw-r--r--include/linux/spinlock_up.h74
-rw-r--r--include/linux/string.h2
-rw-r--r--include/linux/sunrpc/auth.h7
-rw-r--r--include/linux/sunrpc/debug.h3
-rw-r--r--include/linux/sunrpc/gss_api.h27
-rw-r--r--include/linux/sunrpc/gss_err.h10
-rw-r--r--include/linux/sunrpc/gss_krb5.h27
-rw-r--r--include/linux/sunrpc/gss_spkm3.h4
-rw-r--r--include/linux/sunrpc/msg_prot.h25
-rw-r--r--include/linux/sunrpc/xdr.h6
-rw-r--r--include/linux/sunrpc/xprt.h227
-rw-r--r--include/linux/suspend.h2
-rw-r--r--include/linux/swap.h6
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/sysctl.h29
-rw-r--r--include/linux/tc_ematch/tc_em_meta.h2
-rw-r--r--include/linux/textsearch.h7
-rw-r--r--include/linux/tfrc.h35
-rw-r--r--include/linux/time.h9
-rw-r--r--include/linux/timer.h4
-rw-r--r--include/linux/tty.h3
-rw-r--r--include/linux/types.h11
-rw-r--r--include/linux/usb.h19
-rw-r--r--include/linux/usb_gadget.h12
-rw-r--r--include/linux/usb_isp116x.h30
-rw-r--r--include/linux/usbdevice_fs.h2
-rw-r--r--include/linux/videodev.h3
-rw-r--r--include/linux/videodev2.h113
-rw-r--r--include/linux/vmalloc.h4
-rw-r--r--include/linux/wanpipe.h9
-rw-r--r--include/linux/writeback.h2
-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.h35
-rw-r--r--include/net/bluetooth/bluetooth.h2
-rw-r--r--include/net/bluetooth/hci.h11
-rw-r--r--include/net/bluetooth/rfcomm.h2
-rw-r--r--include/net/compat.h5
-rw-r--r--include/net/dn_nsp.h8
-rw-r--r--include/net/dn_route.h2
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/ieee80211.h525
-rw-r--r--include/net/ieee80211_crypt.h38
-rw-r--r--include/net/ieee80211_radiotap.h231
-rw-r--r--include/net/inet6_hashtables.h21
-rw-r--r--include/net/inet_connection_sock.h2
-rw-r--r--include/net/inet_hashtables.h66
-rw-r--r--include/net/inet_timewait_sock.h5
-rw-r--r--include/net/ip_vs.h5
-rw-r--r--include/net/ipv6.h5
-rw-r--r--include/net/llc.h30
-rw-r--r--include/net/llc_conn.h15
-rw-r--r--include/net/llc_pdu.h4
-rw-r--r--include/net/llc_sap.h8
-rw-r--r--include/net/netrom.h32
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--include/net/sctp/sm.h10
-rw-r--r--include/net/sctp/structs.h24
-rw-r--r--include/net/sctp/ulpevent.h16
-rw-r--r--include/net/sctp/ulpqueue.h11
-rw-r--r--include/net/sctp/user.h33
-rw-r--r--include/net/sock.h23
-rw-r--r--include/net/syncppp.h1
-rw-r--r--include/net/tcp.h3
-rw-r--r--include/net/transp_v6.h2
-rw-r--r--include/net/xfrm.h7
-rw-r--r--include/pcmcia/ds.h2
-rw-r--r--include/pcmcia/ss.h9
-rw-r--r--include/rdma/ib_cm.h1
-rw-r--r--include/rdma/ib_mad.h38
-rw-r--r--include/rdma/ib_sa.h41
-rw-r--r--include/rdma/ib_user_cm.h72
-rw-r--r--include/rdma/ib_user_verbs.h21
-rw-r--r--include/rdma/ib_verbs.h1
-rw-r--r--include/rxrpc/call.h2
-rw-r--r--include/rxrpc/message.h2
-rw-r--r--include/scsi/scsi_cmnd.h2
-rw-r--r--include/scsi/scsi_device.h5
-rw-r--r--include/scsi/scsi_host.h11
-rw-r--r--include/scsi/scsi_request.h2
-rw-r--r--include/scsi/scsi_transport_fc.h12
-rw-r--r--include/scsi/scsi_transport_sas.h100
-rw-r--r--include/sound/ac97_codec.h2
-rw-r--r--include/sound/core.h16
-rw-r--r--include/sound/cs46xx.h14
-rw-r--r--include/sound/driver.h2
-rw-r--r--include/sound/emu10k1.h9
-rw-r--r--include/sound/memalloc.h2
-rw-r--r--include/sound/pcm.h10
-rw-r--r--include/sound/pcm_oss.h3
-rw-r--r--include/sound/tea575x-tuner.h2
-rw-r--r--include/sound/trident.h17
-rw-r--r--include/sound/version.h2
-rw-r--r--include/sound/ymfpci.h22
-rw-r--r--include/video/cyblafb.h171
-rw-r--r--include/video/pm3fb.h3
-rw-r--r--include/video/sisfb.h188
-rw-r--r--include/video/w100fb.h1
-rw-r--r--init/initramfs.c12
-rw-r--r--ipc/mqueue.c3
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/acct.c43
-rw-r--r--kernel/audit.c128
-rw-r--r--kernel/auditsc.c327
-rw-r--r--kernel/compat.c9
-rw-r--r--kernel/cpuset.c114
-rw-r--r--kernel/exit.c35
-rw-r--r--kernel/fork.c106
-rw-r--r--kernel/kexec.c7
-rw-r--r--kernel/kfifo.c4
-rw-r--r--kernel/module.c11
-rw-r--r--kernel/params.c10
-rw-r--r--kernel/posix-cpu-timers.c91
-rw-r--r--kernel/posix-timers.c2
-rw-r--r--kernel/power/Kconfig3
-rw-r--r--kernel/power/disk.c6
-rw-r--r--kernel/power/power.h7
-rw-r--r--kernel/power/swsusp.c36
-rw-r--r--kernel/printk.c7
-rw-r--r--kernel/rcupdate.c27
-rw-r--r--kernel/sched.c278
-rw-r--r--kernel/signal.c90
-rw-r--r--kernel/softirq.c2
-rw-r--r--kernel/spinlock.c15
-rw-r--r--kernel/sys.c55
-rw-r--r--kernel/time.c1
-rw-r--r--kernel/timer.c37
-rw-r--r--lib/.gitignore6
-rw-r--r--lib/Kconfig8
-rw-r--r--lib/Kconfig.debug8
-rw-r--r--lib/Makefile4
-rw-r--r--lib/crc16.c67
-rw-r--r--lib/dec_and_lock.c38
-rw-r--r--lib/idr.c15
-rw-r--r--lib/kernel_lock.c3
-rw-r--r--lib/kobject.c2
-rw-r--r--lib/kobject_uevent.c4
-rw-r--r--lib/radix-tree.c2
-rw-r--r--lib/sort.c5
-rw-r--r--lib/spinlock_debug.c257
-rw-r--r--lib/textsearch.c2
-rw-r--r--lib/ts_bm.c2
-rw-r--r--lib/ts_fsm.c2
-rw-r--r--lib/ts_kmp.c2
-rw-r--r--mm/Kconfig4
-rw-r--r--mm/bootmem.c31
-rw-r--r--mm/filemap.c25
-rw-r--r--mm/fremap.c3
-rw-r--r--mm/highmem.c14
-rw-r--r--mm/hugetlb.c57
-rw-r--r--mm/madvise.c11
-rw-r--r--mm/memory.c6
-rw-r--r--mm/mempolicy.c23
-rw-r--r--mm/mempool.c8
-rw-r--r--mm/mmap.c5
-rw-r--r--mm/mprotect.c3
-rw-r--r--mm/mremap.c6
-rw-r--r--mm/nommu.c20
-rw-r--r--mm/oom_kill.c5
-rw-r--r--mm/page-writeback.c6
-rw-r--r--mm/page_alloc.c52
-rw-r--r--mm/page_io.c2
-rw-r--r--mm/shmem.c28
-rw-r--r--mm/slab.c1198
-rw-r--r--mm/swap_state.c4
-rw-r--r--mm/swapfile.c4
-rw-r--r--mm/vmalloc.c11
-rw-r--r--mm/vmscan.c25
-rw-r--r--net/802/p8022.c2
-rw-r--r--net/802/psnap.c2
-rw-r--r--net/802/tr.c7
-rw-r--r--net/8021q/vlan_dev.c2
-rw-r--r--net/Kconfig3
-rw-r--r--net/appletalk/ddp.c31
-rw-r--r--net/atm/addr.c55
-rw-r--r--net/atm/addr.h12
-rw-r--r--net/atm/atm_misc.c2
-rw-r--r--net/atm/br2684.c2
-rw-r--r--net/atm/clip.c2
-rw-r--r--net/atm/common.c6
-rw-r--r--net/atm/ioctl.c34
-rw-r--r--net/atm/lec.c43
-rw-r--r--net/atm/mpc.c2
-rw-r--r--net/atm/resources.c20
-rw-r--r--net/atm/signaling.c8
-rw-r--r--net/atm/svc.c1
-rw-r--r--net/ax25/af_ax25.c46
-rw-r--r--net/ax25/ax25_addr.c27
-rw-r--r--net/ax25/ax25_in.c2
-rw-r--r--net/ax25/ax25_ip.c6
-rw-r--r--net/bluetooth/hci_event.c33
-rw-r--r--net/bluetooth/l2cap.c2
-rw-r--r--net/bluetooth/rfcomm/core.c2
-rw-r--r--net/bluetooth/rfcomm/sock.c32
-rw-r--r--net/bluetooth/rfcomm/tty.c2
-rw-r--r--net/bluetooth/sco.c2
-rw-r--r--net/bridge/br_forward.c3
-rw-r--r--net/bridge/br_if.c2
-rw-r--r--net/bridge/br_netfilter.c8
-rw-r--r--net/bridge/netfilter/ebtables.c27
-rw-r--r--net/compat.c44
-rw-r--r--net/core/datagram.c81
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/dst.c3
-rw-r--r--net/core/neighbour.c76
-rw-r--r--net/core/netpoll.c6
-rw-r--r--net/core/pktgen.c531
-rw-r--r--net/core/skbuff.c27
-rw-r--r--net/core/sock.c32
-rw-r--r--net/core/wireless.c9
-rw-r--r--net/dccp/Makefile2
-rw-r--r--net/dccp/ackvec.c419
-rw-r--r--net/dccp/ackvec.h133
-rw-r--r--net/dccp/ccid.h35
-rw-r--r--net/dccp/ccids/ccid3.c377
-rw-r--r--net/dccp/ccids/ccid3.h37
-rw-r--r--net/dccp/ccids/lib/loss_interval.h2
-rw-r--r--net/dccp/ccids/lib/packet_history.h7
-rw-r--r--net/dccp/dccp.h101
-rw-r--r--net/dccp/input.c100
-rw-r--r--net/dccp/ipv4.c120
-rw-r--r--net/dccp/minisocks.c20
-rw-r--r--net/dccp/options.c505
-rw-r--r--net/dccp/output.c41
-rw-r--r--net/dccp/proto.c96
-rw-r--r--net/decnet/af_decnet.c17
-rw-r--r--net/decnet/dn_nsp_out.c21
-rw-r--r--net/decnet/dn_route.c3
-rw-r--r--net/econet/af_econet.c2
-rw-r--r--net/ethernet/eth.c31
-rw-r--r--net/ieee80211/Kconfig1
-rw-r--r--net/ieee80211/Makefile3
-rw-r--r--net/ieee80211/ieee80211_crypt.c59
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c75
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c150
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c26
-rw-r--r--net/ieee80211/ieee80211_geo.c141
-rw-r--r--net/ieee80211/ieee80211_module.c67
-rw-r--r--net/ieee80211/ieee80211_rx.c610
-rw-r--r--net/ieee80211/ieee80211_tx.c321
-rw-r--r--net/ieee80211/ieee80211_wx.c372
-rw-r--r--net/ipv4/af_inet.c13
-rw-r--r--net/ipv4/arp.c21
-rw-r--r--net/ipv4/devinet.c25
-rw-r--r--net/ipv4/esp4.c17
-rw-r--r--net/ipv4/fib_frontend.c4
-rw-r--r--net/ipv4/fib_semantics.c4
-rw-r--r--net/ipv4/fib_trie.c858
-rw-r--r--net/ipv4/icmp.c7
-rw-r--r--net/ipv4/igmp.c4
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/inet_timewait_sock.c7
-rw-r--r--net/ipv4/inetpeer.c3
-rw-r--r--net/ipv4/ip_gre.c4
-rw-r--r--net/ipv4/ip_output.c8
-rw-r--r--net/ipv4/ipconfig.c6
-rw-r--r--net/ipv4/ipmr.c6
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c43
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c16
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c20
-rw-r--r--net/ipv4/netfilter/Kconfig55
-rw-r--r--net/ipv4/netfilter/Makefile12
-rw-r--r--net/ipv4/netfilter/arp_tables.c14
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c183
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c806
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c45
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c52
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_gre.c328
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_sctp.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c30
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c37
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c401
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_gre.c214
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c25
-rw-r--r--net/ipv4/netfilter/ip_queue.c4
-rw-r--r--net/ipv4/netfilter/ip_tables.c17
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c223
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c6
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c16
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c5
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c4
-rw-r--r--net/ipv4/netfilter/ipt_owner.c1
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c35
-rw-r--r--net/ipv4/tcp_bic.c2
-rw-r--r--net/ipv4/tcp_input.c19
-rw-r--r--net/ipv4/tcp_ipv4.c11
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c31
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv6/addrconf.c7
-rw-r--r--net/ipv6/datagram.c139
-rw-r--r--net/ipv6/esp6.c18
-rw-r--r--net/ipv6/exthdrs.c119
-rw-r--r--net/ipv6/icmp.c29
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_flowlabel.c18
-rw-r--r--net/ipv6/ip6_output.c26
-rw-r--r--net/ipv6/ip6_tunnel.c7
-rw-r--r--net/ipv6/ipv6_sockglue.c186
-rw-r--r--net/ipv6/mcast.c4
-rw-r--r--net/ipv6/ndisc.c18
-rw-r--r--net/ipv6/netfilter/Kconfig11
-rw-r--r--net/ipv6/netfilter/Makefile2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c69
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c5
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c81
-rw-r--r--net/ipv6/netfilter/ip6t_dst.c88
-rw-r--r--net/ipv6/netfilter/ip6t_esp.c73
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c90
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c88
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c1
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c97
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/ipv6/raw.c23
-rw-r--r--net/ipv6/reassembly.c9
-rw-r--r--net/ipv6/tcp_ipv6.c54
-rw-r--r--net/ipv6/udp.c56
-rw-r--r--net/irda/ircomm/ircomm_tty.c9
-rw-r--r--net/irda/irlan/irlan_eth.c2
-rw-r--r--net/irda/irttp.c16
-rw-r--r--net/key/af_key.c18
-rw-r--r--net/llc/Makefile1
-rw-r--r--net/llc/af_llc.c501
-rw-r--r--net/llc/llc_c_ac.c271
-rw-r--r--net/llc/llc_c_ev.c157
-rw-r--r--net/llc/llc_conn.c211
-rw-r--r--net/llc/llc_core.c34
-rw-r--r--net/llc/llc_if.c11
-rw-r--r--net/llc/llc_input.c19
-rw-r--r--net/llc/llc_output.c2
-rw-r--r--net/llc/llc_proc.c2
-rw-r--r--net/llc/llc_s_ac.c16
-rw-r--r--net/llc/llc_sap.c20
-rw-r--r--net/llc/llc_station.c25
-rw-r--r--net/llc/sysctl_net_llc.c131
-rw-r--r--net/netfilter/nfnetlink.c6
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c4
-rw-r--r--net/netlink/af_netlink.c9
-rw-r--r--net/netrom/af_netrom.c28
-rw-r--r--net/netrom/nr_dev.c56
-rw-r--r--net/netrom/nr_in.c15
-rw-r--r--net/netrom/nr_loopback.c2
-rw-r--r--net/netrom/nr_subr.c7
-rw-r--r--net/netrom/sysctl_net_netrom.c12
-rw-r--r--net/packet/af_packet.c63
-rw-r--r--net/rose/af_rose.c34
-rw-r--r--net/rose/rose_dev.c2
-rw-r--r--net/rose/rose_route.c2
-rw-r--r--net/rose/rose_subr.c4
-rw-r--r--net/rxrpc/call.c2
-rw-r--r--net/rxrpc/connection.c2
-rw-r--r--net/sched/Kconfig4
-rw-r--r--net/sched/em_meta.c6
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/sctp/associola.c10
-rw-r--r--net/sctp/bind_addr.c12
-rw-r--r--net/sctp/chunk.c2
-rw-r--r--net/sctp/endpointola.c5
-rw-r--r--net/sctp/proc.c4
-rw-r--r--net/sctp/protocol.c4
-rw-r--r--net/sctp/sm_make_chunk.c14
-rw-r--r--net/sctp/sm_sideeffect.c12
-rw-r--r--net/sctp/sm_statefuns.c22
-rw-r--r--net/sctp/socket.c252
-rw-r--r--net/sctp/ssnmap.c2
-rw-r--r--net/sctp/transport.c4
-rw-r--r--net/sctp/ulpevent.c18
-rw-r--r--net/sctp/ulpqueue.c8
-rw-r--r--net/socket.c23
-rw-r--r--net/sunrpc/Makefile2
-rw-r--r--net/sunrpc/auth.c1
-rw-r--r--net/sunrpc/auth_gss/Makefile2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c187
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c260
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c41
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c44
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c39
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c363
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c29
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c21
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_seal.c4
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_unseal.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c9
-rw-r--r--net/sunrpc/auth_null.c2
-rw-r--r--net/sunrpc/auth_unix.c2
-rw-r--r--net/sunrpc/clnt.c147
-rw-r--r--net/sunrpc/pmap_clnt.c12
-rw-r--r--net/sunrpc/rpc_pipe.c29
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/socklib.c175
-rw-r--r--net/sunrpc/sunrpc_syms.c1
-rw-r--r--net/sunrpc/svcsock.c91
-rw-r--r--net/sunrpc/sysctl.c32
-rw-r--r--net/sunrpc/xdr.c177
-rw-r--r--net/sunrpc/xprt.c1613
-rw-r--r--net/sunrpc/xprtsock.c1252
-rw-r--r--net/sysctl_net.c2
-rw-r--r--net/xfrm/xfrm_policy.c57
-rw-r--r--net/xfrm/xfrm_state.c6
-rw-r--r--scripts/.gitignore4
-rw-r--r--scripts/Kbuild.include3
-rw-r--r--scripts/basic/.gitignore3
-rw-r--r--scripts/kconfig/.gitignore16
-rw-r--r--scripts/mod/.gitignore4
-rw-r--r--scripts/mod/file2alias.c2
-rw-r--r--scripts/mod/modpost.c6
-rw-r--r--scripts/reference_discarded.pl7
-rw-r--r--security/Kconfig1
-rw-r--r--security/Makefile2
-rw-r--r--security/dummy.c54
-rw-r--r--security/inode.c347
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/internal.h26
-rw-r--r--security/keys/key.c81
-rw-r--r--security/keys/keyctl.c301
-rw-r--r--security/keys/keyring.c86
-rw-r--r--security/keys/permission.c70
-rw-r--r--security/keys/proc.c2
-rw-r--r--security/keys/process_keys.c164
-rw-r--r--security/keys/request_key.c38
-rw-r--r--security/keys/request_key_auth.c5
-rw-r--r--security/seclvl.c237
-rw-r--r--security/selinux/avc.c4
-rw-r--r--security/selinux/hooks.c214
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/policydb.c6
-rw-r--r--security/selinux/ss/services.c4
-rw-r--r--sound/arm/Kconfig1
-rw-r--r--sound/arm/aaci.c5
-rw-r--r--sound/arm/pxa2xx-ac97.c2
-rw-r--r--sound/arm/sa11xx-uda1341.c7
-rw-r--r--sound/core/Kconfig14
-rw-r--r--sound/core/control.c12
-rw-r--r--sound/core/control_compat.c8
-rw-r--r--sound/core/device.c2
-rw-r--r--sound/core/hwdep.c2
-rw-r--r--sound/core/info.c8
-rw-r--r--sound/core/init.c193
-rw-r--r--sound/core/memalloc.c9
-rw-r--r--sound/core/memory.c14
-rw-r--r--sound/core/oss/mixer_oss.c26
-rw-r--r--sound/core/oss/pcm_oss.c17
-rw-r--r--sound/core/oss/pcm_plugin.c2
-rw-r--r--sound/core/pcm.c6
-rw-r--r--sound/core/pcm_lib.c117
-rw-r--r--sound/core/pcm_memory.c4
-rw-r--r--sound/core/pcm_native.c11
-rw-r--r--sound/core/rawmidi.c16
-rw-r--r--sound/core/seq/instr/ainstr_gf1.c7
-rw-r--r--sound/core/seq/instr/ainstr_iw.c12
-rw-r--r--sound/core/seq/instr/ainstr_simple.c3
-rw-r--r--sound/core/seq/oss/seq_oss_init.c2
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c6
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c2
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c4
-rw-r--r--sound/core/seq/oss/seq_oss_timer.c2
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c2
-rw-r--r--sound/core/seq/seq.c8
-rw-r--r--sound/core/seq/seq_clientmgr.c9
-rw-r--r--sound/core/seq/seq_device.c2
-rw-r--r--sound/core/seq/seq_dummy.c2
-rw-r--r--sound/core/seq/seq_fifo.c2
-rw-r--r--sound/core/seq/seq_instr.c4
-rw-r--r--sound/core/seq/seq_memory.c2
-rw-r--r--sound/core/seq/seq_midi.c2
-rw-r--r--sound/core/seq/seq_midi_event.c2
-rw-r--r--sound/core/seq/seq_ports.c4
-rw-r--r--sound/core/seq/seq_prioq.c2
-rw-r--r--sound/core/seq/seq_queue.c2
-rw-r--r--sound/core/seq/seq_system.c4
-rw-r--r--sound/core/seq/seq_timer.c2
-rw-r--r--sound/core/seq/seq_virmidi.c6
-rw-r--r--sound/core/sound.c15
-rw-r--r--sound/core/timer.c10
-rw-r--r--sound/core/wrappers.c2
-rw-r--r--sound/drivers/Kconfig5
-rw-r--r--sound/drivers/dummy.c8
-rw-r--r--sound/drivers/mpu401/mpu401.c26
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c2
-rw-r--r--sound/drivers/mtpav.c5
-rw-r--r--sound/drivers/opl3/opl3_lib.c2
-rw-r--r--sound/drivers/opl3/opl3_oss.c2
-rw-r--r--sound/drivers/opl4/opl4_lib.c2
-rw-r--r--sound/drivers/serial-u16550.c28
-rw-r--r--sound/drivers/virmidi.c4
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/drivers/vx/vx_pcm.c2
-rw-r--r--sound/i2c/cs8427.c2
-rw-r--r--sound/i2c/i2c.c4
-rw-r--r--sound/i2c/l3/uda1341.c6
-rw-r--r--sound/i2c/other/ak4114.c2
-rw-r--r--sound/i2c/other/ak4117.c2
-rw-r--r--sound/i2c/tea6330t.c2
-rw-r--r--sound/isa/Kconfig18
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c2
-rw-r--r--sound/isa/ad1848/ad1848.c37
-rw-r--r--sound/isa/ad1848/ad1848_lib.c2
-rw-r--r--sound/isa/cmi8330.c77
-rw-r--r--sound/isa/cs423x/cs4231.c46
-rw-r--r--sound/isa/cs423x/cs4231_lib.c2
-rw-r--r--sound/isa/cs423x/cs4236.c97
-rw-r--r--sound/isa/es1688/es1688.c61
-rw-r--r--sound/isa/es1688/es1688_lib.c2
-rw-r--r--sound/isa/es18xx.c83
-rw-r--r--sound/isa/gus/gus_main.c2
-rw-r--r--sound/isa/gus/gus_mem_proc.c4
-rw-r--r--sound/isa/gus/gus_pcm.c2
-rw-r--r--sound/isa/gus/gusclassic.c115
-rw-r--r--sound/isa/gus/gusextreme.c49
-rw-r--r--sound/isa/gus/gusmax.c145
-rw-r--r--sound/isa/gus/interwave.c167
-rw-r--r--sound/isa/opl3sa2.c40
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c13
-rw-r--r--sound/isa/sb/emu8000.c2
-rw-r--r--sound/isa/sb/emu8000_pcm.c2
-rw-r--r--sound/isa/sb/sb16.c144
-rw-r--r--sound/isa/sb/sb16_csp.c46
-rw-r--r--sound/isa/sb/sb8.c62
-rw-r--r--sound/isa/sb/sb_common.c2
-rw-r--r--sound/isa/sgalaxy.c65
-rw-r--r--sound/isa/sscape.c22
-rw-r--r--sound/isa/wavefront/wavefront.c5
-rw-r--r--sound/mips/Kconfig1
-rw-r--r--sound/mips/au1x00.c5
-rw-r--r--sound/oss/au1000.c2
-rw-r--r--sound/oss/dmasound/dmasound.h2
-rw-r--r--sound/oss/dmasound/dmasound_atari.c4
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c4
-rw-r--r--sound/oss/dmasound/dmasound_paula.c4
-rw-r--r--sound/oss/dmasound/dmasound_q40.c4
-rw-r--r--sound/oss/ite8172.c2
-rw-r--r--sound/oss/midibuf.c2
-rw-r--r--sound/oss/skeleton.c219
-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/parisc/harmony.c2
-rw-r--r--sound/pci/Kconfig12
-rw-r--r--sound/pci/Makefile2
-rw-r--r--sound/pci/ac97/ac97_bus.c23
-rw-r--r--sound/pci/ac97/ac97_codec.c8
-rw-r--r--sound/pci/ac97/ac97_id.h1
-rw-r--r--sound/pci/ac97/ac97_patch.c30
-rw-r--r--sound/pci/ac97/ak4531_codec.c2
-rw-r--r--sound/pci/ad1889.c1090
-rw-r--r--sound/pci/ad1889.h189
-rw-r--r--sound/pci/ali5451/ali5451.c33
-rw-r--r--sound/pci/als4000.c1
-rw-r--r--sound/pci/atiixp.c4
-rw-r--r--sound/pci/atiixp_modem.c19
-rw-r--r--sound/pci/au88x0/au88x0.c29
-rw-r--r--sound/pci/azt3328.c3
-rw-r--r--sound/pci/bt87x.c13
-rw-r--r--sound/pci/ca0106/ca0106_main.c7
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c18
-rw-r--r--sound/pci/cmipci.c29
-rw-r--r--sound/pci/cs4281.c14
-rw-r--r--sound/pci/cs46xx/cs46xx.c1
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c28
-rw-r--r--sound/pci/emu10k1/emu10k1.c1
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c10
-rw-r--r--sound/pci/emu10k1/emu10k1x.c7
-rw-r--r--sound/pci/emu10k1/emufx.c20
-rw-r--r--sound/pci/emu10k1/emumixer.c11
-rw-r--r--sound/pci/emu10k1/emupcm.c10
-rw-r--r--sound/pci/emu10k1/p16v.c4
-rw-r--r--sound/pci/ens1370.c10
-rw-r--r--sound/pci/es1938.c10
-rw-r--r--sound/pci/es1968.c26
-rw-r--r--sound/pci/fm801.c3
-rw-r--r--sound/pci/hda/hda_codec.c6
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c10
-rw-r--r--sound/pci/hda/hda_intel.c98
-rw-r--r--sound/pci/hda/hda_proc.c2
-rw-r--r--sound/pci/hda/patch_analog.c6
-rw-r--r--sound/pci/hda/patch_cmedia.c2
-rw-r--r--sound/pci/hda/patch_realtek.c30
-rw-r--r--sound/pci/hda/patch_si3054.c3
-rw-r--r--sound/pci/hda/patch_sigmatel.c4
-rw-r--r--sound/pci/ice1712/aureon.c2
-rw-r--r--sound/pci/ice1712/ice1712.c9
-rw-r--r--sound/pci/ice1712/ice1724.c9
-rw-r--r--sound/pci/ice1712/juli.c2
-rw-r--r--sound/pci/ice1712/phase.c4
-rw-r--r--sound/pci/ice1712/pontis.c2
-rw-r--r--sound/pci/intel8x0.c91
-rw-r--r--sound/pci/intel8x0m.c64
-rw-r--r--sound/pci/korg1212/korg1212.c5
-rw-r--r--sound/pci/maestro3.c32
-rw-r--r--sound/pci/mixart/mixart.c5
-rw-r--r--sound/pci/nm256/nm256.c20
-rw-r--r--sound/pci/rme32.c65
-rw-r--r--sound/pci/rme96.c86
-rw-r--r--sound/pci/rme9652/hdsp.c9
-rw-r--r--sound/pci/rme9652/hdspm.c13
-rw-r--r--sound/pci/rme9652/rme9652.c8
-rw-r--r--sound/pci/sonicvibes.c10
-rw-r--r--sound/pci/trident/trident.c1
-rw-r--r--sound/pci/trident/trident_main.c4
-rw-r--r--sound/pci/via82xx.c16
-rw-r--r--sound/pci/via82xx_modem.c3
-rw-r--r--sound/pci/vx222/vx222.c1
-rw-r--r--sound/pci/ymfpci/ymfpci.c1
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c6
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c2
-rw-r--r--sound/ppc/Kconfig15
-rw-r--r--sound/ppc/pmac.c4
-rw-r--r--sound/ppc/powermac.c3
-rw-r--r--sound/ppc/tumbler.c23
-rw-r--r--sound/sparc/Kconfig3
-rw-r--r--sound/sparc/amd7930.c5
-rw-r--r--sound/sparc/cs4231.c330
-rw-r--r--sound/sparc/dbri.c234
-rw-r--r--sound/synth/emux/emux.c2
-rw-r--r--sound/synth/emux/emux_seq.c2
-rw-r--r--sound/synth/emux/soundfont.c8
-rw-r--r--sound/synth/util_mem.c2
-rw-r--r--sound/usb/usbaudio.c36
-rw-r--r--sound/usb/usbmidi.c8
-rw-r--r--sound/usb/usbmixer.c10
-rw-r--r--sound/usb/usbmixer_maps.c10
-rw-r--r--sound/usb/usbquirks.h50
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c2
-rw-r--r--usr/.gitignore7
3518 files changed, 183587 insertions, 113544 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..5014bfa48ac1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# Normal rules
+#
+.*
+*.o
+*.a
+*.s
+*.ko
+*.mod.c
+
+#
+# Top-level generic files
+#
+vmlinux*
+System.map
+Module.symvers
+
+#
+# Generated include files
+#
+include/asm
+include/config
+include/linux/autoconf.h
+include/linux/compile.h
+include/linux/version.h
+
diff --git a/COPYING b/COPYING
index 2a7e338ec2fc..ca442d313d86 100644
--- a/COPYING
+++ b/COPYING
@@ -18,7 +18,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -321,7 +321,7 @@ the "copyright" line and a pointer to where the full notice is found.
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
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
diff --git a/CREDITS b/CREDITS
index f553f8cfaa62..a347520bef2d 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2211,6 +2211,15 @@ D: OV511 driver
S: (address available on request)
S: USA
+N: Ian McDonald
+E: iam4@cs.waikato.ac.nz
+E: imcdnzl@gmail.com
+W: http://wand.net.nz/~iam4
+W: http://imcdnzl.blogspot.com
+D: DCCP, CCID3
+S: Hamilton
+S: New Zealand
+
N: Patrick McHardy
E: kaber@trash.net
P: 1024D/12155E80 B128 7DE6 FF0A C2B2 48BE AB4C C9D4 964E 1215 5E80
@@ -2246,19 +2255,12 @@ S: D-90453 Nuernberg
S: Germany
N: Arnaldo Carvalho de Melo
-E: acme@conectiva.com.br
-E: acme@kernel.org
-E: acme@gnu.org
-W: http://bazar2.conectiva.com.br/~acme
-W: http://advogato.org/person/acme
+E: acme@mandriva.com
+E: acme@ghostprotocols.net
+W: http://oops.ghostprotocols.net:81/blog/
P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01
-D: wanrouter hacking
-D: misc Makefile, Config.in, drivers and network stacks fixes
-D: IPX & LLC network stacks maintainer
-D: Cyclom 2X synchronous card driver
-D: wl3501 PCMCIA wireless card driver
-D: i18n for minicom, net-tools, util-linux, fetchmail, etc
-S: Conectiva S.A.
+D: IPX, LLC, DCCP, cyc2x, wl3501_cs, net/ hacks
+S: Mandriva
S: R. Tocantins, 89 - Cristo Rei
S: 80050-430 - Curitiba - Paraná
S: Brazil
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index f28a24e0279b..433cf5e9ae04 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
@@ -275,7 +277,7 @@ tty.txt
unicode.txt
- info on the Unicode character/font mapping used in Linux.
uml/
- - directory with infomation about User Mode Linux.
+ - directory with information about User Mode Linux.
usb/
- directory with info regarding the Universal Serial Bus.
video4linux/
diff --git a/Documentation/Changes b/Documentation/Changes
index 5eaab0441d76..27232be26e1a 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -237,6 +237,12 @@ udev
udev is a userspace application for populating /dev dynamically with
only entries for devices actually present. udev replaces devfs.
+FUSE
+----
+
+Needs libfuse 2.4.0 or later. Absolute minimum is 2.3.0 but mount
+options 'direct_io' and 'kernel_cache' won't work.
+
Networking
==========
@@ -390,6 +396,10 @@ udev
----
o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
+FUSE
+----
+o <http://sourceforge.net/projects/fuse>
+
Networking
**********
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index f25b3953f513..eb7db3c19227 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -236,6 +236,9 @@ ugly), but try to avoid excess. Instead, put the comments at the head
of the function, telling people what it does, and possibly WHY it does
it.
+When commenting the kernel API functions, please use the kerneldoc format.
+See the files Documentation/kernel-doc-nano-HOWTO.txt and scripts/kernel-doc
+for details.
Chapter 8: You've made a mess of it
@@ -407,7 +410,26 @@ Kernel messages do not have to be terminated with a period.
Printing numbers in parentheses (%d) adds no value and should be avoided.
- Chapter 13: References
+ Chapter 13: Allocating memory
+
+The kernel provides the following general purpose memory allocators:
+kmalloc(), kzalloc(), kcalloc(), and vmalloc(). Please refer to the API
+documentation for further information about them.
+
+The preferred form for passing a size of a struct is the following:
+
+ p = kmalloc(sizeof(*p), ...);
+
+The alternative form where struct name is spelled out hurts readability and
+introduces an opportunity for a bug when the pointer variable type is changed
+but the corresponding sizeof that is passed to a memory allocator is not.
+
+Casting the return value which is a void pointer is redundant. The conversion
+from void pointer to any other pointer type is guaranteed by the C programming
+language.
+
+
+ Chapter 14: References
The C Programming Language, Second Edition
by Brian W. Kernighan and Dennis M. Ritchie.
diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 6ee3cd6134df..1af0f2d50220 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -121,7 +121,7 @@ pool's device.
dma_addr_t addr);
This puts memory back into the pool. The pool is what was passed to
-the the pool allocation routine; the cpu and dma addresses are what
+the pool allocation routine; the cpu and dma addresses are what
were returned when that routine allocated the memory being freed.
diff --git a/Documentation/DMA-ISA-LPC.txt b/Documentation/DMA-ISA-LPC.txt
new file mode 100644
index 000000000000..705f6be92bdb
--- /dev/null
+++ b/Documentation/DMA-ISA-LPC.txt
@@ -0,0 +1,151 @@
+ 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/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl
index 1ef6f43c6d8f..341aaa4ce481 100644
--- a/Documentation/DocBook/journal-api.tmpl
+++ b/Documentation/DocBook/journal-api.tmpl
@@ -116,7 +116,7 @@ filesystem. Almost.
You still need to actually journal your filesystem changes, this
is done by wrapping them into transactions. Additionally you
-also need to wrap the modification of each of the the buffers
+also need to wrap the modification of each of the buffers
with calls to the journal layer, so it knows what the modifications
you are actually making are. To do this use journal_start() which
returns a transaction handle.
@@ -128,7 +128,7 @@ and its counterpart journal_stop(), which indicates the end of a transaction
are nestable calls, so you can reenter a transaction if necessary,
but remember you must call journal_stop() the same number of times as
journal_start() before the transaction is completed (or more accurately
-leaves the the update phase). Ext3/VFS makes use of this feature to simplify
+leaves the update phase). Ext3/VFS makes use of this feature to simplify
quota support.
</para>
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 49a9ef82d575..582032eea872 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 (__FUNCTION__).
</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/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index 375ae760dc1e..d260d92089ad 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -415,6 +415,362 @@ and other resources, etc.
</sect1>
</chapter>
+ <chapter id="libataEH">
+ <title>Error handling</title>
+
+ <para>
+ This chapter describes how errors are handled under libata.
+ Readers are advised to read SCSI EH
+ (Documentation/scsi/scsi_eh.txt) and ATA exceptions doc first.
+ </para>
+
+ <sect1><title>Origins of commands</title>
+ <para>
+ In libata, a command is represented with struct ata_queued_cmd
+ or qc. qc's are preallocated during port initialization and
+ repetitively used for command executions. Currently only one
+ qc is allocated per port but yet-to-be-merged NCQ branch
+ allocates one for each tag and maps each qc to NCQ tag 1-to-1.
+ </para>
+ <para>
+ libata commands can originate from two sources - libata itself
+ and SCSI midlayer. libata internal commands are used for
+ initialization and error handling. All normal blk requests
+ and commands for SCSI emulation are passed as SCSI commands
+ through queuecommand callback of SCSI host template.
+ </para>
+ </sect1>
+
+ <sect1><title>How commands are issued</title>
+
+ <variablelist>
+
+ <varlistentry><term>Internal commands</term>
+ <listitem>
+ <para>
+ First, qc is allocated and initialized using
+ ata_qc_new_init(). Although ata_qc_new_init() doesn't
+ implement any wait or retry mechanism when qc is not
+ available, internal commands are currently issued only during
+ initialization and error recovery, so no other command is
+ active and allocation is guaranteed to succeed.
+ </para>
+ <para>
+ Once allocated qc's taskfile is initialized for the command to
+ be executed. qc currently has two mechanisms to notify
+ completion. One is via qc->complete_fn() callback and the
+ other is completion qc->waiting. qc->complete_fn() callback
+ is the asynchronous path used by normal SCSI translated
+ commands and qc->waiting is the synchronous (issuer sleeps in
+ process context) path used by internal commands.
+ </para>
+ <para>
+ Once initialization is complete, host_set lock is acquired
+ and the qc is issued.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>SCSI commands</term>
+ <listitem>
+ <para>
+ All libata drivers use ata_scsi_queuecmd() as
+ hostt->queuecommand callback. scmds can either be simulated
+ or translated. No qc is involved in processing a simulated
+ scmd. The result is computed right away and the scmd is
+ completed.
+ </para>
+ <para>
+ For a translated scmd, ata_qc_new_init() is invoked to
+ allocate a qc and the scmd is translated into the qc. SCSI
+ midlayer's completion notification function pointer is stored
+ into qc->scsidone.
+ </para>
+ <para>
+ qc->complete_fn() callback is used for completion
+ notification. ATA commands use ata_scsi_qc_complete() while
+ ATAPI commands use atapi_qc_complete(). Both functions end up
+ calling qc->scsidone to notify upper layer when the qc is
+ finished. After translation is completed, the qc is issued
+ with ata_qc_issue().
+ </para>
+ <para>
+ Note that SCSI midlayer invokes hostt->queuecommand while
+ holding host_set lock, so all above occur while holding
+ host_set lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+
+ <sect1><title>How commands are processed</title>
+ <para>
+ Depending on which protocol and which controller are used,
+ commands are processed differently. For the purpose of
+ discussion, a controller which uses taskfile interface and all
+ standard callbacks is assumed.
+ </para>
+ <para>
+ Currently 6 ATA command protocols are used. They can be
+ sorted into the following four categories according to how
+ they are processed.
+ </para>
+
+ <variablelist>
+ <varlistentry><term>ATA NO DATA or DMA</term>
+ <listitem>
+ <para>
+ ATA_PROT_NODATA and ATA_PROT_DMA fall into this category.
+ These types of commands don't require any software
+ intervention once issued. Device will raise interrupt on
+ completion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATA PIO</term>
+ <listitem>
+ <para>
+ ATA_PROT_PIO is in this category. libata currently
+ implements PIO with polling. ATA_NIEN bit is set to turn
+ off interrupt and pio_task on ata_wq performs polling and
+ IO.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATAPI NODATA or DMA</term>
+ <listitem>
+ <para>
+ ATA_PROT_ATAPI_NODATA and ATA_PROT_ATAPI_DMA are in this
+ category. packet_task is used to poll BSY bit after
+ issuing PACKET command. Once BSY is turned off by the
+ device, packet_task transfers CDB and hands off processing
+ to interrupt handler.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATAPI PIO</term>
+ <listitem>
+ <para>
+ ATA_PROT_ATAPI is in this category. ATA_NIEN bit is set
+ and, as in ATAPI NODATA or DMA, packet_task submits cdb.
+ However, after submitting cdb, further processing (data
+ transfer) is handed off to pio_task.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1><title>How commands are completed</title>
+ <para>
+ Once issued, all qc's are either completed with
+ ata_qc_complete() or time out. For commands which are handled
+ by interrupts, ata_host_intr() invokes ata_qc_complete(), and,
+ for PIO tasks, pio_task invokes ata_qc_complete(). In error
+ cases, packet_task may also complete commands.
+ </para>
+ <para>
+ ata_qc_complete() does the following.
+ </para>
+
+ <orderedlist>
+
+ <listitem>
+ <para>
+ DMA memory is unmapped.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ ATA_QCFLAG_ACTIVE is clared from qc->flags.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ qc->complete_fn() callback is invoked. If the return value of
+ the callback is not zero. Completion is short circuited and
+ ata_qc_complete() returns.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ __ata_qc_complete() is called, which does
+ <orderedlist>
+
+ <listitem>
+ <para>
+ qc->flags is cleared to zero.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ ap->active_tag and qc->tag are poisoned.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ qc->waiting is claread &amp; completed (in that order).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ qc is deallocated by clearing appropriate bit in ap->qactive.
+ </para>
+ </listitem>
+
+ </orderedlist>
+ </para>
+ </listitem>
+
+ </orderedlist>
+
+ <para>
+ So, it basically notifies upper layer and deallocates qc. One
+ exception is short-circuit path in #3 which is used by
+ atapi_qc_complete().
+ </para>
+ <para>
+ For all non-ATAPI commands, whether it fails or not, almost
+ the same code path is taken and very little error handling
+ takes place. A qc is completed with success status if it
+ succeeded, with failed status otherwise.
+ </para>
+ <para>
+ However, failed ATAPI commands require more handling as
+ REQUEST SENSE is needed to acquire sense data. If an ATAPI
+ command fails, ata_qc_complete() is invoked with error status,
+ which in turn invokes atapi_qc_complete() via
+ qc->complete_fn() callback.
+ </para>
+ <para>
+ This makes atapi_qc_complete() set scmd->result to
+ SAM_STAT_CHECK_CONDITION, complete the scmd and return 1. As
+ the sense data is empty but scmd->result is CHECK CONDITION,
+ SCSI midlayer will invoke EH for the scmd, and returning 1
+ makes ata_qc_complete() to return without deallocating the qc.
+ This leads us to ata_scsi_error() with partially completed qc.
+ </para>
+
+ </sect1>
+
+ <sect1><title>ata_scsi_error()</title>
+ <para>
+ ata_scsi_error() is the current hostt->eh_strategy_handler()
+ for libata. As discussed above, this will be entered in two
+ cases - timeout and ATAPI error completion. This function
+ calls low level libata driver's eng_timeout() callback, the
+ standard callback for which is ata_eng_timeout(). It checks
+ if a qc is active and calls ata_qc_timeout() on the qc if so.
+ Actual error handling occurs in ata_qc_timeout().
+ </para>
+ <para>
+ If EH is invoked for timeout, ata_qc_timeout() stops BMDMA and
+ completes the qc. Note that as we're currently in EH, we
+ cannot call scsi_done. As described in SCSI EH doc, a
+ recovered scmd should be either retried with
+ scsi_queue_insert() or finished with scsi_finish_command().
+ Here, we override qc->scsidone with scsi_finish_command() and
+ calls ata_qc_complete().
+ </para>
+ <para>
+ If EH is invoked due to a failed ATAPI qc, the qc here is
+ completed but not deallocated. The purpose of this
+ half-completion is to use the qc as place holder to make EH
+ code reach this place. This is a bit hackish, but it works.
+ </para>
+ <para>
+ Once control reaches here, the qc is deallocated by invoking
+ __ata_qc_complete() explicitly. Then, internal qc for REQUEST
+ SENSE is issued. Once sense data is acquired, scmd is
+ finished by directly invoking scsi_finish_command() on the
+ scmd. Note that as we already have completed and deallocated
+ the qc which was associated with the scmd, we don't need
+ to/cannot call ata_qc_complete() again.
+ </para>
+
+ </sect1>
+
+ <sect1><title>Problems with the current EH</title>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Error representation is too crude. Currently any and all
+ error conditions are represented with ATA STATUS and ERROR
+ registers. Errors which aren't ATA device errors are treated
+ as ATA device errors by setting ATA_ERR bit. Better error
+ descriptor which can properly represent ATA and other
+ errors/exceptions is needed.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When handling timeouts, no action is taken to make device
+ forget about the timed out command and ready for new commands.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ EH handling via ata_scsi_error() is not properly protected
+ from usual command processing. On EH entrance, the device is
+ not in quiescent state. Timed out commands may succeed or
+ fail any time. pio_task and atapi_task may still be running.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Too weak error recovery. Devices / controllers causing HSM
+ mismatch errors and other errors quite often require reset to
+ return to known state. Also, advanced error handling is
+ necessary to support features like NCQ and hotplug.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ ATA errors are directly handled in the interrupt handler and
+ PIO errors in pio_task. This is problematic for advanced
+ error handling for the following reasons.
+ </para>
+ <para>
+ First, advanced error handling often requires context and
+ internal qc execution.
+ </para>
+ <para>
+ Second, even a simple failure (say, CRC error) needs
+ information gathering and could trigger complex error handling
+ (say, resetting &amp; reconfiguring). Having multiple code
+ paths to gather information, enter EH and trigger actions
+ makes life painful.
+ </para>
+ <para>
+ Third, scattered EH code makes implementing low level drivers
+ difficult. Low level drivers override libata callbacks. If
+ EH is scattered over several places, each affected callbacks
+ should perform its part of error handling. This can be error
+ prone and painful.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+ </chapter>
+
<chapter id="libataExt">
<title>libata Library</title>
!Edrivers/scsi/libata-core.c
@@ -431,6 +787,722 @@ and other resources, etc.
!Idrivers/scsi/libata-scsi.c
</chapter>
+ <chapter id="ataExceptions">
+ <title>ATA errors &amp; exceptions</title>
+
+ <para>
+ This chapter tries to identify what error/exception conditions exist
+ for ATA/ATAPI devices and describe how they should be handled in
+ implementation-neutral way.
+ </para>
+
+ <para>
+ The term 'error' is used to describe conditions where either an
+ explicit error condition is reported from device or a command has
+ timed out.
+ </para>
+
+ <para>
+ The term 'exception' is either used to describe exceptional
+ conditions which are not errors (say, power or hotplug events), or
+ to describe both errors and non-error exceptional conditions. Where
+ explicit distinction between error and exception is necessary, the
+ term 'non-error exception' is used.
+ </para>
+
+ <sect1 id="excat">
+ <title>Exception categories</title>
+ <para>
+ Exceptions are described primarily with respect to legacy
+ taskfile + bus master IDE interface. If a controller provides
+ other better mechanism for error reporting, mapping those into
+ categories described below shouldn't be difficult.
+ </para>
+
+ <para>
+ In the following sections, two recovery actions - reset and
+ reconfiguring transport - are mentioned. These are described
+ further in <xref linkend="exrec"/>.
+ </para>
+
+ <sect2 id="excatHSMviolation">
+ <title>HSM violation</title>
+ <para>
+ This error is indicated when STATUS value doesn't match HSM
+ requirement during issuing or excution any ATA/ATAPI command.
+ </para>
+
+ <itemizedlist>
+ <title>Examples</title>
+
+ <listitem>
+ <para>
+ ATA_STATUS doesn't contain !BSY &amp;&amp; DRDY &amp;&amp; !DRQ while trying
+ to issue a command.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; !DRQ during PIO data transfer.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ DRQ on command completion.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR after CDB tranfer starts but before the
+ last byte of CDB is transferred. ATA/ATAPI standard states
+ that &quot;The device shall not terminate the PACKET command
+ with an error before the last byte of the command packet has
+ been written&quot; in the error outputs description of PACKET
+ command and the state diagram doesn't include such
+ transitions.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ In these cases, HSM is violated and not much information
+ regarding the error can be acquired from STATUS or ERROR
+ register. IOW, this error can be anything - driver bug,
+ faulty device, controller and/or cable.
+ </para>
+
+ <para>
+ As HSM is violated, reset is necessary to restore known state.
+ Reconfiguring transport for lower speed might be helpful too
+ as transmission errors sometimes cause this kind of errors.
+ </para>
+ </sect2>
+
+ <sect2 id="excatDevErr">
+ <title>ATA/ATAPI device error (non-NCQ / non-CHECK CONDITION)</title>
+
+ <para>
+ These are errors detected and reported by ATA/ATAPI devices
+ indicating device problems. For this type of errors, STATUS
+ and ERROR register values are valid and describe error
+ condition. Note that some of ATA bus errors are detected by
+ ATA/ATAPI devices and reported using the same mechanism as
+ device errors. Those cases are described later in this
+ section.
+ </para>
+
+ <para>
+ For ATA commands, this type of errors are indicated by !BSY
+ &amp;&amp; ERR during command execution and on completion.
+ </para>
+
+ <para>For ATAPI commands,</para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR &amp;&amp; ABRT right after issuing PACKET
+ indicates that PACKET command is not supported and falls in
+ this category.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR(==CHK) &amp;&amp; !ABRT after the last
+ byte of CDB is transferred indicates CHECK CONDITION and
+ doesn't fall in this category.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR(==CHK) &amp;&amp; ABRT after the last byte
+ of CDB is transferred *probably* indicates CHECK CONDITION and
+ doesn't fall in this category.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Of errors detected as above, the followings are not ATA/ATAPI
+ device errors but ATA bus errors and should be handled
+ according to <xref linkend="excatATAbusErr"/>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>CRC error during data transfer</term>
+ <listitem>
+ <para>
+ This is indicated by ICRC bit in the ERROR register and
+ means that corruption occurred during data transfer. Upto
+ ATA/ATAPI-7, the standard specifies that this bit is only
+ applicable to UDMA transfers but ATA/ATAPI-8 draft revision
+ 1f says that the bit may be applicable to multiword DMA and
+ PIO.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ABRT error during data transfer or on completion</term>
+ <listitem>
+ <para>
+ Upto ATA/ATAPI-7, the standard specifies that ABRT could be
+ set on ICRC errors and on cases where a device is not able
+ to complete a command. Combined with the fact that MWDMA
+ and PIO transfer errors aren't allowed to use ICRC bit upto
+ ATA/ATAPI-7, it seems to imply that ABRT bit alone could
+ indicate tranfer errors.
+ </para>
+ <para>
+ However, ATA/ATAPI-8 draft revision 1f removes the part
+ that ICRC errors can turn on ABRT. So, this is kind of
+ gray area. Some heuristics are needed here.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ ATA/ATAPI device errors can be further categorized as follows.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Media errors</term>
+ <listitem>
+ <para>
+ This is indicated by UNC bit in the ERROR register. ATA
+ devices reports UNC error only after certain number of
+ retries cannot recover the data, so there's nothing much
+ else to do other than notifying upper layer.
+ </para>
+ <para>
+ READ and WRITE commands report CHS or LBA of the first
+ failed sector but ATA/ATAPI standard specifies that the
+ amount of transferred data on error completion is
+ indeterminate, so we cannot assume that sectors preceding
+ the failed sector have been transferred and thus cannot
+ complete those sectors successfully as SCSI does.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Media changed / media change requested error</term>
+ <listitem>
+ <para>
+ &lt;&lt;TODO: fill here&gt;&gt;
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>Address error</term>
+ <listitem>
+ <para>
+ This is indicated by IDNF bit in the ERROR register.
+ Report to upper layer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>Other errors</term>
+ <listitem>
+ <para>
+ This can be invalid command or parameter indicated by ABRT
+ ERROR bit or some other error condition. Note that ABRT
+ bit can indicate a lot of things including ICRC and Address
+ errors. Heuristics needed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Depending on commands, not all STATUS/ERROR bits are
+ applicable. These non-applicable bits are marked with
+ &quot;na&quot; in the output descriptions but upto ATA/ATAPI-7
+ no definition of &quot;na&quot; can be found. However,
+ ATA/ATAPI-8 draft revision 1f describes &quot;N/A&quot; as
+ follows.
+ </para>
+
+ <blockquote>
+ <variablelist>
+ <varlistentry><term>3.2.3.3a N/A</term>
+ <listitem>
+ <para>
+ A keyword the indicates a field has no defined value in
+ this standard and should not be checked by the host or
+ device. N/A fields should be cleared to zero.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </blockquote>
+
+ <para>
+ So, it seems reasonable to assume that &quot;na&quot; bits are
+ cleared to zero by devices and thus need no explicit masking.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatATAPIcc">
+ <title>ATAPI device CHECK CONDITION</title>
+
+ <para>
+ ATAPI device CHECK CONDITION error is indicated by set CHK bit
+ (ERR bit) in the STATUS register after the last byte of CDB is
+ transferred for a PACKET command. For this kind of errors,
+ sense data should be acquired to gather information regarding
+ the errors. REQUEST SENSE packet command should be used to
+ acquire sense data.
+ </para>
+
+ <para>
+ Once sense data is acquired, this type of errors can be
+ handled similary to other SCSI errors. Note that sense data
+ may indicate ATA bus error (e.g. Sense Key 04h HARDWARE ERROR
+ &amp;&amp; ASC/ASCQ 47h/00h SCSI PARITY ERROR). In such
+ cases, the error should be considered as an ATA bus error and
+ handled according to <xref linkend="excatATAbusErr"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatNCQerr">
+ <title>ATA device error (NCQ)</title>
+
+ <para>
+ NCQ command error is indicated by cleared BSY and set ERR bit
+ during NCQ command phase (one or more NCQ commands
+ outstanding). Although STATUS and ERROR registers will
+ contain valid values describing the error, READ LOG EXT is
+ required to clear the error condition, determine which command
+ has failed and acquire more information.
+ </para>
+
+ <para>
+ READ LOG EXT Log Page 10h reports which tag has failed and
+ taskfile register values describing the error. With this
+ information the failed command can be handled as a normal ATA
+ command error as in <xref linkend="excatDevErr"/> and all
+ other in-flight commands must be retried. Note that this
+ retry should not be counted - it's likely that commands
+ retried this way would have completed normally if it were not
+ for the failed command.
+ </para>
+
+ <para>
+ Note that ATA bus errors can be reported as ATA device NCQ
+ errors. This should be handled as described in <xref
+ linkend="excatATAbusErr"/>.
+ </para>
+
+ <para>
+ If READ LOG EXT Log Page 10h fails or reports NQ, we're
+ thoroughly screwed. This condition should be treated
+ according to <xref linkend="excatHSMviolation"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatATAbusErr">
+ <title>ATA bus error</title>
+
+ <para>
+ ATA bus error means that data corruption occurred during
+ transmission over ATA bus (SATA or PATA). This type of errors
+ can be indicated by
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ ICRC or ABRT error as described in <xref linkend="excatDevErr"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Controller-specific error completion with error information
+ indicating transmission error.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On some controllers, command timeout. In this case, there may
+ be a mechanism to determine that the timeout is due to
+ transmission error.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Unknown/random errors, timeouts and all sorts of weirdities.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ As described above, transmission errors can cause wide variety
+ of symptoms ranging from device ICRC error to random device
+ lockup, and, for many cases, there is no way to tell if an
+ error condition is due to transmission error or not;
+ therefore, it's necessary to employ some kind of heuristic
+ when dealing with errors and timeouts. For example,
+ encountering repetitive ABRT errors for known supported
+ command is likely to indicate ATA bus error.
+ </para>
+
+ <para>
+ Once it's determined that ATA bus errors have possibly
+ occurred, lowering ATA bus transmission speed is one of
+ actions which may alleviate the problem. See <xref
+ linkend="exrecReconf"/> for more information.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatPCIbusErr">
+ <title>PCI bus error</title>
+
+ <para>
+ Data corruption or other failures during transmission over PCI
+ (or other system bus). For standard BMDMA, this is indicated
+ by Error bit in the BMDMA Status register. This type of
+ errors must be logged as it indicates something is very wrong
+ with the system. Resetting host controller is recommended.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatLateCompletion">
+ <title>Late completion</title>
+
+ <para>
+ This occurs when timeout occurs and the timeout handler finds
+ out that the timed out command has completed successfully or
+ with error. This is usually caused by lost interrupts. This
+ type of errors must be logged. Resetting host controller is
+ recommended.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatUnknown">
+ <title>Unknown error (timeout)</title>
+
+ <para>
+ This is when timeout occurs and the command is still
+ processing or the host and device are in unknown state. When
+ this occurs, HSM could be in any valid or invalid state. To
+ bring the device to known state and make it forget about the
+ timed out command, resetting is necessary. The timed out
+ command may be retried.
+ </para>
+
+ <para>
+ Timeouts can also be caused by transmission errors. Refer to
+ <xref linkend="excatATAbusErr"/> for more details.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatHoplugPM">
+ <title>Hotplug and power management exceptions</title>
+
+ <para>
+ &lt;&lt;TODO: fill here&gt;&gt;
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="exrec">
+ <title>EH recovery actions</title>
+
+ <para>
+ This section discusses several important recovery actions.
+ </para>
+
+ <sect2 id="exrecClr">
+ <title>Clearing error condition</title>
+
+ <para>
+ Many controllers require its error registers to be cleared by
+ error handler. Different controllers may have different
+ requirements.
+ </para>
+
+ <para>
+ For SATA, it's strongly recommended to clear at least SError
+ register during error handling.
+ </para>
+ </sect2>
+
+ <sect2 id="exrecRst">
+ <title>Reset</title>
+
+ <para>
+ During EH, resetting is necessary in the following cases.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ HSM is in unknown or invalid state
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ HBA is in unknown or invalid state
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ EH needs to make HBA/device forget about in-flight commands
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ HBA/device behaves weirdly
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Resetting during EH might be a good idea regardless of error
+ condition to improve EH robustness. Whether to reset both or
+ either one of HBA and device depends on situation but the
+ following scheme is recommended.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ When it's known that HBA is in ready state but ATA/ATAPI
+ device in in unknown state, reset only device.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If HBA is in unknown state, reset both HBA and device.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ HBA resetting is implementation specific. For a controller
+ complying to taskfile/BMDMA PCI IDE, stopping active DMA
+ transaction may be sufficient iff BMDMA state is the only HBA
+ context. But even mostly taskfile/BMDMA PCI IDE complying
+ controllers may have implementation specific requirements and
+ mechanism to reset themselves. This must be addressed by
+ specific drivers.
+ </para>
+
+ <para>
+ OTOH, ATA/ATAPI standard describes in detail ways to reset
+ ATA/ATAPI devices.
+ </para>
+
+ <variablelist>
+
+ <varlistentry><term>PATA hardware reset</term>
+ <listitem>
+ <para>
+ This is hardware initiated device reset signalled with
+ asserted PATA RESET- signal. There is no standard way to
+ initiate hardware reset from software although some
+ hardware provides registers that allow driver to directly
+ tweak the RESET- signal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>Software reset</term>
+ <listitem>
+ <para>
+ This is achieved by turning CONTROL SRST bit on for at
+ least 5us. Both PATA and SATA support it but, in case of
+ SATA, this may require controller-specific support as the
+ second Register FIS to clear SRST should be transmitted
+ while BSY bit is still set. Note that on PATA, this resets
+ both master and slave devices on a channel.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>EXECUTE DEVICE DIAGNOSTIC command</term>
+ <listitem>
+ <para>
+ Although ATA/ATAPI standard doesn't describe exactly, EDD
+ implies some level of resetting, possibly similar level
+ with software reset. Host-side EDD protocol can be handled
+ with normal command processing and most SATA controllers
+ should be able to handle EDD's just like other commands.
+ As in software reset, EDD affects both devices on a PATA
+ bus.
+ </para>
+ <para>
+ Although EDD does reset devices, this doesn't suit error
+ handling as EDD cannot be issued while BSY is set and it's
+ unclear how it will act when device is in unknown/weird
+ state.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATAPI DEVICE RESET command</term>
+ <listitem>
+ <para>
+ This is very similar to software reset except that reset
+ can be restricted to the selected device without affecting
+ the other device sharing the cable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>SATA phy reset</term>
+ <listitem>
+ <para>
+ This is the preferred way of resetting a SATA device. In
+ effect, it's identical to PATA hardware reset. Note that
+ this can be done with the standard SCR Control register.
+ As such, it's usually easier to implement than software
+ reset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ One more thing to consider when resetting devices is that
+ resetting clears certain configuration parameters and they
+ need to be set to their previous or newly adjusted values
+ after reset.
+ </para>
+
+ <para>
+ Parameters affected are.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ CHS set up with INITIALIZE DEVICE PARAMETERS (seldomly used)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Parameters set with SET FEATURES including transfer mode setting
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Block count set with SET MULTIPLE MODE
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Other parameters (SET MAX, MEDIA LOCK...)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ ATA/ATAPI standard specifies that some parameters must be
+ maintained across hardware or software reset, but doesn't
+ strictly specify all of them. Always reconfiguring needed
+ parameters after reset is required for robustness. Note that
+ this also applies when resuming from deep sleep (power-off).
+ </para>
+
+ <para>
+ Also, ATA/ATAPI standard requires that IDENTIFY DEVICE /
+ IDENTIFY PACKET DEVICE is issued after any configuration
+ parameter is updated or a hardware reset and the result used
+ for further operation. OS driver is required to implement
+ revalidation mechanism to support this.
+ </para>
+
+ </sect2>
+
+ <sect2 id="exrecReconf">
+ <title>Reconfigure transport</title>
+
+ <para>
+ For both PATA and SATA, a lot of corners are cut for cheap
+ connectors, cables or controllers and it's quite common to see
+ high transmission error rate. This can be mitigated by
+ lowering transmission speed.
+ </para>
+
+ <para>
+ The following is a possible scheme Jeff Garzik suggested.
+ </para>
+
+ <blockquote>
+ <para>
+ If more than $N (3?) transmission errors happen in 15 minutes,
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ if SATA, decrease SATA PHY speed. if speed cannot be decreased,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ decrease UDMA xfer speed. if at UDMA0, switch to PIO4,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ decrease PIO xfer speed. if at PIO3, complain, but continue
+ </para>
+ </listitem>
+ </itemizedlist>
+ </blockquote>
+
+ </sect2>
+
+ </sect1>
+
+ </chapter>
+
<chapter id="PiixInt">
<title>ata_piix Internals</title>
!Idrivers/scsi/ata_piix.c
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
index f3ef0bf435e9..705c442c7bf4 100644
--- a/Documentation/DocBook/usb.tmpl
+++ b/Documentation/DocBook/usb.tmpl
@@ -841,7 +841,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
File modification time is not updated by this request.
</para><para>
Those struct members are from some interface descriptor
- applying to the the current configuration.
+ applying to the current configuration.
The interface number is the bInterfaceNumber value, and
the altsetting number is the bAlternateSetting value.
(This resets each endpoint in the interface.)
diff --git a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt
index d5032eb480aa..63edc5f847c4 100644
--- a/Documentation/MSI-HOWTO.txt
+++ b/Documentation/MSI-HOWTO.txt
@@ -430,7 +430,7 @@ which may result in system hang. The software driver of specific
MSI-capable hardware is responsible for whether calling
pci_enable_msi or not. A return of zero indicates the kernel
successfully initializes the MSI/MSI-X capability structure of the
-device funtion. The device function is now running on MSI/MSI-X mode.
+device function. The device function is now running on MSI/MSI-X mode.
5.6 How to tell whether MSI/MSI-X is enabled on device function
diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt
index 9c6d450138ea..fcbcbc35b122 100644
--- a/Documentation/RCU/RTFP.txt
+++ b/Documentation/RCU/RTFP.txt
@@ -2,7 +2,8 @@ Read the F-ing Papers!
This document describes RCU-related publications, and is followed by
-the corresponding bibtex entries.
+the corresponding bibtex entries. A number of the publications may
+be found at http://www.rdrop.com/users/paulmck/RCU/.
The first thing resembling RCU was published in 1980, when Kung and Lehman
[Kung80] recommended use of a garbage collector to defer destruction
@@ -113,6 +114,10 @@ describing how to make RCU safe for soft-realtime applications [Sarma04c],
and a paper describing SELinux performance with RCU [JamesMorris04b].
+2005 has seen further adaptation of RCU to realtime use, permitting
+preemption of RCU realtime critical sections [PaulMcKenney05a,
+PaulMcKenney05b].
+
Bibtex Entries
@article{Kung80
@@ -410,3 +415,32 @@ Oregon Health and Sciences University"
\url{http://www.livejournal.com/users/james_morris/2153.html}
[Viewed December 10, 2004]"
}
+
+@unpublished{PaulMcKenney05a
+,Author="Paul E. McKenney"
+,Title="{[RFC]} {RCU} and {CONFIG\_PREEMPT\_RT} progress"
+,month="May"
+,year="2005"
+,note="Available:
+\url{http://lkml.org/lkml/2005/5/9/185}
+[Viewed May 13, 2005]"
+,annotation="
+ First publication of working lock-based deferred free patches
+ for the CONFIG_PREEMPT_RT environment.
+"
+}
+
+@conference{PaulMcKenney05b
+,Author="Paul E. McKenney and Dipankar Sarma"
+,Title="Towards Hard Realtime Response from the Linux Kernel on SMP Hardware"
+,Booktitle="linux.conf.au 2005"
+,month="April"
+,year="2005"
+,address="Canberra, Australia"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/realtimeRCU.2005.04.23a.pdf}
+[Viewed May 13, 2005]"
+,annotation="
+ Realtime turns into making RCU yet more realtime friendly.
+"
+}
diff --git a/Documentation/RCU/UP.txt b/Documentation/RCU/UP.txt
index 3bfb84b3b7db..aab4a9ec3931 100644
--- a/Documentation/RCU/UP.txt
+++ b/Documentation/RCU/UP.txt
@@ -8,7 +8,7 @@ is that since there is only one CPU, it should not be necessary to
wait for anything else to get done, since there are no other CPUs for
anything else to be happening on. Although this approach will -sort- -of-
work a surprising amount of the time, it is a very bad idea in general.
-This document presents two examples that demonstrate exactly how bad an
+This document presents three examples that demonstrate exactly how bad an
idea this is.
@@ -26,6 +26,9 @@ from softirq, the list scan would find itself referencing a newly freed
element B. This situation can greatly decrease the life expectancy of
your kernel.
+This same problem can occur if call_rcu() is invoked from a hardware
+interrupt handler.
+
Example 2: Function-Call Fatality
@@ -44,8 +47,37 @@ its arguments would cause it to fail to make the fundamental guarantee
underlying RCU, namely that call_rcu() defers invoking its arguments until
all RCU read-side critical sections currently executing have completed.
-Quick Quiz: why is it -not- legal to invoke synchronize_rcu() in
-this case?
+Quick Quiz #1: why is it -not- legal to invoke synchronize_rcu() in
+ this case?
+
+
+Example 3: Death by Deadlock
+
+Suppose that call_rcu() is invoked while holding a lock, and that the
+callback function must acquire this same lock. In this case, if
+call_rcu() were to directly invoke the callback, the result would
+be self-deadlock.
+
+In some cases, it would possible to restructure to code so that
+the call_rcu() is delayed until after the lock is released. However,
+there are cases where this can be quite ugly:
+
+1. If a number of items need to be passed to call_rcu() within
+ the same critical section, then the code would need to create
+ a list of them, then traverse the list once the lock was
+ released.
+
+2. In some cases, the lock will be held across some kernel API,
+ so that delaying the call_rcu() until the lock is released
+ requires that the data item be passed up via a common API.
+ It is far better to guarantee that callbacks are invoked
+ with no locks held than to have to modify such APIs to allow
+ arbitrary data items to be passed back up through them.
+
+If call_rcu() directly invokes the callback, painful locking restrictions
+or API changes would be required.
+
+Quick Quiz #2: What locking restriction must RCU callbacks respect?
Summary
@@ -53,12 +85,35 @@ Summary
Permitting call_rcu() to immediately invoke its arguments or permitting
synchronize_rcu() to immediately return breaks RCU, even on a UP system.
So do not do it! Even on a UP system, the RCU infrastructure -must-
-respect grace periods.
-
-
-Answer to Quick Quiz
-
-The calling function is scanning an RCU-protected linked list, and
-is therefore within an RCU read-side critical section. Therefore,
-the called function has been invoked within an RCU read-side critical
-section, and is not permitted to block.
+respect grace periods, and -must- invoke callbacks from a known environment
+in which no locks are held.
+
+
+Answer to Quick Quiz #1:
+ Why is it -not- legal to invoke synchronize_rcu() in this case?
+
+ Because the calling function is scanning an RCU-protected linked
+ list, and is therefore within an RCU read-side critical section.
+ Therefore, the called function has been invoked within an RCU
+ read-side critical section, and is not permitted to block.
+
+Answer to Quick Quiz #2:
+ What locking restriction must RCU callbacks respect?
+
+ Any lock that is acquired within an RCU callback must be
+ acquired elsewhere using an _irq variant of the spinlock
+ primitive. For example, if "mylock" is acquired by an
+ RCU callback, then a process-context acquisition of this
+ lock must use something like spin_lock_irqsave() to
+ acquire the lock.
+
+ If the process-context code were to simply use spin_lock(),
+ then, since RCU callbacks can be invoked from softirq context,
+ the callback might be called from a softirq that interrupted
+ the process-context critical section. This would result in
+ self-deadlock.
+
+ This restriction might seem gratuitous, since very few RCU
+ callbacks acquire locks directly. However, a great many RCU
+ callbacks do acquire locks -indirectly-, for example, via
+ the kfree() primitive.
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index 8f3fb77c9cd3..e118a7c1a092 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -43,6 +43,10 @@ over a rather long period of time, but improvements are always welcome!
rcu_read_lock_bh()) in the read-side critical sections,
and are also an excellent aid to readability.
+ As a rough rule of thumb, any dereference of an RCU-protected
+ pointer must be covered by rcu_read_lock() or rcu_read_lock_bh()
+ or by the appropriate update-side lock.
+
3. Does the update code tolerate concurrent accesses?
The whole point of RCU is to permit readers to run without
@@ -90,7 +94,11 @@ over a rather long period of time, but improvements are always welcome!
The rcu_dereference() primitive is used by the various
"_rcu()" list-traversal primitives, such as the
- list_for_each_entry_rcu().
+ list_for_each_entry_rcu(). Note that it is perfectly
+ legal (if redundant) for update-side code to use
+ rcu_dereference() and the "_rcu()" list-traversal
+ primitives. This is particularly useful in code
+ that is common to readers and updaters.
b. If the list macros are being used, the list_add_tail_rcu()
and list_add_rcu() primitives must be used in order
@@ -150,16 +158,9 @@ over a rather long period of time, but improvements are always welcome!
Use of the _rcu() list-traversal primitives outside of an
RCU read-side critical section causes no harm other than
- a slight performance degradation on Alpha CPUs and some
- confusion on the part of people trying to read the code.
-
- Another way of thinking of this is "If you are holding the
- lock that prevents the data structure from changing, why do
- you also need RCU-based protection?" That said, there may
- well be situations where use of the _rcu() list-traversal
- primitives while the update-side lock is held results in
- simpler and more maintainable code. The jury is still out
- on this question.
+ a slight performance degradation on Alpha CPUs. It can
+ also be quite helpful in reducing code bloat when common
+ code is shared between readers and updaters.
10. Conversely, if you are in an RCU read-side critical section,
you -must- use the "_rcu()" variants of the list macros.
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index eb444006683e..6fa092251586 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -64,6 +64,54 @@ o I hear that RCU is patented? What is with that?
Of these, one was allowed to lapse by the assignee, and the
others have been contributed to the Linux kernel under GPL.
+o I hear that RCU needs work in order to support realtime kernels?
+
+ Yes, work in progress.
+
o Where can I find more information on RCU?
See the RTFP.txt file in this directory.
+ Or point your browser at http://www.rdrop.com/users/paulmck/RCU/.
+
+o What are all these files in this directory?
+
+
+ NMI-RCU.txt
+
+ Describes how to use RCU to implement dynamic
+ NMI handlers, which can be revectored on the fly,
+ without rebooting.
+
+ RTFP.txt
+
+ List of RCU-related publications and web sites.
+
+ UP.txt
+
+ Discussion of RCU usage in UP kernels.
+
+ arrayRCU.txt
+
+ Describes how to use RCU to protect arrays, with
+ resizeable arrays whose elements reference other
+ data structures being of the most interest.
+
+ checklist.txt
+
+ Lists things to check for when inspecting code that
+ uses RCU.
+
+ listRCU.txt
+
+ Describes how to use RCU to protect linked lists.
+ This is the simplest and most common use of RCU
+ in the Linux kernel.
+
+ rcu.txt
+
+ You are reading it!
+
+ whatisRCU.txt
+
+ Overview of how the RCU implementation works. Along
+ the way, presents a conceptual view of RCU.
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
new file mode 100644
index 000000000000..a23fee66064d
--- /dev/null
+++ b/Documentation/RCU/rcuref.txt
@@ -0,0 +1,74 @@
+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/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
new file mode 100644
index 000000000000..354d89c78377
--- /dev/null
+++ b/Documentation/RCU/whatisRCU.txt
@@ -0,0 +1,902 @@
+What is RCU?
+
+RCU is a synchronization mechanism that was added to the Linux kernel
+during the 2.5 development effort that is optimized for read-mostly
+situations. Although RCU is actually quite simple once you understand it,
+getting there can sometimes be a challenge. Part of the problem is that
+most of the past descriptions of RCU have been written with the mistaken
+assumption that there is "one true way" to describe RCU. Instead,
+the experience has been that different people must take different paths
+to arrive at an understanding of RCU. This document provides several
+different paths, as follows:
+
+1. RCU OVERVIEW
+2. WHAT IS RCU'S CORE API?
+3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API?
+4. WHAT IF MY UPDATING THREAD CANNOT BLOCK?
+5. WHAT ARE SOME SIMPLE IMPLEMENTATIONS OF RCU?
+6. ANALOGY WITH READER-WRITER LOCKING
+7. FULL LIST OF RCU APIs
+8. ANSWERS TO QUICK QUIZZES
+
+People who prefer starting with a conceptual overview should focus on
+Section 1, though most readers will profit by reading this section at
+some point. People who prefer to start with an API that they can then
+experiment with should focus on Section 2. People who prefer to start
+with example uses should focus on Sections 3 and 4. People who need to
+understand the RCU implementation should focus on Section 5, then dive
+into the kernel source code. People who reason best by analogy should
+focus on Section 6. Section 7 serves as an index to the docbook API
+documentation, and Section 8 is the traditional answer key.
+
+So, start with the section that makes the most sense to you and your
+preferred method of learning. If you need to know everything about
+everything, feel free to read the whole thing -- but if you are really
+that type of person, you have perused the source code and will therefore
+never need this document anyway. ;-)
+
+
+1. RCU OVERVIEW
+
+The basic idea behind RCU is to split updates into "removal" and
+"reclamation" phases. The removal phase removes references to data items
+within a data structure (possibly by replacing them with references to
+new versions of these data items), and can run concurrently with readers.
+The reason that it is safe to run the removal phase concurrently with
+readers is the semantics of modern CPUs guarantee that readers will see
+either the old or the new version of the data structure rather than a
+partially updated reference. The reclamation phase does the work of reclaiming
+(e.g., freeing) the data items removed from the data structure during the
+removal phase. Because reclaiming data items can disrupt any readers
+concurrently referencing those data items, the reclamation phase must
+not start until readers no longer hold references to those data items.
+
+Splitting the update into removal and reclamation phases permits the
+updater to perform the removal phase immediately, and to defer the
+reclamation phase until all readers active during the removal phase have
+completed, either by blocking until they finish or by registering a
+callback that is invoked after they finish. Only readers that are active
+during the removal phase need be considered, because any reader starting
+after the removal phase will be unable to gain a reference to the removed
+data items, and therefore cannot be disrupted by the reclamation phase.
+
+So the typical RCU update sequence goes something like the following:
+
+a. Remove pointers to a data structure, so that subsequent
+ readers cannot gain a reference to it.
+
+b. Wait for all previous readers to complete their RCU read-side
+ critical sections.
+
+c. At this point, there cannot be any readers who hold references
+ to the data structure, so it now may safely be reclaimed
+ (e.g., kfree()d).
+
+Step (b) above is the key idea underlying RCU's deferred destruction.
+The ability to wait until all readers are done allows RCU readers to
+use much lighter-weight synchronization, in some cases, absolutely no
+synchronization at all. In contrast, in more conventional lock-based
+schemes, readers must use heavy-weight synchronization in order to
+prevent an updater from deleting the data structure out from under them.
+This is because lock-based updaters typically update data items in place,
+and must therefore exclude readers. In contrast, RCU-based updaters
+typically take advantage of the fact that writes to single aligned
+pointers are atomic on modern CPUs, allowing atomic insertion, removal,
+and replacement of data items in a linked structure without disrupting
+readers. Concurrent RCU readers can then continue accessing the old
+versions, and can dispense with the atomic operations, memory barriers,
+and communications cache misses that are so expensive on present-day
+SMP computer systems, even in absence of lock contention.
+
+In the three-step procedure shown above, the updater is performing both
+the removal and the reclamation step, but it is often helpful for an
+entirely different thread to do the reclamation, as is in fact the case
+in the Linux kernel's directory-entry cache (dcache). Even if the same
+thread performs both the update step (step (a) above) and the reclamation
+step (step (c) above), it is often helpful to think of them separately.
+For example, RCU readers and updaters need not communicate at all,
+but RCU provides implicit low-overhead communication between readers
+and reclaimers, namely, in step (b) above.
+
+So how the heck can a reclaimer tell when a reader is done, given
+that readers are not doing any sort of synchronization operations???
+Read on to learn about how RCU's API makes this easy.
+
+
+2. WHAT IS RCU'S CORE API?
+
+The core RCU API is quite small:
+
+a. rcu_read_lock()
+b. rcu_read_unlock()
+c. synchronize_rcu() / call_rcu()
+d. rcu_assign_pointer()
+e. rcu_dereference()
+
+There are many other members of the RCU API, but the rest can be
+expressed in terms of these five, though most implementations instead
+express synchronize_rcu() in terms of the call_rcu() callback API.
+
+The five core RCU APIs are described below, the other 18 will be enumerated
+later. See the kernel docbook documentation for more info, or look directly
+at the function header comments.
+
+rcu_read_lock()
+
+ void rcu_read_lock(void);
+
+ Used by a reader to inform the reclaimer that the reader is
+ entering an RCU read-side critical section. It is illegal
+ to block while in an RCU read-side critical section, though
+ kernels built with CONFIG_PREEMPT_RCU can preempt RCU read-side
+ critical sections. Any RCU-protected data structure accessed
+ during an RCU read-side critical section is guaranteed to remain
+ unreclaimed for the full duration of that critical section.
+ Reference counts may be used in conjunction with RCU to maintain
+ longer-term references to data structures.
+
+rcu_read_unlock()
+
+ void rcu_read_unlock(void);
+
+ Used by a reader to inform the reclaimer that the reader is
+ exiting an RCU read-side critical section. Note that RCU
+ read-side critical sections may be nested and/or overlapping.
+
+synchronize_rcu()
+
+ void synchronize_rcu(void);
+
+ Marks the end of updater code and the beginning of reclaimer
+ code. It does this by blocking until all pre-existing RCU
+ read-side critical sections on all CPUs have completed.
+ Note that synchronize_rcu() will -not- necessarily wait for
+ any subsequent RCU read-side critical sections to complete.
+ For example, consider the following sequence of events:
+
+ CPU 0 CPU 1 CPU 2
+ ----------------- ------------------------- ---------------
+ 1. rcu_read_lock()
+ 2. enters synchronize_rcu()
+ 3. rcu_read_lock()
+ 4. rcu_read_unlock()
+ 5. exits synchronize_rcu()
+ 6. rcu_read_unlock()
+
+ To reiterate, synchronize_rcu() waits only for ongoing RCU
+ read-side critical sections to complete, not necessarily for
+ any that begin after synchronize_rcu() is invoked.
+
+ Of course, synchronize_rcu() does not necessarily return
+ -immediately- after the last pre-existing RCU read-side critical
+ section completes. For one thing, there might well be scheduling
+ delays. For another thing, many RCU implementations process
+ requests in batches in order to improve efficiencies, which can
+ further delay synchronize_rcu().
+
+ Since synchronize_rcu() is the API that must figure out when
+ readers are done, its implementation is key to RCU. For RCU
+ to be useful in all but the most read-intensive situations,
+ synchronize_rcu()'s overhead must also be quite small.
+
+ The call_rcu() API is a callback form of synchronize_rcu(),
+ and is described in more detail in a later section. Instead of
+ blocking, it registers a function and argument which are invoked
+ after all ongoing RCU read-side critical sections have completed.
+ This callback variant is particularly useful in situations where
+ it is illegal to block.
+
+rcu_assign_pointer()
+
+ typeof(p) rcu_assign_pointer(p, typeof(p) v);
+
+ Yes, rcu_assign_pointer() -is- implemented as a macro, though it
+ would be cool to be able to declare a function in this manner.
+ (Compiler experts will no doubt disagree.)
+
+ The updater uses this function to assign a new value to an
+ RCU-protected pointer, in order to safely communicate the change
+ in value from the updater to the reader. This function returns
+ the new value, and also executes any memory-barrier instructions
+ required for a given CPU architecture.
+
+ Perhaps more important, it serves to document which pointers
+ are protected by RCU. That said, rcu_assign_pointer() is most
+ frequently used indirectly, via the _rcu list-manipulation
+ primitives such as list_add_rcu().
+
+rcu_dereference()
+
+ typeof(p) rcu_dereference(p);
+
+ Like rcu_assign_pointer(), rcu_dereference() must be implemented
+ as a macro.
+
+ The reader uses rcu_dereference() to fetch an RCU-protected
+ pointer, which returns a value that may then be safely
+ dereferenced. Note that rcu_deference() does not actually
+ dereference the pointer, instead, it protects the pointer for
+ later dereferencing. It also executes any needed memory-barrier
+ instructions for a given CPU architecture. Currently, only Alpha
+ needs memory barriers within rcu_dereference() -- on other CPUs,
+ it compiles to nothing, not even a compiler directive.
+
+ Common coding practice uses rcu_dereference() to copy an
+ RCU-protected pointer to a local variable, then dereferences
+ this local variable, for example as follows:
+
+ p = rcu_dereference(head.next);
+ return p->data;
+
+ However, in this case, one could just as easily combine these
+ into one statement:
+
+ return rcu_dereference(head.next)->data;
+
+ If you are going to be fetching multiple fields from the
+ RCU-protected structure, using the local variable is of
+ course preferred. Repeated rcu_dereference() calls look
+ ugly and incur unnecessary overhead on Alpha CPUs.
+
+ Note that the value returned by rcu_dereference() is valid
+ only within the enclosing RCU read-side critical section.
+ For example, the following is -not- legal:
+
+ rcu_read_lock();
+ p = rcu_dereference(head.next);
+ rcu_read_unlock();
+ x = p->address;
+ rcu_read_lock();
+ y = p->data;
+ rcu_read_unlock();
+
+ Holding a reference from one RCU read-side critical section
+ to another is just as illegal as holding a reference from
+ one lock-based critical section to another! Similarly,
+ using a reference outside of the critical section in which
+ it was acquired is just as illegal as doing so with normal
+ locking.
+
+ As with rcu_assign_pointer(), an important function of
+ rcu_dereference() is to document which pointers are protected
+ by RCU. And, again like rcu_assign_pointer(), rcu_dereference()
+ is typically used indirectly, via the _rcu list-manipulation
+ primitives, such as list_for_each_entry_rcu().
+
+The following diagram shows how each API communicates among the
+reader, updater, and reclaimer.
+
+
+ rcu_assign_pointer()
+ +--------+
+ +---------------------->| reader |---------+
+ | +--------+ |
+ | | |
+ | | | Protect:
+ | | | rcu_read_lock()
+ | | | rcu_read_unlock()
+ | rcu_dereference() | |
+ +---------+ | |
+ | updater |<---------------------+ |
+ +---------+ V
+ | +-----------+
+ +----------------------------------->| reclaimer |
+ +-----------+
+ Defer:
+ synchronize_rcu() & call_rcu()
+
+
+The RCU infrastructure observes the time sequence of rcu_read_lock(),
+rcu_read_unlock(), synchronize_rcu(), and call_rcu() invocations in
+order to determine when (1) synchronize_rcu() invocations may return
+to their callers and (2) call_rcu() callbacks may be invoked. Efficient
+implementations of the RCU infrastructure make heavy use of batching in
+order to amortize their overhead over many uses of the corresponding APIs.
+
+There are no fewer than three RCU mechanisms in the Linux kernel; the
+diagram above shows the first one, which is by far the most commonly used.
+The rcu_dereference() and rcu_assign_pointer() primitives are used for
+all three mechanisms, but different defer and protect primitives are
+used as follows:
+
+ Defer Protect
+
+a. synchronize_rcu() rcu_read_lock() / rcu_read_unlock()
+ call_rcu()
+
+b. call_rcu_bh() rcu_read_lock_bh() / rcu_read_unlock_bh()
+
+c. synchronize_sched() preempt_disable() / preempt_enable()
+ local_irq_save() / local_irq_restore()
+ hardirq enter / hardirq exit
+ NMI enter / NMI exit
+
+These three mechanisms are used as follows:
+
+a. RCU applied to normal data structures.
+
+b. RCU applied to networking data structures that may be subjected
+ to remote denial-of-service attacks.
+
+c. RCU applied to scheduler and interrupt/NMI-handler tasks.
+
+Again, most uses will be of (a). The (b) and (c) cases are important
+for specialized uses, but are relatively uncommon.
+
+
+3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API?
+
+This section shows a simple use of the core RCU API to protect a
+global pointer to a dynamically allocated structure. More typical
+uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt.
+
+ struct foo {
+ int a;
+ char b;
+ long c;
+ };
+ DEFINE_SPINLOCK(foo_mutex);
+
+ struct foo *gbl_foo;
+
+ /*
+ * Create a new struct foo that is the same as the one currently
+ * pointed to by gbl_foo, except that field "a" is replaced
+ * with "new_a". Points gbl_foo to the new structure, and
+ * frees up the old structure after a grace period.
+ *
+ * Uses rcu_assign_pointer() to ensure that concurrent readers
+ * see the initialized version of the new structure.
+ *
+ * Uses synchronize_rcu() to ensure that any readers that might
+ * have references to the old structure complete before freeing
+ * the old structure.
+ */
+ void foo_update_a(int new_a)
+ {
+ struct foo *new_fp;
+ struct foo *old_fp;
+
+ new_fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+ spin_lock(&foo_mutex);
+ old_fp = gbl_foo;
+ *new_fp = *old_fp;
+ new_fp->a = new_a;
+ rcu_assign_pointer(gbl_foo, new_fp);
+ spin_unlock(&foo_mutex);
+ synchronize_rcu();
+ kfree(old_fp);
+ }
+
+ /*
+ * Return the value of field "a" of the current gbl_foo
+ * structure. Use rcu_read_lock() and rcu_read_unlock()
+ * to ensure that the structure does not get deleted out
+ * from under us, and use rcu_dereference() to ensure that
+ * we see the initialized version of the structure (important
+ * for DEC Alpha and for people reading the code).
+ */
+ int foo_get_a(void)
+ {
+ int retval;
+
+ rcu_read_lock();
+ retval = rcu_dereference(gbl_foo)->a;
+ rcu_read_unlock();
+ return retval;
+ }
+
+So, to sum up:
+
+o Use rcu_read_lock() and rcu_read_unlock() to guard RCU
+ read-side critical sections.
+
+o Within an RCU read-side critical section, use rcu_dereference()
+ to dereference RCU-protected pointers.
+
+o Use some solid scheme (such as locks or semaphores) to
+ keep concurrent updates from interfering with each other.
+
+o Use rcu_assign_pointer() to update an RCU-protected pointer.
+ This primitive protects concurrent readers from the updater,
+ -not- concurrent updates from each other! You therefore still
+ need to use locking (or something similar) to keep concurrent
+ rcu_assign_pointer() primitives from interfering with each other.
+
+o Use synchronize_rcu() -after- removing a data element from an
+ RCU-protected data structure, but -before- reclaiming/freeing
+ the data element, in order to wait for the completion of all
+ RCU read-side critical sections that might be referencing that
+ data item.
+
+See checklist.txt for additional rules to follow when using RCU.
+
+
+4. WHAT IF MY UPDATING THREAD CANNOT BLOCK?
+
+In the example above, foo_update_a() blocks until a grace period elapses.
+This is quite simple, but in some cases one cannot afford to wait so
+long -- there might be other high-priority work to be done.
+
+In such cases, one uses call_rcu() rather than synchronize_rcu().
+The call_rcu() API is as follows:
+
+ void call_rcu(struct rcu_head * head,
+ void (*func)(struct rcu_head *head));
+
+This function invokes func(head) after a grace period has elapsed.
+This invocation might happen from either softirq or process context,
+so the function is not permitted to block. The foo struct needs to
+have an rcu_head structure added, perhaps as follows:
+
+ struct foo {
+ int a;
+ char b;
+ long c;
+ struct rcu_head rcu;
+ };
+
+The foo_update_a() function might then be written as follows:
+
+ /*
+ * Create a new struct foo that is the same as the one currently
+ * pointed to by gbl_foo, except that field "a" is replaced
+ * with "new_a". Points gbl_foo to the new structure, and
+ * frees up the old structure after a grace period.
+ *
+ * Uses rcu_assign_pointer() to ensure that concurrent readers
+ * see the initialized version of the new structure.
+ *
+ * Uses call_rcu() to ensure that any readers that might have
+ * references to the old structure complete before freeing the
+ * old structure.
+ */
+ void foo_update_a(int new_a)
+ {
+ struct foo *new_fp;
+ struct foo *old_fp;
+
+ new_fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+ spin_lock(&foo_mutex);
+ old_fp = gbl_foo;
+ *new_fp = *old_fp;
+ new_fp->a = new_a;
+ rcu_assign_pointer(gbl_foo, new_fp);
+ spin_unlock(&foo_mutex);
+ call_rcu(&old_fp->rcu, foo_reclaim);
+ }
+
+The foo_reclaim() function might appear as follows:
+
+ void foo_reclaim(struct rcu_head *rp)
+ {
+ struct foo *fp = container_of(rp, struct foo, rcu);
+
+ kfree(fp);
+ }
+
+The container_of() primitive is a macro that, given a pointer into a
+struct, the type of the struct, and the pointed-to field within the
+struct, returns a pointer to the beginning of the struct.
+
+The use of call_rcu() permits the caller of foo_update_a() to
+immediately regain control, without needing to worry further about the
+old version of the newly updated element. It also clearly shows the
+RCU distinction between updater, namely foo_update_a(), and reclaimer,
+namely foo_reclaim().
+
+The summary of advice is the same as for the previous section, except
+that we are now using call_rcu() rather than synchronize_rcu():
+
+o Use call_rcu() -after- removing a data element from an
+ RCU-protected data structure in order to register a callback
+ function that will be invoked after the completion of all RCU
+ read-side critical sections that might be referencing that
+ data item.
+
+Again, see checklist.txt for additional rules governing the use of RCU.
+
+
+5. WHAT ARE SOME SIMPLE IMPLEMENTATIONS OF RCU?
+
+One of the nice things about RCU is that it has extremely simple "toy"
+implementations that are a good first step towards understanding the
+production-quality implementations in the Linux kernel. This section
+presents two such "toy" implementations of RCU, one that is implemented
+in terms of familiar locking primitives, and another that more closely
+resembles "classic" RCU. Both are way too simple for real-world use,
+lacking both functionality and performance. However, they are useful
+in getting a feel for how RCU works. See kernel/rcupdate.c for a
+production-quality implementation, and see:
+
+ http://www.rdrop.com/users/paulmck/RCU
+
+for papers describing the Linux kernel RCU implementation. The OLS'01
+and OLS'02 papers are a good introduction, and the dissertation provides
+more details on the current implementation.
+
+
+5A. "TOY" IMPLEMENTATION #1: LOCKING
+
+This section presents a "toy" RCU implementation that is based on
+familiar locking primitives. Its overhead makes it a non-starter for
+real-life use, as does its lack of scalability. It is also unsuitable
+for realtime use, since it allows scheduling latency to "bleed" from
+one read-side critical section to another.
+
+However, it is probably the easiest implementation to relate to, so is
+a good starting point.
+
+It is extremely simple:
+
+ static DEFINE_RWLOCK(rcu_gp_mutex);
+
+ void rcu_read_lock(void)
+ {
+ read_lock(&rcu_gp_mutex);
+ }
+
+ void rcu_read_unlock(void)
+ {
+ read_unlock(&rcu_gp_mutex);
+ }
+
+ void synchronize_rcu(void)
+ {
+ write_lock(&rcu_gp_mutex);
+ write_unlock(&rcu_gp_mutex);
+ }
+
+[You can ignore rcu_assign_pointer() and rcu_dereference() without
+missing much. But here they are anyway. And whatever you do, don't
+forget about them when submitting patches making use of RCU!]
+
+ #define rcu_assign_pointer(p, v) ({ \
+ smp_wmb(); \
+ (p) = (v); \
+ })
+
+ #define rcu_dereference(p) ({ \
+ typeof(p) _________p1 = p; \
+ smp_read_barrier_depends(); \
+ (_________p1); \
+ })
+
+
+The rcu_read_lock() and rcu_read_unlock() primitive read-acquire
+and release a global reader-writer lock. The synchronize_rcu()
+primitive write-acquires this same lock, then immediately releases
+it. This means that once synchronize_rcu() exits, all RCU read-side
+critical sections that were in progress before synchonize_rcu() was
+called are guaranteed to have completed -- there is no way that
+synchronize_rcu() would have been able to write-acquire the lock
+otherwise.
+
+It is possible to nest rcu_read_lock(), since reader-writer locks may
+be recursively acquired. Note also that rcu_read_lock() is immune
+from deadlock (an important property of RCU). The reason for this is
+that the only thing that can block rcu_read_lock() is a synchronize_rcu().
+But synchronize_rcu() does not acquire any locks while holding rcu_gp_mutex,
+so there can be no deadlock cycle.
+
+Quick Quiz #1: Why is this argument naive? How could a deadlock
+ occur when using this algorithm in a real-world Linux
+ kernel? How could this deadlock be avoided?
+
+
+5B. "TOY" EXAMPLE #2: CLASSIC RCU
+
+This section presents a "toy" RCU implementation that is based on
+"classic RCU". It is also short on performance (but only for updates) and
+on features such as hotplug CPU and the ability to run in CONFIG_PREEMPT
+kernels. The definitions of rcu_dereference() and rcu_assign_pointer()
+are the same as those shown in the preceding section, so they are omitted.
+
+ void rcu_read_lock(void) { }
+
+ void rcu_read_unlock(void) { }
+
+ void synchronize_rcu(void)
+ {
+ int cpu;
+
+ for_each_cpu(cpu)
+ run_on(cpu);
+ }
+
+Note that rcu_read_lock() and rcu_read_unlock() do absolutely nothing.
+This is the great strength of classic RCU in a non-preemptive kernel:
+read-side overhead is precisely zero, at least on non-Alpha CPUs.
+And there is absolutely no way that rcu_read_lock() can possibly
+participate in a deadlock cycle!
+
+The implementation of synchronize_rcu() simply schedules itself on each
+CPU in turn. The run_on() primitive can be implemented straightforwardly
+in terms of the sched_setaffinity() primitive. Of course, a somewhat less
+"toy" implementation would restore the affinity upon completion rather
+than just leaving all tasks running on the last CPU, but when I said
+"toy", I meant -toy-!
+
+So how the heck is this supposed to work???
+
+Remember that it is illegal to block while in an RCU read-side critical
+section. Therefore, if a given CPU executes a context switch, we know
+that it must have completed all preceding RCU read-side critical sections.
+Once -all- CPUs have executed a context switch, then -all- preceding
+RCU read-side critical sections will have completed.
+
+So, suppose that we remove a data item from its structure and then invoke
+synchronize_rcu(). Once synchronize_rcu() returns, we are guaranteed
+that there are no RCU read-side critical sections holding a reference
+to that data item, so we can safely reclaim it.
+
+Quick Quiz #2: Give an example where Classic RCU's read-side
+ overhead is -negative-.
+
+Quick Quiz #3: If it is illegal to block in an RCU read-side
+ critical section, what the heck do you do in
+ PREEMPT_RT, where normal spinlocks can block???
+
+
+6. ANALOGY WITH READER-WRITER LOCKING
+
+Although RCU can be used in many different ways, a very common use of
+RCU is analogous to reader-writer locking. The following unified
+diff shows how closely related RCU and reader-writer locking can be.
+
+ @@ -13,15 +14,15 @@
+ struct list_head *lp;
+ struct el *p;
+
+ - read_lock();
+ - list_for_each_entry(p, head, lp) {
+ + rcu_read_lock();
+ + list_for_each_entry_rcu(p, head, lp) {
+ if (p->key == key) {
+ *result = p->data;
+ - read_unlock();
+ + rcu_read_unlock();
+ return 1;
+ }
+ }
+ - read_unlock();
+ + rcu_read_unlock();
+ return 0;
+ }
+
+ @@ -29,15 +30,16 @@
+ {
+ struct el *p;
+
+ - write_lock(&listmutex);
+ + spin_lock(&listmutex);
+ list_for_each_entry(p, head, lp) {
+ if (p->key == key) {
+ list_del(&p->list);
+ - write_unlock(&listmutex);
+ + spin_unlock(&listmutex);
+ + synchronize_rcu();
+ kfree(p);
+ return 1;
+ }
+ }
+ - write_unlock(&listmutex);
+ + spin_unlock(&listmutex);
+ return 0;
+ }
+
+Or, for those who prefer a side-by-side listing:
+
+ 1 struct el { 1 struct el {
+ 2 struct list_head list; 2 struct list_head list;
+ 3 long key; 3 long key;
+ 4 spinlock_t mutex; 4 spinlock_t mutex;
+ 5 int data; 5 int data;
+ 6 /* Other data fields */ 6 /* Other data fields */
+ 7 }; 7 };
+ 8 spinlock_t listmutex; 8 spinlock_t listmutex;
+ 9 struct el head; 9 struct el head;
+
+ 1 int search(long key, int *result) 1 int search(long key, int *result)
+ 2 { 2 {
+ 3 struct list_head *lp; 3 struct list_head *lp;
+ 4 struct el *p; 4 struct el *p;
+ 5 5
+ 6 read_lock(); 6 rcu_read_lock();
+ 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, head, lp) {
+ 8 if (p->key == key) { 8 if (p->key == key) {
+ 9 *result = p->data; 9 *result = p->data;
+10 read_unlock(); 10 rcu_read_unlock();
+11 return 1; 11 return 1;
+12 } 12 }
+13 } 13 }
+14 read_unlock(); 14 rcu_read_unlock();
+15 return 0; 15 return 0;
+16 } 16 }
+
+ 1 int delete(long key) 1 int delete(long key)
+ 2 { 2 {
+ 3 struct el *p; 3 struct el *p;
+ 4 4
+ 5 write_lock(&listmutex); 5 spin_lock(&listmutex);
+ 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, head, lp) {
+ 7 if (p->key == key) { 7 if (p->key == key) {
+ 8 list_del(&p->list); 8 list_del(&p->list);
+ 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex);
+ 10 synchronize_rcu();
+10 kfree(p); 11 kfree(p);
+11 return 1; 12 return 1;
+12 } 13 }
+13 } 14 }
+14 write_unlock(&listmutex); 15 spin_unlock(&listmutex);
+15 return 0; 16 return 0;
+16 } 17 }
+
+Either way, the differences are quite small. Read-side locking moves
+to rcu_read_lock() and rcu_read_unlock, update-side locking moves from
+from a reader-writer lock to a simple spinlock, and a synchronize_rcu()
+precedes the kfree().
+
+However, there is one potential catch: the read-side and update-side
+critical sections can now run concurrently. In many cases, this will
+not be a problem, but it is necessary to check carefully regardless.
+For example, if multiple independent list updates must be seen as
+a single atomic update, converting to RCU will require special care.
+
+Also, the presence of synchronize_rcu() means that the RCU version of
+delete() can now block. If this is a problem, there is a callback-based
+mechanism that never blocks, namely call_rcu(), that can be used in
+place of synchronize_rcu().
+
+
+7. FULL LIST OF RCU APIs
+
+The RCU APIs are documented in docbook-format header comments in the
+Linux-kernel source code, but it helps to have a full list of the
+APIs, since there does not appear to be a way to categorize them
+in docbook. Here is the list, by category.
+
+Markers for RCU read-side critical sections:
+
+ rcu_read_lock
+ rcu_read_unlock
+ rcu_read_lock_bh
+ rcu_read_unlock_bh
+
+RCU pointer/list traversal:
+
+ rcu_dereference
+ list_for_each_rcu (to be deprecated in favor of
+ list_for_each_entry_rcu)
+ list_for_each_safe_rcu (deprecated, not used)
+ list_for_each_entry_rcu
+ list_for_each_continue_rcu (to be deprecated in favor of new
+ list_for_each_entry_continue_rcu)
+ hlist_for_each_rcu (to be deprecated in favor of
+ hlist_for_each_entry_rcu)
+ hlist_for_each_entry_rcu
+
+RCU pointer update:
+
+ rcu_assign_pointer
+ list_add_rcu
+ list_add_tail_rcu
+ list_del_rcu
+ list_replace_rcu
+ hlist_del_rcu
+ hlist_add_head_rcu
+
+RCU grace period:
+
+ synchronize_kernel (deprecated)
+ synchronize_net
+ synchronize_sched
+ synchronize_rcu
+ call_rcu
+ call_rcu_bh
+
+See the comment headers in the source code (or the docbook generated
+from them) for more information.
+
+
+8. ANSWERS TO QUICK QUIZZES
+
+Quick Quiz #1: Why is this argument naive? How could a deadlock
+ occur when using this algorithm in a real-world Linux
+ kernel? [Referring to the lock-based "toy" RCU
+ algorithm.]
+
+Answer: Consider the following sequence of events:
+
+ 1. CPU 0 acquires some unrelated lock, call it
+ "problematic_lock".
+
+ 2. CPU 1 enters synchronize_rcu(), write-acquiring
+ rcu_gp_mutex.
+
+ 3. CPU 0 enters rcu_read_lock(), but must wait
+ because CPU 1 holds rcu_gp_mutex.
+
+ 4. CPU 1 is interrupted, and the irq handler
+ attempts to acquire problematic_lock.
+
+ The system is now deadlocked.
+
+ One way to avoid this deadlock is to use an approach like
+ that of CONFIG_PREEMPT_RT, where all normal spinlocks
+ become blocking locks, and all irq handlers execute in
+ the context of special tasks. In this case, in step 4
+ above, the irq handler would block, allowing CPU 1 to
+ release rcu_gp_mutex, avoiding the deadlock.
+
+ Even in the absence of deadlock, this RCU implementation
+ allows latency to "bleed" from readers to other
+ readers through synchronize_rcu(). To see this,
+ consider task A in an RCU read-side critical section
+ (thus read-holding rcu_gp_mutex), task B blocked
+ attempting to write-acquire rcu_gp_mutex, and
+ task C blocked in rcu_read_lock() attempting to
+ read_acquire rcu_gp_mutex. Task A's RCU read-side
+ latency is holding up task C, albeit indirectly via
+ task B.
+
+ Realtime RCU implementations therefore use a counter-based
+ approach where tasks in RCU read-side critical sections
+ cannot be blocked by tasks executing synchronize_rcu().
+
+Quick Quiz #2: Give an example where Classic RCU's read-side
+ overhead is -negative-.
+
+Answer: Imagine a single-CPU system with a non-CONFIG_PREEMPT
+ kernel where a routing table is used by process-context
+ code, but can be updated by irq-context code (for example,
+ by an "ICMP REDIRECT" packet). The usual way of handling
+ this would be to have the process-context code disable
+ interrupts while searching the routing table. Use of
+ RCU allows such interrupt-disabling to be dispensed with.
+ Thus, without RCU, you pay the cost of disabling interrupts,
+ and with RCU you don't.
+
+ One can argue that the overhead of RCU in this
+ case is negative with respect to the single-CPU
+ interrupt-disabling approach. Others might argue that
+ the overhead of RCU is merely zero, and that replacing
+ the positive overhead of the interrupt-disabling scheme
+ with the zero-overhead RCU scheme does not constitute
+ negative overhead.
+
+ In real life, of course, things are more complex. But
+ even the theoretical possibility of negative overhead for
+ a synchronization primitive is a bit unexpected. ;-)
+
+Quick Quiz #3: If it is illegal to block in an RCU read-side
+ critical section, what the heck do you do in
+ PREEMPT_RT, where normal spinlocks can block???
+
+Answer: Just as PREEMPT_RT permits preemption of spinlock
+ critical sections, it permits preemption of RCU
+ read-side critical sections. It also permits
+ spinlocks blocking while in RCU read-side critical
+ sections.
+
+ Why the apparent inconsistency? Because it is it
+ possible to use priority boosting to keep the RCU
+ grace periods short if need be (for example, if running
+ short of memory). In contrast, if blocking waiting
+ for (say) network reception, there is no way to know
+ what should be boosted. Especially given that the
+ process we need to boost might well be a human being
+ who just went out for a pizza or something. And although
+ a computer-operated cattle prod might arouse serious
+ interest, it might also provoke serious objections.
+ Besides, how does the computer know what pizza parlor
+ the human being went to???
+
+
+ACKNOWLEDGEMENTS
+
+My thanks to the people who helped make this human-readable, including
+Jon Walpole, Josh Triplett, Serge Hallyn, and Suzanne Wood.
+
+
+For more information, see http://www.rdrop.com/users/paulmck/RCU.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 7f43b040311e..237d54c44bc5 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -301,8 +301,84 @@ now, but you can do this to mark internal company procedures or just
point out some special detail about the sign-off.
+12) The canonical patch format
-12) More references for submitting patches
+The canonical patch subject line is:
+
+ Subject: [PATCH 001/123] subsystem: summary phrase
+
+The canonical patch message body contains the following:
+
+ - A "from" line specifying the patch author.
+
+ - An empty line.
+
+ - The body of the explanation, which will be copied to the
+ permanent changelog to describe this patch.
+
+ - The "Signed-off-by:" lines, described above, which will
+ also go in the changelog.
+
+ - A marker line containing simply "---".
+
+ - Any additional comments not suitable for the changelog.
+
+ - The actual patch (diff output).
+
+The Subject line format makes it very easy to sort the emails
+alphabetically by subject line - pretty much any email reader will
+support that - since because the sequence number is zero-padded,
+the numerical and alphabetic sort is the same.
+
+The "subsystem" in the email's Subject should identify which
+area or subsystem of the kernel is being patched.
+
+The "summary phrase" in the email's Subject should concisely
+describe the patch which that email contains. The "summary
+phrase" should not be a filename. Do not use the same "summary
+phrase" for every patch in a whole patch series.
+
+Bear in mind that the "summary phrase" of your email becomes
+a globally-unique identifier for that patch. It propagates
+all the way into the git changelog. The "summary phrase" may
+later be used in developer discussions which refer to the patch.
+People will want to google for the "summary phrase" to read
+discussion regarding that patch.
+
+A couple of example Subjects:
+
+ Subject: [patch 2/5] ext2: improve scalability of bitmap searching
+ Subject: [PATCHv2 001/207] x86: fix eflags tracking
+
+The "from" line must be the very first line in the message body,
+and has the form:
+
+ From: Original Author <author@example.com>
+
+The "from" line specifies who will be credited as the author of the
+patch in the permanent changelog. If the "from" line is missing,
+then the "From:" line from the email header will be used to determine
+the patch author in the changelog.
+
+The explanation body will be committed to the permanent source
+changelog, so should make sense to a competent reader who has long
+since forgotten the immediate details of the discussion that might
+have led to this patch.
+
+The "---" marker line serves the essential purpose of marking for patch
+handling tools where the changelog message ends.
+
+One good use for the additional comments after the "---" marker is for
+a diffstat, to show what files have changed, and the number of inserted
+and deleted lines per file. A diffstat is especially useful on bigger
+patches. Other comments relevant only to the moment or the maintainer,
+not suitable for the permanent changelog, should also go here.
+
+See more details on the proper patch format in the following
+references.
+
+
+13) More references for submitting patches
Andrew Morton, "The perfect patch" (tpp).
<http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
@@ -310,6 +386,14 @@ Andrew Morton, "The perfect patch" (tpp).
Jeff Garzik, "Linux kernel patch submission format."
<http://linux.yyz.us/patch-format.html>
+Greg KH, "How to piss off a kernel subsystem maintainer"
+ <http://www.kroah.com/log/2005/03/31/>
+
+Kernel Documentation/CodingStyle
+ <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
+
+Linus Torvald's mail on the canonical patch format:
+ <http://lkml.org/lkml/2005/4/7/183>
-----------------------------------
diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
index 0acdc80c30c2..744f1aec6553 100644
--- a/Documentation/acpi-hotkey.txt
+++ b/Documentation/acpi-hotkey.txt
@@ -35,4 +35,4 @@ created. Please use command "cat /proc/acpi/hotkey/polling_method"
to retrieve it.
Note: Use cmdline "acpi_generic_hotkey" to over-ride
-loading any platform specific drivers.
+platform-specific with generic driver.
diff --git a/Documentation/aoe/mkshelf.sh b/Documentation/aoe/mkshelf.sh
index 8bacf9f2c7cc..32615814271c 100644
--- a/Documentation/aoe/mkshelf.sh
+++ b/Documentation/aoe/mkshelf.sh
@@ -8,13 +8,15 @@ fi
n_partitions=${n_partitions:-16}
dir=$1
shelf=$2
+nslots=16
+maxslot=`echo $nslots 1 - p | dc`
MAJOR=152
set -e
-minor=`echo 10 \* $shelf \* $n_partitions | bc`
+minor=`echo $nslots \* $shelf \* $n_partitions | bc`
endp=`echo $n_partitions - 1 | bc`
-for slot in `seq 0 9`; do
+for slot in `seq 0 $maxslot`; do
for part in `seq 0 $endp`; do
name=e$shelf.$slot
test "$part" != "0" && name=${name}p$part
diff --git a/Documentation/applying-patches.txt b/Documentation/applying-patches.txt
new file mode 100644
index 000000000000..681e426e2482
--- /dev/null
+++ b/Documentation/applying-patches.txt
@@ -0,0 +1,439 @@
+
+ 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/block/biodoc.txt b/Documentation/block/biodoc.txt
index 6dd274d7e1cf..2d65c2182161 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -906,9 +906,20 @@ Aside:
4. The I/O scheduler
-I/O schedulers are now per queue. They should be runtime switchable and modular
-but aren't yet. Jens has most bits to do this, but the sysfs implementation is
-missing.
+I/O scheduler, a.k.a. elevator, is implemented in two layers. Generic dispatch
+queue and specific I/O schedulers. Unless stated otherwise, elevator is used
+to refer to both parts and I/O scheduler to specific I/O schedulers.
+
+Block layer implements generic dispatch queue in ll_rw_blk.c and elevator.c.
+The generic dispatch queue is responsible for properly ordering barrier
+requests, requeueing, handling non-fs requests and all other subtleties.
+
+Specific I/O schedulers are responsible for ordering normal filesystem
+requests. They can also choose to delay certain requests to improve
+throughput or whatever purpose. As the plural form indicates, there are
+multiple I/O schedulers. They can be built as modules but at least one should
+be built inside the kernel. Each queue can choose different one and can also
+change to another one dynamically.
A block layer call to the i/o scheduler follows the convention elv_xxx(). This
calls elevator_xxx_fn in the elevator switch (drivers/block/elevator.c). Oh,
@@ -921,44 +932,36 @@ keeping work.
The functions an elevator may implement are: (* are mandatory)
elevator_merge_fn called to query requests for merge with a bio
-elevator_merge_req_fn " " " with another request
+elevator_merge_req_fn called when two requests get merged. the one
+ which gets merged into the other one will be
+ never seen by I/O scheduler again. IOW, after
+ being merged, the request is gone.
elevator_merged_fn called when a request in the scheduler has been
involved in a merge. It is used in the deadline
scheduler for example, to reposition the request
if its sorting order has changed.
-*elevator_next_req_fn returns the next scheduled request, or NULL
- if there are none (or none are ready).
+elevator_dispatch_fn fills the dispatch queue with ready requests.
+ I/O schedulers are free to postpone requests by
+ not filling the dispatch queue unless @force
+ is non-zero. Once dispatched, I/O schedulers
+ are not allowed to manipulate the requests -
+ they belong to generic dispatch queue.
-*elevator_add_req_fn called to add a new request into the scheduler
+elevator_add_req_fn called to add a new request into the scheduler
elevator_queue_empty_fn returns true if the merge queue is empty.
Drivers shouldn't use this, but rather check
if elv_next_request is NULL (without losing the
request if one exists!)
-elevator_remove_req_fn This is called when a driver claims ownership of
- the target request - it now belongs to the
- driver. It must not be modified or merged.
- Drivers must not lose the request! A subsequent
- call of elevator_next_req_fn must return the
- _next_ request.
-
-elevator_requeue_req_fn called to add a request to the scheduler. This
- is used when the request has alrnadebeen
- returned by elv_next_request, but hasn't
- completed. If this is not implemented then
- elevator_add_req_fn is called instead.
-
elevator_former_req_fn
elevator_latter_req_fn These return the request before or after the
one specified in disk sort order. Used by the
block layer to find merge possibilities.
-elevator_completed_req_fn called when a request is completed. This might
- come about due to being merged with another or
- when the device completes the request.
+elevator_completed_req_fn called when a request is completed.
elevator_may_queue_fn returns true if the scheduler wants to allow the
current context to queue a new request even if
@@ -967,13 +970,33 @@ elevator_may_queue_fn returns true if the scheduler wants to allow the
elevator_set_req_fn
elevator_put_req_fn Must be used to allocate and free any elevator
- specific storate for a request.
+ specific storage for a request.
+
+elevator_activate_req_fn Called when device driver first sees a request.
+ I/O schedulers can use this callback to
+ determine when actual execution of a request
+ starts.
+elevator_deactivate_req_fn Called when device driver decides to delay
+ a request by requeueing it.
elevator_init_fn
elevator_exit_fn Allocate and free any elevator specific storage
for a queue.
-4.2 I/O scheduler implementation
+4.2 Request flows seen by I/O schedulers
+All requests seens by I/O schedulers strictly follow one of the following three
+flows.
+
+ set_req_fn ->
+
+ i. add_req_fn -> (merged_fn ->)* -> dispatch_fn -> activate_req_fn ->
+ (deactivate_req_fn -> activate_req_fn ->)* -> completed_req_fn
+ ii. add_req_fn -> (merged_fn ->)* -> merge_req_fn
+ iii. [none]
+
+ -> put_req_fn
+
+4.3 I/O scheduler implementation
The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
optimal disk scan and request servicing performance (based on generic
principles and device capabilities), optimized for:
@@ -993,18 +1016,7 @@ request in sort order to prevent binary tree lookups.
This arrangement is not a generic block layer characteristic however, so
elevators may implement queues as they please.
-ii. Last merge hint
-The last merge hint is part of the generic queue layer. I/O schedulers must do
-some management on it. For the most part, the most important thing is to make
-sure q->last_merge is cleared (set to NULL) when the request on it is no longer
-a candidate for merging (for example if it has been sent to the driver).
-
-The last merge performed is cached as a hint for the subsequent request. If
-sequential data is being submitted, the hint is used to perform merges without
-any scanning. This is not sufficient when there are multiple processes doing
-I/O though, so a "merge hash" is used by some schedulers.
-
-iii. Merge hash
+ii. Merge hash
AS and deadline use a hash table indexed by the last sector of a request. This
enables merging code to quickly look up "back merge" candidates, even when
multiple I/O streams are being performed at once on one disk.
@@ -1013,29 +1025,8 @@ multiple I/O streams are being performed at once on one disk.
are far less common than "back merges" due to the nature of most I/O patterns.
Front merges are handled by the binary trees in AS and deadline schedulers.
-iv. Handling barrier cases
-A request with flags REQ_HARDBARRIER or REQ_SOFTBARRIER must not be ordered
-around. That is, they must be processed after all older requests, and before
-any newer ones. This includes merges!
-
-In AS and deadline schedulers, barriers have the effect of flushing the reorder
-queue. The performance cost of this will vary from nothing to a lot depending
-on i/o patterns and device characteristics. Obviously they won't improve
-performance, so their use should be kept to a minimum.
-
-v. Handling insertion position directives
-A request may be inserted with a position directive. The directives are one of
-ELEVATOR_INSERT_BACK, ELEVATOR_INSERT_FRONT, ELEVATOR_INSERT_SORT.
-
-ELEVATOR_INSERT_SORT is a general directive for non-barrier requests.
-ELEVATOR_INSERT_BACK is used to insert a barrier to the back of the queue.
-ELEVATOR_INSERT_FRONT is used to insert a barrier to the front of the queue, and
-overrides the ordering requested by any previous barriers. In practice this is
-harmless and required, because it is used for SCSI requeueing. This does not
-require flushing the reorder queue, so does not impose a performance penalty.
-
-vi. Plugging the queue to batch requests in anticipation of opportunities for
- merge/sort optimizations
+iii. Plugging the queue to batch requests in anticipation of opportunities for
+ merge/sort optimizations
This is just the same as in 2.4 so far, though per-device unplugging
support is anticipated for 2.5. Also with a priority-based i/o scheduler,
@@ -1069,7 +1060,7 @@ Aside:
blk_kick_queue() to unplug a specific queue (right away ?)
or optionally, all queues, is in the plan.
-4.3 I/O contexts
+4.4 I/O contexts
I/O contexts provide a dynamically allocated per process data area. They may
be used in I/O schedulers, and in the block layer (could be used for IO statis,
priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
index c8f9a73111da..68a711fb82cf 100644
--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -17,7 +17,9 @@ This driver is known to work with the following cards:
* SA P600
* SA P800
* SA E400
- * SA E300
+ * SA P400i
+ * SA E200
+ * SA E200i
If nodes are not already created in the /dev/cciss directory, run as root:
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
new file mode 100644
index 000000000000..b7de82e9c0e0
--- /dev/null
+++ b/Documentation/connector/cn_test.c
@@ -0,0 +1,194 @@
+/*
+ * cn_test.c
+ *
+ * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ * 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. 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/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/skbuff.h>
+#include <linux/timer.h>
+
+#include "connector.h"
+
+static struct cb_id cn_test_id = { 0x123, 0x456 };
+static char cn_test_name[] = "cn_test";
+static struct sock *nls;
+static struct timer_list cn_test_timer;
+
+void cn_test_callback(void *data)
+{
+ struct cn_msg *msg = (struct cn_msg *)data;
+
+ printk("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
+ __func__, jiffies, msg->id.idx, msg->id.val,
+ msg->seq, msg->ack, msg->len, (char *)msg->data);
+}
+
+static int cn_test_want_notify(void)
+{
+ struct cn_ctl_msg *ctl;
+ struct cn_notify_req *req;
+ struct cn_msg *msg = NULL;
+ int size, size0;
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ u32 group = 1;
+
+ size0 = sizeof(*msg) + sizeof(*ctl) + 3 * sizeof(*req);
+
+ size = NLMSG_SPACE(size0);
+
+ skb = alloc_skb(size, GFP_ATOMIC);
+ if (!skb) {
+ printk(KERN_ERR "Failed to allocate new skb with size=%u.\n",
+ size);
+
+ return -ENOMEM;
+ }
+
+ nlh = NLMSG_PUT(skb, 0, 0x123, NLMSG_DONE, size - sizeof(*nlh));
+
+ msg = (struct cn_msg *)NLMSG_DATA(nlh);
+
+ memset(msg, 0, size0);
+
+ msg->id.idx = -1;
+ msg->id.val = -1;
+ msg->seq = 0x123;
+ msg->ack = 0x345;
+ msg->len = size0 - sizeof(*msg);
+
+ ctl = (struct cn_ctl_msg *)(msg + 1);
+
+ ctl->idx_notify_num = 1;
+ ctl->val_notify_num = 2;
+ ctl->group = group;
+ ctl->len = msg->len - sizeof(*ctl);
+
+ req = (struct cn_notify_req *)(ctl + 1);
+
+ /*
+ * Idx.
+ */
+ req->first = cn_test_id.idx;
+ req->range = 10;
+
+ /*
+ * Val 0.
+ */
+ req++;
+ req->first = cn_test_id.val;
+ req->range = 10;
+
+ /*
+ * Val 1.
+ */
+ req++;
+ req->first = cn_test_id.val + 20;
+ req->range = 10;
+
+ NETLINK_CB(skb).dst_groups = ctl->group;
+ //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
+ netlink_unicast(nls, skb, 0, 0);
+
+ printk(KERN_INFO "Request was sent. Group=0x%x.\n", ctl->group);
+
+ return 0;
+
+nlmsg_failure:
+ printk(KERN_ERR "Failed to send %u.%u\n", msg->seq, msg->ack);
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+static u32 cn_test_timer_counter;
+static void cn_test_timer_func(unsigned long __data)
+{
+ struct cn_msg *m;
+ char data[32];
+
+ m = kmalloc(sizeof(*m) + sizeof(data), GFP_ATOMIC);
+ if (m) {
+ memset(m, 0, sizeof(*m) + sizeof(data));
+
+ memcpy(&m->id, &cn_test_id, sizeof(m->id));
+ m->seq = cn_test_timer_counter;
+ m->len = sizeof(data);
+
+ m->len =
+ scnprintf(data, sizeof(data), "counter = %u",
+ cn_test_timer_counter) + 1;
+
+ memcpy(m + 1, data, m->len);
+
+ cn_netlink_send(m, 0, gfp_any());
+ kfree(m);
+ }
+
+ cn_test_timer_counter++;
+
+ mod_timer(&cn_test_timer, jiffies + HZ);
+}
+
+static int cn_test_init(void)
+{
+ int err;
+
+ err = cn_add_callback(&cn_test_id, cn_test_name, cn_test_callback);
+ if (err)
+ goto err_out;
+ cn_test_id.val++;
+ err = cn_add_callback(&cn_test_id, cn_test_name, cn_test_callback);
+ if (err) {
+ cn_del_callback(&cn_test_id);
+ goto err_out;
+ }
+
+ init_timer(&cn_test_timer);
+ cn_test_timer.function = cn_test_timer_func;
+ cn_test_timer.expires = jiffies + HZ;
+ cn_test_timer.data = 0;
+ add_timer(&cn_test_timer);
+
+ return 0;
+
+ err_out:
+ if (nls && nls->sk_socket)
+ sock_release(nls->sk_socket);
+
+ return err;
+}
+
+static void cn_test_fini(void)
+{
+ del_timer_sync(&cn_test_timer);
+ cn_del_callback(&cn_test_id);
+ cn_test_id.val--;
+ cn_del_callback(&cn_test_id);
+ if (nls && nls->sk_socket)
+ sock_release(nls->sk_socket);
+}
+
+module_init(cn_test_init);
+module_exit(cn_test_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
+MODULE_DESCRIPTION("Connector's test module");
diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt
new file mode 100644
index 000000000000..57a314b14cf8
--- /dev/null
+++ b/Documentation/connector/connector.txt
@@ -0,0 +1,177 @@
+/*****************************************/
+Kernel Connector.
+/*****************************************/
+
+Kernel connector - new netlink based userspace <-> kernel space easy
+to use communication module.
+
+Connector driver adds possibility to connect various agents using
+netlink based network. One must register callback and
+identifier. When driver receives special netlink message with
+appropriate identifier, appropriate callback will be called.
+
+From the userspace point of view it's quite straightforward:
+
+ socket();
+ bind();
+ send();
+ recv();
+
+But if kernelspace want to use full power of such connections, driver
+writer must create special sockets, must know about struct sk_buff
+handling... Connector allows any kernelspace agents to use netlink
+based networking for inter-process communication in a significantly
+easier way:
+
+int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
+void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);
+
+struct cb_id
+{
+ __u32 idx;
+ __u32 val;
+};
+
+idx and val are unique identifiers which must be registered in
+connector.h for in-kernel usage. void (*callback) (void *) - is a
+callback function which will be called when message with above idx.val
+will be received by connector core. Argument for that function must
+be dereferenced to struct cn_msg *.
+
+struct cn_msg
+{
+ struct cb_id id;
+
+ __u32 seq;
+ __u32 ack;
+
+ __u32 len; /* Length of the following data */
+ __u8 data[0];
+};
+
+/*****************************************/
+Connector interfaces.
+/*****************************************/
+
+int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
+
+Registers new callback with connector core.
+
+struct cb_id *id - unique connector's user identifier.
+ It must be registered in connector.h for legal in-kernel users.
+char *name - connector's callback symbolic name.
+void (*callback) (void *) - connector's callback.
+ Argument must be dereferenced to struct cn_msg *.
+
+void cn_del_callback(struct cb_id *id);
+
+Unregisters new callback with connector core.
+
+struct cb_id *id - unique connector's user identifier.
+
+void cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask);
+
+Sends message to the specified groups. It can be safely called from
+any context, but may silently fail under strong memory pressure.
+
+struct cn_msg * - message header(with attached data).
+u32 __group - destination group.
+ If __group is zero, then appropriate group will
+ be searched through all registered connector users,
+ and message will be delivered to the group which was
+ created for user with the same ID as in msg.
+ If __group is not zero, then message will be delivered
+ to the specified group.
+int gfp_mask - GFP mask.
+
+Note: When registering new callback user, connector core assigns
+netlink group to the user which is equal to it's id.idx.
+
+/*****************************************/
+Protocol description.
+/*****************************************/
+
+Current offers transport layer with fixed header. Recommended
+protocol which uses such header is following:
+
+msg->seq and msg->ack are used to determine message genealogy. When
+someone sends message it puts there locally unique sequence and random
+acknowledge numbers. Sequence number may be copied into
+nlmsghdr->nlmsg_seq too.
+
+Sequence number is incremented with each message to be sent.
+
+If we expect reply to our message, then sequence number in received
+message MUST be the same as in original message, and acknowledge
+number MUST be the same + 1.
+
+If we receive message and it's sequence number is not equal to one we
+are expecting, then it is new message. If we receive message and it's
+sequence number is the same as one we are expecting, but it's
+acknowledge is not equal acknowledge number in original message + 1,
+then it is new message.
+
+Obviously, protocol header contains above id.
+
+connector allows event notification in the following form: kernel
+driver or userspace process can ask connector to notify it when
+selected id's will be turned on or off(registered or unregistered it's
+callback). It is done by sending special command to connector
+driver(it also registers itself with id={-1, -1}).
+
+As example of usage Documentation/connector now contains cn_test.c -
+testing module which uses connector to request notification and to
+send messages.
+
+/*****************************************/
+Reliability.
+/*****************************************/
+
+Netlink itself is not reliable protocol, that means that messages can
+be lost due to memory pressure or process' receiving queue overflowed,
+so caller is warned must be prepared. That is why struct cn_msg [main
+connector's message header] contains u32 seq and u32 ack fields.
+
+/*****************************************/
+Userspace usage.
+/*****************************************/
+2.6.14 has a new netlink socket implementation, which by default does not
+allow to send data to netlink groups other than 1.
+So, if to use netlink socket (for example using connector)
+with different group number userspace application must subscribe to
+that group. It can be achieved by following pseudocode:
+
+s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+
+l_local.nl_family = AF_NETLINK;
+l_local.nl_groups = 12345;
+l_local.nl_pid = 0;
+
+if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
+ perror("bind");
+ close(s);
+ return -1;
+}
+
+{
+ int on = l_local.nl_groups;
+ setsockopt(s, 270, 1, &on, sizeof(on));
+}
+
+Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
+option. To drop multicast subscription one should call above socket option
+with NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
+
+2.6.14 netlink code only allows to select a group which is less or equal to
+the maximum group number, which is used at netlink_kernel_create() time.
+In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
+group number 12345, you must increment CN_NETLINK_USERS to that number.
+Additional 0xf numbers are allocated to be used by non-in-kernel users.
+
+Due to this limitation, group 0xffffffff does not work now, so one can
+not use add/remove connector's group notifications, but as far as I know,
+only cn_test.c test module used it.
+
+Some work in netlink area is still being done, so things can be changed in
+2.6.15 timeframe, if it will happen, documentation will be updated for that
+kernel.
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt
index e2d1e760b4ba..6a82948ff4bd 100644
--- a/Documentation/cpu-freq/cpufreq-stats.txt
+++ b/Documentation/cpu-freq/cpufreq-stats.txt
@@ -36,7 +36,7 @@ cpufreq stats provides following statistics (explained in detail below).
All the statistics will be from the time the stats driver has been inserted
to the time when a read of a particular statistic is done. Obviously, stats
-driver will not have any information about the the frequcny transitions before
+driver will not have any information about the frequency transitions before
the stats driver insertion.
--------------------------------------------------------------------------------
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 47f4114fbf54..d17b7d2dd771 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -277,7 +277,7 @@ rewritten to the 'tasks' file of its cpuset. This is done to avoid
impacting the scheduler code in the kernel with a check for changes
in a tasks processor placement.
-There is an exception to the above. If hotplug funtionality is used
+There is an exception to the above. If hotplug functionality is used
to remove all the CPUs that are currently assigned to a cpuset,
then the kernel will automatically update the cpus_allowed of all
tasks attached to CPUs in that cpuset to allow all CPUs. When memory
diff --git a/Documentation/crypto/descore-readme.txt b/Documentation/crypto/descore-readme.txt
index 166474c2ee0b..16e9e6350755 100644
--- a/Documentation/crypto/descore-readme.txt
+++ b/Documentation/crypto/descore-readme.txt
@@ -1,4 +1,4 @@
-Below is the orginal README file from the descore.shar package.
+Below is the original README file from the descore.shar package.
------------------------------------------------------------------------------
des - fast & portable DES encryption & decryption.
diff --git a/Documentation/dell_rbu.txt b/Documentation/dell_rbu.txt
index bcfa5c35036b..941343a7a265 100644
--- a/Documentation/dell_rbu.txt
+++ b/Documentation/dell_rbu.txt
@@ -13,6 +13,8 @@ the BIOS on Dell servers (starting from servers sold since 1999), desktops
and notebooks (starting from those sold in 2005).
Please go to http://support.dell.com register and you can find info on
OpenManage and Dell Update packages (DUP).
+Libsmbios can also be used to update BIOS on Dell systems go to
+http://linux.dell.com/libsmbios/ for details.
Dell_RBU driver supports BIOS update using the monilothic image and packetized
image methods. In case of moniolithic the driver allocates a contiguous chunk
@@ -22,8 +24,8 @@ would place each packet in contiguous physical memory. The driver also
maintains a link list of packets for reading them back.
If the dell_rbu driver is unloaded all the allocated memory is freed.
-The rbu driver needs to have an application which will inform the BIOS to
-enable the update in the next system reboot.
+The rbu driver needs to have an application (as mentioned above)which will
+inform the BIOS to enable the update in the next system reboot.
The user should not unload the rbu driver after downloading the BIOS image
or updating.
@@ -33,6 +35,7 @@ The driver load creates the following directories under the /sys file system.
/sys/class/firmware/dell_rbu/data
/sys/devices/platform/dell_rbu/image_type
/sys/devices/platform/dell_rbu/data
+/sys/devices/platform/dell_rbu/packet_size
The driver supports two types of update mechanism; monolithic and packetized.
These update mechanism depends upon the BIOS currently running on the system.
@@ -42,10 +45,30 @@ In case of packet mechanism the single memory can be broken in smaller chuks
of contiguous memory and the BIOS image is scattered in these packets.
By default the driver uses monolithic memory for the update type. This can be
-changed to contiguous during the driver load time by specifying the load
+changed to packets during the driver load time by specifying the load
parameter image_type=packet. This can also be changed later as below
echo packet > /sys/devices/platform/dell_rbu/image_type
+In packet update mode the packet size has to be given before any packets can
+be downloaded. It is done as below
+echo XXXX > /sys/devices/platform/dell_rbu/packet_size
+In the packet update mechanism, the user neesd to create a new file having
+packets of data arranged back to back. It can be done as follows
+The user creates packets header, gets the chunk of the BIOS image and
+placs it next to the packetheader; now, the packetheader + BIOS image chunk
+added to geather should match the specified packet_size. This makes one
+packet, the user needs to create more such packets out of the entire BIOS
+image file and then arrange all these packets back to back in to one single
+file.
+This file is then copied to /sys/class/firmware/dell_rbu/data.
+Once this file gets to the driver, the driver extracts packet_size data from
+the file and spreads it accross the physical memory in contiguous packet_sized
+space.
+This method makes sure that all the packets get to the driver in a single operation.
+
+In monolithic update the user simply get the BIOS image (.hdr file) and copies
+to the data file as is without any change to the BIOS image itself.
+
Do the steps below to download the BIOS image.
1) echo 1 > /sys/class/firmware/dell_rbu/loading
2) cp bios_image.hdr /sys/class/firmware/dell_rbu/data
@@ -53,20 +76,23 @@ Do the steps below to download the BIOS image.
The /sys/class/firmware/dell_rbu/ entries will remain till the following is
done.
-echo -1 > /sys/class/firmware/dell_rbu/loading
+echo -1 > /sys/class/firmware/dell_rbu/loading.
+Until this step is completed the driver cannot be unloaded.
+Also echoing either mono ,packet or init in to image_type will free up the
+memory allocated by the driver.
-Until this step is completed the drivr cannot be unloaded.
+If an user by accident executes steps 1 and 3 above without executing step 2;
+it will make the /sys/class/firmware/dell_rbu/ entries to disappear.
+The entries can be recreated by doing the following
+echo init > /sys/devices/platform/dell_rbu/image_type
+NOTE: echoing init in image_type does not change it original value.
Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to
-read back the image downloaded. This is useful in case of packet update
-mechanism where the above steps 1,2,3 will repeated for every packet.
-By reading the /sys/devices/platform/dell_rbu/data file all packet data
-downloaded can be verified in a single file.
-The packets are arranged in this file one after the other in a FIFO order.
+read back the image downloaded.
NOTE:
-This driver requires a patch for firmware_class.c which has the addition
-of request_firmware_nowait_nohotplug function to wortk
+This driver requires a patch for firmware_class.c which has the modified
+request_firmware_nowait function.
Also after updating the BIOS image an user mdoe application neeeds to execute
code which message the BIOS update request to the BIOS. So on the next reboot
the BIOS knows about the new image downloaded and it updates it self.
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt
new file mode 100644
index 000000000000..dca274ff4005
--- /dev/null
+++ b/Documentation/device-mapper/snapshot.txt
@@ -0,0 +1,73 @@
+Device-mapper snapshot support
+==============================
+
+Device-mapper allows you, without massive data copying:
+
+*) To create snapshots of any block device i.e. mountable, saved states of
+the block device which are also writable without interfering with the
+original content;
+*) To create device "forks", i.e. multiple different versions of the
+same data stream.
+
+
+In both cases, dm copies only the chunks of data that get changed and
+uses a separate copy-on-write (COW) block device for storage.
+
+
+There are two dm targets available: snapshot and snapshot-origin.
+
+*) snapshot-origin <origin>
+
+which will normally have one or more snapshots based on it.
+You must create the snapshot-origin device before you can create snapshots.
+Reads will be mapped directly to the backing device. For each write, the
+original data will be saved in the <COW device> of each snapshot to keep
+its visible content unchanged, at least until the <COW device> fills up.
+
+
+*) snapshot <origin> <COW device> <persistent?> <chunksize>
+
+A snapshot is created of the <origin> block device. Changed chunks of
+<chunksize> sectors will be stored on the <COW device>. Writes will
+only go to the <COW device>. Reads will come from the <COW device> or
+from <origin> for unchanged data. <COW device> will often be
+smaller than the origin and if it fills up the snapshot will become
+useless and be disabled, returning errors. So it is important to monitor
+the amount of free space and expand the <COW device> before it fills up.
+
+<persistent?> is P (Persistent) or N (Not persistent - will not survive
+after reboot).
+
+
+How this is used by LVM2
+========================
+When you create the first LVM2 snapshot of a volume, four dm devices are used:
+
+1) a device containing the original mapping table of the source volume;
+2) a device used as the <COW device>;
+3) a "snapshot" device, combining #1 and #2, which is the visible snapshot
+ volume;
+4) the "original" volume (which uses the device number used by the original
+ source volume), whose table is replaced by a "snapshot-origin" mapping
+ from device #1.
+
+A fixed naming scheme is used, so with the following commands:
+
+lvcreate -L 1G -n base volumeGroup
+lvcreate -L 100M --snapshot -n snap volumeGroup/base
+
+we'll have this situation (with volumes in above order):
+
+# dmsetup table|grep volumeGroup
+
+volumeGroup-base-real: 0 2097152 linear 8:19 384
+volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
+volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
+volumeGroup-base: 0 2097152 snapshot-origin 254:11
+
+# ls -lL /dev/mapper/volumeGroup-*
+brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
+brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
+brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
+brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
+
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 96bea278bbf6..24adfe9af3ca 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -55,6 +55,7 @@ aic7*seq.h*
aicasm
aicdb.h*
asm
+asm-offsets.*
asm_offsets.*
autoconf.h*
bbootsect
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index 4b8c326c6aac..cb63b7a93c82 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,55 +1,74 @@
-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 62e0701b542a..95f0e73b2135 100644
--- a/Documentation/dvb/ci.txt
+++ b/Documentation/dvb/ci.txt
@@ -23,7 +23,6 @@ This application requires the following to function properly as of now.
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 000000000000..f90cc66ea919
--- /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 000000000000..0eb3b443dc2b
--- /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 000000000000..bb1aac048425
--- /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 000000000000..cf4351fc32ff
--- /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 000000000000..eb4e47a9cea6
--- /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 000000000000..80fb2f89b6c1
--- /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 000000000000..e627c8f54211
--- /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 000000000000..a123bc11e698
--- /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/intel810.txt b/Documentation/fb/intel810.txt
index fd68b162e4a1..4f0d6bc789ef 100644
--- a/Documentation/fb/intel810.txt
+++ b/Documentation/fb/intel810.txt
@@ -5,6 +5,7 @@ Intel 810/815 Framebuffer driver
March 17, 2002
First Released: July 2001
+ Last Update: September 12, 2005
================================================================
A. Introduction
@@ -44,6 +45,8 @@ B. Features
- Hardware Cursor Support
+ - Supports EDID probing either by DDC/I2C or through the BIOS
+
C. List of available options
a. "video=i810fb"
@@ -52,14 +55,17 @@ C. List of available options
Recommendation: required
b. "xres:<value>"
- select horizontal resolution in pixels
+ select horizontal resolution in pixels. (This parameter will be
+ ignored if 'mode_option' is specified. See 'o' below).
Recommendation: user preference
(default = 640)
c. "yres:<value>"
select vertical resolution in scanlines. If Discrete Video Timings
- is enabled, this will be ignored and computed as 3*xres/4.
+ is enabled, this will be ignored and computed as 3*xres/4. (This
+ parameter will be ignored if 'mode_option' is specified. See 'o'
+ below)
Recommendation: user preference
(default = 480)
@@ -86,7 +92,8 @@ C. List of available options
g. "hsync1/hsync2:<value>"
select the minimum and maximum Horizontal Sync Frequency of the
monitor in KHz. If a using a fixed frequency monitor, hsync1 must
- be equal to hsync2.
+ be equal to hsync2. If EDID probing is successful, these will be
+ ignored and values will be taken from the EDID block.
Recommendation: check monitor manual for correct values
default (29/30)
@@ -94,7 +101,8 @@ C. List of available options
h. "vsync1/vsync2:<value>"
select the minimum and maximum Vertical Sync Frequency of the monitor
in Hz. You can also use this option to lock your monitor's refresh
- rate.
+ rate. If EDID probing is successful, these will be ignored and values
+ will be taken from the EDID block.
Recommendation: check monitor manual for correct values
(default = 60/60)
@@ -154,7 +162,11 @@ C. List of available options
Recommendation: do not set
(default = not set)
-
+ o. <xres>x<yres>[-<bpp>][@<refresh>]
+ The driver will now accept specification of boot mode option. If this
+ is specified, the options 'xres' and 'yres' will be ignored. See
+ Documentation/fb/modedb.txt for usage.
+
D. Kernel booting
Separate each option/option-pair by commas (,) and the option from its value
@@ -176,7 +188,10 @@ will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.
IMPORTANT:
You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes
-better than 640x480 at 60Hz.
+better than 640x480 at 60Hz. HOWEVER, if your chipset/display combination
+supports I2C and has an EDID block, you can safely exclude hsync1, hsync2,
+vsync1 and vsync2 parameters. These parameters will be taken from the EDID
+block.
E. Module options
@@ -217,32 +232,21 @@ F. Setup
This is required. The option is under "Character Devices"
d. Under "Graphics Support", select "Intel 810/815" either statically
- or as a module. Choose "use VESA GTF for video timings" if you
- need to maximize the capability of your display. To be on the
+ or as a module. Choose "use VESA Generalized Timing Formula" if
+ you need to maximize the capability of your display. To be on the
safe side, you can leave this unselected.
- e. If you want a framebuffer console, enable it under "Console
+ e. If you want support for DDC/I2C probing (Plug and Play Displays),
+ set 'Enable DDC Support' to 'y'. To make this option appear, set
+ 'use VESA Generalized Timing Formula' to 'y'.
+
+ f. If you want a framebuffer console, enable it under "Console
Drivers"
- f. Compile your kernel.
+ g. Compile your kernel.
- g. Load the driver as described in section D and E.
+ h. Load the driver as described in section D and E.
- Optional:
- h. If you are going to run XFree86 with its native drivers, the
- standard XFree86 4.1.0 and 4.2.0 drivers should work as is.
- However, there's a bug in the XFree86 i810 drivers. It attempts
- to use XAA even when switched to the console. This will crash
- your server. I have a fix at this site:
-
- http://i810fb.sourceforge.net.
-
- You can either use the patch, or just replace
-
- /usr/X11R6/lib/modules/drivers/i810_drv.o
-
- with the one provided at the website.
-
i. Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver
patch to see the chipset in action (or inaction :-).
diff --git a/Documentation/fb/modedb.txt b/Documentation/fb/modedb.txt
index e04458b319d5..4fcdb4cf4cca 100644
--- a/Documentation/fb/modedb.txt
+++ b/Documentation/fb/modedb.txt
@@ -20,12 +20,83 @@ in a video= option, fbmem considers that to be a global video mode option.
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 2e0a01b21fe0..b67189a8d8d4 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -17,32 +17,6 @@ Who: Greg Kroah-Hartman <greg@kroah.com>
---------------------------
-What: ACPI S4bios support
-When: May 2005
-Why: Noone uses it, and it probably does not work, anyway. swsusp is
- faster, more reliable, and people are actually using it.
-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
- addressabilty (by using a pfn) and supports sparc & sparc64
- iospace as part of the pfn.
-Who: Randy Dunlap <rddunlap@osdl.org>
-
----------------------------
-
What: RAW driver (CONFIG_RAW_DRIVER)
When: December 2005
Why: declared obsolete since kernel 2.6.3
diff --git a/Documentation/filesystems/files.txt b/Documentation/filesystems/files.txt
new file mode 100644
index 000000000000..8c206f4e0250
--- /dev/null
+++ b/Documentation/filesystems/files.txt
@@ -0,0 +1,123 @@
+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 000000000000..6b5741e651a2
--- /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 eef4aca0c753..a5fbc8e897fa 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 5024ba7a592c..d4773565ea2f 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/relayfs.txt b/Documentation/filesystems/relayfs.txt
index d24e1b0d4f39..d803abed29f0 100644
--- a/Documentation/filesystems/relayfs.txt
+++ b/Documentation/filesystems/relayfs.txt
@@ -15,7 +15,7 @@ retrieve the data as it becomes available.
The format of the data logged into the channel buffers is completely
up to the relayfs client; relayfs does however provide hooks which
-allow clients to impose some stucture on the buffer data. Nor does
+allow clients to impose some structure on the buffer data. Nor does
relayfs implement any form of data filtering - this also is left to
the client. The purpose is to keep relayfs as simple as possible.
diff --git a/Documentation/filesystems/v9fs.txt b/Documentation/filesystems/v9fs.txt
new file mode 100644
index 000000000000..4e92feb6b507
--- /dev/null
+++ b/Documentation/filesystems/v9fs.txt
@@ -0,0 +1,95 @@
+ 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 3f318dd44c77..f042c12e0ed2 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/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c
index e1c56a7e6583..4bef8c25172c 100644
--- a/Documentation/firmware_class/firmware_sample_driver.c
+++ b/Documentation/firmware_class/firmware_sample_driver.c
@@ -32,14 +32,14 @@ static void sample_firmware_load(char *firmware, int size)
u8 buf[size+1];
memcpy(buf, firmware, size);
buf[size] = '\0';
- printk("firmware_sample_driver: firmware: %s\n", buf);
+ printk(KERN_INFO "firmware_sample_driver: firmware: %s\n", buf);
}
static void sample_probe_default(void)
{
/* uses the default method to get the firmware */
const struct firmware *fw_entry;
- printk("firmware_sample_driver: a ghost device got inserted :)\n");
+ printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0)
{
@@ -61,7 +61,7 @@ static void sample_probe_specific(void)
/* NOTE: This currently doesn't work */
- printk("firmware_sample_driver: a ghost device got inserted :)\n");
+ printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0)
{
@@ -83,7 +83,7 @@ static void sample_probe_async_cont(const struct firmware *fw, void *context)
return;
}
- printk("firmware_sample_driver: device pointer \"%s\"\n",
+ printk(KERN_INFO "firmware_sample_driver: device pointer \"%s\"\n",
(char *)context);
sample_firmware_load(fw->data, fw->size);
}
diff --git a/Documentation/ia64/mca.txt b/Documentation/ia64/mca.txt
new file mode 100644
index 000000000000..a71cc6a67ef7
--- /dev/null
+++ b/Documentation/ia64/mca.txt
@@ -0,0 +1,194 @@
+An ad-hoc collection of notes on IA64 MCA and INIT processing. Feel
+free to update it with notes about any area that is not clear.
+
+---
+
+MCA/INIT are completely asynchronous. They can occur at any time, when
+the OS is in any state. Including when one of the cpus is already
+holding a spinlock. Trying to get any lock from MCA/INIT state is
+asking for deadlock. Also the state of structures that are protected
+by locks is indeterminate, including linked lists.
+
+---
+
+The complicated ia64 MCA process. All of this is mandated by Intel's
+specification for ia64 SAL, error recovery and and unwind, it is not as
+if we have a choice here.
+
+* MCA occurs on one cpu, usually due to a double bit memory error.
+ This is the monarch cpu.
+
+* SAL sends an MCA rendezvous interrupt (which is a normal interrupt)
+ to all the other cpus, the slaves.
+
+* Slave cpus that receive the MCA interrupt call down into SAL, they
+ end up spinning disabled while the MCA is being serviced.
+
+* If any slave cpu was already spinning disabled when the MCA occurred
+ then it cannot service the MCA interrupt. SAL waits ~20 seconds then
+ sends an unmaskable INIT event to the slave cpus that have not
+ already rendezvoused.
+
+* Because MCA/INIT can be delivered at any time, including when the cpu
+ is down in PAL in physical mode, the registers at the time of the
+ event are _completely_ undefined. In particular the MCA/INIT
+ handlers cannot rely on the thread pointer, PAL physical mode can
+ (and does) modify TP. It is allowed to do that as long as it resets
+ TP on return. However MCA/INIT events expose us to these PAL
+ internal TP changes. Hence curr_task().
+
+* If an MCA/INIT event occurs while the kernel was running (not user
+ space) and the kernel has called PAL then the MCA/INIT handler cannot
+ assume that the kernel stack is in a fit state to be used. Mainly
+ because PAL may or may not maintain the stack pointer internally.
+ Because the MCA/INIT handlers cannot trust the kernel stack, they
+ have to use their own, per-cpu stacks. The MCA/INIT stacks are
+ preformatted with just enough task state to let the relevant handlers
+ do their job.
+
+* Unlike most other architectures, the ia64 struct task is embedded in
+ the kernel stack[1]. So switching to a new kernel stack means that
+ we switch to a new task as well. Because various bits of the kernel
+ assume that current points into the struct task, switching to a new
+ stack also means a new value for current.
+
+* Once all slaves have rendezvoused and are spinning disabled, the
+ monarch is entered. The monarch now tries to diagnose the problem
+ and decide if it can recover or not.
+
+* Part of the monarch's job is to look at the state of all the other
+ tasks. The only way to do that on ia64 is to call the unwinder,
+ as mandated by Intel.
+
+* The starting point for the unwind depends on whether a task is
+ running or not. That is, whether it is on a cpu or is blocked. The
+ monarch has to determine whether or not a task is on a cpu before it
+ knows how to start unwinding it. The tasks that received an MCA or
+ INIT event are no longer running, they have been converted to blocked
+ tasks. But (and its a big but), the cpus that received the MCA
+ rendezvous interrupt are still running on their normal kernel stacks!
+
+* To distinguish between these two cases, the monarch must know which
+ tasks are on a cpu and which are not. Hence each slave cpu that
+ switches to an MCA/INIT stack, registers its new stack using
+ set_curr_task(), so the monarch can tell that the _original_ task is
+ no longer running on that cpu. That gives us a decent chance of
+ getting a valid backtrace of the _original_ task.
+
+* MCA/INIT can be nested, to a depth of 2 on any cpu. In the case of a
+ nested error, we want diagnostics on the MCA/INIT handler that
+ failed, not on the task that was originally running. Again this
+ requires set_curr_task() so the MCA/INIT handlers can register their
+ own stack as running on that cpu. Then a recursive error gets a
+ trace of the failing handler's "task".
+
+[1] My (Keith Owens) original design called for ia64 to separate its
+ struct task and the kernel stacks. Then the MCA/INIT data would be
+ chained stacks like i386 interrupt stacks. But that required
+ radical surgery on the rest of ia64, plus extra hard wired TLB
+ entries with its associated performance degradation. David
+ Mosberger vetoed that approach. Which meant that separate kernel
+ stacks meant separate "tasks" for the MCA/INIT handlers.
+
+---
+
+INIT is less complicated than MCA. Pressing the nmi button or using
+the equivalent command on the management console sends INIT to all
+cpus. SAL picks one one of the cpus as the monarch and the rest are
+slaves. All the OS INIT handlers are entered at approximately the same
+time. The OS monarch prints the state of all tasks and returns, after
+which the slaves return and the system resumes.
+
+At least that is what is supposed to happen. Alas there are broken
+versions of SAL out there. Some drive all the cpus as monarchs. Some
+drive them all as slaves. Some drive one cpu as monarch, wait for that
+cpu to return from the OS then drive the rest as slaves. Some versions
+of SAL cannot even cope with returning from the OS, they spin inside
+SAL on resume. The OS INIT code has workarounds for some of these
+broken SAL symptoms, but some simply cannot be fixed from the OS side.
+
+---
+
+The scheduler hooks used by ia64 (curr_task, set_curr_task) are layer
+violations. Unfortunately MCA/INIT start off as massive layer
+violations (can occur at _any_ time) and they build from there.
+
+At least ia64 makes an attempt at recovering from hardware errors, but
+it is a difficult problem because of the asynchronous nature of these
+errors. When processing an unmaskable interrupt we sometimes need
+special code to cope with our inability to take any locks.
+
+---
+
+How is ia64 MCA/INIT different from x86 NMI?
+
+* x86 NMI typically gets delivered to one cpu. MCA/INIT gets sent to
+ all cpus.
+
+* x86 NMI cannot be nested. MCA/INIT can be nested, to a depth of 2
+ per cpu.
+
+* x86 has a separate struct task which points to one of multiple kernel
+ stacks. ia64 has the struct task embedded in the single kernel
+ stack, so switching stack means switching task.
+
+* x86 does not call the BIOS so the NMI handler does not have to worry
+ about any registers having changed. MCA/INIT can occur while the cpu
+ is in PAL in physical mode, with undefined registers and an undefined
+ kernel stack.
+
+* i386 backtrace is not very sensitive to whether a process is running
+ or not. ia64 unwind is very, very sensitive to whether a process is
+ running or not.
+
+---
+
+What happens when MCA/INIT is delivered what a cpu is running user
+space code?
+
+The user mode registers are stored in the RSE area of the MCA/INIT on
+entry to the OS and are restored from there on return to SAL, so user
+mode registers are preserved across a recoverable MCA/INIT. Since the
+OS has no idea what unwind data is available for the user space stack,
+MCA/INIT never tries to backtrace user space. Which means that the OS
+does not bother making the user space process look like a blocked task,
+i.e. the OS does not copy pt_regs and switch_stack to the user space
+stack. Also the OS has no idea how big the user space RSE and memory
+stacks are, which makes it too risky to copy the saved state to a user
+mode stack.
+
+---
+
+How do we get a backtrace on the tasks that were running when MCA/INIT
+was delivered?
+
+mca.c:::ia64_mca_modify_original_stack(). That identifies and
+verifies the original kernel stack, copies the dirty registers from
+the MCA/INIT stack's RSE to the original stack's RSE, copies the
+skeleton struct pt_regs and switch_stack to the original stack, fills
+in the skeleton structures from the PAL minstate area and updates the
+original stack's thread.ksp. That makes the original stack look
+exactly like any other blocked task, i.e. it now appears to be
+sleeping. To get a backtrace, just start with thread.ksp for the
+original task and unwind like any other sleeping task.
+
+---
+
+How do we identify the tasks that were running when MCA/INIT was
+delivered?
+
+If the previous task has been verified and converted to a blocked
+state, then sos->prev_task on the MCA/INIT stack is updated to point to
+the previous task. You can look at that field in dumps or debuggers.
+To help distinguish between the handler and the original tasks,
+handlers have _TIF_MCA_INIT set in thread_info.flags.
+
+The sos data is always in the MCA/INIT handler stack, at offset
+MCA_SOS_OFFSET. You can get that value from mca_asm.h or calculate it
+as KERNEL_STACK_SIZE - sizeof(struct pt_regs) - sizeof(struct
+ia64_sal_os_state), with 16 byte alignment for all structures.
+
+Also the comm field of the MCA/INIT task is modified to include the pid
+of the original task, for humans to use. For example, a comm field of
+'MCA 12159' means that pid 12159 was running when the MCA was
+delivered.
diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index c437b1aeff55..8b3fd82b2ce7 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -1,16 +1,16 @@
IBM ThinkPad ACPI Extras Driver
- Version 0.8
- 8 November 2004
+ Version 0.12
+ 17 August 2005
Borislav Deianov <borislav@users.sf.net>
http://ibm-acpi.sf.net/
-This is a Linux ACPI driver for the IBM ThinkPad laptops. It aims to
-support various features of these laptops which are accessible through
-the ACPI framework but not otherwise supported by the generic Linux
-ACPI drivers.
+This is a Linux ACPI driver for the IBM ThinkPad laptops. It supports
+various features of these laptops which are accessible through the
+ACPI framework but not otherwise supported by the generic Linux ACPI
+drivers.
Status
@@ -25,9 +25,14 @@ detailed description):
- ThinkLight on and off
- limited docking and undocking
- UltraBay eject
- - Experimental: CMOS control
- - Experimental: LED control
- - Experimental: ACPI sounds
+ - CMOS control
+ - LED control
+ - ACPI sounds
+ - temperature sensors
+ - Experimental: embedded controller register dump
+ - Experimental: LCD brightness control
+ - Experimental: volume control
+ - Experimental: fan speed, fan enable/disable
A compatibility table by model and feature is maintained on the web
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -91,12 +96,12 @@ driver is still in the alpha stage, the exact proc file format and
commands supported by the various features is guaranteed to change
frequently.
-Driver Version -- /proc/acpi/ibm/driver
---------------------------------------
+Driver version -- /proc/acpi/ibm/driver
+---------------------------------------
The driver name and version. No commands can be written to this file.
-Hot Keys -- /proc/acpi/ibm/hotkey
+Hot keys -- /proc/acpi/ibm/hotkey
---------------------------------
Without this driver, only the Fn-F4 key (sleep button) generates an
@@ -188,7 +193,7 @@ and, on the X40, video corruption. By disabling automatic switching,
the flickering or video corruption can be avoided.
The video_switch command cycles through the available video outputs
-(it sumulates the behavior of Fn-F7).
+(it simulates the behavior of Fn-F7).
Video expansion can be toggled through this feature. This controls
whether the display is expanded to fill the entire LCD screen when a
@@ -201,6 +206,12 @@ Fn-F7 from working. This also disables the video output switching
features of this driver, as it uses the same ACPI methods as
Fn-F7. Video switching on the console should still work.
+UPDATE: There's now a patch for the X.org Radeon driver which
+addresses this issue. Some people are reporting success with the patch
+while others are still having problems. For more information:
+
+https://bugs.freedesktop.org/show_bug.cgi?id=2000
+
ThinkLight control -- /proc/acpi/ibm/light
------------------------------------------
@@ -211,7 +222,7 @@ models which do not make the status available will show it as
echo on > /proc/acpi/ibm/light
echo off > /proc/acpi/ibm/light
-Docking / Undocking -- /proc/acpi/ibm/dock
+Docking / undocking -- /proc/acpi/ibm/dock
------------------------------------------
Docking and undocking (e.g. with the X4 UltraBase) requires some
@@ -228,11 +239,15 @@ NOTE: These events will only be generated if the laptop was docked
when originally booted. This is due to the current lack of support for
hot plugging of devices in the Linux ACPI framework. If the laptop was
booted while not in the dock, the following message is shown in the
-logs: "ibm_acpi: dock device not present". No dock-related events are
-generated but the dock and undock commands described below still
-work. They can be executed manually or triggered by Fn key
-combinations (see the example acpid configuration files included in
-the driver tarball package available on the web site).
+logs:
+
+ Mar 17 01:42:34 aero kernel: ibm_acpi: dock device not present
+
+In this case, no dock-related events are generated but the dock and
+undock commands described below still work. They can be executed
+manually or triggered by Fn key combinations (see the example acpid
+configuration files included in the driver tarball package available
+on the web site).
When the eject request button on the dock is pressed, the first event
above is generated. The handler for this event should issue the
@@ -267,7 +282,7 @@ the only docking stations currently supported are the X-series
UltraBase docks and "dumb" port replicators like the Mini Dock (the
latter don't need any ACPI support, actually).
-UltraBay Eject -- /proc/acpi/ibm/bay
+UltraBay eject -- /proc/acpi/ibm/bay
------------------------------------
Inserting or ejecting an UltraBay device requires some actions to be
@@ -284,8 +299,11 @@ when the laptop was originally booted (on the X series, the UltraBay
is in the dock, so it may not be present if the laptop was undocked).
This is due to the current lack of support for hot plugging of devices
in the Linux ACPI framework. If the laptop was booted without the
-UltraBay, the following message is shown in the logs: "ibm_acpi: bay
-device not present". No bay-related events are generated but the eject
+UltraBay, the following message is shown in the logs:
+
+ Mar 17 01:42:34 aero kernel: ibm_acpi: bay device not present
+
+In this case, no bay-related events are generated but the eject
command described below still works. It can be executed manually or
triggered by a hot key combination.
@@ -306,22 +324,33 @@ necessary to enable the UltraBay device (e.g. call idectl).
The contents of the /proc/acpi/ibm/bay file shows the current status
of the UltraBay, as provided by the ACPI framework.
-Experimental Features
----------------------
+EXPERIMENTAL warm eject support on the 600e/x, A22p and A3x (To use
+this feature, you need to supply the experimental=1 parameter when
+loading the module):
+
+These models do not have a button near the UltraBay device to request
+a hot eject but rather require the laptop to be put to sleep
+(suspend-to-ram) before the bay device is ejected or inserted).
+The sequence of steps to eject the device is as follows:
+
+ echo eject > /proc/acpi/ibm/bay
+ put the ThinkPad to sleep
+ remove the drive
+ resume from sleep
+ cat /proc/acpi/ibm/bay should show that the drive was removed
+
+On the A3x, both the UltraBay 2000 and UltraBay Plus devices are
+supported. Use "eject2" instead of "eject" for the second bay.
-The following features are marked experimental because using them
-involves guessing the correct values of some parameters. Guessing
-incorrectly may have undesirable effects like crashing your
-ThinkPad. USE THESE WITH CAUTION! To activate them, you'll need to
-supply the experimental=1 parameter when loading the module.
+Note: the UltraBay eject support on the 600e/x, A22p and A3x is
+EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
-Experimental: CMOS control - /proc/acpi/ibm/cmos
-------------------------------------------------
+CMOS control -- /proc/acpi/ibm/cmos
+-----------------------------------
This feature is used internally by the ACPI firmware to control the
-ThinkLight on most newer ThinkPad models. It appears that it can also
-control LCD brightness, sounds volume and more, but only on some
-models.
+ThinkLight on most newer ThinkPad models. It may also control LCD
+brightness, sounds volume and more, but only on some models.
The commands are non-negative integer numbers:
@@ -330,10 +359,9 @@ The commands are non-negative integer numbers:
echo 2 >/proc/acpi/ibm/cmos
...
-The range of numbers which are used internally by various models is 0
-to 21, but it's possible that numbers outside this range have
-interesting behavior. Here is the behavior on the X40 (tpb is the
-ThinkPad Buttons utility):
+The range of valid numbers is 0 to 21, but not all have an effect and
+the behavior varies from model to model. Here is the behavior on the
+X40 (tpb is the ThinkPad Buttons utility):
0 - no effect but tpb reports "Volume down"
1 - no effect but tpb reports "Volume up"
@@ -346,26 +374,18 @@ ThinkPad Buttons utility):
13 - ThinkLight off
14 - no effect but tpb reports ThinkLight status change
-If you try this feature, please send me a report similar to the
-above. On models which allow control of LCD brightness or sound
-volume, I'd like to provide this functionality in an user-friendly
-way, but first I need a way to identify the models which this is
-possible.
-
-Experimental: LED control - /proc/acpi/ibm/LED
-----------------------------------------------
+LED control -- /proc/acpi/ibm/led
+---------------------------------
Some of the LED indicators can be controlled through this feature. The
available commands are:
- echo <led number> on >/proc/acpi/ibm/led
- echo <led number> off >/proc/acpi/ibm/led
- echo <led number> blink >/proc/acpi/ibm/led
+ echo '<led number> on' >/proc/acpi/ibm/led
+ echo '<led number> off' >/proc/acpi/ibm/led
+ echo '<led number> blink' >/proc/acpi/ibm/led
-The <led number> parameter is a non-negative integer. The range of LED
-numbers used internally by various models is 0 to 7 but it's possible
-that numbers outside this range are also valid. Here is the mapping on
-the X40:
+The <led number> range is 0 to 7. The set of LEDs that can be
+controlled varies from model to model. Here is the mapping on the X40:
0 - power
1 - battery (orange)
@@ -376,49 +396,224 @@ the X40:
All of the above can be turned on and off and can be made to blink.
-If you try this feature, please send me a report similar to the
-above. I'd like to provide this functionality in an user-friendly way,
-but first I need to identify the which numbers correspond to which
-LEDs on various models.
-
-Experimental: ACPI sounds - /proc/acpi/ibm/beep
------------------------------------------------
+ACPI sounds -- /proc/acpi/ibm/beep
+----------------------------------
The BEEP method is used internally by the ACPI firmware to provide
-audible alerts in various situtation. This feature allows the same
+audible alerts in various situations. This feature allows the same
sounds to be triggered manually.
The commands are non-negative integer numbers:
- echo 0 >/proc/acpi/ibm/beep
- echo 1 >/proc/acpi/ibm/beep
- echo 2 >/proc/acpi/ibm/beep
- ...
+ echo <number> >/proc/acpi/ibm/beep
-The range of numbers which are used internally by various models is 0
-to 17, but it's possible that numbers outside this range are also
-valid. Here is the behavior on the X40:
+The valid <number> range is 0 to 17. Not all numbers trigger sounds
+and the sounds vary from model to model. Here is the behavior on the
+X40:
- 2 - two beeps, pause, third beep
+ 0 - stop a sound in progress (but use 17 to stop 16)
+ 2 - two beeps, pause, third beep ("low battery")
3 - single beep
- 4 - "unable"
+ 4 - high, followed by low-pitched beep ("unable")
5 - single beep
- 6 - "AC/DC"
+ 6 - very high, followed by high-pitched beep ("AC/DC")
7 - high-pitched beep
9 - three short beeps
10 - very long beep
12 - low-pitched beep
+ 15 - three high-pitched beeps repeating constantly, stop with 0
+ 16 - one medium-pitched beep repeating constantly, stop with 17
+ 17 - stop 16
+
+Temperature sensors -- /proc/acpi/ibm/thermal
+---------------------------------------------
+
+Most ThinkPads include six or more separate temperature sensors but
+only expose the CPU temperature through the standard ACPI methods.
+This feature shows readings from up to eight different sensors. Some
+readings may not be valid, e.g. may show large negative values. For
+example, on the X40, a typical output may be:
+
+temperatures: 42 42 45 41 36 -128 33 -128
+
+Thomas Gruber took his R51 apart and traced all six active sensors in
+his laptop (the location of sensors may vary on other models):
+
+1: CPU
+2: Mini PCI Module
+3: HDD
+4: GPU
+5: Battery
+6: N/A
+7: Battery
+8: N/A
+
+No commands can be written to this file.
+
+EXPERIMENTAL: Embedded controller reigster dump -- /proc/acpi/ibm/ecdump
+------------------------------------------------------------------------
+
+This feature is marked EXPERIMENTAL because the implementation
+directly accesses hardware registers and may not work as expected. USE
+WITH CAUTION! To use this feature, you need to supply the
+experimental=1 parameter when loading the module.
+
+This feature dumps the values of 256 embedded controller
+registers. Values which have changed since the last time the registers
+were dumped are marked with a star:
+
+[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
+EC +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f
+EC 0x00: a7 47 87 01 fe 96 00 08 01 00 cb 00 00 00 40 00
+EC 0x10: 00 00 ff ff f4 3c 87 09 01 ff 42 01 ff ff 0d 00
+EC 0x20: 00 00 00 00 00 00 00 00 00 00 00 03 43 00 00 80
+EC 0x30: 01 07 1a 00 30 04 00 00 *85 00 00 10 00 50 00 00
+EC 0x40: 00 00 00 00 00 00 14 01 00 04 00 00 00 00 00 00
+EC 0x50: 00 c0 02 0d 00 01 01 02 02 03 03 03 03 *bc *02 *bc
+EC 0x60: *02 *bc *02 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0x70: 00 00 00 00 00 12 30 40 *24 *26 *2c *27 *20 80 *1f 80
+EC 0x80: 00 00 00 06 *37 *0e 03 00 00 00 0e 07 00 00 00 00
+EC 0x90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xa0: *ff 09 ff 09 ff ff *64 00 *00 *00 *a2 41 *ff *ff *e0 00
+EC 0xb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xd0: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xe0: 00 00 00 00 00 00 00 00 11 20 49 04 24 06 55 03
+EC 0xf0: 31 55 48 54 35 38 57 57 08 2f 45 73 07 65 6c 1a
+
+This feature can be used to determine the register holding the fan
+speed on some models. To do that, do the following:
+
+ - make sure the battery is fully charged
+ - make sure the fan is running
+ - run 'cat /proc/acpi/ibm/ecdump' several times, once per second or so
+
+The first step makes sure various charging-related values don't
+vary. The second ensures that the fan-related values do vary, since
+the fan speed fluctuates a bit. The third will (hopefully) mark the
+fan register with a star:
+
+[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
+EC +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f
+EC 0x00: a7 47 87 01 fe 96 00 08 01 00 cb 00 00 00 40 00
+EC 0x10: 00 00 ff ff f4 3c 87 09 01 ff 42 01 ff ff 0d 00
+EC 0x20: 00 00 00 00 00 00 00 00 00 00 00 03 43 00 00 80
+EC 0x30: 01 07 1a 00 30 04 00 00 85 00 00 10 00 50 00 00
+EC 0x40: 00 00 00 00 00 00 14 01 00 04 00 00 00 00 00 00
+EC 0x50: 00 c0 02 0d 00 01 01 02 02 03 03 03 03 bc 02 bc
+EC 0x60: 02 bc 02 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0x70: 00 00 00 00 00 12 30 40 24 27 2c 27 21 80 1f 80
+EC 0x80: 00 00 00 06 *be 0d 03 00 00 00 0e 07 00 00 00 00
+EC 0x90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xa0: ff 09 ff 09 ff ff 64 00 00 00 a2 41 ff ff e0 00
+EC 0xb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xd0: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+EC 0xe0: 00 00 00 00 00 00 00 00 11 20 49 04 24 06 55 03
+EC 0xf0: 31 55 48 54 35 38 57 57 08 2f 45 73 07 65 6c 1a
+
+Another set of values that varies often is the temperature
+readings. Since temperatures don't change vary fast, you can take
+several quick dumps to eliminate them.
+
+You can use a similar method to figure out the meaning of other
+embedded controller registers - e.g. make sure nothing else changes
+except the charging or discharging battery to determine which
+registers contain the current battery capacity, etc. If you experiment
+with this, do send me your results (including some complete dumps with
+a description of the conditions when they were taken.)
+
+EXPERIMENTAL: LCD brightness control -- /proc/acpi/ibm/brightness
+-----------------------------------------------------------------
+
+This feature is marked EXPERIMENTAL because the implementation
+directly accesses hardware registers and may not work as expected. USE
+WITH CAUTION! To use this feature, you need to supply the
+experimental=1 parameter when loading the module.
+
+This feature allows software control of the LCD brightness on ThinkPad
+models which don't have a hardware brightness slider. The available
+commands are:
+
+ echo up >/proc/acpi/ibm/brightness
+ echo down >/proc/acpi/ibm/brightness
+ echo 'level <level>' >/proc/acpi/ibm/brightness
+
+The <level> number range is 0 to 7, although not all of them may be
+distinct. The current brightness level is shown in the file.
+
+EXPERIMENTAL: Volume control -- /proc/acpi/ibm/volume
+-----------------------------------------------------
+
+This feature is marked EXPERIMENTAL because the implementation
+directly accesses hardware registers and may not work as expected. USE
+WITH CAUTION! To use this feature, you need to supply the
+experimental=1 parameter when loading the module.
+
+This feature allows volume control on ThinkPad models which don't have
+a hardware volume knob. The available commands are:
+
+ echo up >/proc/acpi/ibm/volume
+ echo down >/proc/acpi/ibm/volume
+ echo mute >/proc/acpi/ibm/volume
+ echo 'level <level>' >/proc/acpi/ibm/volume
+
+The <level> number range is 0 to 15 although not all of them may be
+distinct. The unmute the volume after the mute command, use either the
+up or down command (the level command will not unmute the volume).
+The current volume level and mute state is shown in the file.
+
+EXPERIMENTAL: fan speed, fan enable/disable -- /proc/acpi/ibm/fan
+-----------------------------------------------------------------
+
+This feature is marked EXPERIMENTAL because the implementation
+directly accesses hardware registers and may not work as expected. USE
+WITH CAUTION! To use this feature, you need to supply the
+experimental=1 parameter when loading the module.
+
+This feature attempts to show the current fan speed. The speed is read
+directly from the hardware registers of the embedded controller. This
+is known to work on later R, T and X series ThinkPads but may show a
+bogus value on other models.
+
+The fan may be enabled or disabled with the following commands:
+
+ echo enable >/proc/acpi/ibm/fan
+ echo disable >/proc/acpi/ibm/fan
+
+WARNING WARNING WARNING: do not leave the fan disabled unless you are
+monitoring the temperature sensor readings and you are ready to enable
+it if necessary to avoid overheating.
+
+The fan only runs if it's enabled *and* the various temperature
+sensors which control it read high enough. On the X40, this seems to
+depend on the CPU and HDD temperatures. Specifically, the fan is
+turned on when either the CPU temperature climbs to 56 degrees or the
+HDD temperature climbs to 46 degrees. The fan is turned off when the
+CPU temperature drops to 49 degrees and the HDD temperature drops to
+41 degrees. These thresholds cannot currently be controlled.
+
+On the X31 and X40 (and ONLY on those models), the fan speed can be
+controlled to a certain degree. Once the fan is running, it can be
+forced to run faster or slower with the following command:
+
+ echo 'speed <speed>' > /proc/acpi/ibm/thermal
+
+The sustainable range of fan speeds on the X40 appears to be from
+about 3700 to about 7350. Values outside this range either do not have
+any effect or the fan speed eventually settles somewhere in that
+range. The fan cannot be stopped or started with this command.
+
+On the 570, temperature readings are not available through this
+feature and the fan control works a little differently. The fan speed
+is reported in levels from 0 (off) to 7 (max) and can be controlled
+with the following command:
-(I've only been able to identify a couple of them).
-
-If you try this feature, please send me a report similar to the
-above. I'd like to provide this functionality in an user-friendly way,
-but first I need to identify the which numbers correspond to which
-sounds on various models.
+ echo 'level <level>' > /proc/acpi/ibm/thermal
-Multiple Command, Module Parameters
------------------------------------
+Multiple Commands, Module Parameters
+------------------------------------
Multiple commands can be written to the proc files in one shot by
separating them with commas, for example:
@@ -451,24 +646,19 @@ scripts (included with ibm-acpi for completeness):
/usr/local/sbin/laptop_mode -- from the Linux kernel source
distribution, see Documentation/laptop-mode.txt
/sbin/service -- comes with Redhat/Fedora distributions
+ /usr/sbin/hibernate -- from the Software Suspend 2 distribution,
+ see http://softwaresuspend.berlios.de/
-Toan T Nguyen <ntt@control.uchicago.edu> has written a SuSE powersave
-script for the X20, included in config/usr/sbin/ibm_hotkeys_X20
+Toan T Nguyen <ntt@physics.ucla.edu> notes that Suse uses the
+powersave program to suspend ('powersave --suspend-to-ram') or
+hibernate ('powersave --suspend-to-disk'). This means that the
+hibernate script is not needed on that distribution.
Henrik Brix Andersen <brix@gentoo.org> has written a Gentoo ACPI event
handler script for the X31. You can get the latest version from
http://dev.gentoo.org/~brix/files/x31.sh
David Schweikert <dws@ee.eth.ch> has written an alternative blank.sh
-script which works on Debian systems, included in
-configs/etc/acpi/actions/blank-debian.sh
-
-
-TODO
-----
-
-I'd like to implement the following features but haven't yet found the
-time and/or I don't yet know how to implement them:
-
-- UltraBay floppy drive support
-
+script which works on Debian systems. This scripts has now been
+extended to also work on Fedora systems and included as the default
+blank.sh in the distribution.
diff --git a/Documentation/input/appletouch.txt b/Documentation/input/appletouch.txt
new file mode 100644
index 000000000000..b48d11d0326d
--- /dev/null
+++ b/Documentation/input/appletouch.txt
@@ -0,0 +1,84 @@
+Apple Touchpad Driver (appletouch)
+----------------------------------
+ Copyright (C) 2005 Stelian Pop <stelian@popies.net>
+
+appletouch is a Linux kernel driver for the USB touchpad found on post
+February 2005 Apple Alu Powerbooks.
+
+This driver is derived from Johannes Berg's appletrackpad driver[1], but it has
+been improved in some areas:
+ * appletouch is a full kernel driver, no userspace program is necessary
+ * appletouch can be interfaced with the synaptics X11 driver, in order
+ to have touchpad acceleration, scrolling, etc.
+
+Credits go to Johannes Berg for reverse-engineering the touchpad protocol,
+Frank Arnold for further improvements, and Alex Harper for some additional
+information about the inner workings of the touchpad sensors.
+
+Usage:
+------
+
+In order to use the touchpad in the basic mode, compile the driver and load
+the module. A new input device will be detected and you will be able to read
+the mouse data from /dev/input/mice (using gpm, or X11).
+
+In X11, you can configure the touchpad to use the synaptics X11 driver, which
+will give additional functionalities, like acceleration, scrolling, 2 finger
+tap for middle button mouse emulation, 3 finger tap for right button mouse
+emulation, etc. In order to do this, make sure you're using a recent version of
+the synaptics driver (tested with 0.14.2, available from [2]), and configure a
+new input device in your X11 configuration file (take a look below for an
+example). For additional configuration, see the synaptics driver documentation.
+
+ Section "InputDevice"
+ Identifier "Synaptics Touchpad"
+ Driver "synaptics"
+ Option "SendCoreEvents" "true"
+ Option "Device" "/dev/input/mice"
+ Option "Protocol" "auto-dev"
+ Option "LeftEdge" "0"
+ Option "RightEdge" "850"
+ Option "TopEdge" "0"
+ Option "BottomEdge" "645"
+ Option "MinSpeed" "0.4"
+ Option "MaxSpeed" "1"
+ Option "AccelFactor" "0.02"
+ Option "FingerLow" "0"
+ Option "FingerHigh" "30"
+ Option "MaxTapMove" "20"
+ Option "MaxTapTime" "100"
+ Option "HorizScrollDelta" "0"
+ Option "VertScrollDelta" "30"
+ Option "SHMConfig" "on"
+ EndSection
+
+ Section "ServerLayout"
+ ...
+ InputDevice "Mouse"
+ InputDevice "Synaptics Touchpad"
+ ...
+ EndSection
+
+Fuzz problems:
+--------------
+
+The touchpad sensors are very sensitive to heat, and will generate a lot of
+noise when the temperature changes. This is especially true when you power-on
+the laptop for the first time.
+
+The appletouch driver tries to handle this noise and auto adapt itself, but it
+is not perfect. If finger movements are not recognized anymore, try reloading
+the driver.
+
+You can activate debugging using the 'debug' module parameter. A value of 0
+deactivates any debugging, 1 activates tracing of invalid samples, 2 activates
+full tracing (each sample is being traced):
+ modprobe appletouch debug=1
+ or
+ echo "1" > /sys/module/appletouch/parameters/debug
+
+Links:
+------
+
+[1]: http://johannes.sipsolutions.net/PowerBook/touchpad/
+[2]: http://web.telia.com/~u89404340/touchpad/index.html
diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
new file mode 100644
index 000000000000..85f095a7ad04
--- /dev/null
+++ b/Documentation/input/yealink.txt
@@ -0,0 +1,203 @@
+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/ioctl/cdrom.txt b/Documentation/ioctl/cdrom.txt
index 4ccdcc6fe364..8ec32cc49eb1 100644
--- a/Documentation/ioctl/cdrom.txt
+++ b/Documentation/ioctl/cdrom.txt
@@ -878,7 +878,7 @@ DVD_READ_STRUCT Read structure
error returns:
EINVAL physical.layer_num exceeds number of layers
- EIO Recieved invalid response from drive
+ EIO Received invalid response from drive
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 9a1586590d82..d802ce88bedc 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -31,7 +31,7 @@ This document describes the Linux kernel Makefiles.
=== 6 Architecture Makefiles
--- 6.1 Set variables to tweak the build to the architecture
- --- 6.2 Add prerequisites to prepare:
+ --- 6.2 Add prerequisites to archprepare:
--- 6.3 List directories to visit when descending
--- 6.4 Architecture specific boot images
--- 6.5 Building non-kbuild targets
@@ -734,18 +734,18 @@ When kbuild executes the following steps are followed (roughly):
for loadable kernel modules.
---- 6.2 Add prerequisites to prepare:
+--- 6.2 Add prerequisites to archprepare:
- The prepare: rule is used to list prerequisites that needs to be
+ The archprepare: rule is used to list prerequisites that needs to be
built before starting to descend down in the subdirectories.
This is usual header files containing assembler constants.
Example:
- #arch/s390/Makefile
- prepare: include/asm-$(ARCH)/offsets.h
+ #arch/arm/Makefile
+ archprepare: maketools
- In this example the file include/asm-$(ARCH)/offsets.h will
- be built before descending down in the subdirectories.
+ In this example the file target maketools will be processed
+ before descending down in the subdirectories.
See also chapter XXX-TODO that describe how kbuild supports
generating offset header files.
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 7ff213f4becd..5f08f9ce6046 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.
@@ -67,11 +66,11 @@ SETUP
c) Enable "/proc/vmcore support" (Optional, in Pseudo filesystems).
CONFIG_PROC_VMCORE=y
d) Disable SMP support and build a UP kernel (Until it is fixed).
- CONFIG_SMP=n
+ CONFIG_SMP=n
e) Enable "Local APIC support on uniprocessors".
- CONFIG_X86_UP_APIC=y
+ CONFIG_X86_UP_APIC=y
f) Enable "IO-APIC support on uniprocessors"
- CONFIG_X86_UP_IOAPIC=y
+ CONFIG_X86_UP_IOAPIC=y
Note: i) Options a) and b) depend upon "Configure standard kernel features
(for small systems)" (under General setup).
@@ -84,17 +83,23 @@ 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.
+ iv) <root-dev> needs to be specified in a format corresponding to
+ the root device name in the output of mount command.
+ v) If you have built the drivers required to mount root file
+ system as modules in <second-kernel>, then, specify
+ --initrd=<initrd-for-second-kernel>.
5) System reboots into the second kernel when a panic occurs. A module can be
written to force the panic or "ALT-SysRq-c" can be used initiate a crash
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d2f0c67ba1fb..971589a9752d 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -17,7 +17,7 @@ are specified on the kernel command line with the module name plus
usbcore.blinkenlights=1
-The text in square brackets at the beginning of the description state the
+The text in square brackets at the beginning of the description states the
restrictions on the kernel for the said kernel parameter to be valid. The
restrictions referred to are that the relevant option is valid if:
@@ -27,8 +27,8 @@ restrictions referred to are that the relevant option is valid if:
APM Advanced Power Management support is enabled.
AX25 Appropriate AX.25 support is enabled.
CD Appropriate CD support is enabled.
- DEVFS devfs support is enabled.
- DRM Direct Rendering Management support is enabled.
+ DEVFS devfs support is enabled.
+ DRM Direct Rendering Management support is enabled.
EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
EFI EFI Partitioning (GPT) is enabled
EIDE EIDE/ATAPI support is enabled.
@@ -71,7 +71,7 @@ restrictions referred to are that the relevant option is valid if:
SERIAL Serial support is enabled.
SMP The kernel is an SMP kernel.
SPARC Sparc architecture is enabled.
- SWSUSP Software suspension is enabled.
+ SWSUSP Software suspend is enabled.
TS Appropriate touchscreen support is enabled.
USB USB support is enabled.
USBHID USB Human Interface Device support is enabled.
@@ -105,13 +105,13 @@ running once the system is up.
See header of drivers/scsi/53c7xx.c.
See also Documentation/scsi/ncr53c7xx.txt.
- acpi= [HW,ACPI] Advanced Configuration and Power Interface
- Format: { force | off | ht | strict }
+ acpi= [HW,ACPI] Advanced Configuration and Power Interface
+ Format: { force | off | ht | strict | noirq }
force -- enable ACPI if default was off
off -- disable ACPI if default was on
noirq -- do not use ACPI for IRQ routing
ht -- run only enough ACPI to enable Hyper Threading
- strict -- Be less tolerant of platforms that are not
+ strict -- Be less tolerant of platforms that are not
strictly ACPI specification compliant.
See also Documentation/pm.txt, pci=noacpi
@@ -119,20 +119,23 @@ running once the system is up.
acpi_sleep= [HW,ACPI] Sleep options
Format: { s3_bios, s3_mode }
See Documentation/power/video.txt
-
+
acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
- Format: { level | edge | high | low }
+ Format: { level | edge | high | low }
- acpi_irq_balance [HW,ACPI] ACPI will balance active IRQs
- default in APIC mode
+ acpi_irq_balance [HW,ACPI]
+ ACPI will balance active IRQs
+ default in APIC mode
- acpi_irq_nobalance [HW,ACPI] ACPI will not move active IRQs (default)
- default in PIC mode
+ acpi_irq_nobalance [HW,ACPI]
+ ACPI will not move active IRQs (default)
+ default in PIC mode
- acpi_irq_pci= [HW,ACPI] If irq_balance, Clear listed IRQs for use by PCI
+ acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for
+ use by PCI
Format: <irq>,<irq>...
- acpi_irq_isa= [HW,ACPI] If irq_balance, Mark listed IRQs used by ISA
+ acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
Format: <irq>,<irq>...
acpi_osi= [HW,ACPI] empty param disables _OSI
@@ -145,14 +148,14 @@ running once the system is up.
acpi_dbg_layer= [HW,ACPI]
Format: <int>
- Each bit of the <int> indicates an acpi debug layer,
+ Each bit of the <int> indicates an ACPI debug layer,
1: enable, 0: disable. It is useful for boot time
debugging. After system has booted up, it can be set
via /proc/acpi/debug_layer.
acpi_dbg_level= [HW,ACPI]
Format: <int>
- Each bit of the <int> indicates an acpi debug level,
+ Each bit of the <int> indicates an ACPI debug level,
1: enable, 0: disable. It is useful for boot time
debugging. After system has booted up, it can be set
via /proc/acpi/debug_level.
@@ -161,9 +164,19 @@ running once the system is up.
acpi_generic_hotkey [HW,ACPI]
Allow consolidated generic hotkey driver to
- over-ride platform specific driver.
+ override platform specific driver.
See also Documentation/acpi-hotkey.txt.
+ enable_timer_pin_1 [i386,x86-64]
+ Enable PIN 1 of APIC timer
+ Can be useful to work around chipset bugs
+ (in particular on some ATI chipsets).
+ The kernel tries to set a reasonable default.
+
+ disable_timer_pin_1 [i386,x86-64]
+ Disable PIN 1 of APIC timer
+ Can be useful to work around chipset bugs.
+
ad1816= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
See also Documentation/sound/oss/AD1816.
@@ -173,7 +186,7 @@ running once the system is up.
adlib= [HW,OSS]
Format: <io>
-
+
advansys= [HW,SCSI]
See header of drivers/scsi/advansys.c.
@@ -183,7 +196,7 @@ running once the system is up.
aedsp16= [HW,OSS] Audio Excel DSP 16
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
-
+
aha152x= [HW,SCSI]
See Documentation/scsi/aha152x.txt.
@@ -196,10 +209,6 @@ running once the system is up.
aic79xx= [HW,SCSI]
See Documentation/scsi/aic79xx.txt.
- AM53C974= [HW,SCSI]
- Format: <host-scsi-id>,<target-scsi-id>,<max-rate>,<max-offset>
- See also header of drivers/scsi/AM53C974.c.
-
amijoy.map= [HW,JOY] Amiga joystick support
Map of devices attached to JOY0DAT and JOY1DAT
Format: <a>,<b>
@@ -210,23 +219,24 @@ running once the system is up.
connected to one of 16 gameports
Format: <type1>,<type2>,..<type16>
- apc= [HW,SPARC] Power management functions (SPARCstation-4/5 + deriv.)
+ apc= [HW,SPARC]
+ Power management functions (SPARCstation-4/5 + deriv.)
Format: noidle
Disable APC CPU standby support. SPARCstation-Fox does
not play well with APC CPU idle - disable it if you have
APC and your system crashes randomly.
- apic= [APIC,i386] Change the output verbosity whilst booting
+ apic= [APIC,i386] Change the output verbosity whilst booting
Format: { quiet (default) | verbose | debug }
Change the amount of debugging information output
when initialising the APIC and IO-APIC components.
-
+
apm= [APM] Advanced Power Management
See header of arch/i386/kernel/apm.c.
applicom= [HW]
Format: <mem>,<irq>
-
+
arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
Format: <io>,<irq>,<nodeID>
@@ -241,38 +251,40 @@ running once the system is up.
atkbd.reset= [HW] Reset keyboard during initialization
- atkbd.set= [HW] Select keyboard code set
- Format: <int> (2 = AT (default) 3 = PS/2)
+ atkbd.set= [HW] Select keyboard code set
+ Format: <int> (2 = AT (default), 3 = PS/2)
atkbd.scroll= [HW] Enable scroll wheel on MS Office and similar
keyboards
atkbd.softraw= [HW] Choose between synthetic and real raw mode
Format: <bool> (0 = real, 1 = synthetic (default))
-
- atkbd.softrepeat=
- [HW] Use software keyboard repeat
+
+ atkbd.softrepeat= [HW]
+ Use software keyboard repeat
autotest [IA64]
awe= [HW,OSS] AWE32/SB32/AWE64 wave table synth
Format: <io>,<memsize>,<isapnp>
-
+
aztcd= [HW,CD] Aztech CD268 CDROM driver
Format: <io>,0x79 (?)
baycom_epp= [HW,AX25]
Format: <io>,<mode>
-
+
baycom_par= [HW,AX25] BayCom Parallel Port AX.25 Modem
Format: <io>,<mode>
See header of drivers/net/hamradio/baycom_par.c.
- baycom_ser_fdx= [HW,AX25] BayCom Serial Port AX.25 Modem (Full Duplex Mode)
+ baycom_ser_fdx= [HW,AX25]
+ BayCom Serial Port AX.25 Modem (Full Duplex Mode)
Format: <io>,<irq>,<mode>[,<baud>]
See header of drivers/net/hamradio/baycom_ser_fdx.c.
- baycom_ser_hdx= [HW,AX25] BayCom Serial Port AX.25 Modem (Half Duplex Mode)
+ baycom_ser_hdx= [HW,AX25]
+ BayCom Serial Port AX.25 Modem (Half Duplex Mode)
Format: <io>,<irq>,<mode>
See header of drivers/net/hamradio/baycom_ser_hdx.c.
@@ -283,7 +295,8 @@ running once the system is up.
blkmtd_count=
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
- bttv.radio= Most important insmod options are available as kernel args too.
+ bttv.radio= Most important insmod options are available as
+ kernel args too.
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
@@ -309,15 +322,17 @@ running once the system is up.
checkreqprot [SELINUX] Set initial checkreqprot flag value.
Format: { "0" | "1" }
See security/selinux/Kconfig help text.
- 0 -- check protection applied by kernel (includes any implied execute protection).
+ 0 -- check protection applied by kernel (includes
+ any implied execute protection).
1 -- check protection requested by application.
Default value is set via a kernel config option.
- Value can be changed at runtime via /selinux/checkreqprot.
-
- clock= [BUGS=IA-32, HW] gettimeofday timesource override.
+ Value can be changed at runtime via
+ /selinux/checkreqprot.
+
+ clock= [BUGS=IA-32,HW] gettimeofday timesource override.
Forces specified timesource (if avaliable) to be used
- when calculating gettimeofday(). If specicified timesource
- is not avalible, it defaults to PIT.
+ when calculating gettimeofday(). If specicified
+ timesource is not avalible, it defaults to PIT.
Format: { pit | tsc | cyclone | pmtmr }
hpet= [IA-32,HPET] option to disable HPET and use PIT.
@@ -327,17 +342,19 @@ running once the system is up.
Format: { auto | [<io>,][<irq>] }
com20020= [HW,NET] ARCnet - COM20020 chipset
- Format: <io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
+ Format:
+ <io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
com90io= [HW,NET] ARCnet - COM90xx chipset (IO-mapped buffers)
Format: <io>[,<irq>]
- com90xx= [HW,NET] ARCnet - COM90xx chipset (memory-mapped buffers)
+ com90xx= [HW,NET]
+ ARCnet - COM90xx chipset (memory-mapped buffers)
Format: <io>[,<irq>[,<memstart>]]
condev= [HW,S390] console device
conmode=
-
+
console= [KNL] Output console device and options.
tty<n> Use the virtual console device <n>.
@@ -358,7 +375,8 @@ running once the system is up.
options are the same as for ttyS, above.
cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
- Format: <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
+ Format:
+ <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
cpia_pp= [HW,PPT]
Format: { parport<nr> | auto | none }
@@ -375,10 +393,10 @@ running once the system is up.
cs89x0_media= [HW,NET]
Format: { rj45 | aui | bnc }
-
+
cyclades= [HW,SERIAL] Cyclades multi-serial port adapter.
-
- dasd= [HW,NET]
+
+ dasd= [HW,NET]
See header of drivers/s390/block/dasd_devmap.c.
db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port
@@ -397,7 +415,7 @@ running once the system is up.
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
-
+
digi= [HW,SERIAL]
IO parameters + enable/disable command.
@@ -415,11 +433,11 @@ running once the system is up.
dtc3181e= [HW,SCSI]
- earlyprintk= [IA-32, X86-64]
+ earlyprintk= [IA-32,X86-64]
earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
- Append ,keep to not disable it when the real console
+ Append ",keep" to not disable it when the real console
takes over.
Only vga or serial at a time, not both.
@@ -442,7 +460,7 @@ running once the system is up.
Format: {"of[f]" | "sk[ipmbr]"}
See comment in arch/i386/boot/edd.S
- eicon= [HW,ISDN]
+ eicon= [HW,ISDN]
Format: <id>,<membase>,<irq>
eisa_irq_edge= [PARISC,HW]
@@ -453,12 +471,13 @@ running once the system is up.
arch/i386/kernel/cpu/cpufreq/elanfreq.c.
elevator= [IOSCHED]
- Format: {"as"|"cfq"|"deadline"|"noop"}
- See Documentation/block/as-iosched.txt
- and Documentation/block/deadline-iosched.txt for details.
+ Format: {"as" | "cfq" | "deadline" | "noop"}
+ See Documentation/block/as-iosched.txt and
+ Documentation/block/deadline-iosched.txt for details.
+
elfcorehdr= [IA-32]
- Specifies physical address of start of kernel core image
- elf header.
+ Specifies physical address of start of kernel core
+ image elf header.
See Documentation/kdump.txt for details.
enforcing [SELINUX] Set initial enforcing status.
@@ -476,7 +495,7 @@ running once the system is up.
es1371= [HW,OSS]
Format: <spdif>,[<nomix>,[<amplifier>]]
See also header of sound/oss/es1371.c.
-
+
ether= [HW,NET] Ethernet cards parameters
This option is obsoleted by the "netdev=" option, which
has equivalent usage. See its documentation for details.
@@ -517,12 +536,13 @@ running once the system is up.
gus= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma16>
-
+
gvp11= [HW,SCSI]
hashdist= [KNL,NUMA] Large hashes allocated during boot
are distributed across NUMA nodes. Defaults on
for IA-64, off otherwise.
+ Format: 0 | 1 (for off | on)
hcl= [IA-64] SGI's Hardware Graph compatibility layer
@@ -549,6 +569,7 @@ running once the system is up.
keyboard and can not control its state
(Don't attempt to blink the leds)
i8042.noaux [HW] Don't check for auxiliary (== mouse) port
+ i8042.nokbd [HW] Don't check/create keyboard port
i8042.nomux [HW] Don't check presence of an active multiplexing
controller
i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
@@ -585,13 +606,13 @@ running once the system is up.
ide?= [HW] (E)IDE subsystem
Format: ide?=noprobe or chipset specific parameters.
See Documentation/ide.txt.
-
+
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
See Documentation/ide.txt.
idle= [HW]
Format: idle=poll or idle=halt
-
+
ihash_entries= [KNL]
Set number of hash buckets for inode cache.
@@ -639,7 +660,7 @@ running once the system is up.
firmware running.
isapnp= [ISAPNP]
- Format: <RDP>, <reset>, <pci_scan>, <verbosity>
+ Format: <RDP>,<reset>,<pci_scan>,<verbosity>
isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler.
Format: <cpu number>,...,<cpu number>
@@ -651,32 +672,33 @@ running once the system is up.
"number of CPUs in system - 1".
This option is the preferred way to isolate CPUs. The
- alternative - manually setting the CPU mask of all tasks
- in the system can cause problems and suboptimal load
- balancer performance.
+ alternative -- manually setting the CPU mask of all
+ tasks in the system -- can cause problems and
+ suboptimal load balancer performance.
isp16= [HW,CD]
Format: <io>,<irq>,<dma>,<setup>
- iucv= [HW,NET]
+ iucv= [HW,NET]
js= [HW,JOY] Analog joystick
See Documentation/input/joystick.txt.
keepinitrd [HW,ARM]
- kstack=N [IA-32, X86-64] Print N words from the kernel stack
+ kstack=N [IA-32,X86-64] Print N words from the kernel stack
in oops dumps.
l2cr= [PPC]
- lapic [IA-32,APIC] Enable the local APIC even if BIOS disabled it.
+ lapic [IA-32,APIC] Enable the local APIC even if BIOS
+ disabled it.
lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip
Format: addr:<io>,irq:<irq>
- llsc*= [IA64]
- See function print_params() in arch/ia64/sn/kernel/llsc4.c.
+ llsc*= [IA64] See function print_params() in
+ arch/ia64/sn/kernel/llsc4.c.
load_ramdisk= [RAM] List of ramdisks to load from floppy
See Documentation/ramdisk.txt.
@@ -703,8 +725,9 @@ running once the system is up.
7 (KERN_DEBUG) debug-level messages
log_buf_len=n Sets the size of the printk ring buffer, in bytes.
- Format is n, nk, nM. n must be a power of two. The
- default is set in kernel config.
+ Format: { n | nk | nM }
+ n must be a power of two. The default size
+ is set in the kernel config file.
lp=0 [LP] Specify parallel ports to use, e.g,
lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses
@@ -740,23 +763,23 @@ running once the system is up.
ltpc= [NET]
Format: <io>,<irq>,<dma>
- mac5380= [HW,SCSI]
- Format: <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
+ mac5380= [HW,SCSI] Format:
+ <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
- mac53c9x= [HW,SCSI]
- Format: <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
+ mac53c9x= [HW,SCSI] Format:
+ <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
- machvec= [IA64]
- Force the use of a particular machine-vector (machvec) in a generic
- kernel. Example: machvec=hpzx1_swiotlb
+ machvec= [IA64] Force the use of a particular machine-vector
+ (machvec) in a generic kernel.
+ Example: machvec=hpzx1_swiotlb
- mad16= [HW,OSS]
- Format: <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
+ mad16= [HW,OSS] Format:
+ <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
maui= [HW,OSS]
Format: <io>,<irq>
-
- max_loop= [LOOP] Maximum number of loopback devices that can
+
+ max_loop= [LOOP] Maximum number of loopback devices that can
be mounted
Format: <1-256>
@@ -766,11 +789,11 @@ running once the system is up.
max_addr=[KMG] [KNL,BOOT,ia64] All physical memory greater than or
equal to this physical address is ignored.
- max_luns= [SCSI] Maximum number of LUNs to probe
+ max_luns= [SCSI] Maximum number of LUNs to probe.
Should be between 1 and 2^32-1.
max_report_luns=
- [SCSI] Maximum number of LUNs received
+ [SCSI] Maximum number of LUNs received.
Should be between 1 and 16384.
mca-pentium [BUGS=IA-32]
@@ -786,11 +809,11 @@ running once the system is up.
md= [HW] RAID subsystems devices and level
See Documentation/md.txt.
-
+
mdacon= [MDA]
Format: <first>,<last>
Specifies range of consoles to be captured by the MDA.
-
+
mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory
Amount of memory to be used when the kernel is not able
to see the whole system memory or for test.
@@ -841,15 +864,15 @@ running once the system is up.
MTD_Partition= [MTD]
Format: <name>,<region-number>,<size>,<offset>
- MTD_Region= [MTD]
- Format: <name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>]
+ MTD_Region= [MTD] Format:
+ <name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>]
mtdparts= [MTD]
See drivers/mtd/cmdline.c.
mtouchusb.raw_coordinates=
- [HW] Make the MicroTouch USB driver use raw coordinates ('y', default)
- or cooked coordinates ('n')
+ [HW] Make the MicroTouch USB driver use raw coordinates
+ ('y', default) or cooked coordinates ('n')
n2= [NET] SDL Inc. RISCom/N2 synchronous serial card
@@ -870,7 +893,9 @@ running once the system is up.
Format: <irq>,<io>,<mem_start>,<mem_end>,<name>
Note that mem_start is often overloaded to mean
something different and driver-specific.
-
+ This usage is only documented in each driver source
+ file if at all.
+
nfsaddrs= [NFS]
See Documentation/nfsroot.txt.
@@ -883,8 +908,8 @@ running once the system is up.
emulation library even if a 387 maths coprocessor
is present.
- noalign [KNL,ARM]
-
+ noalign [KNL,ARM]
+
noapic [SMP,APIC] Tells the kernel to not make use of any
IOAPICs that may be present in the system.
@@ -895,19 +920,19 @@ running once the system is up.
on "Classic" PPC cores.
nocache [ARM]
-
+
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
noexec [IA-64]
- noexec [IA-32, X86-64]
+ noexec [IA-32,X86-64]
noexec=on: enable non-executable mappings (default)
noexec=off: disable nn-executable mappings
nofxsr [BUGS=IA-32]
nohlt [BUGS=ARM]
-
+
no-hlt [BUGS=IA-32] Tells the kernel that the hlt
instruction doesn't work correctly and not to
use it.
@@ -938,8 +963,9 @@ running once the system is up.
noresidual [PPC] Don't use residual data on PReP machines.
- noresume [SWSUSP] Disables resume and restore original swap space.
-
+ noresume [SWSUSP] Disables resume and restores original swap
+ space.
+
no-scroll [VGA] Disables scrollback.
This is required for the Braillex ib80-piezo Braille
reader made by F.H. Papenmeier (Germany).
@@ -955,16 +981,16 @@ running once the system is up.
nousb [USB] Disable the USB subsystem
nowb [ARM]
-
+
opl3= [HW,OSS]
Format: <io>
opl3sa= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<mpu_io>,<mpu_irq>
- opl3sa2= [HW,OSS]
- Format: <io>,<irq>,<dma>,<dma2>,<mss_io>,<mpu_io>,<ymode>,<loopback>[,<isapnp>,<multiple]
-
+ opl3sa2= [HW,OSS] Format:
+ <io>,<irq>,<dma>,<dma2>,<mss_io>,<mpu_io>,<ymode>,<loopback>[,<isapnp>,<multiple]
+
oprofile.timer= [HW]
Use timer interrupt instead of performance counters
@@ -983,36 +1009,33 @@ running once the system is up.
Format: <parport#>
parkbd.mode= [HW] Parallel port keyboard adapter mode of operation,
0 for XT, 1 for AT (default is AT).
- Format: <mode>
-
- parport=0 [HW,PPT] Specify parallel ports. 0 disables.
- parport=auto Use 'auto' to force the driver to use
- parport=0xBBB[,IRQ[,DMA]] any IRQ/DMA settings detected (the
- default is to ignore detected IRQ/DMA
- settings because of possible
- conflicts). You can specify the base
- address, IRQ, and DMA settings; IRQ and
- DMA should be numbers, or 'auto' (for
- using detected settings on that
- particular port), or 'nofifo' (to avoid
- using a FIFO even if it is detected).
- Parallel ports are assigned in the
- order they are specified on the command
- line, starting with parport0.
-
- parport_init_mode=
- [HW,PPT] Configure VIA parallel port to
- operate in specific mode. This is
- necessary on Pegasos computer where
- firmware has no options for setting up
- parallel port mode and sets it to
- spp. Currently this function knows
- 686a and 8231 chips.
+ Format: <mode>
+
+ parport= [HW,PPT] Specify parallel ports. 0 disables.
+ Format: { 0 | auto | 0xBBB[,IRQ[,DMA]] }
+ Use 'auto' to force the driver to use any
+ IRQ/DMA settings detected (the default is to
+ ignore detected IRQ/DMA settings because of
+ possible conflicts). You can specify the base
+ address, IRQ, and DMA settings; IRQ and DMA
+ should be numbers, or 'auto' (for using detected
+ settings on that particular port), or 'nofifo'
+ (to avoid using a FIFO even if it is detected).
+ Parallel ports are assigned in the order they
+ are specified on the command line, starting
+ with parport0.
+
+ parport_init_mode= [HW,PPT]
+ Configure VIA parallel port to operate in
+ a specific mode. This is necessary on Pegasos
+ computer where firmware has no options for setting
+ up parallel port mode and sets it to spp.
+ Currently this function knows 686a and 8231 chips.
Format: [spp|ps2|epp|ecp|ecpepp]
- pas2= [HW,OSS]
- Format: <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
-
+ pas2= [HW,OSS] Format:
+ <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
+
pas16= [HW,SCSI]
See header of drivers/scsi/pas16.c.
@@ -1022,64 +1045,67 @@ running once the system is up.
See header of drivers/block/paride/pcd.c.
See also Documentation/paride.txt.
- pci=option[,option...] [PCI] various PCI subsystem options:
- off [IA-32] don't probe for the PCI bus
- bios [IA-32] force use of PCI BIOS, don't access
- the hardware directly. Use this if your machine
- has a non-standard PCI host bridge.
- nobios [IA-32] disallow use of PCI BIOS, only direct
- hardware access methods are allowed. Use this
- if you experience crashes upon bootup and you
- suspect they are caused by the BIOS.
- conf1 [IA-32] Force use of PCI Configuration Mechanism 1.
- conf2 [IA-32] Force use of PCI Configuration Mechanism 2.
- nosort [IA-32] Don't sort PCI devices according to
- order given by the PCI BIOS. This sorting is done
- to get a device order compatible with older kernels.
- biosirq [IA-32] Use PCI BIOS calls to get the interrupt
- routing table. These calls are known to be buggy
- on several machines and they hang the machine when used,
- but on other computers it's the only way to get the
- interrupt routing table. Try this option if the kernel
- is unable to allocate IRQs or discover secondary PCI
- buses on your motherboard.
- rom [IA-32] Assign address space to expansion ROMs.
- Use with caution as certain devices share address
- decoders between ROMs and other resources.
- irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
- automatically to PCI devices. You can make the kernel
- exclude IRQs of your ISA cards this way.
+ pci=option[,option...] [PCI] various PCI subsystem options:
+ off [IA-32] don't probe for the PCI bus
+ bios [IA-32] force use of PCI BIOS, don't access
+ the hardware directly. Use this if your machine
+ has a non-standard PCI host bridge.
+ nobios [IA-32] disallow use of PCI BIOS, only direct
+ hardware access methods are allowed. Use this
+ if you experience crashes upon bootup and you
+ suspect they are caused by the BIOS.
+ conf1 [IA-32] Force use of PCI Configuration
+ Mechanism 1.
+ conf2 [IA-32] Force use of PCI Configuration
+ Mechanism 2.
+ nosort [IA-32] Don't sort PCI devices according to
+ order given by the PCI BIOS. This sorting is
+ done to get a device order compatible with
+ older kernels.
+ biosirq [IA-32] Use PCI BIOS calls to get the interrupt
+ routing table. These calls are known to be buggy
+ on several machines and they hang the machine
+ when used, but on other computers it's the only
+ way to get the interrupt routing table. Try
+ this option if the kernel is unable to allocate
+ IRQs or discover secondary PCI buses on your
+ motherboard.
+ rom [IA-32] Assign address space to expansion ROMs.
+ Use with caution as certain devices share
+ address decoders between ROMs and other
+ resources.
+ irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be
+ assigned automatically to PCI devices. You can
+ make the kernel exclude IRQs of your ISA cards
+ this way.
pirqaddr=0xAAAAA [IA-32] Specify the physical address
- of the PIRQ table (normally generated
- by the BIOS) if it is outside the
- F0000h-100000h range.
- lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
- if the kernel is unable to find your secondary buses
- and you want to tell it explicitly which ones they are.
- assign-busses [IA-32] Always assign all PCI bus
- numbers ourselves, overriding
- whatever the firmware may have
- done.
- usepirqmask [IA-32] Honor the possible IRQ mask
- stored in the BIOS $PIR table. This is
- needed on some systems with broken
- BIOSes, notably some HP Pavilion N5400
- and Omnibook XE3 notebooks. This will
- have no effect if ACPI IRQ routing is
- enabled.
- noacpi [IA-32] Do not use ACPI for IRQ routing
- or for PCI scanning.
- routeirq Do IRQ routing for all PCI devices.
- This is normally done in pci_enable_device(),
- so this option is a temporary workaround
- for broken drivers that don't call it.
-
- firmware [ARM] Do not re-enumerate the bus but
- instead just use the configuration
- from the bootloader. This is currently
- used on IXP2000 systems where the
- bus has to be configured a certain way
- for adjunct CPUs.
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the
+ F0000h-100000h range.
+ lastbus=N [IA-32] Scan all buses thru bus #N. Can be
+ useful if the kernel is unable to find your
+ secondary buses and you want to tell it
+ explicitly which ones they are.
+ assign-busses [IA-32] Always assign all PCI bus
+ numbers ourselves, overriding
+ whatever the firmware may have done.
+ usepirqmask [IA-32] Honor the possible IRQ mask stored
+ in the BIOS $PIR table. This is needed on
+ some systems with broken BIOSes, notably
+ some HP Pavilion N5400 and Omnibook XE3
+ notebooks. This will have no effect if ACPI
+ IRQ routing is enabled.
+ noacpi [IA-32] Do not use ACPI for IRQ routing
+ or for PCI scanning.
+ routeirq Do IRQ routing for all PCI devices.
+ This is normally done in pci_enable_device(),
+ so this option is a temporary workaround
+ for broken drivers that don't call it.
+ firmware [ARM] Do not re-enumerate the bus but instead
+ just use the configuration from the
+ bootloader. This is currently used on
+ IXP2000 systems where the bus has to be
+ configured a certain way for adjunct CPUs.
pcmv= [HW,PCMCIA] BadgePAD 4
@@ -1117,19 +1143,20 @@ running once the system is up.
[ISAPNP] Exclude DMAs for the autoconfiguration
pnp_reserve_io= [ISAPNP] Exclude I/O ports for the autoconfiguration
- Ranges are in pairs (I/O port base and size).
+ Ranges are in pairs (I/O port base and size).
pnp_reserve_mem=
- [ISAPNP] Exclude memory regions for the autoconfiguration
+ [ISAPNP] Exclude memory regions for the
+ autoconfiguration.
Ranges are in pairs (memory base and size).
profile= [KNL] Enable kernel profiling via /proc/profile
- { schedule | <number> }
- (param: schedule - profile schedule points}
- (param: profile step/bucket size as a power of 2 for
- statistical time based profiling)
+ Format: [schedule,]<number>
+ Param: "schedule" - profile schedule points.
+ Param: <number> - step/bucket size as a power of 2 for
+ statistical time based profiling.
- processor.max_cstate= [HW, ACPI]
+ processor.max_cstate= [HW,ACPI]
Limit processor to maximum C-state
max_cstate=9 overrides any DMI blacklist limit.
@@ -1137,27 +1164,28 @@ running once the system is up.
before loading.
See Documentation/ramdisk.txt.
- psmouse.proto= [HW,MOUSE] Highest PS2 mouse protocol extension to
- probe for (bare|imps|exps|lifebook|any).
+ psmouse.proto= [HW,MOUSE] Highest PS2 mouse protocol extension to
+ probe for; one of (bare|imps|exps|lifebook|any).
psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports
per second.
- psmouse.resetafter=
- [HW,MOUSE] Try to reset the device after so many bad packets
+ psmouse.resetafter= [HW,MOUSE]
+ Try to reset the device after so many bad packets
(0 = never).
psmouse.resolution=
[HW,MOUSE] Set desired mouse resolution, in dpi.
psmouse.smartscroll=
- [HW,MOUSE] Controls Logitech smartscroll autorepeat,
+ [HW,MOUSE] Controls Logitech smartscroll autorepeat.
0 = disabled, 1 = enabled (default).
pss= [HW,OSS] Personal Sound System (ECHO ESC614)
- Format: <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
+ Format:
+ <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
pt. [PARIDE]
See Documentation/paride.txt.
quiet= [KNL] Disable log messages
-
+
r128= [HW,DRM]
raid= [HW,RAID]
@@ -1166,10 +1194,9 @@ running once the system is up.
ramdisk= [RAM] Sizes of RAM disks in kilobytes [deprecated]
See Documentation/ramdisk.txt.
- ramdisk_blocksize=
- [RAM]
+ ramdisk_blocksize= [RAM]
See Documentation/ramdisk.txt.
-
+
ramdisk_size= [RAM] Sizes of RAM disks in kilobytes
New name for the ramdisk parameter.
See Documentation/ramdisk.txt.
@@ -1185,7 +1212,8 @@ running once the system is up.
reserve= [KNL,BUGS] Force the kernel to ignore some iomem area
- resume= [SWSUSP] Specify the partition device for software suspension
+ resume= [SWSUSP]
+ Specify the partition device for software suspend
rhash_entries= [KNL,NET]
Set number of hash buckets for route cache
@@ -1215,7 +1243,7 @@ running once the system is up.
Format: <io>,<irq>,<dma>,<dma2>
sbni= [NET] Granch SBNI12 leased line adapter
-
+
sbpcd= [HW,CD] Soundblaster CD adapter
Format: <io>,<type>
See a comment before function sbpcd_setup() in
@@ -1248,21 +1276,20 @@ running once the system is up.
serialnumber [BUGS=IA-32]
- sg_def_reserved_size=
- [SCSI]
-
+ sg_def_reserved_size= [SCSI]
+
sgalaxy= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<sgbase>
shapers= [NET]
Maximal number of shapers.
-
+
sim710= [SCSI,HW]
See header of drivers/scsi/sim710.c.
simeth= [IA-64]
simscsi=
-
+
sjcd= [HW,CD]
Format: <io>,<irq>,<dma>
See header of drivers/cdrom/sjcd.c.
@@ -1393,10 +1420,10 @@ running once the system is up.
snd-wavefront= [HW,ALSA]
snd-ymfpci= [HW,ALSA]
-
+
sonicvibes= [HW,OSS]
Format: <reverb>
-
+
sonycd535= [HW,CD]
Format: <io>[,<irq>]
@@ -1413,7 +1440,7 @@ running once the system is up.
sscape= [HW,OSS]
Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
-
+
st= [HW,SCSI] SCSI tape parameters (buffers, etc.)
See Documentation/scsi/st.txt.
@@ -1436,7 +1463,7 @@ running once the system is up.
stram_swap= [HW,M68k]
swiotlb= [IA-64] Number of I/O TLB slabs
-
+
switches= [HW,M68k]
sym53c416= [HW,SCSI]
@@ -1469,14 +1496,16 @@ running once the system is up.
tp720= [HW,PS2]
trix= [HW,OSS] MediaTrix AudioTrix Pro
- Format: <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
-
+ Format:
+ <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
+
tsdev.xres= [TS] Horizontal screen resolution.
tsdev.yres= [TS] Vertical screen resolution.
- turbografx.map[2|3]=
- [HW,JOY] TurboGraFX parallel port interface
- Format: <port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
+ turbografx.map[2|3]= [HW,JOY]
+ TurboGraFX parallel port interface
+ Format:
+ <port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
See also Documentation/input/joystick-parport.txt
u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter
@@ -1492,17 +1521,18 @@ running once the system is up.
usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at.
-
+
video= [FB] Frame buffer configuration
See Documentation/fb/modedb.txt.
vga= [BOOT,IA-32] Select a particular video mode
- See Documentation/i386/boot.txt and Documentation/svga.txt.
+ See Documentation/i386/boot.txt and
+ Documentation/svga.txt.
Use vga=ask for menu.
This is actually a boot loader parameter; the value is
passed to the kernel using a special protocol.
- vmalloc=nn[KMG] [KNL,BOOT] forces the vmalloc area to have an exact
+ vmalloc=nn[KMG] [KNL,BOOT] Forces the vmalloc area to have an exact
size of <nn>. This can be used to increase the
minimum size (128MB on x86). It can also be used to
decrease the size and leave more room for directly
@@ -1510,11 +1540,11 @@ running once the system is up.
vmhalt= [KNL,S390]
- vmpoff= [KNL,S390]
-
+ vmpoff= [KNL,S390]
+
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
-
+
wd33c93= [HW,SCSI]
See header of drivers/scsi/wd33c93.c.
@@ -1528,21 +1558,25 @@ running once the system is up.
xd_geo= See header of drivers/block/xd.c.
xirc2ps_cs= [NET,PCMCIA]
- Format: <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
-
+ Format:
+ <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
+______________________________________________________________________
Changelog:
+2000-06-?? Mr. Unknown
The last known update (for 2.4.0) - the changelog was not kept before.
- 2000-06-?? Mr. Unknown
+2002-11-24 Petr Baudis <pasky@ucw.cz>
+ Randy Dunlap <randy.dunlap@verizon.net>
Update for 2.5.49, description for most of the options introduced,
references to other documentation (C files, READMEs, ..), added S390,
PPC, SPARC, MTD, ALSA and OSS category. Minor corrections and
reformatting.
- 2002-11-24 Petr Baudis <pasky@ucw.cz>
- Randy Dunlap <randy.dunlap@verizon.net>
+
+2005-10-19 Randy Dunlap <rdunlap@xenotime.net>
+ Lots of typos, whitespace, some reformatting.
TODO:
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt
new file mode 100644
index 000000000000..5f2b9c5edbb5
--- /dev/null
+++ b/Documentation/keys-request-key.txt
@@ -0,0 +1,161 @@
+ ===================
+ KEY REQUEST SERVICE
+ ===================
+
+The key request service is part of the key retention service (refer to
+Documentation/keys.txt). This document explains more fully how that the
+requesting algorithm works.
+
+The process starts by either the kernel requesting a service by calling
+request_key():
+
+ struct key *request_key(const struct key_type *type,
+ const char *description,
+ const char *callout_string);
+
+Or by userspace invoking the request_key system call:
+
+ key_serial_t request_key(const char *type,
+ const char *description,
+ const char *callout_info,
+ key_serial_t dest_keyring);
+
+The main difference between the two access points is that the in-kernel
+interface does not need to link the key to a keyring to prevent it from being
+immediately destroyed. The kernel interface returns a pointer directly to the
+key, and it's up to the caller to destroy the key.
+
+The userspace interface links the key to a keyring associated with the process
+to prevent the key from going away, and returns the serial number of the key to
+the caller.
+
+
+===========
+THE PROCESS
+===========
+
+A request proceeds in the following manner:
+
+ (1) Process A calls request_key() [the userspace syscall calls the kernel
+ interface].
+
+ (2) request_key() searches the process's subscribed keyrings to see if there's
+ a suitable key there. If there is, it returns the key. If there isn't, and
+ callout_info is not set, an error is returned. Otherwise the process
+ proceeds to the next step.
+
+ (3) request_key() sees that A doesn't have the desired key yet, so it creates
+ two things:
+
+ (a) An uninstantiated key U of requested type and description.
+
+ (b) An authorisation key V that refers to key U and notes that process A
+ is the context in which key U should be instantiated and secured, and
+ from which associated key requests may be satisfied.
+
+ (4) request_key() then forks and executes /sbin/request-key with a new session
+ keyring that contains a link to auth key V.
+
+ (5) /sbin/request-key execs an appropriate program to perform the actual
+ instantiation.
+
+ (6) The program may want to access another key from A's context (say a
+ Kerberos TGT key). It just requests the appropriate key, and the keyring
+ search notes that the session keyring has auth key V in its bottom level.
+
+ This will permit it to then search the keyrings of process A with the
+ UID, GID, groups and security info of process A as if it was process A,
+ and come up with key W.
+
+ (7) The program then does what it must to get the data with which to
+ instantiate key U, using key W as a reference (perhaps it contacts a
+ Kerberos server using the TGT) and then instantiates key U.
+
+ (8) Upon instantiating key U, auth key V is automatically revoked so that it
+ may not be used again.
+
+ (9) The program then exits 0 and request_key() deletes key V and returns key
+ U to the caller.
+
+This also extends further. If key W (step 5 above) didn't exist, key W would be
+created uninstantiated, another auth key (X) would be created [as per step 3]
+and another copy of /sbin/request-key spawned [as per step 4]; but the context
+specified by auth key X will still be process A, as it was in auth key V.
+
+This is because process A's keyrings can't simply be attached to
+/sbin/request-key at the appropriate places because (a) execve will discard two
+of them, and (b) it requires the same UID/GID/Groups all the way through.
+
+
+======================
+NEGATIVE INSTANTIATION
+======================
+
+Rather than instantiating a key, it is possible for the possessor of an
+authorisation key to negatively instantiate a key that's under construction.
+This is a short duration placeholder that causes any attempt at re-requesting
+the key whilst it exists to fail with error ENOKEY.
+
+This is provided to prevent excessive repeated spawning of /sbin/request-key
+processes for a key that will never be obtainable.
+
+Should the /sbin/request-key process exit anything other than 0 or die on a
+signal, the key under construction will be automatically negatively
+instantiated for a short amount of time.
+
+
+====================
+THE SEARCH ALGORITHM
+====================
+
+A search of any particular keyring proceeds in the following fashion:
+
+ (1) When the key management code searches for a key (keyring_search_aux) it
+ firstly calls key_permission(SEARCH) on the keyring it's starting with,
+ if this denies permission, it doesn't search further.
+
+ (2) It considers all the non-keyring keys within that keyring and, if any key
+ matches the criteria specified, calls key_permission(SEARCH) on it to see
+ if the key is allowed to be found. If it is, that key is returned; if
+ not, the search continues, and the error code is retained if of higher
+ priority than the one currently set.
+
+ (3) It then considers all the keyring-type keys in the keyring it's currently
+ searching. It calls key_permission(SEARCH) on each keyring, and if this
+ grants permission, it recurses, executing steps (2) and (3) on that
+ keyring.
+
+The process stops immediately a valid key is found with permission granted to
+use it. Any error from a previous match attempt is discarded and the key is
+returned.
+
+When search_process_keyrings() is invoked, it performs the following searches
+until one succeeds:
+
+ (1) If extant, the process's thread keyring is searched.
+
+ (2) If extant, the process's process keyring is searched.
+
+ (3) The process's session keyring is searched.
+
+ (4) If the process has a request_key() authorisation key in its session
+ keyring then:
+
+ (a) If extant, the calling process's thread keyring is searched.
+
+ (b) If extant, the calling process's process keyring is searched.
+
+ (c) The calling process's session keyring is searched.
+
+The moment one succeeds, all pending errors are discarded and the found key is
+returned.
+
+Only if all these fail does the whole thing fail with the highest priority
+error. Note that several errors may have come from LSM.
+
+The error priority is:
+
+ EKEYREVOKED > EKEYEXPIRED > ENOKEY
+
+EACCES/EPERM are only returned on a direct search of a specific keyring where
+the basal keyring does not grant Search permission.
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 0321ded4b9ae..4afe03a58c5b 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -195,8 +195,8 @@ KEY ACCESS PERMISSIONS
======================
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
-has up to eight bits each for user, group and other access. Only five of each
-set of eight bits are defined. These permissions granted are:
+has up to eight bits each for possessor, user, group and other access. Only
+five of each set of eight bits are defined. These permissions granted are:
(*) View
@@ -241,16 +241,16 @@ about the status of the key service:
type, description and permissions. The payload of the key is not available
this way:
- SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
- 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4
- 00000002 I----- 2 perm 1f0000 0 0 keyring _uid.0: empty
- 00000007 I----- 1 perm 1f0000 0 0 keyring _pid.1: empty
- 0000018d I----- 1 perm 1f0000 0 0 keyring _pid.412: empty
- 000004d2 I--Q-- 1 perm 1f0000 32 -1 keyring _uid.32: 1/4
- 000004d3 I--Q-- 3 perm 1f0000 32 -1 keyring _uid_ses.32: empty
- 00000892 I--QU- 1 perm 1f0000 0 0 user metal:copper: 0
- 00000893 I--Q-N 1 35s 1f0000 0 0 user metal:silver: 0
- 00000894 I--Q-- 1 10h 1f0000 0 0 user metal:gold: 0
+ SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
+ 00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4
+ 00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty
+ 00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty
+ 0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty
+ 000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4
+ 000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty
+ 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
+ 00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0
+ 00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0
The flags are:
@@ -361,6 +361,8 @@ The main syscalls are:
/sbin/request-key will be invoked in an attempt to obtain a key. The
callout_info string will be passed as an argument to the program.
+ See also Documentation/keys-request-key.txt.
+
The keyctl syscall functions are:
@@ -533,8 +535,8 @@ The keyctl syscall functions are:
(*) Read the payload data from a key:
- key_serial_t keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
- size_t buflen);
+ long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
+ size_t buflen);
This function attempts to read the payload data from the specified key
into the buffer. The process must have read permission on the key to
@@ -555,9 +557,9 @@ The keyctl syscall functions are:
(*) Instantiate a partially constructed key.
- key_serial_t keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
- const void *payload, size_t plen,
- key_serial_t keyring);
+ long keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
+ const void *payload, size_t plen,
+ key_serial_t keyring);
If the kernel calls back to userspace to complete the instantiation of a
key, userspace should use this call to supply data for the key before the
@@ -576,8 +578,8 @@ The keyctl syscall functions are:
(*) Negatively instantiate a partially constructed key.
- key_serial_t keyctl(KEYCTL_NEGATE, key_serial_t key,
- unsigned timeout, key_serial_t keyring);
+ long keyctl(KEYCTL_NEGATE, key_serial_t key,
+ unsigned timeout, key_serial_t keyring);
If the kernel calls back to userspace to complete the instantiation of a
key, userspace should use this call mark the key as negative before the
@@ -637,6 +639,34 @@ call, and the key released upon close. How to deal with conflicting keys due to
two different users opening the same file is left to the filesystem author to
solve.
+Note that there are two different types of pointers to keys that may be
+encountered:
+
+ (*) struct key *
+
+ This simply points to the key structure itself. Key structures will be at
+ least four-byte aligned.
+
+ (*) key_ref_t
+
+ This is equivalent to a struct key *, but the least significant bit is set
+ if the caller "possesses" the key. By "possession" it is meant that the
+ calling processes has a searchable link to the key from one of its
+ keyrings. There are three functions for dealing with these:
+
+ key_ref_t make_key_ref(const struct key *key,
+ unsigned long possession);
+
+ struct key *key_ref_to_ptr(const key_ref_t key_ref);
+
+ unsigned long is_key_possessed(const key_ref_t key_ref);
+
+ The first function constructs a key reference from a key pointer and
+ possession information (which must be 0 or 1 and not any other value).
+
+ The second function retrieves the key pointer from a reference and the
+ third retrieves the possession flag.
+
When accessing a key's payload contents, certain precautions must be taken to
prevent access vs modification races. See the section "Notes on accessing
payload contents" for more information.
@@ -660,12 +690,18 @@ payload contents" for more information.
If successful, the key will have been attached to the default keyring for
implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
+ See also Documentation/keys-request-key.txt.
+
(*) When it is no longer required, the key should be released using:
void key_put(struct key *key);
- This can be called from interrupt context. If CONFIG_KEYS is not set then
+ Or:
+
+ void key_ref_put(key_ref_t key_ref);
+
+ These can be called from interrupt context. If CONFIG_KEYS is not set then
the argument will not be parsed.
@@ -689,13 +725,17 @@ payload contents" for more information.
(*) If a keyring was found in the search, this can be further searched by:
- struct key *keyring_search(struct key *keyring,
- const struct key_type *type,
- const char *description)
+ key_ref_t keyring_search(key_ref_t keyring_ref,
+ const struct key_type *type,
+ const char *description)
This searches the keyring tree specified for a matching key. Error ENOKEY
- is returned upon failure. If successful, the returned key will need to be
- released.
+ is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
+ the returned key will need to be released.
+
+ The possession attribute from the keyring reference is used to control
+ access through the permissions mask and is propagated to the returned key
+ reference pointer if successful.
(*) To check the validity of a key, this function can be called:
@@ -732,7 +772,7 @@ More complex payload contents must be allocated and a pointer to them set in
key->payload.data. One of the following ways must be selected to access the
data:
- (1) Unmodifyable key type.
+ (1) Unmodifiable key type.
If the key type does not have a modify method, then the key's payload can
be accessed without any form of locking, provided that it's known to be
diff --git a/Documentation/mono.txt b/Documentation/mono.txt
index 6739ab9615ef..807a0c7b4737 100644
--- a/Documentation/mono.txt
+++ b/Documentation/mono.txt
@@ -30,7 +30,7 @@ other program after you have done the following:
Read the file 'binfmt_misc.txt' in this directory to know
more about the configuration process.
-3) Add the following enries to /etc/rc.local or similar script
+3) Add the following entries to /etc/rc.local or similar script
to be run at system startup:
# Insert BINFMT_MISC module into the kernel
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 24d029455baa..b0fe41da007b 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -777,7 +777,7 @@ doing so is the same as described in the "Configuring Multiple Bonds
Manually" section, below.
NOTE: It has been observed that some Red Hat supplied kernels
-are apparently unable to rename modules at load time (the "-obonding1"
+are apparently unable to rename modules at load time (the "-o bond1"
part). Attempts to pass that option to modprobe will produce an
"Operation not permitted" error. This has been reported on some
Fedora Core kernels, and has been seen on RHEL 4 as well. On kernels
@@ -883,7 +883,8 @@ the above does not work, and the second bonding instance never sees
its options. In that case, the second options line can be substituted
as follows:
-install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50
+install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
+ mode=balance-alb miimon=50
This may be repeated any number of times, specifying a new and
unique name in place of bond1 for each subsequent instance.
@@ -1241,7 +1242,7 @@ traffic while still maintaining carrier on.
If running SNMP agents, the bonding driver should be loaded
before any network drivers participating in a bond. This requirement
-is due to the the interface index (ipAdEntIfIndex) being associated to
+is due to the interface index (ipAdEntIfIndex) being associated to
the first interface found with a given IP address. That is, there is
only one ipAdEntIfIndex for each IP address. For example, if eth0 and
eth1 are slaves of bond0 and the driver for eth0 is loaded before the
@@ -1937,7 +1938,7 @@ switches currently available support 802.3ad.
If not explicitly configured (with ifconfig or ip link), the
MAC address of the bonding device is taken from its first slave
device. This MAC address is then passed to all following slaves and
-remains persistent (even if the the first slave is removed) until the
+remains persistent (even if the first slave is removed) until the
bonding device is brought down or reconfigured.
If you wish to change the MAC address, you can set it with
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ab65714d95fc..b433c8a27e2d 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -355,10 +355,14 @@ ip_dynaddr - BOOLEAN
Default: 0
icmp_echo_ignore_all - BOOLEAN
+ If set non-zero, then the kernel will ignore all ICMP ECHO
+ requests sent to it.
+ Default: 0
+
icmp_echo_ignore_broadcasts - BOOLEAN
- If either is set to true, then the kernel will ignore either all
- ICMP ECHO requests sent to it or just those to broadcast/multicast
- addresses, respectively.
+ If set non-zero, then the kernel will ignore all ICMP ECHO and
+ TIMESTAMP requests sent to it via broadcast/multicast.
+ Default: 1
icmp_ratelimit - INTEGER
Limit the maximal rates for sending ICMP packets whose type matches
diff --git a/Documentation/networking/wan-router.txt b/Documentation/networking/wan-router.txt
index aea20cd2a56e..c96897aa08b6 100644
--- a/Documentation/networking/wan-router.txt
+++ b/Documentation/networking/wan-router.txt
@@ -355,7 +355,7 @@ REVISION HISTORY
There is no functional difference between the two packages
2.0.7 Aug 26, 1999 o Merged X25API code into WANPIPE.
- o Fixed a memeory leak for X25API
+ o Fixed a memory leak for X25API
o Updated the X25API code for 2.2.X kernels.
o Improved NEM handling.
@@ -514,7 +514,7 @@ beta2-2.2.0 Jan 8 2001
o Patches for 2.4.0 kernel
o Patches for 2.2.18 kernel
o Minor updates to PPP and CHLDC drivers.
- Note: No functinal difference.
+ Note: No functional difference.
beta3-2.2.9 Jan 10 2001
o I missed the 2.2.18 kernel patches in beta2-2.2.0
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index da711028e5f7..66eaaab7773d 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -205,8 +205,8 @@ Phone: 701-234-7556
Tainted kernels:
Some oops reports contain the string 'Tainted: ' after the program
-counter, this indicates that the kernel has been tainted by some
-mechanism. The string is followed by a series of position sensitive
+counter. This indicates that the kernel has been tainted by some
+mechanism. The string is followed by a series of position-sensitive
characters, each representing a particular tainted value.
1: 'G' if all modules loaded have a GPL or compatible license, 'P' if
@@ -214,16 +214,25 @@ characters, each representing a particular tainted value.
MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by
insmod as GPL compatible are assumed to be proprietary.
- 2: 'F' if any module was force loaded by insmod -f, ' ' if all
+ 2: 'F' if any module was force loaded by "insmod -f", ' ' if all
modules were loaded normally.
3: 'S' if the oops occurred on an SMP kernel running on hardware that
- hasn't been certified as safe to run multiprocessor.
- Currently this occurs only on various Athlons that are not
- SMP capable.
+ hasn't been certified as safe to run multiprocessor.
+ Currently this occurs only on various Athlons that are not
+ SMP capable.
+
+ 4: 'R' if a module was force unloaded by "rmmod -f", ' ' if all
+ modules were unloaded normally.
+
+ 5: 'M' if any processor has reported a Machine Check Exception,
+ ' ' if no Machine Check Exceptions have occurred.
+
+ 6: 'B' if a page-release function has found a bad page reference or
+ some unexpected page flags.
The primary reason for the 'Tainted: ' string is to tell kernel
debuggers if this is a clean kernel or if anything unusual has
-occurred. Tainting is permanent, even if an offending module is
-unloading the tainted value remains to indicate that the kernel is not
+occurred. Tainting is permanent: even if an offending module is
+unloaded, the tainted value remains to indicate that the kernel is not
trustworthy.
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
index 76d28d033657..711210b38f5f 100644
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -84,7 +84,7 @@ Each entry consists of:
Most drivers don't need to use the driver_data field. Best practice
for use of driver_data is to use it as an index into a static list of
-equivalant device types, not to use it as a pointer.
+equivalent device types, not to use it as a pointer.
Have a table entry {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID}
to have probe() called for every PCI device known to the system.
diff --git a/Documentation/pm.txt b/Documentation/pm.txt
index cc63ae18d147..2ea1149bf6b0 100644
--- a/Documentation/pm.txt
+++ b/Documentation/pm.txt
@@ -38,6 +38,12 @@ system the associated daemon will exit gracefully.
Driver Interface -- OBSOLETE, DO NOT USE!
----------------*************************
+
+Note: pm_register(), pm_access(), pm_dev_idle() and friends are
+obsolete. Please do not use them. Instead you should properly hook
+your driver into the driver model, and use its suspend()/resume()
+callbacks to do this kind of stuff.
+
If you are writing a new driver or maintaining an old driver, it
should include power management support. Without power management
support, a single driver may prevent a system with power management
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index 2bfe71beec5b..e75d7474322c 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -134,7 +134,7 @@ pci_get_device_by_addr() will find the pci device associated
with that address (if any).
The default include/asm-ppc64/io.h macros readb(), inb(), insb(),
-etc. include a check to see if the the i/o read returned all-0xff's.
+etc. include a check to see if the i/o read returned all-0xff's.
If so, these make a call to eeh_dn_check_failure(), which in turn
asks the firmware if the all-ff's value is the sign of a true EEH
error. If it is not, processing continues as normal. The grand
diff --git a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt
index e24fdeada970..e321a8ed2a2d 100644
--- a/Documentation/s390/s390dbf.txt
+++ b/Documentation/s390/s390dbf.txt
@@ -468,7 +468,7 @@ The hex_ascii view shows the data field in hex and ascii representation
The raw view returns a bytestream as the debug areas are stored in memory.
The sprintf view formats the debug entries in the same way as the sprintf
-function would do. The sprintf event/expection fuctions write to the
+function would do. The sprintf event/expection functions write to the
debug entry a pointer to the format string (size = sizeof(long))
and for each vararg a long value. So e.g. for a debug entry with a format
string plus two varargs one would need to allocate a (3 * sizeof(long))
diff --git a/Documentation/scsi/00-INDEX b/Documentation/scsi/00-INDEX
index f9cb5bdcce41..fef92ebf266f 100644
--- a/Documentation/scsi/00-INDEX
+++ b/Documentation/scsi/00-INDEX
@@ -60,6 +60,8 @@ scsi.txt
- short blurb on using SCSI support as a module.
scsi_mid_low_api.txt
- info on API between SCSI layer and low level drivers
+scsi_eh.txt
+ - info on SCSI midlayer error handling infrastructure
st.txt
- info on scsi tape driver
sym53c500_cs.txt
diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
index 2814491600ff..2ffb3ae0ef4d 100644
--- a/Documentation/scsi/ibmmca.txt
+++ b/Documentation/scsi/ibmmca.txt
@@ -344,7 +344,7 @@
/proc/scsi/ibmmca/<host_no>. ibmmca_proc_info() provides this information.
This table is quite informative for interested users. It shows the load
- of commands on the subsystem and wether you are running the bypassed
+ of commands on the subsystem and whether you are running the bypassed
(software) or integrated (hardware) SCSI-command set (see below). The
amount of accesses is shown. Read, write, modeselect is shown separately
in order to help debugging problems with CD-ROMs or tapedrives.
diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
new file mode 100644
index 000000000000..534a50922a7b
--- /dev/null
+++ b/Documentation/scsi/scsi_eh.txt
@@ -0,0 +1,479 @@
+
+SCSI EH
+======================================
+
+ This document describes SCSI midlayer error handling infrastructure.
+Please refer to Documentation/scsi/scsi_mid_low_api.txt for more
+information regarding SCSI midlayer.
+
+TABLE OF CONTENTS
+
+[1] How SCSI commands travel through the midlayer and to EH
+ [1-1] struct scsi_cmnd
+ [1-2] How do scmd's get completed?
+ [1-2-1] Completing a scmd w/ scsi_done
+ [1-2-2] Completing a scmd w/ timeout
+ [1-3] How EH takes over
+[2] How SCSI EH works
+ [2-1] EH through fine-grained callbacks
+ [2-1-1] Overview
+ [2-1-2] Flow of scmds through EH
+ [2-1-3] Flow of control
+ [2-2] EH through hostt->eh_strategy_handler()
+ [2-2-1] Pre hostt->eh_strategy_handler() SCSI midlayer conditions
+ [2-2-2] Post hostt->eh_strategy_handler() SCSI midlayer conditions
+ [2-2-3] Things to consider
+
+
+[1] How SCSI commands travel through the midlayer and to EH
+
+[1-1] struct scsi_cmnd
+
+ Each SCSI command is represented with struct scsi_cmnd (== scmd). A
+scmd has two list_head's to link itself into lists. The two are
+scmd->list and scmd->eh_entry. The former is used for free list or
+per-device allocated scmd list and not of much interest to this EH
+discussion. The latter is used for completion and EH lists and unless
+otherwise stated scmds are always linked using scmd->eh_entry in this
+discussion.
+
+
+[1-2] How do scmd's get completed?
+
+ Once LLDD gets hold of a scmd, either the LLDD will complete the
+command by calling scsi_done callback passed from midlayer when
+invoking hostt->queuecommand() or SCSI midlayer will time it out.
+
+
+[1-2-1] Completing a scmd w/ scsi_done
+
+ For all non-EH commands, scsi_done() is the completion callback. It
+does the following.
+
+ 1. Delete timeout timer. If it fails, it means that timeout timer
+ has expired and is going to finish the command. Just return.
+
+ 2. Link scmd to per-cpu scsi_done_q using scmd->en_entry
+
+ 3. Raise SCSI_SOFTIRQ
+
+ SCSI_SOFTIRQ handler scsi_softirq calls scsi_decide_disposition() to
+determine what to do with the command. scsi_decide_disposition()
+looks at the scmd->result value and sense data to determine what to do
+with the command.
+
+ - SUCCESS
+ scsi_finish_command() is invoked for the command. The
+ function does some maintenance choirs and notify completion by
+ calling scmd->done() callback, which, for fs requests, would
+ be HLD completion callback - sd:sd_rw_intr, sr:rw_intr,
+ st:st_intr.
+
+ - NEEDS_RETRY
+ - ADD_TO_MLQUEUE
+ scmd is requeued to blk queue.
+
+ - otherwise
+ scsi_eh_scmd_add(scmd, 0) is invoked for the command. See
+ [1-3] for details of this funciton.
+
+
+[1-2-2] Completing a scmd w/ timeout
+
+ The timeout handler is scsi_times_out(). When a timeout occurs, this
+function
+
+ 1. invokes optional hostt->eh_timedout() callback. Return value can
+ be one of
+
+ - EH_HANDLED
+ This indicates that eh_timedout() dealt with the timeout. The
+ scmd is passed to __scsi_done() and thus linked into per-cpu
+ scsi_done_q. Normal command completion described in [1-2-1]
+ follows.
+
+ - EH_RESET_TIMER
+ This indicates that more time is required to finish the
+ command. Timer is restarted. This action is counted as a
+ retry and only allowed scmd->allowed + 1(!) times. Once the
+ limit is reached, action for EH_NOT_HANDLED is taken instead.
+
+ *NOTE* This action is racy as the LLDD could finish the scmd
+ after the timeout has expired but before it's added back. In
+ such cases, scsi_done() would think that timeout has occurred
+ and return without doing anything. We lose completion and the
+ command will time out again.
+
+ - EH_NOT_HANDLED
+ This is the same as when eh_timedout() callback doesn't exist.
+ Step #2 is taken.
+
+ 2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the
+ command. See [1-3] for more information.
+
+
+[1-3] How EH takes over
+
+ scmds enter EH via scsi_eh_scmd_add(), which does the following.
+
+ 1. Turns on scmd->eh_eflags as requested. It's 0 for error
+ completions and SCSI_EH_CANCEL_CMD for timeouts.
+
+ 2. Links scmd->eh_entry to shost->eh_cmd_q
+
+ 3. Sets SHOST_RECOVERY bit in shost->shost_state
+
+ 4. Increments shost->host_failed
+
+ 5. Wakes up SCSI EH thread if shost->host_busy == shost->host_failed
+
+ As can be seen above, once any scmd is added to shost->eh_cmd_q,
+SHOST_RECOVERY shost_state bit is turned on. This prevents any new
+scmd to be issued from blk queue to the host; eventually, all scmds on
+the host either complete normally, fail and get added to eh_cmd_q, or
+time out and get added to shost->eh_cmd_q.
+
+ If all scmds either complete or fail, the number of in-flight scmds
+becomes equal to the number of failed scmds - i.e. shost->host_busy ==
+shost->host_failed. This wakes up SCSI EH thread. So, once woken up,
+SCSI EH thread can expect that all in-flight commands have failed and
+are linked on shost->eh_cmd_q.
+
+ Note that this does not mean lower layers are quiescent. If a LLDD
+completed a scmd with error status, the LLDD and lower layers are
+assumed to forget about the scmd at that point. However, if a scmd
+has timed out, unless hostt->eh_timedout() made lower layers forget
+about the scmd, which currently no LLDD does, the command is still
+active as long as lower layers are concerned and completion could
+occur at any time. Of course, all such completions are ignored as the
+timer has already expired.
+
+ We'll talk about how SCSI EH takes actions to abort - make LLDD
+forget about - timed out scmds later.
+
+
+[2] How SCSI EH works
+
+ LLDD's can implement SCSI EH actions in one of the following two
+ways.
+
+ - Fine-grained EH callbacks
+ LLDD can implement fine-grained EH callbacks and let SCSI
+ midlayer drive error handling and call appropriate callbacks.
+ This will be dicussed further in [2-1].
+
+ - eh_strategy_handler() callback
+ This is one big callback which should perform whole error
+ handling. As such, it should do all choirs SCSI midlayer
+ performs during recovery. This will be discussed in [2-2].
+
+ Once recovery is complete, SCSI EH resumes normal operation by
+calling scsi_restart_operations(), which
+
+ 1. Checks if door locking is needed and locks door.
+
+ 2. Clears SHOST_RECOVERY shost_state bit
+
+ 3. Wakes up waiters on shost->host_wait. This occurs if someone
+ calls scsi_block_when_processing_errors() on the host.
+ (*QUESTION* why is it needed? All operations will be blocked
+ anyway after it reaches blk queue.)
+
+ 4. Kicks queues in all devices on the host in the asses
+
+
+[2-1] EH through fine-grained callbacks
+
+[2-1-1] Overview
+
+ If eh_strategy_handler() is not present, SCSI midlayer takes charge
+of driving error handling. EH's goals are two - make LLDD, host and
+device forget about timed out scmds and make them ready for new
+commands. A scmd is said to be recovered if the scmd is forgotten by
+lower layers and lower layers are ready to process or fail the scmd
+again.
+
+ To achieve these goals, EH performs recovery actions with increasing
+severity. Some actions are performed by issueing SCSI commands and
+others are performed by invoking one of the following fine-grained
+hostt EH callbacks. Callbacks may be omitted and omitted ones are
+considered to fail always.
+
+int (* eh_abort_handler)(struct scsi_cmnd *);
+int (* eh_device_reset_handler)(struct scsi_cmnd *);
+int (* eh_bus_reset_handler)(struct scsi_cmnd *);
+int (* eh_host_reset_handler)(struct scsi_cmnd *);
+
+ Higher-severity actions are taken only when lower-severity actions
+cannot recover some of failed scmds. Also, note that failure of the
+highest-severity action means EH failure and results in offlining of
+all unrecovered devices.
+
+ During recovery, the following rules are followed
+
+ - Recovery actions are performed on failed scmds on the to do list,
+ eh_work_q. If a recovery action succeeds for a scmd, recovered
+ scmds are removed from eh_work_q.
+
+ Note that single recovery action on a scmd can recover multiple
+ scmds. e.g. resetting a device recovers all failed scmds on the
+ device.
+
+ - Higher severity actions are taken iff eh_work_q is not empty after
+ lower severity actions are complete.
+
+ - EH reuses failed scmds to issue commands for recovery. For
+ timed-out scmds, SCSI EH ensures that LLDD forgets about a scmd
+ before reusing it for EH commands.
+
+ When a scmd is recovered, the scmd is moved from eh_work_q to EH
+local eh_done_q using scsi_eh_finish_cmd(). After all scmds are
+recovered (eh_work_q is empty), scsi_eh_flush_done_q() is invoked to
+either retry or error-finish (notify upper layer of failure) recovered
+scmds.
+
+ scmds are retried iff its sdev is still online (not offlined during
+EH), REQ_FAILFAST is not set and ++scmd->retries is less than
+scmd->allowed.
+
+
+[2-1-2] Flow of scmds through EH
+
+ 1. Error completion / time out
+ ACTION: scsi_eh_scmd_add() is invoked for scmd
+ - set scmd->eh_eflags
+ - add scmd to shost->eh_cmd_q
+ - set SHOST_RECOVERY
+ - shost->host_failed++
+ LOCKING: shost->host_lock
+
+ 2. EH starts
+ ACTION: move all scmds to EH's local eh_work_q. shost->eh_cmd_q
+ is cleared.
+ LOCKING: shost->host_lock (not strictly necessary, just for
+ consistency)
+
+ 3. scmd recovered
+ ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
+ - shost->host_failed--
+ - clear scmd->eh_eflags
+ - scsi_setup_cmd_retry()
+ - move from local eh_work_q to local eh_done_q
+ LOCKING: none
+
+ 4. EH completes
+ ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper
+ layer of failure.
+ - scmd is removed from eh_done_q and scmd->eh_entry is cleared
+ - if retry is necessary, scmd is requeued using
+ scsi_queue_insert()
+ - otherwise, scsi_finish_command() is invoked for scmd
+ LOCKING: queue or finish function performs appropriate locking
+
+
+[2-1-3] Flow of control
+
+ EH through fine-grained callbacks start from scsi_unjam_host().
+
+<<scsi_unjam_host>>
+
+ 1. Lock shost->host_lock, splice_init shost->eh_cmd_q into local
+ eh_work_q and unlock host_lock. Note that shost->eh_cmd_q is
+ cleared by this action.
+
+ 2. Invoke scsi_eh_get_sense.
+
+ <<scsi_eh_get_sense>>
+
+ This action is taken for each error-completed
+ (!SCSI_EH_CANCEL_CMD) commands without valid sense data. Most
+ SCSI transports/LLDDs automatically acquire sense data on
+ command failures (autosense). Autosense is recommended for
+ performance reasons and as sense information could get out of
+ sync inbetween occurrence of CHECK CONDITION and this action.
+
+ Note that if autosense is not supported, scmd->sense_buffer
+ contains invalid sense data when error-completing the scmd
+ with scsi_done(). scsi_decide_disposition() always returns
+ FAILED in such cases thus invoking SCSI EH. When the scmd
+ reaches here, sense data is acquired and
+ scsi_decide_disposition() is called again.
+
+ 1. Invoke scsi_request_sense() which issues REQUEST_SENSE
+ command. If fails, no action. Note that taking no action
+ causes higher-severity recovery to be taken for the scmd.
+
+ 2. Invoke scsi_decide_disposition() on the scmd
+
+ - SUCCESS
+ scmd->retries is set to scmd->allowed preventing
+ scsi_eh_flush_done_q() from retrying the scmd and
+ scsi_eh_finish_cmd() is invoked.
+
+ - NEEDS_RETRY
+ scsi_eh_finish_cmd() invoked
+
+ - otherwise
+ No action.
+
+ 3. If !list_empty(&eh_work_q), invoke scsi_eh_abort_cmds().
+
+ <<scsi_eh_abort_cmds>>
+
+ This action is taken for each timed out command.
+ hostt->eh_abort_handler() is invoked for each scmd. The
+ handler returns SUCCESS if it has succeeded to make LLDD and
+ all related hardware forget about the scmd.
+
+ If a timedout scmd is successfully aborted and the sdev is
+ either offline or ready, scsi_eh_finish_cmd() is invoked for
+ the scmd. Otherwise, the scmd is left in eh_work_q for
+ higher-severity actions.
+
+ Note that both offline and ready status mean that the sdev is
+ ready to process new scmds, where processing also implies
+ immediate failing; thus, if a sdev is in one of the two
+ states, no further recovery action is needed.
+
+ Device readiness is tested using scsi_eh_tur() which issues
+ TEST_UNIT_READY command. Note that the scmd must have been
+ aborted successfully before reusing it for TEST_UNIT_READY.
+
+ 4. If !list_empty(&eh_work_q), invoke scsi_eh_ready_devs()
+
+ <<scsi_eh_ready_devs>>
+
+ This function takes four increasingly more severe measures to
+ make failed sdevs ready for new commands.
+
+ 1. Invoke scsi_eh_stu()
+
+ <<scsi_eh_stu>>
+
+ For each sdev which has failed scmds with valid sense data
+ of which scsi_check_sense()'s verdict is FAILED,
+ START_STOP_UNIT command is issued w/ start=1. Note that
+ as we explicitly choose error-completed scmds, it is known
+ that lower layers have forgotten about the scmd and we can
+ reuse it for STU.
+
+ If STU succeeds and the sdev is either offline or ready,
+ all failed scmds on the sdev are EH-finished with
+ scsi_eh_finish_cmd().
+
+ *NOTE* If hostt->eh_abort_handler() isn't implemented or
+ failed, we may still have timed out scmds at this point
+ and STU doesn't make lower layers forget about those
+ scmds. Yet, this function EH-finish all scmds on the sdev
+ if STU succeeds leaving lower layers in an inconsistent
+ state. It seems that STU action should be taken only when
+ a sdev has no timed out scmd.
+
+ 2. If !list_empty(&eh_work_q), invoke scsi_eh_bus_device_reset().
+
+ <<scsi_eh_bus_device_reset>>
+
+ This action is very similar to scsi_eh_stu() except that,
+ instead of issuing STU, hostt->eh_device_reset_handler()
+ is used. Also, as we're not issuing SCSI commands and
+ resetting clears all scmds on the sdev, there is no need
+ to choose error-completed scmds.
+
+ 3. If !list_empty(&eh_work_q), invoke scsi_eh_bus_reset()
+
+ <<scsi_eh_bus_reset>>
+
+ hostt->eh_bus_reset_handler() is invoked for each channel
+ with failed scmds. If bus reset succeeds, all failed
+ scmds on all ready or offline sdevs on the channel are
+ EH-finished.
+
+ 4. If !list_empty(&eh_work_q), invoke scsi_eh_host_reset()
+
+ <<scsi_eh_host_reset>>
+
+ This is the last resort. hostt->eh_host_reset_handler()
+ is invoked. If host reset succeeds, all failed scmds on
+ all ready or offline sdevs on the host are EH-finished.
+
+ 5. If !list_empty(&eh_work_q), invoke scsi_eh_offline_sdevs()
+
+ <<scsi_eh_offline_sdevs>>
+
+ Take all sdevs which still have unrecovered scmds offline
+ and EH-finish the scmds.
+
+ 5. Invoke scsi_eh_flush_done_q().
+
+ <<scsi_eh_flush_done_q>>
+
+ At this point all scmds are recovered (or given up) and
+ put on eh_done_q by scsi_eh_finish_cmd(). This function
+ flushes eh_done_q by either retrying or notifying upper
+ layer of failure of the scmds.
+
+
+[2-2] EH through hostt->eh_strategy_handler()
+
+ hostt->eh_strategy_handler() is invoked in the place of
+scsi_unjam_host() and it is responsible for whole recovery process.
+On completion, the handler should have made lower layers forget about
+all failed scmds and either ready for new commands or offline. Also,
+it should perform SCSI EH maintenance choirs to maintain integrity of
+SCSI midlayer. IOW, of the steps described in [2-1-2], all steps
+except for #1 must be implemented by eh_strategy_handler().
+
+
+[2-2-1] Pre hostt->eh_strategy_handler() SCSI midlayer conditions
+
+ The following conditions are true on entry to the handler.
+
+ - Each failed scmd's eh_flags field is set appropriately.
+
+ - Each failed scmd is linked on scmd->eh_cmd_q by scmd->eh_entry.
+
+ - SHOST_RECOVERY is set.
+
+ - shost->host_failed == shost->host_busy
+
+
+[2-2-2] Post hostt->eh_strategy_handler() SCSI midlayer conditions
+
+ The following conditions must be true on exit from the handler.
+
+ - shost->host_failed is zero.
+
+ - Each scmd's eh_eflags field is cleared.
+
+ - Each scmd is in such a state that scsi_setup_cmd_retry() on the
+ scmd doesn't make any difference.
+
+ - shost->eh_cmd_q is cleared.
+
+ - Each scmd->eh_entry is cleared.
+
+ - Either scsi_queue_insert() or scsi_finish_command() is called on
+ each scmd. Note that the handler is free to use scmd->retries and
+ ->allowed to limit the number of retries.
+
+
+[2-2-3] Things to consider
+
+ - Know that timed out scmds are still active on lower layers. Make
+ lower layers forget about them before doing anything else with
+ those scmds.
+
+ - For consistency, when accessing/modifying shost data structure,
+ grab shost->host_lock.
+
+ - On completion, each failed sdev must have forgotten about all
+ active scmds.
+
+ - On completion, each failed sdev must be ready for new commands or
+ offline.
+
+
+--
+Tejun Heo
+htejun@gmail.com
+11th September 2005
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 5c49ba07e709..13cba955cb5a 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -75,7 +75,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
adsp_map - PCM device number maps assigned to the 2st OSS device.
- Default: 1
nonblock_open
- - Don't block opening busy PCM devices.
+ - Don't block opening busy PCM devices. Default: 1
For example, when dsp_map=2, /dev/dsp will be mapped to PCM #2 of
the card #0. Similarly, when adsp_map=0, /dev/adsp will be mapped
@@ -148,6 +148,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module supports up to 8 cards. This module does not support autoprobe
thus main port must be specified!!! Other ports are optional.
+ Module snd-ad1889
+ -----------------
+
+ Module for Analog Devices AD1889 chips.
+
+ ac97_quirk - AC'97 workaround for strange hardware
+ See the description of intel8x0 module for details.
+
+ This module supports up to 8 cards.
+
Module snd-ali5451
------------------
@@ -189,15 +199,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-atiixp
-----------------
- Module for ATI IXP 150/200/250 AC97 controllers.
+ Module for ATI IXP 150/200/250/400 AC97 controllers.
- ac97_clock - AC'97 clock (defalut = 48000)
+ ac97_clock - AC'97 clock (default = 48000)
ac97_quirk - AC'97 workaround for strange hardware
- See the description of intel8x0 module for details.
+ See "AC97 Quirk Option" section below.
spdif_aclink - S/PDIF transfer over AC-link (default = 1)
This module supports up to 8 cards and autoprobe.
+ ATI IXP has two different methods to control SPDIF output. One is
+ over AC-link and another is over the "direct" SPDIF output. The
+ implementation depends on the motherboard, and you'll need to
+ choose the correct one via spdif_aclink module option.
+
Module snd-atiixp-modem
-----------------------
@@ -230,7 +245,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The hardware EQ hardware and SPDIF is only present in the Vortex2 and
Advantage.
- Note: Some ALSA mixer applicactions don't handle the SPDIF samplerate
+ Note: Some ALSA mixer applications don't handle the SPDIF sample rate
control correctly. If you have problems regarding this, try
another ALSA compliant mixer (alsamixer works).
@@ -302,7 +317,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_port - 0x300,0x310,0x320,0x330, 0 = disable (default)
fm_port - 0x388 (default), 0 = disable (default)
- soft_ac3 - Sofware-conversion of raw SPDIF packets (model 033 only)
+ soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only)
(default = 1)
joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
@@ -384,7 +399,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for PCI sound cards based on CS4610/CS4612/CS4614/CS4615/CS4622/
CS4624/CS4630/CS4280 PCI chips.
- external_amp - Force to enable external amplifer.
+ external_amp - Force to enable external amplifier.
thinkpad - Force to enable Thinkpad's CLKRUN control.
mmap_valid - Support OSS mmap mode (default = 0).
@@ -620,7 +635,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
VIA VT8251/VT8237A
model - force the model name
- position_fix - Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)
+ position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
Module supports up to 8 cards.
@@ -656,6 +671,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
allout 5-jack in back, 2-jack in front, SPDIF out
auto auto-config reading BIOS (default)
+ If the default configuration doesn't work and one of the above
+ matches with your device, report it together with the PCI
+ subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
+ ML (see the section "Links and Addresses").
+
Note 2: If you get click noises on output, try the module option
position_fix=1 or 2. position_fix=1 will use the SD_LPIB
register value without FIFO size correction as the current
@@ -783,20 +803,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_clock - AC'97 codec clock base (0 = auto-detect)
ac97_quirk - AC'97 workaround for strange hardware
- The following strings are accepted:
- default = don't override the default setting
- disable = disable the quirk
- hp_only = use headphone control as master
- swap_hp = swap headphone and master controls
- swap_surround = swap master and surround controls
- ad_sharing = for AD1985, turn on OMS bit and use headphone
- alc_jack = for ALC65x, turn on the jack sense mode
- inv_eapd = inverted EAPD implementation
- mute_led = bind EAPD bit for turning on/off mute LED
- For backward compatibility, the corresponding integer
- value -1, 0, ... are accepted, too.
+ See "AC97 Quirk Option" section below.
buggy_irq - Enable workaround for buggy interrupts on some
- motherboards (default off)
+ motherboards (default yes on nForce chips,
+ otherwise off)
+ buggy_semaphore - Enable workaround for hardwares with buggy
+ semaphores (e.g. on some ASUS laptops)
+ (default off)
Module supports autoprobe and multiple bus-master chips (max 8).
@@ -808,13 +821,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
motherboard has these devices, use the ns558 or snd-mpu401
modules, respectively.
- The ac97_quirk option is used to enable/override the workaround
- for specific devices. Some hardware have swapped output pins
- between Master and Headphone, or Surround. The driver provides
- the auto-detection of known problematic devices, but some might
- be unknown or wrongly detected. In such a case, pass the proper
- value with this option.
-
The power-management is supported.
Module snd-intel8x0m
@@ -966,7 +972,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
with machines with other (most likely CS423x or OPL3SAx) chips,
even though the device is detected in lspci. In such a case, try
other drivers, e.g. snd-cs4232 or snd-opl3sa2. Some has ISA-PnP
- but some doesn't have ISA PnP. You'll need to speicfy isapnp=0
+ but some doesn't have ISA PnP. You'll need to specify isapnp=0
and proper hardware parameters in the case without ISA PnP.
Note: some laptops need a workaround for AC97 RESET. For the
@@ -1302,7 +1308,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
channels
[VIA8233/C, 8235, 8237 only]
ac97_quirk - AC'97 workaround for strange hardware
- See the description of intel8x0 module for details.
+ See "AC97 Quirk Option" section below.
Module supports autoprobe and multiple bus-master chips (max 8).
@@ -1327,16 +1333,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
"lspci -nv").
If dxs_support=5 does not work, try dxs_support=4; if it
doesn't work too, try dxs_support=1. (dxs_support=1 is
- usually for old motherboards. The correct implementated
+ usually for old motherboards. The correct implemented
board should work with 4 or 5.) If it still doesn't
work and the default setting is ok, dxs_support=3 is the
right choice. If the default setting doesn't work at all,
try dxs_support=2 to disable the DXS channels.
In any cases, please let us know the result and the
- subsystem vendor/device ids.
+ subsystem vendor/device ids. See "Links and Addresses"
+ below.
Note: for the MPU401 on VIA823x, use snd-mpu401 driver
- additonally. The mpu_port option is for VIA686 chips only.
+ additionally. The mpu_port option is for VIA686 chips only.
Module snd-via82xx-modem
------------------------
@@ -1398,8 +1405,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module supports up to 8 cards. The module is compiled only when
PCMCIA is supported on kernel.
- To activate the driver via the card manager, you'll need to set
- up /etc/pcmcia/vxpocket.conf. See the sound/pcmcia/vx/vxpocket.c.
+ With the older 2.6.x kernel, to activate the driver via the card
+ manager, you'll need to set up /etc/pcmcia/vxpocket.conf. See the
+ sound/pcmcia/vx/vxpocket.c. 2.6.13 or later kernel requires no
+ longer require a config file.
When the driver is compiled as a module and the hotplug firmware
is supported, the firmware data is loaded via hotplug automatically.
@@ -1411,6 +1420,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: the driver is build only when CONFIG_ISA is set.
+ Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
+ ALSA 1.0.10.
+
Module snd-ymfpci
-----------------
@@ -1436,6 +1448,37 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: the driver is build only when CONFIG_ISA is set.
+AC97 Quirk Option
+=================
+
+The ac97_quirk option is used to enable/override the workaround for
+specific devices on drivers for on-board AC'97 controllers like
+snd-intel8x0. Some hardware have swapped output pins between Master
+and Headphone, or Surround (thanks to confusion of AC'97
+specifications from version to version :-)
+
+The driver provides the auto-detection of known problematic devices,
+but some might be unknown or wrongly detected. In such a case, pass
+the proper value with this option.
+
+The following strings are accepted:
+ - default Don't override the default setting
+ - disable Disable the quirk
+ - hp_only Bind Master and Headphone controls as a single control
+ - swap_hp Swap headphone and master controls
+ - swap_surround Swap master and surround controls
+ - ad_sharing For AD1985, turn on OMS bit and use headphone
+ - alc_jack For ALC65x, turn on the jack sense mode
+ - inv_eapd Inverted EAPD implementation
+ - mute_led Bind EAPD bit for turning on/off mute LED
+
+For backward compatibility, the corresponding integer value -1, 0,
+... are accepted, too.
+
+For example, if "Master" volume control has no effect on your device
+but only "Headphone" does, pass ac97_quirk=hp_only module option.
+
+
Configuring Non-ISAPNP Cards
============================
@@ -1459,7 +1502,7 @@ devices where %i is sound card number from zero to seven.
To auto-load an ALSA driver for OSS services, define the string
'sound-slot-%i' where %i means the slot number for OSS, which
corresponds to the card index of ALSA. Usually, define this
-as the the same card module.
+as the same card module.
An example configuration for a single emu10k1 card is like below:
----- /etc/modprobe.conf
@@ -1553,6 +1596,8 @@ Proc interfaces (/proc/asound)
- whole-frag write only whole fragments (optimization affecting
playback only)
- no-silence do not fill silence ahead to avoid clicks
+ - buggy-ptr Returns the whitespace blocks in GETOPTR ioctl
+ instead of filled blocks
Example: echo "x11amp 128 16384" > /proc/asound/card0/pcm0p/oss
echo "squake 0 0 disable" > /proc/asound/card0/pcm0c/oss
@@ -1589,9 +1634,14 @@ commands to the snd-page-alloc driver:
use.
-Links
-=====
+Links and Addresses
+===================
ALSA project homepage
http://www.alsa-project.org
+ ALSA Bug Tracking System
+ https://bugtrack.alsa-project.org/bugs/
+
+ ALSA Developers ML
+ mailto:alsa-devel@lists.sourceforge.net
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 0475478c2484..24e85520890b 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -447,7 +447,7 @@
....
/* allocate a chip-specific data with zero filled */
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
@@ -949,7 +949,7 @@
After allocating a card instance via
<function>snd_card_new()</function> (with
<constant>NULL</constant> on the 4th arg), call
- <function>kcalloc()</function>.
+ <function>kzalloc()</function>.
<informalexample>
<programlisting>
@@ -958,7 +958,7 @@
mychip_t *chip;
card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
.....
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
]]>
</programlisting>
</informalexample>
@@ -1136,7 +1136,7 @@
return -ENXIO;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1292,7 +1292,7 @@
need to initialize this number as -1 before actual allocation,
since irq 0 is valid. The port address and its resource pointer
can be initialized as null by
- <function>kcalloc()</function> automatically, so you
+ <function>kzalloc()</function> automatically, so you
don't have to take care of resetting them.
</para>
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index f97841478459..1829009db771 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -51,13 +51,13 @@ or you don't get any checking at all.
Where to get sparse
~~~~~~~~~~~~~~~~~~~
-With BK, you can just get it from
+With git, you can just get it from
- bk://sparse.bkbits.net/sparse
+ rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git
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/sysrq.txt b/Documentation/sysrq.txt
index 136d817c01ba..baf17b381588 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -171,7 +171,7 @@ the header 'include/linux/sysrq.h', this will define everything else you need.
Next, you must create a sysrq_key_op struct, and populate it with A) the key
handler function you will use, B) a help_msg string, that will print when SysRQ
prints help, and C) an action_msg string, that will print right before your
-handler is called. Your handler must conform to the protoype in 'sysrq.h'.
+handler is called. Your handler must conform to the prototype in 'sysrq.h'.
After the sysrq_key_op is created, you can call the macro
register_sysrq_key(int key, struct sysrq_key_op *op_p) that is defined in
diff --git a/Documentation/uml/UserModeLinux-HOWTO.txt b/Documentation/uml/UserModeLinux-HOWTO.txt
index 0c7b654fec99..544430e39980 100644
--- a/Documentation/uml/UserModeLinux-HOWTO.txt
+++ b/Documentation/uml/UserModeLinux-HOWTO.txt
@@ -2176,7 +2176,7 @@
If you want to access files on the host machine from inside UML, you
can treat it as a separate machine and either nfs mount directories
from the host or copy files into the virtual machine with scp or rcp.
- However, since UML is running on the the host, it can access those
+ However, since UML is running on the host, it can access those
files just like any other process and make them available inside the
virtual machine without needing to use the network.
diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt
index d59b95cc6f1b..a49e5f2c2b46 100644
--- a/Documentation/usb/URB.txt
+++ b/Documentation/usb/URB.txt
@@ -1,5 +1,6 @@
Revised: 2000-Dec-05.
Again: 2002-Jul-06
+Again: 2005-Sep-19
NOTE:
@@ -18,8 +19,8 @@ called USB Request Block, or URB for short.
and deliver the data and status back.
- Execution of an URB is inherently an asynchronous operation, i.e. the
- usb_submit_urb(urb) call returns immediately after it has successfully queued
- the requested action.
+ usb_submit_urb(urb) call returns immediately after it has successfully
+ queued the requested action.
- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.
@@ -94,8 +95,9 @@ To free an URB, use
void usb_free_urb(struct urb *urb)
-You may not free an urb that you've submitted, but which hasn't yet been
-returned to you in a completion callback.
+You may free an urb that you've submitted, but which hasn't yet been
+returned to you in a completion callback. It will automatically be
+deallocated when it is no longer in use.
1.4. What has to be filled in?
@@ -145,30 +147,36 @@ to get seamless ISO streaming.
1.6. How to cancel an already running URB?
-For an URB which you've submitted, but which hasn't been returned to
-your driver by the host controller, call
+There are two ways to cancel an URB you've submitted but which hasn't
+been returned to your driver yet. For an asynchronous cancel, call
int usb_unlink_urb(struct urb *urb)
It removes the urb from the internal list and frees all allocated
-HW descriptors. The status is changed to reflect unlinking. After
-usb_unlink_urb() returns with that status code, you can free the URB
-with usb_free_urb().
+HW descriptors. The status is changed to reflect unlinking. Note
+that the URB will not normally have finished when usb_unlink_urb()
+returns; you must still wait for the completion handler to be called.
-There is also an asynchronous unlink mode. To use this, set the
-the URB_ASYNC_UNLINK flag in urb->transfer flags before calling
-usb_unlink_urb(). When using async unlinking, the URB will not
-normally be unlinked when usb_unlink_urb() returns. Instead, wait
-for the completion handler to be called.
+To cancel an URB synchronously, call
+
+ void usb_kill_urb(struct urb *urb)
+
+It does everything usb_unlink_urb does, and in addition it waits
+until after the URB has been returned and the completion handler
+has finished. It also marks the URB as temporarily unusable, so
+that if the completion handler or anyone else tries to resubmit it
+they will get a -EPERM error. Thus you can be sure that when
+usb_kill_urb() returns, the URB is totally idle.
1.7. What about the completion handler?
The handler is of the following type:
- typedef void (*usb_complete_t)(struct urb *);
+ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)
-i.e. it gets just the URB that caused the completion call.
+I.e., it gets the URB that caused the completion call, plus the
+register values at the time of the corresponding interrupt (if any).
In the completion handler, you should have a look at urb->status to
detect any USB errors. Since the context parameter is included in the URB,
you can pass information to the completion handler.
@@ -176,17 +184,11 @@ you can pass information to the completion handler.
Note that even when an error (or unlink) is reported, data may have been
transferred. That's because USB transfers are packetized; it might take
sixteen packets to transfer your 1KByte buffer, and ten of them might
-have transferred succesfully before the completion is called.
+have transferred succesfully before the completion was called.
NOTE: ***** WARNING *****
-Don't use urb->dev field in your completion handler; it's cleared
-as part of giving urbs back to drivers. (Addressing an issue with
-ownership of periodic URBs, which was otherwise ambiguous.) Instead,
-use urb->context to hold all the data your driver needs.
-
-NOTE: ***** WARNING *****
-Also, NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
+NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
during hardware interrupt processing. If you can, defer substantial
work to a tasklet (bottom half) to keep system latencies low. You'll
probably need to use spinlocks to protect data structures you manipulate
@@ -229,24 +231,10 @@ ISO data with some other event stream.
Interrupt transfers, like isochronous transfers, are periodic, and happen
in intervals that are powers of two (1, 2, 4 etc) units. Units are frames
for full and low speed devices, and microframes for high speed ones.
-
-Currently, after you submit one interrupt URB, that urb is owned by the
-host controller driver until you cancel it with usb_unlink_urb(). You
-may unlink interrupt urbs in their completion handlers, if you need to.
-
-After a transfer completion is called, the URB is automagically resubmitted.
-THIS BEHAVIOR IS EXPECTED TO BE REMOVED!!
-
-Interrupt transfers may only send (or receive) the "maxpacket" value for
-the given interrupt endpoint; if you need more data, you will need to
-copy that data out of (or into) another buffer. Similarly, you can't
-queue interrupt transfers.
-THESE RESTRICTIONS ARE EXPECTED TO BE REMOVED!!
-
-Note that this automagic resubmission model does make it awkward to use
-interrupt OUT transfers. The portable solution involves unlinking those
-OUT urbs after the data is transferred, and perhaps submitting a final
-URB for a short packet.
-
The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value.
+
+In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
+restarted when they complete. They end when the completion handler is
+called, just like other URBs. If you want an interrupt URB to be restarted,
+your completion handler must resubmit it.
diff --git a/Documentation/usb/gadget_serial.txt b/Documentation/usb/gadget_serial.txt
index a938c3dd13d6..815f5c2301ff 100644
--- a/Documentation/usb/gadget_serial.txt
+++ b/Documentation/usb/gadget_serial.txt
@@ -20,7 +20,7 @@ License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA.
-This document and the the gadget serial driver itself are
+This document and the gadget serial driver itself are
Copyright (C) 2004 by Al Borchers (alborchers@steinerpoint.com).
If you have questions, problems, or suggestions for this driver
diff --git a/Documentation/usb/proc_usb_info.txt b/Documentation/usb/proc_usb_info.txt
index 729c72d34c89..f86550fe38ee 100644
--- a/Documentation/usb/proc_usb_info.txt
+++ b/Documentation/usb/proc_usb_info.txt
@@ -20,7 +20,7 @@ the /proc/bus/usb/BBB/DDD files.
to /etc/fstab. This will mount usbfs at each reboot.
You can then issue `cat /proc/bus/usb/devices` to extract
- USB device information, and user mode drivers can use usbfs
+ USB device information, and user mode drivers can use usbfs
to interact with USB devices.
There are a number of mount options supported by usbfs.
@@ -32,7 +32,7 @@ the /proc/bus/usb/BBB/DDD files.
still see references to the older "usbdevfs" name.
For more information on mounting the usbfs file system, see the
-"USB Device Filesystem" section of the USB Guide. The latest copy
+"USB Device Filesystem" section of the USB Guide. The latest copy
of the USB Guide can be found at http://www.linux-usb.org/
@@ -133,7 +133,7 @@ B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
are the only transfers that reserve bandwidth. Control and bulk
transfers use all other bandwidth, including reserved bandwidth that
is not used for transfers (such as for short packets).
-
+
The percentage is how much of the "reserved" bandwidth is scheduled by
those transfers. For a low or full speed bus (loosely, "USB 1.1"),
90% of the bus bandwidth is reserved. For a high speed bus (loosely,
@@ -197,7 +197,7 @@ C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
| | |__NumberOfInterfaces
| |__ "*" indicates the active configuration (others are " ")
|__Config info tag
-
+
USB devices may have multiple configurations, each of which act
rather differently. For example, a bus-powered configuration
might be much less capable than one that is self-powered. Only
@@ -228,7 +228,7 @@ I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
For example, default settings may not use more than a small
amount of periodic bandwidth. To use significant fractions
of bus bandwidth, drivers must select a non-default altsetting.
-
+
Only one setting for an interface may be active at a time, and
only one driver may bind to an interface at a time. Most devices
have only one alternate setting per interface.
@@ -297,18 +297,21 @@ S: SerialNumber=dce0
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
+
T: Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 4
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0451 ProdID=1446 Rev= 1.00
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
+
T: Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=04b4 ProdID=0001 Rev= 0.00
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=mouse
E: Ad=81(I) Atr=03(Int.) MxPS= 3 Ivl= 10ms
+
T: Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0565 ProdID=0001 Rev= 1.08
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 62a12a08e2ac..ec785f9f15a3 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -126,10 +126,12 @@ card=124 - AverMedia AverTV DVB-T 761
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 1b5a3a9ffbe2..dc57225f39be 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 f3302e1b1b9c..f5876be658a6 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/Documentation/video4linux/Zoran b/Documentation/video4linux/Zoran
index 01425c21986b..52c94bd7dca1 100644
--- a/Documentation/video4linux/Zoran
+++ b/Documentation/video4linux/Zoran
@@ -222,7 +222,7 @@ was introduced in 1991, is used in the DC10 old
can generate: PAL , NTSC , SECAM
The adv717x, should be able to produce PAL N. But you find nothing PAL N
-specific in the the registers. Seem that you have to reuse a other standard
+specific in the registers. Seem that you have to reuse a other standard
to generate PAL N, maybe it would work if you use the PAL M settings.
==========================
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 678e8f192db2..ffe1c062088b 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -11,6 +11,11 @@ Machine check
If your BIOS doesn't do that it's a good idea to enable though
to make sure you log even machine check events that result
in a reboot.
+ mce=tolerancelevel (number)
+ 0: always panic, 1: panic if deadlock possible,
+ 2: try to avoid panic, 3: never panic or exit (for testing)
+ default is 1
+ Can be also set using sysfs which is preferable.
nomce (for compatibility with i386): same as mce=off
diff --git a/Kbuild b/Kbuild
new file mode 100644
index 000000000000..79003918f37f
--- /dev/null
+++ b/Kbuild
@@ -0,0 +1,49 @@
+#
+# Kbuild for top-level directory of the kernel
+# This file takes care of the following:
+# 1) Generate asm-offsets.h
+
+#####
+# 1) Generate asm-offsets.h
+#
+
+offsets-file := include/asm-$(ARCH)/asm-offsets.h
+
+always := $(offsets-file)
+targets := $(offsets-file)
+targets += arch/$(ARCH)/kernel/asm-offsets.s
+
+# Default sed regexp - multiline due to syntax constraints
+define sed-y
+ "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
+endef
+# Override default regexp for specific architectures
+sed-$(CONFIG_MIPS) := "/^@@@/s///p"
+
+quiet_cmd_offsets = GEN $@
+define cmd_offsets
+ mkdir -p $(dir $@); \
+ cat $< | \
+ (set -e; \
+ echo "#ifndef __ASM_OFFSETS_H__"; \
+ echo "#define __ASM_OFFSETS_H__"; \
+ echo "/*"; \
+ echo " * DO NOT MODIFY."; \
+ echo " *"; \
+ echo " * This file was generated by $(srctree)/Kbuild"; \
+ echo " *"; \
+ echo " */"; \
+ echo ""; \
+ sed -ne $(sed-y); \
+ echo ""; \
+ echo "#endif" ) > $@
+endef
+
+# We use internal kbuild rules to avoid the "is up to date" message from make
+arch/$(ARCH)/kernel/asm-offsets.s: arch/$(ARCH)/kernel/asm-offsets.c FORCE
+ $(Q)mkdir -p $(dir $@)
+ $(call if_changed_dep,cc_s_c)
+
+$(obj)/$(offsets-file): arch/$(ARCH)/kernel/asm-offsets.s Kbuild
+ $(call cmd,offsets)
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 8e4e82921070..767fb610963e 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
@@ -364,7 +370,10 @@ W: http://atmelwlandriver.sourceforge.net/
S: Maintained
AUDIT SUBSYSTEM
-L: linux-audit@redhat.com (subscribers-only)
+P: David Woodhouse
+M: dwmw2@infradead.org
+L: linux-audit@redhat.com
+W: http://people.redhat.com/sgrubb/audit/
S: Maintained
AX.25 NETWORK LAYER
@@ -595,6 +604,15 @@ P: H. Peter Anvin
M: hpa@zytor.com
S: Maintained
+CPUSETS
+P: Paul Jackson
+P: Simon Derr
+M: pj@sgi.com
+M: simon.derr@bull.net
+L: linux-kernel@vger.kernel.org
+W: http://www.bullopensource.org/cpuset/
+S: Supported
+
CRAMFS FILESYSTEM
W: http://sourceforge.net/projects/cramfs/
S: Orphan
@@ -620,6 +638,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
@@ -671,6 +695,13 @@ P: Guennadi Liakhovetski
M: g.liakhovetski@gmx.de
S: Maintained
+DCCP PROTOCOL
+P: Arnaldo Carvalho de Melo
+M: acme@mandriva.com
+L: dccp@vger.kernel.org
+W: http://www.wlug.org.nz/DCCP
+S: Maintained
+
DECnet NETWORK LAYER
P: Patrick Caulfield
M: patrick@tykepenguin.com
@@ -919,6 +950,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
@@ -945,6 +983,13 @@ L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.nu/
S: Maintained
+HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
+P: Robert Love
+M: rlove@rlove.org
+M: linux-kernel@vger.kernel.org
+W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
+S: Maintained
+
HARMONY SOUND DRIVER
P: Kyle McMartin
M: kyle@parisc-linux.org
@@ -1027,8 +1072,6 @@ M: wli@holomorphy.com
S: Maintained
I2C SUBSYSTEM
-P: Greg Kroah-Hartman
-M: greg@kroah.com
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
@@ -1125,11 +1168,6 @@ L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
-IEEE 1394 SBP2
-L: linux1394-devel@lists.sourceforge.net
-W: http://www.linux1394.org/
-S: Orphan
-
IEEE 1394 SUBSYSTEM
P: Ben Collins
M: bcollins@debian.org
@@ -1164,6 +1202,15 @@ L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
+IEEE 1394 SBP2
+P: Ben Collins
+M: bcollins@debian.org
+P: Stefan Richter
+M: stefanr@s5r6.in-berlin.de
+L: linux1394-devel@lists.sourceforge.net
+W: http://www.linux1394.org/
+S: Maintained
+
IMS TWINTURBO FRAMEBUFFER DRIVER
P: Paul Mundt
M: lethal@chaoticdreams.org
@@ -1368,6 +1415,18 @@ L: linux-kernel@vger.kernel.org
L: fastboot@osdl.org
S: Maintained
+KPROBES
+P: Prasanna S Panchamukhi
+M: prasanna@in.ibm.com
+P: Ananth N Mavinakayanahalli
+M: ananth@in.ibm.com
+P: Anil S Keshavamurthy
+M: anil.s.keshavamurthy@intel.com
+P: David S. Miller
+M: davem@davemloft.net
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
LANMEDIA WAN CARD DRIVER
P: Andrew Stanley-Jones
M: asj@lanmedia.com
@@ -1559,6 +1618,13 @@ M: vandrove@vc.cvut.cz
L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained
+MEGARAID SCSI DRIVERS
+P: Neela Syam Kolli
+M: Neela.Kolli@engenio.com
+S: linux-scsi@vger.kernel.org
+W: http://megaraid.lsilogic.com
+S: Maintained
+
MEMORY TECHNOLOGY DEVICES
P: David Woodhouse
M: dwmw2@infradead.org
@@ -1688,8 +1754,11 @@ S: Maintained
IPVS
P: Wensong Zhang
M: wensong@linux-vs.org
+P: Simon Horman
+M: horms@verge.net.au
P: Julian Anastasov
M: ja@ssi.bg
+L: netdev@vger.kernel.org
S: Maintained
NFS CLIENT
@@ -1813,13 +1882,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
@@ -1867,6 +1929,13 @@ M: joern@wh.fh-wedel.de
L: linux-mtd@lists.infradead.org
S: Maintained
+PKTCDVD DRIVER
+P: Peter Osterlund
+M: petero2@telia.com
+L: linux-kernel@vger.kernel.org
+L: packet-writing@suse.com
+S: Maintained
+
POSIX CLOCKS and TIMERS
P: George Anzinger
M: george@mvista.com
@@ -2237,6 +2306,12 @@ M: kristen.c.accardi@intel.com
L: pcihpd-discuss@lists.sourceforge.net
S: Maintained
+SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
+P: Stephen Hemminger
+M: shemminger@osdl.org
+L: netdev@vger.kernel.org
+S: Maintained
+
SPARC (sparc32):
P: William L. Irwin
M: wli@holomorphy.com
@@ -2249,12 +2324,6 @@ M: R.E.Wolff@BitWizard.nl
L: linux-kernel@vger.kernel.org ?
S: Supported
-SPX NETWORK LAYER
-P: Jay Schulist
-M: jschlst@samba.org
-L: netdev@vger.kernel.org
-S: Supported
-
SRM (Alpha) environment access
P: Jan-Benedict Glaw
M: jbglaw@lug-owl.de
@@ -2685,6 +2754,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/Makefile b/Makefile
index 63e5c9f0bc7a..f1d121f23025 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 13
+SUBLEVEL = 14
EXTRAVERSION =
NAME=Affluent Albatross
@@ -334,7 +334,7 @@ KALLSYMS = scripts/kallsyms
PERL = perl
CHECK = sparse
-CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__
+CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
MODFLAGS = -DMODULE
CFLAGS_MODULE = $(MODFLAGS)
AFLAGS_MODULE = $(MODFLAGS)
@@ -372,7 +372,7 @@ export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_ve
# Files to ignore in find ... statements
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg \) -prune -o
-RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg
+export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg
# ===========================================================================
# Rules shared between *config targets and build targets
@@ -382,6 +382,9 @@ RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CV
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
+# To avoid any implicit rule to kick in, define an empty command.
+scripts/basic/%: scripts_basic ;
+
.PHONY: outputmakefile
# outputmakefile generate a Makefile to be placed in output directory, if
# using a seperate output directory. This allows convinient use
@@ -444,9 +447,8 @@ ifeq ($(config-targets),1)
include $(srctree)/arch/$(ARCH)/Makefile
export KBUILD_DEFCONFIG
-config: scripts_basic outputmakefile FORCE
- $(Q)$(MAKE) $(build)=scripts/kconfig $@
-%config: scripts_basic outputmakefile FORCE
+config %config: scripts_basic outputmakefile FORCE
+ $(Q)mkdir -p include/linux
$(Q)$(MAKE) $(build)=scripts/kconfig $@
else
@@ -489,6 +491,7 @@ include .config
# If .config is newer than include/linux/autoconf.h, someone tinkered
# with it and forgot to run make oldconfig
include/linux/autoconf.h: .config
+ $(Q)mkdir -p include/linux
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else
# Dummy target needed, because used as prerequisite
@@ -641,8 +644,13 @@ quiet_cmd_vmlinux__ ?= LD $@
# Generate new vmlinux version
quiet_cmd_vmlinux_version = GEN .version
cmd_vmlinux_version = set -e; \
- . $(srctree)/scripts/mkversion > .tmp_version; \
- mv -f .tmp_version .version; \
+ if [ ! -r .version ]; then \
+ rm -f .version; \
+ echo 1 >.version; \
+ else \
+ mv .version .old_version; \
+ expr 0$$(cat .old_version) + 1 >.version; \
+ fi; \
$(MAKE) $(build)=init
# Generate System.map
@@ -652,8 +660,10 @@ quiet_cmd_sysmap = SYSMAP
# Link of vmlinux
# If CONFIG_KALLSYMS is set .version is already updated
# Generate System.map and verify that the content is consistent
-
+# Use + in front of the vmlinux_version rule to silent warning with make -j2
+# First command is ':' to allow us to use + in front of the rule
define rule_vmlinux__
+ :
$(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))
$(call cmd,vmlinux__)
@@ -756,6 +766,7 @@ endif # ifdef CONFIG_KALLSYMS
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
$(call if_changed_rule,vmlinux__)
+ $(Q)rm -f .old_version
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
@@ -768,22 +779,27 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
# Error messages still appears in the original language
.PHONY: $(vmlinux-dirs)
-$(vmlinux-dirs): prepare-all scripts
+$(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
# Things we need to do before we recursively start building the kernel
-# or the modules are listed in "prepare-all".
-# A multi level approach is used. prepare1 is updated first, then prepare0.
-# prepare-all is the collection point for the prepare targets.
+# or the modules are listed in "prepare".
+# A multi level approach is used. prepareN is processed before prepareN-1.
+# archprepare is used in arch Makefiles and when processed asm symlink,
+# version.h and scripts_basic is processed / created.
-.PHONY: prepare-all prepare prepare0 prepare1 prepare2
+# Listed in dependency order
+.PHONY: prepare archprepare prepare0 prepare1 prepare2 prepare3
-# prepare2 is used to check if we are building in a separate output directory,
+# prepare-all is deprecated, use prepare as valid replacement
+.PHONY: prepare-all
+
+# prepare3 is used to check if we are building in a separate output directory,
# and if so do:
# 1) Check that make has not been executed in the kernel src $(srctree)
# 2) Create the include2 directory, used for the second asm symlink
-prepare2:
+prepare3:
ifneq ($(KBUILD_SRC),)
@echo ' Using $(srctree) as source for kernel'
$(Q)if [ -f $(srctree)/.config ]; then \
@@ -795,18 +811,23 @@ ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
endif
-# prepare1 creates a makefile if using a separate output directory
-prepare1: prepare2 outputmakefile
+# prepare2 creates a makefile if using a separate output directory
+prepare2: prepare3 outputmakefile
-prepare0: prepare1 include/linux/version.h include/asm \
+prepare1: prepare2 include/linux/version.h include/asm \
include/config/MARKER
ifneq ($(KBUILD_MODULES),)
$(Q)rm -rf $(MODVERDIR)
$(Q)mkdir -p $(MODVERDIR)
endif
+archprepare: prepare1 scripts_basic
+
+prepare0: archprepare FORCE
+ $(Q)$(MAKE) $(build)=.
+
# All the preparing..
-prepare-all: prepare0 prepare
+prepare prepare-all: prepare0
# Leave this as default for preprocessing vmlinux.lds.S, which is now
# done in arch/$(ARCH)/kernel/Makefile
@@ -845,7 +866,7 @@ include/asm:
# Split autoconf.h into include/linux/config/*
-include/config/MARKER: include/linux/autoconf.h
+include/config/MARKER: scripts/basic/split-include include/linux/autoconf.h
@echo ' SPLIT include/linux/autoconf.h -> include/config/*'
@scripts/basic/split-include include/linux/autoconf.h include/config
@touch $@
@@ -897,7 +918,7 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
# Target to prepare building external modules
.PHONY: modules_prepare
-modules_prepare: prepare-all scripts
+modules_prepare: prepare scripts
# Target to install modules
.PHONY: modules_install
@@ -949,26 +970,6 @@ modules modules_install: FORCE
endif # CONFIG_MODULES
-# Generate asm-offsets.h
-# ---------------------------------------------------------------------------
-
-define filechk_gen-asm-offsets
- (set -e; \
- echo "#ifndef __ASM_OFFSETS_H__"; \
- echo "#define __ASM_OFFSETS_H__"; \
- echo "/*"; \
- echo " * DO NOT MODIFY."; \
- echo " *"; \
- echo " * This file was generated by arch/$(ARCH)/Makefile"; \
- echo " *"; \
- echo " */"; \
- echo ""; \
- sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \
- echo ""; \
- echo "#endif" )
-endef
-
-
###
# Cleaning is done on three levels.
# make clean Delete most generated files
@@ -991,7 +992,7 @@ MRPROPER_FILES += .config .config.old include/asm .version \
#
clean: rm-dirs := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES)
-clean-dirs := $(addprefix _clean_,$(vmlinux-alldirs))
+clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs))
.PHONY: $(clean-dirs) clean archclean
$(clean-dirs):
@@ -1070,6 +1071,7 @@ help:
@echo ' rpm - Build a kernel as an RPM package'
@echo ' tags/TAGS - Generate tags file for editors'
@echo ' cscope - Generate cscope index'
+ @echo ' kernelrelease - Output the release version string'
@echo ''
@echo 'Static analysers'
@echo ' buildcheck - List dangling references to vmlinux discarded sections'
diff --git a/README b/README
index 76dd780d88ed..d1edcc7adabe 100644
--- a/README
+++ b/README
@@ -149,6 +149,9 @@ CONFIGURING the kernel:
"make gconfig" X windows (Gtk) based configuration tool.
"make oldconfig" Default all questions based on the contents of
your existing ./.config file.
+ "make silentoldconfig"
+ Like above, but avoids cluttering the screen
+ with questions already answered.
NOTES on "make config":
- having unnecessary drivers will make the kernel bigger, and can
@@ -169,9 +172,6 @@ CONFIGURING the kernel:
should probably answer 'n' to the questions for
"development", "experimental", or "debugging" features.
- - Check the top Makefile for further site-dependent configuration
- (default SVGA mode etc).
-
COMPILING the kernel:
- Make sure you have gcc 2.95.3 available.
@@ -199,6 +199,9 @@ COMPILING the kernel:
are installing a new kernel with the same version number as your
working kernel, make a backup of your modules directory before you
do a "make modules_install".
+ Alternatively, before compiling, use the kernel config option
+ "LOCALVERSION" to append a unique suffix to the regular kernel version.
+ LOCALVERSION can be set in the "General Setup" menu.
- In order to boot your new kernel, you'll need to copy the kernel
image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
diff --git a/REPORTING-BUGS b/REPORTING-BUGS
index 224c34741d32..f9da827a0c18 100644
--- a/REPORTING-BUGS
+++ b/REPORTING-BUGS
@@ -9,7 +9,7 @@ screen please read "Documentation/oops-tracing.txt" before posting your
bug report. This explains what you should do with the "Oops" information
to make it useful to the recipient.
- Send the output the maintainer of the kernel area that seems to
+ Send the output to the maintainer of the kernel area that seems to
be involved with the problem. Don't worry too much about getting the
wrong person. If you are unsure send it to the person responsible for the
code relevant to what you were doing. If it occurs repeatably try and
@@ -18,15 +18,15 @@ The list of maintainers is in the MAINTAINERS file in this directory.
If it is a security bug, please copy the Security Contact listed
in the MAINTAINERS file. They can help coordinate bugfix and disclosure.
-See Documentation/SecurityBugs for more infomation.
+See Documentation/SecurityBugs for more information.
If you are totally stumped as to whom to send the report, send it to
linux-kernel@vger.kernel.org. (For more information on the linux-kernel
mailing list see http://www.tux.org/lkml/).
-This is a suggested format for a bug report sent to the Linux kernel mailing
-list. Having a standardized bug report form makes it easier for you not to
-overlook things, and easier for the developers to find the pieces of
+This is a suggested format for a bug report sent to the Linux kernel mailing
+list. Having a standardized bug report form makes it easier for you not to
+overlook things, and easier for the developers to find the pieces of
information they're really interested in. Don't feel you have to follow it.
First run the ver_linux script included as scripts/ver_linux, which
@@ -35,9 +35,9 @@ the command "sh scripts/ver_linux".
Use that information to fill in all fields of the bug report form, and
post it to the mailing list with a subject of "PROBLEM: <one line
-summary from [1.]>" for easy identification by the developers
+summary from [1.]>" for easy identification by the developers.
-[1.] One line summary of the problem:
+[1.] One line summary of the problem:
[2.] Full description of the problem/report:
[3.] Keywords (i.e., modules, networking, kernel):
[4.] Kernel version (from /proc/version):
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 22ebfb2be0e4..1b704ee54bf3 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -108,20 +108,9 @@ $(boot)/vmlinux.gz: vmlinux
bootimage bootpfile bootpzfile: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
-
-prepare: include/asm-$(ARCH)/asm_offsets.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/asm_offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h
-
define archhelp
echo '* boot - Compressed kernel image (arch/alpha/boot/vmlinux.gz)'
echo ' bootimage - SRM bootable image (arch/alpha/boot/bootimage)'
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index fc5ef90c4fc9..24ae9a366073 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -185,15 +185,6 @@ EXPORT_SYMBOL(smp_num_cpus);
EXPORT_SYMBOL(smp_call_function);
EXPORT_SYMBOL(smp_call_function_on_cpu);
EXPORT_SYMBOL(_atomic_dec_and_lock);
-#ifdef CONFIG_DEBUG_SPINLOCK
-EXPORT_SYMBOL(_raw_spin_unlock);
-EXPORT_SYMBOL(debug_spin_lock);
-EXPORT_SYMBOL(debug_spin_trylock);
-#endif
-#ifdef CONFIG_DEBUG_RWLOCK
-EXPORT_SYMBOL(_raw_write_lock);
-EXPORT_SYMBOL(_raw_read_lock);
-#endif
EXPORT_SYMBOL(cpu_present_mask);
#endif /* CONFIG_SMP */
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index f0927ee53f29..e38671c922bc 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -5,7 +5,7 @@
*/
#include <linux/config.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/pal.h>
#include <asm/errno.h>
@@ -196,6 +196,7 @@ entUna:
stq $26, 208($sp)
stq $27, 216($sp)
stq $28, 224($sp)
+ mov $sp, $19
stq $gp, 232($sp)
lda $8, 0x3fff
stq $31, 248($sp)
diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S
index 4ca2e404708a..0905721fcbca 100644
--- a/arch/alpha/kernel/head.S
+++ b/arch/alpha/kernel/head.S
@@ -9,7 +9,7 @@
#include <linux/config.h>
#include <asm/system.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.globl swapper_pg_dir
.globl _stext
diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index fc271e316a38..aac6d4b22f7a 100644
--- a/arch/alpha/kernel/module.c
+++ b/arch/alpha/kernel/module.c
@@ -47,7 +47,7 @@ module_free(struct module *mod, void *module_region)
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 167fd89f8707..01fe990d3e54 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -37,6 +37,7 @@
#include <linux/namei.h>
#include <linux/uio.h>
#include <linux/vfs.h>
+#include <linux/rcupdate.h>
#include <asm/fpu.h>
#include <asm/io.h>
@@ -974,6 +975,8 @@ 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;
+ int max_fdset;
timeout = MAX_SCHEDULE_TIMEOUT;
if (tvp) {
@@ -995,7 +998,11 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
}
}
- if (n < 0 || n > current->files->max_fdset)
+ rcu_read_lock();
+ fdt = files_fdtable(current->files);
+ max_fdset = fdt->max_fdset;
+ rcu_read_unlock();
+ if (n < 0 || n > max_fdset)
goto out_nofds;
/*
@@ -1152,8 +1159,7 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai
ticks = timeval_to_jiffies(&tmp);
- current->state = TASK_INTERRUPTIBLE;
- ticks = schedule_timeout(ticks);
+ ticks = schedule_timeout_interruptible(ticks);
if (remain) {
jiffies_to_timeval(ticks, &tmp);
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 582a3519fb28..9903e3a79102 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -154,7 +154,7 @@ pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
void *
dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 7cb23f12ecbd..c468e312e5f8 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -397,7 +397,7 @@ pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
{
void *cpu_addr;
long order = get_order(size);
- int gfp = GFP_ATOMIC;
+ gfp_t gfp = GFP_ATOMIC;
try_again:
cpu_addr = (void *)__get_free_pages(gfp, order);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index fa98dae3cd98..eb20c3afff58 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -127,6 +127,10 @@ common_shutdown_1(void *generic_ptr)
/* If booted from SRM, reset some of the original environment. */
if (alpha_using_srm) {
#ifdef CONFIG_DUMMY_CONSOLE
+ /* If we've gotten here after SysRq-b, leave interrupt
+ context before taking over the console. */
+ if (in_interrupt())
+ irq_exit();
/* This has the effect of resetting the VGA video origin. */
take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
#endif
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index e211aa7404e6..da0be3465791 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -989,175 +989,3 @@ flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
preempt_enable();
}
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-void
-_raw_spin_unlock(spinlock_t * lock)
-{
- mb();
- lock->lock = 0;
-
- lock->on_cpu = -1;
- lock->previous = NULL;
- lock->task = NULL;
- lock->base_file = "none";
- lock->line_no = 0;
-}
-
-void
-debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
-{
- long tmp;
- long stuck;
- void *inline_pc = __builtin_return_address(0);
- unsigned long started = jiffies;
- int printed = 0;
- int cpu = smp_processor_id();
-
- stuck = 1L << 30;
- try_again:
-
- /* Use sub-sections to put the actual loop at the end
- of this object file's text section so as to perfect
- branch prediction. */
- __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
- " subq %2,1,%2\n"
- " blbs %0,2f\n"
- " or %0,1,%0\n"
- " stl_c %0,%1\n"
- " beq %0,3f\n"
- "4: mb\n"
- ".subsection 2\n"
- "2: ldl %0,%1\n"
- " subq %2,1,%2\n"
- "3: blt %2,4b\n"
- " blbs %0,2b\n"
- " br 1b\n"
- ".previous"
- : "=r" (tmp), "=m" (lock->lock), "=r" (stuck)
- : "m" (lock->lock), "2" (stuck) : "memory");
-
- if (stuck < 0) {
- printk(KERN_WARNING
- "%s:%d spinlock stuck in %s at %p(%d)"
- " owner %s at %p(%d) %s:%d\n",
- base_file, line_no,
- current->comm, inline_pc, cpu,
- lock->task->comm, lock->previous,
- lock->on_cpu, lock->base_file, lock->line_no);
- stuck = 1L << 36;
- printed = 1;
- goto try_again;
- }
-
- /* Exiting. Got the lock. */
- lock->on_cpu = cpu;
- lock->previous = inline_pc;
- lock->task = current;
- lock->base_file = base_file;
- lock->line_no = line_no;
-
- if (printed) {
- printk(KERN_WARNING
- "%s:%d spinlock grabbed in %s at %p(%d) %ld ticks\n",
- base_file, line_no, current->comm, inline_pc,
- cpu, jiffies - started);
- }
-}
-
-int
-debug_spin_trylock(spinlock_t * lock, const char *base_file, int line_no)
-{
- int ret;
- if ((ret = !test_and_set_bit(0, lock))) {
- lock->on_cpu = smp_processor_id();
- lock->previous = __builtin_return_address(0);
- lock->task = current;
- } else {
- lock->base_file = base_file;
- lock->line_no = line_no;
- }
- return ret;
-}
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
-#ifdef CONFIG_DEBUG_RWLOCK
-void _raw_write_lock(rwlock_t * lock)
-{
- long regx, regy;
- int stuck_lock, stuck_reader;
- void *inline_pc = __builtin_return_address(0);
-
- try_again:
-
- stuck_lock = 1<<30;
- stuck_reader = 1<<30;
-
- __asm__ __volatile__(
- "1: ldl_l %1,%0\n"
- " blbs %1,6f\n"
- " blt %1,8f\n"
- " mov 1,%1\n"
- " stl_c %1,%0\n"
- " beq %1,6f\n"
- "4: mb\n"
- ".subsection 2\n"
- "6: blt %3,4b # debug\n"
- " subl %3,1,%3 # debug\n"
- " ldl %1,%0\n"
- " blbs %1,6b\n"
- "8: blt %4,4b # debug\n"
- " subl %4,1,%4 # debug\n"
- " ldl %1,%0\n"
- " blt %1,8b\n"
- " br 1b\n"
- ".previous"
- : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy),
- "=&r" (stuck_lock), "=&r" (stuck_reader)
- : "m" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
-
- if (stuck_lock < 0) {
- printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc);
- goto try_again;
- }
- if (stuck_reader < 0) {
- printk(KERN_WARNING "write_lock stuck on readers at %p\n",
- inline_pc);
- goto try_again;
- }
-}
-
-void _raw_read_lock(rwlock_t * lock)
-{
- long regx;
- int stuck_lock;
- void *inline_pc = __builtin_return_address(0);
-
- try_again:
-
- stuck_lock = 1<<30;
-
- __asm__ __volatile__(
- "1: ldl_l %1,%0;"
- " blbs %1,6f;"
- " subl %1,2,%1;"
- " stl_c %1,%0;"
- " beq %1,6f;"
- "4: mb\n"
- ".subsection 2\n"
- "6: ldl %1,%0;"
- " blt %2,4b # debug\n"
- " subl %2,1,%2 # debug\n"
- " blbs %1,6b;"
- " br 1b\n"
- ".previous"
- : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock)
- : "m" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
-
- if (stuck_lock < 0) {
- printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc);
- goto try_again;
- }
-}
-#endif /* CONFIG_DEBUG_RWLOCK */
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 9e36b07fa940..d5da6b1b28ee 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -395,6 +395,22 @@ clipper_init_irq(void)
*/
static int __init
+isa_irq_fixup(struct pci_dev *dev, int irq)
+{
+ u8 irq8;
+
+ if (irq > 0)
+ return irq;
+
+ /* This interrupt is routed via ISA bridge, so we'll
+ just have to trust whatever value the console might
+ have assigned. */
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
+
+ return irq8 & 0xf;
+}
+
+static int __init
dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[6][5] __initdata = {
@@ -407,25 +423,13 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */
};
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
-
struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
- if (irq > 0) {
+ if (irq > 0)
irq += 16 * hose->index;
- } else {
- /* ??? The Contaq IDE controller on the ISA bridge uses
- "legacy" interrupts 14 and 15. I don't know if anything
- can wind up at the same slot+pin on hose1, so we'll
- just have to trust whatever value the console might
- have assigned. */
-
- u8 irq8;
- pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
- irq = irq8;
- }
- return irq;
+ return isa_irq_fixup(dev, irq);
}
static int __init
@@ -453,7 +457,8 @@ monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/
};
const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
- return COMMON_TABLE_LOOKUP;
+
+ return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
}
static u8 __init
@@ -507,7 +512,8 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */
};
const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
- return COMMON_TABLE_LOOKUP;
+
+ return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
}
static int __init
@@ -524,14 +530,13 @@ clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
};
const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
-
struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0)
irq += 16 * hose->index;
- return irq;
+ return isa_irq_fixup(dev, irq);
}
static void __init
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 804727853d25..e32fee505220 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -373,12 +373,11 @@ marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
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/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 6f509a644bdd..f9d12319e0fb 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -446,16 +446,15 @@ struct unaligned_stat {
/* Macro for exception fixup code to access integer registers. */
-#define una_reg(r) (regs.regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
+#define una_reg(r) (regs->regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
asmlinkage void
do_entUna(void * va, unsigned long opcode, unsigned long reg,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct allregs regs)
+ struct allregs *regs)
{
long error, tmp1, tmp2, tmp3, tmp4;
- unsigned long pc = regs.pc - 4;
+ unsigned long pc = regs->pc - 4;
const struct exception_table_entry *fixup;
unaligned[0].count++;
@@ -636,7 +635,7 @@ got_exception:
printk("Forwarding unaligned exception at %lx (%lx)\n",
pc, newpc);
- (&regs)->pc = newpc;
+ regs->pc = newpc;
return;
}
@@ -650,7 +649,7 @@ got_exception:
current->comm, current->pid);
printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
- pc, una_reg(26), regs.ps);
+ pc, una_reg(26), regs->ps);
printk("r0 = %016lx r1 = %016lx r2 = %016lx\n",
una_reg(0), una_reg(1), una_reg(2));
printk("r3 = %016lx r4 = %016lx r5 = %016lx\n",
@@ -670,10 +669,10 @@ got_exception:
una_reg(22), una_reg(23), una_reg(24));
printk("r25= %016lx r27= %016lx r28= %016lx\n",
una_reg(25), una_reg(27), una_reg(28));
- printk("gp = %016lx sp = %p\n", regs.gp, &regs+1);
+ printk("gp = %016lx sp = %p\n", regs->gp, regs+1);
dik_show_code((unsigned int *)pc);
- dik_show_trace((unsigned long *)(&regs+1));
+ dik_show_trace((unsigned long *)(regs+1));
if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) {
printk("die_if_kernel recursion detected.\n");
diff --git a/arch/alpha/lib/dbg_stackcheck.S b/arch/alpha/lib/dbg_stackcheck.S
index cc5ce3a5fcad..3c1f3e6522e5 100644
--- a/arch/alpha/lib/dbg_stackcheck.S
+++ b/arch/alpha/lib/dbg_stackcheck.S
@@ -5,7 +5,7 @@
* Verify that we have not overflowed the stack. Oops if we have.
*/
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.text
.set noat
diff --git a/arch/alpha/lib/dbg_stackkill.S b/arch/alpha/lib/dbg_stackkill.S
index e09f2ae1e09e..e9f6a9dcf2b7 100644
--- a/arch/alpha/lib/dbg_stackkill.S
+++ b/arch/alpha/lib/dbg_stackkill.S
@@ -6,7 +6,7 @@
* uninitialized local variables in the act.
*/
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.text
.set noat
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0f2899b4159d..682367bd0f65 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -204,6 +204,7 @@ config ARCH_H720X
config ARCH_AAEC2000
bool "Agilent AAEC-2000 based"
+ select ARM_AMBA
help
This enables support for systems based on the Agilent AAEC-2000
@@ -326,8 +327,8 @@ config SMP
processor machines. On a single processor machine, the kernel will
run faster if you say N here.
- See also the <file:Documentation/smp.tex>,
- <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
+ See also the <file:Documentation/smp.txt>,
+ <file:Documentation/i386/IO-APIC.txt>,
<file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
<http://www.linuxdoc.org/docs.html#howto>.
@@ -687,7 +688,8 @@ source "drivers/acorn/block/Kconfig"
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
- || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
+ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+ || MACH_MP1000
source "drivers/ide/Kconfig"
endif
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 45a5709eaaa4..5d3acff8c596 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -53,7 +53,7 @@ config DEBUG_LL
bool "Kernel low-level debugging functions"
depends on DEBUG_KERNEL
help
- Say Y here to include definitions of printascii, printchar, printhex
+ Say Y here to include definitions of printascii, printch, printhex
in the kernel. This is helpful if you are debugging code that
executes before the console is initialized.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 67f1453ade05..299bc0468702 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -53,7 +53,7 @@ tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
-tune-$(CONFIG_CPU_V6) :=-mtune=strongarm
+tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
# Need -Uarm for gcc < 3.x
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
@@ -175,10 +175,10 @@ else
endif
@touch $@
-prepare: maketools include/asm-arm/.arch
+archprepare: maketools
.PHONY: maketools FORCE
-maketools: include/asm-arm/constants.h include/linux/version.h FORCE
+maketools: include/linux/version.h include/asm-arm/.arch FORCE
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
# Convert bzImage to zImage
@@ -190,7 +190,7 @@ zImage Image xipImage bootpImage uImage: vmlinux
zinstall install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
-CLEAN_FILES += include/asm-arm/constants.h* include/asm-arm/mach-types.h \
+CLEAN_FILES += include/asm-arm/mach-types.h \
include/asm-arm/arch include/asm-arm/.arch
# We use MRPROPER_FILES and CLEAN_FILES now
@@ -201,11 +201,6 @@ archclean:
bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/asm-arm/.arch
-
-include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
define archhelp
echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 7c7f475e213e..a54d2eb64892 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -39,7 +39,8 @@
defined(CONFIG_ARCH_IXP4XX) || \
defined(CONFIG_ARCH_IXP2000) || \
defined(CONFIG_ARCH_LH7A40X) || \
- defined(CONFIG_ARCH_OMAP)
+ defined(CONFIG_ARCH_OMAP) || \
+ defined(CONFIG_MACH_MP1000)
.macro loadsp, rb
addruart \rb
.endm
diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c
index 7f6f5db0d060..465c54b6b128 100644
--- a/arch/arm/boot/compressed/ofw-shark.c
+++ b/arch/arm/boot/compressed/ofw-shark.c
@@ -256,5 +256,5 @@ asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
temp[11]='\0';
mem_len = OF_getproplen(o,phandle, temp);
OF_getprop(o,phandle, temp, buffer, mem_len);
- (unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
+ * ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
}
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index d74990717559..c02dc8116a18 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -68,6 +68,7 @@ static void gic_unmask_irq(unsigned int irq)
writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4);
}
+#ifdef CONFIG_SMP
static void gic_set_cpu(struct irqdesc *desc, unsigned int irq, unsigned int cpu)
{
void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3);
@@ -78,6 +79,7 @@ static void gic_set_cpu(struct irqdesc *desc, unsigned int irq, unsigned int cpu
val |= 1 << (cpu + shift);
writel(val, reg);
}
+#endif
static struct irqchip gic_chip = {
.ack = gic_ack_irq,
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 51f430cc2fbf..e8053d16829b 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -27,7 +27,6 @@
#include <linux/spinlock.h>
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
@@ -541,6 +540,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, pm_message_t state, 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 +803,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/common/scoop.c b/arch/arm/common/scoop.c
index 688a595598c8..9e5245c702de 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -26,6 +26,8 @@ struct scoop_pcmcia_dev *scoop_devs;
struct scoop_dev {
void *base;
spinlock_t scoop_lock;
+ unsigned short suspend_clr;
+ unsigned short suspend_set;
u32 scoop_gpwr;
};
@@ -90,14 +92,24 @@ EXPORT_SYMBOL(reset_scoop);
EXPORT_SYMBOL(read_scoop_reg);
EXPORT_SYMBOL(write_scoop_reg);
+static void check_scoop_reg(struct scoop_dev *sdev)
+{
+ unsigned short mcr;
+
+ mcr = SCOOP_REG(sdev->base, SCOOP_MCR);
+ if ((mcr & 0x100) == 0)
+ SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101;
+}
+
#ifdef CONFIG_PM
-static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level)
+static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
{
if (level == SUSPEND_POWER_DOWN) {
struct scoop_dev *sdev = dev_get_drvdata(dev);
- sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR);
- SCOOP_REG(sdev->base,SCOOP_GPWR) = 0;
+ check_scoop_reg(sdev);
+ sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
+ SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
}
return 0;
}
@@ -107,6 +119,7 @@ static int scoop_resume(struct device *dev, uint32_t level)
if (level == RESUME_POWER_ON) {
struct scoop_dev *sdev = dev_get_drvdata(dev);
+ check_scoop_reg(sdev);
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
}
return 0;
@@ -151,6 +164,9 @@ int __init scoop_probe(struct device *dev)
SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
+ devptr->suspend_clr = inf->suspend_clr;
+ devptr->suspend_set = inf->suspend_set;
+
return 0;
}
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
new file mode 100644
index 000000000000..40dfe07a8bce
--- /dev/null
+++ b/arch/arm/configs/collie_defconfig
@@ -0,0 +1,888 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc3
+# Sun Oct 9 16:55:14 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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=y
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_SA1100_CERF is not set
+CONFIG_SA1100_COLLIE=y
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_SA1100=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_CACHE_V4WB=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WB=y
+
+#
+# Processor Features
+#
+CONFIG_SHARP_LOCOMO=y
+CONFIG_SHARP_PARAM=y
+CONFIG_SHARP_SCOOP=y
+
+#
+# Bus support
+#
+CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_SMP is not set
+CONFIG_PREEMPT=y
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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_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=m
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_OBSOLETE_CHIPS=y
+# CONFIG_MTD_AMDSTD is not set
+CONFIG_MTD_SHARP=y
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# 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=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN 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=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_LOCOMO=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON 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=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW 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_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_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 is not set
+# 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
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_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
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP_SA11X0 is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# 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 is not set
+# CONFIG_NFSD 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=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
new file mode 100644
index 000000000000..24987c89609a
--- /dev/null
+++ b/arch/arm/configs/corgi_defconfig
@@ -0,0 +1,1523 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc3
+# Sun Oct 9 15:46:42 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_PXA_SHARPSL=y
+CONFIG_PXA_SHARPSL_25x=y
+# CONFIG_PXA_SHARPSL_27x is not set
+# CONFIG_MACH_POODLE is not set
+CONFIG_MACH_CORGI=y
+CONFIG_MACH_SHEPHERD=y
+CONFIG_MACH_HUSKY=y
+CONFIG_PXA25x=y
+CONFIG_PXA_SHARP_C7xx=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_XSCALE_PMU=y
+CONFIG_SHARP_PARAM=y
+CONFIG_SHARP_SCOOP=y
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=y
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+# CONFIG_IP_NF_MATCH_STRING is not set
+CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+# CONFIG_IP_NF_TARGET_MASQUERADE is not set
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_TOS is not set
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_DSCP is not set
+# CONFIG_IP_NF_TARGET_MARK is not set
+# CONFIG_IP_NF_TARGET_CLASSIFY is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=m
+# CONFIG_IP_NF_TARGET_NOTRACK is not set
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_TARGET_LOG is not set
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_TARGET_MARK is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_RAW=m
+
+#
+# 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=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+# CONFIG_BT_HCIUSB_SCO is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_SHARP_SL=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_SHARPSL=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# 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_IDECS=y
+# 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_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA 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=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# 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
+#
+# CONFIG_ISDN 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=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_KEYBOARD_CORGI=y
+CONFIG_KEYBOARD_SPITZ=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_CORGI=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# 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=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_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 is not set
+# 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
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_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
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_PXA is not set
+CONFIG_FB_W100=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CORGI=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_AD1980 is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# 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
+# CONFIG_USB_STORAGE_ONETOUCH 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=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+# CONFIG_USB_ACECAD is not set
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+# CONFIG_USB_ITMTOUCH is not set
+CONFIG_USB_EGALAX=m
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_PWC is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+CONFIG_USB_SERIAL_BELKIN=m
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+CONFIG_USB_GADGET_PXA2XX=y
+CONFIG_USB_PXA2XX=y
+# CONFIG_USB_PXA2XX_SMALL is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_WBSD 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_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig
index f67ca01b4982..30e6444f9aaa 100644
--- a/arch/arm/configs/enp2611_defconfig
+++ b/arch/arm/configs/enp2611_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Thu Jul 7 16:41:21 2005
+# Linux kernel version: 2.6.13
+# Wed Sep 14 10:51:52 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -135,7 +135,6 @@ CONFIG_PCI_NAMES=y
#
# Kernel Features
#
-# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -179,6 +178,68 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PM is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+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=y
+# 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 is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
# Device Drivers
#
@@ -248,6 +309,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP2000=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -334,72 +396,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-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=y
-# 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 is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# 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
+# Network device support
#
-# 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=y
# CONFIG_BONDING is not set
@@ -509,6 +507,8 @@ CONFIG_DLCI_MAX=8
# 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
@@ -635,7 +635,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_IXP2000 is not set
+CONFIG_I2C_IXP2000=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -649,11 +649,28 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_SENSOR=y
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=y
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# 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_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -679,30 +696,15 @@ CONFIG_I2C_SENSOR=y
# 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_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-CONFIG_SENSORS_EEPROM=y
-# 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
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -770,6 +772,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -812,8 +815,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_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
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index 5c6c928215d0..678720fa2e2e 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Thu Jul 7 16:49:01 2005
+# Linux kernel version: 2.6.13
+# Wed Sep 14 10:52:01 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -136,7 +136,6 @@ CONFIG_PCI_NAMES=y
#
# Kernel Features
#
-# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -180,6 +179,68 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PM is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+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=y
+# 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 is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
# Device Drivers
#
@@ -249,6 +310,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP2000=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -335,72 +397,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-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=y
-# 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 is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# 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
+# Network device support
#
-# 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=y
# CONFIG_BONDING is not set
@@ -510,6 +508,8 @@ CONFIG_DLCI_MAX=8
# 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
@@ -636,7 +636,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_IXP2000 is not set
+CONFIG_I2C_IXP2000=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -650,11 +650,28 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_SENSOR=y
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=y
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# 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_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -680,30 +697,15 @@ CONFIG_I2C_SENSOR=y
# 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_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-CONFIG_SENSORS_EEPROM=y
-# 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
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -771,6 +773,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -813,8 +816,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_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
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 6dc40f6be0ef..38c9a721d5c9 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Thu Jul 7 16:49:08 2005
+# Linux kernel version: 2.6.13
+# Wed Sep 14 10:52:10 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -136,7 +136,6 @@ CONFIG_PCI_NAMES=y
#
# Kernel Features
#
-# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -180,6 +179,68 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PM is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+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=y
+# 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_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
# Device Drivers
#
@@ -249,6 +310,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP2000=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -335,72 +397,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-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=y
-# 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_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# 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
+# Network device support
#
-# 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=y
# CONFIG_BONDING is not set
@@ -511,6 +509,8 @@ CONFIG_DLCI_MAX=8
# 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
@@ -637,7 +637,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_IXP2000 is not set
+CONFIG_I2C_IXP2000=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -651,11 +651,28 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_SENSOR=y
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=y
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# 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_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -681,30 +698,15 @@ CONFIG_I2C_SENSOR=y
# 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_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-CONFIG_SENSORS_EEPROM=y
-# 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
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -772,6 +774,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -814,8 +817,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_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
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index d2bb0b7153fe..261e2343903b 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Thu Jul 7 16:49:20 2005
+# Linux kernel version: 2.6.13
+# Wed Sep 14 10:52:23 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -136,7 +136,6 @@ CONFIG_PCI_NAMES=y
#
# Kernel Features
#
-# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -180,6 +179,68 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PM is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+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=y
+# 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 is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
# Device Drivers
#
@@ -249,6 +310,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP2000=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -335,72 +397,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-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=y
-# 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 is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# 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
+# Network device support
#
-# 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=y
# CONFIG_BONDING is not set
@@ -510,6 +508,8 @@ CONFIG_DLCI_MAX=8
# 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
@@ -636,7 +636,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_IXP2000 is not set
+CONFIG_I2C_IXP2000=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -650,11 +650,28 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_SENSOR=y
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=y
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# 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_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -680,30 +697,15 @@ CONFIG_I2C_SENSOR=y
# 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_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-CONFIG_SENSORS_EEPROM=y
-# 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
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -771,6 +773,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -813,8 +816,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_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
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index 2d6f960e3395..12ef23d1c016 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Thu Jul 7 16:49:13 2005
+# Linux kernel version: 2.6.13
+# Wed Sep 14 10:52:16 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -136,7 +136,6 @@ CONFIG_PCI_NAMES=y
#
# Kernel Features
#
-# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -180,6 +179,68 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PM is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+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=y
+# 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 is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
# Device Drivers
#
@@ -249,6 +310,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP2000=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -335,72 +397,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-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=y
-# 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 is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# 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
+# Network device support
#
-# 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=y
# CONFIG_BONDING is not set
@@ -511,6 +509,8 @@ CONFIG_DLCI_MAX=8
# 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
@@ -637,7 +637,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_IXP2000 is not set
+CONFIG_I2C_IXP2000=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -651,11 +651,28 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_SENSOR=y
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=y
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# 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_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -681,30 +698,15 @@ CONFIG_I2C_SENSOR=y
# 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_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-CONFIG_SENSORS_EEPROM=y
-# 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
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -772,6 +774,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -814,8 +817,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_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
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 94aafec5fb46..c279e41ed10e 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -1,14 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:53:40 2005
+# Linux kernel version: 2.6.14-rc1-git5
+# Tue Sep 20 17:26:28 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
#
# Code maturity level options
@@ -16,11 +15,13 @@ CONFIG_GENERIC_IOMAP=y
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
@@ -31,10 +32,13 @@ CONFIG_SYSCTL=y
# 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_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
@@ -81,6 +85,7 @@ CONFIG_ARCH_IXP4XX=y
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
#
@@ -90,15 +95,16 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
#
# IXP4xx Platforms
#
-# CONFIG_ARCH_AVILA is not set
+CONFIG_ARCH_AVILA=y
CONFIG_ARCH_ADI_COYOTE=y
CONFIG_ARCH_IXDP425=y
-# CONFIG_MACH_IXDPG425 is not set
-# CONFIG_MACH_IXDP465 is not set
+CONFIG_MACH_IXDPG425=y
+CONFIG_MACH_IXDP465=y
CONFIG_ARCH_IXCDP1100=y
CONFIG_ARCH_PRPMC1100=y
CONFIG_ARCH_IXDP4XX=y
-# CONFIG_MACH_GTWX5715 is not set
+CONFIG_CPU_IXP46X=y
+CONFIG_MACH_GTWX5715=y
#
# IXP4xx Options
@@ -114,7 +120,6 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
#
# Processor Features
@@ -127,9 +132,10 @@ CONFIG_DMABOUNCE=y
#
# Bus support
#
+CONFIG_ISA_DMA_API=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -140,6 +146,15 @@ CONFIG_PCI_NAMES=y
# Kernel Features
#
# CONFIG_PREEMPT 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
#
@@ -175,6 +190,241 @@ CONFIG_PM=y
CONFIG_APM=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# 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_FWMARK=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=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# 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 is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+CONFIG_IP_VS_DEBUG=y
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+# CONFIG_IP_VS_PROTO_TCP is not set
+# CONFIG_IP_VS_PROTO_UDP is not set
+# CONFIG_IP_VS_PROTO_ESP is not set
+# CONFIG_IP_VS_PROTO_AH is not set
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+# CONFIG_IP_VS_SED is not set
+# CONFIG_IP_VS_NQ is not set
+
+#
+# IPVS application helper
+#
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+# CONFIG_IP_NF_TFTP is not set
+# CONFIG_IP_NF_AMANDA is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+CONFIG_IP_NF_MATCH_MAC=m
+# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+# CONFIG_IP_NF_MATCH_RECENT is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+# CONFIG_IP_NF_MATCH_HELPER is not set
+CONFIG_IP_NF_MATCH_STATE=m
+# CONFIG_IP_NF_MATCH_CONNTRACK is not set
+CONFIG_IP_NF_MATCH_OWNER=m
+# CONFIG_IP_NF_MATCH_PHYSDEV is not set
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+# CONFIG_IP_NF_MATCH_SCTP is not set
+# CONFIG_IP_NF_MATCH_DCCP is not set
+# CONFIG_IP_NF_MATCH_COMMENT is not set
+# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
+# CONFIG_IP_NF_MATCH_STRING is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_DSCP is not set
+CONFIG_IP_NF_TARGET_MARK=m
+# CONFIG_IP_NF_TARGET_CLASSIFY is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+# CONFIG_NET_DIVERT is not set
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_ATM is not set
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+# CONFIG_NET_SCH_NETEM is not set
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -244,6 +494,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP4XX=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -283,7 +534,6 @@ CONFIG_MTD_NAND_IDS=m
#
# 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
@@ -297,7 +547,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -351,6 +600,7 @@ CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_HPT366=y
# 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=y
@@ -369,6 +619,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -379,6 +630,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -391,235 +643,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=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=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# 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_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-CONFIG_IP_VS=m
-CONFIG_IP_VS_DEBUG=y
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-# CONFIG_IP_VS_PROTO_TCP is not set
-# CONFIG_IP_VS_PROTO_UDP is not set
-# CONFIG_IP_VS_PROTO_ESP is not set
-# CONFIG_IP_VS_PROTO_AH is not set
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-# CONFIG_IP_VS_SED is not set
-# CONFIG_IP_VS_NQ is not set
-
-#
-# IPVS application helper
-#
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-# CONFIG_IP_NF_MATCH_IPRANGE is not set
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-# CONFIG_IP_NF_MATCH_SCTP is not set
-# CONFIG_IP_NF_MATCH_COMMENT is not set
-# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-# CONFIG_IP_NF_TARGET_CLASSIFY is not set
-# CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-# CONFIG_IP_NF_ARP_MANGLE is not set
-
-#
-# Bridge: Netfilter Configuration
-#
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-# CONFIG_ATM_CLIP_NO_ICMP is not set
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
-# CONFIG_ATM_BR2684_IPFILTER is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-# CONFIG_DECNET is not set
-CONFIG_LLC=m
-# CONFIG_LLC2 is not set
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=y
-CONFIG_IPDDP=m
-CONFIG_IPDDP_ENCAP=y
-CONFIG_IPDDP_DECAP=y
-CONFIG_X25=m
-CONFIG_LAPB=m
-# CONFIG_NET_DIVERT is not set
-CONFIG_ECONET=m
-CONFIG_ECONET_AUNUDP=y
-CONFIG_ECONET_NATIVE=y
-CONFIG_WAN_ROUTER=m
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-# CONFIG_NET_SCH_HFSC is not set
-# CONFIG_NET_SCH_ATM is not set
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-# CONFIG_NET_SCH_NETEM is not set
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-# CONFIG_NET_CLS_BASIC is not set
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-# CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
-# CONFIG_CLS_U32_MARK is not set
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-# 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=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -627,6 +657,11 @@ CONFIG_DUMMY=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -635,6 +670,7 @@ CONFIG_MII=y
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
#
# Tulip family network device support
@@ -671,13 +707,17 @@ CONFIG_EEPRO100=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -702,6 +742,7 @@ CONFIG_NET_RADIO=y
CONFIG_HERMES=y
# CONFIG_PLX_HERMES is not set
# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
CONFIG_PCI_HERMES=y
# CONFIG_ATMEL is not set
@@ -709,6 +750,7 @@ CONFIG_PCI_HERMES=y
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
CONFIG_NET_WIRELESS=y
#
@@ -758,6 +800,8 @@ CONFIG_ATM_TCP=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
@@ -795,7 +839,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
#
# Character devices
@@ -816,6 +859,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -882,12 +926,11 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_IOP3XX is not set
-# CONFIG_I2C_ISA is not set
CONFIG_I2C_IXP4XX=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_SCx200_ACB is not set
@@ -901,14 +944,33 @@ CONFIG_I2C_IXP4XX=y
# CONFIG_I2C_PCA_ISA is not set
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=y
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# 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 is not set
# 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
@@ -924,30 +986,26 @@ CONFIG_I2C_SENSOR=y
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_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_EEPROM=y
-# 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
#
#
@@ -994,6 +1052,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -1004,17 +1063,15 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1034,12 +1091,10 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1054,8 +1109,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_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
@@ -1072,12 +1126,14 @@ CONFIG_JFFS2_RTIME=y
#
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
@@ -1086,6 +1142,7 @@ CONFIG_SUNRPC=y
# 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
@@ -1124,6 +1181,7 @@ CONFIG_MSDOS_PARTITION=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1158,6 +1216,7 @@ CONFIG_DEBUG_LL=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/mp1000_defconfig b/arch/arm/configs/mp1000_defconfig
new file mode 100644
index 000000000000..d2cbc6fada1d
--- /dev/null
+++ b/arch/arm/configs/mp1000_defconfig
@@ -0,0 +1,897 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc1
+# Fri Sep 16 15:48:13 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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=y
+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 is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+CONFIG_ARCH_CLPS711X=y
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CEIVA is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+CONFIG_MACH_MP1000=y
+CONFIG_MP1000_90MHZ=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM720T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_LV4T=y
+CONFIG_CPU_CACHE_V4=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WT=y
+CONFIG_CPU_TLB_V4WT=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_SMP is not set
+CONFIG_PREEMPT=y
+# 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
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_media=rj45"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP 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=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# 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=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL 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
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=m
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=m
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP_START=0x0000000
+CONFIG_MTD_PHYSMAP_LEN=0x4000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_EDB7312=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_MP1000=y
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+# 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_HD_IDE 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_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+CONFIG_IDE_ARM=y
+CONFIG_BLK_DEV_IDE_MP1000=y
+# CONFIG_BLK_DEV_IDEDMA 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 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_CRYPT is not set
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+CONFIG_CS89x0=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# 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
+#
+# CONFIG_ISDN 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=y
+
+#
+# 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=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW 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=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CLPS711X=y
+CONFIG_SERIAL_CLPS711X_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_NVRAM=y
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN 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=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST 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_ZLIB_DEFLATE=m
diff --git a/arch/arm/configs/poodle_defconfig b/arch/arm/configs/poodle_defconfig
new file mode 100644
index 000000000000..72822907759f
--- /dev/null
+++ b/arch/arm/configs/poodle_defconfig
@@ -0,0 +1,1015 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc3
+# Sun Oct 9 17:04:29 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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=y
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_PXA_SHARPSL=y
+CONFIG_PXA_SHARPSL_25x=y
+# CONFIG_PXA_SHARPSL_27x is not set
+CONFIG_MACH_POODLE=y
+# CONFIG_MACH_CORGI is not set
+# CONFIG_MACH_SHEPHERD is not set
+# CONFIG_MACH_HUSKY is not set
+CONFIG_PXA25x=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_XSCALE_PMU=y
+CONFIG_SHARP_LOCOMO=y
+CONFIG_SHARP_PARAM=y
+CONFIG_SHARP_SCOOP=y
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=y
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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_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=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_SHARP_SL=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_SHARPSL=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# 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_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA 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 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# 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
+#
+# CONFIG_ISDN 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=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_LOCOMO=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_CORGI is not set
+CONFIG_KEYBOARD_SPITZ=y
+# 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_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_PXA is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# 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
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_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
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+CONFIG_USB_GADGET_PXA2XX=y
+CONFIG_USB_PXA2XX=y
+# CONFIG_USB_PXA2XX_SMALL is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_WBSD is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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 is not set
+# CONFIG_NFSD 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 96a794d8de84..756348bf5170 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,7 +1,7 @@
#
# 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/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
new file mode 100644
index 000000000000..900e04f8e38c
--- /dev/null
+++ b/arch/arm/configs/spitz_defconfig
@@ -0,0 +1,1401 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc3
+# Sun Oct 9 17:11:19 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_PXA_SHARPSL=y
+# CONFIG_PXA_SHARPSL_25x is not set
+CONFIG_PXA_SHARPSL_27x=y
+CONFIG_MACH_SPITZ=y
+CONFIG_MACH_BORZOI=y
+CONFIG_PXA27x=y
+CONFIG_PXA_SHARP_Cxx00=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_XSCALE_PMU=y
+CONFIG_SHARP_PARAM=y
+CONFIG_SHARP_SCOOP=y
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=y
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+# CONFIG_IP_NF_MATCH_STRING is not set
+CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+# CONFIG_IP_NF_TARGET_MASQUERADE is not set
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_TOS is not set
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_DSCP is not set
+# CONFIG_IP_NF_TARGET_MARK is not set
+# CONFIG_IP_NF_TARGET_CLASSIFY is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=m
+# CONFIG_IP_NF_TARGET_NOTRACK is not set
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_TARGET_LOG is not set
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_TARGET_MARK is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_RAW=m
+
+#
+# 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=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+# CONFIG_BT_HCIUSB_SCO is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_SHARP_SL=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_SHARPSL=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# 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_IDECS=y
+# 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_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA 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=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# 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
+#
+# CONFIG_ISDN 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=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_CORGI is not set
+CONFIG_KEYBOARD_SPITZ=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_CORGI=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# 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=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP 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=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
+CONFIG_BACKLIGHT_CORGI=y
+
+#
+# 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=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# 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_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# 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
+# CONFIG_USB_STORAGE_ONETOUCH 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=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+# CONFIG_USB_ACECAD is not set
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+# CONFIG_USB_ITMTOUCH is not set
+CONFIG_USB_EGALAX=m
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+CONFIG_USB_SERIAL_BELKIN=m
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+# CONFIG_USB_SERIAL_OPTION is not set
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_DUMMY_HCD=m
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_WBSD is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 835d450797a1..7b17a87a3311 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -45,8 +45,8 @@ extern void fp_enter(void);
#define EXPORT_SYMBOL_ALIAS(sym,orig) \
EXPORT_CRC_ALIAS(sym) \
- const struct kernel_symbol __ksymtab_##sym \
- __attribute__((section("__ksymtab"))) = \
+ static const struct kernel_symbol __ksymtab_##sym \
+ __attribute_used__ __attribute__((section("__ksymtab"))) = \
{ (unsigned long)&orig, #sym };
/*
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index db07ce42b3b2..2ad4aa2a1536 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -10,7 +10,7 @@
* This file is included twice in entry-common.S
*/
#ifndef NR_syscalls
-#define NR_syscalls 320
+#define NR_syscalls 328
#else
__syscall_start:
@@ -131,7 +131,7 @@ __syscall_start:
.long sys_wait4
/* 115 */ .long sys_swapoff
.long sys_sysinfo
- .long sys_ipc
+ .long sys_ipc_wrapper
.long sys_fsync
.long sys_sigreturn_wrapper
/* 120 */ .long sys_clone_wrapper
@@ -333,6 +333,9 @@ __syscall_start:
.long sys_inotify_init
.long sys_inotify_add_watch
.long sys_inotify_rm_watch
+ .long sys_mbind_wrapper
+/* 320 */ .long sys_get_mempolicy
+ .long sys_set_mempolicy
__syscall_end:
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7152bfbee581..93b5e8e5292e 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -537,7 +537,7 @@ ENTRY(__switch_to)
#ifdef CONFIG_CPU_MPCORE
clrex
#else
- strex r3, r4, [ip] @ Clear exclusive monitor
+ strex r5, r4, [ip] @ Clear exclusive monitor
#endif
#endif
#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 6281d488ac97..066597f4345a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -106,15 +106,10 @@ ENTRY(ret_from_fork)
.endm
.Larm700bug:
- ldr r0, [sp, #S_PSR] @ Get calling cpsr
- sub lr, lr, #4
- str lr, [r8]
- msr spsr_cxsf, r0
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0
- ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
- movs pc, lr
+ subs pc, lr, #4
#else
.macro arm710_bug_check, instr, temp
.endm
@@ -269,6 +264,14 @@ sys_arm_fadvise64_64_wrapper:
str r5, [sp, #4] @ push r5 to stack
b sys_arm_fadvise64_64
+sys_mbind_wrapper:
+ str r5, [sp, #4]
+ b sys_mbind
+
+sys_ipc_wrapper:
+ str r5, [sp, #4] @ push sixth arg
+ b sys_ipc
+
/*
* Note: off_4k (r5) is always units of 4K. If we can't do the requested
* offset, we return EINVAL.
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index afef21273963..648cfff93138 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -3,7 +3,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/errno.h>
#include <asm/thread_info.h>
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 1155cf07c871..539626351348 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -20,7 +20,7 @@
#include <asm/mach-types.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/system.h>
diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c
index 6c20c1188b60..1f6822dfae74 100644
--- a/arch/arm/kernel/io.c
+++ b/arch/arm/kernel/io.c
@@ -7,7 +7,7 @@
* Copy data from IO memory space to "real" memory space.
* This needs to be optimized.
*/
-void _memcpy_fromio(void *to, void __iomem *from, size_t count)
+void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
{
unsigned char *t = to;
while (count) {
@@ -22,7 +22,7 @@ void _memcpy_fromio(void *to, void __iomem *from, size_t count)
* Copy data from "real" memory space to IO memory space.
* This needs to be optimized.
*/
-void _memcpy_toio(void __iomem *to, const void *from, size_t count)
+void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
{
const unsigned char *f = from;
while (count) {
@@ -37,7 +37,7 @@ void _memcpy_toio(void __iomem *to, const void *from, size_t count)
* "memset" on IO memory space.
* This needs to be optimized.
*/
-void _memset_io(void __iomem *dst, int c, size_t count)
+void _memset_io(volatile void __iomem *dst, int c, size_t count)
{
while (count) {
count--;
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index 8f74e24536ba..24c7b0477a09 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -17,7 +17,7 @@
#include <linux/linkage.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#define MMX_WR0 (0x00)
#define MMX_WR1 (0x08)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 1a85cfdad5ac..6055e1427ba3 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -11,6 +11,7 @@
*/
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/moduleloader.h>
#include <linux/kernel.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index ac423e3e224b..4c31f2923055 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -178,7 +178,7 @@ int __down_trylock(struct semaphore * sem)
* registers (r0 to r3 and lr), but not ip, as we use it as a return
* value in some cases..
*/
-asm(" .section .sched.text,\"ax\" \n\
+asm(" .section .sched.text,\"ax\",%progbits \n\
.align 5 \n\
.globl __down_failed \n\
__down_failed: \n\
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 42629ff84f5a..ea569ba482b1 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -305,7 +305,7 @@ long execve(const char *filename, char **argv, char **envp)
"Ir" (THREAD_START_SP - sizeof(regs)),
"r" (&regs),
"Ir" (sizeof(regs))
- : "r0", "r1", "r2", "r3", "ip", "memory");
+ : "r0", "r1", "r2", "r3", "ip", "lr", "memory");
out:
return ret;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 4554c961251c..baa09601a64e 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -345,7 +345,9 @@ static int bad_syscall(int n, struct pt_regs *regs)
struct thread_info *thread = current_thread_info();
siginfo_t info;
- if (current->personality != PER_LINUX && thread->exec_domain->handler) {
+ if (current->personality != PER_LINUX &&
+ current->personality != PER_LINUX_32BIT &&
+ thread->exec_domain->handler) {
thread->exec_domain->handler(n, regs);
return regs->ARM_r0;
}
@@ -504,7 +506,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
bad_access:
spin_unlock(&mm->page_table_lock);
- /* simulate a read access fault */
+ /* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;
}
@@ -624,6 +626,9 @@ void __attribute__((noreturn)) __bug(const char *file, int line, void *data)
printk(" - extra data = %p", data);
printk("\n");
*(int *)0 = 0;
+
+ /* Avoid "noreturn function does return" */
+ for (;;);
}
EXPORT_SYMBOL(__bug);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index ad2d66c93a5c..0d5db5279c5c 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -23,20 +23,20 @@ SECTIONS
*(.init.text)
_einittext = .;
__proc_info_begin = .;
- *(.proc.info)
+ *(.proc.info.init)
__proc_info_end = .;
__arch_info_begin = .;
- *(.arch.info)
+ *(.arch.info.init)
__arch_info_end = .;
__tagtable_begin = .;
- *(.taglist)
+ *(.taglist.init)
__tagtable_end = .;
. = ALIGN(16);
__setup_start = .;
*(.init.setup)
__setup_end = .;
__early_begin = .;
- *(__early_param)
+ *(.early_param.init)
__early_end = .;
__initcall_start = .;
*(.initcall1.init)
@@ -89,13 +89,6 @@ SECTIONS
*(.got) /* Global offset table */
}
- . = ALIGN(16);
- __ex_table : { /* Exception table */
- __start___ex_table = .;
- *(__ex_table)
- __stop___ex_table = .;
- }
-
RODATA
_etext = .; /* End of text and rodata section */
@@ -138,6 +131,14 @@ SECTIONS
*(.data.cacheline_aligned)
/*
+ * The exception fixup table (might need resorting at runtime)
+ */
+ . = ALIGN(32);
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+
+ /*
* and the usual data section
*/
*(.data)
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 8725d63e4219..71e5b99e519e 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
strnlen_user.o strchr.o strrchr.o testchangebit.o \
testclearbit.o testsetbit.o uaccess.o getuser.o \
putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
- ucmpdi2.o lib1funcs.o div64.o \
+ ucmpdi2.o lib1funcs.o div64.o sha1.o \
io-readsb.o io-writesb.o io-readsl.o io-writesl.o
ifeq ($(CONFIG_CPU_32v3),y)
diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
index 4c38abdbe497..68117968482b 100644
--- a/arch/arm/lib/copy_page.S
+++ b/arch/arm/lib/copy_page.S
@@ -11,7 +11,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#define COPY_COUNT (PAGE_SZ/64 PLD( -1 ))
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 46a2dc962e9d..333bca292de9 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -13,7 +13,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
.text
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 64aa6f4fe5e4..d204018070a4 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -26,7 +26,7 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000.
* Note also that it is intended that __get_user_bad is not global.
*/
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index b09398d95aac..4593e9c07f05 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -26,7 +26,7 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000
* Note also that it is intended that __put_user_bad is not global.
*/
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
new file mode 100644
index 000000000000..ff6ece487ffc
--- /dev/null
+++ b/arch/arm/lib/sha1.S
@@ -0,0 +1,206 @@
+/*
+ * linux/arch/arm/lib/sha1.S
+ *
+ * SHA transform optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
+ * Created: September 17, 2005
+ *
+ * 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.
+ *
+ * The reference implementation for this code is linux/lib/sha1.c
+ */
+
+#include <linux/linkage.h>
+
+ .text
+
+
+/*
+ * void sha_transform(__u32 *digest, const char *in, __u32 *W)
+ *
+ * Note: the "in" ptr may be unaligned.
+ */
+
+ENTRY(sha_transform)
+
+ stmfd sp!, {r4 - r8, lr}
+
+ @ for (i = 0; i < 16; i++)
+ @ W[i] = be32_to_cpu(in[i]); */
+
+#ifdef __ARMEB__
+ mov r4, r0
+ mov r0, r2
+ mov r2, #64
+ bl memcpy
+ mov r2, r0
+ mov r0, r4
+#else
+ mov r3, r2
+ mov lr, #16
+1: ldrb r4, [r1], #1
+ ldrb r5, [r1], #1
+ ldrb r6, [r1], #1
+ ldrb r7, [r1], #1
+ subs lr, lr, #1
+ orr r5, r5, r4, lsl #8
+ orr r6, r6, r5, lsl #8
+ orr r7, r7, r6, lsl #8
+ str r7, [r3], #4
+ bne 1b
+#endif
+
+ @ for (i = 0; i < 64; i++)
+ @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
+
+ sub r3, r2, #4
+ mov lr, #64
+2: ldr r4, [r3, #4]!
+ subs lr, lr, #1
+ ldr r5, [r3, #8]
+ ldr r6, [r3, #32]
+ ldr r7, [r3, #52]
+ eor r4, r4, r5
+ eor r4, r4, r6
+ eor r4, r4, r7
+ mov r4, r4, ror #31
+ str r4, [r3, #64]
+ bne 2b
+
+ /*
+ * The SHA functions are:
+ *
+ * f1(B,C,D) = (D ^ (B & (C ^ D)))
+ * f2(B,C,D) = (B ^ C ^ D)
+ * f3(B,C,D) = ((B & C) | (D & (B | C)))
+ *
+ * Then the sub-blocks are processed as follows:
+ *
+ * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
+ * B' = A
+ * C' = ror(B, 2)
+ * D' = C
+ * E' = D
+ *
+ * We therefore unroll each loop 5 times to avoid register shuffling.
+ * Also the ror for C (and also D and E which are successivelyderived
+ * from it) is applied in place to cut on an additional mov insn for
+ * each round.
+ */
+
+ .macro sha_f1, A, B, C, D, E
+ ldr r3, [r2], #4
+ eor ip, \C, \D
+ add \E, r1, \E, ror #2
+ and ip, \B, ip, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f2, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ eor ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f3, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ orr ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ and ip, ip, \D, ror #2
+ add \E, \E, r3
+ and r3, \B, \C, ror #2
+ orr ip, ip, r3
+ add \E, \E, ip
+ .endm
+
+ ldmia r0, {r4 - r8}
+
+ mov lr, #4
+ ldr r1, .L_sha_K + 0
+
+ /* adjust initial values */
+ mov r6, r6, ror #30
+ mov r7, r7, ror #30
+ mov r8, r8, ror #30
+
+3: subs lr, lr, #1
+ sha_f1 r4, r5, r6, r7, r8
+ sha_f1 r8, r4, r5, r6, r7
+ sha_f1 r7, r8, r4, r5, r6
+ sha_f1 r6, r7, r8, r4, r5
+ sha_f1 r5, r6, r7, r8, r4
+ bne 3b
+
+ ldr r1, .L_sha_K + 4
+ mov lr, #4
+
+4: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 4b
+
+ ldr r1, .L_sha_K + 8
+ mov lr, #4
+
+5: subs lr, lr, #1
+ sha_f3 r4, r5, r6, r7, r8
+ sha_f3 r8, r4, r5, r6, r7
+ sha_f3 r7, r8, r4, r5, r6
+ sha_f3 r6, r7, r8, r4, r5
+ sha_f3 r5, r6, r7, r8, r4
+ bne 5b
+
+ ldr r1, .L_sha_K + 12
+ mov lr, #4
+
+6: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 6b
+
+ ldmia r0, {r1, r2, r3, ip, lr}
+ add r4, r1, r4
+ add r5, r2, r5
+ add r6, r3, r6, ror #2
+ add r7, ip, r7, ror #2
+ add r8, lr, r8, ror #2
+ stmia r0, {r4 - r8}
+
+ ldmfd sp!, {r4 - r8, pc}
+
+.L_sha_K:
+ .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
+
+
+/*
+ * void sha_init(__u32 *buf)
+ */
+
+.L_sha_initial_digest:
+ .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
+
+ENTRY(sha_init)
+
+ str lr, [sp, #-4]!
+ adr r1, .L_sha_initial_digest
+ ldmia r1, {r1, r2, r3, ip, lr}
+ stmia r0, {r1, r2, r3, ip, lr}
+ ldr pc, [sp], #4
+
diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
index 20ec83896c37..a8e462f58bc9 100644
--- a/arch/arm/mach-aaec2000/Makefile
+++ b/arch/arm/mach-aaec2000/Makefile
@@ -3,7 +3,7 @@
#
# Common support (must be linked before board specific support)
-obj-y += core.o
+obj-y += core.o clock.o
# Specific board support
obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
index c9d899886648..f5ef69702296 100644
--- a/arch/arm/mach-aaec2000/aaed2000.c
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -27,16 +27,65 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/arch/aaed2000.h>
+
#include "core.h"
+static void aaed2000_clcd_disable(struct clcd_fb *fb)
+{
+ AAED_EXT_GPIO &= ~AAED_EGPIO_LCD_PWR_EN;
+}
+
+static void aaed2000_clcd_enable(struct clcd_fb *fb)
+{
+ AAED_EXT_GPIO |= AAED_EGPIO_LCD_PWR_EN;
+}
+
+struct aaec2000_clcd_info clcd_info = {
+ .enable = aaed2000_clcd_enable,
+ .disable = aaed2000_clcd_disable,
+ .panel = {
+ .mode = {
+ .name = "Sharp",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 20,
+ .right_margin = 44,
+ .upper_margin = 21,
+ .lower_margin = 34,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IVS | TIM2_IHS,
+ .cntl = CNTL_LCDTFT,
+ .bpp = 16,
+ },
+};
+
static void __init aaed2000_init_irq(void)
{
aaec2000_init_irq();
}
+static void __init aaed2000_init(void)
+{
+ aaec2000_set_clcd_plat_data(&clcd_info);
+}
+
+static struct map_desc aaed2000_io_desc[] __initdata = {
+ { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */
+};
+
static void __init aaed2000_map_io(void)
{
aaec2000_map_io();
+ iotable_init(aaed2000_io_desc, ARRAY_SIZE(aaed2000_io_desc));
}
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
@@ -47,4 +96,5 @@ MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
.map_io = aaed2000_map_io,
.init_irq = aaed2000_init_irq,
.timer = &aaec2000_timer,
+ .init_machine = aaed2000_init,
MACHINE_END
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
new file mode 100644
index 000000000000..99e019169dda
--- /dev/null
+++ b/arch/arm/mach-aaec2000/clock.c
@@ -0,0 +1,110 @@
+/*
+ * linux/arch/arm/mach-aaec2000/clock.c
+ *
+ * Copyright (C) 2005 Nicolas Bellido Y Ortega
+ *
+ * Based on linux/arch/arm/mach-integrator/clock.c
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware/clock.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+ down(&clocks_sem);
+ list_for_each_entry(p, &clocks, node) {
+ if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ up(&clocks_sem);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_register(struct clk *clk)
+{
+ down(&clocks_sem);
+ list_add(&clk->node, &clocks);
+ up(&clocks_sem);
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ down(&clocks_sem);
+ list_del(&clk->node);
+ up(&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init(void)
+{
+ return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-aaec2000/clock.h b/arch/arm/mach-aaec2000/clock.h
new file mode 100644
index 000000000000..d4bb74ff613f
--- /dev/null
+++ b/arch/arm/mach-aaec2000/clock.h
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-aaec2000/clock.h
+ *
+ * Copyright (C) 2005 Nicolas Bellido Y Ortega
+ *
+ * Based on linux/arch/arm/mach-integrator/clock.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.
+ */
+struct module;
+
+struct clk {
+ struct list_head node;
+ unsigned long rate;
+ struct module *owner;
+ const char *name;
+ void *data;
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index aece0cd4f0a3..0c53dab80905 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -13,19 +13,27 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/device.h>
#include <linux/list.h>
#include <linux/errno.h>
+#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/signal.h>
#include <asm/hardware.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/hardware/amba.h>
+#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
+#include "core.h"
+#include "clock.h"
+
/*
* Common I/O mapping:
*
@@ -40,9 +48,17 @@
* default mapping provided here.
*/
static struct map_desc standard_io_desc[] __initdata = {
- /* virtual physical length type */
- { VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE },
- { VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE }
+ {
+ .virtual = VIO_APB_BASE,
+ .physical = __phys_to_pfn(PIO_APB_BASE),
+ .length = IO_APB_LENGTH,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VIO_AHB_BASE,
+ .physical = __phys_to_pfn(PIO_AHB_BASE),
+ .length = IO_AHB_LENGTH,
+ .type = MT_DEVICE
+ }
};
void __init aaec2000_map_io(void)
@@ -155,3 +171,116 @@ struct sys_timer aaec2000_timer = {
.offset = aaec2000_gettimeoffset,
};
+static struct clcd_panel mach_clcd_panel;
+
+static int aaec2000_clcd_setup(struct clcd_fb *fb)
+{
+ dma_addr_t dma;
+
+ fb->panel = &mach_clcd_panel;
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, SZ_1M,
+ &dma, GFP_KERNEL);
+
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = SZ_1M;
+
+ return 0;
+}
+
+static int aaec2000_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base,
+ fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+static void aaec2000_clcd_remove(struct clcd_fb *fb)
+{
+ dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board clcd_plat_data = {
+ .name = "AAEC-2000",
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .setup = aaec2000_clcd_setup,
+ .mmap = aaec2000_clcd_mmap,
+ .remove = aaec2000_clcd_remove,
+};
+
+static struct amba_device clcd_device = {
+ .dev = {
+ .bus_id = "mb:16",
+ .coherent_dma_mask = ~0,
+ .platform_data = &clcd_plat_data,
+ },
+ .res = {
+ .start = AAEC_CLCD_PHYS,
+ .end = AAEC_CLCD_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { INT_LCD, NO_IRQ },
+ .periphid = 0x41110,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &clcd_device,
+};
+
+static struct clk aaec2000_clcd_clk = {
+ .name = "CLCDCLK",
+};
+
+void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *clcd)
+{
+ clcd_plat_data.enable = clcd->enable;
+ clcd_plat_data.disable = clcd->disable;
+ memcpy(&mach_clcd_panel, &clcd->panel, sizeof(struct clcd_panel));
+}
+
+static struct flash_platform_data aaec2000_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 4,
+};
+
+static struct resource aaec2000_flash_resource = {
+ .start = AAEC_FLASH_BASE,
+ .end = AAEC_FLASH_BASE + AAEC_FLASH_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device aaec2000_flash_device = {
+ .name = "armflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &aaec2000_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &aaec2000_flash_resource,
+};
+
+static int __init aaec2000_init(void)
+{
+ int i;
+
+ clk_register(&aaec2000_clcd_clk);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+ platform_device_register(&aaec2000_flash_device);
+
+ return 0;
+};
+arch_initcall(aaec2000_init);
+
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
index 91893d848c16..daefc0ea14a1 100644
--- a/arch/arm/mach-aaec2000/core.h
+++ b/arch/arm/mach-aaec2000/core.h
@@ -9,8 +9,19 @@
*
*/
+#include <asm/hardware/amba_clcd.h>
+
struct sys_timer;
extern struct sys_timer aaec2000_timer;
extern void __init aaec2000_map_io(void);
extern void __init aaec2000_init_irq(void);
+
+struct aaec2000_clcd_info {
+ struct clcd_panel panel;
+ void (*disable)(struct clcd_fb *);
+ void (*enable)(struct clcd_fb *);
+};
+
+extern void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *);
+
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index 0793dcf54f2e..d5c155045762 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -69,6 +69,17 @@ config EP72XX_ROM_BOOT
You almost surely want to say N here.
+config MACH_MP1000
+ bool "MACH_MP1000"
+ help
+ Say Y if you intend to run the kernel on the Comdial MP1000 platform.
+
+config MP1000_90MHZ
+ bool "MP1000_90MHZ"
+ depends on MACH_MP1000
+ help
+ Say Y if you have the MP1000 configured to be set at 90MHZ rather than 74MHZ
+
endmenu
endif
diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
index 4a197315f0cf..8a6dc1ccf8fe 100644
--- a/arch/arm/mach-clps711x/Makefile
+++ b/arch/arm/mach-clps711x/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
+obj-$(CONFIG_MACH_MP1000) += mp1000-mach.o mp1000-mm.o mp1000-seprom.o
obj-$(CONFIG_ARCH_P720T) += p720t.o
leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
obj-$(CONFIG_LEDS) += $(leds-y)
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index dc73feb1ffb0..43b9423d1440 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -46,10 +46,14 @@
*/
static struct map_desc autcpu12_io_desc[] __initdata = {
- /* virtual, physical, length, type */
- /* memory-mapped extra io and CS8900A Ethernet chip */
- /* ethernet chip */
- { AUTCPU12_VIRT_CS8900A, AUTCPU12_PHYS_CS8900A, SZ_1M, MT_DEVICE }
+ /* memory-mapped extra io and CS8900A Ethernet chip */
+ /* ethernet chip */
+ {
+ .virtual = AUTCPU12_VIRT_CS8900A,
+ .pfn = __phys_to_pfn(AUTCPU12_PHYS_CS8900A),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
void __init autcpu12_map_io(void)
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index a46c82cd2711..cba7be5a06c3 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -39,7 +39,12 @@
* ethernet driver, perhaps.
*/
static struct map_desc cdb89712_io_desc[] __initdata = {
- { ETHER_BASE, ETHER_START, ETHER_SIZE, MT_DEVICE }
+ {
+ .virtual = ETHER_BASE,
+ .pfn =__phys_to_pfn(ETHER_START),
+ .length = ETHER_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init cdb89712_map_io(void)
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
index 780d91805984..35d51a759b59 100644
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -37,11 +37,13 @@
#include "common.h"
static struct map_desc ceiva_io_desc[] __initdata = {
- /* virtual, physical, length, type */
-
- /* SED1355 controlled video RAM & registers */
- { CEIVA_VIRT_SED1355, CEIVA_PHYS_SED1355, SZ_2M, MT_DEVICE }
-
+ /* SED1355 controlled video RAM & registers */
+ {
+ .virtual = CEIVA_VIRT_SED1355,
+ .pfn = __phys_to_pfn(CEIVA_PHYS_SED1355),
+ .length = SZ_2M,
+ .type = MT_DEVICE
+ }
};
diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c
index 7fd7b01822d0..72f8bb05d55e 100644
--- a/arch/arm/mach-clps711x/edb7211-mm.c
+++ b/arch/arm/mach-clps711x/edb7211-mm.c
@@ -51,15 +51,27 @@ extern void clps711x_map_io(void);
* happens).
*/
static struct map_desc edb7211_io_desc[] __initdata = {
- /* virtual, physical, length, type */
-
- /* memory-mapped extra keyboard row and CS8900A Ethernet chip */
- { EP7211_VIRT_EXTKBD, EP7211_PHYS_EXTKBD, SZ_1M, MT_DEVICE },
- { EP7211_VIRT_CS8900A, EP7211_PHYS_CS8900A, SZ_1M, MT_DEVICE },
-
- /* flash banks */
- { EP7211_VIRT_FLASH1, EP7211_PHYS_FLASH1, SZ_8M, MT_DEVICE },
- { EP7211_VIRT_FLASH2, EP7211_PHYS_FLASH2, SZ_8M, MT_DEVICE }
+ { /* memory-mapped extra keyboard row */
+ .virtual = EP7211_VIRT_EXTKBD,
+ .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD),
+ .length = SZ_1M,
+ .type - MT_DEVICE
+ }, { /* and CS8900A Ethernet chip */
+ .virtual = EP7211_VIRT_CS8900A,
+ .pfn = __phys_to_pfn(EP7211_PHYS_CS8900A),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, { /* flash banks */
+ .virtual = EP7211_VIRT_FLASH1,
+ .pfn = __phys_to_pfn(EP7211_PHYS_FLASH1),
+ .length = SZ_8M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = EP7211_VIRT_FLASH2,
+ .pfn = __phys_to_pfn(EP7211_PHYS_FLASH2),
+ .length = SZ_8M,
+ .type = MT_DEVICE
+ }
};
void __init edb7211_map_io(void)
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index f83a59761e02..3d88da0c287b 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -31,6 +31,8 @@
#include <asm/mach/arch.h>
+#include <asm/memory.h>
+
#include "common.h"
struct meminfo memmap = {
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index 120b7cac84b5..a00f77ef8df8 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <asm/sizes.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -34,7 +35,12 @@
* This maps the generic CLPS711x registers
*/
static struct map_desc clps711x_io_desc[] __initdata = {
- { CLPS7111_VIRT_BASE, CLPS7111_PHYS_BASE, 1048576, MT_DEVICE }
+ {
+ .virtual = CLPS7111_VIRT_BASE,
+ .pfn = __phys_to_pfn(CLPS7111_PHYS_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
void __init clps711x_map_io(void)
diff --git a/arch/arm/mach-clps711x/mp1000-mach.c b/arch/arm/mach-clps711x/mp1000-mach.c
new file mode 100644
index 000000000000..c2816bcde5e7
--- /dev/null
+++ b/arch/arm/mach-clps711x/mp1000-mach.c
@@ -0,0 +1,49 @@
+/*
+ * linux/arch/arm/mach-mp1000/mp1000.c
+ *
+ * Copyright (C) 2005 Comdial Corporation
+ *
+ * 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/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/mp1000-seprom.h>
+
+#include "common.h"
+
+extern void mp1000_map_io(void);
+
+static void __init mp1000_init(void)
+{
+ seprom_init();
+}
+
+MACHINE_START(MP1000, "Comdial MP1000")
+ /* Maintainer: Jon Ringle */
+ .phys_ram = 0xc0000000,
+ .phys_io = 0x80000000,
+ .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
+ .boot_params = 0xc0015100,
+ .map_io = mp1000_map_io,
+ .init_irq = clps711x_init_irq,
+ .init_machine = mp1000_init,
+ .timer = &clps711x_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-clps711x/mp1000-mm.c b/arch/arm/mach-clps711x/mp1000-mm.c
new file mode 100644
index 000000000000..20e810b0ec0c
--- /dev/null
+++ b/arch/arm/mach-clps711x/mp1000-mm.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-mp1000/mm.c
+ *
+ * Extra MM routines for the MP1000
+ *
+ * Copyright (C) 2005 Comdial Corporation
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/map.h>
+
+extern void clps711x_map_io(void);
+
+static struct map_desc mp1000_io_desc[] __initdata = {
+ { MP1000_EIO_BASE, MP1000_EIO_START, MP1000_EIO_SIZE, MT_DEVICE },
+ { MP1000_FIO_BASE, MP1000_FIO_START, MP1000_FIO_SIZE, MT_DEVICE },
+ { MP1000_LIO_BASE, MP1000_LIO_START, MP1000_LIO_SIZE, MT_DEVICE },
+ { MP1000_NIO_BASE, MP1000_NIO_START, MP1000_NIO_SIZE, MT_DEVICE },
+ { MP1000_IDE_BASE, MP1000_IDE_START, MP1000_IDE_SIZE, MT_DEVICE },
+ { MP1000_DSP_BASE, MP1000_DSP_START, MP1000_DSP_SIZE, MT_DEVICE }
+};
+
+void __init mp1000_map_io(void)
+{
+ clps711x_map_io();
+ iotable_init(mp1000_io_desc, ARRAY_SIZE(mp1000_io_desc));
+}
diff --git a/arch/arm/mach-clps711x/mp1000-seprom.c b/arch/arm/mach-clps711x/mp1000-seprom.c
new file mode 100644
index 000000000000..b22d0bebb851
--- /dev/null
+++ b/arch/arm/mach-clps711x/mp1000-seprom.c
@@ -0,0 +1,195 @@
+/*`
+ * mp1000-seprom.c
+ *
+ * This file contains the Serial EEPROM code for the MP1000 board
+ *
+ * Copyright (C) 2005 Comdial Corporation
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/hardware/clps7111.h>
+#include <asm/arch/mp1000-seprom.h>
+
+/* If SepromInit() can initialize and checksum the seprom successfully, */
+/* then it will point seprom_data_ptr at the shadow copy. */
+
+static eeprom_struct seprom_data; /* shadow copy of seprom content */
+
+eeprom_struct *seprom_data_ptr = 0; /* 0 => not initialized */
+
+/*
+ * Port D Bit 5 is Chip Select for EEPROM
+ * Port E Bit 0 is Input, Data out from EEPROM
+ * Port E Bit 1 is Output, Data in to EEPROM
+ * Port E Bit 2 is Output, CLK to EEPROM
+ */
+
+static char *port_d_ptr = (char *)(CLPS7111_VIRT_BASE + PDDR);
+static char *port_e_ptr = (char *)(CLPS7111_VIRT_BASE + PEDR);
+
+#define NO_OF_SHORTS 64 // Device is 64 x 16 bits
+#define ENABLE_RW 0
+#define DISABLE_RW 1
+
+static inline void toggle_seprom_clock(void)
+{
+ *port_e_ptr |= HwPortESepromCLK;
+ *port_e_ptr &= ~(HwPortESepromCLK);
+}
+
+static inline void select_eeprom(void)
+{
+ *port_d_ptr |= HwPortDEECS;
+ *port_e_ptr &= ~(HwPortESepromCLK);
+}
+
+static inline void deselect_eeprom(void)
+{
+ *port_d_ptr &= ~(HwPortDEECS);
+ *port_e_ptr &= ~(HwPortESepromDIn);
+}
+
+/*
+ * GetSepromDataPtr - returns pointer to shadow (RAM) copy of seprom
+ * and returns 0 if seprom is not initialized or
+ * has a checksum error.
+ */
+
+eeprom_struct* get_seprom_ptr(void)
+{
+ return seprom_data_ptr;
+}
+
+unsigned char* get_eeprom_mac_address(void)
+{
+ return seprom_data_ptr->variant.eprom_struct.mac_Address;
+}
+
+/*
+ * ReadSProm, Physically reads data from the Serial PROM
+ */
+static void read_sprom(short address, int length, eeprom_struct *buffer)
+{
+ short data = COMMAND_READ | (address & 0x3F);
+ short bit;
+ int i;
+
+ select_eeprom();
+
+ // Clock in 9 bits of the command
+ for (i = 0, bit = 0x100; i < 9; i++, bit >>= 1) {
+ if (data & bit)
+ *port_e_ptr |= HwPortESepromDIn;
+ else
+ *port_e_ptr &= ~(HwPortESepromDIn);
+
+ toggle_seprom_clock();
+ }
+
+ //
+ // Now read one or more shorts of data from the Seprom
+ //
+ while (length-- > 0) {
+ data = 0;
+
+ // Read 16 bits at a time
+ for (i = 0; i < 16; i++) {
+ data <<= 1;
+ toggle_seprom_clock();
+ data |= *port_e_ptr & HwPortESepromDOut;
+
+ }
+
+ buffer->variant.eprom_short_data[address++] = data;
+ }
+
+ deselect_eeprom();
+
+ return;
+}
+
+
+
+/*
+ * ReadSerialPROM
+ *
+ * Input: Pointer to array of 64 x 16 Bits
+ *
+ * Output: if no problem reading data is filled in
+ */
+static void read_serial_prom(eeprom_struct *data)
+{
+ read_sprom(0, 64, data);
+}
+
+
+//
+// Compute Serial EEPROM checksum
+//
+// Input: Pointer to struct with Eprom data
+//
+// Output: The computed Eprom checksum
+//
+static short compute_seprom_checksum(eeprom_struct *data)
+{
+ short checksum = 0;
+ int i;
+
+ for (i = 0; i < 126; i++) {
+ checksum += (short)data->variant.eprom_byte_data[i];
+ }
+
+ return((short)(0x5555 - (checksum & 0xFFFF)));
+}
+
+//
+// Make sure the data port bits for the SEPROM are correctly initialised
+//
+
+void __init seprom_init(void)
+{
+ short checksum;
+
+ // Init Port D
+ *(char *)(CLPS7111_VIRT_BASE + PDDDR) = 0x0;
+ *(char *)(CLPS7111_VIRT_BASE + PDDR) = 0x15;
+
+ // Init Port E
+ *(int *)(CLPS7111_VIRT_BASE + PEDDR) = 0x06;
+ *(int *)(CLPS7111_VIRT_BASE + PEDR) = 0x04;
+
+ //
+ // Make sure that EEPROM struct size never exceeds 128 bytes
+ //
+ if (sizeof(eeprom_struct) > 128) {
+ panic("Serial PROM struct size > 128, aborting read\n");
+ }
+
+ read_serial_prom(&seprom_data);
+
+ checksum = compute_seprom_checksum(&seprom_data);
+
+ if (checksum != seprom_data.variant.eprom_short_data[63]) {
+ panic("Serial EEPROM checksum failed\n");
+ }
+
+ seprom_data_ptr = &seprom_data;
+}
+
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index 5bdb90edf992..a1acb945fb51 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -29,6 +29,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/setup.h>
+#include <asm/sizes.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -42,8 +43,17 @@
* We map both here.
*/
static struct map_desc p720t_io_desc[] __initdata = {
- { SYSPLD_VIRT_BASE, SYSPLD_PHYS_BASE, 1048576, MT_DEVICE },
- { 0xfe400000, 0x10400000, 1048576, MT_DEVICE }
+ {
+ .virtual = SYSPLD_VIRT_BASE,
+ .pfn = __phys_to_pfn(SYSPLD_PHYS_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfe400000,
+ .pfn = __phys_to_pfn(0x10400000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
static void __init
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 112f1d68fb2b..0364ba4b539e 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -259,10 +259,27 @@ static void __init clps7500_init_irq(void)
}
static struct map_desc cl7500_io_desc[] __initdata = {
- { IO_BASE, IO_START, IO_SIZE, MT_DEVICE }, /* IO space */
- { ISA_BASE, ISA_START, ISA_SIZE, MT_DEVICE }, /* ISA space */
- { FLASH_BASE, FLASH_START, FLASH_SIZE, MT_DEVICE }, /* Flash */
- { LED_BASE, LED_START, LED_SIZE, MT_DEVICE } /* LED */
+ { /* IO space */
+ .virtual = IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }, { /* ISA space */
+ .virtual = ISA_BASE,
+ .pfn = __phys_to_pfn(ISA_START),
+ .length = ISA_SIZE,
+ .type = MT_DEVICE
+ }, { /* Flash */
+ .virtual = FLASH_BASE,
+ .pfn = __phys_to_pfn(FLASH_START),
+ .length = FLASH_SIZE,
+ .type = MT_DEVICE
+ }, { /* LED */
+ .virtual = LED_BASE,
+ .pfn = __phys_to_pfn(LED_START),
+ .length = LED_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init clps7500_map_io(void)
@@ -354,7 +371,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 23c4da10101b..15261646dcdd 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -76,16 +76,42 @@ static struct map_desc ebsa110_io_desc[] __initdata = {
/*
* sparse external-decode ISAIO space
*/
- { IRQ_STAT, TRICK4_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_STAT/IRQ_MCLR */
- { IRQ_MASK, TRICK3_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_MASK/IRQ_MSET */
- { SOFT_BASE, TRICK1_PHYS, PGDIR_SIZE, MT_DEVICE }, /* SOFT_BASE */
- { PIT_BASE, TRICK0_PHYS, PGDIR_SIZE, MT_DEVICE }, /* PIT_BASE */
+ { /* IRQ_STAT/IRQ_MCLR */
+ .virtual = IRQ_STAT,
+ .pfn = __phys_to_pfn(TRICK4_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* IRQ_MASK/IRQ_MSET */
+ .virtual = IRQ_MASK,
+ .pfn = __phys_to_pfn(TRICK3_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* SOFT_BASE */
+ .virtual = SOFT_BASE,
+ .pfn = __phys_to_pfn(TRICK1_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* PIT_BASE */
+ .virtual = PIT_BASE,
+ .pfn = __phys_to_pfn(TRICK0_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ },
/*
* self-decode ISAIO space
*/
- { ISAIO_BASE, ISAIO_PHYS, ISAIO_SIZE, MT_DEVICE },
- { ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, MT_DEVICE }
+ {
+ .virtual = ISAIO_BASE,
+ .pfn = __phys_to_pfn(ISAIO_PHYS),
+ .length = ISAIO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = ISAMEM_BASE,
+ .pfn = __phys_to_pfn(ISAMEM_PHYS),
+ .length = ISAMEM_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init ebsa110_map_io(void)
@@ -219,7 +245,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/io.c b/arch/arm/mach-ebsa110/io.c
index ef7eb5dc91bd..c648bfb676a1 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/page.h>
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index 7daa021676d0..44c56571d183 100644
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -52,7 +52,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
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/mm.c b/arch/arm/mach-epxa10db/mm.c
index 2aa57fa46da3..e8832d0910ee 100644
--- a/arch/arm/mach-epxa10db/mm.c
+++ b/arch/arm/mach-epxa10db/mm.c
@@ -31,12 +31,37 @@
/* Page table mapping for I/O region */
static struct map_desc epxa10db_io_desc[] __initdata = {
- { IO_ADDRESS(EXC_REGISTERS_BASE), EXC_REGISTERS_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK0_BASE), EXC_PLD_BLOCK0_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK1_BASE), EXC_PLD_BLOCK1_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK2_BASE), EXC_PLD_BLOCK2_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK3_BASE), EXC_PLD_BLOCK3_BASE, SZ_16K, MT_DEVICE },
- { FLASH_VADDR(EXC_EBI_BLOCK0_BASE), EXC_EBI_BLOCK0_BASE, SZ_16M, MT_DEVICE }
+ {
+ .virtual = IO_ADDRESS(EXC_REGISTERS_BASE),
+ .pfn = __phys_to_pfn(EXC_REGISTERS_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK0_BASE),
+ .pfn = __phys_to_pfn(EXC_PLD_BLOCK0_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK1_BASE),
+ .pfn =__phys_to_pfn(EXC_PLD_BLOCK1_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK2_BASE),
+ .physical = __phys_to_pfn(EXC_PLD_BLOCK2_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK3_BASE),
+ .pfn = __phys_to_pfn(EXC_PLD_BLOCK3_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = FLASH_VADDR(EXC_EBI_BLOCK0_BASE),
+ .pfn = __phys_to_pfn(EXC_EBI_BLOCK0_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }
};
void __init epxa10db_map_io(void)
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index eb8238c1ef06..dc09fd200c16 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -130,8 +130,17 @@ void __init footbridge_init_irq(void)
* it means that we have extra bullet protection on our feet.
*/
static struct map_desc fb_common_io_desc[] __initdata = {
- { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, MT_DEVICE },
- { XBUS_BASE, 0x40000000, XBUS_SIZE, MT_DEVICE }
+ {
+ .virtual = ARMCSR_BASE,
+ .pfn = DC21285_ARMCSR_BASE,
+ .length = ARMCSR_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = XBUS_BASE,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = XBUS_SIZE,
+ .type = MT_DEVICE
+ }
};
/*
@@ -140,11 +149,32 @@ static struct map_desc fb_common_io_desc[] __initdata = {
*/
static struct map_desc ebsa285_host_io_desc[] __initdata = {
#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE },
- { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, MT_DEVICE },
- { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, MT_DEVICE },
- { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, MT_DEVICE },
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE }
+ {
+ .virtual = PCIMEM_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_MEM),
+ .length = PCIMEM_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCICFG0_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
+ .length = PCICFG0_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCICFG1_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
+ .length = PCICFG1_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCIIACK_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IACK),
+ .length = PCIIACK_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCIO_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IO),
+ .length = PCIO_SIZE,
+ .type = MT_DEVICE
+ }
#endif
};
@@ -153,8 +183,17 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
*/
static struct map_desc co285_io_desc[] __initdata = {
#ifdef CONFIG_ARCH_CO285
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE },
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE }
+ {
+ .virtual = PCIO_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IO),
+ .length = PCIO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCIMEM_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_MEM),
+ .length = PCIMEM_SIZE,
+ .type = MT_DEVICE
+ }
#endif
};
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
index aa3a1fef563e..28846c7edaaf 100644
--- a/arch/arm/mach-footbridge/isa.c
+++ b/arch/arm/mach-footbridge/isa.c
@@ -34,7 +34,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
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/common.c b/arch/arm/mach-h720x/common.c
index 5110e2e65ddd..c096b4569308 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -237,7 +237,12 @@ void __init h720x_init_irq (void)
}
static struct map_desc h720x_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
};
/* Initialize io tables */
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 4b3199319e68..a4a7c0125d03 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -90,7 +90,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
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-imx/generic.c b/arch/arm/mach-imx/generic.c
index 41e5849ae8da..cb14b0682cef 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -28,14 +28,15 @@
#include <linux/module.h>
#include <asm/arch/imxfb.h>
#include <asm/hardware.h>
+#include <asm/arch/imx-regs.h>
#include <asm/mach/map.h>
void imx_gpio_mode(int gpio_mode)
{
unsigned int pin = gpio_mode & GPIO_PIN_MASK;
- unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
- unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
unsigned int tmp;
/* Pullup enable */
@@ -57,7 +58,7 @@ void imx_gpio_mode(int gpio_mode)
GPR(port) &= ~(1<<pin);
/* use as gpio? */
- if( ocr == 3 )
+ if(gpio_mode & GPIO_GIUS)
GIUS(port) |= (1<<pin);
else
GIUS(port) &= ~(1<<pin);
@@ -72,20 +73,20 @@ void imx_gpio_mode(int gpio_mode)
tmp |= (ocr << (pin*2));
OCR1(port) = tmp;
- if( gpio_mode & GPIO_AOUT )
- ICONFA1(port) &= ~( 3<<(pin*2));
- if( gpio_mode & GPIO_BOUT )
- ICONFB1(port) &= ~( 3<<(pin*2));
+ ICONFA1(port) &= ~( 3<<(pin*2));
+ ICONFA1(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
+ ICONFB1(port) &= ~( 3<<(pin*2));
+ ICONFB1(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
} else {
tmp = OCR2(port);
tmp &= ~( 3<<((pin-16)*2));
tmp |= (ocr << ((pin-16)*2));
OCR2(port) = tmp;
- if( gpio_mode & GPIO_AOUT )
- ICONFA2(port) &= ~( 3<<((pin-16)*2));
- if( gpio_mode & GPIO_BOUT )
- ICONFB2(port) &= ~( 3<<((pin-16)*2));
+ ICONFA2(port) &= ~( 3<<((pin-16)*2));
+ ICONFA2(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << ((pin-16) * 2);
+ ICONFB2(port) &= ~( 3<<((pin-16)*2));
+ ICONFB2(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << ((pin-16) * 2);
}
}
@@ -272,8 +273,12 @@ static struct platform_device *devices[] __initdata = {
};
static struct map_desc imx_io_desc[] __initdata = {
- /* virtual physical length type */
- {IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE},
+ {
+ .virtual = IMX_IO_BASE,
+ .pfn = __phys_to_pfn(IMX_IO_PHYS),
+ .length = IMX_IO_SIZE,
+ .type = MT_DEVICE
+ }
};
void __init
diff --git a/arch/arm/mach-imx/leds-mx1ads.c b/arch/arm/mach-imx/leds-mx1ads.c
index e6399b06e4a4..79236404aec2 100644
--- a/arch/arm/mach-imx/leds-mx1ads.c
+++ b/arch/arm/mach-imx/leds-mx1ads.c
@@ -17,7 +17,6 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/leds.h>
-#include <asm/mach-types.h>
#include "leds.h"
/*
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index 5d25434d332c..4cbdc1fe04b1 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -55,19 +55,43 @@ static void __init
mx1ads_init(void)
{
#ifdef CONFIG_LEDS
- imx_gpio_mode(GPIO_PORTA | GPIO_OUT | GPIO_GPIO | 2);
+ imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2);
#endif
platform_add_devices(devices, ARRAY_SIZE(devices));
}
static struct map_desc mx1ads_io_desc[] __initdata = {
- /* virtual physical length type */
- {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE},
- {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE},
- {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE},
- {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE},
- {IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE},
- {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE},
+ {
+ .virtual = IMX_CS0_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS0_PHYS),
+ .length = IMX_CS0_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS1_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS1_PHYS),
+ .length = IMX_CS1_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS2_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS2_PHYS),
+ .length = IMX_CS2_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS3_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS3_PHYS),
+ .length = IMX_CS3_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS4_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS4_PHYS),
+ .length = IMX_CS4_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS5_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS5_PHYS),
+ .length = IMX_CS5_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index c3c2f17d030e..a1b153d1626c 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -67,7 +67,7 @@ static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
}
writel(0, impd1->base + IMPD1_LOCK);
-#if DEBUG
+#ifdef DEBUG
vco.v = val & 0x1ff;
vco.r = (val >> 9) & 0x7f;
vco.s = (val >> 16) & 7;
@@ -427,17 +427,18 @@ static int impd1_probe(struct lm_device *dev)
return ret;
}
+static int impd1_remove_one(struct device *dev, void *data)
+{
+ device_unregister(dev);
+ return 0;
+}
+
static void impd1_remove(struct lm_device *dev)
{
struct impd1_module *impd1 = lm_get_drvdata(dev);
- struct list_head *l, *n;
int i;
- list_for_each_safe(l, n, &dev->dev.children) {
- struct device *d = list_to_dev(l);
-
- device_unregister(d);
- }
+ device_for_each_child(&dev->dev, NULL, impd1_remove_one);
for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++)
clk_unregister(&impd1->vcos[i]);
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 36e2b6eb67b7..f368b85f0447 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -75,19 +75,72 @@
*/
static struct map_desc ap_io_desc[] __initdata = {
- { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
- { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
- { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE },
- { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE },
- { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE }
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_MEMORY_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_CONFIG_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_V3_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_IO_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }
};
static void __init ap_map_io(void)
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 2be5c03ab87f..aa34c58b96c4 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -74,17 +74,62 @@
*/
static struct map_desc intcp_io_desc[] __initdata = {
- { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
- { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE },
- { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfca00000,
+ .pfn = __phys_to_pfn(0xca000000),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfcb00000,
+ .pfn = __phys_to_pfn(0xcb000000),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }
};
static void __init intcp_map_io(void)
diff --git a/arch/arm/mach-iop3xx/common.c b/arch/arm/mach-iop3xx/common.c
index bda7394ec06c..fdeeef489a73 100644
--- a/arch/arm/mach-iop3xx/common.c
+++ b/arch/arm/mach-iop3xx/common.c
@@ -27,7 +27,6 @@ unsigned long iop3xx_pcibios_min_mem = 0;
/*
* Default power-off for EP80219
*/
-#include <asm/mach-types.h>
static inline void ep80219_send_to_pic(__u8 c) {
}
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
index 0f921ba2750c..bb5091223b63 100644
--- a/arch/arm/mach-iop3xx/iop321-setup.c
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -38,13 +38,17 @@
* Standard IO mapping for all IOP321 based systems
*/
static struct map_desc iop321_std_desc[] __initdata = {
- /* virtual physical length type */
-
- /* mem mapped registers */
- { IOP321_VIRT_MEM_BASE, IOP321_PHYS_MEM_BASE, 0x00002000, MT_DEVICE },
-
- /* PCI IO space */
- { IOP321_PCI_LOWER_IO_VA, IOP321_PCI_LOWER_IO_PA, IOP321_PCI_IO_WINDOW_SIZE, MT_DEVICE }
+ { /* mem mapped registers */
+ .virtual = IOP321_VIRT_MEM_BASE,
+ .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE),
+ .length = 0x00002000,
+ .type = MT_DEVICE
+ }, { /* PCI IO space */
+ .virtual = IOP321_PCI_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA),
+ .length = IOP321_PCI_IO_WINDOW_SIZE,
+ .type = MT_DEVICE
+ }
};
#ifdef CONFIG_ARCH_IQ80321
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
index 0039793b694a..d67ac0e5d438 100644
--- a/arch/arm/mach-iop3xx/iop321-time.c
+++ b/arch/arm/mach-iop3xx/iop321-time.c
@@ -23,7 +23,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
-#include <asm/mach-types.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
index fc74b722f72f..a2533c3ab42f 100644
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -37,13 +37,17 @@
* Standard IO mapping for all IOP331 based systems
*/
static struct map_desc iop331_std_desc[] __initdata = {
- /* virtual physical length type */
-
- /* mem mapped registers */
- { IOP331_VIRT_MEM_BASE, IOP331_PHYS_MEM_BASE, 0x00002000, MT_DEVICE },
-
- /* PCI IO space */
- { IOP331_PCI_LOWER_IO_VA, IOP331_PCI_LOWER_IO_PA, IOP331_PCI_IO_WINDOW_SIZE, MT_DEVICE }
+ { /* mem mapped registers */
+ .virtual = IOP331_VIRT_MEM_BASE,
+ .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE),
+ .length = 0x00002000,
+ .type = MT_DEVICE
+ }, { /* PCI IO space */
+ .virtual = IOP331_PCI_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA),
+ .length = IOP331_PCI_IO_WINDOW_SIZE,
+ .type = MT_DEVICE
+ }
};
static struct uart_port iop331_serial_ports[] = {
diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c
index 8eddfac7e2b0..3c1f0ebbd636 100644
--- a/arch/arm/mach-iop3xx/iop331-time.c
+++ b/arch/arm/mach-iop3xx/iop331-time.c
@@ -23,7 +23,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
-#include <asm/mach-types.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c
index b01042f7de71..e874b54eefe3 100644
--- a/arch/arm/mach-iop3xx/iq31244-mm.c
+++ b/arch/arm/mach-iop3xx/iq31244-mm.c
@@ -21,7 +21,6 @@
#include <asm/page.h>
#include <asm/mach/map.h>
-#include <asm/mach-types.h>
/*
@@ -30,10 +29,12 @@
* We use RedBoot's setup for the onboard devices.
*/
static struct map_desc iq31244_io_desc[] __initdata = {
- /* virtual physical length type */
-
- /* on-board devices */
- { IQ31244_UART, IQ31244_UART, 0x00100000, MT_DEVICE }
+ { /* on-board devices */
+ .virtual = IQ31244_UART,
+ .pfn = __phys_to_pfn(IQ31244_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
void __init iq31244_map_io(void)
diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c
index 1580c7ed2b9d..d9cac5e1fc3d 100644
--- a/arch/arm/mach-iop3xx/iq80321-mm.c
+++ b/arch/arm/mach-iop3xx/iq80321-mm.c
@@ -21,7 +21,6 @@
#include <asm/page.h>
#include <asm/mach/map.h>
-#include <asm/mach-types.h>
/*
@@ -30,10 +29,12 @@
* We use RedBoot's setup for the onboard devices.
*/
static struct map_desc iq80321_io_desc[] __initdata = {
- /* virtual physical length type */
-
- /* on-board devices */
- { IQ80321_UART, IQ80321_UART, 0x00100000, MT_DEVICE }
+ { /* on-board devices */
+ .virtual = IQ80321_UART,
+ .pfn = __phys_to_pfn(IQ80321_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
void __init iq80321_map_io(void)
diff --git a/arch/arm/mach-iop3xx/iq80331-mm.c b/arch/arm/mach-iop3xx/iq80331-mm.c
index ee8c333e115f..129eb49b0670 100644
--- a/arch/arm/mach-iop3xx/iq80331-mm.c
+++ b/arch/arm/mach-iop3xx/iq80331-mm.c
@@ -21,7 +21,6 @@
#include <asm/page.h>
#include <asm/mach/map.h>
-#include <asm/mach-types.h>
/*
diff --git a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c
index 084afcdfb1eb..2feaf7591f53 100644
--- a/arch/arm/mach-iop3xx/iq80332-mm.c
+++ b/arch/arm/mach-iop3xx/iq80332-mm.c
@@ -21,7 +21,6 @@
#include <asm/page.h>
#include <asm/mach/map.h>
-#include <asm/mach-types.h>
/*
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 098c817a7fb8..01c393c504d0 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -30,7 +30,6 @@
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
@@ -84,42 +83,42 @@ void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
static struct map_desc ixp2000_io_desc[] __initdata = {
{
.virtual = IXP2000_CAP_VIRT_BASE,
- .physical = IXP2000_CAP_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
.length = IXP2000_CAP_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_INTCTL_VIRT_BASE,
- .physical = IXP2000_INTCTL_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
.length = IXP2000_INTCTL_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_PCI_CREG_VIRT_BASE,
- .physical = IXP2000_PCI_CREG_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
.length = IXP2000_PCI_CREG_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_PCI_CSR_VIRT_BASE,
- .physical = IXP2000_PCI_CSR_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
.length = IXP2000_PCI_CSR_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_MSF_VIRT_BASE,
- .physical = IXP2000_MSF_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
.length = IXP2000_MSF_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_PCI_IO_VIRT_BASE,
- .physical = IXP2000_PCI_IO_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
.length = IXP2000_PCI_IO_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_PCI_CFG0_VIRT_BASE,
- .physical = IXP2000_PCI_CFG0_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
.length = IXP2000_PCI_CFG0_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXP2000_PCI_CFG1_VIRT_BASE,
- .physical = IXP2000_PCI_CFG1_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
.length = IXP2000_PCI_CFG1_SIZE,
.type = MT_DEVICE
}
@@ -168,13 +167,13 @@ static struct plat_serial8250_port ixp2000_serial_port[] = {
static struct resource ixp2000_uart_resource = {
.start = IXP2000_UART_PHYS_BASE,
- .end = IXP2000_UART_PHYS_BASE + 0xffff,
+ .end = IXP2000_UART_PHYS_BASE + 0x1f,
.flags = IORESOURCE_MEM,
};
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-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 63ba0191aa65..8b4a839b6279 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -176,7 +176,7 @@ void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long
*************************************************************************/
static struct map_desc ixdp2x00_io_desc __initdata = {
.virtual = IXDP2X00_VIRT_CPLD_BASE,
- .physical = IXDP2X00_PHYS_CPLD_BASE,
+ .pfn = __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE),
.length = IXDP2X00_CPLD_SIZE,
.type = MT_DEVICE
};
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 7a5109921287..fee1d7b73503 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -136,7 +136,7 @@ void __init ixdp2x01_init_irq(void)
*************************************************************************/
static struct map_desc ixdp2x01_io_desc __initdata = {
.virtual = IXDP2X01_VIRT_CPLD_BASE,
- .physical = IXDP2X01_PHYS_CPLD_BASE,
+ .pfn = __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE),
.length = IXDP2X01_CPLD_REGION_SIZE,
.type = MT_DEVICE
};
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 0788fb2b5c10..522205acb316 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/mach/pci.h>
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 52ad11328e96..6c396447c4e0 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -44,24 +44,24 @@
static struct map_desc ixp4xx_io_desc[] __initdata = {
{ /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
.virtual = IXP4XX_PERIPHERAL_BASE_VIRT,
- .physical = IXP4XX_PERIPHERAL_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
.length = IXP4XX_PERIPHERAL_REGION_SIZE,
.type = MT_DEVICE
}, { /* Expansion Bus Config Registers */
.virtual = IXP4XX_EXP_CFG_BASE_VIRT,
- .physical = IXP4XX_EXP_CFG_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
.length = IXP4XX_EXP_CFG_REGION_SIZE,
.type = MT_DEVICE
}, { /* PCI Registers */
.virtual = IXP4XX_PCI_CFG_BASE_VIRT,
- .physical = IXP4XX_PCI_CFG_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
.length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE
},
#ifdef CONFIG_DEBUG_LL
{ /* Debug UART mapping */
.virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
- .physical = IXP4XX_DEBUG_UART_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
.length = IXP4XX_DEBUG_UART_REGION_SIZE,
.type = MT_DEVICE
}
@@ -125,7 +125,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
} else if (type & IRQT_LOW) {
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP4XX_IRQ_LEVEL;
- }
+ } else
+ return -EINVAL;
ixp4xx_config_irq(irq, irq_type);
@@ -142,6 +143,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
/* Set the new style */
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
+
+ return 0;
}
static void ixp4xx_irq_mask(unsigned int irq)
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 8b2f25322452..050c92768913 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -66,7 +66,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
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 3fd92c5cbaa8..29a6d02fa851 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -93,7 +93,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
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 6c14ff3c23a0..0a41080d2266 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
@@ -123,6 +123,7 @@ static void __init ixdp425_init(void)
platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
}
+#ifdef CONFIG_ARCH_IXDP425
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_ram = PHYS_OFFSET,
@@ -134,7 +135,9 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
+#endif
+#ifdef CONFIG_MACH_IXDP465
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_ram = PHYS_OFFSET,
@@ -146,7 +149,9 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_PRPMC1100
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_ram = PHYS_OFFSET,
@@ -158,6 +163,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
+#endif
/*
* Avila is functionally equivalent to IXDP425 except that it adds
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 2a7fee2a7635..03ed742ae2be 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -7,12 +7,17 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/device.h>
+#include <asm/types.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/page.h>
+#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <asm/arch/hardware.h>
+#include <asm/mach/irq.h>
/*
* IRQ base register
@@ -48,6 +53,12 @@ static void l7200_unmask_irq(unsigned int irq)
{
IRQ_ENABLE = 1 << irq;
}
+
+static struct irqchip l7200_irq_chip = {
+ .ack = l7200_mask_irq,
+ .mask = l7200_mask_irq,
+ .unmask = l7200_unmask_irq
+};
static void __init l7200_init_irq(void)
{
@@ -57,11 +68,9 @@ static void __init l7200_init_irq(void)
FIQ_ENABLECLEAR = 0xffffffff; /* clear all fast interrupt enables */
for (irq = 0; irq < NR_IRQS; irq++) {
- irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
- irq_desc[irq].mask_ack = l7200_mask_irq;
- irq_desc[irq].mask = l7200_mask_irq;
- irq_desc[irq].unmask = l7200_unmask_irq;
+ set_irq_chip(irq, &l7200_irq_chip);
+ set_irq_flags(irq, IRQF_VALID);
+ set_irq_handler(irq, do_level_IRQ);
}
init_FIQ();
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index cb3dcd3bd00a..19f2fa2244c4 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -26,8 +26,17 @@
/* This function calls the board specific IRQ initialization function. */
static struct map_desc kev7a400_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
- { CPLD_VIRT, CPLD_PHYS, CPLD_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD_VIRT,
+ .pfn = __phys_to_pfn(CPLD_PHYS),
+ .length = CPLD_SIZE,
+ .type = MT_DEVICE
+ }
};
void __init kev7a400_map_io(void)
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index 6eb61a17c63b..a20eabc132b0 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -227,23 +227,79 @@ void __init lh7a40x_init_board_irq (void)
}
static struct map_desc lpd7a400_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
- /* Mapping added to work around chip select problems */
- { IOBARRIER_VIRT, IOBARRIER_PHYS, IOBARRIER_SIZE, MT_DEVICE },
- { CF_VIRT, CF_PHYS, CF_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }, { /* Mapping added to work around chip select problems */
+ .virtual = IOBARRIER_VIRT,
+ .pfn = __phys_to_pfn(IOBARRIER_PHYS),
+ .length = IOBARRIER_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CF_VIRT,
+ .pfn = __phys_to_pfn(CF_PHYS),
+ .length = CF_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD02_VIRT,
+ .pfn = __phys_to_pfn(CPLD02_PHYS),
+ .length = CPLD02_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD06_VIRT,
+ .pfn = __phys_to_pfn(CPLD06_PHYS),
+ .length = CPLD06_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD08_VIRT,
+ .pfn = __phys_to_pfn(CPLD08_PHYS),
+ .length = CPLD08_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD0C_VIRT,
+ .pfn = __phys_to_pfn(CPLD0C_PHYS),
+ .length = CPLD0C_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD0E_VIRT,
+ .pfn = __phys_to_pfn(CPLD0E_PHYS),
+ .length = CPLD0E_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD10_VIRT,
+ .pfn = __phys_to_pfn(CPLD10_PHYS),
+ .length = CPLD10_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD12_VIRT,
+ .pfn = __phys_to_pfn(CPLD12_PHYS),
+ .length = CPLD12_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD14_VIRT,
+ .pfn = __phys_to_pfn(CPLD14_PHYS),
+ .length = CPLD14_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD16_VIRT,
+ .pfn = __phys_to_pfn(CPLD16_PHYS),
+ .length = CPLD16_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD18_VIRT,
+ .pfn = __phys_to_pfn(CPLD18_PHYS),
+ .length = CPLD18_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD1A_VIRT,
+ .pfn = __phys_to_pfn(CPLD1A_PHYS),
+ .length = CPLD1A_SIZE,
+ .type = MT_DEVICE
+ },
/* This mapping is redundant since the smc driver performs another. */
/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */
- { CPLD02_VIRT, CPLD02_PHYS, CPLD02_SIZE, MT_DEVICE },
- { CPLD06_VIRT, CPLD06_PHYS, CPLD06_SIZE, MT_DEVICE },
- { CPLD08_VIRT, CPLD08_PHYS, CPLD08_SIZE, MT_DEVICE },
- { CPLD0C_VIRT, CPLD0C_PHYS, CPLD0C_SIZE, MT_DEVICE },
- { CPLD0E_VIRT, CPLD0E_PHYS, CPLD0E_SIZE, MT_DEVICE },
- { CPLD10_VIRT, CPLD10_PHYS, CPLD10_SIZE, MT_DEVICE },
- { CPLD12_VIRT, CPLD12_PHYS, CPLD12_SIZE, MT_DEVICE },
- { CPLD14_VIRT, CPLD14_PHYS, CPLD14_SIZE, MT_DEVICE },
- { CPLD16_VIRT, CPLD16_PHYS, CPLD16_SIZE, MT_DEVICE },
- { CPLD18_VIRT, CPLD18_PHYS, CPLD18_SIZE, MT_DEVICE },
- { CPLD1A_VIRT, CPLD1A_PHYS, CPLD1A_SIZE, MT_DEVICE },
};
void __init
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 7408ac94f771..27fc2e8e5fca 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -47,6 +47,14 @@ config MACH_OMAP_OSK
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 d386fd913f0c..181a93deaaee 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 122796ebe8f5..c209c7172a9a 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -48,19 +48,43 @@ static struct omap_usb_config generic1510_usb_config __initdata = {
#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 f4983ee95ab4..d46a70063b0c 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 7cd419d61b40..2798613696fa 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -82,8 +82,7 @@ static struct flash_platform_data h3_flash_data = {
};
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 91de60a91ef8..fd9183ff2ed5 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>
@@ -102,8 +103,12 @@ static struct platform_device innovator_flash_device = {
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc innovator1510_io_desc[] __initdata = {
-{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
- MT_DEVICE },
+ {
+ .virtual = OMAP1510_FPGA_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_FPGA_START),
+ .length = OMAP1510_FPGA_SIZE,
+ .type = MT_DEVICE
+ }
};
static struct resource innovator1510_smc91x_resources[] = {
@@ -173,7 +178,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 +224,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 6750b2014092..d904e643f5ec 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -75,16 +75,15 @@ static void __init netstar_init(void)
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 6844e536c698..21103df50415 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 213317392d9b..2ba26e239108 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,
};
@@ -133,8 +134,12 @@ void omap_perseus2_init_irq(void)
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc omap_perseus2_io_desc[] __initdata = {
- {H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
- MT_DEVICE},
+ {
+ .virtual = H2P2_DBG_FPGA_BASE,
+ .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START),
+ .length = H2P2_DBG_FPGA_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init omap_perseus2_map_io(void)
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index e42281988990..bf30b1acda0b 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -25,13 +25,14 @@
#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 000000000000..e8b3981444cd
--- /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 c12a78335625..aca2a120813a 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 207df0fe934d..79fb86535ebc 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -19,48 +19,66 @@
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
* default mapping provided here.
*/
static struct map_desc omap_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }
};
#ifdef CONFIG_ARCH_OMAP730
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 }
+ {
+ .virtual = OMAP730_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP730_DSP_START),
+ .length = OMAP730_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP730_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP730_DSPREG_START),
+ .length = OMAP730_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
};
#endif
#ifdef CONFIG_ARCH_OMAP1510
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 }
+ {
+ .virtual = OMAP1510_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_DSP_START),
+ .length = OMAP1510_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP1510_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_DSPREG_START),
+ .length = OMAP1510_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
};
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
-static struct map_desc omap1610_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 }
+static struct map_desc omap16xx_io_desc[] __initdata = {
+ {
+ .virtual = OMAP16XX_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP16XX_DSP_START),
+ .length = OMAP16XX_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP16XX_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP16XX_DSPREG_START),
+ .length = OMAP16XX_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
};
#endif
@@ -86,14 +104,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 +125,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 afd5d67e4ae7..192ce6055faa 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 ec0d8285f243..be283cda63dd 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -1,5 +1,5 @@
/*
- * 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 8043b7d0f66e..c8ffd1ddcded 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 4a0e8b9d4fc3..2c8bda847c18 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 8ab21fe98e1b..5c6b1bb6e722 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 214e5d17c8b5..40c4f7c40e73 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 d540539c9bbb..191a9b1ee9b7 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -247,13 +247,6 @@ unsigned long long sched_clock(void)
#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/Kconfig b/arch/arm/mach-pxa/Kconfig
index 405a55f2287c..3e5f69bb5ac4 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -20,40 +20,66 @@ config ARCH_PXA_IDP
select PXA25x
config PXA_SHARPSL
- bool "SHARP SL-5600 and SL-C7xx Models"
- select PXA25x
+ bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
select SHARP_SCOOP
select SHARP_PARAM
help
Say Y here if you intend to run this kernel on a
- Sharp SL-5600 (Poodle), Sharp SL-C700 (Corgi),
- SL-C750 (Shepherd) or a Sharp SL-C760 (Husky)
- handheld computer.
+ Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
+ SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
+ SL-C3000 (Spitz) or SL-C3100 (Borzoi) handheld computer.
endchoice
+if PXA_SHARPSL
+
+choice
+ prompt "Select target Sharp Zaurus device range"
+
+config PXA_SHARPSL_25x
+ bool "Sharp PXA25x models (SL-5600 and SL-C7xx)"
+ select PXA25x
+
+config PXA_SHARPSL_27x
+ bool "Sharp PXA270 models (SL-Cxx00)"
+ select PXA27x
+
+endchoice
+
+endif
+
endmenu
config MACH_POODLE
bool "Enable Sharp SL-5600 (Poodle) Support"
- depends PXA_SHARPSL
+ depends PXA_SHARPSL_25x
select SHARP_LOCOMO
config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
- depends PXA_SHARPSL
+ depends PXA_SHARPSL_25x
select PXA_SHARP_C7xx
config MACH_SHEPHERD
bool "Enable Sharp SL-C750 (Shepherd) Support"
- depends PXA_SHARPSL
+ depends PXA_SHARPSL_25x
select PXA_SHARP_C7xx
config MACH_HUSKY
bool "Enable Sharp SL-C760 (Husky) Support"
- depends PXA_SHARPSL
+ depends PXA_SHARPSL_25x
select PXA_SHARP_C7xx
+config MACH_SPITZ
+ bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
+ depends PXA_SHARPSL_27x
+ select PXA_SHARP_Cxx00
+
+config MACH_BORZOI
+ bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
+ depends PXA_SHARPSL_27x
+ select PXA_SHARP_Cxx00
+
config PXA25x
bool
help
@@ -74,4 +100,9 @@ config PXA_SHARP_C7xx
help
Enable support for all Sharp C7xx models
+config PXA_SHARP_Cxx00
+ bool
+ help
+ Enable common support for Sharp Cxx00 models
+
endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 33dae99ec2d8..f609a0f232cb 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
+obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o
obj-$(CONFIG_MACH_POODLE) += poodle.o
# Support for blinky lights
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 29185acdd9e1..60c8b9d8bb9c 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -36,11 +36,13 @@
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/corgi.h>
+#include <asm/arch/sharpsl.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/scoop.h>
#include "generic.h"
+#include "sharpsl.h"
/*
@@ -94,14 +96,30 @@ struct platform_device corgissp_device = {
.id = -1,
};
+struct corgissp_machinfo corgi_ssp_machinfo = {
+ .port = 1,
+ .cs_lcdcon = CORGI_GPIO_LCDCON_CS,
+ .cs_ads7846 = CORGI_GPIO_ADS7846_CS,
+ .cs_max1111 = CORGI_GPIO_MAX1111_CS,
+ .clk_lcdcon = 76,
+ .clk_ads7846 = 2,
+ .clk_max1111 = 8,
+};
+
/*
* Corgi Backlight Device
*/
+static struct corgibl_machinfo corgi_bl_machinfo = {
+ .max_intensity = 0x2f,
+ .set_bl_intensity = corgi_bl_set_intensity,
+};
+
static struct platform_device corgibl_device = {
.name = "corgi-bl",
.dev = {
.parent = &corgifb_device.dev,
+ .platform_data = &corgi_bl_machinfo,
},
.id = -1,
};
@@ -119,39 +137,41 @@ static struct platform_device corgikbd_device = {
/*
* Corgi Touch Screen Device
*/
+static struct resource corgits_resources[] = {
+ [0] = {
+ .start = CORGI_IRQ_GPIO_TP_INT,
+ .end = CORGI_IRQ_GPIO_TP_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct corgits_machinfo corgi_ts_machinfo = {
+ .get_hsync_len = corgi_get_hsync_len,
+ .put_hsync = corgi_put_hsync,
+ .wait_hsync = corgi_wait_hsync,
+};
+
static struct platform_device corgits_device = {
.name = "corgi-ts",
.dev = {
.parent = &corgissp_device.dev,
+ .platform_data = &corgi_ts_machinfo,
},
.id = -1,
+ .num_resources = ARRAY_SIZE(corgits_resources),
+ .resource = corgits_resources,
};
/*
* MMC/SD Device
*
- * The card detect interrupt isn't debounced so we delay it by HZ/4
+ * The card detect interrupt isn't debounced so we delay it by 250ms
* to give the card a chance to fully insert/eject.
*/
-static struct mmc_detect {
- struct timer_list detect_timer;
- void *devid;
-} mmc_detect;
-
-static void mmc_detect_callback(unsigned long data)
-{
- mmc_detect_change(mmc_detect.devid);
-}
-
-static irqreturn_t corgi_mmc_detect_int(int irq, void *devid, struct pt_regs *regs)
-{
- mmc_detect.devid=devid;
- mod_timer(&mmc_detect.detect_timer, jiffies + HZ/4);
- return IRQ_HANDLED;
-}
+static struct pxamci_platform_data corgi_mci_platform_data;
-static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(int, void *, struct pt_regs *), void *data)
+static int corgi_mci_init(struct device *dev, irqreturn_t (*corgi_detect_int)(int, void *, struct pt_regs *), void *data)
{
int err;
@@ -161,11 +181,9 @@ static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(i
pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN);
pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT);
- init_timer(&mmc_detect.detect_timer);
- mmc_detect.detect_timer.function = mmc_detect_callback;
- mmc_detect.detect_timer.data = (unsigned long) &mmc_detect;
+ corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
- err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_mmc_detect_int, SA_INTERRUPT,
+ err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, SA_INTERRUPT,
"MMC card detect", data);
if (err) {
printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
@@ -181,13 +199,10 @@ static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data* p_d = dev->platform_data;
- if (( 1 << vdd) & p_d->ocr_mask) {
- printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+ if (( 1 << vdd) & p_d->ocr_mask)
GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
- } else {
- printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+ else
GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
- }
}
static int corgi_mci_get_ro(struct device *dev)
@@ -198,7 +213,6 @@ static int corgi_mci_get_ro(struct device *dev)
static void corgi_mci_exit(struct device *dev, void *data)
{
free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
- del_timer(&mmc_detect.detect_timer);
}
static struct pxamci_platform_data corgi_mci_platform_data = {
@@ -243,7 +257,20 @@ static struct platform_device *devices[] __initdata = {
static void __init corgi_init(void)
{
+ /* setup sleep mode values */
+ PWER = 0x00000002;
+ PFER = 0x00000000;
+ PRER = 0x00000002;
+ PGSR0 = 0x0158C000;
+ PGSR1 = 0x00FF0080;
+ PGSR2 = 0x0001C004;
+ /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+ PCFR |= PCFR_OPDE;
+
+ corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
+ pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&corgi_mci_platform_data);
@@ -266,42 +293,14 @@ static void __init fixup_corgi(struct machine_desc *desc,
mi->bank[0].size = (64*1024*1024);
}
-static void __init corgi_init_irq(void)
-{
- pxa_init_irq();
-}
-
-static struct map_desc corgi_io_desc[] __initdata = {
-/* virtual physical length */
-/* { 0xf1000000, 0x08000000, 0x01000000, MT_DEVICE },*/ /* LCDC (readable for Qt driver) */
-/* { 0xef700000, 0x10800000, 0x00001000, MT_DEVICE },*/ /* SCOOP */
- { 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */
-};
-
-static void __init corgi_map_io(void)
-{
- pxa_map_io();
- iotable_init(corgi_io_desc,ARRAY_SIZE(corgi_io_desc));
-
- /* setup sleep mode values */
- PWER = 0x00000002;
- PFER = 0x00000000;
- PRER = 0x00000002;
- PGSR0 = 0x0158C000;
- PGSR1 = 0x00FF0080;
- PGSR2 = 0x0001C004;
- /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
- PCFR |= PCFR_OPDE;
-}
-
#ifdef CONFIG_MACH_CORGI
MACHINE_START(CORGI, "SHARP Corgi")
.phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
- .map_io = corgi_map_io,
- .init_irq = corgi_init_irq,
+ .map_io = pxa_map_io,
+ .init_irq = pxa_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
@@ -313,8 +312,8 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
- .map_io = corgi_map_io,
- .init_irq = corgi_init_irq,
+ .map_io = pxa_map_io,
+ .init_irq = pxa_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
@@ -326,8 +325,8 @@ MACHINE_START(HUSKY, "SHARP Husky")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
- .map_io = corgi_map_io,
- .init_irq = corgi_init_irq,
+ .map_io = pxa_map_io,
+ .init_irq = pxa_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index deac29c00290..370df113dc06 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -1,10 +1,14 @@
/*
* linux/drivers/video/w100fb.c
*
- * Corgi LCD Specific Code for ATI Imageon w100 (Wallaby)
+ * Corgi/Spitz LCD Specific Code
*
* Copyright (C) 2005 Richard Purdie
*
+ * Connectivity:
+ * Corgi - LCD to ATI Imageon w100 (Wallaby)
+ * Spitz - LCD to PXA Framebuffer
+ *
* 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.
@@ -14,9 +18,16 @@
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/device.h>
+#include <linux/module.h>
+#include <asm/arch/akita.h>
#include <asm/arch/corgi.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/spitz.h>
+#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
-#include <video/w100fb.h>
+#include "generic.h"
/* Register Addresses */
#define RESCTL_ADRS 0x00
@@ -134,10 +145,10 @@ static void lcdtg_set_common_voltage(u8 base_data, u8 data)
}
/* Set Phase Adjuct */
-static void lcdtg_set_phadadj(struct w100fb_par *par)
+static void lcdtg_set_phadadj(int mode)
{
int adj;
- switch(par->xres) {
+ switch(mode) {
case 480:
case 640:
/* Setting for VGA */
@@ -161,7 +172,7 @@ static void lcdtg_set_phadadj(struct w100fb_par *par)
static int lcd_inited;
-static void lcdtg_hw_init(struct w100fb_par *par)
+static void lcdtg_hw_init(int mode)
{
if (!lcd_inited) {
int comadj;
@@ -215,7 +226,7 @@ static void lcdtg_hw_init(struct w100fb_par *par)
corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
/* Set Phase Adjuct */
- lcdtg_set_phadadj(par);
+ lcdtg_set_phadadj(mode);
/* Initialize for Input Signals from ATI */
corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
@@ -224,10 +235,10 @@ static void lcdtg_hw_init(struct w100fb_par *par)
lcd_inited=1;
} else {
- lcdtg_set_phadadj(par);
+ lcdtg_set_phadadj(mode);
}
- switch(par->xres) {
+ switch(mode) {
case 480:
case 640:
/* Set Lcd Resolution (VGA) */
@@ -242,7 +253,7 @@ static void lcdtg_hw_init(struct w100fb_par *par)
}
}
-static void lcdtg_suspend(struct w100fb_par *par)
+static void lcdtg_suspend(void)
{
/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
mdelay(34);
@@ -276,15 +287,30 @@ static void lcdtg_suspend(struct w100fb_par *par)
lcd_inited = 0;
}
-static struct w100_tg_info corgi_lcdtg_info = {
- .change=lcdtg_hw_init,
- .suspend=lcdtg_suspend,
- .resume=lcdtg_hw_init,
-};
/*
* Corgi w100 Frame Buffer Device
*/
+#ifdef CONFIG_PXA_SHARP_C7xx
+
+#include <video/w100fb.h>
+
+static void w100_lcdtg_suspend(struct w100fb_par *par)
+{
+ lcdtg_suspend();
+}
+
+static void w100_lcdtg_init(struct w100fb_par *par)
+{
+ lcdtg_hw_init(par->xres);
+}
+
+
+static struct w100_tg_info corgi_lcdtg_info = {
+ .change = w100_lcdtg_init,
+ .suspend = w100_lcdtg_suspend,
+ .resume = w100_lcdtg_init,
+};
static struct w100_mem_info corgi_fb_mem = {
.ext_cntl = 0x00040003,
@@ -394,3 +420,165 @@ struct platform_device corgifb_device = {
},
};
+#endif
+
+
+/*
+ * Spitz PXA Frame Buffer Device
+ */
+#ifdef CONFIG_PXA_SHARP_Cxx00
+
+#include <asm/arch/pxafb.h>
+
+void spitz_lcd_power(int on)
+{
+ if (on)
+ lcdtg_hw_init(480);
+ else
+ lcdtg_suspend();
+}
+
+#endif
+
+
+/*
+ * Corgi/Spitz Touchscreen to LCD interface
+ */
+static unsigned long (*get_hsync_time)(struct device *dev);
+
+static void inline sharpsl_wait_sync(int gpio)
+{
+ while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
+ while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
+}
+
+#ifdef CONFIG_PXA_SHARP_C7xx
+unsigned long corgi_get_hsync_len(void)
+{
+ if (!get_hsync_time)
+ get_hsync_time = symbol_get(w100fb_get_hsynclen);
+ if (!get_hsync_time)
+ return 0;
+
+ return get_hsync_time(&corgifb_device.dev);
+}
+
+void corgi_put_hsync(void)
+{
+ if (get_hsync_time)
+ symbol_put(w100fb_get_hsynclen);
+ get_hsync_time = NULL;
+}
+
+void corgi_wait_hsync(void)
+{
+ sharpsl_wait_sync(CORGI_GPIO_HSYNC);
+}
+#endif
+
+#ifdef CONFIG_PXA_SHARP_Cxx00
+static struct device *spitz_pxafb_dev;
+
+static int is_pxafb_device(struct device * dev, void * data)
+{
+ struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+
+ return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
+}
+
+unsigned long spitz_get_hsync_len(void)
+{
+#ifdef CONFIG_FB_PXA
+ if (!spitz_pxafb_dev) {
+ spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
+ if (!spitz_pxafb_dev)
+ return 0;
+ }
+ if (!get_hsync_time)
+ get_hsync_time = symbol_get(pxafb_get_hsync_time);
+ if (!get_hsync_time)
+#endif
+ return 0;
+
+ return pxafb_get_hsync_time(spitz_pxafb_dev);
+}
+
+void spitz_put_hsync(void)
+{
+ put_device(spitz_pxafb_dev);
+ if (get_hsync_time)
+ symbol_put(pxafb_get_hsync_time);
+ spitz_pxafb_dev = NULL;
+ get_hsync_time = NULL;
+}
+
+void spitz_wait_hsync(void)
+{
+ sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
+}
+#endif
+
+/*
+ * Corgi/Spitz Backlight Power
+ */
+#ifdef CONFIG_PXA_SHARP_C7xx
+void corgi_bl_set_intensity(int intensity)
+{
+ if (intensity > 0x10)
+ intensity += 0x10;
+
+ /* Bits 0-4 are accessed via the SSP interface */
+ corgi_ssp_blduty_set(intensity & 0x1f);
+
+ /* Bit 5 is via SCOOP */
+ if (intensity & 0x0020)
+ set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+ else
+ reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+}
+#endif
+
+
+#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
+void spitz_bl_set_intensity(int intensity)
+{
+ if (intensity > 0x10)
+ intensity += 0x10;
+
+ /* Bits 0-4 are accessed via the SSP interface */
+ corgi_ssp_blduty_set(intensity & 0x1f);
+
+ /* Bit 5 is via SCOOP */
+ if (intensity & 0x0020)
+ reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
+ else
+ set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
+
+ if (intensity)
+ set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
+ else
+ reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
+}
+#endif
+
+#ifdef CONFIG_MACH_AKITA
+void akita_bl_set_intensity(int intensity)
+{
+ if (intensity > 0x10)
+ intensity += 0x10;
+
+ /* Bits 0-4 are accessed via the SSP interface */
+ corgi_ssp_blduty_set(intensity & 0x1f);
+
+ /* Bit 5 is via IO-Expander */
+ if (intensity & 0x0020)
+ akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
+ else
+ akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
+
+ if (intensity)
+ akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
+ else
+ akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
+}
+#endif
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 8ccffba0018f..0ef428287055 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -1,7 +1,7 @@
/*
* SSP control code for Sharp Corgi devices
*
- * Copyright (c) 2004 Richard Purdie
+ * Copyright (c) 2004-2005 Richard Purdie
*
* 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
@@ -17,14 +17,16 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/arch/ssp.h>
-#include <asm/arch/corgi.h>
#include <asm/arch/pxa-regs.h>
+#include "sharpsl.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;
+static struct corgissp_machinfo *ssp_machinfo;
/*
* There are three devices connected to the SSP interface:
@@ -48,12 +50,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data)
unsigned long ret,flag;
spin_lock_irqsave(&corgi_ssp_lock, flag);
- GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+ GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
ssp_write_word(&corgi_ssp_dev,data);
ret = ssp_read_word(&corgi_ssp_dev);
- GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+ GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
spin_unlock_irqrestore(&corgi_ssp_lock, flag);
return ret;
@@ -66,12 +68,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data)
void corgi_ssp_ads7846_lock(void)
{
spin_lock(&corgi_ssp_lock);
- GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+ GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
}
void corgi_ssp_ads7846_unlock(void)
{
- GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+ GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
spin_unlock(&corgi_ssp_lock);
}
@@ -97,23 +99,27 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get);
*/
unsigned long corgi_ssp_dac_put(ulong data)
{
- unsigned long flag;
+ unsigned long flag, sscr1 = SSCR1_SPH;
spin_lock_irqsave(&corgi_ssp_lock, flag);
- GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
+ if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
+ sscr1 = 0;
ssp_disable(&corgi_ssp_dev);
- ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76));
+ ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
ssp_enable(&corgi_ssp_dev);
+ GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
ssp_write_word(&corgi_ssp_dev,data);
/* Read null data back from device to prevent SSP overflow */
ssp_read_word(&corgi_ssp_dev);
+ GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
ssp_disable(&corgi_ssp_dev);
- ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+ ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
ssp_enable(&corgi_ssp_dev);
- GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
spin_unlock_irqrestore(&corgi_ssp_lock, flag);
return 0;
@@ -141,9 +147,9 @@ int corgi_ssp_max1111_get(ulong data)
int voltage,voltage1,voltage2;
spin_lock_irqsave(&corgi_ssp_lock, flag);
- GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+ GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
ssp_disable(&corgi_ssp_dev);
- ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8));
+ ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
ssp_enable(&corgi_ssp_dev);
udelay(1);
@@ -161,9 +167,9 @@ int corgi_ssp_max1111_get(ulong data)
voltage2=ssp_read_word(&corgi_ssp_dev);
ssp_disable(&corgi_ssp_dev);
- ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+ ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
ssp_enable(&corgi_ssp_dev);
- GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+ GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
spin_unlock_irqrestore(&corgi_ssp_lock, flag);
if (voltage1 & 0xc0 || voltage2 & 0x3f)
@@ -179,25 +185,31 @@ EXPORT_SYMBOL(corgi_ssp_max1111_get);
/*
* Support Routines
*/
-int __init corgi_ssp_probe(struct device *dev)
+
+void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
+{
+ ssp_machinfo = machinfo;
+}
+
+static int __init corgi_ssp_probe(struct device *dev)
{
int ret;
/* Chip Select - Disable All */
- GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */
- GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */
- GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */
- GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/
- GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS); /* output */
- GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/
+ GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */
+ GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
+ GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */
+ GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+ GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */
+ GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
- ret=ssp_init(&corgi_ssp_dev,1);
+ ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port);
if (ret)
printk(KERN_ERR "Unable to register SSP handler!\n");
else {
ssp_disable(&corgi_ssp_dev);
- ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+ ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
ssp_enable(&corgi_ssp_dev);
}
@@ -222,9 +234,9 @@ static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level)
static int corgi_ssp_resume(struct device *dev, u32 level)
{
if (level == RESUME_POWER_ON) {
- GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */
- GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/
- GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/
+ GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
+ GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+ GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
ssp_enable(&corgi_ssp_dev);
}
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index a45aaa115a76..3248bc9b9495 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -34,6 +34,8 @@
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/i2c.h>
#include "generic.h"
@@ -91,14 +93,42 @@ EXPORT_SYMBOL(pxa_set_cken);
* and cache flush area.
*/
static struct map_desc standard_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */
- { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
- { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
- { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */
- { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */
- { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */
- { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */
+ { /* Devs */
+ .virtual = 0xf2000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* LCD */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x44000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* Mem Ctl */
+ .virtual = 0xf6000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* USB host */
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0x4c000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* Camera */
+ .virtual = 0xfa000000,
+ .pfn = __phys_to_pfn(0x50000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* IMem ctl */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0x58000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* UNCACHED_PHYS_0 */
+ .virtual = 0xff000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
void __init pxa_map_io(void)
@@ -207,6 +237,11 @@ static struct platform_device pxafb_device = {
.resource = pxafb_resources,
};
+void __init set_pxa_fb_parent(struct device *parent_dev)
+{
+ pxafb_device.dev.parent = parent_dev;
+}
+
static struct platform_device ffuart_device = {
.name = "pxa2xx-uart",
.id = 0,
@@ -219,6 +254,10 @@ static struct platform_device stuart_device = {
.name = "pxa2xx-uart",
.id = 2,
};
+static struct platform_device hwuart_device = {
+ .name = "pxa2xx-uart",
+ .id = 3,
+};
static struct resource i2c_resources[] = {
{
@@ -244,6 +283,41 @@ void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
i2c_device.dev.platform_data = info;
}
+static struct resource i2s_resources[] = {
+ {
+ .start = 0x40400000,
+ .end = 0x40400083,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_I2S,
+ .end = IRQ_I2S,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2s_device = {
+ .name = "pxa2xx-i2s",
+ .id = -1,
+ .resource = i2s_resources,
+ .num_resources = ARRAY_SIZE(i2s_resources),
+};
+
+static u64 pxaficp_dmamask = ~(u32)0;
+
+static struct platform_device pxaficp_device = {
+ .name = "pxa2xx-ir",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxaficp_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
+{
+ pxaficp_device.dev.platform_data = info;
+}
+
static struct platform_device *devices[] __initdata = {
&pxamci_device,
&udc_device,
@@ -251,12 +325,26 @@ static struct platform_device *devices[] __initdata = {
&ffuart_device,
&btuart_device,
&stuart_device,
+ &pxaficp_device,
&i2c_device,
+ &i2s_device,
};
static int __init pxa_init(void)
{
- return platform_add_devices(devices, ARRAY_SIZE(devices));
+ int cpuid, ret;
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if (ret)
+ return ret;
+
+ /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
+ cpuid = read_cpuid(CPUID_ID);
+ if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
+ ((cpuid >> 4) & 0xfff) == 0x290)
+ ret = platform_device_register(&hwuart_device);
+
+ return ret;
}
subsys_initcall(pxa_init);
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 386e107b53cc..01a83ab09ac3 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -152,16 +152,17 @@ static void __init idp_init_irq(void)
}
static struct map_desc idp_io_desc[] __initdata = {
- /* virtual physical length type */
-
- { IDP_COREVOLT_VIRT,
- IDP_COREVOLT_PHYS,
- IDP_COREVOLT_SIZE,
- MT_DEVICE },
- { IDP_CPLD_VIRT,
- IDP_CPLD_PHYS,
- IDP_CPLD_SIZE,
- MT_DEVICE }
+ {
+ .virtual = IDP_COREVOLT_VIRT,
+ .pfn = __phys_to_pfn(IDP_COREVOLT_PHYS),
+ .length = IDP_COREVOLT_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IDP_CPLD_VIRT,
+ .pfn = __phys_to_pfn(IDP_CPLD_PHYS),
+ .length = IDP_CPLD_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init idp_map_io(void)
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 923f6eb774c0..beccf455f796 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -35,6 +35,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/lubbock.h>
#include <asm/arch/udc.h>
+#include <asm/arch/irda.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
@@ -146,6 +147,11 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
// no D+ pullup; lubbock can't connect/disconnect in software
};
+static struct platform_device lub_audio_device = {
+ .name = "pxa2xx-ac97",
+ .id = -1,
+};
+
static struct resource sa1111_resources[] = {
[0] = {
.start = 0x10000000,
@@ -195,6 +201,7 @@ static struct platform_device smc91x_device = {
static struct platform_device *devices[] __initdata = {
&sa1111_device,
+ &lub_audio_device,
&smc91x_device,
};
@@ -231,16 +238,40 @@ static struct pxamci_platform_data lubbock_mci_platform_data = {
.init = lubbock_mci_init,
};
+static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ LUB_MISC_WR &= ~(1 << 4);
+ } else if (mode & IR_FIRMODE) {
+ LUB_MISC_WR |= 1 << 4;
+ }
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data lubbock_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
+ .transceiver_mode = lubbock_irda_transceiver_mode,
+};
+
static void __init lubbock_init(void)
{
pxa_set_udc_info(&udc_info);
set_pxa_fb_info(&sharp_lm8v31);
pxa_set_mci_info(&lubbock_mci_platform_data);
+ pxa_set_ficp_info(&lubbock_ficp_platform_data);
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
}
static struct map_desc lubbock_io_desc[] __initdata = {
- { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
+ { /* CPLD */
+ .virtual = LUBBOCK_FPGA_VIRT,
+ .pfn = __phys_to_pfn(LUBBOCK_FPGA_PHYS),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init lubbock_map_io(void)
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 85fdb5b1470a..a48c64026e1f 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -37,6 +37,7 @@
#include <asm/arch/audio.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
#include "generic.h"
@@ -294,6 +295,29 @@ static struct pxamci_platform_data mainstone_mci_platform_data = {
.exit = mainstone_mci_exit,
};
+static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
+ } else if (mode & IR_FIRMODE) {
+ MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
+ }
+ if (mode & IR_OFF) {
+ MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
+ } else {
+ MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
+ }
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data mainstone_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = mainstone_irda_transceiver_mode,
+};
+
static void __init mainstone_init(void)
{
/*
@@ -313,11 +337,17 @@ static void __init mainstone_init(void)
set_pxa_fb_info(&toshiba_ltm035a776c);
pxa_set_mci_info(&mainstone_mci_platform_data);
+ pxa_set_ficp_info(&mainstone_ficp_platform_data);
}
static struct map_desc mainstone_io_desc[] __initdata = {
- { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
+ { /* CPLD */
+ .virtual = MST_FPGA_VIRT,
+ .pfn = __phys_to_pfn(MST_FPGA_PHYS),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init mainstone_map_io(void)
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 47cfb8bb8318..f25638810017 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -30,6 +30,8 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/udc.h>
#include <asm/arch/poodle.h>
#include <asm/arch/pxafb.h>
@@ -93,6 +95,83 @@ static struct platform_device locomo_device = {
.resource = locomo_resources,
};
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+static struct pxamci_platform_data poodle_mci_platform_data;
+
+static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+ int err;
+
+ /* setup GPIO for PXA25x MMC controller */
+ pxa_gpio_mode(GPIO6_MMCCLK_MD);
+ pxa_gpio_mode(GPIO8_MMCCS0_MD);
+ pxa_gpio_mode(POODLE_GPIO_nSD_DETECT | GPIO_IN);
+ pxa_gpio_mode(POODLE_GPIO_SD_PWR | GPIO_OUT);
+
+ poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
+
+ err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, SA_INTERRUPT,
+ "MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+ return -1;
+ }
+
+ set_irq_type(POODLE_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+ return 0;
+}
+
+static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if (( 1 << vdd) & p_d->ocr_mask)
+ GPSR1 = GPIO_bit(POODLE_GPIO_SD_PWR);
+ else
+ GPCR1 = GPIO_bit(POODLE_GPIO_SD_PWR);
+}
+
+static void poodle_mci_exit(struct device *dev, void *data)
+{
+ free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data);
+}
+
+static struct pxamci_platform_data poodle_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = poodle_mci_init,
+ .setpower = poodle_mci_setpower,
+ .exit = poodle_mci_exit,
+};
+
+
+/*
+ * USB Device Controller
+ */
+static void poodle_udc_command(int cmd)
+{
+ switch(cmd) {
+ case PXA2XX_UDC_CMD_CONNECT:
+ GPSR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP);
+ break;
+ case PXA2XX_UDC_CMD_DISCONNECT:
+ GPCR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP);
+ break;
+ }
+}
+
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ /* no connect GPIO; poodle can't tell connection status */
+ .udc_command = poodle_udc_command,
+};
+
+
/* PXAFB device */
static struct pxafb_mach_info poodle_fb_info __initdata = {
.pixclock = 144700,
@@ -126,6 +205,15 @@ static void __init poodle_init(void)
{
int ret = 0;
+ /* setup sleep mode values */
+ PWER = 0x00000002;
+ PFER = 0x00000000;
+ PRER = 0x00000002;
+ PGSR0 = 0x00008000;
+ PGSR1 = 0x003F0202;
+ PGSR2 = 0x0001C000;
+ PCFR |= PCFR_OPDE;
+
/* cpu initialize */
/* Pgsr Register */
PGSR0 = 0x0146dd80;
@@ -155,6 +243,9 @@ static void __init poodle_init(void)
GPSR2 = 0x00000000;
set_pxa_fb_info(&poodle_fb_info);
+ pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
+ pxa_set_udc_info(&udc_info);
+ pxa_set_mci_info(&poodle_mci_platform_data);
scoop_num = 1;
scoop_devs = &poodle_pcmcia_scoop[0];
@@ -171,32 +262,12 @@ static void __init fixup_poodle(struct machine_desc *desc,
sharpsl_save_param();
}
-static struct map_desc poodle_io_desc[] __initdata = {
- /* virtual physical length */
- { 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */
-};
-
-static void __init poodle_map_io(void)
-{
- pxa_map_io();
- iotable_init(poodle_io_desc, ARRAY_SIZE(poodle_io_desc));
-
- /* setup sleep mode values */
- PWER = 0x00000002;
- PFER = 0x00000000;
- PRER = 0x00000002;
- PGSR0 = 0x00008000;
- PGSR1 = 0x003F0202;
- PGSR2 = 0x0001C000;
- PCFR |= PCFR_OPDE;
-}
-
MACHINE_START(POODLE, "SHARP Poodle")
.phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_poodle,
- .map_io = poodle_map_io,
+ .map_io = pxa_map_io,
.init_irq = pxa_init_irq,
.timer = &pxa_timer,
.init_machine = poodle_init,
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 7869c3b4e62f..573a5758e781 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -129,7 +129,7 @@ void pxa_cpu_pm_enter(suspend_state_t state)
case PM_SUSPEND_MEM:
/* set resume return address */
PSPR = virt_to_phys(pxa_cpu_resume);
- pxa_cpu_suspend(3);
+ pxa_cpu_suspend(PWRMODE_SLEEP);
break;
}
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 9a791b07118d..09a5d593f04b 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -157,7 +157,7 @@ void pxa_cpu_pm_enter(suspend_state_t state)
case PM_SUSPEND_MEM:
/* set resume return address */
PSPR = virt_to_phys(pxa_cpu_resume);
- pxa_cpu_suspend(3);
+ pxa_cpu_suspend(PWRMODE_SLEEP);
break;
}
}
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
new file mode 100644
index 000000000000..3977a77aacdd
--- /dev/null
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -0,0 +1,34 @@
+/*
+ * SharpSL SSP Driver
+ */
+
+struct corgissp_machinfo {
+ int port;
+ int cs_lcdcon;
+ int cs_ads7846;
+ int cs_max1111;
+ int clk_lcdcon;
+ int clk_ads7846;
+ int clk_max1111;
+};
+
+void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
+
+/*
+ * SharpSL Backlight
+ */
+
+void corgi_bl_set_intensity(int intensity);
+void spitz_bl_set_intensity(int intensity);
+void akita_bl_set_intensity(int intensity);
+
+/*
+ * SharpSL Touchscreen Driver
+ */
+
+unsigned long corgi_get_hsync_len(void);
+unsigned long spitz_get_hsync_len(void);
+void corgi_put_hsync(void);
+void spitz_put_hsync(void);
+void corgi_wait_hsync(void);
+void spitz_wait_hsync(void);
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 5786ccad938c..c9862688ff3d 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -28,7 +28,9 @@
/*
* pxa_cpu_suspend()
*
- * Forces CPU into sleep state
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
*/
ENTRY(pxa_cpu_suspend)
@@ -53,6 +55,7 @@ ENTRY(pxa_cpu_suspend)
mov r10, sp
stmfd sp!, {r3 - r10}
+ mov r5, r0 @ save sleep mode
@ preserve phys address of stack
mov r0, sp
bl sleep_phys_sp
@@ -66,7 +69,7 @@ ENTRY(pxa_cpu_suspend)
@ (also workaround for sighting 28071)
@ prepare value for sleep mode
- mov r1, #3 @ sleep mode
+ mov r1, r5 @ sleep mode
@ prepare pointer to physical address 0 (virtual mapping in generic.c)
mov r2, #UNCACHED_PHYS_0
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
new file mode 100644
index 000000000000..d0ab428c2d7d
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz.c
@@ -0,0 +1,378 @@
+/*
+ * Support for Sharp SL-Cxx00 Series of PDAs
+ * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi)
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches/lubbock.c
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/host.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/akita.h>
+#include <asm/arch/spitz.h>
+#include <asm/arch/sharpsl.h>
+
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/scoop.h>
+
+#include "generic.h"
+#include "sharpsl.h"
+
+/*
+ * Spitz SCOOP Device #1
+ */
+static struct resource spitz_scoop_resources[] = {
+ [0] = {
+ .start = 0x10800000,
+ .end = 0x10800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config spitz_scoop_setup = {
+ .io_dir = SPITZ_SCP_IO_DIR,
+ .io_out = SPITZ_SCP_IO_OUT,
+ .suspend_clr = SPITZ_SCP_SUS_CLR,
+ .suspend_set = SPITZ_SCP_SUS_SET,
+};
+
+struct platform_device spitzscoop_device = {
+ .name = "sharp-scoop",
+ .id = 0,
+ .dev = {
+ .platform_data = &spitz_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(spitz_scoop_resources),
+ .resource = spitz_scoop_resources,
+};
+
+/*
+ * Spitz SCOOP Device #2
+ */
+static struct resource spitz_scoop2_resources[] = {
+ [0] = {
+ .start = 0x08800040,
+ .end = 0x08800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config spitz_scoop2_setup = {
+ .io_dir = SPITZ_SCP2_IO_DIR,
+ .io_out = SPITZ_SCP2_IO_OUT,
+ .suspend_clr = SPITZ_SCP2_SUS_CLR,
+ .suspend_set = SPITZ_SCP2_SUS_SET,
+};
+
+struct platform_device spitzscoop2_device = {
+ .name = "sharp-scoop",
+ .id = 1,
+ .dev = {
+ .platform_data = &spitz_scoop2_setup,
+ },
+ .num_resources = ARRAY_SIZE(spitz_scoop2_resources),
+ .resource = spitz_scoop2_resources,
+};
+
+static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
+{
+ .dev = &spitzscoop_device.dev,
+ .irq = SPITZ_IRQ_GPIO_CF_IRQ,
+ .cd_irq = SPITZ_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+},{
+ .dev = &spitzscoop2_device.dev,
+ .irq = SPITZ_IRQ_GPIO_CF2_IRQ,
+ .cd_irq = -1,
+},
+};
+
+
+/*
+ * Spitz SSP Device
+ *
+ * Set the parent as the scoop device because a lot of SSP devices
+ * also use scoop functions and this makes the power up/down order
+ * work correctly.
+ */
+struct platform_device spitzssp_device = {
+ .name = "corgi-ssp",
+ .dev = {
+ .parent = &spitzscoop_device.dev,
+ },
+ .id = -1,
+};
+
+struct corgissp_machinfo spitz_ssp_machinfo = {
+ .port = 2,
+ .cs_lcdcon = SPITZ_GPIO_LCDCON_CS,
+ .cs_ads7846 = SPITZ_GPIO_ADS7846_CS,
+ .cs_max1111 = SPITZ_GPIO_MAX1111_CS,
+ .clk_lcdcon = 520,
+ .clk_ads7846 = 14,
+ .clk_max1111 = 56,
+};
+
+
+/*
+ * Spitz Backlight Device
+ */
+static struct corgibl_machinfo spitz_bl_machinfo = {
+ .max_intensity = 0x2f,
+};
+
+static struct platform_device spitzbl_device = {
+ .name = "corgi-bl",
+ .dev = {
+ .platform_data = &spitz_bl_machinfo,
+ },
+ .id = -1,
+};
+
+
+/*
+ * Spitz Keyboard Device
+ */
+static struct platform_device spitzkbd_device = {
+ .name = "spitz-keyboard",
+ .id = -1,
+};
+
+
+/*
+ * Spitz Touch Screen Device
+ */
+static struct resource spitzts_resources[] = {
+ [0] = {
+ .start = SPITZ_IRQ_GPIO_TP_INT,
+ .end = SPITZ_IRQ_GPIO_TP_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct corgits_machinfo spitz_ts_machinfo = {
+ .get_hsync_len = spitz_get_hsync_len,
+ .put_hsync = spitz_put_hsync,
+ .wait_hsync = spitz_wait_hsync,
+};
+
+static struct platform_device spitzts_device = {
+ .name = "corgi-ts",
+ .dev = {
+ .parent = &spitzssp_device.dev,
+ .platform_data = &spitz_ts_machinfo,
+ },
+ .id = -1,
+ .num_resources = ARRAY_SIZE(spitzts_resources),
+ .resource = spitzts_resources,
+};
+
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+
+static struct pxamci_platform_data spitz_mci_platform_data;
+
+static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+ int err;
+
+ /* setup GPIO for PXA27x MMC controller */
+ pxa_gpio_mode(GPIO32_MMCCLK_MD);
+ pxa_gpio_mode(GPIO112_MMCCMD_MD);
+ pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+ pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+ pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+ pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+ pxa_gpio_mode(SPITZ_GPIO_nSD_DETECT | GPIO_IN);
+ pxa_gpio_mode(SPITZ_GPIO_nSD_WP | GPIO_IN);
+
+ spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
+
+ err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT,
+ "MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+ return -1;
+ }
+
+ set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+ return 0;
+}
+
+/* Power control is shared with one of the CF slots so we have a mess */
+static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
+
+ if (( 1 << vdd) & p_d->ocr_mask) {
+ /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */
+ set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+ mdelay(2);
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
+ } else {
+ /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
+
+ if (!(cpr | 0x02)) {
+ mdelay(1);
+ reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+ }
+ }
+}
+
+static int spitz_mci_get_ro(struct device *dev)
+{
+ return GPLR(SPITZ_GPIO_nSD_WP) & GPIO_bit(SPITZ_GPIO_nSD_WP);
+}
+
+static void spitz_mci_exit(struct device *dev, void *data)
+{
+ free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data);
+}
+
+static struct pxamci_platform_data spitz_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = spitz_mci_init,
+ .get_ro = spitz_mci_get_ro,
+ .setpower = spitz_mci_setpower,
+ .exit = spitz_mci_exit,
+};
+
+
+/*
+ * Spitz PXA Framebuffer
+ */
+static struct pxafb_mach_info spitz_pxafb_info __initdata = {
+ .pixclock = 19231,
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .hsync_len = 40,
+ .left_margin = 46,
+ .right_margin = 125,
+ .vsync_len = 3,
+ .upper_margin = 1,
+ .lower_margin = 0,
+ .sync = 0,
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
+ .lccr3 = LCCR3_PixRsEdg | LCCR3_OutEnH,
+ .pxafb_lcd_power = spitz_lcd_power,
+};
+
+
+static struct platform_device *devices[] __initdata = {
+ &spitzscoop_device,
+ &spitzssp_device,
+ &spitzkbd_device,
+ &spitzts_device,
+ &spitzbl_device,
+};
+
+static void __init common_init(void)
+{
+ PMCR = 0x00;
+
+ /* setup sleep mode values */
+ PWER = 0x00000002;
+ PFER = 0x00000000;
+ PRER = 0x00000002;
+ PGSR0 = 0x0158C000;
+ PGSR1 = 0x00FF0080;
+ PGSR2 = 0x0001C004;
+
+ /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+ PCFR |= PCFR_OPDE;
+
+ corgi_ssp_set_machinfo(&spitz_ssp_machinfo);
+
+ pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ pxa_set_mci_info(&spitz_mci_platform_data);
+ set_pxa_fb_parent(&spitzssp_device.dev);
+ set_pxa_fb_info(&spitz_pxafb_info);
+}
+
+static void __init spitz_init(void)
+{
+ scoop_num = 2;
+ scoop_devs = &spitz_pcmcia_scoop[0];
+ spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
+
+ common_init();
+
+ platform_device_register(&spitzscoop2_device);
+}
+
+static void __init fixup_spitz(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ sharpsl_save_param();
+ mi->nr_banks = 1;
+ mi->bank[0].start = 0xa0000000;
+ mi->bank[0].node = 0;
+ mi->bank[0].size = (64*1024*1024);
+}
+
+#ifdef CONFIG_MACH_SPITZ
+MACHINE_START(SPITZ, "SHARP Spitz")
+ .phys_ram = 0xa0000000,
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .fixup = fixup_spitz,
+ .map_io = pxa_map_io,
+ .init_irq = pxa_init_irq,
+ .init_machine = spitz_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_BORZOI
+MACHINE_START(BORZOI, "SHARP Borzoi")
+ .phys_ram = 0xa0000000,
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .fixup = fixup_spitz,
+ .map_io = pxa_map_io,
+ .init_irq = pxa_init_irq,
+ .init_machine = spitz_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
index 8a3f27b76784..6f6dbbd08021 100644
--- a/arch/arm/mach-pxa/standby.S
+++ b/arch/arm/mach-pxa/standby.S
@@ -21,7 +21,7 @@
ENTRY(pxa_cpu_standby)
ldr r0, =PSSR
mov r1, #(PSSR_PH | PSSR_STS)
- mov r2, #2
+ mov r2, #PWRMODE_STANDBY
mov r3, #UNCACHED_PHYS_0 @ Read mem context in.
ldr ip, [r3]
b 1f
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index a10268618f74..5c4ac1c008a6 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -61,9 +61,22 @@ static int __init parse_tag_acorn(const struct tag *tag)
__tagtable(ATAG_ACORN, parse_tag_acorn);
static struct map_desc rpc_io_desc[] __initdata = {
- { SCREEN_BASE, SCREEN_START, 2*1048576, MT_DEVICE }, /* VRAM */
- { (u32)IO_BASE, IO_START, IO_SIZE , MT_DEVICE }, /* IO space */
- { EASI_BASE, EASI_START, EASI_SIZE, MT_DEVICE } /* EASI space */
+ { /* VRAM */
+ .virtual = SCREEN_BASE,
+ .pfn = __phys_to_pfn(SCREEN_START),
+ .length = 2*1048576,
+ .type = MT_DEVICE
+ }, { /* IO space */
+ .virtual = (u32)IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE ,
+ .type = MT_DEVICE
+ }, { /* EASI space */
+ .virtual = EASI_BASE,
+ .pfn = __phys_to_pfn(EASI_START),
+ .length = EASI_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init rpc_map_io(void)
@@ -140,7 +153,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/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 06807c6ee68a..c796bcdd6158 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -12,6 +12,7 @@ config MACH_ANUBIS
config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
select CPU_S3C2410
+ select ISA
help
Say Y here if you are using the Simtec Electronics EB2410ITX
development board (also known as BAST)
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index f59608268751..8b3d5dc35de5 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -98,7 +98,10 @@ struct clk *clk_get(struct device *dev, const char *id)
struct clk *clk = ERR_PTR(-ENOENT);
int idno;
- idno = (dev == NULL) ? -1 : to_platform_device(dev)->id;
+ if (dev == NULL || dev->bus != &platform_bus_type)
+ idno = -1;
+ else
+ idno = to_platform_device(dev)->id;
down(&clocks_sem);
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index 478c15c0e36a..9cbe5eef492b 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -21,7 +21,7 @@
/* todo - fix when rmk changes iodescs to use `void __iomem *` */
-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, S3C2410_PA_##x, S3C24XX_SZ_##x, MT_DEVICE }
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C2410_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
#ifndef MHZ
#define MHZ (1000*1000)
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 4664bd11adc1..08bc7d95a45d 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>
@@ -47,7 +47,7 @@ struct platform_device *s3c24xx_uart_devs[3];
static struct resource s3c_usb_resource[] = {
[0] = {
.start = S3C2410_PA_USBHOST,
- .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST,
+ .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -77,7 +77,7 @@ EXPORT_SYMBOL(s3c_device_usb);
static struct resource s3c_lcd_resource[] = {
[0] = {
.start = S3C2410_PA_LCD,
- .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD,
+ .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -103,12 +103,25 @@ struct platform_device s3c_device_lcd = {
EXPORT_SYMBOL(s3c_device_lcd);
+void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
+{
+ struct s3c2410fb_mach_info *npd;
+
+ npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+ if (npd) {
+ memcpy(npd, pd, sizeof(*npd));
+ s3c_device_lcd.dev.platform_data = npd;
+ } else {
+ printk(KERN_ERR "no memory for LCD platform data\n");
+ }
+}
+
/* NAND Controller */
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C2410_PA_NAND,
- .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND,
+ .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
.flags = IORESOURCE_MEM,
}
};
@@ -127,7 +140,7 @@ EXPORT_SYMBOL(s3c_device_nand);
static struct resource s3c_usbgadget_resource[] = {
[0] = {
.start = S3C2410_PA_USBDEV,
- .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV,
+ .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -152,7 +165,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C2410_PA_WATCHDOG,
- .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG,
+ .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -177,7 +190,7 @@ EXPORT_SYMBOL(s3c_device_wdt);
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C2410_PA_IIC,
- .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC,
+ .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -202,7 +215,7 @@ EXPORT_SYMBOL(s3c_device_i2c);
static struct resource s3c_iis_resource[] = {
[0] = {
.start = S3C2410_PA_IIS,
- .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS,
+ .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS -1,
.flags = IORESOURCE_MEM,
}
};
@@ -256,7 +269,7 @@ EXPORT_SYMBOL(s3c_device_rtc);
static struct resource s3c_adc_resource[] = {
[0] = {
.start = S3C2410_PA_ADC,
- .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC,
+ .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -279,7 +292,7 @@ struct platform_device s3c_device_adc = {
static struct resource s3c_sdi_resource[] = {
[0] = {
.start = S3C2410_PA_SDI,
- .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI,
+ .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -456,7 +469,7 @@ EXPORT_SYMBOL(s3c_device_timer3);
static struct resource s3c_camif_resource[] = {
[0] = {
.start = S3C2440_PA_CAMIF,
- .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF,
+ .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index 94f1776cf312..23ea3d5fa09c 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -30,6 +30,7 @@
* 04-Oct-2004 BJD Added irq filter controls for GPIO
* 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code
* 13-Mar-2005 BJD Updates for __iomem
+ * 26-Oct-2005 BJD Added generic configuration types
*/
@@ -58,6 +59,27 @@ void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
}
+ switch (function) {
+ case S3C2410_GPIO_LEAVE:
+ mask = 0;
+ function = 0;
+ break;
+
+ case S3C2410_GPIO_INPUT:
+ case S3C2410_GPIO_OUTPUT:
+ case S3C2410_GPIO_SFN2:
+ case S3C2410_GPIO_SFN3:
+ if (pin < S3C2410_GPIO_BANKB) {
+ function &= 1;
+ function <<= S3C2410_GPIO_OFFSET(pin);
+ } else {
+ function &= 3;
+ function <<= S3C2410_GPIO_OFFSET(pin)*2;
+ }
+ }
+
+ /* modify the specified register wwith IRQs off */
+
local_irq_save(flags);
con = __raw_readl(base + 0x00);
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index f87aa0b669ad..5ae80f4e3e67 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -12,6 +12,7 @@
*
* Modifications:
* 02-May-2005 BJD Copied from mach-bast.c
+ * 20-Sep-2005 BJD Added static to non-exported items
*/
#include <linux/kernel.h>
@@ -124,7 +125,7 @@ static int external_map[] = { 2 };
static int chip0_map[] = { 0 };
static int chip1_map[] = { 1 };
-struct mtd_partition anubis_default_nand_part[] = {
+static struct mtd_partition anubis_default_nand_part[] = {
[0] = {
.name = "Boot Agent",
.size = SZ_16K,
@@ -232,7 +233,7 @@ static struct s3c24xx_board anubis_board __initdata = {
.clocks_count = ARRAY_SIZE(anubis_clocks)
};
-void __init anubis_map_io(void)
+static void __init anubis_map_io(void)
{
/* initialise the clocks */
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index e9182242da95..c1b5c63ec24a 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -31,6 +31,8 @@
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
* 25-Jul-2005 BJD Removed ASIX static mappings
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
+ * 20-Sep-2005 BJD Added static to non-exported items
+ * 26-Oct-2005 BJD Added FB platform data
*/
#include <linux/kernel.h>
@@ -60,8 +62,10 @@
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-lcd.h>
+
#include <asm/arch/nand.h>
#include <asm/arch/iic.h>
+#include <asm/arch/fb.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -229,7 +233,7 @@ static int chip0_map[] = { 1 };
static int chip1_map[] = { 2 };
static int chip2_map[] = { 3 };
-struct mtd_partition bast_default_nand_part[] = {
+static struct mtd_partition bast_default_nand_part[] = {
[0] = {
.name = "Boot Agent",
.size = SZ_16K,
@@ -306,9 +310,9 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
}
static struct s3c2410_platform_nand bast_nand_info = {
- .tacls = 40,
- .twrph0 = 80,
- .twrph1 = 80,
+ .tacls = 30,
+ .twrph0 = 60,
+ .twrph1 = 60,
.nr_sets = ARRAY_SIZE(bast_nand_sets),
.sets = bast_nand_sets,
.select_chip = bast_nand_select,
@@ -339,7 +343,7 @@ static struct resource bast_dm9k_resource[] = {
* better IO routines can be written and tested
*/
-struct dm9000_plat_data bast_dm9k_platdata = {
+static struct dm9000_plat_data bast_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY
};
@@ -381,7 +385,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,
},
@@ -398,6 +402,38 @@ static struct s3c2410_platform_i2c bast_i2c_info = {
.max_freq = 130*1000,
};
+
+static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
+ .width = 640,
+ .height = 480,
+
+ .xres = {
+ .min = 320,
+ .max = 1024,
+ .defval = 640,
+ },
+
+ .yres = {
+ .min = 240,
+ .max = 600,
+ .defval = 480,
+ },
+
+ .bpp = {
+ .min = 4,
+ .max = 16,
+ .defval = 8,
+ },
+
+ .regs = {
+ .lcdcon1 = 0x00000176,
+ .lcdcon2 = 0x1d77c7c2,
+ .lcdcon3 = 0x013a7f13,
+ .lcdcon4 = 0x00000057,
+ .lcdcon5 = 0x00014b02,
+ }
+};
+
/* Standard BAST devices */
static struct platform_device *bast_devices[] __initdata = {
@@ -428,7 +464,7 @@ static struct s3c24xx_board bast_board __initdata = {
.clocks_count = ARRAY_SIZE(bast_clocks)
};
-void __init bast_map_io(void)
+static void __init bast_map_io(void)
{
/* initialise the clocks */
@@ -453,6 +489,10 @@ void __init bast_map_io(void)
usb_simtec_init();
}
+static void __init bast_init(void)
+{
+ s3c24xx_fb_set_platdata(&bast_lcd_info);
+}
MACHINE_START(BAST, "Simtec-BAST")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
@@ -462,5 +502,6 @@ MACHINE_START(BAST, "Simtec-BAST")
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = bast_map_io,
.init_irq = s3c24xx_init_irq,
+ .init_machine = bast_init,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index ea4fb1a97a50..7efeaaad2361 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -24,6 +24,8 @@
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Added clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
+ * 20-Sep-2005 BJD Added static to non-exported items
+ * 26-Oct-2005 BJD Changed name of fb init call
*/
#include <linux/kernel.h>
@@ -45,6 +47,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 +93,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,
@@ -102,7 +149,7 @@ static struct s3c24xx_board h1940_board __initdata = {
.devices_count = ARRAY_SIZE(h1940_devices)
};
-void __init h1940_map_io(void)
+static void __init h1940_map_io(void)
{
s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
s3c24xx_init_clocks(0);
@@ -110,12 +157,17 @@ void __init h1940_map_io(void)
s3c24xx_set_board(&h1940_board);
}
-void __init h1940_init_irq(void)
+static void __init h1940_init_irq(void)
{
s3c24xx_init_irq();
}
+static void __init h1940_init(void)
+{
+ s3c24xx_fb_set_platdata(&h1940_lcdcfg);
+}
+
MACHINE_START(H1940, "IPAQ-H1940")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_ram = S3C2410_SDRAM_PA,
@@ -124,5 +176,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-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 66bf5bb2b3db..5c0f2b091f95 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -97,7 +97,7 @@ static struct s3c24xx_board n30_board __initdata = {
.devices_count = ARRAY_SIZE(n30_devices)
};
-void __init n30_map_io(void)
+static void __init n30_map_io(void)
{
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
s3c24xx_init_clocks(0);
@@ -105,14 +105,14 @@ void __init n30_map_io(void)
s3c24xx_set_board(&n30_board);
}
-void __init n30_init_irq(void)
+static void __init n30_init_irq(void)
{
s3c24xx_init_irq();
}
/* GPB3 is the line that controls the pull-up for the USB D+ line */
-void __init n30_init(void)
+static void __init n30_init(void)
{
s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index d24c242414ca..c22f8216032d 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -136,7 +136,7 @@ static void __init nexcoder_sensorboard_init(void)
s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
}
-void __init nexcoder_map_io(void)
+static void __init nexcoder_map_io(void)
{
s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index d901ed492ff5..ad1459e402e2 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -105,7 +105,7 @@ static struct s3c24xx_board otom11_board __initdata = {
};
-void __init otom11_map_io(void)
+static void __init otom11_map_io(void)
{
s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index a73d61c1de46..22d9e070fd68 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -16,6 +16,7 @@
* 14-Jan-2005 BJD Added new clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2005 BJD Fixed __iomem warnings
+ * 20-Sep-2005 BJD Added static to non-exported items
*/
#include <linux/kernel.h>
@@ -108,7 +109,7 @@ static struct s3c24xx_board rx3715_board __initdata = {
.devices_count = ARRAY_SIZE(rx3715_devices)
};
-void __init rx3715_map_io(void)
+static void __init rx3715_map_io(void)
{
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
s3c24xx_init_clocks(16934000);
@@ -116,7 +117,7 @@ void __init rx3715_map_io(void)
s3c24xx_set_board(&rx3715_board);
}
-void __init rx3715_init_irq(void)
+static void __init rx3715_init_irq(void)
{
s3c24xx_init_irq();
}
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 67e903a700d3..2eda55a6b678 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -28,6 +28,7 @@
* Ben Dooks <ben@simtec.co.uk>
*
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
+ * 20-Sep-2005 BJD Added static to non-exported items
*
***********************************************************************/
@@ -97,7 +98,7 @@ static struct s3c24xx_board smdk2410_board __initdata = {
.devices_count = ARRAY_SIZE(smdk2410_devices)
};
-void __init smdk2410_map_io(void)
+static void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
@@ -105,7 +106,7 @@ void __init smdk2410_map_io(void)
s3c24xx_set_board(&smdk2410_board);
}
-void __init smdk2410_init_irq(void)
+static void __init smdk2410_init_irq(void)
{
s3c24xx_init_irq();
}
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index 357522106f68..6950e61b7914 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -18,6 +18,8 @@
* 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa
* 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA
* 14-Mar-2005 BJD void __iomem fixes
+ * 20-Sep-2005 BJD Added static to non-exported items
+ * 26-Oct-2005 BJD Added framebuffer data
*/
#include <linux/kernel.h>
@@ -40,7 +42,10 @@
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
#include "s3c2410.h"
#include "s3c2440.h"
@@ -85,6 +90,70 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] = {
}
};
+/* LCD driver info */
+
+static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
+ .regs = {
+
+ .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
+ S3C2410_LCDCON1_TFT |
+ S3C2410_LCDCON1_CLKVAL(0x04),
+
+ .lcdcon2 = S3C2410_LCDCON2_VBPD(7) |
+ S3C2410_LCDCON2_LINEVAL(319) |
+ S3C2410_LCDCON2_VFPD(6) |
+ S3C2410_LCDCON2_VSPW(3),
+
+ .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_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+ },
+
+#if 0
+ /* currently setup by downloader */
+ .gpccon = 0xaa940659,
+ .gpccon_mask = 0xffffffff,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+ .gpdcon = 0xaa84aaa0,
+ .gpdcon_mask = 0xffffffff,
+ .gpdup = 0x0000faff,
+ .gpdup_mask = 0xffffffff,
+#endif
+
+ .lpcsel = ((0xCE6) & ~7) | 1<<4,
+
+ .width = 240,
+ .height = 320,
+
+ .xres = {
+ .min = 240,
+ .max = 240,
+ .defval = 240,
+ },
+
+ .yres = {
+ .min = 320,
+ .max = 320,
+ .defval = 320,
+ },
+
+ .bpp = {
+ .min = 16,
+ .max = 16,
+ .defval = 16,
+ },
+};
+
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
@@ -98,7 +167,7 @@ static struct s3c24xx_board smdk2440_board __initdata = {
.devices_count = ARRAY_SIZE(smdk2440_devices)
};
-void __init smdk2440_map_io(void)
+static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400);
@@ -106,7 +175,7 @@ void __init smdk2440_map_io(void)
s3c24xx_set_board(&smdk2440_board);
}
-void __init smdk2440_machine_init(void)
+static void __init smdk2440_machine_init(void)
{
/* Configure the LEDs (even if we have no LED support)*/
@@ -120,6 +189,8 @@ void __init smdk2440_machine_init(void)
s3c2410_gpio_setpin(S3C2410_GPF6, 0);
s3c2410_gpio_setpin(S3C2410_GPF7, 0);
+ s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
+
s3c2410_pm_init();
}
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 924e8464c212..46b259673c18 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -28,6 +28,7 @@
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2006 BJD void __iomem fixes
* 22-Jun-2006 BJD Added DM9000 platform information
+ * 20-Sep-2005 BJD Added static to non-exported items
*/
#include <linux/kernel.h>
@@ -221,7 +222,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,
},
@@ -287,7 +288,7 @@ static struct resource vr1000_dm9k1_resource[] = {
* better IO routines can be written and tested
*/
-struct dm9000_plat_data vr1000_dm9k_platdata = {
+static struct dm9000_plat_data vr1000_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
@@ -347,7 +348,7 @@ static void vr1000_power_off(void)
s3c2410_gpio_setpin(S3C2410_GPB9, 1);
}
-void __init vr1000_map_io(void)
+static void __init vr1000_map_io(void)
{
/* initialise clock sources */
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 0b88993dfd27..a8bf5ec82602 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -125,9 +125,6 @@ static struct platform_device *uart_devices[] __initdata = {
&s3c_uart2
};
-/* store our uart devices for the serial driver console */
-struct platform_device *s3c2410_uart_devices[3];
-
static int s3c2410_uart_count = 0;
/* uart registration process */
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index d4c8281b55f6..833fa36bce05 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -151,7 +151,7 @@ void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
#ifdef CONFIG_PM
-struct sleep_save s3c2440_sleep[] = {
+static struct sleep_save s3c2440_sleep[] = {
SAVE_ITEM(S3C2440_DSC0),
SAVE_ITEM(S3C2440_DSC1),
SAVE_ITEM(S3C2440_GPJDAT),
@@ -260,7 +260,7 @@ void __init s3c2440_init_clocks(int xtal)
* as a driver which may support both 2410 and 2440 may try and use it.
*/
-int __init s3c2440_core_init(void)
+static int __init s3c2440_core_init(void)
{
return sysdev_class_register(&s3c2440_sysclass);
}
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
index c0acfb2ad790..8a00e3c3cd08 100644
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/mach-s3c2410/time.c
@@ -38,6 +38,7 @@
#include <asm/hardware/clock.h>
#include "clock.h"
+#include "cpu.h"
static unsigned long timer_startval;
static unsigned long timer_usec_ticks;
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index f021fd82be52..5098b50158a3 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -40,7 +40,6 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/mach-types.h>
#include "devs.h"
#include "usb-simtec.h"
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 24687f511bf5..75efb5da5b6d 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -388,9 +388,17 @@ static struct sa1100_port_fns assabet_port_fns __initdata = {
};
static struct map_desc assabet_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf1000000, 0x12000000, 0x00100000, MT_DEVICE }, /* Board Control Register */
- { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE } /* MQ200 */
+ { /* Board Control Register */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x12000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }
};
static void __init assabet_map_io(void)
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index b6169cb09196..c92cebff7f8e 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -254,10 +254,22 @@ EXPORT_SYMBOL(badge4_set_5V);
static struct map_desc badge4_io_desc[] __initdata = {
- /* virtual physical length type */
- {0xf1000000, 0x08000000, 0x00100000, MT_DEVICE },/* SRAM bank 1 */
- {0xf2000000, 0x10000000, 0x00100000, MT_DEVICE },/* SRAM bank 2 */
- {0xf4000000, 0x48000000, 0x00100000, MT_DEVICE } /* SA-1111 */
+ { /* SRAM bank 1 */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SRAM bank 2 */
+ .virtual = 0xf2000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 9484be7dc671..23cb74885275 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -100,8 +100,12 @@ static void __init cerf_init_irq(void)
}
static struct map_desc cerf_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE } /* Crystal Ethernet Chip */
+ { /* Crystal Ethernet Chip */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init cerf_map_io(void)
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 8cb69113a57c..7fd6e29c36b7 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -111,12 +111,11 @@ static struct mtd_partition collie_partitions[] = {
static void collie_set_vpp(int vpp)
{
- write_scoop_reg(SCOOP_GPCR, read_scoop_reg(SCOOP_GPCR) | COLLIE_SCP_VPEN);
- if (vpp) {
- write_scoop_reg(SCOOP_GPWR, read_scoop_reg(SCOOP_GPWR) | COLLIE_SCP_VPEN);
- } else {
- write_scoop_reg(SCOOP_GPWR, read_scoop_reg(SCOOP_GPWR) & ~COLLIE_SCP_VPEN);
- }
+ write_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR) | COLLIE_SCP_VPEN);
+ if (vpp)
+ write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) | COLLIE_SCP_VPEN);
+ else
+ write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) & ~COLLIE_SCP_VPEN);
}
static struct flash_platform_data collie_flash_data = {
@@ -172,9 +171,17 @@ static void __init collie_init(void)
}
static struct map_desc collie_io_desc[] __initdata = {
- /* virtual physical length type */
- {0xe8000000, 0x00000000, 0x02000000, MT_DEVICE}, /* 32M main flash (cs0) */
- {0xea000000, 0x08000000, 0x02000000, MT_DEVICE}, /* 32M boot flash (cs1) */
+ { /* 32M main flash (cs0) */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* 32M boot flash (cs1) */
+ .virtual = 0xea000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }
};
static void __init collie_map_io(void)
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3f1e358455e5..93619497779c 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -369,11 +369,27 @@ EXPORT_SYMBOL(sa1100fb_lcd_power);
*/
static struct map_desc standard_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf8000000, 0x80000000, 0x00100000, MT_DEVICE }, /* PCM */
- { 0xfa000000, 0x90000000, 0x00100000, MT_DEVICE }, /* SCM */
- { 0xfc000000, 0xa0000000, 0x00100000, MT_DEVICE }, /* MER */
- { 0xfe000000, 0xb0000000, 0x00200000, MT_DEVICE } /* LCD + DMA */
+ { /* PCM */
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0x80000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SCM */
+ .virtual = 0xfa000000,
+ .pfn = __phys_to_pfn(0x90000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MER */
+ .virtual = 0xfc000000,
+ .pfn = __phys_to_pfn(0xa0000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* LCD + DMA */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0xb0000000),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ },
};
void __init sa1100_map_io(void)
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 279e3afa3c39..f085d68e568e 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -39,3 +39,6 @@ extern void sa11x0_set_ssp_data(struct sa11x0_ssp_plat_ops *ops);
struct irda_platform_data;
void sa11x0_set_irda_data(struct irda_platform_data *irda);
+
+struct mcp_plat_data;
+void sa11x0_set_mcp_data(struct mcp_plat_data *data);
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index e7aa2681ca64..e8352b7f74b0 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -223,10 +223,22 @@ static void h3xxx_lcd_power(int enable)
}
static struct map_desc h3600_io_desc[] __initdata = {
- /* virtual physical length type */
- { H3600_BANK_2_VIRT, SA1100_CS2_PHYS, 0x02800000, MT_DEVICE }, /* static memory bank 2 CS#2 */
- { H3600_BANK_4_VIRT, SA1100_CS4_PHYS, 0x00800000, MT_DEVICE }, /* static memory bank 4 CS#4 */
- { H3600_EGPIO_VIRT, H3600_EGPIO_PHYS, 0x01000000, MT_DEVICE }, /* EGPIO 0 CS#5 */
+ { /* static memory bank 2 CS#2 */
+ .virtual = H3600_BANK_2_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS2_PHYS),
+ .length = 0x02800000,
+ .type = MT_DEVICE
+ }, { /* static memory bank 4 CS#4 */
+ .virtual = H3600_BANK_4_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS4_PHYS),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* EGPIO 0 CS#5 */
+ .virtual = H3600_EGPIO_VIRT,
+ .pfn = __phys_to_pfn(H3600_EGPIO_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ }
};
/*
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 502d65cfe654..c922e043c424 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -57,8 +57,12 @@ static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
*/
static struct map_desc hackkit_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */
+ { /* Flash bank 0 */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
};
static struct sa1100_port_fns hackkit_port_fns __initdata = {
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 2f497112c96a..9c363bfcf310 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -81,10 +81,22 @@ static int __init jornada720_init(void)
arch_initcall(jornada720_init);
static struct map_desc jornada720_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf0000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Epson registers */
- { 0xf1000000, 0x48200000, 0x00100000, MT_DEVICE }, /* Epson frame buffer */
- { 0xf4000000, 0x40000000, 0x00100000, MT_DEVICE } /* SA-1111 */
+ { /* Epson registers */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* Epson frame buffer */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x48200000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init jornada720_map_io(void)
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index ed6744d480af..8c9e3dd52942 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -31,9 +31,17 @@ static void __init lart_init(void)
}
static struct map_desc lart_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xe8000000, 0x00000000, 0x00400000, MT_DEVICE }, /* main flash memory */
- { 0xec000000, 0x08000000, 0x00400000, MT_DEVICE } /* main flash, alternative location */
+ { /* main flash memory */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x00400000,
+ .type = MT_DEVICE
+ }, { /* main flash, alternative location */
+ .virtual = 0xec000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00400000,
+ .type = MT_DEVICE
+ }
};
static void __init lart_map_io(void)
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index fc061641b7be..0c5eff3bdc09 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -331,9 +331,17 @@ static int __init neponset_init(void)
subsys_initcall(neponset_init);
static struct map_desc neponset_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf3000000, 0x10000000, SZ_1M, MT_DEVICE }, /* System Registers */
- { 0xf4000000, 0x40000000, SZ_1M, MT_DEVICE } /* SA-1111 */
+ { /* System Registers */
+ .virtual = 0xf3000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
void __init neponset_map_io(void)
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 07f6d5fd7bb0..cfb6658e5cdf 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -60,11 +60,17 @@ EXPORT_SYMBOL(set_cs3_bit);
EXPORT_SYMBOL(clear_cs3_bit);
static struct map_desc simpad_io_desc[] __initdata = {
- /* virtual physical length type */
- /* MQ200 */
- { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE },
- /* Paules CS3, write only */
- { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE },
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* Paules CS3, write only */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x18000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
};
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index e737eae4521f..2d428b6dbb58 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,
},
@@ -62,7 +62,12 @@ arch_initcall(shark_init);
extern void shark_init_irq(void);
static struct map_desc shark_io_desc[] __initdata = {
- { IO_BASE , IO_START , IO_SIZE , MT_DEVICE }
+ {
+ .virtual = IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init shark_map_io(void)
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 3c8862fde51a..7e4bdd07f4af 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -30,7 +30,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
-#include <asm/mach-types.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_clcd.h>
#include <asm/hardware/arm_timer.h>
@@ -52,8 +51,9 @@
*
* Setup a VA for the Versatile Vectored Interrupt Controller.
*/
-#define VA_VIC_BASE IO_ADDRESS(VERSATILE_VIC_BASE)
-#define VA_SIC_BASE IO_ADDRESS(VERSATILE_SIC_BASE)
+#define __io_address(n) __io(IO_ADDRESS(n))
+#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
+#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
static void vic_mask_irq(unsigned int irq)
{
@@ -186,25 +186,82 @@ void __init versatile_init_irq(void)
}
static struct map_desc versatile_io_desc[] __initdata = {
- { IO_ADDRESS(VERSATILE_SYS_BASE), VERSATILE_SYS_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_SIC_BASE), VERSATILE_SIC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_VIC_BASE), VERSATILE_VIC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_SCTL_BASE), VERSATILE_SCTL_BASE, SZ_4K * 9, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_SYS_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_SIC_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_VIC_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_VIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_SCTL_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SCTL_BASE),
+ .length = SZ_4K * 9,
+ .type = MT_DEVICE
+ },
#ifdef CONFIG_MACH_VERSATILE_AB
- { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_IB2_BASE), VERSATILE_IB2_BASE, SZ_64M, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_GPIO0_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_GPIO0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_IB2_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_IB2_BASE),
+ .length = SZ_64M,
+ .type = MT_DEVICE
+ },
#endif
#ifdef CONFIG_DEBUG_LL
- { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_UART0_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
#endif
#ifdef CONFIG_PCI
- { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
- { VERSATILE_PCI_VIRT_BASE, VERSATILE_PCI_BASE, VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
- { VERSATILE_PCI_CFG_VIRT_BASE, VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_BASE,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_BASE),
+ .length = VERSATILE_PCI_BASE_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_CFG_VIRT_BASE,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
+ .length = VERSATILE_PCI_CFG_BASE_SIZE,
+ .type = MT_DEVICE
+ },
#if 0
- { VERSATILE_PCI_VIRT_MEM_BASE0, VERSATILE_PCI_MEM_BASE0, SZ_16M, MT_DEVICE },
- { VERSATILE_PCI_VIRT_MEM_BASE1, VERSATILE_PCI_MEM_BASE1, SZ_16M, MT_DEVICE },
- { VERSATILE_PCI_VIRT_MEM_BASE2, VERSATILE_PCI_MEM_BASE2, SZ_16M, MT_DEVICE },
+ {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE0,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE1,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE2,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
#endif
#endif
};
@@ -214,7 +271,7 @@ void __init versatile_map_io(void)
iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
}
-#define VERSATILE_REFCOUNTER (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
/*
* This is the Versatile sched_clock implementation. This has
@@ -231,7 +288,7 @@ unsigned long long sched_clock(void)
}
-#define VERSATILE_FLASHCTRL (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_FLASHCTRL (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
static int versatile_flash_init(void)
{
@@ -309,7 +366,7 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
-#define VERSATILE_SYSMCI (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYSMCI (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
unsigned int mmc_status(struct device *dev)
{
@@ -343,11 +400,11 @@ static const struct icst307_params versatile_oscvco_params = {
static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
{
- unsigned long sys_lock = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
+ void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
#if defined(CONFIG_ARCH_VERSATILE_PB)
- unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET;
+ void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET;
#elif defined(CONFIG_MACH_VERSATILE_AB)
- unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET;
+ void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET;
#endif
u32 val;
@@ -483,7 +540,7 @@ static struct clcd_panel epson_2_2_in = {
*/
static struct clcd_panel *versatile_clcd_panel(void)
{
- unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
struct clcd_panel *panel = &vga;
u32 val;
@@ -510,7 +567,7 @@ static struct clcd_panel *versatile_clcd_panel(void)
*/
static void versatile_clcd_disable(struct clcd_fb *fb)
{
- unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
u32 val;
val = readl(sys_clcd);
@@ -522,7 +579,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
* If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
*/
if (fb->panel == &sanyo_2_5_in) {
- unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL);
+ void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
unsigned long ctrl;
ctrl = readl(versatile_ib2_ctrl);
@@ -537,7 +594,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
*/
static void versatile_clcd_enable(struct clcd_fb *fb)
{
- unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
u32 val;
val = readl(sys_clcd);
@@ -571,7 +628,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
* If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
*/
if (fb->panel == &sanyo_2_5_in) {
- unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL);
+ void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
unsigned long ctrl;
ctrl = readl(versatile_ib2_ctrl);
@@ -720,7 +777,7 @@ static struct amba_device *amba_devs[] __initdata = {
};
#ifdef CONFIG_LEDS
-#define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
+#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
static void versatile_leds_event(led_event_t ledevt)
{
@@ -778,11 +835,11 @@ void __init versatile_init(void)
/*
* Where is the timer (VA)?
*/
-#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
-#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
-#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
-#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE)
+#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
+#define TIMER1_VA_BASE (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_VA_BASE __io_address(VERSATILE_TIMER2_3_BASE)
+#define TIMER3_VA_BASE (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
+#define VA_IC_BASE __io_address(VERSATILE_VIC_BASE)
/*
* How long is the timer interval?
@@ -877,12 +934,12 @@ static void __init versatile_timer_init(void)
* VERSATILE_REFCLK is 32KHz
* VERSATILE_TIMCLK is 1MHz
*/
- val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE));
+ val = readl(__io_address(VERSATILE_SCTL_BASE));
writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
(VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
(VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
(VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
- IO_ADDRESS(VERSATILE_SCTL_BASE));
+ __io_address(VERSATILE_SCTL_BASE));
/*
* Initialise to a known state (all timers off)
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index d1565e851f0e..b80d57d51699 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -29,7 +29,6 @@
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
/*
* these spaces are mapped using the following base registers:
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index db5e47dfc303..c54e04c995ee 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -370,21 +370,21 @@ config CPU_BIG_ENDIAN
config CPU_ICACHE_DISABLE
bool "Disable I-Cache"
- depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020
+ depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6
help
Say Y here to disable the processor instruction cache. Unless
you have a reason not to or are unsure, say N.
config CPU_DCACHE_DISABLE
bool "Disable D-Cache"
- depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020
+ depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6
help
Say Y here to disable the processor data cache. Unless
you have a reason not to or are unsure, say N.
config CPU_DCACHE_WRITETHROUGH
bool "Force write through D-cache"
- depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020) && !CPU_DCACHE_DISABLE
+ depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE
default y if CPU_ARM925T
help
Say Y here to use the data cache in writethrough mode. Unless you
@@ -399,7 +399,7 @@ config CPU_CACHE_ROUND_ROBIN
config CPU_BPREDICT_DISABLE
bool "Disable branch prediction"
- depends on CPU_ARM1020
+ depends on CPU_ARM1020 || CPU_V6
help
Say Y here to disable branch prediction. If unsure, say N.
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 8f76f3df7b4c..dbd346033122 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -20,6 +20,11 @@
*/
.align 5
ENTRY(v6_early_abort)
+#ifdef CONFIG_CPU_MPCORE
+ clrex
+#else
+ strex r0, r1, [sp] @ Clear the exclusive monitor
+#endif
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
/*
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 4b39d867ac14..705c98921c37 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -111,7 +111,7 @@ proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
}
static int proc_alignment_write(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+ unsigned long count, void *data)
{
char mode;
@@ -119,7 +119,7 @@ static int proc_alignment_write(struct file *file, const char __user *buffer,
if (get_user(mode, buffer))
return -EFAULT;
if (mode >= '0' && mode <= '5')
- ai_usermode = mode - '0';
+ ai_usermode = mode - '0';
}
return count;
}
@@ -262,7 +262,7 @@ union offset_union {
goto fault; \
} while (0)
-#define put32_unaligned_check(val,addr) \
+#define put32_unaligned_check(val,addr) \
__put32_unaligned_check("strb", val, addr)
#define put32t_unaligned_check(val,addr) \
@@ -306,19 +306,19 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
return TYPE_LDST;
user:
- if (LDST_L_BIT(instr)) {
- unsigned long val;
- get16t_unaligned_check(val, addr);
+ if (LDST_L_BIT(instr)) {
+ unsigned long val;
+ get16t_unaligned_check(val, addr);
- /* signed half-word? */
- if (instr & 0x40)
- val = (signed long)((signed short) val);
+ /* signed half-word? */
+ if (instr & 0x40)
+ val = (signed long)((signed short) val);
- regs->uregs[rd] = val;
- } else
- put16t_unaligned_check(regs->uregs[rd], addr);
+ regs->uregs[rd] = val;
+ } else
+ put16t_unaligned_check(regs->uregs[rd], addr);
- return TYPE_LDST;
+ return TYPE_LDST;
fault:
return TYPE_FAULT;
@@ -330,6 +330,9 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
{
unsigned int rd = RD_BITS(instr);
+ if (((rd & 1) == 1) || (rd == 14))
+ goto bad;
+
ai_dword += 1;
if (user_mode(regs))
@@ -339,11 +342,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
unsigned long val;
get32_unaligned_check(val, addr);
regs->uregs[rd] = val;
- get32_unaligned_check(val, addr+4);
- regs->uregs[rd+1] = val;
+ get32_unaligned_check(val, addr + 4);
+ regs->uregs[rd + 1] = val;
} else {
put32_unaligned_check(regs->uregs[rd], addr);
- put32_unaligned_check(regs->uregs[rd+1], addr+4);
+ put32_unaligned_check(regs->uregs[rd + 1], addr + 4);
}
return TYPE_LDST;
@@ -353,15 +356,16 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
unsigned long val;
get32t_unaligned_check(val, addr);
regs->uregs[rd] = val;
- get32t_unaligned_check(val, addr+4);
- regs->uregs[rd+1] = val;
+ get32t_unaligned_check(val, addr + 4);
+ regs->uregs[rd + 1] = val;
} else {
put32t_unaligned_check(regs->uregs[rd], addr);
- put32t_unaligned_check(regs->uregs[rd+1], addr+4);
+ put32t_unaligned_check(regs->uregs[rd + 1], addr + 4);
}
return TYPE_LDST;
-
+ bad:
+ return TYPE_ERROR;
fault:
return TYPE_FAULT;
}
@@ -439,7 +443,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
if (LDST_P_EQ_U(instr)) /* U = P */
eaddr += 4;
- /*
+ /*
* For alignment faults on the ARM922T/ARM920T the MMU makes
* the FSR (and hence addr) equal to the updated base address
* of the multiple access rather than the restored value.
@@ -566,7 +570,7 @@ thumb2arm(u16 tinstr)
/* 6.5.1 Format 3: */
case 0x4800 >> 11: /* 7.1.28 LDR(3) */
/* NOTE: This case is not technically possible. We're
- * loading 32-bit memory data via PC relative
+ * loading 32-bit memory data via PC relative
* addressing mode. So we can and should eliminate
* this case. But I'll leave it here for now.
*/
@@ -638,7 +642,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (fault) {
type = TYPE_FAULT;
- goto bad_or_fault;
+ goto bad_or_fault;
}
if (user_mode(regs))
@@ -663,6 +667,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
else if ((instr & 0x001000f0) == 0x000000d0 || /* LDRD */
(instr & 0x001000f0) == 0x000000f0) /* STRD */
handler = do_alignment_ldrdstrd;
+ else if ((instr & 0x01f00ff0) == 0x01000090) /* SWP */
+ goto swp;
else
goto bad;
break;
@@ -733,6 +739,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
do_bad_area(current, current->mm, addr, fsr, regs);
return 0;
+ swp:
+ printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
+
bad:
/*
* Oops, we didn't handle the instruction.
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 85c10a71e7c6..72966d90e956 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -18,6 +18,7 @@
#define HARVARD_CACHE
#define CACHE_LINE_SIZE 32
#define D_CACHE_LINE_SIZE 32
+#define BTB_FLUSH_SIZE 8
/*
* v6_flush_cache_all()
@@ -98,7 +99,13 @@ ENTRY(v6_coherent_user_range)
mcr p15, 0, r0, c7, c5, 1 @ invalidate I line
#endif
mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry
- add r0, r0, #CACHE_LINE_SIZE
+ add r0, r0, #BTB_FLUSH_SIZE
+ mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry
+ add r0, r0, #BTB_FLUSH_SIZE
+ mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry
+ add r0, r0, #BTB_FLUSH_SIZE
+ mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry
+ add r0, r0, #BTB_FLUSH_SIZE
cmp r0, r1
blo 1b
#ifdef HARVARD_CACHE
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 26356ce4da54..82f4d5e27c54 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -75,7 +75,7 @@ static struct vm_region consistent_head = {
};
static struct vm_region *
-vm_region_alloc(struct vm_region *head, size_t size, int gfp)
+vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
{
unsigned long addr = head->vm_start, end = head->vm_end - size;
unsigned long flags;
@@ -133,7 +133,7 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad
#endif
static void *
-__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
+__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
pgprot_t prot)
{
struct page *page;
@@ -251,7 +251,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
* virtual and bus address for that space.
*/
void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
return __dma_alloc(dev, size, handle, gfp,
pgprot_noncached(pgprot_kernel));
@@ -263,7 +263,7 @@ EXPORT_SYMBOL(dma_alloc_coherent);
* dma_alloc_coherent above.
*/
void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
return __dma_alloc(dev, size, handle, gfp,
pgprot_writecombine(pgprot_kernel));
diff --git a/arch/arm/mm/copypage-v3.S b/arch/arm/mm/copypage-v3.S
index 4940f1908316..3c58ebbf0359 100644
--- a/arch/arm/mm/copypage-v3.S
+++ b/arch/arm/mm/copypage-v3.S
@@ -12,7 +12,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
.text
.align 5
diff --git a/arch/arm/mm/copypage-v4wb.S b/arch/arm/mm/copypage-v4wb.S
index b94c345ceb94..83117354b1cd 100644
--- a/arch/arm/mm/copypage-v4wb.S
+++ b/arch/arm/mm/copypage-v4wb.S
@@ -11,7 +11,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
.text
.align 5
diff --git a/arch/arm/mm/copypage-v4wt.S b/arch/arm/mm/copypage-v4wt.S
index 976793937a93..e1f2af28d549 100644
--- a/arch/arm/mm/copypage-v4wt.S
+++ b/arch/arm/mm/copypage-v4wt.S
@@ -14,7 +14,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
.text
.align 5
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 0b6c4db44e08..4a884baf3b9c 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -233,7 +233,17 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (in_interrupt() || !mm)
goto no_context;
- down_read(&mm->mmap_sem);
+ /*
+ * As per x86, we may deadlock here. However, since the kernel only
+ * validly references user space from well defined areas of the code,
+ * we can bug out early if this is from code which shouldn't.
+ */
+ if (!down_read_trylock(&mm->mmap_sem)) {
+ if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
+ goto no_context;
+ down_read(&mm->mmap_sem);
+ }
+
fault = __do_page_fault(mm, addr, fsr, tsk);
up_read(&mm->mmap_sem);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 191788fb18d1..c9a03981b785 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -16,6 +16,7 @@
#include <asm/tlbflush.h>
#ifdef CONFIG_CPU_CACHE_VIPT
+
#define ALIAS_FLUSH_START 0xffff4000
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
@@ -33,6 +34,57 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
: "cc");
}
+
+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);
+}
#else
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
#endif
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index edffa47a4b2a..f4496813615a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/init.c
*
- * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 1995-2005 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -86,14 +86,19 @@ void show_mem(void)
printk("%d pages swap cached\n", cached);
}
-struct node_info {
- unsigned int start;
- unsigned int end;
- int bootmap_pages;
-};
+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
+{
+ return pmd_offset(pgd, virt);
+}
+
+static inline pmd_t *pmd_off_k(unsigned long virt)
+{
+ return pmd_off(pgd_offset_k(virt), virt);
+}
-#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define for_each_nodebank(iter,mi,no) \
+ for (iter = 0; iter < mi->nr_banks; iter++) \
+ if (mi->bank[iter].node == no)
/*
* FIXME: We really want to avoid allocating the bootmap bitmap
@@ -106,15 +111,12 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
{
unsigned int start_pfn, bank, bootmap_pfn;
- start_pfn = O_PFN_UP(__pa(&_end));
+ start_pfn = PAGE_ALIGN(__pa(&_end)) >> PAGE_SHIFT;
bootmap_pfn = 0;
- for (bank = 0; bank < mi->nr_banks; bank ++) {
+ for_each_nodebank(bank, mi, node) {
unsigned int start, end;
- if (mi->bank[bank].node != node)
- continue;
-
start = mi->bank[bank].start >> PAGE_SHIFT;
end = (mi->bank[bank].size +
mi->bank[bank].start) >> PAGE_SHIFT;
@@ -140,92 +142,6 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
return bootmap_pfn;
}
-/*
- * Scan the memory info structure and pull out:
- * - the end of memory
- * - the number of nodes
- * - the pfn range of each node
- * - the number of bootmem bitmap pages
- */
-static unsigned int __init
-find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
-{
- unsigned int i, bootmem_pages = 0, memend_pfn = 0;
-
- for (i = 0; i < MAX_NUMNODES; i++) {
- np[i].start = -1U;
- np[i].end = 0;
- np[i].bootmap_pages = 0;
- }
-
- for (i = 0; i < mi->nr_banks; i++) {
- unsigned long start, end;
- int node;
-
- if (mi->bank[i].size == 0) {
- /*
- * Mark this bank with an invalid node number
- */
- mi->bank[i].node = -1;
- continue;
- }
-
- node = mi->bank[i].node;
-
- /*
- * Make sure we haven't exceeded the maximum number of nodes
- * that we have in this configuration. If we have, we're in
- * trouble. (maybe we ought to limit, instead of bugging?)
- */
- if (node >= MAX_NUMNODES)
- BUG();
- node_set_online(node);
-
- /*
- * Get the start and end pfns for this bank
- */
- start = mi->bank[i].start >> PAGE_SHIFT;
- end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
-
- if (np[node].start > start)
- np[node].start = start;
-
- if (np[node].end < end)
- np[node].end = end;
-
- if (memend_pfn < end)
- memend_pfn = end;
- }
-
- /*
- * Calculate the number of pages we require to
- * store the bootmem bitmaps.
- */
- for_each_online_node(i) {
- if (np[i].end == 0)
- continue;
-
- np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
- np[i].start);
- bootmem_pages += np[i].bootmap_pages;
- }
-
- high_memory = __va(memend_pfn << PAGE_SHIFT);
-
- /*
- * This doesn't seem to be used by the Linux memory
- * manager any more. If we can get rid of it, we
- * also get rid of some of the stuff above as well.
- *
- * Note: max_low_pfn and max_pfn reflect the number
- * of _pages_ in the system, not the maximum PFN.
- */
- max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
- max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
-
- return bootmem_pages;
-}
-
static int __init check_initrd(struct meminfo *mi)
{
int initrd_node = -2;
@@ -266,9 +182,8 @@ static int __init check_initrd(struct meminfo *mi)
/*
* Reserve the various regions of node 0
*/
-static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
+static __init void reserve_node_zero(pg_data_t *pgdat)
{
- pg_data_t *pgdat = NODE_DATA(0);
unsigned long res_size = 0;
/*
@@ -289,13 +204,6 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
PTRS_PER_PGD * sizeof(pgd_t));
/*
- * And don't forget to reserve the allocator bitmap,
- * which will be freed later.
- */
- reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
- bootmap_pages << PAGE_SHIFT);
-
- /*
* Hmm... This should go elsewhere, but we really really need to
* stop things allocating the low memory; ideally we need a better
* implementation of GFP_DMA which does not assume that DMA-able
@@ -324,183 +232,276 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
}
-/*
- * Register all available RAM in this node with the bootmem allocator.
- */
-static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
+void __init build_mem_type_table(void);
+void __init create_mapping(struct map_desc *md);
+
+static unsigned long __init
+bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
{
- pg_data_t *pgdat = NODE_DATA(node);
- int bank;
+ unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
+ unsigned long start_pfn, end_pfn, boot_pfn;
+ unsigned int boot_pages;
+ pg_data_t *pgdat;
+ int i;
- for (bank = 0; bank < mi->nr_banks; bank++)
- if (mi->bank[bank].node == node)
- free_bootmem_node(pgdat, mi->bank[bank].start,
- mi->bank[bank].size);
-}
+ start_pfn = -1UL;
+ end_pfn = 0;
-/*
- * Initialise the bootmem allocator for all nodes. This is called
- * early during the architecture specific initialisation.
- */
-static void __init bootmem_init(struct meminfo *mi)
-{
- struct node_info node_info[MAX_NUMNODES], *np = node_info;
- unsigned int bootmap_pages, bootmap_pfn, map_pg;
- int node, initrd_node;
+ /*
+ * Calculate the pfn range, and map the memory banks for this node.
+ */
+ for_each_nodebank(i, mi, node) {
+ unsigned long start, end;
+ struct map_desc map;
- bootmap_pages = find_memend_and_nodes(mi, np);
- bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages);
- initrd_node = check_initrd(mi);
+ start = mi->bank[i].start >> PAGE_SHIFT;
+ end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
- map_pg = bootmap_pfn;
+ if (start_pfn > start)
+ start_pfn = start;
+ if (end_pfn < end)
+ end_pfn = end;
+
+ map.pfn = __phys_to_pfn(mi->bank[i].start);
+ map.virtual = __phys_to_virt(mi->bank[i].start);
+ map.length = mi->bank[i].size;
+ map.type = MT_MEMORY;
+
+ create_mapping(&map);
+ }
/*
- * Initialise the bootmem nodes.
- *
- * What we really want to do is:
- *
- * unmap_all_regions_except_kernel();
- * for_each_node_in_reverse_order(node) {
- * map_node(node);
- * allocate_bootmem_map(node);
- * init_bootmem_node(node);
- * free_bootmem_node(node);
- * }
- *
- * but this is a 2.5-type change. For now, we just set
- * the nodes up in reverse order.
- *
- * (we could also do with rolling bootmem_init and paging_init
- * into one generic "memory_init" type function).
+ * If there is no memory in this node, ignore it.
*/
- np += num_online_nodes() - 1;
- for (node = num_online_nodes() - 1; node >= 0; node--, np--) {
- /*
- * If there are no pages in this node, ignore it.
- * Note that node 0 must always have some pages.
- */
- if (np->end == 0 || !node_online(node)) {
- if (node == 0)
- BUG();
- continue;
- }
+ if (end_pfn == 0)
+ return end_pfn;
- /*
- * Initialise the bootmem allocator.
- */
- init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end);
- free_bootmem_node_bank(node, mi);
- map_pg += np->bootmap_pages;
+ /*
+ * Allocate the bootmem bitmap page.
+ */
+ boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+ boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
- /*
- * If this is node 0, we need to reserve some areas ASAP -
- * we may use bootmem on node 0 to setup the other nodes.
- */
- if (node == 0)
- reserve_node_zero(bootmap_pfn, bootmap_pages);
- }
+ /*
+ * Initialise the bootmem allocator for this node, handing the
+ * memory banks over to bootmem.
+ */
+ node_set_online(node);
+ pgdat = NODE_DATA(node);
+ init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+ for_each_nodebank(i, mi, node)
+ free_bootmem_node(pgdat, mi->bank[i].start, mi->bank[i].size);
+
+ /*
+ * Reserve the bootmem bitmap for this node.
+ */
+ reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
+ boot_pages << PAGE_SHIFT);
#ifdef CONFIG_BLK_DEV_INITRD
- if (phys_initrd_size && initrd_node >= 0) {
- reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
+ /*
+ * If the initrd is in this node, reserve its memory.
+ */
+ if (node == initrd_node) {
+ reserve_bootmem_node(pgdat, phys_initrd_start,
phys_initrd_size);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
#endif
- BUG_ON(map_pg != bootmap_pfn + bootmap_pages);
+ /*
+ * Finally, reserve any node zero regions.
+ */
+ if (node == 0)
+ reserve_node_zero(pgdat);
+
+ /*
+ * initialise the zones within this node.
+ */
+ memset(zone_size, 0, sizeof(zone_size));
+ memset(zhole_size, 0, sizeof(zhole_size));
+
+ /*
+ * The size of this node has already been determined. If we need
+ * to do anything fancy with the allocation of this memory to the
+ * zones, now is the time to do it.
+ */
+ zone_size[0] = end_pfn - start_pfn;
+
+ /*
+ * For each bank in this node, calculate the size of the holes.
+ * holes = node_size - sum(bank_sizes_in_node)
+ */
+ zhole_size[0] = zone_size[0];
+ for_each_nodebank(i, mi, node)
+ zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+
+ /*
+ * Adjust the sizes according to any special requirements for
+ * this machine type.
+ */
+ arch_adjust_zones(node, zone_size, zhole_size);
+
+ free_area_init_node(node, pgdat, zone_size, start_pfn, zhole_size);
+
+ return end_pfn;
}
-/*
- * paging_init() sets up the page tables, initialises the zone memory
- * maps, and sets up the zero page, bad page and bad page tables.
- */
-void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+static void __init bootmem_init(struct meminfo *mi)
{
- void *zero_page;
- int node;
+ unsigned long addr, memend_pfn = 0;
+ int node, initrd_node, i;
- bootmem_init(mi);
+ /*
+ * Invalidate the node number for empty or invalid memory banks
+ */
+ for (i = 0; i < mi->nr_banks; i++)
+ if (mi->bank[i].size == 0 || mi->bank[i].node >= MAX_NUMNODES)
+ mi->bank[i].node = -1;
memcpy(&meminfo, mi, sizeof(meminfo));
+#ifdef CONFIG_XIP_KERNEL
+#error needs fixing
+ p->pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PMD_MASK);
+ p->virtual = (unsigned long)&_stext & PMD_MASK;
+ p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK;
+ p->type = MT_ROM;
+ p ++;
+#endif
+
/*
- * allocate the zero page. Note that we count on this going ok.
+ * Clear out all the mappings below the kernel image.
+ * FIXME: what about XIP?
*/
- zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+ for (addr = 0; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
/*
- * initialise the page tables.
+ * Clear out all the kernel space mappings, except for the first
+ * memory bank, up to the end of the vmalloc region.
*/
- memtable_init(mi);
- if (mdesc->map_io)
- mdesc->map_io();
- local_flush_tlb_all();
+ for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
+ addr < VMALLOC_END; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
/*
- * initialise the zones within each node
+ * Locate which node contains the ramdisk image, if any.
*/
- for_each_online_node(node) {
- unsigned long zone_size[MAX_NR_ZONES];
- unsigned long zhole_size[MAX_NR_ZONES];
- struct bootmem_data *bdata;
- pg_data_t *pgdat;
- int i;
+ initrd_node = check_initrd(mi);
- /*
- * Initialise the zone size information.
- */
- for (i = 0; i < MAX_NR_ZONES; i++) {
- zone_size[i] = 0;
- zhole_size[i] = 0;
- }
+ /*
+ * Run through each node initialising the bootmem allocator.
+ */
+ for_each_node(node) {
+ unsigned long end_pfn;
- pgdat = NODE_DATA(node);
- bdata = pgdat->bdata;
+ end_pfn = bootmem_init_node(node, initrd_node, mi);
/*
- * The size of this node has already been determined.
- * If we need to do anything fancy with the allocation
- * of this memory to the zones, now is the time to do
- * it.
+ * Remember the highest memory PFN.
*/
- zone_size[0] = bdata->node_low_pfn -
- (bdata->node_boot_start >> PAGE_SHIFT);
+ if (end_pfn > memend_pfn)
+ memend_pfn = end_pfn;
+ }
- /*
- * If this zone has zero size, skip it.
- */
- if (!zone_size[0])
- continue;
+ high_memory = __va(memend_pfn << PAGE_SHIFT);
- /*
- * For each bank in this node, calculate the size of the
- * holes. holes = node_size - sum(bank_sizes_in_node)
- */
- zhole_size[0] = zone_size[0];
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].node != node)
- continue;
+ /*
+ * This doesn't seem to be used by the Linux memory manager any
+ * more, but is used by ll_rw_block. If we can get rid of it, we
+ * also get rid of some of the stuff above as well.
+ *
+ * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
+ * the system, not the maximum PFN.
+ */
+ max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET;
+}
- zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
- }
+/*
+ * Set up device the mappings. Since we clear out the page tables for all
+ * mappings above VMALLOC_END, we will remove any debug device mappings.
+ * This means you have to be careful how you debug this function, or any
+ * called function. (Do it by code inspection!)
+ */
+static void __init devicemaps_init(struct machine_desc *mdesc)
+{
+ struct map_desc map;
+ unsigned long addr;
+ void *vectors;
- /*
- * Adjust the sizes according to any special
- * requirements for this machine type.
- */
- arch_adjust_zones(node, zone_size, zhole_size);
+ for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
- free_area_init_node(node, pgdat, zone_size,
- bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
+ /*
+ * Map the cache flushing regions.
+ */
+#ifdef FLUSH_BASE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
+ map.virtual = FLUSH_BASE;
+ map.length = PGDIR_SIZE;
+ map.type = MT_CACHECLEAN;
+ create_mapping(&map);
+#endif
+#ifdef FLUSH_BASE_MINICACHE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE);
+ map.virtual = FLUSH_BASE_MINICACHE;
+ map.length = PGDIR_SIZE;
+ map.type = MT_MINICLEAN;
+ create_mapping(&map);
+#endif
+
+ flush_cache_all();
+ local_flush_tlb_all();
+
+ vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+ BUG_ON(!vectors);
+
+ /*
+ * Create a mapping for the machine vectors at the high-vectors
+ * location (0xffff0000). If we aren't using high-vectors, also
+ * create a mapping at the low-vectors virtual address.
+ */
+ map.pfn = __phys_to_pfn(virt_to_phys(vectors));
+ map.virtual = 0xffff0000;
+ map.length = PAGE_SIZE;
+ map.type = MT_HIGH_VECTORS;
+ create_mapping(&map);
+
+ if (!vectors_high()) {
+ map.virtual = 0;
+ map.type = MT_LOW_VECTORS;
+ create_mapping(&map);
}
/*
- * finish off the bad pages once
- * the mem_map is initialised
+ * Ask the machine support to map in the statically mapped devices.
+ * After this point, we can start to touch devices again.
+ */
+ if (mdesc->map_io)
+ mdesc->map_io();
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+ void *zero_page;
+
+ build_mem_type_table();
+ bootmem_init(mi);
+ devicemaps_init(mdesc);
+
+ top_pmd = pmd_off_k(0xffff0000);
+
+ /*
+ * allocate the zero page. Note that we count on this going ok.
*/
+ zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
memzero(zero_page, PAGE_SIZE);
empty_zero_page = virt_to_page(zero_page);
flush_dcache_page(empty_zero_page);
@@ -562,10 +563,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi)
* may not be the case, especially if the user has provided the
* information on the command line.
*/
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size == 0 || mi->bank[i].node != node)
- continue;
-
+ for_each_nodebank(i, mi, node) {
bank_start = mi->bank[i].start >> PAGE_SHIFT;
if (bank_start < prev_bank_end) {
printk(KERN_ERR "MEM: unordered memory banks. "
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 7110e54182b1..6fb1258df1b5 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <asm/cacheflush.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index d125a3dc061c..61bc2fa0511e 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/mm-armv.c
*
- * Copyright (C) 1998-2002 Russell King
+ * Copyright (C) 1998-2005 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -305,16 +305,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
}
-/*
- * Clear any PGD mapping. On a two-level page table system,
- * the clearance is done by the middle-level functions (pmd)
- * rather than the top-level (pgd) functions.
- */
-static inline void clear_mapping(unsigned long virt)
-{
- pmd_clear(pmd_off_k(virt));
-}
-
struct mem_types {
unsigned int prot_pte;
unsigned int prot_l1;
@@ -373,7 +363,7 @@ static struct mem_types mem_types[] __initdata = {
/*
* Adjust the PMD section entries according to the CPU in use.
*/
-static void __init build_mem_type_table(void)
+void __init build_mem_type_table(void)
{
struct cachepolicy *cp;
unsigned int cr = get_cr();
@@ -483,25 +473,25 @@ static void __init build_mem_type_table(void)
* offsets, and we take full advantage of sections and
* supersections.
*/
-static void __init create_mapping(struct map_desc *md)
+void __init create_mapping(struct map_desc *md)
{
unsigned long virt, length;
int prot_sect, prot_l1, domain;
pgprot_t prot_pte;
- long off;
+ unsigned long off = (u32)__pfn_to_phys(md->pfn);
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
- "0x%08lx at 0x%08lx in user region\n",
- md->physical, md->virtual);
+ "0x%016llx at 0x%08lx in user region\n",
+ __pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
- printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx "
+ printk(KERN_WARNING "BUG: mapping for 0x%016llx at 0x%08lx "
"overlaps vmalloc space\n",
- md->physical, md->virtual);
+ __pfn_to_phys((u64)md->pfn), md->virtual);
}
domain = mem_types[md->type].domain;
@@ -509,15 +499,40 @@ static void __init create_mapping(struct map_desc *md)
prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
+ /*
+ * Catch 36-bit addresses
+ */
+ if(md->pfn >= 0x100000) {
+ if(domain) {
+ printk(KERN_ERR "MM: invalid domain in supersection "
+ "mapping for 0x%016llx at 0x%08lx\n",
+ __pfn_to_phys((u64)md->pfn), md->virtual);
+ return;
+ }
+ if((md->virtual | md->length | __pfn_to_phys(md->pfn))
+ & ~SUPERSECTION_MASK) {
+ printk(KERN_ERR "MM: cannot create mapping for "
+ "0x%016llx at 0x%08lx invalid alignment\n",
+ __pfn_to_phys((u64)md->pfn), md->virtual);
+ return;
+ }
+
+ /*
+ * Shift bits [35:32] of address into bits [23:20] of PMD
+ * (See ARMv6 spec).
+ */
+ off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
+ }
+
virt = md->virtual;
- off = md->physical - virt;
+ off -= virt;
length = md->length;
if (mem_types[md->type].prot_l1 == 0 &&
(virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
"be mapped using pages, ignoring.\n",
- md->physical, md->virtual);
+ __pfn_to_phys(md->pfn), md->virtual);
return;
}
@@ -535,13 +550,22 @@ static void __init create_mapping(struct map_desc *md)
* of the actual domain assignments in use.
*/
if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) {
- /* Align to supersection boundary */
- while ((virt & ~SUPERSECTION_MASK || (virt + off) &
- ~SUPERSECTION_MASK) && length >= (PGDIR_SIZE / 2)) {
- alloc_init_section(virt, virt + off, prot_sect);
-
- virt += (PGDIR_SIZE / 2);
- length -= (PGDIR_SIZE / 2);
+ /*
+ * Align to supersection boundary if !high pages.
+ * High pages have already been checked for proper
+ * alignment above and they will fail the SUPSERSECTION_MASK
+ * check because of the way the address is encoded into
+ * offset.
+ */
+ if (md->pfn <= 0x100000) {
+ while ((virt & ~SUPERSECTION_MASK ||
+ (virt + off) & ~SUPERSECTION_MASK) &&
+ length >= (PGDIR_SIZE / 2)) {
+ alloc_init_section(virt, virt + off, prot_sect);
+
+ virt += (PGDIR_SIZE / 2);
+ length -= (PGDIR_SIZE / 2);
+ }
}
while (length >= SUPERSECTION_SIZE) {
@@ -601,100 +625,6 @@ void setup_mm_for_reboot(char mode)
}
}
-extern void _stext, _etext;
-
-/*
- * Setup initial mappings. We use the page we allocated for zero page to hold
- * the mappings, which will get overwritten by the vectors in traps_init().
- * The mappings must be in virtual address order.
- */
-void __init memtable_init(struct meminfo *mi)
-{
- struct map_desc *init_maps, *p, *q;
- unsigned long address = 0;
- int i;
-
- build_mem_type_table();
-
- init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
-
-#ifdef CONFIG_XIP_KERNEL
- p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK;
- p->virtual = (unsigned long)&_stext & PMD_MASK;
- p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK;
- p->type = MT_ROM;
- p ++;
-#endif
-
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size == 0)
- continue;
-
- p->physical = mi->bank[i].start;
- p->virtual = __phys_to_virt(p->physical);
- p->length = mi->bank[i].size;
- p->type = MT_MEMORY;
- p ++;
- }
-
-#ifdef FLUSH_BASE
- p->physical = FLUSH_BASE_PHYS;
- p->virtual = FLUSH_BASE;
- p->length = PGDIR_SIZE;
- p->type = MT_CACHECLEAN;
- p ++;
-#endif
-
-#ifdef FLUSH_BASE_MINICACHE
- p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
- p->virtual = FLUSH_BASE_MINICACHE;
- p->length = PGDIR_SIZE;
- p->type = MT_MINICLEAN;
- p ++;
-#endif
-
- /*
- * Go through the initial mappings, but clear out any
- * pgdir entries that are not in the description.
- */
- q = init_maps;
- do {
- if (address < q->virtual || q == p) {
- clear_mapping(address);
- address += PGDIR_SIZE;
- } else {
- create_mapping(q);
-
- address = q->virtual + q->length;
- address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
-
- q ++;
- }
- } while (address != 0);
-
- /*
- * Create a mapping for the machine vectors at the high-vectors
- * location (0xffff0000). If we aren't using high-vectors, also
- * create a mapping at the low-vectors virtual address.
- */
- init_maps->physical = virt_to_phys(init_maps);
- init_maps->virtual = 0xffff0000;
- init_maps->length = PAGE_SIZE;
- init_maps->type = MT_HIGH_VECTORS;
- create_mapping(init_maps);
-
- if (!vectors_high()) {
- init_maps->virtual = 0;
- init_maps->type = MT_LOW_VECTORS;
- create_mapping(init_maps);
- }
-
- flush_cache_all();
- local_flush_tlb_all();
-
- top_pmd = pmd_off_k(0xffff0000);
-}
-
/*
* Create the architecture specific mappings
*/
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 5c0ae5260d1c..82ec954e45b6 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -28,7 +28,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
@@ -509,7 +509,7 @@ cpu_arm1020_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm1020_proc_info,#object
__arm1020_proc_info:
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index d69389c4d4ba..7375fe930f72 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -28,7 +28,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
@@ -491,7 +491,7 @@ cpu_arm1020e_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm1020e_proc_info,#object
__arm1020e_proc_info:
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 747ed963e1df..6ca639094d6f 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -17,7 +17,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
@@ -473,7 +473,7 @@ cpu_arm1022_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm1022_proc_info,#object
__arm1022_proc_info:
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 248110c9cf13..10317e4f55d2 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -17,7 +17,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
@@ -469,7 +469,7 @@ cpu_arm1026_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm1026_proc_info,#object
__arm1026_proc_info:
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 189ef6a71ba1..8e7e1e70ab05 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -13,7 +13,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
@@ -332,7 +332,7 @@ cpu_arm710_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm6_proc_info, #object
__arm6_proc_info:
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 57cfa6a2f54f..a13e0184d343 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -33,7 +33,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
@@ -222,7 +222,7 @@ cpu_arm720_name:
* See linux/include/asm-arm/procinfo.h for a definition of this structure.
*/
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm710_proc_info, #object
__arm710_proc_info:
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 0f490a0fcb71..d16513899999 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -452,7 +452,7 @@ cpu_arm920_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm920_proc_info,#object
__arm920_proc_info:
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 62bc34a139ee..23b8ed97f4e3 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -456,7 +456,7 @@ cpu_arm922_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm922_proc_info,#object
__arm922_proc_info:
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index ee49aa2ca781..ee95c52db513 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -521,7 +521,7 @@ cpu_arm925_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm925_proc_info,#object
__arm925_proc_info:
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index bb95cc9fed03..7d042dc20c47 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -471,7 +471,7 @@ cpu_arm926_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __arm926_proc_info,#object
__arm926_proc_info:
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 9137fe563599..7cfc2604a1ee 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -4,7 +4,7 @@
* VMA_VM_FLAGS
* VM_EXEC
*/
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
/*
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 360cae905692..bd330c4075a1 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -15,7 +15,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
@@ -249,7 +249,7 @@ cpu_sa110_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __sa110_proc_info,#object
__sa110_proc_info:
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index d447cd5f3dd9..91b89124c0d7 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -20,7 +20,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
@@ -280,7 +280,7 @@ cpu_sa1110_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __sa1100_proc_info,#object
__sa1100_proc_info:
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 139a38670c5d..9bb5fff406fb 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -11,7 +11,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/procinfo.h>
#include <asm/pgtable.h>
@@ -55,7 +55,14 @@ ENTRY(cpu_v6_proc_init)
mov pc, lr
ENTRY(cpu_v6_proc_fin)
- mov pc, lr
+ stmfd sp!, {lr}
+ cpsid if @ disable interrupts
+ bl v6_flush_kern_cache_all
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x0006 @ .............ca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ ldmfd sp!, {pc}
/*
* cpu_v6_reset(loc)
@@ -240,7 +247,7 @@ cpu_elf_name:
.size cpu_elf_name, . - cpu_elf_name
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
/*
* Match any ARMv6 processor core.
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index b88de2700146..861b35947280 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -578,7 +578,7 @@ cpu_pxa270_name:
.align
- .section ".proc.info", #alloc, #execinstr
+ .section ".proc.info.init", #alloc, #execinstr
.type __80200_proc_info,#object
__80200_proc_info:
diff --git a/arch/arm/mm/tlb-v3.S b/arch/arm/mm/tlb-v3.S
index 44b0daeaff9b..c10786ec8e0a 100644
--- a/arch/arm/mm/tlb-v3.S
+++ b/arch/arm/mm/tlb-v3.S
@@ -13,7 +13,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
#include "proc-macros.S"
diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
index db82ee468248..d6c94457c2b9 100644
--- a/arch/arm/mm/tlb-v4.S
+++ b/arch/arm/mm/tlb-v4.S
@@ -14,7 +14,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
#include "proc-macros.S"
diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
index 7908d5f1f130..cb829ca7845d 100644
--- a/arch/arm/mm/tlb-v4wb.S
+++ b/arch/arm/mm/tlb-v4wb.S
@@ -14,7 +14,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
#include "proc-macros.S"
diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S
index efbe94bbe1a7..60cfc4a25dd5 100644
--- a/arch/arm/mm/tlb-v4wbi.S
+++ b/arch/arm/mm/tlb-v4wbi.S
@@ -14,7 +14,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
#include "proc-macros.S"
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
index 99ed26e78adf..6f76b89ef46e 100644
--- a/arch/arm/mm/tlb-v6.S
+++ b/arch/arm/mm/tlb-v6.S
@@ -11,7 +11,7 @@
* These assume a split I/D TLB.
*/
#include <linux/linkage.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
#include "proc-macros.S"
diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S
index 0ed38b0913db..51940a96d6a6 100644
--- a/arch/arm/nwfpe/entry26.S
+++ b/arch/arm/nwfpe/entry26.S
@@ -20,7 +20,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
/* This is the kernel's entry point into the floating point emulator.
It is called from the kernel with code similar to this:
diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c
index 7690f731ee87..7b3d74d73c80 100644
--- a/arch/arm/nwfpe/fpa11.c
+++ b/arch/arm/nwfpe/fpa11.c
@@ -31,11 +31,6 @@
#include <linux/string.h>
#include <asm/system.h>
-/* forward declarations */
-unsigned int EmulateCPDO(const unsigned int);
-unsigned int EmulateCPDT(const unsigned int);
-unsigned int EmulateCPRT(const unsigned int);
-
/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
static void resetFPA11(void)
{
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index 93523ae4b7a1..9677ae8448e8 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -95,4 +95,24 @@ extern int8 SetRoundingMode(const unsigned int);
extern int8 SetRoundingPrecision(const unsigned int);
extern void nwfpe_init_fpa(union fp_state *fp);
+extern unsigned int EmulateAll(unsigned int opcode);
+
+extern unsigned int EmulateCPDT(const unsigned int opcode);
+extern unsigned int EmulateCPDO(const unsigned int opcode);
+extern unsigned int EmulateCPRT(const unsigned int opcode);
+
+/* fpa11_cpdt.c */
+extern unsigned int PerformLDF(const unsigned int opcode);
+extern unsigned int PerformSTF(const unsigned int opcode);
+extern unsigned int PerformLFM(const unsigned int opcode);
+extern unsigned int PerformSFM(const unsigned int opcode);
+
+/* single_cpdo.c */
+
+extern unsigned int SingleCPDO(struct roundingData *roundData,
+ const unsigned int opcode, FPREG * rFd);
+/* double_cpdo.c */
+extern unsigned int DoubleCPDO(struct roundingData *roundData,
+ const unsigned int opcode, FPREG * rFd);
+
#endif
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c
index adf8d3000540..7c67023655e4 100644
--- a/arch/arm/nwfpe/fpa11_cprt.c
+++ b/arch/arm/nwfpe/fpa11_cprt.c
@@ -26,12 +26,11 @@
#include "fpa11.inl"
#include "fpmodule.h"
#include "fpmodule.inl"
+#include "softfloat.h"
#ifdef CONFIG_FPE_NWFPE_XP
extern flag floatx80_is_nan(floatx80);
#endif
-extern flag float64_is_nan(float64);
-extern flag float32_is_nan(float32);
unsigned int PerformFLT(const unsigned int opcode);
unsigned int PerformFIX(const unsigned int opcode);
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
index 1777e92a88e6..6528e081c83f 100644
--- a/arch/arm/nwfpe/fpopcode.h
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -476,4 +476,10 @@ static inline unsigned int getDestinationSize(const unsigned int opcode)
return (nRc);
}
+extern unsigned int checkCondition(const unsigned int opcode,
+ const unsigned int ccodes);
+
+extern const float64 float64Constant[];
+extern const float32 float32Constant[];
+
#endif
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 1c8799b9ee4d..14151700b6b2 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -265,4 +265,7 @@ static inline flag float64_lt_nocheck(float64 a, float64 b)
return (a != b) && (aSign ^ (a < b));
}
+extern flag float32_is_nan( float32 a );
+extern flag float64_is_nan( float64 a );
+
#endif
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 8ffb523e6c77..6a94e54848fd 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o \
timer_int.o )
-oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
-oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o
+oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
+oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index e57dde882898..1415930ceee1 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -10,74 +10,23 @@
#include <linux/init.h>
#include <linux/oprofile.h>
#include <linux/errno.h>
-#include <asm/semaphore.h>
#include <linux/sysdev.h>
+#include <asm/semaphore.h>
#include "op_counter.h"
#include "op_arm_model.h"
-static struct op_arm_model_spec *pmu_model;
-static int pmu_enabled;
-static struct semaphore pmu_sem;
-
-static int pmu_start(void);
-static int pmu_setup(void);
-static void pmu_stop(void);
-static int pmu_create_files(struct super_block *, struct dentry *);
-
-#ifdef CONFIG_PM
-static int pmu_suspend(struct sys_device *dev, pm_message_t state)
-{
- if (pmu_enabled)
- pmu_stop();
- return 0;
-}
-
-static int pmu_resume(struct sys_device *dev)
-{
- if (pmu_enabled)
- pmu_start();
- return 0;
-}
-
-static struct sysdev_class oprofile_sysclass = {
- set_kset_name("oprofile"),
- .resume = pmu_resume,
- .suspend = pmu_suspend,
-};
-
-static struct sys_device device_oprofile = {
- .id = 0,
- .cls = &oprofile_sysclass,
-};
-
-static int __init init_driverfs(void)
-{
- int ret;
-
- if (!(ret = sysdev_class_register(&oprofile_sysclass)))
- ret = sysdev_register(&device_oprofile);
-
- return ret;
-}
-
-static void exit_driverfs(void)
-{
- sysdev_unregister(&device_oprofile);
- sysdev_class_unregister(&oprofile_sysclass);
-}
-#else
-#define init_driverfs() do { } while (0)
-#define exit_driverfs() do { } while (0)
-#endif /* CONFIG_PM */
+static struct op_arm_model_spec *op_arm_model;
+static int op_arm_enabled;
+static struct semaphore op_arm_sem;
struct op_counter_config counter_config[OP_MAX_COUNTER];
-static int pmu_create_files(struct super_block *sb, struct dentry *root)
+static int op_arm_create_files(struct super_block *sb, struct dentry *root)
{
unsigned int i;
- for (i = 0; i < pmu_model->num_counters; i++) {
+ for (i = 0; i < op_arm_model->num_counters; i++) {
struct dentry *dir;
char buf[2];
@@ -94,63 +43,123 @@ static int pmu_create_files(struct super_block *sb, struct dentry *root)
return 0;
}
-static int pmu_setup(void)
+static int op_arm_setup(void)
{
int ret;
spin_lock(&oprofilefs_lock);
- ret = pmu_model->setup_ctrs();
+ ret = op_arm_model->setup_ctrs();
spin_unlock(&oprofilefs_lock);
return ret;
}
-static int pmu_start(void)
+static int op_arm_start(void)
{
int ret = -EBUSY;
- down(&pmu_sem);
- if (!pmu_enabled) {
- ret = pmu_model->start();
- pmu_enabled = !ret;
+ down(&op_arm_sem);
+ if (!op_arm_enabled) {
+ ret = op_arm_model->start();
+ op_arm_enabled = !ret;
}
- up(&pmu_sem);
+ up(&op_arm_sem);
return ret;
}
-static void pmu_stop(void)
+static void op_arm_stop(void)
+{
+ down(&op_arm_sem);
+ if (op_arm_enabled)
+ op_arm_model->stop();
+ op_arm_enabled = 0;
+ up(&op_arm_sem);
+}
+
+#ifdef CONFIG_PM
+static int op_arm_suspend(struct sys_device *dev, pm_message_t state)
{
- down(&pmu_sem);
- if (pmu_enabled)
- pmu_model->stop();
- pmu_enabled = 0;
- up(&pmu_sem);
+ down(&op_arm_sem);
+ if (op_arm_enabled)
+ op_arm_model->stop();
+ up(&op_arm_sem);
+ return 0;
}
-int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec)
+static int op_arm_resume(struct sys_device *dev)
{
- init_MUTEX(&pmu_sem);
+ down(&op_arm_sem);
+ if (op_arm_enabled && op_arm_model->start())
+ op_arm_enabled = 0;
+ up(&op_arm_sem);
+ return 0;
+}
+
+static struct sysdev_class oprofile_sysclass = {
+ set_kset_name("oprofile"),
+ .resume = op_arm_resume,
+ .suspend = op_arm_suspend,
+};
- if (spec->init() < 0)
- return -ENODEV;
+static struct sys_device device_oprofile = {
+ .id = 0,
+ .cls = &oprofile_sysclass,
+};
- pmu_model = spec;
- init_driverfs();
- ops->create_files = pmu_create_files;
- ops->setup = pmu_setup;
- ops->shutdown = pmu_stop;
- ops->start = pmu_start;
- ops->stop = pmu_stop;
- ops->cpu_type = pmu_model->name;
- printk(KERN_INFO "oprofile: using %s PMU\n", spec->name);
+static int __init init_driverfs(void)
+{
+ int ret;
- return 0;
+ if (!(ret = sysdev_class_register(&oprofile_sysclass)))
+ ret = sysdev_register(&device_oprofile);
+
+ return ret;
+}
+
+static void exit_driverfs(void)
+{
+ sysdev_unregister(&device_oprofile);
+ sysdev_class_unregister(&oprofile_sysclass);
+}
+#else
+#define init_driverfs() do { } while (0)
+#define exit_driverfs() do { } while (0)
+#endif /* CONFIG_PM */
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+ struct op_arm_model_spec *spec = NULL;
+ int ret = -ENODEV;
+
+#ifdef CONFIG_CPU_XSCALE
+ spec = &op_xscale_spec;
+#endif
+
+ if (spec) {
+ init_MUTEX(&op_arm_sem);
+
+ if (spec->init() < 0)
+ return -ENODEV;
+
+ op_arm_model = spec;
+ init_driverfs();
+ ops->create_files = op_arm_create_files;
+ ops->setup = op_arm_setup;
+ ops->shutdown = op_arm_stop;
+ ops->start = op_arm_start;
+ ops->stop = op_arm_stop;
+ ops->cpu_type = op_arm_model->name;
+ ops->backtrace = arm_backtrace;
+ printk(KERN_INFO "oprofile: using %s\n", spec->name);
+ }
+
+ return ret;
}
-void pmu_exit(void)
+void oprofile_arch_exit(void)
{
- if (pmu_model) {
+ if (op_arm_model) {
exit_driverfs();
- pmu_model = NULL;
+ op_arm_model = NULL;
}
}
diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c
deleted file mode 100644
index d315a3a86c86..000000000000
--- a/arch/arm/oprofile/init.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file init.c
- *
- * @remark Copyright 2004 Oprofile Authors
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-#include <linux/oprofile.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include "op_arm_model.h"
-
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
- int ret = -ENODEV;
-
-#ifdef CONFIG_CPU_XSCALE
- ret = pmu_init(ops, &op_xscale_spec);
-#endif
-
- ops->backtrace = arm_backtrace;
-
- return ret;
-}
-
-void oprofile_arch_exit(void)
-{
-#ifdef CONFIG_CPU_XSCALE
- pmu_exit();
-#endif
-}
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 2148d07484b7..38c6ad158547 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -26,6 +26,6 @@ extern struct op_arm_model_spec op_xscale_spec;
extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
-extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
-extern void pmu_exit(void);
+extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
+extern void op_arm_exit(void);
#endif /* OP_ARM_MODEL_H */
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 6cb20aea7f51..02bcc6c1cd1b 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -25,7 +25,6 @@
#include <asm/mach/map.h>
#include <asm/hardware/clock.h>
#include <asm/io.h>
-#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/arch/board.h>
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 409aac2c4b9d..fd894bb00107 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -21,7 +21,6 @@
#include <linux/err.h>
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/system.h>
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 7719a4062e3a..7ad69f14a3e7 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -59,7 +59,11 @@ void __init omap_detect_sram(void)
}
static struct map_desc omap_sram_io_desc[] __initdata = {
- { OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE }
+ { /* .length gets filled in at runtime */
+ .virtual = OMAP1_SRAM_BASE,
+ .pfn = __phys_to_pfn(OMAP1_SRAM_START),
+ .type = MT_DEVICE
+ }
};
/*
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 98f1c76f8660..14a836d7ac25 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -33,7 +33,6 @@
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 6d3a79e5fef8..ae7c64b8cec3 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -2,11 +2,17 @@
#
# This file is linux/arch/arm/tools/mach-types
#
+# Up to date versions of this file can be obtained from:
+#
+# http://www.arm.linux.org.uk/developer/machines/?action=download
+#
# Please do not send patches to this file; it is automatically generated!
# To add an entry into this database, please see Documentation/arm/README,
-# or contact rmk@arm.linux.org.uk
+# or visit:
+#
+# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Thu Jun 23 20:19:33 2005
+# Last update: Mon Oct 10 09:46:25 2005
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -421,7 +427,7 @@ mt02 MACH_MT02 MT02 410
mport3s MACH_MPORT3S MPORT3S 411
ra_alpha MACH_RA_ALPHA RA_ALPHA 412
xcep MACH_XCEP XCEP 413
-arcom_mercury MACH_ARCOM_MERCURY ARCOM_MERCURY 414
+arcom_vulcan MACH_ARCOM_VULCAN ARCOM_VULCAN 414
stargate MACH_STARGATE STARGATE 415
armadilloj MACH_ARMADILLOJ ARMADILLOJ 416
elroy_jack MACH_ELROY_JACK ELROY_JACK 417
@@ -454,7 +460,7 @@ esl_sarva MACH_ESL_SARVA ESL_SARVA 443
xm250 MACH_XM250 XM250 444
t6tc1xb MACH_T6TC1XB T6TC1XB 445
ess710 MACH_ESS710 ESS710 446
-mx3ads MACH_MX3ADS MX3ADS 447
+mx31ads MACH_MX3ADS MX3ADS 447
himalaya MACH_HIMALAYA HIMALAYA 448
bolfenk MACH_BOLFENK BOLFENK 449
at91rm9200kr MACH_AT91RM9200KR AT91RM9200KR 450
@@ -787,3 +793,79 @@ ez_ixp42x MACH_EZ_IXP42X EZ_IXP42X 778
tapwave_zodiac MACH_TAPWAVE_ZODIAC TAPWAVE_ZODIAC 779
universalmeter MACH_UNIVERSALMETER UNIVERSALMETER 780
hicoarm9 MACH_HICOARM9 HICOARM9 781
+pnx4008 MACH_PNX4008 PNX4008 782
+kws6000 MACH_KWS6000 KWS6000 783
+portux920t MACH_PORTUX920T PORTUX920T 784
+ez_x5 MACH_EZ_X5 EZ_X5 785
+omap_rudolph MACH_OMAP_RUDOLPH OMAP_RUDOLPH 786
+cpuat91 MACH_CPUAT91 CPUAT91 787
+rea9200 MACH_REA9200 REA9200 788
+acts_pune_sa1110 MACH_ACTS_PUNE_SA1110 ACTS_PUNE_SA1110 789
+ixp425 MACH_IXP425 IXP425 790
+argonplusodyssey MACH_ODYSSEY ODYSSEY 791
+perch MACH_PERCH PERCH 792
+eis05r1 MACH_EIS05R1 EIS05R1 793
+pepperpad MACH_PEPPERPAD PEPPERPAD 794
+sb3010 MACH_SB3010 SB3010 795
+rm9200 MACH_RM9200 RM9200 796
+dma03 MACH_DMA03 DMA03 797
+road_s101 MACH_ROAD_S101 ROAD_S101 798
+iq_nextgen_a MACH_IQ_NEXTGEN_A IQ_NEXTGEN_A 799
+iq_nextgen_b MACH_IQ_NEXTGEN_B IQ_NEXTGEN_B 800
+iq_nextgen_c MACH_IQ_NEXTGEN_C IQ_NEXTGEN_C 801
+iq_nextgen_d MACH_IQ_NEXTGEN_D IQ_NEXTGEN_D 802
+iq_nextgen_e MACH_IQ_NEXTGEN_E IQ_NEXTGEN_E 803
+mallow_at91 MACH_MALLOW_AT91 MALLOW_AT91 804
+cybertracker MACH_CYBERTRACKER CYBERTRACKER 805
+gesbc931x MACH_GESBC931X GESBC931X 806
+centipad MACH_CENTIPAD CENTIPAD 807
+armsoc MACH_ARMSOC ARMSOC 808
+se4200 MACH_SE4200 SE4200 809
+ems197a MACH_EMS197A EMS197A 810
+micro9 MACH_MICRO9 MICRO9 811
+micro9l MACH_MICRO9L MICRO9L 812
+uc5471dsp MACH_UC5471DSP UC5471DSP 813
+sj5471eng MACH_SJ5471ENG SJ5471ENG 814
+none MACH_CMPXA26X CMPXA26X 815
+nc MACH_NC NC 816
+omap_palmte MACH_OMAP_PALMTE OMAP_PALMTE 817
+ajax52x MACH_AJAX52X AJAX52X 818
+siriustar MACH_SIRIUSTAR SIRIUSTAR 819
+iodata_hdlg MACH_IODATA_HDLG IODATA_HDLG 820
+at91rm9200utl MACH_AT91RM9200UTL AT91RM9200UTL 821
+biosafe MACH_BIOSAFE BIOSAFE 822
+mp1000 MACH_MP1000 MP1000 823
+parsy MACH_PARSY PARSY 824
+ccxp270 MACH_CCXP CCXP 825
+omap_gsample MACH_OMAP_GSAMPLE OMAP_GSAMPLE 826
+realview_eb MACH_REALVIEW_EB REALVIEW_EB 827
+samoa MACH_SAMOA SAMOA 828
+t3xscale MACH_T3XSCALE T3XSCALE 829
+i878 MACH_I878 I878 830
+borzoi MACH_BORZOI BORZOI 831
+gecko MACH_GECKO GECKO 832
+ds101 MACH_DS101 DS101 833
+omap_palmtt2 MACH_OMAP_PALMTT2 OMAP_PALMTT2 834
+xscale_palmld MACH_XSCALE_PALMLD XSCALE_PALMLD 835
+cc9c MACH_CC9C CC9C 836
+sbc1670 MACH_SBC1670 SBC1670 837
+ixdp28x5 MACH_IXDP28X5 IXDP28X5 838
+omap_palmtt MACH_OMAP_PALMTT OMAP_PALMTT 839
+ml696k MACH_ML696K ML696K 840
+arcom_zeus MACH_ARCOM_ZEUS ARCOM_ZEUS 841
+osiris MACH_OSIRIS OSIRIS 842
+maestro MACH_MAESTRO MAESTRO 843
+tunge2 MACH_TUNGE2 TUNGE2 844
+ixbbm MACH_IXBBM IXBBM 845
+mx27 MACH_MX27 MX27 846
+ax8004 MACH_AX8004 AX8004 847
+at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848
+loft MACH_LOFT LOFT 849
+magpie MACH_MAGPIE MAGPIE 850
+mx21 MACH_MX21 MX21 851
+mb87m3400 MACH_MB87M3400 MB87M3400 852
+mguard_delta MACH_MGUARD_DELTA MGUARD_DELTA 853
+davinci_dvdp MACH_DAVINCI_DVDP DAVINCI_DVDP 854
+htcuniversal MACH_HTCUNIVERSAL HTCUNIVERSAL 855
+tpad MACH_TPAD TPAD 856
+roverp3 MACH_ROVERP3 ROVERP3 857
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index e73c8deca592..6f17187ab32a 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -17,7 +17,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
#include <asm/vfpmacros.h>
.globl do_vfp
diff --git a/arch/arm26/Makefile b/arch/arm26/Makefile
index e9cb8ef4f3fb..844a9e46886e 100644
--- a/arch/arm26/Makefile
+++ b/arch/arm26/Makefile
@@ -49,10 +49,6 @@ all: zImage
boot := arch/arm26/boot
-prepare: include/asm-$(ARCH)/asm_offsets.h
-CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h
-
-
.PHONY: maketools FORCE
maketools: FORCE
@@ -94,12 +90,6 @@ zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall
fi; \
)
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/asm_offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
define archhelp
echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
diff --git a/arch/arm26/boot/compressed/hw-bse.c b/arch/arm26/boot/compressed/hw-bse.c
deleted file mode 100644
index 3e8f07f8e08a..000000000000
--- a/arch/arm26/boot/compressed/hw-bse.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Bright Star Engineering Inc.
- *
- * code for readng parameters from the
- * parameter blocks of the boot block
- * flash memory
- *
- */
-
-static int strcmp(const char *s1, const char *s2)
-{
- while (*s1 != '\0' && *s1 == *s2)
- {
- s1++;
- s2++;
- }
-
- return (*(unsigned char *) s1) - (*(unsigned char *) s2);
-}
-
-struct pblk_t {
- char type;
- unsigned short size;
-};
-
-static char *bse_getflashparam(char *name) {
- unsigned int esize;
- char *q,*r;
- unsigned char *p,*e;
- struct pblk_t *thepb = (struct pblk_t *) 0x00004000;
- struct pblk_t *altpb = (struct pblk_t *) 0x00006000;
- if (thepb->type&1) {
- if (altpb->type&1) {
- /* no valid param block */
- return (char*)0;
- } else {
- /* altpb is valid */
- struct pblk_t *tmp;
- tmp = thepb;
- thepb = altpb;
- altpb = tmp;
- }
- }
- p = (char*)thepb + sizeof(struct pblk_t);
- e = p + thepb->size;
- while (p < e) {
- q = p;
- esize = *p;
- if (esize == 0xFF) break;
- if (esize == 0) break;
- if (esize > 127) {
- esize = (esize&0x7F)<<8 | p[1];
- q++;
- }
- q++;
- r=q;
- if (*r && ((name == 0) || (!strcmp(name,r)))) {
- while (*q++) ;
- return q;
- }
- p+=esize;
- }
- return (char*)0;
-}
-
-void bse_setup(void) {
- /* extract the linux cmdline from flash */
- char *name=bse_getflashparam("linuxboot");
- char *x = (char *)0xc0000100;
- if (name) {
- while (*name) *x++=*name++;
- }
- *x=0;
-}
diff --git a/arch/arm26/kernel/entry.S b/arch/arm26/kernel/entry.S
index a231dd88d0e1..6d910ea43d34 100644
--- a/arch/arm26/kernel/entry.S
+++ b/arch/arm26/kernel/entry.S
@@ -10,7 +10,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/errno.h>
#include <asm/hardware.h>
#include <asm/sysirq.h>
diff --git a/arch/arm26/lib/copy_page.S b/arch/arm26/lib/copy_page.S
index 2d79ee12ea1f..c7511a2739d3 100644
--- a/arch/arm26/lib/copy_page.S
+++ b/arch/arm26/lib/copy_page.S
@@ -11,7 +11,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.text
.align 5
diff --git a/arch/arm26/lib/csumpartialcopyuser.S b/arch/arm26/lib/csumpartialcopyuser.S
index 5b821188e479..261dd154c1a4 100644
--- a/arch/arm26/lib/csumpartialcopyuser.S
+++ b/arch/arm26/lib/csumpartialcopyuser.S
@@ -11,7 +11,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.text
diff --git a/arch/arm26/lib/getuser.S b/arch/arm26/lib/getuser.S
index e6d59b334851..2b1de7fbfe1f 100644
--- a/arch/arm26/lib/getuser.S
+++ b/arch/arm26/lib/getuser.S
@@ -26,7 +26,7 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000.
* Note also that it is intended that __get_user_bad is not global.
*/
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
diff --git a/arch/arm26/lib/putuser.S b/arch/arm26/lib/putuser.S
index 87588cbe46ae..46c7f15f9f2d 100644
--- a/arch/arm26/lib/putuser.S
+++ b/arch/arm26/lib/putuser.S
@@ -26,7 +26,7 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000
* Note also that it is intended that __put_user_bad is not global.
*/
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
diff --git a/arch/arm26/mm/proc-funcs.S b/arch/arm26/mm/proc-funcs.S
index c3d4cd3f457e..f9fca524c57a 100644
--- a/arch/arm26/mm/proc-funcs.S
+++ b/arch/arm26/mm/proc-funcs.S
@@ -14,7 +14,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
diff --git a/arch/arm26/nwfpe/entry.S b/arch/arm26/nwfpe/entry.S
index 7d6dfaad80c2..e6312000d9f8 100644
--- a/arch/arm26/nwfpe/entry.S
+++ b/arch/arm26/nwfpe/entry.S
@@ -20,7 +20,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
/* This is the kernel's entry point into the floating point emulator.
It is called from the kernel with code similar to this:
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
index 90ca8730b120..ea65d585cf5e 100644
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -107,8 +107,7 @@ archclean:
rm -f timage vmlinux.bin decompress.bin rescue.bin cramfs.img
rm -rf $(LD_SCRIPT).tmp
-prepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch \
- include/asm-$(ARCH)/$(SARCH)/offset.h
+archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch
# Create some links to make all tools happy
$(SRC_ARCH)/.links:
@@ -120,6 +119,7 @@ $(SRC_ARCH)/.links:
@ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
@ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
@ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
+ @ln -sfn $(SRC_ARCH)/$(SARCH)/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
@touch $@
# Create link to sub arch includes
@@ -128,9 +128,3 @@ $(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h)
@rm -f include/asm-$(ARCH)/arch
@ln -sf $(srctree)/include/asm-$(ARCH)/$(SARCH) $(srctree)/include/asm-$(ARCH)/arch
@touch $@
-
-arch/$(ARCH)/$(SARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/$(SARCH)/offset.h: arch/$(ARCH)/$(SARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
index c0163bf94a50..c808005e8457 100644
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -270,7 +270,7 @@
#include <asm/arch/sv_addr_ag.h>
#include <asm/errno.h>
#include <asm/thread_info.h>
-#include <asm/arch/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index 10329306d23c..426b09878a05 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -24,7 +24,7 @@ struct dma_coherent_mem {
};
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S
index a8ed55e5b403..3bd8503fec68 100644
--- a/arch/cris/arch-v32/kernel/entry.S
+++ b/arch/cris/arch-v32/kernel/entry.S
@@ -23,7 +23,7 @@
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/thread_info.h>
-#include <asm/arch/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/arch/hwregs/asm/reg_map_asm.h>
#include <asm/arch/hwregs/asm/intr_vect_defs_asm.h>
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 2c5cae04a95c..957f551ba5ce 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#define IPI_SCHEDULE 1
#define IPI_CALL 2
@@ -28,6 +29,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
/* CPU masks */
cpumask_t cpu_online_map = CPU_MASK_NONE;
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(phys_cpu_present_map);
/* Variables used during SMP boot */
volatile int cpu_now_booting = 0;
diff --git a/arch/frv/kernel/asm-offsets.c b/arch/frv/kernel/asm-offsets.c
new file mode 100644
index 000000000000..9e263112a6e2
--- /dev/null
+++ b/arch/frv/kernel/asm-offsets.c
@@ -0,0 +1 @@
+/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 819895cf0b9e..2082a9647f4f 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -33,7 +33,7 @@ struct dma_alloc_record {
static DEFINE_SPINLOCK(dma_alloc_lock);
static LIST_HEAD(dma_alloc_list);
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
+void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
{
struct dma_alloc_record *new;
struct list_head *this = &dma_alloc_list;
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 27eb12066507..86fbdadc51b6 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -17,7 +17,7 @@
#include <linux/highmem.h>
#include <asm/io.h>
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
+void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
index 4b38d45435f6..cfc4f97490c6 100644
--- a/arch/frv/mm/dma-alloc.c
+++ b/arch/frv/mm/dma-alloc.c
@@ -81,7 +81,7 @@ static int map_page(unsigned long va, unsigned long pa, pgprot_t prot)
* portions of the kernel with single large page TLB entries, and
* still get unique uncached pages for consistent DMA.
*/
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
{
struct vm_struct *area;
unsigned long page, va, pa;
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
index c9b80cffd71d..40b3f56f3666 100644
--- a/arch/h8300/Makefile
+++ b/arch/h8300/Makefile
@@ -61,12 +61,6 @@ archmrproper:
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-prepare: include/asm-$(ARCH)/asm-offsets.h
-
-include/asm-$(ARCH)/asm-offsets.h: arch/$(ARCH)/kernel/asm-offsets.s \
- include/asm include/linux/version.h
- $(call filechk,gen-asm-offsets)
-
vmlinux.srec vmlinux.bin: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
@@ -74,5 +68,3 @@ define archhelp
echo 'vmlinux.bin - Create raw binary'
echo 'vmlinux.srec - Create srec binary'
endef
-
-CLEAN_FILES += include/asm-$(ARCH)/asm-offsets.h
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 5d51b38bd70d..d2703cda61ea 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -908,11 +908,6 @@ config IRQBALANCE
The default yes will allow the kernel to do irq load balancing.
Saying no will keep the kernel from doing irq load balancing.
-config HAVE_DEC_LOCK
- bool
- depends on (SMP || PREEMPT) && X86_CMPXCHG
- default y
-
# turning this on wastes a bunch of space.
# Summit needs it only when NUMA is on
config BOOT_IOREMAP
@@ -1212,7 +1207,6 @@ config PCI_DIRECT
config PCI_MMCONFIG
bool
depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
- select ACPI_BOOT
default y
source "drivers/pci/pcie/Kconfig"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index bf7c9ba709f3..09951990a622 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -156,15 +156,6 @@ install: vmlinux
install kernel_install:
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
-prepare: include/asm-$(ARCH)/asm_offsets.h
-CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/asm_offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
archclean:
$(Q)$(MAKE) $(clean)=arch/i386/boot
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 0587477c99f2..92f669470142 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -97,6 +97,7 @@
#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/defconfig b/arch/i386/defconfig
index ca07b95c06b8..6a431b926019 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -131,8 +131,6 @@ CONFIG_SOFTWARE_SUSPEND=y
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SLEEP_PROC_FS=y
CONFIG_ACPI_AC=y
@@ -144,10 +142,8 @@ CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_TOSHIBA is not set
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_X86_PM_TIMER is not set
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 64682a0edacf..f10de0f2c5e6 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
obj-y += cpu/
obj-y += timers/
-obj-$(CONFIG_ACPI_BOOT) += acpi/
+obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_X86_MSR) += msr.o
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
index 5e291a20c03d..267ca48e1b6c 100644
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_ACPI_BOOT) := boot.o
+obj-y := boot.o
obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 34ee500c26e5..b66c13c0cc0f 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -27,32 +27,37 @@
#include <linux/config.h>
#include <linux/acpi.h>
#include <linux/efi.h>
-#include <linux/irq.h>
#include <linux/module.h>
#include <linux/dmi.h>
+#include <linux/irq.h>
#include <asm/pgtable.h>
#include <asm/io_apic.h>
#include <asm/apic.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/mpspec.h>
#ifdef CONFIG_X86_64
-static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { }
+static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+}
extern void __init clustered_apic_check(void);
-static inline int ioapic_setup_disabled(void) { return 0; }
+static inline int ioapic_setup_disabled(void)
+{
+ return 0;
+}
+
#include <asm/proto.h>
-#else /* X86 */
+#else /* X86 */
#ifdef CONFIG_X86_LOCAL_APIC
#include <mach_apic.h>
#include <mach_mpparse.h>
-#endif /* CONFIG_X86_LOCAL_APIC */
+#endif /* CONFIG_X86_LOCAL_APIC */
-#endif /* X86 */
+#endif /* X86 */
#define BAD_MADT_ENTRY(entry, end) ( \
(!entry) || (unsigned long)entry + sizeof(*entry) > end || \
@@ -60,13 +65,8 @@ static inline int ioapic_setup_disabled(void) { return 0; }
#define PREFIX "ACPI: "
-#ifdef CONFIG_ACPI_PCI
int acpi_noirq __initdata; /* skip ACPI IRQ initialization */
-int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
-#else
-int acpi_noirq __initdata = 1;
-int acpi_pci_disabled __initdata = 1;
-#endif
+int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
int acpi_ht __initdata = 1; /* enable HT */
int acpi_lapic;
@@ -88,7 +88,7 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
#define MAX_MADT_ENTRIES 256
u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
- { [0 ... MAX_MADT_ENTRIES-1] = 0xff };
+ {[0 ... MAX_MADT_ENTRIES - 1] = 0xff };
EXPORT_SYMBOL(x86_acpiid_to_apicid);
/* --------------------------------------------------------------------------
@@ -99,7 +99,7 @@ EXPORT_SYMBOL(x86_acpiid_to_apicid);
* The default interrupt routing model is PIC (8259). This gets
* overriden if IOAPICs are enumerated (below).
*/
-enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
#ifdef CONFIG_X86_64
@@ -107,7 +107,7 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
char *__acpi_map_table(unsigned long phys_addr, unsigned long size)
{
if (!phys_addr || !size)
- return NULL;
+ return NULL;
if (phys_addr < (end_pfn_map << PAGE_SHIFT))
return __va(phys_addr);
@@ -134,8 +134,8 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
unsigned long base, offset, mapped_size;
int idx;
- if (phys + size < 8*1024*1024)
- return __va(phys);
+ if (phys + size < 8 * 1024 * 1024)
+ return __va(phys);
offset = phys & (PAGE_SIZE - 1);
mapped_size = PAGE_SIZE - offset;
@@ -154,7 +154,7 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
mapped_size += PAGE_SIZE;
}
- return ((unsigned char *) base + offset);
+ return ((unsigned char *)base + offset);
}
#endif
@@ -172,7 +172,7 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
if (!phys_addr || !size)
return -EINVAL;
- mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size);
+ mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size);
if (!mcfg) {
printk(KERN_WARNING PREFIX "Unable to map MCFG\n");
return -ENODEV;
@@ -209,20 +209,17 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
return 0;
}
-#endif /* CONFIG_PCI_MMCONFIG */
+#endif /* CONFIG_PCI_MMCONFIG */
#ifdef CONFIG_X86_LOCAL_APIC
-static int __init
-acpi_parse_madt (
- unsigned long phys_addr,
- unsigned long size)
+static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
{
- struct acpi_table_madt *madt = NULL;
+ struct acpi_table_madt *madt = NULL;
if (!phys_addr || !size)
return -EINVAL;
- madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
+ madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
if (!madt) {
printk(KERN_WARNING PREFIX "Unable to map MADT\n");
return -ENODEV;
@@ -232,22 +229,20 @@ acpi_parse_madt (
acpi_lapic_addr = (u64) madt->lapic_address;
printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n",
- madt->lapic_address);
+ madt->lapic_address);
}
acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
-
+
return 0;
}
-
static int __init
-acpi_parse_lapic (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
{
- struct acpi_table_lapic *processor = NULL;
+ struct acpi_table_lapic *processor = NULL;
- processor = (struct acpi_table_lapic*) header;
+ processor = (struct acpi_table_lapic *)header;
if (BAD_MADT_ENTRY(processor, end))
return -EINVAL;
@@ -260,20 +255,19 @@ acpi_parse_lapic (
x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
- mp_register_lapic (
- processor->id, /* APIC ID */
- processor->flags.enabled); /* Enabled? */
+ mp_register_lapic(processor->id, /* APIC ID */
+ processor->flags.enabled); /* Enabled? */
return 0;
}
static int __init
-acpi_parse_lapic_addr_ovr (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
- lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
+ lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header;
if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
return -EINVAL;
@@ -284,12 +278,11 @@ acpi_parse_lapic_addr_ovr (
}
static int __init
-acpi_parse_lapic_nmi (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_lapic_nmi *lapic_nmi = NULL;
- lapic_nmi = (struct acpi_table_lapic_nmi*) header;
+ lapic_nmi = (struct acpi_table_lapic_nmi *)header;
if (BAD_MADT_ENTRY(lapic_nmi, end))
return -EINVAL;
@@ -302,37 +295,32 @@ acpi_parse_lapic_nmi (
return 0;
}
+#endif /*CONFIG_X86_LOCAL_APIC */
-#endif /*CONFIG_X86_LOCAL_APIC*/
-
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+#ifdef CONFIG_X86_IO_APIC
static int __init
-acpi_parse_ioapic (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_ioapic *ioapic = NULL;
- ioapic = (struct acpi_table_ioapic*) header;
+ ioapic = (struct acpi_table_ioapic *)header;
if (BAD_MADT_ENTRY(ioapic, end))
return -EINVAL;
-
+
acpi_table_print_madt_entry(header);
- mp_register_ioapic (
- ioapic->id,
- ioapic->address,
- ioapic->global_irq_base);
-
+ mp_register_ioapic(ioapic->id,
+ ioapic->address, ioapic->global_irq_base);
+
return 0;
}
/*
* Parse Interrupt Source Override for the ACPI SCI
*/
-static void
-acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
{
if (trigger == 0) /* compatible SCI trigger is level */
trigger = 3;
@@ -348,7 +336,7 @@ acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
polarity = acpi_sci_flags.polarity;
/*
- * mp_config_acpi_legacy_irqs() already setup IRQs < 16
+ * mp_config_acpi_legacy_irqs() already setup IRQs < 16
* If GSI is < 16, this will update its flags,
* else it will create a new mp_irqs[] entry.
*/
@@ -363,12 +351,12 @@ acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
}
static int __init
-acpi_parse_int_src_ovr (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_int_src_ovr(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_int_src_ovr *intsrc = NULL;
- intsrc = (struct acpi_table_int_src_ovr*) header;
+ intsrc = (struct acpi_table_int_src_ovr *)header;
if (BAD_MADT_ENTRY(intsrc, end))
return -EINVAL;
@@ -377,33 +365,30 @@ acpi_parse_int_src_ovr (
if (intsrc->bus_irq == acpi_fadt.sci_int) {
acpi_sci_ioapic_setup(intsrc->global_irq,
- intsrc->flags.polarity, intsrc->flags.trigger);
+ intsrc->flags.polarity,
+ intsrc->flags.trigger);
return 0;
}
if (acpi_skip_timer_override &&
- intsrc->bus_irq == 0 && intsrc->global_irq == 2) {
- printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
- return 0;
+ intsrc->bus_irq == 0 && intsrc->global_irq == 2) {
+ printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
+ return 0;
}
- mp_override_legacy_irq (
- intsrc->bus_irq,
- intsrc->flags.polarity,
- intsrc->flags.trigger,
- intsrc->global_irq);
+ mp_override_legacy_irq(intsrc->bus_irq,
+ intsrc->flags.polarity,
+ intsrc->flags.trigger, intsrc->global_irq);
return 0;
}
-
static int __init
-acpi_parse_nmi_src (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_nmi_src *nmi_src = NULL;
- nmi_src = (struct acpi_table_nmi_src*) header;
+ nmi_src = (struct acpi_table_nmi_src *)header;
if (BAD_MADT_ENTRY(nmi_src, end))
return -EINVAL;
@@ -415,9 +400,7 @@ acpi_parse_nmi_src (
return 0;
}
-#endif /* CONFIG_X86_IO_APIC */
-
-#ifdef CONFIG_ACPI_BUS
+#endif /* CONFIG_X86_IO_APIC */
/*
* acpi_pic_sci_set_trigger()
@@ -433,8 +416,7 @@ acpi_parse_nmi_src (
* ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
*/
-void __init
-acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
+void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
{
unsigned int mask = 1 << irq;
unsigned int old, new;
@@ -454,10 +436,10 @@ acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
* routing tables..
*/
switch (trigger) {
- case 1: /* Edge - clear */
+ case 1: /* Edge - clear */
new &= ~mask;
break;
- case 3: /* Level - set */
+ case 3: /* Level - set */
new |= mask;
break;
}
@@ -470,21 +452,22 @@ acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
outb(new >> 8, 0x4d1);
}
-
-#endif /* CONFIG_ACPI_BUS */
-
int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
{
#ifdef CONFIG_X86_IO_APIC
if (use_pci_vector() && !platform_legacy_irq(gsi))
- *irq = IO_APIC_VECTOR(gsi);
+ *irq = IO_APIC_VECTOR(gsi);
else
#endif
*irq = gsi;
return 0;
}
-unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
+/*
+ * success: return IRQ number (>=0)
+ * failure: return < 0
+ */
+int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
{
unsigned int irq;
unsigned int plat_gsi = gsi;
@@ -497,7 +480,7 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
extern void eisa_set_level_irq(unsigned int irq);
if (edge_level == ACPI_LEVEL_SENSITIVE)
- eisa_set_level_irq(gsi);
+ eisa_set_level_irq(gsi);
}
#endif
@@ -509,60 +492,58 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
acpi_gsi_to_irq(plat_gsi, &irq);
return irq;
}
+
EXPORT_SYMBOL(acpi_register_gsi);
/*
* ACPI based hotplug support for CPU
*/
#ifdef CONFIG_ACPI_HOTPLUG_CPU
-int
-acpi_map_lsapic(acpi_handle handle, int *pcpu)
+int acpi_map_lsapic(acpi_handle handle, int *pcpu)
{
/* TBD */
return -EINVAL;
}
-EXPORT_SYMBOL(acpi_map_lsapic);
+EXPORT_SYMBOL(acpi_map_lsapic);
-int
-acpi_unmap_lsapic(int cpu)
+int acpi_unmap_lsapic(int cpu)
{
/* TBD */
return -EINVAL;
}
+
EXPORT_SYMBOL(acpi_unmap_lsapic);
-#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
-int
-acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
+int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
{
/* TBD */
return -EINVAL;
}
+
EXPORT_SYMBOL(acpi_register_ioapic);
-int
-acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
+int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
{
/* TBD */
return -EINVAL;
}
+
EXPORT_SYMBOL(acpi_unregister_ioapic);
static unsigned long __init
-acpi_scan_rsdp (
- unsigned long start,
- unsigned long length)
+acpi_scan_rsdp(unsigned long start, unsigned long length)
{
- unsigned long offset = 0;
- unsigned long sig_len = sizeof("RSD PTR ") - 1;
+ unsigned long offset = 0;
+ unsigned long sig_len = sizeof("RSD PTR ") - 1;
/*
* Scan all 16-byte boundaries of the physical memory region for the
* RSDP signature.
*/
for (offset = 0; offset < length; offset += 16) {
- if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
+ if (strncmp((char *)(start + offset), "RSD PTR ", sig_len))
continue;
return (start + offset);
}
@@ -575,20 +556,19 @@ static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size)
struct acpi_table_sbf *sb;
if (!phys_addr || !size)
- return -EINVAL;
+ return -EINVAL;
- sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size);
+ sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size);
if (!sb) {
printk(KERN_WARNING PREFIX "Unable to map SBF\n");
return -ENODEV;
}
- sbf_port = sb->sbf_cmos; /* Save CMOS port */
+ sbf_port = sb->sbf_cmos; /* Save CMOS port */
return 0;
}
-
#ifdef CONFIG_HPET_TIMER
static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
@@ -598,7 +578,7 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
if (!phys || !size)
return -EINVAL;
- hpet_tbl = (struct acpi_table_hpet *) __acpi_map_table(phys, size);
+ hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size);
if (!hpet_tbl) {
printk(KERN_WARNING PREFIX "Unable to map HPET\n");
return -ENODEV;
@@ -609,22 +589,21 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
"memory.\n");
return -1;
}
-
#ifdef CONFIG_X86_64
- vxtime.hpet_address = hpet_tbl->addr.addrl |
- ((long) hpet_tbl->addr.addrh << 32);
+ vxtime.hpet_address = hpet_tbl->addr.addrl |
+ ((long)hpet_tbl->addr.addrh << 32);
- printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
- hpet_tbl->id, vxtime.hpet_address);
-#else /* X86 */
+ printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
+ hpet_tbl->id, vxtime.hpet_address);
+#else /* X86 */
{
extern unsigned long hpet_address;
hpet_address = hpet_tbl->addr.addrl;
printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
- hpet_tbl->id, hpet_address);
+ hpet_tbl->id, hpet_address);
}
-#endif /* X86 */
+#endif /* X86 */
return 0;
}
@@ -640,28 +619,25 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
{
struct fadt_descriptor_rev2 *fadt = NULL;
- fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size);
- if(!fadt) {
+ fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size);
+ if (!fadt) {
printk(KERN_WARNING PREFIX "Unable to map FADT\n");
return 0;
}
-
-#ifdef CONFIG_ACPI_INTERPRETER
/* initialize sci_int early for INT_SRC_OVR MADT parsing */
acpi_fadt.sci_int = fadt->sci_int;
-#endif
-#ifdef CONFIG_ACPI_BUS
/* initialize rev and apic_phys_dest_mode for x86_64 genapic */
acpi_fadt.revision = fadt->revision;
- acpi_fadt.force_apic_physical_destination_mode = fadt->force_apic_physical_destination_mode;
-#endif
+ acpi_fadt.force_apic_physical_destination_mode =
+ fadt->force_apic_physical_destination_mode;
#ifdef CONFIG_X86_PM_TIMER
/* detect the location of the ACPI PM Timer */
if (fadt->revision >= FADT2_REVISION_ID) {
/* FADT rev. 2 */
- if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO)
+ if (fadt->xpm_tmr_blk.address_space_id !=
+ ACPI_ADR_SPACE_SYSTEM_IO)
return 0;
pmtmr_ioport = fadt->xpm_tmr_blk.address;
@@ -670,16 +646,15 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
pmtmr_ioport = fadt->V1_pm_tmr_blk;
}
if (pmtmr_ioport)
- printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport);
+ printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n",
+ pmtmr_ioport);
#endif
return 0;
}
-
-unsigned long __init
-acpi_find_rsdp (void)
+unsigned long __init acpi_find_rsdp(void)
{
- unsigned long rsdp_phys = 0;
+ unsigned long rsdp_phys = 0;
if (efi_enabled) {
if (efi.acpi20)
@@ -691,9 +666,9 @@ acpi_find_rsdp (void)
* Scan memory looking for the RSDP signature. First search EBDA (low
* memory) paragraphs and then search upper memory (E0000-FFFFF).
*/
- rsdp_phys = acpi_scan_rsdp (0, 0x400);
+ rsdp_phys = acpi_scan_rsdp(0, 0x400);
if (!rsdp_phys)
- rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000);
+ rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000);
return rsdp_phys;
}
@@ -703,8 +678,7 @@ acpi_find_rsdp (void)
* Parse LAPIC entries in MADT
* returns 0 on success, < 0 on error
*/
-static int __init
-acpi_parse_madt_lapic_entries(void)
+static int __init acpi_parse_madt_lapic_entries(void)
{
int count;
@@ -713,28 +687,31 @@ acpi_parse_madt_lapic_entries(void)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
*/
- count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
+ count =
+ acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
+ acpi_parse_lapic_addr_ovr, 0);
if (count < 0) {
- printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
+ printk(KERN_ERR PREFIX
+ "Error parsing LAPIC address override entry\n");
return count;
}
mp_register_lapic_address(acpi_lapic_addr);
count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
- MAX_APICS);
- if (!count) {
+ MAX_APICS);
+ if (!count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
/* TBD: Cleanup to allow fallback to MPS */
return -ENODEV;
- }
- else if (count < 0) {
+ } else if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
}
- count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
+ count =
+ acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
@@ -742,15 +719,14 @@ acpi_parse_madt_lapic_entries(void)
}
return 0;
}
-#endif /* CONFIG_X86_LOCAL_APIC */
+#endif /* CONFIG_X86_LOCAL_APIC */
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+#ifdef CONFIG_X86_IO_APIC
/*
* Parse IOAPIC related entries in MADT
* returns 0 on success, < 0 on error
*/
-static int __init
-acpi_parse_madt_ioapic_entries(void)
+static int __init acpi_parse_madt_ioapic_entries(void)
{
int count;
@@ -762,30 +738,34 @@ acpi_parse_madt_ioapic_entries(void)
*/
if (acpi_disabled || acpi_noirq) {
return -ENODEV;
- }
+ }
/*
- * if "noapic" boot option, don't look for IO-APICs
+ * if "noapic" boot option, don't look for IO-APICs
*/
if (skip_ioapic_setup) {
printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
- "due to 'noapic' option.\n");
+ "due to 'noapic' option.\n");
return -ENODEV;
}
- count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
+ count =
+ acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic,
+ MAX_IO_APICS);
if (!count) {
printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
return -ENODEV;
- }
- else if (count < 0) {
+ } else if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
return count;
}
- count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
+ count =
+ acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr,
+ NR_IRQ_VECTORS);
if (count < 0) {
- printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
+ printk(KERN_ERR PREFIX
+ "Error parsing interrupt source overrides entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
}
@@ -800,7 +780,9 @@ acpi_parse_madt_ioapic_entries(void)
/* Fill in identity legacy mapings where no override */
mp_config_acpi_legacy_irqs();
- count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS);
+ count =
+ acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
+ NR_IRQ_VECTORS);
if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
@@ -814,11 +796,9 @@ static inline int acpi_parse_madt_ioapic_entries(void)
{
return -1;
}
-#endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */
+#endif /* !CONFIG_X86_IO_APIC */
-
-static void __init
-acpi_process_madt(void)
+static void __init acpi_process_madt(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
int count, error;
@@ -853,7 +833,8 @@ acpi_process_madt(void)
/*
* Dell Precision Workstation 410, 610 come here.
*/
- printk(KERN_ERR PREFIX "Invalid BIOS MADT, disabling ACPI\n");
+ printk(KERN_ERR PREFIX
+ "Invalid BIOS MADT, disabling ACPI\n");
disable_acpi();
}
}
@@ -865,7 +846,6 @@ extern int acpi_force;
#ifdef __i386__
-#ifdef CONFIG_ACPI_PCI
static int __init disable_acpi_irq(struct dmi_system_id *d)
{
if (!acpi_force) {
@@ -885,12 +865,11 @@ static int __init disable_acpi_pci(struct dmi_system_id *d)
}
return 0;
}
-#endif
static int __init dmi_disable_acpi(struct dmi_system_id *d)
{
if (!acpi_force) {
- printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
+ printk(KERN_NOTICE "%s detected: acpi off\n", d->ident);
disable_acpi();
} else {
printk(KERN_NOTICE
@@ -905,7 +884,8 @@ static int __init dmi_disable_acpi(struct dmi_system_id *d)
static int __init force_acpi_ht(struct dmi_system_id *d)
{
if (!acpi_force) {
- printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
+ printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
+ d->ident);
disable_acpi();
acpi_ht = 1;
} else {
@@ -924,155 +904,155 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
* Boxes that need ACPI disabled
*/
{
- .callback = dmi_disable_acpi,
- .ident = "IBM Thinkpad",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
- },
- },
+ .callback = dmi_disable_acpi,
+ .ident = "IBM Thinkpad",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+ DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
+ },
+ },
/*
* Boxes that need acpi=ht
*/
{
- .callback = force_acpi_ht,
- .ident = "FSC Primergy T850",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "FSC Primergy T850",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "DELL GX240",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
- DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "DELL GX240",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
+ DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "HP VISUALIZE NT Workstation",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "HP VISUALIZE NT Workstation",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "Compaq Workstation W8000",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "Compaq Workstation W8000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "ASUS P4B266",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "ASUS P4B266",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "ASUS P2B-DS",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "ASUS P2B-DS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "ASUS CUR-DLS",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "ASUS CUR-DLS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "ABIT i440BX-W83977",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
- DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "ABIT i440BX-W83977",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+ DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "IBM Bladecenter",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "IBM Bladecenter",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+ DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "IBM eServer xSeries 360",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "IBM eServer xSeries 360",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+ DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "IBM eserver xSeries 330",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
- },
- },
+ .callback = force_acpi_ht,
+ .ident = "IBM eserver xSeries 330",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+ DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
+ },
+ },
{
- .callback = force_acpi_ht,
- .ident = "IBM eserver xSeries 440",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
- },
- },
-
-#ifdef CONFIG_ACPI_PCI
+ .callback = force_acpi_ht,
+ .ident = "IBM eserver xSeries 440",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
+ },
+ },
+
/*
* Boxes that need ACPI PCI IRQ routing disabled
*/
{
- .callback = disable_acpi_irq,
- .ident = "ASUS A7V",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
- DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
- /* newer BIOS, Revision 1011, does work */
- DMI_MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
- },
- },
+ .callback = disable_acpi_irq,
+ .ident = "ASUS A7V",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+ DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
+ /* newer BIOS, Revision 1011, does work */
+ DMI_MATCH(DMI_BIOS_VERSION,
+ "ASUS A7V ACPI BIOS Revision 1007"),
+ },
+ },
/*
* Boxes that need ACPI PCI IRQ routing and PCI scan disabled
*/
- { /* _BBN 0 bug */
- .callback = disable_acpi_pci,
- .ident = "ASUS PR-DLS",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
- DMI_MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
- DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
- },
- },
+ { /* _BBN 0 bug */
+ .callback = disable_acpi_pci,
+ .ident = "ASUS PR-DLS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
+ DMI_MATCH(DMI_BIOS_VERSION,
+ "ASUS PR-DLS ACPI BIOS Revision 1010"),
+ DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
+ },
+ },
{
- .callback = disable_acpi_pci,
- .ident = "Acer TravelMate 36x Laptop",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
- DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
- },
- },
-#endif
- { }
+ .callback = disable_acpi_pci,
+ .ident = "Acer TravelMate 36x Laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+ },
+ },
+ {}
};
-#endif /* __i386__ */
+#endif /* __i386__ */
/*
* acpi_boot_table_init() and acpi_boot_init()
@@ -1097,8 +1077,7 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
* !0: failure
*/
-int __init
-acpi_boot_table_init(void)
+int __init acpi_boot_table_init(void)
{
int error;
@@ -1111,7 +1090,7 @@ acpi_boot_table_init(void)
* One exception: acpi=ht continues far enough to enumerate LAPICs
*/
if (acpi_disabled && !acpi_ht)
- return 1;
+ return 1;
/*
* Initialize the ACPI boot-time table parser.
@@ -1121,7 +1100,6 @@ acpi_boot_table_init(void)
disable_acpi();
return error;
}
-
#ifdef __i386__
check_acpi_pci();
#endif
@@ -1145,7 +1123,6 @@ acpi_boot_table_init(void)
return 0;
}
-
int __init acpi_boot_init(void)
{
/*
@@ -1153,7 +1130,7 @@ int __init acpi_boot_init(void)
* One exception: acpi=ht continues far enough to enumerate LAPICs
*/
if (acpi_disabled && !acpi_ht)
- return 1;
+ return 1;
acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
@@ -1171,4 +1148,3 @@ int __init acpi_boot_init(void)
return 0;
}
-
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index 726a5ca4b165..f1b9d2a46dab 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -8,44 +8,44 @@
#include <asm/pci-direct.h>
#include <asm/acpi.h>
-static int __init check_bridge(int vendor, int device)
+static int __init check_bridge(int vendor, int device)
{
/* According to Nvidia all timer overrides are bogus. Just ignore
them all. */
- if (vendor == PCI_VENDOR_ID_NVIDIA) {
- acpi_skip_timer_override = 1;
+ if (vendor == PCI_VENDOR_ID_NVIDIA) {
+ acpi_skip_timer_override = 1;
}
return 0;
}
-
-void __init check_acpi_pci(void)
-{
- int num,slot,func;
+
+void __init check_acpi_pci(void)
+{
+ int num, slot, func;
/* Assume the machine supports type 1. If not it will
always read ffffffff and should not have any side effect. */
/* Poor man's PCI discovery */
- for (num = 0; num < 32; num++) {
- for (slot = 0; slot < 32; slot++) {
- for (func = 0; func < 8; func++) {
+ for (num = 0; num < 32; num++) {
+ for (slot = 0; slot < 32; slot++) {
+ for (func = 0; func < 8; func++) {
u32 class;
u32 vendor;
- class = read_pci_config(num,slot,func,
+ class = read_pci_config(num, slot, func,
PCI_CLASS_REVISION);
if (class == 0xffffffff)
- break;
+ break;
if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
- continue;
-
- vendor = read_pci_config(num, slot, func,
+ continue;
+
+ vendor = read_pci_config(num, slot, func,
PCI_VENDOR_ID);
-
- if (check_bridge(vendor&0xffff, vendor >> 16))
- return;
- }
-
+
+ if (check_bridge(vendor & 0xffff, vendor >> 16))
+ return;
+ }
+
}
}
}
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
index c1af93032ff3..1cb2b186a3af 100644
--- a/arch/i386/kernel/acpi/sleep.c
+++ b/arch/i386/kernel/acpi/sleep.c
@@ -20,12 +20,13 @@ extern void zap_low_mappings(void);
extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
-static void init_low_mapping(pgd_t *pgd, int pgd_limit)
+static void init_low_mapping(pgd_t * pgd, int pgd_limit)
{
int pgd_ofs = 0;
- while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
- set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD));
+ while ((pgd_ofs < pgd_limit)
+ && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
+ set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
pgd_ofs++, pgd++;
}
flush_tlb_all();
@@ -37,12 +38,13 @@ static void init_low_mapping(pgd_t *pgd, int pgd_limit)
* Create an identity mapped page table and copy the wakeup routine to
* low memory.
*/
-int acpi_save_state_mem (void)
+int acpi_save_state_mem(void)
{
if (!acpi_wakeup_address)
return 1;
init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
- memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
+ memcpy((void *)acpi_wakeup_address, &wakeup_start,
+ &wakeup_end - &wakeup_start);
acpi_copy_wakeup_routine(acpi_wakeup_address);
return 0;
@@ -51,7 +53,7 @@ int acpi_save_state_mem (void)
/*
* acpi_restore_state - undo effects of acpi_save_state_mem
*/
-void acpi_restore_state_mem (void)
+void acpi_restore_state_mem(void)
{
zap_low_mappings();
}
@@ -67,7 +69,8 @@ void acpi_restore_state_mem (void)
void __init acpi_reserve_bootmem(void)
{
if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) {
- printk(KERN_ERR "ACPI: Wakeup code way too big, S3 disabled.\n");
+ printk(KERN_ERR
+ "ACPI: Wakeup code way too big, S3 disabled.\n");
return;
}
@@ -90,10 +93,8 @@ static int __init acpi_sleep_setup(char *str)
return 1;
}
-
__setup("acpi_sleep=", acpi_sleep_setup);
-
static __init int reset_videomode_after_s3(struct dmi_system_id *d)
{
acpi_video_flags |= 2;
@@ -101,14 +102,14 @@ static __init int reset_videomode_after_s3(struct dmi_system_id *d)
}
static __initdata struct dmi_system_id acpisleep_dmi_table[] = {
- { /* Reset video mode after returning from ACPI S3 sleep */
- .callback = reset_videomode_after_s3,
- .ident = "Toshiba Satellite 4030cdt",
- .matches = {
- DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
- },
- },
- { }
+ { /* Reset video mode after returning from ACPI S3 sleep */
+ .callback = reset_videomode_after_s3,
+ .ident = "Toshiba Satellite 4030cdt",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+ },
+ },
+ {}
};
static int __init acpisleep_dmi_init(void)
diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
index 44d886c745ec..7c74fe0dc93c 100644
--- a/arch/i386/kernel/acpi/wakeup.S
+++ b/arch/i386/kernel/acpi/wakeup.S
@@ -304,12 +304,6 @@ ret_point:
call restore_processor_state
ret
-ENTRY(do_suspend_lowlevel_s4bios)
- call save_processor_state
- call save_registers
- call acpi_enter_sleep_state_s4bios
- ret
-
ALIGN
# saved registers
saved_gdt: .long 0,0
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index a22a866de8f9..5546ddebec33 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 73aeaf5a9d4e..53a1681cd964 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -28,6 +28,22 @@ static void __init init_amd(struct cpuinfo_x86 *c)
int mbytes = num_physpages >> (20-PAGE_SHIFT);
int r;
+#ifdef CONFIG_SMP
+ unsigned long long value;
+
+ /* Disable TLB flush filter by setting HWCR.FFDIS on K8
+ * bit 6 of msr C001_0015
+ *
+ * Errata 63 for SH-B3 steppings
+ * Errata 122 for all steppings (F+ have it disabled by default)
+ */
+ if (c->x86 == 15) {
+ rdmsrl(MSR_K7_HWCR, value);
+ value |= 1 << 6;
+ wrmsrl(MSR_K7_HWCR, value);
+ }
+#endif
+
/*
* FIXME: We should handle the K5 here. Set up the write
* range and also turn on MSR 83 bits 4 and 31 (write alloc,
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 46ce9b248f55..9ad43be9a01f 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -151,7 +151,7 @@ static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
}
-void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
+static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
{
char *v = c->x86_vendor_id;
int i;
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 60a9e54dd20e..822c8ce9d1f1 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -31,6 +31,7 @@
#include <linux/cpufreq.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/compiler.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
@@ -57,6 +58,8 @@ static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS];
static struct cpufreq_driver acpi_cpufreq_driver;
+static unsigned int acpi_pstate_strict;
+
static int
acpi_processor_write_port(
u16 port,
@@ -163,34 +166,44 @@ acpi_processor_set_performance (
}
/*
- * Then we read the 'status_register' and compare the value with the
- * target state's 'status' to make sure the transition was successful.
- * Note that we'll poll for up to 1ms (100 cycles of 10us) before
- * giving up.
+ * Assume the write went through when acpi_pstate_strict is not used.
+ * As read status_register is an expensive operation and there
+ * are no specific error cases where an IO port write will fail.
*/
-
- port = data->acpi_data.status_register.address;
- bit_width = data->acpi_data.status_register.bit_width;
-
- dprintk("Looking for 0x%08x from port 0x%04x\n",
- (u32) data->acpi_data.states[state].status, port);
-
- for (i=0; i<100; i++) {
- ret = acpi_processor_read_port(port, bit_width, &value);
- if (ret) {
- dprintk("Invalid port width 0x%04x\n", bit_width);
- retval = ret;
- goto migrate_end;
+ if (acpi_pstate_strict) {
+ /* Then we read the 'status_register' and compare the value
+ * with the target state's 'status' to make sure the
+ * transition was successful.
+ * Note that we'll poll for up to 1ms (100 cycles of 10us)
+ * before giving up.
+ */
+
+ port = data->acpi_data.status_register.address;
+ bit_width = data->acpi_data.status_register.bit_width;
+
+ dprintk("Looking for 0x%08x from port 0x%04x\n",
+ (u32) data->acpi_data.states[state].status, port);
+
+ for (i=0; i<100; i++) {
+ ret = acpi_processor_read_port(port, bit_width, &value);
+ if (ret) {
+ dprintk("Invalid port width 0x%04x\n", bit_width);
+ retval = ret;
+ goto migrate_end;
+ }
+ if (value == (u32) data->acpi_data.states[state].status)
+ break;
+ udelay(10);
}
- if (value == (u32) data->acpi_data.states[state].status)
- break;
- udelay(10);
+ } else {
+ i = 0;
+ value = (u32) data->acpi_data.states[state].status;
}
/* notify cpufreq */
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
- if (value != (u32) data->acpi_data.states[state].status) {
+ if (unlikely(value != (u32) data->acpi_data.states[state].status)) {
unsigned int tmp = cpufreq_freqs.new;
cpufreq_freqs.new = cpufreq_freqs.old;
cpufreq_freqs.old = tmp;
@@ -537,6 +550,8 @@ acpi_cpufreq_exit (void)
return;
}
+module_param(acpi_pstate_strict, uint, 0644);
+MODULE_PARM_DESC(acpi_pstate_strict, "value 0 or non-zero. non-zero -> strict ACPI checks are performed during frequency changes.");
late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit);
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index bf02b5026e62..8ef38544453c 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -467,11 +467,11 @@ static void __init longhaul_setup_voltagescaling(void)
}
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/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index ab6e0611303d..58ca98fdc2ca 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -44,7 +44,7 @@
#define PFX "powernow-k8: "
#define BFX PFX "BIOS error: "
-#define VERSION "version 1.50.3"
+#define VERSION "version 1.50.4"
#include "powernow-k8.h"
/* serialize freq changes */
@@ -111,8 +111,8 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
u32 i = 0;
do {
- if (i++ > 0x1000000) {
- printk(KERN_ERR PFX "detected change pending stuck\n");
+ if (i++ > 10000) {
+ dprintk("detected change pending stuck\n");
return 1;
}
rdmsr(MSR_FIDVID_STATUS, lo, hi);
@@ -159,6 +159,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
{
u32 lo;
u32 savevid = data->currvid;
+ u32 i = 0;
if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) {
printk(KERN_ERR PFX "internal error - overflow on fid write\n");
@@ -170,10 +171,13 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
fid, lo, data->plllock * PLL_LOCK_CONVERSION);
- wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
-
- if (query_current_values_with_pending_wait(data))
- return 1;
+ do {
+ wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
+ if (i++ > 100) {
+ printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+ return 1;
+ }
+ } while (query_current_values_with_pending_wait(data));
count_off_irt(data);
@@ -197,6 +201,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
{
u32 lo;
u32 savefid = data->currfid;
+ int i = 0;
if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) {
printk(KERN_ERR PFX "internal error - overflow on vid write\n");
@@ -208,10 +213,13 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
vid, lo, STOP_GRANT_5NS);
- wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
-
- if (query_current_values_with_pending_wait(data))
- return 1;
+ do {
+ wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
+ if (i++ > 100) {
+ printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+ return 1;
+ }
+ } while (query_current_values_with_pending_wait(data));
if (savefid != data->currfid) {
printk(KERN_ERR PFX "fid changed on vid trans, old 0x%x new 0x%x\n",
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 327a55d4d1c6..c397b6220430 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -259,7 +259,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
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 b25fb6b635ae..2718fb6f6aba 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -99,7 +99,7 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
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/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c
index c4abe7657397..7c6b9c73522f 100644
--- a/arch/i386/kernel/cpu/mcheck/k7.c
+++ b/arch/i386/kernel/cpu/mcheck/k7.c
@@ -7,7 +7,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/config.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c
index 7864ddfccf07..82dffe0d4954 100644
--- a/arch/i386/kernel/cpu/mcheck/non-fatal.c
+++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/config.h>
-#include <linux/irq.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index 0abccb6fdf9e..1d1e885f500a 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -6,7 +6,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/config.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c
index ec0614cd2925..3a2e24baddc7 100644
--- a/arch/i386/kernel/cpu/mcheck/p5.c
+++ b/arch/i386/kernel/cpu/mcheck/p5.c
@@ -6,7 +6,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
index f01b73f947e1..3c035b8fa3d9 100644
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -6,7 +6,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c
index 7bae68fa168f..5b9d2dd411d3 100644
--- a/arch/i386/kernel/cpu/mcheck/winchip.c
+++ b/arch/i386/kernel/cpu/mcheck/winchip.c
@@ -6,7 +6,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/processor.h>
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 913be77bb844..0248e084017c 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -11,10 +11,8 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/smp.h>
-#include <linux/irq.h>
#include <linux/reboot.h>
#include <linux/kexec.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 3aad03839660..9e24f7b207ee 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -319,7 +319,7 @@ work_notifysig: # deal with pending signals and
# vm86-space
xorl %edx, %edx
call do_notify_resume
- jmp restore_all
+ jmp resume_userspace
ALIGN
work_notifysig_v86:
@@ -329,7 +329,7 @@ work_notifysig_v86:
movl %eax, %esp
xorl %edx, %edx
call do_notify_resume
- jmp restore_all
+ jmp resume_userspace
# perform syscall exit tracing
ALIGN
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 0480ca9e9e57..e437fb367498 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -17,7 +17,7 @@
#include <asm/desc.h>
#include <asm/cache.h>
#include <asm/thread_info.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/setup.h>
/*
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 178f4e9bac9d..323ef8ab3244 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -16,7 +16,6 @@
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/timer.h>
#include <asm/pgtable.h>
#include <asm/delay.h>
@@ -25,8 +24,6 @@
#include <asm/arch_hooks.h>
#include <asm/i8259.h>
-#include <linux/irq.h>
-
#include <io_ports.h>
/*
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 0e727e6da5c9..fb3991e8229e 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -21,7 +21,6 @@
*/
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -60,6 +59,8 @@ int sis_apic_bug = -1;
*/
int nr_ioapic_registers[MAX_IO_APICS];
+int disable_timer_pin_1 __initdata;
+
/*
* Rough estimation of how many shared IRQs there are, can
* be changed anytime.
@@ -573,8 +574,7 @@ static int balanced_irq(void *unused)
}
for ( ; ; ) {
- set_current_state(TASK_INTERRUPTIBLE);
- time_remaining = schedule_timeout(time_remaining);
+ time_remaining = schedule_timeout_interruptible(time_remaining);
try_to_freeze();
if (time_after(jiffies,
prev_balance_time+balanced_irq_interval)) {
@@ -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) {
@@ -2212,6 +2212,8 @@ static inline void check_timer(void)
setup_nmi();
enable_8259A_irq(0);
}
+ if (disable_timer_pin_1 > 0)
+ clear_IO_APIC_pin(0, pin1);
return;
}
clear_IO_APIC_pin(0, pin1);
@@ -2423,7 +2425,7 @@ device_initcall(ioapic_init_sysfs);
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
int __init io_apic_get_unique_id (int ioapic, int apic_id)
{
@@ -2577,4 +2579,4 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
return 0;
}
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /* CONFIG_ACPI */
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 5d0b9a8fc43d..27aabfceb67e 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -14,7 +14,6 @@
*/
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/delay.h>
@@ -122,8 +121,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 +180,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 +193,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;
@@ -668,8 +663,6 @@ void __init get_smp_config (void)
struct intel_mp_floating *mpf = mpf_found;
/*
- * ACPI may be used to obtain the entire SMP configuration or just to
- * enumerate/configure processors (CONFIG_ACPI_BOOT). Note that
* ACPI supports both logical (e.g. Hyper-Threading) and physical
* processors, where MPS only supports physical.
*/
@@ -825,7 +818,7 @@ void __init find_smp_config (void)
ACPI-based MP Configuration
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
void __init mp_register_lapic_address (
u64 address)
@@ -871,7 +864,7 @@ void __init mp_register_lapic (
MP_processor_info(&processor);
}
-#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT))
+#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0
#define MP_MAX_IOAPIC_PIN 127
@@ -1086,11 +1079,9 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
*/
static int gsi_to_irq[MAX_GSI_NUM];
-#ifdef CONFIG_ACPI_BUS
/* Don't set up the ACPI SCI because it's already set up */
if (acpi_fadt.sci_int == gsi)
return gsi;
-#endif
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0) {
@@ -1133,13 +1124,11 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
if (gsi < MAX_GSI_NUM) {
if (gsi > 15)
gsi = pci_irq++;
-#ifdef CONFIG_ACPI_BUS
/*
* Don't assign IRQ used by ACPI SCI
*/
if (gsi == acpi_fadt.sci_int)
gsi = pci_irq++;
-#endif
gsi_to_irq[irq] = gsi;
} else {
printk(KERN_ERR "GSI %u is too high\n", gsi);
@@ -1153,5 +1142,5 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
return gsi;
}
-#endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /* CONFIG_X86_IO_APIC */
+#endif /* CONFIG_ACPI */
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 0178457db721..72515b8a1b12 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -15,7 +15,6 @@
#include <linux/config.h>
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
index 1e51427cc9eb..25fe66853934 100644
--- a/arch/i386/kernel/pci-dma.c
+++ b/arch/i386/kernel/pci-dma.c
@@ -23,7 +23,7 @@ struct dma_coherent_mem {
};
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index b45cbf93d439..7a14fdfd3af9 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -47,13 +47,11 @@
#include <asm/ldt.h>
#include <asm/processor.h>
#include <asm/i387.h>
-#include <asm/irq.h>
#include <asm/desc.h>
#ifdef CONFIG_MATH_EMULATION
#include <asm/math_emu.h>
#endif
-#include <linux/irq.h>
#include <linux/err.h>
#include <asm/tlbflush.h>
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 340980203b09..7b6368bf8974 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -694,17 +694,22 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
__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/reboot.c b/arch/i386/kernel/reboot.c
index 1cbb9c0f4704..350ea6680f63 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -11,6 +11,7 @@
#include <linux/mc146818rtc.h>
#include <linux/efi.h>
#include <linux/dmi.h>
+#include <linux/ctype.h>
#include <asm/uaccess.h>
#include <asm/apic.h>
#include <asm/desc.h>
@@ -28,8 +29,6 @@ static int reboot_thru_bios;
#ifdef CONFIG_SMP
static int reboot_cpu = -1;
-/* shamelessly grabbed from lib/vsprintf.c for readability */
-#define is_digit(c) ((c) >= '0' && (c) <= '9')
#endif
static int __init reboot_setup(char *str)
{
@@ -49,9 +48,9 @@ static int __init reboot_setup(char *str)
break;
#ifdef CONFIG_SMP
case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
- if (is_digit(*(str+1))) {
+ if (isdigit(*(str+1))) {
reboot_cpu = (int) (*(str+1) - '0');
- if (is_digit(*(str+2)))
+ if (isdigit(*(str+2)))
reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
}
/* we will leave sorting out the final value
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index e29fd5aeaf8e..9b8c8a19824d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -87,14 +87,14 @@ EXPORT_SYMBOL(boot_cpu_data);
unsigned long mmu_cr4_features;
-#ifdef CONFIG_ACPI_INTERPRETER
+#ifdef CONFIG_ACPI
int acpi_disabled = 0;
#else
int acpi_disabled = 1;
#endif
EXPORT_SYMBOL(acpi_disabled);
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
int __initdata acpi_force = 0;
extern acpi_interrupt_flags acpi_sci_flags;
#endif
@@ -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)
@@ -798,7 +799,7 @@ static void __init parse_cmdline_early (char ** cmdline_p)
}
#endif
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/* "acpi=off" disables both ACPI table parsing and interpreter */
else if (!memcmp(from, "acpi=off", 8)) {
disable_acpi();
@@ -847,14 +848,17 @@ static void __init parse_cmdline_early (char ** cmdline_p)
#ifdef CONFIG_X86_IO_APIC
else if (!memcmp(from, "acpi_skip_timer_override", 24))
acpi_skip_timer_override = 1;
-#endif
-#ifdef CONFIG_X86_LOCAL_APIC
+ if (!memcmp(from, "disable_timer_pin_1", 19))
+ disable_timer_pin_1 = 1;
+ if (!memcmp(from, "enable_timer_pin_1", 18))
+ disable_timer_pin_1 = -1;
+
/* disable IO-APIC */
else if (!memcmp(from, "noapic", 6))
disable_ioapic_setup();
-#endif /* CONFIG_X86_LOCAL_APIC */
-#endif /* CONFIG_ACPI_BOOT */
+#endif /* CONFIG_X86_IO_APIC */
+#endif /* CONFIG_ACPI */
#ifdef CONFIG_X86_LOCAL_APIC
/* enable local APIC */
@@ -1299,7 +1303,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 +1348,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);
@@ -1579,7 +1583,7 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled)
efi_map_memmap();
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
*/
diff --git a/arch/i386/kernel/sigframe.h b/arch/i386/kernel/sigframe.h
index d21b14f5c25c..0b2221711dad 100644
--- a/arch/i386/kernel/sigframe.h
+++ b/arch/i386/kernel/sigframe.h
@@ -1,6 +1,6 @@
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/signal.c b/arch/i386/kernel/signal.c
index 61eb0c8a6e47..adcd069db91e 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -338,7 +338,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
esp = (unsigned long) ka->sa.sa_restorer;
}
- return (void __user *)((esp - frame_size) & -8ul);
+ esp -= frame_size;
+ /* Align the stack pointer according to the i386 ABI,
+ * i.e. so that on function entry ((sp + 4) & 15) == 0. */
+ esp = ((esp + 4) & -16ul) - 4;
+ return (void __user *) esp;
}
/* These symbols are defined with the addresses in the vsyscall page.
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 48b55db3680f..218d725a5a1e 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 5e4893d2b9f2..1fb26d0e30b6 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -42,7 +42,6 @@
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/smp_lock.h>
-#include <linux/irq.h>
#include <linux/bootmem.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
@@ -202,7 +201,7 @@ static void __devinit smp_store_cpu_info(int id)
goto valid_k7;
/* If we get here, it's not a certified SMP capable AMD system. */
- tainted |= TAINT_UNSAFE_SMP;
+ add_taint(TAINT_UNSAFE_SMP);
}
valid_k7:
@@ -1330,8 +1329,7 @@ void __cpu_die(unsigned int cpu)
printk ("CPU %d is now offline\n", cpu);
return;
}
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ/10);
+ msleep(100);
}
printk(KERN_ERR "CPU %u didn't die...\n", cpu);
}
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 7b3b27d64409..516bf5653b02 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -213,12 +213,18 @@ static __init void node_read_chunk(int nid, struct node_memory_chunk_s *memory_c
node_end_pfn[nid] = memory_chunk->end_pfn;
}
+static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */
+
+int pxm_to_node(int pxm)
+{
+ return pxm_to_nid_map[pxm];
+}
+
/* Parse the ACPI Static Resource Affinity Table */
static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
{
u8 *start, *end, *p;
int i, j, nid;
- u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */
u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */
start = (u8 *)(&(sratp->reserved) + 1); /* skip header */
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index eefea7c55008..2883a4d4f01f 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -329,8 +329,7 @@ EXPORT_SYMBOL(get_cmos_time);
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/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
index eddb64038234..e42e46d35159 100644
--- a/arch/i386/kernel/timers/timer_pit.c
+++ b/arch/i386/kernel/timers/timer_pit.c
@@ -6,7 +6,6 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/device.h>
-#include <linux/irq.h>
#include <linux/sysdev.h>
#include <linux/timex.h>
#include <asm/delay.h>
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 09a58cb6daa7..19e90bdd84ea 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -52,7 +52,6 @@
#include <asm/arch_hooks.h>
#include <asm/kdebug.h>
-#include <linux/irq.h>
#include <linux/module.h>
#include "mach_traps.h"
@@ -807,8 +806,9 @@ void math_error(void __user *eip)
cwd = get_fpu_cwd(task);
swd = get_fpu_swd(task);
switch (swd & ~cwd & 0x3f) {
- case 0x000:
- default:
+ case 0x000: /* No unmasked exception */
+ return;
+ default: /* Multiple exceptions */
break;
case 0x001: /* Invalid Op */
/*
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 13b9c62cbbb4..4710195b6b74 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -144,12 +144,7 @@ SECTIONS
*(.exitcall.exit)
}
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
+ STABS_DEBUG
+
+ DWARF_DEBUG
}
diff --git a/arch/i386/kernel/vsyscall-sigreturn.S b/arch/i386/kernel/vsyscall-sigreturn.S
index 68afa50dd7cf..fadb5bc3c374 100644
--- a/arch/i386/kernel/vsyscall-sigreturn.S
+++ b/arch/i386/kernel/vsyscall-sigreturn.S
@@ -7,7 +7,7 @@
*/
#include <asm/unistd.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
/* XXX
diff --git a/arch/i386/kernel/vsyscall.lds.S b/arch/i386/kernel/vsyscall.lds.S
index a7977707c8e5..98699ca6e52d 100644
--- a/arch/i386/kernel/vsyscall.lds.S
+++ b/arch/i386/kernel/vsyscall.lds.S
@@ -3,7 +3,7 @@
* object prelinked to its virtual address, and with only one read-only
* segment (that fits in one page). This script controls its layout.
*/
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
SECTIONS
{
diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile
index 7b1932d20f96..914933e9ec3d 100644
--- a/arch/i386/lib/Makefile
+++ b/arch/i386/lib/Makefile
@@ -7,4 +7,3 @@ lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
bitops.o
lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
-lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff --git a/arch/i386/lib/dec_and_lock.c b/arch/i386/lib/dec_and_lock.c
deleted file mode 100644
index 8b81b2524fa6..000000000000
--- a/arch/i386/lib/dec_and_lock.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * x86 version of "atomic_dec_and_lock()" using
- * the atomic "cmpxchg" instruction.
- *
- * (For CPU's lacking cmpxchg, we use the slow
- * generic version, and this one never even gets
- * compiled).
- */
-
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <asm/atomic.h>
-
-int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-{
- int counter;
- int newcount;
-
-repeat:
- counter = atomic_read(atomic);
- newcount = counter-1;
-
- if (!newcount)
- goto slow_path;
-
- asm volatile("lock; cmpxchgl %1,%2"
- :"=a" (newcount)
- :"r" (newcount), "m" (atomic->counter), "0" (counter));
-
- /* If the above failed, "eax" will have changed */
- if (newcount != counter)
- goto repeat;
- return 0;
-
-slow_path:
- spin_lock(lock);
- if (atomic_dec_and_test(atomic))
- return 1;
- spin_unlock(lock);
- return 0;
-}
-EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c
index e5a1a83d09ef..b4a7455c6993 100644
--- a/arch/i386/mach-default/setup.c
+++ b/arch/i386/mach-default/setup.c
@@ -5,7 +5,6 @@
#include <linux/config.h>
#include <linux/smp.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/acpi.h>
#include <asm/arch_hooks.h>
diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c
index 2000bdca2fc2..dc6660511b07 100644
--- a/arch/i386/mach-es7000/es7000plat.c
+++ b/arch/i386/mach-es7000/es7000plat.c
@@ -51,7 +51,7 @@ struct mip_reg *host_reg;
int mip_port;
unsigned long mip_addr, host_addr;
-#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT))
+#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI)
/*
* GSI override for ES7000 platforms.
@@ -73,7 +73,7 @@ es7000_rename_gsi(int ioapic, int gsi)
return gsi;
}
-#endif // (CONFIG_X86_IO_APIC) && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)
+#endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
void __init
setup_unisys ()
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c
index 26ada6fc0d77..07fac7e749c7 100644
--- a/arch/i386/mach-visws/setup.c
+++ b/arch/i386/mach-visws/setup.c
@@ -5,7 +5,6 @@
#include <linux/smp.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/fixmap.h>
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
index 04e6585849a2..3e64fb721291 100644
--- a/arch/i386/mach-visws/visws_apic.c
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -19,7 +19,6 @@
#include <linux/config.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c
index df123fc487bb..7d8a3acb9441 100644
--- a/arch/i386/mach-voyager/setup.c
+++ b/arch/i386/mach-voyager/setup.c
@@ -4,7 +4,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/acpi.h>
#include <asm/arch_hooks.h>
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c
index cc69875d979b..aa49a33a572c 100644
--- a/arch/i386/mach-voyager/voyager_basic.c
+++ b/arch/i386/mach-voyager/voyager_basic.c
@@ -27,7 +27,6 @@
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/pm.h>
-#include <linux/irq.h>
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>
#include <asm/i8253.h>
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 46b0cf4a31e0..72a1b9cae2e4 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -30,8 +30,6 @@
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>
-#include <linux/irq.h>
-
/* TLB state -- visible externally, indexed physically */
DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c
index a9341b0eebff..2b03884fdb2a 100644
--- a/arch/i386/mach-voyager/voyager_thread.c
+++ b/arch/i386/mach-voyager/voyager_thread.c
@@ -31,8 +31,6 @@
#include <asm/mtrr.h>
#include <asm/msr.h>
-#include <linux/irq.h>
-
#define THREAD_NAME "kvoyagerd"
/* external variables */
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
index ad93cdd55d63..930a1127bb30 100644
--- a/arch/i386/oprofile/nmi_timer_int.c
+++ b/arch/i386/oprofile/nmi_timer_int.c
@@ -9,7 +9,7 @@
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/irq.h>
+#include <linux/errno.h>
#include <linux/oprofile.h>
#include <linux/rcupdate.h>
diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile
index 1bff03f36965..ead6122dd06d 100644
--- a/arch/i386/pci/Makefile
+++ b/arch/i386/pci/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o
obj-$(CONFIG_PCI_DIRECT) += direct.o
pci-y := fixup.o
-pci-$(CONFIG_ACPI_PCI) += acpi.o
+pci-$(CONFIG_ACPI) += acpi.o
pci-y += legacy.o irq.o
pci-$(CONFIG_X86_VISWS) := visws.o fixup.o
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
index 42913f43feb0..4c4522b43be5 100644
--- a/arch/i386/pci/acpi.c
+++ b/arch/i386/pci/acpi.c
@@ -2,17 +2,31 @@
#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/irq.h>
-#include <asm/hw_irq.h>
+#include <asm/numa.h>
#include "pci.h"
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
{
+ struct pci_bus *bus;
+
if (domain != 0) {
printk(KERN_WARNING "PCI: Multiple domains not supported\n");
return NULL;
}
- return pcibios_scan_root(busnum);
+ bus = pcibios_scan_root(busnum);
+#ifdef CONFIG_ACPI_NUMA
+ if (bus != NULL) {
+ int pxm = acpi_get_pxm(device->handle);
+ if (pxm >= 0) {
+ bus->sysdata = (void *)(unsigned long)pxm_to_node(pxm);
+ printk("bus %d -> pxm %d -> node %ld\n",
+ busnum, pxm, (long)(bus->sysdata));
+ }
+ }
+#endif
+
+ return bus;
}
extern int pci_routeirq;
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index 3cc480998a47..6d6338500c3c 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -283,9 +283,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
/* 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/i386/pci/irq.c b/arch/i386/pci/irq.c
index 86348b68fda1..cddafe33ff7c 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -11,12 +11,11 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/dmi.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/io_apic.h>
-#include <asm/hw_irq.h>
+#include <linux/irq.h>
#include <linux/acpi.h>
#include "pci.h"
@@ -1075,7 +1074,7 @@ static void pirq_penalize_isa_irq(int irq, int active)
void pcibios_penalize_isa_irq(int irq, int active)
{
-#ifdef CONFIG_ACPI_PCI
+#ifdef CONFIG_ACPI
if (!acpi_noirq)
acpi_penalize_isa_irq(irq, active);
else
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 60f0e7a1162a..dfbf80cff834 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -127,13 +127,6 @@ static int __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0))
goto out;
- /* Kludge for now. Don't use mmconfig on AMD systems because
- those have some busses where mmconfig doesn't work,
- and we don't parse ACPI MCFG well enough to handle that.
- Remove when proper handling is added. */
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
- goto out;
-
printk(KERN_INFO "PCI: Using MMCONFIG\n");
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index 7b0b9ad848e5..b27c5acc79d0 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -8,25 +8,8 @@
*/
#include <linux/config.h>
-#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/poll.h>
-#include <linux/delay.h>
-#include <linux/sysrq.h>
-#include <linux/proc_fs.h>
-#include <linux/irq.h>
-#include <linux/pm.h>
-#include <linux/device.h>
#include <linux/suspend.h>
-#include <linux/acpi.h>
-
-#include <asm/uaccess.h>
-#include <asm/acpi.h>
-#include <asm/tlbflush.h>
-#include <asm/processor.h>
static struct saved_context saved_context;
diff --git a/arch/i386/power/swsusp.S b/arch/i386/power/swsusp.S
index c4105286ff26..c893b897217f 100644
--- a/arch/i386/power/swsusp.S
+++ b/arch/i386/power/swsusp.S
@@ -12,7 +12,7 @@
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/page.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.text
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 17b5dbf8c311..945c15a0722b 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -60,6 +60,7 @@ choice
config IA64_GENERIC
bool "generic"
+ select ACPI
select NUMA
select ACPI_NUMA
select VIRTUAL_MEM_MAP
@@ -297,11 +298,6 @@ config PREEMPT
source "mm/Kconfig"
-config HAVE_DEC_LOCK
- bool
- depends on (SMP || PREEMPT)
- default y
-
config IA32_SUPPORT
bool "Support for Linux/x86 binaries"
help
@@ -338,11 +334,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 IOSAPIC && EXPERIMENTAL
- default y
-
source "drivers/firmware/Kconfig"
source "fs/Kconfig.binfmt"
@@ -351,38 +342,10 @@ endmenu
menu "Power management and ACPI"
-config PM
- bool "Power Management support"
- depends on !IA64_HP_SIM
- default y
- help
- "Power Management" means that parts of your computer are shut
- off or put into a power conserving "sleep" mode if they are not
- being used. There are two competing standards for doing this: APM
- and ACPI. If you want to use either one, say Y here and then also
- to the requisite support below.
-
- Power Management is most important for battery powered laptop
- computers; if you have a laptop, check out the Linux Laptop home
- page on the WWW at <http://www.linux-on-laptops.com/> and the
- Battery Powered Linux mini-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Note that, even if you say N here, Linux on the x86 architecture
- will issue the hlt instruction if nothing is to be done, thereby
- sending the processor to sleep and saving power.
-
-config ACPI
- bool
- depends on !IA64_HP_SIM
- default y
-
-if !IA64_HP_SIM
+source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
-endif
-
if PM
source "arch/ia64/kernel/cpufreq/Kconfig"
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index f9bd88ada708..67932ad53082 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -82,24 +82,7 @@ unwcheck: vmlinux
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-CLEAN_FILES += include/asm-ia64/.offsets.h.stamp vmlinux.gz bootloader
-
-MRPROPER_FILES += include/asm-ia64/offsets.h
-
-prepare: include/asm-ia64/offsets.h
-
-arch/ia64/kernel/asm-offsets.s: include/asm include/linux/version.h include/config/MARKER
-
-include/asm-ia64/offsets.h: arch/ia64/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
-arch/ia64/kernel/asm-offsets.s: include/asm-ia64/.offsets.h.stamp
-
-include/asm-ia64/.offsets.h.stamp:
- mkdir -p include/asm-ia64
- [ -s include/asm-ia64/offsets.h ] \
- || echo "#define IA64_TASK_SIZE 0" > include/asm-ia64/offsets.h
- touch $@
+CLEAN_FILES += vmlinux.gz bootloader
boot: lib/lib.a vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
index b95fcf86ea00..3b65cbb31b1d 100644
--- a/arch/ia64/configs/bigsur_defconfig
+++ b/arch/ia64/configs/bigsur_defconfig
@@ -107,18 +107,12 @@ CONFIG_ACPI=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_VIDEO=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_THERMAL=m
-CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
#
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index dccf35c60b94..08112ab38468 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
@@ -130,19 +129,12 @@ CONFIG_ACPI=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
# CONFIG_ACPI_BUTTON is not set
-CONFIG_ACPI_VIDEO=m
-CONFIG_ACPI_HOTKEY=m
# CONFIG_ACPI_FAN is not set
# CONFIG_ACPI_PROCESSOR is not set
CONFIG_ACPI_NUMA=y
-CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_ACPI_CONTAINER is not set
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index c853cfcd2d11..d452e18ac494 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
@@ -128,20 +127,13 @@ CONFIG_ACPI=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_BUTTON=m
-# CONFIG_ACPI_VIDEO is not set
-# CONFIG_ACPI_HOTKEY is not set
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
# CONFIG_ACPI_HOTPLUG_CPU is not set
CONFIG_ACPI_THERMAL=m
-CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_ACPI_CONTAINER is not set
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 88e8867fa8e8..80b0e9eb7fb3 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
@@ -128,19 +127,12 @@ CONFIG_ACPI=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_VIDEO=m
-CONFIG_ACPI_HOTKEY=m
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
-CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_ACPI_CONTAINER is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 8444add76380..5da208115ea1 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
@@ -118,20 +117,14 @@ CONFIG_ACPI=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_VIDEO=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=m
CONFIG_ACPI_NUMA=y
-CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
CONFIG_ACPI_CONTAINER=m
@@ -341,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/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
index 80f8ef013939..1ba02baf2f94 100644
--- a/arch/ia64/hp/common/hwsw_iommu.c
+++ b/arch/ia64/hp/common/hwsw_iommu.c
@@ -71,7 +71,7 @@ hwsw_init (void)
}
void *
-hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
{
if (use_swiotlb(dev))
return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 11957598a8b9..21bffba78b6d 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1076,7 +1076,7 @@ void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir)
* See Documentation/DMA-mapping.txt
*/
void *
-sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
{
struct ioc *ioc;
void *addr;
diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S
index 1c8c7e6a9a5e..a9bd71ac78e2 100644
--- a/arch/ia64/hp/sim/boot/boot_head.S
+++ b/arch/ia64/hp/sim/boot/boot_head.S
@@ -4,6 +4,7 @@
*/
#include <asm/asmmacro.h>
+#include <asm/pal.h>
.bss
.align 16
@@ -49,7 +50,11 @@ GLOBAL_ENTRY(jmp_to_kernel)
br.sptk.few b7
END(jmp_to_kernel)
-
+/*
+ * r28 contains the index of the PAL function
+ * r29--31 the args
+ * Return values in ret0--3 (r8--11)
+ */
GLOBAL_ENTRY(pal_emulator_static)
mov r8=-1
mov r9=256
@@ -62,7 +67,7 @@ GLOBAL_ENTRY(pal_emulator_static)
cmp.gtu p6,p7=r9,r28
(p6) br.cond.sptk.few stacked
;;
-static: cmp.eq p6,p7=6,r28 /* PAL_PTCE_INFO */
+static: cmp.eq p6,p7=PAL_PTCE_INFO,r28
(p7) br.cond.sptk.few 1f
;;
mov r8=0 /* status = 0 */
@@ -70,21 +75,21 @@ static: cmp.eq p6,p7=6,r28 /* PAL_PTCE_INFO */
movl r10=0x0000000200000003 /* count[0], count[1] */
movl r11=0x1000000000002000 /* stride[0], stride[1] */
br.cond.sptk.few rp
-1: cmp.eq p6,p7=14,r28 /* PAL_FREQ_RATIOS */
+1: cmp.eq p6,p7=PAL_FREQ_RATIOS,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9 =0x100000064 /* proc_ratio (1/100) */
movl r10=0x100000100 /* bus_ratio<<32 (1/256) */
movl r11=0x100000064 /* itc_ratio<<32 (1/100) */
;;
-1: cmp.eq p6,p7=19,r28 /* PAL_RSE_INFO */
+1: cmp.eq p6,p7=PAL_RSE_INFO,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
mov r9=96 /* num phys stacked */
mov r10=0 /* hints */
mov r11=0
br.cond.sptk.few rp
-1: cmp.eq p6,p7=1,r28 /* PAL_CACHE_FLUSH */
+1: cmp.eq p6,p7=PAL_CACHE_FLUSH,r28 /* PAL_CACHE_FLUSH */
(p7) br.cond.sptk.few 1f
mov r9=ar.lc
movl r8=524288 /* flush 512k million cache lines (16MB) */
@@ -102,7 +107,7 @@ static: cmp.eq p6,p7=6,r28 /* PAL_PTCE_INFO */
mov ar.lc=r9
mov r8=r0
;;
-1: cmp.eq p6,p7=15,r28 /* PAL_PERF_MON_INFO */
+1: cmp.eq p6,p7=PAL_PERF_MON_INFO,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9 =0x08122f04 /* generic=4 width=47 retired=8 cycles=18 */
@@ -138,6 +143,20 @@ static: cmp.eq p6,p7=6,r28 /* PAL_PTCE_INFO */
st8 [r29]=r0,16 /* clear remaining bits */
st8 [r18]=r0,16 /* clear remaining bits */
;;
+1: cmp.eq p6,p7=PAL_VM_SUMMARY,r28
+(p7) br.cond.sptk.few 1f
+ mov r8=0 /* status = 0 */
+ movl r9=0x2044040020F1865 /* num_tc_levels=2, num_unique_tcs=4 */
+ /* max_itr_entry=64, max_dtr_entry=64 */
+ /* hash_tag_id=2, max_pkr=15 */
+ /* key_size=24, phys_add_size=50, vw=1 */
+ movl r10=0x183C /* rid_size=24, impl_va_msb=60 */
+ ;;
+1: cmp.eq p6,p7=PAL_MEM_ATTRIB,r28
+(p7) br.cond.sptk.few 1f
+ mov r8=0 /* status = 0 */
+ mov r9=0x80|0x01 /* NatPage|WB */
+ ;;
1: br.cond.sptk.few rp
stacked:
br.ret.sptk.few rp
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index 56405dbfd739..a18983a3c934 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
}
+static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
+{
+
+ int scatterlen = sc->use_sg;
+ struct scatterlist *slp;
+
+ if (scatterlen == 0)
+ memcpy(sc->request_buffer, buf, len);
+ else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) {
+ unsigned thislen = min(len, slp->length);
+
+ memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+ slp++;
+ len -= thislen;
+ }
+}
+
static int
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
{
@@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
char fname[MAX_ROOT_LEN+16];
size_t disk_size;
char *buf;
+ char localbuf[36];
#if DEBUG_SIMSCSI
register long sp asm ("sp");
@@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
/* disk doesn't exist... */
break;
}
- buf = sc->request_buffer;
+ buf = localbuf;
buf[0] = 0; /* magnetic disk */
buf[1] = 0; /* not a removable medium */
buf[2] = 2; /* SCSI-2 compliant device */
@@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
buf[6] = 0; /* reserved */
buf[7] = 0; /* various flags */
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
+ simscsi_fillresult(sc, buf, 36);
sc->result = GOOD;
break;
@@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
simscsi_readwrite10(sc, SSC_WRITE);
break;
-
case READ_CAPACITY:
if (desc[target_id] < 0 || sc->request_bufflen < 8) {
break;
}
- buf = sc->request_buffer;
-
+ buf = localbuf;
disk_size = simscsi_get_disk_size(desc[target_id]);
- /* pretend to be a 1GB disk (partition table contains real stuff): */
buf[0] = (disk_size >> 24) & 0xff;
buf[1] = (disk_size >> 16) & 0xff;
buf[2] = (disk_size >> 8) & 0xff;
@@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
buf[5] = 0;
buf[6] = 2;
buf[7] = 0;
+ simscsi_fillresult(sc, buf, 8);
sc->result = GOOD;
break;
case MODE_SENSE:
case MODE_SENSE_10:
/* sd.c uses this to determine whether disk does write-caching. */
- memset(sc->request_buffer, 0, 128);
+ simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
sc->result = GOOD;
break;
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index 31de70b7c67f..a7280d9f6c16 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -216,12 +216,6 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack)
if (!mpnt)
return -ENOMEM;
- if (security_vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))
- >> PAGE_SHIFT)) {
- kmem_cache_free(vm_area_cachep, mpnt);
- return -ENOMEM;
- }
-
memset(mpnt, 0, sizeof(*mpnt));
down_write(&current->mm->mmap_sem);
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index 0708edb06cc4..494fad6bf376 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -1,6 +1,6 @@
#include <asm/asmmacro.h>
#include <asm/ia32.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/signal.h>
#include <asm/thread_info.h>
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index e29a8a55486a..3fa67ecebc83 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -2327,7 +2327,7 @@ sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
set_fs(old_fs);
- if (!ret && offset && put_user(of, offset))
+ if (offset && put_user(of, offset))
return -EFAULT;
return ret;
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c
index 2623df5e2633..13a5b3b49bf8 100644
--- a/arch/ia64/kernel/acpi-ext.c
+++ b/arch/ia64/kernel/acpi-ext.c
@@ -17,20 +17,20 @@
#include <asm/acpi-ext.h>
struct acpi_vendor_descriptor {
- u8 guid_id;
- efi_guid_t guid;
+ u8 guid_id;
+ efi_guid_t guid;
};
struct acpi_vendor_info {
- struct acpi_vendor_descriptor *descriptor;
- u8 *data;
- u32 length;
+ struct acpi_vendor_descriptor *descriptor;
+ u8 *data;
+ u32 length;
};
acpi_status
acpi_vendor_resource_match(struct acpi_resource *resource, void *context)
{
- struct acpi_vendor_info *info = (struct acpi_vendor_info *) context;
+ struct acpi_vendor_info *info = (struct acpi_vendor_info *)context;
struct acpi_resource_vendor *vendor;
struct acpi_vendor_descriptor *descriptor;
u32 length;
@@ -38,8 +38,8 @@ acpi_vendor_resource_match(struct acpi_resource *resource, void *context)
if (resource->id != ACPI_RSTYPE_VENDOR)
return AE_OK;
- vendor = (struct acpi_resource_vendor *) &resource->data;
- descriptor = (struct acpi_vendor_descriptor *) vendor->reserved;
+ vendor = (struct acpi_resource_vendor *)&resource->data;
+ descriptor = (struct acpi_vendor_descriptor *)vendor->reserved;
if (vendor->length <= sizeof(*info->descriptor) ||
descriptor->guid_id != info->descriptor->guid_id ||
efi_guidcmp(descriptor->guid, info->descriptor->guid))
@@ -50,21 +50,24 @@ acpi_vendor_resource_match(struct acpi_resource *resource, void *context)
if (!info->data)
return AE_NO_MEMORY;
- memcpy(info->data, vendor->reserved + sizeof(struct acpi_vendor_descriptor), length);
+ memcpy(info->data,
+ vendor->reserved + sizeof(struct acpi_vendor_descriptor),
+ length);
info->length = length;
return AE_CTRL_TERMINATE;
}
acpi_status
-acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id,
- u8 **data, u32 *length)
+acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id,
+ u8 ** data, u32 * length)
{
struct acpi_vendor_info info;
info.descriptor = id;
info.data = NULL;
- acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, &info);
+ acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match,
+ &info);
if (!info.data)
return AE_NOT_FOUND;
@@ -75,17 +78,19 @@ acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id,
struct acpi_vendor_descriptor hp_ccsr_descriptor = {
.guid_id = 2,
- .guid = EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
+ .guid =
+ EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01,
+ 0x37, 0x0e, 0xad)
};
-acpi_status
-hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
+acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length)
{
acpi_status status;
u8 *data;
u32 length;
- status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
+ status =
+ acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
if (ACPI_FAILURE(status) || length != 16)
return AE_NOT_FOUND;
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 9609f243e5d0..7e926471e4ec 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -74,12 +74,11 @@ unsigned int acpi_cpei_override;
unsigned int acpi_cpei_phys_cpuid;
#define MAX_SAPICS 256
-u16 ia64_acpiid_to_sapicid[MAX_SAPICS] =
- { [0 ... MAX_SAPICS - 1] = -1 };
+u16 ia64_acpiid_to_sapicid[MAX_SAPICS] = {[0 ... MAX_SAPICS - 1] = -1 };
+
EXPORT_SYMBOL(ia64_acpiid_to_sapicid);
-const char *
-acpi_get_sysname (void)
+const char *acpi_get_sysname(void)
{
#ifdef CONFIG_IA64_GENERIC
unsigned long rsdp_phys;
@@ -89,27 +88,29 @@ acpi_get_sysname (void)
rsdp_phys = acpi_find_rsdp();
if (!rsdp_phys) {
- printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n");
+ printk(KERN_ERR
+ "ACPI 2.0 RSDP not found, default to \"dig\"\n");
return "dig";
}
- rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
+ rsdp = (struct acpi20_table_rsdp *)__va(rsdp_phys);
if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
- printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
+ printk(KERN_ERR
+ "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
return "dig";
}
- xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
+ xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_address);
hdr = &xsdt->header;
if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
- printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
+ printk(KERN_ERR
+ "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
return "dig";
}
if (!strcmp(hdr->oem_id, "HP")) {
return "hpzx1";
- }
- else if (!strcmp(hdr->oem_id, "SGI")) {
+ } else if (!strcmp(hdr->oem_id, "SGI")) {
return "sn2";
}
@@ -131,7 +132,7 @@ acpi_get_sysname (void)
#endif
}
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
#define ACPI_MAX_PLATFORM_INTERRUPTS 256
@@ -146,8 +147,7 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
* Interrupt routing API for device drivers. Provides interrupt vector for
* a generic platform event. Currently only CPEI is implemented.
*/
-int
-acpi_request_vector (u32 int_type)
+int acpi_request_vector(u32 int_type)
{
int vector = -1;
@@ -155,12 +155,12 @@ acpi_request_vector (u32 int_type)
/* corrected platform error interrupt */
vector = platform_intr_list[int_type];
} else
- printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
+ printk(KERN_ERR
+ "acpi_request_vector(): invalid interrupt type\n");
return vector;
}
-char *
-__acpi_map_table (unsigned long phys_addr, unsigned long size)
+char *__acpi_map_table(unsigned long phys_addr, unsigned long size)
{
return __va(phys_addr);
}
@@ -169,19 +169,18 @@ __acpi_map_table (unsigned long phys_addr, unsigned long size)
Boot-time Table Parsing
-------------------------------------------------------------------------- */
-static int total_cpus __initdata;
-static int available_cpus __initdata;
-struct acpi_table_madt * acpi_madt __initdata;
-static u8 has_8259;
-
+static int total_cpus __initdata;
+static int available_cpus __initdata;
+struct acpi_table_madt *acpi_madt __initdata;
+static u8 has_8259;
static int __init
-acpi_parse_lapic_addr_ovr (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_lapic_addr_ovr *lapic;
- lapic = (struct acpi_table_lapic_addr_ovr *) header;
+ lapic = (struct acpi_table_lapic_addr_ovr *)header;
if (BAD_MADT_ENTRY(lapic, end))
return -EINVAL;
@@ -193,22 +192,23 @@ acpi_parse_lapic_addr_ovr (
return 0;
}
-
static int __init
-acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_lsapic(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_lsapic *lsapic;
- lsapic = (struct acpi_table_lsapic *) header;
+ lsapic = (struct acpi_table_lsapic *)header;
if (BAD_MADT_ENTRY(lsapic, end))
return -EINVAL;
if (lsapic->flags.enabled) {
#ifdef CONFIG_SMP
- smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
+ smp_boot_data.cpu_phys_id[available_cpus] =
+ (lsapic->id << 8) | lsapic->eid;
#endif
- ia64_acpiid_to_sapicid[lsapic->acpi_id] = (lsapic->id << 8) | lsapic->eid;
+ ia64_acpiid_to_sapicid[lsapic->acpi_id] =
+ (lsapic->id << 8) | lsapic->eid;
++available_cpus;
}
@@ -216,13 +216,12 @@ acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end)
return 0;
}
-
static int __init
-acpi_parse_lapic_nmi (acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_lapic_nmi *lacpi_nmi;
- lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
+ lacpi_nmi = (struct acpi_table_lapic_nmi *)header;
if (BAD_MADT_ENTRY(lacpi_nmi, end))
return -EINVAL;
@@ -231,13 +230,12 @@ acpi_parse_lapic_nmi (acpi_table_entry_header *header, const unsigned long end)
return 0;
}
-
static int __init
-acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_iosapic(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_iosapic *iosapic;
- iosapic = (struct acpi_table_iosapic *) header;
+ iosapic = (struct acpi_table_iosapic *)header;
if (BAD_MADT_ENTRY(iosapic, end))
return -EINVAL;
@@ -245,15 +243,14 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
return iosapic_init(iosapic->address, iosapic->global_irq_base);
}
-
static int __init
-acpi_parse_plat_int_src (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_plat_int_src(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_plat_int_src *plintsrc;
int vector;
- plintsrc = (struct acpi_table_plat_int_src *) header;
+ plintsrc = (struct acpi_table_plat_int_src *)header;
if (BAD_MADT_ENTRY(plintsrc, end))
return -EINVAL;
@@ -267,8 +264,12 @@ acpi_parse_plat_int_src (
plintsrc->iosapic_vector,
plintsrc->eid,
plintsrc->id,
- (plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
- (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
+ (plintsrc->flags.polarity ==
+ 1) ? IOSAPIC_POL_HIGH :
+ IOSAPIC_POL_LOW,
+ (plintsrc->flags.trigger ==
+ 1) ? IOSAPIC_EDGE :
+ IOSAPIC_LEVEL);
platform_intr_list[plintsrc->type] = vector;
if (acpi_madt_rev > 1) {
@@ -283,7 +284,6 @@ acpi_parse_plat_int_src (
return 0;
}
-
unsigned int can_cpei_retarget(void)
{
extern int cpe_vector;
@@ -322,29 +322,30 @@ unsigned int get_cpei_target_cpu(void)
}
static int __init
-acpi_parse_int_src_ovr (
- acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_int_src_ovr(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_int_src_ovr *p;
- p = (struct acpi_table_int_src_ovr *) header;
+ p = (struct acpi_table_int_src_ovr *)header;
if (BAD_MADT_ENTRY(p, end))
return -EINVAL;
iosapic_override_isa_irq(p->bus_irq, p->global_irq,
- (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
- (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
+ (p->flags.polarity ==
+ 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+ (p->flags.trigger ==
+ 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
return 0;
}
-
static int __init
-acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end)
+acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end)
{
struct acpi_table_nmi_src *nmi_src;
- nmi_src = (struct acpi_table_nmi_src*) header;
+ nmi_src = (struct acpi_table_nmi_src *)header;
if (BAD_MADT_ENTRY(nmi_src, end))
return -EINVAL;
@@ -353,11 +354,9 @@ acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end)
return 0;
}
-static void __init
-acpi_madt_oem_check (char *oem_id, char *oem_table_id)
+static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
- if (!strncmp(oem_id, "IBM", 3) &&
- (!strncmp(oem_table_id, "SERMOW", 6))) {
+ if (!strncmp(oem_id, "IBM", 3) && (!strncmp(oem_table_id, "SERMOW", 6))) {
/*
* Unfortunately ITC_DRIFT is not yet part of the
@@ -370,19 +369,18 @@ acpi_madt_oem_check (char *oem_id, char *oem_table_id)
}
}
-static int __init
-acpi_parse_madt (unsigned long phys_addr, unsigned long size)
+static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
{
if (!phys_addr || !size)
return -EINVAL;
- acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
+ acpi_madt = (struct acpi_table_madt *)__va(phys_addr);
acpi_madt_rev = acpi_madt->header.revision;
/* remember the value for reference after free_initmem() */
#ifdef CONFIG_ITANIUM
- has_8259 = 1; /* Firmware on old Itanium systems is broken */
+ has_8259 = 1; /* Firmware on old Itanium systems is broken */
#else
has_8259 = acpi_madt->flags.pcat_compat;
#endif
@@ -396,19 +394,18 @@ acpi_parse_madt (unsigned long phys_addr, unsigned long size)
printk(KERN_INFO PREFIX "Local APIC address %p\n", ipi_base_addr);
acpi_madt_oem_check(acpi_madt->header.oem_id,
- acpi_madt->header.oem_table_id);
+ acpi_madt->header.oem_table_id);
return 0;
}
-
#ifdef CONFIG_ACPI_NUMA
#undef SLIT_DEBUG
#define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
-static int __initdata srat_num_cpus; /* number of cpus */
+static int __initdata srat_num_cpus; /* number of cpus */
static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];
#define pxm_bit_set(bit) (set_bit(bit,(void *)pxm_flag))
#define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag))
@@ -421,15 +418,15 @@ static struct acpi_table_slit __initdata *slit_table;
* ACPI 2.0 SLIT (System Locality Information Table)
* http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
*/
-void __init
-acpi_numa_slit_init (struct acpi_table_slit *slit)
+void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
{
u32 len;
len = sizeof(struct acpi_table_header) + 8
- + slit->localities * slit->localities;
+ + slit->localities * slit->localities;
if (slit->header.length != len) {
- printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
+ printk(KERN_ERR
+ "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
len, slit->header.length);
memset(numa_slit, 10, sizeof(numa_slit));
return;
@@ -438,19 +435,20 @@ acpi_numa_slit_init (struct acpi_table_slit *slit)
}
void __init
-acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa)
+acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
{
/* record this node in proximity bitmap */
pxm_bit_set(pa->proximity_domain);
- node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid);
+ node_cpuid[srat_num_cpus].phys_id =
+ (pa->apic_id << 8) | (pa->lsapic_eid);
/* nid should be overridden as logical node id later */
node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
srat_num_cpus++;
}
void __init
-acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
+acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
{
unsigned long paddr, size;
u8 pxm;
@@ -487,8 +485,7 @@ acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
num_node_memblks++;
}
-void __init
-acpi_numa_arch_fixup (void)
+void __init acpi_numa_arch_fixup(void)
{
int i, j, node_from, node_to;
@@ -534,21 +531,24 @@ acpi_numa_arch_fixup (void)
for (i = 0; i < srat_num_cpus; i++)
node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
- printk(KERN_INFO "Number of logical nodes in system = %d\n", num_online_nodes());
- printk(KERN_INFO "Number of memory chunks in system = %d\n", num_node_memblks);
+ printk(KERN_INFO "Number of logical nodes in system = %d\n",
+ num_online_nodes());
+ printk(KERN_INFO "Number of memory chunks in system = %d\n",
+ num_node_memblks);
- if (!slit_table) return;
+ if (!slit_table)
+ return;
memset(numa_slit, -1, sizeof(numa_slit));
- for (i=0; i<slit_table->localities; i++) {
+ for (i = 0; i < slit_table->localities; i++) {
if (!pxm_bit_test(i))
continue;
node_from = pxm_to_nid_map[i];
- for (j=0; j<slit_table->localities; j++) {
+ for (j = 0; j < slit_table->localities; j++) {
if (!pxm_bit_test(j))
continue;
node_to = pxm_to_nid_map[j];
node_distance(node_from, node_to) =
- slit_table->entry[i*slit_table->localities + j];
+ slit_table->entry[i * slit_table->localities + j];
}
}
@@ -556,36 +556,41 @@ acpi_numa_arch_fixup (void)
printk("ACPI 2.0 SLIT locality table:\n");
for_each_online_node(i) {
for_each_online_node(j)
- printk("%03d ", node_distance(i,j));
+ printk("%03d ", node_distance(i, j));
printk("\n");
}
#endif
}
-#endif /* CONFIG_ACPI_NUMA */
+#endif /* CONFIG_ACPI_NUMA */
-unsigned int
-acpi_register_gsi (u32 gsi, int edge_level, int active_high_low)
+/*
+ * success: return IRQ number (>=0)
+ * failure: return < 0
+ */
+int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
{
if (has_8259 && gsi < 16)
return isa_irq_to_vector(gsi);
return iosapic_register_intr(gsi,
- (active_high_low == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
- (edge_level == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
+ (active_high_low ==
+ ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH :
+ IOSAPIC_POL_LOW,
+ (edge_level ==
+ ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE :
+ IOSAPIC_LEVEL);
}
+
EXPORT_SYMBOL(acpi_register_gsi);
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
-void
-acpi_unregister_gsi (u32 gsi)
+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)
+static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size)
{
struct acpi_table_header *fadt_header;
struct fadt_descriptor_rev2 *fadt;
@@ -593,11 +598,11 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
if (!phys_addr || !size)
return -EINVAL;
- fadt_header = (struct acpi_table_header *) __va(phys_addr);
+ fadt_header = (struct acpi_table_header *)__va(phys_addr);
if (fadt_header->revision != 3)
- return -ENODEV; /* Only deal with ACPI 2.0 FADT */
+ return -ENODEV; /* Only deal with ACPI 2.0 FADT */
- fadt = (struct fadt_descriptor_rev2 *) fadt_header;
+ fadt = (struct fadt_descriptor_rev2 *)fadt_header;
if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
acpi_kbd_controller_present = 0;
@@ -609,22 +614,19 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
return 0;
}
-
-unsigned long __init
-acpi_find_rsdp (void)
+unsigned long __init acpi_find_rsdp(void)
{
unsigned long rsdp_phys = 0;
if (efi.acpi20)
rsdp_phys = __pa(efi.acpi20);
else if (efi.acpi)
- printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
+ printk(KERN_WARNING PREFIX
+ "v1.0/r0.71 tables no longer supported\n");
return rsdp_phys;
}
-
-int __init
-acpi_boot_init (void)
+int __init acpi_boot_init(void)
{
/*
@@ -642,31 +644,43 @@ acpi_boot_init (void)
/* Local APIC */
- if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
- printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
+ if (acpi_table_parse_madt
+ (ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
+ printk(KERN_ERR PREFIX
+ "Error parsing LAPIC address override entry\n");
- if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1)
- printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
+ if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS)
+ < 1)
+ printk(KERN_ERR PREFIX
+ "Error parsing MADT - no LAPIC entries\n");
- if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0)
+ if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0)
+ < 0)
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* I/O APIC */
- if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
- printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
+ if (acpi_table_parse_madt
+ (ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
+ printk(KERN_ERR PREFIX
+ "Error parsing MADT - no IOSAPIC entries\n");
/* System-Level Interrupt Routing */
- if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
- printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
+ if (acpi_table_parse_madt
+ (ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src,
+ ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
+ printk(KERN_ERR PREFIX
+ "Error parsing platform interrupt source entry\n");
- if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0)
- printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
+ if (acpi_table_parse_madt
+ (ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0)
+ printk(KERN_ERR PREFIX
+ "Error parsing interrupt source overrides entry\n");
if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0)
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
- skip_madt:
+ skip_madt:
/*
* FADT says whether a legacy keyboard controller is present.
@@ -681,8 +695,9 @@ acpi_boot_init (void)
if (available_cpus == 0) {
printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
- smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
- available_cpus = 1; /* We've got at least one of these, no? */
+ smp_boot_data.cpu_phys_id[available_cpus] =
+ hard_smp_processor_id();
+ available_cpus = 1; /* We've got at least one of these, no? */
}
smp_boot_data.cpu_count = available_cpus;
@@ -691,8 +706,10 @@ acpi_boot_init (void)
if (srat_num_cpus == 0) {
int cpu, i = 1;
for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++)
- if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id())
- node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu];
+ if (smp_boot_data.cpu_phys_id[cpu] !=
+ hard_smp_processor_id())
+ node_cpuid[i++].phys_id =
+ smp_boot_data.cpu_phys_id[cpu];
}
# endif
#endif
@@ -700,12 +717,12 @@ acpi_boot_init (void)
build_cpu_to_node_map();
#endif
/* Make boot-up look pretty */
- printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+ printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus,
+ total_cpus);
return 0;
}
-int
-acpi_gsi_to_irq (u32 gsi, unsigned int *irq)
+int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
{
int vector;
@@ -726,11 +743,10 @@ acpi_gsi_to_irq (u32 gsi, unsigned int *irq)
*/
#ifdef CONFIG_ACPI_HOTPLUG_CPU
static
-int
-acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
+int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
{
#ifdef CONFIG_ACPI_NUMA
- int pxm_id;
+ int pxm_id;
pxm_id = acpi_get_pxm(handle);
@@ -738,31 +754,28 @@ acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
* Assuming that the container driver would have set the proximity
* domain and would have initialized pxm_to_nid_map[pxm_id] && pxm_flag
*/
- node_cpuid[cpu].nid = (pxm_id < 0) ? 0:
- pxm_to_nid_map[pxm_id];
+ node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_nid_map[pxm_id];
- node_cpuid[cpu].phys_id = physid;
+ node_cpuid[cpu].phys_id = physid;
#endif
- return(0);
+ return (0);
}
-
-int
-acpi_map_lsapic(acpi_handle handle, int *pcpu)
+int acpi_map_lsapic(acpi_handle handle, int *pcpu)
{
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
struct acpi_table_lsapic *lsapic;
cpumask_t tmp_map;
long physid;
int cpu;
-
+
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
return -EINVAL;
- if (!buffer.length || !buffer.pointer)
+ if (!buffer.length || !buffer.pointer)
return -EINVAL;
-
+
obj = buffer.pointer;
if (obj->type != ACPI_TYPE_BUFFER ||
obj->buffer.length < sizeof(*lsapic)) {
@@ -778,7 +791,7 @@ acpi_map_lsapic(acpi_handle handle, int *pcpu)
return -EINVAL;
}
- physid = ((lsapic->id <<8) | (lsapic->eid));
+ physid = ((lsapic->id << 8) | (lsapic->eid));
acpi_os_free(buffer.pointer);
buffer.length = ACPI_ALLOCATE_BUFFER;
@@ -786,50 +799,49 @@ acpi_map_lsapic(acpi_handle handle, int *pcpu)
cpus_complement(tmp_map, cpu_present_map);
cpu = first_cpu(tmp_map);
- if(cpu >= NR_CPUS)
+ if (cpu >= NR_CPUS)
return -EINVAL;
acpi_map_cpu2node(handle, cpu, physid);
- cpu_set(cpu, cpu_present_map);
+ cpu_set(cpu, cpu_present_map);
ia64_cpu_to_sapicid[cpu] = physid;
ia64_acpiid_to_sapicid[lsapic->acpi_id] = ia64_cpu_to_sapicid[cpu];
*pcpu = cpu;
- return(0);
+ return (0);
}
-EXPORT_SYMBOL(acpi_map_lsapic);
+EXPORT_SYMBOL(acpi_map_lsapic);
-int
-acpi_unmap_lsapic(int cpu)
+int acpi_unmap_lsapic(int cpu)
{
int i;
- for (i=0; i<MAX_SAPICS; i++) {
- if (ia64_acpiid_to_sapicid[i] == ia64_cpu_to_sapicid[cpu]) {
- ia64_acpiid_to_sapicid[i] = -1;
- break;
- }
- }
+ for (i = 0; i < MAX_SAPICS; i++) {
+ if (ia64_acpiid_to_sapicid[i] == ia64_cpu_to_sapicid[cpu]) {
+ ia64_acpiid_to_sapicid[i] = -1;
+ break;
+ }
+ }
ia64_cpu_to_sapicid[cpu] = -1;
- cpu_clear(cpu,cpu_present_map);
+ cpu_clear(cpu, cpu_present_map);
#ifdef CONFIG_ACPI_NUMA
/* NUMA specific cleanup's */
#endif
- return(0);
+ return (0);
}
+
EXPORT_SYMBOL(acpi_unmap_lsapic);
-#endif /* CONFIG_ACPI_HOTPLUG_CPU */
-
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
#ifdef CONFIG_ACPI_NUMA
acpi_status __devinit
-acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
+acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret)
{
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
struct acpi_table_iosapic *iosapic;
unsigned int gsi_base;
@@ -878,29 +890,29 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
map_iosapic_to_node(gsi_base, node);
return AE_OK;
}
-#endif /* CONFIG_NUMA */
+#endif /* CONFIG_NUMA */
-int
-acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
+int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
{
int err;
if ((err = iosapic_init(phys_addr, gsi_base)))
return err;
-#if CONFIG_ACPI_NUMA
+#ifdef CONFIG_ACPI_NUMA
acpi_map_iosapic(handle, 0, NULL, NULL);
-#endif /* CONFIG_ACPI_NUMA */
+#endif /* CONFIG_ACPI_NUMA */
return 0;
}
+
EXPORT_SYMBOL(acpi_register_ioapic);
-int
-acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
+int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
{
return iosapic_remove(gsi_base);
}
+
EXPORT_SYMBOL(acpi_unregister_ioapic);
-#endif /* CONFIG_ACPI_BOOT */
+#endif /* CONFIG_ACPI */
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 7d1ae2982c53..77225659e968 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -4,6 +4,7 @@
* to extract and format the required data.
*/
+#define ASM_OFFSETS_C 1
#include <linux/config.h>
#include <linux/sched.h>
@@ -211,17 +212,41 @@ void foo(void)
#endif
BLANK();
- DEFINE(IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET,
- offsetof (struct ia64_mca_cpu, proc_state_dump));
- DEFINE(IA64_MCA_CPU_STACK_OFFSET,
- offsetof (struct ia64_mca_cpu, stack));
- DEFINE(IA64_MCA_CPU_STACKFRAME_OFFSET,
- offsetof (struct ia64_mca_cpu, stackframe));
- DEFINE(IA64_MCA_CPU_RBSTORE_OFFSET,
- offsetof (struct ia64_mca_cpu, rbstore));
+ DEFINE(IA64_MCA_CPU_MCA_STACK_OFFSET,
+ offsetof (struct ia64_mca_cpu, mca_stack));
DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET,
offsetof (struct ia64_mca_cpu, init_stack));
BLANK();
+ DEFINE(IA64_SAL_OS_STATE_COMMON_OFFSET,
+ offsetof (struct ia64_sal_os_state, sal_ra));
+ DEFINE(IA64_SAL_OS_STATE_OS_GP_OFFSET,
+ offsetof (struct ia64_sal_os_state, os_gp));
+ DEFINE(IA64_SAL_OS_STATE_PAL_MIN_STATE_OFFSET,
+ offsetof (struct ia64_sal_os_state, pal_min_state));
+ DEFINE(IA64_SAL_OS_STATE_PROC_STATE_PARAM_OFFSET,
+ offsetof (struct ia64_sal_os_state, proc_state_param));
+ DEFINE(IA64_SAL_OS_STATE_SIZE,
+ sizeof (struct ia64_sal_os_state));
+ DEFINE(IA64_PMSA_GR_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_gr));
+ DEFINE(IA64_PMSA_BANK1_GR_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_bank1_gr));
+ DEFINE(IA64_PMSA_PR_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_pr));
+ DEFINE(IA64_PMSA_BR0_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_br0));
+ DEFINE(IA64_PMSA_RSC_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_rsc));
+ DEFINE(IA64_PMSA_IIP_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_iip));
+ DEFINE(IA64_PMSA_IPSR_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_ipsr));
+ DEFINE(IA64_PMSA_IFS_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_ifs));
+ DEFINE(IA64_PMSA_XIP_OFFSET,
+ offsetof (struct pal_min_state_area_s, pmsa_xip));
+ BLANK();
+
/* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
DEFINE(IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET, offsetof (struct time_interpolator, addr));
DEFINE(IA64_TIME_INTERPOLATOR_SOURCE_OFFSET, offsetof (struct time_interpolator, source));
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 9be53e1ea404..0741b066b98f 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -37,7 +37,7 @@
#include <asm/cache.h>
#include <asm/errno.h>
#include <asm/kregs.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/percpu.h>
#include <asm/processor.h>
@@ -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_stack)
+
GLOBAL_ENTRY(execve)
mov r15=__NR_execve // put syscall number in place
break __BREAK_SYSCALL
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 7d7684a369d3..2ddbac6f4999 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -14,7 +14,7 @@
#include <asm/asmmacro.h>
#include <asm/errno.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/percpu.h>
#include <asm/thread_info.h>
#include <asm/sal.h>
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index 86948ce63e43..86064ca98952 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -10,7 +10,7 @@
#include <asm/asmmacro.h>
#include <asm/errno.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/sigcontext.h>
#include <asm/system.h>
#include <asm/unistd.h>
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index 8d3a9291b47f..bfe65b2e8621 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -25,7 +25,7 @@
#include <asm/fpu.h>
#include <asm/kregs.h>
#include <asm/mmu_context.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/pal.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 7936b62f7a2e..574084f343fa 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -561,7 +561,7 @@ static inline int vector_is_shared (int vector)
return (iosapic_intr_info[vector].count > 1);
}
-static void
+static int
register_intr (unsigned int gsi, int vector, unsigned char delivery,
unsigned long polarity, unsigned long trigger)
{
@@ -576,7 +576,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
index = find_iosapic(gsi);
if (index < 0) {
printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi);
- return;
+ return -ENODEV;
}
iosapic_address = iosapic_lists[index].addr;
@@ -587,7 +587,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
rte = iosapic_alloc_rte();
if (!rte) {
printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__);
- return;
+ return -ENOMEM;
}
rte_index = gsi - gsi_base;
@@ -603,7 +603,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
struct iosapic_intr_info *info = &iosapic_intr_info[vector];
if (info->trigger != trigger || info->polarity != polarity) {
printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__);
- return;
+ return -EINVAL;
}
}
@@ -623,6 +623,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
__FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
idesc->handler = irq_type;
}
+ return 0;
}
static unsigned int
@@ -710,7 +711,7 @@ int
iosapic_register_intr (unsigned int gsi,
unsigned long polarity, unsigned long trigger)
{
- int vector, mask = 1;
+ int vector, mask = 1, err;
unsigned int dest;
unsigned long flags;
struct iosapic_rte_info *rte;
@@ -737,8 +738,8 @@ again:
vector = assign_irq_vector(AUTO_ASSIGN);
if (vector < 0) {
vector = iosapic_find_sharable_vector(trigger, polarity);
- if (vector < 0)
- panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ if (vector < 0)
+ return -ENOSPC;
}
spin_lock_irqsave(&irq_descp(vector)->lock, flags);
@@ -753,8 +754,13 @@ again:
}
dest = get_target_cpu(gsi, vector);
- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+ err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
polarity, trigger);
+ if (err < 0) {
+ spin_unlock(&iosapic_lock);
+ spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
+ return err;
+ }
/*
* If the vector is shared and already unmasked for
@@ -776,7 +782,6 @@ again:
return vector;
}
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
void
iosapic_unregister_intr (unsigned int gsi)
{
@@ -859,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/ivt.S b/arch/ia64/kernel/ivt.S
index 3bb3a13c4047..c13ca0d49c4a 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -44,7 +44,7 @@
#include <asm/break.h>
#include <asm/ia32.h>
#include <asm/kregs.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
@@ -69,7 +69,6 @@
# define DBG_FAULT(i)
#endif
-#define MINSTATE_VIRT /* needed by minstate.h */
#include "minstate.h"
#define FAULT(n) \
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 4ebbf3974381..d0a5106fba24 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -48,6 +48,9 @@
* Delete dead variables and functions.
* Reorder to remove the need for forward declarations and to consolidate
* related code.
+ *
+ * 2005-08-12 Keith Owens <kaos@sgi.com>
+ * Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
*/
#include <linux/config.h>
#include <linux/types.h>
@@ -77,6 +80,8 @@
#include <asm/irq.h>
#include <asm/hw_irq.h>
+#include "entry.h"
+
#if defined(IA64_MCA_DEBUG_INFO)
# define IA64_MCA_DEBUG(fmt...) printk(fmt)
#else
@@ -84,9 +89,7 @@
#endif
/* Used by mca_asm.S */
-ia64_mca_sal_to_os_state_t ia64_sal_to_os_handoff_state;
-ia64_mca_os_to_sal_state_t ia64_os_to_sal_handoff_state;
-u64 ia64_mca_serialize;
+u32 ia64_mca_serialize;
DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
DEFINE_PER_CPU(u64, ia64_mca_pal_pte); /* PTE to map PAL code */
@@ -95,8 +98,10 @@ DEFINE_PER_CPU(u64, ia64_mca_pal_base); /* vaddr PAL code granule */
unsigned long __per_cpu_mca[NR_CPUS];
/* In mca_asm.S */
-extern void ia64_monarch_init_handler (void);
-extern void ia64_slave_init_handler (void);
+extern void ia64_os_init_dispatch_monarch (void);
+extern void ia64_os_init_dispatch_slave (void);
+
+static int monarch_cpu = -1;
static ia64_mc_info_t ia64_mc_info;
@@ -234,7 +239,8 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
* This function retrieves a specified error record type from SAL
* and wakes up any processes waiting for error records.
*
- * Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT)
+ * Inputs : sal_info_type (Type of error record MCA/CMC/CPE)
+ * FIXME: remove MCA and irq_safe.
*/
static void
ia64_mca_log_sal_error_record(int sal_info_type)
@@ -242,7 +248,7 @@ ia64_mca_log_sal_error_record(int sal_info_type)
u8 *buffer;
sal_log_record_header_t *rh;
u64 size;
- int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA && sal_info_type != SAL_INFO_TYPE_INIT;
+ int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA;
#ifdef IA64_MCA_DEBUG_INFO
static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" };
#endif
@@ -330,191 +336,6 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
#endif /* CONFIG_ACPI */
-static void
-show_min_state (pal_min_state_area_t *minstate)
-{
- u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri;
- u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri;
-
- printk("NaT bits\t%016lx\n", minstate->pmsa_nat_bits);
- printk("pr\t\t%016lx\n", minstate->pmsa_pr);
- printk("b0\t\t%016lx ", minstate->pmsa_br0); print_symbol("%s\n", minstate->pmsa_br0);
- printk("ar.rsc\t\t%016lx\n", minstate->pmsa_rsc);
- printk("cr.iip\t\t%016lx ", iip); print_symbol("%s\n", iip);
- printk("cr.ipsr\t\t%016lx\n", minstate->pmsa_ipsr);
- printk("cr.ifs\t\t%016lx\n", minstate->pmsa_ifs);
- printk("xip\t\t%016lx ", xip); print_symbol("%s\n", xip);
- printk("xpsr\t\t%016lx\n", minstate->pmsa_xpsr);
- printk("xfs\t\t%016lx\n", minstate->pmsa_xfs);
- printk("b1\t\t%016lx ", minstate->pmsa_br1);
- print_symbol("%s\n", minstate->pmsa_br1);
-
- printk("\nstatic registers r0-r15:\n");
- printk(" r0- 3 %016lx %016lx %016lx %016lx\n",
- 0UL, minstate->pmsa_gr[0], minstate->pmsa_gr[1], minstate->pmsa_gr[2]);
- printk(" r4- 7 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_gr[3], minstate->pmsa_gr[4],
- minstate->pmsa_gr[5], minstate->pmsa_gr[6]);
- printk(" r8-11 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_gr[7], minstate->pmsa_gr[8],
- minstate->pmsa_gr[9], minstate->pmsa_gr[10]);
- printk("r12-15 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_gr[11], minstate->pmsa_gr[12],
- minstate->pmsa_gr[13], minstate->pmsa_gr[14]);
-
- printk("\nbank 0:\n");
- printk("r16-19 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank0_gr[0], minstate->pmsa_bank0_gr[1],
- minstate->pmsa_bank0_gr[2], minstate->pmsa_bank0_gr[3]);
- printk("r20-23 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank0_gr[4], minstate->pmsa_bank0_gr[5],
- minstate->pmsa_bank0_gr[6], minstate->pmsa_bank0_gr[7]);
- printk("r24-27 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank0_gr[8], minstate->pmsa_bank0_gr[9],
- minstate->pmsa_bank0_gr[10], minstate->pmsa_bank0_gr[11]);
- printk("r28-31 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank0_gr[12], minstate->pmsa_bank0_gr[13],
- minstate->pmsa_bank0_gr[14], minstate->pmsa_bank0_gr[15]);
-
- printk("\nbank 1:\n");
- printk("r16-19 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank1_gr[0], minstate->pmsa_bank1_gr[1],
- minstate->pmsa_bank1_gr[2], minstate->pmsa_bank1_gr[3]);
- printk("r20-23 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank1_gr[4], minstate->pmsa_bank1_gr[5],
- minstate->pmsa_bank1_gr[6], minstate->pmsa_bank1_gr[7]);
- printk("r24-27 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank1_gr[8], minstate->pmsa_bank1_gr[9],
- minstate->pmsa_bank1_gr[10], minstate->pmsa_bank1_gr[11]);
- printk("r28-31 %016lx %016lx %016lx %016lx\n",
- minstate->pmsa_bank1_gr[12], minstate->pmsa_bank1_gr[13],
- minstate->pmsa_bank1_gr[14], minstate->pmsa_bank1_gr[15]);
-}
-
-static void
-fetch_min_state (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw)
-{
- u64 *dst_banked, *src_banked, bit, shift, nat_bits;
- int i;
-
- /*
- * First, update the pt-regs and switch-stack structures with the contents stored
- * in the min-state area:
- */
- if (((struct ia64_psr *) &ms->pmsa_ipsr)->ic == 0) {
- pt->cr_ipsr = ms->pmsa_xpsr;
- pt->cr_iip = ms->pmsa_xip;
- pt->cr_ifs = ms->pmsa_xfs;
- } else {
- pt->cr_ipsr = ms->pmsa_ipsr;
- pt->cr_iip = ms->pmsa_iip;
- pt->cr_ifs = ms->pmsa_ifs;
- }
- pt->ar_rsc = ms->pmsa_rsc;
- pt->pr = ms->pmsa_pr;
- pt->r1 = ms->pmsa_gr[0];
- pt->r2 = ms->pmsa_gr[1];
- pt->r3 = ms->pmsa_gr[2];
- sw->r4 = ms->pmsa_gr[3];
- sw->r5 = ms->pmsa_gr[4];
- sw->r6 = ms->pmsa_gr[5];
- sw->r7 = ms->pmsa_gr[6];
- pt->r8 = ms->pmsa_gr[7];
- pt->r9 = ms->pmsa_gr[8];
- pt->r10 = ms->pmsa_gr[9];
- pt->r11 = ms->pmsa_gr[10];
- pt->r12 = ms->pmsa_gr[11];
- pt->r13 = ms->pmsa_gr[12];
- pt->r14 = ms->pmsa_gr[13];
- pt->r15 = ms->pmsa_gr[14];
- dst_banked = &pt->r16; /* r16-r31 are contiguous in struct pt_regs */
- src_banked = ms->pmsa_bank1_gr;
- for (i = 0; i < 16; ++i)
- dst_banked[i] = src_banked[i];
- pt->b0 = ms->pmsa_br0;
- sw->b1 = ms->pmsa_br1;
-
- /* construct the NaT bits for the pt-regs structure: */
-# define PUT_NAT_BIT(dst, addr) \
- do { \
- bit = nat_bits & 1; nat_bits >>= 1; \
- shift = ((unsigned long) addr >> 3) & 0x3f; \
- dst = ((dst) & ~(1UL << shift)) | (bit << shift); \
- } while (0)
-
- /* Rotate the saved NaT bits such that bit 0 corresponds to pmsa_gr[0]: */
- shift = ((unsigned long) &ms->pmsa_gr[0] >> 3) & 0x3f;
- nat_bits = (ms->pmsa_nat_bits >> shift) | (ms->pmsa_nat_bits << (64 - shift));
-
- PUT_NAT_BIT(sw->caller_unat, &pt->r1);
- PUT_NAT_BIT(sw->caller_unat, &pt->r2);
- PUT_NAT_BIT(sw->caller_unat, &pt->r3);
- PUT_NAT_BIT(sw->ar_unat, &sw->r4);
- PUT_NAT_BIT(sw->ar_unat, &sw->r5);
- PUT_NAT_BIT(sw->ar_unat, &sw->r6);
- PUT_NAT_BIT(sw->ar_unat, &sw->r7);
- PUT_NAT_BIT(sw->caller_unat, &pt->r8); PUT_NAT_BIT(sw->caller_unat, &pt->r9);
- PUT_NAT_BIT(sw->caller_unat, &pt->r10); PUT_NAT_BIT(sw->caller_unat, &pt->r11);
- PUT_NAT_BIT(sw->caller_unat, &pt->r12); PUT_NAT_BIT(sw->caller_unat, &pt->r13);
- PUT_NAT_BIT(sw->caller_unat, &pt->r14); PUT_NAT_BIT(sw->caller_unat, &pt->r15);
- nat_bits >>= 16; /* skip over bank0 NaT bits */
- PUT_NAT_BIT(sw->caller_unat, &pt->r16); PUT_NAT_BIT(sw->caller_unat, &pt->r17);
- PUT_NAT_BIT(sw->caller_unat, &pt->r18); PUT_NAT_BIT(sw->caller_unat, &pt->r19);
- PUT_NAT_BIT(sw->caller_unat, &pt->r20); PUT_NAT_BIT(sw->caller_unat, &pt->r21);
- PUT_NAT_BIT(sw->caller_unat, &pt->r22); PUT_NAT_BIT(sw->caller_unat, &pt->r23);
- PUT_NAT_BIT(sw->caller_unat, &pt->r24); PUT_NAT_BIT(sw->caller_unat, &pt->r25);
- PUT_NAT_BIT(sw->caller_unat, &pt->r26); PUT_NAT_BIT(sw->caller_unat, &pt->r27);
- PUT_NAT_BIT(sw->caller_unat, &pt->r28); PUT_NAT_BIT(sw->caller_unat, &pt->r29);
- PUT_NAT_BIT(sw->caller_unat, &pt->r30); PUT_NAT_BIT(sw->caller_unat, &pt->r31);
-}
-
-static void
-init_handler_platform (pal_min_state_area_t *ms,
- struct pt_regs *pt, struct switch_stack *sw)
-{
- struct unw_frame_info info;
-
- /* if a kernel debugger is available call it here else just dump the registers */
-
- /*
- * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
- * generated via the BMC's command-line interface, but since the console is on the
- * same serial line, the user will need some time to switch out of the BMC before
- * the dump begins.
- */
- printk("Delaying for 5 seconds...\n");
- udelay(5*1000000);
- show_min_state(ms);
-
- printk("Backtrace of current task (pid %d, %s)\n", current->pid, current->comm);
- fetch_min_state(ms, pt, sw);
- unw_init_from_interruption(&info, current, pt, sw);
- ia64_do_show_stack(&info, NULL);
-
-#ifdef CONFIG_SMP
- /* read_trylock() would be handy... */
- if (!tasklist_lock.write_lock)
- read_lock(&tasklist_lock);
-#endif
- {
- struct task_struct *g, *t;
- do_each_thread (g, t) {
- if (t == current)
- continue;
-
- printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
- show_stack(t, NULL);
- } while_each_thread (g, t);
- }
-#ifdef CONFIG_SMP
- if (!tasklist_lock.write_lock)
- read_unlock(&tasklist_lock);
-#endif
-
- printk("\nINIT dump complete. Please reboot now.\n");
- while (1); /* hang city if no debugger */
-}
-
#ifdef CONFIG_ACPI
/*
* ia64_mca_register_cpev
@@ -657,42 +478,6 @@ ia64_mca_cmc_vector_enable_keventd(void *unused)
}
/*
- * ia64_mca_wakeup_ipi_wait
- *
- * Wait for the inter-cpu interrupt to be sent by the
- * monarch processor once it is done with handling the
- * MCA.
- *
- * Inputs : None
- * Outputs : None
- */
-static void
-ia64_mca_wakeup_ipi_wait(void)
-{
- int irr_num = (IA64_MCA_WAKEUP_VECTOR >> 6);
- int irr_bit = (IA64_MCA_WAKEUP_VECTOR & 0x3f);
- u64 irr = 0;
-
- do {
- switch(irr_num) {
- case 0:
- irr = ia64_getreg(_IA64_REG_CR_IRR0);
- break;
- case 1:
- irr = ia64_getreg(_IA64_REG_CR_IRR1);
- break;
- case 2:
- irr = ia64_getreg(_IA64_REG_CR_IRR2);
- break;
- case 3:
- irr = ia64_getreg(_IA64_REG_CR_IRR3);
- break;
- }
- cpu_relax();
- } while (!(irr & (1UL << irr_bit))) ;
-}
-
-/*
* ia64_mca_wakeup
*
* Send an inter-cpu interrupt to wake-up a particular cpu
@@ -757,11 +542,9 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
*/
ia64_sal_mc_rendez();
- /* Wait for the wakeup IPI from the monarch
- * This waiting is done by polling on the wakeup-interrupt
- * vector bit in the processor's IRRs
- */
- ia64_mca_wakeup_ipi_wait();
+ /* Wait for the monarch cpu to exit. */
+ while (monarch_cpu != -1)
+ cpu_relax(); /* spin until monarch leaves */
/* Enable all interrupts */
local_irq_restore(flags);
@@ -789,53 +572,13 @@ ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs)
return IRQ_HANDLED;
}
-/*
- * ia64_return_to_sal_check
- *
- * This is function called before going back from the OS_MCA handler
- * to the OS_MCA dispatch code which finally takes the control back
- * to the SAL.
- * The main purpose of this routine is to setup the OS_MCA to SAL
- * return state which can be used by the OS_MCA dispatch code
- * just before going back to SAL.
- *
- * Inputs : None
- * Outputs : None
- */
-
-static void
-ia64_return_to_sal_check(int recover)
-{
-
- /* Copy over some relevant stuff from the sal_to_os_mca_handoff
- * so that it can be used at the time of os_mca_to_sal_handoff
- */
- ia64_os_to_sal_handoff_state.imots_sal_gp =
- ia64_sal_to_os_handoff_state.imsto_sal_gp;
-
- ia64_os_to_sal_handoff_state.imots_sal_check_ra =
- ia64_sal_to_os_handoff_state.imsto_sal_check_ra;
-
- if (recover)
- ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_CORRECTED;
- else
- ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT;
-
- /* Default = tell SAL to return to same context */
- ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT;
-
- ia64_os_to_sal_handoff_state.imots_new_min_state =
- (u64 *)ia64_sal_to_os_handoff_state.pal_min_state;
-
-}
-
/* Function pointer for extra MCA recovery */
int (*ia64_mca_ucmc_extension)
- (void*,ia64_mca_sal_to_os_state_t*,ia64_mca_os_to_sal_state_t*)
+ (void*,struct ia64_sal_os_state*)
= NULL;
int
-ia64_reg_MCA_extension(void *fn)
+ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *))
{
if (ia64_mca_ucmc_extension)
return 1;
@@ -854,8 +597,321 @@ ia64_unreg_MCA_extension(void)
EXPORT_SYMBOL(ia64_reg_MCA_extension);
EXPORT_SYMBOL(ia64_unreg_MCA_extension);
+
+static inline void
+copy_reg(const u64 *fr, u64 fnat, u64 *tr, u64 *tnat)
+{
+ u64 fslot, tslot, nat;
+ *tr = *fr;
+ fslot = ((unsigned long)fr >> 3) & 63;
+ tslot = ((unsigned long)tr >> 3) & 63;
+ *tnat &= ~(1UL << tslot);
+ nat = (fnat >> fslot) & 1;
+ *tnat |= (nat << tslot);
+}
+
+/* On entry to this routine, we are running on the per cpu stack, see
+ * mca_asm.h. The original stack has not been touched by this event. Some of
+ * the original stack's registers will be in the RBS on this stack. This stack
+ * also contains a partial pt_regs and switch_stack, the rest of the data is in
+ * PAL minstate.
+ *
+ * The first thing to do is modify the original stack to look like a blocked
+ * task so we can run backtrace on the original task. Also mark the per cpu
+ * stack as current to ensure that we use the correct task state, it also means
+ * that we can do backtrace on the MCA/INIT handler code itself.
+ */
+
+static task_t *
+ia64_mca_modify_original_stack(struct pt_regs *regs,
+ const struct switch_stack *sw,
+ struct ia64_sal_os_state *sos,
+ const char *type)
+{
+ char *p, comm[sizeof(current->comm)];
+ ia64_va va;
+ extern char ia64_leave_kernel[]; /* Need asm address, not function descriptor */
+ const pal_min_state_area_t *ms = sos->pal_min_state;
+ task_t *previous_current;
+ struct pt_regs *old_regs;
+ struct switch_stack *old_sw;
+ unsigned size = sizeof(struct pt_regs) +
+ sizeof(struct switch_stack) + 16;
+ u64 *old_bspstore, *old_bsp;
+ u64 *new_bspstore, *new_bsp;
+ u64 old_unat, old_rnat, new_rnat, nat;
+ u64 slots, loadrs = regs->loadrs;
+ u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1];
+ u64 ar_bspstore = regs->ar_bspstore;
+ u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16);
+ const u64 *bank;
+ const char *msg;
+ int cpu = smp_processor_id();
+
+ previous_current = curr_task(cpu);
+ set_curr_task(cpu, current);
+ if ((p = strchr(current->comm, ' ')))
+ *p = '\0';
+
+ /* Best effort attempt to cope with MCA/INIT delivered while in
+ * physical mode.
+ */
+ regs->cr_ipsr = ms->pmsa_ipsr;
+ if (ia64_psr(regs)->dt == 0) {
+ va.l = r12;
+ if (va.f.reg == 0) {
+ va.f.reg = 7;
+ r12 = va.l;
+ }
+ va.l = r13;
+ if (va.f.reg == 0) {
+ va.f.reg = 7;
+ r13 = va.l;
+ }
+ }
+ if (ia64_psr(regs)->rt == 0) {
+ va.l = ar_bspstore;
+ if (va.f.reg == 0) {
+ va.f.reg = 7;
+ ar_bspstore = va.l;
+ }
+ va.l = ar_bsp;
+ if (va.f.reg == 0) {
+ va.f.reg = 7;
+ ar_bsp = va.l;
+ }
+ }
+
+ /* mca_asm.S ia64_old_stack() cannot assume that the dirty registers
+ * have been copied to the old stack, the old stack may fail the
+ * validation tests below. So ia64_old_stack() must restore the dirty
+ * registers from the new stack. The old and new bspstore probably
+ * have different alignments, so loadrs calculated on the old bsp
+ * cannot be used to restore from the new bsp. Calculate a suitable
+ * loadrs for the new stack and save it in the new pt_regs, where
+ * ia64_old_stack() can get it.
+ */
+ old_bspstore = (u64 *)ar_bspstore;
+ old_bsp = (u64 *)ar_bsp;
+ slots = ia64_rse_num_regs(old_bspstore, old_bsp);
+ new_bspstore = (u64 *)((u64)current + IA64_RBS_OFFSET);
+ new_bsp = ia64_rse_skip_regs(new_bspstore, slots);
+ regs->loadrs = (new_bsp - new_bspstore) * 8 << 16;
+
+ /* Verify the previous stack state before we change it */
+ if (user_mode(regs)) {
+ msg = "occurred in user space";
+ goto no_mod;
+ }
+ if (r13 != sos->prev_IA64_KR_CURRENT) {
+ msg = "inconsistent previous current and r13";
+ goto no_mod;
+ }
+ if ((r12 - r13) >= KERNEL_STACK_SIZE) {
+ msg = "inconsistent r12 and r13";
+ goto no_mod;
+ }
+ if ((ar_bspstore - r13) >= KERNEL_STACK_SIZE) {
+ msg = "inconsistent ar.bspstore and r13";
+ goto no_mod;
+ }
+ va.p = old_bspstore;
+ if (va.f.reg < 5) {
+ msg = "old_bspstore is in the wrong region";
+ goto no_mod;
+ }
+ if ((ar_bsp - r13) >= KERNEL_STACK_SIZE) {
+ msg = "inconsistent ar.bsp and r13";
+ goto no_mod;
+ }
+ size += (ia64_rse_skip_regs(old_bspstore, slots) - old_bspstore) * 8;
+ if (ar_bspstore + size > r12) {
+ msg = "no room for blocked state";
+ goto no_mod;
+ }
+
+ /* Change the comm field on the MCA/INT task to include the pid that
+ * was interrupted, it makes for easier debugging. If that pid was 0
+ * (swapper or nested MCA/INIT) then use the start of the previous comm
+ * field suffixed with its cpu.
+ */
+ if (previous_current->pid)
+ snprintf(comm, sizeof(comm), "%s %d",
+ current->comm, previous_current->pid);
+ else {
+ int l;
+ if ((p = strchr(previous_current->comm, ' ')))
+ l = p - previous_current->comm;
+ else
+ l = strlen(previous_current->comm);
+ snprintf(comm, sizeof(comm), "%s %*s %d",
+ current->comm, l, previous_current->comm,
+ previous_current->thread_info->cpu);
+ }
+ memcpy(current->comm, comm, sizeof(current->comm));
+
+ /* Make the original task look blocked. First stack a struct pt_regs,
+ * describing the state at the time of interrupt. mca_asm.S built a
+ * partial pt_regs, copy it and fill in the blanks using minstate.
+ */
+ p = (char *)r12 - sizeof(*regs);
+ old_regs = (struct pt_regs *)p;
+ memcpy(old_regs, regs, sizeof(*regs));
+ /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
+ * pmsa_{xip,xpsr,xfs}
+ */
+ if (ia64_psr(regs)->ic) {
+ old_regs->cr_iip = ms->pmsa_iip;
+ old_regs->cr_ipsr = ms->pmsa_ipsr;
+ old_regs->cr_ifs = ms->pmsa_ifs;
+ } else {
+ old_regs->cr_iip = ms->pmsa_xip;
+ old_regs->cr_ipsr = ms->pmsa_xpsr;
+ old_regs->cr_ifs = ms->pmsa_xfs;
+ }
+ old_regs->pr = ms->pmsa_pr;
+ old_regs->b0 = ms->pmsa_br0;
+ old_regs->loadrs = loadrs;
+ old_regs->ar_rsc = ms->pmsa_rsc;
+ old_unat = old_regs->ar_unat;
+ copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &old_regs->r1, &old_unat);
+ copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &old_regs->r2, &old_unat);
+ copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &old_regs->r3, &old_unat);
+ copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &old_regs->r8, &old_unat);
+ copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &old_regs->r9, &old_unat);
+ copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &old_regs->r10, &old_unat);
+ copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &old_regs->r11, &old_unat);
+ copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &old_regs->r12, &old_unat);
+ copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &old_regs->r13, &old_unat);
+ copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &old_regs->r14, &old_unat);
+ copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &old_regs->r15, &old_unat);
+ if (ia64_psr(old_regs)->bn)
+ bank = ms->pmsa_bank1_gr;
+ else
+ bank = ms->pmsa_bank0_gr;
+ copy_reg(&bank[16-16], ms->pmsa_nat_bits, &old_regs->r16, &old_unat);
+ copy_reg(&bank[17-16], ms->pmsa_nat_bits, &old_regs->r17, &old_unat);
+ copy_reg(&bank[18-16], ms->pmsa_nat_bits, &old_regs->r18, &old_unat);
+ copy_reg(&bank[19-16], ms->pmsa_nat_bits, &old_regs->r19, &old_unat);
+ copy_reg(&bank[20-16], ms->pmsa_nat_bits, &old_regs->r20, &old_unat);
+ copy_reg(&bank[21-16], ms->pmsa_nat_bits, &old_regs->r21, &old_unat);
+ copy_reg(&bank[22-16], ms->pmsa_nat_bits, &old_regs->r22, &old_unat);
+ copy_reg(&bank[23-16], ms->pmsa_nat_bits, &old_regs->r23, &old_unat);
+ copy_reg(&bank[24-16], ms->pmsa_nat_bits, &old_regs->r24, &old_unat);
+ copy_reg(&bank[25-16], ms->pmsa_nat_bits, &old_regs->r25, &old_unat);
+ copy_reg(&bank[26-16], ms->pmsa_nat_bits, &old_regs->r26, &old_unat);
+ copy_reg(&bank[27-16], ms->pmsa_nat_bits, &old_regs->r27, &old_unat);
+ copy_reg(&bank[28-16], ms->pmsa_nat_bits, &old_regs->r28, &old_unat);
+ copy_reg(&bank[29-16], ms->pmsa_nat_bits, &old_regs->r29, &old_unat);
+ copy_reg(&bank[30-16], ms->pmsa_nat_bits, &old_regs->r30, &old_unat);
+ copy_reg(&bank[31-16], ms->pmsa_nat_bits, &old_regs->r31, &old_unat);
+
+ /* Next stack a struct switch_stack. mca_asm.S built a partial
+ * switch_stack, copy it and fill in the blanks using pt_regs and
+ * minstate.
+ *
+ * In the synthesized switch_stack, b0 points to ia64_leave_kernel,
+ * ar.pfs is set to 0.
+ *
+ * unwind.c::unw_unwind() does special processing for interrupt frames.
+ * It checks if the PRED_NON_SYSCALL predicate is set, if the predicate
+ * is clear then unw_unwind() does _not_ adjust bsp over pt_regs. Not
+ * that this is documented, of course. Set PRED_NON_SYSCALL in the
+ * switch_stack on the original stack so it will unwind correctly when
+ * unwind.c reads pt_regs.
+ *
+ * thread.ksp is updated to point to the synthesized switch_stack.
+ */
+ p -= sizeof(struct switch_stack);
+ old_sw = (struct switch_stack *)p;
+ memcpy(old_sw, sw, sizeof(*sw));
+ old_sw->caller_unat = old_unat;
+ old_sw->ar_fpsr = old_regs->ar_fpsr;
+ copy_reg(&ms->pmsa_gr[4-1], ms->pmsa_nat_bits, &old_sw->r4, &old_unat);
+ copy_reg(&ms->pmsa_gr[5-1], ms->pmsa_nat_bits, &old_sw->r5, &old_unat);
+ copy_reg(&ms->pmsa_gr[6-1], ms->pmsa_nat_bits, &old_sw->r6, &old_unat);
+ copy_reg(&ms->pmsa_gr[7-1], ms->pmsa_nat_bits, &old_sw->r7, &old_unat);
+ old_sw->b0 = (u64)ia64_leave_kernel;
+ old_sw->b1 = ms->pmsa_br1;
+ old_sw->ar_pfs = 0;
+ old_sw->ar_unat = old_unat;
+ old_sw->pr = old_regs->pr | (1UL << PRED_NON_SYSCALL);
+ previous_current->thread.ksp = (u64)p - 16;
+
+ /* Finally copy the original stack's registers back to its RBS.
+ * Registers from ar.bspstore through ar.bsp at the time of the event
+ * are in the current RBS, copy them back to the original stack. The
+ * copy must be done register by register because the original bspstore
+ * and the current one have different alignments, so the saved RNAT
+ * data occurs at different places.
+ *
+ * mca_asm does cover, so the old_bsp already includes all registers at
+ * the time of MCA/INIT. It also does flushrs, so all registers before
+ * this function have been written to backing store on the MCA/INIT
+ * stack.
+ */
+ new_rnat = ia64_get_rnat(ia64_rse_rnat_addr(new_bspstore));
+ old_rnat = regs->ar_rnat;
+ while (slots--) {
+ if (ia64_rse_is_rnat_slot(new_bspstore)) {
+ new_rnat = ia64_get_rnat(new_bspstore++);
+ }
+ if (ia64_rse_is_rnat_slot(old_bspstore)) {
+ *old_bspstore++ = old_rnat;
+ old_rnat = 0;
+ }
+ nat = (new_rnat >> ia64_rse_slot_num(new_bspstore)) & 1UL;
+ old_rnat &= ~(1UL << ia64_rse_slot_num(old_bspstore));
+ old_rnat |= (nat << ia64_rse_slot_num(old_bspstore));
+ *old_bspstore++ = *new_bspstore++;
+ }
+ old_sw->ar_bspstore = (unsigned long)old_bspstore;
+ old_sw->ar_rnat = old_rnat;
+
+ sos->prev_task = previous_current;
+ return previous_current;
+
+no_mod:
+ printk(KERN_INFO "cpu %d, %s %s, original stack not modified\n",
+ smp_processor_id(), type, msg);
+ return previous_current;
+}
+
+/* The monarch/slave interaction is based on monarch_cpu and requires that all
+ * slaves have entered rendezvous before the monarch leaves. If any cpu has
+ * not entered rendezvous yet then wait a bit. The assumption is that any
+ * slave that has not rendezvoused after a reasonable time is never going to do
+ * so. In this context, slave includes cpus that respond to the MCA rendezvous
+ * interrupt, as well as cpus that receive the INIT slave event.
+ */
+
+static void
+ia64_wait_for_slaves(int monarch)
+{
+ int c, wait = 0;
+ for_each_online_cpu(c) {
+ if (c == monarch)
+ continue;
+ if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) {
+ udelay(1000); /* short wait first */
+ wait = 1;
+ break;
+ }
+ }
+ if (!wait)
+ return;
+ for_each_online_cpu(c) {
+ if (c == monarch)
+ continue;
+ if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) {
+ udelay(5*1000000); /* wait 5 seconds for slaves (arbitrary) */
+ break;
+ }
+ }
+}
+
/*
- * ia64_mca_ucmc_handler
+ * ia64_mca_handler
*
* This is uncorrectable machine check handler called from OS_MCA
* dispatch code which is in turn called from SAL_CHECK().
@@ -866,16 +922,28 @@ EXPORT_SYMBOL(ia64_unreg_MCA_extension);
* further MCA logging is enabled by clearing logs.
* Monarch also has the duty of sending wakeup-IPIs to pull the
* slave processors out of rendezvous spinloop.
- *
- * Inputs : None
- * Outputs : None
*/
void
-ia64_mca_ucmc_handler(void)
+ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
+ struct ia64_sal_os_state *sos)
{
pal_processor_state_info_t *psp = (pal_processor_state_info_t *)
- &ia64_sal_to_os_handoff_state.proc_state_param;
- int recover;
+ &sos->proc_state_param;
+ int recover, cpu = smp_processor_id();
+ task_t *previous_current;
+
+ oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
+ previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
+ monarch_cpu = cpu;
+ ia64_wait_for_slaves(cpu);
+
+ /* Wakeup all the processors which are spinning in the rendezvous loop.
+ * They will leave SAL, then spin in the OS with interrupts disabled
+ * until this monarch cpu leaves the MCA handler. That gets control
+ * back to the OS so we can backtrace the other cpus, backtrace when
+ * spinning in SAL does not work.
+ */
+ ia64_mca_wakeup_all();
/* Get the MCA error record and log it */
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
@@ -883,25 +951,20 @@ ia64_mca_ucmc_handler(void)
/* TLB error is only exist in this SAL error record */
recover = (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc))
/* other error recovery */
- || (ia64_mca_ucmc_extension
+ || (ia64_mca_ucmc_extension
&& ia64_mca_ucmc_extension(
IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA),
- &ia64_sal_to_os_handoff_state,
- &ia64_os_to_sal_handoff_state));
+ sos));
if (recover) {
sal_log_record_header_t *rh = IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA);
rh->severity = sal_log_severity_corrected;
ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
+ sos->os_status = IA64_MCA_CORRECTED;
}
- /*
- * Wakeup all the processors which are spinning in the rendezvous
- * loop.
- */
- ia64_mca_wakeup_all();
- /* Return to SAL */
- ia64_return_to_sal_check(recover);
+ set_curr_task(cpu, previous_current);
+ monarch_cpu = -1;
}
static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL);
@@ -953,6 +1016,11 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
cmc_polling_enabled = 1;
spin_unlock(&cmc_history_lock);
+ /* If we're being hit with CMC interrupts, we won't
+ * ever execute the schedule_work() below. Need to
+ * disable CMC interrupts on this processor now.
+ */
+ ia64_mca_cmc_vector_disable(NULL);
schedule_work(&cmc_disable_work);
/*
@@ -1125,34 +1193,114 @@ ia64_mca_cpe_poll (unsigned long dummy)
/*
* C portion of the OS INIT handler
*
- * Called from ia64_monarch_init_handler
- *
- * Inputs: pointer to pt_regs where processor info was saved.
+ * Called from ia64_os_init_dispatch
*
- * Returns:
- * 0 if SAL must warm boot the System
- * 1 if SAL must return to interrupted context using PAL_MC_RESUME
+ * Inputs: pointer to pt_regs where processor info was saved. SAL/OS state for
+ * this event. This code is used for both monarch and slave INIT events, see
+ * sos->monarch.
*
+ * All INIT events switch to the INIT stack and change the previous process to
+ * blocked status. If one of the INIT events is the monarch then we are
+ * probably processing the nmi button/command. Use the monarch cpu to dump all
+ * the processes. The slave INIT events all spin until the monarch cpu
+ * returns. We can also get INIT slave events for MCA, in which case the MCA
+ * process is the monarch.
*/
+
void
-ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
+ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
+ struct ia64_sal_os_state *sos)
{
- pal_min_state_area_t *ms;
+ static atomic_t slaves;
+ static atomic_t monarchs;
+ task_t *previous_current;
+ int cpu = smp_processor_id(), c;
+ struct task_struct *g, *t;
- oops_in_progress = 1; /* avoid deadlock in printk, but it makes recovery dodgy */
+ oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
console_loglevel = 15; /* make sure printks make it to console */
- printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
- ia64_sal_to_os_handoff_state.proc_state_param);
+ printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n",
+ sos->proc_state_param, cpu, sos->monarch);
+ salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0);
- /*
- * Address of minstate area provided by PAL is physical,
- * uncacheable (bit 63 set). Convert to Linux virtual
- * address in region 6.
+ previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "INIT");
+ sos->os_status = IA64_INIT_RESUME;
+
+ /* FIXME: Workaround for broken proms that drive all INIT events as
+ * slaves. The last slave that enters is promoted to be a monarch.
+ * Remove this code in September 2006, that gives platforms a year to
+ * fix their proms and get their customers updated.
*/
- ms = (pal_min_state_area_t *)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61));
+ if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) {
+ printk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n",
+ __FUNCTION__, cpu);
+ atomic_dec(&slaves);
+ sos->monarch = 1;
+ }
+
+ /* FIXME: Workaround for broken proms that drive all INIT events as
+ * monarchs. Second and subsequent monarchs are demoted to slaves.
+ * Remove this code in September 2006, that gives platforms a year to
+ * fix their proms and get their customers updated.
+ */
+ if (sos->monarch && atomic_add_return(1, &monarchs) > 1) {
+ printk(KERN_WARNING "%s: Demoting cpu %d to slave.\n",
+ __FUNCTION__, cpu);
+ atomic_dec(&monarchs);
+ sos->monarch = 0;
+ }
- init_handler_platform(ms, pt, sw); /* call platform specific routines */
+ if (!sos->monarch) {
+ ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
+ while (monarch_cpu == -1)
+ cpu_relax(); /* spin until monarch enters */
+ while (monarch_cpu != -1)
+ cpu_relax(); /* spin until monarch leaves */
+ printk("Slave on cpu %d returning to normal service.\n", cpu);
+ set_curr_task(cpu, previous_current);
+ ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
+ atomic_dec(&slaves);
+ return;
+ }
+
+ monarch_cpu = cpu;
+
+ /*
+ * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
+ * generated via the BMC's command-line interface, but since the console is on the
+ * same serial line, the user will need some time to switch out of the BMC before
+ * the dump begins.
+ */
+ printk("Delaying for 5 seconds...\n");
+ udelay(5*1000000);
+ ia64_wait_for_slaves(cpu);
+ printk(KERN_ERR "Processes interrupted by INIT -");
+ for_each_online_cpu(c) {
+ struct ia64_sal_os_state *s;
+ t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
+ s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
+ g = s->prev_task;
+ if (g) {
+ if (g->pid)
+ printk(" %d", g->pid);
+ else
+ printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
+ }
+ }
+ printk("\n\n");
+ if (read_trylock(&tasklist_lock)) {
+ do_each_thread (g, t) {
+ printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
+ show_stack(t, NULL);
+ } while_each_thread (g, t);
+ read_unlock(&tasklist_lock);
+ }
+ printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
+ atomic_dec(&monarchs);
+ set_curr_task(cpu, previous_current);
+ monarch_cpu = -1;
+ return;
}
static int __init
@@ -1202,6 +1350,34 @@ static struct irqaction mca_cpep_irqaction = {
};
#endif /* CONFIG_ACPI */
+/* Minimal format of the MCA/INIT stacks. The pseudo processes that run on
+ * these stacks can never sleep, they cannot return from the kernel to user
+ * space, they do not appear in a normal ps listing. So there is no need to
+ * format most of the fields.
+ */
+
+static void
+format_mca_init_stack(void *mca_data, unsigned long offset,
+ const char *type, int cpu)
+{
+ struct task_struct *p = (struct task_struct *)((char *)mca_data + offset);
+ struct thread_info *ti;
+ memset(p, 0, KERNEL_STACK_SIZE);
+ ti = (struct thread_info *)((char *)p + IA64_TASK_SIZE);
+ ti->flags = _TIF_MCA_INIT;
+ ti->preempt_count = 1;
+ ti->task = p;
+ ti->cpu = cpu;
+ p->thread_info = ti;
+ p->state = TASK_UNINTERRUPTIBLE;
+ __set_bit(cpu, &p->cpus_allowed);
+ INIT_LIST_HEAD(&p->tasks);
+ p->parent = p->real_parent = p->group_leader = p;
+ INIT_LIST_HEAD(&p->children);
+ INIT_LIST_HEAD(&p->sibling);
+ strncpy(p->comm, type, sizeof(p->comm)-1);
+}
+
/* Do per-CPU MCA-related initialization. */
void __devinit
@@ -1214,19 +1390,28 @@ ia64_mca_cpu_init(void *cpu_data)
int cpu;
mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
- * NR_CPUS);
+ * NR_CPUS + KERNEL_STACK_SIZE);
+ mca_data = (void *)(((unsigned long)mca_data +
+ KERNEL_STACK_SIZE - 1) &
+ (-KERNEL_STACK_SIZE));
for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ format_mca_init_stack(mca_data,
+ offsetof(struct ia64_mca_cpu, mca_stack),
+ "MCA", cpu);
+ format_mca_init_stack(mca_data,
+ offsetof(struct ia64_mca_cpu, init_stack),
+ "INIT", cpu);
__per_cpu_mca[cpu] = __pa(mca_data);
mca_data += sizeof(struct ia64_mca_cpu);
}
}
- /*
- * The MCA info structure was allocated earlier and its
- * physical address saved in __per_cpu_mca[cpu]. Copy that
- * address * to ia64_mca_data so we can access it as a per-CPU
- * variable.
- */
+ /*
+ * The MCA info structure was allocated earlier and its
+ * physical address saved in __per_cpu_mca[cpu]. Copy that
+ * address * to ia64_mca_data so we can access it as a per-CPU
+ * variable.
+ */
__get_cpu_var(ia64_mca_data) = __per_cpu_mca[smp_processor_id()];
/*
@@ -1236,11 +1421,11 @@ ia64_mca_cpu_init(void *cpu_data)
__get_cpu_var(ia64_mca_per_cpu_pte) =
pte_val(mk_pte_phys(__pa(cpu_data), PAGE_KERNEL));
- /*
- * Also, stash away a copy of the PAL address and the PTE
- * needed to map it.
- */
- pal_vaddr = efi_get_pal_addr();
+ /*
+ * Also, stash away a copy of the PAL address and the PTE
+ * needed to map it.
+ */
+ pal_vaddr = efi_get_pal_addr();
if (!pal_vaddr)
return;
__get_cpu_var(ia64_mca_pal_base) =
@@ -1272,8 +1457,8 @@ ia64_mca_cpu_init(void *cpu_data)
void __init
ia64_mca_init(void)
{
- ia64_fptr_t *mon_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler;
- ia64_fptr_t *slave_init_ptr = (ia64_fptr_t *)ia64_slave_init_handler;
+ ia64_fptr_t *init_hldlr_ptr_monarch = (ia64_fptr_t *)ia64_os_init_dispatch_monarch;
+ ia64_fptr_t *init_hldlr_ptr_slave = (ia64_fptr_t *)ia64_os_init_dispatch_slave;
ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
int i;
s64 rc;
@@ -1351,9 +1536,9 @@ ia64_mca_init(void)
* XXX - disable SAL checksum by setting size to 0, should be
* size of the actual init handler in mca_asm.S.
*/
- ia64_mc_info.imi_monarch_init_handler = ia64_tpa(mon_init_ptr->fp);
+ ia64_mc_info.imi_monarch_init_handler = ia64_tpa(init_hldlr_ptr_monarch->fp);
ia64_mc_info.imi_monarch_init_handler_size = 0;
- ia64_mc_info.imi_slave_init_handler = ia64_tpa(slave_init_ptr->fp);
+ ia64_mc_info.imi_slave_init_handler = ia64_tpa(init_hldlr_ptr_slave->fp);
ia64_mc_info.imi_slave_init_handler_size = 0;
IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __FUNCTION__,
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index ef3fd7265b67..db32fc1d3935 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -16,6 +16,9 @@
// 04/11/12 Russ Anderson <rja@sgi.com>
// Added per cpu MCA/INIT stack save areas.
//
+// 12/08/05 Keith Owens <kaos@sgi.com>
+// Use per cpu MCA/INIT stacks for all data.
+//
#include <linux/config.h>
#include <linux/threads.h>
@@ -25,96 +28,23 @@
#include <asm/mca_asm.h>
#include <asm/mca.h>
-/*
- * When we get a machine check, the kernel stack pointer is no longer
- * valid, so we need to set a new stack pointer.
- */
-#define MINSTATE_PHYS /* Make sure stack access is physical for MINSTATE */
-
-/*
- * Needed for return context to SAL
- */
-#define IA64_MCA_SAME_CONTEXT 0
-#define IA64_MCA_COLD_BOOT -2
-
-#include "minstate.h"
-
-/*
- * SAL_TO_OS_MCA_HANDOFF_STATE (SAL 3.0 spec)
- * 1. GR1 = OS GP
- * 2. GR8 = PAL_PROC physical address
- * 3. GR9 = SAL_PROC physical address
- * 4. GR10 = SAL GP (physical)
- * 5. GR11 = Rendez state
- * 6. GR12 = Return address to location within SAL_CHECK
- */
-#define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp) \
- LOAD_PHYSICAL(p0, _tmp, ia64_sal_to_os_handoff_state);; \
- st8 [_tmp]=r1,0x08;; \
- st8 [_tmp]=r8,0x08;; \
- st8 [_tmp]=r9,0x08;; \
- st8 [_tmp]=r10,0x08;; \
- st8 [_tmp]=r11,0x08;; \
- st8 [_tmp]=r12,0x08;; \
- st8 [_tmp]=r17,0x08;; \
- st8 [_tmp]=r18,0x08
-
-/*
- * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
- * (p6) is executed if we never entered virtual mode (TLB error)
- * (p7) is executed if we entered virtual mode as expected (normal case)
- * 1. GR8 = OS_MCA return status
- * 2. GR9 = SAL GP (physical)
- * 3. GR10 = 0/1 returning same/new context
- * 4. GR22 = New min state save area pointer
- * returns ptr to SAL rtn save loc in _tmp
- */
-#define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp) \
- movl _tmp=ia64_os_to_sal_handoff_state;; \
- DATA_VA_TO_PA(_tmp);; \
- ld8 r8=[_tmp],0x08;; \
- ld8 r9=[_tmp],0x08;; \
- ld8 r10=[_tmp],0x08;; \
- ld8 r22=[_tmp],0x08;;
- // now _tmp is pointing to SAL rtn save location
-
-/*
- * COLD_BOOT_HANDOFF_STATE() sets ia64_mca_os_to_sal_state
- * imots_os_status=IA64_MCA_COLD_BOOT
- * imots_sal_gp=SAL GP
- * imots_context=IA64_MCA_SAME_CONTEXT
- * imots_new_min_state=Min state save area pointer
- * imots_sal_check_ra=Return address to location within SAL_CHECK
- *
- */
-#define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\
- movl tmp=IA64_MCA_COLD_BOOT; \
- movl sal_to_os_handoff=__pa(ia64_sal_to_os_handoff_state); \
- movl os_to_sal_handoff=__pa(ia64_os_to_sal_handoff_state);; \
- st8 [os_to_sal_handoff]=tmp,8;; \
- ld8 tmp=[sal_to_os_handoff],48;; \
- st8 [os_to_sal_handoff]=tmp,8;; \
- movl tmp=IA64_MCA_SAME_CONTEXT;; \
- st8 [os_to_sal_handoff]=tmp,8;; \
- ld8 tmp=[sal_to_os_handoff],-8;; \
- st8 [os_to_sal_handoff]=tmp,8;; \
- ld8 tmp=[sal_to_os_handoff];; \
- st8 [os_to_sal_handoff]=tmp;;
+#include "entry.h"
#define GET_IA64_MCA_DATA(reg) \
GET_THIS_PADDR(reg, ia64_mca_data) \
;; \
ld8 reg=[reg]
- .global ia64_os_mca_dispatch
- .global ia64_os_mca_dispatch_end
- .global ia64_sal_to_os_handoff_state
- .global ia64_os_to_sal_handoff_state
.global ia64_do_tlb_purge
+ .global ia64_os_mca_dispatch
+ .global ia64_os_init_dispatch_monarch
+ .global ia64_os_init_dispatch_slave
.text
.align 16
+//StartMain////////////////////////////////////////////////////////////////////
+
/*
* Just the TLB purge part is moved to a separate function
* so we can re-use the code for cpu hotplug code as well
@@ -207,34 +137,31 @@ ia64_do_tlb_purge:
br.sptk.many b1
;;
-ia64_os_mca_dispatch:
+//EndMain//////////////////////////////////////////////////////////////////////
+
+//StartMain////////////////////////////////////////////////////////////////////
+ia64_os_mca_dispatch:
// Serialize all MCA processing
mov r3=1;;
LOAD_PHYSICAL(p0,r2,ia64_mca_serialize);;
ia64_os_mca_spin:
- xchg8 r4=[r2],r3;;
+ xchg4 r4=[r2],r3;;
cmp.ne p6,p0=r4,r0
(p6) br ia64_os_mca_spin
- // Save the SAL to OS MCA handoff state as defined
- // by SAL SPEC 3.0
- // NOTE : The order in which the state gets saved
- // is dependent on the way the C-structure
- // for ia64_mca_sal_to_os_state_t has been
- // defined in include/asm/mca.h
- SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
- ;;
-
- // LOG PROCESSOR STATE INFO FROM HERE ON..
-begin_os_mca_dump:
- br ia64_os_mca_proc_state_dump;;
-
-ia64_os_mca_done_dump:
+ mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ mov r19=1 // All MCA events are treated as monarch (for now)
+ br.sptk ia64_state_save // save the state that is not in minstate
+1:
- LOAD_PHYSICAL(p0,r16,ia64_sal_to_os_handoff_state+56)
+ GET_IA64_MCA_DATA(r2)
+ // Using MCA stack, struct ia64_sal_os_state, variable proc_state_param
+ ;;
+ add r3=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SOS_OFFSET+IA64_SAL_OS_STATE_PROC_STATE_PARAM_OFFSET, r2
;;
- ld8 r18=[r16] // Get processor state parameter on existing PALE_CHECK.
+ ld8 r18=[r3] // Get processor state parameter on existing PALE_CHECK.
;;
tbit.nz p6,p7=r18,60
(p7) br.spnt done_tlb_purge_and_reload
@@ -323,624 +250,849 @@ ia64_reload_tr:
itr.d dtr[r20]=r16
;;
srlz.d
- ;;
- br.sptk.many done_tlb_purge_and_reload
-err:
- COLD_BOOT_HANDOFF_STATE(r20,r21,r22)
- br.sptk.many ia64_os_mca_done_restore
done_tlb_purge_and_reload:
- // Setup new stack frame for OS_MCA handling
- GET_IA64_MCA_DATA(r2)
- ;;
- add r3 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2
- add r2 = IA64_MCA_CPU_RBSTORE_OFFSET, r2
- ;;
- rse_switch_context(r6,r3,r2);; // RSC management in this new context
+ // switch to per cpu MCA stack
+ mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_new_stack
+1:
+
+ // everything saved, now we can set the kernel registers
+ mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_set_kernel_registers
+1:
+ // This must be done in physical mode
GET_IA64_MCA_DATA(r2)
;;
- add r2 = IA64_MCA_CPU_STACK_OFFSET+IA64_MCA_STACK_SIZE-16, r2
- ;;
- mov r12=r2 // establish new stack-pointer
+ mov r7=r2
// Enter virtual mode from physical mode
VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
-ia64_os_mca_virtual_begin:
+
+ // This code returns to SAL via SOS r2, in general SAL has no unwind
+ // data. To get a clean termination when backtracing the C MCA/INIT
+ // handler, set a dummy return address of 0 in this routine. That
+ // requires that ia64_os_mca_virtual_begin be a global function.
+ENTRY(ia64_os_mca_virtual_begin)
+ .prologue
+ .save rp,r0
+ .body
+
+ mov ar.rsc=3 // set eager mode for C handler
+ mov r2=r7 // see GET_IA64_MCA_DATA above
+ ;;
// Call virtual mode handler
- movl r2=ia64_mca_ucmc_handler;;
- mov b6=r2;;
- br.call.sptk.many b0=b6;;
-.ret0:
+ alloc r14=ar.pfs,0,0,3,0
+ ;;
+ DATA_PA_TO_VA(r2,r7)
+ ;;
+ add out0=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_PT_REGS_OFFSET, r2
+ add out1=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SWITCH_STACK_OFFSET, r2
+ add out2=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SOS_OFFSET, r2
+ br.call.sptk.many b0=ia64_mca_handler
+
// Revert back to physical mode before going back to SAL
PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)
ia64_os_mca_virtual_end:
- // restore the original stack frame here
+END(ia64_os_mca_virtual_begin)
+
+ // switch back to previous stack
+ alloc r14=ar.pfs,0,0,0,0 // remove the MCA handler frame
+ mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_old_stack
+1:
+
+ mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_state_restore // restore the SAL state
+1:
+
+ mov b0=r12 // SAL_CHECK return address
+
+ // release lock
+ LOAD_PHYSICAL(p0,r3,ia64_mca_serialize);;
+ st4.rel [r3]=r0
+
+ br b0
+
+//EndMain//////////////////////////////////////////////////////////////////////
+
+//StartMain////////////////////////////////////////////////////////////////////
+
+//
+// SAL to OS entry point for INIT on all processors. This has been defined for
+// registration purposes with SAL as a part of ia64_mca_init. Monarch and
+// slave INIT have identical processing, except for the value of the
+// sos->monarch flag in r19.
+//
+
+ia64_os_init_dispatch_monarch:
+ mov r19=1 // Bow, bow, ye lower middle classes!
+ br.sptk ia64_os_init_dispatch
+
+ia64_os_init_dispatch_slave:
+ mov r19=0 // <igor>yeth, mathter</igor>
+
+ia64_os_init_dispatch:
+
+ mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_state_save // save the state that is not in minstate
+1:
+
+ // switch to per cpu INIT stack
+ mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_new_stack
+1:
+
+ // everything saved, now we can set the kernel registers
+ mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_set_kernel_registers
+1:
+
+ // This must be done in physical mode
GET_IA64_MCA_DATA(r2)
;;
- add r2 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2
- ;;
- movl r4=IA64_PSR_MC
+ mov r7=r2
+
+ // Enter virtual mode from physical mode
+ VIRTUAL_MODE_ENTER(r2, r3, ia64_os_init_virtual_begin, r4)
+
+ // This code returns to SAL via SOS r2, in general SAL has no unwind
+ // data. To get a clean termination when backtracing the C MCA/INIT
+ // handler, set a dummy return address of 0 in this routine. That
+ // requires that ia64_os_init_virtual_begin be a global function.
+ENTRY(ia64_os_init_virtual_begin)
+ .prologue
+ .save rp,r0
+ .body
+
+ mov ar.rsc=3 // set eager mode for C handler
+ mov r2=r7 // see GET_IA64_MCA_DATA above
;;
- rse_return_context(r4,r3,r2) // switch from interrupt context for RSE
- // let us restore all the registers from our PSI structure
- mov r8=gp
+ // Call virtual mode handler
+ alloc r14=ar.pfs,0,0,3,0
;;
-begin_os_mca_restore:
- br ia64_os_mca_proc_state_restore;;
+ DATA_PA_TO_VA(r2,r7)
+ ;;
+ add out0=IA64_MCA_CPU_INIT_STACK_OFFSET+MCA_PT_REGS_OFFSET, r2
+ add out1=IA64_MCA_CPU_INIT_STACK_OFFSET+MCA_SWITCH_STACK_OFFSET, r2
+ add out2=IA64_MCA_CPU_INIT_STACK_OFFSET+MCA_SOS_OFFSET, r2
+ br.call.sptk.many b0=ia64_init_handler
-ia64_os_mca_done_restore:
- OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2);;
- // branch back to SALE_CHECK
- ld8 r3=[r2];;
- mov b0=r3;; // SAL_CHECK return address
+ // Revert back to physical mode before going back to SAL
+ PHYSICAL_MODE_ENTER(r2, r3, ia64_os_init_virtual_end, r4)
+ia64_os_init_virtual_end:
- // release lock
- movl r3=ia64_mca_serialize;;
- DATA_VA_TO_PA(r3);;
- st8.rel [r3]=r0
+END(ia64_os_init_virtual_begin)
+ mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_state_restore // restore the SAL state
+1:
+
+ // switch back to previous stack
+ alloc r14=ar.pfs,0,0,0,0 // remove the INIT handler frame
+ mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
+ LOAD_PHYSICAL(p0,r2,1f) // return address
+ br.sptk ia64_old_stack
+1:
+
+ mov b0=r12 // SAL_CHECK return address
br b0
- ;;
-ia64_os_mca_dispatch_end:
+
//EndMain//////////////////////////////////////////////////////////////////////
+// common defines for the stubs
+#define ms r4
+#define regs r5
+#define temp1 r2 /* careful, it overlaps with input registers */
+#define temp2 r3 /* careful, it overlaps with input registers */
+#define temp3 r7
+#define temp4 r14
+
//++
// Name:
-// ia64_os_mca_proc_state_dump()
+// ia64_state_save()
//
// Stub Description:
//
-// This stub dumps the processor state during MCHK to a data area
+// Save the state that is not in minstate. This is sensitive to the layout of
+// struct ia64_sal_os_state in mca.h.
+//
+// r2 contains the return address, r3 contains either
+// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
+//
+// The OS to SAL section of struct ia64_sal_os_state is set to a default
+// value of cold boot (MCA) or warm boot (INIT) and return to the same
+// context. ia64_sal_os_state is also used to hold some registers that
+// need to be saved and restored across the stack switches.
+//
+// Most input registers to this stub come from PAL/SAL
+// r1 os gp, physical
+// r8 pal_proc entry point
+// r9 sal_proc entry point
+// r10 sal gp
+// r11 MCA - rendevzous state, INIT - reason code
+// r12 sal return address
+// r17 pal min_state
+// r18 processor state parameter
+// r19 monarch flag, set by the caller of this routine
+//
+// In addition to the SAL to OS state, this routine saves all the
+// registers that appear in struct pt_regs and struct switch_stack,
+// excluding those that are already in the PAL minstate area. This
+// results in a partial pt_regs and switch_stack, the C code copies the
+// remaining registers from PAL minstate to pt_regs and switch_stack. The
+// resulting structures contain all the state of the original process when
+// MCA/INIT occurred.
//
//--
-ia64_os_mca_proc_state_dump:
-// Save bank 1 GRs 16-31 which will be used by c-language code when we switch
-// to virtual addressing mode.
- GET_IA64_MCA_DATA(r2)
+ia64_state_save:
+ add regs=MCA_SOS_OFFSET, r3
+ add ms=MCA_SOS_OFFSET+8, r3
+ mov b0=r2 // save return address
+ cmp.eq p1,p2=IA64_MCA_CPU_MCA_STACK_OFFSET, r3
+ ;;
+ GET_IA64_MCA_DATA(temp2)
+ ;;
+ add temp1=temp2, regs // struct ia64_sal_os_state on MCA or INIT stack
+ add temp2=temp2, ms // struct ia64_sal_os_state+8 on MCA or INIT stack
+ ;;
+ mov regs=temp1 // save the start of sos
+ st8 [temp1]=r1,16 // os_gp
+ st8 [temp2]=r8,16 // pal_proc
+ ;;
+ st8 [temp1]=r9,16 // sal_proc
+ st8 [temp2]=r11,16 // rv_rc
+ mov r11=cr.iipa
;;
- add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2
- ;;
-// save ar.NaT
- mov r5=ar.unat // ar.unat
-
-// save banked GRs 16-31 along with NaT bits
- bsw.1;;
- st8.spill [r2]=r16,8;;
- st8.spill [r2]=r17,8;;
- st8.spill [r2]=r18,8;;
- st8.spill [r2]=r19,8;;
- st8.spill [r2]=r20,8;;
- st8.spill [r2]=r21,8;;
- st8.spill [r2]=r22,8;;
- st8.spill [r2]=r23,8;;
- st8.spill [r2]=r24,8;;
- st8.spill [r2]=r25,8;;
- st8.spill [r2]=r26,8;;
- st8.spill [r2]=r27,8;;
- st8.spill [r2]=r28,8;;
- st8.spill [r2]=r29,8;;
- st8.spill [r2]=r30,8;;
- st8.spill [r2]=r31,8;;
-
- mov r4=ar.unat;;
- st8 [r2]=r4,8 // save User NaT bits for r16-r31
- mov ar.unat=r5 // restore original unat
- bsw.0;;
-
-//save BRs
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2 // duplicate r2 in r4
-
- mov r3=b0
- mov r5=b1
- mov r7=b2;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=b3
- mov r5=b4
- mov r7=b5;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=b6
- mov r5=b7;;
- st8 [r2]=r3,2*8
- st8 [r4]=r5,2*8;;
-
-cSaveCRs:
-// save CRs
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2 // duplicate r2 in r4
-
- mov r3=cr.dcr
- mov r5=cr.itm
- mov r7=cr.iva;;
-
- st8 [r2]=r3,8*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;; // 48 byte rements
-
- mov r3=cr.pta;;
- st8 [r2]=r3,8*8;; // 64 byte rements
-
-// if PSR.ic=0, reading interruption registers causes an illegal operation fault
- mov r3=psr;;
- tbit.nz.unc p6,p0=r3,PSR_IC;; // PSI Valid Log bit pos. test
-(p6) st8 [r2]=r0,9*8+160 // increment by 232 byte inc.
-begin_skip_intr_regs:
-(p6) br SkipIntrRegs;;
-
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2 // duplicate r2 in r6
-
- mov r3=cr.ipsr
- mov r5=cr.isr
- mov r7=r0;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=cr.iip
- mov r5=cr.ifa
- mov r7=cr.itir;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=cr.iipa
- mov r5=cr.ifs
- mov r7=cr.iim;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=cr25;; // cr.iha
- st8 [r2]=r3,160;; // 160 byte rement
-
-SkipIntrRegs:
- st8 [r2]=r0,152;; // another 152 byte .
-
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2 // duplicate r2 in r6
-
- mov r3=cr.lid
-// mov r5=cr.ivr // cr.ivr, don't read it
- mov r7=cr.tpr;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=r0 // cr.eoi => cr67
- mov r5=r0 // cr.irr0 => cr68
- mov r7=r0;; // cr.irr1 => cr69
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=r0 // cr.irr2 => cr70
- mov r5=r0 // cr.irr3 => cr71
- mov r7=cr.itv;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=cr.pmv
- mov r5=cr.cmcv;;
- st8 [r2]=r3,7*8
- st8 [r4]=r5,7*8;;
-
- mov r3=r0 // cr.lrr0 => cr80
- mov r5=r0;; // cr.lrr1 => cr81
- st8 [r2]=r3,23*8
- st8 [r4]=r5,23*8;;
-
- adds r2=25*8,r2;;
-
-cSaveARs:
-// save ARs
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2 // duplicate r2 in r6
-
- mov r3=ar.k0
- mov r5=ar.k1
- mov r7=ar.k2;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=ar.k3
- mov r5=ar.k4
- mov r7=ar.k5;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=ar.k6
- mov r5=ar.k7
- mov r7=r0;; // ar.kr8
- st8 [r2]=r3,10*8
- st8 [r4]=r5,10*8
- st8 [r6]=r7,10*8;; // rement by 72 bytes
-
- mov r3=ar.rsc
- mov ar.rsc=r0 // put RSE in enforced lazy mode
- mov r5=ar.bsp
- ;;
- mov r7=ar.bspstore;;
- st8 [r2]=r3,3*8
- st8 [r4]=r5,3*8
- st8 [r6]=r7,3*8;;
-
- mov r3=ar.rnat;;
- st8 [r2]=r3,8*13 // increment by 13x8 bytes
-
- mov r3=ar.ccv;;
- st8 [r2]=r3,8*4
-
- mov r3=ar.unat;;
- st8 [r2]=r3,8*4
-
- mov r3=ar.fpsr;;
- st8 [r2]=r3,8*4
-
- mov r3=ar.itc;;
- st8 [r2]=r3,160 // 160
-
- mov r3=ar.pfs;;
- st8 [r2]=r3,8
-
- mov r3=ar.lc;;
- st8 [r2]=r3,8
-
- mov r3=ar.ec;;
- st8 [r2]=r3
- add r2=8*62,r2 //padding
-
-// save RRs
- mov ar.lc=0x08-1
- movl r4=0x00;;
-
-cStRR:
- dep.z r5=r4,61,3;;
- mov r3=rr[r5];;
- st8 [r2]=r3,8
- add r4=1,r4
- br.cloop.sptk.few cStRR
- ;;
-end_os_mca_dump:
- br ia64_os_mca_done_dump;;
+ st8 [temp1]=r18,16 // proc_state_param
+ st8 [temp2]=r19,16 // monarch
+ mov r6=IA64_KR(CURRENT)
+ ;;
+ st8 [temp1]=r12,16 // sal_ra
+ st8 [temp2]=r10,16 // sal_gp
+ mov r12=cr.isr
+ ;;
+ st8 [temp1]=r17,16 // pal_min_state
+ st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT
+ mov r6=IA64_KR(CURRENT_STACK)
+ ;;
+ st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK
+ st8 [temp2]=r0,16 // prev_task, starts off as NULL
+ mov r6=cr.ifa
+ ;;
+ st8 [temp1]=r12,16 // cr.isr
+ st8 [temp2]=r6,16 // cr.ifa
+ mov r12=cr.itir
+ ;;
+ st8 [temp1]=r12,16 // cr.itir
+ st8 [temp2]=r11,16 // cr.iipa
+ mov r12=cr.iim
+ ;;
+ st8 [temp1]=r12,16 // cr.iim
+(p1) mov r12=IA64_MCA_COLD_BOOT
+(p2) mov r12=IA64_INIT_WARM_BOOT
+ mov r6=cr.iha
+ ;;
+ st8 [temp2]=r6,16 // cr.iha
+ st8 [temp1]=r12 // os_status, default is cold boot
+ mov r6=IA64_MCA_SAME_CONTEXT
+ ;;
+ st8 [temp1]=r6 // context, default is same context
+
+ // Save the pt_regs data that is not in minstate. The previous code
+ // left regs at sos.
+ add regs=MCA_PT_REGS_OFFSET-MCA_SOS_OFFSET, regs
+ ;;
+ add temp1=PT(B6), regs
+ mov temp3=b6
+ mov temp4=b7
+ add temp2=PT(B7), regs
+ ;;
+ st8 [temp1]=temp3,PT(AR_CSD)-PT(B6) // save b6
+ st8 [temp2]=temp4,PT(AR_SSD)-PT(B7) // save b7
+ mov temp3=ar.csd
+ mov temp4=ar.ssd
+ cover // must be last in group
+ ;;
+ st8 [temp1]=temp3,PT(AR_UNAT)-PT(AR_CSD) // save ar.csd
+ st8 [temp2]=temp4,PT(AR_PFS)-PT(AR_SSD) // save ar.ssd
+ mov temp3=ar.unat
+ mov temp4=ar.pfs
+ ;;
+ st8 [temp1]=temp3,PT(AR_RNAT)-PT(AR_UNAT) // save ar.unat
+ st8 [temp2]=temp4,PT(AR_BSPSTORE)-PT(AR_PFS) // save ar.pfs
+ mov temp3=ar.rnat
+ mov temp4=ar.bspstore
+ ;;
+ st8 [temp1]=temp3,PT(LOADRS)-PT(AR_RNAT) // save ar.rnat
+ st8 [temp2]=temp4,PT(AR_FPSR)-PT(AR_BSPSTORE) // save ar.bspstore
+ mov temp3=ar.bsp
+ ;;
+ sub temp3=temp3, temp4 // ar.bsp - ar.bspstore
+ mov temp4=ar.fpsr
+ ;;
+ shl temp3=temp3,16 // compute ar.rsc to be used for "loadrs"
+ ;;
+ st8 [temp1]=temp3,PT(AR_CCV)-PT(LOADRS) // save loadrs
+ st8 [temp2]=temp4,PT(F6)-PT(AR_FPSR) // save ar.fpsr
+ mov temp3=ar.ccv
+ ;;
+ st8 [temp1]=temp3,PT(F7)-PT(AR_CCV) // save ar.ccv
+ stf.spill [temp2]=f6,PT(F8)-PT(F6)
+ ;;
+ stf.spill [temp1]=f7,PT(F9)-PT(F7)
+ stf.spill [temp2]=f8,PT(F10)-PT(F8)
+ ;;
+ stf.spill [temp1]=f9,PT(F11)-PT(F9)
+ stf.spill [temp2]=f10
+ ;;
+ stf.spill [temp1]=f11
+
+ // Save the switch_stack data that is not in minstate nor pt_regs. The
+ // previous code left regs at pt_regs.
+ add regs=MCA_SWITCH_STACK_OFFSET-MCA_PT_REGS_OFFSET, regs
+ ;;
+ add temp1=SW(F2), regs
+ add temp2=SW(F3), regs
+ ;;
+ stf.spill [temp1]=f2,32
+ stf.spill [temp2]=f3,32
+ ;;
+ stf.spill [temp1]=f4,32
+ stf.spill [temp2]=f5,32
+ ;;
+ stf.spill [temp1]=f12,32
+ stf.spill [temp2]=f13,32
+ ;;
+ stf.spill [temp1]=f14,32
+ stf.spill [temp2]=f15,32
+ ;;
+ stf.spill [temp1]=f16,32
+ stf.spill [temp2]=f17,32
+ ;;
+ stf.spill [temp1]=f18,32
+ stf.spill [temp2]=f19,32
+ ;;
+ stf.spill [temp1]=f20,32
+ stf.spill [temp2]=f21,32
+ ;;
+ stf.spill [temp1]=f22,32
+ stf.spill [temp2]=f23,32
+ ;;
+ stf.spill [temp1]=f24,32
+ stf.spill [temp2]=f25,32
+ ;;
+ stf.spill [temp1]=f26,32
+ stf.spill [temp2]=f27,32
+ ;;
+ stf.spill [temp1]=f28,32
+ stf.spill [temp2]=f29,32
+ ;;
+ stf.spill [temp1]=f30,SW(B2)-SW(F30)
+ stf.spill [temp2]=f31,SW(B3)-SW(F31)
+ mov temp3=b2
+ mov temp4=b3
+ ;;
+ st8 [temp1]=temp3,16 // save b2
+ st8 [temp2]=temp4,16 // save b3
+ mov temp3=b4
+ mov temp4=b5
+ ;;
+ st8 [temp1]=temp3,SW(AR_LC)-SW(B4) // save b4
+ st8 [temp2]=temp4 // save b5
+ mov temp3=ar.lc
+ ;;
+ st8 [temp1]=temp3 // save ar.lc
+
+ // FIXME: Some proms are incorrectly accessing the minstate area as
+ // cached data. The C code uses region 6, uncached virtual. Ensure
+ // that there is no cache data lying around for the first 1K of the
+ // minstate area.
+ // Remove this code in September 2006, that gives platforms a year to
+ // fix their proms and get their customers updated.
+
+ add r1=32*1,r17
+ add r2=32*2,r17
+ add r3=32*3,r17
+ add r4=32*4,r17
+ add r5=32*5,r17
+ add r6=32*6,r17
+ add r7=32*7,r17
+ ;;
+ fc r17
+ fc r1
+ fc r2
+ fc r3
+ fc r4
+ fc r5
+ fc r6
+ fc r7
+ add r17=32*8,r17
+ add r1=32*8,r1
+ add r2=32*8,r2
+ add r3=32*8,r3
+ add r4=32*8,r4
+ add r5=32*8,r5
+ add r6=32*8,r6
+ add r7=32*8,r7
+ ;;
+ fc r17
+ fc r1
+ fc r2
+ fc r3
+ fc r4
+ fc r5
+ fc r6
+ fc r7
+ add r17=32*8,r17
+ add r1=32*8,r1
+ add r2=32*8,r2
+ add r3=32*8,r3
+ add r4=32*8,r4
+ add r5=32*8,r5
+ add r6=32*8,r6
+ add r7=32*8,r7
+ ;;
+ fc r17
+ fc r1
+ fc r2
+ fc r3
+ fc r4
+ fc r5
+ fc r6
+ fc r7
+ add r17=32*8,r17
+ add r1=32*8,r1
+ add r2=32*8,r2
+ add r3=32*8,r3
+ add r4=32*8,r4
+ add r5=32*8,r5
+ add r6=32*8,r6
+ add r7=32*8,r7
+ ;;
+ fc r17
+ fc r1
+ fc r2
+ fc r3
+ fc r4
+ fc r5
+ fc r6
+ fc r7
+
+ br.sptk b0
//EndStub//////////////////////////////////////////////////////////////////////
//++
// Name:
-// ia64_os_mca_proc_state_restore()
+// ia64_state_restore()
//
// Stub Description:
//
-// This is a stub to restore the saved processor state during MCHK
+// Restore the SAL/OS state. This is sensitive to the layout of struct
+// ia64_sal_os_state in mca.h.
+//
+// r2 contains the return address, r3 contains either
+// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
+//
+// In addition to the SAL to OS state, this routine restores all the
+// registers that appear in struct pt_regs and struct switch_stack,
+// excluding those in the PAL minstate area.
//
//--
-ia64_os_mca_proc_state_restore:
+ia64_state_restore:
+ // Restore the switch_stack data that is not in minstate nor pt_regs.
+ add regs=MCA_SWITCH_STACK_OFFSET, r3
+ mov b0=r2 // save return address
+ ;;
+ GET_IA64_MCA_DATA(temp2)
+ ;;
+ add regs=temp2, regs
+ ;;
+ add temp1=SW(F2), regs
+ add temp2=SW(F3), regs
+ ;;
+ ldf.fill f2=[temp1],32
+ ldf.fill f3=[temp2],32
+ ;;
+ ldf.fill f4=[temp1],32
+ ldf.fill f5=[temp2],32
+ ;;
+ ldf.fill f12=[temp1],32
+ ldf.fill f13=[temp2],32
+ ;;
+ ldf.fill f14=[temp1],32
+ ldf.fill f15=[temp2],32
+ ;;
+ ldf.fill f16=[temp1],32
+ ldf.fill f17=[temp2],32
+ ;;
+ ldf.fill f18=[temp1],32
+ ldf.fill f19=[temp2],32
+ ;;
+ ldf.fill f20=[temp1],32
+ ldf.fill f21=[temp2],32
+ ;;
+ ldf.fill f22=[temp1],32
+ ldf.fill f23=[temp2],32
+ ;;
+ ldf.fill f24=[temp1],32
+ ldf.fill f25=[temp2],32
+ ;;
+ ldf.fill f26=[temp1],32
+ ldf.fill f27=[temp2],32
+ ;;
+ ldf.fill f28=[temp1],32
+ ldf.fill f29=[temp2],32
+ ;;
+ ldf.fill f30=[temp1],SW(B2)-SW(F30)
+ ldf.fill f31=[temp2],SW(B3)-SW(F31)
+ ;;
+ ld8 temp3=[temp1],16 // restore b2
+ ld8 temp4=[temp2],16 // restore b3
+ ;;
+ mov b2=temp3
+ mov b3=temp4
+ ld8 temp3=[temp1],SW(AR_LC)-SW(B4) // restore b4
+ ld8 temp4=[temp2] // restore b5
+ ;;
+ mov b4=temp3
+ mov b5=temp4
+ ld8 temp3=[temp1] // restore ar.lc
+ ;;
+ mov ar.lc=temp3
-// Restore bank1 GR16-31
- GET_IA64_MCA_DATA(r2)
+ // Restore the pt_regs data that is not in minstate. The previous code
+ // left regs at switch_stack.
+ add regs=MCA_PT_REGS_OFFSET-MCA_SWITCH_STACK_OFFSET, regs
+ ;;
+ add temp1=PT(B6), regs
+ add temp2=PT(B7), regs
+ ;;
+ ld8 temp3=[temp1],PT(AR_CSD)-PT(B6) // restore b6
+ ld8 temp4=[temp2],PT(AR_SSD)-PT(B7) // restore b7
+ ;;
+ mov b6=temp3
+ mov b7=temp4
+ ld8 temp3=[temp1],PT(AR_UNAT)-PT(AR_CSD) // restore ar.csd
+ ld8 temp4=[temp2],PT(AR_PFS)-PT(AR_SSD) // restore ar.ssd
;;
- add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2
-
-restore_GRs: // restore bank-1 GRs 16-31
- bsw.1;;
- add r3=16*8,r2;; // to get to NaT of GR 16-31
- ld8 r3=[r3];;
- mov ar.unat=r3;; // first restore NaT
-
- ld8.fill r16=[r2],8;;
- ld8.fill r17=[r2],8;;
- ld8.fill r18=[r2],8;;
- ld8.fill r19=[r2],8;;
- ld8.fill r20=[r2],8;;
- ld8.fill r21=[r2],8;;
- ld8.fill r22=[r2],8;;
- ld8.fill r23=[r2],8;;
- ld8.fill r24=[r2],8;;
- ld8.fill r25=[r2],8;;
- ld8.fill r26=[r2],8;;
- ld8.fill r27=[r2],8;;
- ld8.fill r28=[r2],8;;
- ld8.fill r29=[r2],8;;
- ld8.fill r30=[r2],8;;
- ld8.fill r31=[r2],8;;
-
- ld8 r3=[r2],8;; // increment to skip NaT
- bsw.0;;
-
-restore_BRs:
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2;; // duplicate r2 in r4
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov b0=r3
- mov b1=r5
- mov b2=r7;;
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov b3=r3
- mov b4=r5
- mov b5=r7;;
-
- ld8 r3=[r2],2*8
- ld8 r5=[r4],2*8;;
- mov b6=r3
- mov b7=r5;;
-
-restore_CRs:
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2;; // duplicate r2 in r4
-
- ld8 r3=[r2],8*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;; // 48 byte increments
- mov cr.dcr=r3
- mov cr.itm=r5
- mov cr.iva=r7;;
-
- ld8 r3=[r2],8*8;; // 64 byte increments
-// mov cr.pta=r3
-
-
-// if PSR.ic=1, reading interruption registers causes an illegal operation fault
- mov r3=psr;;
- tbit.nz.unc p6,p0=r3,PSR_IC;; // PSI Valid Log bit pos. test
-(p6) st8 [r2]=r0,9*8+160 // increment by 232 byte inc.
-
-begin_rskip_intr_regs:
-(p6) br rSkipIntrRegs;;
-
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2;; // duplicate r2 in r4
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov cr.ipsr=r3
-// mov cr.isr=r5 // cr.isr is read only
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov cr.iip=r3
- mov cr.ifa=r5
- mov cr.itir=r7;;
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov cr.iipa=r3
- mov cr.ifs=r5
- mov cr.iim=r7
-
- ld8 r3=[r2],160;; // 160 byte increment
- mov cr.iha=r3
-
-rSkipIntrRegs:
- ld8 r3=[r2],152;; // another 152 byte inc.
-
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2;; // duplicate r2 in r6
-
- ld8 r3=[r2],8*3
- ld8 r5=[r4],8*3
- ld8 r7=[r6],8*3;;
- mov cr.lid=r3
-// mov cr.ivr=r5 // cr.ivr is read only
- mov cr.tpr=r7;;
-
- ld8 r3=[r2],8*3
- ld8 r5=[r4],8*3
- ld8 r7=[r6],8*3;;
-// mov cr.eoi=r3
-// mov cr.irr0=r5 // cr.irr0 is read only
-// mov cr.irr1=r7;; // cr.irr1 is read only
-
- ld8 r3=[r2],8*3
- ld8 r5=[r4],8*3
- ld8 r7=[r6],8*3;;
-// mov cr.irr2=r3 // cr.irr2 is read only
-// mov cr.irr3=r5 // cr.irr3 is read only
- mov cr.itv=r7;;
-
- ld8 r3=[r2],8*7
- ld8 r5=[r4],8*7;;
- mov cr.pmv=r3
- mov cr.cmcv=r5;;
-
- ld8 r3=[r2],8*23
- ld8 r5=[r4],8*23;;
- adds r2=8*23,r2
- adds r4=8*23,r4;;
-// mov cr.lrr0=r3
-// mov cr.lrr1=r5
-
- adds r2=8*2,r2;;
-
-restore_ARs:
- add r4=8,r2 // duplicate r2 in r4
- add r6=2*8,r2;; // duplicate r2 in r4
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov ar.k0=r3
- mov ar.k1=r5
- mov ar.k2=r7;;
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
- mov ar.k3=r3
- mov ar.k4=r5
- mov ar.k5=r7;;
-
- ld8 r3=[r2],10*8
- ld8 r5=[r4],10*8
- ld8 r7=[r6],10*8;;
- mov ar.k6=r3
- mov ar.k7=r5
- ;;
-
- ld8 r3=[r2],3*8
- ld8 r5=[r4],3*8
- ld8 r7=[r6],3*8;;
-// mov ar.rsc=r3
-// mov ar.bsp=r5 // ar.bsp is read only
- mov ar.rsc=r0 // make sure that RSE is in enforced lazy mode
- ;;
- mov ar.bspstore=r7;;
-
- ld8 r9=[r2],8*13;;
- mov ar.rnat=r9
-
- mov ar.rsc=r3
- ld8 r3=[r2],8*4;;
- mov ar.ccv=r3
-
- ld8 r3=[r2],8*4;;
- mov ar.unat=r3
-
- ld8 r3=[r2],8*4;;
- mov ar.fpsr=r3
-
- ld8 r3=[r2],160;; // 160
-// mov ar.itc=r3
-
- ld8 r3=[r2],8;;
- mov ar.pfs=r3
-
- ld8 r3=[r2],8;;
- mov ar.lc=r3
-
- ld8 r3=[r2];;
- mov ar.ec=r3
- add r2=8*62,r2;; // padding
-
-restore_RRs:
- mov r5=ar.lc
- mov ar.lc=0x08-1
- movl r4=0x00;;
-cStRRr:
- dep.z r7=r4,61,3
- ld8 r3=[r2],8;;
- mov rr[r7]=r3 // what are its access previledges?
- add r4=1,r4
- br.cloop.sptk.few cStRRr
- ;;
- mov ar.lc=r5
- ;;
-end_os_mca_restore:
- br ia64_os_mca_done_restore;;
+ mov ar.csd=temp3
+ mov ar.ssd=temp4
+ ld8 temp3=[temp1] // restore ar.unat
+ add temp1=PT(AR_CCV)-PT(AR_UNAT), temp1
+ ld8 temp4=[temp2],PT(AR_FPSR)-PT(AR_PFS) // restore ar.pfs
+ ;;
+ mov ar.unat=temp3
+ mov ar.pfs=temp4
+ // ar.rnat, ar.bspstore, loadrs are restore in ia64_old_stack.
+ ld8 temp3=[temp1],PT(F6)-PT(AR_CCV) // restore ar.ccv
+ ld8 temp4=[temp2],PT(F7)-PT(AR_FPSR) // restore ar.fpsr
+ ;;
+ mov ar.ccv=temp3
+ mov ar.fpsr=temp4
+ ldf.fill f6=[temp1],PT(F8)-PT(F6)
+ ldf.fill f7=[temp2],PT(F9)-PT(F7)
+ ;;
+ ldf.fill f8=[temp1],PT(F10)-PT(F8)
+ ldf.fill f9=[temp2],PT(F11)-PT(F9)
+ ;;
+ ldf.fill f10=[temp1]
+ ldf.fill f11=[temp2]
+
+ // Restore the SAL to OS state. The previous code left regs at pt_regs.
+ add regs=MCA_SOS_OFFSET-MCA_PT_REGS_OFFSET, regs
+ ;;
+ add temp1=IA64_SAL_OS_STATE_COMMON_OFFSET, regs
+ add temp2=IA64_SAL_OS_STATE_COMMON_OFFSET+8, regs
+ ;;
+ ld8 r12=[temp1],16 // sal_ra
+ ld8 r9=[temp2],16 // sal_gp
+ ;;
+ ld8 r22=[temp1],16 // pal_min_state, virtual
+ ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT
+ ;;
+ ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK
+ ld8 r20=[temp2],16 // prev_task
+ ;;
+ ld8 temp3=[temp1],16 // cr.isr
+ ld8 temp4=[temp2],16 // cr.ifa
+ ;;
+ mov cr.isr=temp3
+ mov cr.ifa=temp4
+ ld8 temp3=[temp1],16 // cr.itir
+ ld8 temp4=[temp2],16 // cr.iipa
+ ;;
+ mov cr.itir=temp3
+ mov cr.iipa=temp4
+ ld8 temp3=[temp1],16 // cr.iim
+ ld8 temp4=[temp2],16 // cr.iha
+ ;;
+ mov cr.iim=temp3
+ mov cr.iha=temp4
+ dep r22=0,r22,62,2 // pal_min_state, physical, uncached
+ mov IA64_KR(CURRENT)=r21
+ ld8 r8=[temp1] // os_status
+ ld8 r10=[temp2] // context
+
+ /* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To
+ * avoid any dependencies on the algorithm in ia64_switch_to(), just
+ * purge any existing CURRENT_STACK mapping and insert the new one.
+ *
+ * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains
+ * prev_IA64_KR_CURRENT, these values may have been changed by the C
+ * code. Do not use r8, r9, r10, r22, they contain values ready for
+ * the return to SAL.
+ */
+
+ mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
+ ;;
+ shl r15=r15,IA64_GRANULE_SHIFT
+ ;;
+ dep r15=-1,r15,61,3 // virtual granule
+ mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
+ ;;
+ ptr.d r15,r18
+ ;;
+ srlz.d
+
+ extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT
+ shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK
+ movl r21=PAGE_KERNEL // page properties
+ ;;
+ mov IA64_KR(CURRENT_STACK)=r16
+ cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region?
+ or r21=r20,r21 // construct PA | page properties
+(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:(
+ ;;
+ mov cr.itir=r18
+ mov cr.ifa=r21
+ mov r20=IA64_TR_CURRENT_STACK
+ ;;
+ itr.d dtr[r20]=r21
+ ;;
+ srlz.d
+1:
+
+ br.sptk b0
//EndStub//////////////////////////////////////////////////////////////////////
-// ok, the issue here is that we need to save state information so
-// it can be useable by the kernel debugger and show regs routines.
-// In order to do this, our best bet is save the current state (plus
-// the state information obtain from the MIN_STATE_AREA) into a pt_regs
-// format. This way we can pass it on in a useable format.
+//++
+// Name:
+// ia64_new_stack()
//
-
+// Stub Description:
//
-// SAL to OS entry point for INIT on the monarch processor
-// This has been defined for registration purposes with SAL
-// as a part of ia64_mca_init.
+// Switch to the MCA/INIT stack.
//
-// When we get here, the following registers have been
-// set by the SAL for our use
+// r2 contains the return address, r3 contains either
+// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
//
-// 1. GR1 = OS INIT GP
-// 2. GR8 = PAL_PROC physical address
-// 3. GR9 = SAL_PROC physical address
-// 4. GR10 = SAL GP (physical)
-// 5. GR11 = Init Reason
-// 0 = Received INIT for event other than crash dump switch
-// 1 = Received wakeup at the end of an OS_MCA corrected machine check
-// 2 = Received INIT dude to CrashDump switch assertion
+// On entry RBS is still on the original stack, this routine switches RBS
+// to use the MCA/INIT stack.
//
-// 6. GR12 = Return address to location within SAL_INIT procedure
-
+// On entry, sos->pal_min_state is physical, on exit it is virtual.
+//
+//--
-GLOBAL_ENTRY(ia64_monarch_init_handler)
- .prologue
- // stash the information the SAL passed to os
- SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
+ia64_new_stack:
+ add regs=MCA_PT_REGS_OFFSET, r3
+ add temp2=MCA_SOS_OFFSET+IA64_SAL_OS_STATE_PAL_MIN_STATE_OFFSET, r3
+ mov b0=r2 // save return address
+ GET_IA64_MCA_DATA(temp1)
+ invala
;;
- SAVE_MIN_WITH_COVER
+ add temp2=temp2, temp1 // struct ia64_sal_os_state.pal_min_state on MCA or INIT stack
+ add regs=regs, temp1 // struct pt_regs on MCA or INIT stack
;;
- mov r8=cr.ifa
- mov r9=cr.isr
- adds r3=8,r2 // set up second base pointer
+ // Address of minstate area provided by PAL is physical, uncacheable.
+ // Convert to Linux virtual address in region 6 for C code.
+ ld8 ms=[temp2] // pal_min_state, physical
;;
- SAVE_REST
-
-// ok, enough should be saved at this point to be dangerous, and supply
-// information for a dump
-// We need to switch to Virtual mode before hitting the C functions.
+ dep temp1=-1,ms,62,2 // set region 6
+ mov temp3=IA64_RBS_OFFSET-MCA_PT_REGS_OFFSET
+ ;;
+ st8 [temp2]=temp1 // pal_min_state, virtual
- movl r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN
- mov r3=psr // get the current psr, minimum enabled at this point
+ add temp4=temp3, regs // start of bspstore on new stack
;;
- or r2=r2,r3
+ mov ar.bspstore=temp4 // switch RBS to MCA/INIT stack
;;
- movl r3=IVirtual_Switch
+ flushrs // must be first in group
+ br.sptk b0
+
+//EndStub//////////////////////////////////////////////////////////////////////
+
+
+//++
+// Name:
+// ia64_old_stack()
+//
+// Stub Description:
+//
+// Switch to the old stack.
+//
+// r2 contains the return address, r3 contains either
+// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
+//
+// On entry, pal_min_state is virtual, on exit it is physical.
+//
+// On entry RBS is on the MCA/INIT stack, this routine switches RBS
+// back to the previous stack.
+//
+// The psr is set to all zeroes. SAL return requires either all zeroes or
+// just psr.mc set. Leaving psr.mc off allows INIT to be issued if this
+// code does not perform correctly.
+//
+// The dirty registers at the time of the event were flushed to the
+// MCA/INIT stack in ia64_pt_regs_save(). Restore the dirty registers
+// before reverting to the previous bspstore.
+//--
+
+ia64_old_stack:
+ add regs=MCA_PT_REGS_OFFSET, r3
+ mov b0=r2 // save return address
+ GET_IA64_MCA_DATA(temp2)
+ LOAD_PHYSICAL(p0,temp1,1f)
;;
- mov cr.iip=r3 // short return to set the appropriate bits
- mov cr.ipsr=r2 // need to do an rfi to set appropriate bits
+ mov cr.ipsr=r0
+ mov cr.ifs=r0
+ mov cr.iip=temp1
;;
+ invala
rfi
+1:
+
+ add regs=regs, temp2 // struct pt_regs on MCA or INIT stack
;;
-IVirtual_Switch:
- //
- // We should now be running virtual
- //
- // Let's call the C handler to get the rest of the state info
- //
- alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!)
+ add temp1=PT(LOADRS), regs
;;
- adds out0=16,sp // out0 = pointer to pt_regs
+ ld8 temp2=[temp1],PT(AR_BSPSTORE)-PT(LOADRS) // restore loadrs
+ ;;
+ ld8 temp3=[temp1],PT(AR_RNAT)-PT(AR_BSPSTORE) // restore ar.bspstore
+ mov ar.rsc=temp2
+ ;;
+ loadrs
+ ld8 temp4=[temp1] // restore ar.rnat
+ ;;
+ mov ar.bspstore=temp3 // back to old stack
+ ;;
+ mov ar.rnat=temp4
;;
- DO_SAVE_SWITCH_STACK
- .body
- adds out1=16,sp // out0 = pointer to switch_stack
- br.call.sptk.many rp=ia64_init_handler
-.ret1:
+ br.sptk b0
+
+//EndStub//////////////////////////////////////////////////////////////////////
-return_from_init:
- br.sptk return_from_init
-END(ia64_monarch_init_handler)
+//++
+// Name:
+// ia64_set_kernel_registers()
+//
+// Stub Description:
+//
+// Set the registers that are required by the C code in order to run on an
+// MCA/INIT stack.
//
-// SAL to OS entry point for INIT on the slave processor
-// This has been defined for registration purposes with SAL
-// as a part of ia64_mca_init.
+// r2 contains the return address, r3 contains either
+// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
//
+//--
-GLOBAL_ENTRY(ia64_slave_init_handler)
-1: br.sptk 1b
-END(ia64_slave_init_handler)
+ia64_set_kernel_registers:
+ add temp3=MCA_SP_OFFSET, r3
+ add temp4=MCA_SOS_OFFSET+IA64_SAL_OS_STATE_OS_GP_OFFSET, r3
+ mov b0=r2 // save return address
+ GET_IA64_MCA_DATA(temp1)
+ ;;
+ add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp
+ add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack
+ add r13=temp1, r3 // set current to start of MCA/INIT stack
+ add r20=temp1, r3 // physical start of MCA/INIT stack
+ ;;
+ ld8 r1=[temp4] // OS GP from SAL OS state
+ ;;
+ DATA_PA_TO_VA(r1,temp1)
+ DATA_PA_TO_VA(r12,temp2)
+ DATA_PA_TO_VA(r13,temp3)
+ ;;
+ mov IA64_KR(CURRENT)=r13
+
+ /* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid
+ * any dependencies on the algorithm in ia64_switch_to(), just purge
+ * any existing CURRENT_STACK mapping and insert the new one.
+ */
+
+ mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
+ ;;
+ shl r16=r16,IA64_GRANULE_SHIFT
+ ;;
+ dep r16=-1,r16,61,3 // virtual granule
+ mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
+ ;;
+ ptr.d r16,r18
+ ;;
+ srlz.d
+
+ shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack
+ movl r21=PAGE_KERNEL // page properties
+ ;;
+ mov IA64_KR(CURRENT_STACK)=r16
+ or r21=r20,r21 // construct PA | page properties
+ ;;
+ mov cr.itir=r18
+ mov cr.ifa=r13
+ mov r20=IA64_TR_CURRENT_STACK
+ ;;
+ itr.d dtr[r20]=r21
+ ;;
+ srlz.d
+
+ br.sptk b0
+
+//EndStub//////////////////////////////////////////////////////////////////////
+
+#undef ms
+#undef regs
+#undef temp1
+#undef temp2
+#undef temp3
+#undef temp4
+
+
+// Support function for mca.c, it is here to avoid using inline asm. Given the
+// address of an rnat slot, if that address is below the current ar.bspstore
+// then return the contents of that slot, otherwise return the contents of
+// ar.rnat.
+GLOBAL_ENTRY(ia64_get_rnat)
+ alloc r14=ar.pfs,1,0,0,0
+ mov ar.rsc=0
+ ;;
+ mov r14=ar.bspstore
+ ;;
+ cmp.lt p6,p7=in0,r14
+ ;;
+(p6) ld8 r8=[in0]
+(p7) mov r8=ar.rnat
+ mov ar.rsc=3
+ br.ret.sptk.many rp
+END(ia64_get_rnat)
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index abc0113a821d..f081c60ab206 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -4,6 +4,8 @@
*
* Copyright (C) 2004 FUJITSU LIMITED
* Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com)
+ * Copyright (C) 2005 Silicon Graphics, Inc
+ * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
*/
#include <linux/config.h>
#include <linux/types.h>
@@ -38,10 +40,6 @@
/* max size of SAL error record (default) */
static int sal_rec_max = 10000;
-/* from mca.c */
-static ia64_mca_sal_to_os_state_t *sal_to_os_handoff_state;
-static ia64_mca_os_to_sal_state_t *os_to_sal_handoff_state;
-
/* from mca_drv_asm.S */
extern void *mca_handler_bhhook(void);
@@ -58,8 +56,9 @@ static struct page *page_isolate[MAX_PAGE_ISOLATE];
static int num_page_isolate = 0;
typedef enum {
- ISOLATE_NG = 0,
- ISOLATE_OK = 1
+ ISOLATE_NG,
+ ISOLATE_OK,
+ ISOLATE_NONE
} isolate_status_t;
/*
@@ -76,7 +75,7 @@ static struct {
* @paddr: poisoned memory location
*
* Return value:
- * ISOLATE_OK / ISOLATE_NG
+ * one of isolate_status_t, ISOLATE_OK/NG/NONE.
*/
static isolate_status_t
@@ -86,23 +85,26 @@ mca_page_isolate(unsigned long paddr)
struct page *p;
/* whether physical address is valid or not */
- if ( !ia64_phys_addr_valid(paddr) )
- return ISOLATE_NG;
+ if (!ia64_phys_addr_valid(paddr))
+ return ISOLATE_NONE;
+
+ if (!pfn_valid(paddr))
+ return ISOLATE_NONE;
/* convert physical address to physical page number */
p = pfn_to_page(paddr>>PAGE_SHIFT);
/* check whether a page number have been already registered or not */
- for( i = 0; i < num_page_isolate; i++ )
- if( page_isolate[i] == p )
+ for (i = 0; i < num_page_isolate; i++)
+ if (page_isolate[i] == p)
return ISOLATE_OK; /* already listed */
/* limitation check */
- if( num_page_isolate == MAX_PAGE_ISOLATE )
+ if (num_page_isolate == MAX_PAGE_ISOLATE)
return ISOLATE_NG;
/* kick pages having attribute 'SLAB' or 'Reserved' */
- if( PageSlab(p) || PageReserved(p) )
+ if (PageSlab(p) || PageReserved(p))
return ISOLATE_NG;
/* add attribute 'Reserved' and register the page */
@@ -124,10 +126,15 @@ mca_handler_bh(unsigned long paddr)
current->pid, current->comm);
spin_lock(&mca_bh_lock);
- if (mca_page_isolate(paddr) == ISOLATE_OK) {
+ switch (mca_page_isolate(paddr)) {
+ case ISOLATE_OK:
printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
- } else {
+ break;
+ case ISOLATE_NG:
printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr);
+ break;
+ default:
+ break;
}
spin_unlock(&mca_bh_lock);
@@ -141,10 +148,10 @@ mca_handler_bh(unsigned long paddr)
* @peidx: pointer to index of processor error section
*/
-static void
+static void
mca_make_peidx(sal_log_processor_info_t *slpi, peidx_table_t *peidx)
{
- /*
+ /*
* calculate the start address of
* "struct cpuid_info" and "sal_processor_static_info_t".
*/
@@ -166,7 +173,7 @@ mca_make_peidx(sal_log_processor_info_t *slpi, peidx_table_t *peidx)
}
/**
- * mca_make_slidx - Make index of SAL error record
+ * mca_make_slidx - Make index of SAL error record
* @buffer: pointer to SAL error record
* @slidx: pointer to index of SAL error record
*
@@ -174,12 +181,12 @@ mca_make_peidx(sal_log_processor_info_t *slpi, peidx_table_t *peidx)
* 1 if record has platform error / 0 if not
*/
#define LOG_INDEX_ADD_SECT_PTR(sect, ptr) \
- { slidx_list_t *hl = &slidx_pool.buffer[slidx_pool.cur_idx]; \
- hl->hdr = ptr; \
- list_add(&hl->list, &(sect)); \
- slidx_pool.cur_idx = (slidx_pool.cur_idx + 1)%slidx_pool.max_idx; }
+ {slidx_list_t *hl = &slidx_pool.buffer[slidx_pool.cur_idx]; \
+ hl->hdr = ptr; \
+ list_add(&hl->list, &(sect)); \
+ slidx_pool.cur_idx = (slidx_pool.cur_idx + 1)%slidx_pool.max_idx; }
-static int
+static int
mca_make_slidx(void *buffer, slidx_table_t *slidx)
{
int platform_err = 0;
@@ -216,28 +223,36 @@ mca_make_slidx(void *buffer, slidx_table_t *slidx)
sp = (sal_log_section_hdr_t *)((char*)buffer + ercd_pos);
if (!efi_guidcmp(sp->guid, SAL_PROC_DEV_ERR_SECT_GUID)) {
LOG_INDEX_ADD_SECT_PTR(slidx->proc_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_MEM_DEV_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_MEM_DEV_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->mem_dev_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_SEL_DEV_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_SEL_DEV_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->sel_dev_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_PCI_BUS_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_PCI_BUS_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->pci_bus_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->smbios_dev_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_PCI_COMP_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_PCI_COMP_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->pci_comp_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_SPECIFIC_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_SPECIFIC_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->plat_specific_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_HOST_CTLR_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_HOST_CTLR_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->host_ctlr_err, sp);
- } else if (!efi_guidcmp(sp->guid, SAL_PLAT_BUS_ERR_SECT_GUID)) {
+ } else if (!efi_guidcmp(sp->guid,
+ SAL_PLAT_BUS_ERR_SECT_GUID)) {
platform_err = 1;
LOG_INDEX_ADD_SECT_PTR(slidx->plat_bus_err, sp);
} else {
@@ -255,15 +270,16 @@ mca_make_slidx(void *buffer, slidx_table_t *slidx)
* Return value:
* 0 on Success / -ENOMEM on Failure
*/
-static int
+static int
init_record_index_pools(void)
{
int i;
int rec_max_size; /* Maximum size of SAL error records */
int sect_min_size; /* Minimum size of SAL error sections */
/* minimum size table of each section */
- static int sal_log_sect_min_sizes[] = {
- sizeof(sal_log_processor_info_t) + sizeof(sal_processor_static_info_t),
+ static int sal_log_sect_min_sizes[] = {
+ sizeof(sal_log_processor_info_t)
+ + sizeof(sal_processor_static_info_t),
sizeof(sal_log_mem_dev_err_info_t),
sizeof(sal_log_sel_dev_err_info_t),
sizeof(sal_log_pci_bus_err_info_t),
@@ -296,7 +312,8 @@ init_record_index_pools(void)
/* - 3 - */
slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1;
- slidx_pool.buffer = (slidx_list_t *) kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL);
+ slidx_pool.buffer = (slidx_list_t *)
+ kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL);
return slidx_pool.buffer ? 0 : -ENOMEM;
}
@@ -310,24 +327,27 @@ init_record_index_pools(void)
* is_mca_global - Check whether this MCA is global or not
* @peidx: pointer of index of processor error section
* @pbci: pointer to pal_bus_check_info_t
+ * @sos: pointer to hand off struct between SAL and OS
*
* Return value:
* MCA_IS_LOCAL / MCA_IS_GLOBAL
*/
static mca_type_t
-is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci)
+is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
+ struct ia64_sal_os_state *sos)
{
- pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx);
+ pal_processor_state_info_t *psp =
+ (pal_processor_state_info_t*)peidx_psp(peidx);
- /*
+ /*
* PAL can request a rendezvous, if the MCA has a global scope.
- * If "rz_always" flag is set, SAL requests MCA rendezvous
+ * If "rz_always" flag is set, SAL requests MCA rendezvous
* in spite of global MCA.
* Therefore it is local MCA when rendezvous has not been requested.
* Failed to rendezvous, the system must be down.
*/
- switch (sal_to_os_handoff_state->imsto_rendez_state) {
+ switch (sos->rv_rc) {
case -1: /* SAL rendezvous unsuccessful */
return MCA_IS_GLOBAL;
case 0: /* SAL rendezvous not required */
@@ -382,13 +402,16 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci)
* @slidx: pointer of index of SAL error record
* @peidx: pointer of index of processor error section
* @pbci: pointer of pal_bus_check_info
+ * @sos: pointer to hand off struct between SAL and OS
*
* Return value:
* 1 on Success / 0 on Failure
*/
static int
-recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci)
+recover_from_read_error(slidx_table_t *slidx,
+ peidx_table_t *peidx, pal_bus_check_info_t *pbci,
+ struct ia64_sal_os_state *sos)
{
sal_log_mod_error_info_t *smei;
pal_min_state_area_t *pmsa;
@@ -426,7 +449,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
* setup for resume to bottom half of MCA,
* "mca_handler_bhhook"
*/
- pmsa = (pal_min_state_area_t *)(sal_to_os_handoff_state->pal_min_state | (6ul<<61));
+ pmsa = sos->pal_min_state;
/* pass to bhhook as 1st argument (gr8) */
pmsa->pmsa_gr[8-1] = smei->target_identifier;
/* set interrupted return address (but no use) */
@@ -453,23 +476,28 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
* @slidx: pointer of index of SAL error record
* @peidx: pointer of index of processor error section
* @pbci: pointer of pal_bus_check_info
+ * @sos: pointer to hand off struct between SAL and OS
*
* Return value:
* 1 on Success / 0 on Failure
*/
static int
-recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci)
+recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx,
+ pal_bus_check_info_t *pbci,
+ struct ia64_sal_os_state *sos)
{
int status = 0;
- pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx);
+ pal_processor_state_info_t *psp =
+ (pal_processor_state_info_t*)peidx_psp(peidx);
if (psp->bc && pbci->eb && pbci->bsi == 0) {
switch(pbci->type) {
case 1: /* partial read */
case 3: /* full line(cpu) read */
case 9: /* I/O space read */
- status = recover_from_read_error(slidx, peidx, pbci);
+ status = recover_from_read_error(slidx, peidx, pbci,
+ sos);
break;
case 0: /* unknown */
case 2: /* partial write */
@@ -480,7 +508,8 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_
case 8: /* write coalescing transactions */
case 10: /* I/O space write */
case 11: /* inter-processor interrupt message(IPI) */
- case 12: /* interrupt acknowledge or external task priority cycle */
+ case 12: /* interrupt acknowledge or
+ external task priority cycle */
default:
break;
}
@@ -495,6 +524,7 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_
* @slidx: pointer of index of SAL error record
* @peidx: pointer of index of processor error section
* @pbci: pointer of pal_bus_check_info
+ * @sos: pointer to hand off struct between SAL and OS
*
* Return value:
* 1 on Success / 0 on Failure
@@ -508,14 +538,17 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_
*/
static int
-recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci)
+recover_from_processor_error(int platform, slidx_table_t *slidx,
+ peidx_table_t *peidx, pal_bus_check_info_t *pbci,
+ struct ia64_sal_os_state *sos)
{
- pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx);
+ pal_processor_state_info_t *psp =
+ (pal_processor_state_info_t*)peidx_psp(peidx);
- /*
+ /*
* We cannot recover errors with other than bus_check.
*/
- if (psp->cc || psp->rc || psp->uc)
+ if (psp->cc || psp->rc || psp->uc)
return 0;
/*
@@ -544,10 +577,10 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *
* (e.g. a load from poisoned memory)
* This means "there are some platform errors".
*/
- if (platform)
- return recover_from_platform_error(slidx, peidx, pbci);
- /*
- * On account of strange SAL error record, we cannot recover.
+ if (platform)
+ return recover_from_platform_error(slidx, peidx, pbci, sos);
+ /*
+ * On account of strange SAL error record, we cannot recover.
*/
return 0;
}
@@ -555,15 +588,14 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *
/**
* mca_try_to_recover - Try to recover from MCA
* @rec: pointer to a SAL error record
+ * @sos: pointer to hand off struct between SAL and OS
*
* Return value:
* 1 on Success / 0 on Failure
*/
static int
-mca_try_to_recover(void *rec,
- ia64_mca_sal_to_os_state_t *sal_to_os_state,
- ia64_mca_os_to_sal_state_t *os_to_sal_state)
+mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos)
{
int platform_err;
int n_proc_err;
@@ -571,10 +603,6 @@ mca_try_to_recover(void *rec,
peidx_table_t peidx;
pal_bus_check_info_t pbci;
- /* handoff state from/to mca.c */
- sal_to_os_handoff_state = sal_to_os_state;
- os_to_sal_handoff_state = os_to_sal_state;
-
/* Make index of SAL error record */
platform_err = mca_make_slidx(rec, &slidx);
@@ -591,17 +619,19 @@ mca_try_to_recover(void *rec,
}
/* Make index of processor error section */
- mca_make_peidx((sal_log_processor_info_t*)slidx_first_entry(&slidx.proc_err)->hdr, &peidx);
+ mca_make_peidx((sal_log_processor_info_t*)
+ slidx_first_entry(&slidx.proc_err)->hdr, &peidx);
/* Extract Processor BUS_CHECK[0] */
*((u64*)&pbci) = peidx_check_info(&peidx, bus_check, 0);
/* Check whether MCA is global or not */
- if (is_mca_global(&peidx, &pbci))
+ if (is_mca_global(&peidx, &pbci, sos))
return 0;
/* Try to recover a processor error */
- return recover_from_processor_error(platform_err, &slidx, &peidx, &pbci);
+ return recover_from_processor_error(platform_err, &slidx, &peidx,
+ &pbci, sos);
}
/*
@@ -614,7 +644,7 @@ int __init mca_external_handler_init(void)
return -ENOMEM;
/* register external mca handlers */
- if (ia64_reg_MCA_extension(mca_try_to_recover)){
+ if (ia64_reg_MCA_extension(mca_try_to_recover)) {
printk(KERN_ERR "ia64_reg_MCA_extension failed.\n");
kfree(slidx_pool.buffer);
return -EFAULT;
diff --git a/arch/ia64/kernel/mca_drv.h b/arch/ia64/kernel/mca_drv.h
index 0227b761f2c4..e2f6fa1e0ef6 100644
--- a/arch/ia64/kernel/mca_drv.h
+++ b/arch/ia64/kernel/mca_drv.h
@@ -6,7 +6,7 @@
* Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com)
*/
/*
- * Processor error section:
+ * Processor error section:
*
* +-sal_log_processor_info_t *info-------------+
* | sal_log_section_hdr_t header; |
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S
index 2d7e0217638d..3f298ee4d00c 100644
--- a/arch/ia64/kernel/mca_drv_asm.S
+++ b/arch/ia64/kernel/mca_drv_asm.S
@@ -13,45 +13,45 @@
#include <asm/ptrace.h>
GLOBAL_ENTRY(mca_handler_bhhook)
- invala // clear RSE ?
- ;; //
- cover //
- ;; //
- clrrrb //
+ invala // clear RSE ?
+ ;;
+ cover
+ ;;
+ clrrrb
;;
- alloc r16=ar.pfs,0,2,1,0 // make a new frame
+ alloc r16=ar.pfs,0,2,1,0 // make a new frame
;;
- mov ar.rsc=0
+ mov ar.rsc=0
;;
- mov r13=IA64_KR(CURRENT) // current task pointer
+ mov r13=IA64_KR(CURRENT) // current task pointer
;;
- mov r2=r13
+ mov r2=r13
;;
- addl r22=IA64_RBS_OFFSET,r2
+ addl r22=IA64_RBS_OFFSET,r2
;;
- mov ar.bspstore=r22
+ mov ar.bspstore=r22
;;
- addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
+ addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
;;
- adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+ adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
;;
- st1 [r2]=r0 // clear current->thread.on_ustack flag
- mov loc0=r16
- movl loc1=mca_handler_bh // recovery C function
+ st1 [r2]=r0 // clear current->thread.on_ustack flag
+ mov loc0=r16
+ movl loc1=mca_handler_bh // recovery C function
;;
- mov out0=r8 // poisoned address
- mov b6=loc1
+ mov out0=r8 // poisoned address
+ mov b6=loc1
;;
- mov loc1=rp
+ mov loc1=rp
;;
- ssm psr.i
+ ssm psr.i
;;
- br.call.sptk.many rp=b6 // does not return ...
+ br.call.sptk.many rp=b6 // does not return ...
;;
- mov ar.pfs=loc0
- mov rp=loc1
+ mov ar.pfs=loc0
+ mov rp=loc1
;;
- mov r8=r0
+ mov r8=r0
br.ret.sptk.many rp
;;
END(mca_handler_bhhook)
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
index f6d8a010d99b..85ed54179afa 100644
--- a/arch/ia64/kernel/minstate.h
+++ b/arch/ia64/kernel/minstate.h
@@ -5,73 +5,6 @@
#include "entry.h"
/*
- * For ivt.s we want to access the stack virtually so we don't have to disable translation
- * on interrupts.
- *
- * On entry:
- * r1: pointer to current task (ar.k6)
- */
-#define MINSTATE_START_SAVE_MIN_VIRT \
-(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
- ;; \
-(pUStk) mov.m r24=ar.rnat; \
-(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \
-(pKStk) mov r1=sp; /* get sp */ \
- ;; \
-(pUStk) lfetch.fault.excl.nt1 [r22]; \
-(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \
-(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \
- ;; \
-(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \
-(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
- ;; \
-(pUStk) mov r18=ar.bsp; \
-(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */
-
-#define MINSTATE_END_SAVE_MIN_VIRT \
- bsw.1; /* switch back to bank 1 (must be last in insn group) */ \
- ;;
-
-/*
- * For mca_asm.S we want to access the stack physically since the state is saved before we
- * go virtual and don't want to destroy the iip or ipsr.
- */
-#define MINSTATE_START_SAVE_MIN_PHYS \
-(pKStk) mov r3=IA64_KR(PER_CPU_DATA);; \
-(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \
-(pKStk) ld8 r3 = [r3];; \
-(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \
-(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \
-(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
-(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \
- ;; \
-(pUStk) mov r24=ar.rnat; \
-(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \
-(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \
-(pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \
- ;; \
-(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \
- ;; \
-(pUStk) mov r18=ar.bsp; \
-(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \
-
-#define MINSTATE_END_SAVE_MIN_PHYS \
- dep r12=-1,r12,61,3; /* make sp a kernel virtual address */ \
- ;;
-
-#ifdef MINSTATE_VIRT
-# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT)
-# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_VIRT
-# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_VIRT
-#endif
-
-#ifdef MINSTATE_PHYS
-# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT);; tpa reg=reg
-# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_PHYS
-# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_PHYS
-#endif
-
-/*
* DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
* the minimum state necessary that allows us to turn psr.ic back
* on.
@@ -97,7 +30,7 @@
* we can pass interruption state as arguments to a handler.
*/
#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \
- MINSTATE_GET_CURRENT(r16); /* M (or M;;I) */ \
+ mov r16=IA64_KR(CURRENT); /* M */ \
mov r27=ar.rsc; /* M */ \
mov r20=r1; /* A */ \
mov r25=ar.unat; /* M */ \
@@ -118,7 +51,21 @@
SAVE_IFS; \
cmp.eq pKStk,pUStk=r0,r17; /* are we in kernel mode already? */ \
;; \
- MINSTATE_START_SAVE_MIN \
+(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
+ ;; \
+(pUStk) mov.m r24=ar.rnat; \
+(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \
+(pKStk) mov r1=sp; /* get sp */ \
+ ;; \
+(pUStk) lfetch.fault.excl.nt1 [r22]; \
+(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \
+(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \
+ ;; \
+(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \
+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
+ ;; \
+(pUStk) mov r18=ar.bsp; \
+(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \
adds r17=2*L1_CACHE_BYTES,r1; /* really: biggest cache-line size */ \
adds r16=PT(CR_IPSR),r1; \
;; \
@@ -181,7 +128,8 @@
EXTRA; \
movl r1=__gp; /* establish kernel global pointer */ \
;; \
- MINSTATE_END_SAVE_MIN
+ bsw.1; /* switch back to bank 1 (must be last in insn group) */ \
+ ;;
/*
* SAVE_REST saves the remainder of pt_regs (with psr.ic on).
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
index 25e7c8344564..89faa603c6be 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -307,11 +307,9 @@ vm_info(char *page)
if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
- return 0;
- }
+ } else {
-
- p += sprintf(p,
+ p += sprintf(p,
"Physical Address Space : %d bits\n"
"Virtual Address Space : %d bits\n"
"Protection Key Registers(PKR) : %d\n"
@@ -319,92 +317,99 @@ vm_info(char *page)
"Hash Tag ID : 0x%x\n"
"Size of RR.rid : %d\n",
vm_info_1.pal_vm_info_1_s.phys_add_size,
- vm_info_2.pal_vm_info_2_s.impl_va_msb+1, vm_info_1.pal_vm_info_1_s.max_pkr+1,
- vm_info_1.pal_vm_info_1_s.key_size, vm_info_1.pal_vm_info_1_s.hash_tag_id,
+ vm_info_2.pal_vm_info_2_s.impl_va_msb+1,
+ vm_info_1.pal_vm_info_1_s.max_pkr+1,
+ vm_info_1.pal_vm_info_1_s.key_size,
+ vm_info_1.pal_vm_info_1_s.hash_tag_id,
vm_info_2.pal_vm_info_2_s.rid_size);
+ }
- if (ia64_pal_mem_attrib(&attrib) != 0)
- return 0;
-
- p += sprintf(p, "Supported memory attributes : ");
- sep = "";
- for (i = 0; i < 8; i++) {
- if (attrib & (1 << i)) {
- p += sprintf(p, "%s%s", sep, mem_attrib[i]);
- sep = ", ";
+ if (ia64_pal_mem_attrib(&attrib) == 0) {
+ p += sprintf(p, "Supported memory attributes : ");
+ sep = "";
+ for (i = 0; i < 8; i++) {
+ if (attrib & (1 << i)) {
+ p += sprintf(p, "%s%s", sep, mem_attrib[i]);
+ sep = ", ";
+ }
}
+ p += sprintf(p, "\n");
}
- p += sprintf(p, "\n");
if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status);
- return 0;
- }
-
- p += sprintf(p,
- "\nTLB walker : %simplemented\n"
- "Number of DTR : %d\n"
- "Number of ITR : %d\n"
- "TLB insertable page sizes : ",
- vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
- vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
- vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
+ } else {
+ p += sprintf(p,
+ "\nTLB walker : %simplemented\n"
+ "Number of DTR : %d\n"
+ "Number of ITR : %d\n"
+ "TLB insertable page sizes : ",
+ vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
+ vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
+ vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
- p = bitvector_process(p, tr_pages);
- p += sprintf(p, "\nTLB purgeable page sizes : ");
+ p = bitvector_process(p, tr_pages);
- p = bitvector_process(p, vw_pages);
+ p += sprintf(p, "\nTLB purgeable page sizes : ");
+ p = bitvector_process(p, vw_pages);
+ }
if ((status=ia64_get_ptce(&ptce)) != 0) {
printk(KERN_ERR "ia64_get_ptce=%ld\n", status);
- return 0;
- }
-
- p += sprintf(p,
+ } else {
+ p += sprintf(p,
"\nPurge base address : 0x%016lx\n"
"Purge outer loop count : %d\n"
"Purge inner loop count : %d\n"
"Purge outer loop stride : %d\n"
"Purge inner loop stride : %d\n",
- ptce.base, ptce.count[0], ptce.count[1], ptce.stride[0], ptce.stride[1]);
+ ptce.base, ptce.count[0], ptce.count[1],
+ ptce.stride[0], ptce.stride[1]);
- p += sprintf(p,
+ p += sprintf(p,
"TC Levels : %d\n"
"Unique TC(s) : %d\n",
vm_info_1.pal_vm_info_1_s.num_tc_levels,
vm_info_1.pal_vm_info_1_s.max_unique_tcs);
- for(i=0; i < vm_info_1.pal_vm_info_1_s.num_tc_levels; i++) {
- for (j=2; j>0 ; j--) {
- tc_pages = 0; /* just in case */
+ for(i=0; i < vm_info_1.pal_vm_info_1_s.num_tc_levels; i++) {
+ for (j=2; j>0 ; j--) {
+ tc_pages = 0; /* just in case */
- /* even without unification, some levels may not be present */
- if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) {
- continue;
- }
+ /* even without unification, some levels may not be present */
+ if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) {
+ continue;
+ }
- p += sprintf(p,
+ p += sprintf(p,
"\n%s Translation Cache Level %d:\n"
"\tHash sets : %d\n"
"\tAssociativity : %d\n"
"\tNumber of entries : %d\n"
"\tFlags : ",
- cache_types[j+tc_info.tc_unified], i+1, tc_info.tc_num_sets,
- tc_info.tc_associativity, tc_info.tc_num_entries);
+ cache_types[j+tc_info.tc_unified], i+1,
+ tc_info.tc_num_sets,
+ tc_info.tc_associativity,
+ tc_info.tc_num_entries);
- if (tc_info.tc_pf) p += sprintf(p, "PreferredPageSizeOptimized ");
- if (tc_info.tc_unified) p += sprintf(p, "Unified ");
- if (tc_info.tc_reduce_tr) p += sprintf(p, "TCReduction");
+ if (tc_info.tc_pf)
+ p += sprintf(p, "PreferredPageSizeOptimized ");
+ if (tc_info.tc_unified)
+ p += sprintf(p, "Unified ");
+ if (tc_info.tc_reduce_tr)
+ p += sprintf(p, "TCReduction");
- p += sprintf(p, "\n\tSupported page sizes: ");
+ p += sprintf(p, "\n\tSupported page sizes: ");
- p = bitvector_process(p, tc_pages);
+ p = bitvector_process(p, tc_pages);
- /* when unified date (j=2) is enough */
- if (tc_info.tc_unified) break;
+ /* when unified date (j=2) is enough */
+ if (tc_info.tc_unified)
+ break;
+ }
}
}
p += sprintf(p, "\n");
@@ -440,14 +445,14 @@ register_info(char *page)
p += sprintf(p, "\n");
}
- if (ia64_pal_rse_info(&phys_stacked, &hints) != 0) return 0;
+ if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) {
p += sprintf(p,
"RSE stacked physical registers : %ld\n"
"RSE load/store hints : %ld (%s)\n",
phys_stacked, hints.ph_data,
hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)");
-
+ }
if (ia64_pal_debug_info(&iregs, &dregs))
return 0;
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f1201ac8a116..d71731ee5b61 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;
@@ -573,7 +574,7 @@ pfm_protect_ctx_ctxsw(pfm_context_t *x)
return 0UL;
}
-static inline unsigned long
+static inline void
pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
{
spin_unlock(&(x)->ctx_lock);
@@ -2217,15 +2218,18 @@ static void
pfm_free_fd(int fd, struct file *file)
{
struct files_struct *files = current->files;
+ struct fdtable *fdt;
/*
* there ie no fd_uninstall(), so we do it here
*/
spin_lock(&files->file_lock);
- files->fd[fd] = NULL;
+ fdt = files_fdtable(files);
+ 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/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index 6f0cc7a6634e..ca68e6e44a72 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -22,6 +22,11 @@
*
* Dec 5 2004 kaos@sgi.com
* Standardize which records are cleared automatically.
+ *
+ * Aug 18 2005 kaos@sgi.com
+ * mca.c may not pass a buffer, a NULL buffer just indicates that a new
+ * record is available in SAL.
+ * Replace some NR_CPUS by cpus_online, for hotplug cpu.
*/
#include <linux/types.h>
@@ -193,7 +198,7 @@ shift1_data_saved (struct salinfo_data *data, int shift)
* The buffer passed from mca.c points to the output from ia64_log_get. This is
* a persistent buffer but its contents can change between the interrupt and
* when user space processes the record. Save the record id to identify
- * changes.
+ * changes. If the buffer is NULL then just update the bitmap.
*/
void
salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
@@ -206,27 +211,29 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
BUG_ON(type >= ARRAY_SIZE(salinfo_log_name));
- if (irqsafe)
- spin_lock_irqsave(&data_saved_lock, flags);
- for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
- if (!data_saved->buffer)
- break;
- }
- if (i == saved_size) {
- if (!data->saved_num) {
- shift1_data_saved(data, 0);
- data_saved = data->data_saved + saved_size - 1;
- } else
- data_saved = NULL;
- }
- if (data_saved) {
- data_saved->cpu = smp_processor_id();
- data_saved->id = ((sal_log_record_header_t *)buffer)->id;
- data_saved->size = size;
- data_saved->buffer = buffer;
+ if (buffer) {
+ if (irqsafe)
+ spin_lock_irqsave(&data_saved_lock, flags);
+ for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
+ if (!data_saved->buffer)
+ break;
+ }
+ if (i == saved_size) {
+ if (!data->saved_num) {
+ shift1_data_saved(data, 0);
+ data_saved = data->data_saved + saved_size - 1;
+ } else
+ data_saved = NULL;
+ }
+ if (data_saved) {
+ data_saved->cpu = smp_processor_id();
+ data_saved->id = ((sal_log_record_header_t *)buffer)->id;
+ data_saved->size = size;
+ data_saved->buffer = buffer;
+ }
+ if (irqsafe)
+ spin_unlock_irqrestore(&data_saved_lock, flags);
}
- if (irqsafe)
- spin_unlock_irqrestore(&data_saved_lock, flags);
if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) {
if (irqsafe)
@@ -244,7 +251,7 @@ salinfo_timeout_check(struct salinfo_data *data)
int i;
if (!data->open)
return;
- for (i = 0; i < NR_CPUS; ++i) {
+ for_each_online_cpu(i) {
if (test_bit(i, &data->cpu_event)) {
/* double up() is not a problem, user space will see no
* records for the additional "events".
@@ -291,7 +298,7 @@ retry:
n = data->cpu_check;
for (i = 0; i < NR_CPUS; i++) {
- if (test_bit(n, &data->cpu_event)) {
+ if (test_bit(n, &data->cpu_event) && cpu_online(n)) {
cpu = n;
break;
}
@@ -585,11 +592,10 @@ salinfo_init(void)
/* we missed any events before now */
online = 0;
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j)) {
- set_bit(j, &data->cpu_event);
- ++online;
- }
+ for_each_online_cpu(j) {
+ set_bit(j, &data->cpu_event);
+ ++online;
+ }
sema_init(&data->sem, online);
*sdir++ = dir;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 84f89da7c640..1f5c26dbe705 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -384,7 +384,7 @@ setup_arch (char **cmdline_p)
if (early_console_setup(*cmdline_p) == 0)
mark_bsp_online();
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/* Initialize the ACPI boot-time table parser */
acpi_table_init();
# ifdef CONFIG_ACPI_NUMA
@@ -420,7 +420,7 @@ setup_arch (char **cmdline_p)
cpu_init(); /* initialize the bootstrap CPU */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
acpi_boot_init();
#endif
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 92ff46ad21e2..706b7734e191 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -36,7 +36,7 @@ int arch_register_cpu(int num)
parent = &sysfs_nodes[cpu_to_node(num)];
#endif /* CONFIG_NUMA */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/*
* If CPEI cannot be re-targetted, and this is
* CPEI target, then dont create the control file
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index 3288be47bc75..93d5a3b41f69 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -2020,28 +2020,6 @@ init_frame_info (struct unw_frame_info *info, struct task_struct *t,
}
void
-unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t,
- struct pt_regs *pt, struct switch_stack *sw)
-{
- unsigned long sof;
-
- init_frame_info(info, t, sw, pt->r12);
- info->cfm_loc = &pt->cr_ifs;
- info->unat_loc = &pt->ar_unat;
- info->pfs_loc = &pt->ar_pfs;
- sof = *info->cfm_loc & 0x7f;
- info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sof);
- info->ip = pt->cr_iip + ia64_psr(pt)->ri;
- info->pt = (unsigned long) pt;
- UNW_DPRINT(3, "unwind.%s:\n"
- " bsp 0x%lx\n"
- " sof 0x%lx\n"
- " ip 0x%lx\n",
- __FUNCTION__, info->bsp, sof, info->ip);
- find_save_locs(info);
-}
-
-void
unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
{
unsigned long sol;
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
index 799407e7726f..cb1af597370b 100644
--- a/arch/ia64/lib/Makefile
+++ b/arch/ia64/lib/Makefile
@@ -15,7 +15,6 @@ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
lib-$(CONFIG_PERFMON) += carta_random.o
lib-$(CONFIG_MD_RAID5) += xor.o
-lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
AFLAGS___divdi3.o =
AFLAGS___udivdi3.o = -DUNSIGNED
diff --git a/arch/ia64/lib/dec_and_lock.c b/arch/ia64/lib/dec_and_lock.c
deleted file mode 100644
index c7ce92f968f1..000000000000
--- a/arch/ia64/lib/dec_and_lock.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2003 Jerome Marchand, Bull S.A.
- * Cleaned up by David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * This file is released under the GPLv2, or at your option any later version.
- *
- * ia64 version of "atomic_dec_and_lock()" using the atomic "cmpxchg" instruction. This
- * code is an adaptation of the x86 version of "atomic_dec_and_lock()".
- */
-
-#include <linux/compiler.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-
-/*
- * Decrement REFCOUNT and if the count reaches zero, acquire the spinlock. Both of these
- * operations have to be done atomically, so that the count doesn't drop to zero without
- * acquiring the spinlock first.
- */
-int
-_atomic_dec_and_lock (atomic_t *refcount, spinlock_t *lock)
-{
- int old, new;
-
- do {
- old = atomic_read(refcount);
- new = old - 1;
-
- if (unlikely (old == 1)) {
- /* oops, we may be decrementing to zero, do it the slow way... */
- spin_lock(lock);
- if (atomic_dec_and_test(refcount))
- return 1;
- spin_unlock(lock);
- return 0;
- }
- } while (cmpxchg(&refcount->counter, old, new) != old);
- return 0;
-}
-
-EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
index 6f308e62c137..46c9331e7ab5 100644
--- a/arch/ia64/lib/memcpy_mck.S
+++ b/arch/ia64/lib/memcpy_mck.S
@@ -625,8 +625,11 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \
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/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
index dbc0b3e449c5..3ebbb3c8ba36 100644
--- a/arch/ia64/lib/swiotlb.c
+++ b/arch/ia64/lib/swiotlb.c
@@ -123,8 +123,8 @@ swiotlb_init_with_default_size (size_t default_size)
/*
* Get IO TLB memory from the low pages
*/
- io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs *
- (1 << IO_TLB_SHIFT));
+ io_tlb_start = alloc_bootmem_low_pages_limit(io_tlb_nslabs *
+ (1 << IO_TLB_SHIFT), 0x100000000);
if (!io_tlb_start)
panic("Cannot allocate SWIOTLB buffer");
io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
@@ -314,7 +314,7 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
void *
swiotlb_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, int flags)
+ dma_addr_t *dma_handle, gfp_t flags)
{
unsigned long dev_addr;
void *ret;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 24614869e866..3c32af910d60 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -230,9 +230,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
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/mm/init.c b/arch/ia64/mm/init.c
index 65f9958db9f0..1281c609ee98 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -382,13 +382,22 @@ ia64_mmu_init (void *my_cpu_data)
if (impl_va_bits < 51 || impl_va_bits > 61)
panic("CPU has bogus IMPL_VA_MSB value of %lu!\n", impl_va_bits - 1);
+ /*
+ * mapped_space_bits - PAGE_SHIFT is the total number of ptes we need,
+ * which must fit into "vmlpt_bits - pte_bits" slots. Second half of
+ * the test makes sure that our mapped space doesn't overlap the
+ * unimplemented hole in the middle of the region.
+ */
+ if ((mapped_space_bits - PAGE_SHIFT > vmlpt_bits - pte_bits) ||
+ (mapped_space_bits > impl_va_bits - 1))
+ panic("Cannot build a big enough virtual-linear page table"
+ " to cover mapped address space.\n"
+ " Try using a smaller page size.\n");
+
/* place the VMLPT at the end of each page-table mapped region: */
pta = POW2(61) - POW2(vmlpt_bits);
- if (POW2(mapped_space_bits) >= pta)
- panic("mm/init: overlap between virtually mapped linear page table and "
- "mapped kernel space!");
/*
* Set the (virtually mapped linear) page table address. Bit
* 8 selects between the short and long format, bits 2-7 the
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 9977c122e9fa..9b5de589b82f 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -498,13 +498,11 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
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/irq.c b/arch/ia64/sn/kernel/irq.c
index 9fc74631ba8a..01d18b7b5bb3 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -23,7 +23,7 @@ static void force_interrupt(int irq);
static void register_intr_pda(struct sn_irq_info *sn_irq_info);
static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);
-extern int sn_force_interrupt_flag;
+int sn_force_interrupt_flag = 1;
extern int sn_ioif_inited;
static struct list_head **sn_irq_lh;
static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index a594aca959e6..6f8c5883716b 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -49,6 +49,7 @@
#include <asm/sn/clksupport.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/geo.h>
+#include <asm/sn/sn_feature_sets.h>
#include "xtalk/xwidgetdev.h"
#include "xtalk/hubdev.h"
#include <asm/sn/klconfig.h>
@@ -56,7 +57,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];
@@ -97,6 +98,7 @@ EXPORT_SYMBOL(sn_region_size);
int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
short physical_node_map[MAX_PHYSNODE_ID];
+static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS];
EXPORT_SYMBOL(physical_node_map);
@@ -271,7 +273,10 @@ void __init sn_setup(char **cmdline_p)
u32 version = sn_sal_rev();
extern void sn_cpu_init(void);
- ia64_sn_plat_set_error_handling_features();
+ ia64_sn_plat_set_error_handling_features(); // obsolete
+ ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
+ ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
+
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
/*
@@ -314,16 +319,6 @@ void __init sn_setup(char **cmdline_p)
printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
- /*
- * Confirm the SAL we're running on is recent enough...
- */
- if (version < SN_SAL_MIN_VERSION) {
- printk(KERN_ERR "This kernel needs SGI SAL version >= "
- "%x.%02x\n", SN_SAL_MIN_VERSION >> 8,
- SN_SAL_MIN_VERSION & 0x00FF);
- panic("PROM version too old\n");
- }
-
master_nasid = boot_get_nasid();
status =
@@ -480,6 +475,10 @@ void __init sn_cpu_init(void)
if (nodepdaindr[0] == NULL)
return;
+ for (i = 0; i < MAX_PROM_FEATURE_SETS; i++)
+ if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0)
+ break;
+
cpuid = smp_processor_id();
cpuphyid = get_sapicid();
@@ -651,3 +650,12 @@ nasid_slice_to_cpuid(int nasid, int slice)
return -1;
}
+
+int sn_prom_feature_available(int id)
+{
+ if (id >= BITS_PER_LONG * MAX_PROM_FEATURE_SETS)
+ return 0;
+ return test_bit(id, sn_prom_features);
+}
+EXPORT_SYMBOL(sn_prom_feature_available);
+
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
index 51bf82720d99..a06719d752a0 100644
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
@@ -52,7 +52,7 @@ static int licenseID_open(struct inode *inode, struct file *file)
* the bridge chip. The hardware will then send an interrupt message if the
* interrupt line is active. This mimics a level sensitive interrupt.
*/
-int sn_force_interrupt_flag = 1;
+extern int sn_force_interrupt_flag;
static int sn_force_interrupt_show(struct seq_file *s, void *p)
{
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
index d0ee635daf2e..e5f5a4e51f70 100644
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -939,7 +939,7 @@ xpc_map_bte_errors(bte_result_t error)
static inline void *
-xpc_kmalloc_cacheline_aligned(size_t size, int flags, void **base)
+xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
{
/* see if kmalloc will give us cachline aligned memory by default */
*base = kmalloc(size, flags);
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index bb1d5cf30440..ed7c21586e98 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -885,6 +885,10 @@ xpc_init(void)
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 78c13d676fa6..e5c6d3c0a8e9 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -130,7 +130,7 @@ struct net_device *xpnet_device;
*/
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/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 0e4b9ad9ef02..75e6e874bebf 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -75,7 +75,7 @@ EXPORT_SYMBOL(sn_dma_set_mask);
* more information.
*/
void *sn_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int flags)
+ dma_addr_t * dma_handle, gfp_t flags)
{
void *cpuaddr;
unsigned long phys_addr;
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 7622d4ec5f08..4d100f3886e1 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -220,11 +220,6 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure.
-config HAVE_DEC_LOCK
- bool
- depends on (SMP || PREEMPT)
- default n
-
config SMP
bool "Symmetric multi-processing support"
---help---
@@ -242,8 +237,8 @@ config SMP
Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
Management" code will be disabled if you say Y here.
- See also the <file:Documentation/smp.tex>,
- <file:Documentation/smp.txt> and the SMP-HOWTO available at
+ See also the <file:Documentation/smp.txt>,
+ and the SMP-HOWTO available at
<http://www.linuxdoc.org/docs.html#howto>.
If you don't know what to do here, say N.
diff --git a/arch/m32r/Makefile b/arch/m32r/Makefile
index dd4418d846e9..983d438b14b6 100644
--- a/arch/m32r/Makefile
+++ b/arch/m32r/Makefile
@@ -24,7 +24,7 @@ aflags-$(CONFIG_ISA_M32R) += -DNO_FPU -Wa,-no-bitinst
CFLAGS += $(cflags-y)
AFLAGS += $(aflags-y)
-CHECKFLAGS := $(CHECK) -D__m32r__
+CHECKFLAGS += -D__m32r__ -D__BIG_ENDIAN__=1
head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o
diff --git a/arch/m32r/kernel/asm-offsets.c b/arch/m32r/kernel/asm-offsets.c
new file mode 100644
index 000000000000..9e263112a6e2
--- /dev/null
+++ b/arch/m32r/kernel/asm-offsets.c
@@ -0,0 +1 @@
+/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index dddbf6b5ed2c..85920fb8d08c 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -681,6 +681,15 @@ ENTRY(debug_trap)
bl do_debug_trap
bra error_code
+ENTRY(ill_trap)
+ /* void ill_trap(void) */
+ SWITCH_TO_KERNEL_STACK
+ SAVE_ALL
+ ldi r1, #0 ; error_code ; FIXME
+ mv r0, sp ; pt_regs
+ bl do_ill_trap
+ bra error_code
+
/* Cache flushing handler */
ENTRY(cache_flushing_handler)
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
index 48b187f2d2b3..8b1f6eb76870 100644
--- a/arch/m32r/kernel/smp.c
+++ b/arch/m32r/kernel/smp.c
@@ -275,12 +275,14 @@ static void flush_tlb_all_ipi(void *info)
*==========================================================================*/
void smp_flush_tlb_mm(struct mm_struct *mm)
{
- int cpu_id = smp_processor_id();
+ int cpu_id;
cpumask_t cpu_mask;
- unsigned long *mmc = &mm->context[cpu_id];
+ unsigned long *mmc;
unsigned long flags;
preempt_disable();
+ cpu_id = smp_processor_id();
+ mmc = &mm->context[cpu_id];
cpu_mask = mm->cpu_vm_mask;
cpu_clear(cpu_id, cpu_mask);
@@ -343,12 +345,14 @@ void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
{
struct mm_struct *mm = vma->vm_mm;
- int cpu_id = smp_processor_id();
+ int cpu_id;
cpumask_t cpu_mask;
- unsigned long *mmc = &mm->context[cpu_id];
+ unsigned long *mmc;
unsigned long flags;
preempt_disable();
+ cpu_id = smp_processor_id();
+ mmc = &mm->context[cpu_id];
cpu_mask = mm->cpu_vm_mask;
cpu_clear(cpu_id, cpu_mask);
@@ -892,7 +896,6 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
int try)
{
spinlock_t *ipilock;
- unsigned long flags = 0;
volatile unsigned long *ipicr_addr;
unsigned long ipicr_val;
unsigned long my_physid_mask;
@@ -916,50 +919,27 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
* write IPICRi (send IPIi)
* unlock ipi_lock[i]
*/
+ spin_lock(ipilock);
__asm__ __volatile__ (
- ";; LOCK ipi_lock[i] \n\t"
+ ";; CHECK IPICRi == 0 \n\t"
".fillinsn \n"
"1: \n\t"
- "mvfc %1, psw \n\t"
- "clrpsw #0x40 -> nop \n\t"
- DCACHE_CLEAR("r4", "r5", "%2")
- "lock r4, @%2 \n\t"
- "addi r4, #-1 \n\t"
- "unlock r4, @%2 \n\t"
- "mvtc %1, psw \n\t"
- "bnez r4, 2f \n\t"
- LOCK_SECTION_START(".balign 4 \n\t")
- ".fillinsn \n"
- "2: \n\t"
- "ld r4, @%2 \n\t"
- "blez r4, 2b \n\t"
+ "ld %0, @%1 \n\t"
+ "and %0, %4 \n\t"
+ "beqz %0, 2f \n\t"
+ "bnez %3, 3f \n\t"
"bra 1b \n\t"
- LOCK_SECTION_END
- ";; CHECK IPICRi == 0 \n\t"
- ".fillinsn \n"
- "3: \n\t"
- "ld %0, @%3 \n\t"
- "and %0, %6 \n\t"
- "beqz %0, 4f \n\t"
- "bnez %5, 5f \n\t"
- "bra 3b \n\t"
";; WRITE IPICRi (send IPIi) \n\t"
".fillinsn \n"
- "4: \n\t"
- "st %4, @%3 \n\t"
- ";; UNLOCK ipi_lock[i] \n\t"
+ "2: \n\t"
+ "st %2, @%1 \n\t"
".fillinsn \n"
- "5: \n\t"
- "ldi r4, #1 \n\t"
- "st r4, @%2 \n\t"
+ "3: \n\t"
: "=&r"(ipicr_val)
- : "r"(flags), "r"(&ipilock->slock), "r"(ipicr_addr),
- "r"(mask), "r"(try), "r"(my_physid_mask)
- : "memory", "r4"
-#ifdef CONFIG_CHIP_M32700_TS1
- , "r5"
-#endif /* CONFIG_CHIP_M32700_TS1 */
+ : "r"(ipicr_addr), "r"(mask), "r"(try), "r"(my_physid_mask)
+ : "memory"
);
+ spin_unlock(ipilock);
return ipicr_val;
}
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 01922271d17e..5fe8ed6d62dc 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -5,8 +5,6 @@
* Hitoshi Yamamoto
*/
-/* $Id$ */
-
/*
* 'traps.c' handles hardware traps and faults after we have saved some
* state in 'entry.S'.
@@ -35,6 +33,7 @@ asmlinkage void ei_handler(void);
asmlinkage void rie_handler(void);
asmlinkage void debug_trap(void);
asmlinkage void cache_flushing_handler(void);
+asmlinkage void ill_trap(void);
#ifdef CONFIG_SMP
extern void smp_reschedule_interrupt(void);
@@ -77,22 +76,22 @@ void set_eit_vector_entries(void)
eit_vector[5] = BRA_INSN(default_eit_handler, 5);
eit_vector[8] = BRA_INSN(rie_handler, 8);
eit_vector[12] = BRA_INSN(alignment_check, 12);
- eit_vector[16] = 0xff000000UL;
+ eit_vector[16] = BRA_INSN(ill_trap, 16);
eit_vector[17] = BRA_INSN(debug_trap, 17);
eit_vector[18] = BRA_INSN(system_call, 18);
- eit_vector[19] = 0xff000000UL;
- eit_vector[20] = 0xff000000UL;
- eit_vector[21] = 0xff000000UL;
- eit_vector[22] = 0xff000000UL;
- eit_vector[23] = 0xff000000UL;
- eit_vector[24] = 0xff000000UL;
- eit_vector[25] = 0xff000000UL;
- eit_vector[26] = 0xff000000UL;
- eit_vector[27] = 0xff000000UL;
+ eit_vector[19] = BRA_INSN(ill_trap, 19);
+ eit_vector[20] = BRA_INSN(ill_trap, 20);
+ eit_vector[21] = BRA_INSN(ill_trap, 21);
+ eit_vector[22] = BRA_INSN(ill_trap, 22);
+ eit_vector[23] = BRA_INSN(ill_trap, 23);
+ eit_vector[24] = BRA_INSN(ill_trap, 24);
+ eit_vector[25] = BRA_INSN(ill_trap, 25);
+ eit_vector[26] = BRA_INSN(ill_trap, 26);
+ eit_vector[27] = BRA_INSN(ill_trap, 27);
eit_vector[28] = BRA_INSN(cache_flushing_handler, 28);
- eit_vector[29] = 0xff000000UL;
- eit_vector[30] = 0xff000000UL;
- eit_vector[31] = 0xff000000UL;
+ eit_vector[29] = BRA_INSN(ill_trap, 29);
+ eit_vector[30] = BRA_INSN(ill_trap, 30);
+ eit_vector[31] = BRA_INSN(ill_trap, 31);
eit_vector[32] = BRA_INSN(ei_handler, 32);
eit_vector[64] = BRA_INSN(pie_handler, 64);
#ifdef CONFIG_MMU
@@ -286,7 +285,8 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
DO_ERROR( 1, SIGTRAP, "debug trap", debug_trap)
DO_ERROR_INFO(0x20, SIGILL, "reserved instruction ", rie_handler, ILL_ILLOPC, regs->bpc)
-DO_ERROR_INFO(0x100, SIGILL, "privilege instruction", pie_handler, ILL_PRVOPC, regs->bpc)
+DO_ERROR_INFO(0x100, SIGILL, "privileged instruction", pie_handler, ILL_PRVOPC, regs->bpc)
+DO_ERROR_INFO(-1, SIGILL, "illegal trap", ill_trap, ILL_ILLTRP, regs->bpc)
extern int handle_unaligned_access(unsigned long, struct pt_regs *);
@@ -329,4 +329,3 @@ asmlinkage void do_alignment_check(struct pt_regs *regs, long error_code)
set_fs(oldfs);
}
}
-
diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c
index 6c6855f1aa05..ce16bbe26a52 100644
--- a/arch/m32r/lib/usercopy.c
+++ b/arch/m32r/lib/usercopy.c
@@ -13,7 +13,7 @@
#include <asm/uaccess.h>
unsigned long
-__generic_copy_to_user(void *to, const void *from, unsigned long n)
+__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
{
prefetch(from);
if (access_ok(VERIFY_WRITE, to, n))
@@ -22,7 +22,7 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n)
}
unsigned long
-__generic_copy_from_user(void *to, const void *from, unsigned long n)
+__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
{
prefetchw(to);
if (access_ok(VERIFY_READ, from, n))
@@ -111,7 +111,7 @@ do { \
#endif /* CONFIG_ISA_DUAL_ISSUE */
long
-__strncpy_from_user(char *dst, const char *src, long count)
+__strncpy_from_user(char *dst, const char __user *src, long count)
{
long res;
__do_strncpy_from_user(dst, src, count, res);
@@ -119,7 +119,7 @@ __strncpy_from_user(char *dst, const char *src, long count)
}
long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
@@ -222,7 +222,7 @@ do { \
#endif /* not CONFIG_ISA_DUAL_ISSUE */
unsigned long
-clear_user(void *to, unsigned long n)
+clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
__do_clear_user(to, n);
@@ -230,7 +230,7 @@ clear_user(void *to, unsigned long n)
}
unsigned long
-__clear_user(void *to, unsigned long n)
+__clear_user(void __user *to, unsigned long n)
{
__do_clear_user(to, n);
return n;
@@ -244,7 +244,7 @@ __clear_user(void *to, unsigned long n)
#ifdef CONFIG_ISA_DUAL_ISSUE
-long strnlen_user(const char *s, long n)
+long strnlen_user(const char __user *s, long n)
{
unsigned long mask = -__addr_ok(s);
unsigned long res;
@@ -313,7 +313,7 @@ long strnlen_user(const char *s, long n)
#else /* not CONFIG_ISA_DUAL_ISSUE */
-long strnlen_user(const char *s, long n)
+long strnlen_user(const char __user *s, long n)
{
unsigned long mask = -__addr_ok(s);
unsigned long res;
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index 466e7407afc7..34d826d10f1b 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -113,14 +113,5 @@ else
bzip2 -1c vmlinux >vmlinux.bz2
endif
-prepare: include/asm-$(ARCH)/offsets.h
-CLEAN_FILES += include/asm-$(ARCH)/offsets.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
archclean:
rm -f vmlinux.gz vmlinux.bz2
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index cb5d93630467..bd5d134e9f12 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -63,7 +63,7 @@ void __init amiga_init_sound(void)
}
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/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S
index dbc1255a5e99..9571a21d6ad4 100644
--- a/arch/m68k/fpsp040/skeleton.S
+++ b/arch/m68k/fpsp040/skeleton.S
@@ -40,7 +40,7 @@
#include <linux/linkage.h>
#include <asm/entry.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
|SKELETON idnt 2,1 | Motorola 040 Floating Point Software Package
diff --git a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
index 803a6ecdda81..4ba2c74da93d 100644
--- a/arch/m68k/ifpsp060/iskeleton.S
+++ b/arch/m68k/ifpsp060/iskeleton.S
@@ -36,7 +36,7 @@
#include <linux/linkage.h>
#include <asm/entry.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
|################################
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index e964015a31dc..23ca60a45552 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -42,7 +42,7 @@
#include <asm/traps.h>
#include <asm/unistd.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.globl system_call, buserr, trap
.globl resume, ret_from_exception
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
index 7cd6de17c20d..d4336d846df1 100644
--- a/arch/m68k/kernel/head.S
+++ b/arch/m68k/kernel/head.S
@@ -263,7 +263,7 @@
#include <asm/entry.h>
#include <asm/pgtable.h>
#include <asm/page.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#ifdef CONFIG_MAC
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index 44c5cd2ad6a8..8f0640847ad2 100644
--- a/arch/m68k/mac/macboing.c
+++ b/arch/m68k/mac/macboing.c
@@ -56,8 +56,7 @@ static void ( *mac_special_bell )( unsigned int, unsigned int, unsigned int );
/*
* 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/m68k/math-emu/fp_emu.h b/arch/m68k/math-emu/fp_emu.h
index 1d6edc975d89..c1ecfef7886a 100644
--- a/arch/m68k/math-emu/fp_emu.h
+++ b/arch/m68k/math-emu/fp_emu.h
@@ -39,7 +39,7 @@
#define _FP_EMU_H
#ifdef __ASSEMBLY__
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#endif
#include <asm/math-emu.h>
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index 7ce5e55b2401..b8fdf191b8f6 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -102,21 +102,11 @@ CFLAGS += -DUTS_SYSNAME=\"uClinux\"
head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o
-CLEAN_FILES := include/asm-$(ARCH)/asm-offsets.h \
- arch/$(ARCH)/kernel/asm-offsets.s
-
core-y += arch/m68knommu/kernel/ \
arch/m68knommu/mm/ \
$(CLASSDIR) \
arch/m68knommu/platform/$(PLATFORM)/
libs-y += arch/m68knommu/lib/
-prepare: include/asm-$(ARCH)/asm-offsets.h
-
archclean:
$(Q)$(MAKE) $(clean)=arch/m68knommu/boot
-
-include/asm-$(ARCH)/asm-offsets.h: arch/$(ARCH)/kernel/asm-offsets.s \
- include/asm include/linux/version.h \
- include/config/MARKER
- $(call filechk,gen-asm-offsets)
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile
new file mode 100644
index 000000000000..c1578b016160
--- /dev/null
+++ b/arch/m68knommu/platform/523x/Makefile
@@ -0,0 +1,19 @@
+#
+# 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 5cb28690f89a..cf36e7d007b9 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -104,11 +104,11 @@ int mcf_timerirqpending(int timer)
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 84b6b70641e1..6fe5a2b8fb08 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 fd7c93f86481..bcfa5d7fe1e2 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/head-de2.S b/arch/m68knommu/platform/68328/head-de2.S
new file mode 100644
index 000000000000..94c5a1609a75
--- /dev/null
+++ b/arch/m68knommu/platform/68328/head-de2.S
@@ -0,0 +1,135 @@
+#include <linux/config.h>
+
+#if defined(CONFIG_RAM32MB)
+#define MEM_END 0x02000000 /* Memory size 32Mb */
+#elif defined(CONFIG_RAM16MB)
+#define MEM_END 0x01000000 /* Memory size 16Mb */
+#else
+#define MEM_END 0x00800000 /* Memory size 8Mb */
+#endif
+
+#undef CRT_DEBUG
+
+.macro PUTC CHAR
+#ifdef CRT_DEBUG
+ moveq #\CHAR, %d7
+ jsr putc
+#endif
+.endm
+
+ .global _start
+ .global _rambase
+ .global _ramvec
+ .global _ramstart
+ .global _ramend
+
+ .data
+
+/*
+ * Set up the usable of RAM stuff
+ */
+_rambase:
+ .long 0
+_ramvec:
+ .long 0
+_ramstart:
+ .long 0
+_ramend:
+ .long 0
+
+ .text
+
+_start:
+
+/*
+ * Setup initial stack
+ */
+ /* disable all interrupts */
+ movew #0x2700, %sr
+ movel #-1, 0xfffff304
+ movel #MEM_END-4, %sp
+
+ PUTC '\r'
+ PUTC '\n'
+ PUTC 'A'
+ PUTC 'B'
+
+/*
+ * Determine end of RAM
+ */
+
+ movel #MEM_END, %a0
+ movel %a0, _ramend
+
+ PUTC 'C'
+
+/*
+ * Move ROM filesystem above bss :-)
+ */
+
+ moveal #_sbss, %a0 /* romfs at the start of bss */
+ moveal #_ebss, %a1 /* Set up destination */
+ movel %a0, %a2 /* Copy of bss start */
+
+ movel 8(%a0), %d1 /* Get size of ROMFS */
+ addql #8, %d1 /* Allow for rounding */
+ andl #0xfffffffc, %d1 /* Whole words */
+
+ addl %d1, %a0 /* Copy from end */
+ addl %d1, %a1 /* Copy from end */
+ movel %a1, _ramstart /* Set start of ram */
+
+1:
+ movel -(%a0), %d0 /* Copy dword */
+ movel %d0, -(%a1)
+ cmpl %a0, %a2 /* Check if at end */
+ bne 1b
+
+ PUTC 'D'
+
+/*
+ * Initialize BSS segment to 0
+ */
+
+ lea _sbss, %a0
+ lea _ebss, %a1
+
+ /* Copy 0 to %a0 until %a0 == %a1 */
+2: cmpal %a0, %a1
+ beq 1f
+ clrl (%a0)+
+ bra 2b
+1:
+
+ PUTC 'E'
+
+/*
+ * Load the current task pointer and stack
+ */
+
+ lea init_thread_union, %a0
+ lea 0x2000(%a0), %sp
+
+ PUTC 'F'
+ PUTC '\r'
+ PUTC '\n'
+
+/*
+ * Go
+ */
+
+ jmp start_kernel
+
+/*
+ * Local functions
+ */
+
+#ifdef CRT_DEBUG
+putc:
+ moveb %d7, 0xfffff907
+1:
+ movew 0xfffff906, %d7
+ andw #0x2000, %d7
+ beq 1b
+ rts
+#endif
diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c
new file mode 100644
index 000000000000..68c2cd6b0030
--- /dev/null
+++ b/arch/m68knommu/platform/68328/timers.c
@@ -0,0 +1,106 @@
+/***************************************************************************/
+
+/*
+ * 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/68360/head-ram.S b/arch/m68knommu/platform/68360/head-ram.S
new file mode 100644
index 000000000000..a5c639a51eef
--- /dev/null
+++ b/arch/m68knommu/platform/68360/head-ram.S
@@ -0,0 +1,408 @@
+/* arch/m68knommu/platform/68360/head-ram.S
+ *
+ * Startup code for Motorola 68360
+ *
+ * Copyright 2001 (C) SED Systems, a Division of Calian Ltd.
+ * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
+ * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
+ * uClinux Kernel
+ * Copyright (C) Michael Leslie <mleslie@lineo.com>
+ * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
+ * Copyright (C) 1998 D. Jeff Dionne <jeff@uclinux.org>,
+ *
+ */
+#define ASSEMBLY
+#include <linux/config.h>
+
+.global _stext
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global _quicc_base
+.global _periph_base
+
+#define REGB 0x1000
+#define PEPAR (_dprbase + REGB + 0x0016)
+#define GMR (_dprbase + REGB + 0x0040)
+#define OR0 (_dprbase + REGB + 0x0054)
+#define BR0 (_dprbase + REGB + 0x0050)
+#define OR1 (_dprbase + REGB + 0x0064)
+#define BR1 (_dprbase + REGB + 0x0060)
+#define OR4 (_dprbase + REGB + 0x0094)
+#define BR4 (_dprbase + REGB + 0x0090)
+#define OR6 (_dprbase + REGB + 0x00b4)
+#define BR6 (_dprbase + REGB + 0x00b0)
+#define OR7 (_dprbase + REGB + 0x00c4)
+#define BR7 (_dprbase + REGB + 0x00c0)
+
+#define MCR (_dprbase + REGB + 0x0000)
+#define AVR (_dprbase + REGB + 0x0008)
+
+#define SYPCR (_dprbase + REGB + 0x0022)
+
+#define PLLCR (_dprbase + REGB + 0x0010)
+#define CLKOCR (_dprbase + REGB + 0x000C)
+#define CDVCR (_dprbase + REGB + 0x0014)
+
+#define BKAR (_dprbase + REGB + 0x0030)
+#define BKCR (_dprbase + REGB + 0x0034)
+#define SWIV (_dprbase + REGB + 0x0023)
+#define PICR (_dprbase + REGB + 0x0026)
+#define PITR (_dprbase + REGB + 0x002A)
+
+/* Define for all memory configuration */
+#define MCU_SIM_GMR 0x00000000
+#define SIM_OR_MASK 0x0fffffff
+
+/* Defines for chip select zero - the flash */
+#define SIM_OR0_MASK 0x20000002
+#define SIM_BR0_MASK 0x00000001
+
+
+/* Defines for chip select one - the RAM */
+#define SIM_OR1_MASK 0x10000000
+#define SIM_BR1_MASK 0x00000001
+
+#define MCU_SIM_MBAR_ADRS 0x0003ff00
+#define MCU_SIM_MBAR_BA_MASK 0xfffff000
+#define MCU_SIM_MBAR_AS_MASK 0x00000001
+
+#define MCU_SIM_PEPAR 0x00B4
+
+#define MCU_DISABLE_INTRPTS 0x2700
+#define MCU_SIM_AVR 0x00
+
+#define MCU_SIM_MCR 0x00005cff
+
+#define MCU_SIM_CLKOCR 0x00
+#define MCU_SIM_PLLCR 0x8000
+#define MCU_SIM_CDVCR 0x0000
+
+#define MCU_SIM_SYPCR 0x0000
+#define MCU_SIM_SWIV 0x00
+#define MCU_SIM_PICR 0x0000
+#define MCU_SIM_PITR 0x0000
+
+
+#include <asm/m68360_regs.h>
+
+
+/*
+ * By the time this RAM specific code begins to execute, DPRAM
+ * and DRAM should already be mapped and accessible.
+ */
+
+ .text
+_start:
+_stext:
+ nop
+ ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */
+ /* We should not need to setup the boot stack the reset should do it. */
+ movea.l #__ramend, %sp /*set up stack at the end of DRAM:*/
+
+set_mbar_register:
+ moveq.l #0x07, %d1 /* Setup MBAR */
+ movec %d1, %dfc
+
+ lea.l MCU_SIM_MBAR_ADRS, %a0
+ move.l #_dprbase, %d0
+ andi.l #MCU_SIM_MBAR_BA_MASK, %d0
+ ori.l #MCU_SIM_MBAR_AS_MASK, %d0
+ moves.l %d0, %a0@
+
+ moveq.l #0x05, %d1
+ movec.l %d1, %dfc
+
+ /* Now we can begin to access registers in DPRAM */
+
+set_sim_mcr:
+ /* Set Module Configuration Register */
+ move.l #MCU_SIM_MCR, MCR
+
+ /* to do: Determine cause of reset */
+
+ /*
+ * configure system clock MC68360 p. 6-40
+ * (value +1)*osc/128 = system clock
+ */
+set_sim_clock:
+ move.w #MCU_SIM_PLLCR, PLLCR
+ move.b #MCU_SIM_CLKOCR, CLKOCR
+ move.w #MCU_SIM_CDVCR, CDVCR
+
+ /* Wait for the PLL to settle */
+ move.w #16384, %d0
+pll_settle_wait:
+ subi.w #1, %d0
+ bne pll_settle_wait
+
+ /* Setup the system protection register, and watchdog timer register */
+ move.b #MCU_SIM_SWIV, SWIV
+ move.w #MCU_SIM_PICR, PICR
+ move.w #MCU_SIM_PITR, PITR
+ move.w #MCU_SIM_SYPCR, SYPCR
+
+ /* Clear DPRAM - system + parameter */
+ movea.l #_dprbase, %a0
+ movea.l #_dprbase+0x2000, %a1
+
+ /* Copy 0 to %a0 until %a0 == %a1 */
+clear_dpram:
+ movel #0, %a0@+
+ cmpal %a0, %a1
+ bhi clear_dpram
+
+configure_memory_controller:
+ /* Set up Global Memory Register (GMR) */
+ move.l #MCU_SIM_GMR, %d0
+ move.l %d0, GMR
+
+configure_chip_select_0:
+ move.l #__ramend, %d0
+ subi.l #__ramstart, %d0
+ subq.l #0x01, %d0
+ eori.l #SIM_OR_MASK, %d0
+ ori.l #SIM_OR0_MASK, %d0
+ move.l %d0, OR0
+
+ move.l #__ramstart, %d0
+ ori.l #SIM_BR0_MASK, %d0
+ move.l %d0, BR0
+
+configure_chip_select_1:
+ move.l #__rom_end, %d0
+ subi.l #__rom_start, %d0
+ subq.l #0x01, %d0
+ eori.l #SIM_OR_MASK, %d0
+ ori.l #SIM_OR1_MASK, %d0
+ move.l %d0, OR1
+
+ move.l #__rom_start, %d0
+ ori.l #SIM_BR1_MASK, %d0
+ move.l %d0, BR1
+
+ move.w #MCU_SIM_PEPAR, PEPAR
+
+ /* point to vector table: */
+ move.l #_romvec, %a0
+ move.l #_ramvec, %a1
+copy_vectors:
+ move.l %a0@, %d0
+ move.l %d0, %a1@
+ move.l %a0@, %a1@
+ addq.l #0x04, %a0
+ addq.l #0x04, %a1
+ cmp.l #_start, %a0
+ blt copy_vectors
+
+ move.l #_ramvec, %a1
+ movec %a1, %vbr
+
+
+ /* Copy data segment from ROM to RAM */
+ moveal #_stext, %a0
+ moveal #_sdata, %a1
+ moveal #_edata, %a2
+
+ /* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+ move.l %a0@, %d0
+ addq.l #0x04, %a0
+ move.l %d0, %a1@
+ addq.l #0x04, %a1
+ cmp.l #_edata, %a1
+ blt LD1
+
+ moveal #_sbss, %a0
+ moveal #_ebss, %a1
+
+ /* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+ movel #0, %a0@+
+ cmpal %a0, %a1
+ bhi L1
+
+load_quicc:
+ move.l #_dprbase, _quicc_base
+
+store_ram_size:
+ /* Set ram size information */
+ move.l #_sdata, _rambase
+ move.l #_ebss, _ramstart
+ move.l #__ramend, %d0
+ sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/
+ move.l %d0, _ramend /* Different from __ramend.*/
+
+store_flash_size:
+ /* Set rom size information */
+ move.l #__rom_end, %d0
+ sub.l #__rom_start, %d0
+ move.l %d0, rom_length
+
+ pea 0
+ pea env
+ pea %sp@(4)
+ pea 0
+
+ lea init_thread_union, %a2
+ lea 0x2000(%a2), %sp
+
+lp:
+ jsr start_kernel
+
+_exit:
+ jmp _exit
+
+
+ .data
+ .align 4
+env:
+ .long 0
+_quicc_base:
+ .long 0
+_periph_base:
+ .long 0
+_ramvec:
+ .long 0
+_rambase:
+ .long 0
+_ramstart:
+ .long 0
+_ramend:
+ .long 0
+_dprbase:
+ .long 0xffffe000
+
+ .text
+
+ /*
+ * These are the exception vectors at boot up, they are copied into RAM
+ * and then overwritten as needed.
+ */
+
+.section ".data.initvect","awx"
+ .long __ramend /* Reset: Initial Stack Pointer - 0. */
+ .long _start /* Reset: Initial Program Counter - 1. */
+ .long buserr /* Bus Error - 2. */
+ .long trap /* Address Error - 3. */
+ .long trap /* Illegal Instruction - 4. */
+ .long trap /* Divide by zero - 5. */
+ .long trap /* CHK, CHK2 Instructions - 6. */
+ .long trap /* TRAPcc, TRAPV Instructions - 7. */
+ .long trap /* Privilege Violation - 8. */
+ .long trap /* Trace - 9. */
+ .long trap /* Line 1010 Emulator - 10. */
+ .long trap /* Line 1111 Emualtor - 11. */
+ .long trap /* Harware Breakpoint - 12. */
+ .long trap /* (Reserved for Coprocessor Protocol Violation)- 13. */
+ .long trap /* Format Error - 14. */
+ .long trap /* Uninitialized Interrupt - 15. */
+ .long trap /* (Unassigned, Reserver) - 16. */
+ .long trap /* (Unassigned, Reserver) - 17. */
+ .long trap /* (Unassigned, Reserver) - 18. */
+ .long trap /* (Unassigned, Reserver) - 19. */
+ .long trap /* (Unassigned, Reserver) - 20. */
+ .long trap /* (Unassigned, Reserver) - 21. */
+ .long trap /* (Unassigned, Reserver) - 22. */
+ .long trap /* (Unassigned, Reserver) - 23. */
+ .long trap /* Spurious Interrupt - 24. */
+ .long trap /* Level 1 Interrupt Autovector - 25. */
+ .long trap /* Level 2 Interrupt Autovector - 26. */
+ .long trap /* Level 3 Interrupt Autovector - 27. */
+ .long trap /* Level 4 Interrupt Autovector - 28. */
+ .long trap /* Level 5 Interrupt Autovector - 29. */
+ .long trap /* Level 6 Interrupt Autovector - 30. */
+ .long trap /* Level 7 Interrupt Autovector - 31. */
+ .long system_call /* Trap Instruction Vectors 0 - 32. */
+ .long trap /* Trap Instruction Vectors 1 - 33. */
+ .long trap /* Trap Instruction Vectors 2 - 34. */
+ .long trap /* Trap Instruction Vectors 3 - 35. */
+ .long trap /* Trap Instruction Vectors 4 - 36. */
+ .long trap /* Trap Instruction Vectors 5 - 37. */
+ .long trap /* Trap Instruction Vectors 6 - 38. */
+ .long trap /* Trap Instruction Vectors 7 - 39. */
+ .long trap /* Trap Instruction Vectors 8 - 40. */
+ .long trap /* Trap Instruction Vectors 9 - 41. */
+ .long trap /* Trap Instruction Vectors 10 - 42. */
+ .long trap /* Trap Instruction Vectors 11 - 43. */
+ .long trap /* Trap Instruction Vectors 12 - 44. */
+ .long trap /* Trap Instruction Vectors 13 - 45. */
+ .long trap /* Trap Instruction Vectors 14 - 46. */
+ .long trap /* Trap Instruction Vectors 15 - 47. */
+ .long 0 /* (Reserved for Coprocessor) - 48. */
+ .long 0 /* (Reserved for Coprocessor) - 49. */
+ .long 0 /* (Reserved for Coprocessor) - 50. */
+ .long 0 /* (Reserved for Coprocessor) - 51. */
+ .long 0 /* (Reserved for Coprocessor) - 52. */
+ .long 0 /* (Reserved for Coprocessor) - 53. */
+ .long 0 /* (Reserved for Coprocessor) - 54. */
+ .long 0 /* (Reserved for Coprocessor) - 55. */
+ .long 0 /* (Reserved for Coprocessor) - 56. */
+ .long 0 /* (Reserved for Coprocessor) - 57. */
+ .long 0 /* (Reserved for Coprocessor) - 58. */
+ .long 0 /* (Unassigned, Reserved) - 59. */
+ .long 0 /* (Unassigned, Reserved) - 60. */
+ .long 0 /* (Unassigned, Reserved) - 61. */
+ .long 0 /* (Unassigned, Reserved) - 62. */
+ .long 0 /* (Unassigned, Reserved) - 63. */
+ /* The assignment of these vectors to the CPM is */
+ /* dependent on the configuration of the CPM vba */
+ /* fields. */
+ .long 0 /* (User-Defined Vectors 1) CPM Error - 64. */
+ .long 0 /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+ .long 0 /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+ .long 0 /* (User-Defined Vectors 4) CPM SMC2 / PIP - 67. */
+ .long 0 /* (User-Defined Vectors 5) CPM SMC1 - 68. */
+ .long 0 /* (User-Defined Vectors 6) CPM SPI - 69. */
+ .long 0 /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+ .long 0 /* (User-Defined Vectors 8) CPM Timer 4 - 71. */
+ .long 0 /* (User-Defined Vectors 9) CPM Reserved - 72. */
+ .long 0 /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+ .long 0 /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+ .long 0 /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+ .long 0 /* (User-Defined Vectors 13) CPM Timer 3 - 76. */
+ .long 0 /* (User-Defined Vectors 14) CPM Reserved - 77. */
+ .long 0 /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+ .long 0 /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+ .long 0 /* (User-Defined Vectors 17) CPM Reserved - 80. */
+ .long 0 /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+ .long 0 /* (User-Defined Vectors 19) CPM Timer 2 - 82. */
+ .long 0 /* (User-Defined Vectors 21) CPM Reserved - 83. */
+ .long 0 /* (User-Defined Vectors 22) CPM IDMA2 - 84. */
+ .long 0 /* (User-Defined Vectors 23) CPM IDMA1 - 85. */
+ .long 0 /* (User-Defined Vectors 24) CPM SDMA Bus Err - 86. */
+ .long 0 /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+ .long 0 /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+ .long 0 /* (User-Defined Vectors 27) CPM Timer 1 - 89. */
+ .long 0 /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+ .long 0 /* (User-Defined Vectors 29) CPM SCC 4 - 91. */
+ .long 0 /* (User-Defined Vectors 30) CPM SCC 3 - 92. */
+ .long 0 /* (User-Defined Vectors 31) CPM SCC 2 - 93. */
+ .long 0 /* (User-Defined Vectors 32) CPM SCC 1 - 94. */
+ .long 0 /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+ /* I don't think anything uses the vectors after here. */
+ .long 0 /* (User-Defined Vectors 34) - 96. */
+ .long 0,0,0,0,0 /* (User-Defined Vectors 35 - 39). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 40 - 49). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 50 - 59). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 60 - 69). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 70 - 79). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 80 - 89). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 90 - 99). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 100 - 109). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 110 - 119). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 120 - 129). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 130 - 139). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 140 - 149). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 150 - 159). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 160 - 169). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 170 - 179). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 180 - 189). */
+ .long 0,0,0 /* (User-Defined Vectors 190 - 192). */
+.text
+ignore: rte
diff --git a/arch/m68knommu/platform/68360/head-rom.S b/arch/m68knommu/platform/68360/head-rom.S
new file mode 100644
index 000000000000..0da357a4cfee
--- /dev/null
+++ b/arch/m68knommu/platform/68360/head-rom.S
@@ -0,0 +1,420 @@
+/* arch/m68knommu/platform/68360/head-rom.S
+ *
+ * Startup code for Motorola 68360
+ *
+ * Copyright (C) SED Systems, a Division of Calian Ltd.
+ * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
+ * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
+ * uClinux Kernel
+ * Copyright (C) Michael Leslie <mleslie@lineo.com>
+ * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
+ * Copyright (C) 1998 D. Jeff Dionne <jeff@uclinux.org>,
+ *
+ */
+#include <linux/config.h>
+
+.global _stext
+.global _sbss
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global _quicc_base
+.global _periph_base
+
+#define REGB 0x1000
+#define PEPAR (_dprbase + REGB + 0x0016)
+#define GMR (_dprbase + REGB + 0x0040)
+#define OR0 (_dprbase + REGB + 0x0054)
+#define BR0 (_dprbase + REGB + 0x0050)
+
+#define OR1 (_dprbase + REGB + 0x0064)
+#define BR1 (_dprbase + REGB + 0x0060)
+
+#define OR2 (_dprbase + REGB + 0x0074)
+#define BR2 (_dprbase + REGB + 0x0070)
+
+#define OR3 (_dprbase + REGB + 0x0084)
+#define BR3 (_dprbase + REGB + 0x0080)
+
+#define OR4 (_dprbase + REGB + 0x0094)
+#define BR4 (_dprbase + REGB + 0x0090)
+
+#define OR5 (_dprbase + REGB + 0x00A4)
+#define BR5 (_dprbase + REGB + 0x00A0)
+
+#define OR6 (_dprbase + REGB + 0x00b4)
+#define BR6 (_dprbase + REGB + 0x00b0)
+
+#define OR7 (_dprbase + REGB + 0x00c4)
+#define BR7 (_dprbase + REGB + 0x00c0)
+
+#define MCR (_dprbase + REGB + 0x0000)
+#define AVR (_dprbase + REGB + 0x0008)
+
+#define SYPCR (_dprbase + REGB + 0x0022)
+
+#define PLLCR (_dprbase + REGB + 0x0010)
+#define CLKOCR (_dprbase + REGB + 0x000C)
+#define CDVCR (_dprbase + REGB + 0x0014)
+
+#define BKAR (_dprbase + REGB + 0x0030)
+#define BKCR (_dprbase + REGB + 0x0034)
+#define SWIV (_dprbase + REGB + 0x0023)
+#define PICR (_dprbase + REGB + 0x0026)
+#define PITR (_dprbase + REGB + 0x002A)
+
+/* Define for all memory configuration */
+#define MCU_SIM_GMR 0x00000000
+#define SIM_OR_MASK 0x0fffffff
+
+/* Defines for chip select zero - the flash */
+#define SIM_OR0_MASK 0x20000000
+#define SIM_BR0_MASK 0x00000001
+
+/* Defines for chip select one - the RAM */
+#define SIM_OR1_MASK 0x10000000
+#define SIM_BR1_MASK 0x00000001
+
+#define MCU_SIM_MBAR_ADRS 0x0003ff00
+#define MCU_SIM_MBAR_BA_MASK 0xfffff000
+#define MCU_SIM_MBAR_AS_MASK 0x00000001
+
+#define MCU_SIM_PEPAR 0x00B4
+
+#define MCU_DISABLE_INTRPTS 0x2700
+#define MCU_SIM_AVR 0x00
+
+#define MCU_SIM_MCR 0x00005cff
+
+#define MCU_SIM_CLKOCR 0x00
+#define MCU_SIM_PLLCR 0x8000
+#define MCU_SIM_CDVCR 0x0000
+
+#define MCU_SIM_SYPCR 0x0000
+#define MCU_SIM_SWIV 0x00
+#define MCU_SIM_PICR 0x0000
+#define MCU_SIM_PITR 0x0000
+
+
+#include <asm/m68360_regs.h>
+
+
+/*
+ * By the time this RAM specific code begins to execute, DPRAM
+ * and DRAM should already be mapped and accessible.
+ */
+
+ .text
+_start:
+_stext:
+ nop
+ ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */
+ /* We should not need to setup the boot stack the reset should do it. */
+ movea.l #__ramend, %sp /* set up stack at the end of DRAM:*/
+
+
+set_mbar_register:
+ moveq.l #0x07, %d1 /* Setup MBAR */
+ movec %d1, %dfc
+
+ lea.l MCU_SIM_MBAR_ADRS, %a0
+ move.l #_dprbase, %d0
+ andi.l #MCU_SIM_MBAR_BA_MASK, %d0
+ ori.l #MCU_SIM_MBAR_AS_MASK, %d0
+ moves.l %d0, %a0@
+
+ moveq.l #0x05, %d1
+ movec.l %d1, %dfc
+
+ /* Now we can begin to access registers in DPRAM */
+
+set_sim_mcr:
+ /* Set Module Configuration Register */
+ move.l #MCU_SIM_MCR, MCR
+
+ /* to do: Determine cause of reset */
+
+ /*
+ * configure system clock MC68360 p. 6-40
+ * (value +1)*osc/128 = system clock
+ * or
+ * (value + 1)*osc = system clock
+ * You do not need to divide the oscillator by 128 unless you want to.
+ */
+set_sim_clock:
+ move.w #MCU_SIM_PLLCR, PLLCR
+ move.b #MCU_SIM_CLKOCR, CLKOCR
+ move.w #MCU_SIM_CDVCR, CDVCR
+
+ /* Wait for the PLL to settle */
+ move.w #16384, %d0
+pll_settle_wait:
+ subi.w #1, %d0
+ bne pll_settle_wait
+
+ /* Setup the system protection register, and watchdog timer register */
+ move.b #MCU_SIM_SWIV, SWIV
+ move.w #MCU_SIM_PICR, PICR
+ move.w #MCU_SIM_PITR, PITR
+ move.w #MCU_SIM_SYPCR, SYPCR
+
+ /* Clear DPRAM - system + parameter */
+ movea.l #_dprbase, %a0
+ movea.l #_dprbase+0x2000, %a1
+
+ /* Copy 0 to %a0 until %a0 == %a1 */
+clear_dpram:
+ movel #0, %a0@+
+ cmpal %a0, %a1
+ bhi clear_dpram
+
+configure_memory_controller:
+ /* Set up Global Memory Register (GMR) */
+ move.l #MCU_SIM_GMR, %d0
+ move.l %d0, GMR
+
+configure_chip_select_0:
+ move.l #0x00400000, %d0
+ subq.l #0x01, %d0
+ eori.l #SIM_OR_MASK, %d0
+ ori.l #SIM_OR0_MASK, %d0
+ move.l %d0, OR0
+
+ move.l #__rom_start, %d0
+ ori.l #SIM_BR0_MASK, %d0
+ move.l %d0, BR0
+
+ move.l #0x0, BR1
+ move.l #0x0, BR2
+ move.l #0x0, BR3
+ move.l #0x0, BR4
+ move.l #0x0, BR5
+ move.l #0x0, BR6
+ move.l #0x0, BR7
+
+ move.w #MCU_SIM_PEPAR, PEPAR
+
+ /* point to vector table: */
+ move.l #_romvec, %a0
+ move.l #_ramvec, %a1
+copy_vectors:
+ move.l %a0@, %d0
+ move.l %d0, %a1@
+ move.l %a0@, %a1@
+ addq.l #0x04, %a0
+ addq.l #0x04, %a1
+ cmp.l #_start, %a0
+ blt copy_vectors
+
+ move.l #_ramvec, %a1
+ movec %a1, %vbr
+
+
+ /* Copy data segment from ROM to RAM */
+ moveal #_etext, %a0
+ moveal #_sdata, %a1
+ moveal #_edata, %a2
+
+ /* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+ move.l %a0@, %d0
+ addq.l #0x04, %a0
+ move.l %d0, %a1@
+ addq.l #0x04, %a1
+ cmp.l #_edata, %a1
+ blt LD1
+
+ moveal #_sbss, %a0
+ moveal #_ebss, %a1
+
+ /* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+ movel #0, %a0@+
+ cmpal %a0, %a1
+ bhi L1
+
+load_quicc:
+ move.l #_dprbase, _quicc_base
+
+store_ram_size:
+ /* Set ram size information */
+ move.l #_sdata, _rambase
+ move.l #_ebss, _ramstart
+ move.l #__ramend, %d0
+ sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/
+ move.l %d0, _ramend /* Different from __ramend.*/
+
+store_flash_size:
+ /* Set rom size information */
+ move.l #__rom_end, %d0
+ sub.l #__rom_start, %d0
+ move.l %d0, rom_length
+
+ pea 0
+ pea env
+ pea %sp@(4)
+ pea 0
+
+ lea init_thread_union, %a2
+ lea 0x2000(%a2), %sp
+
+lp:
+ jsr start_kernel
+
+_exit:
+ jmp _exit
+
+
+ .data
+ .align 4
+env:
+ .long 0
+_quicc_base:
+ .long 0
+_periph_base:
+ .long 0
+_ramvec:
+ .long 0
+_rambase:
+ .long 0
+_ramstart:
+ .long 0
+_ramend:
+ .long 0
+_dprbase:
+ .long 0xffffe000
+
+
+ .text
+
+ /*
+ * These are the exception vectors at boot up, they are copied into RAM
+ * and then overwritten as needed.
+ */
+
+.section ".data.initvect","awx"
+ .long __ramend /* Reset: Initial Stack Pointer - 0. */
+ .long _start /* Reset: Initial Program Counter - 1. */
+ .long buserr /* Bus Error - 2. */
+ .long trap /* Address Error - 3. */
+ .long trap /* Illegal Instruction - 4. */
+ .long trap /* Divide by zero - 5. */
+ .long trap /* CHK, CHK2 Instructions - 6. */
+ .long trap /* TRAPcc, TRAPV Instructions - 7. */
+ .long trap /* Privilege Violation - 8. */
+ .long trap /* Trace - 9. */
+ .long trap /* Line 1010 Emulator - 10. */
+ .long trap /* Line 1111 Emualtor - 11. */
+ .long trap /* Harware Breakpoint - 12. */
+ .long trap /* (Reserved for Coprocessor Protocol Violation)- 13. */
+ .long trap /* Format Error - 14. */
+ .long trap /* Uninitialized Interrupt - 15. */
+ .long trap /* (Unassigned, Reserver) - 16. */
+ .long trap /* (Unassigned, Reserver) - 17. */
+ .long trap /* (Unassigned, Reserver) - 18. */
+ .long trap /* (Unassigned, Reserver) - 19. */
+ .long trap /* (Unassigned, Reserver) - 20. */
+ .long trap /* (Unassigned, Reserver) - 21. */
+ .long trap /* (Unassigned, Reserver) - 22. */
+ .long trap /* (Unassigned, Reserver) - 23. */
+ .long trap /* Spurious Interrupt - 24. */
+ .long trap /* Level 1 Interrupt Autovector - 25. */
+ .long trap /* Level 2 Interrupt Autovector - 26. */
+ .long trap /* Level 3 Interrupt Autovector - 27. */
+ .long trap /* Level 4 Interrupt Autovector - 28. */
+ .long trap /* Level 5 Interrupt Autovector - 29. */
+ .long trap /* Level 6 Interrupt Autovector - 30. */
+ .long trap /* Level 7 Interrupt Autovector - 31. */
+ .long system_call /* Trap Instruction Vectors 0 - 32. */
+ .long trap /* Trap Instruction Vectors 1 - 33. */
+ .long trap /* Trap Instruction Vectors 2 - 34. */
+ .long trap /* Trap Instruction Vectors 3 - 35. */
+ .long trap /* Trap Instruction Vectors 4 - 36. */
+ .long trap /* Trap Instruction Vectors 5 - 37. */
+ .long trap /* Trap Instruction Vectors 6 - 38. */
+ .long trap /* Trap Instruction Vectors 7 - 39. */
+ .long trap /* Trap Instruction Vectors 8 - 40. */
+ .long trap /* Trap Instruction Vectors 9 - 41. */
+ .long trap /* Trap Instruction Vectors 10 - 42. */
+ .long trap /* Trap Instruction Vectors 11 - 43. */
+ .long trap /* Trap Instruction Vectors 12 - 44. */
+ .long trap /* Trap Instruction Vectors 13 - 45. */
+ .long trap /* Trap Instruction Vectors 14 - 46. */
+ .long trap /* Trap Instruction Vectors 15 - 47. */
+ .long 0 /* (Reserved for Coprocessor) - 48. */
+ .long 0 /* (Reserved for Coprocessor) - 49. */
+ .long 0 /* (Reserved for Coprocessor) - 50. */
+ .long 0 /* (Reserved for Coprocessor) - 51. */
+ .long 0 /* (Reserved for Coprocessor) - 52. */
+ .long 0 /* (Reserved for Coprocessor) - 53. */
+ .long 0 /* (Reserved for Coprocessor) - 54. */
+ .long 0 /* (Reserved for Coprocessor) - 55. */
+ .long 0 /* (Reserved for Coprocessor) - 56. */
+ .long 0 /* (Reserved for Coprocessor) - 57. */
+ .long 0 /* (Reserved for Coprocessor) - 58. */
+ .long 0 /* (Unassigned, Reserved) - 59. */
+ .long 0 /* (Unassigned, Reserved) - 60. */
+ .long 0 /* (Unassigned, Reserved) - 61. */
+ .long 0 /* (Unassigned, Reserved) - 62. */
+ .long 0 /* (Unassigned, Reserved) - 63. */
+ /* The assignment of these vectors to the CPM is */
+ /* dependent on the configuration of the CPM vba */
+ /* fields. */
+ .long 0 /* (User-Defined Vectors 1) CPM Error - 64. */
+ .long 0 /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+ .long 0 /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+ .long 0 /* (User-Defined Vectors 4) CPM SMC2 / PIP - 67. */
+ .long 0 /* (User-Defined Vectors 5) CPM SMC1 - 68. */
+ .long 0 /* (User-Defined Vectors 6) CPM SPI - 69. */
+ .long 0 /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+ .long 0 /* (User-Defined Vectors 8) CPM Timer 4 - 71. */
+ .long 0 /* (User-Defined Vectors 9) CPM Reserved - 72. */
+ .long 0 /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+ .long 0 /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+ .long 0 /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+ .long 0 /* (User-Defined Vectors 13) CPM Timer 3 - 76. */
+ .long 0 /* (User-Defined Vectors 14) CPM Reserved - 77. */
+ .long 0 /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+ .long 0 /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+ .long 0 /* (User-Defined Vectors 17) CPM Reserved - 80. */
+ .long 0 /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+ .long 0 /* (User-Defined Vectors 19) CPM Timer 2 - 82. */
+ .long 0 /* (User-Defined Vectors 21) CPM Reserved - 83. */
+ .long 0 /* (User-Defined Vectors 22) CPM IDMA2 - 84. */
+ .long 0 /* (User-Defined Vectors 23) CPM IDMA1 - 85. */
+ .long 0 /* (User-Defined Vectors 24) CPM SDMA Bus Err - 86. */
+ .long 0 /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+ .long 0 /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+ .long 0 /* (User-Defined Vectors 27) CPM Timer 1 - 89. */
+ .long 0 /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+ .long 0 /* (User-Defined Vectors 29) CPM SCC 4 - 91. */
+ .long 0 /* (User-Defined Vectors 30) CPM SCC 3 - 92. */
+ .long 0 /* (User-Defined Vectors 31) CPM SCC 2 - 93. */
+ .long 0 /* (User-Defined Vectors 32) CPM SCC 1 - 94. */
+ .long 0 /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+ /* I don't think anything uses the vectors after here. */
+ .long 0 /* (User-Defined Vectors 34) - 96. */
+ .long 0,0,0,0,0 /* (User-Defined Vectors 35 - 39). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 40 - 49). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 50 - 59). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 60 - 69). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 70 - 79). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 80 - 89). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 90 - 99). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 100 - 109). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 110 - 119). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 120 - 129). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 130 - 139). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 140 - 149). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 150 - 159). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 160 - 169). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 170 - 179). */
+ .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 180 - 189). */
+ .long 0,0,0 /* (User-Defined Vectors 190 - 192). */
+.text
+ignore: rte
diff --git a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68knommu/platform/68EZ328/config.c
index c21971971ff5..d8d56e5de310 100644
--- a/arch/m68knommu/platform/68EZ328/config.c
+++ b/arch/m68knommu/platform/68EZ328/config.c
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
/*
- * 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 d0586197f113..d926524cdf82 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 2deadaffd81e..000000000000
--- 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 8d76eb1ff291..4cd724c05700 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
@@ -1002,10 +1009,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
-config HAVE_DEC_LOCK
- bool
- default y
-
#
# Select some configuration options automatically based on user selections.
#
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index b0fdaee8d8d9..346e803f153b 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -720,38 +720,7 @@ archclean:
@$(MAKE) $(clean)=arch/mips/boot
@$(MAKE) $(clean)=arch/mips/lasat
-# Generate <asm/offset.h
-#
-# The default rule is suffering from funny problems on MIPS so we using our
-# own ...
-#
-# ---------------------------------------------------------------------------
-
-define filechk_gen-asm-offset.h
- (set -e; \
- echo "#ifndef _ASM_OFFSET_H"; \
- echo "#define _ASM_OFFSET_H"; \
- echo "/*"; \
- echo " * DO NOT MODIFY."; \
- echo " *"; \
- echo " * This file was generated by arch/$(ARCH)/Makefile"; \
- echo " *"; \
- echo " */"; \
- echo ""; \
- sed -ne "/^@@@/s///p"; \
- echo "#endif /* _ASM_OFFSET_H */" )
-endef
-
-prepare: include/asm-$(ARCH)/offset.h
-
-arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s
- $(call filechk,gen-asm-offset.h)
-
-CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
- include/asm-$(ARCH)/offset.h \
- vmlinux.32 \
+
+CLEAN_FILES += vmlinux.32 \
vmlinux.64 \
vmlinux.ecoff
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
new file mode 100644
index 000000000000..17b9f2f65ba0
--- /dev/null
+++ b/arch/mips/configs/tb0287_defconfig
@@ -0,0 +1,1041 @@
+#
+# 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/offset.c b/arch/mips/kernel/asm-offsets.c
index 2c11abb5a406..2c11abb5a406 100644
--- a/arch/mips/kernel/offset.c
+++ b/arch/mips/kernel/asm-offsets.c
diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
index 288bf51ad4ec..71416e7bbbaa 100644
--- a/arch/mips/kernel/genrtc.c
+++ b/arch/mips/kernel/genrtc.c
@@ -14,7 +14,7 @@
#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 7eec7568bfea..447759201d1d 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -31,7 +31,7 @@ void disable_8259A_irq(unsigned int irq);
* 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 4cd3d38a22c2..3cdc22346f4c 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/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 4c114ae21793..eff89322ba50 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -440,18 +440,6 @@ struct irix5_siginfo {
} stuff;
};
-static inline unsigned long timespectojiffies(struct timespec *value)
-{
- unsigned long sec = (unsigned) value->tv_sec;
- long nsec = value->tv_nsec;
-
- if (sec > (LONG_MAX / HZ))
- return LONG_MAX;
- nsec += 1000000000L / HZ - 1;
- nsec /= 1000000000L / HZ;
- return HZ * sec + nsec;
-}
-
asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
struct timespec *tp)
{
@@ -489,14 +477,13 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
error = -EINVAL;
goto out;
}
- expire = timespectojiffies(tp)+(tp->tv_sec||tp->tv_nsec);
+ expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec);
}
while(1) {
long tmp = 0;
- current->state = TASK_INTERRUPTIBLE;
- expire = schedule_timeout(expire);
+ expire = schedule_timeout_interruptible(expire);
for (i=0; i<=4; i++)
tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index f83c31f720c4..ac68e68339db 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -15,7 +15,7 @@
#include <asm/errno.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define EX(a,b) \
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index f10019640ee9..0d9c4a32a9c2 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -15,7 +15,7 @@
#include <asm/cachectl.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index aba665bcb386..1a14c6b18829 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -17,7 +17,7 @@
#include <asm/errno.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
.macro EX insn, reg, src
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index e02b7722ccb8..d2afbd19a9c8 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -15,7 +15,7 @@
#include <asm/cachectl.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/pgtable-bits.h>
#include <asm/regdef.h>
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
index d8d3b13fe57f..43cda53f5af6 100644
--- a/arch/mips/kernel/r6000_fpu.S
+++ b/arch/mips/kernel/r6000_fpu.S
@@ -13,7 +13,7 @@
#include <asm/asm.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
.set noreorder
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 344f2e29eb61..17b5030fb6ea 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -19,7 +19,7 @@
#include <asm/thread_info.h>
#include <asm/unistd.h>
#include <asm/war.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
/* Highest syscall used of any syscall flavour */
#define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 32efb888160a..ffb22a2068bf 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -14,7 +14,7 @@
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/sysmips.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index ae2a1312d4ef..21e3e13a4b44 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -31,7 +31,7 @@
#include <asm/cachectl.h>
#include <asm/cacheflush.h>
#include <asm/ipc.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/signal.h>
#include <asm/sim.h>
#include <asm/shmparam.h>
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index b46595462717..7ae4af476974 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -581,18 +581,13 @@ asmlinkage int irix_brk(unsigned long brk)
}
/*
- * Check if we have enough memory..
+ * Ok, looks good - let it rip.
*/
- if (security_vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
+ if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) {
ret = -ENOMEM;
goto out;
}
-
- /*
- * Ok, looks good - let it rip.
- */
mm->brk = brk;
- do_brk(oldbrk, newbrk-oldbrk);
ret = 0;
out:
@@ -1032,8 +1027,7 @@ bad:
asmlinkage int irix_sginap(int ticks)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(ticks);
+ schedule_timeout_interruptible(ticks);
return 0;
}
diff --git a/arch/mips/lib-32/memset.S b/arch/mips/lib-32/memset.S
index ad9ff4071ce9..1981485bd48b 100644
--- a/arch/mips/lib-32/memset.S
+++ b/arch/mips/lib-32/memset.S
@@ -7,7 +7,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <asm/asm.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define EX(insn,reg,addr,handler) \
diff --git a/arch/mips/lib-64/memset.S b/arch/mips/lib-64/memset.S
index 242f1976cfaf..e2c42c85113b 100644
--- a/arch/mips/lib-64/memset.S
+++ b/arch/mips/lib-64/memset.S
@@ -7,7 +7,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <asm/asm.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define EX(insn,reg,addr,handler) \
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 21b92b9dd013..037303412909 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,7 +2,7 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial_copy.o dec_and_lock.o memcpy.o promlib.o \
+lib-y += csum_partial_copy.o memcpy.o promlib.o \
strlen_user.o strncpy_user.o strnlen_user.o
obj-y += iomap.o
diff --git a/arch/mips/lib/dec_and_lock.c b/arch/mips/lib/dec_and_lock.c
deleted file mode 100644
index e44e9579bd36..000000000000
--- a/arch/mips/lib/dec_and_lock.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * MIPS version of atomic_dec_and_lock() using cmpxchg
- *
- * 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/spinlock.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-
-/*
- * This is an implementation of the notion of "decrement a
- * reference count, and return locked if it decremented to zero".
- *
- * This implementation can be used on any architecture that
- * has a cmpxchg, and where atomic->value is an int holding
- * the value of the atomic (i.e. the high bits aren't used
- * for a lock or anything like that).
- *
- * N.B. ATOMIC_DEC_AND_LOCK gets defined in include/linux/spinlock.h
- * if spinlocks are empty and thus atomic_dec_and_lock is defined
- * to be atomic_dec_and_test - in that case we don't need it
- * defined here as well.
- */
-
-#ifndef ATOMIC_DEC_AND_LOCK
-int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-{
- int counter;
- int newcount;
-
- for (;;) {
- counter = atomic_read(atomic);
- newcount = counter - 1;
- if (!newcount)
- break; /* do it the slow way */
-
- newcount = cmpxchg(&atomic->counter, counter, newcount);
- if (newcount == counter)
- return 0;
- }
-
- spin_lock(lock);
- if (atomic_dec_and_test(atomic))
- return 1;
- spin_unlock(lock);
- return 0;
-}
-
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif /* ATOMIC_DEC_AND_LOCK */
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index 90ee8d43261f..a78865f76547 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -14,7 +14,7 @@
*/
#include <linux/config.h>
#include <asm/asm.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define dst a0
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
index 07660e86c99d..eca558d83a37 100644
--- a/arch/mips/lib/strlen_user.S
+++ b/arch/mips/lib/strlen_user.S
@@ -7,7 +7,7 @@
* Copyright (c) 1999 Silicon Graphics, Inc.
*/
#include <asm/asm.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define EX(insn,reg,addr,handler) \
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
index 14bed17c1648..d16c76fbfac7 100644
--- a/arch/mips/lib/strncpy_user.S
+++ b/arch/mips/lib/strncpy_user.S
@@ -7,7 +7,7 @@
*/
#include <linux/errno.h>
#include <asm/asm.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define EX(insn,reg,addr,handler) \
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index 6e7a8eed4de8..c0ea15194a0e 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -7,7 +7,7 @@
* Copyright (c) 1999 Silicon Graphics, Inc.
*/
#include <asm/asm.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define EX(insn,reg,addr,handler) \
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index 97a50d38c98f..a617f8c327e8 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -18,7 +18,7 @@
#include <asm/io.h>
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -39,7 +39,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
__attribute__((alias("dma_alloc_noncoherent")));
EXPORT_SYMBOL(dma_alloc_coherent);
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
index aa7c94b5d781..8da19fd22ac6 100644
--- a/arch/mips/mm/dma-ip27.c
+++ b/arch/mips/mm/dma-ip27.c
@@ -22,7 +22,7 @@
pdev_to_baddr(to_pci_dev(dev), (addr))
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
@@ -44,7 +44,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
__attribute__((alias("dma_alloc_noncoherent")));
EXPORT_SYMBOL(dma_alloc_coherent);
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
index 2cbe196c35fb..a7e3072ff78d 100644
--- a/arch/mips/mm/dma-ip32.c
+++ b/arch/mips/mm/dma-ip32.c
@@ -37,7 +37,7 @@
#define RAM_OFFSET_MASK 0x3fffffff
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -61,7 +61,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 59e54f12212e..4ce02028a292 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -24,7 +24,7 @@
*/
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -45,7 +45,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c53e4cb359ba..83d81c9cdc2b 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
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-tb0226.c b/arch/mips/pci/fixup-tb0226.c
index 61513d5d97da..b5d42b12de10 100644
--- a/arch/mips/pci/fixup-tb0226.c
+++ b/arch/mips/pci/fixup-tb0226.c
@@ -1,7 +1,7 @@
/*
* fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups.
*
- * Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ * Copyright (C) 2002-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
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/pci.h>
+#include <asm/vr41xx/giu.h>
#include <asm/vr41xx/tb0226.h>
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
@@ -29,42 +30,42 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
switch (slot) {
case 12:
vr41xx_set_irq_trigger(GD82559_1_PIN,
- TRIGGER_LEVEL,
- SIGNAL_THROUGH);
- vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW);
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(GD82559_1_PIN, IRQ_LEVEL_LOW);
irq = GD82559_1_IRQ;
break;
case 13:
vr41xx_set_irq_trigger(GD82559_2_PIN,
- TRIGGER_LEVEL,
- SIGNAL_THROUGH);
- vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW);
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(GD82559_2_PIN, IRQ_LEVEL_LOW);
irq = GD82559_2_IRQ;
break;
case 14:
switch (pin) {
case 1:
vr41xx_set_irq_trigger(UPD720100_INTA_PIN,
- TRIGGER_LEVEL,
- SIGNAL_THROUGH);
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(UPD720100_INTA_PIN,
- LEVEL_LOW);
+ IRQ_LEVEL_LOW);
irq = UPD720100_INTA_IRQ;
break;
case 2:
vr41xx_set_irq_trigger(UPD720100_INTB_PIN,
- TRIGGER_LEVEL,
- SIGNAL_THROUGH);
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(UPD720100_INTB_PIN,
- LEVEL_LOW);
+ IRQ_LEVEL_LOW);
irq = UPD720100_INTB_IRQ;
break;
case 3:
vr41xx_set_irq_trigger(UPD720100_INTC_PIN,
- TRIGGER_LEVEL,
- SIGNAL_THROUGH);
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(UPD720100_INTC_PIN,
- LEVEL_LOW);
+ IRQ_LEVEL_LOW);
irq = UPD720100_INTC_IRQ;
break;
default:
diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c
new file mode 100644
index 000000000000..8436d7f1fdb2
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0287.c
@@ -0,0 +1,65 @@
+/*
+ * 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/parisc/Makefile b/arch/parisc/Makefile
index 0403d2fcb85e..3b339b1cce13 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -100,15 +100,7 @@ kernel_install: vmlinux
install: kernel_install modules_install
-prepare: include/asm-parisc/offsets.h
-
-arch/parisc/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-parisc/offsets.h: arch/parisc/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
-CLEAN_FILES += lifimage include/asm-parisc/offsets.h
+CLEAN_FILES += lifimage
MRPROPER_FILES += palo.conf
define archhelp
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
index 2680a1c0fa77..aaaf3306c05a 100644
--- a/arch/parisc/hpux/gate.S
+++ b/arch/parisc/hpux/gate.S
@@ -9,7 +9,7 @@
*/
#include <asm/assembly.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/errno.h>
diff --git a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S
index 1aa936dfe147..0b0c3a66b1be 100644
--- a/arch/parisc/hpux/wrappers.S
+++ b/arch/parisc/hpux/wrappers.S
@@ -24,7 +24,7 @@
#warning PA64 support needs more work...did first cut
#endif
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/assembly.h>
#include <asm/signal.h>
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index ee58d37dbb27..be0f07f2fa58 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -23,7 +23,7 @@
*/
#include <linux/config.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
/* we have the following possibilities to act on an interruption:
* - handle in assembly and use shadowed registers only
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index ddf7e914f15e..28405edf8448 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -14,7 +14,7 @@
#include <linux/autoconf.h> /* for CONFIG_SMP */
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/psw.h>
#include <asm/pdc.h>
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 368cc095c99f..844c2877a2e3 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -349,7 +349,7 @@ pcxl_dma_init(void)
__initcall(pcxl_dma_init);
-static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
+static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
{
unsigned long vaddr;
unsigned long paddr;
@@ -502,13 +502,13 @@ struct hppa_dma_ops pcxl_dma_ops = {
};
static void *fail_alloc_consistent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
return NULL;
}
static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
void *addr = NULL;
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 4fc04501d5e5..46b759385115 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -47,7 +47,7 @@
#include <linux/kallsyms.h>
#include <asm/io.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
#include <asm/pgalloc.h>
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index c07db9dff7cd..f3428e5e86fb 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -23,7 +23,7 @@
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
/* PSW bits we allow the debugger to modify */
#define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB)
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 55d71c15e1f7..0224651fd8f1 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -32,7 +32,7 @@
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 32ea701f4d20..8c7a7185cd3b 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -7,7 +7,7 @@
* sorry about the wall, puffin..
*/
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/psw.h>
diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
index 7bf705676297..5f2e6904d14a 100644
--- a/arch/parisc/lib/Makefile
+++ b/arch/parisc/lib/Makefile
@@ -5,5 +5,3 @@
lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
obj-y := iomap.o
-
-lib-$(CONFIG_SMP) += debuglocks.o
diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c
index 2de182f6fe8a..90f400b10282 100644
--- a/arch/parisc/lib/bitops.c
+++ b/arch/parisc/lib/bitops.c
@@ -13,8 +13,8 @@
#include <asm/atomic.h>
#ifdef CONFIG_SMP
-spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
- [0 ... (ATOMIC_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
+raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
+ [0 ... (ATOMIC_HASH_SIZE-1)] = __RAW_SPIN_LOCK_UNLOCKED
};
#endif
diff --git a/arch/parisc/lib/debuglocks.c b/arch/parisc/lib/debuglocks.c
deleted file mode 100644
index 1b33fe6e5b7a..000000000000
--- a/arch/parisc/lib/debuglocks.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Debugging versions of SMP locking primitives.
- *
- * Copyright (C) 2004 Thibaut VARENE <varenet@parisc-linux.org>
- *
- * Some code stollen from alpha & sparc64 ;)
- *
- * 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
- *
- * We use pdc_printf() throughout the file for all output messages, to avoid
- * losing messages because of disabled interrupts. Since we're using these
- * messages for debugging purposes, it makes sense not to send them to the
- * linux console.
- */
-
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/hardirq.h> /* in_interrupt() */
-#include <asm/system.h>
-#include <asm/hardirq.h> /* in_interrupt() */
-#include <asm/pdc.h>
-
-#undef INIT_STUCK
-#define INIT_STUCK 1L << 30
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-
-
-void _dbg_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
-{
- volatile unsigned int *a;
- long stuck = INIT_STUCK;
- void *inline_pc = __builtin_return_address(0);
- unsigned long started = jiffies;
- int printed = 0;
- int cpu = smp_processor_id();
-
-try_again:
-
- /* Do the actual locking */
- /* <T-Bone> ggg: we can't get stuck on the outter loop?
- * <ggg> T-Bone: We can hit the outer loop
- * alot if multiple CPUs are constantly racing for a lock
- * and the backplane is NOT fair about which CPU sees
- * the update first. But it won't hang since every failed
- * attempt will drop us back into the inner loop and
- * decrement `stuck'.
- * <ggg> K-class and some of the others are NOT fair in the HW
- * implementation so we could see false positives.
- * But fixing the lock contention is easier than
- * fixing the HW to be fair.
- * <tausq> __ldcw() returns 1 if we get the lock; otherwise we
- * spin until the value of the lock changes, or we time out.
- */
- mb();
- a = __ldcw_align(lock);
- while (stuck && (__ldcw(a) == 0))
- while ((*a == 0) && --stuck);
- mb();
-
- if (unlikely(stuck <= 0)) {
- pdc_printf(
- "%s:%d: spin_lock(%s/%p) stuck in %s at %p(%d)"
- " owned by %s:%d in %s at %p(%d)\n",
- base_file, line_no, lock->module, lock,
- current->comm, inline_pc, cpu,
- lock->bfile, lock->bline, lock->task->comm,
- lock->previous, lock->oncpu);
- stuck = INIT_STUCK;
- printed = 1;
- goto try_again;
- }
-
- /* Exiting. Got the lock. */
- lock->oncpu = cpu;
- lock->previous = inline_pc;
- lock->task = current;
- lock->bfile = (char *)base_file;
- lock->bline = line_no;
-
- if (unlikely(printed)) {
- pdc_printf(
- "%s:%d: spin_lock grabbed in %s at %p(%d) %ld ticks\n",
- base_file, line_no, current->comm, inline_pc,
- cpu, jiffies - started);
- }
-}
-
-void _dbg_spin_unlock(spinlock_t * lock, const char *base_file, int line_no)
-{
- CHECK_LOCK(lock);
- volatile unsigned int *a;
- mb();
- a = __ldcw_align(lock);
- if (unlikely((*a != 0) && lock->babble)) {
- lock->babble--;
- pdc_printf(
- "%s:%d: spin_unlock(%s:%p) not locked\n",
- base_file, line_no, lock->module, lock);
- }
- *a = 1;
- mb();
-}
-
-int _dbg_spin_trylock(spinlock_t * lock, const char *base_file, int line_no)
-{
- int ret;
- volatile unsigned int *a;
- mb();
- a = __ldcw_align(lock);
- ret = (__ldcw(a) != 0);
- mb();
- if (ret) {
- lock->oncpu = smp_processor_id();
- lock->previous = __builtin_return_address(0);
- lock->task = current;
- } else {
- lock->bfile = (char *)base_file;
- lock->bline = line_no;
- }
- return ret;
-}
-
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
-#ifdef CONFIG_DEBUG_RWLOCK
-
-/* Interrupts trouble detailed explanation, thx Grant:
- *
- * o writer (wants to modify data) attempts to acquire the rwlock
- * o He gets the write lock.
- * o Interupts are still enabled, we take an interrupt with the
- * write still holding the lock.
- * o interrupt handler tries to acquire the rwlock for read.
- * o deadlock since the writer can't release it at this point.
- *
- * In general, any use of spinlocks that competes between "base"
- * level and interrupt level code will risk deadlock. Interrupts
- * need to be disabled in the base level routines to avoid it.
- * Or more precisely, only the IRQ the base level routine
- * is competing with for the lock. But it's more efficient/faster
- * to just disable all interrupts on that CPU to guarantee
- * once it gets the lock it can release it quickly too.
- */
-
-void _dbg_write_lock(rwlock_t *rw, const char *bfile, int bline)
-{
- void *inline_pc = __builtin_return_address(0);
- unsigned long started = jiffies;
- long stuck = INIT_STUCK;
- int printed = 0;
- int cpu = smp_processor_id();
-
- if(unlikely(in_interrupt())) { /* acquiring write lock in interrupt context, bad idea */
- pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline);
- BUG();
- }
-
- /* Note: if interrupts are disabled (which is most likely), the printk
- will never show on the console. We might need a polling method to flush
- the dmesg buffer anyhow. */
-
-retry:
- _raw_spin_lock(&rw->lock);
-
- if(rw->counter != 0) {
- /* this basically never happens */
- _raw_spin_unlock(&rw->lock);
-
- stuck--;
- if ((unlikely(stuck <= 0)) && (rw->counter < 0)) {
- pdc_printf(
- "%s:%d: write_lock stuck on writer"
- " in %s at %p(%d) %ld ticks\n",
- bfile, bline, current->comm, inline_pc,
- cpu, jiffies - started);
- stuck = INIT_STUCK;
- printed = 1;
- }
- else if (unlikely(stuck <= 0)) {
- pdc_printf(
- "%s:%d: write_lock stuck on reader"
- " in %s at %p(%d) %ld ticks\n",
- bfile, bline, current->comm, inline_pc,
- cpu, jiffies - started);
- stuck = INIT_STUCK;
- printed = 1;
- }
-
- while(rw->counter != 0);
-
- goto retry;
- }
-
- /* got it. now leave without unlocking */
- rw->counter = -1; /* remember we are locked */
-
- if (unlikely(printed)) {
- pdc_printf(
- "%s:%d: write_lock grabbed in %s at %p(%d) %ld ticks\n",
- bfile, bline, current->comm, inline_pc,
- cpu, jiffies - started);
- }
-}
-
-int _dbg_write_trylock(rwlock_t *rw, const char *bfile, int bline)
-{
-#if 0
- void *inline_pc = __builtin_return_address(0);
- int cpu = smp_processor_id();
-#endif
-
- if(unlikely(in_interrupt())) { /* acquiring write lock in interrupt context, bad idea */
- pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline);
- BUG();
- }
-
- /* Note: if interrupts are disabled (which is most likely), the printk
- will never show on the console. We might need a polling method to flush
- the dmesg buffer anyhow. */
-
- _raw_spin_lock(&rw->lock);
-
- if(rw->counter != 0) {
- /* this basically never happens */
- _raw_spin_unlock(&rw->lock);
- return 0;
- }
-
- /* got it. now leave without unlocking */
- rw->counter = -1; /* remember we are locked */
-#if 0
- pdc_printf("%s:%d: try write_lock grabbed in %s at %p(%d)\n",
- bfile, bline, current->comm, inline_pc, cpu);
-#endif
- return 1;
-}
-
-void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline)
-{
-#if 0
- void *inline_pc = __builtin_return_address(0);
- unsigned long started = jiffies;
- int cpu = smp_processor_id();
-#endif
- unsigned long flags;
-
- local_irq_save(flags);
- _raw_spin_lock(&rw->lock);
-
- rw->counter++;
-#if 0
- pdc_printf(
- "%s:%d: read_lock grabbed in %s at %p(%d) %ld ticks\n",
- bfile, bline, current->comm, inline_pc,
- cpu, jiffies - started);
-#endif
- _raw_spin_unlock(&rw->lock);
- local_irq_restore(flags);
-}
-
-#endif /* CONFIG_DEBUG_RWLOCK */
diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S
index 134f0cd240f5..1b91612ed964 100644
--- a/arch/parisc/lib/fixup.S
+++ b/arch/parisc/lib/fixup.S
@@ -20,7 +20,7 @@
* Fixup routines for kernel exception handling.
*/
#include <linux/config.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/assembly.h>
#include <asm/errno.h>
diff --git a/arch/ppc/8xx_io/cs4218.h b/arch/ppc/8xx_io/cs4218.h
index a3c38c5a5db2..f1c7392255f8 100644
--- a/arch/ppc/8xx_io/cs4218.h
+++ b/arch/ppc/8xx_io/cs4218.h
@@ -78,7 +78,7 @@ typedef struct {
const char *name2;
void (*open)(void);
void (*release)(void);
- void *(*dma_alloc)(unsigned int, int);
+ void *(*dma_alloc)(unsigned int, gfp_t);
void (*dma_free)(void *, unsigned int);
int (*irqinit)(void);
#ifdef MODULE
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index 89fe0ceeaa40..532caa388dc2 100644
--- a/arch/ppc/8xx_io/cs4218_tdm.c
+++ b/arch/ppc/8xx_io/cs4218_tdm.c
@@ -318,7 +318,7 @@ struct cs_sound_settings {
static struct cs_sound_settings sound;
-static void *CS_Alloc(unsigned int size, int flags);
+static void *CS_Alloc(unsigned int size, gfp_t flags);
static void CS_Free(void *ptr, unsigned int size);
static int CS_IrqInit(void);
#ifdef MODULE
@@ -959,7 +959,7 @@ static TRANS transCSNormalRead = {
/*** Low level stuff *********************************************************/
-static void *CS_Alloc(unsigned int size, int flags)
+static void *CS_Alloc(unsigned int size, gfp_t flags)
{
int order;
@@ -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 6ab7e5ea5fcf..776941c75672 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -26,10 +26,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
-config HAVE_DEC_LOCK
- bool
- default y
-
config PPC
bool
default y
@@ -265,6 +261,15 @@ config PPC601_SYNC_FIX
If in doubt, say Y here.
+config HOTPLUG_CPU
+ bool "Support for enabling/disabling CPUs"
+ depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PMAC
+ ---help---
+ Say Y here to be able to disable and re-enable individual
+ CPUs at runtime on SMP machines.
+
+ Say N if you are unsure.
+
source arch/ppc/platforms/4xx/Kconfig
source arch/ppc/platforms/85xx/Kconfig
@@ -499,11 +504,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 +680,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/Makefile b/arch/ppc/Makefile
index d1b6e6dcb504..16e2675f3270 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -21,13 +21,14 @@ CC := $(CC) -m32
endif
LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic
-CPPFLAGS += -Iarch/$(ARCH) -Iinclude3
+# The -Iarch/$(ARCH)/include is temporary while we are merging
+CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
AFLAGS += -Iarch/$(ARCH)
CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -mmultiple
CPP = $(CC) -E $(CFLAGS)
# Temporary hack until we have migrated to asm-powerpc
-LINUXINCLUDE += -Iinclude3
+LINUXINCLUDE += -Iarch/$(ARCH)/include
CHECKFLAGS += -D__powerpc__
@@ -103,21 +104,16 @@ endef
archclean:
$(Q)$(MAKE) $(clean)=arch/ppc/boot
- $(Q)rm -rf include3
+ # Temporary hack until we have migrated to asm-powerpc
+ $(Q)rm -rf arch/$(ARCH)/include
-prepare: include/asm-$(ARCH)/offsets.h checkbin
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
+archprepare: checkbin
# Temporary hack until we have migrated to asm-powerpc
-include/asm: include3/asm
-include3/asm:
- $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi
- $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
+include/asm: arch/$(ARCH)/include/asm
+arch/$(ARCH)/include/asm:
+ $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
+ $(Q)ln -fsn $(srctree)/include/asm-powerpc arch/$(ARCH)/include/asm
# Use the file '.tmp_gas_check' for binutils tests, as gas won't output
# to stdout and these checks are run even on install targets.
@@ -143,7 +139,5 @@ checkbin:
false ; \
fi
-CLEAN_FILES += include/asm-$(ARCH)/offsets.h \
- arch/$(ARCH)/kernel/asm-offsets.s \
- $(TOUT)
+CLEAN_FILES += $(TOUT)
diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c
index 9017c547a6f6..26818bbb6cff 100644
--- a/arch/ppc/boot/common/ns16550.c
+++ b/arch/ppc/boot/common/ns16550.c
@@ -23,7 +23,7 @@ static int shift;
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 47e641455bc5..c96c9f80521e 100644
--- a/arch/ppc/boot/common/util.S
+++ b/arch/ppc/boot/common/util.S
@@ -252,7 +252,7 @@ _GLOBAL(flush_instruction_cache)
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/boot/ld.script b/arch/ppc/boot/ld.script
index 9362193742ac..d4dd8f15395e 100644
--- a/arch/ppc/boot/ld.script
+++ b/arch/ppc/boot/ld.script
@@ -1,4 +1,4 @@
-OUTPUT_ARCH(powerpc)
+OUTPUT_ARCH(powerpc:common)
SECTIONS
{
/* Read-only sections, merged into text segment: */
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index bd037caa4055..ba396438ede3 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/ppc/kernel/cpu_setup_6xx.S
@@ -12,10 +12,9 @@
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/page.h>
-#include <asm/ppc_asm.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cache.h>
_GLOBAL(__setup_cpu_601)
diff --git a/arch/ppc/kernel/cpu_setup_power4.S b/arch/ppc/kernel/cpu_setup_power4.S
index f2ea1a990f17..7e4fbb653724 100644
--- a/arch/ppc/kernel/cpu_setup_power4.S
+++ b/arch/ppc/kernel/cpu_setup_power4.S
@@ -14,8 +14,7 @@
#include <asm/page.h>
#include <asm/ppc_asm.h>
#include <asm/cputable.h>
-#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cache.h>
_GLOBAL(__970_cpu_preinit)
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 546e1ea4cafa..6b76cf58d9e0 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -91,7 +91,7 @@ struct cpu_spec cpu_specs[] = {
.cpu_features = CPU_FTR_COMMON | CPU_FTR_601 |
CPU_FTR_HPTE_TABLE,
.cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR |
- PPC_FEATURE_UNIFIED_CACHE,
+ PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_601
@@ -745,7 +745,8 @@ struct cpu_spec cpu_specs[] = {
.cpu_name = "403GCX",
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
CPU_FTR_USE_TB,
- .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ .cpu_user_features = PPC_FEATURE_32 |
+ PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
.icache_bsize = 16,
.dcache_bsize = 16,
},
diff --git a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c
index e0c631cf96b0..0f710d2baec6 100644
--- a/arch/ppc/kernel/dma-mapping.c
+++ b/arch/ppc/kernel/dma-mapping.c
@@ -115,7 +115,7 @@ static struct vm_region consistent_head = {
};
static struct vm_region *
-vm_region_alloc(struct vm_region *head, size_t size, int gfp)
+vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
{
unsigned long addr = head->vm_start, end = head->vm_end - size;
unsigned long flags;
@@ -173,7 +173,7 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad
* virtual and bus address for that space.
*/
void *
-__dma_alloc_coherent(size_t size, dma_addr_t *handle, int gfp)
+__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
{
struct page *page;
struct vm_region *c;
@@ -393,7 +393,7 @@ EXPORT_SYMBOL(__dma_sync);
* __dma_sync_page() implementation for systems using highmem.
* In this case, each page of a buffer must be kmapped/kunmapped
* in order to have a virtual address for __dma_sync(). This must
- * not sleep so kmap_atmomic()/kunmap_atomic() are used.
+ * not sleep so kmap_atomic()/kunmap_atomic() are used.
*
* Note: yes, it is possible and correct to have a buffer extend
* beyond the first page.
@@ -401,10 +401,10 @@ EXPORT_SYMBOL(__dma_sync);
static inline void __dma_sync_page_highmem(struct page *page,
unsigned long offset, size_t size, int direction)
{
- size_t seg_size = min((size_t)PAGE_SIZE, size) - offset;
+ size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
size_t cur_size = seg_size;
unsigned long flags, start, seg_offset = offset;
- int nr_segs = PAGE_ALIGN(size + (PAGE_SIZE - offset))/PAGE_SIZE;
+ int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
int seg_nr = 0;
local_irq_save(flags);
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index cb83045e2edf..03d4886869f3 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -29,7 +29,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#undef SHOW_SYSCALLS
diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S
index 6189b26f640f..665d7d34304c 100644
--- a/arch/ppc/kernel/fpu.S
+++ b/arch/ppc/kernel/fpu.S
@@ -18,7 +18,7 @@
#include <asm/cache.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
/*
* This task wants to use the FPU now.
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index a931d773715f..1960fb8c259c 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -31,7 +31,7 @@
#include <asm/cache.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#ifdef CONFIG_APUS
#include <asm/amigappc.h>
@@ -1023,23 +1023,21 @@ __secondary_start_gemini:
andc r4,r4,r3
mtspr SPRN_HID0,r4
sync
- bl gemini_prom_init
b __secondary_start
#endif /* CONFIG_GEMINI */
- .globl __secondary_start_psurge
-__secondary_start_psurge:
- li r24,1 /* cpu # */
- b __secondary_start_psurge99
- .globl __secondary_start_psurge2
-__secondary_start_psurge2:
- li r24,2 /* cpu # */
- b __secondary_start_psurge99
- .globl __secondary_start_psurge3
-__secondary_start_psurge3:
- li r24,3 /* cpu # */
- b __secondary_start_psurge99
-__secondary_start_psurge99:
- /* we come in here with IR=0 and DR=1, and DBAT 0
+
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
+ /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
set to map the 0xf0000000 - 0xffffffff region */
mfmsr r0
rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 9e68e32edb60..599245b0407e 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -40,7 +40,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include "head_booke.h"
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
index 0a5e723d3be6..8562b807b37c 100644
--- a/arch/ppc/kernel/head_4xx.S
+++ b/arch/ppc/kernel/head_4xx.S
@@ -40,7 +40,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
/* As with the other PowerPC ports, it is expected that when code
* execution begins here, the following registers contain valid, yet
@@ -453,6 +453,7 @@ label:
#else
CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException)
#endif
+#endif
/* 0x1100 - Data TLB Miss Exception
* As the name implies, translation is not in the MMU, so search the
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index eb18cadb3755..cb1a3a54a026 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -30,7 +30,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
/* Macro to make the code more readable. */
#ifdef CONFIG_8xx_CPU6
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index 4028f4c7d978..8e52e8408316 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -41,7 +41,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include "head_booke.h"
/* As with the other PowerPC ports, it is expected that when code
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 53547b6de45b..fba29c876b62 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -22,6 +22,7 @@
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
+#include <linux/cpu.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -35,6 +36,7 @@
void default_idle(void)
{
void (*powersave)(void);
+ int cpu = smp_processor_id();
powersave = ppc_md.power_save;
@@ -44,7 +46,7 @@ void default_idle(void)
#ifdef CONFIG_SMP
else {
set_thread_flag(TIF_POLLING_NRFLAG);
- while (!need_resched())
+ while (!need_resched() && !cpu_is_offline(cpu))
barrier();
clear_thread_flag(TIF_POLLING_NRFLAG);
}
@@ -52,6 +54,8 @@ void default_idle(void)
}
if (need_resched())
schedule();
+ if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+ cpu_die();
}
/*
diff --git a/arch/ppc/kernel/idle_6xx.S b/arch/ppc/kernel/idle_6xx.S
index 25d009c75f7b..1a2194cf6828 100644
--- a/arch/ppc/kernel/idle_6xx.S
+++ b/arch/ppc/kernel/idle_6xx.S
@@ -20,7 +20,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#undef DEBUG
diff --git a/arch/ppc/kernel/idle_power4.S b/arch/ppc/kernel/idle_power4.S
index 73a58ff03900..cc0d535365cd 100644
--- a/arch/ppc/kernel/idle_power4.S
+++ b/arch/ppc/kernel/idle_power4.S
@@ -20,7 +20,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#undef DEBUG
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index ce71b4a01585..90d917d2e856 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -23,7 +23,7 @@
#include <asm/mmu.h>
#include <asm/ppc_asm.h>
#include <asm/thread_info.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.text
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 7b3586a3bf30..854e45beb387 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -80,7 +80,6 @@ fixup_broken_pcnet32(struct pci_dev* dev)
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/perfmon.c b/arch/ppc/kernel/perfmon.c
index fa1dad96b830..22df9a596a0f 100644
--- a/arch/ppc/kernel/perfmon.c
+++ b/arch/ppc/kernel/perfmon.c
@@ -45,9 +45,8 @@ static void dummy_perf(struct pt_regs *regs)
mtpmr(PMRN_PMGC0, pmgc0);
}
-#else
+#elif defined(CONFIG_6xx)
/* Ensure exceptions are disabled */
-
static void dummy_perf(struct pt_regs *regs)
{
unsigned int mmcr0 = mfspr(SPRN_MMCR0);
@@ -55,6 +54,10 @@ static void dummy_perf(struct pt_regs *regs)
mmcr0 &= ~MMCR0_PMXE;
mtspr(SPRN_MMCR0, mmcr0);
}
+#else
+static void dummy_perf(struct pt_regs *regs)
+{
+}
#endif
void (*perf_irq)(struct pt_regs *) = dummy_perf;
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index e70b587b9e51..726fe7ce1747 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -45,6 +45,7 @@ cpumask_t cpu_online_map;
cpumask_t cpu_possible_map;
int smp_hw_index[NR_CPUS];
struct thread_info *secondary_ti;
+static struct task_struct *idle_tasks[NR_CPUS];
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
@@ -286,7 +287,8 @@ static void __devinit smp_store_cpu_info(int id)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- int num_cpus, i;
+ int num_cpus, i, cpu;
+ struct task_struct *p;
/* Fixup boot cpu */
smp_store_cpu_info(smp_processor_id());
@@ -308,6 +310,17 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (smp_ops->space_timers)
smp_ops->space_timers(num_cpus);
+
+ for_each_cpu(cpu) {
+ if (cpu == smp_processor_id())
+ continue;
+ /* create a process for the processor */
+ p = fork_idle(cpu);
+ if (IS_ERR(p))
+ panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
+ p->thread_info->cpu = cpu;
+ idle_tasks[cpu] = p;
+ }
}
void __devinit smp_prepare_boot_cpu(void)
@@ -334,12 +347,17 @@ int __devinit start_secondary(void *unused)
set_dec(tb_ticks_per_jiffy);
cpu_callin_map[cpu] = 1;
- printk("CPU %i done callin...\n", cpu);
+ printk("CPU %d done callin...\n", cpu);
smp_ops->setup_cpu(cpu);
- printk("CPU %i done setup...\n", cpu);
- local_irq_enable();
+ printk("CPU %d done setup...\n", cpu);
smp_ops->take_timebase();
- printk("CPU %i done timebase take...\n", cpu);
+ printk("CPU %d done timebase take...\n", cpu);
+
+ spin_lock(&call_lock);
+ cpu_set(cpu, cpu_online_map);
+ spin_unlock(&call_lock);
+
+ local_irq_enable();
cpu_idle();
return 0;
@@ -347,17 +365,11 @@ int __devinit start_secondary(void *unused)
int __cpu_up(unsigned int cpu)
{
- struct task_struct *p;
char buf[32];
int c;
- /* create a process for the processor */
- /* only regs.msr is actually used, and 0 is OK for it */
- p = fork_idle(cpu);
- if (IS_ERR(p))
- panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
- secondary_ti = p->thread_info;
- p->thread_info->cpu = cpu;
+ secondary_ti = idle_tasks[cpu]->thread_info;
+ mb();
/*
* There was a cache flush loop here to flush the cache
@@ -389,7 +401,11 @@ int __cpu_up(unsigned int cpu)
printk("Processor %d found.\n", cpu);
smp_ops->give_timebase();
- cpu_set(cpu, cpu_online_map);
+
+ /* Wait until cpu puts itself in the online map */
+ while (!cpu_online(cpu))
+ cpu_relax();
+
return 0;
}
diff --git a/arch/ppc/kernel/swsusp.S b/arch/ppc/kernel/swsusp.S
index 55148bb88d39..69773cc1a85f 100644
--- a/arch/ppc/kernel/swsusp.S
+++ b/arch/ppc/kernel/swsusp.S
@@ -5,7 +5,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
/*
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index 124313ce3c09..127f040de9de 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -41,10 +41,6 @@
#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/temp.c b/arch/ppc/kernel/temp.c
index fe8bb634ead0..26bd8ea35a4e 100644
--- a/arch/ppc/kernel/temp.c
+++ b/arch/ppc/kernel/temp.c
@@ -21,7 +21,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <asm/segment.h>
#include <asm/io.h>
#include <asm/reg.h>
#include <asm/nvram.h>
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index a3c5281a5d2d..22d7fd1e0aea 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -58,7 +58,6 @@
#include <linux/init.h>
#include <linux/profile.h>
-#include <asm/segment.h>
#include <asm/io.h>
#include <asm/nvram.h>
#include <asm/cache.h>
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index d87423d1003a..961ede87be72 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -118,6 +118,28 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
info.si_code = code;
info.si_addr = (void __user *) addr;
force_sig_info(signr, &info, current);
+
+ /*
+ * Init gets no signals that it doesn't have a handler for.
+ * That's all very well, but if it has caused a synchronous
+ * exception and we ignore the resulting signal, it will just
+ * generate the same exception over and over again and we get
+ * nowhere. Better to kill it and let the kernel panic.
+ */
+ if (current->pid == 1) {
+ __sighandler_t handler;
+
+ spin_lock_irq(&current->sighand->siglock);
+ handler = current->sighand->action[signr-1].sa.sa_handler;
+ spin_unlock_irq(&current->sighand->siglock);
+ if (handler == SIG_DFL) {
+ /* init has generated a synchronous exception
+ and it doesn't have a handler for the signal */
+ printk(KERN_CRIT "init has generated signal %d "
+ "but has no handler for it\n", signr);
+ do_exit(signr);
+ }
+ }
}
/*
@@ -849,10 +871,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/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 9353584fb710..17d2db7e537d 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -96,6 +96,9 @@ SECTIONS
*(.init.text)
_einittext = .;
}
+ /* .exit.text is discarded at runtime, not link time,
+ to deal with references from __bug_table */
+ .exit.text : { *(.exit.text) }
.init.data : {
*(.init.data);
__vtop_table_begin = .;
@@ -190,5 +193,6 @@ SECTIONS
/* Sections to be discarded. */
/DISCARD/ : {
*(.exitcall.exit)
+ *(.exit.data)
}
}
diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
index 1c380e67d435..50358e4ea159 100644
--- a/arch/ppc/lib/Makefile
+++ b/arch/ppc/lib/Makefile
@@ -2,8 +2,7 @@
# Makefile for ppc-specific library files..
#
-obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o
+obj-y := checksum.o string.o strcase.o div64.o
-obj-$(CONFIG_SMP) += locks.o
obj-$(CONFIG_8xx) += rheap.o
obj-$(CONFIG_CPM2) += rheap.o
diff --git a/arch/ppc/lib/dec_and_lock.c b/arch/ppc/lib/dec_and_lock.c
deleted file mode 100644
index 4ee888070d91..000000000000
--- a/arch/ppc/lib/dec_and_lock.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-
-/*
- * This is an implementation of the notion of "decrement a
- * reference count, and return locked if it decremented to zero".
- *
- * This implementation can be used on any architecture that
- * has a cmpxchg, and where atomic->value is an int holding
- * the value of the atomic (i.e. the high bits aren't used
- * for a lock or anything like that).
- *
- * N.B. ATOMIC_DEC_AND_LOCK gets defined in include/linux/spinlock.h
- * if spinlocks are empty and thus atomic_dec_and_lock is defined
- * to be atomic_dec_and_test - in that case we don't need it
- * defined here as well.
- */
-
-#ifndef ATOMIC_DEC_AND_LOCK
-int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-{
- int counter;
- int newcount;
-
- for (;;) {
- counter = atomic_read(atomic);
- newcount = counter - 1;
- if (!newcount)
- break; /* do it the slow way */
-
- newcount = cmpxchg(&atomic->counter, counter, newcount);
- if (newcount == counter)
- return 0;
- }
-
- spin_lock(lock);
- if (atomic_dec_and_test(atomic))
- return 1;
- spin_unlock(lock);
- return 0;
-}
-
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif /* ATOMIC_DEC_AND_LOCK */
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 57d9930843ac..ee5e9f25baf9 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -278,11 +278,7 @@ bad_area:
/* User mode accesses cause a SIGSEGV */
if (user_mode(regs)) {
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = code;
- info.si_addr = (void __user *) address;
- force_sig_info(SIGSEGV, &info, current);
+ _exception(SIGSEGV, regs, code, address);
return 0;
}
diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S
index ab83132a7ed0..3ec87c91343e 100644
--- a/arch/ppc/mm/hashtable.S
+++ b/arch/ppc/mm/hashtable.S
@@ -30,7 +30,7 @@
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/thread_info.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#ifdef CONFIG_SMP
.comm mmu_hash_lock,4
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index 81a3d7446d37..43505b1fc5d8 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -114,9 +114,9 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
struct page *ptepage;
#ifdef CONFIG_HIGHPTE
- int flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
+ gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
#else
- int flags = GFP_KERNEL | __GFP_REPEAT;
+ gfp_t flags = GFP_KERNEL | __GFP_REPEAT;
#endif
ptepage = alloc_pages(flags, 0);
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c
index ac391d463d78..78a403b48dba 100644
--- a/arch/ppc/platforms/4xx/bamboo.c
+++ b/arch/ppc/platforms/4xx/bamboo.c
@@ -27,7 +27,6 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/initrd.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/tty.h>
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 0fd3442f5131..27b778ab903b 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/initrd.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/tty.h>
@@ -91,15 +90,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/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
index a38e6f9ef858..16d953bda22c 100644
--- a/arch/ppc/platforms/4xx/luan.c
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -28,7 +28,6 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/initrd.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/tty.h>
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index 80028df1b445..506949c5dd29 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -28,7 +28,6 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/initrd.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/tty.h>
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index b38a851a64ec..79b3f533d0a3 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -24,7 +24,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index f761fdf160db..7dc8a68acfd0 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -24,7 +24,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index f2748c88665a..8841fd7da6ee 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -24,7 +24,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index 18e952d1767c..bd3ac0136756 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -24,7 +24,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/module.h>
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 6267b294f704..9f9039498ae5 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -24,7 +24,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/module.h>
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index 165df94d4aa6..c76760a781c1 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -24,7 +24,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
diff --git a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c
index 4f6d1ddd6fb8..c02f110219f5 100644
--- a/arch/ppc/platforms/85xx/sbc85xx.c
+++ b/arch/ppc/platforms/85xx/sbc85xx.c
@@ -23,7 +23,6 @@
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/module.h>
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index c99b365d6110..20940f4044f4 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -30,7 +30,6 @@
#include <linux/blkdev.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/root_dev.h>
#include <linux/seq_file.h>
#include <linux/serial.h>
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
index 7786818bd9d0..df6ff98c023a 100644
--- a/arch/ppc/platforms/chestnut.c
+++ b/arch/ppc/platforms/chestnut.c
@@ -35,7 +35,6 @@
#include <asm/time.h>
#include <asm/dma.h>
#include <asm/io.h>
-#include <linux/irq.h>
#include <asm/hw_irq.h>
#include <asm/machdep.h>
#include <asm/kgdb.h>
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 57f29ab29bda..66346f0de7ec 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/ide.h>
-#include <linux/irq.h>
#include <linux/console.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 4864a7de3daa..6037ce7796f5 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/bcd.h>
-#include <asm/segment.h>
#include <asm/io.h>
#include <asm/nvram.h>
#include <asm/prom.h>
diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
index e391e52383c7..3a5ff9fb71d6 100644
--- a/arch/ppc/platforms/gemini_setup.c
+++ b/arch/ppc/platforms/gemini_setup.c
@@ -21,7 +21,6 @@
#include <linux/major.h>
#include <linux/initrd.h>
#include <linux/console.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/bcd.h>
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index b659d7b3d747..ff3796860123 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -58,7 +58,7 @@ static void parse_bootinfo(unsigned long r3,
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/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
index b292b44b760c..ce2ce88c8033 100644
--- a/arch/ppc/platforms/mvme5100.c
+++ b/arch/ppc/platforms/mvme5100.c
@@ -20,7 +20,6 @@
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <linux/kdev_t.h>
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index c0605244edda..d4bc5f67ec53 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -695,6 +695,13 @@ static int __init pmac_cpufreq_setup(void)
set_speed_proc = pmu_set_cpu_speed;
is_pmu_based = 1;
}
+ /* Else check for TiPb 550 */
+ else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
+ hi_freq = cur_freq;
+ low_freq = 500000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
/* Else check for TiPb 400 & 500 */
else if (machine_is_compatible("PowerBook3,2")) {
/* We only know about the 400 MHz and the 500Mhz model
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index 867336ad5d36..dd6d45ae0501 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -2337,6 +2337,10 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
},
+ { "PowerBook6,7", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
{ "PowerBook6,8", "PowerBook G4 12\"",
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
index b392b9a15987..d6356f480d90 100644
--- a/arch/ppc/platforms/pmac_setup.c
+++ b/arch/ppc/platforms/pmac_setup.c
@@ -48,7 +48,6 @@
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/bitops.h>
@@ -719,7 +718,8 @@ pmac_declare_of_platform_devices(void)
if (np) {
for (np = np->child; np != NULL; np = np->sibling)
if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "uni-n-i2c");
+ of_platform_device_create(np, "uni-n-i2c",
+ NULL);
break;
}
}
@@ -727,17 +727,18 @@ pmac_declare_of_platform_devices(void)
if (np) {
for (np = np->child; np != NULL; np = np->sibling)
if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "u3-i2c");
+ of_platform_device_create(np, "u3-i2c",
+ NULL);
break;
}
}
np = find_devices("valkyrie");
if (np)
- of_platform_device_create(np, "valkyrie");
+ of_platform_device_create(np, "valkyrie", NULL);
np = find_devices("platinum");
if (np)
- of_platform_device_create(np, "platinum");
+ of_platform_device_create(np, "platinum", NULL);
return 0;
}
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
index 016a74649155..88419c77ac43 100644
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -17,7 +17,7 @@
#include <asm/cputable.h>
#include <asm/cache.h>
#include <asm/thread_info.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#define MAGIC 0x4c617273 /* 'Lars' */
@@ -161,6 +161,8 @@ _GLOBAL(low_sleep_handler)
addi r3,r3,sleep_storage@l
stw r5,0(r3)
+ .globl low_cpu_die
+low_cpu_die:
/* Flush & disable all caches */
bl flush_disable_caches
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
index 8e049dab4e63..794a23994b82 100644
--- a/arch/ppc/platforms/pmac_smp.c
+++ b/arch/ppc/platforms/pmac_smp.c
@@ -33,6 +33,7 @@
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/hardirq.h>
+#include <linux/cpu.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -55,9 +56,7 @@
* Powersurge (old powermac SMP) support.
*/
-extern void __secondary_start_psurge(void);
-extern void __secondary_start_psurge2(void); /* Temporary horrible hack */
-extern void __secondary_start_psurge3(void); /* Temporary horrible hack */
+extern void __secondary_start_pmac_0(void);
/* Addresses for powersurge registers */
#define HAMMERHEAD_BASE 0xf8000000
@@ -119,7 +118,7 @@ static volatile int sec_tb_reset = 0;
static unsigned int pri_tb_hi, pri_tb_lo;
static unsigned int pri_tb_stamp;
-static void __init core99_init_caches(int cpu)
+static void __devinit core99_init_caches(int cpu)
{
if (!cpu_has_feature(CPU_FTR_L2CR))
return;
@@ -346,7 +345,7 @@ static int __init smp_psurge_probe(void)
static void __init smp_psurge_kick_cpu(int nr)
{
- void (*start)(void) = __secondary_start_psurge;
+ unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
unsigned long a;
/* may need to flush here if secondary bats aren't setup */
@@ -356,17 +355,7 @@ static void __init smp_psurge_kick_cpu(int nr)
if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
- /* setup entry point of secondary processor */
- switch (nr) {
- case 2:
- start = __secondary_start_psurge2;
- break;
- case 3:
- start = __secondary_start_psurge3;
- break;
- }
-
- out_be32(psurge_start, __pa(start));
+ out_be32(psurge_start, start);
mb();
psurge_set_ipi(nr);
@@ -500,14 +489,14 @@ static int __init smp_core99_probe(void)
return ncpus;
}
-static void __init smp_core99_kick_cpu(int nr)
+static void __devinit smp_core99_kick_cpu(int nr)
{
unsigned long save_vector, new_vector;
unsigned long flags;
volatile unsigned long *vector
= ((volatile unsigned long *)(KERNELBASE+0x100));
- if (nr < 1 || nr > 3)
+ if (nr < 0 || nr > 3)
return;
if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
@@ -518,19 +507,9 @@ static void __init smp_core99_kick_cpu(int nr)
save_vector = *vector;
/* Setup fake reset vector that does
- * b __secondary_start_psurge - KERNELBASE
+ * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
*/
- switch(nr) {
- case 1:
- new_vector = (unsigned long)__secondary_start_psurge;
- break;
- case 2:
- new_vector = (unsigned long)__secondary_start_psurge2;
- break;
- case 3:
- new_vector = (unsigned long)__secondary_start_psurge3;
- break;
- }
+ new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8;
*vector = 0x48000002 + new_vector - KERNELBASE;
/* flush data cache and inval instruction cache */
@@ -554,7 +533,7 @@ static void __init smp_core99_kick_cpu(int nr)
if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
}
-static void __init smp_core99_setup_cpu(int cpu_nr)
+static void __devinit smp_core99_setup_cpu(int cpu_nr)
{
/* Setup L2/L3 */
if (cpu_nr != 0)
@@ -668,3 +647,47 @@ struct smp_ops_t core99_smp_ops __pmacdata = {
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
};
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+int __cpu_disable(void)
+{
+ cpu_clear(smp_processor_id(), cpu_online_map);
+
+ /* XXX reset cpu affinity here */
+ openpic_set_priority(0xf);
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ mb();
+ udelay(20);
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ return 0;
+}
+
+extern void low_cpu_die(void) __attribute__((noreturn)); /* in pmac_sleep.S */
+static int cpu_dead[NR_CPUS];
+
+void cpu_die(void)
+{
+ local_irq_disable();
+ cpu_dead[smp_processor_id()] = 1;
+ mb();
+ low_cpu_die();
+}
+
+void __cpu_die(unsigned int cpu)
+{
+ int timeout;
+
+ timeout = 1000;
+ while (!cpu_dead[cpu]) {
+ if (--timeout == 0) {
+ printk("CPU %u refused to die!\n", cpu);
+ break;
+ }
+ msleep(1);
+ }
+ cpu_callin_map[cpu] = 0;
+ cpu_dead[cpu] = 0;
+}
+
+#endif
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
index 778ce4fec368..efb819f9490d 100644
--- a/arch/ppc/platforms/pmac_time.c
+++ b/arch/ppc/platforms/pmac_time.c
@@ -195,7 +195,7 @@ via_calibrate_decr(void)
;
dend = get_dec();
- tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100));
+ tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
diff --git a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c
index 0abe15159e6c..e6b520e6e13f 100644
--- a/arch/ppc/platforms/powerpmc250.c
+++ b/arch/ppc/platforms/powerpmc250.c
@@ -26,7 +26,6 @@
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/ide.h>
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index 65705c911795..e70aae20d6f9 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -22,7 +22,6 @@
#include <linux/ioport.h>
#include <linux/console.h>
#include <linux/pci.h>
-#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
diff --git a/arch/ppc/platforms/prpmc750.c b/arch/ppc/platforms/prpmc750.c
index 24ae1caafc61..0bb14a5e824c 100644
--- a/arch/ppc/platforms/prpmc750.c
+++ b/arch/ppc/platforms/prpmc750.c
@@ -24,7 +24,6 @@
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/ide.h>
#include <linux/root_dev.h>
diff --git a/arch/ppc/platforms/prpmc800.c b/arch/ppc/platforms/prpmc800.c
index 8b09fa69b35b..de7baefacd3a 100644
--- a/arch/ppc/platforms/prpmc800.c
+++ b/arch/ppc/platforms/prpmc800.c
@@ -22,7 +22,6 @@
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/ide.h>
#include <linux/root_dev.h>
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index c30607a972d8..0376c8cff5d1 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -32,7 +32,6 @@
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
@@ -59,7 +58,6 @@
#include <asm/mpc10x.h>
#include <asm/pci-bridge.h>
#include <asm/mv64x60.h>
-#include <asm/i8259.h>
#include "radstone_ppc7d.h"
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index 21e31346b12b..5232283c1974 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -74,7 +74,6 @@
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 8b9b226005d1..b8d08f33f7ee 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -34,7 +34,8 @@ ifeq ($(CONFIG_40x),y)
obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o ppc405_pci.o
endif
endif
-obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y)
+obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
+ ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
ifeq ($(CONFIG_8xx),y)
obj-$(CONFIG_PCI) += qspan_pci.o i8259.o
endif
diff --git a/arch/ppc/syslib/cpc700_pic.c b/arch/ppc/syslib/cpc700_pic.c
index 774709807538..75fe8eb10693 100644
--- a/arch/ppc/syslib/cpc700_pic.c
+++ b/arch/ppc/syslib/cpc700_pic.c
@@ -90,14 +90,10 @@ cpc700_mask_and_ack_irq(unsigned int irq)
}
static struct hw_interrupt_type cpc700_pic = {
- "CPC700 PIC",
- NULL,
- NULL,
- cpc700_unmask_irq,
- cpc700_mask_irq,
- cpc700_mask_and_ack_irq,
- NULL,
- NULL
+ .typename = "CPC700 PIC",
+ .enable = cpc700_unmask_irq,
+ .disable = cpc700_mask_irq,
+ .ack = cpc700_mask_and_ack_irq,
};
__init static void
diff --git a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
index b9391e650141..5c7908c20e43 100644
--- a/arch/ppc/syslib/i8259.c
+++ b/arch/ppc/syslib/i8259.c
@@ -129,14 +129,11 @@ static void i8259_end_irq(unsigned int irq)
}
struct hw_interrupt_type i8259_pic = {
- " i8259 ",
- NULL,
- NULL,
- i8259_unmask_irq,
- i8259_mask_irq,
- i8259_mask_and_ack_irq,
- i8259_end_irq,
- NULL
+ .typename = " i8259 ",
+ .enable = i8259_unmask_irq,
+ .disable = i8259_mask_irq,
+ .ack = i8259_mask_and_ack_irq,
+ .end = i8259_end_irq,
};
static struct resource pic1_iores = {
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index d4776af6a3ca..0bb919859b8b 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -236,9 +236,10 @@ void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p)
/* 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 87065e2e4c5f..3e039706bdbc 100644
--- a/arch/ppc/syslib/mpc10x_common.c
+++ b/arch/ppc/syslib/mpc10x_common.c
@@ -140,12 +140,12 @@ struct platform_device ppc_sys_platform_devices[] = {
},
[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 5aaf0e58e1f9..95b3b8a7f0ba 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -165,7 +165,7 @@ struct platform_device ppc_sys_platform_devices[] = {
},
[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 8af322dd476a..bbc5ac0de878 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -282,7 +282,7 @@ struct platform_device ppc_sys_platform_devices[] = {
},
[MPC85xx_DUART] = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = serial_platform_data,
},
[MPC85xx_PERFMON] = {
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
new file mode 100644
index 000000000000..2b5f0e701687
--- /dev/null
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -0,0 +1,224 @@
+/*
+ * arch/ppc/syslib/mpc8xx_devices.c
+ *
+ * MPC8xx Device descriptions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug<vbordug@ru.mvista.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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/serial_8250.h>
+#include <linux/mii.h>
+#include <asm/commproc.h>
+#include <asm/mpc8xx.h>
+#include <asm/irq.h>
+#include <asm/ppc_sys.h>
+
+/* We use offsets for IORESOURCE_MEM to do not set dependences at compile time.
+ * They will get fixed up by mach_mpc8xx_fixup
+ */
+
+struct platform_device ppc_sys_platform_devices[] = {
+ [MPC8xx_CPM_FEC1] = {
+ .name = "fsl-cpm-fec",
+ .id = 1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xe00,
+ .end = 0xe88,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_FEC1,
+ .end = MPC8xx_INT_FEC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_FEC2] = {
+ .name = "fsl-cpm-fec",
+ .id = 2,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0x1e00,
+ .end = 0x1e88,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_FEC2,
+ .end = MPC8xx_INT_FEC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_SCC1] = {
+ .name = "fsl-cpm-scc",
+ .id = 1,
+ .num_resources = 3,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xa00,
+ .end = 0xa18,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "pram",
+ .start = 0x3c00,
+ .end = 0x3c80,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_SCC1,
+ .end = MPC8xx_INT_SCC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_SCC2] = {
+ .name = "fsl-cpm-scc",
+ .id = 2,
+ .num_resources = 3,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xa20,
+ .end = 0xa38,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "pram",
+ .start = 0x3d00,
+ .end = 0x3d80,
+ .flags = IORESOURCE_MEM,
+ },
+
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_SCC2,
+ .end = MPC8xx_INT_SCC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_SCC3] = {
+ .name = "fsl-cpm-scc",
+ .id = 3,
+ .num_resources = 3,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xa40,
+ .end = 0xa58,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "pram",
+ .start = 0x3e00,
+ .end = 0x3e80,
+ .flags = IORESOURCE_MEM,
+ },
+
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_SCC3,
+ .end = MPC8xx_INT_SCC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_SCC4] = {
+ .name = "fsl-cpm-scc",
+ .id = 4,
+ .num_resources = 3,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xa60,
+ .end = 0xa78,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "pram",
+ .start = 0x3f00,
+ .end = 0x3f80,
+ .flags = IORESOURCE_MEM,
+ },
+
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_SCC4,
+ .end = MPC8xx_INT_SCC4,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_SMC1] = {
+ .name = "fsl-cpm-smc",
+ .id = 1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xa82,
+ .end = 0xa91,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_SMC1,
+ .end = MPC8xx_INT_SMC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC8xx_CPM_SMC2] = {
+ .name = "fsl-cpm-smc",
+ .id = 2,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .name = "regs",
+ .start = 0xa92,
+ .end = 0xaa1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "interrupt",
+ .start = MPC8xx_INT_SMC2,
+ .end = MPC8xx_INT_SMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+};
+
+static int __init mach_mpc8xx_fixup(struct platform_device *pdev)
+{
+ ppc_sys_fixup_mem_resource (pdev, IMAP_ADDR);
+ return 0;
+}
+
+static int __init mach_mpc8xx_init(void)
+{
+ ppc_sys_device_fixup = mach_mpc8xx_fixup;
+ return 0;
+}
+
+postcore_initcall(mach_mpc8xx_init);
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
new file mode 100644
index 000000000000..a532ccc861c0
--- /dev/null
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -0,0 +1,61 @@
+/*
+ * arch/ppc/platforms/mpc8xx_sys.c
+ *
+ * MPC8xx System descriptions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <asm/ppc_sys.h>
+
+struct ppc_sys_spec *cur_ppc_sys_spec;
+struct ppc_sys_spec ppc_sys_specs[] = {
+ {
+ .ppc_sys_name = "MPC86X",
+ .mask = 0xFFFFFFFF,
+ .value = 0x00000000,
+ .num_devices = 2,
+ .device_list = (enum ppc_sys_devices[])
+ {
+ MPC8xx_CPM_FEC1,
+ MPC8xx_CPM_SCC1,
+ MPC8xx_CPM_SCC2,
+ MPC8xx_CPM_SCC3,
+ MPC8xx_CPM_SCC4,
+ MPC8xx_CPM_SMC1,
+ MPC8xx_CPM_SMC2,
+ },
+ },
+ {
+ .ppc_sys_name = "MPC885",
+ .mask = 0xFFFFFFFF,
+ .value = 0x00000000,
+ .num_devices = 3,
+ .device_list = (enum ppc_sys_devices[])
+ {
+ MPC8xx_CPM_FEC1,
+ MPC8xx_CPM_FEC2,
+ MPC8xx_CPM_SCC1,
+ MPC8xx_CPM_SCC2,
+ MPC8xx_CPM_SCC3,
+ MPC8xx_CPM_SCC4,
+ MPC8xx_CPM_SMC1,
+ MPC8xx_CPM_SMC2,
+ },
+ },
+ { /* default match */
+ .ppc_sys_name = "",
+ .mask = 0x00000000,
+ .value = 0x00000000,
+ },
+};
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 6262b11f366f..4849850a59ed 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -31,10 +31,10 @@
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;
+static void __iomem *mv64x60_bridge_vbase;
static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID;
static u32 mv64x60_bridge_rev;
#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
@@ -938,7 +938,7 @@ mv64x60_setup_for_chip(struct mv64x60_handle *bh)
*
* Return the virtual address of the bridge's registers.
*/
-void *
+void __iomem *
mv64x60_get_bridge_vbase(void)
{
return mv64x60_bridge_vbase;
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
index da8a0f2128dc..93c7231ea709 100644
--- a/arch/ppc/syslib/of_device.c
+++ b/arch/ppc/syslib/of_device.c
@@ -234,7 +234,9 @@ void of_device_unregister(struct of_device *ofdev)
device_unregister(&ofdev->dev);
}
-struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id)
+struct of_device* of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
{
struct of_device *dev;
u32 *reg;
@@ -247,7 +249,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
dev->node = of_node_get(np);
dev->dma_mask = 0xffffffffUL;
dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.parent = NULL;
+ dev->dev.parent = parent;
dev->dev.bus = &of_platform_bus_type;
dev->dev.release = of_release_dev;
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 53da58523e39..1cf5de21a3fd 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
#include <linux/errno.h>
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
index 7e272c51a497..16cff91d9f41 100644
--- a/arch/ppc/syslib/open_pic2.c
+++ b/arch/ppc/syslib/open_pic2.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
#include <linux/errno.h>
@@ -82,13 +81,11 @@ static void openpic2_end_irq(unsigned int irq_nr);
static void openpic2_ack_irq(unsigned int irq_nr);
struct hw_interrupt_type open_pic2 = {
- " OpenPIC2 ",
- NULL,
- NULL,
- openpic2_enable_irq,
- openpic2_disable_irq,
- openpic2_ack_irq,
- openpic2_end_irq,
+ .typename = " OpenPIC2 ",
+ .enable = openpic2_enable_irq,
+ .disable = openpic2_disable_irq,
+ .ack = openpic2_ack_irq,
+ .end = openpic2_end_irq,
};
/*
@@ -577,7 +574,7 @@ static void openpic2_cached_disable_irq(u_int irq)
* we need something better to deal with that... Maybe switch to S1 for
* cpufreq changes
*/
-int openpic2_suspend(struct sys_device *sysdev, u32 state)
+int openpic2_suspend(struct sys_device *sysdev, pm_message_t state)
{
int i;
unsigned long flags;
diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
index 06cb0af2a58d..ce4d1deb86e9 100644
--- a/arch/ppc/syslib/ppc403_pic.c
+++ b/arch/ppc/syslib/ppc403_pic.c
@@ -34,13 +34,10 @@ static void ppc403_aic_disable(unsigned int irq);
static void ppc403_aic_disable_and_ack(unsigned int irq);
static struct hw_interrupt_type ppc403_aic = {
- "403GC AIC",
- NULL,
- NULL,
- ppc403_aic_enable,
- ppc403_aic_disable,
- ppc403_aic_disable_and_ack,
- 0
+ .typename = "403GC AIC",
+ .enable = ppc403_aic_enable,
+ .disable = ppc403_aic_disable,
+ .ack = ppc403_aic_disable_and_ack,
};
int
diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
index b843c4fef25e..bf83240689dc 100644
--- a/arch/ppc/syslib/ppc4xx_setup.c
+++ b/arch/ppc/syslib/ppc4xx_setup.c
@@ -18,7 +18,6 @@
#include <linux/smp.h>
#include <linux/threads.h>
#include <linux/spinlock.h>
-#include <linux/irq.h>
#include <linux/reboot.h>
#include <linux/param.h>
#include <linux/string.h>
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index b7242f1bd931..832b8bf99ae7 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -184,8 +184,8 @@ mpc85xx_setup_pci1(struct pci_controller *hose)
pci->powar1 = 0x80044000 |
(__ilog2(MPC85XX_PCI1_UPPER_MEM - MPC85XX_PCI1_LOWER_MEM + 1) - 1);
- /* Setup outboud IO windows @ MPC85XX_PCI1_IO_BASE */
- pci->potar2 = 0x00000000;
+ /* Setup outbound IO windows @ MPC85XX_PCI1_IO_BASE */
+ pci->potar2 = (MPC85XX_PCI1_LOWER_IO >> 12) & 0x000fffff;
pci->potear2 = 0x00000000;
pci->powbar2 = (MPC85XX_PCI1_IO_BASE >> 12) & 0x000fffff;
/* Enable, IO R/W */
@@ -235,8 +235,8 @@ mpc85xx_setup_pci2(struct pci_controller *hose)
pci->powar1 = 0x80044000 |
(__ilog2(MPC85XX_PCI2_UPPER_MEM - MPC85XX_PCI2_LOWER_MEM + 1) - 1);
- /* Setup outboud IO windows @ MPC85XX_PCI2_IO_BASE */
- pci->potar2 = 0x00000000;
+ /* Setup outbound IO windows @ MPC85XX_PCI2_IO_BASE */
+ pci->potar2 = (MPC85XX_PCI2_LOWER_IO >> 12) & 0x000fffff;;
pci->potear2 = 0x00000000;
pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff;
/* Enable, IO R/W */
diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
index 2bcf8a16d1c9..8599850ca772 100644
--- a/arch/ppc/syslib/prep_nvram.c
+++ b/arch/ppc/syslib/prep_nvram.c
@@ -15,7 +15,6 @@
#include <linux/ioport.h>
#include <asm/sections.h>
-#include <asm/segment.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/prep_nvram.h>
diff --git a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c
index 57f4ed5e5ae1..0970b5d30391 100644
--- a/arch/ppc/syslib/qspan_pci.c
+++ b/arch/ppc/syslib/qspan_pci.c
@@ -94,7 +94,7 @@
#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/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
index e0bd66f0847a..2cbcad278cef 100644
--- a/arch/ppc/syslib/xilinx_pic.c
+++ b/arch/ppc/syslib/xilinx_pic.c
@@ -79,14 +79,11 @@ xilinx_intc_end(unsigned int irq)
}
static struct hw_interrupt_type xilinx_intc = {
- "Xilinx Interrupt Controller",
- NULL,
- NULL,
- xilinx_intc_enable,
- xilinx_intc_disable,
- xilinx_intc_disable_and_ack,
- xilinx_intc_end,
- 0
+ .typename = "Xilinx Interrupt Controller",
+ .enable = xilinx_intc_enable,
+ .disable = xilinx_intc_disable,
+ .ack = xilinx_intc_disable_and_ack,
+ .end = xilinx_intc_end,
};
int
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index deca68ad644a..c658650af429 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -28,10 +28,6 @@ config GENERIC_ISA_DMA
bool
default y
-config HAVE_DEC_LOCK
- bool
- default y
-
config EARLY_PRINTK
bool
default y
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 8189953a372c..521c2a5a2862 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -56,7 +56,7 @@ LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD)
CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \
-mcall-aixdesc
# Temporary hack until we have migrated to asm-powerpc
-CPPFLAGS += -Iinclude3
+CPPFLAGS += -Iarch/$(ARCH)/include
GCC_VERSION := $(call cc-version)
GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;)
@@ -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
@@ -106,7 +107,7 @@ install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
defaultimage-$(CONFIG_PPC_PSERIES) := zImage
-defaultimage-$(CONFIG_PPC_PMAC) := vmlinux
+defaultimage-$(CONFIG_PPC_PMAC) := zImage.vmode
defaultimage-$(CONFIG_PPC_MAPLE) := zImage
defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
KBUILD_IMAGE := $(defaultimage-y)
@@ -114,27 +115,21 @@ all: $(KBUILD_IMAGE)
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
- $(Q)rm -rf include3
+ # Temporary hack until we have migrated to asm-powerpc
+ $(Q)rm -rf arch/$(ARCH)/include
-prepare: include/asm-ppc64/offsets.h
-
-arch/ppc64/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-ppc64/offsets.h: arch/ppc64/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
# Temporary hack until we have migrated to asm-powerpc
-include/asm: include3/asm
-include3/asm:
- $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi;
- $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
+include/asm: arch/$(ARCH)/include/asm
+arch/$(ARCH)/include/asm:
+ $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
+ $(Q)ln -fsn $(srctree)/include/asm-powerpc arch/$(ARCH)/include/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
-
-CLEAN_FILES += include/asm-ppc64/offsets.h
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 2c5f5e73d00c..33fdc8710891 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -37,6 +37,9 @@ quiet_cmd_bootcc = BOOTCC $@
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 99e68cfbe688..f7ec19a2d0b0 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -23,7 +23,8 @@ extern void flush_cache(void *, unsigned long);
/* 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/configs/bpa_defconfig b/arch/ppc64/configs/bpa_defconfig
index 46c5da41c3ae..67ffecbc05cb 100644
--- a/arch/ppc64/configs/bpa_defconfig
+++ b/arch/ppc64/configs/bpa_defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 14:12:19 2005
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:29:10 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
@@ -26,6 +26,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
@@ -36,6 +37,7 @@ CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -95,6 +97,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_NUMA is not set
CONFIG_SCHED_SMT=y
CONFIG_PREEMPT_NONE=y
@@ -110,17 +113,18 @@ CONFIG_PPC_RTAS=y
CONFIG_RTAS_PROC=y
CONFIG_RTAS_FLASH=y
CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
CONFIG_ISA_DMA_API=y
#
-# General setup
+# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
@@ -132,8 +136,6 @@ CONFIG_PCI_NAMES=y
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
#
# Networking
@@ -163,8 +165,8 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
@@ -181,6 +183,7 @@ CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
#
# IP: Netfilter Configuration
@@ -188,11 +191,14 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=y
# CONFIG_IP_NF_CT_ACCT is not set
# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
CONFIG_IP_NF_CT_PROTO_SCTP=y
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -216,13 +222,16 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -240,6 +249,7 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_ARPTABLES=m
@@ -251,6 +261,12 @@ CONFIG_IP_NF_ARP_MANGLE=m
#
# CONFIG_IP6_NF_QUEUE is not set
# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -278,6 +294,7 @@ CONFIG_NET_CLS_ROUTE=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -292,6 +309,11 @@ CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -322,7 +344,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=131072
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -395,6 +416,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -436,12 +458,18 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -462,15 +490,18 @@ CONFIG_E1000=m
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
CONFIG_SKGE=m
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_SPIDER_NET is not set
# CONFIG_MV643XX_ETH is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -552,6 +583,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
# CONFIG_SYNCLINK is not set
@@ -642,7 +674,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_ISA is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -656,7 +687,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_SENSOR is not set
#
# Miscellaneous I2C Chip support
@@ -683,12 +713,17 @@ CONFIG_I2C_ALGOBIT=y
# 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
@@ -756,10 +791,6 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -768,6 +799,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -794,13 +826,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-# CONFIG_TMPFS_SECURITY is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -846,6 +876,7 @@ CONFIG_SUNRPC=m
# 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
@@ -923,6 +954,7 @@ CONFIG_NLS_ISO8859_15=m
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=15
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -981,7 +1013,12 @@ CONFIG_CRYPTO_DEFLATE=m
# 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_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
index fc83d9330282..6323065fbf2c 100644
--- a/arch/ppc64/configs/g5_defconfig
+++ b/arch/ppc64/configs/g5_defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 14:16:59 2005
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:30:23 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -37,6 +38,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -97,6 +99,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_NUMA is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PREEMPT_NONE=y
@@ -109,19 +112,20 @@ CONFIG_HZ_250=y
CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
CONFIG_ISA_DMA_API=y
#
-# General setup
+# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
-# CONFIG_HOTPLUG_CPU is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -132,8 +136,6 @@ CONFIG_PCI_NAMES=y
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
#
# Networking
@@ -163,8 +165,8 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
@@ -175,6 +177,7 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
#
# IP: Netfilter Configuration
@@ -182,11 +185,14 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -210,14 +216,18 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -235,6 +245,7 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -244,6 +255,11 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -270,6 +286,7 @@ CONFIG_NET_CLS_ROUTE=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -284,6 +301,11 @@ CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -315,7 +337,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -395,6 +416,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -422,6 +444,7 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -435,10 +458,12 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
CONFIG_SCSI_SATA=y
# CONFIG_SCSI_SATA_AHCI is not set
CONFIG_SCSI_SATA_SVW=y
# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
# CONFIG_SCSI_SATA_NV is not set
# CONFIG_SCSI_SATA_PROMISE is not set
# CONFIG_SCSI_SATA_QSTOR is not set
@@ -498,6 +523,7 @@ CONFIG_DM_ZERO=m
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -540,7 +566,6 @@ CONFIG_IEEE1394_RAWIO=y
#
CONFIG_ADB_PMU=y
CONFIG_PMAC_SMU=y
-# CONFIG_PMAC_BACKLIGHT is not set
CONFIG_THERM_PM72=y
#
@@ -558,12 +583,18 @@ CONFIG_TUN=m
# 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=y
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -585,6 +616,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
CONFIG_TIGON3=m
@@ -594,6 +626,7 @@ CONFIG_TIGON3=m
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -760,8 +793,8 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_ISA is not set
CONFIG_I2C_KEYWEST=y
+CONFIG_I2C_PMAC_SMU=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -775,7 +808,6 @@ CONFIG_I2C_KEYWEST=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_SENSOR is not set
#
# Miscellaneous I2C Chip support
@@ -802,12 +834,17 @@ CONFIG_I2C_KEYWEST=y
# 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
@@ -856,6 +893,7 @@ CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
@@ -937,6 +975,7 @@ CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ONETOUCH is not set
#
# USB Input Devices
@@ -956,9 +995,11 @@ CONFIG_USB_HIDDEV=y
# 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
@@ -983,30 +1024,14 @@ CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
-
-#
-# USB Host-to-Host Cables
-#
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
-CONFIG_USB_KC2190=y
-
-#
-# Intelligent USB Devices/Gadgets
-#
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
CONFIG_USB_MON=y
#
@@ -1124,16 +1149,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -1141,6 +1162,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1168,14 +1190,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1225,6 +1244,7 @@ CONFIG_CIFS=m
# 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
@@ -1303,6 +1323,7 @@ CONFIG_OPROFILE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1360,7 +1381,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig
index 013d4e0e4003..62e92c7e9e27 100644
--- a/arch/ppc64/configs/iSeries_defconfig
+++ b/arch/ppc64/configs/iSeries_defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 14:17:02 2005
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:30:56 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -38,6 +39,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -88,6 +90,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_NUMA is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PREEMPT_NONE=y
@@ -101,17 +104,16 @@ CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_LPARCFG=y
CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
CONFIG_ISA_DMA_API=y
#
-# General setup
+# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
@@ -152,8 +154,8 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
@@ -164,6 +166,7 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
#
# IP: Netfilter Configuration
@@ -171,11 +174,14 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -199,14 +205,18 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -224,6 +234,7 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -233,6 +244,11 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -259,6 +275,7 @@ CONFIG_NET_CLS_ROUTE=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -273,6 +290,11 @@ CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -303,7 +325,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -323,6 +344,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -350,6 +372,7 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -363,6 +386,7 @@ CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
@@ -415,6 +439,7 @@ CONFIG_DM_ZERO=m
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -445,12 +470,18 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -489,6 +520,7 @@ CONFIG_E1000=m
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -498,6 +530,7 @@ CONFIG_E1000=m
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -632,7 +665,6 @@ CONFIG_MAX_RAW_DEVS=256
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
@@ -643,12 +675,17 @@ CONFIG_MAX_RAW_DEVS=256
# 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
@@ -722,16 +759,12 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -739,6 +772,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -766,14 +800,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -824,6 +855,7 @@ CONFIG_CIFS_POSIX=y
# 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
@@ -897,6 +929,7 @@ CONFIG_OPROFILE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -954,7 +987,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig
index dd42892cd873..7b480f3d1406 100644
--- a/arch/ppc64/configs/maple_defconfig
+++ b/arch/ppc64/configs/maple_defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 14:17:04 2005
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:31:24 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -37,6 +38,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
@@ -97,6 +99,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_NUMA is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PREEMPT_NONE=y
@@ -109,17 +112,18 @@ CONFIG_HZ_250=y
CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
CONFIG_ISA_DMA_API=y
#
-# General setup
+# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
@@ -131,8 +135,6 @@ CONFIG_PCI_NAMES=y
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
#
# Networking
@@ -163,14 +165,19 @@ CONFIG_IP_PNP_DHCP=y
# 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_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
@@ -196,6 +203,7 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -210,6 +218,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -240,7 +253,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -313,6 +325,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -354,12 +367,18 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -398,6 +417,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -408,6 +428,7 @@ CONFIG_E1000=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -553,7 +574,6 @@ CONFIG_I2C_AMD8111=y
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_ISA is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -567,7 +587,6 @@ CONFIG_I2C_AMD8111=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_SENSOR is not set
#
# Miscellaneous I2C Chip support
@@ -594,12 +613,17 @@ CONFIG_I2C_AMD8111=y
# 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
@@ -681,9 +705,11 @@ CONFIG_USB_HIDINPUT=y
# 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
@@ -814,10 +840,6 @@ CONFIG_JBD=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -826,6 +848,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -849,14 +872,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -898,6 +918,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
# 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
@@ -975,6 +996,7 @@ CONFIG_NLS_UTF8=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
CONFIG_DEBUG_SLAB=y
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1034,6 +1056,7 @@ CONFIG_CRYPTO_DES=y
# Library routines
#
CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
index 29f7b80b0efc..9f09dff9e11a 100644
--- a/arch/ppc64/configs/pSeries_defconfig
+++ b/arch/ppc64/configs/pSeries_defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 14:17:07 2005
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:32:17 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -38,6 +39,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
@@ -104,6 +106,7 @@ CONFIG_DISCONTIGMEM_MANUAL=y
CONFIG_DISCONTIGMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
CONFIG_NODES_SPAN_OTHER_NODES=y
CONFIG_NUMA=y
@@ -124,19 +127,20 @@ CONFIG_RTAS_FLASH=m
CONFIG_SCANLOG=m
CONFIG_LPARCFG=y
CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
CONFIG_ISA_DMA_API=y
#
-# General setup
+# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
-CONFIG_HOTPLUG_CPU=y
#
# PCCARD (PCMCIA/CardBus) support
@@ -152,8 +156,6 @@ CONFIG_HOTPLUG_PCI=m
# CONFIG_HOTPLUG_PCI_SHPC is not set
CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
#
# Networking
@@ -183,8 +185,8 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
@@ -195,6 +197,9 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -202,11 +207,15 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -230,14 +239,18 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -255,6 +268,7 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -264,6 +278,11 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -290,6 +309,7 @@ CONFIG_NET_CLS_ROUTE=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -304,6 +324,11 @@ CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -342,7 +367,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -416,6 +440,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -443,6 +468,7 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -456,6 +482,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
@@ -517,6 +544,7 @@ CONFIG_DM_MULTIPATH_EMC=m
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -547,12 +575,18 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=y
# CONFIG_TYPHOON is not set
@@ -581,6 +615,7 @@ CONFIG_E100=y
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
@@ -594,6 +629,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -604,6 +640,7 @@ CONFIG_TIGON3=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
CONFIG_IXGB=m
# CONFIG_IXGB_NAPI is not set
CONFIG_S2IO=m
@@ -789,7 +826,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_ISA is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -804,7 +840,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_SENSOR is not set
#
# Miscellaneous I2C Chip support
@@ -831,12 +866,17 @@ CONFIG_I2C_ALGOBIT=y
# 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
@@ -885,6 +925,7 @@ CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
@@ -982,9 +1023,11 @@ CONFIG_USB_HIDDEV=y
# 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
@@ -1057,7 +1100,8 @@ CONFIG_USB_MON=y
# InfiniBand support
#
CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_VERBS=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
CONFIG_INFINIBAND_MTHCA=m
# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
CONFIG_INFINIBAND_IPOIB=m
@@ -1095,16 +1139,12 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -1112,6 +1152,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1139,14 +1180,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1197,6 +1235,7 @@ CONFIG_CIFS_POSIX=y
# 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
@@ -1261,6 +1300,7 @@ CONFIG_OPROFILE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1320,7 +1360,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 7cb4750bb7a9..37c157c93cef 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 14:16:54 2005
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:28:33 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -37,6 +38,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -106,6 +108,7 @@ CONFIG_DISCONTIGMEM_MANUAL=y
CONFIG_DISCONTIGMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
CONFIG_NODES_SPAN_OTHER_NODES=y
# CONFIG_NUMA is not set
@@ -126,19 +129,20 @@ CONFIG_RTAS_FLASH=m
CONFIG_SCANLOG=m
CONFIG_LPARCFG=y
CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
CONFIG_ISA_DMA_API=y
#
-# General setup
+# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
# CONFIG_PCI_DEBUG is not set
-CONFIG_HOTPLUG_CPU=y
#
# PCCARD (PCMCIA/CardBus) support
@@ -154,8 +158,6 @@ CONFIG_HOTPLUG_PCI=m
# CONFIG_HOTPLUG_PCI_SHPC is not set
CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
#
# Networking
@@ -185,8 +187,8 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=y
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
@@ -197,6 +199,9 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -204,11 +209,15 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -232,14 +241,18 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -257,6 +270,7 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -266,6 +280,11 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -292,6 +311,7 @@ CONFIG_NET_CLS_ROUTE=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -306,6 +326,11 @@ CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -344,7 +369,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -422,6 +446,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -449,6 +474,7 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -462,10 +488,12 @@ CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
CONFIG_SCSI_SATA=y
# CONFIG_SCSI_SATA_AHCI is not set
CONFIG_SCSI_SATA_SVW=y
# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
# CONFIG_SCSI_SATA_NV is not set
# CONFIG_SCSI_SATA_PROMISE is not set
# CONFIG_SCSI_SATA_QSTOR is not set
@@ -535,6 +563,7 @@ CONFIG_DM_MULTIPATH_EMC=m
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -578,7 +607,6 @@ CONFIG_IEEE1394_AMDTP=m
#
CONFIG_ADB_PMU=y
CONFIG_PMAC_SMU=y
-# CONFIG_PMAC_BACKLIGHT is not set
CONFIG_THERM_PM72=y
#
@@ -596,12 +624,18 @@ CONFIG_TUN=m
# 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=y
+# CONFIG_CASSINI is not set
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=y
# CONFIG_TYPHOON is not set
@@ -630,6 +664,7 @@ CONFIG_E100=y
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
@@ -643,16 +678,19 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
# CONFIG_BNX2 is not set
+# CONFIG_SPIDER_NET is not set
# CONFIG_MV643XX_ETH is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
CONFIG_IXGB=m
# CONFIG_IXGB_NAPI is not set
# CONFIG_S2IO is not set
@@ -838,8 +876,8 @@ CONFIG_I2C_AMD8111=y
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_ISA is not set
CONFIG_I2C_KEYWEST=y
+CONFIG_I2C_PMAC_SMU=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -854,7 +892,6 @@ CONFIG_I2C_KEYWEST=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_SENSOR is not set
#
# Miscellaneous I2C Chip support
@@ -881,12 +918,17 @@ CONFIG_I2C_KEYWEST=y
# 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
@@ -939,6 +981,7 @@ CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
@@ -1020,6 +1063,7 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
#
# USB Input Devices
@@ -1036,9 +1080,11 @@ CONFIG_USB_HIDDEV=y
# 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
@@ -1111,7 +1157,8 @@ CONFIG_USB_PEGASUS=y
# InfiniBand support
#
CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_VERBS=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
CONFIG_INFINIBAND_MTHCA=m
# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
CONFIG_INFINIBAND_IPOIB=m
@@ -1149,16 +1196,12 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -1166,6 +1209,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1192,14 +1236,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1250,6 +1291,7 @@ CONFIG_CIFS_POSIX=y
# 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
@@ -1328,6 +1370,7 @@ CONFIG_OPROFILE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1387,7 +1430,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index 17e35d0fed09..1ff4fa05a973 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -68,6 +68,7 @@ int main(void)
DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
#endif /* CONFIG_ALTIVEC */
DEFINE(MM, offsetof(struct task_struct, mm));
+ DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
index c8f3dc3fad70..0aaa878e19d3 100644
--- a/arch/ppc64/kernel/bpa_iic.c
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic(int cpu)
}
#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/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c
index f33a7bccb0d7..5f2460090e03 100644
--- a/arch/ppc64/kernel/bpa_iommu.c
+++ b/arch/ppc64/kernel/bpa_iommu.c
@@ -99,7 +99,11 @@ get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_
break;
default: /* not a known compile time constant */
- BUILD_BUG_ON(1);
+ {
+ /* BUILD_BUG_ON() is not usable here */
+ extern void __get_iost_entry_bad_page_size(void);
+ __get_iost_entry_bad_page_size();
+ }
break;
}
@@ -306,7 +310,7 @@ static void bpa_map_iommu(void)
static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
void *ret;
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S
index 0482c063c26e..1fb673c511ff 100644
--- a/arch/ppc64/kernel/cpu_setup_power4.S
+++ b/arch/ppc64/kernel/cpu_setup_power4.S
@@ -12,10 +12,9 @@
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/page.h>
-#include <asm/ppc_asm.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cache.h>
_GLOBAL(__970_cpu_preinit)
diff --git a/arch/ppc64/kernel/dma.c b/arch/ppc64/kernel/dma.c
index 4da8e31b2b61..7c3419656ccc 100644
--- a/arch/ppc64/kernel/dma.c
+++ b/arch/ppc64/kernel/dma.c
@@ -53,7 +53,7 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
EXPORT_SYMBOL(dma_set_mask);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
index af5272fedadf..ba93fd731222 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/ppc64/kernel/eeh.c
@@ -202,10 +202,9 @@ static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
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/entry.S b/arch/ppc64/kernel/entry.S
index bf99b4a92f20..e8c0bbf4d000 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -28,7 +28,7 @@
#include <asm/mmu.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cputable.h>
#ifdef CONFIG_PPC_ISERIES
@@ -276,12 +276,22 @@ _GLOBAL(ppc64_rt_sigsuspend)
_GLOBAL(ppc32_rt_sigsuspend)
bl .save_nvgprs
bl .sys32_rt_sigsuspend
- /* If sigsuspend() returns zero, we are going into a signal handler */
70: cmpdi 0,r3,0
- beq .ret_from_except
- /* If it returned -EINTR, we need to return via syscall_exit to set
+ /* If it returned an error, we need to return via syscall_exit to set
the SO bit in cr0 and potentially stop for ptrace. */
- b syscall_exit
+ bne syscall_exit
+ /* If sigsuspend() returns zero, we are going into a signal handler. We
+ may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
+#ifdef CONFIG_AUDIT
+ ld r3,PACACURRENT(r13)
+ ld r4,AUDITCONTEXT(r3)
+ cmpdi 0,r4,0
+ beq .ret_from_except /* No audit_context: Leave immediately. */
+ li r4, 2 /* AUDITSC_FAILURE */
+ li r5,-4 /* It's always -EINTR */
+ bl .audit_syscall_exit
+#endif
+ b .ret_from_except
_GLOBAL(ppc_fork)
bl .save_nvgprs
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index b436206e317d..72c61041151a 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -30,7 +30,7 @@
#include <asm/mmu.h>
#include <asm/systemcfg.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/bug.h>
#include <asm/cputable.h>
#include <asm/setup.h>
@@ -1649,7 +1649,7 @@ _GLOBAL(__secondary_start)
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
- bne 98f
+ beq 98f /* branch if result is 0 */
mfspr r3,PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
@@ -1813,7 +1813,7 @@ _STATIC(start_here_multiplatform)
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
- bne 98f
+ beq 98f /* branch if result is 0 */
mfspr r3,PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
@@ -1834,7 +1834,7 @@ _STATIC(start_here_multiplatform)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
/* Test if bit 0 is set (LPAR bit) */
andi. r3,r3,PLATFORM_LPAR
- bne 98f
+ bne 98f /* branch if result is !0 */
LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
sub r6,r6,r26
ld r6,0(r6) /* get the value of _SDR1 */
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c
index d11c732daf81..5d921792571f 100644
--- a/arch/ppc64/kernel/iSeries_VpdInfo.c
+++ b/arch/ppc64/kernel/iSeries_VpdInfo.c
@@ -264,8 +264,5 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
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/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c
index 2192055a90a0..073b76661747 100644
--- a/arch/ppc64/kernel/iSeries_htab.c
+++ b/arch/ppc64/kernel/iSeries_htab.c
@@ -66,7 +66,7 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
}
if (slot < 0) { /* MSB set means secondary group */
- vflags |= HPTE_V_VALID;
+ vflags |= HPTE_V_SECONDARY;
secondary = 1;
slot &= 0x7fffffffffffffff;
}
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
index 356e4fd9a94f..fbc273c32bcc 100644
--- a/arch/ppc64/kernel/iSeries_pci.c
+++ b/arch/ppc64/kernel/iSeries_pci.c
@@ -252,7 +252,7 @@ unsigned long __init find_and_init_phbs(void)
phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
if (phb == NULL)
return -ENOMEM;
- pci_setup_pci_controller(phb);
+ pci_setup_pci_controller(phb);
phb->pci_mem_offset = phb->local_number = bus;
phb->first_busno = bus;
diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/ppc64/kernel/idle_power4.S
index 97e4a2655040..ca02afe2a795 100644
--- a/arch/ppc64/kernel/idle_power4.S
+++ b/arch/ppc64/kernel/idle_power4.S
@@ -20,7 +20,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#undef DEBUG
diff --git a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c
index 153cc8b0f136..6160c8dbb7c5 100644
--- a/arch/ppc64/kernel/iomap.c
+++ b/arch/ppc64/kernel/iomap.c
@@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __iomem *addr)
{
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 845eebd1e28d..4d9b4388918b 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;
@@ -518,7 +519,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
* to the dma address (mapping) of the first page.
*/
void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
void *ret = NULL;
dma_addr_t mapping;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 7e80d49c589a..9c6facc24f70 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -59,9 +59,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
/* insn must be on a special executable page on ppc64 */
if (!ret) {
- up(&kprobe_mutex);
- p->ainsn.insn = get_insn_slot();
down(&kprobe_mutex);
+ p->ainsn.insn = get_insn_slot();
+ up(&kprobe_mutex);
if (!p->ainsn.insn)
ret = -ENOMEM;
}
@@ -90,9 +90,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- up(&kprobe_mutex);
- free_insn_slot(p->ainsn.insn);
down(&kprobe_mutex);
+ free_insn_slot(p->ainsn.insn);
+ up(&kprobe_mutex);
}
static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
index 4775f12a013c..bf7cc4f8210f 100644
--- a/arch/ppc64/kernel/machine_kexec.c
+++ b/arch/ppc64/kernel/machine_kexec.c
@@ -205,6 +205,7 @@ static void kexec_prepare_cpus(void)
continue;
while (paca[i].hw_cpu_id != -1) {
+ barrier();
if (!cpu_possible(i)) {
printk("kexec: cpu %d hw_cpu_id %d is not"
" possible, ignoring\n",
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
index 53993999b265..1d297e0edfc0 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/ppc64/kernel/maple_pci.c
@@ -283,7 +283,7 @@ static void __init setup_u3_agp(struct pci_controller* hose)
* the reg address cell, we shall fix that by killing struct
* reg_property and using some accessor functions instead
*/
- hose->first_busno = 0xf0;
+ hose->first_busno = 0xf0;
hose->last_busno = 0xff;
hose->ops = &u3_agp_pci_ops;
hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
@@ -315,24 +315,24 @@ static int __init add_bridge(struct device_node *dev)
char* disp_name;
int *bus_range;
int primary = 1;
- struct property *of_prop;
+ struct property *of_prop;
DBG("Adding PCI host bridge %s\n", dev->full_name);
- bus_range = (int *) get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
- dev->full_name);
- }
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
+ }
hose = alloc_bootmem(sizeof(struct pci_controller));
if (hose == NULL)
return -ENOMEM;
- pci_setup_pci_controller(hose);
+ pci_setup_pci_controller(hose);
- hose->arch_data = dev;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
+ hose->arch_data = dev;
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
of_prop = alloc_bootmem(sizeof(struct property) +
sizeof(hose->global_number));
@@ -346,25 +346,25 @@ static int __init add_bridge(struct device_node *dev)
}
disp_name = NULL;
- if (device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose);
- disp_name = "U3-HT";
- primary = 1;
- }
- printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
- disp_name, hose->first_busno, hose->last_busno);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev);
+ if (device_is_compatible(dev, "u3-agp")) {
+ setup_u3_agp(hose);
+ disp_name = "U3-AGP";
+ primary = 0;
+ } else if (device_is_compatible(dev, "u3-ht")) {
+ setup_u3_ht(hose);
+ disp_name = "U3-HT";
+ primary = 1;
+ }
+ printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+ disp_name, hose->first_busno, hose->last_busno);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev);
pci_setup_phb_io(hose, primary);
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
+ /* Fixup "bus-range" OF property */
+ fixup_bus_range(dev);
return 0;
}
@@ -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 6d860c1d9fa0..e7241ad80a08 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -26,7 +26,7 @@
#include <asm/page.h>
#include <asm/cache.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cputable.h>
.text
@@ -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/module.c b/arch/ppc64/kernel/module.c
index c683bf88e690..928b8581fcb0 100644
--- a/arch/ppc64/kernel/module.c
+++ b/arch/ppc64/kernel/module.c
@@ -341,6 +341,19 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
*(unsigned long *)location = my_r2(sechdrs, me);
break;
+ case R_PPC64_TOC16:
+ /* Subtact TOC pointer */
+ value -= my_r2(sechdrs, me);
+ if (value + 0x8000 > 0xffff) {
+ printk("%s: bad TOC16 relocation (%lu)\n",
+ me->name, value);
+ return -ENOEXEC;
+ }
+ *((uint16_t *) location)
+ = (*((uint16_t *) location) & ~0xffff)
+ | (value & 0xffff);
+ break;
+
case R_PPC64_TOC16_DS:
/* Subtact TOC pointer */
value -= my_r2(sechdrs, me);
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c
index cc262a05ddb4..5f5bc73754d9 100644
--- a/arch/ppc64/kernel/mpic.c
+++ b/arch/ppc64/kernel/mpic.c
@@ -506,8 +506,8 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr,
mpic->senses_count = senses_count;
/* Map the global registers */
- mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
- mpic->tmregs = mpic->gregs + (MPIC_TIMER_BASE >> 2);
+ mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x2000);
+ mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
BUG_ON(mpic->gregs == NULL);
/* Reset */
diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c
index da580812ddfe..9f200f0f2ad5 100644
--- a/arch/ppc64/kernel/of_device.c
+++ b/arch/ppc64/kernel/of_device.c
@@ -233,7 +233,9 @@ void of_device_unregister(struct of_device *ofdev)
device_unregister(&ofdev->dev);
}
-struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id)
+struct of_device* of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
{
struct of_device *dev;
@@ -245,7 +247,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
dev->node = np;
dev->dma_mask = 0xffffffffUL;
dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.parent = NULL;
+ dev->dev.parent = parent;
dev->dev.bus = &of_platform_bus_type;
dev->dev.release = of_release_dev;
@@ -259,6 +261,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
return dev;
}
+
EXPORT_SYMBOL(of_match_device);
EXPORT_SYMBOL(of_platform_bus_type);
EXPORT_SYMBOL(of_register_driver);
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
index 9d5e1e7fc389..d17f0108a032 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/ppc64/kernel/pSeries_iommu.c
@@ -265,8 +265,10 @@ static void iommu_table_setparms(struct pci_controller *phb,
tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
/* Test if we are going over 2GB of DMA space */
- if (phb->dma_window_base_cur + phb->dma_window_size > (1L << 31))
+ if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
+ udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
+ }
phb->dma_window_base_cur += phb->dma_window_size;
@@ -295,7 +297,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) |
@@ -310,90 +312,85 @@ 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 device_node *dn;
struct iommu_table *tbl;
+ struct device_node *isa_dn, *isa_dn_orig;
+ struct device_node *tmp;
+ struct pci_dn *pci;
+ int children;
DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
- /* For each (root) bus, we carve up the available DMA space in 256MB
- * pieces. Since each piece is used by one (sub) bus/device, that would
- * give a maximum of 7 devices per PHB. In most cases, this is plenty.
- *
- * The exception is on Python PHBs (pre-POWER4). Here we don't have EADS
- * bridges below the PHB to allocate the sectioned tables to, so instead
- * we allocate a 1GB table at the PHB level.
+ dn = pci_bus_to_OF_node(bus);
+ pci = PCI_DN(dn);
+
+ if (bus->self) {
+ /* This is not a root bus, any setup will be done for the
+ * device-side of the bridge in iommu_dev_setup_pSeries().
+ */
+ return;
+ }
+
+ /* Check if the ISA bus on the system is under
+ * this PHB.
*/
+ isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
- dn = pci_bus_to_OF_node(bus);
+ while (isa_dn && isa_dn != dn)
+ isa_dn = isa_dn->parent;
- if (!bus->self) {
- /* Root bus */
- if (is_python(dn)) {
- unsigned int *iohole;
-
- DBG("Python root bus %s\n", bus->name);
-
- iohole = (unsigned int *)get_property(dn, "io-hole", 0);
-
- if (iohole) {
- /* On first bus we need to leave room for the
- * ISA address space. Just skip the first 256MB
- * 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;
- } else {
- /* 1GB window by default */
- dn->phb->dma_window_size = 1 << 30;
- dn->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);
- } else {
- /* Do a 128MB table at root. This is used for the IDE
- * controller on some SMP-mode POWER4 machines. It
- * doesn't hurt to allocate it on other machines
- * -- it'll just be unused since new tables are
- * allocated on the EADS level.
- *
- * 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;
-
- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
-
- iommu_table_setparms(dn->phb, dn, tbl);
- dn->iommu_table = iommu_init_table(tbl);
-
- /* All child buses have 256MB tables */
- dn->phb->dma_window_size = 1 << 28;
- }
- } else {
- pdn = pci_bus_to_OF_node(bus->parent);
+ if (isa_dn_orig)
+ of_node_put(isa_dn_orig);
+
+ /* Count number of direct PCI children of the PHB.
+ * All PCI device nodes have class-code property, so it's
+ * an easy way to find them.
+ */
+ for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
+ if (get_property(tmp, "class-code", NULL))
+ children++;
- if (!bus->parent->self && !is_python(pdn)) {
- struct iommu_table *tbl;
- /* First child and not python means this is the EADS
- * level. Allocate new table for this slot with 256MB
- * window.
- */
+ DBG("Children: %d\n", children);
- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+ /* Calculate amount of DMA window per slot. Each window must be
+ * a power of two (due to pci_alloc_consistent requirements).
+ *
+ * Keep 256MB aside for PHBs with ISA.
+ */
- iommu_table_setparms(dn->phb, dn, tbl);
+ if (!isa_dn) {
+ /* No ISA/IDE - just set window size and return */
+ pci->phb->dma_window_size = 0x80000000ul; /* To be divided */
- dn->iommu_table = iommu_init_table(tbl);
- } else {
- /* Lower than first child or under python, use parent table */
- dn->iommu_table = pdn->iommu_table;
- }
+ while (pci->phb->dma_window_size * children > 0x80000000ul)
+ pci->phb->dma_window_size >>= 1;
+ DBG("No ISA/IDE, window size is 0x%lx\n",
+ pci->phb->dma_window_size);
+ pci->phb->dma_window_base_cur = 0;
+
+ return;
}
+
+ /* If we have ISA, then we probably have an IDE
+ * controller too. Allocate a 128MB table but
+ * skip the first 128MB to avoid stepping on ISA
+ * space.
+ */
+ pci->phb->dma_window_size = 0x8000000ul;
+ pci->phb->dma_window_base_cur = 0x8000000ul;
+
+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+ iommu_table_setparms(pci->phb, dn, tbl);
+ pci->iommu_table = iommu_init_table(tbl);
+
+ /* Divide the rest (1.75GB) among the children */
+ pci->phb->dma_window_size = 0x80000000ul;
+ while (pci->phb->dma_window_size * children > 0x70000000ul)
+ pci->phb->dma_window_size >>= 1;
+
+ DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
+
}
@@ -401,6 +398,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,43 +417,60 @@ 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;
}
static void iommu_dev_setup_pSeries(struct pci_dev *dev)
{
struct device_node *dn, *mydn;
+ struct iommu_table *tbl;
+
+ DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
- DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);
- /* Now copy the iommu_table ptr from the bus device down to the
- * pci device_node. This means get_iommu_table() won't need to search
- * up the device tree to find it.
- */
mydn = dn = pci_device_to_OF_node(dev);
- while (dn && dn->iommu_table == NULL)
+ /* If we're the direct child of a root bus, then we need to allocate
+ * an iommu table ourselves. The bus setup code should have setup
+ * the window sizes already.
+ */
+ if (!dev->bus->self) {
+ DBG(" --> first child, no bridge. Allocating iommu table.\n");
+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+ iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
+ PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);
+
+ return;
+ }
+
+ /* If this device is further down the bus tree, search upwards until
+ * an already allocated iommu table is found and use that.
+ */
+
+ 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);
+ DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
}
}
@@ -463,10 +478,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,8 +502,9 @@ 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);
+ DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
/* dev setup for LPAR is a little tricky, since the device tree might
* contain the dma-window properties per-device and not neccesarily
@@ -497,8 +514,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;
}
@@ -507,28 +526,28 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
* slots on POWER4 machines.
*/
if (dma_window == NULL || pdn->parent == NULL) {
- /* Fall back to regular (non-LPAR) dev setup */
- DBG("No dma window for device, falling back to regular setup\n");
- iommu_dev_setup_pSeries(dev);
+ DBG("No dma window for device, linking to parent\n");
+ PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
return;
} else {
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/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
index 1f5f141fb7a1..928f8febdb3b 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/ppc64/kernel/pSeries_pci.c
@@ -32,7 +32,7 @@
#include "pci.h"
-static int __initdata s7a_workaround = -1;
+static int __devinitdata s7a_workaround = -1;
#if 0
void pcibios_name_device(struct pci_dev *dev)
@@ -60,7 +60,7 @@ void pcibios_name_device(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
#endif
-static void __init check_s7a(void)
+static void __devinit check_s7a(void)
{
struct device_node *root;
char *model;
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index 9490b6c5b173..3009701eb90d 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -238,8 +238,8 @@ static void __init pSeries_setup_arch(void)
/* Find and initialize PCI host bridges */
init_pci_config_tokens();
- eeh_init();
find_and_init_phbs();
+ eeh_init();
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -590,6 +590,13 @@ static int pseries_shared_idle(void)
return 0;
}
+static int pSeries_pci_probe_mode(struct pci_bus *bus)
+{
+ if (systemcfg->platform & PLATFORM_LPAR)
+ return PCI_PROBE_DEVTREE;
+ return PCI_PROBE_NORMAL;
+}
+
struct machdep_calls __initdata pSeries_md = {
.probe = pSeries_probe,
.setup_arch = pSeries_setup_arch,
@@ -597,6 +604,7 @@ struct machdep_calls __initdata pSeries_md = {
.get_cpuinfo = pSeries_get_cpuinfo,
.log_error = pSeries_log_error,
.pcibios_fixup = pSeries_final_fixup,
+ .pci_probe_mode = pSeries_pci_probe_mode,
.irq_bus_setup = pSeries_irq_bus_setup,
.restart = rtas_restart,
.power_off = rtas_power_off,
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index 79c7f3223665..d2c7e2c4733b 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -272,6 +272,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
unsigned long start_here = __pa((u32)*((unsigned long *)
pSeries_secondary_smp_init));
unsigned int pcpu;
+ int start_cpu;
if (cpu_isset(lcpu, of_spin_map))
/* Already started by OF and sitting in spin loop */
@@ -282,12 +283,20 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
/* Fixup atomic count: it exited inside IRQ handler. */
paca[lcpu].__current->thread_info->preempt_count = 0;
- status = rtas_call(rtas_token("start-cpu"), 3, 1, NULL,
- pcpu, start_here, lcpu);
+ /*
+ * If the RTAS start-cpu token does not exist then presume the
+ * cpu is already spinning.
+ */
+ start_cpu = rtas_token("start-cpu");
+ if (start_cpu == RTAS_UNKNOWN_SERVICE)
+ return 1;
+
+ status = rtas_call(start_cpu, 3, 1, NULL, pcpu, start_here, lcpu);
if (status != 0) {
printk(KERN_ERR "start-cpu failed: %i\n", status);
return 0;
}
+
return 1;
}
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index d0d55c7908ef..ff4be1da69d5 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>
@@ -50,6 +51,10 @@ unsigned long io_page_mask;
EXPORT_SYMBOL(io_page_mask);
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static void fixup_resource(struct resource *res, struct pci_dev *dev);
+static void do_bus_setup(struct pci_bus *bus);
+#endif
unsigned int pcibios_assign_all_busses(void)
{
@@ -84,7 +89,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);
@@ -225,10 +229,290 @@ static void __init pcibios_claim_of_setup(void)
}
#endif
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
+{
+ u32 *prop;
+ int len;
+
+ prop = (u32 *) get_property(np, name, &len);
+ if (prop && len >= 4)
+ return *prop;
+ return def;
+}
+
+static unsigned int pci_parse_of_flags(u32 addr0)
+{
+ unsigned int flags = 0;
+
+ if (addr0 & 0x02000000) {
+ flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
+ flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
+ flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+ if (addr0 & 0x40000000)
+ flags |= IORESOURCE_PREFETCH
+ | PCI_BASE_ADDRESS_MEM_PREFETCH;
+ } else if (addr0 & 0x01000000)
+ flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+ return flags;
+}
+
+#define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1])
+
+static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
+{
+ u64 base, size;
+ unsigned int flags;
+ struct resource *res;
+ u32 *addrs, i;
+ int proplen;
+
+ addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
+ if (!addrs)
+ return;
+ for (; proplen >= 20; proplen -= 20, addrs += 5) {
+ flags = pci_parse_of_flags(addrs[0]);
+ if (!flags)
+ continue;
+ base = GET_64BIT(addrs, 1);
+ size = GET_64BIT(addrs, 3);
+ if (!size)
+ continue;
+ i = addrs[0] & 0xff;
+ if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
+ res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
+ } else if (i == dev->rom_base_reg) {
+ res = &dev->resource[PCI_ROM_RESOURCE];
+ flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+ } else {
+ printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
+ continue;
+ }
+ res->start = base;
+ res->end = base + size - 1;
+ res->flags = flags;
+ res->name = pci_name(dev);
+ fixup_resource(res, dev);
+ }
+}
+
+static struct pci_dev *of_create_pci_dev(struct device_node *node,
+ struct pci_bus *bus, int devfn)
+{
+ struct pci_dev *dev;
+ const char *type;
+
+ dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+ type = get_property(node, "device_type", NULL);
+ if (type == NULL)
+ type = "";
+
+ memset(dev, 0, sizeof(struct pci_dev));
+ dev->bus = bus;
+ dev->sysdata = node;
+ dev->dev.parent = bus->bridge;
+ dev->dev.bus = &pci_bus_type;
+ dev->devfn = devfn;
+ dev->multifunction = 0; /* maybe a lie? */
+
+ dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
+ dev->device = get_int_prop(node, "device-id", 0xffff);
+ dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
+ dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
+
+ dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/
+
+ sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+ dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ dev->class = get_int_prop(node, "class-code", 0);
+
+ dev->current_state = 4; /* unknown power state */
+
+ if (!strcmp(type, "pci")) {
+ /* a PCI-PCI bridge */
+ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+ dev->rom_base_reg = PCI_ROM_ADDRESS1;
+ } else if (!strcmp(type, "cardbus")) {
+ dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+ } else {
+ dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+ dev->rom_base_reg = PCI_ROM_ADDRESS;
+ dev->irq = NO_IRQ;
+ if (node->n_intrs > 0) {
+ dev->irq = node->intrs[0].line;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+ dev->irq);
+ }
+ }
+
+ pci_parse_of_addrs(node, dev);
+
+ pci_device_add(dev, bus);
+
+ /* XXX pci_scan_msi_device(dev); */
+
+ return dev;
+}
+
+static void of_scan_pci_bridge(struct device_node *node, struct pci_dev *dev);
+
+static void __devinit of_scan_bus(struct device_node *node,
+ struct pci_bus *bus)
+{
+ struct device_node *child = NULL;
+ u32 *reg;
+ int reglen, devfn;
+ struct pci_dev *dev;
+
+ while ((child = of_get_next_child(node, child)) != NULL) {
+ reg = (u32 *) get_property(child, "reg", &reglen);
+ if (reg == NULL || reglen < 20)
+ continue;
+ devfn = (reg[0] >> 8) & 0xff;
+ /* create a new pci_dev for this device */
+ dev = of_create_pci_dev(child, bus, devfn);
+ if (!dev)
+ continue;
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ of_scan_pci_bridge(child, dev);
+ }
+
+ do_bus_setup(bus);
+}
+
+static void __devinit of_scan_pci_bridge(struct device_node *node,
+ struct pci_dev *dev)
+{
+ struct pci_bus *bus;
+ u32 *busrange, *ranges;
+ int len, i, mode;
+ struct resource *res;
+ unsigned int flags;
+ u64 size;
+
+ /* parse bus-range property */
+ busrange = (u32 *) get_property(node, "bus-range", &len);
+ if (busrange == NULL || len != 8) {
+ printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n",
+ node->full_name);
+ return;
+ }
+ ranges = (u32 *) get_property(node, "ranges", &len);
+ if (ranges == NULL) {
+ printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n",
+ node->full_name);
+ return;
+ }
+
+ bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+ if (!bus) {
+ printk(KERN_ERR "Failed to create pci bus for %s\n",
+ node->full_name);
+ return;
+ }
+
+ bus->primary = dev->bus->number;
+ bus->subordinate = busrange[1];
+ bus->bridge_ctl = 0;
+ bus->sysdata = node;
+
+ /* parse ranges property */
+ /* PCI #address-cells == 3 and #size-cells == 2 always */
+ res = &dev->resource[PCI_BRIDGE_RESOURCES];
+ for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
+ res->flags = 0;
+ bus->resource[i] = res;
+ ++res;
+ }
+ i = 1;
+ for (; len >= 32; len -= 32, ranges += 8) {
+ flags = pci_parse_of_flags(ranges[0]);
+ size = GET_64BIT(ranges, 6);
+ if (flags == 0 || size == 0)
+ continue;
+ if (flags & IORESOURCE_IO) {
+ res = bus->resource[0];
+ if (res->flags) {
+ printk(KERN_ERR "PCI: ignoring extra I/O range"
+ " for bridge %s\n", node->full_name);
+ continue;
+ }
+ } else {
+ if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
+ printk(KERN_ERR "PCI: too many memory ranges"
+ " for bridge %s\n", node->full_name);
+ continue;
+ }
+ res = bus->resource[i];
+ ++i;
+ }
+ res->start = GET_64BIT(ranges, 1);
+ res->end = res->start + size - 1;
+ res->flags = flags;
+ fixup_resource(res, dev);
+ }
+ sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
+ bus->number);
+
+ mode = PCI_PROBE_NORMAL;
+ if (ppc_md.pci_probe_mode)
+ mode = ppc_md.pci_probe_mode(bus);
+ if (mode == PCI_PROBE_DEVTREE)
+ of_scan_bus(node, bus);
+ else if (mode == PCI_PROBE_NORMAL)
+ pci_scan_child_bus(bus);
+}
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+static void __devinit scan_phb(struct pci_controller *hose)
+{
+ struct pci_bus *bus;
+ struct device_node *node = hose->arch_data;
+ int i, mode;
+ struct resource *res;
+
+ bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
+ if (bus == NULL) {
+ printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+ hose->global_number);
+ return;
+ }
+ bus->secondary = hose->first_busno;
+ hose->bus = bus;
+
+ bus->resource[0] = res = &hose->io_resource;
+ if (res->flags && request_resource(&ioport_resource, res))
+ printk(KERN_ERR "Failed to request PCI IO region "
+ "on PCI domain %04x\n", hose->global_number);
+
+ for (i = 0; i < 3; ++i) {
+ res = &hose->mem_resources[i];
+ bus->resource[i+1] = res;
+ if (res->flags && request_resource(&iomem_resource, res))
+ printk(KERN_ERR "Failed to request PCI memory region "
+ "on PCI domain %04x\n", hose->global_number);
+ }
+
+ mode = PCI_PROBE_NORMAL;
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ if (ppc_md.pci_probe_mode)
+ mode = ppc_md.pci_probe_mode(bus);
+ if (mode == PCI_PROBE_DEVTREE) {
+ bus->subordinate = hose->last_busno;
+ of_scan_bus(node, bus);
+ }
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+ if (mode == PCI_PROBE_NORMAL)
+ hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+ pci_bus_add_devices(bus);
+}
+
static int __init pcibios_init(void)
{
struct pci_controller *hose, *tmp;
- struct pci_bus *bus;
/* For now, override phys_mem_access_prot. If we need it,
* later, we may move that initialization to each ppc_md
@@ -242,13 +526,8 @@ static int __init pcibios_init(void)
printk("PCI: Probing PCI hardware\n");
/* Scan all of the recorded PCI controllers. */
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- hose->last_busno = 0xff;
- bus = pci_scan_bus(hose->first_busno, hose->ops,
- hose->arch_data);
- hose->bus = bus;
- hose->last_busno = bus->subordinate;
- }
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+ scan_phb(hose);
#ifndef CONFIG_PPC_ISERIES
if (pci_probe_only)
@@ -820,118 +1099,89 @@ void phbs_remap_io(void)
/*
* ppc64 can have multifunction devices that do not respond to function 0.
* In this case we must scan all functions.
+ * XXX this can go now, we use the OF device tree in all the
+ * cases that caused problems. -- paulus
*/
int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
{
- struct device_node *busdn, *dn;
+ return 0;
+}
+
+static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
+{
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ unsigned long start, end, mask, offset;
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = bus->sysdata; /* must be a phb */
+ if (res->flags & IORESOURCE_IO) {
+ offset = (unsigned long)hose->io_base_virt - pci_io_base;
- if (busdn == NULL)
- return 0;
+ start = res->start += offset;
+ end = res->end += offset;
- /*
- * Check to see if there is any of the 8 functions are in the
- * 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))
- return 1;
+ /* Need to allow IO access to pages that are in the
+ ISA range */
+ if (start < MAX_ISA_PORT) {
+ if (end > MAX_ISA_PORT)
+ end = MAX_ISA_PORT;
- return 0;
-}
+ start >>= PAGE_SHIFT;
+ end >>= PAGE_SHIFT;
+ /* get the range of pages for the map */
+ mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1);
+ io_page_mask |= mask;
+ }
+ } else if (res->flags & IORESOURCE_MEM) {
+ res->start += hose->pci_mem_offset;
+ res->end += hose->pci_mem_offset;
+ }
+}
void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
- struct pci_bus *bus)
+ struct pci_bus *bus)
{
/* Update device resources. */
- struct pci_controller *hose = pci_bus_to_host(bus);
int i;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- if (dev->resource[i].flags & IORESOURCE_IO) {
- unsigned long offset = (unsigned long)hose->io_base_virt
- - pci_io_base;
- unsigned long start, end, mask;
-
- start = dev->resource[i].start += offset;
- end = dev->resource[i].end += offset;
-
- /* Need to allow IO access to pages that are in the
- ISA range */
- if (start < MAX_ISA_PORT) {
- if (end > MAX_ISA_PORT)
- end = MAX_ISA_PORT;
-
- start >>= PAGE_SHIFT;
- end >>= PAGE_SHIFT;
-
- /* get the range of pages for the map */
- mask = ((1 << (end+1))-1) ^ ((1 << start)-1);
- io_page_mask |= mask;
- }
- }
- else if (dev->resource[i].flags & IORESOURCE_MEM) {
- dev->resource[i].start += hose->pci_mem_offset;
- dev->resource[i].end += hose->pci_mem_offset;
- }
- }
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ if (dev->resource[i].flags)
+ fixup_resource(&dev->resource[i], dev);
}
EXPORT_SYMBOL(pcibios_fixup_device_resources);
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+static void __devinit do_bus_setup(struct pci_bus *bus)
{
- struct pci_controller *hose = pci_bus_to_host(bus);
- struct pci_dev *dev = bus->self;
- struct resource *res;
- int i;
+ struct pci_dev *dev;
- if (!dev) {
- /* Root bus. */
+ ppc_md.iommu_bus_setup(bus);
- hose->bus = bus;
- bus->resource[0] = res = &hose->io_resource;
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ ppc_md.iommu_dev_setup(dev);
- if (res->flags && request_resource(&ioport_resource, res))
- printk(KERN_ERR "Failed to request IO on "
- "PCI domain %d\n", pci_domain_nr(bus));
+ if (ppc_md.irq_bus_setup)
+ ppc_md.irq_bus_setup(bus);
+}
- for (i = 0; i < 3; ++i) {
- res = &hose->mem_resources[i];
- bus->resource[i+1] = res;
- if (res->flags && request_resource(&iomem_resource, res))
- printk(KERN_ERR "Failed to request MEM on "
- "PCI domain %d\n",
- pci_domain_nr(bus));
- }
- } else if (pci_probe_only &&
- (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_dev *dev = bus->self;
+
+ if (dev && pci_probe_only &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
/* This is a subordinate bridge */
pci_read_bridge_bases(bus);
pcibios_fixup_device_resources(dev, bus);
}
- ppc_md.iommu_bus_setup(bus);
-
- list_for_each_entry(dev, &bus->devices, bus_list)
- ppc_md.iommu_dev_setup(dev);
-
- if (ppc_md.irq_bus_setup)
- ppc_md.irq_bus_setup(bus);
+ do_bus_setup(bus);
if (!pci_probe_only)
return;
- list_for_each_entry(dev, &bus->devices, bus_list) {
+ list_for_each_entry(dev, &bus->devices, bus_list)
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
pcibios_fixup_device_resources(dev, bus);
- }
}
EXPORT_SYMBOL(pcibios_fixup_bus);
@@ -983,3 +1233,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 26be78b13af1..5eb2cc320566 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -34,7 +34,6 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
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_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c
index b8f7f58824f4..54055c81017a 100644
--- a/arch/ppc64/kernel/pci_direct_iommu.c
+++ b/arch/ppc64/kernel/pci_direct_iommu.c
@@ -31,7 +31,7 @@
#include "pci.h"
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
void *ret;
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index ec345462afc3..a86389d07d57 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -23,6 +23,8 @@
#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 ef0a62b916be..d9e33b7d4203 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 */
}
@@ -76,7 +76,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
* to the dma address (mapping) of the first page.
*/
static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle,
flag);
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
index 98ed2bccab1a..eb4e6c3f694d 100644
--- a/arch/ppc64/kernel/pmac_feature.c
+++ b/arch/ppc64/kernel/pmac_feature.c
@@ -674,6 +674,7 @@ void __init pmac_check_ht_link(void)
#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 71fe911ad183..dc40a0cad0b4 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;
@@ -388,7 +388,7 @@ static void __init setup_u3_agp(struct pci_controller* hose)
* the reg address cell, we shall fix that by killing struct
* reg_property and using some accessor functions instead
*/
- hose->first_busno = 0xf0;
+ hose->first_busno = 0xf0;
hose->last_busno = 0xff;
has_uninorth = 1;
hose->ops = &macrisc_pci_ops;
@@ -473,7 +473,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
continue;
}
cur++;
- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
+ DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
cur-1, res->start - 1, cur, res->end + 1);
hose->mem_resources[cur].name = np->full_name;
hose->mem_resources[cur].flags = IORESOURCE_MEM;
@@ -603,24 +603,24 @@ static int __init add_bridge(struct device_node *dev)
char* disp_name;
int *bus_range;
int primary = 1;
- struct property *of_prop;
+ struct property *of_prop;
DBG("Adding PCI host bridge %s\n", dev->full_name);
- bus_range = (int *) get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
- dev->full_name);
- }
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
+ }
hose = alloc_bootmem(sizeof(struct pci_controller));
if (hose == NULL)
return -ENOMEM;
- pci_setup_pci_controller(hose);
+ pci_setup_pci_controller(hose);
- hose->arch_data = dev;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
+ hose->arch_data = dev;
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
of_prop = alloc_bootmem(sizeof(struct property) +
sizeof(hose->global_number));
@@ -634,24 +634,24 @@ static int __init add_bridge(struct device_node *dev)
}
disp_name = NULL;
- if (device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose);
- disp_name = "U3-HT";
- primary = 1;
- }
- printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
- disp_name, hose->first_busno, hose->last_busno);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pmac_process_bridge_OF_ranges(hose, dev, primary);
-
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
+ if (device_is_compatible(dev, "u3-agp")) {
+ setup_u3_agp(hose);
+ disp_name = "U3-AGP";
+ primary = 0;
+ } else if (device_is_compatible(dev, "u3-ht")) {
+ setup_u3_ht(hose);
+ disp_name = "U3-HT";
+ primary = 1;
+ }
+ printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+ disp_name, hose->first_busno, hose->last_busno);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pmac_process_bridge_OF_ranges(hose, dev, primary);
+
+ /* Fixup "bus-range" OF property */
+ fixup_bus_range(dev);
return 0;
}
@@ -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/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
index e7f695dcd8c8..fa8121d53b89 100644
--- a/arch/ppc64/kernel/pmac_setup.c
+++ b/arch/ppc64/kernel/pmac_setup.c
@@ -115,7 +115,7 @@ static void __pmac pmac_show_cpuinfo(struct seq_file *m)
/* find motherboard type */
seq_printf(m, "machine\t\t: ");
- np = find_devices("device-tree");
+ np = of_find_node_by_path("/");
if (np != NULL) {
pp = (char *) get_property(np, "model", NULL);
if (pp != NULL)
@@ -133,6 +133,7 @@ static void __pmac pmac_show_cpuinfo(struct seq_file *m)
}
seq_printf(m, "\n");
}
+ of_node_put(np);
} else
seq_printf(m, "PowerMac\n");
@@ -434,15 +435,23 @@ static int pmac_check_legacy_ioport(unsigned int baseport)
static int __init pmac_declare_of_platform_devices(void)
{
- struct device_node *np;
+ struct device_node *np, *npp;
- np = find_devices("u3");
- if (np) {
- for (np = np->child; np != NULL; np = np->sibling)
+ npp = of_find_node_by_name(NULL, "u3");
+ if (npp) {
+ for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "u3-i2c");
+ of_platform_device_create(np, "u3-i2c", NULL);
+ of_node_put(np);
break;
}
+ }
+ of_node_put(npp);
+ }
+ npp = of_find_node_by_type(NULL, "smu");
+ if (npp) {
+ of_platform_device_create(npp, "smu", NULL);
+ of_node_put(npp);
}
return 0;
@@ -477,6 +486,18 @@ static int __init pmac_probe(int platform)
return 1;
}
+static int pmac_probe_mode(struct pci_bus *bus)
+{
+ struct device_node *node = bus->sysdata;
+
+ /* We need to use normal PCI probing for the AGP bus,
+ since the device for the AGP bridge isn't in the tree. */
+ if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
+ return PCI_PROBE_NORMAL;
+
+ return PCI_PROBE_DEVTREE;
+}
+
struct machdep_calls __initdata pmac_md = {
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = generic_mach_cpu_die,
@@ -488,6 +509,7 @@ struct machdep_calls __initdata pmac_md = {
.init_IRQ = pmac_init_IRQ,
.get_irq = mpic_get_irq,
.pcibios_fixup = pmac_pcibios_fixup,
+ .pci_probe_mode = pmac_probe_mode,
.restart = pmac_restart,
.power_off = pmac_power_off,
.halt = pmac_halt,
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
index 3059edb09cc8..41bbb8c59697 100644
--- a/arch/ppc64/kernel/pmac_time.c
+++ b/arch/ppc64/kernel/pmac_time.c
@@ -84,7 +84,7 @@ void __pmac pmac_get_rtc_time(struct rtc_time *tm)
#ifdef CONFIG_PMAC_SMU
case SYS_CTRLER_SMU:
- smu_get_rtc_time(tm);
+ smu_get_rtc_time(tm, 1);
break;
#endif /* CONFIG_PMAC_SMU */
default:
@@ -128,7 +128,7 @@ int __pmac pmac_set_rtc_time(struct rtc_time *tm)
#ifdef CONFIG_PMAC_SMU
case SYS_CTRLER_SMU:
- return smu_set_rtc_time(tm);
+ return smu_set_rtc_time(tm, 1);
#endif /* CONFIG_PMAC_SMU */
default:
return -ENODEV;
diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c
index cdfec7438d01..63d9481c3ec2 100644
--- a/arch/ppc64/kernel/pmc.c
+++ b/arch/ppc64/kernel/pmc.c
@@ -26,7 +26,7 @@ static void dummy_perf(struct pt_regs *regs)
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/process.c b/arch/ppc64/kernel/process.c
index 7a7e027653ad..887005358eb1 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -54,6 +54,7 @@
#include <asm/sections.h>
#include <asm/tlbflush.h>
#include <asm/time.h>
+#include <asm/plpar_wrappers.h>
#ifndef CONFIG_SMP
struct task_struct *last_task_used_math = NULL;
@@ -163,7 +164,30 @@ int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
#endif /* CONFIG_ALTIVEC */
+static void set_dabr_spr(unsigned long val)
+{
+ mtspr(SPRN_DABR, val);
+}
+
+int set_dabr(unsigned long dabr)
+{
+ int ret = 0;
+
+ if (firmware_has_feature(FW_FEATURE_XDABR)) {
+ /* We want to catch accesses from kernel and userspace */
+ unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
+ ret = plpar_set_xdabr(dabr, flags);
+ } else if (firmware_has_feature(FW_FEATURE_DABR)) {
+ ret = plpar_set_dabr(dabr);
+ } else {
+ set_dabr_spr(dabr);
+ }
+
+ return ret;
+}
+
DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
+static DEFINE_PER_CPU(unsigned long, current_dabr);
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *new)
@@ -198,6 +222,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
new->thread.regs->msr |= MSR_VEC;
#endif /* CONFIG_ALTIVEC */
+ if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
+ set_dabr(new->thread.dabr);
+ __get_cpu_var(current_dabr) = new->thread.dabr;
+ }
+
flush_tlb_pending();
new_thread = &new->thread;
@@ -334,6 +363,11 @@ void flush_thread(void)
last_task_used_altivec = NULL;
#endif /* CONFIG_ALTIVEC */
#endif /* CONFIG_SMP */
+
+ if (current->thread.dabr) {
+ current->thread.dabr = 0;
+ set_dabr(0);
+ }
}
void
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 6ad5a8467f87..7035deb6de92 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -1733,6 +1733,7 @@ static void of_node_release(struct kref *kref)
kfree(node->intrs);
kfree(node->addrs);
kfree(node->full_name);
+ kfree(node->data);
kfree(node);
}
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 9979919cdf92..f252670874a4 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -1711,6 +1711,7 @@ static void __init flatten_device_tree(void)
unsigned long offset = reloc_offset();
unsigned long mem_start, mem_end, room;
struct boot_param_header *hdr;
+ struct prom_t *_prom = PTRRELOC(&prom);
char *namep;
u64 *rsvmap;
@@ -1765,6 +1766,7 @@ static void __init flatten_device_tree(void)
RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
/* Finish header */
+ hdr->boot_cpuid_phys = _prom->cpu;
hdr->magic = OF_DT_HEADER;
hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
@@ -1854,7 +1856,6 @@ static void __init prom_find_boot_cpu(void)
cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
- prom_setprop(cpu_pkg, "linux,boot-cpu", NULL, 0);
prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
_prom->cpu = getprop_rval;
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 2993f108d96d..b1c044ca5756 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -17,6 +17,7 @@
* this archive for more details.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -206,6 +207,20 @@ int sys_ptrace(long request, long pid, long addr, long data)
break;
}
+ case PTRACE_GET_DEBUGREG: {
+ ret = -EINVAL;
+ /* We only support one DABR and no IABRS at the moment */
+ if (addr > 0)
+ break;
+ ret = put_user(child->thread.dabr,
+ (unsigned long __user *)data);
+ break;
+ }
+
+ case PTRACE_SET_DEBUGREG:
+ ret = ptrace_set_debugreg(child, addr, data);
+ break;
+
case PTRACE_DETACH:
ret = ptrace_detach(child, data);
break;
@@ -274,6 +289,20 @@ int sys_ptrace(long request, long pid, long addr, long data)
break;
}
+#ifdef CONFIG_ALTIVEC
+ case PTRACE_GETVRREGS:
+ /* Get the child altivec register state. */
+ flush_altivec_to_thread(child);
+ ret = get_vrregs((unsigned long __user *)data, child);
+ break;
+
+ case PTRACE_SETVRREGS:
+ /* Set the child altivec register state. */
+ flush_altivec_to_thread(child);
+ ret = set_vrregs(child, (unsigned long __user *)data);
+ break;
+#endif
+
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
index 16436426c7e2..fb8c22d6084a 100644
--- a/arch/ppc64/kernel/ptrace32.c
+++ b/arch/ppc64/kernel/ptrace32.c
@@ -17,6 +17,7 @@
* this archive for more details.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -337,6 +338,19 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
break;
}
+ case PTRACE_GET_DEBUGREG: {
+ ret = -EINVAL;
+ /* We only support one DABR and no IABRS at the moment */
+ if (addr > 0)
+ break;
+ ret = put_user(child->thread.dabr, (u32 __user *)data);
+ break;
+ }
+
+ case PTRACE_SET_DEBUGREG:
+ ret = ptrace_set_debugreg(child, addr, data);
+ break;
+
case PTRACE_DETACH:
ret = ptrace_detach(child, data);
break;
@@ -405,9 +419,23 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
break;
}
- case PTRACE_GETEVENTMSG:
- ret = put_user(child->ptrace_message, (unsigned int __user *) data);
- break;
+ case PTRACE_GETEVENTMSG:
+ ret = put_user(child->ptrace_message, (unsigned int __user *) data);
+ break;
+
+#ifdef CONFIG_ALTIVEC
+ case PTRACE_GETVRREGS:
+ /* Get the child altivec register state. */
+ flush_altivec_to_thread(child);
+ ret = get_vrregs((unsigned long __user *)data, child);
+ break;
+
+ case PTRACE_SETVRREGS:
+ /* Set the child altivec register state. */
+ flush_altivec_to_thread(child);
+ ret = set_vrregs(child, (unsigned long __user *)data);
+ break;
+#endif
default:
ret = ptrace_request(child, request, addr, data);
diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
index 3c00f7bfc1b5..41b97dc9cc0a 100644
--- a/arch/ppc64/kernel/ras.c
+++ b/arch/ppc64/kernel/ras.c
@@ -59,8 +59,6 @@ char mce_data_buf[RTAS_ERROR_LOG_MAX]
/* This is true if we are using the firmware NMI handler (typically LPAR) */
extern int fwnmi_active;
-extern void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
-
static int ras_get_sensor_state_token;
static int ras_check_exception_token;
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
index 1dccadaddd1d..4a9719b48abe 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -48,7 +48,7 @@ static int write_pci_config;
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 d0bb68af0ea4..5ac48bd64891 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -1064,8 +1064,6 @@ void __init setup_arch(char **cmdline_p)
#define PPC64_LINUX_FUNCTION 0x0f000000
#define PPC64_IPL_MESSAGE 0xc0000000
#define PPC64_TERM_MESSAGE 0xb0000000
-#define PPC64_ATTN_MESSAGE 0xa0000000
-#define PPC64_DUMP_MESSAGE 0xd0000000
static void ppc64_do_msg(unsigned int src, const char *msg)
{
@@ -1093,20 +1091,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
printk("[terminate]%04x %s\n", src, msg);
}
-/* Print something that needs attention (device error, etc) */
-void ppc64_attention_msg(unsigned int src, const char *msg)
-{
- ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg);
- printk("[attention]%04x %s\n", src, msg);
-}
-
-/* Print a dump progress message. */
-void ppc64_dump_msg(unsigned int src, const char *msg)
-{
- ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg);
- printk("[dump]%04x %s\n", src, msg);
-}
-
/* This should only be called on processor 0 during calibrate decr */
void __init setup_default_decr(void)
{
@@ -1283,7 +1267,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/signal.c b/arch/ppc64/kernel/signal.c
index 49a79a55c32d..347112cca3c0 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -550,6 +550,15 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* Whee! Actually deliver the signal. */
if (TRAP(regs) == 0x0C00)
syscall_restart(regs, &ka);
+
+ /*
+ * Reenable the DABR before delivering the signal to
+ * user space. The DABR will have been cleared if it
+ * triggered inside the kernel.
+ */
+ if (current->thread.dabr)
+ set_dabr(current->thread.dabr);
+
return handle_signal(signr, &ka, &info, oldset, regs);
}
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
index 46f4d6cc7fc9..a8b7a5a56bb4 100644
--- a/arch/ppc64/kernel/signal32.c
+++ b/arch/ppc64/kernel/signal32.c
@@ -970,6 +970,14 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
newsp = regs->gpr[1];
newsp &= ~0xfUL;
+ /*
+ * Reenable the DABR before delivering the signal to
+ * user space. The DABR will have been cleared if it
+ * triggered inside the kernel.
+ */
+ if (current->thread.dabr)
+ set_dabr(current->thread.dabr);
+
/* Whee! Actually deliver the signal. */
if (ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 214914a95a50..e93c13458910 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -708,62 +708,9 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu
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 a8cbb202b8cd..05f16633bd2c 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/time.c b/arch/ppc64/kernel/time.c
index 9939c206afa4..b56c6a324e17 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -870,7 +870,7 @@ void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
rb = ((ra + b) - (x * divisor)) << 32;
y = (rb + c)/divisor;
- rc = ((rb + b) - (y * divisor)) << 32;
+ rc = ((rb + c) - (y * divisor)) << 32;
z = (rc + d)/divisor;
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
index b6e3bca4102d..41ea09cb9ac7 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/ppc64/kernel/u3_iommu.c
@@ -276,7 +276,7 @@ static void iommu_dev_setup_u3(struct pci_dev *dev)
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 ed6766e21f5a..d49c3613c8ec 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/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
index 4777676365fe..efa985f05aca 100644
--- a/arch/ppc64/kernel/vdso.c
+++ b/arch/ppc64/kernel/vdso.c
@@ -224,10 +224,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (vma == NULL)
return -ENOMEM;
- if (security_vm_enough_memory(vdso_pages)) {
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
+
memset(vma, 0, sizeof(*vma));
/*
@@ -237,8 +234,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
*/
vdso_base = get_unmapped_area(NULL, vdso_base,
vdso_pages << PAGE_SHIFT, 0, 0);
- if (vdso_base & ~PAGE_MASK)
+ if (vdso_base & ~PAGE_MASK) {
+ kmem_cache_free(vm_area_cachep, vma);
return (int)vdso_base;
+ }
current->thread.vdso_base = vdso_base;
@@ -266,7 +265,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
vma->vm_ops = &vdso_vmops;
down_write(&mm->mmap_sem);
- insert_vm_struct(mm, vma);
+ if (insert_vm_struct(mm, vma)) {
+ up_write(&mm->mmap_sem);
+ kmem_cache_free(vm_area_cachep, vma);
+ return -ENOMEM;
+ }
mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
up_write(&mm->mmap_sem);
diff --git a/arch/ppc64/kernel/vdso32/cacheflush.S b/arch/ppc64/kernel/vdso32/cacheflush.S
index 0ed7ea721715..c8db993574ee 100644
--- a/arch/ppc64/kernel/vdso32/cacheflush.S
+++ b/arch/ppc64/kernel/vdso32/cacheflush.S
@@ -13,7 +13,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/vdso.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.text
diff --git a/arch/ppc64/kernel/vdso32/datapage.S b/arch/ppc64/kernel/vdso32/datapage.S
index 29b6bd32e1f1..4f4eb0be3992 100644
--- a/arch/ppc64/kernel/vdso32/datapage.S
+++ b/arch/ppc64/kernel/vdso32/datapage.S
@@ -12,7 +12,7 @@
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/vdso.h>
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S
index 2b48bf1fb109..e243c1d24af7 100644
--- a/arch/ppc64/kernel/vdso32/gettimeofday.S
+++ b/arch/ppc64/kernel/vdso32/gettimeofday.S
@@ -13,7 +13,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/vdso.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
.text
@@ -109,7 +109,7 @@ __do_get_xsec:
lwz r6,(CFG_TB_TO_XS+4)(r9)
mulhwu r4,r7,r5
mulhwu r6,r7,r6
- mullw r6,r7,r5
+ mullw r0,r7,r5
addc r6,r6,r0
/* At this point, we have the scaled xsec value in r4 + XER:CA
diff --git a/arch/ppc64/kernel/vdso64/cacheflush.S b/arch/ppc64/kernel/vdso64/cacheflush.S
index e0725b7b7003..d4a0ad28d534 100644
--- a/arch/ppc64/kernel/vdso64/cacheflush.S
+++ b/arch/ppc64/kernel/vdso64/cacheflush.S
@@ -13,7 +13,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/vdso.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.text
diff --git a/arch/ppc64/kernel/vdso64/datapage.S b/arch/ppc64/kernel/vdso64/datapage.S
index 18afd971c9d9..ed6e599ae824 100644
--- a/arch/ppc64/kernel/vdso64/datapage.S
+++ b/arch/ppc64/kernel/vdso64/datapage.S
@@ -12,7 +12,7 @@
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/vdso.h>
diff --git a/arch/ppc64/kernel/vdso64/gettimeofday.S b/arch/ppc64/kernel/vdso64/gettimeofday.S
index ed3f970ff05e..f6df8028570a 100644
--- a/arch/ppc64/kernel/vdso64/gettimeofday.S
+++ b/arch/ppc64/kernel/vdso64/gettimeofday.S
@@ -14,7 +14,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/vdso.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.text
/*
diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c
index c90e1dd875ce..0e555b7a6587 100644
--- a/arch/ppc64/kernel/vio.c
+++ b/arch/ppc64/kernel/vio.c
@@ -218,7 +218,7 @@ static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
}
static void *vio_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
dma_handle, flag);
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index d9dc6f28d050..daf93885dcfa 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -38,7 +38,7 @@ static void xics_mask_and_ack_irq(unsigned int irq);
static void xics_end_irq(unsigned int irq);
static void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask);
-struct hw_interrupt_type xics_pic = {
+static struct hw_interrupt_type xics_pic = {
.typename = " XICS ",
.startup = xics_startup,
.enable = xics_enable_irq,
@@ -48,7 +48,7 @@ struct hw_interrupt_type xics_pic = {
.set_affinity = xics_set_affinity
};
-struct hw_interrupt_type xics_8259_pic = {
+static struct hw_interrupt_type xics_8259_pic = {
.typename = " XICS/8259",
.ack = xics_mask_and_ack_irq,
};
@@ -89,9 +89,8 @@ static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
static int xics_irq_8259_cascade = 0;
static int xics_irq_8259_cascade_real = 0;
static unsigned int default_server = 0xFF;
-/* also referenced in smp.c... */
-unsigned int default_distrib_server = 0;
-unsigned int interrupt_server_size = 8;
+static unsigned int default_distrib_server = 0;
+static unsigned int interrupt_server_size = 8;
/*
* XICS only has a single IPI, so encode the messages per CPU
@@ -99,10 +98,10 @@ unsigned int interrupt_server_size = 8;
struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
/* RTAS service tokens */
-int ibm_get_xive;
-int ibm_set_xive;
-int ibm_int_on;
-int ibm_int_off;
+static int ibm_get_xive;
+static int ibm_set_xive;
+static int ibm_int_on;
+static int ibm_int_off;
typedef struct {
int (*xirr_info_get)(int cpu);
@@ -284,16 +283,17 @@ static void xics_enable_irq(unsigned int virq)
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
DEFAULT_PRIORITY);
if (call_status != 0) {
- printk(KERN_ERR "xics_enable_irq: irq=%d: ibm_set_xive "
- "returned %x\n", irq, call_status);
+ printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive "
+ "returned %d\n", irq, call_status);
+ printk("set_xive %x, server %x\n", ibm_set_xive, server);
return;
}
/* Now unmask the interrupt (often a no-op) */
call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
if (call_status != 0) {
- printk(KERN_ERR "xics_enable_irq: irq=%d: ibm_int_on "
- "returned %x\n", irq, call_status);
+ printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on "
+ "returned %d\n", irq, call_status);
return;
}
}
@@ -308,8 +308,8 @@ static void xics_disable_real_irq(unsigned int irq)
call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
if (call_status != 0) {
- printk(KERN_ERR "xics_disable_real_irq: irq=%d: "
- "ibm_int_off returned %x\n", irq, call_status);
+ printk(KERN_ERR "xics_disable_real_irq: irq=%u: "
+ "ibm_int_off returned %d\n", irq, call_status);
return;
}
@@ -317,8 +317,8 @@ static void xics_disable_real_irq(unsigned int irq)
/* Have to set XIVE to 0xff to be able to remove a slot */
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff);
if (call_status != 0) {
- printk(KERN_ERR "xics_disable_irq: irq=%d: ibm_set_xive(0xff)"
- " returned %x\n", irq, call_status);
+ printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)"
+ " returned %d\n", irq, call_status);
return;
}
}
@@ -380,7 +380,7 @@ int xics_get_irq(struct pt_regs *regs)
if (irq == NO_IRQ)
irq = real_irq_to_virt_slowpath(vec);
if (irq == NO_IRQ) {
- printk(KERN_ERR "Interrupt %d (real) is invalid,"
+ printk(KERN_ERR "Interrupt %u (real) is invalid,"
" disabling it.\n", vec);
xics_disable_real_irq(vec);
} else
@@ -622,7 +622,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
if (status) {
- printk(KERN_ERR "xics_set_affinity: irq=%d ibm,get-xive "
+ printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive "
"returns %d\n", irq, status);
return;
}
@@ -641,7 +641,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
irq, newmask, xics_status[1]);
if (status) {
- printk(KERN_ERR "xics_set_affinity: irq=%d ibm,set-xive "
+ printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive "
"returns %d\n", irq, status);
return;
}
@@ -720,7 +720,7 @@ void xics_migrate_irqs_away(void)
status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
if (status) {
- printk(KERN_ERR "migrate_irqs_away: irq=%d "
+ printk(KERN_ERR "migrate_irqs_away: irq=%u "
"ibm,get-xive returns %d\n",
virq, status);
goto unlock;
@@ -734,7 +734,7 @@ void xics_migrate_irqs_away(void)
if (xics_status[0] != get_hard_smp_processor_id(cpu))
goto unlock;
- printk(KERN_WARNING "IRQ %d affinity broken off cpu %u\n",
+ printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
virq, cpu);
/* Reset affinity to all cpus */
diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
index 76fbfa9f706f..0b6e967de948 100644
--- a/arch/ppc64/lib/Makefile
+++ b/arch/ppc64/lib/Makefile
@@ -2,7 +2,7 @@
# Makefile for ppc64-specific library files..
#
-lib-y := checksum.o dec_and_lock.o string.o strcase.o
+lib-y := checksum.o string.o strcase.o
lib-y += copypage.o memcpy.o copyuser.o usercopy.o
# Lock primitives are defined as no-ops in include/linux/spinlock.h
diff --git a/arch/ppc64/lib/dec_and_lock.c b/arch/ppc64/lib/dec_and_lock.c
deleted file mode 100644
index 6e8d8591708c..000000000000
--- a/arch/ppc64/lib/dec_and_lock.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ppc64 version of atomic_dec_and_lock() using cmpxchg
- *
- * 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/spinlock.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-
-/*
- * This is an implementation of the notion of "decrement a
- * reference count, and return locked if it decremented to zero".
- *
- * This implementation can be used on any architecture that
- * has a cmpxchg, and where atomic->value is an int holding
- * the value of the atomic (i.e. the high bits aren't used
- * for a lock or anything like that).
- *
- * N.B. ATOMIC_DEC_AND_LOCK gets defined in include/linux/spinlock.h
- * if spinlocks are empty and thus atomic_dec_and_lock is defined
- * to be atomic_dec_and_test - in that case we don't need it
- * defined here as well.
- */
-
-#ifndef ATOMIC_DEC_AND_LOCK
-int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-{
- int counter;
- int newcount;
-
- for (;;) {
- counter = atomic_read(atomic);
- newcount = counter - 1;
- if (!newcount)
- break; /* do it the slow way */
-
- newcount = cmpxchg(&atomic->counter, counter, newcount);
- if (newcount == counter)
- return 0;
- }
-
- spin_lock(lock);
- if (atomic_dec_and_test(atomic))
- return 1;
- spin_unlock(lock);
- return 0;
-}
-
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif /* ATOMIC_DEC_AND_LOCK */
diff --git a/arch/ppc64/lib/locks.c b/arch/ppc64/lib/locks.c
index ef70ef91abe2..033643ab69e0 100644
--- a/arch/ppc64/lib/locks.c
+++ b/arch/ppc64/lib/locks.c
@@ -23,12 +23,12 @@
/* waiting for a spinlock... */
#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
-void __spin_yield(spinlock_t *lock)
+void __spin_yield(raw_spinlock_t *lock)
{
unsigned int lock_value, holder_cpu, yield_count;
struct paca_struct *holder_paca;
- lock_value = lock->lock;
+ lock_value = lock->slock;
if (lock_value == 0)
return;
holder_cpu = lock_value & 0xffff;
@@ -38,7 +38,7 @@ void __spin_yield(spinlock_t *lock)
if ((yield_count & 1) == 0)
return; /* virtual cpu is currently running */
rmb();
- if (lock->lock != lock_value)
+ if (lock->slock != lock_value)
return; /* something has changed */
#ifdef CONFIG_PPC_ISERIES
HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
@@ -54,7 +54,7 @@ void __spin_yield(spinlock_t *lock)
* This turns out to be the same for read and write locks, since
* we only know the holder if it is write-locked.
*/
-void __rw_yield(rwlock_t *rw)
+void __rw_yield(raw_rwlock_t *rw)
{
int lock_value;
unsigned int holder_cpu, yield_count;
@@ -82,9 +82,9 @@ void __rw_yield(rwlock_t *rw)
}
#endif
-void spin_unlock_wait(spinlock_t *lock)
+void __raw_spin_unlock_wait(raw_spinlock_t *lock)
{
- while (lock->lock) {
+ while (lock->slock) {
HMT_low();
if (SHARED_PROCESSOR)
__spin_yield(lock);
@@ -92,4 +92,4 @@ void spin_unlock_wait(spinlock_t *lock)
HMT_medium();
}
-EXPORT_SYMBOL(spin_unlock_wait);
+EXPORT_SYMBOL(__raw_spin_unlock_wait);
diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c
index 772f0714a5b7..be3f25cf3e9f 100644
--- a/arch/ppc64/mm/fault.c
+++ b/arch/ppc64/mm/fault.c
@@ -38,6 +38,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/kdebug.h>
+#include <asm/siginfo.h>
/*
* Check whether the instruction at regs->nip is a store using
@@ -77,6 +78,28 @@ static int store_updates_sp(struct pt_regs *regs)
return 0;
}
+static void do_dabr(struct pt_regs *regs, unsigned long error_code)
+{
+ siginfo_t info;
+
+ if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
+ 11, SIGSEGV) == NOTIFY_STOP)
+ return;
+
+ if (debugger_dabr_match(regs))
+ return;
+
+ /* Clear the DABR */
+ set_dabr(0);
+
+ /* Deliver the signal to userspace */
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_HWBKPT;
+ info.si_addr = (void __user *)regs->nip;
+ force_sig_info(SIGTRAP, &info, current);
+}
+
/*
* The error_code parameter is
* - DSISR for a non-SLB data access fault,
@@ -111,12 +134,9 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
- if (error_code & DSISR_DABRMATCH) {
- if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
- 11, SIGSEGV) == NOTIFY_STOP)
- return 0;
- if (debugger_dabr_match(regs))
- return 0;
+ if (error_code & DSISR_DABRMATCH) {
+ do_dabr(regs, error_code);
+ return 0;
}
if (in_atomic() || mm == NULL) {
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
index 35eb49e1b890..ee5a5d36bfa8 100644
--- a/arch/ppc64/mm/hash_low.S
+++ b/arch/ppc64/mm/hash_low.S
@@ -16,7 +16,7 @@
#include <asm/page.h>
#include <asm/types.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cputable.h>
.text
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
index 7626bb59954d..bfd385b7713c 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/ppc64/mm/hash_native.c
@@ -343,9 +343,7 @@ static void native_flush_hash_range(unsigned long context,
hpte_t *hptep;
unsigned long hpte_v;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-
- /* XXX fix for large ptes */
- unsigned long large = 0;
+ unsigned long large = batch->large;
local_irq_save(flags);
@@ -407,7 +405,7 @@ static void native_flush_hash_range(unsigned long context,
asm volatile("ptesync":::"memory");
for (i = 0; i < j; i++)
- __tlbie(batch->vaddr[i], 0);
+ __tlbie(batch->vaddr[i], large);
asm volatile("eieio; tlbsync; ptesync":::"memory");
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
index 338771ec70d7..0ea0994ed974 100644
--- a/arch/ppc64/mm/hugetlbpage.c
+++ b/arch/ppc64/mm/hugetlbpage.c
@@ -710,10 +710,13 @@ repeat:
hpte_group = ((~hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL;
slot = ppc_md.hpte_insert(hpte_group, va, prpn,
- HPTE_V_LARGE, rflags);
+ HPTE_V_LARGE |
+ HPTE_V_SECONDARY,
+ rflags);
if (slot == -1) {
if (mftb() & 0x1)
- hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+ hpte_group = ((hash & htab_hash_mask) *
+ HPTES_PER_GROUP)&~0x7UL;
ppc_md.hpte_remove(hpte_group);
goto repeat;
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index a14ab87df491..be64b157afce 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++)
@@ -799,8 +799,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
local = 1;
- __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep,
- 0x300, local);
+ __hash_page(ea, 0, vsid, ptep, 0x300, local);
local_irq_restore(flags);
}
diff --git a/arch/ppc64/mm/slb_low.S b/arch/ppc64/mm/slb_low.S
index 698d6b9ed6d1..a3a03da503bc 100644
--- a/arch/ppc64/mm/slb_low.S
+++ b/arch/ppc64/mm/slb_low.S
@@ -21,7 +21,7 @@
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/cputable.h>
/* void slb_allocate(unsigned long ea);
diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c
index d8a6593a13f0..21fbffb23a43 100644
--- a/arch/ppc64/mm/tlb.c
+++ b/arch/ppc64/mm/tlb.c
@@ -143,7 +143,8 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
* up scanning and resetting referenced bits then our batch context
* will change mid stream.
*/
- if (unlikely(i != 0 && context != batch->context)) {
+ if (i != 0 && (context != batch->context ||
+ batch->large != pte_huge(pte))) {
flush_tlb_pending();
i = 0;
}
@@ -151,6 +152,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
if (i == 0) {
batch->context = context;
batch->mm = mm;
+ batch->large = pte_huge(pte);
}
batch->pte[i] = __pte(pte);
batch->addr[i] = addr;
diff --git a/arch/ppc64/xmon/privinst.h b/arch/ppc64/xmon/privinst.h
index 183c3e400258..02eb40dac0b3 100644
--- a/arch/ppc64/xmon/privinst.h
+++ b/arch/ppc64/xmon/privinst.h
@@ -46,7 +46,6 @@ GSETSPR(287, pvr)
GSETSPR(1008, hid0)
GSETSPR(1009, hid1)
GSETSPR(1010, iabr)
-GSETSPR(1013, dabr)
GSETSPR(1023, pir)
static inline void store_inst(void *p)
diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
index 45908b10acd3..74e63a886a69 100644
--- a/arch/ppc64/xmon/xmon.c
+++ b/arch/ppc64/xmon/xmon.c
@@ -586,6 +586,8 @@ int xmon_dabr_match(struct pt_regs *regs)
{
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
return 0;
+ if (dabr.enabled == 0)
+ return 0;
xmon_core(regs, 0);
return 1;
}
@@ -628,20 +630,6 @@ int xmon_fault_handler(struct pt_regs *regs)
return 0;
}
-/* On systems with a hypervisor, we can't set the DABR
- (data address breakpoint register) directly. */
-static void set_controlled_dabr(unsigned long val)
-{
-#ifdef CONFIG_PPC_PSERIES
- if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
- int rc = plpar_hcall_norets(H_SET_DABR, val);
- if (rc != H_Success)
- xmon_printf("Warning: setting DABR failed (%d)\n", rc);
- } else
-#endif
- set_dabr(val);
-}
-
static struct bpt *at_breakpoint(unsigned long pc)
{
int i;
@@ -728,7 +716,7 @@ static void insert_bpts(void)
static void insert_cpu_bpts(void)
{
if (dabr.enabled)
- set_controlled_dabr(dabr.address | (dabr.enabled & 7));
+ set_dabr(dabr.address | (dabr.enabled & 7));
if (iabr && cpu_has_feature(CPU_FTR_IABR))
set_iabr(iabr->address
| (iabr->enabled & (BP_IABR|BP_IABR_TE)));
@@ -756,7 +744,7 @@ static void remove_bpts(void)
static void remove_cpu_bpts(void)
{
- set_controlled_dabr(0);
+ set_dabr(0);
if (cpu_has_feature(CPU_FTR_IABR))
set_iabr(0);
}
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 3cd8dd25c9d7..98db30481d97 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)
@@ -100,16 +102,6 @@ image: vmlinux
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-prepare: include/asm-$(ARCH)/offsets.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
-CLEAN_FILES += include/asm-$(ARCH)/offsets.h
-
# Don't use tabs in echo arguments
define archhelp
echo '* image - Kernel image for IPL ($(boot)/image)'
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 0865251a3f44..45d44c6bb39d 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc4
-# Fri Jul 29 14:49:30 2005
+# Linux kernel version: 2.6.14-rc1
+# Wed Sep 14 16:46:19 2005
#
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -21,6 +21,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -33,6 +34,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -94,6 +96,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
#
# I/O subsystem configuration
@@ -151,8 +154,8 @@ CONFIG_IP_FIB_HASH=y
# 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
CONFIG_IPV6=y
@@ -165,6 +168,11 @@ CONFIG_IPV6=y
# CONFIG_NETFILTER is not set
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -217,9 +225,11 @@ CONFIG_NET_CLS_POLICE=y
# 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
# CONFIG_PCMCIA is not set
#
@@ -233,6 +243,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -260,6 +271,7 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SPI_ATTRS is not set
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -280,7 +292,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_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -384,6 +395,10 @@ CONFIG_EQUALIZER=m
CONFIG_TUN=m
#
+# PHY device support
+#
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -453,10 +468,6 @@ 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
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -465,6 +476,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -485,11 +497,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -533,6 +544,7 @@ CONFIG_SUNRPC=y
# 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
@@ -572,6 +584,7 @@ CONFIG_MSDOS_PARTITION=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
@@ -626,5 +639,6 @@ CONFIG_CRYPTO=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=m
# CONFIG_LIBCRC32C is not set
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index ab1e49d2e518..8584dd823218 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional
obj-y := bitmap.o traps.o time.o process.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
- semaphore.o s390_ext.o debug.o profile.o irq.o
+ semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
extra-$(CONFIG_ARCH_S390_31) += head.o
extra-$(CONFIG_ARCH_S390X) += head64.o
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 18610cea03a2..ed877d0f27e6 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -678,7 +678,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size
ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
set_fs(old_fs);
- if (!ret && offset && put_user(of, offset))
+ if (offset && put_user(of, offset))
return -EFAULT;
return ret;
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 7358cdb8441f..4ff6808456ea 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -143,7 +143,7 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
break;
case __SI_FAULT >> 16:
err |= __get_user(tmp, &from->si_addr);
- to->si_addr = (void *)(u64) (tmp & PSW32_ADDR_INSN);
+ to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN);
break;
case __SI_POLL >> 16:
err |= __get_user(to->si_band, &from->si_band);
@@ -338,7 +338,7 @@ sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss,
err |= __get_user(kss.ss_flags, &uss->ss_flags);
if (err)
return -EFAULT;
- kss.ss_sp = (void *) ss_sp;
+ kss.ss_sp = (void __user *) ss_sp;
}
set_fs (KERNEL_DS);
@@ -461,7 +461,7 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
goto badframe;
err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
- st.ss_sp = (void *) A((unsigned long)ss_sp);
+ st.ss_sp = compat_ptr(ss_sp);
err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
if (err)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index cbe7d6a2d02c..9b30f4cf32c4 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -18,7 +18,7 @@
#include <asm/errno.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/page.h>
@@ -108,7 +108,7 @@ STACK_SIZE = 1 << STACK_SHIFT
bl BASED(0f)
l %r14,BASED(.Lcleanup_critical)
basr %r14,%r14
- tm 0(%r12),0x01 # retest problem state after cleanup
+ tm 1(%r12),0x01 # retest problem state after cleanup
bnz BASED(1f)
0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
slr %r14,%r15
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index fb77b72ab262..7b9b4a2ba1d7 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -18,7 +18,7 @@
#include <asm/errno.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/page.h>
@@ -101,7 +101,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
clc \psworg+8(8),BASED(.Lcritical_start)
jl 0f
brasl %r14,cleanup_critical
- tm 0(%r12),0x01 # retest problem state after cleanup
+ tm 1(%r12),0x01 # retest problem state after cleanup
jnz 1f
0: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ?
slgr %r14,%r15
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 2710e66fefba..55654b6e16dc 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -30,7 +30,7 @@
#include <linux/config.h>
#include <asm/setup.h>
#include <asm/lowcore.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 9a8263a153cb..c9ff0404c875 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -30,7 +30,7 @@
#include <linux/config.h>
#include <asm/setup.h>
#include <asm/lowcore.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c
new file mode 100644
index 000000000000..83cb42bc0b76
--- /dev/null
+++ b/arch/s390/kernel/reipl_diag.c
@@ -0,0 +1,39 @@
+/*
+ * This file contains the implementation of the
+ * Linux re-IPL support
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Volker Sameske (sameske@de.ibm.com)
+ *
+ */
+
+#include <linux/kernel.h>
+
+static unsigned int reipl_diag_rc1;
+static unsigned int reipl_diag_rc2;
+
+/*
+ * re-IPL the system using the last used IPL parameters
+ */
+void reipl_diag(void)
+{
+ asm volatile (
+ " la %%r4,0\n"
+ " la %%r5,0\n"
+ " diag %%r4,%2,0x308\n"
+ "0:\n"
+ " st %%r4,%0\n"
+ " st %%r5,%1\n"
+ ".section __ex_table,\"a\"\n"
+#ifdef __s390x__
+ " .align 8\n"
+ " .quad 0b, 0b\n"
+#else
+ " .align 4\n"
+ " .long 0b, 0b\n"
+#endif
+ ".previous\n"
+ : "=m" (reipl_diag_rc1), "=m" (reipl_diag_rc2)
+ : "d" (3) : "cc", "4", "5" );
+}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 5ba5a5485da9..5204778b8e5e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -261,8 +261,11 @@ void (*_machine_power_off)(void) = machine_power_off_smp;
* Reboot, halt and power_off routines for non SMP.
*/
extern void reipl(unsigned long devno);
+extern void reipl_diag(void);
static void do_machine_restart_nonsmp(char * __unused)
{
+ reipl_diag();
+
if (MACHINE_IS_VM)
cpcmd ("IPL", NULL, 0);
else
@@ -634,6 +637,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
struct cpuinfo_S390 *cpuinfo;
unsigned long n = (unsigned long) v - 1;
+ preempt_disable();
if (!n) {
seq_printf(m, "vendor_id : IBM/S390\n"
"# processors : %i\n"
@@ -658,6 +662,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
cpuinfo->cpu_id.ident,
cpuinfo->cpu_id.machine);
}
+ preempt_enable();
return 0;
}
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 6a3f5b7473a9..6e0110d71191 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -376,8 +376,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
- err |= __put_user(0, &frame->uc.uc_link);
- err |= __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(NULL, &frame->uc.uc_link);
+ err |= __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->gprs[15]),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 85222fee4361..e13c87b446b2 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -65,6 +65,7 @@ extern char vmhalt_cmd[];
extern char vmpoff_cmd[];
extern void reipl(unsigned long devno);
+extern void reipl_diag(void);
static void smp_ext_bitcall(int, ec_bit_sig);
static void smp_ext_bitcall_others(ec_bit_sig);
@@ -283,6 +284,8 @@ static void do_machine_restart(void * __unused)
* interrupted by an external interrupt and s390irq
* locks are always held disabled).
*/
+ reipl_diag();
+
if (MACHINE_IS_VM)
cpcmd ("IPL", NULL, 0, NULL);
else
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 888b5596c195..2dc14e9c8327 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -36,7 +36,7 @@ _diag44(void)
}
void
-_raw_spin_lock_wait(spinlock_t *lp, unsigned int pc)
+_raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
{
int count = spin_retry;
@@ -53,7 +53,7 @@ _raw_spin_lock_wait(spinlock_t *lp, unsigned int pc)
EXPORT_SYMBOL(_raw_spin_lock_wait);
int
-_raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc)
+_raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
{
int count = spin_retry;
@@ -67,7 +67,7 @@ _raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc)
EXPORT_SYMBOL(_raw_spin_trylock_retry);
void
-_raw_read_lock_wait(rwlock_t *rw)
+_raw_read_lock_wait(raw_rwlock_t *rw)
{
unsigned int old;
int count = spin_retry;
@@ -86,7 +86,7 @@ _raw_read_lock_wait(rwlock_t *rw)
EXPORT_SYMBOL(_raw_read_lock_wait);
int
-_raw_read_trylock_retry(rwlock_t *rw)
+_raw_read_trylock_retry(raw_rwlock_t *rw)
{
unsigned int old;
int count = spin_retry;
@@ -102,7 +102,7 @@ _raw_read_trylock_retry(rwlock_t *rw)
EXPORT_SYMBOL(_raw_read_trylock_retry);
void
-_raw_write_lock_wait(rwlock_t *rw)
+_raw_write_lock_wait(raw_rwlock_t *rw)
{
int count = spin_retry;
@@ -119,7 +119,7 @@ _raw_write_lock_wait(rwlock_t *rw)
EXPORT_SYMBOL(_raw_write_lock_wait);
int
-_raw_write_trylock_retry(rwlock_t *rw)
+_raw_write_trylock_retry(raw_rwlock_t *rw)
{
int count = spin_retry;
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
index e8029ef42ef2..88fc94fe6488 100644
--- a/arch/s390/lib/uaccess.S
+++ b/arch/s390/lib/uaccess.S
@@ -11,7 +11,7 @@
#include <linux/errno.h>
#include <asm/lowcore.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.text
.align 4
diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S
index 0ca56972f4f0..50219786fc7a 100644
--- a/arch/s390/lib/uaccess64.S
+++ b/arch/s390/lib/uaccess64.S
@@ -11,7 +11,7 @@
#include <linux/errno.h>
#include <asm/lowcore.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
.text
.align 4
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index b5635635b5ee..4a3049080b41 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -152,10 +152,10 @@ endif
@touch $@
-prepare: maketools include/asm-sh/.cpu include/asm-sh/.mach
+archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach
.PHONY: maketools FORCE
-maketools: include/asm-sh/asm-offsets.h include/linux/version.h FORCE
+maketools: include/linux/version.h FORCE
$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
all: zImage
@@ -168,14 +168,7 @@ compressed: zImage
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-CLEAN_FILES += include/asm-sh/machtypes.h include/asm-sh/asm-offsets.h
-
-arch/sh/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/asm-sh/.cpu include/asm-sh/.mach
-
-include/asm-sh/asm-offsets.h: arch/sh/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
+CLEAN_FILES += include/asm-sh/machtypes.h
define archhelp
@echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)'
diff --git a/arch/sh/boards/adx/irq_maskreg.c b/arch/sh/boards/adx/irq_maskreg.c
index ca91bb0f1f5c..c0973f8d57ba 100644
--- a/arch/sh/boards/adx/irq_maskreg.c
+++ b/arch/sh/boards/adx/irq_maskreg.c
@@ -37,13 +37,13 @@ static void end_maskreg_irq(unsigned int irq);
/* hw_interrupt_type */
static struct hw_interrupt_type maskreg_irq_type = {
- " Mask Register",
- startup_maskreg_irq,
- shutdown_maskreg_irq,
- enable_maskreg_irq,
- disable_maskreg_irq,
- mask_and_ack_maskreg,
- end_maskreg_irq
+ .typename = " Mask Register",
+ .startup = startup_maskreg_irq,
+ .shutdown = shutdown_maskreg_irq,
+ .enable = enable_maskreg_irq,
+ .disable = disable_maskreg_irq,
+ .ack = mask_and_ack_maskreg,
+ .end = end_maskreg_irq
};
/* actual implementatin */
diff --git a/arch/sh/boards/bigsur/io.c b/arch/sh/boards/bigsur/io.c
index 697144de7419..a9fde781b21a 100644
--- a/arch/sh/boards/bigsur/io.c
+++ b/arch/sh/boards/bigsur/io.c
@@ -37,10 +37,6 @@ static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP];
static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP];
static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP];
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
{
u32 port, endport = baseport + nports;
@@ -57,7 +53,7 @@ void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
addr += (1<<(BIGSUR_IOMAP_LO_SHIFT));
}
- for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
+ for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH);
port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
pr_debug(" maphi[0x%x] = 0x%08x\n", port, addr);
@@ -80,7 +76,7 @@ void bigsur_port_unmap(u32 baseport, u32 nports)
bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0;
}
- for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
+ for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH);
port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0;
diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c
index c188fc32dc9a..6ddbcc77244d 100644
--- a/arch/sh/boards/bigsur/irq.c
+++ b/arch/sh/boards/bigsur/irq.c
@@ -228,23 +228,23 @@ static void shutdown_bigsur_irq(unsigned int irq)
/* Define the IRQ structures for the L1 and L2 IRQ types */
static struct hw_interrupt_type bigsur_l1irq_type = {
- "BigSur-CPLD-Level1-IRQ",
- startup_bigsur_irq,
- shutdown_bigsur_irq,
- enable_bigsur_l1irq,
- disable_bigsur_l1irq,
- mask_and_ack_bigsur,
- end_bigsur_irq
+ .typename = "BigSur-CPLD-Level1-IRQ",
+ .startup = startup_bigsur_irq,
+ .shutdown = shutdown_bigsur_irq,
+ .enable = enable_bigsur_l1irq,
+ .disable = disable_bigsur_l1irq,
+ .ack = mask_and_ack_bigsur,
+ .end = end_bigsur_irq
};
static struct hw_interrupt_type bigsur_l2irq_type = {
- "BigSur-CPLD-Level2-IRQ",
- startup_bigsur_irq,
- shutdown_bigsur_irq,
- enable_bigsur_l2irq,
- disable_bigsur_l2irq,
- mask_and_ack_bigsur,
- end_bigsur_irq
+ .typename = "BigSur-CPLD-Level2-IRQ",
+ .startup = startup_bigsur_irq,
+ .shutdown =shutdown_bigsur_irq,
+ .enable = enable_bigsur_l2irq,
+ .disable = disable_bigsur_l2irq,
+ .ack = mask_and_ack_bigsur,
+ .end = end_bigsur_irq
};
diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c
index fa6cfe5a20a7..d1da0d844567 100644
--- a/arch/sh/boards/cqreek/irq.c
+++ b/arch/sh/boards/cqreek/irq.c
@@ -83,13 +83,13 @@ static void shutdown_cqreek_irq(unsigned int irq)
}
static struct hw_interrupt_type cqreek_irq_type = {
- "CqREEK-IRQ",
- startup_cqreek_irq,
- shutdown_cqreek_irq,
- enable_cqreek_irq,
- disable_cqreek_irq,
- mask_and_ack_cqreek,
- end_cqreek_irq
+ .typename = "CqREEK-IRQ",
+ .startup = startup_cqreek_irq,
+ .shutdown = shutdown_cqreek_irq,
+ .enable = enable_cqreek_irq,
+ .disable = disable_cqreek_irq,
+ .ack = mask_and_ack_cqreek,
+ .end = end_cqreek_irq
};
int cqreek_has_ide, cqreek_has_isa;
diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c
index acd58489970f..52d0ba39031b 100644
--- a/arch/sh/boards/harp/irq.c
+++ b/arch/sh/boards/harp/irq.c
@@ -39,13 +39,13 @@ static unsigned int startup_harp_irq(unsigned int irq)
}
static struct hw_interrupt_type harp_irq_type = {
- "Harp-IRQ",
- startup_harp_irq,
- shutdown_harp_irq,
- enable_harp_irq,
- disable_harp_irq,
- mask_and_ack_harp,
- end_harp_irq
+ .typename = "Harp-IRQ",
+ .startup = startup_harp_irq,
+ .shutdown = shutdown_harp_irq,
+ .enable = enable_harp_irq,
+ .disable = disable_harp_irq,
+ .ack = mask_and_ack_harp,
+ .end = end_harp_irq
};
static void disable_harp_irq(unsigned int irq)
diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c
index 23adc6be71e7..715e8feb3a68 100644
--- a/arch/sh/boards/overdrive/irq.c
+++ b/arch/sh/boards/overdrive/irq.c
@@ -86,13 +86,13 @@ static unsigned int startup_od_irq(unsigned int irq)
}
static struct hw_interrupt_type od_irq_type = {
- "Overdrive-IRQ",
- startup_od_irq,
- shutdown_od_irq,
- enable_od_irq,
- disable_od_irq,
- mask_and_ack_od,
- end_od_irq
+ .typename = "Overdrive-IRQ",
+ .startup = startup_od_irq,
+ .shutdown = shutdown_od_irq,
+ .enable = enable_od_irq,
+ .disable = disable_od_irq,
+ .ack = mask_and_ack_od,
+ .end = end_od_irq
};
static void disable_od_irq(unsigned int irq)
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c
index a7921f67a35f..ed4c5b50ea45 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/irq.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c
@@ -74,13 +74,13 @@ static void end_hs7751rvoip_irq(unsigned int irq)
}
static struct hw_interrupt_type hs7751rvoip_irq_type = {
- "HS7751RVoIP IRQ",
- startup_hs7751rvoip_irq,
- shutdown_hs7751rvoip_irq,
- enable_hs7751rvoip_irq,
- disable_hs7751rvoip_irq,
- ack_hs7751rvoip_irq,
- end_hs7751rvoip_irq,
+ .typename = "HS7751RVoIP IRQ",
+ .startup = startup_hs7751rvoip_irq,
+ .shutdown = shutdown_hs7751rvoip_irq,
+ .enable = enable_hs7751rvoip_irq,
+ .disable = disable_hs7751rvoip_irq,
+ .ack = ack_hs7751rvoip_irq,
+ .end = end_hs7751rvoip_irq,
};
static void make_hs7751rvoip_irq(unsigned int irq)
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c
index 95717f4f1e2d..d36c9374aed1 100644
--- a/arch/sh/boards/renesas/rts7751r2d/irq.c
+++ b/arch/sh/boards/renesas/rts7751r2d/irq.c
@@ -88,13 +88,13 @@ static void end_rts7751r2d_irq(unsigned int irq)
}
static struct hw_interrupt_type rts7751r2d_irq_type = {
- "RTS7751R2D IRQ",
- startup_rts7751r2d_irq,
- shutdown_rts7751r2d_irq,
- enable_rts7751r2d_irq,
- disable_rts7751r2d_irq,
- ack_rts7751r2d_irq,
- end_rts7751r2d_irq,
+ .typename = "RTS7751R2D IRQ",
+ .startup = startup_rts7751r2d_irq,
+ .shutdown = shutdown_rts7751r2d_irq,
+ .enable = enable_rts7751r2d_irq,
+ .disable = disable_rts7751r2d_irq,
+ .ack = ack_rts7751r2d_irq,
+ .end = end_rts7751r2d_irq,
};
static void make_rts7751r2d_irq(unsigned int irq)
diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c
index 1efc18e786d5..610740512d56 100644
--- a/arch/sh/boards/renesas/rts7751r2d/mach.c
+++ b/arch/sh/boards/renesas/rts7751r2d/mach.c
@@ -23,7 +23,7 @@ extern void init_rts7751r2d_IRQ(void);
extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
extern int rts7751r2d_irq_demux(int irq);
-extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
+extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
/*
diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c
index 5675a4134eee..7a2eb10edb56 100644
--- a/arch/sh/boards/renesas/systemh/irq.c
+++ b/arch/sh/boards/renesas/systemh/irq.c
@@ -35,13 +35,13 @@ static void end_systemh_irq(unsigned int irq);
/* hw_interrupt_type */
static struct hw_interrupt_type systemh_irq_type = {
- " SystemH Register",
- startup_systemh_irq,
- shutdown_systemh_irq,
- enable_systemh_irq,
- disable_systemh_irq,
- mask_and_ack_systemh,
- end_systemh_irq
+ .typename = " SystemH Register",
+ .startup = startup_systemh_irq,
+ .shutdown = shutdown_systemh_irq,
+ .enable = enable_systemh_irq,
+ .disable = disable_systemh_irq,
+ .ack = mask_and_ack_systemh,
+ .end = end_systemh_irq
};
static unsigned int startup_systemh_irq(unsigned int irq)
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c
index 1298883eca4b..1395c1e65da4 100644
--- a/arch/sh/boards/superh/microdev/irq.c
+++ b/arch/sh/boards/superh/microdev/irq.c
@@ -83,13 +83,13 @@ static unsigned int startup_microdev_irq(unsigned int irq)
}
static struct hw_interrupt_type microdev_irq_type = {
- "MicroDev-IRQ",
- startup_microdev_irq,
- shutdown_microdev_irq,
- enable_microdev_irq,
- disable_microdev_irq,
- mask_and_ack_microdev,
- end_microdev_irq
+ .typename = "MicroDev-IRQ",
+ .startup = startup_microdev_irq,
+ .shutdown = shutdown_microdev_irq,
+ .enable = enable_microdev_irq,
+ .disable = disable_microdev_irq,
+ .ack = mask_and_ack_microdev,
+ .end = end_microdev_irq
};
static void disable_microdev_irq(unsigned int irq)
diff --git a/arch/sh/cchips/hd6446x/hd64465/io.c b/arch/sh/cchips/hd6446x/hd64465/io.c
index 99ac709c550e..84cb142def0b 100644
--- a/arch/sh/cchips/hd6446x/hd64465/io.c
+++ b/arch/sh/cchips/hd6446x/hd64465/io.c
@@ -48,10 +48,6 @@ static unsigned char hd64465_iomap_lo_shift[HD64465_IOMAP_LO_NMAP];
static unsigned long hd64465_iomap_hi[HD64465_IOMAP_HI_NMAP];
static unsigned char hd64465_iomap_hi_shift[HD64465_IOMAP_HI_NMAP];
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
void hd64465_port_map(unsigned short baseport, unsigned int nports,
@@ -71,7 +67,7 @@ void hd64465_port_map(unsigned short baseport, unsigned int nports,
addr += (1<<(HD64465_IOMAP_LO_SHIFT));
}
- for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
+ for (port = max_t(unsigned int, baseport, HD64465_IOMAP_LO_THRESH);
port < endport && port < HD64465_IOMAP_HI_THRESH ;
port += (1<<HD64465_IOMAP_HI_SHIFT)) {
DPRINTK(" maphi[0x%x] = 0x%08lx\n", port, addr);
@@ -95,7 +91,7 @@ void hd64465_port_unmap(unsigned short baseport, unsigned int nports)
hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = 0;
}
- for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
+ for (port = max_t(unsigned int, baseport, HD64465_IOMAP_LO_THRESH);
port < endport && port < HD64465_IOMAP_HI_THRESH ;
port += (1<<HD64465_IOMAP_HI_SHIFT)) {
hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = 0;
diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
index 5b92585a38d2..3d9a02c093a3 100644
--- a/arch/sh/cchips/voyagergx/consistent.c
+++ b/arch/sh/cchips/voyagergx/consistent.c
@@ -31,7 +31,7 @@ static LIST_HEAD(voya_alloc_list);
#define OHCI_SRAM_SIZE 0x10000
void *voyagergx_consistent_alloc(struct device *dev, size_t size,
- dma_addr_t *handle, int flag)
+ dma_addr_t *handle, gfp_t flag)
{
struct list_head *list = &voya_alloc_list;
struct voya_alloc_entry *entry;
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index 3079234cb65b..1b6ac523b458 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -87,13 +87,13 @@ static void shutdown_voyagergx_irq(unsigned int irq)
}
static struct hw_interrupt_type voyagergx_irq_type = {
- "VOYAGERGX-IRQ",
- startup_voyagergx_irq,
- shutdown_voyagergx_irq,
- enable_voyagergx_irq,
- disable_voyagergx_irq,
- mask_and_ack_voyagergx,
- end_voyagergx_irq,
+ .typename = "VOYAGERGX-IRQ",
+ .startup = startup_voyagergx_irq,
+ .shutdown = shutdown_voyagergx_irq,
+ .enable = enable_voyagergx_irq,
+ .disable = disable_voyagergx_irq,
+ .ack = mask_and_ack_voyagergx,
+ .end = end_voyagergx_irq,
};
static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
index 83de7ef4e7df..e12418bb1fa5 100644
--- a/arch/sh/drivers/pci/dma-dreamcast.c
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -33,7 +33,7 @@
static int gapspci_dma_used = 0;
void *dreamcast_consistent_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
unsigned long buf;
diff --git a/arch/sh/kernel/cpu/irq_imask.c b/arch/sh/kernel/cpu/irq_imask.c
index f76901e732fb..a963d00a971e 100644
--- a/arch/sh/kernel/cpu/irq_imask.c
+++ b/arch/sh/kernel/cpu/irq_imask.c
@@ -46,13 +46,13 @@ static unsigned int startup_imask_irq(unsigned int irq)
}
static struct hw_interrupt_type imask_irq_type = {
- "SR.IMASK",
- startup_imask_irq,
- shutdown_imask_irq,
- enable_imask_irq,
- disable_imask_irq,
- mask_and_ack_imask,
- end_imask_irq
+ .typename = "SR.IMASK",
+ .startup = startup_imask_irq,
+ .shutdown = shutdown_imask_irq,
+ .enable = enable_imask_irq,
+ .disable = disable_imask_irq,
+ .ack = mask_and_ack_imask,
+ .end = end_imask_irq
};
void static inline set_interrupt_registers(int ip)
diff --git a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq_ipr.c
index 7ea3d2d030e5..71f92096132b 100644
--- a/arch/sh/kernel/cpu/irq_ipr.c
+++ b/arch/sh/kernel/cpu/irq_ipr.c
@@ -48,13 +48,13 @@ static unsigned int startup_ipr_irq(unsigned int irq)
}
static struct hw_interrupt_type ipr_irq_type = {
- "IPR-IRQ",
- startup_ipr_irq,
- shutdown_ipr_irq,
- enable_ipr_irq,
- disable_ipr_irq,
- mask_and_ack_ipr,
- end_ipr_irq
+ .typename = "IPR-IRQ",
+ .startup = startup_ipr_irq,
+ .shutdown = shutdown_ipr_irq,
+ .enable = enable_ipr_irq,
+ .disable = disable_ipr_irq,
+ .ack = mask_and_ack_ipr,
+ .end = end_ipr_irq
};
static void disable_ipr_irq(unsigned int irq)
@@ -142,13 +142,13 @@ static unsigned int startup_pint_irq(unsigned int irq)
}
static struct hw_interrupt_type pint_irq_type = {
- "PINT-IRQ",
- startup_pint_irq,
- shutdown_pint_irq,
- enable_pint_irq,
- disable_pint_irq,
- mask_and_ack_pint,
- end_pint_irq
+ .typename = "PINT-IRQ",
+ .startup = startup_pint_irq,
+ .shutdown = shutdown_pint_irq,
+ .enable = enable_pint_irq,
+ .disable = disable_pint_irq,
+ .ack = mask_and_ack_pint,
+ .end = end_pint_irq
};
static void disable_pint_irq(unsigned int irq)
diff --git a/arch/sh/kernel/cpu/sh4/irq_intc2.c b/arch/sh/kernel/cpu/sh4/irq_intc2.c
index 099ebbf89745..f6b16ba01932 100644
--- a/arch/sh/kernel/cpu/sh4/irq_intc2.c
+++ b/arch/sh/kernel/cpu/sh4/irq_intc2.c
@@ -48,13 +48,13 @@ static unsigned int startup_intc2_irq(unsigned int irq)
}
static struct hw_interrupt_type intc2_irq_type = {
- "INTC2-IRQ",
- startup_intc2_irq,
- shutdown_intc2_irq,
- enable_intc2_irq,
- disable_intc2_irq,
- mask_and_ack_intc2,
- end_intc2_irq
+ .typename = "INTC2-IRQ",
+ .startup = startup_intc2_irq,
+ .shutdown = shutdown_intc2_irq,
+ .enable = enable_intc2_irq,
+ .disable = disable_intc2_irq,
+ .ack = mask_and_ack_intc2,
+ .end = end_intc2_irq
};
static void disable_intc2_irq(unsigned int irq)
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 56a39d69e080..5ecefc02896a 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -22,6 +22,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/sched.h>
+#include <linux/module.h>
#include <asm/atomic.h>
#include <asm/processor.h>
@@ -39,6 +40,8 @@ struct sh_cpuinfo cpu_data[NR_CPUS];
extern void per_cpu_trap_init(void);
cpumask_t cpu_possible_map;
+EXPORT_SYMBOL(cpu_possible_map);
+
cpumask_t cpu_online_map;
static atomic_t cpus_booted = ATOMIC_INIT(0);
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 1f7af0c73cf4..df3a9e452cc5 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -11,7 +11,7 @@
#include <linux/dma-mapping.h>
#include <asm/io.h>
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle)
+void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
{
struct page *page, *end, *free;
void *ret;
diff --git a/arch/sh64/Makefile b/arch/sh64/Makefile
index b4fd8e13fea9..8ca57ffa2b70 100644
--- a/arch/sh64/Makefile
+++ b/arch/sh64/Makefile
@@ -73,11 +73,7 @@ compressed: zImage
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-prepare: include/asm-$(ARCH)/asm-offsets.h arch/$(ARCH)/lib/syscalltab.h
-
-include/asm-$(ARCH)/asm-offsets.h: arch/$(ARCH)/kernel/asm-offsets.s \
- include/asm include/linux/version.h
- $(call filechk,gen-asm-offsets)
+archprepare: arch/$(ARCH)/lib/syscalltab.h
define filechk_gen-syscalltab
(set -e; \
@@ -108,7 +104,7 @@ endef
arch/$(ARCH)/lib/syscalltab.h: arch/sh64/kernel/syscalls.S
$(call filechk,gen-syscalltab)
-CLEAN_FILES += include/asm-$(ARCH)/asm-offsets.h arch/$(ARCH)/lib/syscalltab.h
+CLEAN_FILES += arch/$(ARCH)/lib/syscalltab.h
define archhelp
@echo ' zImage - Compressed kernel image (arch/sh64/boot/zImage)'
diff --git a/arch/sh64/kernel/irq_intc.c b/arch/sh64/kernel/irq_intc.c
index 43f88f3a78b0..fc99bf4e362c 100644
--- a/arch/sh64/kernel/irq_intc.c
+++ b/arch/sh64/kernel/irq_intc.c
@@ -107,13 +107,13 @@ static void mask_and_ack_intc(unsigned int);
static void end_intc_irq(unsigned int irq);
static struct hw_interrupt_type intc_irq_type = {
- "INTC",
- startup_intc_irq,
- shutdown_intc_irq,
- enable_intc_irq,
- disable_intc_irq,
- mask_and_ack_intc,
- end_intc_irq
+ .typename = "INTC",
+ .startup = startup_intc_irq,
+ .shutdown = shutdown_intc_irq,
+ .enable = enable_intc_irq,
+ .disable = disable_intc_irq,
+ .ack = mask_and_ack_intc,
+ .end = end_intc_irq
};
static int irlm; /* IRL mode */
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index aba05394d30a..6537445dac0e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -25,62 +25,6 @@ source "init/Kconfig"
menu "General machine setup"
-config VT
- bool
- select INPUT
- default y
- ---help---
- If you say Y here, you will get support for terminal devices with
- display and keyboard devices. These are called "virtual" because you
- can run several virtual terminals (also called virtual consoles) on
- one physical terminal. This is rather useful, for example one
- virtual terminal can collect system messages and warnings, another
- one can be used for a text-mode user session, and a third could run
- an X session, all in parallel. Switching between virtual terminals
- is done with certain key combinations, usually Alt-<function key>.
-
- The setterm command ("man setterm") can be used to change the
- properties (such as colors or beeping) of a virtual terminal. The
- man page console_codes(4) ("man console_codes") contains the special
- character sequences that can be used to change those properties
- directly. The fonts used on virtual terminals can be changed with
- the setfont ("man setfont") command and the key bindings are defined
- with the loadkeys ("man loadkeys") command.
-
- You need at least one virtual terminal device in order to make use
- of your keyboard and monitor. Therefore, only people configuring an
- embedded system would want to say N here in order to save some
- memory; the only way to log into such a system is then via a serial
- or network connection.
-
- If unsure, say Y, or else you won't be able to do much with your new
- shiny Linux system :-)
-
-config VT_CONSOLE
- bool
- default y
- ---help---
- The system console is the device which receives all kernel messages
- and warnings and which allows logins in single user mode. If you
- answer Y here, a virtual terminal (the device used to interact with
- a physical terminal) can be used as system console. This is the most
- common mode of operations, so you should say Y here unless you want
- the kernel messages be output only to a serial port (in which case
- you should say Y to "Console on serial port", below).
-
- If you do say Y here, by default the currently visible virtual
- terminal (/dev/tty0) will be used as system console. You can change
- that with a kernel command line option such as "console=tty3" which
- would use the third virtual terminal as system console. (Try "man
- bootparam" or see the documentation of your boot loader (lilo or
- loadlin) about how to pass options to the kernel at boot time.)
-
- If unsure, say Y.
-
-config HW_CONSOLE
- bool
- default y
-
config SMP
bool "Symmetric multi-processing support (does not work on sun4/sun4c)"
depends on BROKEN
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 7b3bbaf083a6..dea48f6cff38 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -59,17 +59,7 @@ image tftpboot.img: vmlinux
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-prepare: include/asm-$(ARCH)/asm_offsets.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/asm_offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
-CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h \
- arch/$(ARCH)/kernel/asm-offsets.s \
- arch/$(ARCH)/boot/System.map
+CLEAN_FILES += arch/$(ARCH)/boot/System.map
# Don't use tabs in echo arguments.
define archhelp
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index b448166f5da9..03ecb4e4614e 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -17,7 +17,7 @@
#include <asm/kgdb.h>
#include <asm/contregs.h>
#include <asm/ptrace.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/psr.h>
#include <asm/vaddrs.h>
#include <asm/memreg.h>
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 7931d6f92819..787d5f1347ec 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -10,6 +10,7 @@
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
+#include <linux/ctype.h>
void *module_alloc(unsigned long size)
{
@@ -37,7 +38,7 @@ void module_free(struct module *mod, void *module_region)
}
/* Make generic code ignore STT_REGISTER dummy undefined symbols,
- * and replace references to .func with func as in ppc64's dedotify.
+ * and replace references to .func with _Func
*/
int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
@@ -64,8 +65,10 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
sym[i].st_shndx = SHN_ABS;
else {
char *name = strtab + sym[i].st_name;
- if (name[0] == '.')
- memmove(name, name+1, strlen(name));
+ if (name[0] == '.') {
+ name[0] = '_';
+ name[1] = toupper(name[1]);
+ }
}
}
}
diff --git a/arch/sparc/kernel/sclow.S b/arch/sparc/kernel/sclow.S
index 3a867fc19927..136e37c53d49 100644
--- a/arch/sparc/kernel/sclow.S
+++ b/arch/sparc/kernel/sclow.S
@@ -7,7 +7,7 @@
*/
#include <asm/ptrace.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/errno.h>
#include <asm/winmacro.h>
#include <asm/thread_info.h>
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 53c192a4982f..3509e4305532 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -249,8 +249,6 @@ struct tt_entry *sparc_ttable;
struct pt_regs fake_swapper_regs;
-extern void paging_init(void);
-
void __init setup_arch(char **cmdline_p)
{
int i;
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 5d974a2b735a..1c8fd0fd9305 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -97,34 +97,17 @@ extern void ___rw_write_enter(void);
/* Alias functions whose names begin with "." and export the aliases.
* The module references will be fixed up by module_frob_arch_sections.
*/
-#define DOT_ALIAS2(__ret, __x, __arg1, __arg2) \
- extern __ret __x(__arg1, __arg2); \
- asm(".weak " #__x);\
- asm(#__x "=." #__x);
-
-DOT_ALIAS2(int, div, int, int)
-DOT_ALIAS2(int, mul, int, int)
-DOT_ALIAS2(int, rem, int, int)
-DOT_ALIAS2(unsigned, udiv, unsigned, unsigned)
-DOT_ALIAS2(unsigned, umul, unsigned, unsigned)
-DOT_ALIAS2(unsigned, urem, unsigned, unsigned)
-
-#undef DOT_ALIAS2
+extern int _Div(int, int);
+extern int _Mul(int, int);
+extern int _Rem(int, int);
+extern unsigned _Udiv(unsigned, unsigned);
+extern unsigned _Umul(unsigned, unsigned);
+extern unsigned _Urem(unsigned, unsigned);
/* used by various drivers */
EXPORT_SYMBOL(sparc_cpu_model);
EXPORT_SYMBOL(kernel_thread);
-#ifdef CONFIG_DEBUG_SPINLOCK
#ifdef CONFIG_SMP
-EXPORT_SYMBOL(_do_spin_lock);
-EXPORT_SYMBOL(_do_spin_unlock);
-EXPORT_SYMBOL(_spin_trylock);
-EXPORT_SYMBOL(_do_read_lock);
-EXPORT_SYMBOL(_do_read_unlock);
-EXPORT_SYMBOL(_do_write_lock);
-EXPORT_SYMBOL(_do_write_unlock);
-#endif
-#else
// XXX find what uses (or used) these.
EXPORT_SYMBOL(___rw_read_enter);
EXPORT_SYMBOL(___rw_read_exit);
@@ -330,12 +313,12 @@ EXPORT_SYMBOL(__lshrdi3);
EXPORT_SYMBOL(__muldi3);
EXPORT_SYMBOL(__divdi3);
-EXPORT_SYMBOL(rem);
-EXPORT_SYMBOL(urem);
-EXPORT_SYMBOL(mul);
-EXPORT_SYMBOL(umul);
-EXPORT_SYMBOL(div);
-EXPORT_SYMBOL(udiv);
+EXPORT_SYMBOL(_Rem);
+EXPORT_SYMBOL(_Urem);
+EXPORT_SYMBOL(_Mul);
+EXPORT_SYMBOL(_Umul);
+EXPORT_SYMBOL(_Div);
+EXPORT_SYMBOL(_Udiv);
#ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG);
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index bc015e980341..279a62627c10 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -457,7 +457,7 @@ void __init time_init(void)
sbus_time_init();
}
-extern __inline__ unsigned long do_gettimeoffset(void)
+static inline unsigned long do_gettimeoffset(void)
{
return (*master_l10_counter >> 10) & 0x1fffff;
}
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 2296ff9dc47a..fa5006946062 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -9,5 +9,3 @@ lib-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \
strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \
copy_user.o locks.o atomic.o atomic32.o bitops.o \
lshrdi3.o ashldi3.o rwsem.o muldi3.o bitext.o
-
-lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 19724c5800a7..2e64e8c3e8e5 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -20,7 +20,7 @@ spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
#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/sparc/lib/debuglocks.c b/arch/sparc/lib/debuglocks.c
deleted file mode 100644
index fb182352782c..000000000000
--- a/arch/sparc/lib/debuglocks.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* $Id: debuglocks.c,v 1.11 2001/09/20 00:35:31 davem Exp $
- * debuglocks.c: Debugging versions of SMP locking primitives.
- *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au)
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/threads.h> /* For NR_CPUS */
-#include <linux/spinlock.h>
-#include <asm/psr.h>
-#include <asm/system.h>
-
-#ifdef CONFIG_SMP
-
-/* Some notes on how these debugging routines work. When a lock is acquired
- * an extra debugging member lock->owner_pc is set to the caller of the lock
- * acquisition routine. Right before releasing a lock, the debugging program
- * counter is cleared to zero.
- *
- * Furthermore, since PC's are 4 byte aligned on Sparc, we stuff the CPU
- * number of the owner in the lowest two bits.
- */
-
-#define STORE_CALLER(A) __asm__ __volatile__("mov %%i7, %0" : "=r" (A));
-
-static inline void show(char *str, spinlock_t *lock, unsigned long caller)
-{
- int cpu = smp_processor_id();
-
- printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n",str,
- lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
-}
-
-static inline void show_read(char *str, rwlock_t *lock, unsigned long caller)
-{
- int cpu = smp_processor_id();
-
- printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n", str,
- lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
-}
-
-static inline void show_write(char *str, rwlock_t *lock, unsigned long caller)
-{
- int cpu = smp_processor_id();
- int i;
-
- printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)", str,
- lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
-
- for(i = 0; i < NR_CPUS; i++)
- printk(" reader[%d]=%08lx", i, lock->reader_pc[i]);
-
- printk("\n");
-}
-
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
-void _do_spin_lock(spinlock_t *lock, char *str)
-{
- unsigned long caller;
- unsigned long val;
- int cpu = smp_processor_id();
- int stuck = INIT_STUCK;
-
- STORE_CALLER(caller);
-
-again:
- __asm__ __volatile__("ldstub [%1], %0" : "=r" (val) : "r" (&(lock->lock)));
- if(val) {
- while(lock->lock) {
- if (!--stuck) {
- show(str, lock, caller);
- stuck = INIT_STUCK;
- }
- barrier();
- }
- goto again;
- }
- lock->owner_pc = (cpu & 3) | (caller & ~3);
-}
-
-int _spin_trylock(spinlock_t *lock)
-{
- unsigned long val;
- unsigned long caller;
- int cpu = smp_processor_id();
-
- STORE_CALLER(caller);
-
- __asm__ __volatile__("ldstub [%1], %0" : "=r" (val) : "r" (&(lock->lock)));
- if(!val) {
- /* We got it, record our identity for debugging. */
- lock->owner_pc = (cpu & 3) | (caller & ~3);
- }
- return val == 0;
-}
-
-void _do_spin_unlock(spinlock_t *lock)
-{
- lock->owner_pc = 0;
- barrier();
- lock->lock = 0;
-}
-
-void _do_read_lock(rwlock_t *rw, char *str)
-{
- unsigned long caller;
- unsigned long val;
- int cpu = smp_processor_id();
- int stuck = INIT_STUCK;
-
- STORE_CALLER(caller);
-
-wlock_again:
- __asm__ __volatile__("ldstub [%1 + 3], %0" : "=r" (val) : "r" (&(rw->lock)));
- if(val) {
- while(rw->lock & 0xff) {
- if (!--stuck) {
- show_read(str, rw, caller);
- stuck = INIT_STUCK;
- }
- barrier();
- }
- goto wlock_again;
- }
-
- rw->reader_pc[cpu] = caller;
- barrier();
- rw->lock++;
-}
-
-void _do_read_unlock(rwlock_t *rw, char *str)
-{
- unsigned long caller;
- unsigned long val;
- int cpu = smp_processor_id();
- int stuck = INIT_STUCK;
-
- STORE_CALLER(caller);
-
-wlock_again:
- __asm__ __volatile__("ldstub [%1 + 3], %0" : "=r" (val) : "r" (&(rw->lock)));
- if(val) {
- while(rw->lock & 0xff) {
- if (!--stuck) {
- show_read(str, rw, caller);
- stuck = INIT_STUCK;
- }
- barrier();
- }
- goto wlock_again;
- }
-
- rw->reader_pc[cpu] = 0;
- barrier();
- rw->lock -= 0x1ff;
-}
-
-void _do_write_lock(rwlock_t *rw, char *str)
-{
- unsigned long caller;
- unsigned long val;
- int cpu = smp_processor_id();
- int stuck = INIT_STUCK;
-
- STORE_CALLER(caller);
-
-wlock_again:
- __asm__ __volatile__("ldstub [%1 + 3], %0" : "=r" (val) : "r" (&(rw->lock)));
- if(val) {
-wlock_wait:
- while(rw->lock) {
- if (!--stuck) {
- show_write(str, rw, caller);
- stuck = INIT_STUCK;
- }
- barrier();
- }
- goto wlock_again;
- }
-
- if (rw->lock & ~0xff) {
- *(((unsigned char *)&rw->lock)+3) = 0;
- barrier();
- goto wlock_wait;
- }
-
- barrier();
- rw->owner_pc = (cpu & 3) | (caller & ~3);
-}
-
-void _do_write_unlock(rwlock_t *rw)
-{
- rw->owner_pc = 0;
- barrier();
- rw->lock = 0;
-}
-
-#endif /* SMP */
diff --git a/arch/sparc/lib/mul.S b/arch/sparc/lib/mul.S
index 83dffbc2f62f..da693560d878 100644
--- a/arch/sparc/lib/mul.S
+++ b/arch/sparc/lib/mul.S
@@ -16,7 +16,9 @@
*/
.globl .mul
+ .globl _Mul
.mul:
+_Mul: /* needed for export */
mov %o0, %y ! multiplier -> Y
andncc %o0, 0xfff, %g0 ! test bits 12..31
be Lmul_shortway ! if zero, can do it the short way
diff --git a/arch/sparc/lib/rem.S b/arch/sparc/lib/rem.S
index 44508148d055..bf015a90d07e 100644
--- a/arch/sparc/lib/rem.S
+++ b/arch/sparc/lib/rem.S
@@ -43,7 +43,9 @@
.globl .rem
+ .globl _Rem
.rem:
+_Rem: /* needed for export */
! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide
diff --git a/arch/sparc/lib/sdiv.S b/arch/sparc/lib/sdiv.S
index e0ad80b6f63d..af9451629d0b 100644
--- a/arch/sparc/lib/sdiv.S
+++ b/arch/sparc/lib/sdiv.S
@@ -43,7 +43,9 @@
.globl .div
+ .globl _Div
.div:
+_Div: /* needed for export */
! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide
diff --git a/arch/sparc/lib/udiv.S b/arch/sparc/lib/udiv.S
index 2abfc6b0f3e9..169e01da6715 100644
--- a/arch/sparc/lib/udiv.S
+++ b/arch/sparc/lib/udiv.S
@@ -43,7 +43,9 @@
.globl .udiv
+ .globl _Udiv
.udiv:
+_Udiv: /* needed for export */
! Ready to divide. Compute size of quotient; scale comparand.
orcc %o1, %g0, %o5
diff --git a/arch/sparc/lib/umul.S b/arch/sparc/lib/umul.S
index a784720a8a22..f0e5b20a2536 100644
--- a/arch/sparc/lib/umul.S
+++ b/arch/sparc/lib/umul.S
@@ -21,7 +21,9 @@
*/
.globl .umul
+ .globl _Umul
.umul:
+_Umul: /* needed for export */
or %o0, %o1, %o4
mov %o0, %y ! multiplier -> Y
diff --git a/arch/sparc/lib/urem.S b/arch/sparc/lib/urem.S
index ec7f0c502c56..6b92bdc8b04c 100644
--- a/arch/sparc/lib/urem.S
+++ b/arch/sparc/lib/urem.S
@@ -41,7 +41,9 @@
*/
.globl .urem
+ .globl _Urem
.urem:
+_Urem: /* needed for export */
! Ready to divide. Compute size of quotient; scale comparand.
orcc %o1, %g0, %o5
diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S
index 54b8e764b042..a231cca37216 100644
--- a/arch/sparc/mm/hypersparc.S
+++ b/arch/sparc/mm/hypersparc.S
@@ -6,7 +6,7 @@
#include <asm/ptrace.h>
#include <asm/psr.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/pgtsrmmu.h>
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index c89a803cbc20..c664b962987c 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -260,7 +260,7 @@ static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot)
{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); }
/* to find an entry in a top-level page table... */
-extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); }
/* Find an entry in the second-level page table.. */
diff --git a/arch/sparc/mm/swift.S b/arch/sparc/mm/swift.S
index 2dcaa5ac1a38..cd90f3fdc4e7 100644
--- a/arch/sparc/mm/swift.S
+++ b/arch/sparc/mm/swift.S
@@ -9,7 +9,7 @@
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/pgtsrmmu.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
.text
.align 4
diff --git a/arch/sparc/mm/tsunami.S b/arch/sparc/mm/tsunami.S
index 8acd1787fde2..697af617594a 100644
--- a/arch/sparc/mm/tsunami.S
+++ b/arch/sparc/mm/tsunami.S
@@ -6,7 +6,7 @@
#include <linux/config.h>
#include <asm/ptrace.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/psr.h>
#include <asm/asi.h>
#include <asm/page.h>
diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S
index f58712d26bf5..3cbd6de18dde 100644
--- a/arch/sparc/mm/viking.S
+++ b/arch/sparc/mm/viking.S
@@ -9,7 +9,7 @@
#include <linux/config.h>
#include <asm/ptrace.h>
#include <asm/psr.h>
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/asi.h>
#include <asm/mxcc.h>
#include <asm/page.h>
diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug
index cd8d39fb954d..fa06ea04837b 100644
--- a/arch/sparc64/Kconfig.debug
+++ b/arch/sparc64/Kconfig.debug
@@ -33,13 +33,13 @@ config DEBUG_BOOTMEM
depends on DEBUG_KERNEL
bool "Debug BOOTMEM initialization"
-# We have a custom atomic_dec_and_lock() implementation but it's not
-# compatible with spinlock debugging so we need to fall back on
-# the generic version in that case.
-config HAVE_DEC_LOCK
- bool
- depends on SMP && !DEBUG_SPINLOCK
- default y
+config DEBUG_PAGEALLOC
+ bool "Page alloc debugging"
+ depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND
+ help
+ Unmap pages from the kernel linear mapping after free_pages().
+ This results in a large slowdown, but helps to find certain types
+ of memory corruptions.
config MCOUNT
bool
diff --git a/arch/sparc64/kernel/asm-offsets.c b/arch/sparc64/kernel/asm-offsets.c
new file mode 100644
index 000000000000..9e263112a6e2
--- /dev/null
+++ b/arch/sparc64/kernel/asm-offsets.c
@@ -0,0 +1 @@
+/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 48756958116b..77ef5df4e5a7 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -39,6 +39,8 @@ struct cpu_fp_info linux_sparc_fpu[] = {
{ 0x3e, 0x15, 0, "UltraSparc III+ integrated FPU"},
{ 0x3e, 0x16, 0, "UltraSparc IIIi integrated FPU"},
{ 0x3e, 0x18, 0, "UltraSparc IV integrated FPU"},
+ { 0x3e, 0x19, 0, "UltraSparc IV+ integrated FPU"},
+ { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"},
};
#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
@@ -53,6 +55,8 @@ struct cpu_iu_info linux_sparc_chips[] = {
{ 0x3e, 0x15, "TI UltraSparc III+ (Cheetah+)"},
{ 0x3e, 0x16, "TI UltraSparc IIIi (Jalapeno)"},
{ 0x3e, 0x18, "TI UltraSparc IV (Jaguar)"},
+ { 0x3e, 0x19, "TI UltraSparc IV+ (Panther)"},
+ { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"},
};
#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
index d710274e516b..df9a1ca8fd77 100644
--- a/arch/sparc64/kernel/devices.c
+++ b/arch/sparc64/kernel/devices.c
@@ -135,6 +135,28 @@ void __init device_scan(void)
cpu_data(0).clock_tick = prom_getintdefault(cpu_node,
"clock-frequency",
0);
+ cpu_data(0).dcache_size = prom_getintdefault(cpu_node,
+ "dcache-size",
+ 16 * 1024);
+ cpu_data(0).dcache_line_size =
+ prom_getintdefault(cpu_node, "dcache-line-size", 32);
+ cpu_data(0).icache_size = prom_getintdefault(cpu_node,
+ "icache-size",
+ 16 * 1024);
+ cpu_data(0).icache_line_size =
+ prom_getintdefault(cpu_node, "icache-line-size", 32);
+ cpu_data(0).ecache_size = prom_getintdefault(cpu_node,
+ "ecache-size",
+ 4 * 1024 * 1024);
+ cpu_data(0).ecache_line_size =
+ prom_getintdefault(cpu_node, "ecache-line-size", 64);
+ printk("CPU[0]: Caches "
+ "D[sz(%d):line_sz(%d)] "
+ "I[sz(%d):line_sz(%d)] "
+ "E[sz(%d):line_sz(%d)]\n",
+ cpu_data(0).dcache_size, cpu_data(0).dcache_line_size,
+ cpu_data(0).icache_size, cpu_data(0).icache_line_size,
+ cpu_data(0).ecache_size, cpu_data(0).ecache_line_size);
}
#endif
diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S
index 538522848ad4..acc889a7f9c1 100644
--- a/arch/sparc64/kernel/dtlb_backend.S
+++ b/arch/sparc64/kernel/dtlb_backend.S
@@ -9,17 +9,7 @@
#include <asm/pgtable.h>
#include <asm/mmu.h>
-#if PAGE_SHIFT == 13
-#define SZ_BITS _PAGE_SZ8K
-#elif PAGE_SHIFT == 16
-#define SZ_BITS _PAGE_SZ64K
-#elif PAGE_SHIFT == 19
-#define SZ_BITS _PAGE_SZ512K
-#elif PAGE_SHIFT == 22
-#define SZ_BITS _PAGE_SZ4MB
-#endif
-
-#define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS)
+#define VALID_SZ_BITS (_PAGE_VALID | _PAGE_SZBITS)
#define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P )
#define VPTE_SHIFT (PAGE_SHIFT - 3)
@@ -163,7 +153,6 @@ sparc64_vpte_continue:
stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS
retry ! Load PTE once again
-#undef SZ_BITS
#undef VALID_SZ_BITS
#undef VPTE_SHIFT
#undef VPTE_BITS
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
index ded2fed23fcc..6528786840c0 100644
--- a/arch/sparc64/kernel/dtlb_base.S
+++ b/arch/sparc64/kernel/dtlb_base.S
@@ -53,39 +53,36 @@
* be guaranteed to be 0 ... mmu_context.h does guarantee this
* by only using 10 bits in the hwcontext value.
*/
-#define CREATE_VPTE_OFFSET1(r1, r2)
+#define CREATE_VPTE_OFFSET1(r1, r2) nop
#define CREATE_VPTE_OFFSET2(r1, r2) \
srax r1, 10, r2
-#define CREATE_VPTE_NOP nop
#else
#define CREATE_VPTE_OFFSET1(r1, r2) \
srax r1, PAGE_SHIFT, r2
#define CREATE_VPTE_OFFSET2(r1, r2) \
sllx r2, 3, r2
-#define CREATE_VPTE_NOP
#endif
/* DTLB ** ICACHE line 1: Quick user TLB misses */
+ mov TLB_SFSR, %g1
ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus?
from_tl1_trap:
rdpr %tl, %g5 ! For TL==3 test
CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
- be,pn %xcc, 3f ! Yep, special processing
+ be,pn %xcc, kvmap ! Yep, special processing
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
cmp %g5, 4 ! Last trap level?
- be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
- nop ! delay slot
/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */
+ be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
+ nop ! delay slot
ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE
1: brgez,pn %g5, longpath ! Invalid, branch out
nop ! Delay-slot
9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
retry ! Trap return
-3: brlz,pt %g4, 9b ! Kernel virtual map?
- xor %g2, %g4, %g5 ! Finish bit twiddles
- ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc
+ nop
/* DTLB ** ICACHE line 3: winfixups+real_faults */
longpath:
@@ -106,8 +103,7 @@ longpath:
nop
nop
nop
- CREATE_VPTE_NOP
+ nop
#undef CREATE_VPTE_OFFSET1
#undef CREATE_VPTE_OFFSET2
-#undef CREATE_VPTE_NOP
diff --git a/arch/sparc64/kernel/dtlb_prot.S b/arch/sparc64/kernel/dtlb_prot.S
index d848bb7374bb..e0a920162604 100644
--- a/arch/sparc64/kernel/dtlb_prot.S
+++ b/arch/sparc64/kernel/dtlb_prot.S
@@ -14,14 +14,14 @@
*/
/* PROT ** ICACHE line 1: User DTLB protection trap */
- stxa %g0, [%g1] ASI_DMMU ! Clear SFSR FaultValid bit
- membar #Sync ! Synchronize ASI stores
- rdpr %pstate, %g5 ! Move into alternate globals
+ mov TLB_SFSR, %g1
+ stxa %g0, [%g1] ASI_DMMU ! Clear FaultValid bit
+ membar #Sync ! Synchronize stores
+ rdpr %pstate, %g5 ! Move into alt-globals
wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
- rdpr %tl, %g1 ! Need to do a winfixup?
+ rdpr %tl, %g1 ! Need a winfixup?
cmp %g1, 1 ! Trap level >1?
- mov TLB_TAG_ACCESS, %g4 ! Prepare reload of vaddr
- nop
+ mov TLB_TAG_ACCESS, %g4 ! For reload of vaddr
/* PROT ** ICACHE line 2: More real fault processing */
bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 3e0badb820c5..11a848402fb1 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -30,164 +30,10 @@
.text
.align 32
- .globl sparc64_vpte_patchme1
- .globl sparc64_vpte_patchme2
-/*
- * On a second level vpte miss, check whether the original fault is to the OBP
- * range (note that this is only possible for instruction miss, data misses to
- * obp range do not use vpte). If so, go back directly to the faulting address.
- * This is because we want to read the tpc, otherwise we have no way of knowing
- * the 8k aligned faulting address if we are using >8k kernel pagesize. This
- * also ensures no vpte range addresses are dropped into tlb while obp is
- * executing (see inherit_locked_prom_mappings() rant).
- */
-sparc64_vpte_nucleus:
- /* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
- mov 0xf, %g5
- sllx %g5, 28, %g5
-
- /* Is addr >= LOW_OBP_ADDRESS? */
- cmp %g4, %g5
- blu,pn %xcc, sparc64_vpte_patchme1
- mov 0x1, %g5
-
- /* Load 0x100000000, which is HI_OBP_ADDRESS. */
- sllx %g5, 32, %g5
-
- /* Is addr < HI_OBP_ADDRESS? */
- cmp %g4, %g5
- blu,pn %xcc, obp_iaddr_patch
- nop
-
- /* These two instructions are patched by paginig_init(). */
-sparc64_vpte_patchme1:
- sethi %hi(0), %g5
-sparc64_vpte_patchme2:
- or %g5, %lo(0), %g5
-
- /* With kernel PGD in %g5, branch back into dtlb_backend. */
- ba,pt %xcc, sparc64_kpte_continue
- andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */
-
-vpte_noent:
- /* Restore previous TAG_ACCESS, %g5 is zero, and we will
- * skip over the trap instruction so that the top level
- * TLB miss handler will thing this %g5 value is just an
- * invalid PTE, thus branching to full fault processing.
- */
- mov TLB_SFSR, %g1
- stxa %g4, [%g1 + %g1] ASI_DMMU
- done
-
- .globl obp_iaddr_patch
-obp_iaddr_patch:
- /* These two instructions patched by inherit_prom_mappings(). */
- sethi %hi(0), %g5
- or %g5, %lo(0), %g5
-
- /* Behave as if we are at TL0. */
- wrpr %g0, 1, %tl
- rdpr %tpc, %g4 /* Find original faulting iaddr */
- srlx %g4, 13, %g4 /* Throw out context bits */
- sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */
-
- /* Restore previous TAG_ACCESS. */
- mov TLB_SFSR, %g1
- stxa %g4, [%g1 + %g1] ASI_IMMU
-
- /* Get PMD offset. */
- srlx %g4, 23, %g6
- and %g6, 0x7ff, %g6
- sllx %g6, 2, %g6
-
- /* Load PMD, is it valid? */
- lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
- brz,pn %g5, longpath
- sllx %g5, 11, %g5
-
- /* Get PTE offset. */
- srlx %g4, 13, %g6
- and %g6, 0x3ff, %g6
- sllx %g6, 3, %g6
-
- /* Load PTE. */
- ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
- brgez,pn %g5, longpath
- nop
-
- /* TLB load and return from trap. */
- stxa %g5, [%g0] ASI_ITLB_DATA_IN
- retry
-
- .globl obp_daddr_patch
-obp_daddr_patch:
- /* These two instructions patched by inherit_prom_mappings(). */
- sethi %hi(0), %g5
- or %g5, %lo(0), %g5
-
- /* Get PMD offset. */
- srlx %g4, 23, %g6
- and %g6, 0x7ff, %g6
- sllx %g6, 2, %g6
-
- /* Load PMD, is it valid? */
- lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
- brz,pn %g5, longpath
- sllx %g5, 11, %g5
-
- /* Get PTE offset. */
- srlx %g4, 13, %g6
- and %g6, 0x3ff, %g6
- sllx %g6, 3, %g6
-
- /* Load PTE. */
- ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
- brgez,pn %g5, longpath
- nop
-
- /* TLB load and return from trap. */
- stxa %g5, [%g0] ASI_DTLB_DATA_IN
- retry
-
-/*
- * On a first level data miss, check whether this is to the OBP range (note
- * that such accesses can be made by prom, as well as by kernel using
- * prom_getproperty on "address"), and if so, do not use vpte access ...
- * rather, use information saved during inherit_prom_mappings() using 8k
- * pagesize.
- */
-kvmap:
- /* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
- mov 0xf, %g5
- sllx %g5, 28, %g5
-
- /* Is addr >= LOW_OBP_ADDRESS? */
- cmp %g4, %g5
- blu,pn %xcc, vmalloc_addr
- mov 0x1, %g5
-
- /* Load 0x100000000, which is HI_OBP_ADDRESS. */
- sllx %g5, 32, %g5
-
- /* Is addr < HI_OBP_ADDRESS? */
- cmp %g4, %g5
- blu,pn %xcc, obp_daddr_patch
- nop
-
-vmalloc_addr:
- /* If we get here, a vmalloc addr accessed, load kernel VPTE. */
- ldxa [%g3 + %g6] ASI_N, %g5
- brgez,pn %g5, longpath
- nop
-
- /* PTE is valid, load into TLB and return from trap. */
- stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
- retry
-
/* This is trivial with the new code... */
.globl do_fpdis
do_fpdis:
- sethi %hi(TSTATE_PEF), %g4 ! IEU0
+ sethi %hi(TSTATE_PEF), %g4
rdpr %tstate, %g5
andcc %g5, %g4, %g0
be,pt %xcc, 1f
@@ -204,18 +50,18 @@ do_fpdis:
add %g0, %g0, %g0
ba,a,pt %xcc, rtrap_clr_l6
-1: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group
- wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles
- andcc %g5, FPRS_FEF, %g0 ! IEU1 Group
- be,a,pt %icc, 1f ! CTI
- clr %g7 ! IEU0
- ldx [%g6 + TI_GSR], %g7 ! Load Group
-1: andcc %g5, FPRS_DL, %g0 ! IEU1
- bne,pn %icc, 2f ! CTI
- fzero %f0 ! FPA
- andcc %g5, FPRS_DU, %g0 ! IEU1 Group
- bne,pn %icc, 1f ! CTI
- fzero %f2 ! FPA
+1: ldub [%g6 + TI_FPSAVED], %g5
+ wr %g0, FPRS_FEF, %fprs
+ andcc %g5, FPRS_FEF, %g0
+ be,a,pt %icc, 1f
+ clr %g7
+ ldx [%g6 + TI_GSR], %g7
+1: andcc %g5, FPRS_DL, %g0
+ bne,pn %icc, 2f
+ fzero %f0
+ andcc %g5, FPRS_DU, %g0
+ bne,pn %icc, 1f
+ fzero %f2
faddd %f0, %f2, %f4
fmuld %f0, %f2, %f6
faddd %f0, %f2, %f8
@@ -251,15 +97,17 @@ do_fpdis:
faddd %f0, %f2, %f4
fmuld %f0, %f2, %f6
ldxa [%g3] ASI_DMMU, %g5
-cplus_fptrap_insn_1:
- sethi %hi(0), %g2
+ sethi %hi(sparc64_kern_sec_context), %g2
+ ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
add %g6, TI_FPREGS + 0xc0, %g2
faddd %f0, %f2, %f8
fmuld %f0, %f2, %f10
- ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-(
+ membar #Sync
+ ldda [%g1] ASI_BLK_S, %f32
ldda [%g2] ASI_BLK_S, %f48
+ membar #Sync
faddd %f0, %f2, %f12
fmuld %f0, %f2, %f14
faddd %f0, %f2, %f16
@@ -270,7 +118,6 @@ cplus_fptrap_insn_1:
fmuld %f0, %f2, %f26
faddd %f0, %f2, %f28
fmuld %f0, %f2, %f30
- membar #Sync
b,pt %xcc, fpdis_exit
nop
2: andcc %g5, FPRS_DU, %g0
@@ -280,15 +127,17 @@ cplus_fptrap_insn_1:
fzero %f34
ldxa [%g3] ASI_DMMU, %g5
add %g6, TI_FPREGS, %g1
-cplus_fptrap_insn_2:
- sethi %hi(0), %g2
+ sethi %hi(sparc64_kern_sec_context), %g2
+ ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
add %g6, TI_FPREGS + 0x40, %g2
faddd %f32, %f34, %f36
fmuld %f32, %f34, %f38
- ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-(
+ membar #Sync
+ ldda [%g1] ASI_BLK_S, %f0
ldda [%g2] ASI_BLK_S, %f16
+ membar #Sync
faddd %f32, %f34, %f40
fmuld %f32, %f34, %f42
faddd %f32, %f34, %f44
@@ -301,18 +150,18 @@ cplus_fptrap_insn_2:
fmuld %f32, %f34, %f58
faddd %f32, %f34, %f60
fmuld %f32, %f34, %f62
- membar #Sync
ba,pt %xcc, fpdis_exit
nop
3: mov SECONDARY_CONTEXT, %g3
add %g6, TI_FPREGS, %g1
ldxa [%g3] ASI_DMMU, %g5
-cplus_fptrap_insn_3:
- sethi %hi(0), %g2
+ sethi %hi(sparc64_kern_sec_context), %g2
+ ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
mov 0x40, %g2
- ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-(
+ membar #Sync
+ ldda [%g1] ASI_BLK_S, %f0
ldda [%g1 + %g2] ASI_BLK_S, %f16
add %g1, 0x80, %g1
ldda [%g1] ASI_BLK_S, %f32
@@ -473,8 +322,8 @@ do_fptrap_after_fsr:
stx %g3, [%g6 + TI_GSR]
mov SECONDARY_CONTEXT, %g3
ldxa [%g3] ASI_DMMU, %g5
-cplus_fptrap_insn_4:
- sethi %hi(0), %g2
+ sethi %hi(sparc64_kern_sec_context), %g2
+ ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
add %g6, TI_FPREGS, %g2
@@ -495,45 +344,17 @@ cplus_fptrap_insn_4:
ba,pt %xcc, etrap
wr %g0, 0, %fprs
-cplus_fptrap_1:
- sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
-
- .globl cheetah_plus_patch_fpdis
-cheetah_plus_patch_fpdis:
- /* We configure the dTLB512_0 for 4MB pages and the
- * dTLB512_1 for 8K pages when in context zero.
- */
- sethi %hi(cplus_fptrap_1), %o0
- lduw [%o0 + %lo(cplus_fptrap_1)], %o1
-
- set cplus_fptrap_insn_1, %o2
- stw %o1, [%o2]
- flush %o2
- set cplus_fptrap_insn_2, %o2
- stw %o1, [%o2]
- flush %o2
- set cplus_fptrap_insn_3, %o2
- stw %o1, [%o2]
- flush %o2
- set cplus_fptrap_insn_4, %o2
- stw %o1, [%o2]
- flush %o2
-
- retl
- nop
-
/* The registers for cross calls will be:
*
* DATA 0: [low 32-bits] Address of function to call, jmp to this
* [high 32-bits] MMU Context Argument 0, place in %g5
- * DATA 1: Address Argument 1, place in %g6
+ * DATA 1: Address Argument 1, place in %g1
* DATA 2: Address Argument 2, place in %g7
*
* With this method we can do most of the cross-call tlb/cache
* flushing very quickly.
*
- * Current CPU's IRQ worklist table is locked into %g1,
- * don't touch.
+ * Current CPU's IRQ worklist table is locked into %g6, don't touch.
*/
.text
.align 32
@@ -1007,13 +828,14 @@ cheetah_plus_dcpe_trap_vector:
nop
do_cheetah_plus_data_parity:
- ba,pt %xcc, etrap
+ rdpr %pil, %g2
+ wrpr %g0, 15, %pil
+ ba,pt %xcc, etrap_irq
rd %pc, %g7
mov 0x0, %o0
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
- ba,pt %xcc, rtrap
- clr %l6
+ ba,a,pt %xcc, rtrap_irq
cheetah_plus_dcpe_trap_vector_tl1:
membar #Sync
@@ -1037,13 +859,14 @@ cheetah_plus_icpe_trap_vector:
nop
do_cheetah_plus_insn_parity:
- ba,pt %xcc, etrap
+ rdpr %pil, %g2
+ wrpr %g0, 15, %pil
+ ba,pt %xcc, etrap_irq
rd %pc, %g7
mov 0x1, %o0
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
- ba,pt %xcc, rtrap
- clr %l6
+ ba,a,pt %xcc, rtrap_irq
cheetah_plus_icpe_trap_vector_tl1:
membar #Sync
@@ -1076,6 +899,10 @@ do_dcpe_tl1:
nop
wrpr %g1, %tl ! Restore original trap level
do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
+ sethi %hi(dcache_parity_tl1_occurred), %g2
+ lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1
+ add %g1, 1, %g1
+ stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)]
/* Reset D-cache parity */
sethi %hi(1 << 16), %g1 ! D-cache size
mov (1 << 5), %g2 ! D-cache line size
@@ -1122,6 +949,10 @@ do_icpe_tl1:
nop
wrpr %g1, %tl ! Restore original trap level
do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
+ sethi %hi(icache_parity_tl1_occurred), %g2
+ lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1
+ add %g1, 1, %g1
+ stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)]
/* Flush I-cache */
sethi %hi(1 << 15), %g1 ! I-cache size
mov (1 << 5), %g2 ! I-cache line size
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index 50d2af1d98ae..0d8eba21111b 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -68,12 +68,8 @@ etrap_irq:
wrpr %g3, 0, %otherwin
wrpr %g2, 0, %wstate
-cplus_etrap_insn_1:
- sethi %hi(0), %g3
- sllx %g3, 32, %g3
-cplus_etrap_insn_2:
- sethi %hi(0), %g2
- or %g3, %g2, %g3
+ sethi %hi(sparc64_kern_pri_context), %g2
+ ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3
stxa %g3, [%l4] ASI_DMMU
flush %l6
wr %g0, ASI_AIUS, %asi
@@ -215,12 +211,8 @@ scetrap: rdpr %pil, %g2
mov PRIMARY_CONTEXT, %l4
wrpr %g3, 0, %otherwin
wrpr %g2, 0, %wstate
-cplus_etrap_insn_3:
- sethi %hi(0), %g3
- sllx %g3, 32, %g3
-cplus_etrap_insn_4:
- sethi %hi(0), %g2
- or %g3, %g2, %g3
+ sethi %hi(sparc64_kern_pri_context), %g2
+ ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3
stxa %g3, [%l4] ASI_DMMU
flush %l6
@@ -264,38 +256,3 @@ cplus_etrap_insn_4:
#undef TASK_REGOFF
#undef ETRAP_PSTATE1
-
-cplus_einsn_1:
- sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
-cplus_einsn_2:
- sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
-
- .globl cheetah_plus_patch_etrap
-cheetah_plus_patch_etrap:
- /* We configure the dTLB512_0 for 4MB pages and the
- * dTLB512_1 for 8K pages when in context zero.
- */
- sethi %hi(cplus_einsn_1), %o0
- sethi %hi(cplus_etrap_insn_1), %o2
- lduw [%o0 + %lo(cplus_einsn_1)], %o1
- or %o2, %lo(cplus_etrap_insn_1), %o2
- stw %o1, [%o2]
- flush %o2
- sethi %hi(cplus_etrap_insn_3), %o2
- or %o2, %lo(cplus_etrap_insn_3), %o2
- stw %o1, [%o2]
- flush %o2
-
- sethi %hi(cplus_einsn_2), %o0
- sethi %hi(cplus_etrap_insn_2), %o2
- lduw [%o0 + %lo(cplus_einsn_2)], %o1
- or %o2, %lo(cplus_etrap_insn_2), %o2
- stw %o1, [%o2]
- flush %o2
- sethi %hi(cplus_etrap_insn_4), %o2
- or %o2, %lo(cplus_etrap_insn_4), %o2
- stw %o1, [%o2]
- flush %o2
-
- retl
- nop
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 1fa06c4e3bdb..b49dcd4504b0 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -28,19 +28,14 @@
#include <asm/mmu.h>
/* This section from from _start to sparc64_boot_end should fit into
- * 0x0000.0000.0040.4000 to 0x0000.0000.0040.8000 and will be sharing space
- * with bootup_user_stack, which is from 0x0000.0000.0040.4000 to
- * 0x0000.0000.0040.6000 and empty_bad_page, which is from
- * 0x0000.0000.0040.6000 to 0x0000.0000.0040.8000.
+ * 0x0000000000404000 to 0x0000000000408000.
*/
-
.text
.globl start, _start, stext, _stext
_start:
start:
_stext:
stext:
-bootup_user_stack:
! 0x0000000000404000
b sparc64_boot
flushw /* Flush register file. */
@@ -80,15 +75,169 @@ sparc_ramdisk_image64:
.xword 0
.word _end
- /* We must be careful, 32-bit OpenBOOT will get confused if it
- * tries to save away a register window to a 64-bit kernel
- * stack address. Flush all windows, disable interrupts,
- * remap if necessary, jump onto kernel trap table, then kernel
- * stack, or else we die.
+ /* PROM cif handler code address is in %o4. */
+sparc64_boot:
+1: rd %pc, %g7
+ set 1b, %g1
+ cmp %g1, %g7
+ be,pn %xcc, sparc64_boot_after_remap
+ mov %o4, %l7
+
+ /* We need to remap the kernel. Use position independant
+ * code to remap us to KERNBASE.
*
- * PROM entry point is on %o4
+ * SILO can invoke us with 32-bit address masking enabled,
+ * so make sure that's clear.
*/
-sparc64_boot:
+ rdpr %pstate, %g1
+ andn %g1, PSTATE_AM, %g1
+ wrpr %g1, 0x0, %pstate
+ ba,a,pt %xcc, 1f
+
+ .globl prom_finddev_name, prom_chosen_path
+ .globl prom_getprop_name, prom_mmu_name
+ .globl prom_callmethod_name, prom_translate_name
+ .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
+ .globl prom_boot_mapped_pc, prom_boot_mapping_mode
+ .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
+prom_finddev_name:
+ .asciz "finddevice"
+prom_chosen_path:
+ .asciz "/chosen"
+prom_getprop_name:
+ .asciz "getprop"
+prom_mmu_name:
+ .asciz "mmu"
+prom_callmethod_name:
+ .asciz "call-method"
+prom_translate_name:
+ .asciz "translate"
+prom_map_name:
+ .asciz "map"
+prom_unmap_name:
+ .asciz "unmap"
+ .align 4
+prom_mmu_ihandle_cache:
+ .word 0
+prom_boot_mapped_pc:
+ .word 0
+prom_boot_mapping_mode:
+ .word 0
+ .align 8
+prom_boot_mapping_phys_high:
+ .xword 0
+prom_boot_mapping_phys_low:
+ .xword 0
+1:
+ rd %pc, %l0
+ mov (1b - prom_finddev_name), %l1
+ mov (1b - prom_chosen_path), %l2
+ mov (1b - prom_boot_mapped_pc), %l3
+ sub %l0, %l1, %l1
+ sub %l0, %l2, %l2
+ sub %l0, %l3, %l3
+ stw %l0, [%l3]
+ sub %sp, (192 + 128), %sp
+
+ /* chosen_node = prom_finddevice("/chosen") */
+ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice"
+ mov 1, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1
+ stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
+ stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen"
+ stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1
+ call %l7
+ add %sp, (2047 + 128), %o0 ! argument array
+
+ ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node
+
+ mov (1b - prom_getprop_name), %l1
+ mov (1b - prom_mmu_name), %l2
+ mov (1b - prom_mmu_ihandle_cache), %l5
+ sub %l0, %l1, %l1
+ sub %l0, %l2, %l2
+ sub %l0, %l5, %l5
+
+ /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */
+ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop"
+ mov 4, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4
+ mov 1, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
+ stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node
+ stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu"
+ stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache
+ mov 4, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3)
+ stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1
+ call %l7
+ add %sp, (2047 + 128), %o0 ! argument array
+
+ mov (1b - prom_callmethod_name), %l1
+ mov (1b - prom_translate_name), %l2
+ sub %l0, %l1, %l1
+ sub %l0, %l2, %l2
+ lduw [%l5], %l5 ! prom_mmu_ihandle_cache
+
+ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method"
+ mov 3, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3
+ mov 5, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5
+ stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate"
+ stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache
+ /* PAGE align */
+ srlx %l0, 13, %l3
+ sllx %l3, 13, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC
+ stx %g0, [%sp + 2047 + 128 + 0x30] ! res1
+ stx %g0, [%sp + 2047 + 128 + 0x38] ! res2
+ stx %g0, [%sp + 2047 + 128 + 0x40] ! res3
+ stx %g0, [%sp + 2047 + 128 + 0x48] ! res4
+ stx %g0, [%sp + 2047 + 128 + 0x50] ! res5
+ call %l7
+ add %sp, (2047 + 128), %o0 ! argument array
+
+ ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode
+ mov (1b - prom_boot_mapping_mode), %l4
+ sub %l0, %l4, %l4
+ stw %l1, [%l4]
+ mov (1b - prom_boot_mapping_phys_high), %l4
+ sub %l0, %l4, %l4
+ ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high
+ stx %l2, [%l4 + 0x0]
+ ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low
+ /* 4MB align */
+ srlx %l3, 22, %l3
+ sllx %l3, 22, %l3
+ stx %l3, [%l4 + 0x8]
+
+ /* Leave service as-is, "call-method" */
+ mov 7, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7
+ mov 1, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
+ mov (1b - prom_map_name), %l3
+ sub %l0, %l3, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map"
+ /* Leave arg2 as-is, prom_mmu_ihandle_cache */
+ mov -1, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default)
+ sethi %hi(8 * 1024 * 1024), %l3
+ stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB)
+ sethi %hi(KERNBASE), %l3
+ stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE)
+ stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty
+ mov (1b - prom_boot_mapping_phys_low), %l3
+ sub %l0, %l3, %l3
+ ldx [%l3], %l3
+ stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr
+ call %l7
+ add %sp, (2047 + 128), %o0 ! argument array
+
+ add %sp, (192 + 128), %sp
+
+sparc64_boot_after_remap:
BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
ba,pt %xcc, spitfire_boot
@@ -125,185 +274,7 @@ cheetah_generic_boot:
stxa %g0, [%g3] ASI_IMMU
membar #Sync
- wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
- wr %g0, 0, %fprs
-
- /* Just like for Spitfire, we probe itlb-2 for a mapping which
- * matches our current %pc. We take the physical address in
- * that mapping and use it to make our own.
- */
-
- /* %g5 holds the tlb data */
- sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
- sllx %g5, 32, %g5
- or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
-
- /* Put PADDR tlb data mask into %g3. */
- sethi %uhi(_PAGE_PADDR), %g3
- or %g3, %ulo(_PAGE_PADDR), %g3
- sllx %g3, 32, %g3
- sethi %hi(_PAGE_PADDR), %g7
- or %g7, %lo(_PAGE_PADDR), %g7
- or %g3, %g7, %g3
-
- set 2 << 16, %l0 /* TLB entry walker. */
- set 0x1fff, %l2 /* Page mask. */
- rd %pc, %l3
- andn %l3, %l2, %g2 /* vaddr comparator */
-
-1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
- membar #Sync
- andn %g1, %l2, %g1
- cmp %g1, %g2
- be,pn %xcc, cheetah_got_tlbentry
- nop
- and %l0, (127 << 3), %g1
- cmp %g1, (127 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- /* Search the small TLB. OBP never maps us like that but
- * newer SILO can.
- */
- clr %l0
-
-1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
- membar #Sync
- andn %g1, %l2, %g1
- cmp %g1, %g2
- be,pn %xcc, cheetah_got_tlbentry
- nop
- cmp %l0, (15 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- /* BUG() if we get here... */
- ta 0x5
-
-cheetah_got_tlbentry:
- ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0
- ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
- membar #Sync
- and %g1, %g3, %g1
- set 0x5fff, %l0
- andn %g1, %l0, %g1
- or %g5, %g1, %g5
-
- /* Clear out any KERNBASE area entries. */
- set 2 << 16, %l0
- sethi %hi(KERNBASE), %g3
- sethi %hi(KERNBASE<<1), %g7
- mov TLB_TAG_ACCESS, %l7
-
- /* First, check ITLB */
-1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
- membar #Sync
- andn %g1, %l2, %g1
- cmp %g1, %g3
- blu,pn %xcc, 2f
- cmp %g1, %g7
- bgeu,pn %xcc, 2f
- nop
- stxa %g0, [%l7] ASI_IMMU
- membar #Sync
- stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
- membar #Sync
-
-2: and %l0, (127 << 3), %g1
- cmp %g1, (127 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- /* Next, check DTLB */
- set 2 << 16, %l0
-1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
- membar #Sync
- andn %g1, %l2, %g1
- cmp %g1, %g3
- blu,pn %xcc, 2f
- cmp %g1, %g7
- bgeu,pn %xcc, 2f
- nop
- stxa %g0, [%l7] ASI_DMMU
- membar #Sync
- stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
- membar #Sync
-
-2: and %l0, (511 << 3), %g1
- cmp %g1, (511 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- /* On Cheetah+, have to check second DTLB. */
- BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f)
- ba,pt %xcc, 9f
- nop
-
-2: set 3 << 16, %l0
-1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
- membar #Sync
- andn %g1, %l2, %g1
- cmp %g1, %g3
- blu,pn %xcc, 2f
- cmp %g1, %g7
- bgeu,pn %xcc, 2f
- nop
- stxa %g0, [%l7] ASI_DMMU
- membar #Sync
- stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
- membar #Sync
-
-2: and %l0, (511 << 3), %g1
- cmp %g1, (511 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
-9:
-
- /* Now lock the TTE we created into ITLB-0 and DTLB-0,
- * entry 15 (and maybe 14 too).
- */
- sethi %hi(KERNBASE), %g3
- set (0 << 16) | (15 << 3), %g7
- stxa %g3, [%l7] ASI_DMMU
- membar #Sync
- stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
- membar #Sync
- stxa %g3, [%l7] ASI_IMMU
- membar #Sync
- stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
- membar #Sync
- flush %g3
- membar #Sync
- sethi %hi(_end), %g3 /* Check for bigkernel case */
- or %g3, %lo(_end), %g3
- srl %g3, 23, %g3 /* Check if _end > 8M */
- brz,pt %g3, 1f
- sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
- sethi %hi(0x400000), %g3
- or %g3, %lo(0x400000), %g3
- add %g5, %g3, %g5 /* New tte data */
- andn %g5, (_PAGE_G), %g5
- sethi %hi(KERNBASE+0x400000), %g3
- or %g3, %lo(KERNBASE+0x400000), %g3
- set (0 << 16) | (14 << 3), %g7
- stxa %g3, [%l7] ASI_DMMU
- membar #Sync
- stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
- membar #Sync
- stxa %g3, [%l7] ASI_IMMU
- membar #Sync
- stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
- membar #Sync
- flush %g3
- membar #Sync
- sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
- ba,pt %xcc, 1f
- nop
-
-1: set sun4u_init, %g2
- jmpl %g2 + %g0, %g0
- nop
+ ba,a,pt %xcc, jump_to_sun4u_init
spitfire_boot:
/* Typically PROM has already enabled both MMU's and both on-chip
@@ -313,6 +284,7 @@ spitfire_boot:
stxa %g1, [%g0] ASI_LSU_CONTROL
membar #Sync
+jump_to_sun4u_init:
/*
* Make sure we are in privileged mode, have address masking,
* using the ordinary globals and have enabled floating
@@ -324,151 +296,6 @@ spitfire_boot:
wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
wr %g0, 0, %fprs
-spitfire_create_mappings:
- /* %g5 holds the tlb data */
- sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
- sllx %g5, 32, %g5
- or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
-
- /* Base of physical memory cannot reliably be assumed to be
- * at 0x0! Figure out where it happens to be. -DaveM
- */
-
- /* Put PADDR tlb data mask into %g3. */
- sethi %uhi(_PAGE_PADDR_SF), %g3
- or %g3, %ulo(_PAGE_PADDR_SF), %g3
- sllx %g3, 32, %g3
- sethi %hi(_PAGE_PADDR_SF), %g7
- or %g7, %lo(_PAGE_PADDR_SF), %g7
- or %g3, %g7, %g3
-
- /* Walk through entire ITLB, looking for entry which maps
- * our %pc currently, stick PADDR from there into %g5 tlb data.
- */
- clr %l0 /* TLB entry walker. */
- set 0x1fff, %l2 /* Page mask. */
- rd %pc, %l3
- andn %l3, %l2, %g2 /* vaddr comparator */
-1:
- /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
- ldxa [%l0] ASI_ITLB_TAG_READ, %g1
- nop
- nop
- nop
- andn %g1, %l2, %g1 /* Get vaddr */
- cmp %g1, %g2
- be,a,pn %xcc, spitfire_got_tlbentry
- ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
- cmp %l0, (63 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- /* BUG() if we get here... */
- ta 0x5
-
-spitfire_got_tlbentry:
- /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */
- nop
- nop
- nop
- and %g1, %g3, %g1 /* Mask to just get paddr bits. */
- set 0x5fff, %l3 /* Mask offset to get phys base. */
- andn %g1, %l3, %g1
-
- /* NOTE: We hold on to %g1 paddr base as we need it below to lock
- * NOTE: the PROM cif code into the TLB.
- */
-
- or %g5, %g1, %g5 /* Or it into TAG being built. */
-
- clr %l0 /* TLB entry walker. */
- sethi %hi(KERNBASE), %g3 /* 4M lower limit */
- sethi %hi(KERNBASE<<1), %g7 /* 8M upper limit */
- mov TLB_TAG_ACCESS, %l7
-1:
- /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
- ldxa [%l0] ASI_ITLB_TAG_READ, %g1
- nop
- nop
- nop
- andn %g1, %l2, %g1 /* Get vaddr */
- cmp %g1, %g3
- blu,pn %xcc, 2f
- cmp %g1, %g7
- bgeu,pn %xcc, 2f
- nop
- stxa %g0, [%l7] ASI_IMMU
- stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
- membar #Sync
-2:
- cmp %l0, (63 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- nop; nop; nop
-
- clr %l0 /* TLB entry walker. */
-1:
- /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
- ldxa [%l0] ASI_DTLB_TAG_READ, %g1
- nop
- nop
- nop
- andn %g1, %l2, %g1 /* Get vaddr */
- cmp %g1, %g3
- blu,pn %xcc, 2f
- cmp %g1, %g7
- bgeu,pn %xcc, 2f
- nop
- stxa %g0, [%l7] ASI_DMMU
- stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
- membar #Sync
-2:
- cmp %l0, (63 << 3)
- blu,pt %xcc, 1b
- add %l0, (1 << 3), %l0
-
- nop; nop; nop
-
-
- /* PROM never puts any TLB entries into the MMU with the lock bit
- * set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too.
- */
-
- sethi %hi(KERNBASE), %g3
- mov (63 << 3), %g7
- stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */
- stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */
- membar #Sync
- stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */
- stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */
- membar #Sync
- flush %g3
- membar #Sync
- sethi %hi(_end), %g3 /* Check for bigkernel case */
- or %g3, %lo(_end), %g3
- srl %g3, 23, %g3 /* Check if _end > 8M */
- brz,pt %g3, 2f
- sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
- sethi %hi(0x400000), %g3
- or %g3, %lo(0x400000), %g3
- add %g5, %g3, %g5 /* New tte data */
- andn %g5, (_PAGE_G), %g5
- sethi %hi(KERNBASE+0x400000), %g3
- or %g3, %lo(KERNBASE+0x400000), %g3
- mov (62 << 3), %g7
- stxa %g3, [%l7] ASI_DMMU
- stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
- membar #Sync
- stxa %g3, [%l7] ASI_IMMU
- stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
- membar #Sync
- flush %g3
- membar #Sync
- sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
-2: ba,pt %xcc, 1f
- nop
-1:
set sun4u_init, %g2
jmpl %g2 + %g0, %g0
nop
@@ -483,38 +310,12 @@ sun4u_init:
stxa %g0, [%g7] ASI_DMMU
membar #Sync
- /* We are now safely (we hope) in Nucleus context (0), rewrite
- * the KERNBASE TTE's so they no longer have the global bit set.
- * Don't forget to setup TAG_ACCESS first 8-)
- */
- mov TLB_TAG_ACCESS, %g2
- stxa %g3, [%g2] ASI_IMMU
- stxa %g3, [%g2] ASI_DMMU
- membar #Sync
-
BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup)
ba,pt %xcc, spitfire_tlb_fixup
nop
cheetah_tlb_fixup:
- set (0 << 16) | (15 << 3), %g7
- ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g0
- ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
- andn %g1, (_PAGE_G), %g1
- stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
- membar #Sync
-
- ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g0
- ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
- andn %g1, (_PAGE_G), %g1
- stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
- membar #Sync
-
- /* Kill instruction prefetch queues. */
- flush %g3
- membar #Sync
-
mov 2, %g2 /* Set TLB type to cheetah+. */
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
@@ -523,23 +324,7 @@ cheetah_tlb_fixup:
1: sethi %hi(tlb_type), %g1
stw %g2, [%g1 + %lo(tlb_type)]
- BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
- ba,pt %xcc, 2f
- nop
-
-1: /* Patch context register writes to support nucleus page
- * size correctly.
- */
- call cheetah_plus_patch_etrap
- nop
- call cheetah_plus_patch_rtrap
- nop
- call cheetah_plus_patch_fpdis
- nop
- call cheetah_plus_patch_winfixup
- nop
-
-2: /* Patch copy/page operations to cheetah optimized versions. */
+ /* Patch copy/page operations to cheetah optimized versions. */
call cheetah_patch_copyops
nop
call cheetah_patch_copy_page
@@ -551,21 +336,6 @@ cheetah_tlb_fixup:
nop
spitfire_tlb_fixup:
- mov (63 << 3), %g7
- ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
- andn %g1, (_PAGE_G), %g1
- stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
- membar #Sync
-
- ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
- andn %g1, (_PAGE_G), %g1
- stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
- membar #Sync
-
- /* Kill instruction prefetch queues. */
- flush %g3
- membar #Sync
-
/* Set TLB type to spitfire. */
mov 0, %g2
sethi %hi(tlb_type), %g1
@@ -578,24 +348,6 @@ tlb_fixup_done:
mov %sp, %l6
mov %o4, %l7
-#if 0 /* We don't do it like this anymore, but for historical hack value
- * I leave this snippet here to show how crazy we can be sometimes. 8-)
- */
-
- /* Setup "Linux Current Register", thanks Sun 8-) */
- wr %g0, 0x1, %pcr
-
- /* Blackbird errata workaround. See commentary in
- * smp.c:smp_percpu_timer_interrupt() for more
- * information.
- */
- ba,pt %xcc, 99f
- nop
- .align 64
-99: wr %g6, %g0, %pic
- rd %pic, %g0
-#endif
-
wr %g0, ASI_P, %asi
mov 1, %g1
sllx %g1, THREAD_SHIFT, %g1
@@ -629,32 +381,78 @@ tlb_fixup_done:
nop
/* Not reached... */
-/* IMPORTANT NOTE: Whenever making changes here, check
- * trampoline.S as well. -jj */
- .globl setup_tba
-setup_tba: /* i0 = is_starfire */
- save %sp, -160, %sp
+ /* This is meant to allow the sharing of this code between
+ * boot processor invocation (via setup_tba() below) and
+ * secondary processor startup (via trampoline.S). The
+ * former does use this code, the latter does not yet due
+ * to some complexities. That should be fixed up at some
+ * point.
+ *
+ * There used to be enormous complexity wrt. transferring
+ * over from the firwmare's trap table to the Linux kernel's.
+ * For example, there was a chicken & egg problem wrt. building
+ * the OBP page tables, yet needing to be on the Linux kernel
+ * trap table (to translate PAGE_OFFSET addresses) in order to
+ * do that.
+ *
+ * We now handle OBP tlb misses differently, via linear lookups
+ * into the prom_trans[] array. So that specific problem no
+ * longer exists. Yet, unfortunately there are still some issues
+ * preventing trampoline.S from using this code... ho hum.
+ */
+ .globl setup_trap_table
+setup_trap_table:
+ save %sp, -192, %sp
- rdpr %tba, %g7
- sethi %hi(prom_tba), %o1
- or %o1, %lo(prom_tba), %o1
- stx %g7, [%o1]
+ /* Force interrupts to be disabled. */
+ rdpr %pstate, %o1
+ andn %o1, PSTATE_IE, %o1
+ wrpr %o1, 0x0, %pstate
+ wrpr %g0, 15, %pil
+
+ /* Make the firmware call to jump over to the Linux trap table. */
+ call prom_set_trap_table
+ sethi %hi(sparc64_ttable_tl0), %o0
+
+ /* Start using proper page size encodings in ctx register. */
+ sethi %hi(sparc64_kern_pri_context), %g3
+ ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
+ mov PRIMARY_CONTEXT, %g1
+ stxa %g2, [%g1] ASI_DMMU
+ membar #Sync
+
+ /* The Linux trap handlers expect various trap global registers
+ * to be setup with some fixed values. So here we set these
+ * up very carefully. These globals are:
+ *
+ * Alternate Globals (PSTATE_AG):
+ *
+ * %g6 --> current_thread_info()
+ *
+ * MMU Globals (PSTATE_MG):
+ *
+ * %g1 --> TLB_SFSR
+ * %g2 --> ((_PAGE_VALID | _PAGE_SZ4MB |
+ * _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
+ * ^ 0xfffff80000000000)
+ * (this %g2 value is used for computing the PAGE_OFFSET kernel
+ * TLB entries quickly, the virtual address of the fault XOR'd
+ * with this %g2 value is the PTE to load into the TLB)
+ * %g3 --> VPTE_BASE_CHEETAH or VPTE_BASE_SPITFIRE
+ *
+ * Interrupt Globals (PSTATE_IG, setup by init_irqwork_curcpu()):
+ *
+ * %g6 --> __irq_work[smp_processor_id()]
+ */
- /* Setup "Linux" globals 8-) */
rdpr %pstate, %o1
mov %g6, %o2
- wrpr %o1, (PSTATE_AG|PSTATE_IE), %pstate
- sethi %hi(sparc64_ttable_tl0), %g1
- wrpr %g1, %tba
+ wrpr %o1, PSTATE_AG, %pstate
mov %o2, %g6
- /* Set up MMU globals */
- wrpr %o1, (PSTATE_MG|PSTATE_IE), %pstate
-
- /* Set fixed globals used by dTLB miss handler. */
#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
-
+ wrpr %o1, PSTATE_MG, %pstate
mov TSB_REG, %g1
stxa %g0, [%g1] ASI_DMMU
membar #Sync
@@ -666,17 +464,17 @@ setup_tba: /* i0 = is_starfire */
sllx %g2, 32, %g2
or %g2, KERN_LOWBITS, %g2
- BRANCH_IF_ANY_CHEETAH(g3,g7,cheetah_vpte_base)
- ba,pt %xcc, spitfire_vpte_base
+ BRANCH_IF_ANY_CHEETAH(g3,g7,8f)
+ ba,pt %xcc, 9f
nop
-cheetah_vpte_base:
+8:
sethi %uhi(VPTE_BASE_CHEETAH), %g3
or %g3, %ulo(VPTE_BASE_CHEETAH), %g3
ba,pt %xcc, 2f
sllx %g3, 32, %g3
-spitfire_vpte_base:
+9:
sethi %uhi(VPTE_BASE_SPITFIRE), %g3
or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
sllx %g3, 32, %g3
@@ -702,48 +500,55 @@ spitfire_vpte_base:
sllx %o2, 32, %o2
wr %o2, %asr25
- /* Ok, we're done setting up all the state our trap mechanims needs,
- * now get back into normal globals and let the PROM know what is up.
- */
2:
wrpr %g0, %g0, %wstate
- wrpr %o1, PSTATE_IE, %pstate
+ wrpr %o1, 0x0, %pstate
call init_irqwork_curcpu
nop
- call prom_set_trap_table
- sethi %hi(sparc64_ttable_tl0), %o0
-
- BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f)
- ba,pt %xcc, 2f
- nop
-
-1: /* Start using proper page size encodings in ctx register. */
- sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
- mov PRIMARY_CONTEXT, %g1
- sllx %g3, 32, %g3
- sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
- or %g3, %g2, %g3
- stxa %g3, [%g1] ASI_DMMU
- membar #Sync
-
-2:
+ /* Now we can turn interrupts back on. */
rdpr %pstate, %o1
or %o1, PSTATE_IE, %o1
wrpr %o1, 0, %pstate
+ wrpr %g0, 0x0, %pil
+
+ ret
+ restore
+
+ .globl setup_tba
+setup_tba: /* i0 = is_starfire */
+ save %sp, -192, %sp
+
+ /* The boot processor is the only cpu which invokes this
+ * routine, the other cpus set things up via trampoline.S.
+ * So save the OBP trap table address here.
+ */
+ rdpr %tba, %g7
+ sethi %hi(prom_tba), %o1
+ or %o1, %lo(prom_tba), %o1
+ stx %g7, [%o1]
+
+ call setup_trap_table
+ nop
ret
restore
+sparc64_boot_end:
+
+#include "systbls.S"
+#include "ktlb.S"
+#include "etrap.S"
+#include "rtrap.S"
+#include "winfixup.S"
+#include "entry.S"
/*
- * The following skips make sure the trap table in ttable.S is aligned
+ * The following skip makes sure the trap table in ttable.S is aligned
* on a 32K boundary as required by the v9 specs for TBA register.
*/
-sparc64_boot_end:
- .skip 0x2000 + _start - sparc64_boot_end
-bootup_user_stack_end:
- .skip 0x2000
+1:
+ .skip 0x4000 + _start - 1b
#ifdef CONFIG_SBUS
/* This is just a hack to fool make depend config.h discovering
@@ -755,20 +560,6 @@ bootup_user_stack_end:
! 0x0000000000408000
#include "ttable.S"
-#include "systbls.S"
-
- .align 1024
- .globl swapper_pg_dir
-swapper_pg_dir:
- .word 0
-
-#include "etrap.S"
-#include "rtrap.S"
-#include "winfixup.S"
-#include "entry.S"
-
- /* This is just anal retentiveness on my part... */
- .align 16384
.data
.align 8
@@ -776,8 +567,11 @@ swapper_pg_dir:
prom_tba: .xword 0
tlb_type: .word 0 /* Must NOT end up in BSS */
.section ".fixup",#alloc,#execinstr
- .globl __ret_efault
+
+ .globl __ret_efault, __retl_efault
__ret_efault:
ret
restore %g0, -EFAULT, %o0
-
+__retl_efault:
+ retl
+ mov -EFAULT, %o0
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index c9b69167632a..233526ba3abe 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -27,6 +27,7 @@
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/irq.h>
+#include <asm/io.h>
#include <asm/sbus.h>
#include <asm/iommu.h>
#include <asm/upa.h>
diff --git a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S
index b5e32dfa4fbc..4951ff8f6877 100644
--- a/arch/sparc64/kernel/itlb_base.S
+++ b/arch/sparc64/kernel/itlb_base.S
@@ -15,14 +15,12 @@
*/
#define CREATE_VPTE_OFFSET1(r1, r2) \
srax r1, 10, r2
-#define CREATE_VPTE_OFFSET2(r1, r2)
-#define CREATE_VPTE_NOP nop
+#define CREATE_VPTE_OFFSET2(r1, r2) nop
#else /* PAGE_SHIFT */
#define CREATE_VPTE_OFFSET1(r1, r2) \
srax r1, PAGE_SHIFT, r2
#define CREATE_VPTE_OFFSET2(r1, r2) \
sllx r2, 3, r2
-#define CREATE_VPTE_NOP
#endif /* PAGE_SHIFT */
@@ -36,6 +34,7 @@
*/
/* ITLB ** ICACHE line 1: Quick user TLB misses */
+ mov TLB_SFSR, %g1
ldxa [%g1 + %g1] ASI_IMMU, %g4 ! Get TAG_ACCESS
CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
@@ -43,41 +42,38 @@
1: brgez,pn %g5, 3f ! Not valid, branch out
sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot
andcc %g5, %g4, %g0 ! Executable?
+
+/* ITLB ** ICACHE line 2: Real faults */
be,pn %xcc, 3f ! Nope, branch.
nop ! Delay-slot
2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
retry ! Trap return
-3: rdpr %pstate, %g4 ! Move into alternate globals
-
-/* ITLB ** ICACHE line 2: Real faults */
+3: rdpr %pstate, %g4 ! Move into alt-globals
wrpr %g4, PSTATE_AG|PSTATE_MG, %pstate
rdpr %tpc, %g5 ! And load faulting VA
mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB
-sparc64_realfault_common: ! Called by TL0 dtlb_miss too
+
+/* ITLB ** ICACHE line 3: Finish faults */
+sparc64_realfault_common: ! Called by dtlb_miss
stb %g4, [%g6 + TI_FAULT_CODE]
stx %g5, [%g6 + TI_FAULT_ADDR]
ba,pt %xcc, etrap ! Save state
1: rd %pc, %g7 ! ...
- nop
-
-/* ITLB ** ICACHE line 3: Finish faults + window fixups */
call do_sparc64_fault ! Call fault handler
add %sp, PTREGS_OFF, %o0! Compute pt_regs arg
ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state
nop
+
+/* ITLB ** ICACHE line 4: Window fixups */
winfix_trampoline:
rdpr %tpc, %g3 ! Prepare winfixup TNPC
- or %g3, 0x7c, %g3 ! Compute offset to branch
+ or %g3, 0x7c, %g3 ! Compute branch offset
wrpr %g3, %tnpc ! Write it into TNPC
done ! Do it to it
-
-/* ITLB ** ICACHE line 4: Unused... */
nop
nop
nop
nop
- CREATE_VPTE_NOP
#undef CREATE_VPTE_OFFSET1
#undef CREATE_VPTE_OFFSET2
-#undef CREATE_VPTE_NOP
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
new file mode 100644
index 000000000000..d9244d3c9f73
--- /dev/null
+++ b/arch/sparc64/kernel/ktlb.S
@@ -0,0 +1,194 @@
+/* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling.
+ *
+ * Copyright (C) 1995, 1997, 2005 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 1996 Eddie C. Dost (ecd@brainaid.de)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+*/
+
+#include <linux/config.h>
+#include <asm/head.h>
+#include <asm/asi.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+ .text
+ .align 32
+
+/*
+ * On a second level vpte miss, check whether the original fault is to the OBP
+ * range (note that this is only possible for instruction miss, data misses to
+ * obp range do not use vpte). If so, go back directly to the faulting address.
+ * This is because we want to read the tpc, otherwise we have no way of knowing
+ * the 8k aligned faulting address if we are using >8k kernel pagesize. This
+ * also ensures no vpte range addresses are dropped into tlb while obp is
+ * executing (see inherit_locked_prom_mappings() rant).
+ */
+sparc64_vpte_nucleus:
+ /* Note that kvmap below has verified that the address is
+ * in the range MODULES_VADDR --> VMALLOC_END already. So
+ * here we need only check if it is an OBP address or not.
+ */
+ sethi %hi(LOW_OBP_ADDRESS), %g5
+ cmp %g4, %g5
+ blu,pn %xcc, kern_vpte
+ mov 0x1, %g5
+ sllx %g5, 32, %g5
+ cmp %g4, %g5
+ blu,pn %xcc, vpte_insn_obp
+ nop
+
+ /* These two instructions are patched by paginig_init(). */
+kern_vpte:
+ sethi %hi(swapper_pgd_zero), %g5
+ lduw [%g5 + %lo(swapper_pgd_zero)], %g5
+
+ /* With kernel PGD in %g5, branch back into dtlb_backend. */
+ ba,pt %xcc, sparc64_kpte_continue
+ andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */
+
+vpte_noent:
+ /* Restore previous TAG_ACCESS, %g5 is zero, and we will
+ * skip over the trap instruction so that the top level
+ * TLB miss handler will thing this %g5 value is just an
+ * invalid PTE, thus branching to full fault processing.
+ */
+ mov TLB_SFSR, %g1
+ stxa %g4, [%g1 + %g1] ASI_DMMU
+ done
+
+vpte_insn_obp:
+ /* Behave as if we are at TL0. */
+ wrpr %g0, 1, %tl
+ rdpr %tpc, %g4 /* Find original faulting iaddr */
+ srlx %g4, 13, %g4 /* Throw out context bits */
+ sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */
+
+ /* Restore previous TAG_ACCESS. */
+ mov TLB_SFSR, %g1
+ stxa %g4, [%g1 + %g1] ASI_IMMU
+
+ sethi %hi(prom_trans), %g5
+ or %g5, %lo(prom_trans), %g5
+
+1: ldx [%g5 + 0x00], %g6 ! base
+ brz,a,pn %g6, longpath ! no more entries, fail
+ mov TLB_SFSR, %g1 ! and restore %g1
+ ldx [%g5 + 0x08], %g1 ! len
+ add %g6, %g1, %g1 ! end
+ cmp %g6, %g4
+ bgu,pt %xcc, 2f
+ cmp %g4, %g1
+ bgeu,pt %xcc, 2f
+ ldx [%g5 + 0x10], %g1 ! PTE
+
+ /* TLB load, restore %g1, and return from trap. */
+ sub %g4, %g6, %g6
+ add %g1, %g6, %g5
+ mov TLB_SFSR, %g1
+ stxa %g5, [%g0] ASI_ITLB_DATA_IN
+ retry
+
+2: ba,pt %xcc, 1b
+ add %g5, (3 * 8), %g5 ! next entry
+
+kvmap_do_obp:
+ sethi %hi(prom_trans), %g5
+ or %g5, %lo(prom_trans), %g5
+ srlx %g4, 13, %g4
+ sllx %g4, 13, %g4
+
+1: ldx [%g5 + 0x00], %g6 ! base
+ brz,a,pn %g6, longpath ! no more entries, fail
+ mov TLB_SFSR, %g1 ! and restore %g1
+ ldx [%g5 + 0x08], %g1 ! len
+ add %g6, %g1, %g1 ! end
+ cmp %g6, %g4
+ bgu,pt %xcc, 2f
+ cmp %g4, %g1
+ bgeu,pt %xcc, 2f
+ ldx [%g5 + 0x10], %g1 ! PTE
+
+ /* TLB load, restore %g1, and return from trap. */
+ sub %g4, %g6, %g6
+ add %g1, %g6, %g5
+ mov TLB_SFSR, %g1
+ stxa %g5, [%g0] ASI_DTLB_DATA_IN
+ retry
+
+2: ba,pt %xcc, 1b
+ add %g5, (3 * 8), %g5 ! next entry
+
+/*
+ * On a first level data miss, check whether this is to the OBP range (note
+ * that such accesses can be made by prom, as well as by kernel using
+ * prom_getproperty on "address"), and if so, do not use vpte access ...
+ * rather, use information saved during inherit_prom_mappings() using 8k
+ * pagesize.
+ */
+ .align 32
+kvmap:
+ brgez,pn %g4, kvmap_nonlinear
+ nop
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+ .globl kvmap_linear_patch
+kvmap_linear_patch:
+#endif
+ ba,pt %xcc, kvmap_load
+ xor %g2, %g4, %g5
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+ sethi %hi(swapper_pg_dir), %g5
+ or %g5, %lo(swapper_pg_dir), %g5
+ sllx %g4, 64 - (PGDIR_SHIFT + PGDIR_BITS), %g6
+ srlx %g6, 64 - PAGE_SHIFT, %g6
+ andn %g6, 0x3, %g6
+ lduw [%g5 + %g6], %g5
+ brz,pn %g5, longpath
+ sllx %g4, 64 - (PMD_SHIFT + PMD_BITS), %g6
+ srlx %g6, 64 - PAGE_SHIFT, %g6
+ sllx %g5, 11, %g5
+ andn %g6, 0x3, %g6
+ lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
+ brz,pn %g5, longpath
+ sllx %g4, 64 - PMD_SHIFT, %g6
+ srlx %g6, 64 - PAGE_SHIFT, %g6
+ sllx %g5, 11, %g5
+ andn %g6, 0x7, %g6
+ ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
+ brz,pn %g5, longpath
+ nop
+ ba,a,pt %xcc, kvmap_load
+#endif
+
+kvmap_nonlinear:
+ sethi %hi(MODULES_VADDR), %g5
+ cmp %g4, %g5
+ blu,pn %xcc, longpath
+ mov (VMALLOC_END >> 24), %g5
+ sllx %g5, 24, %g5
+ cmp %g4, %g5
+ bgeu,pn %xcc, longpath
+ nop
+
+kvmap_check_obp:
+ sethi %hi(LOW_OBP_ADDRESS), %g5
+ cmp %g4, %g5
+ blu,pn %xcc, kvmap_vmalloc_addr
+ mov 0x1, %g5
+ sllx %g5, 32, %g5
+ cmp %g4, %g5
+ blu,pn %xcc, kvmap_do_obp
+ nop
+
+kvmap_vmalloc_addr:
+ /* If we get here, a vmalloc addr was accessed, load kernel VPTE. */
+ ldxa [%g3 + %g6] ASI_N, %g5
+ brgez,pn %g5, longpath
+ nop
+
+kvmap_load:
+ /* PTE is valid, load into TLB and return from trap. */
+ stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
+ retry
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index ec8bf4012c0c..2ff7c32ab0ce 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -359,134 +359,17 @@ void pcibios_fixup_bus(struct pci_bus *pbus)
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_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 425c60cfea19..a11910be1013 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -49,12 +49,6 @@ static void __iommu_flushall(struct pci_iommu *iommu)
/* Ensure completion of previous PIO writes. */
(void) pci_iommu_read(iommu->write_complete_reg);
-
- /* Now update everyone's flush point. */
- for (entry = 0; entry < PBM_NCLUSTERS; entry++) {
- iommu->alloc_info[entry].flush =
- iommu->alloc_info[entry].next;
- }
}
#define IOPTE_CONSISTENT(CTX) \
@@ -80,120 +74,117 @@ static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
iopte_val(*iopte) = val;
}
-void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize)
+/* Based largely upon the ppc64 iommu allocator. */
+static long pci_arena_alloc(struct pci_iommu *iommu, unsigned long npages)
{
- int i;
-
- tsbsize /= sizeof(iopte_t);
-
- for (i = 0; i < tsbsize; i++)
- iopte_make_dummy(iommu, &iommu->page_table[i]);
-}
-
-static iopte_t *alloc_streaming_cluster(struct pci_iommu *iommu, unsigned long npages)
-{
- iopte_t *iopte, *limit, *first;
- unsigned long cnum, ent, flush_point;
-
- cnum = 0;
- while ((1UL << cnum) < npages)
- cnum++;
- iopte = (iommu->page_table +
- (cnum << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)));
-
- if (cnum == 0)
- limit = (iommu->page_table +
- iommu->lowest_consistent_map);
- else
- limit = (iopte +
- (1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)));
-
- iopte += ((ent = iommu->alloc_info[cnum].next) << cnum);
- flush_point = iommu->alloc_info[cnum].flush;
-
- first = iopte;
- for (;;) {
- if (IOPTE_IS_DUMMY(iommu, iopte)) {
- if ((iopte + (1 << cnum)) >= limit)
- ent = 0;
- else
- ent = ent + 1;
- iommu->alloc_info[cnum].next = ent;
- if (ent == flush_point)
- __iommu_flushall(iommu);
- break;
+ struct pci_iommu_arena *arena = &iommu->arena;
+ unsigned long n, i, start, end, limit;
+ int pass;
+
+ limit = arena->limit;
+ start = arena->hint;
+ pass = 0;
+
+again:
+ n = find_next_zero_bit(arena->map, limit, start);
+ end = n + npages;
+ if (unlikely(end >= limit)) {
+ if (likely(pass < 1)) {
+ limit = start;
+ start = 0;
+ __iommu_flushall(iommu);
+ pass++;
+ goto again;
+ } else {
+ /* Scanned the whole thing, give up. */
+ return -1;
}
- iopte += (1 << cnum);
- ent++;
- if (iopte >= limit) {
- iopte = (iommu->page_table +
- (cnum <<
- (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)));
- ent = 0;
+ }
+
+ for (i = n; i < end; i++) {
+ if (test_bit(i, arena->map)) {
+ start = i + 1;
+ goto again;
}
- if (ent == flush_point)
- __iommu_flushall(iommu);
- if (iopte == first)
- goto bad;
}
- /* I've got your streaming cluster right here buddy boy... */
- return iopte;
+ for (i = n; i < end; i++)
+ __set_bit(i, arena->map);
-bad:
- printk(KERN_EMERG "pci_iommu: alloc_streaming_cluster of npages(%ld) failed!\n",
- npages);
- return NULL;
+ arena->hint = end;
+
+ return n;
}
-static void free_streaming_cluster(struct pci_iommu *iommu, dma_addr_t base,
- unsigned long npages, unsigned long ctx)
+static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, unsigned long npages)
{
- unsigned long cnum, ent;
+ unsigned long i;
- cnum = 0;
- while ((1UL << cnum) < npages)
- cnum++;
+ for (i = base; i < (base + npages); i++)
+ __clear_bit(i, arena->map);
+}
- ent = (base << (32 - IO_PAGE_SHIFT + PBM_LOGCLUSTERS - iommu->page_table_sz_bits))
- >> (32 + PBM_LOGCLUSTERS + cnum - iommu->page_table_sz_bits);
+void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask)
+{
+ unsigned long i, tsbbase, order, sz, num_tsb_entries;
+
+ num_tsb_entries = tsbsize / sizeof(iopte_t);
+
+ /* Setup initial software IOMMU state. */
+ spin_lock_init(&iommu->lock);
+ iommu->ctx_lowest_free = 1;
+ iommu->page_table_map_base = dma_offset;
+ iommu->dma_addr_mask = dma_addr_mask;
+
+ /* Allocate and initialize the free area map. */
+ sz = num_tsb_entries / 8;
+ sz = (sz + 7UL) & ~7UL;
+ iommu->arena.map = kmalloc(sz, GFP_KERNEL);
+ if (!iommu->arena.map) {
+ prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n");
+ prom_halt();
+ }
+ memset(iommu->arena.map, 0, sz);
+ iommu->arena.limit = num_tsb_entries;
- /* If the global flush might not have caught this entry,
- * adjust the flush point such that we will flush before
- * ever trying to reuse it.
+ /* Allocate and initialize the dummy page which we
+ * set inactive IO PTEs to point to.
*/
-#define between(X,Y,Z) (((Z) - (Y)) >= ((X) - (Y)))
- if (between(ent, iommu->alloc_info[cnum].next, iommu->alloc_info[cnum].flush))
- iommu->alloc_info[cnum].flush = ent;
-#undef between
+ iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
+ if (!iommu->dummy_page) {
+ prom_printf("PCI_IOMMU: Error, gfp(dummy_page) failed.\n");
+ prom_halt();
+ }
+ memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
+ iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
+
+ /* Now allocate and setup the IOMMU page table itself. */
+ order = get_order(tsbsize);
+ tsbbase = __get_free_pages(GFP_KERNEL, order);
+ if (!tsbbase) {
+ prom_printf("PCI_IOMMU: Error, gfp(tsb) failed.\n");
+ prom_halt();
+ }
+ iommu->page_table = (iopte_t *)tsbbase;
+
+ for (i = 0; i < num_tsb_entries; i++)
+ iopte_make_dummy(iommu, &iommu->page_table[i]);
}
-/* We allocate consistent mappings from the end of cluster zero. */
-static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long npages)
+static inline iopte_t *alloc_npages(struct pci_iommu *iommu, unsigned long npages)
{
- iopte_t *iopte;
+ long entry;
- iopte = iommu->page_table + (1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS));
- while (iopte > iommu->page_table) {
- iopte--;
- if (IOPTE_IS_DUMMY(iommu, iopte)) {
- unsigned long tmp = npages;
+ entry = pci_arena_alloc(iommu, npages);
+ if (unlikely(entry < 0))
+ return NULL;
- while (--tmp) {
- iopte--;
- if (!IOPTE_IS_DUMMY(iommu, iopte))
- break;
- }
- if (tmp == 0) {
- u32 entry = (iopte - iommu->page_table);
+ return iommu->page_table + entry;
+}
- if (entry < iommu->lowest_consistent_map)
- iommu->lowest_consistent_map = entry;
- return iopte;
- }
- }
- }
- return NULL;
+static inline void free_npages(struct pci_iommu *iommu, dma_addr_t base, unsigned long npages)
+{
+ pci_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages);
}
static int iommu_alloc_ctx(struct pci_iommu *iommu)
@@ -233,7 +224,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
iopte_t *iopte;
- unsigned long flags, order, first_page, ctx;
+ unsigned long flags, order, first_page;
void *ret;
int npages;
@@ -251,9 +242,10 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
iommu = pcp->pbm->iommu;
spin_lock_irqsave(&iommu->lock, flags);
- iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT);
- if (iopte == NULL) {
- spin_unlock_irqrestore(&iommu->lock, flags);
+ iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ if (unlikely(iopte == NULL)) {
free_pages(first_page, order);
return NULL;
}
@@ -262,31 +254,15 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
((iopte - iommu->page_table) << IO_PAGE_SHIFT));
ret = (void *) first_page;
npages = size >> IO_PAGE_SHIFT;
- ctx = 0;
- if (iommu->iommu_ctxflush)
- ctx = iommu_alloc_ctx(iommu);
first_page = __pa(first_page);
while (npages--) {
- iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) |
+ iopte_val(*iopte) = (IOPTE_CONSISTENT(0UL) |
IOPTE_WRITE |
(first_page & IOPTE_PAGE));
iopte++;
first_page += IO_PAGE_SIZE;
}
- {
- int i;
- u32 daddr = *dma_addrp;
-
- npages = size >> IO_PAGE_SHIFT;
- for (i = 0; i < npages; i++) {
- pci_iommu_write(iommu->iommu_flush, daddr);
- daddr += IO_PAGE_SIZE;
- }
- }
-
- spin_unlock_irqrestore(&iommu->lock, flags);
-
return ret;
}
@@ -296,7 +272,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
iopte_t *iopte;
- unsigned long flags, order, npages, i, ctx;
+ unsigned long flags, order, npages;
npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
pcp = pdev->sysdata;
@@ -306,46 +282,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
spin_lock_irqsave(&iommu->lock, flags);
- if ((iopte - iommu->page_table) ==
- iommu->lowest_consistent_map) {
- iopte_t *walk = iopte + npages;
- iopte_t *limit;
-
- limit = (iommu->page_table +
- (1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)));
- while (walk < limit) {
- if (!IOPTE_IS_DUMMY(iommu, walk))
- break;
- walk++;
- }
- iommu->lowest_consistent_map =
- (walk - iommu->page_table);
- }
-
- /* Data for consistent mappings cannot enter the streaming
- * buffers, so we only need to update the TSB. We flush
- * the IOMMU here as well to prevent conflicts with the
- * streaming mapping deferred tlb flush scheme.
- */
-
- ctx = 0;
- if (iommu->iommu_ctxflush)
- ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL;
-
- for (i = 0; i < npages; i++, iopte++)
- iopte_make_dummy(iommu, iopte);
-
- if (iommu->iommu_ctxflush) {
- pci_iommu_write(iommu->iommu_ctxflush, ctx);
- } else {
- for (i = 0; i < npages; i++) {
- u32 daddr = dvma + (i << IO_PAGE_SHIFT);
-
- pci_iommu_write(iommu->iommu_flush, daddr);
- }
- }
-
- iommu_free_ctx(iommu, ctx);
+ free_npages(iommu, dvma, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
@@ -372,25 +309,27 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
- if (direction == PCI_DMA_NONE)
- BUG();
+ if (unlikely(direction == PCI_DMA_NONE))
+ goto bad_no_ctx;
oaddr = (unsigned long)ptr;
npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK);
npages >>= IO_PAGE_SHIFT;
spin_lock_irqsave(&iommu->lock, flags);
+ base = alloc_npages(iommu, npages);
+ ctx = 0;
+ if (iommu->iommu_ctxflush)
+ ctx = iommu_alloc_ctx(iommu);
+ spin_unlock_irqrestore(&iommu->lock, flags);
- base = alloc_streaming_cluster(iommu, npages);
- if (base == NULL)
+ if (unlikely(!base))
goto bad;
+
bus_addr = (iommu->page_table_map_base +
((base - iommu->page_table) << IO_PAGE_SHIFT));
ret = bus_addr | (oaddr & ~IO_PAGE_MASK);
base_paddr = __pa(oaddr & IO_PAGE_MASK);
- ctx = 0;
- if (iommu->iommu_ctxflush)
- ctx = iommu_alloc_ctx(iommu);
if (strbuf->strbuf_enabled)
iopte_protection = IOPTE_STREAMING(ctx);
else
@@ -401,12 +340,13 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE)
iopte_val(*base) = iopte_protection | base_paddr;
- spin_unlock_irqrestore(&iommu->lock, flags);
-
return ret;
bad:
- spin_unlock_irqrestore(&iommu->lock, flags);
+ iommu_free_ctx(iommu, ctx);
+bad_no_ctx:
+ if (printk_ratelimit())
+ WARN_ON(1);
return PCI_DMA_ERROR_CODE;
}
@@ -481,10 +421,13 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
iopte_t *base;
- unsigned long flags, npages, ctx;
+ unsigned long flags, npages, ctx, i;
- if (direction == PCI_DMA_NONE)
- BUG();
+ if (unlikely(direction == PCI_DMA_NONE)) {
+ if (printk_ratelimit())
+ WARN_ON(1);
+ return;
+ }
pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
@@ -510,13 +453,14 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
/* Step 1: Kick data out of streaming buffers if necessary. */
if (strbuf->strbuf_enabled)
- pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
+ pci_strbuf_flush(strbuf, iommu, bus_addr, ctx,
+ npages, direction);
- /* Step 2: Clear out first TSB entry. */
- iopte_make_dummy(iommu, base);
+ /* Step 2: Clear out TSB entries. */
+ for (i = 0; i < npages; i++)
+ iopte_make_dummy(iommu, base + i);
- free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base,
- npages, ctx);
+ free_npages(iommu, bus_addr - iommu->page_table_map_base, npages);
iommu_free_ctx(iommu, ctx);
@@ -621,6 +565,8 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
pci_map_single(pdev,
(page_address(sglist->page) + sglist->offset),
sglist->length, direction);
+ if (unlikely(sglist->dma_address == PCI_DMA_ERROR_CODE))
+ return 0;
sglist->dma_length = sglist->length;
return 1;
}
@@ -629,21 +575,29 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
- if (direction == PCI_DMA_NONE)
- BUG();
+ if (unlikely(direction == PCI_DMA_NONE))
+ goto bad_no_ctx;
/* Step 1: Prepare scatter list. */
npages = prepare_sg(sglist, nelems);
- /* Step 2: Allocate a cluster. */
+ /* Step 2: Allocate a cluster and context, if necessary. */
spin_lock_irqsave(&iommu->lock, flags);
- base = alloc_streaming_cluster(iommu, npages);
+ base = alloc_npages(iommu, npages);
+ ctx = 0;
+ if (iommu->iommu_ctxflush)
+ ctx = iommu_alloc_ctx(iommu);
+
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
if (base == NULL)
goto bad;
- dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT);
+
+ dma_base = iommu->page_table_map_base +
+ ((base - iommu->page_table) << IO_PAGE_SHIFT);
/* Step 3: Normalize DMA addresses. */
used = nelems;
@@ -656,30 +610,28 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
}
used = nelems - used;
- /* Step 4: Choose a context if necessary. */
- ctx = 0;
- if (iommu->iommu_ctxflush)
- ctx = iommu_alloc_ctx(iommu);
-
- /* Step 5: Create the mappings. */
+ /* Step 4: Create the mappings. */
if (strbuf->strbuf_enabled)
iopte_protection = IOPTE_STREAMING(ctx);
else
iopte_protection = IOPTE_CONSISTENT(ctx);
if (direction != PCI_DMA_TODEVICE)
iopte_protection |= IOPTE_WRITE;
- fill_sg (base, sglist, used, nelems, iopte_protection);
+
+ fill_sg(base, sglist, used, nelems, iopte_protection);
+
#ifdef VERIFY_SG
verify_sglist(sglist, nelems, base, npages);
#endif
- spin_unlock_irqrestore(&iommu->lock, flags);
-
return used;
bad:
- spin_unlock_irqrestore(&iommu->lock, flags);
- return PCI_DMA_ERROR_CODE;
+ iommu_free_ctx(iommu, ctx);
+bad_no_ctx:
+ if (printk_ratelimit())
+ WARN_ON(1);
+ return 0;
}
/* Unmap a set of streaming mode DMA translations. */
@@ -692,8 +644,10 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
unsigned long flags, ctx, i, npages;
u32 bus_addr;
- if (direction == PCI_DMA_NONE)
- BUG();
+ if (unlikely(direction == PCI_DMA_NONE)) {
+ if (printk_ratelimit())
+ WARN_ON(1);
+ }
pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
@@ -705,7 +659,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
if (sglist[i].dma_length == 0)
break;
i--;
- npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
+ npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) -
+ bus_addr) >> IO_PAGE_SHIFT;
base = iommu->page_table +
((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
@@ -726,11 +681,11 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
if (strbuf->strbuf_enabled)
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
- /* Step 2: Clear out first TSB entry. */
- iopte_make_dummy(iommu, base);
+ /* Step 2: Clear out the TSB entries. */
+ for (i = 0; i < npages; i++)
+ iopte_make_dummy(iommu, base + i);
- free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base,
- npages, ctx);
+ free_npages(iommu, bus_addr - iommu->page_table_map_base, npages);
iommu_free_ctx(iommu, ctx);
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 91ab466d6c66..c03ed5f49d31 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,16 +1204,12 @@ 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;
+ unsigned long i;
u64 control;
- /* Setup initial software IOMMU state. */
- spin_lock_init(&iommu->lock);
- iommu->ctx_lowest_free = 1;
-
/* Register addresses. */
iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE;
@@ -1240,40 +1236,10 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
+ pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
- iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
- if (!iommu->dummy_page) {
- prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
- prom_halt();
- }
- memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
- iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
- /* Using assumed page size 8K with 128K entries we need 1MB iommu page
- * table (128K ioptes * 8 bytes per iopte). This is
- * page order 7 on UltraSparc.
- */
- tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
- if (!tsbbase) {
- prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
- prom_halt();
- }
- iommu->page_table = (iopte_t *)tsbbase;
- iommu->page_table_sz_bits = 17;
- iommu->page_table_map_base = 0xc0000000;
- iommu->dma_addr_mask = 0xffffffff;
- pci_iommu_table_init(iommu, IO_TSB_SIZE);
-
- /* We start with no consistent mappings. */
- iommu->lowest_consistent_map =
- 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
- for (i = 0; i < PBM_NCLUSTERS; i++) {
- iommu->alloc_info[i].flush = 0;
- iommu->alloc_info[i].next = 0;
- }
-
- psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase));
+ psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE,
+ __pa(iommu->page_table));
control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL);
control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
@@ -1281,7 +1247,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control);
/* If necessary, hook us up for starfire IRQ translations. */
- if(this_is_starfire)
+ if (this_is_starfire)
p->starfire_cookie = starfire_hookup(p->pbm_A.portid);
else
p->starfire_cookie = NULL;
@@ -1327,8 +1293,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 +1447,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 52bf3431a422..da8e1364194f 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,18 +1262,14 @@ 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;
+ unsigned long i;
u64 control;
- /* Setup initial software IOMMU state. */
- spin_lock_init(&iommu->lock);
- iommu->ctx_lowest_free = 1;
-
/* Register addresses. */
iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
@@ -1295,26 +1291,10 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
+ pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask);
- iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
- if (!iommu->dummy_page) {
- prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
- prom_halt();
- }
- memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
- iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
- tsbbase = __get_free_pages(GFP_KERNEL, order = get_order(tsbsize * 1024 * 8));
- if (!tsbbase) {
- prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n");
- prom_halt();
- }
- iommu->page_table = (iopte_t *)tsbbase;
- iommu->page_table_map_base = dvma_offset;
- iommu->dma_addr_mask = dma_mask;
- pci_iommu_table_init(iommu, PAGE_SIZE << order);
-
- sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
+ sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE,
+ __pa(iommu->page_table));
control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
@@ -1322,11 +1302,9 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
switch(tsbsize) {
case 64:
control |= SABRE_IOMMU_TSBSZ_64K;
- iommu->page_table_sz_bits = 16;
break;
case 128:
control |= SABRE_IOMMU_TSBSZ_128K;
- iommu->page_table_sz_bits = 17;
break;
default:
prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
@@ -1334,19 +1312,10 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
break;
}
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
-
- /* We start with no consistent mappings. */
- iommu->lowest_consistent_map =
- 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
- for (i = 0; i < PBM_NCLUSTERS; i++) {
- iommu->alloc_info[i].flush = 0;
- iommu->alloc_info[i].next = 0;
- }
}
-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 +1384,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 +1521,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 6a182bb66281..d8c4e0919b4e 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;
@@ -330,7 +330,7 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
{
unsigned long sync_reg = (unsigned long) _arg2;
- u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO);
+ u64 mask = 1UL << (__irq_ino(__irq(bucket)) & IMAP_INO);
u64 val;
int limit;
@@ -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;
@@ -1765,7 +1765,7 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
{
struct pci_iommu *iommu = pbm->iommu;
- unsigned long tsbbase, i, tagbase, database, order;
+ unsigned long i, tagbase, database;
u32 vdma[2], dma_mask;
u64 control;
int err, tsbsize;
@@ -1800,10 +1800,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
prom_halt();
};
- /* Setup initial software IOMMU state. */
- spin_lock_init(&iommu->lock);
- iommu->ctx_lowest_free = 1;
-
/* Register addresses, SCHIZO has iommu ctx flushing. */
iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
@@ -1832,56 +1828,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
+ pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
- iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
- if (!iommu->dummy_page) {
- prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
- prom_halt();
- }
- memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
- iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
- /* Using assumed page size 8K with 128K entries we need 1MB iommu page
- * table (128K ioptes * 8 bytes per iopte). This is
- * page order 7 on UltraSparc.
- */
- order = get_order(tsbsize * 8 * 1024);
- tsbbase = __get_free_pages(GFP_KERNEL, order);
- if (!tsbbase) {
- prom_printf("%s: Error, gfp(tsb) failed.\n", pbm->name);
- prom_halt();
- }
-
- iommu->page_table = (iopte_t *)tsbbase;
- iommu->page_table_map_base = vdma[0];
- iommu->dma_addr_mask = dma_mask;
- pci_iommu_table_init(iommu, PAGE_SIZE << order);
-
- switch (tsbsize) {
- case 64:
- iommu->page_table_sz_bits = 16;
- break;
-
- case 128:
- iommu->page_table_sz_bits = 17;
- break;
-
- default:
- prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
- prom_halt();
- break;
- };
-
- /* We start with no consistent mappings. */
- iommu->lowest_consistent_map =
- 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
- for (i = 0; i < PBM_NCLUSTERS; i++) {
- iommu->alloc_info[i].flush = 0;
- iommu->alloc_info[i].next = 0;
- }
-
- schizo_write(iommu->iommu_tsbbase, __pa(tsbbase));
+ schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
control = schizo_read(iommu->iommu_control);
control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
@@ -1932,7 +1881,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 +1935,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 +2094,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 +2162,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/power.c b/arch/sparc64/kernel/power.c
index 946cee0257ea..9e8362ea3104 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -17,6 +17,7 @@
#include <asm/system.h>
#include <asm/ebus.h>
+#include <asm/isa.h>
#include <asm/auxio.h>
#include <linux/unistd.h>
@@ -100,46 +101,83 @@ again:
return 0;
}
-static int __init has_button_interrupt(struct linux_ebus_device *edev)
+static int __init has_button_interrupt(unsigned int irq, int prom_node)
{
- if (edev->irqs[0] == PCI_IRQ_NONE)
+ if (irq == PCI_IRQ_NONE)
return 0;
- if (!prom_node_has_property(edev->prom_node, "button"))
+ if (!prom_node_has_property(prom_node, "button"))
return 0;
return 1;
}
-void __init power_init(void)
+static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
{
struct linux_ebus *ebus;
struct linux_ebus_device *edev;
+
+ for_each_ebus(ebus) {
+ for_each_ebusdev(edev, ebus) {
+ if (!strcmp(edev->prom_name, "power")) {
+ *resp = &edev->resource[0];
+ *irq_p = edev->irqs[0];
+ *prom_node_p = edev->prom_node;
+ return 0;
+ }
+ }
+ }
+ return -ENODEV;
+}
+
+static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
+{
+ struct sparc_isa_bridge *isa_bus;
+ struct sparc_isa_device *isa_dev;
+
+ for_each_isa(isa_bus) {
+ for_each_isadev(isa_dev, isa_bus) {
+ if (!strcmp(isa_dev->prom_name, "power")) {
+ *resp = &isa_dev->resource;
+ *irq_p = isa_dev->irq;
+ *prom_node_p = isa_dev->prom_node;
+ return 0;
+ }
+ }
+ }
+ return -ENODEV;
+}
+
+void __init power_init(void)
+{
+ struct resource *res = NULL;
+ unsigned int irq;
+ int prom_node;
static int invoked;
if (invoked)
return;
invoked = 1;
- for_each_ebus(ebus) {
- for_each_ebusdev(edev, ebus) {
- if (!strcmp(edev->prom_name, "power"))
- goto found;
- }
- }
+ if (!power_probe_ebus(&res, &irq, &prom_node))
+ goto found;
+
+ if (!power_probe_isa(&res, &irq, &prom_node))
+ goto found;
+
return;
found:
- power_reg = ioremap(edev->resource[0].start, 0x4);
+ power_reg = ioremap(res->start, 0x4);
printk("power: Control reg at %p ... ", power_reg);
poweroff_method = machine_halt; /* able to use the standard halt */
- if (has_button_interrupt(edev)) {
+ if (has_button_interrupt(irq, prom_node)) {
if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
printk("Failed to start power daemon.\n");
return;
}
printk("powerd running.\n");
- if (request_irq(edev->irqs[0],
+ if (request_irq(irq,
power_handler, SA_SHIRQ, "power", NULL) < 0)
printk("power: Error, cannot register IRQ handler.\n");
} else {
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 66255434128a..7d10b0397091 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -607,11 +607,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
struct thread_info *t = p->thread_info;
char *child_trap_frame;
-#ifdef CONFIG_DEBUG_SPINLOCK
- p->thread.smp_lock_count = 0;
- p->thread.smp_lock_pc = 0;
-#endif
-
/* Calculate offset to stack_frame & pt_regs */
child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ));
memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ));
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 23ad839d113f..774ecbb8a031 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -30,6 +30,8 @@
#include <asm/psrcompat.h>
#include <asm/visasm.h>
#include <asm/spitfire.h>
+#include <asm/page.h>
+#include <asm/cpudata.h>
/* Returning from ptrace is a bit tricky because the syscall return
* low level code assumes any value returned which is negative and
@@ -128,20 +130,24 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
* is mapped to in the user's address space, we can skip the
* D-cache flush.
*/
- if ((uaddr ^ kaddr) & (1UL << 13)) {
+ if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
unsigned long start = __pa(kaddr);
unsigned long end = start + len;
+ unsigned long dcache_line_size;
+
+ dcache_line_size = local_cpu_data().dcache_line_size;
if (tlb_type == spitfire) {
- for (; start < end; start += 32)
- spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
+ for (; start < end; start += dcache_line_size)
+ spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
} else {
- for (; start < end; start += 32)
+ start &= ~(dcache_line_size - 1);
+ for (; start < end; start += dcache_line_size)
__asm__ __volatile__(
"stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (va),
+ : "r" (start),
"i" (ASI_DCACHE_INVALIDATE));
}
}
@@ -149,8 +155,11 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
if (write && tlb_type == spitfire) {
unsigned long start = (unsigned long) kaddr;
unsigned long end = start + len;
+ unsigned long icache_line_size;
+
+ icache_line_size = local_cpu_data().icache_line_size;
- for (; start < end; start += 32)
+ for (; start < end; start += icache_line_size)
flushi(start);
}
}
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index fafd227735fa..090dcca00d2a 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -256,9 +256,8 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
brnz,pn %l3, kern_rtt
mov PRIMARY_CONTEXT, %l7
ldxa [%l7 + %l7] ASI_DMMU, %l0
-cplus_rtrap_insn_1:
- sethi %hi(0), %l1
- sllx %l1, 32, %l1
+ sethi %hi(sparc64_kern_pri_nuc_bits), %l1
+ ldx [%l1 + %lo(sparc64_kern_pri_nuc_bits)], %l1
or %l0, %l1, %l0
stxa %l0, [%l7] ASI_DMMU
flush %g6
@@ -313,53 +312,36 @@ kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5
wr %g1, FPRS_FEF, %fprs
ldx [%o1 + %o5], %g1
add %g6, TI_XFSR, %o1
- membar #StoreLoad | #LoadLoad
sll %o0, 8, %o2
add %g6, TI_FPREGS, %o3
brz,pn %l6, 1f
add %g6, TI_FPREGS+0x40, %o4
+ membar #Sync
ldda [%o3 + %o2] ASI_BLK_P, %f0
ldda [%o4 + %o2] ASI_BLK_P, %f16
+ membar #Sync
1: andcc %l2, FPRS_DU, %g0
be,pn %icc, 1f
wr %g1, 0, %gsr
add %o2, 0x80, %o2
+ membar #Sync
ldda [%o3 + %o2] ASI_BLK_P, %f32
ldda [%o4 + %o2] ASI_BLK_P, %f48
-
1: membar #Sync
ldx [%o1 + %o5], %fsr
2: stb %l5, [%g6 + TI_FPDEPTH]
ba,pt %xcc, rt_continue
nop
5: wr %g0, FPRS_FEF, %fprs
- membar #StoreLoad | #LoadLoad
sll %o0, 8, %o2
add %g6, TI_FPREGS+0x80, %o3
add %g6, TI_FPREGS+0xc0, %o4
+ membar #Sync
ldda [%o3 + %o2] ASI_BLK_P, %f32
ldda [%o4 + %o2] ASI_BLK_P, %f48
membar #Sync
wr %g0, FPRS_DU, %fprs
ba,pt %xcc, rt_continue
stb %l5, [%g6 + TI_FPDEPTH]
-
-cplus_rinsn_1:
- sethi %uhi(CTX_CHEETAH_PLUS_NUC), %l1
-
- .globl cheetah_plus_patch_rtrap
-cheetah_plus_patch_rtrap:
- /* We configure the dTLB512_0 for 4MB pages and the
- * dTLB512_1 for 8K pages when in context zero.
- */
- sethi %hi(cplus_rinsn_1), %o0
- sethi %hi(cplus_rtrap_insn_1), %o2
- lduw [%o0 + %lo(cplus_rinsn_1)], %o1
- or %o2, %lo(cplus_rtrap_insn_1), %o2
- stw %o1, [%o2]
- flush %o2
-
- retl
- nop
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index ddbed3341a23..c1f34237cdf2 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -187,17 +187,13 @@ int prom_callback(long *args)
}
if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) {
- unsigned long kernel_pctx = 0;
-
- if (tlb_type == cheetah_plus)
- kernel_pctx |= (CTX_CHEETAH_PLUS_NUC |
- CTX_CHEETAH_PLUS_CTX0);
+ extern unsigned long sparc64_kern_pri_context;
/* Spitfire Errata #32 workaround */
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"flush %%g6"
: /* No outputs */
- : "r" (kernel_pctx),
+ : "r" (sparc64_kern_pri_context),
"r" (PRIMARY_CONTEXT),
"i" (ASI_DMMU));
@@ -464,8 +460,6 @@ static void __init boot_flags_init(char *commands)
}
}
-extern int prom_probe_memory(void);
-extern unsigned long start, end;
extern void panic_setup(char *, int *);
extern unsigned short root_flags;
@@ -492,13 +486,8 @@ void register_prom_callbacks(void)
"' linux-.soft2 to .soft2");
}
-extern void paging_init(void);
-
void __init setup_arch(char **cmdline_p)
{
- unsigned long highest_paddr;
- int i;
-
/* Initialize PROM console and command line. */
*cmdline_p = prom_getbootargs();
strcpy(saved_command_line, *cmdline_p);
@@ -517,40 +506,6 @@ void __init setup_arch(char **cmdline_p)
boot_flags_init(*cmdline_p);
idprom_init();
- (void) prom_probe_memory();
-
- /* In paging_init() we tip off this value to see if we need
- * to change init_mm.pgd to point to the real alias mapping.
- */
- phys_base = 0xffffffffffffffffUL;
- highest_paddr = 0UL;
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long top;
-
- if (sp_banks[i].base_addr < phys_base)
- phys_base = sp_banks[i].base_addr;
- top = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- if (highest_paddr < top)
- highest_paddr = top;
- }
- pfn_base = phys_base >> PAGE_SHIFT;
-
- switch (tlb_type) {
- default:
- case spitfire:
- kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent());
- kern_base &= _PAGE_PADDR_SF;
- break;
-
- case cheetah:
- case cheetah_plus:
- kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent());
- kern_base &= _PAGE_PADDR;
- break;
- };
-
- kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
if (!root_flags)
root_mountflags &= ~MS_RDONLY;
@@ -625,6 +580,9 @@ extern void smp_info(struct seq_file *);
extern void smp_bogo(struct seq_file *);
extern void mmu_info(struct seq_file *);
+unsigned int dcache_parity_tl1_occurred;
+unsigned int icache_parity_tl1_occurred;
+
static int show_cpuinfo(struct seq_file *m, void *__unused)
{
seq_printf(m,
@@ -635,6 +593,8 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
"type\t\t: sun4u\n"
"ncpus probed\t: %ld\n"
"ncpus active\t: %ld\n"
+ "D$ parity tl1\t: %u\n"
+ "I$ parity tl1\t: %u\n"
#ifndef CONFIG_SMP
"Cpu0Bogo\t: %lu.%02lu\n"
"Cpu0ClkTck\t: %016lx\n"
@@ -647,7 +607,9 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
(prom_prev >> 8) & 0xff,
prom_prev & 0xff,
(long)num_possible_cpus(),
- (long)num_online_cpus()
+ (long)num_online_cpus(),
+ dcache_parity_tl1_occurred,
+ icache_parity_tl1_occurred
#ifndef CONFIG_SMP
, cpu_data(0).udelay_val/(500000/HZ),
(cpu_data(0).udelay_val/(5000/HZ)) % 100,
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index b4fc6a5462b2..b137fd63f5e1 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -93,6 +93,27 @@ void __init smp_store_cpu_info(int id)
cpu_data(id).pte_cache[1] = NULL;
cpu_data(id).pgd_cache = NULL;
cpu_data(id).idle_volume = 1;
+
+ cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size",
+ 16 * 1024);
+ cpu_data(id).dcache_line_size =
+ prom_getintdefault(cpu_node, "dcache-line-size", 32);
+ cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size",
+ 16 * 1024);
+ cpu_data(id).icache_line_size =
+ prom_getintdefault(cpu_node, "icache-line-size", 32);
+ cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size",
+ 4 * 1024 * 1024);
+ cpu_data(id).ecache_line_size =
+ prom_getintdefault(cpu_node, "ecache-line-size", 64);
+ printk("CPU[%d]: Caches "
+ "D[sz(%d):line_sz(%d)] "
+ "I[sz(%d):line_sz(%d)] "
+ "E[sz(%d):line_sz(%d)]\n",
+ id,
+ cpu_data(id).dcache_size, cpu_data(id).dcache_line_size,
+ cpu_data(id).icache_size, cpu_data(id).icache_line_size,
+ cpu_data(id).ecache_size, cpu_data(id).ecache_line_size);
}
static void smp_setup_percpu_timer(void);
@@ -980,13 +1001,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
preempt_enable();
}
-extern unsigned long xcall_promstop;
-
-void smp_promstop_others(void)
-{
- smp_cross_call(&xcall_promstop, 0, 0, 0);
-}
-
#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier
#define prof_counter(__cpu) cpu_data(__cpu).counter
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d89fc24808d3..fb7a5370dbfc 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -115,17 +115,12 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data);
/* used by various drivers */
#ifdef CONFIG_SMP
-#ifndef CONFIG_DEBUG_SPINLOCK
/* Out of line rw-locking implementation. */
EXPORT_SYMBOL(__read_lock);
EXPORT_SYMBOL(__read_unlock);
EXPORT_SYMBOL(__write_lock);
EXPORT_SYMBOL(__write_unlock);
EXPORT_SYMBOL(__write_trylock);
-/* Out of line spin-locking implementation. */
-EXPORT_SYMBOL(_raw_spin_lock);
-EXPORT_SYMBOL(_raw_spin_lock_flags);
-#endif
/* Hard IRQ locking */
EXPORT_SYMBOL(synchronize_irq);
@@ -168,9 +163,6 @@ EXPORT_SYMBOL(atomic64_add);
EXPORT_SYMBOL(atomic64_add_ret);
EXPORT_SYMBOL(atomic64_sub);
EXPORT_SYMBOL(atomic64_sub_ret);
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif
/* Atomic bit operations. */
EXPORT_SYMBOL(test_and_set_bit);
@@ -403,12 +395,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/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index 5f9e4fae612e..9cd272ac3ac1 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -157,173 +157,199 @@ sys32_socketcall: /* %o0=call, %o1=args */
or %g2, %lo(__socketcall_table_begin), %g2
jmpl %g2 + %o0, %g0
nop
+do_einval:
+ retl
+ mov -EINVAL, %o0
- /* Each entry is exactly 32 bytes. */
.align 32
__socketcall_table_begin:
+
+ /* Each entry is exactly 32 bytes. */
do_sys_socket: /* sys_socket(int, int, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+1: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_socket), %g1
- ldswa [%o1 + 0x8] %asi, %o2
+2: ldswa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys_socket), %g0
- ldswa [%o1 + 0x4] %asi, %o1
+3: ldswa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+4: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_bind), %g1
- ldswa [%o1 + 0x8] %asi, %o2
+5: ldswa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys_bind), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+6: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+7: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_connect), %g1
- ldswa [%o1 + 0x8] %asi, %o2
+8: ldswa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys_connect), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+9: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_listen: /* sys_listen(int, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+10: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_listen), %g1
jmpl %g1 + %lo(sys_listen), %g0
- ldswa [%o1 + 0x4] %asi, %o1
+11: ldswa [%o1 + 0x4] %asi, %o1
nop
nop
nop
nop
do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */
- ldswa [%o1 + 0x0] %asi, %o0
+12: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_accept), %g1
- lduwa [%o1 + 0x8] %asi, %o2
+13: lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys_accept), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+14: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */
- ldswa [%o1 + 0x0] %asi, %o0
+15: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_getsockname), %g1
- lduwa [%o1 + 0x8] %asi, %o2
+16: lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys_getsockname), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+17: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */
- ldswa [%o1 + 0x0] %asi, %o0
+18: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_getpeername), %g1
- lduwa [%o1 + 0x8] %asi, %o2
+19: lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys_getpeername), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+20: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */
- ldswa [%o1 + 0x0] %asi, %o0
+21: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_socketpair), %g1
- ldswa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
+22: ldswa [%o1 + 0x8] %asi, %o2
+23: lduwa [%o1 + 0xc] %asi, %o3
jmpl %g1 + %lo(sys_socketpair), %g0
- ldswa [%o1 + 0x4] %asi, %o1
+24: ldswa [%o1 + 0x4] %asi, %o1
nop
nop
do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */
- ldswa [%o1 + 0x0] %asi, %o0
+25: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_send), %g1
- lduwa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
+26: lduwa [%o1 + 0x8] %asi, %o2
+27: lduwa [%o1 + 0xc] %asi, %o3
jmpl %g1 + %lo(sys_send), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+28: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */
- ldswa [%o1 + 0x0] %asi, %o0
+29: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_recv), %g1
- lduwa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
+30: lduwa [%o1 + 0x8] %asi, %o2
+31: lduwa [%o1 + 0xc] %asi, %o3
jmpl %g1 + %lo(sys_recv), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+32: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+33: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_sendto), %g1
- lduwa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
- lduwa [%o1 + 0x10] %asi, %o4
- ldswa [%o1 + 0x14] %asi, %o5
+34: lduwa [%o1 + 0x8] %asi, %o2
+35: lduwa [%o1 + 0xc] %asi, %o3
+36: lduwa [%o1 + 0x10] %asi, %o4
+37: ldswa [%o1 + 0x14] %asi, %o5
jmpl %g1 + %lo(sys_sendto), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+38: lduwa [%o1 + 0x4] %asi, %o1
do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
- ldswa [%o1 + 0x0] %asi, %o0
+39: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_recvfrom), %g1
- lduwa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
- lduwa [%o1 + 0x10] %asi, %o4
- lduwa [%o1 + 0x14] %asi, %o5
+40: lduwa [%o1 + 0x8] %asi, %o2
+41: lduwa [%o1 + 0xc] %asi, %o3
+42: lduwa [%o1 + 0x10] %asi, %o4
+43: lduwa [%o1 + 0x14] %asi, %o5
jmpl %g1 + %lo(sys_recvfrom), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+44: lduwa [%o1 + 0x4] %asi, %o1
do_sys_shutdown: /* sys_shutdown(int, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+45: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys_shutdown), %g1
jmpl %g1 + %lo(sys_shutdown), %g0
- ldswa [%o1 + 0x4] %asi, %o1
+46: ldswa [%o1 + 0x4] %asi, %o1
nop
nop
nop
nop
do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */
- ldswa [%o1 + 0x0] %asi, %o0
+47: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(compat_sys_setsockopt), %g1
- ldswa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
- ldswa [%o1 + 0x10] %asi, %o4
+48: ldswa [%o1 + 0x8] %asi, %o2
+49: lduwa [%o1 + 0xc] %asi, %o3
+50: ldswa [%o1 + 0x10] %asi, %o4
jmpl %g1 + %lo(compat_sys_setsockopt), %g0
- ldswa [%o1 + 0x4] %asi, %o1
+51: ldswa [%o1 + 0x4] %asi, %o1
nop
do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */
- ldswa [%o1 + 0x0] %asi, %o0
+52: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(compat_sys_getsockopt), %g1
- ldswa [%o1 + 0x8] %asi, %o2
- lduwa [%o1 + 0xc] %asi, %o3
- lduwa [%o1 + 0x10] %asi, %o4
+53: ldswa [%o1 + 0x8] %asi, %o2
+54: lduwa [%o1 + 0xc] %asi, %o3
+55: lduwa [%o1 + 0x10] %asi, %o4
jmpl %g1 + %lo(compat_sys_getsockopt), %g0
- ldswa [%o1 + 0x4] %asi, %o1
+56: ldswa [%o1 + 0x4] %asi, %o1
nop
do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
- ldswa [%o1 + 0x0] %asi, %o0
+57: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(compat_sys_sendmsg), %g1
- lduwa [%o1 + 0x8] %asi, %o2
+58: lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(compat_sys_sendmsg), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+59: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
- ldswa [%o1 + 0x0] %asi, %o0
+60: ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(compat_sys_recvmsg), %g1
- lduwa [%o1 + 0x8] %asi, %o2
+61: lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(compat_sys_recvmsg), %g0
- lduwa [%o1 + 0x4] %asi, %o1
+62: lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
-__socketcall_table_end:
-
-do_einval:
- retl
- mov -EINVAL, %o0
-do_efault:
- retl
- mov -EFAULT, %o0
.section __ex_table
.align 4
- .word __socketcall_table_begin, 0, __socketcall_table_end, do_efault
+ .word 1b, __retl_efault, 2b, __retl_efault
+ .word 3b, __retl_efault, 4b, __retl_efault
+ .word 5b, __retl_efault, 6b, __retl_efault
+ .word 7b, __retl_efault, 8b, __retl_efault
+ .word 9b, __retl_efault, 10b, __retl_efault
+ .word 11b, __retl_efault, 12b, __retl_efault
+ .word 13b, __retl_efault, 14b, __retl_efault
+ .word 15b, __retl_efault, 16b, __retl_efault
+ .word 17b, __retl_efault, 18b, __retl_efault
+ .word 19b, __retl_efault, 20b, __retl_efault
+ .word 21b, __retl_efault, 22b, __retl_efault
+ .word 23b, __retl_efault, 24b, __retl_efault
+ .word 25b, __retl_efault, 26b, __retl_efault
+ .word 27b, __retl_efault, 28b, __retl_efault
+ .word 29b, __retl_efault, 30b, __retl_efault
+ .word 31b, __retl_efault, 32b, __retl_efault
+ .word 33b, __retl_efault, 34b, __retl_efault
+ .word 35b, __retl_efault, 36b, __retl_efault
+ .word 37b, __retl_efault, 38b, __retl_efault
+ .word 39b, __retl_efault, 40b, __retl_efault
+ .word 41b, __retl_efault, 42b, __retl_efault
+ .word 43b, __retl_efault, 44b, __retl_efault
+ .word 45b, __retl_efault, 46b, __retl_efault
+ .word 47b, __retl_efault, 48b, __retl_efault
+ .word 49b, __retl_efault, 50b, __retl_efault
+ .word 51b, __retl_efault, 52b, __retl_efault
+ .word 53b, __retl_efault, 54b, __retl_efault
+ .word 55b, __retl_efault, 56b, __retl_efault
+ .word 57b, __retl_efault, 58b, __retl_efault
+ .word 59b, __retl_efault, 60b, __retl_efault
+ .word 61b, __retl_efault, 62b, __retl_efault
.previous
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index 3a145fc39cf2..9478551cb020 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -119,8 +119,8 @@ startup_continue:
sethi %hi(itlb_load), %g2
or %g2, %lo(itlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
+ sethi %hi(prom_mmu_ihandle_cache), %g2
+ lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@@ -156,8 +156,8 @@ startup_continue:
sethi %hi(itlb_load), %g2
or %g2, %lo(itlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
+ sethi %hi(prom_mmu_ihandle_cache), %g2
+ lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE + 0x400000), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@@ -190,8 +190,8 @@ do_dtlb:
sethi %hi(dtlb_load), %g2
or %g2, %lo(dtlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
+ sethi %hi(prom_mmu_ihandle_cache), %g2
+ lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@@ -228,8 +228,8 @@ do_dtlb:
sethi %hi(dtlb_load), %g2
or %g2, %lo(dtlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
+ sethi %hi(prom_mmu_ihandle_cache), %g2
+ lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE + 0x400000), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@@ -336,20 +336,13 @@ do_unlock:
call init_irqwork_curcpu
nop
- BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f)
- ba,pt %xcc, 2f
- nop
-
-1: /* Start using proper page size encodings in ctx register. */
- sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
+ /* Start using proper page size encodings in ctx register. */
+ sethi %hi(sparc64_kern_pri_context), %g3
+ ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
mov PRIMARY_CONTEXT, %g1
- sllx %g3, 32, %g3
- sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
- or %g3, %g2, %g3
- stxa %g3, [%g1] ASI_DMMU
+ stxa %g2, [%g1] ASI_DMMU
membar #Sync
-2:
rdpr %pstate, %o1
or %o1, PSTATE_IE, %o1
wrpr %o1, 0, %pstate
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index b280b2ef674f..5570e7bb22bb 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -189,19 +189,18 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un
if (regs->tstate & TSTATE_PRIV) {
/* Test if this comes from uaccess places. */
- unsigned long fixup;
- unsigned long g2 = regs->u_regs[UREG_G2];
+ const struct exception_table_entry *entry;
- if ((fixup = search_extables_range(regs->tpc, &g2))) {
- /* Ouch, somebody is trying ugly VM hole tricks on us... */
+ entry = search_exception_tables(regs->tpc);
+ if (entry) {
+ /* Ouch, somebody is trying VM hole tricks on us... */
#ifdef DEBUG_EXCEPTIONS
printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc);
- printk("EX_TABLE: insn<%016lx> fixup<%016lx> "
- "g2<%016lx>\n", regs->tpc, fixup, g2);
+ printk("EX_TABLE: insn<%016lx> fixup<%016lx>\n",
+ regs->tpc, entry->fixup);
#endif
- regs->tpc = fixup;
+ regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
- regs->u_regs[UREG_G2] = g2;
return;
}
/* Shit... */
@@ -758,26 +757,12 @@ void __init cheetah_ecache_flush_init(void)
ecache_flush_size = (2 * largest_size);
ecache_flush_linesize = smallest_linesize;
- /* Discover a physically contiguous chunk of physical
- * memory in 'sp_banks' of size ecache_flush_size calculated
- * above. Store the physical base of this area at
- * ecache_flush_physbase.
- */
- for (node = 0; ; node++) {
- if (sp_banks[node].num_bytes == 0)
- break;
- if (sp_banks[node].num_bytes >= ecache_flush_size) {
- ecache_flush_physbase = sp_banks[node].base_addr;
- break;
- }
- }
+ ecache_flush_physbase = find_ecache_flush_span(ecache_flush_size);
- /* Note: Zero would be a valid value of ecache_flush_physbase so
- * don't use that as the success test. :-)
- */
- if (sp_banks[node].num_bytes == 0) {
+ if (ecache_flush_physbase == ~0UL) {
prom_printf("cheetah_ecache_flush_init: Cannot find %d byte "
- "contiguous physical memory.\n", ecache_flush_size);
+ "contiguous physical memory.\n",
+ ecache_flush_size);
prom_halt();
}
@@ -869,14 +854,19 @@ static void cheetah_flush_ecache_line(unsigned long physaddr)
*/
static void __cheetah_flush_icache(void)
{
- unsigned long i;
+ unsigned int icache_size, icache_line_size;
+ unsigned long addr;
+
+ icache_size = local_cpu_data().icache_size;
+ icache_line_size = local_cpu_data().icache_line_size;
/* Clear the valid bits in all the tags. */
- for (i = 0; i < (1 << 15); i += (1 << 5)) {
+ for (addr = 0; addr < icache_size; addr += icache_line_size) {
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (i | (2 << 3)), "i" (ASI_IC_TAG));
+ : "r" (addr | (2 << 3)),
+ "i" (ASI_IC_TAG));
}
}
@@ -904,13 +894,17 @@ static void cheetah_flush_icache(void)
static void cheetah_flush_dcache(void)
{
- unsigned long i;
+ unsigned int dcache_size, dcache_line_size;
+ unsigned long addr;
- for (i = 0; i < (1 << 16); i += (1 << 5)) {
+ dcache_size = local_cpu_data().dcache_size;
+ dcache_line_size = local_cpu_data().dcache_line_size;
+
+ for (addr = 0; addr < dcache_size; addr += dcache_line_size) {
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (i), "i" (ASI_DCACHE_TAG));
+ : "r" (addr), "i" (ASI_DCACHE_TAG));
}
}
@@ -921,24 +915,29 @@ static void cheetah_flush_dcache(void)
*/
static void cheetah_plus_zap_dcache_parity(void)
{
- unsigned long i;
+ unsigned int dcache_size, dcache_line_size;
+ unsigned long addr;
+
+ dcache_size = local_cpu_data().dcache_size;
+ dcache_line_size = local_cpu_data().dcache_line_size;
- for (i = 0; i < (1 << 16); i += (1 << 5)) {
- unsigned long tag = (i >> 14);
- unsigned long j;
+ for (addr = 0; addr < dcache_size; addr += dcache_line_size) {
+ unsigned long tag = (addr >> 14);
+ unsigned long line;
__asm__ __volatile__("membar #Sync\n\t"
"stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (tag), "r" (i),
+ : "r" (tag), "r" (addr),
"i" (ASI_DCACHE_UTAG));
- for (j = i; j < i + (1 << 5); j += (1 << 3))
+ for (line = addr; line < addr + dcache_line_size; line += 8)
__asm__ __volatile__("membar #Sync\n\t"
"stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (j), "i" (ASI_DCACHE_DATA));
+ : "r" (line),
+ "i" (ASI_DCACHE_DATA));
}
}
@@ -1332,16 +1331,12 @@ static int cheetah_fix_ce(unsigned long physaddr)
/* Return non-zero if PADDR is a valid physical memory address. */
static int cheetah_check_main_memory(unsigned long paddr)
{
- int i;
+ unsigned long vaddr = PAGE_OFFSET + paddr;
- for (i = 0; ; i++) {
- if (sp_banks[i].num_bytes == 0)
- break;
- if (paddr >= sp_banks[i].base_addr &&
- paddr < (sp_banks[i].base_addr + sp_banks[i].num_bytes))
- return 1;
- }
- return 0;
+ if (vaddr > (unsigned long) high_memory)
+ return 0;
+
+ return kern_addr_valid(vaddr);
}
void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
@@ -1596,10 +1591,10 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
/* OK, usermode access. */
recoverable = 1;
} else {
- unsigned long g2 = regs->u_regs[UREG_G2];
- unsigned long fixup = search_extables_range(regs->tpc, &g2);
+ const struct exception_table_entry *entry;
- if (fixup != 0UL) {
+ entry = search_exception_tables(regs->tpc);
+ if (entry) {
/* OK, kernel access to userspace. */
recoverable = 1;
@@ -1618,9 +1613,8 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
* recoverable condition.
*/
if (recoverable) {
- regs->tpc = fixup;
+ regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
- regs->u_regs[UREG_G2] = g2;
}
}
}
diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S
index cbb40585253c..1f5b5b708ce7 100644
--- a/arch/sparc64/kernel/una_asm.S
+++ b/arch/sparc64/kernel/una_asm.S
@@ -6,18 +6,11 @@
.text
-kernel_unaligned_trap_fault:
- call kernel_mna_trap_fault
- nop
- retl
- nop
- .size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
-
.globl __do_int_store
__do_int_store:
rd %asi, %o4
wr %o3, 0, %asi
- ldx [%o2], %g3
+ mov %o2, %g3
cmp %o1, 2
be,pn %icc, 2f
cmp %o1, 4
@@ -51,24 +44,24 @@ __do_int_store:
0:
wr %o4, 0x0, %asi
retl
- nop
+ mov 0, %o0
.size __do_int_store, .-__do_int_store
.section __ex_table
- .word 4b, kernel_unaligned_trap_fault
- .word 5b, kernel_unaligned_trap_fault
- .word 6b, kernel_unaligned_trap_fault
- .word 7b, kernel_unaligned_trap_fault
- .word 8b, kernel_unaligned_trap_fault
- .word 9b, kernel_unaligned_trap_fault
- .word 10b, kernel_unaligned_trap_fault
- .word 11b, kernel_unaligned_trap_fault
- .word 12b, kernel_unaligned_trap_fault
- .word 13b, kernel_unaligned_trap_fault
- .word 14b, kernel_unaligned_trap_fault
- .word 15b, kernel_unaligned_trap_fault
- .word 16b, kernel_unaligned_trap_fault
- .word 17b, kernel_unaligned_trap_fault
+ .word 4b, __retl_efault
+ .word 5b, __retl_efault
+ .word 6b, __retl_efault
+ .word 7b, __retl_efault
+ .word 8b, __retl_efault
+ .word 9b, __retl_efault
+ .word 10b, __retl_efault
+ .word 11b, __retl_efault
+ .word 12b, __retl_efault
+ .word 13b, __retl_efault
+ .word 14b, __retl_efault
+ .word 15b, __retl_efault
+ .word 16b, __retl_efault
+ .word 17b, __retl_efault
.previous
.globl do_int_load
@@ -133,21 +126,21 @@ do_int_load:
0:
wr %o5, 0x0, %asi
retl
- nop
+ mov 0, %o0
.size __do_int_load, .-__do_int_load
.section __ex_table
- .word 4b, kernel_unaligned_trap_fault
- .word 5b, kernel_unaligned_trap_fault
- .word 6b, kernel_unaligned_trap_fault
- .word 7b, kernel_unaligned_trap_fault
- .word 8b, kernel_unaligned_trap_fault
- .word 9b, kernel_unaligned_trap_fault
- .word 10b, kernel_unaligned_trap_fault
- .word 11b, kernel_unaligned_trap_fault
- .word 12b, kernel_unaligned_trap_fault
- .word 13b, kernel_unaligned_trap_fault
- .word 14b, kernel_unaligned_trap_fault
- .word 15b, kernel_unaligned_trap_fault
- .word 16b, kernel_unaligned_trap_fault
+ .word 4b, __retl_efault
+ .word 5b, __retl_efault
+ .word 6b, __retl_efault
+ .word 7b, __retl_efault
+ .word 8b, __retl_efault
+ .word 9b, __retl_efault
+ .word 10b, __retl_efault
+ .word 11b, __retl_efault
+ .word 12b, __retl_efault
+ .word 13b, __retl_efault
+ .word 14b, __retl_efault
+ .word 15b, __retl_efault
+ .word 16b, __retl_efault
.previous
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index da9739f0d437..70faf630603b 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -180,17 +180,18 @@ static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs)
die_if_kernel(str, regs);
}
-extern void do_int_load(unsigned long *dest_reg, int size,
- unsigned long *saddr, int is_signed, int asi);
+extern int do_int_load(unsigned long *dest_reg, int size,
+ unsigned long *saddr, int is_signed, int asi);
-extern void __do_int_store(unsigned long *dst_addr, int size,
- unsigned long *src_val, int asi);
+extern int __do_int_store(unsigned long *dst_addr, int size,
+ unsigned long src_val, int asi);
-static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
- struct pt_regs *regs, int asi)
+static inline int do_int_store(int reg_num, int size, unsigned long *dst_addr,
+ struct pt_regs *regs, int asi, int orig_asi)
{
unsigned long zero = 0;
- unsigned long *src_val = &zero;
+ unsigned long *src_val_p = &zero;
+ unsigned long src_val;
if (size == 16) {
size = 8;
@@ -198,9 +199,27 @@ static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
(unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
(unsigned)fetch_reg(reg_num + 1, regs);
} else if (reg_num) {
- src_val = fetch_reg_addr(reg_num, regs);
+ src_val_p = fetch_reg_addr(reg_num, regs);
}
- __do_int_store(dst_addr, size, src_val, asi);
+ src_val = *src_val_p;
+ if (unlikely(asi != orig_asi)) {
+ switch (size) {
+ case 2:
+ src_val = swab16(src_val);
+ break;
+ case 4:
+ src_val = swab32(src_val);
+ break;
+ case 8:
+ src_val = swab64(src_val);
+ break;
+ case 16:
+ default:
+ BUG();
+ break;
+ };
+ }
+ return __do_int_store(dst_addr, size, src_val, asi);
}
static inline void advance(struct pt_regs *regs)
@@ -223,14 +242,14 @@ static inline int ok_for_kernel(unsigned int insn)
return !floating_point_load_or_store_p(insn);
}
-void kernel_mna_trap_fault(void)
+static void kernel_mna_trap_fault(void)
{
struct pt_regs *regs = current_thread_info()->kern_una_regs;
unsigned int insn = current_thread_info()->kern_una_insn;
- unsigned long g2 = regs->u_regs[UREG_G2];
- unsigned long fixup = search_extables_range(regs->tpc, &g2);
+ const struct exception_table_entry *entry;
- if (!fixup) {
+ entry = search_exception_tables(regs->tpc);
+ if (!entry) {
unsigned long address;
address = compute_effective_address(regs, insn,
@@ -251,9 +270,8 @@ void kernel_mna_trap_fault(void)
die_if_kernel("Oops", regs);
/* Not reached */
}
- regs->tpc = fixup;
+ regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
- regs->u_regs [UREG_G2] = g2;
regs->tstate &= ~TSTATE_ASI;
regs->tstate |= (ASI_AIUS << 24UL);
@@ -275,7 +293,8 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
kernel_mna_trap_fault();
} else {
- unsigned long addr;
+ unsigned long addr, *reg_addr;
+ int orig_asi, asi, err;
addr = compute_effective_address(regs, insn,
((insn >> 25) & 0x1f));
@@ -285,25 +304,59 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
regs->tpc, dirstrings[dir], addr, size,
regs->u_regs[UREG_RETPC]);
#endif
+ orig_asi = asi = decode_asi(insn, regs);
+ switch (asi) {
+ case ASI_NL:
+ case ASI_AIUPL:
+ case ASI_AIUSL:
+ case ASI_PL:
+ case ASI_SL:
+ case ASI_PNFL:
+ case ASI_SNFL:
+ asi &= ~0x08;
+ break;
+ };
switch (dir) {
case load:
- do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
- size, (unsigned long *) addr,
- decode_signedness(insn),
- decode_asi(insn, regs));
+ reg_addr = fetch_reg_addr(((insn>>25)&0x1f), regs);
+ err = do_int_load(reg_addr, size,
+ (unsigned long *) addr,
+ decode_signedness(insn), asi);
+ if (likely(!err) && unlikely(asi != orig_asi)) {
+ unsigned long val_in = *reg_addr;
+ switch (size) {
+ case 2:
+ val_in = swab16(val_in);
+ break;
+ case 4:
+ val_in = swab32(val_in);
+ break;
+ case 8:
+ val_in = swab64(val_in);
+ break;
+ case 16:
+ default:
+ BUG();
+ break;
+ };
+ *reg_addr = val_in;
+ }
break;
case store:
- do_int_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs,
- decode_asi(insn, regs));
+ err = do_int_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs,
+ asi, orig_asi);
break;
default:
panic("Impossible kernel unaligned trap.");
/* Not reached... */
}
- advance(regs);
+ if (unlikely(err))
+ kernel_mna_trap_fault();
+ else
+ advance(regs);
}
}
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 9080e7cd4bb0..0340041f6143 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -208,7 +208,10 @@ static int __init us3_freq_init(void)
impl = ((ver >> 32) & 0xffff);
if (manuf == CHEETAH_MANUF &&
- (impl == CHEETAH_IMPL || impl == CHEETAH_PLUS_IMPL)) {
+ (impl == CHEETAH_IMPL ||
+ impl == CHEETAH_PLUS_IMPL ||
+ impl == JAGUAR_IMPL ||
+ impl == PANTHER_IMPL)) {
struct cpufreq_driver *driver;
ret = -ENOMEM;
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index f47d0be39378..2af0cf0a8640 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -9,8 +9,7 @@ ENTRY(_start)
jiffies = jiffies_64;
SECTIONS
{
- swapper_pmd_dir = 0x0000000000402000;
- empty_pg_dir = 0x0000000000403000;
+ swapper_low_pmd_dir = 0x0000000000402000;
. = 0x4000;
.text 0x0000000000404000 :
{
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index 99c809a1e5ac..39160926267b 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -16,23 +16,14 @@
.text
set_pcontext:
-cplus_winfixup_insn_1:
- sethi %hi(0), %l1
+ sethi %hi(sparc64_kern_pri_context), %l1
+ ldx [%l1 + %lo(sparc64_kern_pri_context)], %l1
mov PRIMARY_CONTEXT, %g1
- sllx %l1, 32, %l1
-cplus_winfixup_insn_2:
- sethi %hi(0), %g2
- or %l1, %g2, %l1
stxa %l1, [%g1] ASI_DMMU
flush %g6
retl
nop
-cplus_wfinsn_1:
- sethi %uhi(CTX_CHEETAH_PLUS_NUC), %l1
-cplus_wfinsn_2:
- sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
-
.align 32
/* Here are the rules, pay attention.
@@ -395,23 +386,3 @@ window_dax_from_user_common:
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
clr %l6
-
-
- .globl cheetah_plus_patch_winfixup
-cheetah_plus_patch_winfixup:
- sethi %hi(cplus_wfinsn_1), %o0
- sethi %hi(cplus_winfixup_insn_1), %o2
- lduw [%o0 + %lo(cplus_wfinsn_1)], %o1
- or %o2, %lo(cplus_winfixup_insn_1), %o2
- stw %o1, [%o2]
- flush %o2
-
- sethi %hi(cplus_wfinsn_2), %o0
- sethi %hi(cplus_winfixup_insn_2), %o2
- lduw [%o0 + %lo(cplus_wfinsn_2)], %o1
- or %o2, %lo(cplus_winfixup_insn_2), %o2
- stw %o1, [%o2]
- flush %o2
-
- retl
- nop
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index 6201f1040982..c295806500f7 100644
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -12,9 +12,6 @@ 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
-
-lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
-lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
+ mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
obj-y += iomap.o
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S
index 4e18989bd602..a0ded5c5aa5c 100644
--- a/arch/sparc64/lib/VISsave.S
+++ b/arch/sparc64/lib/VISsave.S
@@ -59,15 +59,17 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3
be,pn %icc, 9b
add %g6, TI_FPREGS, %g2
andcc %o5, FPRS_DL, %g0
- membar #StoreStore | #LoadStore
be,pn %icc, 4f
add %g6, TI_FPREGS+0x40, %g3
+ membar #Sync
stda %f0, [%g2 + %g1] ASI_BLK_P
stda %f16, [%g3 + %g1] ASI_BLK_P
+ membar #Sync
andcc %o5, FPRS_DU, %g0
be,pn %icc, 5f
4: add %g1, 128, %g1
+ membar #Sync
stda %f32, [%g2 + %g1] ASI_BLK_P
stda %f48, [%g3 + %g1] ASI_BLK_P
@@ -87,7 +89,7 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3
sll %g1, 5, %g1
add %g6, TI_FPREGS+0xc0, %g3
wr %g0, FPRS_FEF, %fprs
- membar #StoreStore | #LoadStore
+ membar #Sync
stda %f32, [%g2 + %g1] ASI_BLK_P
stda %f48, [%g3 + %g1] ASI_BLK_P
membar #Sync
@@ -128,8 +130,8 @@ VISenterhalf:
be,pn %icc, 4f
add %g6, TI_FPREGS, %g2
- membar #StoreStore | #LoadStore
add %g6, TI_FPREGS+0x40, %g3
+ membar #Sync
stda %f0, [%g2 + %g1] ASI_BLK_P
stda %f16, [%g3 + %g1] ASI_BLK_P
membar #Sync
diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c
deleted file mode 100644
index f5f0b5586f01..000000000000
--- a/arch/sparc64/lib/debuglocks.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* $Id: debuglocks.c,v 1.9 2001/11/17 00:10:48 davem Exp $
- * debuglocks.c: Debugging versions of SMP locking primitives.
- *
- * Copyright (C) 1998 David S. Miller (davem@redhat.com)
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-
-#ifdef CONFIG_SMP
-
-static inline void show (char *str, spinlock_t *lock, unsigned long caller)
-{
- int cpu = smp_processor_id();
-
- printk("%s(%p) CPU#%d stuck at %08x, owner PC(%08x):CPU(%x)\n",
- str, lock, cpu, (unsigned int) caller,
- lock->owner_pc, lock->owner_cpu);
-}
-
-static inline void show_read (char *str, rwlock_t *lock, unsigned long caller)
-{
- int cpu = smp_processor_id();
-
- printk("%s(%p) CPU#%d stuck at %08x, writer PC(%08x):CPU(%x)\n",
- str, lock, cpu, (unsigned int) caller,
- lock->writer_pc, lock->writer_cpu);
-}
-
-static inline void show_write (char *str, rwlock_t *lock, unsigned long caller)
-{
- int cpu = smp_processor_id();
- int i;
-
- printk("%s(%p) CPU#%d stuck at %08x\n",
- str, lock, cpu, (unsigned int) caller);
- printk("Writer: PC(%08x):CPU(%x)\n",
- lock->writer_pc, lock->writer_cpu);
- printk("Readers:");
- for (i = 0; i < NR_CPUS; i++)
- if (lock->reader_pc[i])
- printk(" %d[%08x]", i, lock->reader_pc[i]);
- printk("\n");
-}
-
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
-void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller)
-{
- unsigned long val;
- int stuck = INIT_STUCK;
- int cpu = get_cpu();
- int shown = 0;
-
-again:
- __asm__ __volatile__("ldstub [%1], %0"
- : "=r" (val)
- : "r" (&(lock->lock))
- : "memory");
- membar_storeload_storestore();
- if (val) {
- while (lock->lock) {
- if (!--stuck) {
- if (shown++ <= 2)
- show(str, lock, caller);
- stuck = INIT_STUCK;
- }
- rmb();
- }
- goto again;
- }
- lock->owner_pc = ((unsigned int)caller);
- lock->owner_cpu = cpu;
- current->thread.smp_lock_count++;
- current->thread.smp_lock_pc = ((unsigned int)caller);
-
- put_cpu();
-}
-
-int _do_spin_trylock(spinlock_t *lock, unsigned long caller)
-{
- unsigned long val;
- int cpu = get_cpu();
-
- __asm__ __volatile__("ldstub [%1], %0"
- : "=r" (val)
- : "r" (&(lock->lock))
- : "memory");
- membar_storeload_storestore();
- if (!val) {
- lock->owner_pc = ((unsigned int)caller);
- lock->owner_cpu = cpu;
- current->thread.smp_lock_count++;
- current->thread.smp_lock_pc = ((unsigned int)caller);
- }
-
- put_cpu();
-
- return val == 0;
-}
-
-void _do_spin_unlock(spinlock_t *lock)
-{
- lock->owner_pc = 0;
- lock->owner_cpu = NO_PROC_ID;
- membar_storestore_loadstore();
- lock->lock = 0;
- current->thread.smp_lock_count--;
-}
-
-/* Keep INIT_STUCK the same... */
-
-void _do_read_lock(rwlock_t *rw, char *str, unsigned long caller)
-{
- unsigned long val;
- int stuck = INIT_STUCK;
- int cpu = get_cpu();
- int shown = 0;
-
-wlock_again:
- /* Wait for any writer to go away. */
- while (((long)(rw->lock)) < 0) {
- if (!--stuck) {
- if (shown++ <= 2)
- show_read(str, rw, caller);
- stuck = INIT_STUCK;
- }
- rmb();
- }
- /* Try once to increment the counter. */
- __asm__ __volatile__(
-" ldx [%0], %%g1\n"
-" brlz,a,pn %%g1, 2f\n"
-" mov 1, %0\n"
-" add %%g1, 1, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" sub %%g1, %%g7, %0\n"
-"2:" : "=r" (val)
- : "0" (&(rw->lock))
- : "g1", "g7", "memory");
- membar_storeload_storestore();
- if (val)
- goto wlock_again;
- rw->reader_pc[cpu] = ((unsigned int)caller);
- current->thread.smp_lock_count++;
- current->thread.smp_lock_pc = ((unsigned int)caller);
-
- put_cpu();
-}
-
-void _do_read_unlock(rwlock_t *rw, char *str, unsigned long caller)
-{
- unsigned long val;
- int stuck = INIT_STUCK;
- int cpu = get_cpu();
- int shown = 0;
-
- /* Drop our identity _first_. */
- rw->reader_pc[cpu] = 0;
- current->thread.smp_lock_count--;
-runlock_again:
- /* Spin trying to decrement the counter using casx. */
- __asm__ __volatile__(
-" membar #StoreLoad | #LoadLoad\n"
-" ldx [%0], %%g1\n"
-" sub %%g1, 1, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" membar #StoreLoad | #StoreStore\n"
-" sub %%g1, %%g7, %0\n"
- : "=r" (val)
- : "0" (&(rw->lock))
- : "g1", "g7", "memory");
- if (val) {
- if (!--stuck) {
- if (shown++ <= 2)
- show_read(str, rw, caller);
- stuck = INIT_STUCK;
- }
- goto runlock_again;
- }
-
- put_cpu();
-}
-
-void _do_write_lock(rwlock_t *rw, char *str, unsigned long caller)
-{
- unsigned long val;
- int stuck = INIT_STUCK;
- int cpu = get_cpu();
- int shown = 0;
-
-wlock_again:
- /* Spin while there is another writer. */
- while (((long)rw->lock) < 0) {
- if (!--stuck) {
- if (shown++ <= 2)
- show_write(str, rw, caller);
- stuck = INIT_STUCK;
- }
- rmb();
- }
-
- /* Try to acuire the write bit. */
- __asm__ __volatile__(
-" mov 1, %%g3\n"
-" sllx %%g3, 63, %%g3\n"
-" ldx [%0], %%g1\n"
-" brlz,pn %%g1, 1f\n"
-" or %%g1, %%g3, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" membar #StoreLoad | #StoreStore\n"
-" ba,pt %%xcc, 2f\n"
-" sub %%g1, %%g7, %0\n"
-"1: mov 1, %0\n"
-"2:" : "=r" (val)
- : "0" (&(rw->lock))
- : "g3", "g1", "g7", "memory");
- if (val) {
- /* We couldn't get the write bit. */
- if (!--stuck) {
- if (shown++ <= 2)
- show_write(str, rw, caller);
- stuck = INIT_STUCK;
- }
- goto wlock_again;
- }
- if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) {
- /* Readers still around, drop the write
- * lock, spin, and try again.
- */
- if (!--stuck) {
- if (shown++ <= 2)
- show_write(str, rw, caller);
- stuck = INIT_STUCK;
- }
- __asm__ __volatile__(
-" mov 1, %%g3\n"
-" sllx %%g3, 63, %%g3\n"
-"1: ldx [%0], %%g1\n"
-" andn %%g1, %%g3, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" cmp %%g1, %%g7\n"
-" membar #StoreLoad | #StoreStore\n"
-" bne,pn %%xcc, 1b\n"
-" nop"
- : /* no outputs */
- : "r" (&(rw->lock))
- : "g3", "g1", "g7", "cc", "memory");
- while(rw->lock != 0) {
- if (!--stuck) {
- if (shown++ <= 2)
- show_write(str, rw, caller);
- stuck = INIT_STUCK;
- }
- rmb();
- }
- goto wlock_again;
- }
-
- /* We have it, say who we are. */
- rw->writer_pc = ((unsigned int)caller);
- rw->writer_cpu = cpu;
- current->thread.smp_lock_count++;
- current->thread.smp_lock_pc = ((unsigned int)caller);
-
- put_cpu();
-}
-
-void _do_write_unlock(rwlock_t *rw, unsigned long caller)
-{
- unsigned long val;
- int stuck = INIT_STUCK;
- int shown = 0;
-
- /* Drop our identity _first_ */
- rw->writer_pc = 0;
- rw->writer_cpu = NO_PROC_ID;
- current->thread.smp_lock_count--;
-wlock_again:
- __asm__ __volatile__(
-" membar #StoreLoad | #LoadLoad\n"
-" mov 1, %%g3\n"
-" sllx %%g3, 63, %%g3\n"
-" ldx [%0], %%g1\n"
-" andn %%g1, %%g3, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" membar #StoreLoad | #StoreStore\n"
-" sub %%g1, %%g7, %0\n"
- : "=r" (val)
- : "0" (&(rw->lock))
- : "g3", "g1", "g7", "memory");
- if (val) {
- if (!--stuck) {
- if (shown++ <= 2)
- show_write("write_unlock", rw, caller);
- stuck = INIT_STUCK;
- }
- goto wlock_again;
- }
-}
-
-int _do_write_trylock(rwlock_t *rw, char *str, unsigned long caller)
-{
- unsigned long val;
- int cpu = get_cpu();
-
- /* Try to acuire the write bit. */
- __asm__ __volatile__(
-" mov 1, %%g3\n"
-" sllx %%g3, 63, %%g3\n"
-" ldx [%0], %%g1\n"
-" brlz,pn %%g1, 1f\n"
-" or %%g1, %%g3, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" membar #StoreLoad | #StoreStore\n"
-" ba,pt %%xcc, 2f\n"
-" sub %%g1, %%g7, %0\n"
-"1: mov 1, %0\n"
-"2:" : "=r" (val)
- : "0" (&(rw->lock))
- : "g3", "g1", "g7", "memory");
-
- if (val) {
- put_cpu();
- return 0;
- }
-
- if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) {
- /* Readers still around, drop the write
- * lock, return failure.
- */
- __asm__ __volatile__(
-" mov 1, %%g3\n"
-" sllx %%g3, 63, %%g3\n"
-"1: ldx [%0], %%g1\n"
-" andn %%g1, %%g3, %%g7\n"
-" casx [%0], %%g1, %%g7\n"
-" cmp %%g1, %%g7\n"
-" membar #StoreLoad | #StoreStore\n"
-" bne,pn %%xcc, 1b\n"
-" nop"
- : /* no outputs */
- : "r" (&(rw->lock))
- : "g3", "g1", "g7", "cc", "memory");
-
- put_cpu();
-
- return 0;
- }
-
- /* We have it, say who we are. */
- rw->writer_pc = ((unsigned int)caller);
- rw->writer_cpu = cpu;
- current->thread.smp_lock_count++;
- current->thread.smp_lock_pc = ((unsigned int)caller);
-
- put_cpu();
-
- return 1;
-}
-
-#endif /* CONFIG_SMP */
diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S
deleted file mode 100644
index 8ee288dd0afc..000000000000
--- a/arch/sparc64/lib/dec_and_lock.S
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $Id: dec_and_lock.S,v 1.5 2001/11/18 00:12:56 davem Exp $
- * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()"
- * using cas and ldstub instructions.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- */
-#include <linux/config.h>
-#include <asm/thread_info.h>
-
- .text
- .align 64
-
- /* CAS basically works like this:
- *
- * void CAS(MEM, REG1, REG2)
- * {
- * START_ATOMIC();
- * if (*(MEM) == REG1) {
- * TMP = *(MEM);
- * *(MEM) = REG2;
- * REG2 = TMP;
- * } else
- * REG2 = *(MEM);
- * END_ATOMIC();
- * }
- */
-
- .globl _atomic_dec_and_lock
-_atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */
-loop1: lduw [%o0], %g2
- subcc %g2, 1, %g7
- be,pn %icc, start_to_zero
- nop
-nzero: cas [%o0], %g2, %g7
- cmp %g2, %g7
- bne,pn %icc, loop1
- mov 0, %g1
-
-out:
- membar #StoreLoad | #StoreStore
- retl
- mov %g1, %o0
-start_to_zero:
-#ifdef CONFIG_PREEMPT
- ldsw [%g6 + TI_PRE_COUNT], %g3
- add %g3, 1, %g3
- stw %g3, [%g6 + TI_PRE_COUNT]
-#endif
-to_zero:
- ldstub [%o1], %g3
- membar #StoreLoad | #StoreStore
- brnz,pn %g3, spin_on_lock
- nop
-loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */
- cmp %g2, %g7
-
- be,pt %icc, out
- mov 1, %g1
- lduw [%o0], %g2
- subcc %g2, 1, %g7
- be,pn %icc, loop2
- nop
- membar #StoreStore | #LoadStore
- stb %g0, [%o1]
-#ifdef CONFIG_PREEMPT
- ldsw [%g6 + TI_PRE_COUNT], %g3
- sub %g3, 1, %g3
- stw %g3, [%g6 + TI_PRE_COUNT]
-#endif
-
- b,pt %xcc, nzero
- nop
-spin_on_lock:
- ldub [%o1], %g3
- membar #LoadLoad
- brnz,pt %g3, spin_on_lock
- nop
- ba,pt %xcc, to_zero
- nop
- nop
diff --git a/arch/sparc64/lib/mb.S b/arch/sparc64/lib/mb.S
deleted file mode 100644
index 4004f748619f..000000000000
--- a/arch/sparc64/lib/mb.S
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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/lib/strncpy_from_user.S b/arch/sparc64/lib/strncpy_from_user.S
index 09cbbaa0ebf4..e1264650ca7a 100644
--- a/arch/sparc64/lib/strncpy_from_user.S
+++ b/arch/sparc64/lib/strncpy_from_user.S
@@ -125,15 +125,11 @@ __strncpy_from_user:
add %o2, %o3, %o0
.size __strncpy_from_user, .-__strncpy_from_user
- .section .fixup,#alloc,#execinstr
- .align 4
-4: retl
- mov -EFAULT, %o0
-
.section __ex_table,#alloc
.align 4
- .word 60b, 4b
- .word 61b, 4b
- .word 62b, 4b
- .word 63b, 4b
- .word 64b, 4b
+ .word 60b, __retl_efault
+ .word 61b, __retl_efault
+ .word 62b, __retl_efault
+ .word 63b, __retl_efault
+ .word 64b, __retl_efault
+ .previous
diff --git a/arch/sparc64/lib/user_fixup.c b/arch/sparc64/lib/user_fixup.c
index 0278e34125db..19d1fdb17d0e 100644
--- a/arch/sparc64/lib/user_fixup.c
+++ b/arch/sparc64/lib/user_fixup.c
@@ -11,61 +11,56 @@
/* Calculating the exact fault address when using
* block loads and stores can be very complicated.
+ *
* Instead of trying to be clever and handling all
* of the cases, just fix things up simply here.
*/
-unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned long size)
+static unsigned long compute_size(unsigned long start, unsigned long size, unsigned long *offset)
{
- char *dst = to;
- const char __user *src = from;
+ unsigned long fault_addr = current_thread_info()->fault_address;
+ unsigned long end = start + size;
- while (size) {
- if (__get_user(*dst, src))
- break;
- dst++;
- src++;
- size--;
+ if (fault_addr < start || fault_addr >= end) {
+ *offset = 0;
+ } else {
+ *offset = start - fault_addr;
+ size = end - fault_addr;
}
+ return size;
+}
- if (size)
- memset(dst, 0, size);
+unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned long size)
+{
+ unsigned long offset;
+
+ size = compute_size((unsigned long) from, size, &offset);
+ if (likely(size))
+ memset(to + offset, 0, size);
return size;
}
unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned long size)
{
- char __user *dst = to;
- const char *src = from;
-
- while (size) {
- if (__put_user(*src, dst))
- break;
- dst++;
- src++;
- size--;
- }
+ unsigned long offset;
- return size;
+ return compute_size((unsigned long) to, size, &offset);
}
unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned long size)
{
- char __user *dst = to;
- char __user *src = from;
+ unsigned long fault_addr = current_thread_info()->fault_address;
+ unsigned long start = (unsigned long) to;
+ unsigned long end = start + size;
- while (size) {
- char tmp;
+ if (fault_addr >= start && fault_addr < end)
+ return end - fault_addr;
- if (__get_user(tmp, src))
- break;
- if (__put_user(tmp, dst))
- break;
- dst++;
- src++;
- size--;
- }
+ start = (unsigned long) from;
+ end = start + size;
+ if (fault_addr >= start && fault_addr < end)
+ return end - fault_addr;
return size;
}
diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
index cda87333a77b..9d0960e69f48 100644
--- a/arch/sparc64/mm/Makefile
+++ b/arch/sparc64/mm/Makefile
@@ -5,6 +5,6 @@
EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS := -Werror
-obj-y := ultra.o tlb.o fault.o init.o generic.o extable.o
+obj-y := ultra.o tlb.o fault.o init.o generic.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/sparc64/mm/extable.c b/arch/sparc64/mm/extable.c
deleted file mode 100644
index ec334297ff4f..000000000000
--- a/arch/sparc64/mm/extable.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * linux/arch/sparc64/mm/extable.c
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
-
-void sort_extable(struct exception_table_entry *start,
- struct exception_table_entry *finish)
-{
-}
-
-/* Caller knows they are in a range if ret->fixup == 0 */
-const struct exception_table_entry *
-search_extable(const struct exception_table_entry *start,
- const struct exception_table_entry *last,
- unsigned long value)
-{
- const struct exception_table_entry *walk;
-
- /* Single insn entries are encoded as:
- * word 1: insn address
- * word 2: fixup code address
- *
- * Range entries are encoded as:
- * word 1: first insn address
- * word 2: 0
- * word 3: last insn address + 4 bytes
- * word 4: fixup code address
- *
- * See asm/uaccess.h for more details.
- */
-
- /* 1. Try to find an exact match. */
- for (walk = start; walk <= last; walk++) {
- if (walk->fixup == 0) {
- /* A range entry, skip both parts. */
- walk++;
- continue;
- }
-
- if (walk->insn == value)
- return walk;
- }
-
- /* 2. Try to find a range match. */
- for (walk = start; walk <= (last - 1); walk++) {
- if (walk->fixup)
- continue;
-
- if (walk[0].insn <= value && walk[1].insn > value)
- return walk;
-
- walk++;
- }
-
- return NULL;
-}
-
-/* Special extable search, which handles ranges. Returns fixup */
-unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
-{
- const struct exception_table_entry *entry;
-
- entry = search_exception_tables(addr);
- if (!entry)
- return 0;
-
- /* Inside range? Fix g2 and return correct fixup */
- if (!entry->fixup) {
- *g2 = (addr - entry->insn) / 4;
- return (entry + 1)->fixup;
- }
-
- return entry->fixup;
-}
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index db1e3310e907..31fbc67719a1 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -32,8 +32,6 @@
#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
-extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
-
/*
* To debug kernel to catch accesses to certain virtual/physical addresses.
* Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
@@ -71,53 +69,6 @@ void set_brkpt(unsigned long addr, unsigned char mask, int flags, int mode)
: "memory");
}
-/* Nice, simple, prom library does all the sweating for us. ;) */
-unsigned long __init prom_probe_memory (void)
-{
- register struct linux_mlist_p1275 *mlist;
- register unsigned long bytes, base_paddr, tally;
- register int i;
-
- i = 0;
- mlist = *prom_meminfo()->p1275_available;
- bytes = tally = mlist->num_bytes;
- base_paddr = mlist->start_adr;
-
- sp_banks[0].base_addr = base_paddr;
- sp_banks[0].num_bytes = bytes;
-
- while (mlist->theres_more != (void *) 0) {
- i++;
- mlist = mlist->theres_more;
- bytes = mlist->num_bytes;
- tally += bytes;
- if (i >= SPARC_PHYS_BANKS-1) {
- printk ("The machine has more banks than "
- "this kernel can support\n"
- "Increase the SPARC_PHYS_BANKS "
- "setting (currently %d)\n",
- SPARC_PHYS_BANKS);
- i = SPARC_PHYS_BANKS-1;
- break;
- }
-
- sp_banks[i].base_addr = mlist->start_adr;
- sp_banks[i].num_bytes = mlist->num_bytes;
- }
-
- i++;
- sp_banks[i].base_addr = 0xdeadbeefbeefdeadUL;
- sp_banks[i].num_bytes = 0;
-
- /* Now mask all bank sizes on a page boundary, it is all we can
- * use anyways.
- */
- for (i = 0; sp_banks[i].num_bytes != 0; i++)
- sp_banks[i].num_bytes &= PAGE_MASK;
-
- return tally;
-}
-
static void __kprobes unhandled_fault(unsigned long address,
struct task_struct *tsk,
struct pt_regs *regs)
@@ -242,7 +193,6 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
unsigned int insn, unsigned long address)
{
- unsigned long g2;
unsigned char asi = ASI_P;
if ((!insn) && (regs->tstate & TSTATE_PRIV))
@@ -273,11 +223,9 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
}
}
- g2 = regs->u_regs[UREG_G2];
-
/* Is this in ex_table? */
if (regs->tstate & TSTATE_PRIV) {
- unsigned long fixup;
+ const struct exception_table_entry *entry;
if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
if (insn & 0x2000)
@@ -288,10 +236,9 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
/* Look in asi.h: All _S asis have LS bit set */
if ((asi & 0x1) &&
- (fixup = search_extables_range(regs->tpc, &g2))) {
- regs->tpc = fixup;
+ (entry = search_exception_tables(regs->tpc))) {
+ regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
- regs->u_regs[UREG_G2] = g2;
return;
}
} else {
@@ -461,7 +408,7 @@ good_area:
}
up_read(&mm->mmap_sem);
- goto fault_done;
+ return;
/*
* Something tried to access memory that isn't in our memory map..
@@ -473,8 +420,7 @@ bad_area:
handle_kernel_fault:
do_kernel_fault(regs, si_code, fault_code, insn, address);
-
- goto fault_done;
+ return;
/*
* We ran out of memory, or some other thing happened to us that made
@@ -505,9 +451,4 @@ do_sigbus:
/* Kernel mode? Handle exceptions or die */
if (regs->tstate & TSTATE_PRIV)
goto handle_kernel_fault;
-
-fault_done:
- /* These values are no longer needed, clear them. */
- set_thread_fault_code(0);
- current_thread_info()->fault_address = 0;
}
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index fdb1ebb308c9..1e44ee26cee8 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -20,6 +20,8 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/kprobes.h>
+#include <linux/cache.h>
+#include <linux/sort.h>
#include <asm/head.h>
#include <asm/system.h>
@@ -40,24 +42,80 @@
extern void device_scan(void);
-struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+#define MAX_BANKS 32
-unsigned long *sparc64_valid_addr_bitmap;
+static struct linux_prom64_registers pavail[MAX_BANKS] __initdata;
+static struct linux_prom64_registers pavail_rescan[MAX_BANKS] __initdata;
+static int pavail_ents __initdata;
+static int pavail_rescan_ents __initdata;
+
+static int cmp_p64(const void *a, const void *b)
+{
+ const struct linux_prom64_registers *x = a, *y = b;
+
+ if (x->phys_addr > y->phys_addr)
+ return 1;
+ if (x->phys_addr < y->phys_addr)
+ return -1;
+ return 0;
+}
+
+static void __init read_obp_memory(const char *property,
+ struct linux_prom64_registers *regs,
+ int *num_ents)
+{
+ int node = prom_finddevice("/memory");
+ int prop_size = prom_getproplen(node, property);
+ int ents, ret, i;
+
+ ents = prop_size / sizeof(struct linux_prom64_registers);
+ if (ents > MAX_BANKS) {
+ prom_printf("The machine has more %s property entries than "
+ "this kernel can support (%d).\n",
+ property, MAX_BANKS);
+ prom_halt();
+ }
+
+ ret = prom_getproperty(node, property, (char *) regs, prop_size);
+ if (ret == -1) {
+ prom_printf("Couldn't get %s property from /memory.\n");
+ prom_halt();
+ }
+
+ *num_ents = ents;
+
+ /* Sanitize what we got from the firmware, by page aligning
+ * everything.
+ */
+ for (i = 0; i < ents; i++) {
+ unsigned long base, size;
+
+ base = regs[i].phys_addr;
+ size = regs[i].reg_size;
+
+ size &= PAGE_MASK;
+ if (base & ~PAGE_MASK) {
+ unsigned long new_base = PAGE_ALIGN(base);
+
+ size -= new_base - base;
+ if ((long) size < 0L)
+ size = 0UL;
+ base = new_base;
+ }
+ regs[i].phys_addr = base;
+ regs[i].reg_size = size;
+ }
+ sort(regs, ents, sizeof(struct linux_prom64_registers),
+ cmp_p64, NULL);
+}
+
+unsigned long *sparc64_valid_addr_bitmap __read_mostly;
/* Ugly, but necessary... -DaveM */
-unsigned long phys_base;
-unsigned long kern_base;
-unsigned long kern_size;
-unsigned long pfn_base;
-
-/* This is even uglier. We have a problem where the kernel may not be
- * located at phys_base. However, initial __alloc_bootmem() calls need to
- * be adjusted to be within the 4-8Megs that the kernel is mapped to, else
- * those page mappings wont work. Things are ok after inherit_prom_mappings
- * is called though. Dave says he'll clean this up some other time.
- * -- BenC
- */
-static unsigned long bootmap_base;
+unsigned long phys_base __read_mostly;
+unsigned long kern_base __read_mostly;
+unsigned long kern_size __read_mostly;
+unsigned long pfn_base __read_mostly;
/* get_new_mmu_context() uses "cache + 1". */
DEFINE_SPINLOCK(ctx_alloc_lock);
@@ -73,7 +131,13 @@ extern unsigned long sparc_ramdisk_image64;
extern unsigned int sparc_ramdisk_image;
extern unsigned int sparc_ramdisk_size;
-struct page *mem_map_zero;
+struct page *mem_map_zero __read_mostly;
+
+unsigned int sparc64_highest_unlocked_tlb_ent __read_mostly;
+
+unsigned long sparc64_kern_pri_context __read_mostly;
+unsigned long sparc64_kern_pri_nuc_bits __read_mostly;
+unsigned long sparc64_kern_sec_context __read_mostly;
int bigkernel = 0;
@@ -179,8 +243,6 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c
: "g1", "g7");
}
-extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code);
-
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
{
struct page *page;
@@ -207,10 +269,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
put_cpu();
}
-
- if (get_thread_fault_code())
- __update_mmu_cache(CTX_NRBITS(vma->vm_mm->context),
- address, pte, get_thread_fault_code());
}
void flush_dcache_page(struct page *page)
@@ -310,6 +368,11 @@ struct linux_prom_translation {
unsigned long data;
};
+/* Exported for kernel TLB miss handling in ktlb.S */
+struct linux_prom_translation prom_trans[512] __read_mostly;
+unsigned int prom_trans_ents __read_mostly;
+unsigned int swapper_pgd_zero __read_mostly;
+
extern unsigned long prom_boot_page;
extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle);
extern int prom_get_mmu_ihandle(void);
@@ -318,297 +381,162 @@ extern void register_prom_callbacks(void);
/* Exported for SMP bootup purposes. */
unsigned long kern_locked_tte_data;
-void __init early_pgtable_allocfail(char *type)
-{
- prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type);
- prom_halt();
-}
-
-#define BASE_PAGE_SIZE 8192
-static pmd_t *prompmd;
-
/*
* Translate PROM's mapping we capture at boot time into physical address.
* The second parameter is only set from prom_callback() invocations.
*/
unsigned long prom_virt_to_phys(unsigned long promva, int *error)
{
- pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff);
- pte_t *ptep;
- unsigned long base;
-
- if (pmd_none(*pmdp)) {
- if (error)
- *error = 1;
- return(0);
- }
- ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff);
- if (!pte_present(*ptep)) {
- if (error)
- *error = 1;
- return(0);
- }
- if (error) {
- *error = 0;
- return(pte_val(*ptep));
+ int i;
+
+ for (i = 0; i < prom_trans_ents; i++) {
+ struct linux_prom_translation *p = &prom_trans[i];
+
+ if (promva >= p->virt &&
+ promva < (p->virt + p->size)) {
+ unsigned long base = p->data & _PAGE_PADDR;
+
+ if (error)
+ *error = 0;
+ return base + (promva & (8192 - 1));
+ }
}
- base = pte_val(*ptep) & _PAGE_PADDR;
- return(base + (promva & (BASE_PAGE_SIZE - 1)));
+ if (error)
+ *error = 1;
+ return 0UL;
}
-static void inherit_prom_mappings(void)
+/* The obp translations are saved based on 8k pagesize, since obp can
+ * use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS ->
+ * HI_OBP_ADDRESS range are handled in ktlb.S and do not use the vpte
+ * scheme (also, see rant in inherit_locked_prom_mappings()).
+ */
+static inline int in_obp_range(unsigned long vaddr)
{
- struct linux_prom_translation *trans;
- unsigned long phys_page, tte_vaddr, tte_data;
- void (*remap_func)(unsigned long, unsigned long, int);
- pmd_t *pmdp;
- pte_t *ptep;
- int node, n, i, tsz;
- extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2];
+ return (vaddr >= LOW_OBP_ADDRESS &&
+ vaddr < HI_OBP_ADDRESS);
+}
+
+static int cmp_ptrans(const void *a, const void *b)
+{
+ const struct linux_prom_translation *x = a, *y = b;
+
+ if (x->virt > y->virt)
+ return 1;
+ if (x->virt < y->virt)
+ return -1;
+ return 0;
+}
+
+/* Read OBP translations property into 'prom_trans[]'. */
+static void __init read_obp_translations(void)
+{
+ int n, node, ents, first, last, i;
node = prom_finddevice("/virtual-memory");
n = prom_getproplen(node, "translations");
- if (n == 0 || n == -1) {
- prom_printf("Couldn't get translation property\n");
+ if (unlikely(n == 0 || n == -1)) {
+ prom_printf("prom_mappings: Couldn't get size.\n");
prom_halt();
}
- n += 5 * sizeof(struct linux_prom_translation);
- for (tsz = 1; tsz < n; tsz <<= 1)
- /* empty */;
- trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base);
- if (trans == NULL) {
- prom_printf("inherit_prom_mappings: Cannot alloc translations.\n");
+ if (unlikely(n > sizeof(prom_trans))) {
+ prom_printf("prom_mappings: Size %Zd is too big.\n", n);
prom_halt();
}
- memset(trans, 0, tsz);
- if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {
- prom_printf("Couldn't get translation property\n");
+ if ((n = prom_getproperty(node, "translations",
+ (char *)&prom_trans[0],
+ sizeof(prom_trans))) == -1) {
+ prom_printf("prom_mappings: Couldn't get property.\n");
prom_halt();
}
- n = n / sizeof(*trans);
- /*
- * The obp translations are saved based on 8k pagesize, since obp can
- * use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000,
- * ie obp range, are handled in entry.S and do not use the vpte scheme
- * (see rant in inherit_locked_prom_mappings()).
- */
-#define OBP_PMD_SIZE 2048
- prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base);
- if (prompmd == NULL)
- early_pgtable_allocfail("pmd");
- memset(prompmd, 0, OBP_PMD_SIZE);
- for (i = 0; i < n; i++) {
- unsigned long vaddr;
-
- if (trans[i].virt >= LOW_OBP_ADDRESS && trans[i].virt < HI_OBP_ADDRESS) {
- for (vaddr = trans[i].virt;
- ((vaddr < trans[i].virt + trans[i].size) &&
- (vaddr < HI_OBP_ADDRESS));
- vaddr += BASE_PAGE_SIZE) {
- unsigned long val;
-
- pmdp = prompmd + ((vaddr >> 23) & 0x7ff);
- if (pmd_none(*pmdp)) {
- ptep = __alloc_bootmem(BASE_PAGE_SIZE,
- BASE_PAGE_SIZE,
- bootmap_base);
- if (ptep == NULL)
- early_pgtable_allocfail("pte");
- memset(ptep, 0, BASE_PAGE_SIZE);
- pmd_set(pmdp, ptep);
- }
- ptep = (pte_t *)__pmd_page(*pmdp) +
- ((vaddr >> 13) & 0x3ff);
+ n = n / sizeof(struct linux_prom_translation);
- val = trans[i].data;
+ ents = n;
- /* Clear diag TTE bits. */
- if (tlb_type == spitfire)
- val &= ~0x0003fe0000000000UL;
+ sort(prom_trans, ents, sizeof(struct linux_prom_translation),
+ cmp_ptrans, NULL);
- set_pte_at(&init_mm, vaddr,
- ptep, __pte(val | _PAGE_MODIFIED));
- trans[i].data += BASE_PAGE_SIZE;
- }
- }
+ /* Now kick out all the non-OBP entries. */
+ for (i = 0; i < ents; i++) {
+ if (in_obp_range(prom_trans[i].virt))
+ break;
+ }
+ first = i;
+ for (; i < ents; i++) {
+ if (!in_obp_range(prom_trans[i].virt))
+ break;
}
- phys_page = __pa(prompmd);
- obp_iaddr_patch[0] |= (phys_page >> 10);
- obp_iaddr_patch[1] |= (phys_page & 0x3ff);
- flushi((long)&obp_iaddr_patch[0]);
- obp_daddr_patch[0] |= (phys_page >> 10);
- obp_daddr_patch[1] |= (phys_page & 0x3ff);
- flushi((long)&obp_daddr_patch[0]);
+ last = i;
- /* Now fixup OBP's idea about where we really are mapped. */
- prom_printf("Remapping the kernel... ");
+ for (i = 0; i < (last - first); i++) {
+ struct linux_prom_translation *src = &prom_trans[i + first];
+ struct linux_prom_translation *dest = &prom_trans[i];
- /* Spitfire Errata #32 workaround */
- /* NOTE: Using plain zero for the context value is
- * correct here, we are not using the Linux trap
- * tables yet so we should not use the special
- * UltraSPARC-III+ page size encodings yet.
- */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- switch (tlb_type) {
- default:
- case spitfire:
- phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());
- break;
-
- case cheetah:
- case cheetah_plus:
- phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent());
- break;
- };
-
- phys_page &= _PAGE_PADDR;
- phys_page += ((unsigned long)&prom_boot_page -
- (unsigned long)KERNBASE);
+ *dest = *src;
+ }
+ for (; i < ents; i++) {
+ struct linux_prom_translation *dest = &prom_trans[i];
+ dest->virt = dest->size = dest->data = 0x0UL;
+ }
+
+ prom_trans_ents = last - first;
if (tlb_type == spitfire) {
- /* Lock this into i/d tlb entry 59 */
- __asm__ __volatile__(
- "stxa %%g0, [%2] %3\n\t"
- "stxa %0, [%1] %4\n\t"
- "membar #Sync\n\t"
- "flush %%g6\n\t"
- "stxa %%g0, [%2] %5\n\t"
- "stxa %0, [%1] %6\n\t"
- "membar #Sync\n\t"
- "flush %%g6"
- : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
- _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
- "r" (59 << 3), "r" (TLB_TAG_ACCESS),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
- "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
- : "memory");
- } else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
- /* Lock this into i/d tlb-0 entry 11 */
- __asm__ __volatile__(
- "stxa %%g0, [%2] %3\n\t"
- "stxa %0, [%1] %4\n\t"
- "membar #Sync\n\t"
- "flush %%g6\n\t"
- "stxa %%g0, [%2] %5\n\t"
- "stxa %0, [%1] %6\n\t"
- "membar #Sync\n\t"
- "flush %%g6"
- : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
- _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
- "r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
- "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
- : "memory");
- } else {
- /* Implement me :-) */
- BUG();
+ /* Clear diag TTE bits. */
+ for (i = 0; i < prom_trans_ents; i++)
+ prom_trans[i].data &= ~0x0003fe0000000000UL;
}
+}
- tte_vaddr = (unsigned long) KERNBASE;
+static void __init remap_kernel(void)
+{
+ unsigned long phys_page, tte_vaddr, tte_data;
+ int tlb_ent = sparc64_highest_locked_tlbent();
- /* Spitfire Errata #32 workaround */
- /* NOTE: Using plain zero for the context value is
- * correct here, we are not using the Linux trap
- * tables yet so we should not use the special
- * UltraSPARC-III+ page size encodings yet.
- */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- if (tlb_type == spitfire)
- tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());
- else
- tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent());
+ tte_vaddr = (unsigned long) KERNBASE;
+ phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
+ tte_data = (phys_page | (_PAGE_VALID | _PAGE_SZ4MB |
+ _PAGE_CP | _PAGE_CV | _PAGE_P |
+ _PAGE_L | _PAGE_W));
kern_locked_tte_data = tte_data;
- remap_func = (void *) ((unsigned long) &prom_remap -
- (unsigned long) &prom_boot_page);
-
-
- /* Spitfire Errata #32 workaround */
- /* NOTE: Using plain zero for the context value is
- * correct here, we are not using the Linux trap
- * tables yet so we should not use the special
- * UltraSPARC-III+ page size encodings yet.
- */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- remap_func((tlb_type == spitfire ?
- (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :
- (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),
- (unsigned long) KERNBASE,
- prom_get_mmu_ihandle());
-
- if (bigkernel)
- remap_func(((tte_data + 0x400000) & _PAGE_PADDR),
- (unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle());
-
- /* Flush out that temporary mapping. */
- spitfire_flush_dtlb_nucleus_page(0x0);
- spitfire_flush_itlb_nucleus_page(0x0);
-
- /* Now lock us back into the TLBs via OBP. */
- prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
- prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
+ /* Now lock us into the TLBs via OBP. */
+ prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
+ prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
if (bigkernel) {
- prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000,
- tte_vaddr + 0x400000);
- prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000,
- tte_vaddr + 0x400000);
+ tlb_ent -= 1;
+ prom_dtlb_load(tlb_ent,
+ tte_data + 0x400000,
+ tte_vaddr + 0x400000);
+ prom_itlb_load(tlb_ent,
+ tte_data + 0x400000,
+ tte_vaddr + 0x400000);
}
-
- /* Re-read translations property. */
- if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {
- prom_printf("Couldn't get translation property\n");
- prom_halt();
+ sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
+ if (tlb_type == cheetah_plus) {
+ sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
+ CTX_CHEETAH_PLUS_NUC);
+ sparc64_kern_pri_nuc_bits = CTX_CHEETAH_PLUS_NUC;
+ sparc64_kern_sec_context = CTX_CHEETAH_PLUS_CTX0;
}
- n = n / sizeof(*trans);
-
- for (i = 0; i < n; i++) {
- unsigned long vaddr = trans[i].virt;
- unsigned long size = trans[i].size;
-
- if (vaddr < 0xf0000000UL) {
- unsigned long avoid_start = (unsigned long) KERNBASE;
- unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);
-
- if (bigkernel)
- avoid_end += (4 * 1024 * 1024);
- if (vaddr < avoid_start) {
- unsigned long top = vaddr + size;
+}
- if (top > avoid_start)
- top = avoid_start;
- prom_unmap(top - vaddr, vaddr);
- }
- if ((vaddr + size) > avoid_end) {
- unsigned long bottom = vaddr;
- if (bottom < avoid_end)
- bottom = avoid_end;
- prom_unmap((vaddr + size) - bottom, bottom);
- }
- }
- }
+static void __init inherit_prom_mappings(void)
+{
+ read_obp_translations();
+ /* Now fixup OBP's idea about where we really are mapped. */
+ prom_printf("Remapping the kernel... ");
+ remap_kernel();
prom_printf("done.\n");
+ prom_printf("Registering callbacks... ");
register_prom_callbacks();
+ prom_printf("done.\n");
}
/* The OBP specifications for sun4u mark 0xfffffffc00000000 and
@@ -792,8 +720,8 @@ void inherit_locked_prom_mappings(int save_p)
}
}
if (tlb_type == spitfire) {
- int high = SPITFIRE_HIGHEST_LOCKED_TLBENT - bigkernel;
- for (i = 0; i < high; i++) {
+ int high = sparc64_highest_unlocked_tlb_ent;
+ for (i = 0; i <= high; i++) {
unsigned long data;
/* Spitfire Errata #32 workaround */
@@ -881,9 +809,9 @@ void inherit_locked_prom_mappings(int save_p)
}
}
} else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
- int high = CHEETAH_HIGHEST_LOCKED_TLBENT - bigkernel;
+ int high = sparc64_highest_unlocked_tlb_ent;
- for (i = 0; i < high; i++) {
+ for (i = 0; i <= high; i++) {
unsigned long data;
data = cheetah_get_ldtlb_data(i);
@@ -1276,14 +1204,14 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
int i;
#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("bootmem_init: Scan sp_banks, ");
+ prom_printf("bootmem_init: Scan pavail, ");
#endif
bytes_avail = 0UL;
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- end_of_phys_memory = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- bytes_avail += sp_banks[i].num_bytes;
+ for (i = 0; i < pavail_ents; i++) {
+ end_of_phys_memory = pavail[i].phys_addr +
+ pavail[i].reg_size;
+ bytes_avail += pavail[i].reg_size;
if (cmdline_memory_size) {
if (bytes_avail > cmdline_memory_size) {
unsigned long slack = bytes_avail - cmdline_memory_size;
@@ -1291,12 +1219,15 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
bytes_avail -= slack;
end_of_phys_memory -= slack;
- sp_banks[i].num_bytes -= slack;
- if (sp_banks[i].num_bytes == 0) {
- sp_banks[i].base_addr = 0xdeadbeef;
+ pavail[i].reg_size -= slack;
+ if ((long)pavail[i].reg_size <= 0L) {
+ pavail[i].phys_addr = 0xdeadbeefUL;
+ pavail[i].reg_size = 0UL;
+ pavail_ents = i;
} else {
- sp_banks[i+1].num_bytes = 0;
- sp_banks[i+1].base_addr = 0xdeadbeef;
+ pavail[i+1].reg_size = 0Ul;
+ pavail[i+1].phys_addr = 0xdeadbeefUL;
+ pavail_ents = i + 1;
}
break;
}
@@ -1347,17 +1278,15 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
#endif
bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn);
- bootmap_base = bootmap_pfn << PAGE_SHIFT;
-
/* Now register the available physical memory with the
* allocator.
*/
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+ for (i = 0; i < pavail_ents; i++) {
#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("free_bootmem(sp_banks:%d): base[%lx] size[%lx]\n",
- i, sp_banks[i].base_addr, sp_banks[i].num_bytes);
+ prom_printf("free_bootmem(pavail:%d): base[%lx] size[%lx]\n",
+ i, pavail[i].phys_addr, pavail[i].reg_size);
#endif
- free_bootmem(sp_banks[i].base_addr, sp_banks[i].num_bytes);
+ free_bootmem(pavail[i].phys_addr, pavail[i].reg_size);
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -1398,121 +1327,167 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
return end_pfn;
}
+#ifdef CONFIG_DEBUG_PAGEALLOC
+static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot)
+{
+ unsigned long vstart = PAGE_OFFSET + pstart;
+ unsigned long vend = PAGE_OFFSET + pend;
+ unsigned long alloc_bytes = 0UL;
+
+ if ((vstart & ~PAGE_MASK) || (vend & ~PAGE_MASK)) {
+ prom_printf("kernel_map: Unaligned physmem[%lx:%lx]\n",
+ vstart, vend);
+ prom_halt();
+ }
+
+ while (vstart < vend) {
+ unsigned long this_end, paddr = __pa(vstart);
+ pgd_t *pgd = pgd_offset_k(vstart);
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pud = pud_offset(pgd, vstart);
+ if (pud_none(*pud)) {
+ pmd_t *new;
+
+ new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+ alloc_bytes += PAGE_SIZE;
+ pud_populate(&init_mm, pud, new);
+ }
+
+ pmd = pmd_offset(pud, vstart);
+ if (!pmd_present(*pmd)) {
+ pte_t *new;
+
+ new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+ alloc_bytes += PAGE_SIZE;
+ pmd_populate_kernel(&init_mm, pmd, new);
+ }
+
+ pte = pte_offset_kernel(pmd, vstart);
+ this_end = (vstart + PMD_SIZE) & PMD_MASK;
+ if (this_end > vend)
+ this_end = vend;
+
+ while (vstart < this_end) {
+ pte_val(*pte) = (paddr | pgprot_val(prot));
+
+ vstart += PAGE_SIZE;
+ paddr += PAGE_SIZE;
+ pte++;
+ }
+ }
+
+ return alloc_bytes;
+}
+
+static struct linux_prom64_registers pall[MAX_BANKS] __initdata;
+static int pall_ents __initdata;
+
+extern unsigned int kvmap_linear_patch[1];
+
+static void __init kernel_physical_mapping_init(void)
+{
+ unsigned long i, mem_alloced = 0UL;
+
+ read_obp_memory("reg", &pall[0], &pall_ents);
+
+ for (i = 0; i < pall_ents; i++) {
+ unsigned long phys_start, phys_end;
+
+ phys_start = pall[i].phys_addr;
+ phys_end = phys_start + pall[i].reg_size;
+ mem_alloced += kernel_map_range(phys_start, phys_end,
+ PAGE_KERNEL);
+ }
+
+ printk("Allocated %ld bytes for kernel page tables.\n",
+ mem_alloced);
+
+ kvmap_linear_patch[0] = 0x01000000; /* nop */
+ flushi(&kvmap_linear_patch[0]);
+
+ __flush_tlb_all();
+}
+
+void kernel_map_pages(struct page *page, int numpages, int enable)
+{
+ unsigned long phys_start = page_to_pfn(page) << PAGE_SHIFT;
+ unsigned long phys_end = phys_start + (numpages * PAGE_SIZE);
+
+ kernel_map_range(phys_start, phys_end,
+ (enable ? PAGE_KERNEL : __pgprot(0)));
+
+ /* we should perform an IPI and flush all tlbs,
+ * but that can deadlock->flush only current cpu.
+ */
+ __flush_tlb_kernel_range(PAGE_OFFSET + phys_start,
+ PAGE_OFFSET + phys_end);
+}
+#endif
+
+unsigned long __init find_ecache_flush_span(unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < pavail_ents; i++) {
+ if (pavail[i].reg_size >= size)
+ return pavail[i].phys_addr;
+ }
+
+ return ~0UL;
+}
+
/* paging_init() sets up the page tables */
extern void cheetah_ecache_flush_init(void);
static unsigned long last_valid_pfn;
+pgd_t swapper_pg_dir[2048];
void __init paging_init(void)
{
- extern pmd_t swapper_pmd_dir[1024];
- extern unsigned int sparc64_vpte_patchme1[1];
- extern unsigned int sparc64_vpte_patchme2[1];
- unsigned long alias_base = kern_base + PAGE_OFFSET;
- unsigned long second_alias_page = 0;
- unsigned long pt, flags, end_pfn, pages_avail;
- unsigned long shift = alias_base - ((unsigned long)KERNBASE);
- unsigned long real_end;
+ unsigned long end_pfn, pages_avail, shift;
+ unsigned long real_end, i;
+
+ /* Find available physical memory... */
+ read_obp_memory("available", &pavail[0], &pavail_ents);
+
+ phys_base = 0xffffffffffffffffUL;
+ for (i = 0; i < pavail_ents; i++)
+ phys_base = min(phys_base, pavail[i].phys_addr);
+
+ pfn_base = phys_base >> PAGE_SHIFT;
+
+ kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
+ kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
set_bit(0, mmu_context_bmap);
+ shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE);
+
real_end = (unsigned long)_end;
if ((real_end > ((unsigned long)KERNBASE + 0x400000)))
bigkernel = 1;
-#ifdef CONFIG_BLK_DEV_INITRD
- if (sparc_ramdisk_image || sparc_ramdisk_image64)
- real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size));
-#endif
-
- /* We assume physical memory starts at some 4mb multiple,
- * if this were not true we wouldn't boot up to this point
- * anyways.
- */
- pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB;
- pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
- local_irq_save(flags);
- if (tlb_type == spitfire) {
- __asm__ __volatile__(
- " stxa %1, [%0] %3\n"
- " stxa %2, [%5] %4\n"
- " membar #Sync\n"
- " flush %%g6\n"
- " nop\n"
- " nop\n"
- " nop\n"
- : /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
- : "memory");
- if (real_end >= KERNBASE + 0x340000) {
- second_alias_page = alias_base + 0x400000;
- __asm__ __volatile__(
- " stxa %1, [%0] %3\n"
- " stxa %2, [%5] %4\n"
- " membar #Sync\n"
- " flush %%g6\n"
- " nop\n"
- " nop\n"
- " nop\n"
- : /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3)
- : "memory");
- }
- } else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
- __asm__ __volatile__(
- " stxa %1, [%0] %3\n"
- " stxa %2, [%5] %4\n"
- " membar #Sync\n"
- " flush %%g6\n"
- " nop\n"
- " nop\n"
- " nop\n"
- : /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3))
- : "memory");
- if (real_end >= KERNBASE + 0x340000) {
- second_alias_page = alias_base + 0x400000;
- __asm__ __volatile__(
- " stxa %1, [%0] %3\n"
- " stxa %2, [%5] %4\n"
- " membar #Sync\n"
- " flush %%g6\n"
- " nop\n"
- " nop\n"
- " nop\n"
- : /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3))
- : "memory");
- }
+ if ((real_end > ((unsigned long)KERNBASE + 0x800000))) {
+ prom_printf("paging_init: Kernel > 8MB, too large.\n");
+ prom_halt();
}
- local_irq_restore(flags);
-
- /* Now set kernel pgd to upper alias so physical page computations
+
+ /* Set kernel pgd to upper alias so physical page computations
* work.
*/
init_mm.pgd += ((shift) / (sizeof(pgd_t)));
- memset(swapper_pmd_dir, 0, sizeof(swapper_pmd_dir));
+ memset(swapper_low_pmd_dir, 0, sizeof(swapper_low_pmd_dir));
/* Now can init the kernel/bad page tables. */
pud_set(pud_offset(&swapper_pg_dir[0], 0),
- swapper_pmd_dir + (shift / sizeof(pgd_t)));
+ swapper_low_pmd_dir + (shift / sizeof(pgd_t)));
- sparc64_vpte_patchme1[0] |=
- (((unsigned long)pgd_val(init_mm.pgd[0])) >> 10);
- sparc64_vpte_patchme2[0] |=
- (((unsigned long)pgd_val(init_mm.pgd[0])) & 0x3ff);
- flushi((long)&sparc64_vpte_patchme1[0]);
+ swapper_pgd_zero = pgd_val(swapper_pg_dir[0]);
- /* Setup bootmem... */
- pages_avail = 0;
- last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
-
- /* Inherit non-locked OBP mappings. */
inherit_prom_mappings();
/* Ok, we can use our TLB miss and window trap handlers safely.
@@ -1527,13 +1502,16 @@ void __init paging_init(void)
inherit_locked_prom_mappings(1);
- /* We only created DTLB mapping of this stuff. */
- spitfire_flush_dtlb_nucleus_page(alias_base);
- if (second_alias_page)
- spitfire_flush_dtlb_nucleus_page(second_alias_page);
-
__flush_tlb_all();
+ /* Setup bootmem... */
+ pages_avail = 0;
+ last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+ kernel_physical_mapping_init();
+#endif
+
{
unsigned long zones_size[MAX_NR_ZONES];
unsigned long zholes_size[MAX_NR_ZONES];
@@ -1554,128 +1532,35 @@ void __init paging_init(void)
device_scan();
}
-/* Ok, it seems that the prom can allocate some more memory chunks
- * as a side effect of some prom calls we perform during the
- * boot sequence. My most likely theory is that it is from the
- * prom_set_traptable() call, and OBP is allocating a scratchpad
- * for saving client program register state etc.
- */
-static void __init sort_memlist(struct linux_mlist_p1275 *thislist)
-{
- int swapi = 0;
- int i, mitr;
- unsigned long tmpaddr, tmpsize;
- unsigned long lowest;
-
- for (i = 0; thislist[i].theres_more != 0; i++) {
- lowest = thislist[i].start_adr;
- for (mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++)
- if (thislist[mitr].start_adr < lowest) {
- lowest = thislist[mitr].start_adr;
- swapi = mitr;
- }
- if (lowest == thislist[i].start_adr)
- continue;
- tmpaddr = thislist[swapi].start_adr;
- tmpsize = thislist[swapi].num_bytes;
- for (mitr = swapi; mitr > i; mitr--) {
- thislist[mitr].start_adr = thislist[mitr-1].start_adr;
- thislist[mitr].num_bytes = thislist[mitr-1].num_bytes;
- }
- thislist[i].start_adr = tmpaddr;
- thislist[i].num_bytes = tmpsize;
- }
-}
-
-void __init rescan_sp_banks(void)
-{
- struct linux_prom64_registers memlist[64];
- struct linux_mlist_p1275 avail[64], *mlist;
- unsigned long bytes, base_paddr;
- int num_regs, node = prom_finddevice("/memory");
- int i;
-
- num_regs = prom_getproperty(node, "available",
- (char *) memlist, sizeof(memlist));
- num_regs = (num_regs / sizeof(struct linux_prom64_registers));
- for (i = 0; i < num_regs; i++) {
- avail[i].start_adr = memlist[i].phys_addr;
- avail[i].num_bytes = memlist[i].reg_size;
- avail[i].theres_more = &avail[i + 1];
- }
- avail[i - 1].theres_more = NULL;
- sort_memlist(avail);
-
- mlist = &avail[0];
- i = 0;
- bytes = mlist->num_bytes;
- base_paddr = mlist->start_adr;
-
- sp_banks[0].base_addr = base_paddr;
- sp_banks[0].num_bytes = bytes;
-
- while (mlist->theres_more != NULL){
- i++;
- mlist = mlist->theres_more;
- bytes = mlist->num_bytes;
- if (i >= SPARC_PHYS_BANKS-1) {
- printk ("The machine has more banks than "
- "this kernel can support\n"
- "Increase the SPARC_PHYS_BANKS "
- "setting (currently %d)\n",
- SPARC_PHYS_BANKS);
- i = SPARC_PHYS_BANKS-1;
- break;
- }
-
- sp_banks[i].base_addr = mlist->start_adr;
- sp_banks[i].num_bytes = mlist->num_bytes;
- }
-
- i++;
- sp_banks[i].base_addr = 0xdeadbeefbeefdeadUL;
- sp_banks[i].num_bytes = 0;
-
- for (i = 0; sp_banks[i].num_bytes != 0; i++)
- sp_banks[i].num_bytes &= PAGE_MASK;
-}
-
static void __init taint_real_pages(void)
{
- struct sparc_phys_banks saved_sp_banks[SPARC_PHYS_BANKS];
int i;
- for (i = 0; i < SPARC_PHYS_BANKS; i++) {
- saved_sp_banks[i].base_addr =
- sp_banks[i].base_addr;
- saved_sp_banks[i].num_bytes =
- sp_banks[i].num_bytes;
- }
-
- rescan_sp_banks();
+ read_obp_memory("available", &pavail_rescan[0], &pavail_rescan_ents);
- /* Find changes discovered in the sp_bank rescan and
+ /* Find changes discovered in the physmem available rescan and
* reserve the lost portions in the bootmem maps.
*/
- for (i = 0; saved_sp_banks[i].num_bytes; i++) {
+ for (i = 0; i < pavail_ents; i++) {
unsigned long old_start, old_end;
- old_start = saved_sp_banks[i].base_addr;
+ old_start = pavail[i].phys_addr;
old_end = old_start +
- saved_sp_banks[i].num_bytes;
+ pavail[i].reg_size;
while (old_start < old_end) {
int n;
- for (n = 0; sp_banks[n].num_bytes; n++) {
+ for (n = 0; pavail_rescan_ents; n++) {
unsigned long new_start, new_end;
- new_start = sp_banks[n].base_addr;
- new_end = new_start + sp_banks[n].num_bytes;
+ new_start = pavail_rescan[n].phys_addr;
+ new_end = new_start +
+ pavail_rescan[n].reg_size;
if (new_start <= old_start &&
new_end >= (old_start + PAGE_SIZE)) {
- set_bit (old_start >> 22,
- sparc64_valid_addr_bitmap);
+ set_bit(old_start >> 22,
+ sparc64_valid_addr_bitmap);
goto do_next_page;
}
}
@@ -1695,8 +1580,7 @@ void __init mem_init(void)
i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
i += 1;
- sparc64_valid_addr_bitmap = (unsigned long *)
- __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base);
+ sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3);
if (sparc64_valid_addr_bitmap == NULL) {
prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
prom_halt();
@@ -1749,7 +1633,7 @@ void __init mem_init(void)
cheetah_ecache_flush_init();
}
-void free_initmem (void)
+void free_initmem(void)
{
unsigned long addr, initend;
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index b2ee9b53227f..e4c9151fa116 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -144,42 +144,29 @@ __flush_icache_page: /* %o0 = phys_page */
#define DTAG_MASK 0x3
+ /* This routine is Spitfire specific so the hardcoded
+ * D-cache size and line-size are OK.
+ */
.align 64
.globl __flush_dcache_page
__flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
sethi %uhi(PAGE_OFFSET), %g1
sllx %g1, 32, %g1
- sub %o0, %g1, %o0
- clr %o4
- srlx %o0, 11, %o0
- sethi %hi(1 << 14), %o2
-1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group
- add %o4, (1 << 5), %o4 ! IEU0
- ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group
- add %o4, (1 << 5), %o4 ! IEU0
- ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available
- add %o4, (1 << 5), %o4 ! IEU0
- andn %o3, DTAG_MASK, %o3 ! IEU1
- ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group
- add %o4, (1 << 5), %o4 ! IEU0
- andn %g1, DTAG_MASK, %g1 ! IEU1
- cmp %o0, %o3 ! IEU1 Group
- be,a,pn %xcc, dflush1 ! CTI
- sub %o4, (4 << 5), %o4 ! IEU0 (Group)
- cmp %o0, %g1 ! IEU1 Group
- andn %g2, DTAG_MASK, %g2 ! IEU0
- be,a,pn %xcc, dflush2 ! CTI
- sub %o4, (3 << 5), %o4 ! IEU0 (Group)
- cmp %o0, %g2 ! IEU1 Group
- andn %g3, DTAG_MASK, %g3 ! IEU0
- be,a,pn %xcc, dflush3 ! CTI
- sub %o4, (2 << 5), %o4 ! IEU0 (Group)
- cmp %o0, %g3 ! IEU1 Group
- be,a,pn %xcc, dflush4 ! CTI
- sub %o4, (1 << 5), %o4 ! IEU0
-2: cmp %o4, %o2 ! IEU1 Group
- bne,pt %xcc, 1b ! CTI
- nop ! IEU0
+ sub %o0, %g1, %o0 ! physical address
+ srlx %o0, 11, %o0 ! make D-cache TAG
+ sethi %hi(1 << 14), %o2 ! D-cache size
+ sub %o2, (1 << 5), %o2 ! D-cache line size
+1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG
+ andcc %o3, DTAG_MASK, %g0 ! Valid?
+ be,pn %xcc, 2f ! Nope, branch
+ andn %o3, DTAG_MASK, %o3 ! Clear valid bits
+ cmp %o3, %o0 ! TAG match?
+ bne,pt %xcc, 2f ! Nope, branch
+ nop
+ stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG
+ membar #Sync
+2: brnz,pt %o2, 1b
+ sub %o2, (1 << 5), %o2 ! D-cache line size
/* The I-cache does not snoop local stores so we
* better flush that too when necessary.
@@ -189,48 +176,9 @@ __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
retl
nop
-dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
-dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
-dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
-dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
- membar #Sync
- ba,pt %xcc, 2b
- nop
#endif /* DCACHE_ALIASING_POSSIBLE */
- .previous .text
- .align 32
-__prefill_dtlb:
- rdpr %pstate, %g7
- wrpr %g7, PSTATE_IE, %pstate
- mov TLB_TAG_ACCESS, %g1
- stxa %o5, [%g1] ASI_DMMU
- stxa %o2, [%g0] ASI_DTLB_DATA_IN
- flush %g6
- retl
- wrpr %g7, %pstate
-__prefill_itlb:
- rdpr %pstate, %g7
- wrpr %g7, PSTATE_IE, %pstate
- mov TLB_TAG_ACCESS, %g1
- stxa %o5, [%g1] ASI_IMMU
- stxa %o2, [%g0] ASI_ITLB_DATA_IN
- flush %g6
- retl
- wrpr %g7, %pstate
-
- .globl __update_mmu_cache
-__update_mmu_cache: /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */
- srlx %o1, PAGE_SHIFT, %o1
- andcc %o3, FAULT_CODE_DTLB, %g0
- sllx %o1, PAGE_SHIFT, %o5
- bne,pt %xcc, __prefill_dtlb
- or %o5, %o0, %o5
- ba,a,pt %xcc, __prefill_itlb
+ .previous
/* Cheetah specific versions, patched at boot time. */
__cheetah_flush_tlb_mm: /* 18 insns */
@@ -283,7 +231,7 @@ __cheetah_flush_tlb_pending: /* 26 insns */
wrpr %g7, 0x0, %pstate
#ifdef DCACHE_ALIASING_POSSIBLE
-flush_dcpage_cheetah: /* 11 insns */
+__cheetah_flush_dcache_page: /* 11 insns */
sethi %uhi(PAGE_OFFSET), %g1
sllx %g1, 32, %g1
sub %o0, %g1, %o0
@@ -329,8 +277,8 @@ cheetah_patch_cachetlbops:
#ifdef DCACHE_ALIASING_POSSIBLE
sethi %hi(__flush_dcache_page), %o0
or %o0, %lo(__flush_dcache_page), %o0
- sethi %hi(flush_dcpage_cheetah), %o1
- or %o1, %lo(flush_dcpage_cheetah), %o1
+ sethi %hi(__cheetah_flush_dcache_page), %o1
+ or %o1, %lo(__cheetah_flush_dcache_page), %o1
call cheetah_patch_one
mov 11, %o2
#endif /* DCACHE_ALIASING_POSSIBLE */
@@ -505,22 +453,6 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
nop
nop
- .globl xcall_promstop
-xcall_promstop:
- rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- rdpr %pil, %g2
- wrpr %g0, 15, %pil
- sethi %hi(109f), %g7
- b,pt %xcc, etrap_irq
-109: or %g7, %lo(109b), %g7
- flushw
- call prom_stopself
- nop
- /* We should not return, just spin if we do... */
-1: b,a,pt %xcc, 1b
- nop
-
.data
errata32_hwbug:
diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile
index 8f2420d9e9e6..3d33ed27bc27 100644
--- a/arch/sparc64/prom/Makefile
+++ b/arch/sparc64/prom/Makefile
@@ -6,5 +6,5 @@
EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS := -Werror
-lib-y := bootstr.o devops.o init.o memory.o misc.o \
- tree.o console.o printf.o p1275.o map.o cif.o
+lib-y := bootstr.o devops.o init.o misc.o \
+ tree.o console.o printf.o p1275.o cif.o
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
index 028a53fcb1ec..eae5db8dda56 100644
--- a/arch/sparc64/prom/console.c
+++ b/arch/sparc64/prom/console.c
@@ -67,7 +67,7 @@ prom_putchar(char c)
}
void
-prom_puts(char *s, int len)
+prom_puts(const char *s, int len)
{
p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
P1275_INOUT(3,1),
diff --git a/arch/sparc64/prom/devops.c b/arch/sparc64/prom/devops.c
index 2c99b21b6981..4641839eb39a 100644
--- a/arch/sparc64/prom/devops.c
+++ b/arch/sparc64/prom/devops.c
@@ -16,7 +16,7 @@
* Returns 0 on failure.
*/
int
-prom_devopen(char *dstr)
+prom_devopen(const char *dstr)
{
return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
P1275_INOUT(1,1),
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c
index 817faae058cd..f3cc2d8578b2 100644
--- a/arch/sparc64/prom/init.c
+++ b/arch/sparc64/prom/init.c
@@ -27,7 +27,6 @@ int prom_chosen_node;
* failure. It gets passed the pointer to the PROM vector.
*/
-extern void prom_meminit(void);
extern void prom_cif_init(void *, void *);
void __init prom_init(void *cif_handler, void *cif_stack)
@@ -46,7 +45,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
if((prom_root_node == 0) || (prom_root_node == -1))
prom_halt();
- prom_chosen_node = prom_finddevice("/chosen");
+ prom_chosen_node = prom_finddevice(prom_chosen_path);
if (!prom_chosen_node || prom_chosen_node == -1)
prom_halt();
@@ -90,8 +89,6 @@ void __init prom_init(void *cif_handler, void *cif_stack)
printk ("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust);
- prom_meminit();
-
/* Initialization successful. */
return;
diff --git a/arch/sparc64/prom/map.S b/arch/sparc64/prom/map.S
deleted file mode 100644
index 21b3f9c99ea7..000000000000
--- a/arch/sparc64/prom/map.S
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $Id: map.S,v 1.2 1999/11/19 05:53:02 davem Exp $
- * map.S: Tricky coding required to fixup the kernel OBP maps
- * properly.
- *
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
- */
-
- .text
- .align 8192
- .globl prom_boot_page
-prom_boot_page:
-call_method:
- .asciz "call-method"
- .align 8
-map:
- .asciz "map"
- .align 8
-
- /* When we are invoked, our caller has remapped us to
- * page zero, therefore we must use PC relative addressing
- * for everything after we begin performing the unmap/map
- * calls.
- */
- .globl prom_remap
-prom_remap: /* %o0 = physpage, %o1 = virtpage, %o2 = mmu_ihandle */
- rd %pc, %g1
- srl %o2, 0, %o2 ! kill sign extension
- sethi %hi(p1275buf), %g2
- or %g2, %lo(p1275buf), %g2
- ldx [%g2 + 0x10], %g3 ! prom_cif_stack
- save %g3, -(192 + 128), %sp
- ldx [%g2 + 0x08], %l0 ! prom_cif_handler
- mov %g6, %i3
- mov %g4, %i4
- mov %g5, %i5
- flushw
-
- sethi %hi(prom_remap - call_method), %g7
- or %g7, %lo(prom_remap - call_method), %g7
- sub %g1, %g7, %l2 ! call-method string
- sethi %hi(prom_remap - map), %g7
- or %g7, %lo(prom_remap - map), %g7
- sub %g1, %g7, %l4 ! map string
-
- /* OK, map the 4MB region we really live at. */
- stx %l2, [%sp + 2047 + 128 + 0x00] ! call-method
- mov 7, %l5
- stx %l5, [%sp + 2047 + 128 + 0x08] ! num_args
- mov 1, %l5
- stx %l5, [%sp + 2047 + 128 + 0x10] ! num_rets
- stx %l4, [%sp + 2047 + 128 + 0x18] ! map
- stx %i2, [%sp + 2047 + 128 + 0x20] ! mmu_ihandle
- mov -1, %l5
- stx %l5, [%sp + 2047 + 128 + 0x28] ! mode == default
- sethi %hi(4 * 1024 * 1024), %l5
- stx %l5, [%sp + 2047 + 128 + 0x30] ! size
- stx %i1, [%sp + 2047 + 128 + 0x38] ! vaddr
- stx %g0, [%sp + 2047 + 128 + 0x40] ! filler
- stx %i0, [%sp + 2047 + 128 + 0x48] ! paddr
- call %l0
- add %sp, (2047 + 128), %o0 ! argument array
-
- /* Restore hard-coded globals. */
- mov %i3, %g6
- mov %i4, %g4
- mov %i5, %g5
-
- /* Wheee.... we are done. */
- ret
- restore
-
- .align 8192
diff --git a/arch/sparc64/prom/memory.c b/arch/sparc64/prom/memory.c
deleted file mode 100644
index f4a8143e052c..000000000000
--- a/arch/sparc64/prom/memory.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* $Id: memory.c,v 1.5 1999/08/31 06:55:04 davem Exp $
- * memory.c: Prom routine for acquiring various bits of information
- * about RAM on the machine, both virtual and physical.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* This routine, for consistency, returns the ram parameters in the
- * V0 prom memory descriptor format. I choose this format because I
- * think it was the easiest to work with. I feel the religious
- * arguments now... ;) Also, I return the linked lists sorted to
- * prevent paging_init() upset stomach as I have not yet written
- * the pepto-bismol kernel module yet.
- */
-
-struct linux_prom64_registers prom_reg_memlist[64];
-struct linux_prom64_registers prom_reg_tmp[64];
-
-struct linux_mlist_p1275 prom_phys_total[64];
-struct linux_mlist_p1275 prom_prom_taken[64];
-struct linux_mlist_p1275 prom_phys_avail[64];
-
-struct linux_mlist_p1275 *prom_ptot_ptr = prom_phys_total;
-struct linux_mlist_p1275 *prom_ptak_ptr = prom_prom_taken;
-struct linux_mlist_p1275 *prom_pavl_ptr = prom_phys_avail;
-
-struct linux_mem_p1275 prom_memlist;
-
-
-/* Internal Prom library routine to sort a linux_mlist_p1275 memory
- * list. Used below in initialization.
- */
-static void __init
-prom_sortmemlist(struct linux_mlist_p1275 *thislist)
-{
- int swapi = 0;
- int i, mitr;
- unsigned long tmpaddr, tmpsize;
- unsigned long lowest;
-
- for(i=0; thislist[i].theres_more; i++) {
- lowest = thislist[i].start_adr;
- for(mitr = i+1; thislist[mitr-1].theres_more; mitr++)
- if(thislist[mitr].start_adr < lowest) {
- lowest = thislist[mitr].start_adr;
- swapi = mitr;
- }
- if(lowest == thislist[i].start_adr) continue;
- tmpaddr = thislist[swapi].start_adr;
- tmpsize = thislist[swapi].num_bytes;
- for(mitr = swapi; mitr > i; mitr--) {
- thislist[mitr].start_adr = thislist[mitr-1].start_adr;
- thislist[mitr].num_bytes = thislist[mitr-1].num_bytes;
- }
- thislist[i].start_adr = tmpaddr;
- thislist[i].num_bytes = tmpsize;
- }
-}
-
-/* Initialize the memory lists based upon the prom version. */
-void __init prom_meminit(void)
-{
- int node = 0;
- unsigned int iter, num_regs;
-
- node = prom_finddevice("/memory");
- num_regs = prom_getproperty(node, "available",
- (char *) prom_reg_memlist,
- sizeof(prom_reg_memlist));
- num_regs = (num_regs/sizeof(struct linux_prom64_registers));
- for(iter=0; iter<num_regs; iter++) {
- prom_phys_avail[iter].start_adr =
- prom_reg_memlist[iter].phys_addr;
- prom_phys_avail[iter].num_bytes =
- prom_reg_memlist[iter].reg_size;
- prom_phys_avail[iter].theres_more =
- &prom_phys_avail[iter+1];
- }
- prom_phys_avail[iter-1].theres_more = NULL;
-
- num_regs = prom_getproperty(node, "reg",
- (char *) prom_reg_memlist,
- sizeof(prom_reg_memlist));
- num_regs = (num_regs/sizeof(struct linux_prom64_registers));
- for(iter=0; iter<num_regs; iter++) {
- prom_phys_total[iter].start_adr =
- prom_reg_memlist[iter].phys_addr;
- prom_phys_total[iter].num_bytes =
- prom_reg_memlist[iter].reg_size;
- prom_phys_total[iter].theres_more =
- &prom_phys_total[iter+1];
- }
- prom_phys_total[iter-1].theres_more = NULL;
-
- node = prom_finddevice("/virtual-memory");
- num_regs = prom_getproperty(node, "available",
- (char *) prom_reg_memlist,
- sizeof(prom_reg_memlist));
- num_regs = (num_regs/sizeof(struct linux_prom64_registers));
-
- /* Convert available virtual areas to taken virtual
- * areas. First sort, then convert.
- */
- for(iter=0; iter<num_regs; iter++) {
- prom_prom_taken[iter].start_adr =
- prom_reg_memlist[iter].phys_addr;
- prom_prom_taken[iter].num_bytes =
- prom_reg_memlist[iter].reg_size;
- prom_prom_taken[iter].theres_more =
- &prom_prom_taken[iter+1];
- }
- prom_prom_taken[iter-1].theres_more = NULL;
-
- prom_sortmemlist(prom_prom_taken);
-
- /* Finally, convert. */
- for(iter=0; iter<num_regs; iter++) {
- prom_prom_taken[iter].start_adr =
- prom_prom_taken[iter].start_adr +
- prom_prom_taken[iter].num_bytes;
- prom_prom_taken[iter].num_bytes =
- prom_prom_taken[iter+1].start_adr -
- prom_prom_taken[iter].start_adr;
- }
- prom_prom_taken[iter-1].num_bytes =
- -1UL - prom_prom_taken[iter-1].start_adr;
-
- /* Sort the other two lists. */
- prom_sortmemlist(prom_phys_total);
- prom_sortmemlist(prom_phys_avail);
-
- /* Link all the lists into the top-level descriptor. */
- prom_memlist.p1275_totphys=&prom_ptot_ptr;
- prom_memlist.p1275_prommap=&prom_ptak_ptr;
- prom_memlist.p1275_available=&prom_pavl_ptr;
-}
-
-/* This returns a pointer to our libraries internal p1275 format
- * memory descriptor.
- */
-struct linux_mem_p1275 *
-prom_meminfo(void)
-{
- return &prom_memlist;
-}
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index 19c44e97e9ee..87f5cfce23bb 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -17,14 +17,14 @@
#include <asm/system.h>
/* Reset and reboot the machine with the command 'bcommand'. */
-void prom_reboot(char *bcommand)
+void prom_reboot(const char *bcommand)
{
p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_INOUT(1, 0), bcommand);
}
/* Forth evaluate the expression contained in 'fstring'. */
-void prom_feval(char *fstring)
+void prom_feval(const char *fstring)
{
if (!fstring || fstring[0] == 0)
return;
@@ -68,19 +68,11 @@ void prom_cmdline(void)
local_irq_restore(flags);
}
-#ifdef CONFIG_SMP
-extern void smp_promstop_others(void);
-#endif
-
/* Drop into the prom, but completely terminate the program.
* No chance of continuing.
*/
void prom_halt(void)
{
-#ifdef CONFIG_SMP
- smp_promstop_others();
- udelay(8000);
-#endif
again:
p1275_cmd("exit", P1275_INOUT(0, 0));
goto again; /* PROM is out to get me -DaveM */
@@ -88,10 +80,6 @@ again:
void prom_halt_power_off(void)
{
-#ifdef CONFIG_SMP
- smp_promstop_others();
- udelay(8000);
-#endif
p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
/* if nothing else helps, we just halt */
@@ -148,21 +136,19 @@ void prom_set_trap_table(unsigned long tba)
p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba);
}
-int mmu_ihandle_cache = 0;
-
int prom_get_mmu_ihandle(void)
{
int node, ret;
- if (mmu_ihandle_cache != 0)
- return mmu_ihandle_cache;
+ if (prom_mmu_ihandle_cache != 0)
+ return prom_mmu_ihandle_cache;
- node = prom_finddevice("/chosen");
- ret = prom_getint(node, "mmu");
+ node = prom_finddevice(prom_chosen_path);
+ ret = prom_getint(node, prom_mmu_name);
if (ret == -1 || ret == 0)
- mmu_ihandle_cache = -1;
+ prom_mmu_ihandle_cache = -1;
else
- mmu_ihandle_cache = ret;
+ prom_mmu_ihandle_cache = ret;
return ret;
}
@@ -190,7 +176,7 @@ long prom_itlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
- return p1275_cmd("call-method",
+ return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
@@ -207,7 +193,7 @@ long prom_dtlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
- return p1275_cmd("call-method",
+ return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
@@ -223,13 +209,13 @@ long prom_dtlb_load(unsigned long index,
int prom_map(int mode, unsigned long size,
unsigned long vaddr, unsigned long paddr)
{
- int ret = p1275_cmd("call-method",
+ int ret = p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_ARG(4, P1275_ARG_IN_64B) |
P1275_ARG(6, P1275_ARG_IN_64B) |
P1275_INOUT(7, 1)),
- "map",
+ prom_map_name,
prom_get_mmu_ihandle(),
mode,
size,
@@ -244,12 +230,12 @@ int prom_map(int mode, unsigned long size,
void prom_unmap(unsigned long size, unsigned long vaddr)
{
- p1275_cmd("call-method",
+ p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_INOUT(4, 0)),
- "unmap",
+ prom_unmap_name,
prom_get_mmu_ihandle(),
size,
vaddr);
@@ -258,7 +244,7 @@ void prom_unmap(unsigned long size, unsigned long vaddr)
/* Set aside physical memory which is not touched or modified
* across soft resets.
*/
-unsigned long prom_retain(char *name,
+unsigned long prom_retain(const char *name,
unsigned long pa_low, unsigned long pa_high,
long size, long align)
{
@@ -290,7 +276,7 @@ int prom_getunumber(int syndrome_code,
unsigned long phys_addr,
char *buf, int buflen)
{
- return p1275_cmd("call-method",
+ return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(3, P1275_ARG_OUT_BUF) |
P1275_ARG(6, P1275_ARG_IN_64B) |
diff --git a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c
index 59fe38bba39e..a5a7c5712028 100644
--- a/arch/sparc64/prom/p1275.c
+++ b/arch/sparc64/prom/p1275.c
@@ -46,7 +46,7 @@ static inline unsigned long spitfire_get_primary_context(void)
*/
DEFINE_SPINLOCK(prom_entry_lock);
-long p1275_cmd (char *service, long fmt, ...)
+long p1275_cmd(const char *service, long fmt, ...)
{
char *p, *q;
unsigned long flags;
diff --git a/arch/sparc64/prom/printf.c b/arch/sparc64/prom/printf.c
index a6df82cafa0d..660943ee4c2a 100644
--- a/arch/sparc64/prom/printf.c
+++ b/arch/sparc64/prom/printf.c
@@ -34,7 +34,7 @@ prom_write(const char *buf, unsigned int n)
}
void
-prom_printf(char *fmt, ...)
+prom_printf(const char *fmt, ...)
{
va_list args;
int i;
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c
index ccf73258ebf7..b1ff9e87dcc6 100644
--- a/arch/sparc64/prom/tree.c
+++ b/arch/sparc64/prom/tree.c
@@ -69,7 +69,7 @@ prom_getsibling(int node)
* Return -1 on error.
*/
__inline__ int
-prom_getproplen(int node, char *prop)
+prom_getproplen(int node, const char *prop)
{
if((!node) || (!prop)) return -1;
return p1275_cmd ("getproplen",
@@ -83,20 +83,20 @@ prom_getproplen(int node, char *prop)
* was successful the length will be returned, else -1 is returned.
*/
__inline__ int
-prom_getproperty(int node, char *prop, char *buffer, int bufsize)
+prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
{
int plen;
plen = prom_getproplen(node, prop);
- if((plen > bufsize) || (plen == 0) || (plen == -1))
+ if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
return -1;
- else {
+ } else {
/* Ok, things seem all right. */
- return p1275_cmd ("getprop",
- P1275_ARG(1,P1275_ARG_IN_STRING)|
- P1275_ARG(2,P1275_ARG_OUT_BUF)|
- P1275_INOUT(4, 1),
- node, prop, buffer, P1275_SIZE(plen));
+ return p1275_cmd(prom_getprop_name,
+ P1275_ARG(1,P1275_ARG_IN_STRING)|
+ P1275_ARG(2,P1275_ARG_OUT_BUF)|
+ P1275_INOUT(4, 1),
+ node, prop, buffer, P1275_SIZE(plen));
}
}
@@ -104,7 +104,7 @@ prom_getproperty(int node, char *prop, char *buffer, int bufsize)
* on failure.
*/
__inline__ int
-prom_getint(int node, char *prop)
+prom_getint(int node, const char *prop)
{
int intprop;
@@ -119,7 +119,7 @@ prom_getint(int node, char *prop)
*/
int
-prom_getintdefault(int node, char *property, int deflt)
+prom_getintdefault(int node, const char *property, int deflt)
{
int retval;
@@ -131,7 +131,7 @@ prom_getintdefault(int node, char *property, int deflt)
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
int
-prom_getbool(int node, char *prop)
+prom_getbool(int node, const char *prop)
{
int retval;
@@ -145,7 +145,7 @@ prom_getbool(int node, char *prop)
* buffer.
*/
void
-prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
+prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
{
int len;
@@ -160,7 +160,7 @@ prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
* YES = 1 NO = 0
*/
int
-prom_nodematch(int node, char *name)
+prom_nodematch(int node, const char *name)
{
char namebuf[128];
prom_getproperty(node, "name", namebuf, sizeof(namebuf));
@@ -172,7 +172,7 @@ prom_nodematch(int node, char *name)
* 'nodename'. Return node if successful, zero if not.
*/
int
-prom_searchsiblings(int node_start, char *nodename)
+prom_searchsiblings(int node_start, const char *nodename)
{
int thisnode, error;
@@ -294,7 +294,7 @@ prom_firstprop(int node, char *buffer)
* property types for this node.
*/
__inline__ char *
-prom_nextprop(int node, char *oprop, char *buffer)
+prom_nextprop(int node, const char *oprop, char *buffer)
{
char buf[32];
@@ -314,15 +314,17 @@ prom_nextprop(int node, char *oprop, char *buffer)
}
int
-prom_finddevice(char *name)
+prom_finddevice(const char *name)
{
- if(!name) return 0;
- return p1275_cmd ("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)|
- P1275_INOUT(1, 1),
- name);
+ if (!name)
+ return 0;
+ return p1275_cmd(prom_finddev_name,
+ P1275_ARG(0,P1275_ARG_IN_STRING)|
+ P1275_INOUT(1, 1),
+ name);
}
-int prom_node_has_property(int node, char *prop)
+int prom_node_has_property(int node, const char *prop)
{
char buf [32];
@@ -339,7 +341,7 @@ int prom_node_has_property(int node, char *prop)
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
int
-prom_setprop(int node, char *pname, char *value, int size)
+prom_setprop(int node, const char *pname, char *value, int size)
{
if(size == 0) return 0;
if((pname == 0) || (value == 0)) return 0;
@@ -364,7 +366,7 @@ prom_inst2pkg(int inst)
* FIXME: Should work for v0 as well
*/
int
-prom_pathtoinode(char *path)
+prom_pathtoinode(const char *path)
{
int node, inst;
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
index cac0a1cf0050..be0a054e3ed6 100644
--- a/arch/sparc64/solaris/ioctl.c
+++ b/arch/sparc64/solaris/ioctl.c
@@ -24,6 +24,7 @@
#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/socksys.c b/arch/sparc64/solaris/socksys.c
index d7c1c76582cc..fc6669e8dde1 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -49,7 +49,7 @@ IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
#else
-extern void * mykmalloc(size_t s, int gfp);
+extern void * mykmalloc(size_t s, gfp_t gfp);
extern void mykfree(void *);
#endif
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index 022c80f43392..b84e5456b025 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -39,7 +39,7 @@ static char * page = NULL ;
#else
-void * mykmalloc(size_t s, int gfp)
+void * mykmalloc(size_t s, gfp_t gfp)
{
static char * page;
static size_t free;
@@ -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/Kconfig.i386 b/arch/um/Kconfig.i386
index 8ad156a00499..5d92cacd56c6 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -42,3 +42,7 @@ config ARCH_HAS_SC_SIGNALS
config ARCH_REUSE_HOST_VSYSCALL_AREA
bool
default y
+
+config X86_CMPXCHG
+ bool
+ default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index b15f6048caae..e1ffad224605 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -28,8 +28,6 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
-GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
-
um-modes-$(CONFIG_MODE_TT) += tt
um-modes-$(CONFIG_MODE_SKAS) += skas
@@ -45,17 +43,19 @@ endif
ARCH_INCLUDE := -I$(ARCH_DIR)/include
ifneq ($(KBUILD_SRC),)
-ARCH_INCLUDE += -I$(ARCH_DIR)/include2
ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include
-MRPROPER_DIRS += $(ARCH_DIR)/include2
endif
SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
# -Dvmap=kernel_vmap affects everything, and prevents anything from
# referencing the libpcap.o symbol so named.
+#
+# Same things for in6addr_loopback - found in libc.
CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
- $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
+ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
+ -Din6addr_loopback=kernel_in6addr_loopback
+
AFLAGS += $(ARCH_INCLUDE)
USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
@@ -83,10 +83,6 @@ CONFIG_KERNEL_HALF_GIGS ?= 0
SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
-ifeq ($(CONFIG_MODE_SKAS), y)
-$(SYS_HEADERS) : $(ARCH_DIR)/include/skas_ptregs.h
-endif
-
.PHONY: linux
all: linux
@@ -103,12 +99,12 @@ endef
ifneq ($(KBUILD_SRC),)
$(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig.$(SUBARCH) $(ARCH_DIR)/Kconfig.arch)
-CLEAN_FILES += $(ARCH_DIR)/Kconfig.arch
else
$(shell cd $(ARCH_DIR) && ln -sf Kconfig.$(SUBARCH) Kconfig.arch)
endif
-prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
+archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h
+prepare: $(ARCH_DIR)/include/kern_constants.h
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
@@ -143,22 +139,20 @@ endef
#When cleaning we don't include .config, so we don't include
#TT or skas makefiles and don't clean skas_ptregs.h.
CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
- $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \
- $(ARCH_DIR)/include/user_constants.h
+ $(ARCH_DIR)/include/user_constants.h \
+ $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
- $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os \
- $(ARCH_DIR)/Kconfig.arch
+ $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
archclean:
- $(Q)$(MAKE) $(clean)=$(ARCH_DIR)/util
@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
-o -name '*.gcov' \) -type f -print | xargs rm -f
$(SYMLINK_HEADERS):
@echo ' SYMLINK $@'
ifneq ($(KBUILD_SRC),)
- ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
+ $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
else
$(Q)cd $(TOPDIR)/$(dir $@) ; \
ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
@@ -177,9 +171,7 @@ $(ARCH_DIR)/include/sysdep:
@echo ' SYMLINK $@'
ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p $(ARCH_DIR)/include
- $(Q)mkdir -p $(ARCH_DIR)/include2
- $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
- $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
+ $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
else
$(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
endif
@@ -197,56 +189,37 @@ define filechk_umlconfig
sed 's/ CONFIG/ UML_CONFIG/'
endef
+define filechk_gen-asm-offsets
+ (set -e; \
+ echo "/*"; \
+ echo " * DO NOT MODIFY."; \
+ echo " *"; \
+ echo " * This file was generated by arch/$(ARCH)/Makefile"; \
+ echo " *"; \
+ echo " */"; \
+ echo ""; \
+ sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \
+ echo ""; )
+endef
+
$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
$(call filechk,umlconfig)
$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
$(CC) $(USER_CFLAGS) -S -o $@ $<
-$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
+$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/user-offsets.s
$(call filechk,gen-asm-offsets)
-CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h
+CLEAN_FILES += $(ARCH_DIR)/user-offsets.s
$(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
- $(ARCH_SYMLINKS) \
- $(SYS_DIR)/sc.h \
- include/asm include/linux/version.h \
- include/config/MARKER \
- $(ARCH_DIR)/include/user_constants.h
+ archprepare
$(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
-$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
+$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/kernel-offsets.s
$(call filechk,gen-asm-offsets)
-CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h
-
-$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
-
-$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
- FORCE ;
-
-$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
-
-$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$@
-
-$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$@
-
-$(ARCH_DIR)/os-$(OS)/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$@
+CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s
export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 1ab431a53ac3..2ee8a2858117 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -32,25 +32,3 @@ CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
ifneq ($(CONFIG_GPROF),y)
ARCH_CFLAGS += -DUM_FASTCALL
endif
-
-SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util
-SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-
-prepare: $(SYS_HEADERS)
-
-$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
- $(call filechk,gen_header)
-
-$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
- $(call filechk,gen_header)
-
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR): scripts_basic include/asm FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
-
-CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/Makefile-skas b/arch/um/Makefile-skas
index fd18ec572271..ac35de5316a6 100644
--- a/arch/um/Makefile-skas
+++ b/arch/um/Makefile-skas
@@ -10,5 +10,3 @@ CFLAGS-$(CONFIG_GCOV) += $(GCOV_OPT)
CFLAGS-$(CONFIG_GPROF) += $(GPROF_OPT)
LINK-$(CONFIG_GCOV) += $(GCOV_OPT)
LINK-$(CONFIG_GPROF) += $(GPROF_OPT)
-
-GEN_HEADERS += $(ARCH_DIR)/include/skas_ptregs.h
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index baddb5d64ca5..4f118d5cc2ee 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -8,27 +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
-
-SYS_UTIL_DIR := $(ARCH_DIR)/sys-x86_64/util
-SYS_DIR := $(ARCH_DIR)/include/sysdep-x86_64
-
-SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-
-prepare: $(SYS_HEADERS)
-
-$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
- $(call filechk,gen_header)
-
-$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
- $(call filechk,gen_header)
-
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 783e18cae090..de17d4c6e02d 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -13,7 +13,7 @@ mcast-objs := mcast_kern.o mcast_user.o
net-objs := net_kern.o net_user.o
mconsole-objs := mconsole_kern.o mconsole_user.o
hostaudio-objs := hostaudio_kern.o
-ubd-objs := ubd_kern.o
+ubd-objs := ubd_kern.o ubd_user.o
port-objs := port_kern.o port_user.o
harddog-objs := harddog_kern.o harddog_user.o
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 14a12d6b3df6..16e7dc89f61d 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -19,18 +19,44 @@
#include "line.h"
#include "os.h"
-#ifdef CONFIG_NOCONFIG_CHAN
+/* XXX: could well be moved to somewhere else, if needed. */
+static int my_printf(const char * fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+static int my_printf(const char * fmt, ...)
+{
+ /* Yes, can be called on atomic context.*/
+ char *buf = kmalloc(4096, GFP_ATOMIC);
+ va_list args;
+ int r;
+
+ if (!buf) {
+ /* We print directly fmt.
+ * Yes, yes, yes, feel free to complain. */
+ r = strlen(fmt);
+ } else {
+ va_start(args, fmt);
+ r = vsprintf(buf, fmt, args);
+ va_end(args);
+ fmt = buf;
+ }
-/* The printk's here are wrong because we are complaining that there is no
- * output device, but printk is printing to that output device. The user will
- * never see the error. printf would be better, except it can't run on a
- * kernel stack because it will overflow it.
- * Use printk for now since that will avoid crashing.
- */
+ if (r)
+ r = os_write_file(1, fmt, r);
+ return r;
+
+}
+
+#ifdef CONFIG_NOCONFIG_CHAN
+/* Despite its name, there's no added trailing newline. */
+static int my_puts(const char * buf)
+{
+ return os_write_file(1, buf, strlen(buf));
+}
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(NULL);
}
@@ -38,27 +64,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_close(int fd, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -66,7 +92,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
static int not_configged_console_write(int fd, const char *buf, int len,
void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -74,14 +100,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_free(void *data)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
}
@@ -457,7 +483,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
}
}
if(ops == NULL){
- printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
+ my_printf("parse_chan couldn't parse \"%s\"\n",
str);
return(NULL);
}
@@ -465,7 +491,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
data = (*ops->init)(str, device, opts);
if(data == NULL) return(NULL);
- chan = kmalloc(sizeof(*chan), GFP_KERNEL);
+ chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
if(chan == NULL) return(NULL);
*chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
.primary = 1,
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index 4fcf3a8d13f4..dc36b222100b 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -3,15 +3,40 @@
#include <asm/types.h>
-#if defined(__BIG_ENDIAN)
-# define ntohll(x) (x)
-# define htonll(x) (x)
-#elif defined(__LITTLE_ENDIAN)
-# define ntohll(x) bswap_64(x)
-# define htonll(x) bswap_64(x)
+#if defined(__KERNEL__)
+
+# include <asm/byteorder.h>
+
+# if defined(__BIG_ENDIAN)
+# define ntohll(x) (x)
+# define htonll(x) (x)
+# elif defined(__LITTLE_ENDIAN)
+# define ntohll(x) be64_to_cpu(x)
+# define htonll(x) cpu_to_be64(x)
+# else
+# error "Could not determine byte order"
+# endif
+
#else
-#error "__BYTE_ORDER not defined"
+/* For the definition of ntohl, htonl and __BYTE_ORDER */
+#include <endian.h>
+#include <netinet/in.h>
+#if defined(__BYTE_ORDER)
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define ntohll(x) (x)
+# define htonll(x) (x)
+# elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define ntohll(x) bswap_64(x)
+# define htonll(x) bswap_64(x)
+# else
+# error "Could not determine byte order: __BYTE_ORDER uncorrectly defined"
+# endif
+
+#else /* ! defined(__BYTE_ORDER) */
+# error "Could not determine byte order: __BYTE_ORDER not defined"
#endif
+#endif /* ! defined(__KERNEL__) */
extern int init_cow_file(int fd, char *cow_file, char *backing_file,
int sectorsize, int alignment, int *bitmap_offset_out,
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index a8ce6fc3ef26..fbe2217db5dd 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -9,7 +9,6 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/user.h>
-#include <netinet/in.h>
#include "os.h"
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 7a0d115b29d0..5db136e2651c 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -13,7 +13,6 @@
#include <errno.h>
#include <unistd.h>
-#include <linux/inet.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
@@ -55,7 +54,7 @@ static int mcast_open(void *data)
struct mcast_data *pri = data;
struct sockaddr_in *sin = pri->mcast_addr;
struct ip_mreq mreq;
- int fd = -EINVAL, yes = 1, err = -EINVAL;;
+ int fd, yes = 1, err = 0;
if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
@@ -66,13 +65,14 @@ static int mcast_open(void *data)
if (fd < 0){
printk("mcast_open : data socket failed, errno = %d\n",
errno);
- fd = -errno;
+ err = -errno;
goto out;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
errno);
+ err = -errno;
goto out_close;
}
@@ -81,6 +81,7 @@ static int mcast_open(void *data)
sizeof(pri->ttl)) < 0) {
printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
errno);
+ err = -errno;
goto out_close;
}
@@ -88,12 +89,14 @@ static int mcast_open(void *data)
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
errno);
+ err = -errno;
goto out_close;
}
/* bind socket to mcast address */
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
printk("mcast_open : data bind failed, errno = %d\n", errno);
+ err = -errno;
goto out_close;
}
@@ -108,14 +111,15 @@ static int mcast_open(void *data)
"interface on the host.\n");
printk("eth0 should be configured in order to use the "
"multicast transport.\n");
+ err = -errno;
goto out_close;
}
- out:
return fd;
out_close:
os_close_file(fd);
+ out:
return err;
}
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index c190c2414197..12c95368124a 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -32,6 +32,7 @@
#include "os.h"
#include "umid.h"
#include "irq_kern.h"
+#include "choose-mode.h"
static int do_unlink_socket(struct notifier_block *notifier,
unsigned long what, void *data)
@@ -276,6 +277,7 @@ void mconsole_proc(struct mc_request *req)
go - continue the UML after a 'stop' \n\
log <string> - make UML enter <string> into the kernel log\n\
proc <file> - returns the contents of the UML's /proc/<file>\n\
+ stack <pid> - returns the stack of the specified pid\n\
"
void mconsole_help(struct mc_request *req)
@@ -479,6 +481,56 @@ void mconsole_sysrq(struct mc_request *req)
}
#endif
+/* Mconsole stack trace
+ * Added by Allan Graves, Jeff Dike
+ * Dumps a stacks registers to the linux console.
+ * Usage stack <pid>.
+ */
+void do_stack(struct mc_request *req)
+{
+ char *ptr = req->request.data;
+ int pid_requested= -1;
+ struct task_struct *from = NULL;
+ struct task_struct *to = NULL;
+
+ /* Would be nice:
+ * 1) Send showregs output to mconsole.
+ * 2) Add a way to stack dump all pids.
+ */
+
+ ptr += strlen("stack");
+ while(isspace(*ptr)) ptr++;
+
+ /* Should really check for multiple pids or reject bad args here */
+ /* What do the arguments in mconsole_reply mean? */
+ if(sscanf(ptr, "%d", &pid_requested) == 0){
+ mconsole_reply(req, "Please specify a pid", 1, 0);
+ return;
+ }
+
+ from = current;
+ to = find_task_by_pid(pid_requested);
+
+ if((to == NULL) || (pid_requested == 0)) {
+ mconsole_reply(req, "Couldn't find that pid", 1, 0);
+ return;
+ }
+ to->thread.saved_task = current;
+
+ switch_to(from, to, from);
+ mconsole_reply(req, "Stack Dumped to console and message log", 0, 0);
+}
+
+void mconsole_stack(struct mc_request *req)
+{
+ /* This command doesn't work in TT mode, so let's check and then
+ * get out of here
+ */
+ CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
+ 1, 0),
+ do_stack(req));
+}
+
/* Changed by mconsole_setup, which is __setup, and called before SMP is
* active.
*/
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index fe5afb13252c..310c1f823f26 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -30,6 +30,7 @@ static struct mconsole_command commands[] = {
{ "go", mconsole_go, MCONSOLE_INTR },
{ "log", mconsole_log, MCONSOLE_INTR },
{ "proc", mconsole_proc, MCONSOLE_PROC },
+ { "stack", mconsole_stack, MCONSOLE_INTR },
};
/* Initialized in mconsole_init, which is an initcall */
@@ -172,9 +173,9 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len)
if(notify_sock < 0){
notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if(notify_sock < 0){
- printk("mconsole_notify - socket failed, errno = %d\n",
- errno);
err = -errno;
+ printk("mconsole_notify - socket failed, errno = %d\n",
+ err);
}
}
unlock_notify();
@@ -197,8 +198,8 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len)
n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
sizeof(target));
if(n < 0){
- printk("mconsole_notify - sendto failed, errno = %d\n", errno);
err = -errno;
+ printk("mconsole_notify - sendto failed, errno = %d\n", errno);
}
return(err);
}
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index c41efd207fcc..189839e4f1d4 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -7,7 +7,6 @@
#include "linux/sched.h"
#include "linux/slab.h"
#include "linux/interrupt.h"
-#include "linux/irq.h"
#include "linux/spinlock.h"
#include "linux/errno.h"
#include "asm/atomic.h"
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index ed84d01df6cc..0306a1b215b7 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -43,8 +43,9 @@ static int pts_open(int input, int output, int primary, void *d,
fd = get_pty();
if(fd < 0){
+ err = -errno;
printk("open_pts : Failed to open pts\n");
- return(-errno);
+ return err;
}
if(data->raw){
CATCH_EINTR(err = tcgetattr(fd, &data->tt));
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index e77a38da4350..f73134333f64 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,7 +35,6 @@
#include "linux/blkpg.h"
#include "linux/genhd.h"
#include "linux/spinlock.h"
-#include "asm/atomic.h"
#include "asm/segment.h"
#include "asm/uaccess.h"
#include "asm/irq.h"
@@ -54,21 +53,20 @@
#include "mem.h"
#include "mem_kern.h"
#include "cow.h"
-#include "aio.h"
enum ubd_req { UBD_READ, UBD_WRITE };
struct io_thread_req {
- enum aio_type op;
+ enum ubd_req op;
int fds[2];
unsigned long offsets[2];
unsigned long long offset;
unsigned long length;
char *buffer;
int sectorsize;
- int bitmap_offset;
- long bitmap_start;
- long bitmap_end;
+ unsigned long sector_mask;
+ unsigned long long cow_offset;
+ unsigned long bitmap_words[2];
int error;
};
@@ -82,31 +80,28 @@ extern int create_cow_file(char *cow_file, char *backing_file,
unsigned long *bitmap_len_out,
int *data_offset_out);
extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
-extern void do_io(struct io_thread_req *req, struct request *r,
- unsigned long *bitmap);
+extern void do_io(struct io_thread_req *req);
-static inline int ubd_test_bit(__u64 bit, void *data)
+static inline int ubd_test_bit(__u64 bit, unsigned char *data)
{
- unsigned char *buffer = data;
__u64 n;
int bits, off;
- bits = sizeof(buffer[0]) * 8;
+ bits = sizeof(data[0]) * 8;
n = bit / bits;
off = bit % bits;
- return((buffer[n] & (1 << off)) != 0);
+ return((data[n] & (1 << off)) != 0);
}
-static inline void ubd_set_bit(__u64 bit, void *data)
+static inline void ubd_set_bit(__u64 bit, unsigned char *data)
{
- unsigned char *buffer = data;
__u64 n;
int bits, off;
- bits = sizeof(buffer[0]) * 8;
+ bits = sizeof(data[0]) * 8;
n = bit / bits;
off = bit % bits;
- buffer[n] |= (1 << off);
+ data[n] |= (1 << off);
}
/*End stuff from ubd_user.h*/
@@ -115,6 +110,8 @@ static inline void ubd_set_bit(__u64 bit, void *data)
static DEFINE_SPINLOCK(ubd_io_lock);
static DEFINE_SPINLOCK(ubd_lock);
+static void (*do_ubd)(void);
+
static int ubd_open(struct inode * inode, struct file * filp);
static int ubd_release(struct inode * inode, struct file * file);
static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -161,8 +158,6 @@ struct cow {
int data_offset;
};
-#define MAX_SG 64
-
struct ubd {
char *file;
int count;
@@ -173,7 +168,6 @@ struct ubd {
int no_cow;
struct cow cow;
struct platform_device pdev;
- struct scatterlist sg[MAX_SG];
};
#define DEFAULT_COW { \
@@ -466,114 +460,81 @@ __uml_help(fakehd,
);
static void do_ubd_request(request_queue_t * q);
-static int in_ubd;
+
+/* Only changed by ubd_init, which is an initcall. */
+int thread_fd = -1;
/* Changed by ubd_handler, which is serialized because interrupts only
* happen on CPU 0.
*/
int intr_count = 0;
-static void ubd_end_request(struct request *req, int bytes, int uptodate)
+/* call ubd_finish if you need to serialize */
+static void __ubd_finish(struct request *req, int error)
{
- if (!end_that_request_first(req, uptodate, bytes >> 9)) {
- add_disk_randomness(req->rq_disk);
- end_that_request_last(req);
+ int nsect;
+
+ if(error){
+ end_request(req, 0);
+ return;
}
+ nsect = req->current_nr_sectors;
+ req->sector += nsect;
+ req->buffer += nsect << 9;
+ req->errors = 0;
+ req->nr_sectors -= nsect;
+ req->current_nr_sectors = 0;
+ end_request(req, 1);
}
-/* call ubd_finish if you need to serialize */
-static void __ubd_finish(struct request *req, int bytes)
+static inline void ubd_finish(struct request *req, int error)
{
- if(bytes < 0){
- ubd_end_request(req, 0, 0);
- return;
- }
-
- ubd_end_request(req, bytes, 1);
+ spin_lock(&ubd_io_lock);
+ __ubd_finish(req, error);
+ spin_unlock(&ubd_io_lock);
}
-static inline void ubd_finish(struct request *req, int bytes)
+/* Called without ubd_io_lock held */
+static void ubd_handler(void)
{
- spin_lock(&ubd_io_lock);
- __ubd_finish(req, bytes);
- spin_unlock(&ubd_io_lock);
+ struct io_thread_req req;
+ struct request *rq = elv_next_request(ubd_queue);
+ int n;
+
+ do_ubd = NULL;
+ intr_count++;
+ n = os_read_file(thread_fd, &req, sizeof(req));
+ if(n != sizeof(req)){
+ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
+ "err = %d\n", os_getpid(), -n);
+ spin_lock(&ubd_io_lock);
+ end_request(rq, 0);
+ spin_unlock(&ubd_io_lock);
+ return;
+ }
+
+ ubd_finish(rq, req.error);
+ reactivate_fd(thread_fd, UBD_IRQ);
+ do_ubd_request(ubd_queue);
}
-struct bitmap_io {
- atomic_t count;
- struct aio_context aio;
-};
-
-struct ubd_aio {
- struct aio_context aio;
- struct request *req;
- int len;
- struct bitmap_io *bitmap;
- void *bitmap_buf;
-};
-
-static int ubd_reply_fd = -1;
-
static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
{
- struct aio_thread_reply reply;
- struct ubd_aio *aio;
- struct request *req;
- int err, n, fd = (int) (long) dev;
-
- while(1){
- err = os_read_file(fd, &reply, sizeof(reply));
- if(err == -EAGAIN)
- break;
- if(err < 0){
- printk("ubd_aio_handler - read returned err %d\n",
- -err);
- break;
- }
-
- aio = container_of(reply.data, struct ubd_aio, aio);
- n = reply.err;
-
- if(n == 0){
- req = aio->req;
- req->nr_sectors -= aio->len >> 9;
-
- if((aio->bitmap != NULL) &&
- (atomic_dec_and_test(&aio->bitmap->count))){
- aio->aio = aio->bitmap->aio;
- aio->len = 0;
- kfree(aio->bitmap);
- aio->bitmap = NULL;
- submit_aio(&aio->aio);
- }
- else {
- if((req->nr_sectors == 0) &&
- (aio->bitmap == NULL)){
- int len = req->hard_nr_sectors << 9;
- ubd_finish(req, len);
- }
-
- if(aio->bitmap_buf != NULL)
- kfree(aio->bitmap_buf);
- kfree(aio);
- }
- }
- else if(n < 0){
- ubd_finish(aio->req, n);
- if(aio->bitmap != NULL)
- kfree(aio->bitmap);
- if(aio->bitmap_buf != NULL)
- kfree(aio->bitmap_buf);
- kfree(aio);
- }
- }
- reactivate_fd(fd, UBD_IRQ);
+ ubd_handler();
+ return(IRQ_HANDLED);
+}
- do_ubd_request(ubd_queue);
+/* Only changed by ubd_init, which is an initcall. */
+static int io_pid = -1;
- return(IRQ_HANDLED);
+void kill_io_thread(void)
+{
+ if(io_pid != -1)
+ os_kill_process(io_pid, 1);
}
+__uml_exitcall(kill_io_thread);
+
static int ubd_file_size(struct ubd *dev, __u64 *size_out)
{
char *file;
@@ -608,7 +569,7 @@ static int ubd_open_dev(struct ubd *dev)
&dev->cow.data_offset, create_ptr);
if((dev->fd == -ENOENT) && create_cow){
- dev->fd = create_cow_file(dev->file, dev->cow.file,
+ dev->fd = create_cow_file(dev->file, dev->cow.file,
dev->openflags, 1 << 9, PAGE_SIZE,
&dev->cow.bitmap_offset,
&dev->cow.bitmap_len,
@@ -870,10 +831,6 @@ int ubd_init(void)
{
int i;
- ubd_reply_fd = init_aio_irq(UBD_IRQ, "ubd", ubd_intr);
- if(ubd_reply_fd < 0)
- printk("Setting up ubd AIO failed, err = %d\n", ubd_reply_fd);
-
devfs_mk_dir("ubd");
if (register_blkdev(MAJOR_NR, "ubd"))
return -1;
@@ -884,7 +841,6 @@ int ubd_init(void)
return -1;
}
- blk_queue_max_hw_segments(ubd_queue, MAX_SG);
if (fake_major != MAJOR_NR) {
char name[sizeof("ubd_nnn\0")];
@@ -896,12 +852,40 @@ int ubd_init(void)
driver_register(&ubd_driver);
for (i = 0; i < MAX_DEV; i++)
ubd_add(i);
-
return 0;
}
late_initcall(ubd_init);
+int ubd_driver_init(void){
+ unsigned long stack;
+ int err;
+
+ /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
+ if(global_openflags.s){
+ printk(KERN_INFO "ubd: Synchronous mode\n");
+ /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
+ * enough. So use anyway the io thread. */
+ }
+ stack = alloc_stack(0, 0);
+ io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
+ &thread_fd);
+ if(io_pid < 0){
+ printk(KERN_ERR
+ "ubd : Failed to start I/O thread (errno = %d) - "
+ "falling back to synchronous I/O\n", -io_pid);
+ io_pid = -1;
+ return(0);
+ }
+ err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
+ SA_INTERRUPT, "ubd", ubd_dev);
+ if(err != 0)
+ printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
+ return(err);
+}
+
+device_initcall(ubd_driver_init);
+
static int ubd_open(struct inode *inode, struct file *filp)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -939,55 +923,105 @@ static int ubd_release(struct inode * inode, struct file * file)
return(0);
}
-static void cowify_bitmap(struct io_thread_req *req, unsigned long *bitmap)
+static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
+ __u64 *cow_offset, unsigned long *bitmap,
+ __u64 bitmap_offset, unsigned long *bitmap_words,
+ __u64 bitmap_len)
{
- __u64 sector = req->offset / req->sectorsize;
- int i;
+ __u64 sector = io_offset >> 9;
+ int i, update_bitmap = 0;
+
+ for(i = 0; i < length >> 9; i++){
+ if(cow_mask != NULL)
+ ubd_set_bit(i, (unsigned char *) cow_mask);
+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
+ continue;
- for(i = 0; i < req->length / req->sectorsize; i++){
- if(ubd_test_bit(sector + i, bitmap))
- continue;
+ update_bitmap = 1;
+ ubd_set_bit(sector + i, (unsigned char *) bitmap);
+ }
+
+ if(!update_bitmap)
+ return;
- if(req->bitmap_start == -1)
- req->bitmap_start = sector + i;
- req->bitmap_end = sector + i + 1;
+ *cow_offset = sector / (sizeof(unsigned long) * 8);
- ubd_set_bit(sector + i, bitmap);
- }
+ /* This takes care of the case where we're exactly at the end of the
+ * device, and *cow_offset + 1 is off the end. So, just back it up
+ * by one word. Thanks to Lynn Kerby for the fix and James McMechan
+ * for the original diagnosis.
+ */
+ if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
+ sizeof(unsigned long) - 1))
+ (*cow_offset)--;
+
+ bitmap_words[0] = bitmap[*cow_offset];
+ bitmap_words[1] = bitmap[*cow_offset + 1];
+
+ *cow_offset *= sizeof(unsigned long);
+ *cow_offset += bitmap_offset;
+}
+
+static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
+ __u64 bitmap_offset, __u64 bitmap_len)
+{
+ __u64 sector = req->offset >> 9;
+ int i;
+
+ if(req->length > (sizeof(req->sector_mask) * 8) << 9)
+ panic("Operation too long");
+
+ if(req->op == UBD_READ) {
+ for(i = 0; i < req->length >> 9; i++){
+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
+ ubd_set_bit(i, (unsigned char *)
+ &req->sector_mask);
+ }
+ }
+ else cowify_bitmap(req->offset, req->length, &req->sector_mask,
+ &req->cow_offset, bitmap, bitmap_offset,
+ req->bitmap_words, bitmap_len);
}
/* Called with ubd_io_lock held */
-static int prepare_request(struct request *req, struct io_thread_req *io_req,
- unsigned long long offset, int page_offset,
- int len, struct page *page)
+static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
struct gendisk *disk = req->rq_disk;
struct ubd *dev = disk->private_data;
+ __u64 offset;
+ int len;
+
+ if(req->rq_status == RQ_INACTIVE) return(1);
/* This should be impossible now */
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
- ubd_end_request(req, 0, 0);
+ end_request(req, 0);
return(1);
}
+ offset = ((__u64) req->sector) << 9;
+ len = req->current_nr_sectors << 9;
+
io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
io_req->fds[1] = dev->fd;
+ io_req->cow_offset = -1;
io_req->offset = offset;
io_req->length = len;
io_req->error = 0;
- io_req->op = (rq_data_dir(req) == READ) ? AIO_READ : AIO_WRITE;
+ io_req->sector_mask = 0;
+
+ io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
io_req->offsets[1] = dev->cow.data_offset;
- io_req->buffer = page_address(page) + page_offset;
+ io_req->buffer = req->buffer;
io_req->sectorsize = 1 << 9;
- io_req->bitmap_offset = dev->cow.bitmap_offset;
- io_req->bitmap_start = -1;
- io_req->bitmap_end = -1;
- if((dev->cow.file != NULL) && (io_req->op == UBD_WRITE))
- cowify_bitmap(io_req, dev->cow.bitmap);
+ if(dev->cow.file != NULL)
+ cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
+ dev->cow.bitmap_len);
+
return(0);
}
@@ -996,36 +1030,30 @@ static void do_ubd_request(request_queue_t *q)
{
struct io_thread_req io_req;
struct request *req;
- __u64 sector;
- int err;
-
- if(in_ubd)
- return;
- in_ubd = 1;
- while((req = elv_next_request(q)) != NULL){
- struct gendisk *disk = req->rq_disk;
- struct ubd *dev = disk->private_data;
- int n, i;
-
- blkdev_dequeue_request(req);
-
- sector = req->sector;
- n = blk_rq_map_sg(q, req, dev->sg);
-
- for(i = 0; i < n; i++){
- struct scatterlist *sg = &dev->sg[i];
-
- err = prepare_request(req, &io_req, sector << 9,
- sg->offset, sg->length,
- sg->page);
- if(err)
- continue;
-
- sector += sg->length >> 9;
- do_io(&io_req, req, dev->cow.bitmap);
+ int err, n;
+
+ if(thread_fd == -1){
+ while((req = elv_next_request(q)) != NULL){
+ err = prepare_request(req, &io_req);
+ if(!err){
+ do_io(&io_req);
+ __ubd_finish(req, io_req.error);
+ }
+ }
+ }
+ else {
+ if(do_ubd || (req = elv_next_request(q)) == NULL)
+ return;
+ err = prepare_request(req, &io_req);
+ if(!err){
+ do_ubd = ubd_handler;
+ n = os_write_file(thread_fd, (char *) &io_req,
+ sizeof(io_req));
+ if(n != sizeof(io_req))
+ printk("write to io thread failed, "
+ "errno = %d\n", -n);
}
}
- in_ubd = 0;
}
static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -1241,95 +1269,131 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
return(err);
}
-void do_io(struct io_thread_req *req, struct request *r, unsigned long *bitmap)
+static int update_bitmap(struct io_thread_req *req)
{
- struct ubd_aio *aio;
- struct bitmap_io *bitmap_io = NULL;
- char *buf;
- void *bitmap_buf = NULL;
- unsigned long len, sector;
- int nsectors, start, end, bit, err;
- __u64 off;
-
- if(req->bitmap_start != -1){
- /* Round up to the nearest word */
- int round = sizeof(unsigned long);
- len = (req->bitmap_end - req->bitmap_start +
- round * 8 - 1) / (round * 8);
- len *= round;
-
- off = req->bitmap_start / (8 * round);
- off *= round;
-
- bitmap_io = kmalloc(sizeof(*bitmap_io), GFP_KERNEL);
- if(bitmap_io == NULL){
- printk("Failed to kmalloc bitmap IO\n");
- req->error = 1;
- return;
- }
+ int n;
- bitmap_buf = kmalloc(len, GFP_KERNEL);
- if(bitmap_buf == NULL){
- printk("do_io : kmalloc of bitmap chunk "
- "failed\n");
- kfree(bitmap_io);
- req->error = 1;
- return;
- }
- memcpy(bitmap_buf, &bitmap[off / sizeof(bitmap[0])], len);
-
- *bitmap_io = ((struct bitmap_io)
- { .count = ATOMIC_INIT(0),
- .aio = INIT_AIO(AIO_WRITE, req->fds[1],
- bitmap_buf, len,
- req->bitmap_offset + off,
- ubd_reply_fd) } );
- }
+ if(req->cow_offset == -1)
+ return(0);
- nsectors = req->length / req->sectorsize;
- start = 0;
- end = nsectors;
- bit = 0;
- do {
- if(bitmap != NULL){
- sector = req->offset / req->sectorsize;
- bit = ubd_test_bit(sector + start, bitmap);
- end = start;
- while((end < nsectors) &&
- (ubd_test_bit(sector + end, bitmap) == bit))
- end++;
- }
+ n = os_seek_file(req->fds[1], req->cow_offset);
+ if(n < 0){
+ printk("do_io - bitmap lseek failed : err = %d\n", -n);
+ return(1);
+ }
- off = req->offsets[bit] + req->offset +
- start * req->sectorsize;
- len = (end - start) * req->sectorsize;
- buf = &req->buffer[start * req->sectorsize];
+ n = os_write_file(req->fds[1], &req->bitmap_words,
+ sizeof(req->bitmap_words));
+ if(n != sizeof(req->bitmap_words)){
+ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
+ req->fds[1]);
+ return(1);
+ }
- aio = kmalloc(sizeof(*aio), GFP_KERNEL);
- if(aio == NULL){
- req->error = 1;
- return;
- }
+ return(0);
+}
- *aio = ((struct ubd_aio)
- { .aio = INIT_AIO(req->op, req->fds[bit], buf,
- len, off, ubd_reply_fd),
- .len = len,
- .req = r,
- .bitmap = bitmap_io,
- .bitmap_buf = bitmap_buf });
-
- if(aio->bitmap != NULL)
- atomic_inc(&aio->bitmap->count);
-
- err = submit_aio(&aio->aio);
- if(err){
- printk("do_io - submit_aio failed, "
- "err = %d\n", err);
- req->error = 1;
- return;
- }
+void do_io(struct io_thread_req *req)
+{
+ char *buf;
+ unsigned long len;
+ int n, nsectors, start, end, bit;
+ int err;
+ __u64 off;
+
+ nsectors = req->length / req->sectorsize;
+ start = 0;
+ do {
+ bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
+ end = start;
+ while((end < nsectors) &&
+ (ubd_test_bit(end, (unsigned char *)
+ &req->sector_mask) == bit))
+ end++;
+
+ off = req->offset + req->offsets[bit] +
+ start * req->sectorsize;
+ len = (end - start) * req->sectorsize;
+ buf = &req->buffer[start * req->sectorsize];
+
+ err = os_seek_file(req->fds[bit], off);
+ if(err < 0){
+ printk("do_io - lseek failed : err = %d\n", -err);
+ req->error = 1;
+ return;
+ }
+ if(req->op == UBD_READ){
+ n = 0;
+ do {
+ buf = &buf[n];
+ len -= n;
+ n = os_read_file(req->fds[bit], buf, len);
+ if (n < 0) {
+ printk("do_io - read failed, err = %d "
+ "fd = %d\n", -n, req->fds[bit]);
+ req->error = 1;
+ return;
+ }
+ } while((n < len) && (n != 0));
+ if (n < len) memset(&buf[n], 0, len - n);
+ } else {
+ n = os_write_file(req->fds[bit], buf, len);
+ if(n != len){
+ printk("do_io - write failed err = %d "
+ "fd = %d\n", -n, req->fds[bit]);
+ req->error = 1;
+ return;
+ }
+ }
+
+ start = end;
+ } while(start < nsectors);
- start = end;
- } while(start < nsectors);
+ req->error = update_bitmap(req);
}
+
+/* Changed in start_io_thread, which is serialized by being called only
+ * from ubd_init, which is an initcall.
+ */
+int kernel_fd = -1;
+
+/* Only changed by the io thread */
+int io_count = 0;
+
+int io_thread(void *arg)
+{
+ struct io_thread_req req;
+ int n;
+
+ ignore_sigwinch_sig();
+ while(1){
+ n = os_read_file(kernel_fd, &req, sizeof(req));
+ if(n != sizeof(req)){
+ if(n < 0)
+ printk("io_thread - read failed, fd = %d, "
+ "err = %d\n", kernel_fd, -n);
+ else {
+ printk("io_thread - short read, fd = %d, "
+ "length = %d\n", kernel_fd, n);
+ }
+ continue;
+ }
+ io_count++;
+ do_io(&req);
+ n = os_write_file(kernel_fd, &req, sizeof(req));
+ if(n != sizeof(req))
+ printk("io_thread - write failed, fd = %d, err = %d\n",
+ kernel_fd, -n);
+ }
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 93dc1911363f..90e0e5ff451e 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -110,13 +110,15 @@ int xterm_open(int input, int output, int primary, void *d,
fd = mkstemp(file);
if(fd < 0){
+ err = -errno;
printk("xterm_open : mkstemp failed, errno = %d\n", errno);
- return(-errno);
+ return err;
}
if(unlink(file)){
+ err = -errno;
printk("xterm_open : unlink failed, errno = %d\n", errno);
- return(-errno);
+ return err;
}
os_close_file(fd);
diff --git a/arch/um/include/aio.h b/arch/um/include/aio.h
index 83f16877ab08..423bae9153f8 100644
--- a/arch/um/include/aio.h
+++ b/arch/um/include/aio.h
@@ -14,27 +14,15 @@ struct aio_thread_reply {
};
struct aio_context {
- enum aio_type type;
- int fd;
- void *data;
- int len;
- unsigned long long offset;
int reply_fd;
struct aio_context *next;
};
-#define INIT_AIO(aio_type, aio_fd, aio_data, aio_len, aio_offset, \
- aio_reply_fd) \
- { .type = aio_type, \
- .fd = aio_fd, \
- .data = aio_data, \
- .len = aio_len, \
- .offset = aio_offset, \
- .reply_fd = aio_reply_fd }
-
#define INIT_AIO_CONTEXT { .reply_fd = -1, \
.next = NULL }
-extern int submit_aio(struct aio_context *aio);
+extern int submit_aio(enum aio_type type, int fd, char *buf, int len,
+ unsigned long long offset, int reply_fd,
+ struct aio_context *aio);
#endif
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 0aa620970adb..356390d1f8b9 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,7 +1,7 @@
/* for use by sys-$SUBARCH/kernel-offsets.c */
-OFFSET(TASK_REGS, task_struct, thread.regs);
-OFFSET(TASK_PID, task_struct, pid);
+OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
+OFFSET(HOST_TASK_PID, task_struct, pid);
DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
@@ -12,4 +12,6 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
DEFINE_STR(UM_KERN_INFO, KERN_INFO);
DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
-DEFINE(HOST_ELF_CLASS, ELF_CLASS);
+DEFINE(UM_ELF_CLASS, ELF_CLASS);
+DEFINE(UM_ELFCLASS32, ELFCLASS32);
+DEFINE(UM_ELFCLASS64, ELFCLASS64);
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index cfa368e045a5..b1b512f47035 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -81,6 +81,7 @@ extern void mconsole_stop(struct mc_request *req);
extern void mconsole_go(struct mc_request *req);
extern void mconsole_log(struct mc_request *req);
extern void mconsole_proc(struct mc_request *req);
+extern void mconsole_stack(struct mc_request *req);
extern int mconsole_get_request(int fd, struct mc_request *req);
extern int mconsole_notify(char *sock_name, int type, const void *data,
diff --git a/arch/um/include/mem.h b/arch/um/include/mem.h
index 99d3ad4a03e5..e8ff0d8fa610 100644
--- a/arch/um/include/mem.h
+++ b/arch/um/include/mem.h
@@ -13,7 +13,17 @@ extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
extern int is_remapped(void *virt);
extern int physmem_remove_mapping(void *virt);
extern void physmem_forget_descriptor(int fd);
-extern unsigned long to_phys(void *virt);
+
+extern unsigned long uml_physmem;
+static inline unsigned long to_phys(void *virt)
+{
+ return(((unsigned long) virt) - uml_physmem);
+}
+
+static inline void *to_virt(unsigned long phys)
+{
+ return((void *) uml_physmem + phys);
+}
#endif
diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
index d6404bb64662..9fef4123a65a 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -51,7 +51,6 @@ extern unsigned long task_size;
extern void check_devanon(void);
extern int init_mem_user(void);
-extern int create_mem_file(unsigned long len);
extern void setup_memory(void *entry);
extern unsigned long find_iomem(char *driver, unsigned long *len_out);
extern int init_maps(unsigned long physmem, unsigned long iomem,
@@ -64,20 +63,6 @@ extern unsigned long phys_offset(unsigned long phys);
extern void unmap_physmem(void);
extern void map_memory(unsigned long virt, unsigned long phys,
unsigned long len, int r, int w, int x);
-extern int protect_memory(unsigned long addr, unsigned long len,
- int r, int w, int x, int must_succeed);
extern unsigned long get_kmem_end(void);
-extern void check_tmpexec(void);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 4c362458052c..2e58e304b8be 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -6,6 +6,7 @@
#ifndef __OS_H__
#define __OS_H__
+#include "uml-config.h"
#include "asm/types.h"
#include "../os/include/file.h"
@@ -157,6 +158,17 @@ extern int os_lock_file(int fd, int excl);
extern void os_early_checks(void);
extern int can_do_skas(void);
+/* Make sure they are clear when running in TT mode. Required by
+ * SEGV_MAYBE_FIXABLE */
+#ifdef UML_CONFIG_MODE_SKAS
+#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
+#else
+#define clear_can_do_skas() do {} while (0)
+#endif
+
+/* mem.c */
+extern int create_mem_file(unsigned long len);
+
/* process.c */
extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid);
@@ -181,6 +193,8 @@ extern unsigned long long os_usecs(void);
/* tt.c
* for tt mode only (will be deleted in future...)
*/
+extern int protect_memory(unsigned long addr, unsigned long len,
+ int r, int w, int x, int must_succeed);
extern void forward_pending_sigio(int target);
extern int start_fork_tramp(void *arg, unsigned long temp_stack,
int clone_flags, int (*tramp)(void *));
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 0a35e6d0baa0..4892e5fcef07 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -15,16 +15,6 @@ extern void save_registers(int pid, union uml_pt_regs *regs);
extern void restore_registers(int pid, union uml_pt_regs *regs);
extern void init_registers(int pid);
extern void get_safe_registers(unsigned long * regs);
+extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/skas_ptregs.h b/arch/um/include/skas_ptregs.h
new file mode 100644
index 000000000000..73db19e9c077
--- /dev/null
+++ b/arch/um/include/skas_ptregs.h
@@ -0,0 +1,6 @@
+#ifndef __SKAS_PT_REGS_
+#define __SKAS_PT_REGS_
+
+#include <user_constants.h>
+
+#endif
diff --git a/arch/um/include/sysdep-i386/sc.h b/arch/um/include/sysdep-i386/sc.h
new file mode 100644
index 000000000000..c57d1780ad37
--- /dev/null
+++ b/arch/um/include/sysdep-i386/sc.h
@@ -0,0 +1,44 @@
+#ifndef __SYSDEP_I386_SC_H
+#define __SYSDEP_I386_SC_H
+
+#include <user_constants.h>
+
+#define SC_OFFSET(sc, field) \
+ *((unsigned long *) &(((char *) (sc))[HOST_##field]))
+#define SC_FP_OFFSET(sc, field) \
+ *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field]))
+#define SC_FP_OFFSET_PTR(sc, field, type) \
+ ((type *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field]))
+
+#define SC_IP(sc) SC_OFFSET(sc, SC_IP)
+#define SC_SP(sc) SC_OFFSET(sc, SC_SP)
+#define SC_FS(sc) SC_OFFSET(sc, SC_FS)
+#define SC_GS(sc) SC_OFFSET(sc, SC_GS)
+#define SC_DS(sc) SC_OFFSET(sc, SC_DS)
+#define SC_ES(sc) SC_OFFSET(sc, SC_ES)
+#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
+#define SC_CS(sc) SC_OFFSET(sc, SC_CS)
+#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS)
+#define SC_EAX(sc) SC_OFFSET(sc, SC_EAX)
+#define SC_EBX(sc) SC_OFFSET(sc, SC_EBX)
+#define SC_ECX(sc) SC_OFFSET(sc, SC_ECX)
+#define SC_EDX(sc) SC_OFFSET(sc, SC_EDX)
+#define SC_EDI(sc) SC_OFFSET(sc, SC_EDI)
+#define SC_ESI(sc) SC_OFFSET(sc, SC_ESI)
+#define SC_EBP(sc) SC_OFFSET(sc, SC_EBP)
+#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO)
+#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR)
+#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2)
+#define SC_FPSTATE(sc) SC_OFFSET(sc, SC_FPSTATE)
+#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK)
+#define SC_FP_CW(sc) SC_FP_OFFSET(sc, SC_FP_CW)
+#define SC_FP_SW(sc) SC_FP_OFFSET(sc, SC_FP_SW)
+#define SC_FP_TAG(sc) SC_FP_OFFSET(sc, SC_FP_TAG)
+#define SC_FP_IPOFF(sc) SC_FP_OFFSET(sc, SC_FP_IPOFF)
+#define SC_FP_CSSEL(sc) SC_FP_OFFSET(sc, SC_FP_CSSEL)
+#define SC_FP_DATAOFF(sc) SC_FP_OFFSET(sc, SC_FP_DATAOFF)
+#define SC_FP_DATASEL(sc) SC_FP_OFFSET(sc, SC_FP_DATASEL)
+#define SC_FP_ST(sc) SC_FP_OFFSET_PTR(sc, SC_FP_ST, struct _fpstate)
+#define SC_FXSR_ENV(sc) SC_FP_OFFSET_PTR(sc, SC_FXSR_ENV, void)
+
+#endif
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 1fe729265167..23fd2644d7ed 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -6,6 +6,7 @@
#ifndef __SYS_SIGCONTEXT_I386_H
#define __SYS_SIGCONTEXT_I386_H
+#include "uml-config.h"
#include <sysdep/sc.h>
#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
@@ -26,7 +27,14 @@
#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
/* This is Page Fault */
-#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+
+/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */
+#ifdef UML_CONFIG_MODE_SKAS
+#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo)
+#else
+#define SEGV_MAYBE_FIXABLE(fi) 0
+#endif
extern unsigned long *sc_sigmask(void *sc_ptr);
extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h
new file mode 100644
index 000000000000..243fed44d780
--- /dev/null
+++ b/arch/um/include/sysdep-i386/thread.h
@@ -0,0 +1,11 @@
+#ifndef __UM_THREAD_H
+#define __UM_THREAD_H
+
+#include <kern_constants.h>
+
+#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS]))
+#ifdef UML_CONFIG_MODE_TT
+#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
+#endif
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 331aa2d1f3f5..8d353f0feec1 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -183,10 +183,6 @@ struct syscall_args {
case RBP: val = UPT_RBP(regs); break; \
case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
case CS: val = UPT_CS(regs); break; \
- case DS: val = UPT_DS(regs); break; \
- case ES: val = UPT_ES(regs); break; \
- case FS: val = UPT_FS(regs); break; \
- case GS: val = UPT_GS(regs); break; \
case EFLAGS: val = UPT_EFLAGS(regs); break; \
default : \
panic("Bad register in UPT_REG : %d\n", reg); \
@@ -218,10 +214,6 @@ struct syscall_args {
case RBP: UPT_RBP(regs) = __upt_val; break; \
case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
case CS: UPT_CS(regs) = __upt_val; break; \
- case DS: UPT_DS(regs) = __upt_val; break; \
- case ES: UPT_ES(regs) = __upt_val; break; \
- case FS: UPT_FS(regs) = __upt_val; break; \
- case GS: UPT_GS(regs) = __upt_val; break; \
case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
default : \
panic("Bad register in UPT_SET : %d\n", reg); \
diff --git a/arch/um/include/sysdep-x86_64/sc.h b/arch/um/include/sysdep-x86_64/sc.h
new file mode 100644
index 000000000000..a160d9fcc596
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/sc.h
@@ -0,0 +1,45 @@
+#ifndef __SYSDEP_X86_64_SC_H
+#define __SYSDEP_X86_64_SC_H
+
+/* Copyright (C) 2003 - 2004 PathScale, Inc
+ * Released under the GPL
+ */
+
+#include <user_constants.h>
+
+#define SC_OFFSET(sc, field) \
+ *((unsigned long *) &(((char *) (sc))[HOST_##field]))
+
+#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX)
+#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX)
+#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX)
+#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI)
+#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI)
+#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP)
+#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX)
+#define SC_R8(sc) SC_OFFSET(sc, SC_R8)
+#define SC_R9(sc) SC_OFFSET(sc, SC_R9)
+#define SC_R10(sc) SC_OFFSET(sc, SC_R10)
+#define SC_R11(sc) SC_OFFSET(sc, SC_R11)
+#define SC_R12(sc) SC_OFFSET(sc, SC_R12)
+#define SC_R13(sc) SC_OFFSET(sc, SC_R13)
+#define SC_R14(sc) SC_OFFSET(sc, SC_R14)
+#define SC_R15(sc) SC_OFFSET(sc, SC_R15)
+#define SC_IP(sc) SC_OFFSET(sc, SC_IP)
+#define SC_SP(sc) SC_OFFSET(sc, SC_SP)
+#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2)
+#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR)
+#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO)
+#define SC_CS(sc) SC_OFFSET(sc, SC_CS)
+#define SC_FS(sc) SC_OFFSET(sc, SC_FS)
+#define SC_GS(sc) SC_OFFSET(sc, SC_GS)
+#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS)
+#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK)
+#if 0
+#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX)
+#define SC_DS(sc) SC_OFFSET(sc, SC_DS)
+#define SC_ES(sc) SC_OFFSET(sc, SC_ES)
+#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
+#endif
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 2a78260d15a0..41073235e7ad 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -31,7 +31,10 @@
#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
/* This is Page Fault */
-#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+
+/* No broken SKAS API, which doesn't pass trap_no, here. */
+#define SEGV_MAYBE_FIXABLE(fi) 0
extern unsigned long *sc_sigmask(void *sc_ptr);
diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h
new file mode 100644
index 000000000000..cbef3e1697f4
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/thread.h
@@ -0,0 +1,10 @@
+#ifndef __UM_THREAD_H
+#define __UM_THREAD_H
+
+#include <kern_constants.h>
+
+#ifdef UML_CONFIG_MODE_TT
+#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
+#endif
+
+#endif
diff --git a/arch/um/include/task.h b/arch/um/include/task.h
new file mode 100644
index 000000000000..6375ba7203c9
--- /dev/null
+++ b/arch/um/include/task.h
@@ -0,0 +1,9 @@
+#ifndef __TASK_H
+#define __TASK_H
+
+#include <kern_constants.h>
+
+#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
+#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
+
+#endif
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index 57ee9e261228..0f865ef46918 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -14,7 +14,9 @@ extern void *um_kmalloc_atomic(int size);
extern void kfree(void *ptr);
extern int in_aton(char *str);
extern int open_gdb_chan(void);
-extern int strlcpy(char *, const char *, int);
+/* These use size_t, however unsigned long is correct on both i386 and x86_64. */
+extern unsigned long strlcpy(char *, const char *, unsigned long);
+extern unsigned long strlcat(char *, const char *, unsigned long);
extern void *um_vmalloc(int size);
extern void vfree(void *ptr);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 614b8ebeb0ed..1a0001b3850c 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -1,4 +1,4 @@
-#
+#
# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL
#
@@ -7,11 +7,11 @@ extra-y := vmlinux.lds
clean-files :=
obj-y = config.o exec_kern.o exitcode.o \
- helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
- physmem.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
- sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o \
- tempfile.o time.o time_kern.o tlb.o trap_kern.o trap_user.o \
- uaccess_user.o um_arch.o umid.o user_util.o
+ helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.o \
+ process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
+ signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
+ time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
+ umid.o user_util.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -24,8 +24,8 @@ obj-$(CONFIG_MODE_SKAS) += skas/
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-USER_OBJS := $(user-objs-y) config.o helper.o main.o tempfile.o time.o \
- tty_log.o umid.o user_util.o
+USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \
+ user_util.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/asm-offsets.c b/arch/um/kernel/asm-offsets.c
new file mode 100644
index 000000000000..c13a64a288f6
--- /dev/null
+++ b/arch/um/kernel/asm-offsets.c
@@ -0,0 +1 @@
+/* Dummy file to make kbuild happy - unused! */
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 3942a5f245de..2517ecb8bf27 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -146,37 +146,8 @@ SECTIONS
}
_end = .;
PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
+
+ STABS_DEBUG
+
+ DWARF_DEBUG
}
diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
index f83e1e8e2392..33fb0bd3b11a 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/kernel/helper.c
@@ -85,8 +85,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
data.fd = fds[1];
pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
if(pid < 0){
- printk("run_helper : clone failed, errno = %d\n", errno);
ret = -errno;
+ printk("run_helper : clone failed, errno = %d\n", errno);
goto out_close;
}
@@ -122,7 +122,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
unsigned long *stack_out, int stack_order)
{
unsigned long stack, sp;
- int pid, status;
+ int pid, status, err;
stack = alloc_stack(stack_order, um_in_interrupt());
if(stack == 0) return(-ENOMEM);
@@ -130,16 +130,18 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
sp = stack + (page_size() << stack_order) - sizeof(void *);
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
if(pid < 0){
+ err = -errno;
printk("run_helper_thread : clone failed, errno = %d\n",
errno);
- return(-errno);
+ return err;
}
if(stack_out == NULL){
CATCH_EINTR(pid = waitpid(pid, &status, 0));
if(pid < 0){
+ err = -errno;
printk("run_helper_thread - wait failed, errno = %d\n",
errno);
- pid = -errno;
+ pid = err;
}
if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
printk("run_helper_thread - thread returned status "
@@ -156,8 +158,8 @@ int helper_wait(int pid)
CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
if(ret < 0){
+ ret = -errno;
printk("helper_wait : waitpid failed, errno = %d\n", errno);
- return(-errno);
}
return(ret);
}
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index cd7c85be0a1b..49ed5ddf0704 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -13,6 +13,7 @@
#include "asm/pgtable.h"
#include "user_util.h"
#include "mem_user.h"
+#include "os.h"
static struct fs_struct init_fs = INIT_FS;
struct mm_struct init_mm = INIT_MM(init_mm);
@@ -45,8 +46,8 @@ __attribute__((__section__(".data.init_task"))) =
void unprotect_stack(unsigned long stack)
{
- protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
- 1, 1, 0, 1);
+ os_protect_memory((void *) stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
+ 1, 1, 0);
}
/*
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index dcd814971995..bbf94bf2921e 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -9,7 +9,6 @@
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/smp.h"
-#include "linux/irq.h"
#include "linux/kernel_stat.h"
#include "linux/interrupt.h"
#include "linux/random.h"
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 32d3076dd220..a97a72e516aa 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -34,14 +34,9 @@ EXPORT_SYMBOL(host_task_size);
EXPORT_SYMBOL(arch_validate);
EXPORT_SYMBOL(get_kmem_end);
-EXPORT_SYMBOL(page_to_phys);
-EXPORT_SYMBOL(phys_to_page);
EXPORT_SYMBOL(high_physmem);
EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(um_virt_to_phys);
-EXPORT_SYMBOL(__virt_to_page);
-EXPORT_SYMBOL(to_phys);
-EXPORT_SYMBOL(to_virt);
EXPORT_SYMBOL(mode_tt);
EXPORT_SYMBOL(handle_page_fault);
EXPORT_SYMBOL(find_iomem);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 64fa062cc119..462cc9d65386 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Licensed under the GPL
*/
@@ -19,6 +19,10 @@
#include "mem_user.h"
#include "uml_uaccess.h"
#include "os.h"
+#include "linux/types.h"
+#include "linux/string.h"
+#include "init.h"
+#include "kern_constants.h"
extern char __binary_start;
@@ -248,7 +252,7 @@ void paging_init(void)
#endif
}
-struct page *arch_validate(struct page *page, int mask, int order)
+struct page *arch_validate(struct page *page, gfp_t mask, int order)
{
unsigned long addr, zero = 0;
int i;
@@ -368,6 +372,16 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
return pte;
}
+struct iomem_region *iomem_regions = NULL;
+int iomem_size = 0;
+
+extern int parse_iomem(char *str, int *add) __init;
+
+__uml_setup("iomem=", parse_iomem,
+"iomem=<name>,<file>\n"
+" Configure <file> as an IO memory region named <name>.\n\n"
+);
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
deleted file mode 100644
index 4a663fd434bb..000000000000
--- a/arch/um/kernel/mem_user.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * arch/um/kernel/mem_user.c
- *
- * BRIEF MODULE DESCRIPTION
- * user side memory routines for supporting IO memory inside user mode linux
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.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 SOFTWARE IS PROVIDED ``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,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include "kern_util.h"
-#include "user.h"
-#include "user_util.h"
-#include "mem_user.h"
-#include "init.h"
-#include "os.h"
-#include "tempfile.h"
-#include "kern_constants.h"
-
-#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
-
-static int create_tmp_file(unsigned long len)
-{
- int fd, err;
- char zero;
-
- fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
- if(fd < 0) {
- os_print_error(fd, "make_tempfile");
- exit(1);
- }
-
- err = os_mode_fd(fd, 0777);
- if(err < 0){
- os_print_error(err, "os_mode_fd");
- exit(1);
- }
- err = os_seek_file(fd, len);
- if(err < 0){
- os_print_error(err, "os_seek_file");
- exit(1);
- }
- zero = 0;
- err = os_write_file(fd, &zero, 1);
- if(err != 1){
- os_print_error(err, "os_write_file");
- exit(1);
- }
-
- return(fd);
-}
-
-void check_tmpexec(void)
-{
- void *addr;
- int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
-
- addr = mmap(NULL, UM_KERN_PAGE_SIZE,
- PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
- printf("Checking PROT_EXEC mmap in /tmp...");
- fflush(stdout);
- if(addr == MAP_FAILED){
- err = errno;
- perror("failed");
- if(err == EPERM)
- printf("/tmp must be not mounted noexec\n");
- exit(1);
- }
- printf("OK\n");
- munmap(addr, UM_KERN_PAGE_SIZE);
-
- os_close_file(fd);
-}
-
-static int have_devanon = 0;
-
-void check_devanon(void)
-{
- int fd;
-
- printk("Checking for /dev/anon on the host...");
- fd = open("/dev/anon", O_RDWR);
- if(fd < 0){
- printk("Not available (open failed with errno %d)\n", errno);
- return;
- }
-
- printk("OK\n");
- have_devanon = 1;
-}
-
-static int create_anon_file(unsigned long len)
-{
- void *addr;
- int fd;
-
- fd = open("/dev/anon", O_RDWR);
- if(fd < 0) {
- os_print_error(fd, "opening /dev/anon");
- exit(1);
- }
-
- addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
- if(addr == MAP_FAILED){
- perror("mapping physmem file");
- exit(1);
- }
- munmap(addr, len);
-
- return(fd);
-}
-
-int create_mem_file(unsigned long len)
-{
- int err, fd;
-
- if(have_devanon)
- fd = create_anon_file(len);
- else fd = create_tmp_file(len);
-
- err = os_set_exec_close(fd, 1);
- if(err < 0)
- os_print_error(err, "exec_close");
- return(fd);
-}
-
-struct iomem_region *iomem_regions = NULL;
-int iomem_size = 0;
-
-static int __init parse_iomem(char *str, int *add)
-{
- struct iomem_region *new;
- struct uml_stat buf;
- char *file, *driver;
- int fd, err, size;
-
- driver = str;
- file = strchr(str,',');
- if(file == NULL){
- printf("parse_iomem : failed to parse iomem\n");
- goto out;
- }
- *file = '\0';
- file++;
- fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
- if(fd < 0){
- os_print_error(fd, "parse_iomem - Couldn't open io file");
- goto out;
- }
-
- err = os_stat_fd(fd, &buf);
- if(err < 0){
- os_print_error(err, "parse_iomem - cannot stat_fd file");
- goto out_close;
- }
-
- new = malloc(sizeof(*new));
- if(new == NULL){
- perror("Couldn't allocate iomem_region struct");
- goto out_close;
- }
-
- size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
-
- *new = ((struct iomem_region) { .next = iomem_regions,
- .driver = driver,
- .fd = fd,
- .size = size,
- .phys = 0,
- .virt = 0 });
- iomem_regions = new;
- iomem_size += new->size + UM_KERN_PAGE_SIZE;
-
- return(0);
- out_close:
- os_close_file(fd);
- out:
- return(1);
-}
-
-__uml_setup("iomem=", parse_iomem,
-"iomem=<name>,<file>\n"
-" Configure <file> as an IO memory region named <name>.\n\n"
-);
-
-int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
- int must_succeed)
-{
- int err;
-
- err = os_protect_memory((void *) addr, len, r, w, x);
- if(err < 0){
- if(must_succeed)
- panic("protect failed, err = %d", -err);
- else return(err);
- }
- return(0);
-}
-
-#if 0
-/* Debugging facility for dumping stuff out to the host, avoiding the timing
- * problems that come with printf and breakpoints.
- * Enable in case of emergency.
- */
-
-int logging = 1;
-int logging_fd = -1;
-
-int logging_line = 0;
-char logging_buf[512];
-
-void log(char *fmt, ...)
-{
- va_list ap;
- struct timeval tv;
- struct openflags flags;
-
- if(logging == 0) return;
- if(logging_fd < 0){
- flags = of_create(of_trunc(of_rdwr(OPENFLAGS())));
- logging_fd = os_open_file("log", flags, 0644);
- }
- gettimeofday(&tv, NULL);
- sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
- tv.tv_usec);
- va_start(ap, fmt);
- vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
- va_end(ap);
- write(logging_fd, logging_buf, strlen(logging_buf));
-}
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index a24e3b7f4bf0..ea670fcc8af5 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -248,16 +248,6 @@ unsigned long high_physmem;
extern unsigned long physmem_size;
-void *to_virt(unsigned long phys)
-{
- return((void *) uml_physmem + phys);
-}
-
-unsigned long to_phys(void *virt)
-{
- return(((unsigned long) virt) - uml_physmem);
-}
-
int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
{
struct page *p, *map;
@@ -298,31 +288,6 @@ int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
return(0);
}
-struct page *phys_to_page(const unsigned long phys)
-{
- return(&mem_map[phys >> PAGE_SHIFT]);
-}
-
-struct page *__virt_to_page(const unsigned long virt)
-{
- return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
-}
-
-phys_t page_to_phys(struct page *page)
-{
- return((page - mem_map) << PAGE_SHIFT);
-}
-
-pte_t mk_pte(struct page *page, pgprot_t pgprot)
-{
- pte_t pte;
-
- pte_set_val(pte, page_to_phys(page), pgprot);
- if(pte_present(pte))
- pte_mknewprot(pte_mknewpage(pte));
- return(pte);
-}
-
/* Changed during early boot */
static unsigned long kmem_top = 0;
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index c23d8a08d0ff..0d73ceeece72 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -80,9 +80,10 @@ void free_stack(unsigned long stack, int order)
unsigned long alloc_stack(int order, int atomic)
{
unsigned long page;
- int flags = GFP_KERNEL;
+ gfp_t flags = GFP_KERNEL;
- if(atomic) flags |= GFP_ATOMIC;
+ if (atomic)
+ flags = GFP_ATOMIC;
page = __get_free_pages(flags, order);
if(page == 0)
return(0);
@@ -113,8 +114,23 @@ void set_current(void *t)
void *_switch_to(void *prev, void *next, void *last)
{
- return(CHOOSE_MODE(switch_to_tt(prev, next),
- switch_to_skas(prev, next)));
+ struct task_struct *from = prev;
+ struct task_struct *to= next;
+
+ to->thread.prev_sched = from;
+ set_current(to);
+
+ do {
+ current->thread.saved_task = NULL ;
+ CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
+ if(current->thread.saved_task)
+ show_regs(&(current->thread.regs));
+ next= current->thread.saved_task;
+ prev= current;
+ } while(current->thread.saved_task);
+
+ return(current->thread.prev_sched);
+
}
void interrupt_end(void)
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index e89218958f38..a52751108aa1 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -340,7 +340,7 @@ static int setup_initial_poll(int fd)
{
struct pollfd *p;
- p = um_kmalloc(sizeof(struct pollfd));
+ p = um_kmalloc_atomic(sizeof(struct pollfd));
if(p == NULL){
printk("setup_initial_poll : failed to allocate poll\n");
return(-1);
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index db36c7c95940..8de471b59c1c 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -6,8 +6,6 @@
obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
syscall.o tlb.o trap_user.o uaccess.o
-subdir- := util
-
USER_OBJS := process.o clone.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h
index e48490028111..c97a80dfe370 100644
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ b/arch/um/kernel/skas/include/mode_kern-skas.h
@@ -11,7 +11,7 @@
#include "asm/ptrace.h"
extern void flush_thread_skas(void);
-extern void *switch_to_skas(void *prev, void *next);
+extern void switch_to_skas(void *prev, void *next);
extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
unsigned long esp);
extern int copy_thread_skas(int nr, unsigned long clone_flags,
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index cd6c280482cb..7da0c2def0ef 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,18 +18,12 @@
((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,
- 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/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 3d1b227226e6..efe92e8aa2a9 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -24,7 +24,7 @@
#include "proc_mm.h"
#include "registers.h"
-void *switch_to_skas(void *prev, void *next)
+void switch_to_skas(void *prev, void *next)
{
struct task_struct *from, *to;
@@ -35,16 +35,11 @@ void *switch_to_skas(void *prev, void *next)
if(current->pid == 0)
switch_timers(0);
- to->thread.prev_sched = from;
- set_current(to);
-
switch_threads(&from->thread.mode.skas.switch_buf,
to->thread.mode.skas.switch_buf);
if(current->pid == 0)
switch_timers(1);
-
- return(current->thread.prev_sched);
}
extern void schedule_tail(struct task_struct *prev);
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
deleted file mode 100644
index f7b7eba83340..000000000000
--- a/arch/um/kernel/skas/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_ptregs
-always := $(hostprogs-y)
-
-mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
-HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
deleted file mode 100644
index 1f96e1eeb8a7..000000000000
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) printf("#define %s %d\n", #name, name)
-
-int main(int argc, char **argv)
-{
- printf("/* Automatically generated by "
- "arch/um/kernel/skas/util/mk_ptregs */\n");
- printf("\n");
- printf("#ifndef __SKAS_PT_REGS_\n");
- printf("#define __SKAS_PT_REGS_\n");
- printf("\n");
- SHOW(HOST_FRAME_SIZE);
- SHOW(HOST_FP_SIZE);
- SHOW(HOST_XFP_SIZE);
-
- SHOW(HOST_IP);
- SHOW(HOST_SP);
- SHOW(HOST_EFLAGS);
- SHOW(HOST_EAX);
- SHOW(HOST_EBX);
- SHOW(HOST_ECX);
- SHOW(HOST_EDX);
- SHOW(HOST_ESI);
- SHOW(HOST_EDI);
- SHOW(HOST_EBP);
- SHOW(HOST_CS);
- SHOW(HOST_SS);
- SHOW(HOST_DS);
- SHOW(HOST_FS);
- SHOW(HOST_ES);
- SHOW(HOST_GS);
-
- printf("\n");
- printf("#endif\n");
- return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
deleted file mode 100644
index 5fccbfe35f78..000000000000
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) \
- printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
-
-int main(int argc, char **argv)
-{
- printf("/* Automatically generated by "
- "arch/um/kernel/skas/util/mk_ptregs */\n");
- printf("\n");
- printf("#ifndef __SKAS_PT_REGS_\n");
- printf("#define __SKAS_PT_REGS_\n");
- SHOW(HOST_FRAME_SIZE);
- SHOW(HOST_RBX);
- SHOW(HOST_RCX);
- SHOW(HOST_RDI);
- SHOW(HOST_RSI);
- SHOW(HOST_RDX);
- SHOW(HOST_RBP);
- SHOW(HOST_RAX);
- SHOW(HOST_R8);
- SHOW(HOST_R9);
- SHOW(HOST_R10);
- SHOW(HOST_R11);
- SHOW(HOST_R12);
- SHOW(HOST_R13);
- SHOW(HOST_R14);
- SHOW(HOST_R15);
- SHOW(HOST_ORIG_RAX);
- SHOW(HOST_CS);
- SHOW(HOST_SS);
- SHOW(HOST_EFLAGS);
-#if 0
- SHOW(HOST_FS);
- SHOW(HOST_GS);
- SHOW(HOST_DS);
- SHOW(HOST_ES);
-#endif
-
- SHOW(HOST_IP);
- SHOW(HOST_SP);
- printf("#define HOST_FP_SIZE 0\n");
- printf("#define HOST_XFP_SIZE 0\n");
- printf("\n");
- printf("\n");
- printf("#endif\n");
- return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index f80850091e79..b331e970002f 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
if (esp == NULL) {
if (task != current && task != NULL) {
- /* XXX: Isn't this bogus? I.e. isn't this the
- * *userspace* stack of this task? If not so, use this
- * even when task == current (as in i386).
- */
esp = (unsigned long *) KSTK_ESP(task);
- /* Which one? No actual difference - just coding style.*/
- //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
} else {
esp = (unsigned long *) &esp;
}
@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
}
printk("Call Trace: \n");
- show_trace(current, esp);
+ show_trace(task, esp);
}
diff --git a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c
deleted file mode 100644
index b1674bc1395d..000000000000
--- a/arch/um/kernel/tempfile.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/param.h>
-#include "init.h"
-
-/* Modified from create_mem_file and start_debugger */
-static char *tempdir = NULL;
-
-static void __init find_tempdir(void)
-{
- char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
- int i;
- char *dir = NULL;
-
- if(tempdir != NULL) return; /* We've already been called */
- for(i = 0; dirs[i]; i++){
- dir = getenv(dirs[i]);
- if((dir != NULL) && (*dir != '\0'))
- break;
- }
- if((dir == NULL) || (*dir == '\0'))
- dir = "/tmp";
-
- tempdir = malloc(strlen(dir) + 2);
- if(tempdir == NULL){
- fprintf(stderr, "Failed to malloc tempdir, "
- "errno = %d\n", errno);
- return;
- }
- strcpy(tempdir, dir);
- strcat(tempdir, "/");
-}
-
-int make_tempfile(const char *template, char **out_tempname, int do_unlink)
-{
- char tempname[MAXPATHLEN];
- int fd;
-
- find_tempdir();
- if (*template != '/')
- strcpy(tempname, tempdir);
- else
- *tempname = 0;
- strcat(tempname, template);
- fd = mkstemp(tempname);
- if(fd < 0){
- fprintf(stderr, "open - cannot create %s: %s\n", tempname,
- strerror(errno));
- return -1;
- }
- if(do_unlink && (unlink(tempname) < 0)){
- perror("unlink");
- return -1;
- }
- if(out_tempname){
- *out_tempname = strdup(tempname);
- if(*out_tempname == NULL){
- perror("strdup");
- return -1;
- }
- }
- return(fd);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 80ed6188e8a2..f5b0636f9ad7 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -193,12 +193,12 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
r = pte_read(*npte);
w = pte_write(*npte);
x = pte_exec(*npte);
- if(!pte_dirty(*npte))
- w = 0;
- if(!pte_young(*npte)){
- r = 0;
- w = 0;
- }
+ if (!pte_young(*npte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*npte)) {
+ w = 0;
+ }
if(force || pte_newpage(*npte)){
if(pte_present(*npte))
ret = add_mmap(addr,
@@ -307,7 +307,7 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
}
else if(pte_newprot(*pte)){
updated = 1;
- protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+ os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
}
addr += PAGE_SIZE;
}
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index b5fc89fe9eab..95c8f8733baf 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -18,6 +18,7 @@
#include "asm/a.out.h"
#include "asm/current.h"
#include "asm/irq.h"
+#include "sysdep/sigcontext.h"
#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
@@ -25,6 +26,9 @@
#include "mconsole_kern.h"
#include "mem.h"
#include "mem_kern.h"
+#ifdef CONFIG_MODE_SKAS
+#include "skas.h"
+#endif
/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
int handle_page_fault(unsigned long address, unsigned long ip,
@@ -39,6 +43,12 @@ int handle_page_fault(unsigned long address, unsigned long ip,
int err = -EFAULT;
*code_out = SEGV_MAPERR;
+
+ /* If the fault was during atomic operation, don't take the fault, just
+ * fail. */
+ if (in_atomic())
+ goto out_nosemaphore;
+
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if(!vma)
@@ -57,7 +67,8 @@ good_area:
if(is_write && !(vma->vm_flags & VM_WRITE))
goto out;
- if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ /* Don't require VM_READ|VM_EXEC for write faults! */
+ if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
goto out;
do {
@@ -84,11 +95,11 @@ survive:
pte = pte_offset_kernel(pmd, address);
} while(!pte_present(*pte));
err = 0;
- *pte = pte_mkyoung(*pte);
- if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
+ WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
flush_tlb_page(vma, address);
out:
up_read(&mm->mmap_sem);
+out_nosemaphore:
return(err);
/*
@@ -125,7 +136,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
}
else if(current->mm == NULL)
panic("Segfault with no mm");
- err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+
+ if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
+ err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+ else {
+ err = -EFAULT;
+ /* A thread accessed NULL, we get a fault, but CR2 is invalid.
+ * This code is used in __do_copy_from_user() of TT mode. */
+ address = 0;
+ }
catcher = current->thread.fault_catcher;
if(!err)
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
index e0ca0e0b2516..2a35b15c5fef 100644
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ b/arch/um/kernel/tt/include/mode_kern-tt.h
@@ -11,7 +11,7 @@
#include "asm/ptrace.h"
#include "asm/uaccess.h"
-extern void *switch_to_tt(void *prev, void *next);
+extern void switch_to_tt(void *prev, void *next);
extern void flush_thread_tt(void);
extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
unsigned long esp);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index 3fbb5fe26f49..dc2ebfa8c54f 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -33,12 +33,6 @@ 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,
- unsigned long size)
-{
- return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
-}
-
extern unsigned long get_fault_addr(void);
extern int __do_copy_from_user(void *to, const void *from, int n,
@@ -50,12 +44,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/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
index 3085267459b1..03e589895388 100644
--- a/arch/um/kernel/tt/mem_user.c
+++ b/arch/um/kernel/tt/mem_user.c
@@ -12,6 +12,7 @@
#include "tt.h"
#include "mem_user.h"
#include "user_util.h"
+#include "os.h"
void remap_data(void *segment_start, void *segment_end, int w)
{
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index a189a2b92935..cfaa373a6e77 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -23,10 +23,11 @@
#include "mem_user.h"
#include "tlb.h"
#include "mode.h"
+#include "mode_kern.h"
#include "init.h"
#include "tt.h"
-void *switch_to_tt(void *prev, void *next, void *last)
+void switch_to_tt(void *prev, void *next)
{
struct task_struct *from, *to, *prev_sched;
unsigned long flags;
@@ -36,8 +37,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
from = prev;
to = next;
- to->thread.prev_sched = from;
-
cpu = from->thread_info->cpu;
if(cpu == 0)
forward_interrupts(to->thread.mode.tt.extern_pid);
@@ -53,7 +52,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
forward_pending_sigio(to->thread.mode.tt.extern_pid);
c = 0;
- set_current(to);
err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
if(err != sizeof(c))
@@ -85,8 +83,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
flush_tlb_all();
local_irq_restore(flags);
-
- return(current->thread.prev_sched);
}
void release_thread_tt(struct task_struct *task)
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index f01475512ecb..8c220f054b61 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n,
__do_copy, &faulted);
TASK_REGS(get_current())->tt = save;
- if(!faulted) return(0);
- else return(n - (fault - (unsigned long) from));
+ if(!faulted)
+ return 0;
+ else if (fault)
+ return n - (fault - (unsigned long) from);
+ else
+ /* In case of a general protection fault, we don't have the
+ * fault address, so NULL is used instead. Pretend we didn't
+ * copy anything. */
+ return n;
}
static void __do_strncpy(void *dst, const void *src, int count)
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 09f6f7ce4695..93dc782dc1cc 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -334,6 +334,8 @@ int linux_main(int argc, char **argv)
add_arg(DEFAULT_COMMAND_LINE);
os_early_checks();
+ if (force_tt)
+ clear_can_do_skas();
mode_tt = force_tt ? 1 : !can_do_skas();
#ifndef CONFIG_MODE_TT
if (mode_tt) {
@@ -361,11 +363,6 @@ int linux_main(int argc, char **argv)
uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
&host_task_size, &task_size);
- /* Need to check this early because mmapping happens before the
- * kernel is running.
- */
- check_tmpexec();
-
brk_start = (unsigned long) sbrk(0);
CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
/* Increase physical memory size for exec-shield users
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 186c28885016..0b21d59ba0cd 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR;
/* Changed by set_umid */
static int umid_is_random = 1;
static int umid_inited = 0;
+/* Have we created the files? Should we remove them? */
+static int umid_owned = 0;
static int make_umid(int (*printer)(const char *fmt, ...));
@@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len)
extern int tracing_pid;
-static int __init create_pid_file(void)
+static void __init create_pid_file(void)
{
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
char pid[sizeof("nnnnn\0")];
int fd, n;
- if(umid_file_name("pid", file, sizeof(file))) return 0;
+ if(umid_file_name("pid", file, sizeof(file)))
+ return;
fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
0644);
if(fd < 0){
printf("Open of machine pid file \"%s\" failed: %s\n",
file, strerror(-fd));
- return 0;
+ return;
}
sprintf(pid, "%d\n", os_getpid());
@@ -103,7 +106,6 @@ static int __init create_pid_file(void)
if(n != strlen(pid))
printf("Write of pid file failed - err = %d\n", -n);
os_close_file(fd);
- return 0;
}
static int actually_do_remove(char *dir)
@@ -147,7 +149,8 @@ static int actually_do_remove(char *dir)
void remove_umid_dir(void)
{
char dir[strlen(uml_dir) + UMID_LEN + 1];
- if(!umid_inited) return;
+ if (!umid_owned)
+ return;
sprintf(dir, "%s%s", uml_dir, umid);
actually_do_remove(dir);
@@ -155,11 +158,12 @@ void remove_umid_dir(void)
char *get_umid(int only_if_set)
{
- if(only_if_set && umid_is_random) return(NULL);
- return(umid);
+ if(only_if_set && umid_is_random)
+ return NULL;
+ return umid;
}
-int not_dead_yet(char *dir)
+static int not_dead_yet(char *dir)
{
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
char pid[sizeof("nnnnn\0")], *end;
@@ -193,7 +197,8 @@ int not_dead_yet(char *dir)
(p == CHOOSE_MODE(tracing_pid, os_getpid())))
dead = 1;
}
- if(!dead) return(1);
+ if(!dead)
+ return(1);
return(actually_do_remove(dir));
}
@@ -232,16 +237,13 @@ static int __init make_uml_dir(void)
strlcpy(dir, home, sizeof(dir));
uml_dir++;
}
+ strlcat(dir, uml_dir, sizeof(dir));
len = strlen(dir);
- strncat(dir, uml_dir, sizeof(dir) - len);
- len = strlen(dir);
- if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
- dir[len] = '/';
- dir[len + 1] = '\0';
- }
+ if (len > 0 && dir[len - 1] != '/')
+ strlcat(dir, "/", sizeof(dir));
uml_dir = malloc(strlen(dir) + 1);
- if(uml_dir == NULL){
+ if (uml_dir == NULL) {
printf("make_uml_dir : malloc failed, errno = %d\n", errno);
exit(1);
}
@@ -286,6 +288,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
if(errno == EEXIST){
if(not_dead_yet(tmp)){
(*printer)("umid '%s' is in use\n", umid);
+ umid_owned = 0;
return(-1);
}
err = mkdir(tmp, 0777);
@@ -296,7 +299,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
return(-1);
}
- return(0);
+ umid_owned = 1;
+ return 0;
}
__uml_setup("uml_dir=", set_uml_dir,
@@ -309,7 +313,8 @@ static int __init make_umid_setup(void)
/* one function with the ordering we need ... */
make_uml_dir();
make_umid(printf);
- return create_pid_file();
+ create_pid_file();
+ return 0;
}
__uml_postsetup(make_umid_setup);
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index b03326d391c9..af11915ce0a8 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -93,14 +93,10 @@ SECTIONS
*(.bss)
*(COMMON)
}
- _end = . ;
+ _end = .;
PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
+
+ STABS_DEBUG
+
+ DWARF_DEBUG
}
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
index 954ff67cc8b3..41d17c71511c 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/kernel/user_util.c
@@ -109,18 +109,14 @@ int raw(int fd)
int err;
CATCH_EINTR(err = tcgetattr(fd, &tt));
- if (err < 0) {
- printk("tcgetattr failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(err < 0)
+ return -errno;
cfmakeraw(&tt);
CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
- if (err < 0) {
- printk("tcsetattr failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(err < 0)
+ return -errno;
/* XXX tcsetattr could have applied only some changes
* (and cfmakeraw() is a set of changes) */
@@ -132,6 +128,12 @@ void setup_machinename(char *machine_out)
struct utsname host;
uname(&host);
+#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
+ if (!strcmp(host.machine, "x86_64")) {
+ strcpy(machine_out, "i686");
+ return;
+ }
+#endif
strcpy(machine_out, host.machine);
}
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 7a1662419c0c..d15ec2af6a22 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,11 +3,11 @@
# Licensed under the GPL
#
-obj-y = aio.o elf_aux.o file.o process.o signal.o start_up.o time.o tt.o \
- tty.o user_syms.o drivers/ sys-$(SUBARCH)/
+obj-y = aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o time.o \
+ tt.o tty.o user_syms.o drivers/ sys-$(SUBARCH)/
-USER_OBJS := aio.o elf_aux.o file.o process.o signal.o start_up.o time.o tt.o \
- tty.o
+USER_OBJS := aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o \
+ time.o tt.o tty.o
elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index b04897cd995d..41cfb0944201 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
-#include <string.h>
#include <errno.h>
#include <sched.h>
#include <sys/syscall.h>
@@ -17,31 +16,18 @@
#include "user.h"
#include "mode.h"
+struct aio_thread_req {
+ enum aio_type type;
+ int io_fd;
+ unsigned long long offset;
+ char *buf;
+ int len;
+ struct aio_context *aio;
+};
+
static int aio_req_fd_r = -1;
static int aio_req_fd_w = -1;
-static int update_aio(struct aio_context *aio, int res)
-{
- if(res < 0)
- aio->len = res;
- else if((res == 0) && (aio->type == AIO_READ)){
- /* This is the EOF case - we have hit the end of the file
- * and it ends in a partial block, so we fill the end of
- * the block with zeros and claim success.
- */
- memset(aio->data, 0, aio->len);
- aio->len = 0;
- }
- else if(res > 0){
- aio->len -= res;
- aio->data += res;
- aio->offset += res;
- return aio->len;
- }
-
- return 0;
-}
-
#if defined(HAVE_AIO_ABI)
#include <linux/aio_abi.h>
@@ -80,7 +66,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
* that it now backs the mmapped area.
*/
-static int do_aio(aio_context_t ctx, struct aio_context *aio)
+static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
+ int len, unsigned long long offset, struct aio_context *aio)
{
struct iocb iocb, *iocbp = &iocb;
char c;
@@ -88,37 +75,40 @@ static int do_aio(aio_context_t ctx, struct aio_context *aio)
iocb = ((struct iocb) { .aio_data = (unsigned long) aio,
.aio_reqprio = 0,
- .aio_fildes = aio->fd,
- .aio_buf = (unsigned long) aio->data,
- .aio_nbytes = aio->len,
- .aio_offset = aio->offset,
+ .aio_fildes = fd,
+ .aio_buf = (unsigned long) buf,
+ .aio_nbytes = len,
+ .aio_offset = offset,
.aio_reserved1 = 0,
.aio_reserved2 = 0,
.aio_reserved3 = 0 });
- switch(aio->type){
+ switch(type){
case AIO_READ:
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
+ err = io_submit(ctx, 1, &iocbp);
break;
case AIO_WRITE:
iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
+ err = io_submit(ctx, 1, &iocbp);
break;
case AIO_MMAP:
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
iocb.aio_buf = (unsigned long) &c;
iocb.aio_nbytes = sizeof(c);
+ err = io_submit(ctx, 1, &iocbp);
break;
default:
- printk("Bogus op in do_aio - %d\n", aio->type);
+ printk("Bogus op in do_aio - %d\n", type);
err = -EINVAL;
- goto out;
+ break;
}
- err = io_submit(ctx, 1, &iocbp);
if(err > 0)
err = 0;
+ else
+ err = -errno;
- out:
return err;
}
@@ -127,9 +117,8 @@ static aio_context_t ctx = 0;
static int aio_thread(void *arg)
{
struct aio_thread_reply reply;
- struct aio_context *aio;
struct io_event event;
- int err, n;
+ int err, n, reply_fd;
signal(SIGWINCH, SIG_IGN);
@@ -142,21 +131,14 @@ static int aio_thread(void *arg)
"errno = %d\n", errno);
}
else {
- aio = (struct aio_context *) event.data;
- if(update_aio(aio, event.res)){
- do_aio(ctx, aio);
- continue;
- }
-
reply = ((struct aio_thread_reply)
- { .data = aio,
- .err = aio->len });
- err = os_write_file(aio->reply_fd, &reply,
- sizeof(reply));
+ { .data = (void *) (long) event.data,
+ .err = event.res });
+ reply_fd = ((struct aio_context *) reply.data)->reply_fd;
+ err = os_write_file(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
- printk("aio_thread - write failed, "
- "fd = %d, err = %d\n", aio->reply_fd,
- -err);
+ printk("aio_thread - write failed, fd = %d, "
+ "err = %d\n", aio_req_fd_r, -err);
}
}
return 0;
@@ -164,35 +146,35 @@ static int aio_thread(void *arg)
#endif
-static int do_not_aio(struct aio_context *aio)
+static int do_not_aio(struct aio_thread_req *req)
{
char c;
int err;
- switch(aio->type){
+ switch(req->type){
case AIO_READ:
- err = os_seek_file(aio->fd, aio->offset);
+ err = os_seek_file(req->io_fd, req->offset);
if(err)
goto out;
- err = os_read_file(aio->fd, aio->data, aio->len);
+ err = os_read_file(req->io_fd, req->buf, req->len);
break;
case AIO_WRITE:
- err = os_seek_file(aio->fd, aio->offset);
+ err = os_seek_file(req->io_fd, req->offset);
if(err)
goto out;
- err = os_write_file(aio->fd, aio->data, aio->len);
+ err = os_write_file(req->io_fd, req->buf, req->len);
break;
case AIO_MMAP:
- err = os_seek_file(aio->fd, aio->offset);
+ err = os_seek_file(req->io_fd, req->offset);
if(err)
goto out;
- err = os_read_file(aio->fd, &c, sizeof(c));
+ err = os_read_file(req->io_fd, &c, sizeof(c));
break;
default:
- printk("do_not_aio - bad request type : %d\n", aio->type);
+ printk("do_not_aio - bad request type : %d\n", req->type);
err = -EINVAL;
break;
}
@@ -203,14 +185,14 @@ static int do_not_aio(struct aio_context *aio)
static int not_aio_thread(void *arg)
{
- struct aio_context *aio;
+ struct aio_thread_req req;
struct aio_thread_reply reply;
int err;
signal(SIGWINCH, SIG_IGN);
while(1){
- err = os_read_file(aio_req_fd_r, &aio, sizeof(aio));
- if(err != sizeof(aio)){
+ err = os_read_file(aio_req_fd_r, &req, sizeof(req));
+ if(err != sizeof(req)){
if(err < 0)
printk("not_aio_thread - read failed, "
"fd = %d, err = %d\n", aio_req_fd_r,
@@ -221,34 +203,17 @@ static int not_aio_thread(void *arg)
}
continue;
}
- again:
- err = do_not_aio(aio);
-
- if(update_aio(aio, err))
- goto again;
-
- reply = ((struct aio_thread_reply) { .data = aio,
- .err = aio->len });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
+ err = do_not_aio(&req);
+ reply = ((struct aio_thread_reply) { .data = req.aio,
+ .err = err });
+ err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("not_aio_thread - write failed, fd = %d, "
"err = %d\n", aio_req_fd_r, -err);
}
}
-static int submit_aio_24(struct aio_context *aio)
-{
- int err;
-
- err = os_write_file(aio_req_fd_w, &aio, sizeof(aio));
- if(err == sizeof(aio))
- err = 0;
-
- return err;
-}
-
static int aio_pid = -1;
-static int (*submit_proc)(struct aio_context *aio);
static int init_aio_24(void)
{
@@ -280,68 +245,64 @@ static int init_aio_24(void)
#endif
printk("2.6 host AIO support not used - falling back to I/O "
"thread\n");
-
- submit_proc = submit_aio_24;
-
return 0;
}
#ifdef HAVE_AIO_ABI
#define DEFAULT_24_AIO 0
-static int submit_aio_26(struct aio_context *aio)
-{
- struct aio_thread_reply reply;
- int err;
-
- err = do_aio(ctx, aio);
- if(err){
- reply = ((struct aio_thread_reply) { .data = aio,
- .err = err });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
- printk("submit_aio_26 - write failed, "
- "fd = %d, err = %d\n", aio->reply_fd, -err);
- else err = 0;
- }
-
- return err;
-}
-
static int init_aio_26(void)
{
unsigned long stack;
int err;
if(io_setup(256, &ctx)){
+ err = -errno;
printk("aio_thread failed to initialize context, err = %d\n",
errno);
- return -errno;
+ return err;
}
err = run_helper_thread(aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
if(err < 0)
- return -errno;
+ return err;
aio_pid = err;
printk("Using 2.6 host AIO\n");
+ return 0;
+}
+
+static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, struct aio_context *aio)
+{
+ struct aio_thread_reply reply;
+ int err;
- submit_proc = submit_aio_26;
+ err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
+ if(err){
+ reply = ((struct aio_thread_reply) { .data = aio,
+ .err = err });
+ err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
+ if(err != sizeof(reply))
+ printk("submit_aio_26 - write failed, "
+ "fd = %d, err = %d\n", aio->reply_fd, -err);
+ else err = 0;
+ }
- return 0;
+ return err;
}
#else
#define DEFAULT_24_AIO 1
-static int submit_aio_26(struct aio_context *aio)
+static int init_aio_26(void)
{
return -ENOSYS;
}
-static int init_aio_26(void)
+static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, struct aio_context *aio)
{
- submit_proc = submit_aio_26;
return -ENOSYS;
}
#endif
@@ -408,7 +369,33 @@ static void exit_aio(void)
__uml_exitcall(exit_aio);
-int submit_aio(struct aio_context *aio)
+static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, struct aio_context *aio)
{
- return (*submit_proc)(aio);
+ struct aio_thread_req req = { .type = type,
+ .io_fd = io_fd,
+ .offset = offset,
+ .buf = buf,
+ .len = len,
+ .aio = aio,
+ };
+ int err;
+
+ err = os_write_file(aio_req_fd_w, &req, sizeof(req));
+ if(err == sizeof(req))
+ err = 0;
+
+ return err;
+}
+
+int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, int reply_fd,
+ struct aio_context *aio)
+{
+ aio->reply_fd = reply_fd;
+ if(aio_24)
+ return submit_aio_24(type, io_fd, buf, len, offset, aio);
+ else {
+ return submit_aio_26(type, io_fd, buf, len, offset, aio);
+ }
}
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 4b83c6c3f48d..4ba9b17adf13 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -75,7 +75,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov;
- int pid, n;
+ int pid, n, err;
sprintf(version_buf, "%d", UML_NET_VERSION);
@@ -105,9 +105,10 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
n = recvmsg(me, &msg, 0);
*used_out = n;
if(n < 0){
+ err = -errno;
printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
errno);
- return(-errno);
+ return err;
}
CATCH_EINTR(waitpid(pid, NULL, 0));
@@ -147,9 +148,10 @@ static int tuntap_open(void *data)
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
+ err = -errno;
printk("TUNSETIFF failed, errno = %d\n", errno);
os_close_file(pri->fd);
- return(-errno);
+ return err;
}
}
else {
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 1399520a8588..5a99dd3fbed0 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -12,9 +12,10 @@
#include "init.h"
#include "elf_user.h"
#include "mem_user.h"
-#include <kernel-offsets.h>
+#include <kern_constants.h>
-#if HOST_ELF_CLASS == ELFCLASS32
+/* Use the one from the kernel - the host may miss it, if having old headers. */
+#if UM_ELF_CLASS == UM_ELFCLASS32
typedef Elf32_auxv_t elf_auxv_t;
#else
typedef Elf64_auxv_t elf_auxv_t;
@@ -54,7 +55,8 @@ __init void scan_elf_aux( char **envp)
* a_un, so we have to use a_val, which is
* all that's left.
*/
- elf_aux_platform = (char *) auxv->a_un.a_val;
+ elf_aux_platform =
+ (char *) (long) auxv->a_un.a_val;
break;
case AT_PAGESZ:
page_size = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index fd45bb260907..f55773c819e6 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -119,15 +119,11 @@ int os_window_size(int fd, int *rows, int *cols)
int os_new_tty_pgrp(int fd, int pid)
{
- if(ioctl(fd, TIOCSCTTY, 0) < 0){
- printk("TIOCSCTTY failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(ioctl(fd, TIOCSCTTY, 0) < 0)
+ return -errno;
- if(tcsetpgrp(fd, pid) < 0){
- printk("tcsetpgrp failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(tcsetpgrp(fd, pid) < 0)
+ return -errno;
return(0);
}
@@ -146,18 +142,12 @@ int os_set_slip(int fd)
int disc, sencap;
disc = N_SLIP;
- if(ioctl(fd, TIOCSETD, &disc) < 0){
- printk("Failed to set slip line discipline - "
- "errno = %d\n", errno);
- return(-errno);
- }
+ if(ioctl(fd, TIOCSETD, &disc) < 0)
+ return -errno;
sencap = 0;
- if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
- printk("Failed to set slip encapsulation - "
- "errno = %d\n", errno);
- return(-errno);
- }
+ if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
+ return -errno;
return(0);
}
@@ -180,22 +170,15 @@ int os_sigio_async(int master, int slave)
int flags;
flags = fcntl(master, F_GETFL);
- if(flags < 0) {
- printk("fcntl F_GETFL failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(flags < 0)
+ return errno;
if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
- (fcntl(master, F_SETOWN, os_getpid()) < 0)){
- printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n",
- errno);
- return(-errno);
- }
+ (fcntl(master, F_SETOWN, os_getpid()) < 0))
+ return -errno;
- if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
- printk("fcntl F_SETFL failed, errno = %d\n", errno);
- return(-errno);
- }
+ if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
+ return -errno;
return(0);
}
@@ -255,7 +238,7 @@ int os_file_mode(char *file, struct openflags *mode_out)
int os_open_file(char *file, struct openflags flags, int mode)
{
- int fd, f = 0;
+ int fd, err, f = 0;
if(flags.r && flags.w) f = O_RDWR;
else if(flags.r) f = O_RDONLY;
@@ -272,8 +255,9 @@ int os_open_file(char *file, struct openflags flags, int mode)
return(-errno);
if(flags.cl && fcntl(fd, F_SETFD, 1)){
+ err = -errno;
os_close_file(fd);
- return(-errno);
+ return err;
}
return(fd);
@@ -383,9 +367,9 @@ int os_file_size(char *file, unsigned long long *size_out)
return(fd);
}
if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
+ err = -errno;
printk("Couldn't get the block size of \"%s\", "
"errno = %d\n", file, errno);
- err = -errno;
os_close_file(fd);
return(err);
}
@@ -473,11 +457,14 @@ int os_pipe(int *fds, int stream, int close_on_exec)
int os_set_fd_async(int fd, int owner)
{
+ int err;
+
/* XXX This should do F_GETFL first */
if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
+ err = -errno;
printk("os_set_fd_async : failed to set O_ASYNC and "
"O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
- return(-errno);
+ return err;
}
#ifdef notdef
if(fcntl(fd, F_SETFD, 1) < 0){
@@ -488,10 +475,11 @@ int os_set_fd_async(int fd, int owner)
if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
(fcntl(fd, F_SETOWN, owner) < 0)){
+ err = -errno;
printk("os_set_fd_async : Failed to fcntl F_SETOWN "
"(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
owner, errno);
- return(-errno);
+ return err;
}
return(0);
@@ -516,11 +504,9 @@ int os_set_fd_block(int fd, int blocking)
if(blocking) flags &= ~O_NONBLOCK;
else flags |= O_NONBLOCK;
- if(fcntl(fd, F_SETFL, flags) < 0){
- printk("Failed to change blocking on fd # %d, errno = %d\n",
- fd, errno);
- return(-errno);
- }
+ if(fcntl(fd, F_SETFL, flags) < 0)
+ return -errno;
+
return(0);
}
@@ -609,11 +595,8 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
int sock, err;
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (sock < 0){
- printk("create_unix_socket - socket failed, errno = %d\n",
- errno);
- return(-errno);
- }
+ if(sock < 0)
+ return -errno;
if(close_on_exec) {
err = os_set_exec_close(sock, 1);
@@ -628,11 +611,8 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
snprintf(addr.sun_path, len, "%s", file);
err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
- if (err < 0){
- printk("create_listening_socket at '%s' - bind failed, "
- "errno = %d\n", file, errno);
- return(-errno);
- }
+ if(err < 0)
+ return -errno;
return(sock);
}
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
new file mode 100644
index 000000000000..8e71edaaf80b
--- /dev/null
+++ b/arch/um/os-Linux/mem.c
@@ -0,0 +1,161 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include "kern_util.h"
+#include "user.h"
+#include "user_util.h"
+#include "mem_user.h"
+#include "init.h"
+#include "os.h"
+#include "tempfile.h"
+#include "kern_constants.h"
+
+#include <sys/param.h>
+
+static char *tempdir = NULL;
+
+static void __init find_tempdir(void)
+{
+ char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
+ int i;
+ char *dir = NULL;
+
+ if(tempdir != NULL) return; /* We've already been called */
+ for(i = 0; dirs[i]; i++){
+ dir = getenv(dirs[i]);
+ if((dir != NULL) && (*dir != '\0'))
+ break;
+ }
+ if((dir == NULL) || (*dir == '\0'))
+ dir = "/tmp";
+
+ tempdir = malloc(strlen(dir) + 2);
+ if(tempdir == NULL){
+ fprintf(stderr, "Failed to malloc tempdir, "
+ "errno = %d\n", errno);
+ return;
+ }
+ strcpy(tempdir, dir);
+ strcat(tempdir, "/");
+}
+
+/*
+ * This proc still used in tt-mode
+ * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
+ * So it isn't 'static' yet.
+ */
+int make_tempfile(const char *template, char **out_tempname, int do_unlink)
+{
+ char tempname[MAXPATHLEN];
+ int fd;
+
+ find_tempdir();
+ if (*template != '/')
+ strcpy(tempname, tempdir);
+ else
+ *tempname = 0;
+ strcat(tempname, template);
+ fd = mkstemp(tempname);
+ if(fd < 0){
+ fprintf(stderr, "open - cannot create %s: %s\n", tempname,
+ strerror(errno));
+ return -1;
+ }
+ if(do_unlink && (unlink(tempname) < 0)){
+ perror("unlink");
+ return -1;
+ }
+ if(out_tempname){
+ *out_tempname = strdup(tempname);
+ if(*out_tempname == NULL){
+ perror("strdup");
+ return -1;
+ }
+ }
+ return(fd);
+}
+
+#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
+
+/*
+ * This proc is used in start_up.c
+ * So it isn't 'static'.
+ */
+int create_tmp_file(unsigned long len)
+{
+ int fd, err;
+ char zero;
+
+ fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
+ if(fd < 0) {
+ exit(1);
+ }
+
+ err = fchmod(fd, 0777);
+ if(err < 0){
+ perror("os_mode_fd");
+ exit(1);
+ }
+
+ if (lseek64(fd, len, SEEK_SET) < 0) {
+ perror("os_seek_file");
+ exit(1);
+ }
+
+ zero = 0;
+
+ err = os_write_file(fd, &zero, 1);
+ if(err != 1){
+ errno = -err;
+ perror("os_write_file");
+ exit(1);
+ }
+
+ return(fd);
+}
+
+static int create_anon_file(unsigned long len)
+{
+ void *addr;
+ int fd;
+
+ fd = open("/dev/anon", O_RDWR);
+ if(fd < 0) {
+ perror("opening /dev/anon");
+ exit(1);
+ }
+
+ addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if(addr == MAP_FAILED){
+ perror("mapping physmem file");
+ exit(1);
+ }
+ munmap(addr, len);
+
+ return(fd);
+}
+
+extern int have_devanon;
+
+int create_mem_file(unsigned long len)
+{
+ int err, fd;
+
+ if(have_devanon)
+ fd = create_anon_file(len);
+ else fd = create_tmp_file(len);
+
+ err = os_set_exec_close(fd, 1);
+ if(err < 0){
+ errno = -err;
+ perror("exec_close");
+ }
+ return(fd);
+}
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index d32413e4b4ce..d9c52387c4a1 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -3,6 +3,7 @@
* Licensed under the GPL
*/
+#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 040cc1472bc7..b99ab414542f 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -4,18 +4,22 @@
*/
#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sched.h>
+#include <fcntl.h>
#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
#include <setjmp.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <asm/unistd.h>
#include <asm/page.h>
+#include <sys/types.h>
#include "user_util.h"
#include "kern_util.h"
#include "user.h"
@@ -25,6 +29,7 @@
#include "sysdep/sigcontext.h"
#include "irq_user.h"
#include "ptrace_user.h"
+#include "mem_user.h"
#include "time_user.h"
#include "init.h"
#include "os.h"
@@ -32,6 +37,8 @@
#include "choose-mode.h"
#include "mode.h"
#include "tempfile.h"
+#include "kern_constants.h"
+
#ifdef UML_CONFIG_MODE_SKAS
#include "skas.h"
#include "skas_ptrace.h"
@@ -136,11 +143,22 @@ static int __init skas0_cmd_param(char *str, int* add)
return 0;
}
+/* The two __uml_setup would conflict, without this stupid alias. */
+
+static int __init mode_skas0_cmd_param(char *str, int* add)
+ __attribute__((alias("skas0_cmd_param")));
+
__uml_setup("skas0", skas0_cmd_param,
"skas0\n"
" Disables SKAS3 usage, so that SKAS0 is used, unless \n"
" you specify mode=tt.\n\n");
+__uml_setup("mode=skas0", mode_skas0_cmd_param,
+ "mode=skas0\n"
+ " Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
+ " specify mode=tt. Note that this was recently added - on \n"
+ " older kernels you must use simply \"skas0\".\n\n");
+
static int force_sysemu_disabled = 0;
static int __init nosysemu_cmd_param(char *str, int* add)
@@ -276,9 +294,38 @@ static void __init check_ptrace(void)
check_sysemu();
}
+extern int create_tmp_file(unsigned long len);
+
+static void check_tmpexec(void)
+{
+ void *addr;
+ int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
+
+ addr = mmap(NULL, UM_KERN_PAGE_SIZE,
+ PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
+ printf("Checking PROT_EXEC mmap in /tmp...");
+ fflush(stdout);
+ if(addr == MAP_FAILED){
+ err = errno;
+ perror("failed");
+ if(err == EPERM)
+ printf("/tmp must be not mounted noexec\n");
+ exit(1);
+ }
+ printf("OK\n");
+ munmap(addr, UM_KERN_PAGE_SIZE);
+
+ close(fd);
+}
+
void os_early_checks(void)
{
check_ptrace();
+
+ /* Need to check this early because mmapping happens before the
+ * kernel is running.
+ */
+ check_tmpexec();
}
static int __init noprocmm_cmd_param(char *str, int* add)
@@ -357,3 +404,72 @@ int can_do_skas(void)
return(0);
}
#endif
+
+int have_devanon = 0;
+
+void check_devanon(void)
+{
+ int fd;
+
+ printk("Checking for /dev/anon on the host...");
+ fd = open("/dev/anon", O_RDWR);
+ if(fd < 0){
+ printk("Not available (open failed with errno %d)\n", errno);
+ return;
+ }
+
+ printk("OK\n");
+ have_devanon = 1;
+}
+
+int __init parse_iomem(char *str, int *add)
+{
+ struct iomem_region *new;
+ struct uml_stat buf;
+ char *file, *driver;
+ int fd, err, size;
+
+ driver = str;
+ file = strchr(str,',');
+ if(file == NULL){
+ printf("parse_iomem : failed to parse iomem\n");
+ goto out;
+ }
+ *file = '\0';
+ file++;
+ fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
+ if(fd < 0){
+ os_print_error(fd, "parse_iomem - Couldn't open io file");
+ goto out;
+ }
+
+ err = os_stat_fd(fd, &buf);
+ if(err < 0){
+ os_print_error(err, "parse_iomem - cannot stat_fd file");
+ goto out_close;
+ }
+
+ new = malloc(sizeof(*new));
+ if(new == NULL){
+ perror("Couldn't allocate iomem_region struct");
+ goto out_close;
+ }
+
+ size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
+
+ *new = ((struct iomem_region) { .next = iomem_regions,
+ .driver = driver,
+ .fd = fd,
+ .size = size,
+ .phys = 0,
+ .virt = 0 });
+ iomem_regions = new;
+ iomem_size += new->size + UM_KERN_PAGE_SIZE;
+
+ return(0);
+ out_close:
+ os_close_file(fd);
+ out:
+ return(1);
+}
+
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 3125d320722c..aee4812333c6 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
+#include <setjmp.h>
#include "sysdep/ptrace_user.h"
#include "sysdep/ptrace.h"
#include "uml-config.h"
@@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
+{
+ struct __jmp_buf_tag *jmpbuf = buffer;
+
+ UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]);
+ UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]);
+ UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]);
+}
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 44438d15c3d6..4b638dfb52b0 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
+#include <setjmp.h>
#include "ptrace_user.h"
#include "uml-config.h"
#include "skas_ptregs.h"
@@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
+{
+ struct __jmp_buf_tag *jmpbuf = buffer;
+
+ UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]);
+ UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]);
+ UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]);
+}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 5b047ab8416a..a6db8877931a 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -36,6 +36,20 @@
#include "mode.h"
#include "tempfile.h"
+int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
+ int must_succeed)
+{
+ int err;
+
+ err = os_protect_memory((void *) addr, len, r, w, x);
+ if(err < 0){
+ if(must_succeed)
+ panic("protect failed, err = %d", -err);
+ else return(err);
+ }
+ return(0);
+}
+
/*
*-------------------------
* only for tt mode (will be deleted in future...)
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
deleted file mode 100644
index 9778aed0c314..000000000000
--- a/arch/um/os-Linux/util/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-hostprogs-y := mk_user_constants
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c
deleted file mode 100644
index 4838f30eecf0..000000000000
--- a/arch/um/os-Linux/util/mk_user_constants.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_user_constants\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_USER_CONSTANTS_H\n");
- printf("#define __UM_USER_CONSTANTS_H\n");
- printf("\n");
- /* I'd like to use FRAME_SIZE from ptrace.h here, but that's wrong on
- * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on
- * both x86_64 and i386.
- */
- printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
-
- printf("\n");
- printf("#endif\n");
-
- return(0);
-}
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 17f305b6bade..651d9d88b656 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -7,8 +7,13 @@ USER_SINGLE_OBJS := \
USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
- $(CFLAGS_$(notdir $@))
+$(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \
+ 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/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 4ca2a229da49..6dfeb70f6957 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -18,6 +18,4 @@ module.c-dir = kernel
$(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS))
-subdir- := util
-
include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
index a1070af2bcd8..35db85057506 100644
--- a/arch/um/sys-i386/kernel-offsets.c
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -18,9 +18,9 @@
void foo(void)
{
- OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
+ OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
#ifdef CONFIG_MODE_TT
- OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+ OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
#endif
#include <common-offsets.h>
}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index bd3c34aa52e5..36b5c2c13289 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -83,6 +83,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
goto out;
}
p = buf;
+ break;
default:
res = -ENOSYS;
goto out;
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c
index e3706d15c4f5..d5244f070539 100644
--- a/arch/um/sys-i386/sysrq.c
+++ b/arch/um/sys-i386/sysrq.c
@@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack)
task = current;
if (task != current) {
- //ebp = (unsigned long) KSTK_EBP(task);
- /* Which one? No actual difference - just coding style.*/
- ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
+ ebp = (unsigned long) KSTK_EBP(task);
} else {
asm ("movl %%ebp, %0" : "=r" (ebp) : );
}
@@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack)
((unsigned long)stack & (~(THREAD_SIZE - 1)));
print_context_stack(context, stack, ebp);
- /*while (((long) stack & (THREAD_SIZE-1)) != 0) {
- addr = *stack;
- if (__kernel_text_address(addr)) {
- printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
- print_symbol(" %s", addr);
- printk("\n");
- }
- stack++;
- }*/
printk("\n");
}
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 3ceaabceb3d7..26b68675053d 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -7,47 +7,48 @@
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define DEFINE_LONGS(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+
#define OFFSET(sym, str, mem) \
DEFINE(sym, offsetof(struct str, mem));
void foo(void)
{
- OFFSET(SC_IP, sigcontext, eip);
- OFFSET(SC_SP, sigcontext, esp);
- OFFSET(SC_FS, sigcontext, fs);
- OFFSET(SC_GS, sigcontext, gs);
- OFFSET(SC_DS, sigcontext, ds);
- OFFSET(SC_ES, sigcontext, es);
- OFFSET(SC_SS, sigcontext, ss);
- OFFSET(SC_CS, sigcontext, cs);
- OFFSET(SC_EFLAGS, sigcontext, eflags);
- OFFSET(SC_EAX, sigcontext, eax);
- OFFSET(SC_EBX, sigcontext, ebx);
- OFFSET(SC_ECX, sigcontext, ecx);
- OFFSET(SC_EDX, sigcontext, edx);
- OFFSET(SC_EDI, sigcontext, edi);
- OFFSET(SC_ESI, sigcontext, esi);
- OFFSET(SC_EBP, sigcontext, ebp);
- OFFSET(SC_TRAPNO, sigcontext, trapno);
- OFFSET(SC_ERR, sigcontext, err);
- OFFSET(SC_CR2, sigcontext, cr2);
- OFFSET(SC_FPSTATE, sigcontext, fpstate);
- OFFSET(SC_SIGMASK, sigcontext, oldmask);
- OFFSET(SC_FP_CW, _fpstate, cw);
- OFFSET(SC_FP_SW, _fpstate, sw);
- OFFSET(SC_FP_TAG, _fpstate, tag);
- OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
- OFFSET(SC_FP_CSSEL, _fpstate, cssel);
- OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
- OFFSET(SC_FP_DATASEL, _fpstate, datasel);
- OFFSET(SC_FP_ST, _fpstate, _st);
- OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
+ OFFSET(HOST_SC_IP, sigcontext, eip);
+ OFFSET(HOST_SC_SP, sigcontext, esp);
+ OFFSET(HOST_SC_FS, sigcontext, fs);
+ OFFSET(HOST_SC_GS, sigcontext, gs);
+ OFFSET(HOST_SC_DS, sigcontext, ds);
+ OFFSET(HOST_SC_ES, sigcontext, es);
+ OFFSET(HOST_SC_SS, sigcontext, ss);
+ OFFSET(HOST_SC_CS, sigcontext, cs);
+ OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
+ OFFSET(HOST_SC_EAX, sigcontext, eax);
+ OFFSET(HOST_SC_EBX, sigcontext, ebx);
+ OFFSET(HOST_SC_ECX, sigcontext, ecx);
+ OFFSET(HOST_SC_EDX, sigcontext, edx);
+ OFFSET(HOST_SC_EDI, sigcontext, edi);
+ OFFSET(HOST_SC_ESI, sigcontext, esi);
+ OFFSET(HOST_SC_EBP, sigcontext, ebp);
+ OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+ OFFSET(HOST_SC_ERR, sigcontext, err);
+ OFFSET(HOST_SC_CR2, sigcontext, cr2);
+ OFFSET(HOST_SC_FPSTATE, sigcontext, fpstate);
+ OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
+ OFFSET(HOST_SC_FP_CW, _fpstate, cw);
+ OFFSET(HOST_SC_FP_SW, _fpstate, sw);
+ OFFSET(HOST_SC_FP_TAG, _fpstate, tag);
+ OFFSET(HOST_SC_FP_IPOFF, _fpstate, ipoff);
+ OFFSET(HOST_SC_FP_CSSEL, _fpstate, cssel);
+ OFFSET(HOST_SC_FP_DATAOFF, _fpstate, dataoff);
+ OFFSET(HOST_SC_FP_DATASEL, _fpstate, datasel);
+ OFFSET(HOST_SC_FP_ST, _fpstate, _st);
+ OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
- DEFINE(HOST_FP_SIZE,
- sizeof(struct user_i387_struct) / sizeof(unsigned long));
- DEFINE(HOST_XFP_SIZE,
- sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+ DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
+ DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));
DEFINE(HOST_IP, EIP);
DEFINE(HOST_SP, UESP);
@@ -65,5 +66,5 @@ void foo(void)
DEFINE(HOST_FS, FS);
DEFINE(HOST_ES, ES);
DEFINE(HOST_GS, GS);
- DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+ DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
}
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
deleted file mode 100644
index bf61afd0b045..000000000000
--- a/arch/um/sys-i386/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_sc mk_thread
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
deleted file mode 100644
index 04c0d73433aa..000000000000
--- a/arch/um/sys-i386/util/mk_sc.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SC_OFFSET(name, field) \
- printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
- name)
-
-#define SC_FP_OFFSET(name, field) \
- printf("#define " #name \
- "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- name)
-
-#define SC_FP_OFFSET_PTR(name, field, type) \
- printf("#define " #name \
- "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- name)
-
-int main(int argc, char **argv)
-{
- SC_OFFSET(SC_IP, eip);
- SC_OFFSET(SC_SP, esp);
- SC_OFFSET(SC_FS, fs);
- SC_OFFSET(SC_GS, gs);
- SC_OFFSET(SC_DS, ds);
- SC_OFFSET(SC_ES, es);
- SC_OFFSET(SC_SS, ss);
- SC_OFFSET(SC_CS, cs);
- SC_OFFSET(SC_EFLAGS, eflags);
- SC_OFFSET(SC_EAX, eax);
- SC_OFFSET(SC_EBX, ebx);
- SC_OFFSET(SC_ECX, ecx);
- SC_OFFSET(SC_EDX, edx);
- SC_OFFSET(SC_EDI, edi);
- SC_OFFSET(SC_ESI, esi);
- SC_OFFSET(SC_EBP, ebp);
- SC_OFFSET(SC_TRAPNO, trapno);
- SC_OFFSET(SC_ERR, err);
- SC_OFFSET(SC_CR2, cr2);
- SC_OFFSET(SC_FPSTATE, fpstate);
- SC_OFFSET(SC_SIGMASK, oldmask);
- SC_FP_OFFSET(SC_FP_CW, cw);
- SC_FP_OFFSET(SC_FP_SW, sw);
- SC_FP_OFFSET(SC_FP_TAG, tag);
- SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
- SC_FP_OFFSET(SC_FP_CSSEL, cssel);
- SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
- SC_FP_OFFSET(SC_FP_DATASEL, datasel);
- SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
- SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
- return(0);
-}
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c
deleted file mode 100644
index 7470d0dda67e..000000000000
--- a/arch/um/sys-i386/util/mk_thread.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_thread\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_THREAD_H\n");
- printf("#define __UM_THREAD_H\n");
- printf("\n");
- printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
- "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
-#ifdef TASK_EXTERN_PID
- printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
- TASK_EXTERN_PID);
-#endif
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index f0ab574d1e95..06c3633457a2 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -29,6 +29,4 @@ module.c-dir = kernel
$(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS))
-subdir- := util
-
include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c
index 998541eade41..bfcb104b846e 100644
--- a/arch/um/sys-x86_64/kernel-offsets.c
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -19,7 +19,7 @@
void foo(void)
{
#ifdef CONFIG_MODE_TT
- OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+ OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
#endif
#include <common-offsets.h>
}
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 65a131b362b6..d1e53bdf2e85 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -10,6 +10,22 @@
#include "uml-config.h"
#include "sysdep/sigcontext.h"
#include "sysdep/faultinfo.h"
+#include <stddef.h>
+
+/* Copied from sys-x86_64/signal.c - Can't find an equivalent definition
+ * in the libc headers anywhere.
+ */
+struct rt_sigframe
+{
+ char *pretcode;
+ struct ucontext uc;
+ struct siginfo info;
+};
+
+/* Copied here from <linux/kernel.h> - we're userspace. */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
void __attribute__ ((__section__ (".__syscall_stub")))
stub_segv_handler(int sig)
@@ -17,16 +33,19 @@ stub_segv_handler(int sig)
struct ucontext *uc;
__asm__("movq %%rdx, %0" : "=g" (uc) :);
- GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
- &uc->uc_mcontext);
+ GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
+ &uc->uc_mcontext);
- __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
+ __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
__asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
- "syscall": : "g" (__NR_kill), "g" (SIGUSR1));
- /* Two popqs to restore the stack to the state just before entering
- * the handler, one pops the return address, the other pops the frame
- * pointer.
+ "syscall": : "g" (__NR_kill), "g" (SIGUSR1) :
+ "%rdi", "%rax", "%rsi");
+ /* sys_sigreturn expects that the stack pointer will be 8 bytes into
+ * the signal frame. So, we use the ucontext pointer, which we know
+ * already, to get the signal frame pointer, and add 8 to that.
*/
- __asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g"
- (__NR_rt_sigreturn));
+ __asm__("movq %0, %%rsp": :
+ "g" ((unsigned long) container_of(uc, struct rt_sigframe,
+ uc) + 8));
+ __asm__("movq %0, %%rax ; syscall" : : "g" (__NR_rt_sigreturn));
}
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 513d17ceafd4..5a585bfbb8c2 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -16,71 +16,76 @@ typedef __u32 u32;
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define DEFINE_LONGS(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+
#define OFFSET(sym, str, mem) \
DEFINE(sym, offsetof(struct str, mem));
void foo(void)
{
- OFFSET(SC_RBX, sigcontext, rbx);
- OFFSET(SC_RCX, sigcontext, rcx);
- OFFSET(SC_RDX, sigcontext, rdx);
- OFFSET(SC_RSI, sigcontext, rsi);
- OFFSET(SC_RDI, sigcontext, rdi);
- OFFSET(SC_RBP, sigcontext, rbp);
- OFFSET(SC_RAX, sigcontext, rax);
- OFFSET(SC_R8, sigcontext, r8);
- OFFSET(SC_R9, sigcontext, r9);
- OFFSET(SC_R10, sigcontext, r10);
- OFFSET(SC_R11, sigcontext, r11);
- OFFSET(SC_R12, sigcontext, r12);
- OFFSET(SC_R13, sigcontext, r13);
- OFFSET(SC_R14, sigcontext, r14);
- OFFSET(SC_R15, sigcontext, r15);
- OFFSET(SC_IP, sigcontext, rip);
- OFFSET(SC_SP, sigcontext, rsp);
- OFFSET(SC_CR2, sigcontext, cr2);
- OFFSET(SC_ERR, sigcontext, err);
- OFFSET(SC_TRAPNO, sigcontext, trapno);
- OFFSET(SC_CS, sigcontext, cs);
- OFFSET(SC_FS, sigcontext, fs);
- OFFSET(SC_GS, sigcontext, gs);
- OFFSET(SC_EFLAGS, sigcontext, eflags);
- OFFSET(SC_SIGMASK, sigcontext, oldmask);
+ OFFSET(HOST_SC_RBX, sigcontext, rbx);
+ OFFSET(HOST_SC_RCX, sigcontext, rcx);
+ OFFSET(HOST_SC_RDX, sigcontext, rdx);
+ OFFSET(HOST_SC_RSI, sigcontext, rsi);
+ OFFSET(HOST_SC_RDI, sigcontext, rdi);
+ OFFSET(HOST_SC_RBP, sigcontext, rbp);
+ OFFSET(HOST_SC_RAX, sigcontext, rax);
+ OFFSET(HOST_SC_R8, sigcontext, r8);
+ OFFSET(HOST_SC_R9, sigcontext, r9);
+ OFFSET(HOST_SC_R10, sigcontext, r10);
+ OFFSET(HOST_SC_R11, sigcontext, r11);
+ OFFSET(HOST_SC_R12, sigcontext, r12);
+ OFFSET(HOST_SC_R13, sigcontext, r13);
+ OFFSET(HOST_SC_R14, sigcontext, r14);
+ OFFSET(HOST_SC_R15, sigcontext, r15);
+ OFFSET(HOST_SC_IP, sigcontext, rip);
+ OFFSET(HOST_SC_SP, sigcontext, rsp);
+ OFFSET(HOST_SC_CR2, sigcontext, cr2);
+ OFFSET(HOST_SC_ERR, sigcontext, err);
+ OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+ OFFSET(HOST_SC_CS, sigcontext, cs);
+ OFFSET(HOST_SC_FS, sigcontext, fs);
+ OFFSET(HOST_SC_GS, sigcontext, gs);
+ OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
+ OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
#if 0
- OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
- OFFSET(SC_DS, sigcontext, ds);
- OFFSET(SC_ES, sigcontext, es);
- OFFSET(SC_SS, sigcontext, ss);
+ OFFSET(HOST_SC_ORIG_RAX, sigcontext, orig_rax);
+ OFFSET(HOST_SC_DS, sigcontext, ds);
+ OFFSET(HOST_SC_ES, sigcontext, es);
+ OFFSET(HOST_SC_SS, sigcontext, ss);
#endif
- DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
- DEFINE(HOST_RBX, RBX);
- DEFINE(HOST_RCX, RCX);
- DEFINE(HOST_RDI, RDI);
- DEFINE(HOST_RSI, RSI);
- DEFINE(HOST_RDX, RDX);
- DEFINE(HOST_RBP, RBP);
- DEFINE(HOST_RAX, RAX);
- DEFINE(HOST_R8, R8);
- DEFINE(HOST_R9, R9);
- DEFINE(HOST_R10, R10);
- DEFINE(HOST_R11, R11);
- DEFINE(HOST_R12, R12);
- DEFINE(HOST_R13, R13);
- DEFINE(HOST_R14, R14);
- DEFINE(HOST_R15, R15);
- DEFINE(HOST_ORIG_RAX, ORIG_RAX);
- DEFINE(HOST_CS, CS);
- DEFINE(HOST_SS, SS);
- DEFINE(HOST_EFLAGS, EFLAGS);
+ DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
+ DEFINE(HOST_FP_SIZE, 0);
+ DEFINE(HOST_XFP_SIZE, 0);
+ DEFINE_LONGS(HOST_RBX, RBX);
+ DEFINE_LONGS(HOST_RCX, RCX);
+ DEFINE_LONGS(HOST_RDI, RDI);
+ DEFINE_LONGS(HOST_RSI, RSI);
+ DEFINE_LONGS(HOST_RDX, RDX);
+ DEFINE_LONGS(HOST_RBP, RBP);
+ DEFINE_LONGS(HOST_RAX, RAX);
+ DEFINE_LONGS(HOST_R8, R8);
+ DEFINE_LONGS(HOST_R9, R9);
+ DEFINE_LONGS(HOST_R10, R10);
+ DEFINE_LONGS(HOST_R11, R11);
+ DEFINE_LONGS(HOST_R12, R12);
+ DEFINE_LONGS(HOST_R13, R13);
+ DEFINE_LONGS(HOST_R14, R14);
+ DEFINE_LONGS(HOST_R15, R15);
+ DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX);
+ DEFINE_LONGS(HOST_CS, CS);
+ DEFINE_LONGS(HOST_SS, SS);
+ DEFINE_LONGS(HOST_EFLAGS, EFLAGS);
#if 0
- DEFINE(HOST_FS, FS);
- DEFINE(HOST_GS, GS);
- DEFINE(HOST_DS, DS);
- DEFINE(HOST_ES, ES);
+ DEFINE_LONGS(HOST_FS, FS);
+ DEFINE_LONGS(HOST_GS, GS);
+ DEFINE_LONGS(HOST_DS, DS);
+ DEFINE_LONGS(HOST_ES, ES);
#endif
- DEFINE(HOST_IP, RIP);
- DEFINE(HOST_SP, RSP);
- DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+ DEFINE_LONGS(HOST_IP, RIP);
+ DEFINE_LONGS(HOST_SP, RSP);
+ DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
}
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
deleted file mode 100644
index 75b052cfc206..000000000000
--- a/arch/um/sys-x86_64/util/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2003 - 2004 Pathscale, Inc
-# Released under the GPL
-
-hostprogs-y := mk_sc mk_thread
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
deleted file mode 100644
index 7619bc377c1f..000000000000
--- a/arch/um/sys-x86_64/util/mk_sc.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2003 - 2004 PathScale, Inc
- * Released under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SC_OFFSET(name) \
- printf("#define " #name \
- "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
- name)
-
-int main(int argc, char **argv)
-{
- SC_OFFSET(SC_RBX);
- SC_OFFSET(SC_RCX);
- SC_OFFSET(SC_RDX);
- SC_OFFSET(SC_RSI);
- SC_OFFSET(SC_RDI);
- SC_OFFSET(SC_RBP);
- SC_OFFSET(SC_RAX);
- SC_OFFSET(SC_R8);
- SC_OFFSET(SC_R9);
- SC_OFFSET(SC_R10);
- SC_OFFSET(SC_R11);
- SC_OFFSET(SC_R12);
- SC_OFFSET(SC_R13);
- SC_OFFSET(SC_R14);
- SC_OFFSET(SC_R15);
- SC_OFFSET(SC_IP);
- SC_OFFSET(SC_SP);
- SC_OFFSET(SC_CR2);
- SC_OFFSET(SC_ERR);
- SC_OFFSET(SC_TRAPNO);
- SC_OFFSET(SC_CS);
- SC_OFFSET(SC_FS);
- SC_OFFSET(SC_GS);
- SC_OFFSET(SC_EFLAGS);
- SC_OFFSET(SC_SIGMASK);
-#if 0
- SC_OFFSET(SC_ORIG_RAX);
- SC_OFFSET(SC_DS);
- SC_OFFSET(SC_ES);
- SC_OFFSET(SC_SS);
-#endif
- return(0);
-}
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c
deleted file mode 100644
index 15517396e9cf..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_thread\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_THREAD_H\n");
- printf("#define __UM_THREAD_H\n");
- printf("\n");
-#ifdef TASK_EXTERN_PID
- printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
- TASK_EXTERN_PID);
-#endif
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
deleted file mode 100644
index 4c7551c28033..000000000000
--- a/arch/um/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_task mk_constants
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
deleted file mode 100644
index ab217becc36a..000000000000
--- a/arch/um/util/mk_constants.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
-#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_constants\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_CONSTANTS_H\n");
- printf("#define __UM_CONSTANTS_H\n");
- printf("\n");
-
- SHOW_INT(UM_KERN_PAGE_SIZE);
-
- SHOW_STR(UM_KERN_EMERG);
- SHOW_STR(UM_KERN_ALERT);
- SHOW_STR(UM_KERN_CRIT);
- SHOW_STR(UM_KERN_ERR);
- SHOW_STR(UM_KERN_WARNING);
- SHOW_STR(UM_KERN_NOTICE);
- SHOW_STR(UM_KERN_INFO);
- SHOW_STR(UM_KERN_DEBUG);
-
- SHOW_INT(UM_NSEC_PER_SEC);
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/um/util/mk_task.c b/arch/um/util/mk_task.c
deleted file mode 100644
index 36c9606505e2..000000000000
--- a/arch/um/util/mk_task.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-void print_ptr(char *name, char *type, int offset)
-{
- printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
- offset);
-}
-
-void print(char *name, char *type, int offset)
-{
- printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
- offset);
-}
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_task\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __TASK_H\n");
- printf("#define __TASK_H\n");
- printf("\n");
- print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
- print("TASK_PID", "int", TASK_PID);
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/v850/Makefile b/arch/v850/Makefile
index bf38ca0ad781..8be9aacb20a7 100644
--- a/arch/v850/Makefile
+++ b/arch/v850/Makefile
@@ -51,16 +51,4 @@ root_fs_image_force: $(ROOT_FS_IMAGE)
$(OBJCOPY) $(OBJCOPY_FLAGS_BLOB) --rename-section .data=.root,alloc,load,readonly,data,contents $< root_fs_image.o
endif
-
-prepare: include/asm-$(ARCH)/asm-consts.h
-
-# Generate constants from C code for use by asm files
-arch/$(ARCH)/kernel/asm-consts.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/asm-consts.h: arch/$(ARCH)/kernel/asm-consts.s
- $(call filechk,gen-asm-offsets)
-
-CLEAN_FILES += include/asm-$(ARCH)/asm-consts.h \
- arch/$(ARCH)/kernel/asm-consts.s \
- root_fs_image.o
+CLEAN_FILES += root_fs_image.o
diff --git a/arch/v850/kernel/asm-consts.c b/arch/v850/kernel/asm-offsets.c
index 24f291369070..24f291369070 100644
--- a/arch/v850/kernel/asm-consts.c
+++ b/arch/v850/kernel/asm-offsets.c
diff --git a/arch/v850/kernel/entry.S b/arch/v850/kernel/entry.S
index 895e27b1d839..d991e4547dbb 100644
--- a/arch/v850/kernel/entry.S
+++ b/arch/v850/kernel/entry.S
@@ -22,7 +22,7 @@
#include <asm/irq.h>
#include <asm/errno.h>
-#include <asm/asm-consts.h>
+#include <asm/asm-offsets.h>
/* Make a slightly more convenient alias for C_SYMBOL_NAME. */
diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c
index 336cbf21dc8f..9e85969ba976 100644
--- a/arch/v850/kernel/irq.c
+++ b/arch/v850/kernel/irq.c
@@ -67,13 +67,13 @@ static void ack_none(unsigned int irq)
#define end_none enable_none
struct hw_interrupt_type no_irq_type = {
- "none",
- startup_none,
- shutdown_none,
- enable_none,
- disable_none,
- ack_none,
- end_none
+ .typename = "none",
+ .startup = startup_none,
+ .shutdown = shutdown_none,
+ .enable = enable_none,
+ .disable = disable_none,
+ .ack = ack_none,
+ .end = end_none
};
volatile unsigned long irq_err_count, spurious_count;
diff --git a/arch/v850/kernel/setup.c b/arch/v850/kernel/setup.c
index abd48409dcca..62bdb8d29fc0 100644
--- a/arch/v850/kernel/setup.c
+++ b/arch/v850/kernel/setup.c
@@ -138,13 +138,13 @@ static void nmi_end (unsigned irq)
}
static struct hw_interrupt_type nmi_irq_type = {
- "NMI",
- irq_zero, /* startup */
- irq_nop, /* shutdown */
- irq_nop, /* enable */
- irq_nop, /* disable */
- irq_nop, /* ack */
- nmi_end, /* end */
+ .typename = "NMI",
+ .startup = irq_zero, /* startup */
+ .shutdown = irq_nop, /* shutdown */
+ .enable = irq_nop, /* enable */
+ .disable = irq_nop, /* disable */
+ .ack = irq_nop, /* ack */
+ .end = nmi_end, /* end */
};
void __init init_IRQ (void)
diff --git a/arch/v850/kernel/sim.c b/arch/v850/kernel/sim.c
index e2cc5580fa2a..17049aaa8f11 100644
--- a/arch/v850/kernel/sim.c
+++ b/arch/v850/kernel/sim.c
@@ -73,13 +73,13 @@ static void irq_nop (unsigned irq) { }
static unsigned irq_zero (unsigned irq) { return 0; }
static struct hw_interrupt_type sim_irq_type = {
- "IRQ",
- irq_zero, /* startup */
- irq_nop, /* shutdown */
- irq_nop, /* enable */
- irq_nop, /* disable */
- irq_nop, /* ack */
- irq_nop, /* end */
+ .typename = "IRQ",
+ .startup = irq_zero, /* startup */
+ .shutdown = irq_nop, /* shutdown */
+ .enable = irq_nop, /* enable */
+ .disable = irq_nop, /* disable */
+ .ack = irq_nop, /* ack */
+ .end = irq_nop, /* end */
};
void __init mach_init_irqs (void)
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 8f868b67ef0f..21afa69a086d 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -152,7 +152,6 @@ config X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
-# disable it for opteron optimized builds because it pulls in ACPI_BOOT
config X86_HT
bool
depends on SMP && !MK8
@@ -278,11 +277,6 @@ source "mm/Kconfig"
config HAVE_ARCH_EARLY_PFN_TO_NID
def_bool y
-config HAVE_DEC_LOCK
- bool
- depends on SMP
- default y
-
config NR_CPUS
int "Maximum number of CPUs (2-256)"
range 2 256
@@ -314,7 +308,7 @@ config HPET_TIMER
present. The HPET provides a stable time base on SMP
systems, unlike the TSC, but it is more expensive to access,
as it is off-chip. You can find the HPET spec at
- <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
+ <http://www.intel.com/hardwaredesign/hpetspec.htm>.
config X86_PM_TIMER
bool "PM timer"
@@ -474,7 +468,6 @@ config PCI_DIRECT
config PCI_MMCONFIG
bool "Support mmconfig PCI config space access"
depends on PCI && ACPI
- select ACPI_BOOT
config UNORDERED_IO
bool "Unordered IO mapping access"
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 4c6ed96d5f7c..a9cd42e61828 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -86,16 +86,6 @@ install fdimage fdimage144 fdimage288: vmlinux
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-prepare: include/asm-$(ARCH)/offset.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/config/MARKER
-
-include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
-CLEAN_FILES += include/asm-$(ARCH)/offset.h
-
define archhelp
echo '* bzImage - Compressed kernel image (arch/$(ARCH)/boot/bzImage)'
echo ' install - Install kernel using'
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
index f4399c701b77..18c6e915d69b 100644
--- a/arch/x86_64/boot/Makefile
+++ b/arch/x86_64/boot/Makefile
@@ -46,7 +46,7 @@ cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
$(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
- @echo 'Kernel: $@ is ready'
+ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c
index b38d5b8b5fb8..0e10fd84c7cc 100644
--- a/arch/x86_64/boot/compressed/misc.c
+++ b/arch/x86_64/boot/compressed/misc.c
@@ -83,7 +83,7 @@ static unsigned char *real_mode; /* Pointer to real-mode data */
#endif
#define SCREEN_INFO (*(struct screen_info *)(real_mode+0))
-extern char input_data[];
+extern unsigned char input_data[];
extern int input_len;
static long bytes_out = 0;
@@ -288,7 +288,7 @@ void setup_normal_output_buffer(void)
#else
if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
#endif
- output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */
+ output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */
free_mem_end_ptr = (long)real_mode;
}
@@ -305,7 +305,7 @@ void setup_output_buffer_if_we_run_high(struct moveparams *mv)
#else
if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
#endif
- mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+ mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START;
low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff;
low_buffer_size = low_buffer_end - LOW_BUFFER_START;
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index b97a61e1c71c..f8db7e500fbf 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,11 +1,12 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6-git3
-# Fri Aug 12 16:40:34 2005
+# Linux kernel version: 2.6.13-git11
+# Mon Sep 12 16:16:16 2005
#
CONFIG_X86_64=y
CONFIG_64BIT=y
CONFIG_X86=y
+CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_MMU=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
@@ -13,6 +14,7 @@ CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
#
# Code maturity level options
@@ -26,6 +28,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -37,6 +40,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
@@ -102,6 +106,7 @@ CONFIG_DISCONTIGMEM_MANUAL=y
CONFIG_DISCONTIGMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_NR_CPUS=32
@@ -122,6 +127,7 @@ CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ISA_DMA_API=y
+CONFIG_GENERIC_PENDING_IRQ=y
#
# Power management options
@@ -135,8 +141,6 @@ CONFIG_PM_STD_PARTITION=""
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
@@ -151,10 +155,8 @@ CONFIG_ACPI_NUMA=y
CONFIG_ACPI_TOSHIBA=y
CONFIG_ACPI_BLACKLIST_YEAR=2001
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_ACPI_CONTAINER is not set
@@ -198,7 +200,6 @@ CONFIG_UNORDERED_IO=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_PCI_MSI=y
# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -238,7 +239,10 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
@@ -248,8 +252,8 @@ CONFIG_IP_FIB_HASH=y
# 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
CONFIG_IPV6=y
@@ -262,6 +266,11 @@ CONFIG_IPV6=y
# CONFIG_NETFILTER is not set
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -284,9 +293,11 @@ CONFIG_IPV6=y
# 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
@@ -333,7 +344,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_LBD=y
# CONFIG_CDROM_PKTCDVD is not set
@@ -413,6 +423,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
@@ -436,7 +447,7 @@ CONFIG_BLK_DEV_SD=y
#
# SCSI Transport Attributes
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
@@ -462,6 +473,7 @@ CONFIG_SCSI_SATA=y
# CONFIG_SCSI_SATA_AHCI is not set
# CONFIG_SCSI_SATA_SVW is not set
CONFIG_SCSI_ATA_PIIX=y
+# CONFIG_SCSI_SATA_MV is not set
# CONFIG_SCSI_SATA_NV is not set
# CONFIG_SCSI_SATA_PROMISE is not set
# CONFIG_SCSI_SATA_QSTOR is not set
@@ -541,6 +553,11 @@ CONFIG_TUN=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -590,6 +607,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -599,6 +617,7 @@ CONFIG_TIGON3=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
CONFIG_S2IO=m
# CONFIG_S2IO_NAPI is not set
@@ -753,7 +772,6 @@ CONFIG_MAX_RAW_DEVS=256
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
@@ -764,6 +782,7 @@ CONFIG_MAX_RAW_DEVS=256
# Hardware Monitoring support
#
CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -772,6 +791,10 @@ CONFIG_HWMON=y
# CONFIG_IBM_ASM is not set
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -862,9 +885,8 @@ CONFIG_USB_UHCI_HCD=y
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=y
@@ -881,6 +903,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
#
# USB Input Devices
@@ -897,6 +920,7 @@ CONFIG_USB_HIDINPUT=y
# 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
@@ -980,6 +1004,8 @@ CONFIG_USB_MON=y
# Firmware Drivers
#
# CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+CONFIG_DCDBAS=m
#
# File systems
@@ -1004,10 +1030,6 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
# CONFIG_REISERFS_FS_SECURITY is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1016,6 +1038,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1041,12 +1064,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1078,6 +1100,7 @@ CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
@@ -1090,6 +1113,7 @@ CONFIG_SUNRPC=y
# 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
@@ -1154,6 +1178,7 @@ CONFIG_OPROFILE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=18
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1161,6 +1186,7 @@ CONFIG_LOG_BUF_SHIFT=18
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
+# CONFIG_FRAME_POINTER is not set
CONFIG_INIT_DEBUG=y
# CONFIG_IOMMU_DEBUG is not set
CONFIG_KPROBES=y
@@ -1184,5 +1210,6 @@ CONFIG_KPROBES=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index c8131f342cfc..d9161e395978 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -353,11 +353,6 @@ int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int exec
mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!mpnt)
return -ENOMEM;
-
- if (security_vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) {
- kmem_cache_free(vm_area_cachep, mpnt);
- return -ENOMEM;
- }
memset(mpnt, 0, sizeof(*mpnt));
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index d259f8a6f811..419758f19ca4 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -24,17 +24,26 @@
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/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 66e2821533db..0903cc1faef2 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -425,7 +425,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
rsp = (unsigned long) ka->sa.sa_restorer;
}
- return (void __user *)((rsp - frame_size) & -8UL);
+ rsp -= frame_size;
+ /* Align the stack pointer according to the i386 ABI,
+ * i.e. so that on function entry ((sp + 4) & 15) == 0. */
+ rsp = ((rsp + 4) & -16ul) - 4;
+ return (void __user *) rsp;
}
int ia32_setup_frame(int sig, struct k_sigaction *ka,
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index f174083d5567..e0eb0c712fe9 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -6,7 +6,7 @@
#include <asm/dwarf2.h>
#include <asm/calling.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/current.h>
#include <asm/errno.h>
#include <asm/ia32_unistd.h>
@@ -55,20 +55,34 @@
* with the int 0x80 path.
*/
ENTRY(ia32_sysenter_target)
- CFI_STARTPROC
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,0
+ CFI_REGISTER rsp,rbp
swapgs
movq %gs:pda_kernelstack, %rsp
addq $(PDA_STACKOFFSET),%rsp
sti
movl %ebp,%ebp /* zero extension */
pushq $__USER32_DS
+ CFI_ADJUST_CFA_OFFSET 8
+ /*CFI_REL_OFFSET ss,0*/
pushq %rbp
+ CFI_ADJUST_CFA_OFFSET 8
+ CFI_REL_OFFSET rsp,0
pushfq
+ CFI_ADJUST_CFA_OFFSET 8
+ /*CFI_REL_OFFSET rflags,0*/
movl $VSYSCALL32_SYSEXIT, %r10d
+ CFI_REGISTER rip,r10
pushq $__USER32_CS
+ CFI_ADJUST_CFA_OFFSET 8
+ /*CFI_REL_OFFSET cs,0*/
movl %eax, %eax
pushq %r10
+ CFI_ADJUST_CFA_OFFSET 8
+ CFI_REL_OFFSET rip,0
pushq %rax
+ CFI_ADJUST_CFA_OFFSET 8
cld
SAVE_ARGS 0,0,1
/* no need to do an access_ok check here because rbp has been
@@ -79,6 +93,7 @@ ENTRY(ia32_sysenter_target)
.previous
GET_THREAD_INFO(%r10)
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
+ CFI_REMEMBER_STATE
jnz sysenter_tracesys
sysenter_do_call:
cmpl $(IA32_NR_syscalls),%eax
@@ -94,14 +109,20 @@ sysenter_do_call:
andl $~0x200,EFLAGS-R11(%rsp)
RESTORE_ARGS 1,24,1,1,1,1
popfq
+ CFI_ADJUST_CFA_OFFSET -8
+ /*CFI_RESTORE rflags*/
popq %rcx /* User %esp */
+ CFI_ADJUST_CFA_OFFSET -8
+ CFI_REGISTER rsp,rcx
movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */
+ CFI_REGISTER rip,rdx
swapgs
sti /* sti only takes effect after the next instruction */
/* sysexit */
.byte 0xf, 0x35
sysenter_tracesys:
+ CFI_RESTORE_STATE
SAVE_REST
CLEAR_RREGS
movq $-ENOSYS,RAX(%rsp) /* really needed? */
@@ -140,21 +161,28 @@ sysenter_tracesys:
* with the int 0x80 path.
*/
ENTRY(ia32_cstar_target)
- CFI_STARTPROC
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,0
+ CFI_REGISTER rip,rcx
+ /*CFI_REGISTER rflags,r11*/
swapgs
movl %esp,%r8d
+ CFI_REGISTER rsp,r8
movq %gs:pda_kernelstack,%rsp
sti
SAVE_ARGS 8,1,1
movl %eax,%eax /* zero extension */
movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
movq %rcx,RIP-ARGOFFSET(%rsp)
+ CFI_REL_OFFSET rip,RIP-ARGOFFSET
movq %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */
movl %ebp,%ecx
movq $__USER32_CS,CS-ARGOFFSET(%rsp)
movq $__USER32_DS,SS-ARGOFFSET(%rsp)
movq %r11,EFLAGS-ARGOFFSET(%rsp)
+ /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
movq %r8,RSP-ARGOFFSET(%rsp)
+ CFI_REL_OFFSET rsp,RSP-ARGOFFSET
/* no need to do an access_ok check here because r8 has been
32bit zero extended */
/* hardware stack frame is complete now */
@@ -164,6 +192,7 @@ ENTRY(ia32_cstar_target)
.previous
GET_THREAD_INFO(%r10)
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
+ CFI_REMEMBER_STATE
jnz cstar_tracesys
cstar_do_call:
cmpl $IA32_NR_syscalls,%eax
@@ -177,12 +206,16 @@ cstar_do_call:
jnz int_ret_from_sys_call
RESTORE_ARGS 1,-ARG_SKIP,1,1,1
movl RIP-ARGOFFSET(%rsp),%ecx
+ CFI_REGISTER rip,rcx
movl EFLAGS-ARGOFFSET(%rsp),%r11d
+ /*CFI_REGISTER rflags,r11*/
movl RSP-ARGOFFSET(%rsp),%esp
+ CFI_RESTORE rsp
swapgs
sysretl
cstar_tracesys:
+ CFI_RESTORE_STATE
SAVE_REST
CLEAR_RREGS
movq $-ENOSYS,RAX(%rsp) /* really needed? */
@@ -226,11 +259,18 @@ ia32_badarg:
*/
ENTRY(ia32_syscall)
- CFI_STARTPROC
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,SS+8-RIP
+ /*CFI_REL_OFFSET ss,SS-RIP*/
+ CFI_REL_OFFSET rsp,RSP-RIP
+ /*CFI_REL_OFFSET rflags,EFLAGS-RIP*/
+ /*CFI_REL_OFFSET cs,CS-RIP*/
+ CFI_REL_OFFSET rip,RIP-RIP
swapgs
sti
movl %eax,%eax
pushq %rax
+ CFI_ADJUST_CFA_OFFSET 8
cld
/* note the registers are not zero extended to the sf.
this could be a problem. */
@@ -278,6 +318,8 @@ quiet_ni_syscall:
jmp ia32_ptregs_common
.endm
+ CFI_STARTPROC
+
PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
@@ -290,8 +332,9 @@ quiet_ni_syscall:
PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx
ENTRY(ia32_ptregs_common)
- CFI_STARTPROC
popq %r11
+ CFI_ADJUST_CFA_OFFSET -8
+ CFI_REGISTER rip, r11
SAVE_REST
call *%rax
RESTORE_REST
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index 04d80406ce4f..5389df610e78 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -751,7 +751,7 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
set_fs(old_fs);
- if (!ret && offset && put_user(of, offset))
+ if (offset && put_user(of, offset))
return -EFAULT;
return ret;
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c
index adbc5f8089e9..3a01329473ab 100644
--- a/arch/x86_64/ia32/syscall32.c
+++ b/arch/x86_64/ia32/syscall32.c
@@ -52,17 +52,13 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!vma)
return -ENOMEM;
- if (security_vm_enough_memory(npages)) {
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
memset(vma, 0, sizeof(struct vm_area_struct));
/* Could randomize here */
vma->vm_start = VSYSCALL32_BASE;
vma->vm_end = VSYSCALL32_END;
/* MAYWRITE to allow gdb to COW and set breakpoints */
- vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYEXEC|VM_MAYWRITE;
+ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
vma->vm_flags |= mm->def_flags;
vma->vm_page_prot = protection_map[vma->vm_flags & 7];
vma->vm_ops = &syscall32_vm_ops;
diff --git a/arch/x86_64/ia32/vsyscall-syscall.S b/arch/x86_64/ia32/vsyscall-syscall.S
index e2aaf3de8a42..b024965bb689 100644
--- a/arch/x86_64/ia32/vsyscall-syscall.S
+++ b/arch/x86_64/ia32/vsyscall-syscall.S
@@ -3,7 +3,7 @@
*/
#include <asm/ia32_unistd.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/segment.h>
.text
diff --git a/arch/x86_64/ia32/vsyscall-sysenter.S b/arch/x86_64/ia32/vsyscall-sysenter.S
index 8fb8e0ff3afa..71f3de586b56 100644
--- a/arch/x86_64/ia32/vsyscall-sysenter.S
+++ b/arch/x86_64/ia32/vsyscall-sysenter.S
@@ -3,7 +3,7 @@
*/
#include <asm/ia32_unistd.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
.text
.section .text.vsyscall,"ax"
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index c32e198d7b2b..bcdd0a805fe7 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -12,7 +12,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
obj-$(CONFIG_X86_MCE) += mce.o
obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o
obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/
-obj-$(CONFIG_ACPI_BOOT) += acpi/
+obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
@@ -46,3 +46,4 @@ microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
quirks-y += ../../i386/kernel/quirks.o
i8237-y += ../../i386/kernel/i8237.o
+msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile
index d2c2ee5f9a88..7da9ace890bd 100644
--- a/arch/x86_64/kernel/acpi/Makefile
+++ b/arch/x86_64/kernel/acpi/Makefile
@@ -1,3 +1,3 @@
-obj-$(CONFIG_ACPI_BOOT) := boot.o
-boot-$(CONFIG_ACPI_BOOT) := ../../../i386/kernel/acpi/boot.o
+obj-y := boot.o
+boot-y := ../../../i386/kernel/acpi/boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c
index 7a275de6df22..867a0ebee177 100644
--- a/arch/x86_64/kernel/acpi/sleep.c
+++ b/arch/x86_64/kernel/acpi/sleep.c
@@ -34,7 +34,6 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/bootmem.h>
-#include <linux/irq.h>
#include <linux/acpi.h>
#include <asm/mpspec.h>
#include <asm/io.h>
@@ -47,7 +46,6 @@
#include <asm/proto.h>
#include <asm/tlbflush.h>
-
/* --------------------------------------------------------------------------
Low-Level Sleep Support
-------------------------------------------------------------------------- */
@@ -77,11 +75,12 @@ static void init_low_mapping(void)
* Create an identity mapped page table and copy the wakeup routine to
* low memory.
*/
-int acpi_save_state_mem (void)
+int acpi_save_state_mem(void)
{
init_low_mapping();
- memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
+ memcpy((void *)acpi_wakeup_address, &wakeup_start,
+ &wakeup_end - &wakeup_start);
acpi_copy_wakeup_routine(acpi_wakeup_address);
return 0;
@@ -90,7 +89,7 @@ int acpi_save_state_mem (void)
/*
* acpi_restore_state
*/
-void acpi_restore_state_mem (void)
+void acpi_restore_state_mem(void)
{
set_pgd(pgd_offset(current->mm, 0UL), low_ptr);
flush_tlb_all();
@@ -108,7 +107,8 @@ void __init acpi_reserve_bootmem(void)
{
acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
- printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
+ printk(KERN_CRIT
+ "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
}
static int __init acpi_sleep_setup(char *str)
@@ -127,6 +127,8 @@ static int __init acpi_sleep_setup(char *str)
__setup("acpi_sleep=", acpi_sleep_setup);
-#endif /*CONFIG_ACPI_SLEEP*/
+#endif /*CONFIG_ACPI_SLEEP */
-void acpi_pci_link_exit(void) {}
+void acpi_pci_link_exit(void)
+{
+}
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index c9a6b812e926..962ad4823b6a 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -245,6 +245,8 @@ void __init iommu_hole_init(void)
if (aper_alloc) {
/* Got the aperture from the AGP bridge */
+ } else if (swiotlb && !valid_agp) {
+ /* Do nothing */
} else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) ||
force_iommu ||
valid_agp ||
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 375d369570ca..b6e7715d877f 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>
@@ -109,11 +108,8 @@ void clear_local_APIC(void)
if (maxlvt >= 4)
apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
v = GET_APIC_VERSION(apic_read(APIC_LVR));
- if (APIC_INTEGRATED(v)) { /* !82489DX */
- if (maxlvt > 3) /* Due to Pentium errata 3AP and 11AP. */
- apic_write(APIC_ESR, 0);
- apic_read(APIC_ESR);
- }
+ apic_write(APIC_ESR, 0);
+ apic_read(APIC_ESR);
}
void __init connect_bsp_APIC(void)
@@ -316,8 +312,6 @@ void __init init_bsp_APIC(void)
*/
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
value = APIC_DM_NMI;
- if (!APIC_INTEGRATED(ver)) /* 82489DX */
- value |= APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT1, value);
}
@@ -325,14 +319,6 @@ void __cpuinit setup_local_APIC (void)
{
unsigned int value, ver, maxlvt;
- /* Pound the ESR really hard over the head with a big hammer - mbligh */
- if (esr_disable) {
- apic_write(APIC_ESR, 0);
- apic_write(APIC_ESR, 0);
- apic_write(APIC_ESR, 0);
- apic_write(APIC_ESR, 0);
- }
-
value = apic_read(APIC_LVR);
ver = GET_APIC_VERSION(value);
@@ -430,15 +416,11 @@ void __cpuinit setup_local_APIC (void)
value = APIC_DM_NMI;
else
value = APIC_DM_NMI | APIC_LVT_MASKED;
- if (!APIC_INTEGRATED(ver)) /* 82489DX */
- value |= APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT1, value);
- if (APIC_INTEGRATED(ver) && !esr_disable) { /* !82489DX */
+ {
unsigned oldvalue;
maxlvt = get_maxlvt();
- if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
- apic_write(APIC_ESR, 0);
oldvalue = apic_read(APIC_ESR);
value = ERROR_APIC_VECTOR; // enables sending errors
apic_write_around(APIC_LVTERR, value);
@@ -452,17 +434,6 @@ void __cpuinit setup_local_APIC (void)
apic_printk(APIC_VERBOSE,
"ESR value after enabling vector: %08x, after %08x\n",
oldvalue, value);
- } else {
- if (esr_disable)
- /*
- * Something untraceble is creating bad interrupts on
- * secondary quads ... for the moment, just leave the
- * ESR disabled - we can't do anything useful with the
- * errors anyway - mbligh
- */
- apic_printk(APIC_DEBUG, "Leaving ESR disabled.\n");
- else
- apic_printk(APIC_DEBUG, "No ESR for 82489DX.\n");
}
nmi_watchdog_default();
@@ -650,8 +621,7 @@ void __init init_apic_mappings(void)
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
*/
- if (boot_cpu_id == -1U)
- boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
+ boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
#ifdef CONFIG_X86_IO_APIC
{
@@ -693,8 +663,6 @@ static void __setup_APIC_LVTT(unsigned int clocks)
ver = GET_APIC_VERSION(apic_read(APIC_LVR));
lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
- if (!APIC_INTEGRATED(ver))
- lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
apic_write_around(APIC_LVTT, lvtt_value);
/*
@@ -1081,7 +1049,7 @@ int __init APIC_init_uniprocessor (void)
connect_bsp_APIC();
- phys_cpu_present_map = physid_mask_of_physid(0);
+ phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
apic_write_around(APIC_ID, boot_cpu_id);
setup_local_APIC();
diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c
index 35b4c3fcbb37..aaa6d3833517 100644
--- a/arch/x86_64/kernel/asm-offsets.c
+++ b/arch/x86_64/kernel/asm-offsets.c
@@ -39,7 +39,6 @@ int main(void)
ENTRY(kernelstack);
ENTRY(oldrsp);
ENTRY(pcurrent);
- ENTRY(irqrsp);
ENTRY(irqcount);
ENTRY(cpunumber);
ENTRY(irqstackptr);
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
index d7fa4248501c..535e04466079 100644
--- a/arch/x86_64/kernel/crash.c
+++ b/arch/x86_64/kernel/crash.c
@@ -11,7 +11,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/smp.h>
-#include <linux/irq.h>
#include <linux/reboot.h>
#include <linux/kexec.h>
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 116ac5f53dce..ab3f87aaff70 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -17,6 +17,8 @@
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/kexec.h>
+#include <linux/module.h>
+
#include <asm/page.h>
#include <asm/e820.h>
#include <asm/proto.h>
@@ -28,6 +30,7 @@ extern char _end[];
* PFN of last memory page.
*/
unsigned long end_pfn;
+EXPORT_SYMBOL(end_pfn);
/*
* end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
@@ -131,7 +134,7 @@ void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned lon
if (ei->type != E820_RAM ||
ei->addr+ei->size <= start ||
- ei->addr > end)
+ ei->addr >= end)
continue;
addr = round_up(ei->addr, PAGE_SIZE);
@@ -567,7 +570,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 +607,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/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 9631c747c5e3..9cd968dd0f5a 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -5,6 +5,7 @@
#include <linux/tty.h>
#include <asm/io.h>
#include <asm/processor.h>
+#include <asm/fcntl.h>
/* Simple VGA output */
@@ -158,6 +159,47 @@ static struct console early_serial_console = {
.index = -1,
};
+/* Console interface to a host file on AMD's SimNow! */
+
+static int simnow_fd;
+
+enum {
+ MAGIC1 = 0xBACCD00A,
+ MAGIC2 = 0xCA110000,
+ XOPEN = 5,
+ XWRITE = 4,
+};
+
+static noinline long simnow(long cmd, long a, long b, long c)
+{
+ long ret;
+ asm volatile("cpuid" :
+ "=a" (ret) :
+ "b" (a), "c" (b), "d" (c), "0" (MAGIC1), "D" (cmd + MAGIC2));
+ return ret;
+}
+
+void __init simnow_init(char *str)
+{
+ char *fn = "klog";
+ if (*str == '=')
+ fn = ++str;
+ /* error ignored */
+ simnow_fd = simnow(XOPEN, (unsigned long)fn, O_WRONLY|O_APPEND|O_CREAT, 0644);
+}
+
+static void simnow_write(struct console *con, const char *s, unsigned n)
+{
+ simnow(XWRITE, simnow_fd, (unsigned long)s, n);
+}
+
+static struct console simnow_console = {
+ .name = "simnow",
+ .write = simnow_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
/* Direct interface for emergencies */
struct console *early_console = &early_vga_console;
static int early_console_initialized = 0;
@@ -205,6 +247,10 @@ int __init setup_early_printk(char *opt)
max_xpos = SCREEN_INFO.orig_video_cols;
max_ypos = SCREEN_INFO.orig_video_lines;
early_console = &early_vga_console;
+ } else if (!strncmp(buf, "simnow", 6)) {
+ simnow_init(buf + 6);
+ early_console = &simnow_console;
+ keep_early = 1;
}
early_console_initialized = 1;
register_console(early_console);
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index be51dbe1f75e..7937971d1853 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -36,7 +36,7 @@
#include <asm/errno.h>
#include <asm/dwarf2.h>
#include <asm/calling.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/msr.h>
#include <asm/unistd.h>
#include <asm/thread_info.h>
@@ -79,16 +79,19 @@
xorl %eax, %eax
pushq %rax /* ss */
CFI_ADJUST_CFA_OFFSET 8
+ /*CFI_REL_OFFSET ss,0*/
pushq %rax /* rsp */
CFI_ADJUST_CFA_OFFSET 8
- CFI_OFFSET rip,0
+ CFI_REL_OFFSET rsp,0
pushq $(1<<9) /* eflags - interrupts on */
CFI_ADJUST_CFA_OFFSET 8
+ /*CFI_REL_OFFSET rflags,0*/
pushq $__KERNEL_CS /* cs */
CFI_ADJUST_CFA_OFFSET 8
+ /*CFI_REL_OFFSET cs,0*/
pushq \child_rip /* rip */
CFI_ADJUST_CFA_OFFSET 8
- CFI_OFFSET rip,0
+ CFI_REL_OFFSET rip,0
pushq %rax /* orig rax */
CFI_ADJUST_CFA_OFFSET 8
.endm
@@ -98,32 +101,39 @@
CFI_ADJUST_CFA_OFFSET -(6*8)
.endm
- .macro CFI_DEFAULT_STACK
- CFI_ADJUST_CFA_OFFSET (SS)
- CFI_OFFSET r15,R15-SS
- CFI_OFFSET r14,R14-SS
- CFI_OFFSET r13,R13-SS
- CFI_OFFSET r12,R12-SS
- CFI_OFFSET rbp,RBP-SS
- CFI_OFFSET rbx,RBX-SS
- CFI_OFFSET r11,R11-SS
- CFI_OFFSET r10,R10-SS
- CFI_OFFSET r9,R9-SS
- CFI_OFFSET r8,R8-SS
- CFI_OFFSET rax,RAX-SS
- CFI_OFFSET rcx,RCX-SS
- CFI_OFFSET rdx,RDX-SS
- CFI_OFFSET rsi,RSI-SS
- CFI_OFFSET rdi,RDI-SS
- CFI_OFFSET rsp,RSP-SS
- CFI_OFFSET rip,RIP-SS
+ .macro CFI_DEFAULT_STACK start=1
+ .if \start
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,SS+8
+ .else
+ CFI_DEF_CFA_OFFSET SS+8
+ .endif
+ CFI_REL_OFFSET r15,R15
+ CFI_REL_OFFSET r14,R14
+ CFI_REL_OFFSET r13,R13
+ CFI_REL_OFFSET r12,R12
+ CFI_REL_OFFSET rbp,RBP
+ CFI_REL_OFFSET rbx,RBX
+ CFI_REL_OFFSET r11,R11
+ CFI_REL_OFFSET r10,R10
+ CFI_REL_OFFSET r9,R9
+ CFI_REL_OFFSET r8,R8
+ CFI_REL_OFFSET rax,RAX
+ CFI_REL_OFFSET rcx,RCX
+ CFI_REL_OFFSET rdx,RDX
+ CFI_REL_OFFSET rsi,RSI
+ CFI_REL_OFFSET rdi,RDI
+ CFI_REL_OFFSET rip,RIP
+ /*CFI_REL_OFFSET cs,CS*/
+ /*CFI_REL_OFFSET rflags,EFLAGS*/
+ CFI_REL_OFFSET rsp,RSP
+ /*CFI_REL_OFFSET ss,SS*/
.endm
/*
* A newly forked process directly context switches into this.
*/
/* rdi: prev */
ENTRY(ret_from_fork)
- CFI_STARTPROC
CFI_DEFAULT_STACK
call schedule_tail
GET_THREAD_INFO(%rcx)
@@ -172,16 +182,21 @@ rff_trace:
*/
ENTRY(system_call)
- CFI_STARTPROC
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,0
+ CFI_REGISTER rip,rcx
+ /*CFI_REGISTER rflags,r11*/
swapgs
movq %rsp,%gs:pda_oldrsp
movq %gs:pda_kernelstack,%rsp
sti
SAVE_ARGS 8,1
movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
- movq %rcx,RIP-ARGOFFSET(%rsp)
+ movq %rcx,RIP-ARGOFFSET(%rsp)
+ CFI_REL_OFFSET rip,RIP-ARGOFFSET
GET_THREAD_INFO(%rcx)
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
+ CFI_REMEMBER_STATE
jnz tracesys
cmpq $__NR_syscall_max,%rax
ja badsys
@@ -201,9 +216,12 @@ sysret_check:
cli
movl threadinfo_flags(%rcx),%edx
andl %edi,%edx
+ CFI_REMEMBER_STATE
jnz sysret_careful
movq RIP-ARGOFFSET(%rsp),%rcx
+ CFI_REGISTER rip,rcx
RESTORE_ARGS 0,-ARG_SKIP,1
+ /*CFI_REGISTER rflags,r11*/
movq %gs:pda_oldrsp,%rsp
swapgs
sysretq
@@ -211,12 +229,15 @@ sysret_check:
/* Handle reschedules */
/* edx: work, edi: workmask */
sysret_careful:
+ CFI_RESTORE_STATE
bt $TIF_NEED_RESCHED,%edx
jnc sysret_signal
sti
pushq %rdi
+ CFI_ADJUST_CFA_OFFSET 8
call schedule
popq %rdi
+ CFI_ADJUST_CFA_OFFSET -8
jmp sysret_check
/* Handle a signal */
@@ -234,8 +255,13 @@ sysret_signal:
1: movl $_TIF_NEED_RESCHED,%edi
jmp sysret_check
+badsys:
+ movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
+ jmp ret_from_sys_call
+
/* Do syscall tracing */
tracesys:
+ CFI_RESTORE_STATE
SAVE_REST
movq $-ENOSYS,RAX(%rsp)
FIXUP_TOP_OF_STACK %rdi
@@ -254,16 +280,29 @@ tracesys:
RESTORE_TOP_OF_STACK %rbx
RESTORE_REST
jmp ret_from_sys_call
+ CFI_ENDPROC
-badsys:
- movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
- jmp ret_from_sys_call
-
/*
* Syscall return path ending with IRET.
* Has correct top of stack, but partial stack frame.
*/
-ENTRY(int_ret_from_sys_call)
+ENTRY(int_ret_from_sys_call)
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,SS+8-ARGOFFSET
+ /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/
+ CFI_REL_OFFSET rsp,RSP-ARGOFFSET
+ /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
+ /*CFI_REL_OFFSET cs,CS-ARGOFFSET*/
+ CFI_REL_OFFSET rip,RIP-ARGOFFSET
+ CFI_REL_OFFSET rdx,RDX-ARGOFFSET
+ CFI_REL_OFFSET rcx,RCX-ARGOFFSET
+ CFI_REL_OFFSET rax,RAX-ARGOFFSET
+ CFI_REL_OFFSET rdi,RDI-ARGOFFSET
+ CFI_REL_OFFSET rsi,RSI-ARGOFFSET
+ CFI_REL_OFFSET r8,R8-ARGOFFSET
+ CFI_REL_OFFSET r9,R9-ARGOFFSET
+ CFI_REL_OFFSET r10,R10-ARGOFFSET
+ CFI_REL_OFFSET r11,R11-ARGOFFSET
cli
testl $3,CS-ARGOFFSET(%rsp)
je retint_restore_args
@@ -284,8 +323,10 @@ int_careful:
jnc int_very_careful
sti
pushq %rdi
+ CFI_ADJUST_CFA_OFFSET 8
call schedule
popq %rdi
+ CFI_ADJUST_CFA_OFFSET -8
cli
jmp int_with_check
@@ -297,9 +338,11 @@ int_very_careful:
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
jz int_signal
pushq %rdi
+ CFI_ADJUST_CFA_OFFSET 8
leaq 8(%rsp),%rdi # &ptregs -> arg1
call syscall_trace_leave
popq %rdi
+ CFI_ADJUST_CFA_OFFSET -8
andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
cli
jmp int_restore_rest
@@ -329,6 +372,8 @@ int_restore_rest:
jmp ptregscall_common
.endm
+ CFI_STARTPROC
+
PTREGSCALL stub_clone, sys_clone, %r8
PTREGSCALL stub_fork, sys_fork, %rdi
PTREGSCALL stub_vfork, sys_vfork, %rdi
@@ -337,40 +382,49 @@ int_restore_rest:
PTREGSCALL stub_iopl, sys_iopl, %rsi
ENTRY(ptregscall_common)
- CFI_STARTPROC
popq %r11
- CFI_ADJUST_CFA_OFFSET -8
+ CFI_ADJUST_CFA_OFFSET -8
+ CFI_REGISTER rip, r11
SAVE_REST
movq %r11, %r15
+ CFI_REGISTER rip, r15
FIXUP_TOP_OF_STACK %r11
call *%rax
RESTORE_TOP_OF_STACK %r11
movq %r15, %r11
+ CFI_REGISTER rip, r11
RESTORE_REST
pushq %r11
- CFI_ADJUST_CFA_OFFSET 8
+ CFI_ADJUST_CFA_OFFSET 8
+ CFI_REL_OFFSET rip, 0
ret
CFI_ENDPROC
ENTRY(stub_execve)
CFI_STARTPROC
popq %r11
- CFI_ADJUST_CFA_OFFSET -8
+ CFI_ADJUST_CFA_OFFSET -8
+ CFI_REGISTER rip, r11
SAVE_REST
movq %r11, %r15
+ CFI_REGISTER rip, r15
FIXUP_TOP_OF_STACK %r11
call sys_execve
GET_THREAD_INFO(%rcx)
bt $TIF_IA32,threadinfo_flags(%rcx)
+ CFI_REMEMBER_STATE
jc exec_32bit
RESTORE_TOP_OF_STACK %r11
movq %r15, %r11
+ CFI_REGISTER rip, r11
RESTORE_REST
- push %r11
+ pushq %r11
+ CFI_ADJUST_CFA_OFFSET 8
+ CFI_REL_OFFSET rip, 0
ret
exec_32bit:
- CFI_ADJUST_CFA_OFFSET REST_SKIP
+ CFI_RESTORE_STATE
movq %rax,RAX(%rsp)
RESTORE_REST
jmp int_ret_from_sys_call
@@ -382,7 +436,8 @@ exec_32bit:
*/
ENTRY(stub_rt_sigreturn)
CFI_STARTPROC
- addq $8, %rsp
+ addq $8, %rsp
+ CFI_ADJUST_CFA_OFFSET -8
SAVE_REST
movq %rsp,%rdi
FIXUP_TOP_OF_STACK %r11
@@ -392,6 +447,25 @@ ENTRY(stub_rt_sigreturn)
jmp int_ret_from_sys_call
CFI_ENDPROC
+/*
+ * initial frame state for interrupts and exceptions
+ */
+ .macro _frame ref
+ CFI_STARTPROC simple
+ CFI_DEF_CFA rsp,SS+8-\ref
+ /*CFI_REL_OFFSET ss,SS-\ref*/
+ CFI_REL_OFFSET rsp,RSP-\ref
+ /*CFI_REL_OFFSET rflags,EFLAGS-\ref*/
+ /*CFI_REL_OFFSET cs,CS-\ref*/
+ CFI_REL_OFFSET rip,RIP-\ref
+ .endm
+
+/* initial frame state for interrupts (and exceptions without error code) */
+#define INTR_FRAME _frame RIP
+/* initial frame state for exceptions with error code (and interrupts with
+ vector already pushed) */
+#define XCPT_FRAME _frame ORIG_RAX
+
/*
* Interrupt entry/exit.
*
@@ -402,10 +476,6 @@ ENTRY(stub_rt_sigreturn)
/* 0(%rsp): interrupt number */
.macro interrupt func
- CFI_STARTPROC simple
- CFI_DEF_CFA rsp,(SS-RDI)
- CFI_REL_OFFSET rsp,(RSP-ORIG_RAX)
- CFI_REL_OFFSET rip,(RIP-ORIG_RAX)
cld
#ifdef CONFIG_DEBUG_INFO
SAVE_ALL
@@ -425,23 +495,27 @@ ENTRY(stub_rt_sigreturn)
swapgs
1: incl %gs:pda_irqcount # RED-PEN should check preempt count
movq %gs:pda_irqstackptr,%rax
- cmoveq %rax,%rsp
+ cmoveq %rax,%rsp /*todo This needs CFI annotation! */
pushq %rdi # save old stack
+ CFI_ADJUST_CFA_OFFSET 8
call \func
.endm
ENTRY(common_interrupt)
+ XCPT_FRAME
interrupt do_IRQ
/* 0(%rsp): oldrsp-ARGOFFSET */
-ret_from_intr:
+ret_from_intr:
popq %rdi
+ CFI_ADJUST_CFA_OFFSET -8
cli
decl %gs:pda_irqcount
#ifdef CONFIG_DEBUG_INFO
movq RBP(%rdi),%rbp
+ CFI_DEF_CFA_REGISTER rsp
#endif
- leaq ARGOFFSET(%rdi),%rsp
-exit_intr:
+ leaq ARGOFFSET(%rdi),%rsp /*todo This needs CFI annotation! */
+exit_intr:
GET_THREAD_INFO(%rcx)
testl $3,CS-ARGOFFSET(%rsp)
je retint_kernel
@@ -453,9 +527,10 @@ exit_intr:
*/
retint_with_reschedule:
movl $_TIF_WORK_MASK,%edi
-retint_check:
+retint_check:
movl threadinfo_flags(%rcx),%edx
andl %edi,%edx
+ CFI_REMEMBER_STATE
jnz retint_careful
retint_swapgs:
swapgs
@@ -476,14 +551,17 @@ bad_iret:
jmp do_exit
.previous
- /* edi: workmask, edx: work */
+ /* edi: workmask, edx: work */
retint_careful:
+ CFI_RESTORE_STATE
bt $TIF_NEED_RESCHED,%edx
jnc retint_signal
sti
pushq %rdi
+ CFI_ADJUST_CFA_OFFSET 8
call schedule
popq %rdi
+ CFI_ADJUST_CFA_OFFSET -8
GET_THREAD_INFO(%rcx)
cli
jmp retint_check
@@ -523,7 +601,9 @@ retint_kernel:
* APIC interrupts.
*/
.macro apicinterrupt num,func
+ INTR_FRAME
pushq $\num-256
+ CFI_ADJUST_CFA_OFFSET 8
interrupt \func
jmp ret_from_intr
CFI_ENDPROC
@@ -536,8 +616,19 @@ ENTRY(thermal_interrupt)
ENTRY(reschedule_interrupt)
apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
-ENTRY(invalidate_interrupt)
- apicinterrupt INVALIDATE_TLB_VECTOR,smp_invalidate_interrupt
+ .macro INVALIDATE_ENTRY num
+ENTRY(invalidate_interrupt\num)
+ apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt
+ .endm
+
+ INVALIDATE_ENTRY 0
+ INVALIDATE_ENTRY 1
+ INVALIDATE_ENTRY 2
+ INVALIDATE_ENTRY 3
+ INVALIDATE_ENTRY 4
+ INVALIDATE_ENTRY 5
+ INVALIDATE_ENTRY 6
+ INVALIDATE_ENTRY 7
ENTRY(call_function_interrupt)
apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
@@ -558,16 +649,23 @@ ENTRY(spurious_interrupt)
* Exception entry points.
*/
.macro zeroentry sym
+ INTR_FRAME
pushq $0 /* push error code/oldrax */
+ CFI_ADJUST_CFA_OFFSET 8
pushq %rax /* push real oldrax to the rdi slot */
+ CFI_ADJUST_CFA_OFFSET 8
leaq \sym(%rip),%rax
jmp error_entry
+ CFI_ENDPROC
.endm
.macro errorentry sym
+ XCPT_FRAME
pushq %rax
+ CFI_ADJUST_CFA_OFFSET 8
leaq \sym(%rip),%rax
jmp error_entry
+ CFI_ENDPROC
.endm
/* error code is on the stack already */
@@ -594,10 +692,7 @@ ENTRY(spurious_interrupt)
* and the exception handler in %rax.
*/
ENTRY(error_entry)
- CFI_STARTPROC simple
- CFI_DEF_CFA rsp,(SS-RDI)
- CFI_REL_OFFSET rsp,(RSP-RDI)
- CFI_REL_OFFSET rip,(RIP-RDI)
+ _frame RDI
/* rdi slot contains rax, oldrax contains error code */
cld
subq $14*8,%rsp
@@ -679,7 +774,9 @@ error_kernelspace:
/* Reload gs selector with exception handling */
/* edi: new selector */
ENTRY(load_gs_index)
+ CFI_STARTPROC
pushf
+ CFI_ADJUST_CFA_OFFSET 8
cli
swapgs
gs_change:
@@ -687,7 +784,9 @@ gs_change:
2: mfence /* workaround */
swapgs
popf
+ CFI_ADJUST_CFA_OFFSET -8
ret
+ CFI_ENDPROC
.section __ex_table,"a"
.align 8
@@ -799,7 +898,7 @@ ENTRY(device_not_available)
/* runs on exception stack */
KPROBE_ENTRY(debug)
- CFI_STARTPROC
+ INTR_FRAME
pushq $0
CFI_ADJUST_CFA_OFFSET 8
paranoidentry do_debug
@@ -809,9 +908,9 @@ KPROBE_ENTRY(debug)
/* runs on exception stack */
ENTRY(nmi)
- CFI_STARTPROC
+ INTR_FRAME
pushq $-1
- CFI_ADJUST_CFA_OFFSET 8
+ CFI_ADJUST_CFA_OFFSET 8
paranoidentry do_nmi
/*
* "Paranoid" exit path from exception stack.
@@ -877,7 +976,7 @@ ENTRY(reserved)
/* runs on exception stack */
ENTRY(double_fault)
- CFI_STARTPROC
+ XCPT_FRAME
paranoidentry do_double_fault
jmp paranoid_exit
CFI_ENDPROC
@@ -890,7 +989,7 @@ ENTRY(segment_not_present)
/* runs on exception stack */
ENTRY(stack_segment)
- CFI_STARTPROC
+ XCPT_FRAME
paranoidentry do_stack_segment
jmp paranoid_exit
CFI_ENDPROC
@@ -911,7 +1010,7 @@ ENTRY(spurious_interrupt_bug)
#ifdef CONFIG_X86_MCE
/* runs on exception stack */
ENTRY(machine_check)
- CFI_STARTPROC
+ INTR_FRAME
pushq $0
CFI_ADJUST_CFA_OFFSET 8
paranoidentry do_machine_check
@@ -923,14 +1022,19 @@ ENTRY(call_debug)
zeroentry do_call_debug
ENTRY(call_softirq)
+ CFI_STARTPROC
movq %gs:pda_irqstackptr,%rax
pushq %r15
+ CFI_ADJUST_CFA_OFFSET 8
movq %rsp,%r15
+ CFI_DEF_CFA_REGISTER r15
incl %gs:pda_irqcount
cmove %rax,%rsp
call __do_softirq
movq %r15,%rsp
+ CFI_DEF_CFA_REGISTER rsp
decl %gs:pda_irqcount
popq %r15
+ CFI_ADJUST_CFA_OFFSET -8
ret
-
+ CFI_ENDPROC
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c
index f062aa03bab7..7a64ea181788 100644
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -20,7 +20,7 @@
#include <asm/smp.h>
#include <asm/ipi.h>
-#if defined(CONFIG_ACPI_BUS)
+#if defined(CONFIG_ACPI)
#include <acpi/acpi_bus.h>
#endif
@@ -45,9 +45,9 @@ void __init clustered_apic_check(void)
u8 clusters, max_cluster;
u8 id;
u8 cluster_cnt[NUM_APIC_CLUSTERS];
- int num_cpus = 0;
+ int max_apic = 0;
-#if defined(CONFIG_ACPI_BUS)
+#if defined(CONFIG_ACPI)
/*
* Some x86_64 machines use physical APIC mode regardless of how many
* procs/clusters are present (x86_64 ES7000 is an example).
@@ -64,14 +64,15 @@ void __init clustered_apic_check(void)
id = bios_cpu_apicid[i];
if (id == BAD_APICID)
continue;
- num_cpus++;
+ if (id > max_apic)
+ max_apic = id;
cluster_cnt[APIC_CLUSTERID(id)]++;
}
/* Don't use clustered mode on AMD platforms. */
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
genapic = &apic_physflat;
-#ifndef CONFIG_CPU_HOTPLUG
+#ifndef CONFIG_HOTPLUG_CPU
/* In the CPU hotplug case we cannot use broadcast mode
because that opens a race when a CPU is removed.
Stay at physflat mode in this case.
@@ -79,7 +80,7 @@ void __init clustered_apic_check(void)
we have ACPI platform support for CPU hotplug
we should detect hotplug capablity from ACPI tables and
only do this when really needed. -AK */
- if (num_cpus <= 8)
+ if (max_apic <= 8)
genapic = &apic_flat;
#endif
goto print;
@@ -103,9 +104,14 @@ void __init clustered_apic_check(void)
* (We don't use lowest priority delivery + HW APIC IRQ steering, so
* can ignore the clustered logical case and go straight to physical.)
*/
- if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster)
+ if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) {
+#ifdef CONFIG_HOTPLUG_CPU
+ /* Don't use APIC shortcuts in CPU hotplug to avoid races */
+ genapic = &apic_physflat;
+#else
genapic = &apic_flat;
- else
+#endif
+ } else
genapic = &apic_cluster;
print:
diff --git a/arch/x86_64/kernel/genapic_cluster.c b/arch/x86_64/kernel/genapic_cluster.c
index f6523dd1bc09..a472d62f899a 100644
--- a/arch/x86_64/kernel/genapic_cluster.c
+++ b/arch/x86_64/kernel/genapic_cluster.c
@@ -51,10 +51,10 @@ static void cluster_init_apic_ldr(void)
count = 3;
id = my_cluster | (1UL << count);
x86_cpu_to_log_apicid[smp_processor_id()] = id;
- apic_write_around(APIC_DFR, APIC_DFR_CLUSTER);
+ apic_write(APIC_DFR, APIC_DFR_CLUSTER);
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
val |= SET_APIC_LOGICAL_ID(id);
- apic_write_around(APIC_LDR, val);
+ apic_write(APIC_LDR, val);
}
/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index adc96282a9e2..9da3edb799ea 100644
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -38,10 +38,10 @@ static void flat_init_apic_ldr(void)
num = smp_processor_id();
id = 1UL << num;
x86_cpu_to_log_apicid[num] = id;
- apic_write_around(APIC_DFR, APIC_DFR_FLAT);
+ apic_write(APIC_DFR, APIC_DFR_FLAT);
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
val |= SET_APIC_LOGICAL_ID(id);
- apic_write_around(APIC_LDR, val);
+ apic_write(APIC_LDR, val);
}
static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
@@ -62,7 +62,7 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
* prepare target chip field
*/
cfg = __prepare_ICR2(mask);
- apic_write_around(APIC_ICR2, cfg);
+ apic_write(APIC_ICR2, cfg);
/*
* program the ICR
@@ -72,14 +72,24 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write_around(APIC_ICR, cfg);
+ apic_write(APIC_ICR, cfg);
local_irq_restore(flags);
}
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)
@@ -167,9 +177,9 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
struct genapic apic_physflat = {
.name = "physical flat",
- .int_delivery_mode = dest_LowestPrio,
+ .int_delivery_mode = dest_Fixed,
.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
- .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_LOWEST,
+ .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED,
.target_cpus = physflat_target_cpus,
.apic_id_registered = flat_apic_id_registered,
.init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index 98ff5eb32b9a..b92e5f45ed46 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -270,26 +270,26 @@ ENTRY(level3_kernel_pgt)
.org 0x4000
ENTRY(level2_ident_pgt)
/* 40MB for bootup. */
- .quad 0x0000000000000283
- .quad 0x0000000000200183
- .quad 0x0000000000400183
- .quad 0x0000000000600183
- .quad 0x0000000000800183
- .quad 0x0000000000A00183
- .quad 0x0000000000C00183
- .quad 0x0000000000E00183
- .quad 0x0000000001000183
- .quad 0x0000000001200183
- .quad 0x0000000001400183
- .quad 0x0000000001600183
- .quad 0x0000000001800183
- .quad 0x0000000001A00183
- .quad 0x0000000001C00183
- .quad 0x0000000001E00183
- .quad 0x0000000002000183
- .quad 0x0000000002200183
- .quad 0x0000000002400183
- .quad 0x0000000002600183
+ .quad 0x0000000000000083
+ .quad 0x0000000000200083
+ .quad 0x0000000000400083
+ .quad 0x0000000000600083
+ .quad 0x0000000000800083
+ .quad 0x0000000000A00083
+ .quad 0x0000000000C00083
+ .quad 0x0000000000E00083
+ .quad 0x0000000001000083
+ .quad 0x0000000001200083
+ .quad 0x0000000001400083
+ .quad 0x0000000001600083
+ .quad 0x0000000001800083
+ .quad 0x0000000001A00083
+ .quad 0x0000000001C00083
+ .quad 0x0000000001E00083
+ .quad 0x0000000002000083
+ .quad 0x0000000002200083
+ .quad 0x0000000002400083
+ .quad 0x0000000002600083
/* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */
.globl temp_boot_pmds
temp_boot_pmds:
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index a89169095129..b2a238b5a17e 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -18,15 +18,12 @@
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/hw_irq.h>
#include <asm/pgtable.h>
#include <asm/delay.h>
#include <asm/desc.h>
#include <asm/apic.h>
-#include <linux/irq.h>
-
/*
* Common place to define all x86 IRQ vectors
*
@@ -486,7 +483,14 @@ void spurious_interrupt(void);
void error_interrupt(void);
void reschedule_interrupt(void);
void call_function_interrupt(void);
-void invalidate_interrupt(void);
+void invalidate_interrupt0(void);
+void invalidate_interrupt1(void);
+void invalidate_interrupt2(void);
+void invalidate_interrupt3(void);
+void invalidate_interrupt4(void);
+void invalidate_interrupt5(void);
+void invalidate_interrupt6(void);
+void invalidate_interrupt7(void);
void thermal_interrupt(void);
void i8254_timer_resume(void);
@@ -562,8 +566,15 @@ void __init init_IRQ(void)
*/
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
- /* IPI for invalidation */
- set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
+ /* IPIs for invalidation */
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
+ set_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
diff --git a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c
index c4dc91491157..e0ba5c1043fd 100644
--- a/arch/x86_64/kernel/init_task.c
+++ b/arch/x86_64/kernel/init_task.c
@@ -44,6 +44,6 @@ EXPORT_SYMBOL(init_task);
* section. Since TSS's are completely CPU-local, we want them
* on exact cacheline boundaries, to eliminate cacheline ping-pong.
*/
-DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp;
+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS;
#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index ba1a744e9bf0..c8eee20cd519 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -21,7 +21,6 @@
*/
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -45,6 +44,8 @@ int sis_apic_bug; /* not actually supported, dummy for compile */
static int no_timer_check;
+int disable_timer_pin_1 __initdata;
+
static DEFINE_SPINLOCK(ioapic_lock);
/*
@@ -1022,13 +1023,11 @@ void __apicdebuginit print_local_APIC(void * dummy)
v = apic_read(APIC_TASKPRI);
printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
- if (APIC_INTEGRATED(ver)) { /* !82489DX */
- v = apic_read(APIC_ARBPRI);
- printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
- v & APIC_ARBPRI_MASK);
- v = apic_read(APIC_PROCPRI);
- printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
- }
+ v = apic_read(APIC_ARBPRI);
+ printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
+ v & APIC_ARBPRI_MASK);
+ v = apic_read(APIC_PROCPRI);
+ printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
v = apic_read(APIC_EOI);
printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
@@ -1048,12 +1047,8 @@ void __apicdebuginit print_local_APIC(void * dummy)
printk(KERN_DEBUG "... APIC IRR field:\n");
print_APIC_bitfield(APIC_IRR);
- if (APIC_INTEGRATED(ver)) { /* !82489DX */
- if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
- apic_write(APIC_ESR, 0);
- v = apic_read(APIC_ESR);
- printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
- }
+ v = apic_read(APIC_ESR);
+ printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
v = apic_read(APIC_ICR);
printk(KERN_DEBUG "... APIC ICR: %08x\n", v);
@@ -1167,9 +1162,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) {
@@ -1665,6 +1660,8 @@ static inline void check_timer(void)
setup_nmi();
enable_8259A_irq(0);
}
+ if (disable_timer_pin_1 > 0)
+ clear_IO_APIC_pin(0, pin1);
return;
}
clear_IO_APIC_pin(0, pin1);
@@ -1864,7 +1861,7 @@ device_initcall(ioapic_init_sysfs);
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
#define IO_APIC_MAX_ID 0xFE
@@ -1947,7 +1944,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
return 0;
}
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /* CONFIG_ACPI */
/*
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
index 849a20aec7ca..d6a04a8320a3 100644
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -99,7 +99,6 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
unsigned irq = regs->orig_rax & 0xff;
irq_enter();
- BUG_ON(irq > 256);
__do_IRQ(irq, regs);
irq_exit();
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index df08c43276a0..76a28b007be9 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -77,9 +77,9 @@ static inline int is_IF_modifier(kprobe_opcode_t *insn)
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
/* insn: must be on special executable page on x86_64. */
- up(&kprobe_mutex);
- p->ainsn.insn = get_insn_slot();
down(&kprobe_mutex);
+ p->ainsn.insn = get_insn_slot();
+ up(&kprobe_mutex);
if (!p->ainsn.insn) {
return -ENOMEM;
}
@@ -231,9 +231,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- up(&kprobe_mutex);
- free_insn_slot(p->ainsn.insn);
down(&kprobe_mutex);
+ free_insn_slot(p->ainsn.insn);
+ up(&kprobe_mutex);
}
static inline void save_previous_kprobe(void)
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 8aa56736cde3..69541db5ff2c 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/cpu.h>
#include <linux/percpu.h>
+#include <linux/ctype.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/mce.h>
@@ -53,27 +54,35 @@ void mce_log(struct mce *mce)
{
unsigned next, entry;
mce->finished = 0;
- smp_wmb();
+ wmb();
for (;;) {
entry = rcu_dereference(mcelog.next);
- /* When the buffer fills up discard new entries. Assume
- that the earlier errors are the more interesting. */
- if (entry >= MCE_LOG_LEN) {
- set_bit(MCE_OVERFLOW, &mcelog.flags);
- return;
+ /* The rmb forces the compiler to reload next in each
+ iteration */
+ rmb();
+ for (;;) {
+ /* When the buffer fills up discard new entries. Assume
+ that the earlier errors are the more interesting. */
+ if (entry >= MCE_LOG_LEN) {
+ set_bit(MCE_OVERFLOW, &mcelog.flags);
+ return;
+ }
+ /* Old left over entry. Skip. */
+ if (mcelog.entry[entry].finished) {
+ entry++;
+ continue;
+ }
+ break;
}
- /* Old left over entry. Skip. */
- if (mcelog.entry[entry].finished)
- continue;
smp_rmb();
next = entry + 1;
if (cmpxchg(&mcelog.next, entry, next) == entry)
break;
}
memcpy(mcelog.entry + entry, mce, sizeof(struct mce));
- smp_wmb();
+ wmb();
mcelog.entry[entry].finished = 1;
- smp_wmb();
+ wmb();
if (!test_and_set_bit(0, &console_logged))
notify_user = 1;
@@ -212,7 +221,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
panicm_found = 1;
}
- tainted |= TAINT_MACHINE_CHECK;
+ add_taint(TAINT_MACHINE_CHECK);
}
/* Never do anything final in the polling timer */
@@ -404,9 +413,15 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff
}
err = 0;
- for (i = 0; i < next; i++) {
- if (!mcelog.entry[i].finished)
- continue;
+ for (i = 0; i < next; i++) {
+ unsigned long start = jiffies;
+ while (!mcelog.entry[i].finished) {
+ if (!time_before(jiffies, start + 2)) {
+ memset(mcelog.entry + i,0, sizeof(struct mce));
+ continue;
+ }
+ cpu_relax();
+ }
smp_rmb();
err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce));
buf += sizeof(struct mce);
@@ -479,6 +494,7 @@ static int __init mcheck_disable(char *str)
/* mce=off disables machine check. Note you can reenable it later
using sysfs.
+ mce=TOLERANCELEVEL (number, see above)
mce=bootlog Log MCEs from before booting. Disabled by default to work
around buggy BIOS that leave bogus MCEs. */
static int __init mcheck_enable(char *str)
@@ -489,6 +505,8 @@ static int __init mcheck_enable(char *str)
mce_dont_init = 1;
else if (!strcmp(str, "bootlog"))
mce_bootlog = 1;
+ else if (isdigit(str[0]))
+ get_option(&str, &tolerant);
else
printk("mce= argument %s ignored. Please use /sys", str);
return 0;
@@ -501,10 +519,12 @@ __setup("mce", mcheck_enable);
* Sysfs support
*/
-/* On resume clear all MCE state. Don't want to see leftovers from the BIOS. */
+/* On resume clear all MCE state. Don't want to see leftovers from the BIOS.
+ Only one CPU is active at this time, the others get readded later using
+ CPU hotplug. */
static int mce_resume(struct sys_device *dev)
{
- on_each_cpu(mce_init, NULL, 1, 1);
+ mce_init(NULL);
return 0;
}
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 79c362d03e2e..f16d38d09daf 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -14,7 +14,6 @@
*/
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/config.h>
@@ -46,8 +45,6 @@ int acpi_found_madt;
int apic_version [MAX_APICS];
unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-unsigned char pci_bus_to_node [256];
-EXPORT_SYMBOL(pci_bus_to_node);
static int mp_current_pci_id = 0;
/* I/O APIC entries */
@@ -74,7 +71,7 @@ static unsigned int num_processors = 0;
physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
/* ACPI MADT entry parsing functions */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern struct acpi_boot_flags acpi_boot;
#ifdef CONFIG_X86_LOCAL_APIC
extern int acpi_parse_lapic (acpi_table_entry_header *header);
@@ -84,7 +81,7 @@ extern int acpi_parse_lapic_nmi (acpi_table_entry_header *header);
#ifdef CONFIG_X86_IO_APIC
extern int acpi_parse_ioapic (acpi_table_entry_header *header);
#endif /*CONFIG_X86_IO_APIC*/
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /*CONFIG_ACPI*/
u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
@@ -519,8 +516,6 @@ void __init get_smp_config (void)
struct intel_mp_floating *mpf = mpf_found;
/*
- * ACPI may be used to obtain the entire SMP configuration or just to
- * enumerate/configure processors (CONFIG_ACPI_BOOT). Note that
* ACPI supports both logical (e.g. Hyper-Threading) and physical
* processors, where MPS only supports physical.
*/
@@ -673,7 +668,7 @@ void __init find_smp_config (void)
ACPI-based MP Configuration
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
void __init mp_register_lapic_address (
u64 address)
@@ -707,7 +702,7 @@ void __init mp_register_lapic (
processor.mpc_type = MP_PROCESSOR;
processor.mpc_apicid = id;
- processor.mpc_apicver = 0x10; /* TBD: lapic version */
+ processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR));
processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
@@ -929,11 +924,9 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
return gsi;
-#ifdef CONFIG_ACPI_BUS
/* Don't set up the ACPI SCI because it's already set up */
if (acpi_fadt.sci_int == gsi)
return gsi;
-#endif
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0) {
@@ -973,13 +966,11 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
if (gsi < MAX_GSI_NUM) {
if (gsi > 15)
gsi = pci_irq++;
-#ifdef CONFIG_ACPI_BUS
/*
* Don't assign IRQ used by ACPI SCI
*/
if (gsi == acpi_fadt.sci_int)
gsi = pci_irq++;
-#endif
gsi_to_irq[irq] = gsi;
} else {
printk(KERN_ERR "GSI %u is too high\n", gsi);
@@ -994,4 +985,4 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
}
#endif /*CONFIG_X86_IO_APIC*/
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /*CONFIG_ACPI*/
diff --git a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c
deleted file mode 100644
index 598953ab0154..000000000000
--- a/arch/x86_64/kernel/msr.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2000 H. Peter Anvin - 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, Inc., 675 Mass Ave, Cambridge MA 02139,
- * USA; either version 2 of the License, or (at your option) any later
- * version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * msr.c
- *
- * x86 MSR access device
- *
- * This device is accessed by lseek() to the appropriate register number
- * and then read/write in chunks of 8 bytes. A larger size means multiple
- * reads or writes of the same register.
- *
- * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
- * an SMP box will direct the access to CPU %d.
- */
-
-#include <linux/module.h>
-#include <linux/config.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-
-#include <asm/processor.h>
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-/* Note: "err" is handled in a funny way below. Otherwise one version
- of gcc or another breaks. */
-
-static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx)
-{
- int err;
-
- asm volatile ("1: wrmsr\n"
- "2:\n"
- ".section .fixup,\"ax\"\n"
- "3: movl %4,%0\n"
- " jmp 2b\n"
- ".previous\n"
- ".section __ex_table,\"a\"\n"
- " .align 8\n" " .quad 1b,3b\n" ".previous":"=&bDS" (err)
- :"a"(eax), "d"(edx), "c"(reg), "i"(-EIO), "0"(0));
-
- return err;
-}
-
-static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx)
-{
- int err;
-
- asm volatile ("1: rdmsr\n"
- "2:\n"
- ".section .fixup,\"ax\"\n"
- "3: movl %4,%0\n"
- " jmp 2b\n"
- ".previous\n"
- ".section __ex_table,\"a\"\n"
- " .align 8\n"
- " .quad 1b,3b\n"
- ".previous":"=&bDS" (err), "=a"(*eax), "=d"(*edx)
- :"c"(reg), "i"(-EIO), "0"(0));
-
- return err;
-}
-
-#ifdef CONFIG_SMP
-
-struct msr_command {
- int cpu;
- int err;
- u32 reg;
- u32 data[2];
-};
-
-static void msr_smp_wrmsr(void *cmd_block)
-{
- struct msr_command *cmd = (struct msr_command *)cmd_block;
-
- if (cmd->cpu == smp_processor_id())
- cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]);
-}
-
-static void msr_smp_rdmsr(void *cmd_block)
-{
- struct msr_command *cmd = (struct msr_command *)cmd_block;
-
- if (cmd->cpu == smp_processor_id())
- cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]);
-}
-
-static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
-{
- struct msr_command cmd;
- int ret;
-
- preempt_disable();
- if (cpu == smp_processor_id()) {
- ret = wrmsr_eio(reg, eax, edx);
- } else {
- cmd.cpu = cpu;
- cmd.reg = reg;
- cmd.data[0] = eax;
- cmd.data[1] = edx;
-
- smp_call_function(msr_smp_wrmsr, &cmd, 1, 1);
- ret = cmd.err;
- }
- preempt_enable();
- return ret;
-}
-
-static inline int do_rdmsr(int cpu, u32 reg, u32 * eax, u32 * edx)
-{
- struct msr_command cmd;
- int ret;
-
- preempt_disable();
- if (cpu == smp_processor_id()) {
- ret = rdmsr_eio(reg, eax, edx);
- } else {
- cmd.cpu = cpu;
- cmd.reg = reg;
-
- smp_call_function(msr_smp_rdmsr, &cmd, 1, 1);
-
- *eax = cmd.data[0];
- *edx = cmd.data[1];
-
- ret = cmd.err;
- }
- preempt_enable();
- return ret;
-}
-
-#else /* ! CONFIG_SMP */
-
-static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
-{
- return wrmsr_eio(reg, eax, edx);
-}
-
-static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
-{
- return rdmsr_eio(reg, eax, edx);
-}
-
-#endif /* ! CONFIG_SMP */
-
-static loff_t msr_seek(struct file *file, loff_t offset, int orig)
-{
- loff_t ret = -EINVAL;
-
- lock_kernel();
- switch (orig) {
- case 0:
- file->f_pos = offset;
- ret = file->f_pos;
- break;
- case 1:
- file->f_pos += offset;
- ret = file->f_pos;
- }
- unlock_kernel();
- return ret;
-}
-
-static ssize_t msr_read(struct file *file, char __user * buf,
- size_t count, loff_t * ppos)
-{
- u32 __user *tmp = (u32 __user *) buf;
- u32 data[2];
- size_t rv;
- u32 reg = *ppos;
- int cpu = iminor(file->f_dentry->d_inode);
- int err;
-
- if (count % 8)
- return -EINVAL; /* Invalid chunk size */
-
- for (rv = 0; count; count -= 8) {
- err = do_rdmsr(cpu, reg, &data[0], &data[1]);
- if (err)
- return err;
- if (copy_to_user(tmp, &data, 8))
- return -EFAULT;
- tmp += 2;
- }
-
- return ((char __user *)tmp) - buf;
-}
-
-static ssize_t msr_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- const u32 __user *tmp = (const u32 __user *)buf;
- u32 data[2];
- size_t rv;
- u32 reg = *ppos;
- int cpu = iminor(file->f_dentry->d_inode);
- int err;
-
- if (count % 8)
- return -EINVAL; /* Invalid chunk size */
-
- for (rv = 0; count; count -= 8) {
- if (copy_from_user(&data, tmp, 8))
- return -EFAULT;
- err = do_wrmsr(cpu, reg, data[0], data[1]);
- if (err)
- return err;
- tmp += 2;
- }
-
- return ((char __user *)tmp) - buf;
-}
-
-static int msr_open(struct inode *inode, struct file *file)
-{
- unsigned int cpu = iminor(file->f_dentry->d_inode);
- struct cpuinfo_x86 *c = &(cpu_data)[cpu];
-
- if (cpu >= NR_CPUS || !cpu_online(cpu))
- return -ENXIO; /* No such CPU */
- if (!cpu_has(c, X86_FEATURE_MSR))
- return -EIO; /* MSR not supported */
-
- return 0;
-}
-
-/*
- * File operations we support
- */
-static struct file_operations msr_fops = {
- .owner = THIS_MODULE,
- .llseek = msr_seek,
- .read = msr_read,
- .write = msr_write,
- .open = msr_open,
-};
-
-static int __init msr_init(void)
-{
- if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
- printk(KERN_ERR "msr: unable to get major %d for msr\n",
- MSR_MAJOR);
- return -EBUSY;
- }
-
- return 0;
-}
-
-static void __exit msr_exit(void)
-{
- unregister_chrdev(MSR_MAJOR, "cpu/msr");
-}
-
-module_init(msr_init);
-module_exit(msr_exit)
-
-MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
-MODULE_DESCRIPTION("x86 generic MSR driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index caf164959e19..39d445e16f22 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -14,7 +14,6 @@
#include <linux/config.h>
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>
@@ -367,7 +366,7 @@ static void setup_k7_watchdog(void)
| K7_NMI_EVENT;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
- wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
+ wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz));
apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= K7_EVNTSEL_ENABLE;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
@@ -408,8 +407,8 @@ static int setup_p4_watchdog(void)
wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
- Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
- wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
+ Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz * 1000UL / nmi_hz));
+ wrmsrl(MSR_P4_IQ_COUNTER0, -((u64)cpu_khz * 1000 / nmi_hz));
apic_write(APIC_LVTPC, APIC_DM_NMI);
wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
return 1;
@@ -488,8 +487,8 @@ void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
== NOTIFY_STOP) {
local_set(&__get_cpu_var(alert_counter), 0);
return;
- }
- die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs);
+ }
+ die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs);
}
} else {
__get_cpu_var(last_irq_sum) = sum;
@@ -507,7 +506,7 @@ void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
apic_write(APIC_LVTPC, APIC_DM_NMI);
}
- wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
+ wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
}
}
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 57f35c68aa34..88be97c96987 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -187,15 +187,13 @@ static void flush_gart(struct device *dev)
/* Allocate DMA memory on node near device */
noinline
-static void *dma_alloc_pages(struct device *dev, unsigned gfp, unsigned order)
+static void *dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order)
{
struct page *page;
int node;
- if (dev->bus == &pci_bus_type) {
- cpumask_t mask;
- mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
- node = cpu_to_node(first_cpu(mask));
- } else
+ if (dev->bus == &pci_bus_type)
+ node = pcibus_to_node(to_pci_dev(dev)->bus);
+ else
node = numa_node_id();
page = alloc_pages_node(node, gfp, order);
return page ? page_address(page) : NULL;
@@ -206,7 +204,7 @@ static void *dma_alloc_pages(struct device *dev, unsigned gfp, unsigned order)
*/
void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- unsigned gfp)
+ gfp_t gfp)
{
void *memory;
unsigned long dma_mask = 0;
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
index 67d90b89af0b..5a981dca87ff 100644
--- a/arch/x86_64/kernel/pci-nommu.c
+++ b/arch/x86_64/kernel/pci-nommu.c
@@ -24,7 +24,7 @@ EXPORT_SYMBOL(iommu_sac_force);
*/
void *dma_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, unsigned gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
u64 mask;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 8661f82ac70b..b5a89c0bdf59 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -32,7 +32,6 @@
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/ptrace.h>
#include <linux/utsname.h>
#include <linux/random.h>
@@ -123,6 +122,7 @@ static void poll_idle (void)
: :
"i" (_TIF_NEED_RESCHED),
"m" (current_thread_info()->flags));
+ clear_thread_flag(TIF_POLLING_NRFLAG);
} else {
set_need_resched();
}
@@ -271,8 +271,11 @@ void __show_regs(struct pt_regs * regs)
printk("\n");
print_modules();
- printk("Pid: %d, comm: %.20s %s %s\n",
- current->pid, current->comm, print_tainted(), system_utsname.release);
+ printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+ current->pid, current->comm, print_tainted(),
+ system_utsname.release,
+ (int)strcspn(system_utsname.version, " "),
+ system_utsname.version);
printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
printk_address(regs->rip);
printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags);
@@ -483,33 +486,6 @@ out:
}
/*
- * This function selects if the context switch from prev to next
- * has to tweak the TSC disable bit in the cr4.
- */
-static inline void disable_tsc(struct task_struct *prev_p,
- struct task_struct *next_p)
-{
- struct thread_info *prev, *next;
-
- /*
- * gcc should eliminate the ->thread_info dereference if
- * has_secure_computing returns 0 at compile time (SECCOMP=n).
- */
- prev = prev_p->thread_info;
- next = next_p->thread_info;
-
- if (has_secure_computing(prev) || has_secure_computing(next)) {
- /* slow path here */
- if (has_secure_computing(prev) &&
- !has_secure_computing(next)) {
- write_cr4(read_cr4() & ~X86_CR4_TSD);
- } else if (!has_secure_computing(prev) &&
- has_secure_computing(next))
- write_cr4(read_cr4() | X86_CR4_TSD);
- }
-}
-
-/*
* This special macro can be used to load a debugging register
*/
#define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
@@ -627,8 +603,6 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *
}
}
- disable_tsc(prev_p, next_p);
-
return prev_p;
}
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index b356f8e6adfe..cb28df14ff6f 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -71,7 +71,7 @@ unsigned long mmu_cr4_features;
int acpi_disabled;
EXPORT_SYMBOL(acpi_disabled);
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern int __initdata acpi_ht;
extern acpi_interrupt_flags acpi_sci_flags;
int __initdata acpi_force = 0;
@@ -294,7 +294,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
maxcpus = simple_strtoul(from + 8, NULL, 0);
}
#endif
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/* "acpi=off" disables both ACPI table parsing and interpreter init */
if (!memcmp(from, "acpi=off", 8))
disable_acpi();
@@ -336,6 +336,11 @@ static __init void parse_cmdline_early (char ** cmdline_p)
#endif
#endif
+ if (!memcmp(from, "disable_timer_pin_1", 19))
+ disable_timer_pin_1 = 1;
+ if (!memcmp(from, "enable_timer_pin_1", 18))
+ disable_timer_pin_1 = -1;
+
if (!memcmp(from, "nolapic", 7) ||
!memcmp(from, "disableapic", 11))
disable_apic = 1;
@@ -566,7 +571,7 @@ void __init setup_arch(char **cmdline_p)
init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/*
* Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
* Call this early for SRAT node setup.
@@ -658,7 +663,7 @@ void __init setup_arch(char **cmdline_p)
check_ioapic();
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
/*
* Read APIC and some other early information from ACPI tables.
*/
@@ -755,6 +760,24 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
}
}
+#ifdef CONFIG_NUMA
+static int nearby_node(int apicid)
+{
+ int i;
+ for (i = apicid - 1; i >= 0; i--) {
+ int node = apicid_to_node[i];
+ if (node != NUMA_NO_NODE && node_online(node))
+ return node;
+ }
+ for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
+ int node = apicid_to_node[i];
+ if (node != NUMA_NO_NODE && node_online(node))
+ return node;
+ }
+ return first_node(node_online_map); /* Shouldn't happen */
+}
+#endif
+
/*
* On a AMD dual core setup the lower bits of the APIC id distingush the cores.
* Assumes number of cores is a power of two.
@@ -763,8 +786,11 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
int cpu = smp_processor_id();
- int node = 0;
unsigned bits;
+#ifdef CONFIG_NUMA
+ int node = 0;
+ unsigned apicid = phys_proc_id[cpu];
+#endif
bits = 0;
while ((1 << bits) < c->x86_num_cores)
@@ -776,20 +802,32 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
phys_proc_id[cpu] >>= bits;
#ifdef CONFIG_NUMA
- /* When an ACPI SRAT table is available use the mappings from SRAT
- instead. */
- if (acpi_numa <= 0) {
- node = phys_proc_id[cpu];
- if (!node_online(node))
- node = first_node(node_online_map);
- cpu_to_node[cpu] = node;
- } else {
- node = cpu_to_node[cpu];
- }
+ node = phys_proc_id[cpu];
+ if (apicid_to_node[apicid] != NUMA_NO_NODE)
+ node = apicid_to_node[apicid];
+ if (!node_online(node)) {
+ /* Two possibilities here:
+ - The CPU is missing memory and no node was created.
+ In that case try picking one from a nearby CPU
+ - The APIC IDs differ from the HyperTransport node IDs
+ which the K8 northbridge parsing fills in.
+ Assume they are all increased by a constant offset,
+ but in the same order as the HT nodeids.
+ If that doesn't result in a usable node fall back to the
+ path for the previous case. */
+ int ht_nodeid = apicid - (phys_proc_id[0] << bits);
+ if (ht_nodeid >= 0 &&
+ apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
+ node = apicid_to_node[ht_nodeid];
+ /* Pick a nearby node */
+ if (!node_online(node))
+ node = nearby_node(apicid);
+ }
+ cpu_to_node[cpu] = node;
+
+ printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
+ cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
#endif
-
- printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
- cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
#endif
}
@@ -798,6 +836,23 @@ static int __init init_amd(struct cpuinfo_x86 *c)
int r;
int level;
+#ifdef CONFIG_SMP
+ unsigned long value;
+
+ /*
+ * Disable TLB flush filter by setting HWCR.FFDIS on K8
+ * bit 6 of msr C001_0015
+ *
+ * Errata 63 for SH-B3 steppings
+ * Errata 122 for all steppings (F+ have it disabled by default)
+ */
+ if (c->x86 == 15) {
+ rdmsrl(MSR_K8_HWCR, value);
+ value |= 1 << 6;
+ wrmsrl(MSR_K8_HWCR, value);
+ }
+#endif
+
/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
clear_bit(0*32+31, &c->x86_capability);
@@ -909,6 +964,24 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
return 1;
}
+static void srat_detect_node(void)
+{
+#ifdef CONFIG_NUMA
+ unsigned node;
+ int cpu = smp_processor_id();
+
+ /* Don't do the funky fallback heuristics the AMD version employs
+ for now. */
+ node = apicid_to_node[hard_smp_processor_id()];
+ if (node == NUMA_NO_NODE)
+ node = 0;
+ cpu_to_node[cpu] = node;
+
+ if (acpi_numa > 0)
+ printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node);
+#endif
+}
+
static void __cpuinit init_intel(struct cpuinfo_x86 *c)
{
/* Cache sizes */
@@ -927,9 +1000,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
if (c->x86 >= 15)
set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
c->x86_num_cores = intel_num_cpu_cores(c);
+
+ srat_detect_node();
}
-void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
+static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
{
char *v = c->x86_vendor_id;
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index e3ffcacc8c90..79190891fbc5 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -87,6 +87,10 @@ void __init setup_per_cpu_areas(void)
int i;
unsigned long size;
+#ifdef CONFIG_HOTPLUG_CPU
+ prefill_possible_map();
+#endif
+
/* Copy section for each CPU (we discard the original) */
size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
#ifdef CONFIG_MODULES
@@ -94,7 +98,7 @@ void __init setup_per_cpu_areas(void)
size = PERCPU_ENOUGH_ROOM;
#endif
- for (i = 0; i < NR_CPUS; i++) {
+ for_each_cpu_mask (i, cpu_possible_map) {
char *ptr;
if (!NODE_DATA(cpu_to_node(i))) {
@@ -119,7 +123,6 @@ void pda_init(int cpu)
asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
- pda->me = pda;
pda->cpunumber = cpu;
pda->irqcount = -1;
pda->kernelstack =
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index e5958220d6b8..9db9dda161b4 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
@@ -29,6 +28,8 @@
#include <asm/proto.h>
#include <asm/apicdef.h>
+#define __cpuinit __init
+
/*
* Smarter SMP flushing macros.
* c/o Linus Torvalds.
@@ -37,19 +38,41 @@
* writing to user space from interrupts. (Its not allowed anyway).
*
* Optimizations Manfred Spraul <manfred@colorfullife.com>
+ *
+ * More scalable flush, from Andi Kleen
+ *
+ * To avoid global state use 8 different call vectors.
+ * Each CPU uses a specific vector to trigger flushes on other
+ * CPUs. Depending on the received vector the target CPUs look into
+ * the right per cpu variable for the flush data.
+ *
+ * With more than 8 CPUs they are hashed to the 8 available
+ * vectors. The limited global vector space forces us to this right now.
+ * In future when interrupts are split into per CPU domains this could be
+ * fixed, at the cost of triggering multiple IPIs in some cases.
*/
-static cpumask_t flush_cpumask;
-static struct mm_struct * flush_mm;
-static unsigned long flush_va;
-static DEFINE_SPINLOCK(tlbstate_lock);
+union smp_flush_state {
+ struct {
+ cpumask_t flush_cpumask;
+ struct mm_struct *flush_mm;
+ unsigned long flush_va;
#define FLUSH_ALL -1ULL
+ spinlock_t tlbstate_lock;
+ };
+ char pad[SMP_CACHE_BYTES];
+} ____cacheline_aligned;
+
+/* State is put into the per CPU data section, but padded
+ to a full cache line because other CPUs can access it and we don't
+ want false sharing in the per cpu data segment. */
+static DEFINE_PER_CPU(union smp_flush_state, flush_state);
/*
* We cannot call mmdrop() because we are in interrupt context,
* instead update mm->cpu_vm_mask.
*/
-static inline void leave_mm (unsigned long cpu)
+static inline void leave_mm(int cpu)
{
if (read_pda(mmu_state) == TLBSTATE_OK)
BUG();
@@ -101,15 +124,25 @@ static inline void leave_mm (unsigned long cpu)
*
* 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
* 2) Leave the mm if we are in the lazy tlb mode.
+ *
+ * Interrupts are disabled.
*/
-asmlinkage void smp_invalidate_interrupt (void)
+asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
{
- unsigned long cpu;
+ int cpu;
+ int sender;
+ union smp_flush_state *f;
- cpu = get_cpu();
+ cpu = smp_processor_id();
+ /*
+ * orig_rax contains the interrupt vector - 256.
+ * Use that to determine where the sender put the data.
+ */
+ sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
+ f = &per_cpu(flush_state, sender);
- if (!cpu_isset(cpu, flush_cpumask))
+ if (!cpu_isset(cpu, f->flush_cpumask))
goto out;
/*
* This was a BUG() but until someone can quote me the
@@ -120,64 +153,63 @@ asmlinkage void smp_invalidate_interrupt (void)
* BUG();
*/
- if (flush_mm == read_pda(active_mm)) {
+ if (f->flush_mm == read_pda(active_mm)) {
if (read_pda(mmu_state) == TLBSTATE_OK) {
- if (flush_va == FLUSH_ALL)
+ if (f->flush_va == FLUSH_ALL)
local_flush_tlb();
else
- __flush_tlb_one(flush_va);
+ __flush_tlb_one(f->flush_va);
} else
leave_mm(cpu);
}
out:
ack_APIC_irq();
- cpu_clear(cpu, flush_cpumask);
- put_cpu_no_resched();
+ cpu_clear(cpu, f->flush_cpumask);
}
static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
unsigned long va)
{
- cpumask_t tmp;
- /*
- * A couple of (to be removed) sanity checks:
- *
- * - we do not send IPIs to not-yet booted CPUs.
- * - current CPU must not be in mask
- * - mask must exist :)
- */
- BUG_ON(cpus_empty(cpumask));
- cpus_and(tmp, cpumask, cpu_online_map);
- BUG_ON(!cpus_equal(tmp, cpumask));
- BUG_ON(cpu_isset(smp_processor_id(), cpumask));
- if (!mm)
- BUG();
+ int sender;
+ union smp_flush_state *f;
- /*
- * I'm not happy about this global shared spinlock in the
- * MM hot path, but we'll see how contended it is.
- * Temporarily this turns IRQs off, so that lockups are
- * detected by the NMI watchdog.
- */
- spin_lock(&tlbstate_lock);
-
- flush_mm = mm;
- flush_va = va;
- cpus_or(flush_cpumask, cpumask, flush_cpumask);
+ /* Caller has disabled preemption */
+ sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
+ f = &per_cpu(flush_state, sender);
+
+ /* Could avoid this lock when
+ num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
+ probably not worth checking this for a cache-hot lock. */
+ spin_lock(&f->tlbstate_lock);
+
+ f->flush_mm = mm;
+ f->flush_va = va;
+ cpus_or(f->flush_cpumask, cpumask, f->flush_cpumask);
/*
* We have to send the IPI only to
* CPUs affected.
*/
- send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR);
+ send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR_START + sender);
+
+ while (!cpus_empty(f->flush_cpumask))
+ cpu_relax();
- while (!cpus_empty(flush_cpumask))
- mb(); /* nothing. lockup detection does not belong here */;
+ f->flush_mm = NULL;
+ f->flush_va = 0;
+ spin_unlock(&f->tlbstate_lock);
+}
- flush_mm = NULL;
- flush_va = 0;
- spin_unlock(&tlbstate_lock);
+int __cpuinit init_smp_flush(void)
+{
+ int i;
+ for_each_cpu_mask(i, cpu_possible_map) {
+ spin_lock_init(&per_cpu(flush_state.tlbstate_lock, i));
+ }
+ return 0;
}
+
+core_initcall(init_smp_flush);
void flush_tlb_current_task(void)
{
@@ -295,8 +327,11 @@ void unlock_ipi_call_lock(void)
/*
* this function sends a 'generic call function' IPI to one other CPU
* in the system.
+ *
+ * cpu is a standard Linux logical CPU number.
*/
-static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info,
+static void
+__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait)
{
struct call_data_struct data;
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 90aeccd15190..658a81b33f3b 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -44,7 +44,6 @@
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/smp_lock.h>
-#include <linux/irq.h>
#include <linux/bootmem.h>
#include <linux/thread_info.h>
#include <linux/module.h>
@@ -58,6 +57,8 @@
#include <asm/tlbflush.h>
#include <asm/proto.h>
#include <asm/nmi.h>
+#include <asm/irq.h>
+#include <asm/hw_irq.h>
/* Number of siblings per CPU package */
int smp_num_siblings = 1;
@@ -413,8 +414,13 @@ void __cpuinit smp_callin(void)
/*
* Get our bogomips.
+ *
+ * Need to enable IRQs because it can take longer and then
+ * the NMI watchdog might kill us.
*/
+ local_irq_enable();
calibrate_delay();
+ local_irq_disable();
Dprintk("Stack at about %p\n",&cpuid);
disable_APIC_timer();
@@ -540,8 +546,8 @@ static void inquire_remote_apic(int apicid)
*/
apic_wait_icr_idle();
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
- apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
+ apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+ apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
timeout = 0;
do {
@@ -574,12 +580,12 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
/*
* Turn INIT on target chip
*/
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+ apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
/*
* Send IPI
*/
- apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
+ apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
| APIC_DM_INIT);
Dprintk("Waiting for send to finish...\n");
@@ -595,10 +601,10 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
Dprintk("Deasserting INIT.\n");
/* Target chip */
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+ apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
/* Send IPI */
- apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+ apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
Dprintk("Waiting for send to finish...\n");
timeout = 0;
@@ -610,16 +616,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
atomic_set(&init_deasserted, 1);
- /*
- * Should we send STARTUP IPIs ?
- *
- * Determine this based on the APIC version.
- * If we don't have an integrated APIC, don't send the STARTUP IPIs.
- */
- if (APIC_INTEGRATED(apic_version[phys_apicid]))
- num_starts = 2;
- else
- num_starts = 0;
+ num_starts = 2;
/*
* Run STARTUP IPI loop.
@@ -640,12 +637,11 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
*/
/* Target chip */
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+ apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
/* Boot on the stack */
/* Kick the second */
- apic_write_around(APIC_ICR, APIC_DM_STARTUP
- | (start_rip >> 12));
+ apic_write(APIC_ICR, APIC_DM_STARTUP | (start_rip >> 12));
/*
* Give the other CPU some time to accept the IPI.
@@ -864,17 +860,6 @@ static __cpuinit void smp_cleanup_boot(void)
* Reset trampoline flag
*/
*((volatile int *) phys_to_virt(0x467)) = 0;
-
-#ifndef CONFIG_HOTPLUG_CPU
- /*
- * Free pages reserved for SMP bootup.
- * When you add hotplug CPU support later remove this
- * Note there is more work to be done for later CPU bootup.
- */
-
- free_page((unsigned long) __va(PAGE_SIZE));
- free_page((unsigned long) __va(SMP_TRAMPOLINE_BASE));
-#endif
}
/*
@@ -894,23 +879,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
@@ -924,7 +892,7 @@ static __init void enforce_max_cpus(unsigned max_cpus)
* those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range.
* - Ashok Raj
*/
-static void prefill_possible_map(void)
+__init void prefill_possible_map(void)
{
int i;
for (i = 0; i < NR_CPUS; i++)
@@ -999,12 +967,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
-
if (smp_sanity_check(max_cpus) < 0) {
printk(KERN_INFO "SMP disabled\n");
disable_smp();
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
index 0612640d91b1..f066c6ab3618 100644
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -8,24 +8,11 @@
*/
#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/poll.h>
-#include <linux/delay.h>
-#include <linux/sysrq.h>
-#include <linux/proc_fs.h>
-#include <linux/irq.h>
-#include <linux/pm.h>
-#include <linux/device.h>
+#include <linux/smp.h>
#include <linux/suspend.h>
-#include <asm/uaccess.h>
-#include <asm/acpi.h>
-#include <asm/tlbflush.h>
-#include <asm/io.h>
#include <asm/proto.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
struct saved_context saved_context;
@@ -155,4 +142,129 @@ void fix_processor_context(void)
}
+#ifdef CONFIG_SOFTWARE_SUSPEND
+/* Defined in arch/x86_64/kernel/suspend_asm.S */
+extern int restore_image(void);
+pgd_t *temp_level4_pgt;
+
+static void **pages;
+
+static inline void *__add_page(void)
+{
+ void **c;
+
+ c = (void **)get_usable_page(GFP_ATOMIC);
+ if (c) {
+ *c = pages;
+ pages = c;
+ }
+ return c;
+}
+
+static inline void *__next_page(void)
+{
+ void **c;
+
+ c = pages;
+ if (c) {
+ pages = *c;
+ *c = NULL;
+ }
+ return c;
+}
+
+/*
+ * Try to allocate as many usable pages as needed and daisy chain them.
+ * If one allocation fails, free the pages allocated so far
+ */
+static int alloc_usable_pages(unsigned long n)
+{
+ void *p;
+
+ pages = NULL;
+ do
+ if (!__add_page())
+ break;
+ while (--n);
+ if (n) {
+ p = __next_page();
+ while (p) {
+ free_page((unsigned long)p);
+ p = __next_page();
+ }
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
+{
+ long i, j;
+
+ i = pud_index(address);
+ pud = pud + i;
+ for (; i < PTRS_PER_PUD; pud++, i++) {
+ unsigned long paddr;
+ pmd_t *pmd;
+
+ paddr = address + i*PUD_SIZE;
+ if (paddr >= end)
+ break;
+
+ pmd = (pmd_t *)__next_page();
+ set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
+ for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
+ unsigned long pe;
+
+ if (paddr >= end)
+ break;
+ pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr;
+ pe &= __supported_pte_mask;
+ set_pmd(pmd, __pmd(pe));
+ }
+ }
+}
+
+static void set_up_temporary_mappings(void)
+{
+ unsigned long start, end, next;
+
+ temp_level4_pgt = (pgd_t *)__next_page();
+
+ /* It is safe to reuse the original kernel mapping */
+ set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
+ init_level4_pgt[pgd_index(__START_KERNEL_map)]);
+
+ /* Set up the direct mapping from scratch */
+ start = (unsigned long)pfn_to_kaddr(0);
+ end = (unsigned long)pfn_to_kaddr(end_pfn);
+
+ for (; start < end; start = next) {
+ pud_t *pud = (pud_t *)__next_page();
+ next = start + PGDIR_SIZE;
+ if (next > end)
+ next = end;
+ res_phys_pud_init(pud, __pa(start), __pa(next));
+ set_pgd(temp_level4_pgt + pgd_index(start),
+ mk_kernel_pgd(__pa(pud)));
+ }
+}
+
+int swsusp_arch_resume(void)
+{
+ unsigned long n;
+
+ n = ((end_pfn << PAGE_SHIFT) + PUD_SIZE - 1) >> PUD_SHIFT;
+ n += (n + PTRS_PER_PUD - 1) / PTRS_PER_PUD + 1;
+ pr_debug("swsusp_arch_resume(): pages needed = %lu\n", n);
+ if (alloc_usable_pages(n)) {
+ free_eaten_memory();
+ return -ENOMEM;
+ }
+ /* We have got enough memory and from now on we cannot recover */
+ set_up_temporary_mappings();
+ restore_image();
+ return 0;
+}
+#endif /* CONFIG_SOFTWARE_SUSPEND */
diff --git a/arch/x86_64/kernel/suspend_asm.S b/arch/x86_64/kernel/suspend_asm.S
index 53f8e1659511..320b6fb00cca 100644
--- a/arch/x86_64/kernel/suspend_asm.S
+++ b/arch/x86_64/kernel/suspend_asm.S
@@ -14,7 +14,7 @@
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/page.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
ENTRY(swsusp_arch_suspend)
@@ -39,12 +39,13 @@ ENTRY(swsusp_arch_suspend)
call swsusp_save
ret
-ENTRY(swsusp_arch_resume)
- /* set up cr3 */
- leaq init_level4_pgt(%rip),%rax
- subq $__START_KERNEL_map,%rax
- movq %rax,%cr3
-
+ENTRY(restore_image)
+ /* switch to temporary page tables */
+ movq $__PAGE_OFFSET, %rdx
+ movq temp_level4_pgt(%rip), %rax
+ subq %rdx, %rax
+ movq %rax, %cr3
+ /* Flush TLB */
movq mmu_cr4_features(%rip), %rax
movq %rax, %rdx
andq $~(1<<7), %rdx # PGE
@@ -69,6 +70,10 @@ loop:
movq pbe_next(%rdx), %rdx
jmp loop
done:
+ /* go back to the original page tables */
+ leaq init_level4_pgt(%rip), %rax
+ subq $__START_KERNEL_map, %rax
+ movq %rax, %cr3
/* Flush TLB, including "global" things (vmalloc) */
movq mmu_cr4_features(%rip), %rax
movq %rax, %rdx
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 7b6abe058253..703acde2a1a5 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -18,7 +18,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/mc146818rtc.h>
-#include <linux/irq.h>
#include <linux/time.h>
#include <linux/ioport.h>
#include <linux/module.h>
@@ -937,7 +936,6 @@ void __init time_init(void)
vxtime.mode = VXTIME_TSC;
vxtime.quot = (1000000L << 32) / vxtime_hz;
vxtime.tsc_quot = (1000L << 32) / cpu_khz;
- vxtime.hz = vxtime_hz;
rdtscll_sync(&vxtime.last_tsc);
setup_irq(0, &irq0);
@@ -961,9 +959,6 @@ static __init int unsynchronized_tsc(void)
are handled in the OEM check above. */
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
return 0;
- /* All in a single socket - should be synchronized */
- if (cpus_weight(cpu_core_map[0]) == num_online_cpus())
- return 0;
#endif
/* Assume multi socket systems are not synchronized */
return num_online_cpus() > 1;
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index f238d6078a5a..b5e09e6b5536 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -47,9 +47,6 @@
#include <asm/proto.h>
#include <asm/nmi.h>
-#include <linux/irq.h>
-
-
extern struct gate_struct idt_table[256];
asmlinkage void divide_error(void);
@@ -324,13 +321,13 @@ void handle_BUG(struct pt_regs *regs)
if (__copy_from_user(&f, (struct bug_frame *) regs->rip,
sizeof(struct bug_frame)))
return;
- if ((unsigned long)f.filename < __PAGE_OFFSET ||
+ if (f.filename >= 0 ||
f.ud2[0] != 0x0f || f.ud2[1] != 0x0b)
return;
- if (__get_user(tmp, f.filename))
- f.filename = "unmapped filename";
+ if (__get_user(tmp, (char *)(long)f.filename))
+ f.filename = (int)(long)"unmapped filename";
printk("----------- [cut here ] --------- [please bite here ] ---------\n");
- printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line);
+ printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", (char *)(long)f.filename, f.line);
}
#ifdef CONFIG_BUG
@@ -343,30 +340,33 @@ void out_of_line_bug(void)
static DEFINE_SPINLOCK(die_lock);
static int die_owner = -1;
-void oops_begin(void)
+unsigned long oops_begin(void)
{
- int cpu = safe_smp_processor_id();
- /* racy, but better than risking deadlock. */
- local_irq_disable();
+ int cpu = safe_smp_processor_id();
+ unsigned long flags;
+
+ /* racy, but better than risking deadlock. */
+ local_irq_save(flags);
if (!spin_trylock(&die_lock)) {
if (cpu == die_owner)
/* nested oops. should stop eventually */;
else
- spin_lock(&die_lock);
+ spin_lock(&die_lock);
}
- die_owner = cpu;
+ die_owner = cpu;
console_verbose();
- bust_spinlocks(1);
+ bust_spinlocks(1);
+ return flags;
}
-void oops_end(void)
+void oops_end(unsigned long flags)
{
die_owner = -1;
- bust_spinlocks(0);
- spin_unlock(&die_lock);
+ bust_spinlocks(0);
+ spin_unlock_irqrestore(&die_lock, flags);
if (panic_on_oops)
- panic("Oops");
-}
+ panic("Oops");
+}
void __die(const char * str, struct pt_regs * regs, long err)
{
@@ -392,10 +392,11 @@ void __die(const char * str, struct pt_regs * regs, long err)
void die(const char * str, struct pt_regs * regs, long err)
{
- oops_begin();
+ unsigned long flags = oops_begin();
+
handle_BUG(regs);
__die(str, regs, err);
- oops_end();
+ oops_end(flags);
do_exit(SIGSEGV);
}
static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
@@ -406,7 +407,8 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e
void die_nmi(char *str, struct pt_regs *regs)
{
- oops_begin();
+ unsigned long flags = oops_begin();
+
/*
* We are in trouble anyway, lets at least try
* to get a message out.
@@ -416,7 +418,7 @@ void die_nmi(char *str, struct pt_regs *regs)
if (panic_on_timeout || panic_on_oops)
panic("nmi watchdog");
printk("console shuts up ...\n");
- oops_end();
+ oops_end(flags);
do_exit(SIGSEGV);
}
@@ -790,13 +792,16 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
*/
cwd = get_fpu_cwd(task);
swd = get_fpu_swd(task);
- switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
+ switch (swd & ~cwd & 0x3f) {
case 0x000:
default:
break;
case 0x001: /* Invalid Op */
- case 0x041: /* Stack Fault */
- case 0x241: /* Stack Fault | Direction */
+ /*
+ * swd & 0x240 == 0x040: Stack Underflow
+ * swd & 0x240 == 0x240: Stack Overflow
+ * User must clear the SF bit (0x40) if set
+ */
info.si_code = FPE_FLTINV;
break;
case 0x002: /* Denormalize */
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index d4abb07af52d..6dd642cad2ef 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -194,20 +194,7 @@ SECTIONS
#endif
}
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-
-
- .comment 0 : { *(.comment) }
+ STABS_DEBUG
+
+ DWARF_DEBUG
}
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index 2e5734425949..70a0bd16085f 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -107,7 +107,7 @@ static force_inline long time_syscall(long *t)
return secs;
}
-static int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
+int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
{
if (unlikely(!__sysctl_vsyscall))
return gettimeofday(tv,tz);
@@ -120,7 +120,7 @@ static int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz
/* This will break when the xtime seconds get inaccurate, but that is
* unlikely */
-static time_t __vsyscall(1) vtime(time_t *t)
+time_t __vsyscall(1) vtime(time_t *t)
{
if (unlikely(!__sysctl_vsyscall))
return time_syscall(t);
@@ -129,12 +129,12 @@ static time_t __vsyscall(1) vtime(time_t *t)
return __xtime.tv_sec;
}
-static long __vsyscall(2) venosys_0(void)
+long __vsyscall(2) venosys_0(void)
{
return -ENOSYS;
}
-static long __vsyscall(3) venosys_1(void)
+long __vsyscall(3) venosys_1(void)
{
return -ENOSYS;
}
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 68ec03070e5a..fd99ddd009bc 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -178,10 +178,6 @@ EXPORT_SYMBOL(rwsem_down_write_failed_thunk);
EXPORT_SYMBOL(empty_zero_page);
-#ifdef CONFIG_HAVE_DEC_LOCK
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif
-
EXPORT_SYMBOL(die_chain);
EXPORT_SYMBOL(register_die_notifier);
diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
index 6b26a1c1e9ff..bba5db6cebd6 100644
--- a/arch/x86_64/lib/Makefile
+++ b/arch/x86_64/lib/Makefile
@@ -10,5 +10,3 @@ lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
usercopy.o getuser.o putuser.o \
thunk.o clear_page.o copy_page.o bitstr.o bitops.o
lib-y += memcpy.o memmove.o memset.o copy_user.o
-
-lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff --git a/arch/x86_64/lib/copy_user.S b/arch/x86_64/lib/copy_user.S
index bd556c804248..dfa358b05c89 100644
--- a/arch/x86_64/lib/copy_user.S
+++ b/arch/x86_64/lib/copy_user.S
@@ -7,7 +7,7 @@
#define FIX_ALIGNMENT 1
#include <asm/current.h>
- #include <asm/offset.h>
+ #include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/cpufeature.h>
diff --git a/arch/x86_64/lib/dec_and_lock.c b/arch/x86_64/lib/dec_and_lock.c
deleted file mode 100644
index ab43394dc775..000000000000
--- a/arch/x86_64/lib/dec_and_lock.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * x86 version of "atomic_dec_and_lock()" using
- * the atomic "cmpxchg" instruction.
- *
- * (For CPU's lacking cmpxchg, we use the slow
- * generic version, and this one never even gets
- * compiled).
- */
-
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-
-int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-{
- int counter;
- int newcount;
-
-repeat:
- counter = atomic_read(atomic);
- newcount = counter-1;
-
- if (!newcount)
- goto slow_path;
-
- asm volatile("lock; cmpxchgl %1,%2"
- :"=a" (newcount)
- :"r" (newcount), "m" (atomic->counter), "0" (counter));
-
- /* If the above failed, "eax" will have changed */
- if (newcount != counter)
- goto repeat;
- return 0;
-
-slow_path:
- spin_lock(lock);
- if (atomic_dec_and_test(atomic))
- return 1;
- spin_unlock(lock);
- return 0;
-}
diff --git a/arch/x86_64/lib/getuser.S b/arch/x86_64/lib/getuser.S
index f80bafee8669..3844d5e885a4 100644
--- a/arch/x86_64/lib/getuser.S
+++ b/arch/x86_64/lib/getuser.S
@@ -29,7 +29,7 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/errno.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
.text
diff --git a/arch/x86_64/lib/putuser.S b/arch/x86_64/lib/putuser.S
index 5828b8191667..7f5593974e2d 100644
--- a/arch/x86_64/lib/putuser.S
+++ b/arch/x86_64/lib/putuser.S
@@ -27,7 +27,7 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/errno.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
.text
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 816732d8858c..b75b872ec154 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -221,12 +221,13 @@ int unhandled_signal(struct task_struct *tsk, int sig)
static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
unsigned long error_code)
{
- oops_begin();
+ unsigned long flags = oops_begin();
+
printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
current->comm, address);
dump_pagetable(address);
__die("Bad pagetable", regs, error_code);
- oops_end();
+ oops_end(flags);
do_exit(SIGKILL);
}
@@ -304,6 +305,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
unsigned long address;
const struct exception_table_entry *fixup;
int write;
+ unsigned long flags;
siginfo_t info;
#ifdef CONFIG_CHECKING
@@ -521,7 +523,7 @@ no_context:
* terminate things with extreme prejudice.
*/
- oops_begin();
+ flags = oops_begin();
if (address < PAGE_SIZE)
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
@@ -534,7 +536,7 @@ no_context:
__die("Oops", regs, error_code);
/* Executive summary in case the body of the oops scrolled away */
printk(KERN_EMERG "CR2: %016lx\n", address);
- oops_end();
+ oops_end(flags);
do_exit(SIGKILL);
/*
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index aa4a5189ecee..e60a1a848de8 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -57,31 +57,31 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
void show_mem(void)
{
- int i, total = 0, reserved = 0;
- int shared = 0, cached = 0;
+ long i, total = 0, reserved = 0;
+ long shared = 0, cached = 0;
pg_data_t *pgdat;
struct page *page;
- printk("Mem-info:\n");
+ printk(KERN_INFO "Mem-info:\n");
show_free_areas();
- printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pfn_to_page(pgdat->node_start_pfn + i);
total++;
- if (PageReserved(page))
- reserved++;
- else if (PageSwapCache(page))
- cached++;
- else if (page_count(page))
- shared += page_count(page) - 1;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (page_count(page))
+ shared += page_count(page) - 1;
}
}
- printk("%d pages of RAM\n", total);
- printk("%d reserved pages\n",reserved);
- printk("%d pages shared\n",shared);
- printk("%d pages swap cached\n",cached);
+ printk(KERN_INFO "%lu pages of RAM\n", total);
+ printk(KERN_INFO "%lu reserved pages\n",reserved);
+ printk(KERN_INFO "%lu pages shared\n",shared);
+ printk(KERN_INFO "%lu pages swap cached\n",cached);
}
/* References to section boundaries */
@@ -381,41 +381,14 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size)
__flush_tlb_all();
}
-static inline int page_is_ram (unsigned long pagenr)
-{
- int i;
-
- for (i = 0; i < e820.nr_map; i++) {
- unsigned long addr, end;
-
- if (e820.map[i].type != E820_RAM) /* not usable memory */
- continue;
- /*
- * !!!FIXME!!! Some BIOSen report areas as RAM that
- * are not. Notably the 640->1Mb area. We need a sanity
- * check here.
- */
- addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
- end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
- if ((pagenr >= addr) && (pagenr < end))
- return 1;
- }
- return 0;
-}
-
-extern int swiotlb_force;
-
static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
kcore_vsyscall;
void __init mem_init(void)
{
- int codesize, reservedpages, datasize, initsize;
- int tmp;
+ long codesize, reservedpages, datasize, initsize;
#ifdef CONFIG_SWIOTLB
- if (swiotlb_force)
- swiotlb = 1;
if (!iommu_aperture &&
(end_pfn >= 0xffffffff>>PAGE_SHIFT || force_iommu))
swiotlb = 1;
@@ -436,25 +409,11 @@ void __init mem_init(void)
/* this will put all low memory onto the freelists */
#ifdef CONFIG_NUMA
- totalram_pages += numa_free_all_bootmem();
- tmp = 0;
- /* should count reserved pages here for all nodes */
+ totalram_pages = numa_free_all_bootmem();
#else
-
-#ifdef CONFIG_FLATMEM
- max_mapnr = end_pfn;
- if (!mem_map) BUG();
-#endif
-
- totalram_pages += free_all_bootmem();
-
- for (tmp = 0; tmp < end_pfn; tmp++)
- /*
- * Only count reserved RAM pages
- */
- if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
- reservedpages++;
+ totalram_pages = free_all_bootmem();
#endif
+ reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
after_bootmem = 1;
@@ -471,7 +430,7 @@ void __init mem_init(void)
kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
VSYSCALL_END - VSYSCALL_START);
- printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+ printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
end_pfn << (PAGE_SHIFT-10),
codesize >> 10,
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index ec35747aacd7..65417b040c1b 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -45,10 +45,12 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
unsigned long prevbase;
struct node nodes[8];
int nodeid, i, nb;
+ unsigned char nodeids[8];
int found = 0;
u32 reg;
unsigned numnodes;
nodemask_t nodes_parsed;
+ unsigned dualcore = 0;
nodes_clear(nodes_parsed);
@@ -67,11 +69,15 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
prevbase = 0;
for (i = 0; i < 8; i++) {
unsigned long base,limit;
-
+ u32 nodeid;
+
+ /* Undefined before E stepping, but hopefully 0 */
+ dualcore |= ((read_pci_config(0, nb, 3, 0xe8) >> 12) & 3) == 1;
base = read_pci_config(0, nb, 1, 0x40 + i*8);
limit = read_pci_config(0, nb, 1, 0x44 + i*8);
nodeid = limit & 7;
+ nodeids[i] = nodeid;
if ((base & 3) == 0) {
if (i < numnodes)
printk("Skipping disabled node %d\n", i);
@@ -157,8 +163,9 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
for (i = 0; i < 8; i++) {
if (nodes[i].start != nodes[i].end) {
- /* assume 1:1 NODE:CPU */
- cpu_to_node[i] = i;
+ nodeid = nodeids[i];
+ apicid_to_node[nodeid << dualcore] = i;
+ apicid_to_node[(nodeid << dualcore) + dualcore] = i;
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
}
}
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 04f7a33e144c..214803821001 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -28,8 +28,13 @@ bootmem_data_t plat_node_bdata[MAX_NUMNODES];
int memnode_shift;
u8 memnodemap[NODEMAPSIZE];
-unsigned char cpu_to_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
-cpumask_t node_to_cpumask[MAX_NUMNODES] __read_mostly;
+unsigned char cpu_to_node[NR_CPUS] __read_mostly = {
+ [0 ... NR_CPUS-1] = NUMA_NO_NODE
+};
+unsigned char apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
+ [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
+};
+cpumask_t node_to_cpumask[MAX_NUMNODES] __read_mostly;
int numa_off __initdata;
@@ -162,18 +167,16 @@ void __init numa_init_array(void)
mapping. To avoid this fill in the mapping for all possible
CPUs, as the number of CPUs is not known yet.
We round robin the existing nodes. */
- rr = 0;
+ rr = first_node(node_online_map);
for (i = 0; i < NR_CPUS; i++) {
if (cpu_to_node[i] != NUMA_NO_NODE)
continue;
+ cpu_to_node[i] = rr;
rr = next_node(rr, node_online_map);
if (rr == MAX_NUMNODES)
rr = first_node(node_online_map);
- cpu_to_node[i] = rr;
- rr++;
}
- set_bit(0, &node_to_cpumask[cpu_to_node(0)]);
}
#ifdef CONFIG_NUMA_EMU
@@ -261,9 +264,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
__cpuinit void numa_add_cpu(int cpu)
{
- /* BP is initialized elsewhere */
- if (cpu)
- set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
+ set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
}
unsigned long __init numa_free_all_bootmem(void)
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 94862e1ec032..b90e8fe9eeb0 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -220,8 +220,6 @@ void global_flush_tlb(void)
down_read(&init_mm.mmap_sem);
df = xchg(&df_list, NULL);
up_read(&init_mm.mmap_sem);
- if (!df)
- return;
flush_map((df && !df->next) ? df->address : 0);
for (; df; df = next_df) {
next_df = df->next;
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 8e3d097a9ddd..4b2e844c15a7 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -20,14 +20,20 @@
static struct acpi_table_slit *acpi_slit;
-/* Internal processor count */
-static unsigned int __initdata num_processors = 0;
-
static nodemask_t nodes_parsed __initdata;
static nodemask_t nodes_found __initdata;
static struct node nodes[MAX_NUMNODES] __initdata;
static __u8 pxm2node[256] = { [0 ... 255] = 0xff };
+static int node_to_pxm(int n);
+
+int pxm_to_node(int pxm)
+{
+ if ((unsigned)pxm >= 256)
+ return 0;
+ return pxm2node[pxm];
+}
+
static __init int setup_node(int pxm)
{
unsigned node = pxm2node[pxm];
@@ -44,14 +50,14 @@ static __init int setup_node(int pxm)
static __init int conflicting_nodes(unsigned long start, unsigned long end)
{
int i;
- for_each_online_node(i) {
+ for_each_node_mask(i, nodes_parsed) {
struct node *nd = &nodes[i];
if (nd->start == nd->end)
continue;
if (nd->end > start && nd->start < end)
- return 1;
+ return i;
if (nd->end == end && nd->start == start)
- return 1;
+ return i;
}
return -1;
}
@@ -75,8 +81,11 @@ static __init void cutoff_node(int i, unsigned long start, unsigned long end)
static __init void bad_srat(void)
{
+ int i;
printk(KERN_ERR "SRAT: SRAT not used.\n");
acpi_numa = -1;
+ for (i = 0; i < MAX_LOCAL_APIC; i++)
+ apicid_to_node[i] = NUMA_NO_NODE;
}
static __init inline int srat_disabled(void)
@@ -104,18 +113,10 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
bad_srat();
return;
}
- if (num_processors >= NR_CPUS) {
- printk(KERN_ERR "SRAT: Processor #%d (lapic %u) INVALID. (Max ID: %d).\n",
- num_processors, pa->apic_id, NR_CPUS);
- bad_srat();
- return;
- }
- cpu_to_node[num_processors] = node;
+ apicid_to_node[pa->apic_id] = node;
acpi_numa = 1;
- printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> CPU %u -> Node %u\n",
- pxm, pa->apic_id, num_processors, node);
-
- num_processors++;
+ printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+ pxm, pa->apic_id, node);
}
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
@@ -143,10 +144,15 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n",
start, end);
i = conflicting_nodes(start, end);
- if (i >= 0) {
+ if (i == node) {
+ printk(KERN_WARNING
+ "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n",
+ pxm, start, end, nodes[i].start, nodes[i].end);
+ } else if (i >= 0) {
printk(KERN_ERR
- "SRAT: pxm %d overlap %lx-%lx with node %d(%Lx-%Lx)\n",
- pxm, start, end, i, nodes[i].start, nodes[i].end);
+ "SRAT: PXM %d (%lx-%lx) overlaps with PXM %d (%Lx-%Lx)\n",
+ pxm, start, end, node_to_pxm(i),
+ nodes[i].start, nodes[i].end);
bad_srat();
return;
}
@@ -174,6 +180,14 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
int i;
if (acpi_numa <= 0)
return -1;
+
+ /* First clean up the node list */
+ for_each_node_mask(i, nodes_parsed) {
+ cutoff_node(i, start, end);
+ if (nodes[i].start == nodes[i].end)
+ node_clear(i, nodes_parsed);
+ }
+
memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
if (memnode_shift < 0) {
printk(KERN_ERR
@@ -181,16 +195,10 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
bad_srat();
return -1;
}
- for (i = 0; i < MAX_NUMNODES; i++) {
- if (!node_isset(i, nodes_parsed))
- continue;
- cutoff_node(i, start, end);
- if (nodes[i].start == nodes[i].end) {
- node_clear(i, nodes_parsed);
- continue;
- }
+
+ /* Finally register nodes */
+ for_each_node_mask(i, nodes_parsed)
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
- }
for (i = 0; i < NR_CPUS; i++) {
if (cpu_to_node[i] == NUMA_NO_NODE)
continue;
@@ -201,7 +209,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
return 0;
}
-int node_to_pxm(int n)
+static int node_to_pxm(int n)
{
int i;
if (pxm2node[n] == n)
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
index 37c92e841dec..bb34e5ef916c 100644
--- a/arch/x86_64/pci/Makefile
+++ b/arch/x86_64/pci/Makefile
@@ -8,7 +8,7 @@ CFLAGS += -Iarch/i386/pci
obj-y := i386.o
obj-$(CONFIG_PCI_DIRECT)+= direct.o
obj-y += fixup.o
-obj-$(CONFIG_ACPI_PCI) += acpi.o
+obj-$(CONFIG_ACPI) += acpi.o
obj-y += legacy.o irq.o common.o
# mmconfig has a 64bit special
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o
diff --git a/arch/x86_64/pci/Makefile-BUS b/arch/x86_64/pci/Makefile-BUS
index 291985f0d2e4..4f0c05abd408 100644
--- a/arch/x86_64/pci/Makefile-BUS
+++ b/arch/x86_64/pci/Makefile-BUS
@@ -8,7 +8,7 @@ CFLAGS += -I arch/i386/pci
obj-y := i386.o
obj-$(CONFIG_PCI_DIRECT)+= direct.o
obj-y += fixup.o
-obj-$(CONFIG_ACPI_PCI) += acpi.o
+obj-$(CONFIG_ACPI) += acpi.o
obj-y += legacy.o irq.o common.o
# mmconfig has a 64bit special
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c
index d80c323669e0..3acf60ded2a0 100644
--- a/arch/x86_64/pci/k8-bus.c
+++ b/arch/x86_64/pci/k8-bus.c
@@ -58,10 +58,16 @@ fill_mp_bus_to_cpumask(void)
for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
j++) {
- int node = NODE_ID(nid);
+ struct pci_bus *bus;
+ long node = NODE_ID(nid);
+ /* Algorithm a bit dumb, but
+ it shouldn't matter here */
+ bus = pci_find_bus(0, j);
+ if (!bus)
+ continue;
if (!node_online(node))
node = 0;
- pci_bus_to_node[j] = node;
+ bus->sysdata = (void *)node;
}
}
}
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index 657e88aa0902..a0838c4a94e4 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -111,13 +111,6 @@ static int __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0))
return 0;
- /* Kludge for now. Don't use mmconfig on AMD systems because
- those have some busses where mmconfig doesn't work,
- and we don't parse ACPI MCFG well enough to handle that.
- Remove when proper handling is added. */
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
- return 0;
-
/* RED-PEN i386 doesn't do _nocache right now */
pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
if (pci_mmcfg_virt == NULL) {
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 2b6257bec4c3..7e841aa2a4aa 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -26,10 +26,6 @@ config RWSEM_XCHGADD_ALGORITHM
bool
default y
-config HAVE_DEC_LOCK
- bool
- default y
-
config GENERIC_HARDIRQS
bool
default y
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 27847e4ffcbf..98fac8489aed 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -66,13 +66,7 @@ boot := arch/xtensa/boot
archinc := include/asm-xtensa
-arch/xtensa/kernel/asm-offsets.s: \
- arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform
-
-include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s
- $(call filechk,gen-asm-offsets)
-
-prepare: $(archinc)/.platform $(archinc)/offsets.h
+archprepare: $(archinc)/.platform
# Update machine cpu and platform symlinks if something which affects
# them changed.
@@ -94,7 +88,7 @@ bzImage : zImage
zImage zImage.initrd: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
-CLEAN_FILES += arch/xtensa/vmlinux.lds $(archinc)/offset.h \
+CLEAN_FILES += arch/xtensa/vmlinux.lds \
$(archinc)/platform $(archinc)/xtensa/config \
$(archinc)/.platform
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S
index 74b1e90ef08c..a4956578a24d 100644
--- a/arch/xtensa/kernel/align.S
+++ b/arch/xtensa/kernel/align.S
@@ -19,7 +19,7 @@
#include <asm/ptrace.h>
#include <asm/ptrace.h>
#include <asm/current.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/page.h>
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index c64a01f71de6..5c018c503dfa 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -14,7 +14,7 @@
*/
#include <linux/linkage.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/processor.h>
#include <asm/thread_info.h>
#include <asm/uaccess.h>
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 84fde258cf85..1ff82268e8ea 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -29,7 +29,7 @@
*/
void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 09887c96e9a1..de19501aa809 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -402,8 +402,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
__pci_mmap_set_flags(dev, vma, mmap_state);
__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
- ret = io_remap_page_range(vma, vma->vm_start, vma->vm_pgoff<<PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot);
+ ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,vma->vm_page_prot);
return ret;
}
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index cf1362784443..03674daabc66 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -39,7 +39,7 @@ _F(int, pcibios_fixup, (void), { return 0; });
_F(int, get_rtc_time, (time_t* t), { return 0; });
_F(int, set_rtc_time, (time_t t), { return 0; });
-#if CONFIG_XTENSA_CALIBRATE_CCOUNT
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
_F(void, calibrate_ccount, (void),
{
printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 4099703b14be..08ef6d82ee51 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -43,7 +43,7 @@
#include <asm/mmu.h>
#include <asm/irq.h>
#include <asm/atomic.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/coprocessor.h>
extern void ret_from_fork(void);
@@ -457,7 +457,7 @@ int
dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
{
/* see asm/coprocessor.h for this magic number 16 */
-#if TOTAL_CPEXTRA_SIZE > 16
+#if XTENSA_CP_EXTRA_SIZE > 16
do_save_fpregs (r, regs, task);
/* For now, bit 16 means some extra state may be present: */
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 1f5bf5d624e4..513ed8d67766 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
# endif
#endif
-#if CONFIG_PCI
+#ifdef CONFIG_PCI
platform_pcibios_init();
#endif
}
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index dc42cede9394..e252b61e45a5 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -182,7 +182,7 @@ restore_cpextra (struct _cpstate *buf)
struct task_struct *tsk = current;
release_all_cp(tsk);
- return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE);
+ return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE);
#endif
return 0;
}
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 1ac7d5ce7456..8e423d1335ce 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -68,7 +68,7 @@ void __init time_init(void)
* speed for the CALIBRATE.
*/
-#if CONFIG_XTENSA_CALIBRATE_CCOUNT
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
printk("Calibrating CPU frequency ");
platform_calibrate_ccount();
printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 81808f0c6742..0e74397bfa2b 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -46,7 +46,7 @@
#include <asm/ptrace.h>
#include <asm/ptrace.h>
#include <asm/current.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/page.h>
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 56aace84aaeb..5a91d6c9e66d 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -239,7 +239,7 @@ void __init mem_init(void)
high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
highmemsize = 0;
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
#error HIGHGMEM not implemented in init.c
#endif
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 46d655fab115..48f446d3c671 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -4,6 +4,8 @@ menu "Device Drivers"
source "drivers/base/Kconfig"
+source "drivers/connector/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 9663132ed825..1a109a6dd953 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -8,7 +8,7 @@
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/
obj-y += video/
-obj-$(CONFIG_ACPI_BOOT) += acpi/
+obj-$(CONFIG_ACPI) += acpi/
# PnP must come after ACPI since it will eventually need to check if acpi
# was used and do nothing if so
obj-$(CONFIG_PNP) += pnp/
@@ -17,6 +17,8 @@ obj-$(CONFIG_PNP) += pnp/
# default.
obj-y += char/
+obj-$(CONFIG_CONNECTOR) += connector/
+
# i810fb and intelfb depend on char/agp/
obj-$(CONFIG_FB_I810) += video/i810/
obj-$(CONFIG_FB_INTEL) += video/intelfb/
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index c0a37d98b4f3..048542341204 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -376,19 +376,15 @@ static void do_fd_request(request_queue_t *);
/************************* 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/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
index 141b4c237a50..2b850e5860a0 100644
--- a/drivers/acorn/char/pcf8583.c
+++ b/drivers/acorn/char/pcf8583.c
@@ -23,12 +23,13 @@ static struct i2c_driver pcf8583_driver;
static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
+static unsigned short *forces[] = { NULL };
static struct i2c_client_address_data addr_data = {
.normal_i2c = normal_addr,
.probe = ignore,
.ignore = ignore,
- .force = ignore,
+ .forces = forces,
};
#define DAT(x) ((unsigned int)(x->dev.driver_data))
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index ba13896cae40..fe1e8126fbae 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -3,7 +3,6 @@
#
menu "ACPI (Advanced Configuration and Power Interface) Support"
- depends on PM
depends on !X86_VISWS
depends on !IA64_HP_SIM
depends on IA64 || X86
@@ -11,6 +10,8 @@ menu "ACPI (Advanced Configuration and Power Interface) Support"
config ACPI
bool "ACPI Support"
depends on IA64 || X86
+ select PM
+ select PCI
default y
---help---
@@ -43,20 +44,10 @@ config ACPI
if ACPI
-config ACPI_BOOT
- bool
- default y
-
-config ACPI_INTERPRETER
- bool
- default y
-
-if ACPI_INTERPRETER
-
config ACPI_SLEEP
- bool "Sleep States (EXPERIMENTAL)"
+ bool "Sleep States"
depends on X86 && (!SMP || SUSPEND_SMP)
- depends on EXPERIMENTAL && PM
+ depends on PM
default y
---help---
This option adds support for ACPI suspend states.
@@ -90,16 +81,16 @@ config ACPI_SLEEP_PROC_SLEEP
config ACPI_AC
tristate "AC Adapter"
depends on X86
- default m
+ default y
help
This driver adds support for the AC Adapter object, which indicates
- whether a system is on AC, or not. Typically, only mobile systems
- have this object, since desktops are always on AC.
+ whether a system is on AC, or not. If you have a system that can
+ switch between A/C and battery, say Y.
config ACPI_BATTERY
tristate "Battery"
depends on X86
- default m
+ default y
help
This driver adds support for battery information through
/proc/acpi/battery. If you have a mobile system with a battery,
@@ -107,18 +98,17 @@ config ACPI_BATTERY
config ACPI_BUTTON
tristate "Button"
- default m
+ default y
help
- This driver registers for events based on buttons, such as the
- power, sleep, and lid switch. In the future, a daemon will read
- /proc/acpi/event and perform user-defined actions such as shutting
- down the system. Until then, you can cat it, and see output when
- a button is pressed.
+ This driver handles events on the power, sleep and lid buttons.
+ A daemon reads /proc/acpi/event and perform user-defined actions
+ such as shutting down the system. This is necessary for
+ software controlled poweroff.
config ACPI_VIDEO
tristate "Video"
- depends on EXPERIMENTAL
- default m
+ depends on X86
+ default y
help
This driver implement the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
@@ -129,10 +119,9 @@ config ACPI_VIDEO
for your integrated video device.
config ACPI_HOTKEY
- tristate "Generic Hotkey"
- depends on ACPI_INTERPRETER
+ tristate "Generic Hotkey (EXPERIMENTAL)"
depends on EXPERIMENTAL
- depends on !IA64_SGI_SN
+ depends on X86
default n
help
Experimental consolidated hotkey driver.
@@ -140,31 +129,30 @@ config ACPI_HOTKEY
config ACPI_FAN
tristate "Fan"
- default m
+ default y
help
This driver adds support for ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
config ACPI_PROCESSOR
tristate "Processor"
- default m
+ default y
help
This driver installs ACPI as the idle handler for Linux, and uses
ACPI C2 and C3 processor states to save power, on systems that
- support it.
+ support it. It is required by several flavors of cpufreq
+ Performance-state drivers.
config ACPI_HOTPLUG_CPU
- bool "Processor Hotplug (EXPERIMENTAL)"
- depends on ACPI_PROCESSOR && HOTPLUG_CPU && EXPERIMENTAL
+ bool
+ depends on ACPI_PROCESSOR && HOTPLUG_CPU
select ACPI_CONTAINER
- default n
- ---help---
- Select this option if your platform support physical CPU hotplug.
+ default y
config ACPI_THERMAL
tristate "Thermal Zone"
depends on ACPI_PROCESSOR
- default m
+ default y
help
This driver adds support for ACPI thermal zones. Most mobile and
some desktop systems support ACPI thermal zones. It is HIGHLY
@@ -180,7 +168,7 @@ config ACPI_NUMA
config ACPI_ASUS
tristate "ASUS/Medion Laptop Extras"
depends on X86
- default m
+ default y
---help---
This driver provides support for extra features of ACPI-compatible
ASUS laptops. As some of Medion laptops are made by ASUS, it may also
@@ -209,7 +197,7 @@ config ACPI_ASUS
config ACPI_IBM
tristate "IBM ThinkPad Laptop Extras"
depends on X86
- default m
+ default y
---help---
This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
@@ -222,7 +210,7 @@ config ACPI_IBM
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86
- default m
+ default y
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
@@ -262,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 ACPI_INTERPRETER
+ 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
@@ -281,10 +268,6 @@ config ACPI_DEBUG
of verbosity. Saying Y enables these statements. This will increase
your kernel size by around 50K.
-config ACPI_BUS
- bool
- default y
-
config ACPI_EC
bool
depends on X86
@@ -298,10 +281,6 @@ config ACPI_POWER
bool
default y
-config ACPI_PCI
- bool
- default PCI
-
config ACPI_SYSTEM
bool
default y
@@ -309,14 +288,11 @@ config ACPI_SYSTEM
This driver will enable your system to shut down using ACPI, and
dump your ACPI DSDT table using /proc/acpi/dsdt.
-endif # ACPI_INTERPRETER
-
config X86_PM_TIMER
bool "Power Management Timer Support"
depends on X86
- depends on ACPI_BOOT && EXPERIMENTAL
depends on !X86_64
- default n
+ default y
help
The Power Management Timer is available on all ACPI-capable,
in most cases even if ACPI is unusable or blacklisted.
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index ad67e8f61e6c..a18243488c66 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -15,13 +15,13 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS)
#
# ACPI Boot-Time Table Parsing
#
-obj-$(CONFIG_ACPI_BOOT) += tables.o
-obj-$(CONFIG_ACPI_INTERPRETER) += blacklist.o
+obj-y += tables.o
+obj-y += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
#
-obj-$(CONFIG_ACPI_INTERPRETER) += osl.o utils.o \
+obj-y += osl.o utils.o \
dispatcher/ events/ executer/ hardware/ \
namespace/ parser/ resources/ tables/ \
utilities/
@@ -35,8 +35,8 @@ ifdef CONFIG_CPU_FREQ
processor-objs += processor_perflib.o
endif
-obj-$(CONFIG_ACPI_BUS) += sleep/
-obj-$(CONFIG_ACPI_BUS) += bus.o glue.o
+obj-y += sleep/
+obj-y += bus.o glue.o
obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
@@ -44,7 +44,7 @@ obj-$(CONFIG_ACPI_EC) += ec.o
obj-$(CONFIG_ACPI_FAN) += fan.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o
-obj-$(CONFIG_ACPI_PCI) += pci_root.o pci_link.o pci_irq.o pci_bind.o
+obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
obj-$(CONFIG_ACPI_POWER) += power.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
@@ -55,5 +55,5 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o
obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
-obj-$(CONFIG_ACPI_BUS) += scan.o motherboard.o
+obj-y += scan.o motherboard.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 23ab761dd721..7839b831df94 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -32,7 +32,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define ACPI_AC_COMPONENT 0x00020000
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_AC_HID "ACPI0003"
@@ -45,47 +44,45 @@
#define ACPI_AC_STATUS_UNKNOWN 0xFF
#define _COMPONENT ACPI_AC_COMPONENT
-ACPI_MODULE_NAME ("acpi_ac")
+ACPI_MODULE_NAME("acpi_ac")
-MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
MODULE_LICENSE("GPL");
-static int acpi_ac_add (struct acpi_device *device);
-static int acpi_ac_remove (struct acpi_device *device, int type);
+static int acpi_ac_add(struct acpi_device *device);
+static int acpi_ac_remove(struct acpi_device *device, int type);
static int acpi_ac_open_fs(struct inode *inode, struct file *file);
static struct acpi_driver acpi_ac_driver = {
- .name = ACPI_AC_DRIVER_NAME,
- .class = ACPI_AC_CLASS,
- .ids = ACPI_AC_HID,
- .ops = {
- .add = acpi_ac_add,
- .remove = acpi_ac_remove,
- },
+ .name = ACPI_AC_DRIVER_NAME,
+ .class = ACPI_AC_CLASS,
+ .ids = ACPI_AC_HID,
+ .ops = {
+ .add = acpi_ac_add,
+ .remove = acpi_ac_remove,
+ },
};
struct acpi_ac {
- acpi_handle handle;
- unsigned long state;
+ acpi_handle handle;
+ unsigned long state;
};
static struct file_operations acpi_ac_fops = {
- .open = acpi_ac_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_ac_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
/* --------------------------------------------------------------------------
AC Adapter Management
-------------------------------------------------------------------------- */
-static int
-acpi_ac_get_state (
- struct acpi_ac *ac)
+static int acpi_ac_get_state(struct acpi_ac *ac)
{
- acpi_status status = AE_OK;
+ acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("acpi_ac_get_state");
@@ -95,24 +92,23 @@ acpi_ac_get_state (
status = acpi_evaluate_integer(ac->handle, "_PSR", NULL, &ac->state);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error reading AC Adapter state\n"));
+ "Error reading AC Adapter state\n"));
ac->state = ACPI_AC_STATUS_UNKNOWN;
return_VALUE(-ENODEV);
}
-
+
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_ac_dir;
+static struct proc_dir_entry *acpi_ac_dir;
static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_ac *ac = (struct acpi_ac *) seq->private;
+ struct acpi_ac *ac = (struct acpi_ac *)seq->private;
ACPI_FUNCTION_TRACE("acpi_ac_seq_show");
@@ -139,23 +135,21 @@ static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
return_VALUE(0);
}
-
+
static int acpi_ac_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_ac_seq_show, PDE(inode)->data);
}
-static int
-acpi_ac_add_fs (
- struct acpi_device *device)
+static int acpi_ac_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_ac_add_fs");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_ac_dir);
+ acpi_ac_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
acpi_device_dir(device)->owner = THIS_MODULE;
@@ -163,11 +157,11 @@ acpi_ac_add_fs (
/* 'state' [R] */
entry = create_proc_entry(ACPI_AC_FILE_STATE,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_AC_FILE_STATE));
+ "Unable to create '%s' fs entry\n",
+ ACPI_AC_FILE_STATE));
else {
entry->proc_fops = &acpi_ac_fops;
entry->data = acpi_driver_data(device);
@@ -177,16 +171,12 @@ acpi_ac_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_ac_remove_fs (
- struct acpi_device *device)
+static int acpi_ac_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_ac_remove_fs");
if (acpi_device_dir(device)) {
- remove_proc_entry(ACPI_AC_FILE_STATE,
- acpi_device_dir(device));
+ remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device), acpi_ac_dir);
acpi_device_dir(device) = NULL;
@@ -195,19 +185,14 @@ acpi_ac_remove_fs (
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Model
-------------------------------------------------------------------------- */
-static void
-acpi_ac_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_ac *ac = (struct acpi_ac *) data;
- struct acpi_device *device = NULL;
+ struct acpi_ac *ac = (struct acpi_ac *)data;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_ac_notify");
@@ -224,21 +209,18 @@ acpi_ac_notify (
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-
-static int
-acpi_ac_add (
- struct acpi_device *device)
+static int acpi_ac_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_ac *ac = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_ac *ac = NULL;
ACPI_FUNCTION_TRACE("acpi_ac_add");
@@ -264,19 +246,20 @@ acpi_ac_add (
goto end;
status = acpi_install_notify_handler(ac->handle,
- ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac);
+ ACPI_DEVICE_NOTIFY, acpi_ac_notify,
+ ac);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
result = -ENODEV;
goto end;
}
- printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
- acpi_device_name(device), acpi_device_bid(device),
- ac->state?"on-line":"off-line");
+ printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+ acpi_device_name(device), acpi_device_bid(device),
+ ac->state ? "on-line" : "off-line");
-end:
+ end:
if (result) {
acpi_ac_remove_fs(device);
kfree(ac);
@@ -285,27 +268,23 @@ end:
return_VALUE(result);
}
-
-static int
-acpi_ac_remove (
- struct acpi_device *device,
- int type)
+static int acpi_ac_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
- struct acpi_ac *ac = NULL;
+ acpi_status status = AE_OK;
+ struct acpi_ac *ac = NULL;
ACPI_FUNCTION_TRACE("acpi_ac_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- ac = (struct acpi_ac *) acpi_driver_data(device);
+ ac = (struct acpi_ac *)acpi_driver_data(device);
status = acpi_remove_notify_handler(ac->handle,
- ACPI_DEVICE_NOTIFY, acpi_ac_notify);
+ ACPI_DEVICE_NOTIFY, acpi_ac_notify);
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
acpi_ac_remove_fs(device);
@@ -314,11 +293,9 @@ acpi_ac_remove (
return_VALUE(0);
}
-
-static int __init
-acpi_ac_init (void)
+static int __init acpi_ac_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_ac_init");
@@ -336,9 +313,7 @@ acpi_ac_init (void)
return_VALUE(0);
}
-
-static void __exit
-acpi_ac_exit (void)
+static void __exit acpi_ac_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_ac_exit");
@@ -349,6 +324,5 @@ acpi_ac_exit (void)
return_VOID;
}
-
module_init(acpi_ac_init);
module_exit(acpi_ac_exit);
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 77285ffe41c5..01a1bd239263 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -32,7 +32,6 @@
#include <linux/memory_hotplug.h>
#include <acpi/acpi_drivers.h>
-
#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL
#define ACPI_MEMORY_DEVICE_CLASS "memory"
#define ACPI_MEMORY_DEVICE_HID "PNP0C80"
@@ -41,8 +40,8 @@
#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT
-ACPI_MODULE_NAME ("acpi_memory")
-MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
+ACPI_MODULE_NAME("acpi_memory")
+ MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME);
MODULE_LICENSE("GPL");
@@ -56,34 +55,33 @@ MODULE_LICENSE("GPL");
#define MEMORY_POWER_ON_STATE 1
#define MEMORY_POWER_OFF_STATE 2
-static int acpi_memory_device_add (struct acpi_device *device);
-static int acpi_memory_device_remove (struct acpi_device *device, int type);
+static int acpi_memory_device_add(struct acpi_device *device);
+static int acpi_memory_device_remove(struct acpi_device *device, int type);
static struct acpi_driver acpi_memory_device_driver = {
- .name = ACPI_MEMORY_DEVICE_DRIVER_NAME,
- .class = ACPI_MEMORY_DEVICE_CLASS,
- .ids = ACPI_MEMORY_DEVICE_HID,
- .ops = {
- .add = acpi_memory_device_add,
- .remove = acpi_memory_device_remove,
- },
+ .name = ACPI_MEMORY_DEVICE_DRIVER_NAME,
+ .class = ACPI_MEMORY_DEVICE_CLASS,
+ .ids = ACPI_MEMORY_DEVICE_HID,
+ .ops = {
+ .add = acpi_memory_device_add,
+ .remove = acpi_memory_device_remove,
+ },
};
struct acpi_memory_device {
acpi_handle handle;
- unsigned int state; /* State of the memory device */
+ unsigned int state; /* State of the memory device */
unsigned short cache_attribute; /* memory cache attribute */
- unsigned short read_write_attribute;/* memory read/write attribute */
- u64 start_addr; /* Memory Range start physical addr */
- u64 end_addr; /* Memory Range end physical addr */
+ unsigned short read_write_attribute; /* memory read/write attribute */
+ u64 start_addr; /* Memory Range start physical addr */
+ u64 end_addr; /* Memory Range end physical addr */
};
-
static int
acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
{
acpi_status status;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_resource *resource = NULL;
struct acpi_resource_address64 address64;
@@ -94,15 +92,15 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
if (ACPI_FAILURE(status))
return_VALUE(-EINVAL);
- resource = (struct acpi_resource *) buffer.pointer;
+ resource = (struct acpi_resource *)buffer.pointer;
status = acpi_resource_to_address64(resource, &address64);
if (ACPI_SUCCESS(status)) {
if (address64.resource_type == ACPI_MEMORY_RANGE) {
/* Populate the structure */
mem_device->cache_attribute =
- address64.attribute.memory.cache_attribute;
+ address64.attribute.memory.cache_attribute;
mem_device->read_write_attribute =
- address64.attribute.memory.read_write_attribute;
+ address64.attribute.memory.read_write_attribute;
mem_device->start_addr = address64.min_address_range;
mem_device->end_addr = address64.max_address_range;
}
@@ -114,7 +112,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
static int
acpi_memory_get_device(acpi_handle handle,
- struct acpi_memory_device **mem_device)
+ struct acpi_memory_device **mem_device)
{
acpi_status status;
acpi_handle phandle;
@@ -128,8 +126,7 @@ acpi_memory_get_device(acpi_handle handle,
status = acpi_get_parent(handle, &phandle);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error in acpi_get_parent\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error in acpi_get_parent\n"));
return_VALUE(-EINVAL);
}
@@ -137,7 +134,7 @@ acpi_memory_get_device(acpi_handle handle,
status = acpi_bus_get_device(phandle, &pdevice);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error in acpi_bus_get_device\n"));
+ "Error in acpi_bus_get_device\n"));
return_VALUE(-EINVAL);
}
@@ -147,23 +144,21 @@ acpi_memory_get_device(acpi_handle handle,
*/
status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error in acpi_bus_add\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error in acpi_bus_add\n"));
return_VALUE(-EINVAL);
}
-end:
+ end:
*mem_device = acpi_driver_data(device);
if (!(*mem_device)) {
- printk(KERN_ERR "\n driver data not found" );
+ printk(KERN_ERR "\n driver data not found");
return_VALUE(-ENODEV);
}
return_VALUE(0);
}
-static int
-acpi_memory_check_device(struct acpi_memory_device *mem_device)
+static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
{
unsigned long current_status;
@@ -171,22 +166,21 @@ acpi_memory_check_device(struct acpi_memory_device *mem_device)
/* Get device present/absent information from the _STA */
if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->handle, "_STA",
- NULL, &current_status)))
+ NULL, &current_status)))
return_VALUE(-ENODEV);
/*
* Check for device status. Device should be
* present/enabled/functioning.
*/
if (!((current_status & ACPI_MEMORY_STA_PRESENT)
- && (current_status & ACPI_MEMORY_STA_ENABLED)
- && (current_status & ACPI_MEMORY_STA_FUNCTIONAL)))
+ && (current_status & ACPI_MEMORY_STA_ENABLED)
+ && (current_status & ACPI_MEMORY_STA_FUNCTIONAL)))
return_VALUE(-ENODEV);
return_VALUE(0);
}
-static int
-acpi_memory_enable_device(struct acpi_memory_device *mem_device)
+static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
{
int result;
@@ -196,7 +190,7 @@ acpi_memory_enable_device(struct acpi_memory_device *mem_device)
result = acpi_memory_get_device_resources(mem_device);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "\nget_device_resources failed\n"));
+ "\nget_device_resources failed\n"));
mem_device->state = MEMORY_INVALID_STATE;
return result;
}
@@ -206,11 +200,10 @@ acpi_memory_enable_device(struct acpi_memory_device *mem_device)
* Note: Assume that this function returns zero on success
*/
result = add_memory(mem_device->start_addr,
- (mem_device->end_addr - mem_device->start_addr) + 1,
- mem_device->read_write_attribute);
+ (mem_device->end_addr - mem_device->start_addr) + 1,
+ mem_device->read_write_attribute);
if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "\nadd_memory failed\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n"));
mem_device->state = MEMORY_INVALID_STATE;
return result;
}
@@ -218,11 +211,10 @@ acpi_memory_enable_device(struct acpi_memory_device *mem_device)
return result;
}
-static int
-acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
+static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
{
acpi_status status;
- struct acpi_object_list arg_list;
+ struct acpi_object_list arg_list;
union acpi_object arg;
unsigned long current_status;
@@ -234,16 +226,16 @@ acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 1;
status = acpi_evaluate_object(mem_device->handle,
- "_EJ0", &arg_list, NULL);
+ "_EJ0", &arg_list, NULL);
/* Return on _EJ0 failure */
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"_EJ0 failed.\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "_EJ0 failed.\n"));
return_VALUE(-ENODEV);
}
/* Evalute _STA to check if the device is disabled */
status = acpi_evaluate_integer(mem_device->handle, "_STA",
- NULL, &current_status);
+ NULL, &current_status);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
@@ -254,8 +246,7 @@ acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
return_VALUE(0);
}
-static int
-acpi_memory_disable_device(struct acpi_memory_device *mem_device)
+static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
{
int result;
u64 start = mem_device->start_addr;
@@ -278,7 +269,7 @@ acpi_memory_disable_device(struct acpi_memory_device *mem_device)
result = acpi_memory_powerdown_device(mem_device);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Device Power Down failed.\n"));
+ "Device Power Down failed.\n"));
/* Set the status of the device to invalid */
mem_device->state = MEMORY_INVALID_STATE;
return result;
@@ -288,8 +279,7 @@ acpi_memory_disable_device(struct acpi_memory_device *mem_device)
return result;
}
-static void
-acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_memory_device *mem_device;
struct acpi_device *device;
@@ -299,37 +289,37 @@ acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "\nReceived BUS CHECK notification for device\n"));
+ "\nReceived BUS CHECK notification for device\n"));
/* Fall Through */
case ACPI_NOTIFY_DEVICE_CHECK:
if (event == ACPI_NOTIFY_DEVICE_CHECK)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "\nReceived DEVICE CHECK notification for device\n"));
+ "\nReceived DEVICE CHECK notification for device\n"));
if (acpi_memory_get_device(handle, &mem_device)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error in finding driver data\n"));
+ "Error in finding driver data\n"));
return_VOID;
}
if (!acpi_memory_check_device(mem_device)) {
if (acpi_memory_enable_device(mem_device))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error in acpi_memory_enable_device\n"));
+ "Error in acpi_memory_enable_device\n"));
}
break;
case ACPI_NOTIFY_EJECT_REQUEST:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "\nReceived EJECT REQUEST notification for device\n"));
+ "\nReceived EJECT REQUEST notification for device\n"));
if (acpi_bus_get_device(handle, &device)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Device doesn't exist\n"));
+ "Device doesn't exist\n"));
break;
}
mem_device = acpi_driver_data(device);
if (!mem_device) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Driver Data is NULL\n"));
+ "Driver Data is NULL\n"));
break;
}
@@ -337,26 +327,25 @@ acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
* Currently disabling memory device from kernel mode
* TBD: Can also be disabled from user mode scripts
* TBD: Can also be disabled by Callback registration
- * with generic sysfs driver
+ * with generic sysfs driver
*/
if (acpi_memory_disable_device(mem_device))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error in acpi_memory_disable_device\n"));
+ "Error in acpi_memory_disable_device\n"));
/*
* TBD: Invoke acpi_bus_remove to cleanup data structures
*/
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-static int
-acpi_memory_device_add(struct acpi_device *device)
+static int acpi_memory_device_add(struct acpi_device *device)
{
int result;
struct acpi_memory_device *mem_device = NULL;
@@ -391,8 +380,7 @@ acpi_memory_device_add(struct acpi_device *device)
return_VALUE(result);
}
-static int
-acpi_memory_device_remove (struct acpi_device *device, int type)
+static int acpi_memory_device_remove(struct acpi_device *device, int type)
{
struct acpi_memory_device *mem_device = NULL;
@@ -401,7 +389,7 @@ acpi_memory_device_remove (struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- mem_device = (struct acpi_memory_device *) acpi_driver_data(device);
+ mem_device = (struct acpi_memory_device *)acpi_driver_data(device);
kfree(mem_device);
return_VALUE(0);
@@ -410,12 +398,11 @@ acpi_memory_device_remove (struct acpi_device *device, int type)
/*
* Helper function to check for memory device
*/
-static acpi_status
-is_memory_device(acpi_handle handle)
+static acpi_status is_memory_device(acpi_handle handle)
{
char *hardware_id;
acpi_status status;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_device_info *info;
ACPI_FUNCTION_TRACE("is_memory_device");
@@ -432,7 +419,7 @@ is_memory_device(acpi_handle handle)
hardware_id = info->hardware_id.value;
if ((hardware_id == NULL) ||
- (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
+ (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
status = AE_ERROR;
acpi_os_free(buffer.pointer);
@@ -440,8 +427,8 @@ is_memory_device(acpi_handle handle)
}
static acpi_status
-acpi_memory_register_notify_handler (acpi_handle handle,
- u32 level, void *ctxt, void **retv)
+acpi_memory_register_notify_handler(acpi_handle handle,
+ u32 level, void *ctxt, void **retv)
{
acpi_status status;
@@ -452,10 +439,10 @@ acpi_memory_register_notify_handler (acpi_handle handle,
return_ACPI_STATUS(AE_OK); /* continue */
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
- acpi_memory_device_notify, NULL);
+ acpi_memory_device_notify, NULL);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
return_ACPI_STATUS(AE_OK); /* continue */
}
@@ -463,8 +450,8 @@ acpi_memory_register_notify_handler (acpi_handle handle,
}
static acpi_status
-acpi_memory_deregister_notify_handler (acpi_handle handle,
- u32 level, void *ctxt, void **retv)
+acpi_memory_deregister_notify_handler(acpi_handle handle,
+ u32 level, void *ctxt, void **retv)
{
acpi_status status;
@@ -475,18 +462,18 @@ acpi_memory_deregister_notify_handler (acpi_handle handle,
return_ACPI_STATUS(AE_OK); /* continue */
status = acpi_remove_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY, acpi_memory_device_notify);
+ ACPI_SYSTEM_NOTIFY,
+ acpi_memory_device_notify);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
return_ACPI_STATUS(AE_OK); /* continue */
}
return_ACPI_STATUS(status);
}
-static int __init
-acpi_memory_device_init (void)
+static int __init acpi_memory_device_init(void)
{
int result;
acpi_status status;
@@ -499,21 +486,20 @@ acpi_memory_device_init (void)
return_VALUE(-ENODEV);
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- acpi_memory_register_notify_handler,
- NULL, NULL);
+ ACPI_UINT32_MAX,
+ acpi_memory_register_notify_handler,
+ NULL, NULL);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed\n"));
acpi_bus_unregister_driver(&acpi_memory_device_driver);
return_VALUE(-ENODEV);
- }
+ }
return_VALUE(0);
}
-static void __exit
-acpi_memory_device_exit (void)
+static void __exit acpi_memory_device_exit(void)
{
acpi_status status;
@@ -524,12 +510,12 @@ acpi_memory_device_exit (void)
* handles.
*/
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- acpi_memory_deregister_notify_handler,
- NULL, NULL);
+ ACPI_UINT32_MAX,
+ acpi_memory_deregister_notify_handler,
+ NULL, NULL);
- if (ACPI_FAILURE (status))
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+ if (ACPI_FAILURE(status))
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed\n"));
acpi_bus_unregister_driver(&acpi_memory_device_driver);
@@ -538,5 +524,3 @@ acpi_memory_device_exit (void)
module_init(acpi_memory_device_init);
module_exit(acpi_memory_device_exit);
-
-
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index a560b1e2da77..fec895af6ae6 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -61,7 +61,7 @@
/*
* Some events we use, same for all Asus
*/
-#define BR_UP 0x10
+#define BR_UP 0x10
#define BR_DOWN 0x20
/*
@@ -75,7 +75,6 @@ MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
MODULE_DESCRIPTION(ACPI_HOTK_NAME);
MODULE_LICENSE("GPL");
-
static uid_t asus_uid;
static gid_t asus_gid;
module_param(asus_uid, uint, 0);
@@ -83,26 +82,25 @@ MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n");
module_param(asus_gid, uint, 0);
MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n");
-
/* For each model, all features implemented,
* those marked with R are relative to HOTK, A for absolute */
struct model_data {
- char *name; //name of the laptop________________A
- char *mt_mled; //method to handle mled_____________R
- char *mled_status; //node to handle mled reading_______A
- char *mt_wled; //method to handle wled_____________R
- char *wled_status; //node to handle wled reading_______A
- char *mt_tled; //method to handle tled_____________R
- char *tled_status; //node to handle tled reading_______A
- char *mt_lcd_switch; //method to turn LCD ON/OFF_________A
- char *lcd_status; //node to read LCD panel state______A
- char *brightness_up; //method to set brightness up_______A
- char *brightness_down; //guess what ?______________________A
- char *brightness_set; //method to set absolute brightness_R
- char *brightness_get; //method to get absolute brightness_R
- char *brightness_status; //node to get brightness____________A
- char *display_set; //method to set video output________R
- char *display_get; //method to get video output________R
+ char *name; //name of the laptop________________A
+ char *mt_mled; //method to handle mled_____________R
+ char *mled_status; //node to handle mled reading_______A
+ char *mt_wled; //method to handle wled_____________R
+ char *wled_status; //node to handle wled reading_______A
+ char *mt_tled; //method to handle tled_____________R
+ char *tled_status; //node to handle tled reading_______A
+ char *mt_lcd_switch; //method to turn LCD ON/OFF_________A
+ char *lcd_status; //node to read LCD panel state______A
+ char *brightness_up; //method to set brightness up_______A
+ char *brightness_down; //guess what ?______________________A
+ char *brightness_set; //method to set absolute brightness_R
+ char *brightness_get; //method to get absolute brightness_R
+ char *brightness_status; //node to get brightness____________A
+ char *display_set; //method to set video output________R
+ char *display_get; //method to get video output________R
};
/*
@@ -110,34 +108,34 @@ struct model_data {
* about the hotk device
*/
struct asus_hotk {
- struct acpi_device *device; //the device we are in
- acpi_handle handle; //the handle of the hotk device
- char status; //status of the hotk, for LEDs, ...
- struct model_data *methods; //methods available on the laptop
- u8 brightness; //brightness level
+ struct acpi_device *device; //the device we are in
+ acpi_handle handle; //the handle of the hotk device
+ char status; //status of the hotk, for LEDs, ...
+ struct model_data *methods; //methods available on the laptop
+ u8 brightness; //brightness level
enum {
- A1x = 0, //A1340D, A1300F
- A2x, //A2500H
- D1x, //D1
- L2D, //L2000D
- L3C, //L3800C
- L3D, //L3400D
- L3H, //L3H, but also L2000E
- L4R, //L4500R
- L5x, //L5800C
- L8L, //L8400L
- M1A, //M1300A
- M2E, //M2400E, L4400L
- M6N, //M6800N
- M6R, //M6700R
- P30, //Samsung P30
- S1x, //S1300A, but also L1400B and M2400A (L84F)
- S2x, //S200 (J1 reported), Victor MP-XP7210
- xxN, //M2400N, M3700N, M5200N, S1300N, S5200N, W1OOON
- //(Centrino)
+ A1x = 0, //A1340D, A1300F
+ A2x, //A2500H
+ D1x, //D1
+ L2D, //L2000D
+ L3C, //L3800C
+ L3D, //L3400D
+ L3H, //L3H, but also L2000E
+ L4R, //L4500R
+ L5x, //L5800C
+ L8L, //L8400L
+ M1A, //M1300A
+ M2E, //M2400E, L4400L
+ M6N, //M6800N
+ M6R, //M6700R
+ P30, //Samsung P30
+ S1x, //S1300A, but also L1400B and M2400A (L84F)
+ S2x, //S200 (J1 reported), Victor MP-XP7210
+ xxN, //M2400N, M3700N, M5200N, S1300N, S5200N, W1OOON
+ //(Centrino)
END_MODEL
- } model; //Models currently supported
- u16 event_count[128]; //count for each event TODO make this better
+ } model; //Models currently supported
+ u16 event_count[128]; //count for each event TODO make this better
};
/* Here we go */
@@ -150,7 +148,7 @@ struct asus_hotk {
#define xxN_PREFIX "\\_SB.PCI0.SBRG.EC0."
static struct model_data model_conf[END_MODEL] = {
- /*
+ /*
* Those pathnames are relative to the HOTK / ATKD device :
* - mt_mled
* - mt_wled
@@ -165,215 +163,197 @@ static struct model_data model_conf[END_MODEL] = {
*/
{
- .name = "A1x",
- .mt_mled = "MLED",
- .mled_status = "\\MAIL",
- .mt_lcd_switch = A1x_PREFIX "_Q10",
- .lcd_status = "\\BKLI",
- .brightness_up = A1x_PREFIX "_Q0E",
- .brightness_down = A1x_PREFIX "_Q0F"
- },
+ .name = "A1x",
+ .mt_mled = "MLED",
+ .mled_status = "\\MAIL",
+ .mt_lcd_switch = A1x_PREFIX "_Q10",
+ .lcd_status = "\\BKLI",
+ .brightness_up = A1x_PREFIX "_Q0E",
+ .brightness_down = A1x_PREFIX "_Q0F"},
{
- .name = "A2x",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .wled_status = "\\SG66",
- .mt_lcd_switch = "\\Q10",
- .lcd_status = "\\BAOF",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "A2x",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .wled_status = "\\SG66",
+ .mt_lcd_switch = "\\Q10",
+ .lcd_status = "\\BAOF",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "D1x",
- .mt_mled = "MLED",
- .mt_lcd_switch = "\\Q0D",
- .lcd_status = "\\GP11",
- .brightness_up = "\\Q0C",
- .brightness_down = "\\Q0B",
- .brightness_status = "\\BLVL",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "D1x",
+ .mt_mled = "MLED",
+ .mt_lcd_switch = "\\Q0D",
+ .lcd_status = "\\GP11",
+ .brightness_up = "\\Q0C",
+ .brightness_down = "\\Q0B",
+ .brightness_status = "\\BLVL",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "L2D",
- .mt_mled = "MLED",
- .mled_status = "\\SGP6",
- .mt_wled = "WLED",
- .wled_status = "\\RCP3",
- .mt_lcd_switch = "\\Q10",
- .lcd_status = "\\SGP0",
- .brightness_up = "\\Q0E",
- .brightness_down = "\\Q0F",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "L2D",
+ .mt_mled = "MLED",
+ .mled_status = "\\SGP6",
+ .mt_wled = "WLED",
+ .wled_status = "\\RCP3",
+ .mt_lcd_switch = "\\Q10",
+ .lcd_status = "\\SGP0",
+ .brightness_up = "\\Q0E",
+ .brightness_down = "\\Q0F",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "L3C",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .mt_lcd_switch = L3C_PREFIX "_Q10",
- .lcd_status = "\\GL32",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\_SB.PCI0.PCI1.VGAC.NMAP"
- },
+ .name = "L3C",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = L3C_PREFIX "_Q10",
+ .lcd_status = "\\GL32",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\_SB.PCI0.PCI1.VGAC.NMAP"},
{
- .name = "L3D",
- .mt_mled = "MLED",
- .mled_status = "\\MALD",
- .mt_wled = "WLED",
- .mt_lcd_switch = "\\Q10",
- .lcd_status = "\\BKLG",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "L3D",
+ .mt_mled = "MLED",
+ .mled_status = "\\MALD",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = "\\Q10",
+ .lcd_status = "\\BKLG",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "L3H",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .mt_lcd_switch = "EHK",
- .lcd_status = "\\_SB.PCI0.PM.PBC",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "L3H",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = "EHK",
+ .lcd_status = "\\_SB.PCI0.PM.PBC",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "L4R",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .wled_status = "\\_SB.PCI0.SBRG.SG13",
- .mt_lcd_switch = xxN_PREFIX "_Q10",
- .lcd_status = "\\_SB.PCI0.SBSM.SEO4",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"
- },
+ .name = "L4R",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .wled_status = "\\_SB.PCI0.SBRG.SG13",
+ .mt_lcd_switch = xxN_PREFIX "_Q10",
+ .lcd_status = "\\_SB.PCI0.SBSM.SEO4",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"},
{
- .name = "L5x",
- .mt_mled = "MLED",
+ .name = "L5x",
+ .mt_mled = "MLED",
/* WLED present, but not controlled by ACPI */
- .mt_tled = "TLED",
- .mt_lcd_switch = "\\Q0D",
- .lcd_status = "\\BAOF",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .mt_tled = "TLED",
+ .mt_lcd_switch = "\\Q0D",
+ .lcd_status = "\\BAOF",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "L8L"
+ .name = "L8L"
/* No features, but at least support the hotkeys */
- },
+ },
{
- .name = "M1A",
- .mt_mled = "MLED",
- .mt_lcd_switch = M1A_PREFIX "Q10",
- .lcd_status = "\\PNOF",
- .brightness_up = M1A_PREFIX "Q0E",
- .brightness_down = M1A_PREFIX "Q0F",
- .brightness_status = "\\BRIT",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "M1A",
+ .mt_mled = "MLED",
+ .mt_lcd_switch = M1A_PREFIX "Q10",
+ .lcd_status = "\\PNOF",
+ .brightness_up = M1A_PREFIX "Q0E",
+ .brightness_down = M1A_PREFIX "Q0F",
+ .brightness_status = "\\BRIT",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "M2E",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .mt_lcd_switch = "\\Q10",
- .lcd_status = "\\GP06",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\INFB"
- },
+ .name = "M2E",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = "\\Q10",
+ .lcd_status = "\\GP06",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
{
- .name = "M6N",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .wled_status = "\\_SB.PCI0.SBRG.SG13",
- .mt_lcd_switch = xxN_PREFIX "_Q10",
- .lcd_status = "\\_SB.BKLT",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\SSTE"
- },
+ .name = "M6N",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .wled_status = "\\_SB.PCI0.SBRG.SG13",
+ .mt_lcd_switch = xxN_PREFIX "_Q10",
+ .lcd_status = "\\_SB.BKLT",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\SSTE"},
{
- .name = "M6R",
- .mt_mled = "MLED",
- .mt_wled = "WLED",
- .mt_lcd_switch = xxN_PREFIX "_Q10",
- .lcd_status = "\\_SB.PCI0.SBSM.SEO4",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\SSTE"
- },
-
+ .name = "M6R",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = xxN_PREFIX "_Q10",
+ .lcd_status = "\\_SB.PCI0.SBSM.SEO4",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\SSTE"},
{
- .name = "P30",
- .mt_wled = "WLED",
- .mt_lcd_switch = P30_PREFIX "_Q0E",
- .lcd_status = "\\BKLT",
- .brightness_up = P30_PREFIX "_Q68",
- .brightness_down = P30_PREFIX "_Q69",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\DNXT"
- },
+ .name = "P30",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = P30_PREFIX "_Q0E",
+ .lcd_status = "\\BKLT",
+ .brightness_up = P30_PREFIX "_Q68",
+ .brightness_down = P30_PREFIX "_Q69",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\DNXT"},
{
- .name = "S1x",
- .mt_mled = "MLED",
- .mled_status = "\\EMLE",
- .mt_wled = "WLED",
- .mt_lcd_switch = S1x_PREFIX "Q10" ,
- .lcd_status = "\\PNOF",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV"
- },
+ .name = "S1x",
+ .mt_mled = "MLED",
+ .mled_status = "\\EMLE",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = S1x_PREFIX "Q10",
+ .lcd_status = "\\PNOF",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV"},
{
- .name = "S2x",
- .mt_mled = "MLED",
- .mled_status = "\\MAIL",
- .mt_lcd_switch = S2x_PREFIX "_Q10",
- .lcd_status = "\\BKLI",
- .brightness_up = S2x_PREFIX "_Q0B",
- .brightness_down = S2x_PREFIX "_Q0A"
- },
+ .name = "S2x",
+ .mt_mled = "MLED",
+ .mled_status = "\\MAIL",
+ .mt_lcd_switch = S2x_PREFIX "_Q10",
+ .lcd_status = "\\BKLI",
+ .brightness_up = S2x_PREFIX "_Q0B",
+ .brightness_down = S2x_PREFIX "_Q0A"},
{
- .name = "xxN",
- .mt_mled = "MLED",
+ .name = "xxN",
+ .mt_mled = "MLED",
/* WLED present, but not controlled by ACPI */
- .mt_lcd_switch = xxN_PREFIX "_Q10",
- .lcd_status = "\\BKLT",
- .brightness_set = "SPLV",
- .brightness_get = "GPLV",
- .display_set = "SDSP",
- .display_get = "\\ADVG"
- }
+ .mt_lcd_switch = xxN_PREFIX "_Q10",
+ .lcd_status = "\\BKLT",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\ADVG"}
};
/* procdir we use */
@@ -395,13 +375,13 @@ static struct asus_hotk *hotk;
static int asus_hotk_add(struct acpi_device *device);
static int asus_hotk_remove(struct acpi_device *device, int type);
static struct acpi_driver asus_hotk_driver = {
- .name = ACPI_HOTK_NAME,
- .class = ACPI_HOTK_CLASS,
- .ids = ACPI_HOTK_HID,
- .ops = {
- .add = asus_hotk_add,
- .remove = asus_hotk_remove,
- },
+ .name = ACPI_HOTK_NAME,
+ .class = ACPI_HOTK_CLASS,
+ .ids = ACPI_HOTK_HID,
+ .ops = {
+ .add = asus_hotk_add,
+ .remove = asus_hotk_remove,
+ },
};
/*
@@ -423,11 +403,10 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
in_obj.type = ACPI_TYPE_INTEGER;
in_obj.integer.value = val;
- status = acpi_evaluate_object(handle, (char *) method, &params, output);
+ status = acpi_evaluate_object(handle, (char *)method, &params, output);
return (status == AE_OK);
}
-
static int read_acpi_int(acpi_handle handle, const char *method, int *val)
{
struct acpi_buffer output;
@@ -437,7 +416,7 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val)
output.length = sizeof(out_obj);
output.pointer = &out_obj;
- status = acpi_evaluate_object(handle, (char *) method, NULL, &output);
+ status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
*val = out_obj.integer.value;
return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
}
@@ -449,7 +428,7 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val)
*/
static int
proc_read_info(char *page, char **start, off_t off, int count, int *eof,
- void *data)
+ void *data)
{
int len = 0;
int temp;
@@ -460,7 +439,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
*/
len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
- len += sprintf(page + len, "Model reference : %s\n",
+ len += sprintf(page + len, "Model reference : %s\n",
hotk->methods->name);
/*
* The SFUN method probably allows the original driver to get the list
@@ -469,7 +448,8 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
* The significance of others is yet to be found.
*/
if (read_acpi_int(hotk->handle, "SFUN", &temp))
- len += sprintf(page + len, "SFUN value : 0x%04x\n", temp);
+ len +=
+ sprintf(page + len, "SFUN value : 0x%04x\n", temp);
/*
* Another value for userspace: the ASYM method returns 0x02 for
* battery low and 0x04 for battery critical, its readings tend to be
@@ -478,7 +458,8 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
* silently ignored.
*/
if (read_acpi_int(hotk->handle, "ASYM", &temp))
- len += sprintf(page + len, "ASYM value : 0x%04x\n", temp);
+ len +=
+ sprintf(page + len, "ASYM value : 0x%04x\n", temp);
if (asus_info) {
snprintf(buf, 16, "%d", asus_info->length);
len += sprintf(page + len, "DSDT length : %s\n", buf);
@@ -501,7 +482,6 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
return len;
}
-
/*
* /proc handlers
* We write our info in page, we begin at offset off and cannot write more
@@ -510,8 +490,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
*/
/* Generic LED functions */
-static int
-read_led(const char *ledname, int ledmask)
+static int read_led(const char *ledname, int ledmask)
{
if (ledname) {
int led_status;
@@ -525,7 +504,7 @@ read_led(const char *ledname, int ledmask)
return (hotk->status & ledmask) ? 1 : 0;
}
-static int parse_arg(const char __user *buf, unsigned long count, int *val)
+static int parse_arg(const char __user * buf, unsigned long count, int *val)
{
char s[32];
if (!count)
@@ -542,8 +521,8 @@ static int parse_arg(const char __user *buf, unsigned long count, int *val)
/* FIXME: kill extraneous args so it can be called independently */
static int
-write_led(const char __user *buffer, unsigned long count,
- char *ledname, int ledmask, int invert)
+write_led(const char __user * buffer, unsigned long count,
+ char *ledname, int ledmask, int invert)
{
int value;
int led_out = 0;
@@ -555,16 +534,16 @@ write_led(const char __user *buffer, unsigned long count,
hotk->status =
(led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask);
- if (invert) /* invert target value */
+ if (invert) /* invert target value */
led_out = !led_out & 0x1;
if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
- printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", ledname);
+ printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
+ ledname);
return count;
}
-
/*
* Proc handlers for MLED
*/
@@ -572,12 +551,12 @@ static int
proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- return sprintf(page, "%d\n", read_led(hotk->methods->mled_status, MLED_ON));
+ return sprintf(page, "%d\n",
+ read_led(hotk->methods->mled_status, MLED_ON));
}
-
static int
-proc_write_mled(struct file *file, const char __user *buffer,
+proc_write_mled(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
@@ -590,11 +569,12 @@ static int
proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- return sprintf(page, "%d\n", read_led(hotk->methods->wled_status, WLED_ON));
+ return sprintf(page, "%d\n",
+ read_led(hotk->methods->wled_status, WLED_ON));
}
static int
-proc_write_wled(struct file *file, const char __user *buffer,
+proc_write_wled(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
@@ -607,35 +587,36 @@ static int
proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- return sprintf(page, "%d\n", read_led(hotk->methods->tled_status, TLED_ON));
+ return sprintf(page, "%d\n",
+ read_led(hotk->methods->tled_status, TLED_ON));
}
static int
-proc_write_tled(struct file *file, const char __user *buffer,
+proc_write_tled(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
}
-
static int get_lcd_state(void)
{
int lcd = 0;
if (hotk->model != L3H) {
- /* We don't have to check anything if we are here */
+ /* We don't have to check anything if we are here */
if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
- printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n");
-
+ printk(KERN_WARNING
+ "Asus ACPI: Error reading LCD status\n");
+
if (hotk->model == L2D)
lcd = ~lcd;
- } else { /* L3H and the like have to be handled differently */
+ } else { /* L3H and the like have to be handled differently */
acpi_status status = 0;
struct acpi_object_list input;
union acpi_object mt_params[2];
struct acpi_buffer output;
union acpi_object out_obj;
-
+
input.count = 2;
input.pointer = mt_params;
/* Note: the following values are partly guessed up, but
@@ -647,15 +628,17 @@ static int get_lcd_state(void)
output.length = sizeof(out_obj);
output.pointer = &out_obj;
-
- status = acpi_evaluate_object(NULL, hotk->methods->lcd_status, &input, &output);
+
+ status =
+ acpi_evaluate_object(NULL, hotk->methods->lcd_status,
+ &input, &output);
if (status != AE_OK)
return -1;
if (out_obj.type == ACPI_TYPE_INTEGER)
/* That's what the AML code does */
lcd = out_obj.integer.value >> 8;
}
-
+
return (lcd & 1);
}
@@ -669,10 +652,13 @@ static int set_lcd_state(int value)
/* switch */
if (hotk->model != L3H) {
status =
- acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch,
+ acpi_evaluate_object(NULL,
+ hotk->methods->mt_lcd_switch,
NULL, NULL);
- } else { /* L3H and the like have to be handled differently */
- if (!write_acpi_int(hotk->handle, hotk->methods->mt_lcd_switch, 0x07, NULL))
+ } else { /* L3H and the like have to be handled differently */
+ if (!write_acpi_int
+ (hotk->handle, hotk->methods->mt_lcd_switch, 0x07,
+ NULL))
status = AE_ERROR;
/* L3H's AML executes EHK (0x07) upon Fn+F7 keypress,
the exact behaviour is simulated here */
@@ -691,33 +677,33 @@ proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
return sprintf(page, "%d\n", get_lcd_state());
}
-
static int
-proc_write_lcd(struct file *file, const char __user *buffer,
+proc_write_lcd(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
int value;
-
+
count = parse_arg(buffer, count, &value);
if (count > 0)
set_lcd_state(value);
return count;
}
-
static int read_brightness(void)
{
int value;
-
- if(hotk->methods->brightness_get) { /* SPLV/GPLV laptop */
- if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get,
+
+ if (hotk->methods->brightness_get) { /* SPLV/GPLV laptop */
+ if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get,
&value))
- printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
- } else if (hotk->methods->brightness_status) { /* For D1 for example */
- if (!read_acpi_int(NULL, hotk->methods->brightness_status,
+ printk(KERN_WARNING
+ "Asus ACPI: Error reading brightness\n");
+ } else if (hotk->methods->brightness_status) { /* For D1 for example */
+ if (!read_acpi_int(NULL, hotk->methods->brightness_status,
&value))
- printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
- } else /* No GPLV method */
+ printk(KERN_WARNING
+ "Asus ACPI: Error reading brightness\n");
+ } else /* No GPLV method */
value = hotk->brightness;
return value;
}
@@ -730,23 +716,25 @@ static void set_brightness(int value)
acpi_status status = 0;
/* SPLV laptop */
- if(hotk->methods->brightness_set) {
- if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
+ if (hotk->methods->brightness_set) {
+ if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
value, NULL))
- printk(KERN_WARNING "Asus ACPI: Error changing brightness\n");
+ printk(KERN_WARNING
+ "Asus ACPI: Error changing brightness\n");
return;
}
/* No SPLV method if we are here, act as appropriate */
value -= read_brightness();
while (value != 0) {
- status = acpi_evaluate_object(NULL, (value > 0) ?
- hotk->methods->brightness_up :
+ status = acpi_evaluate_object(NULL, (value > 0) ?
+ hotk->methods->brightness_up :
hotk->methods->brightness_down,
NULL, NULL);
(value > 0) ? value-- : value++;
if (ACPI_FAILURE(status))
- printk(KERN_WARNING "Asus ACPI: Error changing brightness\n");
+ printk(KERN_WARNING
+ "Asus ACPI: Error changing brightness\n");
}
return;
}
@@ -759,7 +747,7 @@ proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
}
static int
-proc_write_brn(struct file *file, const char __user *buffer,
+proc_write_brn(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
int value;
@@ -767,7 +755,7 @@ proc_write_brn(struct file *file, const char __user *buffer,
count = parse_arg(buffer, count, &value);
if (count > 0) {
value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
- /* 0 <= value <= 15 */
+ /* 0 <= value <= 15 */
set_brightness(value);
} else if (count < 0) {
printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
@@ -779,7 +767,7 @@ proc_write_brn(struct file *file, const char __user *buffer,
static void set_display(int value)
{
/* no sanity check needed for now */
- if (!write_acpi_int(hotk->handle, hotk->methods->display_set,
+ if (!write_acpi_int(hotk->handle, hotk->methods->display_set,
value, NULL))
printk(KERN_WARNING "Asus ACPI: Error setting display\n");
return;
@@ -791,13 +779,14 @@ static void set_display(int value)
*/
static int
proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
- void *data)
+ void *data)
{
int value = 0;
-
+
if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
- printk(KERN_WARNING "Asus ACPI: Error reading display status\n");
- value &= 0x07; /* needed for some models, shouldn't hurt others */
+ printk(KERN_WARNING
+ "Asus ACPI: Error reading display status\n");
+ value &= 0x07; /* needed for some models, shouldn't hurt others */
return sprintf(page, "%d\n", value);
}
@@ -808,8 +797,8 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
* simultaneously, so be warned. See the acpi4asus README for more info.
*/
static int
-proc_write_disp(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+proc_write_disp(struct file *file, const char __user * buffer,
+ unsigned long count, void *data)
{
int value;
@@ -822,19 +811,19 @@ proc_write_disp(struct file *file, const char __user *buffer,
return count;
}
-
-typedef int (proc_readfunc)(char *page, char **start, off_t off, int count,
- int *eof, void *data);
-typedef int (proc_writefunc)(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
+typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
+ int *eof, void *data);
+typedef int (proc_writefunc) (struct file * file, const char __user * buffer,
+ unsigned long count, void *data);
static int
-__init asus_proc_add(char *name, proc_writefunc *writefunc,
- proc_readfunc *readfunc, mode_t mode,
- struct acpi_device *device)
+__init asus_proc_add(char *name, proc_writefunc * writefunc,
+ proc_readfunc * readfunc, mode_t mode,
+ struct acpi_device *device)
{
- struct proc_dir_entry *proc = create_proc_entry(name, mode, acpi_device_dir(device));
- if(!proc) {
+ struct proc_dir_entry *proc =
+ create_proc_entry(name, mode, acpi_device_dir(device));
+ if (!proc) {
printk(KERN_WARNING " Unable to create %s fs entry\n", name);
return -1;
}
@@ -851,14 +840,14 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *proc;
mode_t mode;
-
+
/*
* If parameter uid or gid is not changed, keep the default setting for
* our proc entries (-rw-rw-rw-) else, it means we care about security,
* and then set to -rw-rw----
*/
- if ((asus_uid == 0) && (asus_gid == 0)){
+ if ((asus_uid == 0) && (asus_gid == 0)) {
mode = S_IFREG | S_IRUGO | S_IWUGO;
} else {
mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
@@ -881,15 +870,18 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
}
if (hotk->methods->mt_wled) {
- asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, mode, device);
+ asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled,
+ mode, device);
}
if (hotk->methods->mt_mled) {
- asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, mode, device);
+ asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled,
+ mode, device);
}
if (hotk->methods->mt_tled) {
- asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, mode, device);
+ asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled,
+ mode, device);
}
/*
@@ -897,35 +889,40 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
* from keyboard
*/
if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
- asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, device);
+ asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode,
+ device);
}
-
+
if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
(hotk->methods->brightness_get && hotk->methods->brightness_set)) {
- asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, device);
+ asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode,
+ device);
}
if (hotk->methods->display_set) {
- asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, mode, device);
+ asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp,
+ mode, device);
}
return 0;
}
-static int asus_hotk_remove_fs(struct acpi_device* device)
+static int asus_hotk_remove_fs(struct acpi_device *device)
{
- if(acpi_device_dir(device)) {
- remove_proc_entry(PROC_INFO,acpi_device_dir(device));
+ if (acpi_device_dir(device)) {
+ remove_proc_entry(PROC_INFO, acpi_device_dir(device));
if (hotk->methods->mt_wled)
- remove_proc_entry(PROC_WLED,acpi_device_dir(device));
+ remove_proc_entry(PROC_WLED, acpi_device_dir(device));
if (hotk->methods->mt_mled)
- remove_proc_entry(PROC_MLED,acpi_device_dir(device));
+ remove_proc_entry(PROC_MLED, acpi_device_dir(device));
if (hotk->methods->mt_tled)
- remove_proc_entry(PROC_TLED,acpi_device_dir(device));
+ remove_proc_entry(PROC_TLED, acpi_device_dir(device));
if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status)
remove_proc_entry(PROC_LCD, acpi_device_dir(device));
- if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
- (hotk->methods->brightness_get && hotk->methods->brightness_set))
+ if ((hotk->methods->brightness_up
+ && hotk->methods->brightness_down)
+ || (hotk->methods->brightness_get
+ && hotk->methods->brightness_set))
remove_proc_entry(PROC_BRN, acpi_device_dir(device));
if (hotk->methods->display_set)
remove_proc_entry(PROC_DISP, acpi_device_dir(device));
@@ -933,16 +930,15 @@ static int asus_hotk_remove_fs(struct acpi_device* device)
return 0;
}
-
static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
{
- /* TODO Find a better way to handle events count.*/
+ /* TODO Find a better way to handle events count. */
if (!hotk)
return;
if ((event & ~((u32) BR_UP)) < 16) {
hotk->brightness = (event & ~((u32) BR_UP));
- } else if ((event & ~((u32) BR_DOWN)) < 16 ) {
+ } else if ((event & ~((u32) BR_DOWN)) < 16) {
hotk->brightness = (event & ~((u32) BR_DOWN));
}
@@ -976,7 +972,7 @@ static int __init asus_hotk_get_info(void)
if (ACPI_FAILURE(status))
printk(KERN_WARNING " Couldn't get the DSDT table header\n");
else
- asus_info = (struct acpi_table_header *) dsdt.pointer;
+ asus_info = (struct acpi_table_header *)dsdt.pointer;
/* We have to write 0 on init this far for all ASUS models */
if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
@@ -988,15 +984,17 @@ static int __init asus_hotk_get_info(void)
if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result))
printk(KERN_WARNING " Error calling BSTS\n");
else if (bsts_result)
- printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", bsts_result);
+ printk(KERN_NOTICE " BSTS called, 0x%02x returned\n",
+ bsts_result);
/* Samsung P30 has a device with a valid _HID whose INIT does not
* return anything. Catch this one and any similar here */
if (buffer.pointer == NULL) {
- if (asus_info && /* Samsung P30 */
+ if (asus_info && /* Samsung P30 */
strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) {
hotk->model = P30;
- printk(KERN_NOTICE " Samsung P30 detected, supported\n");
+ printk(KERN_NOTICE
+ " Samsung P30 detected, supported\n");
} else {
hotk->model = M2E;
printk(KERN_WARNING " no string returned by INIT\n");
@@ -1006,10 +1004,11 @@ static int __init asus_hotk_get_info(void)
hotk->methods = &model_conf[hotk->model];
return AE_OK;
}
-
- model = (union acpi_object *) buffer.pointer;
+
+ model = (union acpi_object *)buffer.pointer;
if (model->type == ACPI_TYPE_STRING) {
- printk(KERN_NOTICE " %s model detected, ", model->string.pointer);
+ printk(KERN_NOTICE " %s model detected, ",
+ model->string.pointer);
}
hotk->model = END_MODEL;
@@ -1035,7 +1034,7 @@ static int __init asus_hotk_get_info(void)
strncmp(model->string.pointer, "M6N", 3) == 0 ||
strncmp(model->string.pointer, "S1N", 3) == 0 ||
strncmp(model->string.pointer, "S5N", 3) == 0 ||
- strncmp(model->string.pointer, "W1N", 3) == 0)
+ strncmp(model->string.pointer, "W1N", 3) == 0)
hotk->model = xxN;
else if (strncmp(model->string.pointer, "M1", 2) == 0)
hotk->model = M1A;
@@ -1069,21 +1068,21 @@ static int __init asus_hotk_get_info(void)
/* Sort of per-model blacklist */
if (strncmp(model->string.pointer, "L2B", 3) == 0)
- hotk->methods->lcd_status = NULL;
+ hotk->methods->lcd_status = NULL;
/* L2B is similar enough to L3C to use its settings, with this only
exception */
else if (strncmp(model->string.pointer, "S5N", 3) == 0 ||
strncmp(model->string.pointer, "M5N", 3) == 0)
- hotk->methods->mt_mled = NULL;
+ hotk->methods->mt_mled = NULL;
/* S5N and M5N have no MLED */
else if (strncmp(model->string.pointer, "M2N", 3) == 0 ||
strncmp(model->string.pointer, "W1N", 3) == 0)
- hotk->methods->mt_wled = "WLED";
+ hotk->methods->mt_wled = "WLED";
/* M2N and W1N have a usable WLED */
else if (asus_info) {
if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
hotk->methods->mled_status = NULL;
- /* S1300A reports L84F, but L1400B too, account for that */
+ /* S1300A reports L84F, but L1400B too, account for that */
}
acpi_os_free(model);
@@ -1091,7 +1090,6 @@ static int __init asus_hotk_get_info(void)
return AE_OK;
}
-
static int __init asus_hotk_check(void)
{
int result = 0;
@@ -1110,7 +1108,6 @@ static int __init asus_hotk_check(void)
return result;
}
-
static int __init asus_hotk_add(struct acpi_device *device)
{
acpi_status status = AE_OK;
@@ -1123,7 +1120,7 @@ static int __init asus_hotk_add(struct acpi_device *device)
ASUS_ACPI_VERSION);
hotk =
- (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+ (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
if (!hotk)
return -ENOMEM;
memset(hotk, 0, sizeof(struct asus_hotk));
@@ -1134,7 +1131,6 @@ static int __init asus_hotk_add(struct acpi_device *device)
acpi_driver_data(device) = hotk;
hotk->device = device;
-
result = asus_hotk_check();
if (result)
goto end;
@@ -1153,17 +1149,22 @@ static int __init asus_hotk_add(struct acpi_device *device)
printk(KERN_ERR " Error installing notify handler\n");
/* For laptops without GPLV: init the hotk->brightness value */
- if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) &&
- (hotk->methods->brightness_up && hotk->methods->brightness_down)) {
- status = acpi_evaluate_object(NULL, hotk->methods->brightness_down,
- NULL, NULL);
+ if ((!hotk->methods->brightness_get)
+ && (!hotk->methods->brightness_status)
+ && (hotk->methods->brightness_up
+ && hotk->methods->brightness_down)) {
+ status =
+ acpi_evaluate_object(NULL, hotk->methods->brightness_down,
+ NULL, NULL);
if (ACPI_FAILURE(status))
printk(KERN_WARNING " Error changing brightness\n");
else {
- status = acpi_evaluate_object(NULL, hotk->methods->brightness_up,
- NULL, NULL);
+ status =
+ acpi_evaluate_object(NULL,
+ hotk->methods->brightness_up,
+ NULL, NULL);
if (ACPI_FAILURE(status))
- printk(KERN_WARNING " Strange, error changing"
+ printk(KERN_WARNING " Strange, error changing"
" brightness\n");
}
}
@@ -1176,7 +1177,6 @@ static int __init asus_hotk_add(struct acpi_device *device)
return result;
}
-
static int asus_hotk_remove(struct acpi_device *device, int type)
{
acpi_status status = 0;
@@ -1196,7 +1196,6 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
return 0;
}
-
static int __init asus_acpi_init(void)
{
int result;
@@ -1204,9 +1203,9 @@ static int __init asus_acpi_init(void)
if (acpi_disabled)
return -ENODEV;
- if (!acpi_specific_hotkey_enabled){
+ if (!acpi_specific_hotkey_enabled) {
printk(KERN_ERR "Using generic hotkey driver\n");
- return -ENODEV;
+ return -ENODEV;
}
asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
if (!asus_proc_dir) {
@@ -1225,7 +1224,6 @@ static int __init asus_acpi_init(void)
return 0;
}
-
static void __exit asus_acpi_exit(void)
{
acpi_bus_unregister_driver(&asus_hotk_driver);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index c55feca9b7d5..702e857e98c5 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -34,7 +34,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS"
@@ -53,87 +52,85 @@
#define ACPI_BATTERY_UNITS_WATTS "mW"
#define ACPI_BATTERY_UNITS_AMPS "mA"
-
#define _COMPONENT ACPI_BATTERY_COMPONENT
-ACPI_MODULE_NAME ("acpi_battery")
+ACPI_MODULE_NAME("acpi_battery")
-MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME);
MODULE_LICENSE("GPL");
-static int acpi_battery_add (struct acpi_device *device);
-static int acpi_battery_remove (struct acpi_device *device, int type);
+static int acpi_battery_add(struct acpi_device *device);
+static int acpi_battery_remove(struct acpi_device *device, int type);
static struct acpi_driver acpi_battery_driver = {
- .name = ACPI_BATTERY_DRIVER_NAME,
- .class = ACPI_BATTERY_CLASS,
- .ids = ACPI_BATTERY_HID,
- .ops = {
- .add = acpi_battery_add,
- .remove = acpi_battery_remove,
- },
+ .name = ACPI_BATTERY_DRIVER_NAME,
+ .class = ACPI_BATTERY_CLASS,
+ .ids = ACPI_BATTERY_HID,
+ .ops = {
+ .add = acpi_battery_add,
+ .remove = acpi_battery_remove,
+ },
};
struct acpi_battery_status {
- acpi_integer state;
- acpi_integer present_rate;
- acpi_integer remaining_capacity;
- acpi_integer present_voltage;
+ acpi_integer state;
+ acpi_integer present_rate;
+ acpi_integer remaining_capacity;
+ acpi_integer present_voltage;
};
struct acpi_battery_info {
- acpi_integer power_unit;
- acpi_integer design_capacity;
- acpi_integer last_full_capacity;
- acpi_integer battery_technology;
- acpi_integer design_voltage;
- acpi_integer design_capacity_warning;
- acpi_integer design_capacity_low;
- acpi_integer battery_capacity_granularity_1;
- acpi_integer battery_capacity_granularity_2;
- acpi_string model_number;
- acpi_string serial_number;
- acpi_string battery_type;
- acpi_string oem_info;
+ acpi_integer power_unit;
+ acpi_integer design_capacity;
+ acpi_integer last_full_capacity;
+ acpi_integer battery_technology;
+ acpi_integer design_voltage;
+ acpi_integer design_capacity_warning;
+ acpi_integer design_capacity_low;
+ acpi_integer battery_capacity_granularity_1;
+ acpi_integer battery_capacity_granularity_2;
+ acpi_string model_number;
+ acpi_string serial_number;
+ acpi_string battery_type;
+ acpi_string oem_info;
};
struct acpi_battery_flags {
- u8 present:1; /* Bay occupied? */
- u8 power_unit:1; /* 0=watts, 1=apms */
- u8 alarm:1; /* _BTP present? */
- u8 reserved:5;
+ u8 present:1; /* Bay occupied? */
+ u8 power_unit:1; /* 0=watts, 1=apms */
+ u8 alarm:1; /* _BTP present? */
+ u8 reserved:5;
};
struct acpi_battery_trips {
- unsigned long warning;
- unsigned long low;
+ unsigned long warning;
+ unsigned long low;
};
struct acpi_battery {
- acpi_handle handle;
+ acpi_handle handle;
struct acpi_battery_flags flags;
struct acpi_battery_trips trips;
- unsigned long alarm;
+ unsigned long alarm;
struct acpi_battery_info *info;
};
-
/* --------------------------------------------------------------------------
Battery Management
-------------------------------------------------------------------------- */
static int
-acpi_battery_get_info (
- struct acpi_battery *battery,
- struct acpi_battery_info **bif)
+acpi_battery_get_info(struct acpi_battery *battery,
+ struct acpi_battery_info **bif)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BIF),
- ACPI_BATTERY_FORMAT_BIF};
- struct acpi_buffer data = {0, NULL};
- union acpi_object *package = NULL;
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
+ ACPI_BATTERY_FORMAT_BIF
+ };
+ struct acpi_buffer data = { 0, NULL };
+ union acpi_object *package = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_get_info");
@@ -148,7 +145,7 @@ acpi_battery_get_info (
return_VALUE(-ENODEV);
}
- package = (union acpi_object *) buffer.pointer;
+ package = (union acpi_object *)buffer.pointer;
/* Extract Package Data */
@@ -174,27 +171,27 @@ acpi_battery_get_info (
goto end;
}
-end:
+ end:
acpi_os_free(buffer.pointer);
if (!result)
- (*bif) = (struct acpi_battery_info *) data.pointer;
+ (*bif) = (struct acpi_battery_info *)data.pointer;
return_VALUE(result);
}
static int
-acpi_battery_get_status (
- struct acpi_battery *battery,
- struct acpi_battery_status **bst)
+acpi_battery_get_status(struct acpi_battery *battery,
+ struct acpi_battery_status **bst)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BST),
- ACPI_BATTERY_FORMAT_BST};
- struct acpi_buffer data = {0, NULL};
- union acpi_object *package = NULL;
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
+ ACPI_BATTERY_FORMAT_BST
+ };
+ struct acpi_buffer data = { 0, NULL };
+ union acpi_object *package = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_get_status");
@@ -209,7 +206,7 @@ acpi_battery_get_status (
return_VALUE(-ENODEV);
}
- package = (union acpi_object *) buffer.pointer;
+ package = (union acpi_object *)buffer.pointer;
/* Extract Package Data */
@@ -235,24 +232,21 @@ acpi_battery_get_status (
goto end;
}
-end:
+ end:
acpi_os_free(buffer.pointer);
if (!result)
- (*bst) = (struct acpi_battery_status *) data.pointer;
+ (*bst) = (struct acpi_battery_status *)data.pointer;
return_VALUE(result);
}
-
static int
-acpi_battery_set_alarm (
- struct acpi_battery *battery,
- unsigned long alarm)
+acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm)
{
- acpi_status status = 0;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list arg_list = {1, &arg0};
+ acpi_status status = 0;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg0 };
ACPI_FUNCTION_TRACE("acpi_battery_set_alarm");
@@ -275,19 +269,16 @@ acpi_battery_set_alarm (
return_VALUE(0);
}
-
-static int
-acpi_battery_check (
- struct acpi_battery *battery)
+static int acpi_battery_check(struct acpi_battery *battery)
{
- int result = 0;
- acpi_status status = AE_OK;
- acpi_handle handle = NULL;
- struct acpi_device *device = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ acpi_handle handle = NULL;
+ struct acpi_device *device = NULL;
struct acpi_battery_info *bif = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_check");
-
+
if (!battery)
return_VALUE(-EINVAL);
@@ -336,18 +327,17 @@ acpi_battery_check (
return_VALUE(result);
}
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_battery_dir;
+static struct proc_dir_entry *acpi_battery_dir;
static int acpi_battery_read_info(struct seq_file *seq, void *offset)
{
- int result = 0;
- struct acpi_battery *battery = (struct acpi_battery *) seq->private;
+ int result = 0;
+ struct acpi_battery *battery = (struct acpi_battery *)seq->private;
struct acpi_battery_info *bif = NULL;
- char *units = "?";
+ char *units = "?";
ACPI_FUNCTION_TRACE("acpi_battery_read_info");
@@ -369,19 +359,21 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
goto end;
}
- units = bif->power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
-
+ units =
+ bif->
+ power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+
if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "design capacity: unknown\n");
else
seq_printf(seq, "design capacity: %d %sh\n",
- (u32) bif->design_capacity, units);
+ (u32) bif->design_capacity, units);
if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "last full capacity: unknown\n");
else
seq_printf(seq, "last full capacity: %d %sh\n",
- (u32) bif->last_full_capacity, units);
+ (u32) bif->last_full_capacity, units);
switch ((u32) bif->battery_technology) {
case 0:
@@ -399,26 +391,22 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
seq_printf(seq, "design voltage: unknown\n");
else
seq_printf(seq, "design voltage: %d mV\n",
- (u32) bif->design_voltage);
-
+ (u32) bif->design_voltage);
+
seq_printf(seq, "design capacity warning: %d %sh\n",
- (u32) bif->design_capacity_warning, units);
+ (u32) bif->design_capacity_warning, units);
seq_printf(seq, "design capacity low: %d %sh\n",
- (u32) bif->design_capacity_low, units);
+ (u32) bif->design_capacity_low, units);
seq_printf(seq, "capacity granularity 1: %d %sh\n",
- (u32) bif->battery_capacity_granularity_1, units);
+ (u32) bif->battery_capacity_granularity_1, units);
seq_printf(seq, "capacity granularity 2: %d %sh\n",
- (u32) bif->battery_capacity_granularity_2, units);
- seq_printf(seq, "model number: %s\n",
- bif->model_number);
- seq_printf(seq, "serial number: %s\n",
- bif->serial_number);
- seq_printf(seq, "battery type: %s\n",
- bif->battery_type);
- seq_printf(seq, "OEM info: %s\n",
- bif->oem_info);
-
-end:
+ (u32) bif->battery_capacity_granularity_2, units);
+ seq_printf(seq, "model number: %s\n", bif->model_number);
+ seq_printf(seq, "serial number: %s\n", bif->serial_number);
+ seq_printf(seq, "battery type: %s\n", bif->battery_type);
+ seq_printf(seq, "OEM info: %s\n", bif->oem_info);
+
+ end:
kfree(bif);
return_VALUE(0);
@@ -429,14 +417,12 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_battery_read_info, PDE(inode)->data);
}
-
-static int
-acpi_battery_read_state (struct seq_file *seq, void *offset)
+static int acpi_battery_read_state(struct seq_file *seq, void *offset)
{
- int result = 0;
- struct acpi_battery *battery = (struct acpi_battery *) seq->private;
+ int result = 0;
+ struct acpi_battery *battery = (struct acpi_battery *)seq->private;
struct acpi_battery_status *bst = NULL;
- char *units = "?";
+ char *units = "?";
ACPI_FUNCTION_TRACE("acpi_battery_read_state");
@@ -452,7 +438,9 @@ acpi_battery_read_state (struct seq_file *seq, void *offset)
/* Battery Units */
- units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+ units =
+ battery->flags.
+ power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
/* Battery Status (_BST) */
@@ -467,12 +455,12 @@ acpi_battery_read_state (struct seq_file *seq, void *offset)
else
seq_printf(seq, "capacity state: critical\n");
- if ((bst->state & 0x01) && (bst->state & 0x02)){
- seq_printf(seq, "charging state: charging/discharging\n");
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Battery Charging and Discharging?\n"));
- }
- else if (bst->state & 0x01)
+ if ((bst->state & 0x01) && (bst->state & 0x02)) {
+ seq_printf(seq,
+ "charging state: charging/discharging\n");
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Battery Charging and Discharging?\n"));
+ } else if (bst->state & 0x01)
seq_printf(seq, "charging state: discharging\n");
else if (bst->state & 0x02)
seq_printf(seq, "charging state: charging\n");
@@ -484,21 +472,21 @@ acpi_battery_read_state (struct seq_file *seq, void *offset)
seq_printf(seq, "present rate: unknown\n");
else
seq_printf(seq, "present rate: %d %s\n",
- (u32) bst->present_rate, units);
+ (u32) bst->present_rate, units);
if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "remaining capacity: unknown\n");
else
seq_printf(seq, "remaining capacity: %d %sh\n",
- (u32) bst->remaining_capacity, units);
+ (u32) bst->remaining_capacity, units);
if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present voltage: unknown\n");
else
seq_printf(seq, "present voltage: %d mV\n",
- (u32) bst->present_voltage);
+ (u32) bst->present_voltage);
-end:
+ end:
kfree(bst);
return_VALUE(0);
@@ -509,12 +497,10 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_battery_read_state, PDE(inode)->data);
}
-
-static int
-acpi_battery_read_alarm (struct seq_file *seq, void *offset)
+static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
{
- struct acpi_battery *battery = (struct acpi_battery *) seq->private;
- char *units = "?";
+ struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+ char *units = "?";
ACPI_FUNCTION_TRACE("acpi_battery_read_alarm");
@@ -527,8 +513,10 @@ acpi_battery_read_alarm (struct seq_file *seq, void *offset)
}
/* Battery Units */
-
- units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+
+ units =
+ battery->flags.
+ power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
/* Battery Alarm */
@@ -538,22 +526,19 @@ acpi_battery_read_alarm (struct seq_file *seq, void *offset)
else
seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units);
-end:
+ end:
return_VALUE(0);
}
-
static ssize_t
-acpi_battery_write_alarm (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_battery_write_alarm(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
- int result = 0;
- char alarm_string[12] = {'\0'};
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_battery *battery = (struct acpi_battery *)m->private;
+ int result = 0;
+ char alarm_string[12] = { '\0' };
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_battery *battery = (struct acpi_battery *)m->private;
ACPI_FUNCTION_TRACE("acpi_battery_write_alarm");
@@ -565,11 +550,11 @@ acpi_battery_write_alarm (
if (copy_from_user(alarm_string, buffer, count))
return_VALUE(-EFAULT);
-
+
alarm_string[count] = '\0';
- result = acpi_battery_set_alarm(battery,
- simple_strtoul(alarm_string, NULL, 0));
+ result = acpi_battery_set_alarm(battery,
+ simple_strtoul(alarm_string, NULL, 0));
if (result)
return_VALUE(result);
@@ -582,41 +567,39 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
}
static struct file_operations acpi_battery_info_ops = {
- .open = acpi_battery_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_battery_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
.owner = THIS_MODULE,
};
static struct file_operations acpi_battery_state_ops = {
- .open = acpi_battery_state_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_battery_state_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
.owner = THIS_MODULE,
};
static struct file_operations acpi_battery_alarm_ops = {
- .open = acpi_battery_alarm_open_fs,
- .read = seq_read,
- .write = acpi_battery_write_alarm,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_battery_alarm_open_fs,
+ .read = seq_read,
+ .write = acpi_battery_write_alarm,
+ .llseek = seq_lseek,
+ .release = single_release,
.owner = THIS_MODULE,
};
-static int
-acpi_battery_add_fs (
- struct acpi_device *device)
+static int acpi_battery_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_add_fs");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_battery_dir);
+ acpi_battery_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
acpi_device_dir(device)->owner = THIS_MODULE;
@@ -624,24 +607,24 @@ acpi_battery_add_fs (
/* 'info' [R] */
entry = create_proc_entry(ACPI_BATTERY_FILE_INFO,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BATTERY_FILE_INFO));
+ "Unable to create '%s' fs entry\n",
+ ACPI_BATTERY_FILE_INFO));
else {
- entry->proc_fops = &acpi_battery_info_ops;
+ entry->proc_fops = &acpi_battery_info_ops;
entry->data = acpi_driver_data(device);
entry->owner = THIS_MODULE;
}
/* 'status' [R] */
entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BATTERY_FILE_STATUS));
+ "Unable to create '%s' fs entry\n",
+ ACPI_BATTERY_FILE_STATUS));
else {
entry->proc_fops = &acpi_battery_state_ops;
entry->data = acpi_driver_data(device);
@@ -650,11 +633,12 @@ acpi_battery_add_fs (
/* 'alarm' [R/W] */
entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BATTERY_FILE_ALARM));
+ "Unable to create '%s' fs entry\n",
+ ACPI_BATTERY_FILE_ALARM));
else {
entry->proc_fops = &acpi_battery_alarm_ops;
entry->data = acpi_driver_data(device);
@@ -664,10 +648,7 @@ acpi_battery_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_battery_remove_fs (
- struct acpi_device *device)
+static int acpi_battery_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_battery_remove_fs");
@@ -686,19 +667,14 @@ acpi_battery_remove_fs (
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static void
-acpi_battery_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_battery *battery = (struct acpi_battery *) data;
- struct acpi_device *device = NULL;
+ struct acpi_battery *battery = (struct acpi_battery *)data;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_notify");
@@ -716,24 +692,21 @@ acpi_battery_notify (
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-
-static int
-acpi_battery_add (
- struct acpi_device *device)
+static int acpi_battery_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_battery *battery = NULL;
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_battery *battery = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_add");
-
+
if (!device)
return_VALUE(-EINVAL);
@@ -756,19 +729,20 @@ acpi_battery_add (
goto end;
status = acpi_install_notify_handler(battery->handle,
- ACPI_DEVICE_NOTIFY, acpi_battery_notify, battery);
+ ACPI_DEVICE_NOTIFY,
+ acpi_battery_notify, battery);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
result = -ENODEV;
goto end;
}
printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
- ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
- device->status.battery_present?"present":"absent");
-
-end:
+ ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
+ device->status.battery_present ? "present" : "absent");
+
+ end:
if (result) {
acpi_battery_remove_fs(device);
kfree(battery);
@@ -777,27 +751,24 @@ end:
return_VALUE(result);
}
-
-static int
-acpi_battery_remove (
- struct acpi_device *device,
- int type)
+static int acpi_battery_remove(struct acpi_device *device, int type)
{
- acpi_status status = 0;
- struct acpi_battery *battery = NULL;
+ acpi_status status = 0;
+ struct acpi_battery *battery = NULL;
ACPI_FUNCTION_TRACE("acpi_battery_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- battery = (struct acpi_battery *) acpi_driver_data(device);
+ battery = (struct acpi_battery *)acpi_driver_data(device);
status = acpi_remove_notify_handler(battery->handle,
- ACPI_DEVICE_NOTIFY, acpi_battery_notify);
+ ACPI_DEVICE_NOTIFY,
+ acpi_battery_notify);
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
acpi_battery_remove_fs(device);
@@ -806,11 +777,9 @@ acpi_battery_remove (
return_VALUE(0);
}
-
-static int __init
-acpi_battery_init (void)
+static int __init acpi_battery_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_battery_init");
@@ -828,9 +797,7 @@ acpi_battery_init (void)
return_VALUE(0);
}
-
-static void __exit
-acpi_battery_exit (void)
+static void __exit acpi_battery_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_battery_exit");
@@ -841,6 +808,5 @@ acpi_battery_exit (void)
return_VOID;
}
-
module_init(acpi_battery_init);
module_exit(acpi_battery_exit);
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 4c010e7f11b8..9824f679a910 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -26,7 +26,6 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -34,49 +33,49 @@
#include <acpi/acpi_bus.h>
#include <linux/dmi.h>
-enum acpi_blacklist_predicates
-{
- all_versions,
- less_than_or_equal,
- equal,
- greater_than_or_equal,
+enum acpi_blacklist_predicates {
+ all_versions,
+ less_than_or_equal,
+ equal,
+ greater_than_or_equal,
};
-struct acpi_blacklist_item
-{
- char oem_id[7];
- char oem_table_id[9];
- u32 oem_revision;
- acpi_table_type table;
- enum acpi_blacklist_predicates oem_revision_predicate;
- char *reason;
- u32 is_critical_error;
+struct acpi_blacklist_item {
+ char oem_id[7];
+ char oem_table_id[9];
+ u32 oem_revision;
+ acpi_table_type table;
+ enum acpi_blacklist_predicates oem_revision_predicate;
+ char *reason;
+ u32 is_critical_error;
};
/*
* POLICY: If *anything* doesn't work, put it on the blacklist.
* If they are critical errors, mark it critical, and abort driver load.
*/
-static struct acpi_blacklist_item acpi_blacklist[] __initdata =
-{
+static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
/* Compaq Presario 1700 */
- {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, "Multiple problems", 1},
+ {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal,
+ "Multiple problems", 1},
/* Sony FX120, FX140, FX150? */
- {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal, "ACPI driver problem", 1},
+ {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal,
+ "ACPI driver problem", 1},
/* Compaq Presario 800, Insyde BIOS */
- {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, "Does not use _REG to protect EC OpRegions", 1},
+ {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal,
+ "Does not use _REG to protect EC OpRegions", 1},
/* IBM 600E - _ADR should return 7, but it returns 1 */
- {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal, "Incorrect _ADR", 1},
- {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions, "Bogus PCI routing", 1},
+ {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal,
+ "Incorrect _ADR", 1},
+ {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions,
+ "Bogus PCI routing", 1},
{""}
};
-
#if CONFIG_ACPI_BLACKLIST_YEAR
-static int __init
-blacklist_by_year(void)
+static int __init blacklist_by_year(void)
{
int year;
char *s = dmi_get_system_info(DMI_BIOS_DATE);
@@ -92,36 +91,38 @@ blacklist_by_year(void)
s += 1;
- year = simple_strtoul(s,NULL,0);
+ year = simple_strtoul(s, NULL, 0);
- if (year < 100) { /* 2-digit year */
+ if (year < 100) { /* 2-digit year */
year += 1900;
if (year < 1996) /* no dates < spec 1.0 */
year += 100;
}
if (year < CONFIG_ACPI_BLACKLIST_YEAR) {
- printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), "
- "acpi=force is required to enable ACPI\n",
- year, CONFIG_ACPI_BLACKLIST_YEAR);
+ printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), "
+ "acpi=force is required to enable ACPI\n",
+ year, CONFIG_ACPI_BLACKLIST_YEAR);
return 1;
}
return 0;
}
#else
-static inline int blacklist_by_year(void) { return 0; }
+static inline int blacklist_by_year(void)
+{
+ return 0;
+}
#endif
-int __init
-acpi_blacklisted(void)
+int __init acpi_blacklisted(void)
{
int i = 0;
int blacklisted = 0;
struct acpi_table_header *table_header;
- while (acpi_blacklist[i].oem_id[0] != '\0')
- {
- if (acpi_get_table_header_early(acpi_blacklist[i].table, &table_header)) {
+ while (acpi_blacklist[i].oem_id[0] != '\0') {
+ if (acpi_get_table_header_early
+ (acpi_blacklist[i].table, &table_header)) {
i++;
continue;
}
@@ -131,33 +132,43 @@ acpi_blacklisted(void)
continue;
}
- if (strncmp(acpi_blacklist[i].oem_table_id, table_header->oem_table_id, 8)) {
+ if (strncmp
+ (acpi_blacklist[i].oem_table_id, table_header->oem_table_id,
+ 8)) {
i++;
continue;
}
if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
- || (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal
- && table_header->oem_revision <= acpi_blacklist[i].oem_revision)
- || (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal
- && table_header->oem_revision >= acpi_blacklist[i].oem_revision)
+ || (acpi_blacklist[i].oem_revision_predicate ==
+ less_than_or_equal
+ && table_header->oem_revision <=
+ acpi_blacklist[i].oem_revision)
+ || (acpi_blacklist[i].oem_revision_predicate ==
+ greater_than_or_equal
+ && table_header->oem_revision >=
+ acpi_blacklist[i].oem_revision)
|| (acpi_blacklist[i].oem_revision_predicate == equal
- && table_header->oem_revision == acpi_blacklist[i].oem_revision)) {
-
- printk(KERN_ERR PREFIX "Vendor \"%6.6s\" System \"%8.8s\" "
- "Revision 0x%x has a known ACPI BIOS problem.\n",
- acpi_blacklist[i].oem_id,
- acpi_blacklist[i].oem_table_id,
- acpi_blacklist[i].oem_revision);
-
- printk(KERN_ERR PREFIX "Reason: %s. This is a %s error\n",
- acpi_blacklist[i].reason,
- (acpi_blacklist[i].is_critical_error ? "non-recoverable" : "recoverable"));
+ && table_header->oem_revision ==
+ acpi_blacklist[i].oem_revision)) {
+
+ printk(KERN_ERR PREFIX
+ "Vendor \"%6.6s\" System \"%8.8s\" "
+ "Revision 0x%x has a known ACPI BIOS problem.\n",
+ acpi_blacklist[i].oem_id,
+ acpi_blacklist[i].oem_table_id,
+ acpi_blacklist[i].oem_revision);
+
+ printk(KERN_ERR PREFIX
+ "Reason: %s. This is a %s error\n",
+ acpi_blacklist[i].reason,
+ (acpi_blacklist[i].
+ is_critical_error ? "non-recoverable" :
+ "recoverable"));
blacklisted = acpi_blacklist[i].is_critical_error;
break;
- }
- else {
+ } else {
i++;
}
}
@@ -166,4 +177,3 @@ acpi_blacklisted(void)
return blacklisted;
}
-
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index d77c2307883c..6a4da417c16b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -36,19 +36,17 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME ("acpi_bus")
-
+ACPI_MODULE_NAME("acpi_bus")
#ifdef CONFIG_X86
extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
#endif
-FADT_DESCRIPTOR acpi_fadt;
+FADT_DESCRIPTOR acpi_fadt;
EXPORT_SYMBOL(acpi_fadt);
-struct acpi_device *acpi_root;
-struct proc_dir_entry *acpi_root_dir;
+struct acpi_device *acpi_root;
+struct proc_dir_entry *acpi_root_dir;
EXPORT_SYMBOL(acpi_root_dir);
#define STRUCT_TO_INT(s) (*((int*)&s))
@@ -57,12 +55,9 @@ EXPORT_SYMBOL(acpi_root_dir);
Device Management
-------------------------------------------------------------------------- */
-int
-acpi_bus_get_device (
- acpi_handle handle,
- struct acpi_device **device)
+int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
{
- acpi_status status = AE_OK;
+ acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("acpi_bus_get_device");
@@ -71,24 +66,23 @@ acpi_bus_get_device (
/* TBD: Support fixed-feature devices */
- status = acpi_get_data(handle, acpi_bus_data_handler, (void**) device);
+ status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
if (ACPI_FAILURE(status) || !*device) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No context for object [%p]\n",
- handle));
+ handle));
return_VALUE(-ENODEV);
}
return_VALUE(0);
}
+
EXPORT_SYMBOL(acpi_bus_get_device);
-int
-acpi_bus_get_status (
- struct acpi_device *device)
+int acpi_bus_get_status(struct acpi_device *device)
{
- acpi_status status = AE_OK;
- unsigned long sta = 0;
-
+ acpi_status status = AE_OK;
+ unsigned long sta = 0;
+
ACPI_FUNCTION_TRACE("acpi_bus_get_status");
if (!device)
@@ -98,10 +92,11 @@ acpi_bus_get_status (
* Evaluate _STA if present.
*/
if (device->flags.dynamic_status) {
- status = acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
+ status =
+ acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
- STRUCT_TO_INT(device->status) = (int) sta;
+ STRUCT_TO_INT(device->status) = (int)sta;
}
/*
@@ -115,33 +110,30 @@ acpi_bus_get_status (
if (device->status.functional && !device->status.present) {
printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
- "functional but not present; setting present\n",
- device->pnp.bus_id,
- (u32) STRUCT_TO_INT(device->status));
+ "functional but not present; setting present\n",
+ device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
device->status.present = 1;
}
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
- device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
+ device->pnp.bus_id,
+ (u32) STRUCT_TO_INT(device->status)));
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_bus_get_status);
+EXPORT_SYMBOL(acpi_bus_get_status);
/* --------------------------------------------------------------------------
Power Management
-------------------------------------------------------------------------- */
-int
-acpi_bus_get_power (
- acpi_handle handle,
- int *state)
+int acpi_bus_get_power(acpi_handle handle, int *state)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_device *device = NULL;
- unsigned long psc = 0;
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_device *device = NULL;
+ unsigned long psc = 0;
ACPI_FUNCTION_TRACE("acpi_bus_get_power");
@@ -157,20 +149,18 @@ acpi_bus_get_power (
*state = device->parent->power.state;
else
*state = ACPI_STATE_D0;
- }
- else {
+ } else {
/*
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
if (device->power.flags.explicit_get) {
- status = acpi_evaluate_integer(device->handle, "_PSC",
- NULL, &psc);
+ status = acpi_evaluate_integer(device->handle, "_PSC",
+ NULL, &psc);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
- device->power.state = (int) psc;
- }
- else if (device->power.flags.power_resources) {
+ device->power.state = (int)psc;
+ } else if (device->power.flags.power_resources) {
result = acpi_power_get_inferred_state(device);
if (result)
return_VALUE(result);
@@ -180,22 +170,19 @@ acpi_bus_get_power (
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
- device->pnp.bus_id, device->power.state));
+ device->pnp.bus_id, device->power.state));
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_bus_get_power);
+EXPORT_SYMBOL(acpi_bus_get_power);
-int
-acpi_bus_set_power (
- acpi_handle handle,
- int state)
+int acpi_bus_set_power(acpi_handle handle, int state)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_device *device = NULL;
- char object_name[5] = {'_','P','S','0'+state,'\0'};
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_device *device = NULL;
+ char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
ACPI_FUNCTION_TRACE("acpi_bus_set_power");
@@ -209,7 +196,8 @@ acpi_bus_set_power (
/* Make sure this is a valid target state */
if (!device->flags.power_manageable) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Device is not power manageable\n"));
return_VALUE(-ENODEV);
}
/*
@@ -219,15 +207,18 @@ acpi_bus_set_power (
if (device->power.state == ACPI_STATE_UNKNOWN)
acpi_bus_get_power(device->handle, &device->power.state);
if (state == device->power.state) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
+ state));
return_VALUE(0);
}
if (!device->power.states[state].flags.valid) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", state));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n",
+ state));
return_VALUE(-ENODEV);
}
if (device->parent && (state < device->parent->power.state)) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Cannot set device to a higher-powered state than parent\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Cannot set device to a higher-powered state than parent\n"));
return_VALUE(-ENODEV);
}
@@ -245,18 +236,17 @@ acpi_bus_set_power (
goto end;
}
if (device->power.states[state].flags.explicit_set) {
- status = acpi_evaluate_object(device->handle,
- object_name, NULL, NULL);
+ status = acpi_evaluate_object(device->handle,
+ object_name, NULL, NULL);
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto end;
}
}
- }
- else {
+ } else {
if (device->power.states[state].flags.explicit_set) {
- status = acpi_evaluate_object(device->handle,
- object_name, NULL, NULL);
+ status = acpi_evaluate_object(device->handle,
+ object_name, NULL, NULL);
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto end;
@@ -269,19 +259,20 @@ acpi_bus_set_power (
}
}
-end:
+ end:
if (result)
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error transitioning device [%s] to D%d\n",
- device->pnp.bus_id, state));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Error transitioning device [%s] to D%d\n",
+ device->pnp.bus_id, state));
else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n",
- device->pnp.bus_id, state));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Device [%s] transitioned to D%d\n",
+ device->pnp.bus_id, state));
return_VALUE(result);
}
-EXPORT_SYMBOL(acpi_bus_set_power);
-
+EXPORT_SYMBOL(acpi_bus_set_power);
/* --------------------------------------------------------------------------
Event Management
@@ -292,16 +283,12 @@ static DEFINE_SPINLOCK(acpi_bus_event_lock);
LIST_HEAD(acpi_bus_event_list);
DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
-extern int event_is_open;
+extern int event_is_open;
-int
-acpi_bus_generate_event (
- struct acpi_device *device,
- u8 type,
- int data)
+int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
{
- struct acpi_bus_event *event = NULL;
- unsigned long flags = 0;
+ struct acpi_bus_event *event = NULL;
+ unsigned long flags = 0;
ACPI_FUNCTION_TRACE("acpi_bus_generate_event");
@@ -329,14 +316,13 @@ acpi_bus_generate_event (
return_VALUE(0);
}
+
EXPORT_SYMBOL(acpi_bus_generate_event);
-int
-acpi_bus_receive_event (
- struct acpi_bus_event *event)
+int acpi_bus_receive_event(struct acpi_bus_event *event)
{
- unsigned long flags = 0;
- struct acpi_bus_event *entry = NULL;
+ unsigned long flags = 0;
+ struct acpi_bus_event *entry = NULL;
DECLARE_WAITQUEUE(wait, current);
@@ -361,7 +347,8 @@ acpi_bus_receive_event (
}
spin_lock_irqsave(&acpi_bus_event_lock, flags);
- entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
+ entry =
+ list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
if (entry)
list_del(&entry->node);
spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
@@ -375,19 +362,17 @@ acpi_bus_receive_event (
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_bus_receive_event);
+EXPORT_SYMBOL(acpi_bus_receive_event);
/* --------------------------------------------------------------------------
Notification Handling
-------------------------------------------------------------------------- */
static int
-acpi_bus_check_device (
- struct acpi_device *device,
- int *status_changed)
+acpi_bus_check_device(struct acpi_device *device, int *status_changed)
{
- acpi_status status = 0;
+ acpi_status status = 0;
struct acpi_device_status old_status;
ACPI_FUNCTION_TRACE("acpi_bus_check_device");
@@ -422,15 +407,14 @@ acpi_bus_check_device (
if (status_changed)
*status_changed = 1;
-
+
/*
* Device Insertion/Removal
*/
if ((device->status.present) && !(old_status.present)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
/* TBD: Handle device insertion */
- }
- else if (!(device->status.present) && (old_status.present)) {
+ } else if (!(device->status.present) && (old_status.present)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
/* TBD: Handle device removal */
}
@@ -438,13 +422,10 @@ acpi_bus_check_device (
return_VALUE(0);
}
-
-static int
-acpi_bus_check_scope (
- struct acpi_device *device)
+static int acpi_bus_check_scope(struct acpi_device *device)
{
- int result = 0;
- int status_changed = 0;
+ int result = 0;
+ int status_changed = 0;
ACPI_FUNCTION_TRACE("acpi_bus_check_scope");
@@ -467,20 +448,15 @@ acpi_bus_check_scope (
return_VALUE(0);
}
-
/**
* acpi_bus_notify
* ---------------
* Callback for all 'system-level' device notifications (values 0x00-0x7F).
*/
-static void
-acpi_bus_notify (
- acpi_handle handle,
- u32 type,
- void *data)
+static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
{
- int result = 0;
- struct acpi_device *device = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_notify");
@@ -490,64 +466,73 @@ acpi_bus_notify (
switch (type) {
case ACPI_NOTIFY_BUS_CHECK:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS CHECK notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received BUS CHECK notification for device [%s]\n",
+ device->pnp.bus_id));
result = acpi_bus_check_scope(device);
/*
* TBD: We'll need to outsource certain events to non-ACPI
- * drivers via the device manager (device.c).
+ * drivers via the device manager (device.c).
*/
break;
case ACPI_NOTIFY_DEVICE_CHECK:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received DEVICE CHECK notification for device [%s]\n",
+ device->pnp.bus_id));
result = acpi_bus_check_device(device, NULL);
/*
* TBD: We'll need to outsource certain events to non-ACPI
- * drivers via the device manager (device.c).
+ * drivers via the device manager (device.c).
*/
break;
case ACPI_NOTIFY_DEVICE_WAKE:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received DEVICE WAKE notification for device [%s]\n",
+ device->pnp.bus_id));
/* TBD */
break;
case ACPI_NOTIFY_EJECT_REQUEST:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received EJECT REQUEST notification for device [%s]\n",
+ device->pnp.bus_id));
/* TBD */
break;
case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received DEVICE CHECK LIGHT notification for device [%s]\n",
+ device->pnp.bus_id));
/* TBD: Exactly what does 'light' mean? */
break;
case ACPI_NOTIFY_FREQUENCY_MISMATCH:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received FREQUENCY MISMATCH notification for device [%s]\n",
+ device->pnp.bus_id));
/* TBD */
break;
case ACPI_NOTIFY_BUS_MODE_MISMATCH:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received BUS MODE MISMATCH notification for device [%s]\n",
+ device->pnp.bus_id));
/* TBD */
break;
case ACPI_NOTIFY_POWER_FAULT:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received POWER FAULT notification for device [%s]\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received POWER FAULT notification for device [%s]\n",
+ device->pnp.bus_id));
/* TBD */
break;
default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received unknown/unsupported notification [%08x]\n",
- type));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Received unknown/unsupported notification [%08x]\n",
+ type));
break;
}
@@ -558,13 +543,12 @@ acpi_bus_notify (
Initialization/Cleanup
-------------------------------------------------------------------------- */
-static int __init
-acpi_bus_init_irq (void)
+static int __init acpi_bus_init_irq(void)
{
- acpi_status status = AE_OK;
- union acpi_object arg = {ACPI_TYPE_INTEGER};
- struct acpi_object_list arg_list = {1, &arg};
- char *message = NULL;
+ acpi_status status = AE_OK;
+ union acpi_object arg = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg };
+ char *message = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_init_irq");
@@ -601,12 +585,10 @@ acpi_bus_init_irq (void)
return_VALUE(0);
}
-
-void __init
-acpi_early_init (void)
+void __init acpi_early_init(void)
{
- acpi_status status = AE_OK;
- struct acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt};
+ acpi_status status = AE_OK;
+ struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
ACPI_FUNCTION_TRACE("acpi_early_init");
@@ -619,13 +601,15 @@ acpi_early_init (void)
status = acpi_initialize_subsystem();
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n");
+ printk(KERN_ERR PREFIX
+ "Unable to initialize the ACPI Interpreter\n");
goto error0;
}
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Unable to load the System Description Tables\n");
+ printk(KERN_ERR PREFIX
+ "Unable to load the System Description Tables\n");
goto error0;
}
@@ -637,7 +621,6 @@ acpi_early_init (void)
printk(KERN_ERR PREFIX "Unable to get the FADT\n");
goto error0;
}
-
#ifdef CONFIG_X86
if (!acpi_ioapic) {
extern acpi_interrupt_flags acpi_sci_flags;
@@ -647,7 +630,8 @@ acpi_early_init (void)
acpi_sci_flags.trigger = 3;
/* Set PIC-mode SCI trigger type */
- acpi_pic_sci_set_trigger(acpi_fadt.sci_int, acpi_sci_flags.trigger);
+ acpi_pic_sci_set_trigger(acpi_fadt.sci_int,
+ acpi_sci_flags.trigger);
} else {
extern int acpi_sci_override_gsi;
/*
@@ -658,7 +642,10 @@ acpi_early_init (void)
}
#endif
- status = acpi_enable_subsystem(~(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE));
+ status =
+ acpi_enable_subsystem(~
+ (ACPI_NO_HARDWARE_INIT |
+ ACPI_NO_ACPI_ENABLE));
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
goto error0;
@@ -666,30 +653,32 @@ acpi_early_init (void)
return_VOID;
-error0:
+ error0:
disable_acpi();
return_VOID;
}
-static int __init
-acpi_bus_init (void)
+static int __init acpi_bus_init(void)
{
- int result = 0;
- acpi_status status = AE_OK;
- extern acpi_status acpi_os_initialize1(void);
+ int result = 0;
+ acpi_status status = AE_OK;
+ extern acpi_status acpi_os_initialize1(void);
ACPI_FUNCTION_TRACE("acpi_bus_init");
status = acpi_os_initialize1();
- status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
+ status =
+ acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n");
+ printk(KERN_ERR PREFIX
+ "Unable to start the ACPI Interpreter\n");
goto error1;
}
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Unable to initialize ACPI OS objects\n");
+ printk(KERN_ERR PREFIX
+ "Unable to initialize ACPI OS objects\n");
goto error1;
}
#ifdef CONFIG_ACPI_EC
@@ -723,9 +712,12 @@ acpi_bus_init (void)
/*
* Register the for all standard device notifications.
*/
- status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL);
+ status =
+ acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
+ &acpi_bus_notify, NULL);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Unable to register for device notifications\n");
+ printk(KERN_ERR PREFIX
+ "Unable to register for device notifications\n");
goto error1;
}
@@ -737,21 +729,20 @@ acpi_bus_init (void)
return_VALUE(0);
/* Mimic structured exception handling */
-error1:
+ error1:
acpi_terminate();
return_VALUE(-ENODEV);
}
-decl_subsys(acpi,NULL,NULL);
+decl_subsys(acpi, NULL, NULL);
-static int __init acpi_init (void)
+static int __init acpi_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_init");
- printk(KERN_INFO PREFIX "Subsystem revision %08x\n",
- ACPI_CA_VERSION);
+ printk(KERN_INFO PREFIX "Subsystem revision %08x\n", ACPI_CA_VERSION);
if (acpi_disabled) {
printk(KERN_INFO PREFIX "Interpreter disabled.\n");
@@ -767,7 +758,8 @@ static int __init acpi_init (void)
if (!PM_IS_ACTIVE())
pm_active = 1;
else {
- printk(KERN_INFO PREFIX "APM is already active, exiting\n");
+ printk(KERN_INFO PREFIX
+ "APM is already active, exiting\n");
disable_acpi();
result = -ENODEV;
}
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 8162fd0c21a7..4b6d9f0096a1 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -32,7 +32,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define ACPI_BUTTON_COMPONENT 0x00080000
#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver"
#define ACPI_BUTTON_CLASS "button"
@@ -42,7 +41,7 @@
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
-#define ACPI_BUTTON_HID_POWER "PNP0C0C"
+#define ACPI_BUTTON_HID_POWER "PNP0C0C"
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button (CM)"
#define ACPI_BUTTON_DEVICE_NAME_POWERF "Power Button (FF)"
#define ACPI_BUTTON_TYPE_POWER 0x01
@@ -61,65 +60,65 @@
#define ACPI_BUTTON_TYPE_LID 0x05
#define _COMPONENT ACPI_BUTTON_COMPONENT
-ACPI_MODULE_NAME ("acpi_button")
+ACPI_MODULE_NAME("acpi_button")
-MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
MODULE_LICENSE("GPL");
-
-static int acpi_button_add (struct acpi_device *device);
-static int acpi_button_remove (struct acpi_device *device, int type);
+static int acpi_button_add(struct acpi_device *device);
+static int acpi_button_remove(struct acpi_device *device, int type);
static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
static struct acpi_driver acpi_button_driver = {
- .name = ACPI_BUTTON_DRIVER_NAME,
- .class = ACPI_BUTTON_CLASS,
- .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E",
- .ops = {
- .add = acpi_button_add,
- .remove = acpi_button_remove,
- },
+ .name = ACPI_BUTTON_DRIVER_NAME,
+ .class = ACPI_BUTTON_CLASS,
+ .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E",
+ .ops = {
+ .add = acpi_button_add,
+ .remove = acpi_button_remove,
+ },
};
struct acpi_button {
- acpi_handle handle;
- struct acpi_device *device; /* Fixed button kludge */
- u8 type;
- unsigned long pushed;
+ acpi_handle handle;
+ struct acpi_device *device; /* Fixed button kludge */
+ u8 type;
+ unsigned long pushed;
};
static struct file_operations acpi_button_info_fops = {
- .open = acpi_button_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_button_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static struct file_operations acpi_button_state_fops = {
- .open = acpi_button_state_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_button_state_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
+
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_button_dir;
+static struct proc_dir_entry *acpi_button_dir;
static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_button *button = (struct acpi_button *) seq->private;
+ struct acpi_button *button = (struct acpi_button *)seq->private;
ACPI_FUNCTION_TRACE("acpi_button_info_seq_show");
if (!button || !button->device)
return_VALUE(0);
- seq_printf(seq, "type: %s\n",
- acpi_device_name(button->device));
+ seq_printf(seq, "type: %s\n",
+ acpi_device_name(button->device));
return_VALUE(0);
}
@@ -128,24 +127,24 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
}
-
+
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_button *button = (struct acpi_button *) seq->private;
- acpi_status status;
- unsigned long state;
+ struct acpi_button *button = (struct acpi_button *)seq->private;
+ acpi_status status;
+ unsigned long state;
ACPI_FUNCTION_TRACE("acpi_button_state_seq_show");
if (!button || !button->device)
return_VALUE(0);
- status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state);
+ status = acpi_evaluate_integer(button->handle, "_LID", NULL, &state);
if (ACPI_FAILURE(status)) {
seq_printf(seq, "state: unsupported\n");
- }
- else{
- seq_printf(seq, "state: %s\n", (state ? "open" : "closed"));
+ } else {
+ seq_printf(seq, "state: %s\n",
+ (state ? "open" : "closed"));
}
return_VALUE(0);
@@ -160,12 +159,10 @@ static struct proc_dir_entry *acpi_power_dir;
static struct proc_dir_entry *acpi_sleep_dir;
static struct proc_dir_entry *acpi_lid_dir;
-static int
-acpi_button_add_fs (
- struct acpi_device *device)
+static int acpi_button_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
- struct acpi_button *button = NULL;
+ struct proc_dir_entry *entry = NULL;
+ struct acpi_button *button = NULL;
ACPI_FUNCTION_TRACE("acpi_button_add_fs");
@@ -178,21 +175,21 @@ acpi_button_add_fs (
case ACPI_BUTTON_TYPE_POWER:
case ACPI_BUTTON_TYPE_POWERF:
if (!acpi_power_dir)
- acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
- acpi_button_dir);
+ acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
+ acpi_button_dir);
entry = acpi_power_dir;
break;
case ACPI_BUTTON_TYPE_SLEEP:
case ACPI_BUTTON_TYPE_SLEEPF:
if (!acpi_sleep_dir)
- acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
- acpi_button_dir);
+ acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
+ acpi_button_dir);
entry = acpi_sleep_dir;
break;
case ACPI_BUTTON_TYPE_LID:
if (!acpi_lid_dir)
- acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
- acpi_button_dir);
+ acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
+ acpi_button_dir);
entry = acpi_lid_dir;
break;
}
@@ -208,11 +205,11 @@ acpi_button_add_fs (
/* 'info' [R] */
entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BUTTON_FILE_INFO));
+ "Unable to create '%s' fs entry\n",
+ ACPI_BUTTON_FILE_INFO));
else {
entry->proc_fops = &acpi_button_info_fops;
entry->data = acpi_driver_data(device);
@@ -222,11 +219,11 @@ acpi_button_add_fs (
/* show lid state [R] */
if (button->type == ACPI_BUTTON_TYPE_LID) {
entry = create_proc_entry(ACPI_BUTTON_FILE_STATE,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BUTTON_FILE_INFO));
+ "Unable to create '%s' fs entry\n",
+ ACPI_BUTTON_FILE_INFO));
else {
entry->proc_fops = &acpi_button_state_fops;
entry->data = acpi_driver_data(device);
@@ -237,12 +234,9 @@ acpi_button_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_button_remove_fs (
- struct acpi_device *device)
+static int acpi_button_remove_fs(struct acpi_device *device)
{
- struct acpi_button *button = NULL;
+ struct acpi_button *button = NULL;
ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
@@ -250,30 +244,25 @@ acpi_button_remove_fs (
if (acpi_device_dir(device)) {
if (button->type == ACPI_BUTTON_TYPE_LID)
remove_proc_entry(ACPI_BUTTON_FILE_STATE,
- acpi_device_dir(device));
+ acpi_device_dir(device));
remove_proc_entry(ACPI_BUTTON_FILE_INFO,
- acpi_device_dir(device));
+ acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device),
- acpi_device_dir(device)->parent);
+ acpi_device_dir(device)->parent);
acpi_device_dir(device) = NULL;
}
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static void
-acpi_button_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_button *button = (struct acpi_button *) data;
+ struct acpi_button *button = (struct acpi_button *)data;
ACPI_FUNCTION_TRACE("acpi_button_notify");
@@ -282,24 +271,22 @@ acpi_button_notify (
switch (event) {
case ACPI_BUTTON_NOTIFY_STATUS:
- acpi_bus_generate_event(button->device, event, ++button->pushed);
+ acpi_bus_generate_event(button->device, event,
+ ++button->pushed);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-
-static acpi_status
-acpi_button_notify_fixed (
- void *data)
+static acpi_status acpi_button_notify_fixed(void *data)
{
- struct acpi_button *button = (struct acpi_button *) data;
-
+ struct acpi_button *button = (struct acpi_button *)data;
+
ACPI_FUNCTION_TRACE("acpi_button_notify_fixed");
if (!button)
@@ -310,14 +297,11 @@ acpi_button_notify_fixed (
return_ACPI_STATUS(AE_OK);
}
-
-static int
-acpi_button_add (
- struct acpi_device *device)
+static int acpi_button_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_button *button = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_button *button = NULL;
ACPI_FUNCTION_TRACE("acpi_button_add");
@@ -339,42 +323,34 @@ acpi_button_add (
*/
if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) {
button->type = ACPI_BUTTON_TYPE_POWER;
- strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_POWER);
- sprintf(acpi_device_class(device), "%s/%s",
+ strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_POWER);
+ sprintf(acpi_device_class(device), "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
- }
- else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
+ } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
button->type = ACPI_BUTTON_TYPE_POWERF;
strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_POWERF);
- sprintf(acpi_device_class(device), "%s/%s",
+ ACPI_BUTTON_DEVICE_NAME_POWERF);
+ sprintf(acpi_device_class(device), "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
- }
- else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
+ } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
button->type = ACPI_BUTTON_TYPE_SLEEP;
- strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_SLEEP);
- sprintf(acpi_device_class(device), "%s/%s",
+ strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_SLEEP);
+ sprintf(acpi_device_class(device), "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
- }
- else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
+ } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
button->type = ACPI_BUTTON_TYPE_SLEEPF;
strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_SLEEPF);
- sprintf(acpi_device_class(device), "%s/%s",
+ ACPI_BUTTON_DEVICE_NAME_SLEEPF);
+ sprintf(acpi_device_class(device), "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
- }
- else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
+ } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
button->type = ACPI_BUTTON_TYPE_LID;
- strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_LID);
- sprintf(acpi_device_class(device), "%s/%s",
+ strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_LID);
+ sprintf(acpi_device_class(device), "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
- }
- else {
+ } else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported hid [%s]\n",
- acpi_device_hid(device)));
+ acpi_device_hid(device)));
result = -ENODEV;
goto end;
}
@@ -385,46 +361,46 @@ acpi_button_add (
switch (button->type) {
case ACPI_BUTTON_TYPE_POWERF:
- status = acpi_install_fixed_event_handler (
- ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed,
- button);
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_button_notify_fixed,
+ button);
break;
case ACPI_BUTTON_TYPE_SLEEPF:
- status = acpi_install_fixed_event_handler (
- ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed,
- button);
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_button_notify_fixed,
+ button);
break;
default:
- status = acpi_install_notify_handler (
- button->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify,
- button);
+ status = acpi_install_notify_handler(button->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_button_notify,
+ button);
break;
}
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
result = -ENODEV;
goto end;
}
if (device->wakeup.flags.valid) {
/* Button's GPE is run-wake GPE */
- acpi_set_gpe_type(device->wakeup.gpe_device,
- device->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
- acpi_enable_gpe(device->wakeup.gpe_device,
- device->wakeup.gpe_number, ACPI_NOT_ISR);
+ acpi_set_gpe_type(device->wakeup.gpe_device,
+ device->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
+ acpi_enable_gpe(device->wakeup.gpe_device,
+ device->wakeup.gpe_number, ACPI_NOT_ISR);
device->wakeup.state.enabled = 1;
}
- printk(KERN_INFO PREFIX "%s [%s]\n",
- acpi_device_name(device), acpi_device_bid(device));
+ printk(KERN_INFO PREFIX "%s [%s]\n",
+ acpi_device_name(device), acpi_device_bid(device));
-end:
+ end:
if (result) {
acpi_button_remove_fs(device);
kfree(button);
@@ -433,12 +409,10 @@ end:
return_VALUE(result);
}
-
-static int
-acpi_button_remove (struct acpi_device *device, int type)
+static int acpi_button_remove(struct acpi_device *device, int type)
{
- acpi_status status = 0;
- struct acpi_button *button = NULL;
+ acpi_status status = 0;
+ struct acpi_button *button = NULL;
ACPI_FUNCTION_TRACE("acpi_button_remove");
@@ -450,35 +424,36 @@ acpi_button_remove (struct acpi_device *device, int type)
/* Unregister for device notifications. */
switch (button->type) {
case ACPI_BUTTON_TYPE_POWERF:
- status = acpi_remove_fixed_event_handler(
- ACPI_EVENT_POWER_BUTTON, acpi_button_notify_fixed);
+ status =
+ acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_button_notify_fixed);
break;
case ACPI_BUTTON_TYPE_SLEEPF:
- status = acpi_remove_fixed_event_handler(
- ACPI_EVENT_SLEEP_BUTTON, acpi_button_notify_fixed);
+ status =
+ acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_button_notify_fixed);
break;
default:
status = acpi_remove_notify_handler(button->handle,
- ACPI_DEVICE_NOTIFY, acpi_button_notify);
+ ACPI_DEVICE_NOTIFY,
+ acpi_button_notify);
break;
}
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
- acpi_button_remove_fs(device);
+ acpi_button_remove_fs(device);
kfree(button);
return_VALUE(0);
}
-
-static int __init
-acpi_button_init (void)
+static int __init acpi_button_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_button_init");
@@ -495,15 +470,13 @@ acpi_button_init (void)
return_VALUE(0);
}
-
-static void __exit
-acpi_button_exit (void)
+static void __exit acpi_button_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_button_exit");
acpi_bus_unregister_driver(&acpi_button_driver);
- if (acpi_power_dir)
+ if (acpi_power_dir)
remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir);
if (acpi_sleep_dir)
remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir);
@@ -514,6 +487,5 @@ acpi_button_exit (void)
return_VOID;
}
-
module_init(acpi_button_init);
module_exit(acpi_button_exit);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 97013ddfa202..10dd695a1dd9 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -44,9 +44,9 @@
#define ACPI_CONTAINER_COMPONENT 0x01000000
#define _COMPONENT ACPI_CONTAINER_COMPONENT
-ACPI_MODULE_NAME ("acpi_container")
+ACPI_MODULE_NAME("acpi_container")
-MODULE_AUTHOR("Anil S Keshavamurthy");
+ MODULE_AUTHOR("Anil S Keshavamurthy");
MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME);
MODULE_LICENSE("GPL");
@@ -56,41 +56,38 @@ static int acpi_container_add(struct acpi_device *device);
static int acpi_container_remove(struct acpi_device *device, int type);
static struct acpi_driver acpi_container_driver = {
- .name = ACPI_CONTAINER_DRIVER_NAME,
- .class = ACPI_CONTAINER_CLASS,
- .ids = "ACPI0004,PNP0A05,PNP0A06",
- .ops = {
- .add = acpi_container_add,
- .remove = acpi_container_remove,
- },
+ .name = ACPI_CONTAINER_DRIVER_NAME,
+ .class = ACPI_CONTAINER_CLASS,
+ .ids = "ACPI0004,PNP0A05,PNP0A06",
+ .ops = {
+ .add = acpi_container_add,
+ .remove = acpi_container_remove,
+ },
};
-
/*******************************************************************/
-static int
-is_device_present(acpi_handle handle)
+static int is_device_present(acpi_handle handle)
{
- acpi_handle temp;
- acpi_status status;
- unsigned long sta;
+ acpi_handle temp;
+ acpi_status status;
+ unsigned long sta;
ACPI_FUNCTION_TRACE("is_device_present");
status = acpi_get_handle(handle, "_STA", &temp);
if (ACPI_FAILURE(status))
- return_VALUE(1); /* _STA not found, assmue device present */
+ return_VALUE(1); /* _STA not found, assmue device present */
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status))
- return_VALUE(0); /* Firmware error */
+ return_VALUE(0); /* Firmware error */
return_VALUE((sta & ACPI_STA_PRESENT) == ACPI_STA_PRESENT);
}
/*******************************************************************/
-static int
-acpi_container_add(struct acpi_device *device)
+static int acpi_container_add(struct acpi_device *device)
{
struct acpi_container *container;
@@ -102,28 +99,26 @@ acpi_container_add(struct acpi_device *device)
}
container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
- if(!container)
+ if (!container)
return_VALUE(-ENOMEM);
-
+
memset(container, 0, sizeof(struct acpi_container));
container->handle = device->handle;
strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
acpi_driver_data(device) = container;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n", \
- acpi_device_name(device), acpi_device_bid(device)));
-
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
+ acpi_device_name(device), acpi_device_bid(device)));
return_VALUE(0);
}
-static int
-acpi_container_remove(struct acpi_device *device, int type)
+static int acpi_container_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
- struct acpi_container *pc = NULL;
- pc = (struct acpi_container*) acpi_driver_data(device);
+ acpi_status status = AE_OK;
+ struct acpi_container *pc = NULL;
+ pc = (struct acpi_container *)acpi_driver_data(device);
if (pc)
kfree(pc);
@@ -131,9 +126,7 @@ acpi_container_remove(struct acpi_device *device, int type)
return status;
}
-
-static int
-container_device_add(struct acpi_device **device, acpi_handle handle)
+static int container_device_add(struct acpi_device **device, acpi_handle handle)
{
acpi_handle phandle;
struct acpi_device *pdev;
@@ -158,10 +151,9 @@ container_device_add(struct acpi_device **device, acpi_handle handle)
return_VALUE(result);
}
-static void
-container_notify_cb(acpi_handle handle, u32 type, void *context)
+static void container_notify_cb(acpi_handle handle, u32 type, void *context)
{
- struct acpi_device *device = NULL;
+ struct acpi_device *device = NULL;
int result;
int present;
acpi_status status;
@@ -169,14 +161,14 @@ container_notify_cb(acpi_handle handle, u32 type, void *context)
ACPI_FUNCTION_TRACE("container_notify_cb");
present = is_device_present(handle);
-
+
switch (type) {
case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */
case ACPI_NOTIFY_DEVICE_CHECK:
printk("Container driver received %s event\n",
- (type == ACPI_NOTIFY_BUS_CHECK)?
- "ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+ (type == ACPI_NOTIFY_BUS_CHECK) ?
+ "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
status = acpi_bus_get_device(handle, &device);
if (present) {
if (ACPI_FAILURE(status) || !device) {
@@ -207,15 +199,13 @@ container_notify_cb(acpi_handle handle, u32 type, void *context)
static acpi_status
container_walk_namespace_cb(acpi_handle handle,
- u32 lvl,
- void *context,
- void **rv)
+ u32 lvl, void *context, void **rv)
{
- char *hid = NULL;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_device_info *info;
- acpi_status status;
- int *action = context;
+ char *hid = NULL;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_device_info *info;
+ acpi_status status;
+ int *action = context;
ACPI_FUNCTION_TRACE("container_walk_namespace_cb");
@@ -233,66 +223,60 @@ container_walk_namespace_cb(acpi_handle handle,
}
if (strcmp(hid, "ACPI0004") && strcmp(hid, "PNP0A05") &&
- strcmp(hid, "PNP0A06")) {
+ strcmp(hid, "PNP0A06")) {
goto end;
}
- switch(*action) {
+ switch (*action) {
case INSTALL_NOTIFY_HANDLER:
acpi_install_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- container_notify_cb,
- NULL);
+ ACPI_SYSTEM_NOTIFY,
+ container_notify_cb, NULL);
break;
case UNINSTALL_NOTIFY_HANDLER:
acpi_remove_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- container_notify_cb);
+ ACPI_SYSTEM_NOTIFY,
+ container_notify_cb);
break;
default:
break;
}
-end:
+ end:
acpi_os_free(buffer.pointer);
return_ACPI_STATUS(AE_OK);
}
-
-static int __init
-acpi_container_init(void)
+static int __init acpi_container_init(void)
{
- int result = 0;
- int action = INSTALL_NOTIFY_HANDLER;
+ int result = 0;
+ int action = INSTALL_NOTIFY_HANDLER;
result = acpi_bus_register_driver(&acpi_container_driver);
if (result < 0) {
- return(result);
+ return (result);
}
/* register notify handler to every container device */
acpi_walk_namespace(ACPI_TYPE_DEVICE,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- container_walk_namespace_cb,
- &action, NULL);
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ container_walk_namespace_cb, &action, NULL);
- return(0);
+ return (0);
}
-static void __exit
-acpi_container_exit(void)
+static void __exit acpi_container_exit(void)
{
- int action = UNINSTALL_NOTIFY_HANDLER;
+ int action = UNINSTALL_NOTIFY_HANDLER;
ACPI_FUNCTION_TRACE("acpi_container_exit");
acpi_walk_namespace(ACPI_TYPE_DEVICE,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- container_walk_namespace_cb,
- &action, NULL);
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ container_walk_namespace_cb, &action, NULL);
acpi_bus_unregister_driver(&acpi_container_driver);
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 2c0dac559f16..263322b7d113 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -12,17 +12,14 @@
#include <acpi/acglobal.h>
#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("debug")
-
+ACPI_MODULE_NAME("debug")
#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer"
#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
-
#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
-
#define MODULE_PARAM_PREFIX
-module_param(acpi_dbg_layer, uint, 0400);
+ module_param(acpi_dbg_layer, uint, 0400);
module_param(acpi_dbg_level, uint, 0400);
struct acpi_dlayer {
@@ -35,8 +32,7 @@ struct acpi_dlevel {
};
#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
-static const struct acpi_dlayer acpi_debug_layers[] =
-{
+static const struct acpi_dlayer acpi_debug_layers[] = {
ACPI_DEBUG_INIT(ACPI_UTILITIES),
ACPI_DEBUG_INIT(ACPI_HARDWARE),
ACPI_DEBUG_INIT(ACPI_EVENTS),
@@ -53,8 +49,7 @@ static const struct acpi_dlayer acpi_debug_layers[] =
ACPI_DEBUG_INIT(ACPI_TOOLS),
};
-static const struct acpi_dlevel acpi_debug_levels[] =
-{
+static const struct acpi_dlevel acpi_debug_levels[] = {
ACPI_DEBUG_INIT(ACPI_LV_ERROR),
ACPI_DEBUG_INIT(ACPI_LV_WARN),
ACPI_DEBUG_INIT(ACPI_LV_INIT),
@@ -88,81 +83,77 @@ static const struct acpi_dlevel acpi_debug_levels[] =
ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
- ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
+ ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
};
static int
-acpi_system_read_debug (
- char *page,
- char **start,
- off_t off,
- int count,
- int *eof,
- void *data)
+acpi_system_read_debug(char *page,
+ char **start, off_t off, int count, int *eof, void *data)
{
- char *p = page;
- int size = 0;
- unsigned int i;
+ char *p = page;
+ int size = 0;
+ unsigned int i;
if (off != 0)
goto end;
p += sprintf(p, "%-25s\tHex SET\n", "Description");
- switch ((unsigned long) data) {
+ switch ((unsigned long)data) {
case 0:
for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
- acpi_debug_layers[i].name,
- acpi_debug_layers[i].value,
- (acpi_dbg_layer & acpi_debug_layers[i].value) ?
- '*' : ' ');
+ acpi_debug_layers[i].name,
+ acpi_debug_layers[i].value,
+ (acpi_dbg_layer & acpi_debug_layers[i].
+ value) ? '*' : ' ');
}
p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
- ACPI_ALL_DRIVERS,
- (acpi_dbg_layer & ACPI_ALL_DRIVERS) == ACPI_ALL_DRIVERS?
- '*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS) == 0 ?
- ' ' : '-');
+ ACPI_ALL_DRIVERS,
+ (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
+ ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
+ ACPI_ALL_DRIVERS) ==
+ 0 ? ' ' : '-');
p += sprintf(p,
- "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
- acpi_dbg_layer);
+ "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
+ acpi_dbg_layer);
break;
case 1:
for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
- acpi_debug_levels[i].name,
- acpi_debug_levels[i].value,
- (acpi_dbg_level & acpi_debug_levels[i].value) ?
- '*' : ' ');
+ acpi_debug_levels[i].name,
+ acpi_debug_levels[i].value,
+ (acpi_dbg_level & acpi_debug_levels[i].
+ value) ? '*' : ' ');
}
p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n",
- acpi_dbg_level);
+ acpi_dbg_level);
break;
default:
p += sprintf(p, "Invalid debug option\n");
break;
}
-
-end:
+
+ end:
size = (p - page);
- if (size <= off+count) *eof = 1;
+ if (size <= off + count)
+ *eof = 1;
*start = page + off;
size -= off;
- if (size>count) size = count;
- if (size<0) size = 0;
+ if (size > count)
+ size = count;
+ if (size < 0)
+ size = 0;
return size;
}
-
static int
-acpi_system_write_debug (
- struct file *file,
- const char __user *buffer,
- unsigned long count,
- void *data)
+acpi_system_write_debug(struct file *file,
+ const char __user * buffer,
+ unsigned long count, void *data)
{
- char debug_string[12] = {'\0'};
+ char debug_string[12] = { '\0' };
ACPI_FUNCTION_TRACE("acpi_system_write_debug");
@@ -174,7 +165,7 @@ acpi_system_write_debug (
debug_string[count] = '\0';
- switch ((unsigned long) data) {
+ switch ((unsigned long)data) {
case 0:
acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0);
break;
@@ -190,9 +181,9 @@ acpi_system_write_debug (
static int __init acpi_debug_init(void)
{
- struct proc_dir_entry *entry;
+ struct proc_dir_entry *entry;
int error = 0;
- char * name;
+ char *name;
ACPI_FUNCTION_TRACE("acpi_debug_init");
@@ -201,8 +192,10 @@ static int __init acpi_debug_init(void)
/* 'debug_layer' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
- entry = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir,
- acpi_system_read_debug,(void *)0);
+ entry =
+ create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_root_dir, acpi_system_read_debug,
+ (void *)0);
if (entry)
entry->write_proc = acpi_system_write_debug;
else
@@ -210,19 +203,21 @@ static int __init acpi_debug_init(void)
/* 'debug_level' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LEVEL;
- entry = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir,
- acpi_system_read_debug, (void *)1);
- if (entry)
+ entry =
+ create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_root_dir, acpi_system_read_debug,
+ (void *)1);
+ if (entry)
entry->write_proc = acpi_system_write_debug;
else
goto Error;
- Done:
+ Done:
return_VALUE(error);
- Error:
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' proc fs entry\n", name));
+ Error:
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create '%s' proc fs entry\n", name));
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir);
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index 84193983d6ba..2022aeaecfbb 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/amlcode.h>
#include <acpi/acdispat.h>
@@ -49,18 +48,14 @@
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
-
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsfield")
+ACPI_MODULE_NAME("dsfield")
/* Local prototypes */
-
static acpi_status
-acpi_ds_get_field_names (
- struct acpi_create_field_info *info,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *arg);
-
+acpi_ds_get_field_names(struct acpi_create_field_info *info,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *arg);
/*******************************************************************************
*
@@ -82,41 +77,36 @@ acpi_ds_get_field_names (
******************************************************************************/
acpi_status
-acpi_ds_create_buffer_field (
- union acpi_parse_object *op,
- struct acpi_walk_state *walk_state)
+acpi_ds_create_buffer_field(union acpi_parse_object *op,
+ struct acpi_walk_state *walk_state)
{
- union acpi_parse_object *arg;
- struct acpi_namespace_node *node;
- acpi_status status;
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *second_desc = NULL;
- u32 flags;
-
-
- ACPI_FUNCTION_TRACE ("ds_create_buffer_field");
+ union acpi_parse_object *arg;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *second_desc = NULL;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("ds_create_buffer_field");
/* Get the name_string argument */
if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
- arg = acpi_ps_get_arg (op, 3);
- }
- else {
+ arg = acpi_ps_get_arg(op, 3);
+ } else {
/* Create Bit/Byte/Word/Dword field */
- arg = acpi_ps_get_arg (op, 2);
+ arg = acpi_ps_get_arg(op, 2);
}
if (!arg) {
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
if (walk_state->deferred_node) {
node = walk_state->deferred_node;
status = AE_OK;
- }
- else {
+ } else {
/*
* During the load phase, we want to enter the name of the field into
* the namespace. During the execute phase (when we evaluate the size
@@ -124,21 +114,22 @@ acpi_ds_create_buffer_field (
*/
if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
- }
- else {
+ } else {
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
- ACPI_NS_ERROR_IF_FOUND;
+ ACPI_NS_ERROR_IF_FOUND;
}
/*
* Enter the name_string into the namespace
*/
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
- ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
- flags, walk_state, &(node));
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (arg->common.value.string, status);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info,
+ arg->common.value.string, ACPI_TYPE_ANY,
+ ACPI_IMODE_LOAD_PASS1, flags, walk_state,
+ &(node));
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(arg->common.value.string, status);
+ return_ACPI_STATUS(status);
}
}
@@ -153,9 +144,9 @@ acpi_ds_create_buffer_field (
* and we need to create the field object. Otherwise, this was a lookup
* of an existing node and we don't want to create the field object again.
*/
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -165,7 +156,7 @@ acpi_ds_create_buffer_field (
/* Create the buffer field object */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER_FIELD);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -176,28 +167,26 @@ acpi_ds_create_buffer_field (
* opcode and operands -- since the buffer and index
* operands must be evaluated.
*/
- second_desc = obj_desc->common.next_object;
+ second_desc = obj_desc->common.next_object;
second_desc->extra.aml_start = op->named.data;
second_desc->extra.aml_length = op->named.length;
obj_desc->buffer_field.node = node;
/* Attach constructed field descriptors to parent node */
- status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
-
-cleanup:
+ cleanup:
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_get_field_names
@@ -214,17 +203,14 @@ cleanup:
******************************************************************************/
static acpi_status
-acpi_ds_get_field_names (
- struct acpi_create_field_info *info,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *arg)
+acpi_ds_get_field_names(struct acpi_create_field_info *info,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *arg)
{
- acpi_status status;
- acpi_integer position;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_get_field_names", info);
+ acpi_status status;
+ acpi_integer position;
+ ACPI_FUNCTION_TRACE_PTR("ds_get_field_names", info);
/* First field starts at bit zero */
@@ -243,18 +229,16 @@ acpi_ds_get_field_names (
case AML_INT_RESERVEDFIELD_OP:
position = (acpi_integer) info->field_bit_position
- + (acpi_integer) arg->common.value.size;
+ + (acpi_integer) arg->common.value.size;
if (position > ACPI_UINT32_MAX) {
- ACPI_REPORT_ERROR ((
- "Bit offset within field too large (> 0xFFFFFFFF)\n"));
- return_ACPI_STATUS (AE_SUPPORT);
+ ACPI_REPORT_ERROR(("Bit offset within field too large (> 0xFFFFFFFF)\n"));
+ return_ACPI_STATUS(AE_SUPPORT);
}
info->field_bit_position = (u32) position;
break;
-
case AML_INT_ACCESSFIELD_OP:
/*
@@ -266,73 +250,70 @@ acpi_ds_get_field_names (
* ACCESS_TYPE bits
*/
info->field_flags = (u8)
- ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
- ((u8) ((u32) arg->common.value.integer >> 8)));
+ ((info->
+ field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
+ ((u8) ((u32) arg->common.value.integer >> 8)));
info->attribute = (u8) (arg->common.value.integer);
break;
-
case AML_INT_NAMEDFIELD_OP:
/* Lookup the name */
- status = acpi_ns_lookup (walk_state->scope_info,
- (char *) &arg->named.name,
- info->field_type, ACPI_IMODE_EXECUTE,
- ACPI_NS_DONT_OPEN_SCOPE,
- walk_state, &info->field_node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
+ status = acpi_ns_lookup(walk_state->scope_info,
+ (char *)&arg->named.name,
+ info->field_type,
+ ACPI_IMODE_EXECUTE,
+ ACPI_NS_DONT_OPEN_SCOPE,
+ walk_state, &info->field_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR((char *)&arg->named.name,
+ status);
if (status != AE_ALREADY_EXISTS) {
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Already exists, ignore error */
- }
- else {
+ } else {
arg->common.node = info->field_node;
info->field_bit_length = arg->common.value.size;
/* Create and initialize an object for the new Field Node */
- status = acpi_ex_prep_field_value (info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_prep_field_value(info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Keep track of bit position for the next field */
position = (acpi_integer) info->field_bit_position
- + (acpi_integer) arg->common.value.size;
+ + (acpi_integer) arg->common.value.size;
if (position > ACPI_UINT32_MAX) {
- ACPI_REPORT_ERROR ((
- "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
- (char *) &info->field_node->name));
- return_ACPI_STATUS (AE_SUPPORT);
+ ACPI_REPORT_ERROR(("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n", (char *)&info->field_node->name));
+ return_ACPI_STATUS(AE_SUPPORT);
}
info->field_bit_position += info->field_bit_length;
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid opcode in field list: %X\n",
- arg->common.aml_opcode));
- return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid opcode in field list: %X\n",
+ arg->common.aml_opcode));
+ return_ACPI_STATUS(AE_AML_BAD_OPCODE);
}
arg = arg->common.next;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_field
@@ -348,29 +329,28 @@ acpi_ds_get_field_names (
******************************************************************************/
acpi_status
-acpi_ds_create_field (
- union acpi_parse_object *op,
- struct acpi_namespace_node *region_node,
- struct acpi_walk_state *walk_state)
+acpi_ds_create_field(union acpi_parse_object *op,
+ struct acpi_namespace_node *region_node,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_parse_object *arg;
- struct acpi_create_field_info info;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_create_field", op);
+ acpi_status status;
+ union acpi_parse_object *arg;
+ struct acpi_create_field_info info;
+ ACPI_FUNCTION_TRACE_PTR("ds_create_field", op);
/* First arg is the name of the parent op_region (must already exist) */
arg = op->common.value.arg;
if (!region_node) {
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name,
- ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT, walk_state, &region_node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (arg->common.value.name, status);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info,
+ arg->common.value.name, ACPI_TYPE_REGION,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ walk_state, &region_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(arg->common.value.name, status);
+ return_ACPI_STATUS(status);
}
}
@@ -385,12 +365,11 @@ acpi_ds_create_field (
info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
info.region_node = region_node;
- status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
+ status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_init_field_objects
@@ -407,37 +386,34 @@ acpi_ds_create_field (
******************************************************************************/
acpi_status
-acpi_ds_init_field_objects (
- union acpi_parse_object *op,
- struct acpi_walk_state *walk_state)
+acpi_ds_init_field_objects(union acpi_parse_object *op,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_parse_object *arg = NULL;
- struct acpi_namespace_node *node;
- u8 type = 0;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_init_field_objects", op);
+ acpi_status status;
+ union acpi_parse_object *arg = NULL;
+ struct acpi_namespace_node *node;
+ u8 type = 0;
+ ACPI_FUNCTION_TRACE_PTR("ds_init_field_objects", op);
switch (walk_state->opcode) {
case AML_FIELD_OP:
- arg = acpi_ps_get_arg (op, 2);
+ arg = acpi_ps_get_arg(op, 2);
type = ACPI_TYPE_LOCAL_REGION_FIELD;
break;
case AML_BANK_FIELD_OP:
- arg = acpi_ps_get_arg (op, 4);
+ arg = acpi_ps_get_arg(op, 4);
type = ACPI_TYPE_LOCAL_BANK_FIELD;
break;
case AML_INDEX_FIELD_OP:
- arg = acpi_ps_get_arg (op, 3);
+ arg = acpi_ps_get_arg(op, 3);
type = ACPI_TYPE_LOCAL_INDEX_FIELD;
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -447,16 +423,18 @@ acpi_ds_init_field_objects (
/* Ignore OFFSET and ACCESSAS terms here */
if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
- status = acpi_ns_lookup (walk_state->scope_info,
- (char *) &arg->named.name,
- type, ACPI_IMODE_LOAD_PASS1,
- ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
- ACPI_NS_ERROR_IF_FOUND,
- walk_state, &node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
+ status = acpi_ns_lookup(walk_state->scope_info,
+ (char *)&arg->named.name,
+ type, ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_NO_UPSEARCH |
+ ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND,
+ walk_state, &node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR((char *)&arg->named.name,
+ status);
if (status != AE_ALREADY_EXISTS) {
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Name already exists, just ignore this error */
@@ -472,10 +450,9 @@ acpi_ds_init_field_objects (
arg = arg->common.next;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_bank_field
@@ -491,41 +468,42 @@ acpi_ds_init_field_objects (
******************************************************************************/
acpi_status
-acpi_ds_create_bank_field (
- union acpi_parse_object *op,
- struct acpi_namespace_node *region_node,
- struct acpi_walk_state *walk_state)
+acpi_ds_create_bank_field(union acpi_parse_object *op,
+ struct acpi_namespace_node *region_node,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_parse_object *arg;
- struct acpi_create_field_info info;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_create_bank_field", op);
+ acpi_status status;
+ union acpi_parse_object *arg;
+ struct acpi_create_field_info info;
+ ACPI_FUNCTION_TRACE_PTR("ds_create_bank_field", op);
/* First arg is the name of the parent op_region (must already exist) */
arg = op->common.value.arg;
if (!region_node) {
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name,
- ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT, walk_state, &region_node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (arg->common.value.name, status);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info,
+ arg->common.value.name, ACPI_TYPE_REGION,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ walk_state, &region_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(arg->common.value.name, status);
+ return_ACPI_STATUS(status);
}
}
/* Second arg is the Bank Register (Field) (must already exist) */
arg = arg->common.next;
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
- ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (arg->common.value.string, status);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, walk_state,
+ &info.register_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(arg->common.value.string, status);
+ return_ACPI_STATUS(status);
}
/* Third arg is the bank_value */
@@ -543,12 +521,11 @@ acpi_ds_create_bank_field (
info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
info.region_node = region_node;
- status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
+ status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_index_field
@@ -564,39 +541,40 @@ acpi_ds_create_bank_field (
******************************************************************************/
acpi_status
-acpi_ds_create_index_field (
- union acpi_parse_object *op,
- struct acpi_namespace_node *region_node,
- struct acpi_walk_state *walk_state)
+acpi_ds_create_index_field(union acpi_parse_object *op,
+ struct acpi_namespace_node *region_node,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_parse_object *arg;
- struct acpi_create_field_info info;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_create_index_field", op);
+ acpi_status status;
+ union acpi_parse_object *arg;
+ struct acpi_create_field_info info;
+ ACPI_FUNCTION_TRACE_PTR("ds_create_index_field", op);
/* First arg is the name of the Index register (must already exist) */
arg = op->common.value.arg;
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
- ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (arg->common.value.string, status);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, walk_state,
+ &info.register_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(arg->common.value.string, status);
+ return_ACPI_STATUS(status);
}
/* Second arg is the data register (must already exist) */
arg = arg->common.next;
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
- ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT, walk_state, &info.data_register_node);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (arg->common.value.string, status);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, walk_state,
+ &info.data_register_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(arg->common.value.string, status);
+ return_ACPI_STATUS(status);
}
/* Next arg is the field flags */
@@ -609,9 +587,7 @@ acpi_ds_create_index_field (
info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
info.region_node = region_node;
- status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
+ status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index d7790db50178..8693c704aea6 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -41,23 +41,17 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsinit")
+ACPI_MODULE_NAME("dsinit")
/* Local prototypes */
-
static acpi_status
-acpi_ds_init_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value);
-
+acpi_ds_init_one_object(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value);
/*******************************************************************************
*
@@ -80,26 +74,23 @@ acpi_ds_init_one_object (
******************************************************************************/
static acpi_status
-acpi_ds_init_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ds_init_one_object(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value)
{
- acpi_object_type type;
- acpi_status status;
- struct acpi_init_walk_info *info = (struct acpi_init_walk_info *) context;
-
-
- ACPI_FUNCTION_NAME ("ds_init_one_object");
+ struct acpi_init_walk_info *info =
+ (struct acpi_init_walk_info *)context;
+ struct acpi_namespace_node *node =
+ (struct acpi_namespace_node *)obj_handle;
+ acpi_object_type type;
+ acpi_status status;
+ ACPI_FUNCTION_NAME("ds_init_one_object");
/*
- * We are only interested in objects owned by the table that
+ * We are only interested in NS nodes owned by the table that
* was just loaded
*/
- if (((struct acpi_namespace_node *) obj_handle)->owner_id !=
- info->table_desc->table_id) {
+ if (node->owner_id != info->table_desc->owner_id) {
return (AE_OK);
}
@@ -107,33 +98,31 @@ acpi_ds_init_one_object (
/* And even then, we are only interested in a few object types */
- type = acpi_ns_get_type (obj_handle);
+ type = acpi_ns_get_type(obj_handle);
switch (type) {
case ACPI_TYPE_REGION:
- status = acpi_ds_initialize_region (obj_handle);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Region %p [%4.4s] - Init failure, %s\n",
- obj_handle, acpi_ut_get_node_name (obj_handle),
- acpi_format_exception (status)));
+ status = acpi_ds_initialize_region(obj_handle);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Region %p [%4.4s] - Init failure, %s\n",
+ obj_handle,
+ acpi_ut_get_node_name(obj_handle),
+ acpi_format_exception(status)));
}
info->op_region_count++;
break;
-
case ACPI_TYPE_METHOD:
- info->method_count++;
-
/*
* Print a dot for each method unless we are going to print
* the entire pathname
*/
if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
}
/*
@@ -143,41 +132,32 @@ acpi_ds_init_one_object (
* on a per-table basis. Currently, we just use a global for the width.
*/
if (info->table_desc->pointer->revision == 1) {
- ((struct acpi_namespace_node *) obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
+ node->flags |= ANOBJ_DATA_WIDTH_32;
}
/*
* Always parse methods to detect errors, we will delete
* the parse tree below
*/
- status = acpi_ds_parse_method (obj_handle);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Method %p [%4.4s] - parse failure, %s\n",
- obj_handle, acpi_ut_get_node_name (obj_handle),
- acpi_format_exception (status)));
+ status = acpi_ds_parse_method(obj_handle);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "\n+Method %p [%4.4s] - parse failure, %s\n",
+ obj_handle,
+ acpi_ut_get_node_name(obj_handle),
+ acpi_format_exception(status)));
/* This parse failed, but we will continue parsing more methods */
-
- break;
}
- /*
- * Delete the parse tree. We simply re-parse the method
- * for every execution since there isn't much overhead
- */
- acpi_ns_delete_namespace_subtree (obj_handle);
- acpi_ns_delete_namespace_by_owner (
- ((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
+ info->method_count++;
break;
-
case ACPI_TYPE_DEVICE:
info->device_count++;
break;
-
default:
break;
}
@@ -189,7 +169,6 @@ acpi_ds_init_one_object (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_initialize_objects
@@ -205,45 +184,43 @@ acpi_ds_init_one_object (
******************************************************************************/
acpi_status
-acpi_ds_initialize_objects (
- struct acpi_table_desc *table_desc,
- struct acpi_namespace_node *start_node)
+acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
+ struct acpi_namespace_node * start_node)
{
- acpi_status status;
- struct acpi_init_walk_info info;
+ acpi_status status;
+ struct acpi_init_walk_info info;
+ ACPI_FUNCTION_TRACE("ds_initialize_objects");
- ACPI_FUNCTION_TRACE ("ds_initialize_objects");
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "**** Starting initialization of namespace objects ****\n"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "**** Starting initialization of namespace objects ****\n"));
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
-
- info.method_count = 0;
+ info.method_count = 0;
info.op_region_count = 0;
- info.object_count = 0;
- info.device_count = 0;
- info.table_desc = table_desc;
+ info.object_count = 0;
+ info.device_count = 0;
+ info.table_desc = table_desc;
/* Walk entire namespace from the supplied root */
- status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
- acpi_ds_init_one_object, &info, NULL);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed, %s\n",
- acpi_format_exception (status)));
+ status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+ acpi_ds_init_one_object, &info, NULL);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed, %s\n",
+ acpi_format_exception(status)));
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
- "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
- table_desc->pointer->signature, table_desc->table_id, info.object_count,
- info.device_count, info.method_count, info.op_region_count));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+ "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+ table_desc->pointer->signature,
+ table_desc->owner_id, info.object_count,
+ info.device_count, info.method_count,
+ info.op_region_count));
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "%hd Methods, %hd Regions\n", info.method_count, info.op_region_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "%hd Methods, %hd Regions\n", info.method_count,
+ info.op_region_count));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 9fc3f4c033eb..36c1ca0b9adb 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
@@ -49,67 +48,57 @@
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsmethod")
-
+ACPI_MODULE_NAME("dsmethod")
/*******************************************************************************
*
* FUNCTION: acpi_ds_parse_method
*
- * PARAMETERS: obj_handle - Method node
+ * PARAMETERS: Node - Method node
*
* RETURN: Status
*
- * DESCRIPTION: Call the parser and parse the AML that is associated with the
- * method.
+ * DESCRIPTION: Parse the AML that is associated with the method.
*
* MUTEX: Assumes parser is locked
*
******************************************************************************/
-
-acpi_status
-acpi_ds_parse_method (
- acpi_handle obj_handle)
+acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
- union acpi_parse_object *op;
- struct acpi_namespace_node *node;
- acpi_owner_id owner_id;
- struct acpi_walk_state *walk_state;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle);
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ union acpi_parse_object *op;
+ struct acpi_walk_state *walk_state;
+ ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node);
/* Parameter Validation */
- if (!obj_handle) {
- return_ACPI_STATUS (AE_NULL_ENTRY);
+ if (!node) {
+ return_ACPI_STATUS(AE_NULL_ENTRY);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
- acpi_ut_get_node_name (obj_handle), obj_handle));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "**** Parsing [%4.4s] **** named_obj=%p\n",
+ acpi_ut_get_node_name(node), node));
/* Extract the method object from the method Node */
- node = (struct acpi_namespace_node *) obj_handle;
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NULL_OBJECT);
+ return_ACPI_STATUS(AE_NULL_OBJECT);
}
/* Create a mutex for the method if there is a concurrency limit */
if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
- (!obj_desc->method.semaphore)) {
- status = acpi_os_create_semaphore (obj_desc->method.concurrency,
- obj_desc->method.concurrency,
- &obj_desc->method.semaphore);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ (!obj_desc->method.semaphore)) {
+ status = acpi_os_create_semaphore(obj_desc->method.concurrency,
+ obj_desc->method.concurrency,
+ &obj_desc->method.semaphore);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -117,14 +106,14 @@ acpi_ds_parse_method (
* Allocate a new parser op to be the root of the parsed
* method tree
*/
- op = acpi_ps_alloc_op (AML_METHOD_OP);
+ op = acpi_ps_alloc_op(AML_METHOD_OP);
if (!op) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Init new op with the method name and pointer back to the Node */
- acpi_ps_set_name (op, node->name.integer);
+ acpi_ps_set_name(op, node->name.integer);
op->common.node = node;
/*
@@ -132,22 +121,27 @@ acpi_ds_parse_method (
* objects (such as Operation Regions) can be created during the
* first pass parse.
*/
- owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
- obj_desc->method.owning_id = owner_id;
+ status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
+ if (ACPI_FAILURE(status)) {
+ goto cleanup;
+ }
/* Create and initialize a new walk state */
- walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL);
+ walk_state =
+ acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL,
+ NULL);
if (!walk_state) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ status = AE_NO_MEMORY;
+ goto cleanup2;
}
- status = acpi_ds_init_aml_walk (walk_state, op, node,
- obj_desc->method.aml_start,
- obj_desc->method.aml_length, NULL, 1);
- if (ACPI_FAILURE (status)) {
- acpi_ds_delete_walk_state (walk_state);
- return_ACPI_STATUS (status);
+ status = acpi_ds_init_aml_walk(walk_state, op, node,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length, NULL, 1);
+ if (ACPI_FAILURE(status)) {
+ acpi_ds_delete_walk_state(walk_state);
+ goto cleanup2;
}
/*
@@ -159,19 +153,30 @@ acpi_ds_parse_method (
* method so that operands to the named objects can take on dynamic
* run-time values.
*/
- status = acpi_ps_parse_aml (walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ps_parse_aml(walk_state);
+ if (ACPI_FAILURE(status)) {
+ goto cleanup2;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
- acpi_ut_get_node_name (obj_handle), obj_handle, op));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
+ acpi_ut_get_node_name(node), node, op));
- acpi_ps_delete_parse_tree (op);
- return_ACPI_STATUS (status);
-}
+ /*
+ * Delete the parse tree. We simply re-parse the method for every
+ * execution since there isn't much overhead (compared to keeping lots
+ * of parse trees around)
+ */
+ acpi_ns_delete_namespace_subtree(node);
+ acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
+
+ cleanup2:
+ acpi_ut_release_owner_id(&obj_desc->method.owner_id);
+ cleanup:
+ acpi_ps_delete_parse_tree(op);
+ return_ACPI_STATUS(status);
+}
/*******************************************************************************
*
@@ -190,19 +195,23 @@ acpi_ds_parse_method (
******************************************************************************/
acpi_status
-acpi_ds_begin_method_execution (
- struct acpi_namespace_node *method_node,
- union acpi_operand_object *obj_desc,
- struct acpi_namespace_node *calling_method_node)
+acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
+ union acpi_operand_object *obj_desc,
+ struct acpi_namespace_node *calling_method_node)
{
- acpi_status status = AE_OK;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ds_begin_method_execution", method_node);
- ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node);
+ if (!method_node) {
+ return_ACPI_STATUS(AE_NULL_ENTRY);
+ }
+ /* Prevent wraparound of thread count */
- if (!method_node) {
- return_ACPI_STATUS (AE_NULL_ENTRY);
+ if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
+ ACPI_REPORT_ERROR(("Method reached maximum reentrancy limit (255)\n"));
+ return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
}
/*
@@ -219,8 +228,9 @@ acpi_ds_begin_method_execution (
* thread that is making recursive method calls.
*/
if (method_node == calling_method_node) {
- if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
- return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
+ if (obj_desc->method.thread_count >=
+ obj_desc->method.concurrency) {
+ return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
}
}
@@ -228,8 +238,21 @@ acpi_ds_begin_method_execution (
* Get a unit from the method semaphore. This releases the
* interpreter if we block
*/
- status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
- ACPI_WAIT_FOREVER);
+ status =
+ acpi_ex_system_wait_semaphore(obj_desc->method.semaphore,
+ ACPI_WAIT_FOREVER);
+ }
+
+ /*
+ * Allocate an Owner ID for this method, only if this is the first thread
+ * to begin concurrent execution. We only need one owner_id, even if the
+ * method is invoked recursively.
+ */
+ if (!obj_desc->method.owner_id) {
+ status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
}
/*
@@ -237,10 +260,9 @@ acpi_ds_begin_method_execution (
* reentered one more time (even if it is the same thread)
*/
obj_desc->method.thread_count++;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_call_control_method
@@ -256,101 +278,99 @@ acpi_ds_begin_method_execution (
******************************************************************************/
acpi_status
-acpi_ds_call_control_method (
- struct acpi_thread_state *thread,
- struct acpi_walk_state *this_walk_state,
- union acpi_parse_object *op)
+acpi_ds_call_control_method(struct acpi_thread_state *thread,
+ struct acpi_walk_state *this_walk_state,
+ union acpi_parse_object *op)
{
- acpi_status status;
- struct acpi_namespace_node *method_node;
- struct acpi_walk_state *next_walk_state;
- union acpi_operand_object *obj_desc;
- struct acpi_parameter_info info;
- u32 i;
-
+ acpi_status status;
+ struct acpi_namespace_node *method_node;
+ struct acpi_walk_state *next_walk_state = NULL;
+ union acpi_operand_object *obj_desc;
+ struct acpi_parameter_info info;
+ u32 i;
- ACPI_FUNCTION_TRACE_PTR ("ds_call_control_method", this_walk_state);
+ ACPI_FUNCTION_TRACE_PTR("ds_call_control_method", this_walk_state);
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n",
- this_walk_state->prev_op, this_walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Execute method %p, currentstate=%p\n",
+ this_walk_state->prev_op, this_walk_state));
/*
* Get the namespace entry for the control method we are about to call
*/
method_node = this_walk_state->method_call_node;
if (!method_node) {
- return_ACPI_STATUS (AE_NULL_ENTRY);
+ return_ACPI_STATUS(AE_NULL_ENTRY);
}
- obj_desc = acpi_ns_get_attached_object (method_node);
+ obj_desc = acpi_ns_get_attached_object(method_node);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NULL_OBJECT);
+ return_ACPI_STATUS(AE_NULL_OBJECT);
}
- obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
-
/* Init for new method, wait on concurrency semaphore */
- status = acpi_ds_begin_method_execution (method_node, obj_desc,
- this_walk_state->method_node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_begin_method_execution(method_node, obj_desc,
+ this_walk_state->method_node);
+ if (ACPI_FAILURE(status)) {
+ goto cleanup;
}
if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
/* 1) Parse: Create a new walk state for the preempting walk */
- next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
- op, obj_desc, NULL);
+ next_walk_state =
+ acpi_ds_create_walk_state(obj_desc->method.owner_id, op,
+ obj_desc, NULL);
if (!next_walk_state) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Create and init a Root Node */
- op = acpi_ps_create_scope_op ();
+ op = acpi_ps_create_scope_op();
if (!op) {
status = AE_NO_MEMORY;
goto cleanup;
}
- status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
- obj_desc->method.aml_start, obj_desc->method.aml_length,
- NULL, 1);
- if (ACPI_FAILURE (status)) {
- acpi_ds_delete_walk_state (next_walk_state);
+ status = acpi_ds_init_aml_walk(next_walk_state, op, method_node,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length,
+ NULL, 1);
+ if (ACPI_FAILURE(status)) {
+ acpi_ds_delete_walk_state(next_walk_state);
goto cleanup;
}
/* Begin AML parse */
- status = acpi_ps_parse_aml (next_walk_state);
- acpi_ps_delete_parse_tree (op);
+ status = acpi_ps_parse_aml(next_walk_state);
+ acpi_ps_delete_parse_tree(op);
}
/* 2) Execute: Create a new state for the preempting walk */
- next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
- NULL, obj_desc, thread);
+ next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id,
+ NULL, obj_desc, thread);
if (!next_walk_state) {
status = AE_NO_MEMORY;
goto cleanup;
}
/*
* The resolved arguments were put on the previous walk state's operand
- * stack. Operands on the previous walk state stack always
- * start at index 0.
- * Null terminate the list of arguments
+ * stack. Operands on the previous walk state stack always
+ * start at index 0. Also, null terminate the list of arguments
*/
- this_walk_state->operands [this_walk_state->num_operands] = NULL;
+ this_walk_state->operands[this_walk_state->num_operands] = NULL;
info.parameters = &this_walk_state->operands[0];
info.parameter_type = ACPI_PARAM_ARGS;
- status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node,
- obj_desc->method.aml_start, obj_desc->method.aml_length,
- &info, 3);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length, &info, 3);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -359,38 +379,37 @@ acpi_ds_call_control_method (
* (they were copied to new objects)
*/
for (i = 0; i < obj_desc->method.param_count; i++) {
- acpi_ut_remove_reference (this_walk_state->operands [i]);
- this_walk_state->operands [i] = NULL;
+ acpi_ut_remove_reference(this_walk_state->operands[i]);
+ this_walk_state->operands[i] = NULL;
}
/* Clear the operand stack */
this_walk_state->num_operands = 0;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Starting nested execution, newstate=%p\n", next_walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Starting nested execution, newstate=%p\n",
+ next_walk_state));
if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
- status = obj_desc->method.implementation (next_walk_state);
- return_ACPI_STATUS (status);
+ status = obj_desc->method.implementation(next_walk_state);
}
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(status);
- /* On error, we must delete the new walk state */
+ cleanup:
+ /* Decrement the thread count on the method parse tree */
-cleanup:
if (next_walk_state && (next_walk_state->method_desc)) {
- /* Decrement the thread count on the method parse tree */
-
- next_walk_state->method_desc->method.thread_count--;
+ next_walk_state->method_desc->method.thread_count--;
}
- (void) acpi_ds_terminate_control_method (next_walk_state);
- acpi_ds_delete_walk_state (next_walk_state);
- return_ACPI_STATUS (status);
-}
+ /* On error, we must delete the new walk state */
+
+ acpi_ds_terminate_control_method(next_walk_state);
+ acpi_ds_delete_walk_state(next_walk_state);
+ return_ACPI_STATUS(status);
+}
/*******************************************************************************
*
@@ -407,25 +426,22 @@ cleanup:
******************************************************************************/
acpi_status
-acpi_ds_restart_control_method (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *return_desc)
+acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *return_desc)
{
- acpi_status status;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_restart_control_method", walk_state);
- ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state);
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "****Restart [%4.4s] Op %p return_value_from_callee %p\n",
+ (char *)&walk_state->method_node->name,
+ walk_state->method_call_op, return_desc));
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "****Restart [%4.4s] Op %p return_value_from_callee %p\n",
- (char *) &walk_state->method_node->name, walk_state->method_call_op,
- return_desc));
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- " return_from_this_method_used?=%X res_stack %p Walk %p\n",
- walk_state->return_used,
- walk_state->results, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ " return_from_this_method_used?=%X res_stack %p Walk %p\n",
+ walk_state->return_used,
+ walk_state->results, walk_state));
/* Did the called method return a value? */
@@ -435,10 +451,10 @@ acpi_ds_restart_control_method (
if (walk_state->return_used) {
/* Save the return value from the previous method */
- status = acpi_ds_result_push (return_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
- return_ACPI_STATUS (status);
+ status = acpi_ds_result_push(return_desc, walk_state);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(return_desc);
+ return_ACPI_STATUS(status);
}
/*
@@ -456,26 +472,26 @@ acpi_ds_restart_control_method (
* NOTE: this is optional because the ASL language does not actually
* support this behavior.
*/
- else if (!acpi_ds_do_implicit_return (return_desc, walk_state, FALSE)) {
+ else if (!acpi_ds_do_implicit_return
+ (return_desc, walk_state, FALSE)) {
/*
* Delete the return value if it will not be used by the
* calling method
*/
- acpi_ut_remove_reference (return_desc);
+ acpi_ut_remove_reference(return_desc);
}
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_terminate_control_method
*
* PARAMETERS: walk_state - State of the method
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Terminate a control method. Delete everything that the method
* created, delete all locals and arguments, and delete the parse
@@ -483,63 +499,59 @@ acpi_ds_restart_control_method (
*
******************************************************************************/
-acpi_status
-acpi_ds_terminate_control_method (
- struct acpi_walk_state *walk_state)
+void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *method_node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_terminate_control_method", walk_state);
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *method_node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state);
if (!walk_state) {
- return (AE_BAD_PARAMETER);
+ return_VOID;
}
/* The current method object was saved in the walk state */
obj_desc = walk_state->method_desc;
if (!obj_desc) {
- return_ACPI_STATUS (AE_OK);
+ return_VOID;
}
/* Delete all arguments and locals */
- acpi_ds_method_data_delete_all (walk_state);
+ acpi_ds_method_data_delete_all(walk_state);
/*
* Lock the parser while we terminate this method.
* If this is the last thread executing the method,
* we have additional cleanup to perform
*/
- status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER);
+ if (ACPI_FAILURE(status)) {
+ return_VOID;
}
/* Signal completion of the execution of this method if necessary */
if (walk_state->method_desc->method.semaphore) {
- status = acpi_os_signal_semaphore (
- walk_state->method_desc->method.semaphore, 1);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not signal method semaphore\n"));
- status = AE_OK;
+ status =
+ acpi_os_signal_semaphore(walk_state->method_desc->method.
+ semaphore, 1);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not signal method semaphore\n"));
/* Ignore error and continue cleanup */
}
}
if (walk_state->method_desc->method.thread_count) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "*** Not deleting method namespace, there are still %d threads\n",
- walk_state->method_desc->method.thread_count));
- }
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "*** Not deleting method namespace, there are still %d threads\n",
+ walk_state->method_desc->method.
+ thread_count));
+ } else { /* This is the last executing thread */
- if (!walk_state->method_desc->method.thread_count) {
/*
* Support to dynamically change a method from not_serialized to
* Serialized if it appears that the method is written foolishly and
@@ -551,10 +563,11 @@ acpi_ds_terminate_control_method (
* before creating the synchronization semaphore.
*/
if ((walk_state->method_desc->method.concurrency == 1) &&
- (!walk_state->method_desc->method.semaphore)) {
- status = acpi_os_create_semaphore (1,
- 1,
- &walk_state->method_desc->method.semaphore);
+ (!walk_state->method_desc->method.semaphore)) {
+ status = acpi_os_create_semaphore(1, 1,
+ &walk_state->
+ method_desc->method.
+ semaphore);
}
/*
@@ -569,28 +582,27 @@ acpi_ds_terminate_control_method (
* Delete any namespace entries created immediately underneath
* the method
*/
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ goto exit;
}
if (method_node->child) {
- acpi_ns_delete_namespace_subtree (method_node);
+ acpi_ns_delete_namespace_subtree(method_node);
}
/*
* Delete any namespace entries created anywhere else within
* the namespace
*/
- acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ acpi_ns_delete_namespace_by_owner(walk_state->method_desc->
+ method.owner_id);
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ acpi_ut_release_owner_id(&walk_state->method_desc->method.
+ owner_id);
}
- status = acpi_ut_release_mutex (ACPI_MTX_PARSER);
- return_ACPI_STATUS (status);
+ exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_PARSER);
+ return_VOID;
}
-
-
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index f7998306f756..4095ce70982b 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -41,41 +41,32 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsmthdat")
+ACPI_MODULE_NAME("dsmthdat")
/* Local prototypes */
-
static void
-acpi_ds_method_data_delete_value (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state);
+acpi_ds_method_data_delete_value(u16 opcode,
+ u32 index, struct acpi_walk_state *walk_state);
static acpi_status
-acpi_ds_method_data_set_value (
- u16 opcode,
- u32 index,
- union acpi_operand_object *object,
- struct acpi_walk_state *walk_state);
+acpi_ds_method_data_set_value(u16 opcode,
+ u32 index,
+ union acpi_operand_object *object,
+ struct acpi_walk_state *walk_state);
#ifdef ACPI_OBSOLETE_FUNCTIONS
acpi_object_type
-acpi_ds_method_data_get_type (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state);
+acpi_ds_method_data_get_type(u16 opcode,
+ u32 index, struct acpi_walk_state *walk_state);
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_init
@@ -97,45 +88,41 @@ acpi_ds_method_data_get_type (
*
******************************************************************************/
-void
-acpi_ds_method_data_init (
- struct acpi_walk_state *walk_state)
+void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
{
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ds_method_data_init");
+ u32 i;
+ ACPI_FUNCTION_TRACE("ds_method_data_init");
/* Init the method arguments */
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
- ACPI_MOVE_32_TO_32 (&walk_state->arguments[i].name,
+ ACPI_MOVE_32_TO_32(&walk_state->arguments[i].name,
NAMEOF_ARG_NTE);
walk_state->arguments[i].name.integer |= (i << 24);
- walk_state->arguments[i].descriptor = ACPI_DESC_TYPE_NAMED;
- walk_state->arguments[i].type = ACPI_TYPE_ANY;
- walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST |
- ANOBJ_METHOD_ARG;
+ walk_state->arguments[i].descriptor = ACPI_DESC_TYPE_NAMED;
+ walk_state->arguments[i].type = ACPI_TYPE_ANY;
+ walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST |
+ ANOBJ_METHOD_ARG;
}
/* Init the method locals */
for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
- ACPI_MOVE_32_TO_32 (&walk_state->local_variables[i].name,
+ ACPI_MOVE_32_TO_32(&walk_state->local_variables[i].name,
NAMEOF_LOCAL_NTE);
walk_state->local_variables[i].name.integer |= (i << 24);
- walk_state->local_variables[i].descriptor = ACPI_DESC_TYPE_NAMED;
- walk_state->local_variables[i].type = ACPI_TYPE_ANY;
- walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST |
- ANOBJ_METHOD_LOCAL;
+ walk_state->local_variables[i].descriptor =
+ ACPI_DESC_TYPE_NAMED;
+ walk_state->local_variables[i].type = ACPI_TYPE_ANY;
+ walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST |
+ ANOBJ_METHOD_LOCAL;
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_delete_all
@@ -149,26 +136,25 @@ acpi_ds_method_data_init (
*
******************************************************************************/
-void
-acpi_ds_method_data_delete_all (
- struct acpi_walk_state *walk_state)
+void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
{
- u32 index;
-
-
- ACPI_FUNCTION_TRACE ("ds_method_data_delete_all");
+ u32 index;
+ ACPI_FUNCTION_TRACE("ds_method_data_delete_all");
/* Detach the locals */
for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
if (walk_state->local_variables[index].object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
- index, walk_state->local_variables[index].object));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
+ index,
+ walk_state->local_variables[index].
+ object));
/* Detach object (if present) and remove a reference */
- acpi_ns_detach_object (&walk_state->local_variables[index]);
+ acpi_ns_detach_object(&walk_state->
+ local_variables[index]);
}
}
@@ -176,19 +162,19 @@ acpi_ds_method_data_delete_all (
for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
if (walk_state->arguments[index].object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
- index, walk_state->arguments[index].object));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
+ index,
+ walk_state->arguments[index].object));
/* Detach object (if present) and remove a reference */
- acpi_ns_detach_object (&walk_state->arguments[index]);
+ acpi_ns_detach_object(&walk_state->arguments[index]);
}
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_init_args
@@ -206,47 +192,44 @@ acpi_ds_method_data_delete_all (
******************************************************************************/
acpi_status
-acpi_ds_method_data_init_args (
- union acpi_operand_object **params,
- u32 max_param_count,
- struct acpi_walk_state *walk_state)
+acpi_ds_method_data_init_args(union acpi_operand_object **params,
+ u32 max_param_count,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- u32 index = 0;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_method_data_init_args", params);
+ acpi_status status;
+ u32 index = 0;
+ ACPI_FUNCTION_TRACE_PTR("ds_method_data_init_args", params);
if (!params) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "No param list passed to method\n"));
+ return_ACPI_STATUS(AE_OK);
}
/* Copy passed parameters into the new method stack frame */
while ((index < ACPI_METHOD_NUM_ARGS) &&
- (index < max_param_count) &&
- params[index]) {
+ (index < max_param_count) && params[index]) {
/*
* A valid parameter.
* Store the argument in the method/walk descriptor.
* Do not copy the arg in order to implement call by reference
*/
- status = acpi_ds_method_data_set_value (AML_ARG_OP, index,
- params[index], walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_method_data_set_value(AML_ARG_OP, index,
+ params[index],
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
index++;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", index));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%d args passed to method\n", index));
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_get_node
@@ -263,14 +246,12 @@ acpi_ds_method_data_init_args (
******************************************************************************/
acpi_status
-acpi_ds_method_data_get_node (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node **node)
+acpi_ds_method_data_get_node(u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node **node)
{
- ACPI_FUNCTION_TRACE ("ds_method_data_get_node");
-
+ ACPI_FUNCTION_TRACE("ds_method_data_get_node");
/*
* Method Locals and Arguments are supported
@@ -279,10 +260,10 @@ acpi_ds_method_data_get_node (
case AML_LOCAL_OP:
if (index > ACPI_METHOD_MAX_LOCAL) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Local index %d is invalid (max %d)\n",
- index, ACPI_METHOD_MAX_LOCAL));
- return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Local index %d is invalid (max %d)\n",
+ index, ACPI_METHOD_MAX_LOCAL));
+ return_ACPI_STATUS(AE_AML_INVALID_INDEX);
}
/* Return a pointer to the pseudo-node */
@@ -293,10 +274,10 @@ acpi_ds_method_data_get_node (
case AML_ARG_OP:
if (index > ACPI_METHOD_MAX_ARG) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Arg index %d is invalid (max %d)\n",
- index, ACPI_METHOD_MAX_ARG));
- return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Arg index %d is invalid (max %d)\n",
+ index, ACPI_METHOD_MAX_ARG));
+ return_ACPI_STATUS(AE_AML_INVALID_INDEX);
}
/* Return a pointer to the pseudo-node */
@@ -305,14 +286,14 @@ acpi_ds_method_data_get_node (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
- return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Opcode %d is invalid\n",
+ opcode));
+ return_ACPI_STATUS(AE_AML_BAD_OPCODE);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_set_value
@@ -330,29 +311,26 @@ acpi_ds_method_data_get_node (
******************************************************************************/
static acpi_status
-acpi_ds_method_data_set_value (
- u16 opcode,
- u32 index,
- union acpi_operand_object *object,
- struct acpi_walk_state *walk_state)
+acpi_ds_method_data_set_value(u16 opcode,
+ u32 index,
+ union acpi_operand_object *object,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- struct acpi_namespace_node *node;
-
+ acpi_status status;
+ struct acpi_namespace_node *node;
- ACPI_FUNCTION_TRACE ("ds_method_data_set_value");
+ ACPI_FUNCTION_TRACE("ds_method_data_set_value");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "new_obj %p Opcode %X, Refs=%d [%s]\n", object,
- opcode, object->common.reference_count,
- acpi_ut_get_type_name (object->common.type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "new_obj %p Opcode %X, Refs=%d [%s]\n", object,
+ opcode, object->common.reference_count,
+ acpi_ut_get_type_name(object->common.type)));
/* Get the namespace node for the arg/local */
- status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -361,15 +339,14 @@ acpi_ds_method_data_set_value (
* reference semantics of ACPI Control Method invocation.
* (See ACPI specification 2.0_c)
*/
- acpi_ut_add_reference (object);
+ acpi_ut_add_reference(object);
/* Install the object */
node->object = object;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_get_value
@@ -387,32 +364,30 @@ acpi_ds_method_data_set_value (
******************************************************************************/
acpi_status
-acpi_ds_method_data_get_value (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state,
- union acpi_operand_object **dest_desc)
+acpi_ds_method_data_get_value(u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state,
+ union acpi_operand_object **dest_desc)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- union acpi_operand_object *object;
-
-
- ACPI_FUNCTION_TRACE ("ds_method_data_get_value");
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *object;
+ ACPI_FUNCTION_TRACE("ds_method_data_get_value");
/* Validate the object descriptor */
if (!dest_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointer\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null object descriptor pointer\n"));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the namespace node for the arg/local */
- status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the object from the node */
@@ -433,9 +408,10 @@ acpi_ds_method_data_get_value (
/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
if (acpi_gbl_enable_interpreter_slack) {
- object = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ object =
+ acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!object) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
object->integer.value = 0;
@@ -444,27 +420,29 @@ acpi_ds_method_data_get_value (
/* Otherwise, return the error */
- else switch (opcode) {
- case AML_ARG_OP:
+ else
+ switch (opcode) {
+ case AML_ARG_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Uninitialized Arg[%d] at node %p\n",
- index, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Uninitialized Arg[%d] at node %p\n",
+ index, node));
- return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
+ return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
- case AML_LOCAL_OP:
+ case AML_LOCAL_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Uninitialized Local[%d] at node %p\n",
- index, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Uninitialized Local[%d] at node %p\n",
+ index, node));
- return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
+ return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL);
- default:
- ACPI_REPORT_ERROR (("Not Arg/Local opcode: %X\n", opcode));
- return_ACPI_STATUS (AE_AML_INTERNAL);
- }
+ default:
+ ACPI_REPORT_ERROR(("Not Arg/Local opcode: %X\n",
+ opcode));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
+ }
}
/*
@@ -472,12 +450,11 @@ acpi_ds_method_data_get_value (
* Return an additional reference to the object
*/
*dest_desc = object;
- acpi_ut_add_reference (object);
+ acpi_ut_add_reference(object);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_method_data_delete_value
@@ -494,29 +471,25 @@ acpi_ds_method_data_get_value (
******************************************************************************/
static void
-acpi_ds_method_data_delete_value (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state)
+acpi_ds_method_data_delete_value(u16 opcode,
+ u32 index, struct acpi_walk_state *walk_state)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- union acpi_operand_object *object;
-
-
- ACPI_FUNCTION_TRACE ("ds_method_data_delete_value");
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *object;
+ ACPI_FUNCTION_TRACE("ds_method_data_delete_value");
/* Get the namespace node for the arg/local */
- status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+ if (ACPI_FAILURE(status)) {
return_VOID;
}
/* Get the associated object */
- object = acpi_ns_get_attached_object (node);
+ object = acpi_ns_get_attached_object(node);
/*
* Undefine the Arg or Local by setting its descriptor
@@ -526,19 +499,18 @@ acpi_ds_method_data_delete_value (
node->object = NULL;
if ((object) &&
- (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_OPERAND)) {
+ (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_OPERAND)) {
/*
* There is a valid object.
* Decrement the reference count by one to balance the
* increment when the object was stored.
*/
- acpi_ut_remove_reference (object);
+ acpi_ut_remove_reference(object);
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_store_object_to_local
@@ -557,40 +529,38 @@ acpi_ds_method_data_delete_value (
******************************************************************************/
acpi_status
-acpi_ds_store_object_to_local (
- u16 opcode,
- u32 index,
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state)
+acpi_ds_store_object_to_local(u16 opcode,
+ u32 index,
+ union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- union acpi_operand_object *current_obj_desc;
- union acpi_operand_object *new_obj_desc;
-
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *current_obj_desc;
+ union acpi_operand_object *new_obj_desc;
- ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
- opcode, index, obj_desc));
+ ACPI_FUNCTION_TRACE("ds_store_object_to_local");
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
+ opcode, index, obj_desc));
/* Parameter validation */
if (!obj_desc) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the namespace node for the arg/local */
- status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- current_obj_desc = acpi_ns_get_attached_object (node);
+ current_obj_desc = acpi_ns_get_attached_object(node);
if (current_obj_desc == obj_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
- obj_desc));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p already installed!\n",
+ obj_desc));
+ return_ACPI_STATUS(status);
}
/*
@@ -602,9 +572,11 @@ acpi_ds_store_object_to_local (
*/
new_obj_desc = obj_desc;
if (obj_desc->common.reference_count > 1) {
- status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_copy_iobject_to_iobject(obj_desc, &new_obj_desc,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -633,42 +605,39 @@ acpi_ds_store_object_to_local (
*/
if (opcode == AML_ARG_OP) {
/*
- * Make sure that the object is the correct type. This may be
- * overkill, butit is here because references were NS nodes in
- * the past. Now they are operand objects of type Reference.
- */
- if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
- ACPI_REPORT_ERROR ((
- "Invalid descriptor type while storing to method arg: [%s]\n",
- acpi_ut_get_descriptor_name (current_obj_desc)));
- return_ACPI_STATUS (AE_AML_INTERNAL);
- }
-
- /*
* If we have a valid reference object that came from ref_of(),
* do the indirect store
*/
- if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
- (current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Arg (%p) is an obj_ref(Node), storing in node %p\n",
- new_obj_desc, current_obj_desc));
+ if ((ACPI_GET_DESCRIPTOR_TYPE(current_obj_desc) ==
+ ACPI_DESC_TYPE_OPERAND)
+ && (current_obj_desc->common.type ==
+ ACPI_TYPE_LOCAL_REFERENCE)
+ && (current_obj_desc->reference.opcode ==
+ AML_REF_OF_OP)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Arg (%p) is an obj_ref(Node), storing in node %p\n",
+ new_obj_desc,
+ current_obj_desc));
/*
* Store this object to the Node (perform the indirect store)
* NOTE: No implicit conversion is performed, as per the ACPI
* specification rules on storing to Locals/Args.
*/
- status = acpi_ex_store_object_to_node (new_obj_desc,
- current_obj_desc->reference.object, walk_state,
- ACPI_NO_IMPLICIT_CONVERSION);
+ status =
+ acpi_ex_store_object_to_node(new_obj_desc,
+ current_obj_desc->
+ reference.
+ object,
+ walk_state,
+ ACPI_NO_IMPLICIT_CONVERSION);
/* Remove local reference if we copied the object above */
if (new_obj_desc != obj_desc) {
- acpi_ut_remove_reference (new_obj_desc);
+ acpi_ut_remove_reference(new_obj_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
}
@@ -676,7 +645,7 @@ acpi_ds_store_object_to_local (
* Delete the existing object
* before storing the new one
*/
- acpi_ds_method_data_delete_value (opcode, index, walk_state);
+ acpi_ds_method_data_delete_value(opcode, index, walk_state);
}
/*
@@ -684,18 +653,19 @@ acpi_ds_store_object_to_local (
* the descriptor for the Arg or Local.
* (increments the object reference count by one)
*/
- status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
+ status =
+ acpi_ds_method_data_set_value(opcode, index, new_obj_desc,
+ walk_state);
/* Remove local reference if we copied the object above */
if (new_obj_desc != obj_desc) {
- acpi_ut_remove_reference (new_obj_desc);
+ acpi_ut_remove_reference(new_obj_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
*
@@ -712,39 +682,33 @@ acpi_ds_store_object_to_local (
******************************************************************************/
acpi_object_type
-acpi_ds_method_data_get_type (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state)
+acpi_ds_method_data_get_type(u16 opcode,
+ u32 index, struct acpi_walk_state *walk_state)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- union acpi_operand_object *object;
-
-
- ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *object;
+ ACPI_FUNCTION_TRACE("ds_method_data_get_type");
/* Get the namespace node for the arg/local */
- status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
- if (ACPI_FAILURE (status)) {
- return_VALUE ((ACPI_TYPE_NOT_FOUND));
+ status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+ if (ACPI_FAILURE(status)) {
+ return_VALUE((ACPI_TYPE_NOT_FOUND));
}
/* Get the object */
- object = acpi_ns_get_attached_object (node);
+ object = acpi_ns_get_attached_object(node);
if (!object) {
/* Uninitialized local/arg, return TYPE_ANY */
- return_VALUE (ACPI_TYPE_ANY);
+ return_VALUE(ACPI_TYPE_ANY);
}
/* Get the object type */
- return_VALUE (ACPI_GET_OBJECT_TYPE (object));
+ return_VALUE(ACPI_GET_OBJECT_TYPE(object));
}
#endif
-
-
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index bfbae4e4c667..8ac0cd93adb5 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
@@ -50,14 +49,12 @@
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsobject")
+ACPI_MODULE_NAME("dsobject")
static acpi_status
-acpi_ds_build_internal_object (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- union acpi_operand_object **obj_desc_ptr);
-
+acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ union acpi_operand_object **obj_desc_ptr);
#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
@@ -76,17 +73,14 @@ acpi_ds_build_internal_object (
******************************************************************************/
static acpi_status
-acpi_ds_build_internal_object (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- union acpi_operand_object **obj_desc_ptr)
+acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ union acpi_operand_object **obj_desc_ptr)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ds_build_internal_object");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ds_build_internal_object");
*obj_desc_ptr = NULL;
if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
@@ -96,40 +90,44 @@ acpi_ds_build_internal_object (
* Otherwise, go ahead and look it up now
*/
if (!op->common.node) {
- status = acpi_ns_lookup (walk_state->scope_info,
- op->common.value.string,
- ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
- NULL,
- (struct acpi_namespace_node **) &(op->common.node));
-
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (op->common.value.string, status);
- return_ACPI_STATUS (status);
+ status = acpi_ns_lookup(walk_state->scope_info,
+ op->common.value.string,
+ ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT |
+ ACPI_NS_DONT_OPEN_SCOPE, NULL,
+ (struct acpi_namespace_node **)
+ &(op->common.node));
+
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(op->common.value.string,
+ status);
+ return_ACPI_STATUS(status);
}
}
}
/* Create and init the internal ACPI object */
- obj_desc = acpi_ut_create_internal_object (
- (acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
+ obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
+ (op->common.aml_opcode))->
+ object_type);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode,
- &obj_desc);
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ds_init_object_from_op(walk_state, op, op->common.aml_opcode,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
*obj_desc_ptr = obj_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_build_internal_buffer_obj
@@ -147,20 +145,17 @@ acpi_ds_build_internal_object (
******************************************************************************/
acpi_status
-acpi_ds_build_internal_buffer_obj (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u32 buffer_length,
- union acpi_operand_object **obj_desc_ptr)
+acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u32 buffer_length,
+ union acpi_operand_object **obj_desc_ptr)
{
- union acpi_parse_object *arg;
- union acpi_operand_object *obj_desc;
- union acpi_parse_object *byte_list;
- u32 byte_list_length = 0;
-
-
- ACPI_FUNCTION_TRACE ("ds_build_internal_buffer_obj");
+ union acpi_parse_object *arg;
+ union acpi_operand_object *obj_desc;
+ union acpi_parse_object *byte_list;
+ u32 byte_list_length = 0;
+ ACPI_FUNCTION_TRACE("ds_build_internal_buffer_obj");
obj_desc = *obj_desc_ptr;
if (obj_desc) {
@@ -168,14 +163,13 @@ acpi_ds_build_internal_buffer_obj (
* We are evaluating a Named buffer object "Name (xxxx, Buffer)".
* The buffer object already exists (from the NS node)
*/
- }
- else {
+ } else {
/* Create a new buffer object */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
*obj_desc_ptr = obj_desc;
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
}
@@ -184,16 +178,17 @@ acpi_ds_build_internal_buffer_obj (
* individual bytes or a string initializer. In either case, a
* byte_list appears in the AML.
*/
- arg = op->common.value.arg; /* skip first arg */
+ arg = op->common.value.arg; /* skip first arg */
byte_list = arg->named.next;
if (byte_list) {
if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Expecting bytelist, got AML opcode %X in op %p\n",
- byte_list->common.aml_opcode, byte_list));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Expecting bytelist, got AML opcode %X in op %p\n",
+ byte_list->common.aml_opcode,
+ byte_list));
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
return (AE_TYPE);
}
@@ -214,31 +209,29 @@ acpi_ds_build_internal_buffer_obj (
if (obj_desc->buffer.length == 0) {
obj_desc->buffer.pointer = NULL;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Buffer defined with zero length in AML, creating\n"));
- }
- else {
- obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
- obj_desc->buffer.length);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Buffer defined with zero length in AML, creating\n"));
+ } else {
+ obj_desc->buffer.pointer =
+ ACPI_MEM_CALLOCATE(obj_desc->buffer.length);
if (!obj_desc->buffer.pointer) {
- acpi_ut_delete_object_desc (obj_desc);
- return_ACPI_STATUS (AE_NO_MEMORY);
+ acpi_ut_delete_object_desc(obj_desc);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize buffer from the byte_list (if present) */
if (byte_list) {
- ACPI_MEMCPY (obj_desc->buffer.pointer, byte_list->named.data,
- byte_list_length);
+ ACPI_MEMCPY(obj_desc->buffer.pointer,
+ byte_list->named.data, byte_list_length);
}
}
obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
- op->common.node = (struct acpi_namespace_node *) obj_desc;
- return_ACPI_STATUS (AE_OK);
+ op->common.node = (struct acpi_namespace_node *)obj_desc;
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_build_internal_package_obj
@@ -256,28 +249,25 @@ acpi_ds_build_internal_buffer_obj (
******************************************************************************/
acpi_status
-acpi_ds_build_internal_package_obj (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u32 package_length,
- union acpi_operand_object **obj_desc_ptr)
+acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u32 package_length,
+ union acpi_operand_object **obj_desc_ptr)
{
- union acpi_parse_object *arg;
- union acpi_parse_object *parent;
- union acpi_operand_object *obj_desc = NULL;
- u32 package_list_length;
- acpi_status status = AE_OK;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ds_build_internal_package_obj");
+ union acpi_parse_object *arg;
+ union acpi_parse_object *parent;
+ union acpi_operand_object *obj_desc = NULL;
+ u32 package_list_length;
+ acpi_status status = AE_OK;
+ u32 i;
+ ACPI_FUNCTION_TRACE("ds_build_internal_package_obj");
/* Find the parent of a possibly nested package */
parent = op->common.parent;
- while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
- (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
+ while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
+ (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
parent = parent->common.parent;
}
@@ -287,12 +277,11 @@ acpi_ds_build_internal_package_obj (
* We are evaluating a Named package object "Name (xxxx, Package)".
* Get the existing package object from the NS node
*/
- }
- else {
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+ } else {
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
*obj_desc_ptr = obj_desc;
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
obj_desc->package.node = parent->common.node;
@@ -323,12 +312,13 @@ acpi_ds_build_internal_package_obj (
* individual objects). Add an extra pointer slot so
* that the list is always null terminated.
*/
- obj_desc->package.elements = ACPI_MEM_CALLOCATE (
- ((acpi_size) obj_desc->package.count + 1) * sizeof (void *));
+ obj_desc->package.elements = ACPI_MEM_CALLOCATE(((acpi_size) obj_desc->
+ package.count +
+ 1) * sizeof(void *));
if (!obj_desc->package.elements) {
- acpi_ut_delete_object_desc (obj_desc);
- return_ACPI_STATUS (AE_NO_MEMORY);
+ acpi_ut_delete_object_desc(obj_desc);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
@@ -342,11 +332,13 @@ acpi_ds_build_internal_package_obj (
/* Object (package or buffer) is already built */
obj_desc->package.elements[i] =
- ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
- }
- else {
- status = acpi_ds_build_internal_object (walk_state, arg,
- &obj_desc->package.elements[i]);
+ ACPI_CAST_PTR(union acpi_operand_object,
+ arg->common.node);
+ } else {
+ status = acpi_ds_build_internal_object(walk_state, arg,
+ &obj_desc->
+ package.
+ elements[i]);
}
i++;
@@ -354,11 +346,10 @@ acpi_ds_build_internal_package_obj (
}
obj_desc->package.flags |= AOPOBJ_DATA_VALID;
- op->common.node = (struct acpi_namespace_node *) obj_desc;
- return_ACPI_STATUS (status);
+ op->common.node = (struct acpi_namespace_node *)obj_desc;
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_node
@@ -374,57 +365,53 @@ acpi_ds_build_internal_package_obj (
******************************************************************************/
acpi_status
-acpi_ds_create_node (
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node *node,
- union acpi_parse_object *op)
+acpi_ds_create_node(struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node *node,
+ union acpi_parse_object *op)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_create_node", op);
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE_PTR("ds_create_node", op);
/*
* Because of the execution pass through the non-control-method
* parts of the table, we can arrive here twice. Only init
* the named object node the first time through
*/
- if (acpi_ns_get_attached_object (node)) {
- return_ACPI_STATUS (AE_OK);
+ if (acpi_ns_get_attached_object(node)) {
+ return_ACPI_STATUS(AE_OK);
}
if (!op->common.value.arg) {
/* No arguments, there is nothing to do */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Build an internal object for the argument(s) */
- status = acpi_ds_build_internal_object (walk_state, op->common.value.arg,
- &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_build_internal_object(walk_state, op->common.value.arg,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Re-type the object according to its argument */
- node->type = ACPI_GET_OBJECT_TYPE (obj_desc);
+ node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
/* Attach obj to node */
- status = acpi_ns_attach_object (node, obj_desc, node->type);
+ status = acpi_ns_attach_object(node, obj_desc, node->type);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-#endif /* ACPI_NO_METHOD_EXECUTION */
-
+#endif /* ACPI_NO_METHOD_EXECUTION */
/*******************************************************************************
*
@@ -444,55 +431,50 @@ acpi_ds_create_node (
******************************************************************************/
acpi_status
-acpi_ds_init_object_from_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u16 opcode,
- union acpi_operand_object **ret_obj_desc)
+acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u16 opcode,
+ union acpi_operand_object **ret_obj_desc)
{
- const struct acpi_opcode_info *op_info;
- union acpi_operand_object *obj_desc;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ds_init_object_from_op");
+ const struct acpi_opcode_info *op_info;
+ union acpi_operand_object *obj_desc;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ds_init_object_from_op");
obj_desc = *ret_obj_desc;
- op_info = acpi_ps_get_opcode_info (opcode);
+ op_info = acpi_ps_get_opcode_info(opcode);
if (op_info->class == AML_CLASS_UNKNOWN) {
/* Unknown opcode */
- return_ACPI_STATUS (AE_TYPE);
+ return_ACPI_STATUS(AE_TYPE);
}
/* Perform per-object initialization */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_BUFFER:
/*
* Defer evaluation of Buffer term_arg operand
*/
- obj_desc->buffer.node = (struct acpi_namespace_node *)
- walk_state->operands[0];
+ obj_desc->buffer.node = (struct acpi_namespace_node *)
+ walk_state->operands[0];
obj_desc->buffer.aml_start = op->named.data;
obj_desc->buffer.aml_length = op->named.length;
break;
-
case ACPI_TYPE_PACKAGE:
/*
* Defer evaluation of Package term_arg operand
*/
- obj_desc->package.node = (struct acpi_namespace_node *)
- walk_state->operands[0];
+ obj_desc->package.node = (struct acpi_namespace_node *)
+ walk_state->operands[0];
obj_desc->package.aml_start = op->named.data;
obj_desc->package.aml_length = op->named.length;
break;
-
case ACPI_TYPE_INTEGER:
switch (op_info->type) {
@@ -525,7 +507,7 @@ acpi_ds_init_object_from_op (
/* Truncate value if we are executing from a 32-bit ACPI table */
#ifndef ACPI_NO_METHOD_EXECUTION
- acpi_ex_truncate_for32bit_table (obj_desc);
+ acpi_ex_truncate_for32bit_table(obj_desc);
#endif
break;
@@ -536,33 +518,36 @@ acpi_ds_init_object_from_op (
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown constant opcode %X\n", opcode));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown constant opcode %X\n",
+ opcode));
status = AE_AML_OPERAND_TYPE;
break;
}
break;
-
case AML_TYPE_LITERAL:
obj_desc->integer.value = op->common.value.integer;
+#ifndef ACPI_NO_METHOD_EXECUTION
+ acpi_ex_truncate_for32bit_table(obj_desc);
+#endif
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n",
- op_info->type));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown Integer type %X\n",
+ op_info->type));
status = AE_AML_OPERAND_TYPE;
break;
}
break;
-
case ACPI_TYPE_STRING:
obj_desc->string.pointer = op->common.value.string;
- obj_desc->string.length = (u32) ACPI_STRLEN (op->common.value.string);
+ obj_desc->string.length =
+ (u32) ACPI_STRLEN(op->common.value.string);
/*
* The string is contained in the ACPI table, don't ever try
@@ -571,11 +556,9 @@ acpi_ds_init_object_from_op (
obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
break;
-
case ACPI_TYPE_METHOD:
break;
-
case ACPI_TYPE_LOCAL_REFERENCE:
switch (op_info->type) {
@@ -587,14 +570,17 @@ acpi_ds_init_object_from_op (
obj_desc->reference.offset = opcode - AML_LOCAL_OP;
#ifndef ACPI_NO_METHOD_EXECUTION
- status = acpi_ds_method_data_get_node (AML_LOCAL_OP,
- obj_desc->reference.offset,
- walk_state,
- (struct acpi_namespace_node **) &obj_desc->reference.object);
+ status = acpi_ds_method_data_get_node(AML_LOCAL_OP,
+ obj_desc->
+ reference.offset,
+ walk_state,
+ (struct
+ acpi_namespace_node
+ **)&obj_desc->
+ reference.object);
#endif
break;
-
case AML_TYPE_METHOD_ARGUMENT:
/* Split the opcode into a base opcode + offset */
@@ -603,14 +589,18 @@ acpi_ds_init_object_from_op (
obj_desc->reference.offset = opcode - AML_ARG_OP;
#ifndef ACPI_NO_METHOD_EXECUTION
- status = acpi_ds_method_data_get_node (AML_ARG_OP,
- obj_desc->reference.offset,
- walk_state,
- (struct acpi_namespace_node **) &obj_desc->reference.object);
+ status = acpi_ds_method_data_get_node(AML_ARG_OP,
+ obj_desc->
+ reference.offset,
+ walk_state,
+ (struct
+ acpi_namespace_node
+ **)&obj_desc->
+ reference.object);
#endif
break;
- default: /* Other literals, etc.. */
+ default: /* Other literals, etc.. */
if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
/* Node was saved in Op */
@@ -623,17 +613,15 @@ acpi_ds_init_object_from_op (
}
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n",
- ACPI_GET_OBJECT_TYPE (obj_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unimplemented data type: %X\n",
+ ACPI_GET_OBJECT_TYPE(obj_desc)));
status = AE_AML_OPERAND_TYPE;
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index ba13bca28bee..939d167bf87b 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
@@ -52,26 +51,21 @@
#include <acpi/acevents.h>
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsopcode")
+ACPI_MODULE_NAME("dsopcode")
/* Local prototypes */
-
static acpi_status
-acpi_ds_execute_arguments (
- struct acpi_namespace_node *node,
- struct acpi_namespace_node *scope_node,
- u32 aml_length,
- u8 *aml_start);
+acpi_ds_execute_arguments(struct acpi_namespace_node *node,
+ struct acpi_namespace_node *scope_node,
+ u32 aml_length, u8 * aml_start);
static acpi_status
-acpi_ds_init_buffer_field (
- u16 aml_opcode,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *buffer_desc,
- union acpi_operand_object *offset_desc,
- union acpi_operand_object *length_desc,
- union acpi_operand_object *result_desc);
-
+acpi_ds_init_buffer_field(u16 aml_opcode,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object *buffer_desc,
+ union acpi_operand_object *offset_desc,
+ union acpi_operand_object *length_desc,
+ union acpi_operand_object *result_desc);
/*******************************************************************************
*
@@ -89,26 +83,22 @@ acpi_ds_init_buffer_field (
******************************************************************************/
static acpi_status
-acpi_ds_execute_arguments (
- struct acpi_namespace_node *node,
- struct acpi_namespace_node *scope_node,
- u32 aml_length,
- u8 *aml_start)
+acpi_ds_execute_arguments(struct acpi_namespace_node *node,
+ struct acpi_namespace_node *scope_node,
+ u32 aml_length, u8 * aml_start)
{
- acpi_status status;
- union acpi_parse_object *op;
- struct acpi_walk_state *walk_state;
-
-
- ACPI_FUNCTION_TRACE ("ds_execute_arguments");
+ acpi_status status;
+ union acpi_parse_object *op;
+ struct acpi_walk_state *walk_state;
+ ACPI_FUNCTION_TRACE("ds_execute_arguments");
/*
* Allocate a new parser op to be the root of the parsed tree
*/
- op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
+ op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
if (!op) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Save the Node for use in acpi_ps_parse_aml */
@@ -117,16 +107,17 @@ acpi_ds_execute_arguments (
/* Create and initialize a new parser state */
- walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+ walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
if (!walk_state) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
- status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
- aml_length, NULL, 1);
- if (ACPI_FAILURE (status)) {
- acpi_ds_delete_walk_state (walk_state);
- return_ACPI_STATUS (status);
+ status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
+ aml_length, NULL, 1);
+ if (ACPI_FAILURE(status)) {
+ acpi_ds_delete_walk_state(walk_state);
+ goto cleanup;
}
/* Mark this parse as a deferred opcode */
@@ -136,50 +127,51 @@ acpi_ds_execute_arguments (
/* Pass1: Parse the entire declaration */
- status = acpi_ps_parse_aml (walk_state);
- if (ACPI_FAILURE (status)) {
- acpi_ps_delete_parse_tree (op);
- return_ACPI_STATUS (status);
+ status = acpi_ps_parse_aml(walk_state);
+ if (ACPI_FAILURE(status)) {
+ goto cleanup;
}
/* Get and init the Op created above */
op->common.node = node;
- acpi_ps_delete_parse_tree (op);
+ acpi_ps_delete_parse_tree(op);
/* Evaluate the deferred arguments */
- op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
+ op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
if (!op) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
op->common.node = scope_node;
/* Create and initialize a new parser state */
- walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+ walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
if (!walk_state) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
/* Execute the opcode and arguments */
- status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
- aml_length, NULL, 3);
- if (ACPI_FAILURE (status)) {
- acpi_ds_delete_walk_state (walk_state);
- return_ACPI_STATUS (status);
+ status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
+ aml_length, NULL, 3);
+ if (ACPI_FAILURE(status)) {
+ acpi_ds_delete_walk_state(walk_state);
+ goto cleanup;
}
/* Mark this execution as a deferred opcode */
walk_state->deferred_node = node;
- status = acpi_ps_parse_aml (walk_state);
- acpi_ps_delete_parse_tree (op);
- return_ACPI_STATUS (status);
-}
+ status = acpi_ps_parse_aml(walk_state);
+ cleanup:
+ acpi_ps_delete_parse_tree(op);
+ return_ACPI_STATUS(status);
+}
/*******************************************************************************
*
@@ -195,38 +187,36 @@ acpi_ds_execute_arguments (
******************************************************************************/
acpi_status
-acpi_ds_get_buffer_field_arguments (
- union acpi_operand_object *obj_desc)
+acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
{
- union acpi_operand_object *extra_desc;
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc);
+ union acpi_operand_object *extra_desc;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_get_buffer_field_arguments", obj_desc);
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Get the AML pointer (method object) and buffer_field node */
- extra_desc = acpi_ns_get_secondary_object (obj_desc);
+ extra_desc = acpi_ns_get_secondary_object(obj_desc);
node = obj_desc->buffer_field.node;
- ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
- acpi_ut_get_node_name (node)));
+ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
+ (ACPI_TYPE_BUFFER_FIELD, node, NULL));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
+ acpi_ut_get_node_name(node)));
/* Execute the AML code for the term_arg arguments */
- status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
- extra_desc->extra.aml_length, extra_desc->extra.aml_start);
- return_ACPI_STATUS (status);
+ status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
+ extra_desc->extra.aml_length,
+ extra_desc->extra.aml_start);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_get_buffer_arguments
@@ -240,40 +230,35 @@ acpi_ds_get_buffer_field_arguments (
*
******************************************************************************/
-acpi_status
-acpi_ds_get_buffer_arguments (
- union acpi_operand_object *obj_desc)
+acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc);
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_get_buffer_arguments", obj_desc);
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Get the Buffer node */
node = obj_desc->buffer.node;
if (!node) {
- ACPI_REPORT_ERROR ((
- "No pointer back to NS node in buffer obj %p\n", obj_desc));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("No pointer back to NS node in buffer obj %p\n", obj_desc));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
/* Execute the AML code for the term_arg arguments */
- status = acpi_ds_execute_arguments (node, node,
- obj_desc->buffer.aml_length, obj_desc->buffer.aml_start);
- return_ACPI_STATUS (status);
+ status = acpi_ds_execute_arguments(node, node,
+ obj_desc->buffer.aml_length,
+ obj_desc->buffer.aml_start);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_get_package_arguments
@@ -287,40 +272,36 @@ acpi_ds_get_buffer_arguments (
*
******************************************************************************/
-acpi_status
-acpi_ds_get_package_arguments (
- union acpi_operand_object *obj_desc)
+acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc);
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_get_package_arguments", obj_desc);
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Get the Package node */
node = obj_desc->package.node;
if (!node) {
- ACPI_REPORT_ERROR ((
- "No pointer back to NS node in package %p\n", obj_desc));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("No pointer back to NS node in package %p\n",
+ obj_desc));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
/* Execute the AML code for the term_arg arguments */
- status = acpi_ds_execute_arguments (node, node,
- obj_desc->package.aml_length, obj_desc->package.aml_start);
- return_ACPI_STATUS (status);
+ status = acpi_ds_execute_arguments(node, node,
+ obj_desc->package.aml_length,
+ obj_desc->package.aml_start);
+ return_ACPI_STATUS(status);
}
-
/*****************************************************************************
*
* FUNCTION: acpi_ds_get_region_arguments
@@ -334,44 +315,43 @@ acpi_ds_get_package_arguments (
*
****************************************************************************/
-acpi_status
-acpi_ds_get_region_arguments (
- union acpi_operand_object *obj_desc)
+acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
{
- struct acpi_namespace_node *node;
- acpi_status status;
- union acpi_operand_object *extra_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc);
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ union acpi_operand_object *extra_desc;
+ ACPI_FUNCTION_TRACE_PTR("ds_get_region_arguments", obj_desc);
if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
- extra_desc = acpi_ns_get_secondary_object (obj_desc);
+ extra_desc = acpi_ns_get_secondary_object(obj_desc);
if (!extra_desc) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/* Get the Region node */
node = obj_desc->region.node;
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
+ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
+ (ACPI_TYPE_REGION, node, NULL));
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
- acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[%4.4s] op_region Arg Init at AML %p\n",
+ acpi_ut_get_node_name(node),
+ extra_desc->extra.aml_start));
/* Execute the argument AML */
- status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
- extra_desc->extra.aml_length, extra_desc->extra.aml_start);
- return_ACPI_STATUS (status);
+ status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
+ extra_desc->extra.aml_length,
+ extra_desc->extra.aml_start);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_initialize_region
@@ -384,23 +364,19 @@ acpi_ds_get_region_arguments (
*
******************************************************************************/
-acpi_status
-acpi_ds_initialize_region (
- acpi_handle obj_handle)
+acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
-
- obj_desc = acpi_ns_get_attached_object (obj_handle);
+ obj_desc = acpi_ns_get_attached_object(obj_handle);
/* Namespace is NOT locked */
- status = acpi_ev_initialize_region (obj_desc, FALSE);
+ status = acpi_ev_initialize_region(obj_desc, FALSE);
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_init_buffer_field
@@ -419,30 +395,27 @@ acpi_ds_initialize_region (
******************************************************************************/
static acpi_status
-acpi_ds_init_buffer_field (
- u16 aml_opcode,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *buffer_desc,
- union acpi_operand_object *offset_desc,
- union acpi_operand_object *length_desc,
- union acpi_operand_object *result_desc)
+acpi_ds_init_buffer_field(u16 aml_opcode,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object *buffer_desc,
+ union acpi_operand_object *offset_desc,
+ union acpi_operand_object *length_desc,
+ union acpi_operand_object *result_desc)
{
- u32 offset;
- u32 bit_offset;
- u32 bit_count;
- u8 field_flags;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc);
+ u32 offset;
+ u32 bit_offset;
+ u32 bit_count;
+ u8 field_flags;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_init_buffer_field", obj_desc);
/* Host object must be a Buffer */
- if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Target of Create Field is not a Buffer object - %s\n",
- acpi_ut_get_object_type_name (buffer_desc)));
+ if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Target of Create Field is not a Buffer object - %s\n",
+ acpi_ut_get_object_type_name(buffer_desc)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
@@ -453,11 +426,11 @@ acpi_ds_init_buffer_field (
* out as a name_string, and should therefore now be a NS node
* after resolution in acpi_ex_resolve_operands().
*/
- if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(%s) destination not a NS Node [%s]\n",
- acpi_ps_get_opcode_name (aml_opcode),
- acpi_ut_get_descriptor_name (result_desc)));
+ if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(%s) destination not a NS Node [%s]\n",
+ acpi_ps_get_opcode_name(aml_opcode),
+ acpi_ut_get_descriptor_name(result_desc)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
@@ -475,13 +448,13 @@ acpi_ds_init_buffer_field (
field_flags = AML_FIELD_ACCESS_BYTE;
bit_offset = offset;
- bit_count = (u32) length_desc->integer.value;
+ bit_count = (u32) length_desc->integer.value;
/* Must have a valid (>0) bit count */
if (bit_count == 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Attempt to create_field of length 0\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Attempt to create_field of length 0\n"));
status = AE_AML_OPERAND_VALUE;
goto cleanup;
}
@@ -492,7 +465,7 @@ acpi_ds_init_buffer_field (
/* Offset is in bits, Field is one bit */
bit_offset = offset;
- bit_count = 1;
+ bit_count = 1;
field_flags = AML_FIELD_ACCESS_BYTE;
break;
@@ -501,7 +474,7 @@ acpi_ds_init_buffer_field (
/* Offset is in bytes, field is one byte */
bit_offset = 8 * offset;
- bit_count = 8;
+ bit_count = 8;
field_flags = AML_FIELD_ACCESS_BYTE;
break;
@@ -510,7 +483,7 @@ acpi_ds_init_buffer_field (
/* Offset is in bytes, field is one word */
bit_offset = 8 * offset;
- bit_count = 16;
+ bit_count = 16;
field_flags = AML_FIELD_ACCESS_WORD;
break;
@@ -519,7 +492,7 @@ acpi_ds_init_buffer_field (
/* Offset is in bytes, field is one dword */
bit_offset = 8 * offset;
- bit_count = 32;
+ bit_count = 32;
field_flags = AML_FIELD_ACCESS_DWORD;
break;
@@ -528,29 +501,29 @@ acpi_ds_init_buffer_field (
/* Offset is in bytes, field is one qword */
bit_offset = 8 * offset;
- bit_count = 64;
+ bit_count = 64;
field_flags = AML_FIELD_ACCESS_QWORD;
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown field creation opcode %02x\n",
- aml_opcode));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown field creation opcode %02x\n",
+ aml_opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
/* Entire field must fit within the current length of the buffer */
- if ((bit_offset + bit_count) >
- (8 * (u32) buffer_desc->buffer.length)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
- acpi_ut_get_node_name (result_desc),
- bit_offset + bit_count,
- acpi_ut_get_node_name (buffer_desc->buffer.node),
- 8 * (u32) buffer_desc->buffer.length));
+ if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
+ acpi_ut_get_node_name(result_desc),
+ bit_offset + bit_count,
+ acpi_ut_get_node_name(buffer_desc->buffer.
+ node),
+ 8 * (u32) buffer_desc->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
}
@@ -560,9 +533,9 @@ acpi_ds_init_buffer_field (
* For field_flags, use LOCK_RULE = 0 (NO_LOCK),
* UPDATE_RULE = 0 (UPDATE_PRESERVE)
*/
- status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
- bit_offset, bit_count);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
+ bit_offset, bit_count);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -571,35 +544,33 @@ acpi_ds_init_buffer_field (
/* Reference count for buffer_desc inherits obj_desc count */
buffer_desc->common.reference_count = (u16)
- (buffer_desc->common.reference_count + obj_desc->common.reference_count);
+ (buffer_desc->common.reference_count +
+ obj_desc->common.reference_count);
-
-cleanup:
+ cleanup:
/* Always delete the operands */
- acpi_ut_remove_reference (offset_desc);
- acpi_ut_remove_reference (buffer_desc);
+ acpi_ut_remove_reference(offset_desc);
+ acpi_ut_remove_reference(buffer_desc);
if (aml_opcode == AML_CREATE_FIELD_OP) {
- acpi_ut_remove_reference (length_desc);
+ acpi_ut_remove_reference(length_desc);
}
/* On failure, delete the result descriptor */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (result_desc); /* Result descriptor */
- }
- else {
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(result_desc); /* Result descriptor */
+ } else {
/* Now the address and length are valid for this buffer_field */
obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_buffer_field_operands
@@ -615,24 +586,21 @@ cleanup:
******************************************************************************/
acpi_status
-acpi_ds_eval_buffer_field_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
+acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- union acpi_parse_object *next_op;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op);
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ union acpi_parse_object *next_op;
+ ACPI_FUNCTION_TRACE_PTR("ds_eval_buffer_field_operands", op);
/*
* This is where we evaluate the address and length fields of the
* create_xxx_field declaration
*/
- node = op->common.node;
+ node = op->common.node;
/* next_op points to the op that holds the Buffer */
@@ -640,30 +608,32 @@ acpi_ds_eval_buffer_field_operands (
/* Evaluate/create the address and length operands */
- status = acpi_ds_create_operands (walk_state, next_op);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_create_operands(walk_state, next_op);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/* Resolve the operands */
- status = acpi_ex_resolve_operands (op->common.aml_opcode,
- ACPI_WALK_OPERANDS, walk_state);
+ status = acpi_ex_resolve_operands(op->common.aml_opcode,
+ ACPI_WALK_OPERANDS, walk_state);
- ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name (op->common.aml_opcode),
- walk_state->num_operands, "after acpi_ex_resolve_operands");
+ ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
+ acpi_ps_get_opcode_name(op->common.aml_opcode),
+ walk_state->num_operands,
+ "after acpi_ex_resolve_operands");
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode), status));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
+ acpi_ps_get_opcode_name(op->common.
+ aml_opcode), status));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Initialize the Buffer Field */
@@ -671,22 +641,25 @@ acpi_ds_eval_buffer_field_operands (
if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
/* NOTE: Slightly different operands for this opcode */
- status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
- walk_state->operands[0], walk_state->operands[1],
- walk_state->operands[2], walk_state->operands[3]);
- }
- else {
+ status =
+ acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
+ walk_state->operands[0],
+ walk_state->operands[1],
+ walk_state->operands[2],
+ walk_state->operands[3]);
+ } else {
/* All other, create_xxx_field opcodes */
- status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
- walk_state->operands[0], walk_state->operands[1],
- NULL, walk_state->operands[2]);
+ status =
+ acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
+ walk_state->operands[0],
+ walk_state->operands[1], NULL,
+ walk_state->operands[2]);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_region_operands
@@ -702,25 +675,22 @@ acpi_ds_eval_buffer_field_operands (
******************************************************************************/
acpi_status
-acpi_ds_eval_region_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
+acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *operand_desc;
- struct acpi_namespace_node *node;
- union acpi_parse_object *next_op;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op);
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *operand_desc;
+ struct acpi_namespace_node *node;
+ union acpi_parse_object *next_op;
+ ACPI_FUNCTION_TRACE_PTR("ds_eval_region_operands", op);
/*
* This is where we evaluate the address and length fields of the
* op_region declaration
*/
- node = op->common.node;
+ node = op->common.node;
/* next_op points to the op that holds the space_iD */
@@ -732,26 +702,26 @@ acpi_ds_eval_region_operands (
/* Evaluate/create the address and length operands */
- status = acpi_ds_create_operands (walk_state, next_op);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_create_operands(walk_state, next_op);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Resolve the length and address operands to numbers */
- status = acpi_ex_resolve_operands (op->common.aml_opcode,
- ACPI_WALK_OPERANDS, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_resolve_operands(op->common.aml_opcode,
+ ACPI_WALK_OPERANDS, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name (op->common.aml_opcode),
- 1, "after acpi_ex_resolve_operands");
+ ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
+ acpi_ps_get_opcode_name(op->common.aml_opcode),
+ 1, "after acpi_ex_resolve_operands");
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/*
@@ -761,7 +731,7 @@ acpi_ds_eval_region_operands (
operand_desc = walk_state->operands[walk_state->num_operands - 1];
obj_desc->region.length = (u32) operand_desc->integer.value;
- acpi_ut_remove_reference (operand_desc);
+ acpi_ut_remove_reference(operand_desc);
/*
* Get the address and save it
@@ -770,22 +740,21 @@ acpi_ds_eval_region_operands (
operand_desc = walk_state->operands[walk_state->num_operands - 2];
obj_desc->region.address = (acpi_physical_address)
- operand_desc->integer.value;
- acpi_ut_remove_reference (operand_desc);
+ operand_desc->integer.value;
+ acpi_ut_remove_reference(operand_desc);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
- obj_desc,
- ACPI_FORMAT_UINT64 (obj_desc->region.address),
- obj_desc->region.length));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
+ obj_desc,
+ ACPI_FORMAT_UINT64(obj_desc->region.address),
+ obj_desc->region.length));
/* Now the address and length are valid for this opregion */
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_data_object_operands
@@ -802,46 +771,44 @@ acpi_ds_eval_region_operands (
******************************************************************************/
acpi_status
-acpi_ds_eval_data_object_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- union acpi_operand_object *obj_desc)
+acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ union acpi_operand_object *obj_desc)
{
- acpi_status status;
- union acpi_operand_object *arg_desc;
- u32 length;
-
-
- ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands");
+ acpi_status status;
+ union acpi_operand_object *arg_desc;
+ u32 length;
+ ACPI_FUNCTION_TRACE("ds_eval_data_object_operands");
/* The first operand (for all of these data objects) is the length */
- status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ex_resolve_operands (walk_state->opcode,
- &(walk_state->operands [walk_state->num_operands -1]),
- walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_resolve_operands(walk_state->opcode,
+ &(walk_state->
+ operands[walk_state->num_operands -
+ 1]), walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Extract length operand */
- arg_desc = walk_state->operands [walk_state->num_operands - 1];
+ arg_desc = walk_state->operands[walk_state->num_operands - 1];
length = (u32) arg_desc->integer.value;
/* Cleanup for length operand */
- status = acpi_ds_obj_stack_pop (1, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_obj_stack_pop(1, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- acpi_ut_remove_reference (arg_desc);
+ acpi_ut_remove_reference(arg_desc);
/*
* Create the actual data object
@@ -849,37 +816,42 @@ acpi_ds_eval_data_object_operands (
switch (op->common.aml_opcode) {
case AML_BUFFER_OP:
- status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc);
+ status =
+ acpi_ds_build_internal_buffer_obj(walk_state, op, length,
+ &obj_desc);
break;
case AML_PACKAGE_OP:
case AML_VAR_PACKAGE_OP:
- status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc);
+ status =
+ acpi_ds_build_internal_package_obj(walk_state, op, length,
+ &obj_desc);
break;
default:
- return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ return_ACPI_STATUS(AE_AML_BAD_OPCODE);
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/*
* Return the object in the walk_state, unless the parent is a package -
* in this case, the return object will be stored in the parse tree
* for the package.
*/
if ((!op->common.parent) ||
- ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
- (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) &&
- (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
+ ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
+ (op->common.parent->common.aml_opcode !=
+ AML_VAR_PACKAGE_OP)
+ && (op->common.parent->common.aml_opcode !=
+ AML_NAME_OP))) {
walk_state->result_obj = obj_desc;
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_exec_begin_control_op
@@ -895,19 +867,16 @@ acpi_ds_eval_data_object_operands (
******************************************************************************/
acpi_status
-acpi_ds_exec_begin_control_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
+acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op)
{
- acpi_status status = AE_OK;
- union acpi_generic_state *control_state;
-
+ acpi_status status = AE_OK;
+ union acpi_generic_state *control_state;
- ACPI_FUNCTION_NAME ("ds_exec_begin_control_op");
+ ACPI_FUNCTION_NAME("ds_exec_begin_control_op");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
- op->common.aml_opcode, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
+ op->common.aml_opcode, walk_state));
switch (op->common.aml_opcode) {
case AML_IF_OP:
@@ -918,7 +887,7 @@ acpi_ds_exec_begin_control_op (
* constructs. We need to manage these as a stack, in order
* to handle nesting.
*/
- control_state = acpi_ut_create_control_state ();
+ control_state = acpi_ut_create_control_state();
if (!control_state) {
status = AE_NO_MEMORY;
break;
@@ -927,14 +896,16 @@ acpi_ds_exec_begin_control_op (
* Save a pointer to the predicate for multiple executions
* of a loop
*/
- control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1;
- control_state->control.package_end = walk_state->parser_state.pkg_end;
+ control_state->control.aml_predicate_start =
+ walk_state->parser_state.aml - 1;
+ control_state->control.package_end =
+ walk_state->parser_state.pkg_end;
control_state->control.opcode = op->common.aml_opcode;
-
/* Push the control state on this walk's control stack */
- acpi_ut_push_generic_state (&walk_state->control_state, control_state);
+ acpi_ut_push_generic_state(&walk_state->control_state,
+ control_state);
break;
case AML_ELSE_OP:
@@ -959,7 +930,6 @@ acpi_ds_exec_begin_control_op (
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_exec_end_control_op
@@ -975,46 +945,42 @@ acpi_ds_exec_begin_control_op (
******************************************************************************/
acpi_status
-acpi_ds_exec_end_control_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
+acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
+ union acpi_parse_object * op)
{
- acpi_status status = AE_OK;
- union acpi_generic_state *control_state;
-
-
- ACPI_FUNCTION_NAME ("ds_exec_end_control_op");
+ acpi_status status = AE_OK;
+ union acpi_generic_state *control_state;
+ ACPI_FUNCTION_NAME("ds_exec_end_control_op");
switch (op->common.aml_opcode) {
case AML_IF_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
/*
* Save the result of the predicate in case there is an
* ELSE to come
*/
walk_state->last_predicate =
- (u8) walk_state->control_state->common.value;
+ (u8) walk_state->control_state->common.value;
/*
* Pop the control state that was created at the start
* of the IF and free it
*/
- control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
- acpi_ut_delete_generic_state (control_state);
+ control_state =
+ acpi_ut_pop_generic_state(&walk_state->control_state);
+ acpi_ut_delete_generic_state(control_state);
break;
-
case AML_ELSE_OP:
break;
-
case AML_WHILE_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
if (walk_state->control_state->common.value) {
/* Predicate was true, go back and evaluate it again! */
@@ -1022,22 +988,24 @@ acpi_ds_exec_end_control_op (
status = AE_CTRL_PENDING;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "[WHILE_OP] termination! Op=%p\n",op));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "[WHILE_OP] termination! Op=%p\n", op));
/* Pop this control state and free it */
- control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
+ control_state =
+ acpi_ut_pop_generic_state(&walk_state->control_state);
- walk_state->aml_last_while = control_state->control.aml_predicate_start;
- acpi_ut_delete_generic_state (control_state);
+ walk_state->aml_last_while =
+ control_state->control.aml_predicate_start;
+ acpi_ut_delete_generic_state(control_state);
break;
-
case AML_RETURN_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "[RETURN_OP] Op=%p Arg=%p\n", op,
+ op->common.value.arg));
/*
* One optional operand -- the return value
@@ -1047,12 +1015,14 @@ acpi_ds_exec_end_control_op (
if (op->common.value.arg) {
/* Since we have a real Return(), delete any implicit return */
- acpi_ds_clear_implicit_return (walk_state);
+ acpi_ds_clear_implicit_return(walk_state);
/* Return statement has an immediate operand */
- status = acpi_ds_create_operands (walk_state, op->common.value.arg);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ds_create_operands(walk_state,
+ op->common.value.arg);
+ if (ACPI_FAILURE(status)) {
return (status);
}
@@ -1061,8 +1031,10 @@ acpi_ds_exec_end_control_op (
* an arg or local), resolve it now because it may
* cease to exist at the end of the method.
*/
- status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_resolve_to_value(&walk_state->operands[0],
+ walk_state);
+ if (ACPI_FAILURE(status)) {
return (status);
}
@@ -1072,12 +1044,11 @@ acpi_ds_exec_end_control_op (
* is set to anything other than zero!
*/
walk_state->return_desc = walk_state->operands[0];
- }
- else if ((walk_state->results) &&
- (walk_state->results->results.num_results > 0)) {
+ } else if ((walk_state->results) &&
+ (walk_state->results->results.num_results > 0)) {
/* Since we have a real Return(), delete any implicit return */
- acpi_ds_clear_implicit_return (walk_state);
+ acpi_ds_clear_implicit_return(walk_state);
/*
* The return value has come from a previous calculation.
@@ -1088,67 +1059,78 @@ acpi_ds_exec_end_control_op (
*
* Allow references created by the Index operator to return unchanged.
*/
- if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) &&
- (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
- ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) {
- status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
- if (ACPI_FAILURE (status)) {
+ if ((ACPI_GET_DESCRIPTOR_TYPE
+ (walk_state->results->results.obj_desc[0]) ==
+ ACPI_DESC_TYPE_OPERAND)
+ &&
+ (ACPI_GET_OBJECT_TYPE
+ (walk_state->results->results.obj_desc[0]) ==
+ ACPI_TYPE_LOCAL_REFERENCE)
+ && ((walk_state->results->results.obj_desc[0])->
+ reference.opcode != AML_INDEX_OP)) {
+ status =
+ acpi_ex_resolve_to_value(&walk_state->
+ results->results.
+ obj_desc[0],
+ walk_state);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
- walk_state->return_desc = walk_state->results->results.obj_desc [0];
- }
- else {
+ walk_state->return_desc =
+ walk_state->results->results.obj_desc[0];
+ } else {
/* No return operand */
if (walk_state->num_operands) {
- acpi_ut_remove_reference (walk_state->operands [0]);
+ acpi_ut_remove_reference(walk_state->
+ operands[0]);
}
- walk_state->operands [0] = NULL;
- walk_state->num_operands = 0;
- walk_state->return_desc = NULL;
+ walk_state->operands[0] = NULL;
+ walk_state->num_operands = 0;
+ walk_state->return_desc = NULL;
}
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Completed RETURN_OP State=%p, ret_val=%p\n",
- walk_state, walk_state->return_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Completed RETURN_OP State=%p, ret_val=%p\n",
+ walk_state, walk_state->return_desc));
/* End the control method execution right now */
status = AE_CTRL_TERMINATE;
break;
-
case AML_NOOP_OP:
/* Just do nothing! */
break;
-
case AML_BREAK_POINT_OP:
/* Call up to the OS service layer to handle this */
- status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
+ status =
+ acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
+ "Executed AML Breakpoint opcode");
/* If and when it returns, all done. */
break;
-
case AML_BREAK_OP:
- case AML_CONTINUE_OP: /* ACPI 2.0 */
-
+ case AML_CONTINUE_OP: /* ACPI 2.0 */
/* Pop and delete control states until we find a while */
while (walk_state->control_state &&
- (walk_state->control_state->control.opcode != AML_WHILE_OP)) {
- control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
- acpi_ut_delete_generic_state (control_state);
+ (walk_state->control_state->control.opcode !=
+ AML_WHILE_OP)) {
+ control_state =
+ acpi_ut_pop_generic_state(&walk_state->
+ control_state);
+ acpi_ut_delete_generic_state(control_state);
}
/* No while found? */
@@ -1159,23 +1141,23 @@ acpi_ds_exec_end_control_op (
/* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
- walk_state->aml_last_while = walk_state->control_state->control.package_end;
+ walk_state->aml_last_while =
+ walk_state->control_state->control.package_end;
/* Return status depending on opcode */
if (op->common.aml_opcode == AML_BREAK_OP) {
status = AE_CTRL_BREAK;
- }
- else {
+ } else {
status = AE_CTRL_CONTINUE;
}
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
- op->common.aml_opcode, op));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown control opcode=%X Op=%p\n",
+ op->common.aml_opcode, op));
status = AE_AML_BAD_OPCODE;
break;
@@ -1183,4 +1165,3 @@ acpi_ds_exec_end_control_op (
return (status);
}
-
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 9613349ac31d..83ae1c1aa286 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
@@ -51,8 +50,7 @@
#include <acpi/acdebug.h>
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsutils")
-
+ACPI_MODULE_NAME("dsutils")
/*******************************************************************************
*
@@ -68,13 +66,9 @@
* parent method exits.)
*
******************************************************************************/
-
-void
-acpi_ds_clear_implicit_return (
- struct acpi_walk_state *walk_state)
+void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
{
- ACPI_FUNCTION_NAME ("ds_clear_implicit_return");
-
+ ACPI_FUNCTION_NAME("ds_clear_implicit_return");
/*
* Slack must be enabled for this feature
@@ -89,16 +83,15 @@ acpi_ds_clear_implicit_return (
* complex statements, the implicit return value can be
* bubbled up several levels.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Removing reference on stale implicit return obj %p\n",
- walk_state->implicit_return_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Removing reference on stale implicit return obj %p\n",
+ walk_state->implicit_return_obj));
- acpi_ut_remove_reference (walk_state->implicit_return_obj);
+ acpi_ut_remove_reference(walk_state->implicit_return_obj);
walk_state->implicit_return_obj = NULL;
}
}
-
#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
*
@@ -119,27 +112,22 @@ acpi_ds_clear_implicit_return (
******************************************************************************/
u8
-acpi_ds_do_implicit_return (
- union acpi_operand_object *return_desc,
- struct acpi_walk_state *walk_state,
- u8 add_reference)
+acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
+ struct acpi_walk_state *walk_state, u8 add_reference)
{
- ACPI_FUNCTION_NAME ("ds_do_implicit_return");
-
+ ACPI_FUNCTION_NAME("ds_do_implicit_return");
/*
* Slack must be enabled for this feature, and we must
* have a valid return object
*/
- if ((!acpi_gbl_enable_interpreter_slack) ||
- (!return_desc)) {
+ if ((!acpi_gbl_enable_interpreter_slack) || (!return_desc)) {
return (FALSE);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Result %p will be implicitly returned; Prev=%p\n",
- return_desc,
- walk_state->implicit_return_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Result %p will be implicitly returned; Prev=%p\n",
+ return_desc, walk_state->implicit_return_obj));
/*
* Delete any "stale" implicit return value first. However, in
@@ -151,20 +139,19 @@ acpi_ds_do_implicit_return (
if (walk_state->implicit_return_obj == return_desc) {
return (TRUE);
}
- acpi_ds_clear_implicit_return (walk_state);
+ acpi_ds_clear_implicit_return(walk_state);
}
/* Save the implicit return value, add a reference if requested */
walk_state->implicit_return_obj = return_desc;
if (add_reference) {
- acpi_ut_add_reference (return_desc);
+ acpi_ut_add_reference(return_desc);
}
return (TRUE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_is_result_used
@@ -179,20 +166,18 @@ acpi_ds_do_implicit_return (
******************************************************************************/
u8
-acpi_ds_is_result_used (
- union acpi_parse_object *op,
- struct acpi_walk_state *walk_state)
+acpi_ds_is_result_used(union acpi_parse_object * op,
+ struct acpi_walk_state * walk_state)
{
- const struct acpi_opcode_info *parent_info;
-
- ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
+ const struct acpi_opcode_info *parent_info;
+ ACPI_FUNCTION_TRACE_PTR("ds_is_result_used", op);
/* Must have both an Op and a Result Object */
if (!op) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
- return_VALUE (TRUE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n"));
+ return_VALUE(TRUE);
}
/*
@@ -204,7 +189,8 @@ acpi_ds_is_result_used (
* NOTE: this is optional because the ASL language does not actually
* support this behavior.
*/
- (void) acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
+ (void)acpi_ds_do_implicit_return(walk_state->result_obj, walk_state,
+ TRUE);
/*
* Now determine if the parent will use the result
@@ -215,22 +201,24 @@ acpi_ds_is_result_used (
* via execute_control_method has a scope_op as the parent.
*/
if ((!op->common.parent) ||
- (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
+ (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
/* No parent, the return value cannot possibly be used */
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "At Method level, result of [%s] not used\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode)));
- return_VALUE (FALSE);
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "At Method level, result of [%s] not used\n",
+ acpi_ps_get_opcode_name(op->common.
+ aml_opcode)));
+ return_VALUE(FALSE);
}
/* Get info on the parent. The root_op is AML_SCOPE */
- parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
+ parent_info =
+ acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
if (parent_info->class == AML_CLASS_UNKNOWN) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown parent opcode. Op=%p\n", op));
- return_VALUE (FALSE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown parent opcode. Op=%p\n", op));
+ return_VALUE(FALSE);
}
/*
@@ -256,8 +244,10 @@ acpi_ds_is_result_used (
* If we are executing the predicate AND this is the predicate op,
* we will use the return value
*/
- if ((walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) &&
- (walk_state->control_state->control.predicate_op == op)) {
+ if ((walk_state->control_state->common.state ==
+ ACPI_CONTROL_PREDICATE_EXECUTING)
+ && (walk_state->control_state->control.
+ predicate_op == op)) {
goto result_used;
}
break;
@@ -271,7 +261,6 @@ acpi_ds_is_result_used (
goto result_not_used;
-
case AML_CLASS_CREATE:
/*
@@ -280,15 +269,16 @@ acpi_ds_is_result_used (
*/
goto result_used;
-
case AML_CLASS_NAMED_OBJECT:
- if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
- (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
- (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
- (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
- (op->common.parent->common.aml_opcode == AML_BUFFER_OP) ||
- (op->common.parent->common.aml_opcode == AML_INT_EVAL_SUBTREE_OP)) {
+ if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
+ (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP)
+ || (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)
+ || (op->common.parent->common.aml_opcode ==
+ AML_VAR_PACKAGE_OP)
+ || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
+ || (op->common.parent->common.aml_opcode ==
+ AML_INT_EVAL_SUBTREE_OP)) {
/*
* These opcodes allow term_arg(s) as operands and therefore
* the operands can be method calls. The result is used.
@@ -298,7 +288,6 @@ acpi_ds_is_result_used (
goto result_not_used;
-
default:
/*
@@ -308,26 +297,25 @@ acpi_ds_is_result_used (
goto result_used;
}
+ result_used:
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Result of [%s] used by Parent [%s] Op=%p\n",
+ acpi_ps_get_opcode_name(op->common.aml_opcode),
+ acpi_ps_get_opcode_name(op->common.parent->common.
+ aml_opcode), op));
-result_used:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Result of [%s] used by Parent [%s] Op=%p\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode),
- acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
-
- return_VALUE (TRUE);
-
+ return_VALUE(TRUE);
-result_not_used:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Result of [%s] not used by Parent [%s] Op=%p\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode),
- acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+ result_not_used:
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Result of [%s] not used by Parent [%s] Op=%p\n",
+ acpi_ps_get_opcode_name(op->common.aml_opcode),
+ acpi_ps_get_opcode_name(op->common.parent->common.
+ aml_opcode), op));
- return_VALUE (FALSE);
+ return_VALUE(FALSE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_delete_result_if_not_used
@@ -346,20 +334,17 @@ result_not_used:
******************************************************************************/
void
-acpi_ds_delete_result_if_not_used (
- union acpi_parse_object *op,
- union acpi_operand_object *result_obj,
- struct acpi_walk_state *walk_state)
+acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
+ union acpi_operand_object *result_obj,
+ struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj);
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ds_delete_result_if_not_used", result_obj);
if (!op) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n"));
return_VOID;
}
@@ -367,19 +352,18 @@ acpi_ds_delete_result_if_not_used (
return_VOID;
}
- if (!acpi_ds_is_result_used (op, walk_state)) {
+ if (!acpi_ds_is_result_used(op, walk_state)) {
/* Must pop the result stack (obj_desc should be equal to result_obj) */
- status = acpi_ds_result_pop (&obj_desc, walk_state);
- if (ACPI_SUCCESS (status)) {
- acpi_ut_remove_reference (result_obj);
+ status = acpi_ds_result_pop(&obj_desc, walk_state);
+ if (ACPI_SUCCESS(status)) {
+ acpi_ut_remove_reference(result_obj);
}
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_resolve_operands
@@ -394,16 +378,12 @@ acpi_ds_delete_result_if_not_used (
*
******************************************************************************/
-acpi_status
-acpi_ds_resolve_operands (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state)
{
- u32 i;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state);
+ u32 i;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ds_resolve_operands", walk_state);
/*
* Attempt to resolve each of the valid operands
@@ -411,16 +391,17 @@ acpi_ds_resolve_operands (
* that the actual objects are passed, not copies of the objects.
*/
for (i = 0; i < walk_state->num_operands; i++) {
- status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_resolve_to_value(&walk_state->operands[i],
+ walk_state);
+ if (ACPI_FAILURE(status)) {
break;
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_clear_operands
@@ -433,15 +414,11 @@ acpi_ds_resolve_operands (
*
******************************************************************************/
-void
-acpi_ds_clear_operands (
- struct acpi_walk_state *walk_state)
+void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
{
- u32 i;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
+ u32 i;
+ ACPI_FUNCTION_TRACE_PTR("ds_clear_operands", walk_state);
/* Remove a reference on each operand on the stack */
@@ -450,7 +427,7 @@ acpi_ds_clear_operands (
* Remove a reference to all operands, including both
* "Arguments" and "Targets".
*/
- acpi_ut_remove_reference (walk_state->operands[i]);
+ acpi_ut_remove_reference(walk_state->operands[i]);
walk_state->operands[i] = NULL;
}
@@ -459,7 +436,6 @@ acpi_ds_clear_operands (
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_operand
@@ -478,37 +454,36 @@ acpi_ds_clear_operands (
******************************************************************************/
acpi_status
-acpi_ds_create_operand (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *arg,
- u32 arg_index)
+acpi_ds_create_operand(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *arg, u32 arg_index)
{
- acpi_status status = AE_OK;
- char *name_string;
- u32 name_length;
- union acpi_operand_object *obj_desc;
- union acpi_parse_object *parent_op;
- u16 opcode;
- acpi_interpreter_mode interpreter_mode;
- const struct acpi_opcode_info *op_info;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg);
+ acpi_status status = AE_OK;
+ char *name_string;
+ u32 name_length;
+ union acpi_operand_object *obj_desc;
+ union acpi_parse_object *parent_op;
+ u16 opcode;
+ acpi_interpreter_mode interpreter_mode;
+ const struct acpi_opcode_info *op_info;
+ ACPI_FUNCTION_TRACE_PTR("ds_create_operand", arg);
/* A valid name must be looked up in the namespace */
if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
- (arg->common.value.string)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg));
+ (arg->common.value.string)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
+ arg));
/* Get the entire name string from the AML stream */
- status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->common.value.buffer,
- &name_string, &name_length);
+ status =
+ acpi_ex_get_name_string(ACPI_TYPE_ANY,
+ arg->common.value.buffer,
+ &name_string, &name_length);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* All prefixes have been handled, and the name is in name_string */
@@ -523,13 +498,14 @@ acpi_ds_create_operand (
* actual opcode exists.
*/
if ((walk_state->deferred_node) &&
- (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
- (arg_index != 0)) {
- obj_desc = ACPI_CAST_PTR (
- union acpi_operand_object, walk_state->deferred_node);
+ (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD)
+ && (arg_index != 0)) {
+ obj_desc =
+ ACPI_CAST_PTR(union acpi_operand_object,
+ walk_state->deferred_node);
status = AE_OK;
- }
- else /* All other opcodes */ {
+ } else { /* All other opcodes */
+
/*
* Differentiate between a namespace "create" operation
* versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
@@ -537,43 +513,51 @@ acpi_ds_create_operand (
* namespace objects during the execution of control methods.
*/
parent_op = arg->common.parent;
- op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
- if ((op_info->flags & AML_NSNODE) &&
- (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
- (parent_op->common.aml_opcode != AML_REGION_OP) &&
- (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
+ op_info =
+ acpi_ps_get_opcode_info(parent_op->common.
+ aml_opcode);
+ if ((op_info->flags & AML_NSNODE)
+ && (parent_op->common.aml_opcode !=
+ AML_INT_METHODCALL_OP)
+ && (parent_op->common.aml_opcode != AML_REGION_OP)
+ && (parent_op->common.aml_opcode !=
+ AML_INT_NAMEPATH_OP)) {
/* Enter name into namespace if not found */
interpreter_mode = ACPI_IMODE_LOAD_PASS2;
- }
- else {
+ } else {
/* Return a failure if name not found */
interpreter_mode = ACPI_IMODE_EXECUTE;
}
- status = acpi_ns_lookup (walk_state->scope_info, name_string,
- ACPI_TYPE_ANY, interpreter_mode,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
- walk_state,
- ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
+ status =
+ acpi_ns_lookup(walk_state->scope_info, name_string,
+ ACPI_TYPE_ANY, interpreter_mode,
+ ACPI_NS_SEARCH_PARENT |
+ ACPI_NS_DONT_OPEN_SCOPE, walk_state,
+ ACPI_CAST_INDIRECT_PTR(struct
+ acpi_namespace_node,
+ &obj_desc));
/*
* The only case where we pass through (ignore) a NOT_FOUND
* error is for the cond_ref_of opcode.
*/
if (status == AE_NOT_FOUND) {
- if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
+ if (parent_op->common.aml_opcode ==
+ AML_COND_REF_OF_OP) {
/*
* For the Conditional Reference op, it's OK if
* the name is not found; We just need a way to
* indicate this to the interpreter, set the
* object to the root
*/
- obj_desc = ACPI_CAST_PTR (
- union acpi_operand_object, acpi_gbl_root_node);
+ obj_desc =
+ ACPI_CAST_PTR(union
+ acpi_operand_object,
+ acpi_gbl_root_node);
status = AE_OK;
- }
- else {
+ } else {
/*
* We just plain didn't find it -- which is a
* very serious error at this point
@@ -582,30 +566,30 @@ acpi_ds_create_operand (
}
}
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (name_string, status);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(name_string, status);
}
}
/* Free the namestring created above */
- ACPI_MEM_FREE (name_string);
+ ACPI_MEM_FREE(name_string);
/* Check status from the lookup */
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Put the resulting object onto the current object stack */
- status = acpi_ds_obj_stack_push (obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_obj_stack_push(obj_desc, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
- }
- else {
+ ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
+ (obj_desc, walk_state));
+ } else {
/* Check for null name case */
if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) {
@@ -615,77 +599,83 @@ acpi_ds_create_operand (
* in the original ASL. Create a Zero Constant for a
* placeholder. (Store to a constant is a Noop.)
*/
- opcode = AML_ZERO_OP; /* Has no arguments! */
+ opcode = AML_ZERO_OP; /* Has no arguments! */
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Null namepath: Arg=%p\n", arg));
- }
- else {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Null namepath: Arg=%p\n", arg));
+ } else {
opcode = arg->common.aml_opcode;
}
/* Get the object type of the argument */
- op_info = acpi_ps_get_opcode_info (opcode);
+ op_info = acpi_ps_get_opcode_info(opcode);
if (op_info->object_type == ACPI_TYPE_INVALID) {
- return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+ return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
}
if (op_info->flags & AML_HAS_RETVAL) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Argument previously created, already stacked \n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Argument previously created, already stacked \n"));
- ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (
- walk_state->operands [walk_state->num_operands - 1], walk_state));
+ ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
+ (walk_state->
+ operands[walk_state->num_operands -
+ 1], walk_state));
/*
* Use value that was already previously returned
* by the evaluation of this argument
*/
- status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ds_result_pop_from_bottom(&obj_desc,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
/*
* Only error is underflow, and this indicates
* a missing or null operand!
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Missing or null operand, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Missing or null operand, %s\n",
+ acpi_format_exception
+ (status)));
+ return_ACPI_STATUS(status);
}
- }
- else {
+ } else {
/* Create an ACPI_INTERNAL_OBJECT for the argument */
- obj_desc = acpi_ut_create_internal_object (op_info->object_type);
+ obj_desc =
+ acpi_ut_create_internal_object(op_info->
+ object_type);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize the new object */
- status = acpi_ds_init_object_from_op (
- walk_state, arg, opcode, &obj_desc);
- if (ACPI_FAILURE (status)) {
- acpi_ut_delete_object_desc (obj_desc);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ds_init_object_from_op(walk_state, arg, opcode,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_delete_object_desc(obj_desc);
+ return_ACPI_STATUS(status);
}
}
/* Put the operand object on the object stack */
- status = acpi_ds_obj_stack_push (obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_obj_stack_push(obj_desc, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
+ ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
+ (obj_desc, walk_state));
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_operands
@@ -702,29 +692,27 @@ acpi_ds_create_operand (
******************************************************************************/
acpi_status
-acpi_ds_create_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *first_arg)
+acpi_ds_create_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *first_arg)
{
- acpi_status status = AE_OK;
- union acpi_parse_object *arg;
- u32 arg_count = 0;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg);
+ acpi_status status = AE_OK;
+ union acpi_parse_object *arg;
+ u32 arg_count = 0;
+ ACPI_FUNCTION_TRACE_PTR("ds_create_operands", first_arg);
/* For all arguments in the list... */
arg = first_arg;
while (arg) {
- status = acpi_ds_create_operand (walk_state, arg, arg_count);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_create_operand(walk_state, arg, arg_count);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n",
- arg_count, arg, first_arg));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Arg #%d (%p) done, Arg1=%p\n", arg_count,
+ arg, first_arg));
/* Move on to next argument, if any */
@@ -732,20 +720,17 @@ acpi_ds_create_operands (
arg_count++;
}
- return_ACPI_STATUS (status);
-
+ return_ACPI_STATUS(status);
-cleanup:
+ cleanup:
/*
* We must undo everything done above; meaning that we must
* pop everything off of the operand stack and delete those
* objects
*/
- (void) acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state);
+ (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
- (arg_count + 1), acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
+ (arg_count + 1), acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 10f71318e23b..e522763bb692 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
@@ -52,27 +51,26 @@
#include <acpi/acdebug.h>
#include <acpi/acdisasm.h>
-
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dswexec")
+ACPI_MODULE_NAME("dswexec")
/*
* Dispatch table for opcode classes
*/
-static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = {
- acpi_ex_opcode_0A_0T_1R,
- acpi_ex_opcode_1A_0T_0R,
- acpi_ex_opcode_1A_0T_1R,
- acpi_ex_opcode_1A_1T_0R,
- acpi_ex_opcode_1A_1T_1R,
- acpi_ex_opcode_2A_0T_0R,
- acpi_ex_opcode_2A_0T_1R,
- acpi_ex_opcode_2A_1T_1R,
- acpi_ex_opcode_2A_2T_1R,
- acpi_ex_opcode_3A_0T_0R,
- acpi_ex_opcode_3A_1T_1R,
- acpi_ex_opcode_6A_0T_1R};
-
+static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch[] = {
+ acpi_ex_opcode_0A_0T_1R,
+ acpi_ex_opcode_1A_0T_0R,
+ acpi_ex_opcode_1A_0T_1R,
+ acpi_ex_opcode_1A_1T_0R,
+ acpi_ex_opcode_1A_1T_1R,
+ acpi_ex_opcode_2A_0T_0R,
+ acpi_ex_opcode_2A_0T_1R,
+ acpi_ex_opcode_2A_1T_1R,
+ acpi_ex_opcode_2A_2T_1R,
+ acpi_ex_opcode_3A_0T_0R,
+ acpi_ex_opcode_3A_1T_1R,
+ acpi_ex_opcode_6A_0T_1R
+};
/*****************************************************************************
*
@@ -88,64 +86,64 @@ static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = {
****************************************************************************/
acpi_status
-acpi_ds_get_predicate_value (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *result_obj) {
- acpi_status status = AE_OK;
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *local_obj_desc = NULL;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state);
+acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *result_obj)
+{
+ acpi_status status = AE_OK;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *local_obj_desc = NULL;
+ ACPI_FUNCTION_TRACE_PTR("ds_get_predicate_value", walk_state);
walk_state->control_state->common.state = 0;
if (result_obj) {
- status = acpi_ds_result_pop (&obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not get result from predicate evaluation, %s\n",
- acpi_format_exception (status)));
+ status = acpi_ds_result_pop(&obj_desc, walk_state);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not get result from predicate evaluation, %s\n",
+ acpi_format_exception(status)));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
- }
- else {
- status = acpi_ds_create_operand (walk_state, walk_state->op, 0);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ } else {
+ status = acpi_ds_create_operand(walk_state, walk_state->op, 0);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_resolve_to_value(&walk_state->operands[0],
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- obj_desc = walk_state->operands [0];
+ obj_desc = walk_state->operands[0];
}
if (!obj_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "No predicate obj_desc=%p State=%p\n",
- obj_desc, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No predicate obj_desc=%p State=%p\n",
+ obj_desc, walk_state));
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
/*
* Result of predicate evaluation must be an Integer
* object. Implicitly convert the argument if necessary.
*/
- status = acpi_ex_convert_to_integer (obj_desc, &local_obj_desc, 16);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, 16);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- if (ACPI_GET_OBJECT_TYPE (local_obj_desc) != ACPI_TYPE_INTEGER) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
- obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
+ if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
+ obj_desc, walk_state,
+ ACPI_GET_OBJECT_TYPE(obj_desc)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
@@ -153,7 +151,7 @@ acpi_ds_get_predicate_value (
/* Truncate the predicate to 32-bits if necessary */
- acpi_ex_truncate_for32bit_table (local_obj_desc);
+ acpi_ex_truncate_for32bit_table(local_obj_desc);
/*
* Save the result of the predicate evaluation on
@@ -161,8 +159,7 @@ acpi_ds_get_predicate_value (
*/
if (local_obj_desc->integer.value) {
walk_state->control_state->common.value = TRUE;
- }
- else {
+ } else {
/*
* Predicate is FALSE, we will just toss the
* rest of the package
@@ -171,30 +168,30 @@ acpi_ds_get_predicate_value (
status = AE_CTRL_FALSE;
}
+ cleanup:
-cleanup:
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
+ walk_state->control_state->common.value,
+ walk_state->op));
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
- walk_state->control_state->common.value, walk_state->op));
+ /* Break to debugger to display result */
- /* Break to debugger to display result */
-
- ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (local_obj_desc, walk_state));
+ ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
+ (local_obj_desc, walk_state));
/*
* Delete the predicate result object (we know that
* we don't need it anymore)
*/
if (local_obj_desc != obj_desc) {
- acpi_ut_remove_reference (local_obj_desc);
+ acpi_ut_remove_reference(local_obj_desc);
}
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*****************************************************************************
*
* FUNCTION: acpi_ds_exec_begin_op
@@ -211,38 +208,39 @@ cleanup:
****************************************************************************/
acpi_status
-acpi_ds_exec_begin_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op)
+acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object **out_op)
{
- union acpi_parse_object *op;
- acpi_status status = AE_OK;
- u32 opcode_class;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_exec_begin_op", walk_state);
+ union acpi_parse_object *op;
+ acpi_status status = AE_OK;
+ u32 opcode_class;
+ ACPI_FUNCTION_TRACE_PTR("ds_exec_begin_op", walk_state);
op = walk_state->op;
if (!op) {
- status = acpi_ds_load2_begin_op (walk_state, out_op);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_load2_begin_op(walk_state, out_op);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
op = *out_op;
walk_state->op = op;
walk_state->opcode = op->common.aml_opcode;
- walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
-
- if (acpi_ns_opens_scope (walk_state->op_info->object_type)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "(%s) Popping scope for Op %p\n",
- acpi_ut_get_type_name (walk_state->op_info->object_type), op));
-
- status = acpi_ds_scope_stack_pop (walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(op->common.aml_opcode);
+
+ if (acpi_ns_opens_scope(walk_state->op_info->object_type)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "(%s) Popping scope for Op %p\n",
+ acpi_ut_get_type_name(walk_state->
+ op_info->
+ object_type),
+ op));
+
+ status = acpi_ds_scope_stack_pop(walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
}
@@ -252,7 +250,7 @@ acpi_ds_exec_begin_op (
*out_op = op;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -261,19 +259,20 @@ acpi_ds_exec_begin_op (
* Save this knowledge in the current scope descriptor
*/
if ((walk_state->control_state) &&
- (walk_state->control_state->common.state ==
- ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
- op, walk_state));
+ (walk_state->control_state->common.state ==
+ ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Exec predicate Op=%p State=%p\n", op,
+ walk_state));
- walk_state->control_state->common.state = ACPI_CONTROL_PREDICATE_EXECUTING;
+ walk_state->control_state->common.state =
+ ACPI_CONTROL_PREDICATE_EXECUTING;
/* Save start of predicate */
walk_state->control_state->control.predicate_op = op;
}
-
opcode_class = walk_state->op_info->class;
/* We want to send namepaths to the load code */
@@ -288,15 +287,14 @@ acpi_ds_exec_begin_op (
switch (opcode_class) {
case AML_CLASS_CONTROL:
- status = acpi_ds_result_stack_push (walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_result_stack_push(walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ds_exec_begin_control_op (walk_state, op);
+ status = acpi_ds_exec_begin_control_op(walk_state, op);
break;
-
case AML_CLASS_NAMED_OBJECT:
if (walk_state->walk_type == ACPI_WALK_METHOD) {
@@ -306,15 +304,14 @@ acpi_ds_exec_begin_op (
* object is temporary and will be deleted upon completion of
* the execution of this method.
*/
- status = acpi_ds_load2_begin_op (walk_state, NULL);
+ status = acpi_ds_load2_begin_op(walk_state, NULL);
}
if (op->common.aml_opcode == AML_REGION_OP) {
- status = acpi_ds_result_stack_push (walk_state);
+ status = acpi_ds_result_stack_push(walk_state);
}
break;
-
case AML_CLASS_EXECUTE:
case AML_CLASS_CREATE:
@@ -322,20 +319,18 @@ acpi_ds_exec_begin_op (
* Most operators with arguments.
* Start a new result/operand state
*/
- status = acpi_ds_result_stack_push (walk_state);
+ status = acpi_ds_result_stack_push(walk_state);
break;
-
default:
break;
}
/* Nothing to do here during method execution */
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*****************************************************************************
*
* FUNCTION: acpi_ds_exec_end_op
@@ -350,28 +345,25 @@ acpi_ds_exec_begin_op (
*
****************************************************************************/
-acpi_status
-acpi_ds_exec_end_op (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
{
- union acpi_parse_object *op;
- acpi_status status = AE_OK;
- u32 op_type;
- u32 op_class;
- union acpi_parse_object *next_op;
- union acpi_parse_object *first_arg;
+ union acpi_parse_object *op;
+ acpi_status status = AE_OK;
+ u32 op_type;
+ u32 op_class;
+ union acpi_parse_object *next_op;
+ union acpi_parse_object *first_arg;
+ ACPI_FUNCTION_TRACE_PTR("ds_exec_end_op", walk_state);
- ACPI_FUNCTION_TRACE_PTR ("ds_exec_end_op", walk_state);
-
-
- op = walk_state->op;
+ op = walk_state->op;
op_type = walk_state->op_info->type;
op_class = walk_state->op_info->class;
if (op_class == AML_CLASS_UNKNOWN) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->common.aml_opcode));
- return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown opcode %X\n",
+ op->common.aml_opcode));
+ return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
}
first_arg = op->common.value.arg;
@@ -384,29 +376,31 @@ acpi_ds_exec_end_op (
/* Call debugger for single step support (DEBUG build only) */
- ACPI_DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class));
- ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);});
+ ACPI_DEBUGGER_EXEC(status =
+ acpi_db_single_step(walk_state, op, op_class));
+ ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);}
+ ) ;
/* Decode the Opcode Class */
switch (op_class) {
- case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */
+ case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */
break;
-
- case AML_CLASS_EXECUTE: /* most operators with arguments */
+ case AML_CLASS_EXECUTE: /* most operators with arguments */
/* Build resolved operand stack */
- status = acpi_ds_create_operands (walk_state, first_arg);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_create_operands(walk_state, first_arg);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Done with this result state (Now that operand stack is built) */
- status = acpi_ds_result_stack_pop (walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_result_stack_pop(walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -417,86 +411,93 @@ acpi_ds_exec_end_op (
if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
/* Resolve all operands */
- status = acpi_ex_resolve_operands (walk_state->opcode,
- &(walk_state->operands [walk_state->num_operands -1]),
- walk_state);
- if (ACPI_SUCCESS (status)) {
- ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name (walk_state->opcode),
- walk_state->num_operands, "after ex_resolve_operands");
+ status = acpi_ex_resolve_operands(walk_state->opcode,
+ &(walk_state->
+ operands
+ [walk_state->
+ num_operands - 1]),
+ walk_state);
+ if (ACPI_SUCCESS(status)) {
+ ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
+ ACPI_IMODE_EXECUTE,
+ acpi_ps_get_opcode_name
+ (walk_state->opcode),
+ walk_state->num_operands,
+ "after ex_resolve_operands");
}
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/*
* Dispatch the request to the appropriate interpreter handler
* routine. There is one routine per opcode "type" based upon the
* number of opcode arguments and return type.
*/
- status = acpi_gbl_op_type_dispatch[op_type] (walk_state);
- }
- else {
+ status =
+ acpi_gbl_op_type_dispatch[op_type] (walk_state);
+ } else {
/*
* Treat constructs of the form "Store(local_x,local_x)" as noops when the
* Local is uninitialized.
*/
- if ((status == AE_AML_UNINITIALIZED_LOCAL) &&
- (walk_state->opcode == AML_STORE_OP) &&
- (walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
- (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
- (walk_state->operands[0]->reference.opcode ==
- walk_state->operands[1]->reference.opcode) &&
- (walk_state->operands[0]->reference.offset ==
- walk_state->operands[1]->reference.offset)) {
+ if ((status == AE_AML_UNINITIALIZED_LOCAL) &&
+ (walk_state->opcode == AML_STORE_OP) &&
+ (walk_state->operands[0]->common.type ==
+ ACPI_TYPE_LOCAL_REFERENCE)
+ && (walk_state->operands[1]->common.type ==
+ ACPI_TYPE_LOCAL_REFERENCE)
+ && (walk_state->operands[0]->reference.opcode ==
+ walk_state->operands[1]->reference.opcode)
+ && (walk_state->operands[0]->reference.offset ==
+ walk_state->operands[1]->reference.offset)) {
status = AE_OK;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "[%s]: Could not resolve operands, %s\n",
- acpi_ps_get_opcode_name (walk_state->opcode),
- acpi_format_exception (status)));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "[%s]: Could not resolve operands, %s\n",
+ acpi_ps_get_opcode_name
+ (walk_state->opcode),
+ acpi_format_exception
+ (status)));
}
}
/* Always delete the argument objects and clear the operand stack */
- acpi_ds_clear_operands (walk_state);
+ acpi_ds_clear_operands(walk_state);
/*
* If a result object was returned from above, push it on the
* current result stack
*/
- if (ACPI_SUCCESS (status) &&
- walk_state->result_obj) {
- status = acpi_ds_result_push (walk_state->result_obj, walk_state);
+ if (ACPI_SUCCESS(status) && walk_state->result_obj) {
+ status =
+ acpi_ds_result_push(walk_state->result_obj,
+ walk_state);
}
break;
-
default:
switch (op_type) {
- case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
+ case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
/* 1 Operand, 0 external_result, 0 internal_result */
- status = acpi_ds_exec_end_control_op (walk_state, op);
+ status = acpi_ds_exec_end_control_op(walk_state, op);
/* Make sure to properly pop the result stack */
- if (ACPI_SUCCESS (status)) {
- status = acpi_ds_result_stack_pop (walk_state);
- }
- else if (status == AE_CTRL_PENDING) {
- status = acpi_ds_result_stack_pop (walk_state);
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_ds_result_stack_pop(walk_state);
+ } else if (status == AE_CTRL_PENDING) {
+ status = acpi_ds_result_stack_pop(walk_state);
+ if (ACPI_SUCCESS(status)) {
status = AE_CTRL_PENDING;
}
}
break;
-
case AML_TYPE_METHOD_CALL:
/*
@@ -505,16 +506,22 @@ acpi_ds_exec_end_op (
* a reference to it.
*/
if ((op->asl.parent) &&
- ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
- (op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Method Reference in a Package, Op=%p\n", op));
- op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
- acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
- return_ACPI_STATUS (AE_OK);
+ ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP)
+ || (op->asl.parent->asl.aml_opcode ==
+ AML_VAR_PACKAGE_OP))) {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Method Reference in a Package, Op=%p\n",
+ op));
+ op->common.node =
+ (struct acpi_namespace_node *)op->asl.value.
+ arg->asl.node->object;
+ acpi_ut_add_reference(op->asl.value.arg->asl.
+ node->object);
+ return_ACPI_STATUS(AE_OK);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Method invocation, Op=%p\n", op));
/*
* (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
@@ -531,8 +538,8 @@ acpi_ds_exec_end_op (
/*
* Get the method's arguments and put them on the operand stack
*/
- status = acpi_ds_create_operands (walk_state, next_op);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_create_operands(walk_state, next_op);
+ if (ACPI_FAILURE(status)) {
break;
}
@@ -541,11 +548,11 @@ acpi_ds_exec_end_op (
* we must resolve all local references here (Local variables,
* arguments to *this* method, etc.)
*/
- status = acpi_ds_resolve_operands (walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_resolve_operands(walk_state);
+ if (ACPI_FAILURE(status)) {
/* On error, clear all resolved operands */
- acpi_ds_clear_operands (walk_state);
+ acpi_ds_clear_operands(walk_state);
break;
}
@@ -559,27 +566,28 @@ acpi_ds_exec_end_op (
* Return now; we don't want to disturb anything,
* especially the operand count!
*/
- return_ACPI_STATUS (status);
-
+ return_ACPI_STATUS(status);
case AML_TYPE_CREATE_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Executing create_field Buffer/Index Op=%p\n", op));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Executing create_field Buffer/Index Op=%p\n",
+ op));
- status = acpi_ds_load2_end_op (walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_load2_end_op(walk_state);
+ if (ACPI_FAILURE(status)) {
break;
}
- status = acpi_ds_eval_buffer_field_operands (walk_state, op);
+ status =
+ acpi_ds_eval_buffer_field_operands(walk_state, op);
break;
-
case AML_TYPE_CREATE_OBJECT:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Executing create_object (Buffer/Package) Op=%p\n", op));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Executing create_object (Buffer/Package) Op=%p\n",
+ op));
switch (op->common.parent->common.aml_opcode) {
case AML_NAME_OP:
@@ -588,13 +596,15 @@ acpi_ds_exec_end_op (
* Put the Node on the object stack (Contains the ACPI Name
* of this object)
*/
- walk_state->operands[0] = (void *) op->common.parent->common.node;
+ walk_state->operands[0] =
+ (void *)op->common.parent->common.node;
walk_state->num_operands = 1;
- status = acpi_ds_create_node (walk_state,
- op->common.parent->common.node,
- op->common.parent);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_create_node(walk_state,
+ op->common.parent->
+ common.node,
+ op->common.parent);
+ if (ACPI_FAILURE(status)) {
break;
}
@@ -603,20 +613,26 @@ acpi_ds_exec_end_op (
case AML_INT_EVAL_SUBTREE_OP:
- status = acpi_ds_eval_data_object_operands (walk_state, op,
- acpi_ns_get_attached_object (op->common.parent->common.node));
+ status =
+ acpi_ds_eval_data_object_operands
+ (walk_state, op,
+ acpi_ns_get_attached_object(op->common.
+ parent->common.
+ node));
break;
default:
- status = acpi_ds_eval_data_object_operands (walk_state, op, NULL);
+ status =
+ acpi_ds_eval_data_object_operands
+ (walk_state, op, NULL);
break;
}
/* Done with result state (Now that operand stack is built) */
- status = acpi_ds_result_stack_pop (walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_result_stack_pop(walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -625,56 +641,58 @@ acpi_ds_exec_end_op (
* current result stack
*/
if (walk_state->result_obj) {
- status = acpi_ds_result_push (walk_state->result_obj, walk_state);
+ status =
+ acpi_ds_result_push(walk_state->result_obj,
+ walk_state);
}
break;
-
case AML_TYPE_NAMED_FIELD:
case AML_TYPE_NAMED_COMPLEX:
case AML_TYPE_NAMED_SIMPLE:
case AML_TYPE_NAMED_NO_OBJ:
- status = acpi_ds_load2_end_op (walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_load2_end_op(walk_state);
+ if (ACPI_FAILURE(status)) {
break;
}
if (op->common.aml_opcode == AML_REGION_OP) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Executing op_region Address/Length Op=%p\n", op));
-
- status = acpi_ds_eval_region_operands (walk_state, op);
- if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Executing op_region Address/Length Op=%p\n",
+ op));
+
+ status =
+ acpi_ds_eval_region_operands(walk_state,
+ op);
+ if (ACPI_FAILURE(status)) {
break;
}
- status = acpi_ds_result_stack_pop (walk_state);
+ status = acpi_ds_result_stack_pop(walk_state);
}
break;
-
case AML_TYPE_UNDEFINED:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Undefined opcode type Op=%p\n", op));
- return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
-
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Undefined opcode type Op=%p\n", op));
+ return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
case AML_TYPE_BOGUS:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Internal opcode=%X type Op=%p\n",
- walk_state->opcode, op));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Internal opcode=%X type Op=%p\n",
+ walk_state->opcode, op));
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
- op_class, op_type, op->common.aml_opcode, op));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
+ op_class, op_type,
+ op->common.aml_opcode, op));
status = AE_NOT_IMPLEMENTED;
break;
@@ -685,55 +703,58 @@ acpi_ds_exec_end_op (
* ACPI 2.0 support for 64-bit integers: Truncate numeric
* result value if we are executing from a 32-bit ACPI table
*/
- acpi_ex_truncate_for32bit_table (walk_state->result_obj);
+ acpi_ex_truncate_for32bit_table(walk_state->result_obj);
/*
* Check if we just completed the evaluation of a
* conditional predicate
*/
- if ((ACPI_SUCCESS (status)) &&
- (walk_state->control_state) &&
- (walk_state->control_state->common.state ==
- ACPI_CONTROL_PREDICATE_EXECUTING) &&
- (walk_state->control_state->control.predicate_op == op)) {
- status = acpi_ds_get_predicate_value (walk_state, walk_state->result_obj);
+ if ((ACPI_SUCCESS(status)) &&
+ (walk_state->control_state) &&
+ (walk_state->control_state->common.state ==
+ ACPI_CONTROL_PREDICATE_EXECUTING) &&
+ (walk_state->control_state->control.predicate_op == op)) {
+ status =
+ acpi_ds_get_predicate_value(walk_state,
+ walk_state->result_obj);
walk_state->result_obj = NULL;
}
-
-cleanup:
+ cleanup:
/* Invoke exception handler on error */
- if (ACPI_FAILURE (status) &&
- acpi_gbl_exception_handler &&
- !(status & AE_CODE_CONTROL)) {
- acpi_ex_exit_interpreter ();
- status = acpi_gbl_exception_handler (status,
- walk_state->method_node->name.integer, walk_state->opcode,
- walk_state->aml_offset, NULL);
- (void) acpi_ex_enter_interpreter ();
+ if (ACPI_FAILURE(status) &&
+ acpi_gbl_exception_handler && !(status & AE_CODE_CONTROL)) {
+ acpi_ex_exit_interpreter();
+ status = acpi_gbl_exception_handler(status,
+ walk_state->method_node->
+ name.integer,
+ walk_state->opcode,
+ walk_state->aml_offset,
+ NULL);
+ (void)acpi_ex_enter_interpreter();
}
if (walk_state->result_obj) {
/* Break to debugger to display result */
- ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj,
- walk_state));
+ ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
+ (walk_state->result_obj, walk_state));
/*
* Delete the result op if and only if:
* Parent will not use the result -- such as any
* non-nested type2 op in a method (parent will be method)
*/
- acpi_ds_delete_result_if_not_used (op, walk_state->result_obj, walk_state);
+ acpi_ds_delete_result_if_not_used(op, walk_state->result_obj,
+ walk_state);
}
-
#ifdef _UNDER_DEVELOPMENT
if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
- acpi_db_method_end (walk_state);
+ acpi_db_method_end(walk_state);
}
#endif
@@ -745,12 +766,10 @@ cleanup:
/* On error, display method locals/args */
- if (ACPI_FAILURE (status)) {
- acpi_dm_dump_method_info (status, walk_state, op);
+ if (ACPI_FAILURE(status)) {
+ acpi_dm_dump_method_info(status, walk_state, op);
}
#endif
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index d11620018421..411731261c29 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
@@ -50,13 +49,12 @@
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
-#ifdef _ACPI_ASL_COMPILER
+#ifdef ACPI_ASL_COMPILER
#include <acpi/acdisasm.h>
#endif
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dswload")
-
+ACPI_MODULE_NAME("dswload")
/*******************************************************************************
*
@@ -70,32 +68,29 @@
* DESCRIPTION: Init walk state callbacks
*
******************************************************************************/
-
acpi_status
-acpi_ds_init_callbacks (
- struct acpi_walk_state *walk_state,
- u32 pass_number)
+acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
{
switch (pass_number) {
case 1:
- walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
- ACPI_PARSE_DELETE_TREE;
+ walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE;
walk_state->descending_callback = acpi_ds_load1_begin_op;
walk_state->ascending_callback = acpi_ds_load1_end_op;
break;
case 2:
- walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
- ACPI_PARSE_DELETE_TREE;
+ walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE;
walk_state->descending_callback = acpi_ds_load2_begin_op;
walk_state->ascending_callback = acpi_ds_load2_end_op;
break;
case 3:
#ifndef ACPI_NO_METHOD_EXECUTION
- walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
- ACPI_PARSE_DELETE_TREE;
+ walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
+ ACPI_PARSE_DELETE_TREE;
walk_state->descending_callback = acpi_ds_exec_begin_op;
walk_state->ascending_callback = acpi_ds_exec_end_op;
#endif
@@ -108,7 +103,6 @@ acpi_ds_init_callbacks (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_load1_begin_op
@@ -123,37 +117,26 @@ acpi_ds_init_callbacks (
******************************************************************************/
acpi_status
-acpi_ds_load1_begin_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op)
+acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
+ union acpi_parse_object ** out_op)
{
- union acpi_parse_object *op;
- struct acpi_namespace_node *node;
- acpi_status status;
- acpi_object_type object_type;
- char *path;
- u32 flags;
-
-
- ACPI_FUNCTION_NAME ("ds_load1_begin_op");
+ union acpi_parse_object *op;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ acpi_object_type object_type;
+ char *path;
+ u32 flags;
+ ACPI_FUNCTION_NAME("ds_load1_begin_op");
op = walk_state->op;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
+ walk_state));
/* We are only interested in opcodes that have an associated name */
if (op) {
if (!(walk_state->op_info->flags & AML_NAMED)) {
-#if 0
- if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
- (walk_state->op_info->class == AML_CLASS_CONTROL)) {
- acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n",
- walk_state->op_info->name);
- *out_op = op;
- return (AE_CTRL_SKIP);
- }
-#endif
*out_op = op;
return (AE_OK);
}
@@ -166,14 +149,15 @@ acpi_ds_load1_begin_op (
}
}
- path = acpi_ps_get_next_namestring (&walk_state->parser_state);
+ path = acpi_ps_get_next_namestring(&walk_state->parser_state);
/* Map the raw opcode into an internal object type */
object_type = walk_state->op_info->object_type;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "State=%p Op=%p [%s]\n", walk_state, op,
+ acpi_ut_get_type_name(object_type)));
switch (walk_state->opcode) {
case AML_SCOPE_OP:
@@ -183,23 +167,27 @@ acpi_ds_load1_begin_op (
* that we can actually open the scope to enter new names underneath it.
* Allow search-to-root for single namesegs.
*/
- status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
-#ifdef _ACPI_ASL_COMPILER
+ status =
+ acpi_ns_lookup(walk_state->scope_info, path, object_type,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ walk_state, &(node));
+#ifdef ACPI_ASL_COMPILER
if (status == AE_NOT_FOUND) {
/*
* Table disassembly:
* Target of Scope() not found. Generate an External for it, and
* insert the name into the namespace.
*/
- acpi_dm_add_to_external_list (path);
- status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
- ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
- walk_state, &(node));
+ acpi_dm_add_to_external_list(path);
+ status =
+ acpi_ns_lookup(walk_state->scope_info, path,
+ object_type, ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_SEARCH_PARENT, walk_state,
+ &(node));
}
#endif
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (path, status);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(path, status);
return (status);
}
@@ -208,7 +196,7 @@ acpi_ds_load1_begin_op (
* one of the opcodes that actually opens a scope
*/
switch (node->type) {
- case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
+ case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR:
@@ -232,9 +220,10 @@ acpi_ds_load1_begin_op (
* a warning
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
- path, acpi_ut_get_type_name (node->type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+ path,
+ acpi_ut_get_type_name(node->type)));
node->type = ACPI_TYPE_ANY;
walk_state->scope_info->common.value = ACPI_TYPE_ANY;
@@ -244,15 +233,12 @@ acpi_ds_load1_begin_op (
/* All other types are an error */
- ACPI_REPORT_ERROR ((
- "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
- acpi_ut_get_type_name (node->type), path));
+ ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path));
return (AE_AML_OPERAND_TYPE);
}
break;
-
default:
/*
@@ -281,15 +267,15 @@ acpi_ds_load1_begin_op (
flags = ACPI_NS_NO_UPSEARCH;
if ((walk_state->opcode != AML_SCOPE_OP) &&
- (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
+ (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
flags |= ACPI_NS_ERROR_IF_FOUND;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
- acpi_ut_get_type_name (object_type)));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "[%s] Both Find or Create allowed\n",
- acpi_ut_get_type_name (object_type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "[%s] Cannot already exist\n",
+ acpi_ut_get_type_name(object_type)));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "[%s] Both Find or Create allowed\n",
+ acpi_ut_get_type_name(object_type)));
}
/*
@@ -298,22 +284,23 @@ acpi_ds_load1_begin_op (
* involve arguments to the opcode must be created as we go back up the
* parse tree later.
*/
- status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
- ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node));
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (path, status);
+ status =
+ acpi_ns_lookup(walk_state->scope_info, path, object_type,
+ ACPI_IMODE_LOAD_PASS1, flags, walk_state,
+ &(node));
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(path, status);
return (status);
}
break;
}
-
/* Common exit */
if (!op) {
/* Create a new op */
- op = acpi_ps_alloc_op (walk_state->opcode);
+ op = acpi_ps_alloc_op(walk_state->opcode);
if (!op) {
return (AE_NO_MEMORY);
}
@@ -327,19 +314,18 @@ acpi_ds_load1_begin_op (
op->named.path = (u8 *) path;
#endif
-
/*
* Put the Node in the "op" object that the parser uses, so we
* can get it again quickly when this scope is closed
*/
op->common.node = node;
- acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op);
+ acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
+ op);
*out_op = op;
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_load1_end_op
@@ -353,20 +339,17 @@ acpi_ds_load1_begin_op (
*
******************************************************************************/
-acpi_status
-acpi_ds_load1_end_op (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
{
- union acpi_parse_object *op;
- acpi_object_type object_type;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_NAME ("ds_load1_end_op");
+ union acpi_parse_object *op;
+ acpi_object_type object_type;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_NAME("ds_load1_end_op");
op = walk_state->op;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
+ walk_state));
/* We are only interested in opcodes that have an associated name */
@@ -380,21 +363,20 @@ acpi_ds_load1_end_op (
#ifndef ACPI_NO_METHOD_EXECUTION
if (walk_state->op_info->flags & AML_FIELD) {
- if (walk_state->opcode == AML_FIELD_OP ||
- walk_state->opcode == AML_BANK_FIELD_OP ||
- walk_state->opcode == AML_INDEX_FIELD_OP) {
- status = acpi_ds_init_field_objects (op, walk_state);
+ if (walk_state->opcode == AML_FIELD_OP ||
+ walk_state->opcode == AML_BANK_FIELD_OP ||
+ walk_state->opcode == AML_INDEX_FIELD_OP) {
+ status = acpi_ds_init_field_objects(op, walk_state);
}
return (status);
}
-
if (op->common.aml_opcode == AML_REGION_OP) {
- status = acpi_ex_create_region (op->named.data, op->named.length,
- (acpi_adr_space_type)
- ((op->common.value.arg)->common.value.integer),
- walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_create_region(op->named.data, op->named.length,
+ (acpi_adr_space_type)
+ ((op->common.value.arg)->common.
+ value.integer), walk_state);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -404,8 +386,11 @@ acpi_ds_load1_end_op (
/* For Name opcode, get the object type from the argument */
if (op->common.value.arg) {
- object_type = (acpi_ps_get_opcode_info (
- (op->common.value.arg)->common.aml_opcode))->object_type;
+ object_type = (acpi_ps_get_opcode_info((op->common.
+ value.arg)->
+ common.
+ aml_opcode))->
+ object_type;
op->common.node->type = (u8) object_type;
}
}
@@ -419,23 +404,26 @@ acpi_ds_load1_end_op (
* of invocations of the method (need to know the number of
* arguments.)
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "LOADING-Method: State=%p Op=%p named_obj=%p\n",
- walk_state, op, op->named.node));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "LOADING-Method: State=%p Op=%p named_obj=%p\n",
+ walk_state, op, op->named.node));
- if (!acpi_ns_get_attached_object (op->named.node)) {
- walk_state->operands[0] = (void *) op->named.node;
+ if (!acpi_ns_get_attached_object(op->named.node)) {
+ walk_state->operands[0] = (void *)op->named.node;
walk_state->num_operands = 1;
- status = acpi_ds_create_operands (walk_state, op->common.value.arg);
- if (ACPI_SUCCESS (status)) {
- status = acpi_ex_create_method (op->named.data,
- op->named.length, walk_state);
+ status =
+ acpi_ds_create_operands(walk_state,
+ op->common.value.arg);
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_ex_create_method(op->named.data,
+ op->named.length,
+ walk_state);
}
walk_state->operands[0] = NULL;
walk_state->num_operands = 0;
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -443,17 +431,17 @@ acpi_ds_load1_end_op (
/* Pop the scope stack */
- if (acpi_ns_opens_scope (object_type)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
- acpi_ut_get_type_name (object_type), op));
+ if (acpi_ns_opens_scope(object_type)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "(%s): Popping scope for Op %p\n",
+ acpi_ut_get_type_name(object_type), op));
- status = acpi_ds_scope_stack_pop (walk_state);
+ status = acpi_ds_scope_stack_pop(walk_state);
}
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_load2_begin_op
@@ -468,30 +456,53 @@ acpi_ds_load1_end_op (
******************************************************************************/
acpi_status
-acpi_ds_load2_begin_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op)
+acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
+ union acpi_parse_object ** out_op)
{
- union acpi_parse_object *op;
- struct acpi_namespace_node *node;
- acpi_status status;
- acpi_object_type object_type;
- char *buffer_ptr;
-
-
- ACPI_FUNCTION_TRACE ("ds_load2_begin_op");
+ union acpi_parse_object *op;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ acpi_object_type object_type;
+ char *buffer_ptr;
+ ACPI_FUNCTION_TRACE("ds_load2_begin_op");
op = walk_state->op;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
+ walk_state));
if (op) {
+ if ((walk_state->control_state) &&
+ (walk_state->control_state->common.state ==
+ ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
+ /* We are executing a while loop outside of a method */
+
+ status = acpi_ds_exec_begin_op(walk_state, out_op);
+ return_ACPI_STATUS(status);
+ }
+
/* We only care about Namespace opcodes here */
if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
- (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
- (!(walk_state->op_info->flags & AML_NAMED))) {
- return_ACPI_STATUS (AE_OK);
+ (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
+ (!(walk_state->op_info->flags & AML_NAMED))) {
+#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
+ if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
+ (walk_state->op_info->class == AML_CLASS_CONTROL)) {
+
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Begin/EXEC: %s (fl %8.8X)\n",
+ walk_state->op_info->name,
+ walk_state->op_info->flags));
+
+ /* Executing a type1 or type2 opcode outside of a method */
+
+ status =
+ acpi_ds_exec_begin_op(walk_state, out_op);
+ return_ACPI_STATUS(status);
+ }
+#endif
+ return_ACPI_STATUS(AE_OK);
}
/* Get the name we are going to enter or lookup in the namespace */
@@ -503,28 +514,27 @@ acpi_ds_load2_begin_op (
if (!buffer_ptr) {
/* No name, just exit */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
- }
- else {
+ } else {
/* Get name from the op */
- buffer_ptr = (char *) &op->named.name;
+ buffer_ptr = (char *)&op->named.name;
}
- }
- else {
+ } else {
/* Get the namestring from the raw AML */
- buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state);
+ buffer_ptr =
+ acpi_ps_get_next_namestring(&walk_state->parser_state);
}
/* Map the opcode into an internal object type */
object_type = walk_state->op_info->object_type;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "State=%p Op=%p Type=%X\n", walk_state, op, object_type));
-
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "State=%p Op=%p Type=%X\n", walk_state, op,
+ object_type));
switch (walk_state->opcode) {
case AML_FIELD_OP:
@@ -542,9 +552,10 @@ acpi_ds_load2_begin_op (
* Don't enter the name into the namespace, but look it up
* for use later.
*/
- status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
- walk_state, &(node));
+ status =
+ acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
+ object_type, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, walk_state, &(node));
break;
case AML_SCOPE_OP:
@@ -554,28 +565,28 @@ acpi_ds_load2_begin_op (
* Don't enter the name into the namespace, but look it up
* for use later.
*/
- status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
- walk_state, &(node));
- if (ACPI_FAILURE (status)) {
-#ifdef _ACPI_ASL_COMPILER
+ status =
+ acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
+ object_type, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+ if (ACPI_FAILURE(status)) {
+#ifdef ACPI_ASL_COMPILER
if (status == AE_NOT_FOUND) {
status = AE_OK;
- }
- else {
- ACPI_REPORT_NSERROR (buffer_ptr, status);
+ } else {
+ ACPI_REPORT_NSERROR(buffer_ptr, status);
}
#else
- ACPI_REPORT_NSERROR (buffer_ptr, status);
+ ACPI_REPORT_NSERROR(buffer_ptr, status);
#endif
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/*
* We must check to make sure that the target is
* one of the opcodes that actually opens a scope
*/
switch (node->type) {
- case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
+ case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR:
@@ -596,9 +607,7 @@ acpi_ds_load2_begin_op (
* Scope (DEB) { ... }
*/
- ACPI_REPORT_WARNING ((
- "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
- buffer_ptr, acpi_ut_get_type_name (node->type)));
+ ACPI_REPORT_WARNING(("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", buffer_ptr, acpi_ut_get_type_name(node->type)));
node->type = ACPI_TYPE_ANY;
walk_state->scope_info->common.value = ACPI_TYPE_ANY;
@@ -608,9 +617,7 @@ acpi_ds_load2_begin_op (
/* All other types are an error */
- ACPI_REPORT_ERROR ((
- "Invalid type (%s) for target of Scope operator [%4.4s]\n",
- acpi_ut_get_type_name (node->type), buffer_ptr));
+ ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s]\n", acpi_ut_get_type_name(node->type), buffer_ptr));
return (AE_AML_OPERAND_TYPE);
}
@@ -625,14 +632,16 @@ acpi_ds_load2_begin_op (
node = op->common.node;
- if (acpi_ns_opens_scope (object_type)) {
- status = acpi_ds_scope_stack_push (node, object_type, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (acpi_ns_opens_scope(object_type)) {
+ status =
+ acpi_ds_scope_stack_push(node, object_type,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -651,24 +660,26 @@ acpi_ds_load2_begin_op (
break;
}
- status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH,
- walk_state, &(node));
+ /* Add new entry into namespace */
+
+ status =
+ acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
+ object_type, ACPI_IMODE_LOAD_PASS2,
+ ACPI_NS_NO_UPSEARCH, walk_state, &(node));
break;
}
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_NSERROR (buffer_ptr, status);
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_NSERROR(buffer_ptr, status);
+ return_ACPI_STATUS(status);
}
-
if (!op) {
/* Create a new op */
- op = acpi_ps_alloc_op (walk_state->opcode);
+ op = acpi_ps_alloc_op(walk_state->opcode);
if (!op) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize the new op */
@@ -676,9 +687,7 @@ acpi_ds_load2_begin_op (
if (node) {
op->named.name = node->name.integer;
}
- if (out_op) {
- *out_op = op;
- }
+ *out_op = op;
}
/*
@@ -687,10 +696,9 @@ acpi_ds_load2_begin_op (
*/
op->common.node = node;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_load2_end_op
@@ -704,39 +712,54 @@ acpi_ds_load2_begin_op (
*
******************************************************************************/
-acpi_status
-acpi_ds_load2_end_op (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
{
- union acpi_parse_object *op;
- acpi_status status = AE_OK;
- acpi_object_type object_type;
- struct acpi_namespace_node *node;
- union acpi_parse_object *arg;
- struct acpi_namespace_node *new_node;
+ union acpi_parse_object *op;
+ acpi_status status = AE_OK;
+ acpi_object_type object_type;
+ struct acpi_namespace_node *node;
+ union acpi_parse_object *arg;
+ struct acpi_namespace_node *new_node;
#ifndef ACPI_NO_METHOD_EXECUTION
- u32 i;
+ u32 i;
#endif
-
- ACPI_FUNCTION_TRACE ("ds_load2_end_op");
+ ACPI_FUNCTION_TRACE("ds_load2_end_op");
op = walk_state->op;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
- walk_state->op_info->name, op, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
+ walk_state->op_info->name, op, walk_state));
- /* Only interested in opcodes that have namespace objects */
+ /* Check if opcode had an associated namespace object */
if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
- return_ACPI_STATUS (AE_OK);
+#ifndef ACPI_NO_METHOD_EXECUTION
+#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
+ /* No namespace object. Executable opcode? */
+
+ if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
+ (walk_state->op_info->class == AML_CLASS_CONTROL)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "End/EXEC: %s (fl %8.8X)\n",
+ walk_state->op_info->name,
+ walk_state->op_info->flags));
+
+ /* Executing a type1 or type2 opcode outside of a method */
+
+ status = acpi_ds_exec_end_op(walk_state);
+ return_ACPI_STATUS(status);
+ }
+#endif
+#endif
+ return_ACPI_STATUS(AE_OK);
}
if (op->common.aml_opcode == AML_SCOPE_OP) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Ending scope Op=%p State=%p\n", op, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Ending scope Op=%p State=%p\n", op,
+ walk_state));
}
-
object_type = walk_state->op_info->object_type;
/*
@@ -749,18 +772,19 @@ acpi_ds_load2_end_op (
* Put the Node on the object stack (Contains the ACPI Name of
* this object)
*/
- walk_state->operands[0] = (void *) node;
+ walk_state->operands[0] = (void *)node;
walk_state->num_operands = 1;
/* Pop the scope stack */
- if (acpi_ns_opens_scope (object_type) &&
- (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
- acpi_ut_get_type_name (object_type), op));
+ if (acpi_ns_opens_scope(object_type) &&
+ (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "(%s) Popping scope for Op %p\n",
+ acpi_ut_get_type_name(object_type), op));
- status = acpi_ds_scope_stack_pop (walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_scope_stack_pop(walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
}
@@ -793,9 +817,10 @@ acpi_ds_load2_end_op (
* AML_THERMALZONE
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Create-Load [%s] State=%p Op=%p named_obj=%p\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode), walk_state, op, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "Create-Load [%s] State=%p Op=%p named_obj=%p\n",
+ acpi_ps_get_opcode_name(op->common.aml_opcode),
+ walk_state, op, node));
/* Decode the opcode */
@@ -810,27 +835,32 @@ acpi_ds_load2_end_op (
* Create the field object, but the field buffer and index must
* be evaluated later during the execution phase
*/
- status = acpi_ds_create_buffer_field (op, walk_state);
+ status = acpi_ds_create_buffer_field(op, walk_state);
break;
-
- case AML_TYPE_NAMED_FIELD:
+ case AML_TYPE_NAMED_FIELD:
switch (op->common.aml_opcode) {
case AML_INDEX_FIELD_OP:
- status = acpi_ds_create_index_field (op, (acpi_handle) arg->common.node,
- walk_state);
+ status =
+ acpi_ds_create_index_field(op,
+ (acpi_handle) arg->
+ common.node, walk_state);
break;
case AML_BANK_FIELD_OP:
- status = acpi_ds_create_bank_field (op, arg->common.node, walk_state);
+ status =
+ acpi_ds_create_bank_field(op, arg->common.node,
+ walk_state);
break;
case AML_FIELD_OP:
- status = acpi_ds_create_field (op, arg->common.node, walk_state);
+ status =
+ acpi_ds_create_field(op, arg->common.node,
+ walk_state);
break;
default:
@@ -839,43 +869,42 @@ acpi_ds_load2_end_op (
}
break;
+ case AML_TYPE_NAMED_SIMPLE:
- case AML_TYPE_NAMED_SIMPLE:
-
- status = acpi_ds_create_operands (walk_state, arg);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ds_create_operands(walk_state, arg);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
switch (op->common.aml_opcode) {
case AML_PROCESSOR_OP:
- status = acpi_ex_create_processor (walk_state);
+ status = acpi_ex_create_processor(walk_state);
break;
case AML_POWER_RES_OP:
- status = acpi_ex_create_power_resource (walk_state);
+ status = acpi_ex_create_power_resource(walk_state);
break;
case AML_MUTEX_OP:
- status = acpi_ex_create_mutex (walk_state);
+ status = acpi_ex_create_mutex(walk_state);
break;
case AML_EVENT_OP:
- status = acpi_ex_create_event (walk_state);
+ status = acpi_ex_create_event(walk_state);
break;
case AML_DATA_REGION_OP:
- status = acpi_ex_create_table_region (walk_state);
+ status = acpi_ex_create_table_region(walk_state);
break;
case AML_ALIAS_OP:
- status = acpi_ex_create_alias (walk_state);
+ status = acpi_ex_create_alias(walk_state);
break;
default:
@@ -888,12 +917,12 @@ acpi_ds_load2_end_op (
/* Delete operands */
for (i = 1; i < walk_state->num_operands; i++) {
- acpi_ut_remove_reference (walk_state->operands[i]);
+ acpi_ut_remove_reference(walk_state->operands[i]);
walk_state->operands[i] = NULL;
}
break;
-#endif /* ACPI_NO_METHOD_EXECUTION */
+#endif /* ACPI_NO_METHOD_EXECUTION */
case AML_TYPE_NAMED_COMPLEX:
@@ -909,9 +938,10 @@ acpi_ds_load2_end_op (
* If we have a valid region, initialize it
* Namespace is NOT locked at this point.
*/
- status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node),
- FALSE);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ev_initialize_region
+ (acpi_ns_get_attached_object(node), FALSE);
+ if (ACPI_FAILURE(status)) {
/*
* If AE_NOT_EXIST is returned, it is not fatal
* because many regions get created before a handler
@@ -923,13 +953,11 @@ acpi_ds_load2_end_op (
}
break;
-
case AML_NAME_OP:
- status = acpi_ds_create_node (walk_state, node, op);
+ status = acpi_ds_create_node(walk_state, node, op);
break;
-#endif /* ACPI_NO_METHOD_EXECUTION */
-
+#endif /* ACPI_NO_METHOD_EXECUTION */
default:
/* All NAMED_COMPLEX opcodes must be handled above */
@@ -938,27 +966,29 @@ acpi_ds_load2_end_op (
}
break;
-
case AML_CLASS_INTERNAL:
/* case AML_INT_NAMEPATH_OP: */
break;
-
case AML_CLASS_METHOD_CALL:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "RESOLVING-method_call: State=%p Op=%p named_obj=%p\n",
- walk_state, op, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "RESOLVING-method_call: State=%p Op=%p named_obj=%p\n",
+ walk_state, op, node));
/*
* Lookup the method name and save the Node
*/
- status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
- ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
- walk_state, &(new_node));
- if (ACPI_SUCCESS (status)) {
+ status =
+ acpi_ns_lookup(walk_state->scope_info,
+ arg->common.value.string, ACPI_TYPE_ANY,
+ ACPI_IMODE_LOAD_PASS2,
+ ACPI_NS_SEARCH_PARENT |
+ ACPI_NS_DONT_OPEN_SCOPE, walk_state,
+ &(new_node));
+ if (ACPI_SUCCESS(status)) {
+
/*
* Make sure that what we found is indeed a method
* We didn't search for a method on purpose, to see if the name
@@ -973,24 +1003,20 @@ acpi_ds_load2_end_op (
* parser uses, so we can get it again at the end of this scope
*/
op->common.node = new_node;
- }
- else {
- ACPI_REPORT_NSERROR (arg->common.value.string, status);
+ } else {
+ ACPI_REPORT_NSERROR(arg->common.value.string, status);
}
break;
-
default:
break;
}
-cleanup:
+ cleanup:
/* Remove the Node pushed at the very beginning */
walk_state->operands[0] = NULL;
walk_state->num_operands = 0;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
index 21f4548ff323..defe956ef751 100644
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -41,14 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
-
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dswscope")
-
+ACPI_MODULE_NAME("dswscope")
/****************************************************************************
*
@@ -62,15 +59,11 @@
* root scope object (which remains at the stack top.)
*
***************************************************************************/
-
-void
-acpi_ds_scope_stack_clear (
- struct acpi_walk_state *walk_state)
+void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state)
{
- union acpi_generic_state *scope_info;
-
- ACPI_FUNCTION_NAME ("ds_scope_stack_clear");
+ union acpi_generic_state *scope_info;
+ ACPI_FUNCTION_NAME("ds_scope_stack_clear");
while (walk_state->scope_info) {
/* Pop a scope off the stack */
@@ -78,14 +71,14 @@ acpi_ds_scope_stack_clear (
scope_info = walk_state->scope_info;
walk_state->scope_info = scope_info->scope.next;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Popped object type (%s)\n",
- acpi_ut_get_type_name (scope_info->common.value)));
- acpi_ut_delete_generic_state (scope_info);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Popped object type (%s)\n",
+ acpi_ut_get_type_name(scope_info->common.
+ value)));
+ acpi_ut_delete_generic_state(scope_info);
}
}
-
/****************************************************************************
*
* FUNCTION: acpi_ds_scope_stack_push
@@ -102,74 +95,70 @@ acpi_ds_scope_stack_clear (
***************************************************************************/
acpi_status
-acpi_ds_scope_stack_push (
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_walk_state *walk_state)
+acpi_ds_scope_stack_push(struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_walk_state *walk_state)
{
- union acpi_generic_state *scope_info;
- union acpi_generic_state *old_scope_info;
-
-
- ACPI_FUNCTION_TRACE ("ds_scope_stack_push");
+ union acpi_generic_state *scope_info;
+ union acpi_generic_state *old_scope_info;
+ ACPI_FUNCTION_TRACE("ds_scope_stack_push");
if (!node) {
/* Invalid scope */
- ACPI_REPORT_ERROR (("ds_scope_stack_push: null scope passed\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("ds_scope_stack_push: null scope passed\n"));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Make sure object type is valid */
- if (!acpi_ut_valid_object_type (type)) {
- ACPI_REPORT_WARNING ((
- "ds_scope_stack_push: Invalid object type: 0x%X\n", type));
+ if (!acpi_ut_valid_object_type(type)) {
+ ACPI_REPORT_WARNING(("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
}
/* Allocate a new scope object */
- scope_info = acpi_ut_create_generic_state ();
+ scope_info = acpi_ut_create_generic_state();
if (!scope_info) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Init new scope object */
scope_info->common.data_type = ACPI_DESC_TYPE_STATE_WSCOPE;
- scope_info->scope.node = node;
- scope_info->common.value = (u16) type;
+ scope_info->scope.node = node;
+ scope_info->common.value = (u16) type;
walk_state->scope_depth++;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[%.2d] Pushed scope ", (u32) walk_state->scope_depth));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[%.2d] Pushed scope ",
+ (u32) walk_state->scope_depth));
old_scope_info = walk_state->scope_info;
if (old_scope_info) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
- "[%4.4s] (%s)",
- acpi_ut_get_node_name (old_scope_info->scope.node),
- acpi_ut_get_type_name (old_scope_info->common.value)));
- }
- else {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
- "[\\___] (%s)", "ROOT"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
+ "[%4.4s] (%s)",
+ acpi_ut_get_node_name(old_scope_info->
+ scope.node),
+ acpi_ut_get_type_name(old_scope_info->
+ common.value)));
+ } else {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (%s)", "ROOT"));
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
- ", New scope -> [%4.4s] (%s)\n",
- acpi_ut_get_node_name (scope_info->scope.node),
- acpi_ut_get_type_name (scope_info->common.value)));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
+ ", New scope -> [%4.4s] (%s)\n",
+ acpi_ut_get_node_name(scope_info->scope.node),
+ acpi_ut_get_type_name(scope_info->common.value)));
/* Push new scope object onto stack */
- acpi_ut_push_generic_state (&walk_state->scope_info, scope_info);
- return_ACPI_STATUS (AE_OK);
+ acpi_ut_push_generic_state(&walk_state->scope_info, scope_info);
+ return_ACPI_STATUS(AE_OK);
}
-
/****************************************************************************
*
* FUNCTION: acpi_ds_scope_stack_pop
@@ -182,47 +171,41 @@ acpi_ds_scope_stack_push (
*
***************************************************************************/
-acpi_status
-acpi_ds_scope_stack_pop (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state)
{
- union acpi_generic_state *scope_info;
- union acpi_generic_state *new_scope_info;
-
-
- ACPI_FUNCTION_TRACE ("ds_scope_stack_pop");
+ union acpi_generic_state *scope_info;
+ union acpi_generic_state *new_scope_info;
+ ACPI_FUNCTION_TRACE("ds_scope_stack_pop");
/*
* Pop scope info object off the stack.
*/
- scope_info = acpi_ut_pop_generic_state (&walk_state->scope_info);
+ scope_info = acpi_ut_pop_generic_state(&walk_state->scope_info);
if (!scope_info) {
- return_ACPI_STATUS (AE_STACK_UNDERFLOW);
+ return_ACPI_STATUS(AE_STACK_UNDERFLOW);
}
walk_state->scope_depth--;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
- (u32) walk_state->scope_depth,
- acpi_ut_get_node_name (scope_info->scope.node),
- acpi_ut_get_type_name (scope_info->common.value)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
+ (u32) walk_state->scope_depth,
+ acpi_ut_get_node_name(scope_info->scope.node),
+ acpi_ut_get_type_name(scope_info->common.value)));
new_scope_info = walk_state->scope_info;
if (new_scope_info) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
- "[%4.4s] (%s)\n",
- acpi_ut_get_node_name (new_scope_info->scope.node),
- acpi_ut_get_type_name (new_scope_info->common.value)));
- }
- else {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
- "[\\___] (ROOT)\n"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
+ "[%4.4s] (%s)\n",
+ acpi_ut_get_node_name(new_scope_info->
+ scope.node),
+ acpi_ut_get_type_name(new_scope_info->
+ common.value)));
+ } else {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (ROOT)\n"));
}
- acpi_ut_delete_generic_state (scope_info);
- return_ACPI_STATUS (AE_OK);
+ acpi_ut_delete_generic_state(scope_info);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 9cd3db652b31..7d68a5aaf3c4 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -41,37 +41,28 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/acdispat.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dswstate")
+ACPI_MODULE_NAME("dswstate")
/* Local prototypes */
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
acpi_status
-acpi_ds_result_insert (
- void *object,
- u32 index,
- struct acpi_walk_state *walk_state);
+acpi_ds_result_insert(void *object,
+ u32 index, struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ds_obj_stack_delete_all (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_obj_stack_pop_object (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state);
-
-void *
-acpi_ds_obj_stack_get_value (
- u32 index,
- struct acpi_walk_state *walk_state);
+acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
+ struct acpi_walk_state *walk_state);
+
+void *acpi_ds_obj_stack_get_value(u32 index,
+ struct acpi_walk_state *walk_state);
#endif
#ifdef ACPI_FUTURE_USAGE
@@ -92,36 +83,35 @@ acpi_ds_obj_stack_get_value (
******************************************************************************/
acpi_status
-acpi_ds_result_remove (
- union acpi_operand_object **object,
- u32 index,
- struct acpi_walk_state *walk_state)
+acpi_ds_result_remove(union acpi_operand_object **object,
+ u32 index, struct acpi_walk_state *walk_state)
{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_NAME ("ds_result_remove");
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_remove");
state = walk_state->results;
if (!state) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No result object pushed! State=%p\n",
+ walk_state));
return (AE_NOT_EXIST);
}
if (index >= ACPI_OBJ_MAX_OPERAND) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index out of range: %X State=%p Num=%X\n",
- index, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Index out of range: %X State=%p Num=%X\n",
+ index, walk_state,
+ state->results.num_results));
}
/* Check for a valid result object */
- if (!state->results.obj_desc [index]) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null operand! State=%p #Ops=%X, Index=%X\n",
- walk_state, state->results.num_results, index));
+ if (!state->results.obj_desc[index]) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null operand! State=%p #Ops=%X, Index=%X\n",
+ walk_state, state->results.num_results,
+ index));
return (AE_AML_NO_RETURN_VALUE);
}
@@ -129,18 +119,20 @@ acpi_ds_result_remove (
state->results.num_results--;
- *object = state->results.obj_desc [index];
- state->results.obj_desc [index] = NULL;
+ *object = state->results.obj_desc[index];
+ state->results.obj_desc[index] = NULL;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Obj=%p [%s] Index=%X State=%p Num=%X\n",
- *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
- index, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Obj=%p [%s] Index=%X State=%p Num=%X\n",
+ *object,
+ (*object) ? acpi_ut_get_object_type_name(*object) :
+ "NULL", index, walk_state,
+ state->results.num_results));
return (AE_OK);
}
-#endif /* ACPI_FUTURE_USAGE */
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -157,16 +149,13 @@ acpi_ds_result_remove (
******************************************************************************/
acpi_status
-acpi_ds_result_pop (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state)
+acpi_ds_result_pop(union acpi_operand_object ** object,
+ struct acpi_walk_state * walk_state)
{
- acpi_native_uint index;
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_NAME ("ds_result_pop");
+ acpi_native_uint index;
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_pop");
state = walk_state->results;
if (!state) {
@@ -174,8 +163,9 @@ acpi_ds_result_pop (
}
if (!state->results.num_results) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%p\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Result stack is empty! State=%p\n",
+ walk_state));
return (AE_AML_NO_RETURN_VALUE);
}
@@ -186,26 +176,27 @@ acpi_ds_result_pop (
for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
/* Check for a valid result object */
- if (state->results.obj_desc [index -1]) {
- *object = state->results.obj_desc [index -1];
- state->results.obj_desc [index -1] = NULL;
+ if (state->results.obj_desc[index - 1]) {
+ *object = state->results.obj_desc[index - 1];
+ state->results.obj_desc[index - 1] = NULL;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Obj=%p [%s] Index=%X State=%p Num=%X\n",
- *object,
- (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
- (u32) index -1, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Obj=%p [%s] Index=%X State=%p Num=%X\n",
+ *object,
+ (*object) ?
+ acpi_ut_get_object_type_name(*object)
+ : "NULL", (u32) index - 1, walk_state,
+ state->results.num_results));
return (AE_OK);
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "No result objects! State=%p\n", walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No result objects! State=%p\n", walk_state));
return (AE_AML_NO_RETURN_VALUE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_result_pop_from_bottom
@@ -221,38 +212,37 @@ acpi_ds_result_pop (
******************************************************************************/
acpi_status
-acpi_ds_result_pop_from_bottom (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state)
+acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object,
+ struct acpi_walk_state * walk_state)
{
- acpi_native_uint index;
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_NAME ("ds_result_pop_from_bottom");
+ acpi_native_uint index;
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_pop_from_bottom");
state = walk_state->results;
if (!state) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Warning: No result object pushed! State=%p\n", walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Warning: No result object pushed! State=%p\n",
+ walk_state));
return (AE_NOT_EXIST);
}
if (!state->results.num_results) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No result objects! State=%p\n", walk_state));
return (AE_AML_NO_RETURN_VALUE);
}
/* Remove Bottom element */
- *object = state->results.obj_desc [0];
+ *object = state->results.obj_desc[0];
/* Push entire stack down one element */
for (index = 0; index < state->results.num_results; index++) {
- state->results.obj_desc [index] = state->results.obj_desc [index + 1];
+ state->results.obj_desc[index] =
+ state->results.obj_desc[index + 1];
}
state->results.num_results--;
@@ -260,20 +250,21 @@ acpi_ds_result_pop_from_bottom (
/* Check for a valid result object */
if (!*object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null operand! State=%p #Ops=%X, Index=%X\n",
- walk_state, state->results.num_results, (u32) index));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null operand! State=%p #Ops=%X Index=%X\n",
+ walk_state, state->results.num_results,
+ (u32) index));
return (AE_AML_NO_RETURN_VALUE);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
- *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
- state, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n",
+ *object,
+ (*object) ? acpi_ut_get_object_type_name(*object) :
+ "NULL", state, walk_state));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_result_push
@@ -288,47 +279,50 @@ acpi_ds_result_pop_from_bottom (
******************************************************************************/
acpi_status
-acpi_ds_result_push (
- union acpi_operand_object *object,
- struct acpi_walk_state *walk_state)
+acpi_ds_result_push(union acpi_operand_object * object,
+ struct acpi_walk_state * walk_state)
{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_NAME ("ds_result_push");
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_push");
state = walk_state->results;
if (!state) {
- ACPI_REPORT_ERROR (("No result stack frame during push\n"));
+ ACPI_REPORT_ERROR(("No result stack frame during push\n"));
return (AE_AML_INTERNAL);
}
if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Result stack overflow: Obj=%p State=%p Num=%X\n",
- object, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Result stack overflow: Obj=%p State=%p Num=%X\n",
+ object, walk_state,
+ state->results.num_results));
return (AE_STACK_OVERFLOW);
}
if (!object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null Object! Obj=%p State=%p Num=%X\n",
- object, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null Object! Obj=%p State=%p Num=%X\n",
+ object, walk_state,
+ state->results.num_results));
return (AE_BAD_PARAMETER);
}
- state->results.obj_desc [state->results.num_results] = object;
+ state->results.obj_desc[state->results.num_results] = object;
state->results.num_results++;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
- object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
- walk_state, state->results.num_results, walk_state->current_result));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+ object,
+ object ?
+ acpi_ut_get_object_type_name((union
+ acpi_operand_object *)
+ object) : "NULL",
+ walk_state, state->results.num_results,
+ walk_state->current_result));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_result_stack_push
@@ -341,30 +335,26 @@ acpi_ds_result_push (
*
******************************************************************************/
-acpi_status
-acpi_ds_result_stack_push (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
{
- union acpi_generic_state *state;
-
- ACPI_FUNCTION_NAME ("ds_result_stack_push");
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_stack_push");
- state = acpi_ut_create_generic_state ();
+ state = acpi_ut_create_generic_state();
if (!state) {
return (AE_NO_MEMORY);
}
state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT;
- acpi_ut_push_generic_state (&walk_state->results, state);
+ acpi_ut_push_generic_state(&walk_state->results, state);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
- state, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
+ state, walk_state));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_result_stack_pop
@@ -377,35 +367,31 @@ acpi_ds_result_stack_push (
*
******************************************************************************/
-acpi_status
-acpi_ds_result_stack_pop (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state)
{
- union acpi_generic_state *state;
-
- ACPI_FUNCTION_NAME ("ds_result_stack_pop");
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_stack_pop");
/* Check for stack underflow */
if (walk_state->results == NULL) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n",
+ walk_state));
return (AE_AML_NO_OPERAND);
}
- state = acpi_ut_pop_generic_state (&walk_state->results);
+ state = acpi_ut_pop_generic_state(&walk_state->results);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Result=%p remaining_results=%X State=%p\n",
- state, state->results.num_results, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Result=%p remaining_results=%X State=%p\n",
+ state, state->results.num_results, walk_state));
- acpi_ut_delete_generic_state (state);
+ acpi_ut_delete_generic_state(state);
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_push
@@ -420,35 +406,35 @@ acpi_ds_result_stack_pop (
******************************************************************************/
acpi_status
-acpi_ds_obj_stack_push (
- void *object,
- struct acpi_walk_state *walk_state)
+acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
{
- ACPI_FUNCTION_NAME ("ds_obj_stack_push");
-
+ ACPI_FUNCTION_NAME("ds_obj_stack_push");
/* Check for stack overflow */
if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "overflow! Obj=%p State=%p #Ops=%X\n",
- object, walk_state, walk_state->num_operands));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "overflow! Obj=%p State=%p #Ops=%X\n",
+ object, walk_state,
+ walk_state->num_operands));
return (AE_STACK_OVERFLOW);
}
/* Put the object onto the stack */
- walk_state->operands [walk_state->num_operands] = object;
+ walk_state->operands[walk_state->num_operands] = object;
walk_state->num_operands++;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
- object, acpi_ut_get_object_type_name ((union acpi_operand_object *) object),
- walk_state, walk_state->num_operands));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+ object,
+ acpi_ut_get_object_type_name((union
+ acpi_operand_object *)
+ object), walk_state,
+ walk_state->num_operands));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_pop
@@ -464,38 +450,35 @@ acpi_ds_obj_stack_push (
******************************************************************************/
acpi_status
-acpi_ds_obj_stack_pop (
- u32 pop_count,
- struct acpi_walk_state *walk_state)
+acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state)
{
- u32 i;
-
- ACPI_FUNCTION_NAME ("ds_obj_stack_pop");
+ u32 i;
+ ACPI_FUNCTION_NAME("ds_obj_stack_pop");
for (i = 0; i < pop_count; i++) {
/* Check for stack underflow */
if (walk_state->num_operands == 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Underflow! Count=%X State=%p #Ops=%X\n",
- pop_count, walk_state, walk_state->num_operands));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Underflow! Count=%X State=%p #Ops=%X\n",
+ pop_count, walk_state,
+ walk_state->num_operands));
return (AE_STACK_UNDERFLOW);
}
/* Just set the stack entry to null */
walk_state->num_operands--;
- walk_state->operands [walk_state->num_operands] = NULL;
+ walk_state->operands[walk_state->num_operands] = NULL;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
pop_count, walk_state, walk_state->num_operands));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_pop_and_delete
@@ -511,44 +494,43 @@ acpi_ds_obj_stack_pop (
******************************************************************************/
acpi_status
-acpi_ds_obj_stack_pop_and_delete (
- u32 pop_count,
- struct acpi_walk_state *walk_state)
+acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
+ struct acpi_walk_state * walk_state)
{
- u32 i;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete");
+ u32 i;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_NAME("ds_obj_stack_pop_and_delete");
for (i = 0; i < pop_count; i++) {
/* Check for stack underflow */
if (walk_state->num_operands == 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Underflow! Count=%X State=%p #Ops=%X\n",
- pop_count, walk_state, walk_state->num_operands));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Underflow! Count=%X State=%p #Ops=%X\n",
+ pop_count, walk_state,
+ walk_state->num_operands));
return (AE_STACK_UNDERFLOW);
}
/* Pop the stack and delete an object if present in this stack entry */
walk_state->num_operands--;
- obj_desc = walk_state->operands [walk_state->num_operands];
+ obj_desc = walk_state->operands[walk_state->num_operands];
if (obj_desc) {
- acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
- walk_state->operands [walk_state->num_operands] = NULL;
+ acpi_ut_remove_reference(walk_state->
+ operands[walk_state->
+ num_operands]);
+ walk_state->operands[walk_state->num_operands] = NULL;
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
pop_count, walk_state, walk_state->num_operands));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_get_current_walk_state
@@ -562,25 +544,21 @@ acpi_ds_obj_stack_pop_and_delete (
*
******************************************************************************/
-struct acpi_walk_state *
-acpi_ds_get_current_walk_state (
- struct acpi_thread_state *thread)
-
+struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
+ *thread)
{
- ACPI_FUNCTION_NAME ("ds_get_current_walk_state");
-
+ ACPI_FUNCTION_NAME("ds_get_current_walk_state");
if (!thread) {
return (NULL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current walk_state %p\n",
- thread->walk_state_list));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current walk_state %p\n",
+ thread->walk_state_list));
return (thread->walk_state_list);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_push_walk_state
@@ -595,20 +573,17 @@ acpi_ds_get_current_walk_state (
******************************************************************************/
void
-acpi_ds_push_walk_state (
- struct acpi_walk_state *walk_state,
- struct acpi_thread_state *thread)
+acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
+ struct acpi_thread_state *thread)
{
- ACPI_FUNCTION_TRACE ("ds_push_walk_state");
-
+ ACPI_FUNCTION_TRACE("ds_push_walk_state");
- walk_state->next = thread->walk_state_list;
+ walk_state->next = thread->walk_state_list;
thread->walk_state_list = walk_state;
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_pop_walk_state
@@ -623,15 +598,11 @@ acpi_ds_push_walk_state (
*
******************************************************************************/
-struct acpi_walk_state *
-acpi_ds_pop_walk_state (
- struct acpi_thread_state *thread)
+struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
{
- struct acpi_walk_state *walk_state;
-
-
- ACPI_FUNCTION_TRACE ("ds_pop_walk_state");
+ struct acpi_walk_state *walk_state;
+ ACPI_FUNCTION_TRACE("ds_pop_walk_state");
walk_state = thread->walk_state_list;
@@ -647,10 +618,9 @@ acpi_ds_pop_walk_state (
*/
}
- return_PTR (walk_state);
+ return_PTR(walk_state);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_walk_state
@@ -667,57 +637,55 @@ acpi_ds_pop_walk_state (
*
******************************************************************************/
-struct acpi_walk_state *
-acpi_ds_create_walk_state (
- acpi_owner_id owner_id,
- union acpi_parse_object *origin,
- union acpi_operand_object *mth_desc,
- struct acpi_thread_state *thread)
+struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id,
+ union acpi_parse_object
+ *origin,
+ union acpi_operand_object
+ *mth_desc,
+ struct acpi_thread_state
+ *thread)
{
- struct acpi_walk_state *walk_state;
- acpi_status status;
-
+ struct acpi_walk_state *walk_state;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("ds_create_walk_state");
+ ACPI_FUNCTION_TRACE("ds_create_walk_state");
-
- walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK);
+ walk_state = ACPI_MEM_CALLOCATE(sizeof(struct acpi_walk_state));
if (!walk_state) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
- walk_state->data_type = ACPI_DESC_TYPE_WALK;
- walk_state->owner_id = owner_id;
- walk_state->origin = origin;
- walk_state->method_desc = mth_desc;
- walk_state->thread = thread;
+ walk_state->data_type = ACPI_DESC_TYPE_WALK;
+ walk_state->owner_id = owner_id;
+ walk_state->origin = origin;
+ walk_state->method_desc = mth_desc;
+ walk_state->thread = thread;
walk_state->parser_state.start_op = origin;
/* Init the method args/local */
#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
- acpi_ds_method_data_init (walk_state);
+ acpi_ds_method_data_init(walk_state);
#endif
/* Create an initial result stack entry */
- status = acpi_ds_result_stack_push (walk_state);
- if (ACPI_FAILURE (status)) {
- acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
- return_PTR (NULL);
+ status = acpi_ds_result_stack_push(walk_state);
+ if (ACPI_FAILURE(status)) {
+ ACPI_MEM_FREE(walk_state);
+ return_PTR(NULL);
}
/* Put the new state at the head of the walk list */
if (thread) {
- acpi_ds_push_walk_state (walk_state, thread);
+ acpi_ds_push_walk_state(walk_state, thread);
}
- return_PTR (walk_state);
+ return_PTR(walk_state);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_init_aml_walk
@@ -737,70 +705,70 @@ acpi_ds_create_walk_state (
******************************************************************************/
acpi_status
-acpi_ds_init_aml_walk (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- struct acpi_namespace_node *method_node,
- u8 *aml_start,
- u32 aml_length,
- struct acpi_parameter_info *info,
- u32 pass_number)
+acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ struct acpi_namespace_node *method_node,
+ u8 * aml_start,
+ u32 aml_length,
+ struct acpi_parameter_info *info, u8 pass_number)
{
- acpi_status status;
- struct acpi_parse_state *parser_state = &walk_state->parser_state;
- union acpi_parse_object *extra_op;
+ acpi_status status;
+ struct acpi_parse_state *parser_state = &walk_state->parser_state;
+ union acpi_parse_object *extra_op;
+ ACPI_FUNCTION_TRACE("ds_init_aml_walk");
- ACPI_FUNCTION_TRACE ("ds_init_aml_walk");
-
-
- walk_state->parser_state.aml =
- walk_state->parser_state.aml_start = aml_start;
+ walk_state->parser_state.aml =
+ walk_state->parser_state.aml_start = aml_start;
walk_state->parser_state.aml_end =
- walk_state->parser_state.pkg_end = aml_start + aml_length;
+ walk_state->parser_state.pkg_end = aml_start + aml_length;
/* The next_op of the next_walk will be the beginning of the method */
walk_state->next_op = NULL;
+ walk_state->pass_number = pass_number;
if (info) {
if (info->parameter_type == ACPI_PARAM_GPE) {
- walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
- info->parameters);
- }
- else {
- walk_state->params = info->parameters;
+ walk_state->gpe_event_info =
+ ACPI_CAST_PTR(struct acpi_gpe_event_info,
+ info->parameters);
+ } else {
+ walk_state->params = info->parameters;
walk_state->caller_return_desc = &info->return_object;
}
}
- status = acpi_ps_init_scope (&walk_state->parser_state, op);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ps_init_scope(&walk_state->parser_state, op);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (method_node) {
walk_state->parser_state.start_node = method_node;
- walk_state->walk_type = ACPI_WALK_METHOD;
- walk_state->method_node = method_node;
- walk_state->method_desc = acpi_ns_get_attached_object (method_node);
+ walk_state->walk_type = ACPI_WALK_METHOD;
+ walk_state->method_node = method_node;
+ walk_state->method_desc =
+ acpi_ns_get_attached_object(method_node);
/* Push start scope on scope stack and make it current */
- status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Init the method arguments */
- status = acpi_ds_method_data_init_args (walk_state->params,
- ACPI_METHOD_NUM_ARGS, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_method_data_init_args(walk_state->params,
+ ACPI_METHOD_NUM_ARGS,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- }
- else {
+ } else {
/*
* Setup the current scope.
* Find a Named Op that has a namespace node associated with it.
@@ -814,27 +782,27 @@ acpi_ds_init_aml_walk (
if (!extra_op) {
parser_state->start_node = NULL;
- }
- else {
+ } else {
parser_state->start_node = extra_op->common.node;
}
if (parser_state->start_node) {
/* Push start scope on scope stack and make it current */
- status = acpi_ds_scope_stack_push (parser_state->start_node,
- parser_state->start_node->type, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ds_scope_stack_push(parser_state->start_node,
+ parser_state->start_node->
+ type, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
}
- status = acpi_ds_init_callbacks (walk_state, pass_number);
- return_ACPI_STATUS (status);
+ status = acpi_ds_init_callbacks(walk_state, pass_number);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_delete_walk_state
@@ -847,29 +815,27 @@ acpi_ds_init_aml_walk (
*
******************************************************************************/
-void
-acpi_ds_delete_walk_state (
- struct acpi_walk_state *walk_state)
+void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_delete_walk_state", walk_state);
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_TRACE_PTR("ds_delete_walk_state", walk_state);
if (!walk_state) {
return;
}
if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%p is not a valid walk state\n",
+ walk_state));
return;
}
if (walk_state->parser_state.scope) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%p walk still has a scope list\n",
+ walk_state));
}
/* Always must free any linked control states */
@@ -878,7 +844,7 @@ acpi_ds_delete_walk_state (
state = walk_state->control_state;
walk_state->control_state = state->common.next;
- acpi_ut_delete_generic_state (state);
+ acpi_ut_delete_generic_state(state);
}
/* Always must free any linked parse states */
@@ -887,7 +853,7 @@ acpi_ds_delete_walk_state (
state = walk_state->scope_info;
walk_state->scope_info = state->common.next;
- acpi_ut_delete_generic_state (state);
+ acpi_ut_delete_generic_state(state);
}
/* Always must free any stacked result states */
@@ -896,40 +862,12 @@ acpi_ds_delete_walk_state (
state = walk_state->results;
walk_state->results = state->common.next;
- acpi_ut_delete_generic_state (state);
+ acpi_ut_delete_generic_state(state);
}
- acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
- return_VOID;
-}
-
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-/******************************************************************************
- *
- * FUNCTION: acpi_ds_delete_walk_state_cache
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Purge the global state object cache. Used during subsystem
- * termination.
- *
- ******************************************************************************/
-
-void
-acpi_ds_delete_walk_state_cache (
- void)
-{
- ACPI_FUNCTION_TRACE ("ds_delete_walk_state_cache");
-
-
- acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
+ ACPI_MEM_FREE(walk_state);
return_VOID;
}
-#endif
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
@@ -947,50 +885,53 @@ acpi_ds_delete_walk_state_cache (
******************************************************************************/
acpi_status
-acpi_ds_result_insert (
- void *object,
- u32 index,
- struct acpi_walk_state *walk_state)
+acpi_ds_result_insert(void *object,
+ u32 index, struct acpi_walk_state *walk_state)
{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_NAME ("ds_result_insert");
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_NAME("ds_result_insert");
state = walk_state->results;
if (!state) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
- walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No result object pushed! State=%p\n",
+ walk_state));
return (AE_NOT_EXIST);
}
if (index >= ACPI_OBJ_NUM_OPERANDS) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index out of range: %X Obj=%p State=%p Num=%X\n",
- index, object, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Index out of range: %X Obj=%p State=%p Num=%X\n",
+ index, object, walk_state,
+ state->results.num_results));
return (AE_BAD_PARAMETER);
}
if (!object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
- index, object, walk_state, state->results.num_results));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
+ index, object, walk_state,
+ state->results.num_results));
return (AE_BAD_PARAMETER);
}
- state->results.obj_desc [index] = object;
+ state->results.obj_desc[index] = object;
state->results.num_results++;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
- object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
- walk_state, state->results.num_results, walk_state->current_result));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+ object,
+ object ?
+ acpi_ut_get_object_type_name((union
+ acpi_operand_object *)
+ object) : "NULL",
+ walk_state, state->results.num_results,
+ walk_state->current_result));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_delete_all
@@ -1004,29 +945,24 @@ acpi_ds_result_insert (
*
******************************************************************************/
-acpi_status
-acpi_ds_obj_stack_delete_all (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state)
{
- u32 i;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
+ u32 i;
+ ACPI_FUNCTION_TRACE_PTR("ds_obj_stack_delete_all", walk_state);
/* The stack size is configurable, but fixed */
for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
if (walk_state->operands[i]) {
- acpi_ut_remove_reference (walk_state->operands[i]);
+ acpi_ut_remove_reference(walk_state->operands[i]);
walk_state->operands[i] = NULL;
}
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_pop_object
@@ -1042,19 +978,17 @@ acpi_ds_obj_stack_delete_all (
******************************************************************************/
acpi_status
-acpi_ds_obj_stack_pop_object (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state)
+acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
+ struct acpi_walk_state *walk_state)
{
- ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
-
+ ACPI_FUNCTION_NAME("ds_obj_stack_pop_object");
/* Check for stack underflow */
if (walk_state->num_operands == 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Missing operand/stack empty! State=%p #Ops=%X\n",
- walk_state, walk_state->num_operands));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Missing operand/stack empty! State=%p #Ops=%X\n",
+ walk_state, walk_state->num_operands));
*object = NULL;
return (AE_AML_NO_OPERAND);
}
@@ -1065,27 +999,26 @@ acpi_ds_obj_stack_pop_object (
/* Check for a valid operand */
- if (!walk_state->operands [walk_state->num_operands]) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null operand! State=%p #Ops=%X\n",
- walk_state, walk_state->num_operands));
+ if (!walk_state->operands[walk_state->num_operands]) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null operand! State=%p #Ops=%X\n",
+ walk_state, walk_state->num_operands));
*object = NULL;
return (AE_AML_NO_OPERAND);
}
/* Get operand and set stack entry to null */
- *object = walk_state->operands [walk_state->num_operands];
- walk_state->operands [walk_state->num_operands] = NULL;
+ *object = walk_state->operands[walk_state->num_operands];
+ walk_state->operands[walk_state->num_operands] = NULL;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
- *object, acpi_ut_get_object_type_name (*object),
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+ *object, acpi_ut_get_object_type_name(*object),
walk_state, walk_state->num_operands));
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_get_value
@@ -1101,30 +1034,25 @@ acpi_ds_obj_stack_pop_object (
*
******************************************************************************/
-void *
-acpi_ds_obj_stack_get_value (
- u32 index,
- struct acpi_walk_state *walk_state)
+void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state)
{
- ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
-
+ ACPI_FUNCTION_TRACE_PTR("ds_obj_stack_get_value", walk_state);
/* Can't do it if the stack is empty */
if (walk_state->num_operands == 0) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
/* or if the index is past the top of the stack */
if (index > (walk_state->num_operands - (u32) 1)) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
- return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
- index]);
+ return_PTR(walk_state->
+ operands[(acpi_native_uint) (walk_state->num_operands - 1) -
+ index]);
}
#endif
-
-
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 1ac5731d45e5..7e1a445955bc 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -38,130 +38,112 @@
#include <acpi/actypes.h>
#define _COMPONENT ACPI_EC_COMPONENT
-ACPI_MODULE_NAME ("acpi_ec")
-
+ACPI_MODULE_NAME("acpi_ec")
#define ACPI_EC_COMPONENT 0x00100000
#define ACPI_EC_CLASS "embedded_controller"
#define ACPI_EC_HID "PNP0C09"
#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
-
-
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
-
#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */
#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */
-
#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
-
-#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
-
+#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
+#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
#define ACPI_EC_COMMAND_READ 0x80
#define ACPI_EC_COMMAND_WRITE 0x81
#define ACPI_EC_BURST_ENABLE 0x82
#define ACPI_EC_BURST_DISABLE 0x83
#define ACPI_EC_COMMAND_QUERY 0x84
-
#define EC_POLLING 0xFF
#define EC_BURST 0x00
-
-
-static int acpi_ec_remove (struct acpi_device *device, int type);
-static int acpi_ec_start (struct acpi_device *device);
-static int acpi_ec_stop (struct acpi_device *device, int type);
-static int acpi_ec_burst_add ( struct acpi_device *device);
-static int acpi_ec_polling_add ( struct acpi_device *device);
+static int acpi_ec_remove(struct acpi_device *device, int type);
+static int acpi_ec_start(struct acpi_device *device);
+static int acpi_ec_stop(struct acpi_device *device, int type);
+static int acpi_ec_burst_add(struct acpi_device *device);
+static int acpi_ec_polling_add(struct acpi_device *device);
static struct acpi_driver acpi_ec_driver = {
- .name = ACPI_EC_DRIVER_NAME,
- .class = ACPI_EC_CLASS,
- .ids = ACPI_EC_HID,
- .ops = {
- .add = acpi_ec_polling_add,
- .remove = acpi_ec_remove,
- .start = acpi_ec_start,
- .stop = acpi_ec_stop,
- },
+ .name = ACPI_EC_DRIVER_NAME,
+ .class = ACPI_EC_CLASS,
+ .ids = ACPI_EC_HID,
+ .ops = {
+ .add = acpi_ec_polling_add,
+ .remove = acpi_ec_remove,
+ .start = acpi_ec_start,
+ .stop = acpi_ec_stop,
+ },
};
union acpi_ec {
struct {
- u32 mode;
- acpi_handle handle;
- unsigned long uid;
- unsigned long gpe_bit;
- struct acpi_generic_address status_addr;
- struct acpi_generic_address command_addr;
- struct acpi_generic_address data_addr;
- unsigned long global_lock;
+ u32 mode;
+ acpi_handle handle;
+ unsigned long uid;
+ unsigned long gpe_bit;
+ struct acpi_generic_address status_addr;
+ struct acpi_generic_address command_addr;
+ struct acpi_generic_address data_addr;
+ unsigned long global_lock;
} common;
struct {
- u32 mode;
- acpi_handle handle;
- unsigned long uid;
- unsigned long gpe_bit;
- struct acpi_generic_address status_addr;
- struct acpi_generic_address command_addr;
- struct acpi_generic_address data_addr;
- unsigned long global_lock;
- unsigned int expect_event;
- atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
- atomic_t pending_gpe;
- struct semaphore sem;
- wait_queue_head_t wait;
- }burst;
+ u32 mode;
+ acpi_handle handle;
+ unsigned long uid;
+ unsigned long gpe_bit;
+ struct acpi_generic_address status_addr;
+ struct acpi_generic_address command_addr;
+ struct acpi_generic_address data_addr;
+ unsigned long global_lock;
+ unsigned int expect_event;
+ atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
+ atomic_t pending_gpe;
+ struct semaphore sem;
+ wait_queue_head_t wait;
+ } burst;
struct {
- u32 mode;
- acpi_handle handle;
- unsigned long uid;
- unsigned long gpe_bit;
- struct acpi_generic_address status_addr;
- struct acpi_generic_address command_addr;
- struct acpi_generic_address data_addr;
- unsigned long global_lock;
- spinlock_t lock;
- }polling;
+ u32 mode;
+ acpi_handle handle;
+ unsigned long uid;
+ unsigned long gpe_bit;
+ struct acpi_generic_address status_addr;
+ struct acpi_generic_address command_addr;
+ struct acpi_generic_address data_addr;
+ unsigned long global_lock;
+ spinlock_t lock;
+ } polling;
};
-static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event);
+static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event);
static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event);
-static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data);
-static int acpi_ec_burst_read( union acpi_ec *ec, u8 address, u32 *data);
-static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data);
-static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data);
-static void acpi_ec_gpe_polling_query ( void *ec_cxt);
-static void acpi_ec_gpe_burst_query ( void *ec_cxt);
-static u32 acpi_ec_gpe_polling_handler ( void *data);
-static u32 acpi_ec_gpe_burst_handler ( void *data);
+static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data);
+static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data);
+static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data);
+static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data);
+static void acpi_ec_gpe_polling_query(void *ec_cxt);
+static void acpi_ec_gpe_burst_query(void *ec_cxt);
+static u32 acpi_ec_gpe_polling_handler(void *data);
+static u32 acpi_ec_gpe_burst_handler(void *data);
static acpi_status __init
-acpi_fake_ecdt_polling_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval);
+acpi_fake_ecdt_polling_callback(acpi_handle handle,
+ u32 Level, void *context, void **retval);
static acpi_status __init
-acpi_fake_ecdt_burst_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval);
-
-static int __init
-acpi_ec_polling_get_real_ecdt(void);
-static int __init
-acpi_ec_burst_get_real_ecdt(void);
+acpi_fake_ecdt_burst_callback(acpi_handle handle,
+ u32 Level, void *context, void **retval);
+
+static int __init acpi_ec_polling_get_real_ecdt(void);
+static int __init acpi_ec_burst_get_real_ecdt(void);
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
-static union acpi_ec *ec_ecdt;
+static union acpi_ec *ec_ecdt;
/* External interfaces use first EC only, so remember */
static struct acpi_device *first_ec;
@@ -173,30 +155,24 @@ static int acpi_ec_polling_mode = EC_POLLING;
static inline u32 acpi_ec_read_status(union acpi_ec *ec)
{
- u32 status = 0;
+ u32 status = 0;
acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
return status;
}
-static int
-acpi_ec_wait (
- union acpi_ec *ec,
- u8 event)
+static int acpi_ec_wait(union acpi_ec *ec, u8 event)
{
- if (acpi_ec_polling_mode)
- return acpi_ec_polling_wait (ec, event);
+ if (acpi_ec_polling_mode)
+ return acpi_ec_polling_wait(ec, event);
else
- return acpi_ec_burst_wait (ec, event);
+ return acpi_ec_burst_wait(ec, event);
}
-static int
-acpi_ec_polling_wait (
- union acpi_ec *ec,
- u8 event)
+static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event)
{
- u32 acpi_ec_status = 0;
- u32 i = ACPI_EC_UDELAY_COUNT;
+ u32 acpi_ec_status = 0;
+ u32 i = ACPI_EC_UDELAY_COUNT;
if (!ec)
return -EINVAL;
@@ -205,19 +181,21 @@ acpi_ec_polling_wait (
switch (event) {
case ACPI_EC_EVENT_OBF:
do {
- acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
+ acpi_hw_low_level_read(8, &acpi_ec_status,
+ &ec->common.status_addr);
if (acpi_ec_status & ACPI_EC_FLAG_OBF)
return 0;
udelay(ACPI_EC_UDELAY);
- } while (--i>0);
+ } while (--i > 0);
break;
case ACPI_EC_EVENT_IBE:
do {
- acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
+ acpi_hw_low_level_read(8, &acpi_ec_status,
+ &ec->common.status_addr);
if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
return 0;
udelay(ACPI_EC_UDELAY);
- } while (--i>0);
+ } while (--i > 0);
break;
default:
return -EINVAL;
@@ -227,25 +205,36 @@ acpi_ec_polling_wait (
}
static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_ec_wait");
ec->burst.expect_event = event;
smp_mb();
- result = wait_event_interruptible_timeout(ec->burst.wait,
- !ec->burst.expect_event,
- msecs_to_jiffies(ACPI_EC_DELAY));
-
- ec->burst.expect_event = 0;
- smp_mb();
+ switch (event) {
+ case ACPI_EC_EVENT_OBF:
+ if (acpi_ec_read_status(ec) & event) {
+ ec->burst.expect_event = 0;
+ return_VALUE(0);
+ }
+ break;
- if (result < 0){
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result = %d ", result));
- return_VALUE(result);
+ case ACPI_EC_EVENT_IBE:
+ if (~acpi_ec_read_status(ec) & event) {
+ ec->burst.expect_event = 0;
+ return_VALUE(0);
+ }
+ break;
}
+ result = wait_event_timeout(ec->burst.wait,
+ !ec->burst.expect_event,
+ msecs_to_jiffies(ACPI_EC_DELAY));
+
+ ec->burst.expect_event = 0;
+ smp_mb();
+
/*
* Verify that the event in question has actually happened by
* querying EC status. Do the check even if operation timed-out
@@ -266,95 +255,65 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
return_VALUE(-ETIME);
}
-
-
-static int
-acpi_ec_enter_burst_mode (
- union acpi_ec *ec)
+static int acpi_ec_enter_burst_mode(union acpi_ec *ec)
{
- u32 tmp = 0;
- int status = 0;
+ u32 tmp = 0;
+ int status = 0;
ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode");
status = acpi_ec_read_status(ec);
- if (status != -EINVAL &&
- !(status & ACPI_EC_FLAG_BURST)){
- acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
+ if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ if (status)
+ goto end;
+ acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
+ &ec->common.command_addr);
status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (status){
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+ if (status)
return_VALUE(-EINVAL);
- }
acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- if(tmp != 0x90 ) {/* Burst ACK byte*/
+ if (tmp != 0x90) { /* Burst ACK byte */
return_VALUE(-EINVAL);
}
}
- atomic_set(&ec->burst.leaving_burst , 0);
+ atomic_set(&ec->burst.leaving_burst, 0);
return_VALUE(0);
+ end:
+ printk("Error in acpi_ec_wait\n");
+ return_VALUE(-1);
}
-static int
-acpi_ec_leave_burst_mode (
- union acpi_ec *ec)
+static int acpi_ec_leave_burst_mode(union acpi_ec *ec)
{
- int status =0;
ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
- atomic_set(&ec->burst.leaving_burst , 1);
- status = acpi_ec_read_status(ec);
- if (status != -EINVAL &&
- (status & ACPI_EC_FLAG_BURST)){
- acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
- status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
- if (status){
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
- return_VALUE(-EINVAL);
- }
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- status = acpi_ec_read_status(ec);
- }
-
+ atomic_set(&ec->burst.leaving_burst, 1);
return_VALUE(0);
}
-static int
-acpi_ec_read (
- union acpi_ec *ec,
- u8 address,
- u32 *data)
+static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data)
{
- if (acpi_ec_polling_mode)
+ if (acpi_ec_polling_mode)
return acpi_ec_polling_read(ec, address, data);
else
return acpi_ec_burst_read(ec, address, data);
}
-static int
-acpi_ec_write (
- union acpi_ec *ec,
- u8 address,
- u8 data)
+static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
{
- if (acpi_ec_polling_mode)
+ if (acpi_ec_polling_mode)
return acpi_ec_polling_write(ec, address, data);
else
return acpi_ec_burst_write(ec, address, data);
}
-static int
-acpi_ec_polling_read (
- union acpi_ec *ec,
- u8 address,
- u32 *data)
+static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data)
{
- acpi_status status = AE_OK;
- int result = 0;
- unsigned long flags = 0;
- u32 glk = 0;
+ acpi_status status = AE_OK;
+ int result = 0;
+ unsigned long flags = 0;
+ u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_read");
@@ -371,7 +330,8 @@ acpi_ec_polling_read (
spin_lock_irqsave(&ec->polling.lock, flags);
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
+ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
+ &ec->common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
goto end;
@@ -384,9 +344,9 @@ acpi_ec_polling_read (
acpi_hw_low_level_read(8, data, &ec->common.data_addr);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
- *data, address));
-
-end:
+ *data, address));
+
+ end:
spin_unlock_irqrestore(&ec->polling.lock, flags);
if (ec->common.global_lock)
@@ -395,17 +355,12 @@ end:
return_VALUE(result);
}
-
-static int
-acpi_ec_polling_write (
- union acpi_ec *ec,
- u8 address,
- u8 data)
+static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data)
{
- int result = 0;
- acpi_status status = AE_OK;
- unsigned long flags = 0;
- u32 glk = 0;
+ int result = 0;
+ acpi_status status = AE_OK;
+ unsigned long flags = 0;
+ u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_write");
@@ -420,7 +375,8 @@ acpi_ec_polling_write (
spin_lock_irqsave(&ec->polling.lock, flags);
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
+ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
+ &ec->common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
goto end;
@@ -436,9 +392,9 @@ acpi_ec_polling_write (
goto end;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
- data, address));
+ data, address));
-end:
+ end:
spin_unlock_irqrestore(&ec->polling.lock, flags);
if (ec->common.global_lock)
@@ -447,21 +403,16 @@ end:
return_VALUE(result);
}
-static int
-acpi_ec_burst_read (
- union acpi_ec *ec,
- u8 address,
- u32 *data)
+static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
{
- int status = 0;
- u32 glk;
+ int status = 0;
+ u32 glk;
ACPI_FUNCTION_TRACE("acpi_ec_read");
if (!ec || !data)
return_VALUE(-EINVAL);
-retry:
*data = 0;
if (ec->common.global_lock) {
@@ -473,64 +424,49 @@ retry:
WARN_ON(in_interrupt());
down(&ec->burst.sem);
- if(acpi_ec_enter_burst_mode(ec))
- goto end;
-
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
+ acpi_ec_enter_burst_mode(ec);
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
if (status) {
+ printk("read EC, IB not empty\n");
goto end;
}
+ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
+ &ec->common.command_addr);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ if (status) {
+ printk("read EC, IB not empty\n");
+ }
acpi_hw_low_level_write(8, address, &ec->common.data_addr);
- status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (status){
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+ if (status) {
+ printk("read EC, OB not full\n");
goto end;
}
-
acpi_hw_low_level_read(8, data, &ec->common.data_addr);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
- *data, address));
-
-end:
+ *data, address));
+
+ end:
acpi_ec_leave_burst_mode(ec);
up(&ec->burst.sem);
if (ec->common.global_lock)
acpi_release_global_lock(glk);
- if(atomic_read(&ec->burst.leaving_burst) == 2){
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
- while(atomic_read(&ec->burst.pending_gpe)){
- msleep(1);
- }
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- goto retry;
- }
-
return_VALUE(status);
}
-
-static int
-acpi_ec_burst_write (
- union acpi_ec *ec,
- u8 address,
- u8 data)
+static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data)
{
- int status = 0;
- u32 glk;
- u32 tmp;
+ int status = 0;
+ u32 glk;
ACPI_FUNCTION_TRACE("acpi_ec_write");
if (!ec)
return_VALUE(-EINVAL);
-retry:
+
if (ec->common.global_lock) {
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status))
@@ -540,69 +476,43 @@ retry:
WARN_ON(in_interrupt());
down(&ec->burst.sem);
- if(acpi_ec_enter_burst_mode(ec))
- goto end;
+ acpi_ec_enter_burst_mode(ec);
- status = acpi_ec_read_status(ec);
- if (status != -EINVAL &&
- !(status & ACPI_EC_FLAG_BURST)){
- acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (status)
- goto end;
- acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
- if(tmp != 0x90 ) /* Burst ACK byte*/
- goto end;
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ if (status) {
+ printk("write EC, IB not empty\n");
}
- /*Now we are in burst mode*/
-
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
+ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
+ &ec->common.command_addr);
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- if (status){
- goto end;
+ if (status) {
+ printk("write EC, IB not empty\n");
}
acpi_hw_low_level_write(8, address, &ec->common.data_addr);
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (status){
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- goto end;
+ if (status) {
+ printk("write EC, IB not empty\n");
}
acpi_hw_low_level_write(8, data, &ec->common.data_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- if (status)
- goto end;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
- data, address));
+ data, address));
-end:
acpi_ec_leave_burst_mode(ec);
up(&ec->burst.sem);
if (ec->common.global_lock)
acpi_release_global_lock(glk);
- if(atomic_read(&ec->burst.leaving_burst) == 2){
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
- while(atomic_read(&ec->burst.pending_gpe)){
- msleep(1);
- }
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- goto retry;
- }
-
return_VALUE(status);
}
/*
* Externally callable EC access functions. For now, assume 1 EC only
*/
-int
-ec_read(u8 addr, u8 *val)
+int ec_read(u8 addr, u8 * val)
{
union acpi_ec *ec;
int err;
@@ -618,14 +528,13 @@ ec_read(u8 addr, u8 *val)
if (!err) {
*val = temp_data;
return 0;
- }
- else
+ } else
return err;
}
+
EXPORT_SYMBOL(ec_read);
-int
-ec_write(u8 addr, u8 val)
+int ec_write(u8 addr, u8 val)
{
union acpi_ec *ec;
int err;
@@ -639,27 +548,22 @@ ec_write(u8 addr, u8 val)
return err;
}
+
EXPORT_SYMBOL(ec_write);
-static int
-acpi_ec_query (
- union acpi_ec *ec,
- u32 *data)
+static int acpi_ec_query(union acpi_ec *ec, u32 * data)
{
- if (acpi_ec_polling_mode)
+ if (acpi_ec_polling_mode)
return acpi_ec_polling_query(ec, data);
else
return acpi_ec_burst_query(ec, data);
}
-static int
-acpi_ec_polling_query (
- union acpi_ec *ec,
- u32 *data)
+static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data)
{
- int result = 0;
- acpi_status status = AE_OK;
- unsigned long flags = 0;
- u32 glk = 0;
+ int result = 0;
+ acpi_status status = AE_OK;
+ unsigned long flags = 0;
+ u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_query");
@@ -681,7 +585,8 @@ acpi_ec_polling_query (
*/
spin_lock_irqsave(&ec->polling.lock, flags);
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
+ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
+ &ec->common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
if (result)
goto end;
@@ -690,7 +595,7 @@ acpi_ec_polling_query (
if (!*data)
result = -ENODATA;
-end:
+ end:
spin_unlock_irqrestore(&ec->polling.lock, flags);
if (ec->common.global_lock)
@@ -698,13 +603,10 @@ end:
return_VALUE(result);
}
-static int
-acpi_ec_burst_query (
- union acpi_ec *ec,
- u32 *data)
+static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data)
{
- int status = 0;
- u32 glk;
+ int status = 0;
+ u32 glk;
ACPI_FUNCTION_TRACE("acpi_ec_query");
@@ -719,70 +621,64 @@ acpi_ec_burst_query (
}
down(&ec->burst.sem);
- if(acpi_ec_enter_burst_mode(ec))
+
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ if (status) {
+ printk("query EC, IB not empty\n");
goto end;
+ }
/*
* Query the EC to find out which _Qxx method we need to evaluate.
* Note that successful completion of the query causes the ACPI_EC_SCI
* bit to be cleared (and thus clearing the interrupt source).
*/
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
+ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
+ &ec->common.command_addr);
status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (status){
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+ if (status) {
+ printk("query EC, OB not full\n");
goto end;
}
acpi_hw_low_level_read(8, data, &ec->common.data_addr);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
if (!*data)
status = -ENODATA;
-end:
- acpi_ec_leave_burst_mode(ec);
+ end:
up(&ec->burst.sem);
if (ec->common.global_lock)
acpi_release_global_lock(glk);
- if(atomic_read(&ec->burst.leaving_burst) == 2){
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- status = -ENODATA;
- }
return_VALUE(status);
}
-
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
union acpi_ec_query_data {
- acpi_handle handle;
- u8 data;
+ acpi_handle handle;
+ u8 data;
};
-static void
-acpi_ec_gpe_query (
- void *ec_cxt)
+static void acpi_ec_gpe_query(void *ec_cxt)
{
- if (acpi_ec_polling_mode)
+ if (acpi_ec_polling_mode)
acpi_ec_gpe_polling_query(ec_cxt);
else
acpi_ec_gpe_burst_query(ec_cxt);
}
-static void
-acpi_ec_gpe_polling_query (
- void *ec_cxt)
+static void acpi_ec_gpe_polling_query(void *ec_cxt)
{
- union acpi_ec *ec = (union acpi_ec *) ec_cxt;
- u32 value = 0;
- unsigned long flags = 0;
- static char object_name[5] = {'_','Q','0','0','\0'};
- const char hex[] = {'0','1','2','3','4','5','6','7',
- '8','9','A','B','C','D','E','F'};
+ union acpi_ec *ec = (union acpi_ec *)ec_cxt;
+ u32 value = 0;
+ unsigned long flags = 0;
+ static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
+ const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
@@ -812,19 +708,18 @@ acpi_ec_gpe_polling_query (
acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
-end:
+ end:
acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
}
-static void
-acpi_ec_gpe_burst_query (
- void *ec_cxt)
+static void acpi_ec_gpe_burst_query(void *ec_cxt)
{
- union acpi_ec *ec = (union acpi_ec *) ec_cxt;
- u32 value;
- int result = -ENODATA;
- static char object_name[5] = {'_','Q','0','0','\0'};
- const char hex[] = {'0','1','2','3','4','5','6','7',
- '8','9','A','B','C','D','E','F'};
+ union acpi_ec *ec = (union acpi_ec *)ec_cxt;
+ u32 value;
+ int result = -ENODATA;
+ static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
+ const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
@@ -840,26 +735,22 @@ acpi_ec_gpe_burst_query (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
-end:
+ end:
atomic_dec(&ec->burst.pending_gpe);
return;
}
-static u32
-acpi_ec_gpe_handler (
- void *data)
+static u32 acpi_ec_gpe_handler(void *data)
{
- if (acpi_ec_polling_mode)
+ if (acpi_ec_polling_mode)
return acpi_ec_gpe_polling_handler(data);
else
- return acpi_ec_gpe_burst_handler(data);
+ return acpi_ec_gpe_burst_handler(data);
}
-static u32
-acpi_ec_gpe_polling_handler (
- void *data)
+static u32 acpi_ec_gpe_polling_handler(void *data)
{
- acpi_status status = AE_OK;
- union acpi_ec *ec = (union acpi_ec *) data;
+ acpi_status status = AE_OK;
+ union acpi_ec *ec = (union acpi_ec *)data;
if (!ec)
return ACPI_INTERRUPT_NOT_HANDLED;
@@ -867,61 +758,49 @@ acpi_ec_gpe_polling_handler (
acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
- acpi_ec_gpe_query, ec);
+ acpi_ec_gpe_query, ec);
if (status == AE_OK)
return ACPI_INTERRUPT_HANDLED;
else
return ACPI_INTERRUPT_NOT_HANDLED;
}
-static u32
-acpi_ec_gpe_burst_handler (
- void *data)
+static u32 acpi_ec_gpe_burst_handler(void *data)
{
- acpi_status status = AE_OK;
- u32 value;
- union acpi_ec *ec = (union acpi_ec *) data;
+ acpi_status status = AE_OK;
+ u32 value;
+ union acpi_ec *ec = (union acpi_ec *)data;
if (!ec)
return ACPI_INTERRUPT_NOT_HANDLED;
- acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
-
+ acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
value = acpi_ec_read_status(ec);
- if((value & ACPI_EC_FLAG_IBF) &&
- !(value & ACPI_EC_FLAG_BURST) &&
- (atomic_read(&ec->burst.leaving_burst) == 0)) {
- /*
- * the embedded controller disables
- * burst mode for any reason other
- * than the burst disable command
- * to process critical event.
- */
- atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
- and retry */
+ switch (ec->burst.expect_event) {
+ case ACPI_EC_EVENT_OBF:
+ if (!(value & ACPI_EC_FLAG_OBF))
+ break;
+ case ACPI_EC_EVENT_IBE:
+ if ((value & ACPI_EC_FLAG_IBF))
+ break;
+ ec->burst.expect_event = 0;
wake_up(&ec->burst.wait);
- }else {
- if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
- (value & ACPI_EC_FLAG_OBF)) ||
- (ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
- !(value & ACPI_EC_FLAG_IBF))) {
- ec->burst.expect_event = 0;
- wake_up(&ec->burst.wait);
- return ACPI_INTERRUPT_HANDLED;
- }
+ return ACPI_INTERRUPT_HANDLED;
+ default:
+ break;
}
- if (value & ACPI_EC_FLAG_SCI){
- atomic_add(1, &ec->burst.pending_gpe) ;
+ if (value & ACPI_EC_FLAG_SCI) {
+ atomic_add(1, &ec->burst.pending_gpe);
status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
- acpi_ec_gpe_query, ec);
+ acpi_ec_gpe_query, ec);
return status == AE_OK ?
- ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
- }
+ ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+ }
acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
return status == AE_OK ?
- ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+ ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
}
/* --------------------------------------------------------------------------
@@ -929,37 +808,31 @@ acpi_ec_gpe_burst_handler (
-------------------------------------------------------------------------- */
static acpi_status
-acpi_ec_space_setup (
- acpi_handle region_handle,
- u32 function,
- void *handler_context,
- void **return_context)
+acpi_ec_space_setup(acpi_handle region_handle,
+ u32 function, void *handler_context, void **return_context)
{
/*
* The EC object is in the handler context and is needed
* when calling the acpi_ec_space_handler.
*/
- *return_context = (function != ACPI_REGION_DEACTIVATE) ?
- handler_context : NULL;
+ *return_context = (function != ACPI_REGION_DEACTIVATE) ?
+ handler_context : NULL;
return AE_OK;
}
-
static acpi_status
-acpi_ec_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ec_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- int result = 0;
- union acpi_ec *ec = NULL;
- u64 temp = *value;
- acpi_integer f_v = 0;
- int i = 0;
+ int result = 0;
+ union acpi_ec *ec = NULL;
+ u64 temp = *value;
+ acpi_integer f_v = 0;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_ec_space_handler");
@@ -967,17 +840,18 @@ acpi_ec_space_handler (
return_VALUE(AE_BAD_PARAMETER);
if (bit_width != 8 && acpi_strict) {
- printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
+ printk(KERN_WARNING PREFIX
+ "acpi_ec_space_handler: bit_width should be 8\n");
return_VALUE(AE_BAD_PARAMETER);
}
- ec = (union acpi_ec *) handler_context;
+ ec = (union acpi_ec *)handler_context;
-next_byte:
+ next_byte:
switch (function) {
case ACPI_READ:
temp = 0;
- result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);
+ result = acpi_ec_read(ec, (u8) address, (u32 *) & temp);
break;
case ACPI_WRITE:
result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -1004,8 +878,7 @@ next_byte:
*value = f_v;
}
-
-out:
+ out:
switch (result) {
case -EINVAL:
return_VALUE(AE_BAD_PARAMETER);
@@ -1021,18 +894,15 @@ out:
}
}
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_ec_dir;
-
+static struct proc_dir_entry *acpi_ec_dir;
-static int
-acpi_ec_read_info (struct seq_file *seq, void *offset)
+static int acpi_ec_read_info(struct seq_file *seq, void *offset)
{
- union acpi_ec *ec = (union acpi_ec *) seq->private;
+ union acpi_ec *ec = (union acpi_ec *)seq->private;
ACPI_FUNCTION_TRACE("acpi_ec_read_info");
@@ -1040,14 +910,15 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)
goto end;
seq_printf(seq, "gpe bit: 0x%02x\n",
- (u32) ec->common.gpe_bit);
+ (u32) ec->common.gpe_bit);
seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
- (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address);
+ (u32) ec->common.status_addr.address,
+ (u32) ec->common.data_addr.address);
seq_printf(seq, "use global lock: %s\n",
- ec->common.global_lock?"yes":"no");
+ ec->common.global_lock ? "yes" : "no");
acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-end:
+ end:
return_VALUE(0);
}
@@ -1057,34 +928,32 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
}
static struct file_operations acpi_ec_info_ops = {
- .open = acpi_ec_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_ec_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
.owner = THIS_MODULE,
};
-static int
-acpi_ec_add_fs (
- struct acpi_device *device)
+static int acpi_ec_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_ec_dir);
+ acpi_ec_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
}
entry = create_proc_entry(ACPI_EC_FILE_INFO, S_IRUGO,
- acpi_device_dir(device));
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "Unable to create '%s' fs entry\n",
- ACPI_EC_FILE_INFO));
+ "Unable to create '%s' fs entry\n",
+ ACPI_EC_FILE_INFO));
else {
entry->proc_fops = &acpi_ec_info_ops;
entry->data = acpi_driver_data(device);
@@ -1094,10 +963,7 @@ acpi_ec_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_ec_remove_fs (
- struct acpi_device *device)
+static int acpi_ec_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_ec_remove_fs");
@@ -1110,20 +976,16 @@ acpi_ec_remove_fs (
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-
-static int
-acpi_ec_polling_add (
- struct acpi_device *device)
+static int acpi_ec_polling_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
- unsigned long uid;
+ int result = 0;
+ acpi_status status = AE_OK;
+ union acpi_ec *ec = NULL;
+ unsigned long uid;
ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -1143,26 +1005,31 @@ acpi_ec_polling_add (
acpi_driver_data(device) = ec;
/* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);
+ acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
+ &ec->common.global_lock);
/* If our UID matches the UID for the ECDT-enumerated EC,
- we now have the *real* EC info, so kill the makeshift one.*/
+ we now have the *real* EC info, so kill the makeshift one. */
acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
if (ec_ecdt && ec_ecdt->common.uid == uid) {
acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
-
- acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler);
+
+ acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+ &acpi_ec_gpe_handler);
kfree(ec_ecdt);
}
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
- status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
+ status =
+ acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
+ &ec->common.gpe_bit);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error obtaining GPE bit assignment\n"));
+ "Error obtaining GPE bit assignment\n"));
result = -ENODEV;
goto end;
}
@@ -1172,26 +1039,24 @@ acpi_ec_polling_add (
goto end;
printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
- acpi_device_name(device), acpi_device_bid(device),
- (u32) ec->common.gpe_bit);
+ acpi_device_name(device), acpi_device_bid(device),
+ (u32) ec->common.gpe_bit);
if (!first_ec)
first_ec = device;
-end:
+ end:
if (result)
kfree(ec);
return_VALUE(result);
}
-static int
-acpi_ec_burst_add (
- struct acpi_device *device)
+static int acpi_ec_burst_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
- unsigned long uid;
+ int result = 0;
+ acpi_status status = AE_OK;
+ union acpi_ec *ec = NULL;
+ unsigned long uid;
ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -1205,35 +1070,40 @@ acpi_ec_burst_add (
ec->common.handle = device->handle;
ec->common.uid = -1;
- atomic_set(&ec->burst.pending_gpe, 0);
- atomic_set(&ec->burst.leaving_burst , 1);
- init_MUTEX(&ec->burst.sem);
- init_waitqueue_head(&ec->burst.wait);
+ atomic_set(&ec->burst.pending_gpe, 0);
+ atomic_set(&ec->burst.leaving_burst, 1);
+ init_MUTEX(&ec->burst.sem);
+ init_waitqueue_head(&ec->burst.wait);
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
acpi_driver_data(device) = ec;
/* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);
+ acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
+ &ec->common.global_lock);
/* If our UID matches the UID for the ECDT-enumerated EC,
- we now have the *real* EC info, so kill the makeshift one.*/
+ we now have the *real* EC info, so kill the makeshift one. */
acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
if (ec_ecdt && ec_ecdt->common.uid == uid) {
acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler);
- acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);
+ acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+ &acpi_ec_gpe_handler);
kfree(ec_ecdt);
}
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
- status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
+ status =
+ acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
+ &ec->common.gpe_bit);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error obtaining GPE bit assignment\n"));
+ "Error obtaining GPE bit assignment\n"));
result = -ENODEV;
goto end;
}
@@ -1242,27 +1112,24 @@ acpi_ec_burst_add (
if (result)
goto end;
+ printk("burst-mode-ec-10-Aug\n");
printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
- acpi_device_name(device), acpi_device_bid(device),
- (u32) ec->common.gpe_bit);
+ acpi_device_name(device), acpi_device_bid(device),
+ (u32) ec->common.gpe_bit);
if (!first_ec)
first_ec = device;
-end:
+ end:
if (result)
kfree(ec);
return_VALUE(result);
}
-
-static int
-acpi_ec_remove (
- struct acpi_device *device,
- int type)
+static int acpi_ec_remove(struct acpi_device *device, int type)
{
- union acpi_ec *ec = NULL;
+ union acpi_ec *ec = NULL;
ACPI_FUNCTION_TRACE("acpi_ec_remove");
@@ -1278,13 +1145,10 @@ acpi_ec_remove (
return_VALUE(0);
}
-
static acpi_status
-acpi_ec_io_ports (
- struct acpi_resource *resource,
- void *context)
+acpi_ec_io_ports(struct acpi_resource *resource, void *context)
{
- union acpi_ec *ec = (union acpi_ec *) context;
+ union acpi_ec *ec = (union acpi_ec *)context;
struct acpi_generic_address *addr;
if (resource->id != ACPI_RSTYPE_IO) {
@@ -1312,13 +1176,10 @@ acpi_ec_io_ports (
return AE_OK;
}
-
-static int
-acpi_ec_start (
- struct acpi_device *device)
+static int acpi_ec_start(struct acpi_device *device)
{
- acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
+ acpi_status status = AE_OK;
+ union acpi_ec *ec = NULL;
ACPI_FUNCTION_TRACE("acpi_ec_start");
@@ -1334,49 +1195,50 @@ acpi_ec_start (
* Get I/O port addresses. Convert to GAS format.
*/
status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
- acpi_ec_io_ports, ec);
- if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
+ acpi_ec_io_ports, ec);
+ if (ACPI_FAILURE(status)
+ || ec->common.command_addr.register_bit_width == 0) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error getting I/O port addresses"));
return_VALUE(-ENODEV);
}
ec->common.status_addr = ec->common.command_addr;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
- (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address,
- (u32) ec->common.data_addr.address));
-
+ (u32) ec->common.gpe_bit,
+ (u32) ec->common.command_addr.address,
+ (u32) ec->common.data_addr.address));
/*
* Install GPE handler
*/
status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
- ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
+ ACPI_GPE_EDGE_TRIGGERED,
+ &acpi_ec_gpe_handler, ec);
if (ACPI_FAILURE(status)) {
return_VALUE(-ENODEV);
}
- acpi_set_gpe_type (NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe (NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+ acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
- status = acpi_install_address_space_handler (ec->common.handle,
- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
- &acpi_ec_space_setup, ec);
+ status = acpi_install_address_space_handler(ec->common.handle,
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler,
+ &acpi_ec_space_setup, ec);
if (ACPI_FAILURE(status)) {
- acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
+ acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
+ &acpi_ec_gpe_handler);
return_VALUE(-ENODEV);
}
return_VALUE(AE_OK);
}
-
-static int
-acpi_ec_stop (
- struct acpi_device *device,
- int type)
+static int acpi_ec_stop(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
+ acpi_status status = AE_OK;
+ union acpi_ec *ec = NULL;
ACPI_FUNCTION_TRACE("acpi_ec_stop");
@@ -1386,11 +1248,14 @@ acpi_ec_stop (
ec = acpi_driver_data(device);
status = acpi_remove_address_space_handler(ec->common.handle,
- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
- status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
+ status =
+ acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
+ &acpi_ec_gpe_handler);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
@@ -1398,32 +1263,26 @@ acpi_ec_stop (
}
static acpi_status __init
-acpi_fake_ecdt_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval)
+acpi_fake_ecdt_callback(acpi_handle handle,
+ u32 Level, void *context, void **retval)
{
if (acpi_ec_polling_mode)
return acpi_fake_ecdt_polling_callback(handle,
- Level, context, retval);
+ Level, context, retval);
else
return acpi_fake_ecdt_burst_callback(handle,
- Level, context, retval);
+ Level, context, retval);
}
static acpi_status __init
-acpi_fake_ecdt_polling_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval)
+acpi_fake_ecdt_polling_callback(acpi_handle handle,
+ u32 Level, void *context, void **retval)
{
- acpi_status status;
+ acpi_status status;
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
- acpi_ec_io_ports, ec_ecdt);
+ acpi_ec_io_ports, ec_ecdt);
if (ACPI_FAILURE(status))
return status;
ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
@@ -1431,33 +1290,33 @@ acpi_fake_ecdt_polling_callback (
ec_ecdt->common.uid = -1;
acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
- status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
+ status =
+ acpi_evaluate_integer(handle, "_GPE", NULL,
+ &ec_ecdt->common.gpe_bit);
if (ACPI_FAILURE(status))
return status;
spin_lock_init(&ec_ecdt->polling.lock);
ec_ecdt->common.global_lock = TRUE;
ec_ecdt->common.handle = handle;
- printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
- (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
- (u32) ec_ecdt->common.data_addr.address);
+ printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
+ (u32) ec_ecdt->common.gpe_bit,
+ (u32) ec_ecdt->common.command_addr.address,
+ (u32) ec_ecdt->common.data_addr.address);
return AE_CTRL_TERMINATE;
}
static acpi_status __init
-acpi_fake_ecdt_burst_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval)
+acpi_fake_ecdt_burst_callback(acpi_handle handle,
+ u32 Level, void *context, void **retval)
{
- acpi_status status;
+ acpi_status status;
init_MUTEX(&ec_ecdt->burst.sem);
init_waitqueue_head(&ec_ecdt->burst.wait);
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
- acpi_ec_io_ports, ec_ecdt);
+ acpi_ec_io_ports, ec_ecdt);
if (ACPI_FAILURE(status))
return status;
ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
@@ -1465,15 +1324,18 @@ acpi_fake_ecdt_burst_callback (
ec_ecdt->common.uid = -1;
acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
- status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
+ status =
+ acpi_evaluate_integer(handle, "_GPE", NULL,
+ &ec_ecdt->common.gpe_bit);
if (ACPI_FAILURE(status))
return status;
ec_ecdt->common.global_lock = TRUE;
ec_ecdt->common.handle = handle;
- printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
- (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
- (u32) ec_ecdt->common.data_addr.address);
+ printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
+ (u32) ec_ecdt->common.gpe_bit,
+ (u32) ec_ecdt->common.command_addr.address,
+ (u32) ec_ecdt->common.data_addr.address);
return AE_CTRL_TERMINATE;
}
@@ -1488,11 +1350,10 @@ acpi_fake_ecdt_burst_callback (
* op region (since _REG isn't invoked yet). The assumption is true for
* all systems found.
*/
-static int __init
-acpi_ec_fake_ecdt(void)
+static int __init acpi_ec_fake_ecdt(void)
{
- acpi_status status;
- int ret = 0;
+ acpi_status status;
+ int ret = 0;
printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
@@ -1503,10 +1364,8 @@ acpi_ec_fake_ecdt(void)
}
memset(ec_ecdt, 0, sizeof(union acpi_ec));
- status = acpi_get_devices (ACPI_EC_HID,
- acpi_fake_ecdt_callback,
- NULL,
- NULL);
+ status = acpi_get_devices(ACPI_EC_HID,
+ acpi_fake_ecdt_callback, NULL, NULL);
if (ACPI_FAILURE(status)) {
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -1514,13 +1373,12 @@ acpi_ec_fake_ecdt(void)
goto error;
}
return 0;
-error:
+ error:
printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
return ret;
}
-static int __init
-acpi_ec_get_real_ecdt(void)
+static int __init acpi_ec_get_real_ecdt(void)
{
if (acpi_ec_polling_mode)
return acpi_ec_polling_get_real_ecdt();
@@ -1528,14 +1386,14 @@ acpi_ec_get_real_ecdt(void)
return acpi_ec_burst_get_real_ecdt();
}
-static int __init
-acpi_ec_polling_get_real_ecdt(void)
+static int __init acpi_ec_polling_get_real_ecdt(void)
{
- acpi_status status;
- struct acpi_table_ecdt *ecdt_ptr;
+ acpi_status status;
+ struct acpi_table_ecdt *ecdt_ptr;
- status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
- (struct acpi_table_header **) &ecdt_ptr);
+ status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
+ (struct acpi_table_header **)
+ &ecdt_ptr);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -1558,13 +1416,14 @@ acpi_ec_polling_get_real_ecdt(void)
ec_ecdt->common.global_lock = TRUE;
ec_ecdt->common.uid = ecdt_ptr->uid;
- status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
+ status =
+ acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
if (ACPI_FAILURE(status)) {
goto error;
}
return 0;
-error:
+ error:
printk(KERN_ERR PREFIX "Could not use ECDT\n");
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -1572,15 +1431,14 @@ error:
return -ENODEV;
}
-
-static int __init
-acpi_ec_burst_get_real_ecdt(void)
+static int __init acpi_ec_burst_get_real_ecdt(void)
{
- acpi_status status;
- struct acpi_table_ecdt *ecdt_ptr;
+ acpi_status status;
+ struct acpi_table_ecdt *ecdt_ptr;
status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
- (struct acpi_table_header **) &ecdt_ptr);
+ (struct acpi_table_header **)
+ &ecdt_ptr);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -1594,8 +1452,8 @@ acpi_ec_burst_get_real_ecdt(void)
return -ENOMEM;
memset(ec_ecdt, 0, sizeof(union acpi_ec));
- init_MUTEX(&ec_ecdt->burst.sem);
- init_waitqueue_head(&ec_ecdt->burst.wait);
+ init_MUTEX(&ec_ecdt->burst.sem);
+ init_waitqueue_head(&ec_ecdt->burst.wait);
ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
@@ -1604,13 +1462,14 @@ acpi_ec_burst_get_real_ecdt(void)
ec_ecdt->common.global_lock = TRUE;
ec_ecdt->common.uid = ecdt_ptr->uid;
- status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
+ status =
+ acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
if (ACPI_FAILURE(status)) {
goto error;
}
return 0;
-error:
+ error:
printk(KERN_ERR PREFIX "Could not use ECDT\n");
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -1619,11 +1478,10 @@ error:
}
static int __initdata acpi_fake_ecdt_enabled;
-int __init
-acpi_ec_ecdt_probe (void)
+int __init acpi_ec_ecdt_probe(void)
{
- acpi_status status;
- int ret;
+ acpi_status status;
+ int ret;
ret = acpi_ec_get_real_ecdt();
/* Try to make a fake ECDT */
@@ -1638,26 +1496,28 @@ acpi_ec_ecdt_probe (void)
* Install GPE handler
*/
status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
- ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
- ec_ecdt);
+ ACPI_GPE_EDGE_TRIGGERED,
+ &acpi_ec_gpe_handler, ec_ecdt);
if (ACPI_FAILURE(status)) {
goto error;
}
- acpi_set_gpe_type (NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe (NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
-
- status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
- &acpi_ec_space_setup, ec_ecdt);
+ acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
+
+ status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler,
+ &acpi_ec_space_setup,
+ ec_ecdt);
if (ACPI_FAILURE(status)) {
acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
- &acpi_ec_gpe_handler);
+ &acpi_ec_gpe_handler);
goto error;
}
return 0;
-error:
+ error:
printk(KERN_ERR PREFIX "Could not use ECDT\n");
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -1665,10 +1525,9 @@ error:
return -ENODEV;
}
-
-static int __init acpi_ec_init (void)
+static int __init acpi_ec_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_ec_init");
@@ -1693,8 +1552,7 @@ subsys_initcall(acpi_ec_init);
/* EC driver currently not unloadable */
#if 0
-static void __exit
-acpi_ec_exit (void)
+static void __exit acpi_ec_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_ec_exit");
@@ -1704,7 +1562,7 @@ acpi_ec_exit (void)
return_VOID;
}
-#endif /* 0 */
+#endif /* 0 */
static int __init acpi_fake_ecdt_setup(char *str)
{
@@ -1727,8 +1585,8 @@ static int __init acpi_ec_set_polling_mode(char *str)
acpi_ec_polling_mode = EC_POLLING;
acpi_ec_driver.ops.add = acpi_ec_polling_add;
}
- printk(KERN_INFO PREFIX "EC %s mode.\n",
- burst ? "burst": "polling");
+ printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst" : "polling");
return 0;
}
+
__setup("ec_burst=", acpi_ec_set_polling_mode);
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 43c49f66a328..2dbb1b0f11d5 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -13,45 +13,40 @@
#include <acpi/acpi_drivers.h>
#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("event")
+ACPI_MODULE_NAME("event")
/* Global vars for handling event proc entry */
static DEFINE_SPINLOCK(acpi_system_event_lock);
-int event_is_open = 0;
-extern struct list_head acpi_bus_event_list;
-extern wait_queue_head_t acpi_bus_event_queue;
+int event_is_open = 0;
+extern struct list_head acpi_bus_event_list;
+extern wait_queue_head_t acpi_bus_event_queue;
-static int
-acpi_system_open_event(struct inode *inode, struct file *file)
+static int acpi_system_open_event(struct inode *inode, struct file *file)
{
- spin_lock_irq (&acpi_system_event_lock);
+ spin_lock_irq(&acpi_system_event_lock);
- if(event_is_open)
+ if (event_is_open)
goto out_busy;
event_is_open = 1;
- spin_unlock_irq (&acpi_system_event_lock);
+ spin_unlock_irq(&acpi_system_event_lock);
return 0;
-out_busy:
- spin_unlock_irq (&acpi_system_event_lock);
+ out_busy:
+ spin_unlock_irq(&acpi_system_event_lock);
return -EBUSY;
}
static ssize_t
-acpi_system_read_event (
- struct file *file,
- char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
+ loff_t * ppos)
{
- int result = 0;
- struct acpi_bus_event event;
- static char str[ACPI_MAX_STRING];
- static int chars_remaining = 0;
- static char *ptr;
-
+ int result = 0;
+ struct acpi_bus_event event;
+ static char str[ACPI_MAX_STRING];
+ static int chars_remaining = 0;
+ static char *ptr;
ACPI_FUNCTION_TRACE("acpi_system_read_event");
@@ -63,14 +58,15 @@ acpi_system_read_event (
return_VALUE(-EAGAIN);
result = acpi_bus_receive_event(&event);
- if (result) {
- return_VALUE(-EIO);
- }
-
- chars_remaining = sprintf(str, "%s %s %08x %08x\n",
- event.device_class?event.device_class:"<unknown>",
- event.bus_id?event.bus_id:"<unknown>",
- event.type, event.data);
+ if (result)
+ return_VALUE(result);
+
+ chars_remaining = sprintf(str, "%s %s %08x %08x\n",
+ event.device_class ? event.
+ device_class : "<unknown>",
+ event.bus_id ? event.
+ bus_id : "<unknown>", event.type,
+ event.data);
ptr = str;
}
@@ -88,19 +84,15 @@ acpi_system_read_event (
return_VALUE(count);
}
-static int
-acpi_system_close_event(struct inode *inode, struct file *file)
+static int acpi_system_close_event(struct inode *inode, struct file *file)
{
- spin_lock_irq (&acpi_system_event_lock);
+ spin_lock_irq(&acpi_system_event_lock);
event_is_open = 0;
- spin_unlock_irq (&acpi_system_event_lock);
+ spin_unlock_irq(&acpi_system_event_lock);
return 0;
}
-static unsigned int
-acpi_system_poll_event(
- struct file *file,
- poll_table *wait)
+static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait)
{
poll_wait(file, &acpi_bus_event_queue, wait);
if (!list_empty(&acpi_bus_event_list))
@@ -109,15 +101,15 @@ acpi_system_poll_event(
}
static struct file_operations acpi_system_event_ops = {
- .open = acpi_system_open_event,
- .read = acpi_system_read_event,
- .release = acpi_system_close_event,
- .poll = acpi_system_poll_event,
+ .open = acpi_system_open_event,
+ .read = acpi_system_read_event,
+ .release = acpi_system_close_event,
+ .poll = acpi_system_poll_event,
};
static int __init acpi_event_init(void)
{
- struct proc_dir_entry *entry;
+ struct proc_dir_entry *entry;
int error = 0;
ACPI_FUNCTION_TRACE("acpi_event_init");
@@ -130,8 +122,9 @@ static int __init acpi_event_init(void)
if (entry)
entry->proc_fops = &acpi_system_event_ops;
else {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' proc fs entry\n","event" ));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create '%s' proc fs entry\n",
+ "event"));
error = -EFAULT;
}
return_VALUE(error);
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index dd3a72a869f4..842d1e3fb37b 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -45,18 +45,12 @@
#include <acpi/acevents.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evevent")
+ACPI_MODULE_NAME("evevent")
/* Local prototypes */
+static acpi_status acpi_ev_fixed_event_initialize(void);
-static acpi_status
-acpi_ev_fixed_event_initialize (
- void);
-
-static u32
-acpi_ev_fixed_event_dispatch (
- u32 event);
-
+static u32 acpi_ev_fixed_event_dispatch(u32 event);
/*******************************************************************************
*
@@ -70,21 +64,17 @@ acpi_ev_fixed_event_dispatch (
*
******************************************************************************/
-acpi_status
-acpi_ev_initialize_events (
- void)
+acpi_status acpi_ev_initialize_events(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_initialize_events");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_initialize_events");
/* Make sure we have ACPI tables */
if (!acpi_gbl_DSDT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No ACPI tables present!\n"));
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/*
@@ -92,26 +82,22 @@ acpi_ev_initialize_events (
* enabling SCIs to prevent interrupts from occurring before the handlers are
* installed.
*/
- status = acpi_ev_fixed_event_initialize ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Unable to initialize fixed events, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ev_fixed_event_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Unable to initialize fixed events, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
- status = acpi_ev_gpe_initialize ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Unable to initialize general purpose events, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ev_gpe_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Unable to initialize general purpose events, %s\n", acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_install_xrupt_handlers
@@ -124,41 +110,32 @@ acpi_ev_initialize_events (
*
******************************************************************************/
-acpi_status
-acpi_ev_install_xrupt_handlers (
- void)
+acpi_status acpi_ev_install_xrupt_handlers(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_install_xrupt_handlers");
/* Install the SCI handler */
- status = acpi_ev_install_sci_handler ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Unable to install System Control Interrupt Handler, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ev_install_sci_handler();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Unable to install System Control Interrupt Handler, %s\n", acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
/* Install the handler for the Global Lock */
- status = acpi_ev_init_global_lock_handler ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Unable to initialize Global Lock handler, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ev_init_global_lock_handler();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Unable to initialize Global Lock handler, %s\n", acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
acpi_gbl_events_initialized = TRUE;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_fixed_event_initialize
@@ -171,13 +148,10 @@ acpi_ev_install_xrupt_handlers (
*
******************************************************************************/
-static acpi_status
-acpi_ev_fixed_event_initialize (
- void)
+static acpi_status acpi_ev_fixed_event_initialize(void)
{
- acpi_native_uint i;
- acpi_status status;
-
+ acpi_native_uint i;
+ acpi_status status;
/*
* Initialize the structure that keeps track of fixed event handlers
@@ -190,10 +164,11 @@ acpi_ev_fixed_event_initialize (
/* Enable the fixed event */
if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
- status = acpi_set_register (
- acpi_gbl_fixed_event_info[i].enable_register_id,
- 0, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_set_register(acpi_gbl_fixed_event_info[i].
+ enable_register_id, 0,
+ ACPI_MTX_LOCK);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -202,7 +177,6 @@ acpi_ev_fixed_event_initialize (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_fixed_event_detect
@@ -215,31 +189,27 @@ acpi_ev_fixed_event_initialize (
*
******************************************************************************/
-u32
-acpi_ev_fixed_event_detect (
- void)
+u32 acpi_ev_fixed_event_detect(void)
{
- u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
- u32 fixed_status;
- u32 fixed_enable;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_NAME ("ev_fixed_event_detect");
+ u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
+ u32 fixed_status;
+ u32 fixed_enable;
+ acpi_native_uint i;
+ ACPI_FUNCTION_NAME("ev_fixed_event_detect");
/*
* Read the fixed feature status and enable registers, as all the cases
* depend on their values. Ignore errors here.
*/
- (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
- &fixed_status);
- (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE,
- &fixed_enable);
+ (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS, &fixed_status);
+ (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
- ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
- "Fixed Event Block: Enable %08X Status %08X\n",
- fixed_enable, fixed_status));
+ ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
+ "Fixed Event Block: Enable %08X Status %08X\n",
+ fixed_enable, fixed_status));
/*
* Check for all possible Fixed Events and dispatch those that are active
@@ -247,18 +217,19 @@ acpi_ev_fixed_event_detect (
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
/* Both the status and enable bits must be on for this event */
- if ((fixed_status & acpi_gbl_fixed_event_info[i].status_bit_mask) &&
- (fixed_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) {
+ if ((fixed_status & acpi_gbl_fixed_event_info[i].
+ status_bit_mask)
+ && (fixed_enable & acpi_gbl_fixed_event_info[i].
+ enable_bit_mask)) {
/* Found an active (signalled) event */
- int_status |= acpi_ev_fixed_event_dispatch ((u32) i);
+ int_status |= acpi_ev_fixed_event_dispatch((u32) i);
}
}
return (int_status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_fixed_event_dispatch
@@ -272,39 +243,32 @@ acpi_ev_fixed_event_detect (
*
******************************************************************************/
-static u32
-acpi_ev_fixed_event_dispatch (
- u32 event)
+static u32 acpi_ev_fixed_event_dispatch(u32 event)
{
-
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
/* Clear the status bit */
- (void) acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
- 1, ACPI_MTX_DO_NOT_LOCK);
+ (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, 1, ACPI_MTX_DO_NOT_LOCK);
/*
* Make sure we've got a handler. If not, report an error.
* The event is disabled to prevent further interrupts.
*/
if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
- (void) acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- 0, ACPI_MTX_DO_NOT_LOCK);
+ (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, 0,
+ ACPI_MTX_DO_NOT_LOCK);
- ACPI_REPORT_ERROR (
- ("No installed handler for fixed event [%08X]\n",
- event));
+ ACPI_REPORT_ERROR(("No installed handler for fixed event [%08X]\n", event));
return (ACPI_INTERRUPT_NOT_HANDLED);
}
/* Invoke the Fixed Event handler */
- return ((acpi_gbl_fixed_event_handlers[event].handler)(
- acpi_gbl_fixed_event_handlers[event].context));
+ return ((acpi_gbl_fixed_event_handlers[event].
+ handler) (acpi_gbl_fixed_event_handlers[event].context));
}
-
-
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 081120b109ba..b2f232df13d8 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -46,14 +46,10 @@
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evgpe")
+ACPI_MODULE_NAME("evgpe")
/* Local prototypes */
-
-static void ACPI_SYSTEM_XFACE
-acpi_ev_asynch_execute_gpe_method (
- void *context);
-
+static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
/*******************************************************************************
*
@@ -69,15 +65,11 @@ acpi_ev_asynch_execute_gpe_method (
******************************************************************************/
acpi_status
-acpi_ev_set_gpe_type (
- struct acpi_gpe_event_info *gpe_event_info,
- u8 type)
+acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_set_gpe_type");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_set_gpe_type");
/* Validate type and update register enable masks */
@@ -88,21 +80,20 @@ acpi_ev_set_gpe_type (
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Disable the GPE if currently enabled */
- status = acpi_ev_disable_gpe (gpe_event_info);
+ status = acpi_ev_disable_gpe(gpe_event_info);
/* Type was validated above */
- gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
- gpe_event_info->flags |= type; /* Insert type */
- return_ACPI_STATUS (status);
+ gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
+ gpe_event_info->flags |= type; /* Insert type */
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_update_gpe_enable_masks
@@ -118,57 +109,55 @@ acpi_ev_set_gpe_type (
******************************************************************************/
acpi_status
-acpi_ev_update_gpe_enable_masks (
- struct acpi_gpe_event_info *gpe_event_info,
- u8 type)
+acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
+ u8 type)
{
- struct acpi_gpe_register_info *gpe_register_info;
- u8 register_bit;
-
-
- ACPI_FUNCTION_TRACE ("ev_update_gpe_enable_masks");
+ struct acpi_gpe_register_info *gpe_register_info;
+ u8 register_bit;
+ ACPI_FUNCTION_TRACE("ev_update_gpe_enable_masks");
gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
register_bit = gpe_event_info->register_bit;
/* 1) Disable case. Simply clear all enable bits */
if (type == ACPI_GPE_DISABLE) {
- ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
- ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
- return_ACPI_STATUS (AE_OK);
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
+ register_bit);
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
+ return_ACPI_STATUS(AE_OK);
}
/* 2) Enable case. Set/Clear the appropriate enable bits */
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE:
- ACPI_SET_BIT (gpe_register_info->enable_for_wake, register_bit);
- ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
+ ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
break;
case ACPI_GPE_TYPE_RUNTIME:
- ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
- ACPI_SET_BIT (gpe_register_info->enable_for_run, register_bit);
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
+ register_bit);
+ ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
- ACPI_SET_BIT (gpe_register_info->enable_for_wake, register_bit);
- ACPI_SET_BIT (gpe_register_info->enable_for_run, register_bit);
+ ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
+ ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_enable_gpe
@@ -184,21 +173,19 @@ acpi_ev_update_gpe_enable_masks (
******************************************************************************/
acpi_status
-acpi_ev_enable_gpe (
- struct acpi_gpe_event_info *gpe_event_info,
- u8 write_to_hardware)
+acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
+ u8 write_to_hardware)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_enable_gpe");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_enable_gpe");
/* Make sure HW enable masks are updated */
- status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_ENABLE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_ENABLE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Mark wake-enabled or HW enable, or both */
@@ -206,41 +193,40 @@ acpi_ev_enable_gpe (
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE:
- ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+ ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
- ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+ ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
/*lint -fallthrough */
case ACPI_GPE_TYPE_RUNTIME:
- ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
+ ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
if (write_to_hardware) {
/* Clear the GPE (of stale events), then enable it */
- status = acpi_hw_clear_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_clear_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Enable the requested runtime GPE */
- status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
+ status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
}
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_disable_gpe
@@ -253,36 +239,33 @@ acpi_ev_enable_gpe (
*
******************************************************************************/
-acpi_status
-acpi_ev_disable_gpe (
- struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_disable_gpe");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_disable_gpe");
if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Make sure HW enable masks are updated */
- status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_DISABLE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Mark wake-disabled or HW disable, or both */
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE:
- ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+ ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
- ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+ ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
/*lint -fallthrough */
@@ -290,18 +273,17 @@ acpi_ev_disable_gpe (
/* Disable the requested runtime GPE */
- ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
- status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
+ ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
+ status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_event_info
@@ -319,18 +301,14 @@ acpi_ev_disable_gpe (
*
******************************************************************************/
-struct acpi_gpe_event_info *
-acpi_ev_get_gpe_event_info (
- acpi_handle gpe_device,
- u32 gpe_number)
+struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
+ u32 gpe_number)
{
- union acpi_operand_object *obj_desc;
- struct acpi_gpe_block_info *gpe_block;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_operand_object *obj_desc;
+ struct acpi_gpe_block_info *gpe_block;
+ acpi_native_uint i;
+ ACPI_FUNCTION_ENTRY();
/* A NULL gpe_block means use the FADT-defined GPE block(s) */
@@ -340,11 +318,14 @@ acpi_ev_get_gpe_event_info (
for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
gpe_block = acpi_gbl_gpe_fadt_blocks[i];
if (gpe_block) {
- if ((gpe_number >= gpe_block->block_base_number) &&
- (gpe_number < gpe_block->block_base_number +
- (gpe_block->register_count * 8))) {
- return (&gpe_block->event_info[gpe_number -
- gpe_block->block_base_number]);
+ if ((gpe_number >= gpe_block->block_base_number)
+ && (gpe_number <
+ gpe_block->block_base_number +
+ (gpe_block->register_count * 8))) {
+ return (&gpe_block->
+ event_info[gpe_number -
+ gpe_block->
+ block_base_number]);
}
}
}
@@ -356,23 +337,25 @@ acpi_ev_get_gpe_event_info (
/* A Non-NULL gpe_device means this is a GPE Block Device */
- obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) gpe_device);
- if (!obj_desc ||
- !obj_desc->device.gpe_block) {
+ obj_desc =
+ acpi_ns_get_attached_object((struct acpi_namespace_node *)
+ gpe_device);
+ if (!obj_desc || !obj_desc->device.gpe_block) {
return (NULL);
}
gpe_block = obj_desc->device.gpe_block;
if ((gpe_number >= gpe_block->block_base_number) &&
- (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
+ (gpe_number <
+ gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+ return (&gpe_block->
+ event_info[gpe_number - gpe_block->block_base_number]);
}
return (NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_detect
@@ -387,22 +370,20 @@ acpi_ev_get_gpe_event_info (
*
******************************************************************************/
-u32
-acpi_ev_gpe_detect (
- struct acpi_gpe_xrupt_info *gpe_xrupt_list)
+u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
{
- u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
- u8 enabled_status_byte;
- struct acpi_gpe_register_info *gpe_register_info;
- u32 status_reg;
- u32 enable_reg;
- acpi_status status;
- struct acpi_gpe_block_info *gpe_block;
- acpi_native_uint i;
- acpi_native_uint j;
-
-
- ACPI_FUNCTION_NAME ("ev_gpe_detect");
+ u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
+ u8 enabled_status_byte;
+ struct acpi_gpe_register_info *gpe_register_info;
+ u32 status_reg;
+ u32 enable_reg;
+ u32 flags;
+ acpi_status status;
+ struct acpi_gpe_block_info *gpe_block;
+ acpi_native_uint i;
+ acpi_native_uint j;
+
+ ACPI_FUNCTION_NAME("ev_gpe_detect");
/* Check for the case where there are no GPEs */
@@ -412,7 +393,7 @@ acpi_ev_gpe_detect (
/* Examine all GPE blocks attached to this interrupt level */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
gpe_block = gpe_xrupt_list->gpe_block_list_head;
while (gpe_block) {
/*
@@ -427,23 +408,30 @@ acpi_ev_gpe_detect (
/* Read the Status Register */
- status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg,
- &gpe_register_info->status_address);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH,
+ &status_reg,
+ &gpe_register_info->
+ status_address);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Read the Enable Register */
- status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg,
- &gpe_register_info->enable_address);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH,
+ &enable_reg,
+ &gpe_register_info->
+ enable_address);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
- "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
- gpe_register_info->base_gpe_number, status_reg, enable_reg));
+ ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
+ "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
+ gpe_register_info->base_gpe_number,
+ status_reg, enable_reg));
/* Check if there is anything active at all in this register */
@@ -459,14 +447,21 @@ acpi_ev_gpe_detect (
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
/* Examine one GPE bit */
- if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) {
+ if (enabled_status_byte &
+ acpi_gbl_decode_to8bit[j]) {
/*
* Found an active GPE. Dispatch the event to a handler
* or method.
*/
- int_status |= acpi_ev_gpe_dispatch (
- &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
- (u32) j + gpe_register_info->base_gpe_number);
+ int_status |=
+ acpi_ev_gpe_dispatch(&gpe_block->
+ event_info[(i *
+ ACPI_GPE_REGISTER_WIDTH)
+ +
+ j],
+ (u32) j +
+ gpe_register_info->
+ base_gpe_number);
}
}
}
@@ -474,13 +469,12 @@ acpi_ev_gpe_detect (
gpe_block = gpe_block->next;
}
-unlock_and_exit:
+ unlock_and_exit:
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return (int_status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_asynch_execute_gpe_method
@@ -497,45 +491,41 @@ unlock_and_exit:
*
******************************************************************************/
-static void ACPI_SYSTEM_XFACE
-acpi_ev_asynch_execute_gpe_method (
- void *context)
+static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
- struct acpi_gpe_event_info *gpe_event_info = (void *) context;
- u32 gpe_number = 0;
- acpi_status status;
- struct acpi_gpe_event_info local_gpe_event_info;
- struct acpi_parameter_info info;
-
+ struct acpi_gpe_event_info *gpe_event_info = (void *)context;
+ u32 gpe_number = 0;
+ acpi_status status;
+ struct acpi_gpe_event_info local_gpe_event_info;
+ struct acpi_parameter_info info;
- ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
+ ACPI_FUNCTION_TRACE("ev_asynch_execute_gpe_method");
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
return_VOID;
}
/* Must revalidate the gpe_number/gpe_block */
- if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
- status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
+ status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
return_VOID;
}
/* Set the GPE flags for return to enabled state */
- (void) acpi_ev_enable_gpe (gpe_event_info, FALSE);
+ (void)acpi_ev_enable_gpe(gpe_event_info, FALSE);
/*
* Take a snapshot of the GPE info for this level - we copy the
* info to prevent a race condition with remove_handler/remove_block.
*/
- ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info,
- sizeof (struct acpi_gpe_event_info));
+ ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info,
+ sizeof(struct acpi_gpe_event_info));
- status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
return_VOID;
}
@@ -544,44 +534,40 @@ acpi_ev_asynch_execute_gpe_method (
* time to avoid race with ev_gpe_install_handler
*/
if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD) {
+ ACPI_GPE_DISPATCH_METHOD) {
/*
* Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
* control method that corresponds to this GPE
*/
info.node = local_gpe_event_info.dispatch.method_node;
- info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
+ info.parameters =
+ ACPI_CAST_PTR(union acpi_operand_object *, gpe_event_info);
info.parameter_type = ACPI_PARAM_GPE;
- status = acpi_ns_evaluate_by_handle (&info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "%s while evaluating method [%4.4s] for GPE[%2X]\n",
- acpi_format_exception (status),
- acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
- gpe_number));
+ status = acpi_ns_evaluate_by_handle(&info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception(status), acpi_ut_get_node_name(local_gpe_event_info.dispatch.method_node), gpe_number));
}
}
if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
- ACPI_GPE_LEVEL_TRIGGERED) {
+ ACPI_GPE_LEVEL_TRIGGERED) {
/*
* GPE is level-triggered, we clear the GPE status bit after
* handling the event.
*/
- status = acpi_hw_clear_gpe (&local_gpe_event_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_clear_gpe(&local_gpe_event_info);
+ if (ACPI_FAILURE(status)) {
return_VOID;
}
}
/* Enable this GPE */
- (void) acpi_hw_write_gpe_enable_reg (&local_gpe_event_info);
+ (void)acpi_hw_write_gpe_enable_reg(&local_gpe_event_info);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_dispatch
@@ -599,38 +585,31 @@ acpi_ev_asynch_execute_gpe_method (
******************************************************************************/
u32
-acpi_ev_gpe_dispatch (
- struct acpi_gpe_event_info *gpe_event_info,
- u32 gpe_number)
+acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_gpe_dispatch");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_gpe_dispatch");
/*
* If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced.
*/
if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
- ACPI_GPE_EDGE_TRIGGERED) {
- status = acpi_hw_clear_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
- acpi_format_exception (status), gpe_number));
- return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+ ACPI_GPE_EDGE_TRIGGERED) {
+ status = acpi_hw_clear_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number));
+ return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
}
}
/* Save current system state */
if (acpi_gbl_system_awake_and_running) {
- ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
- }
- else {
- ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
+ ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
+ } else {
+ ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
}
/*
@@ -647,19 +626,19 @@ acpi_ev_gpe_dispatch (
* Invoke the installed handler (at interrupt level)
* Ignore return status for now. TBD: leave GPE disabled on error?
*/
- (void) gpe_event_info->dispatch.handler->address (
- gpe_event_info->dispatch.handler->context);
+ (void)gpe_event_info->dispatch.handler->address(gpe_event_info->
+ dispatch.
+ handler->
+ context);
/* It is now safe to clear level-triggered events. */
if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
- ACPI_GPE_LEVEL_TRIGGERED) {
- status = acpi_hw_clear_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
- acpi_format_exception (status), gpe_number));
- return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+ ACPI_GPE_LEVEL_TRIGGERED) {
+ status = acpi_hw_clear_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number));
+ return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
}
}
break;
@@ -670,24 +649,21 @@ acpi_ev_gpe_dispatch (
* Disable GPE, so it doesn't keep firing before the method has a
* chance to run.
*/
- status = acpi_ev_disable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
- acpi_format_exception (status), gpe_number));
- return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+ status = acpi_ev_disable_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number));
+ return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
}
/*
* Execute the method associated with the GPE
* NOTE: Level-triggered GPEs are cleared after the method completes.
*/
- status = acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
- acpi_ev_asynch_execute_gpe_method, gpe_event_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n",
- acpi_format_exception (status), gpe_number));
+ status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+ acpi_ev_asynch_execute_gpe_method,
+ gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n", acpi_format_exception(status), gpe_number));
}
break;
@@ -695,28 +671,23 @@ acpi_ev_gpe_dispatch (
/* No handler or method to run! */
- ACPI_REPORT_ERROR ((
- "acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n",
- gpe_number));
+ ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n", gpe_number));
/*
* Disable the GPE. The GPE will remain disabled until the ACPI
* Core Subsystem is restarted, or a handler is installed.
*/
- status = acpi_ev_disable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
- acpi_format_exception (status), gpe_number));
- return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+ status = acpi_ev_disable_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number));
+ return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
}
break;
}
- return_VALUE (ACPI_INTERRUPT_HANDLED);
+ return_VALUE(ACPI_INTERRUPT_HANDLED);
}
-
#ifdef ACPI_GPE_NOTIFY_CHECK
/*******************************************************************************
* TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
@@ -735,35 +706,29 @@ acpi_ev_gpe_dispatch (
******************************************************************************/
acpi_status
-acpi_ev_check_for_wake_only_gpe (
- struct acpi_gpe_event_info *gpe_event_info)
+acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
- acpi_status status;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_check_for_wake_only_gpe");
- ACPI_FUNCTION_TRACE ("ev_check_for_wake_only_gpe");
-
-
- if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */
- ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */ {
+ if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */
+ ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */
/* This must be a wake-only GPE, disable it */
- status = acpi_ev_disable_gpe (gpe_event_info);
+ status = acpi_ev_disable_gpe(gpe_event_info);
/* Set GPE to wake-only. Do not change wake disabled/enabled status */
- acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+ acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
- ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
- gpe_event_info));
+ ACPI_REPORT_INFO(("GPE %p was updated from wake/run to wake-only\n", gpe_event_info));
/* This was a wake-only GPE */
- return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
+ return_ACPI_STATUS(AE_WAKE_ONLY_GPE);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
#endif
-
-
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 84186a7d17b2..b312eb33c43e 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -46,41 +46,29 @@
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evgpeblk")
+ACPI_MODULE_NAME("evgpeblk")
/* Local prototypes */
-
static acpi_status
-acpi_ev_save_method_info (
- acpi_handle obj_handle,
- u32 level,
- void *obj_desc,
- void **return_value);
+acpi_ev_save_method_info(acpi_handle obj_handle,
+ u32 level, void *obj_desc, void **return_value);
static acpi_status
-acpi_ev_match_prw_and_gpe (
- acpi_handle obj_handle,
- u32 level,
- void *info,
- void **return_value);
+acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
+ u32 level, void *info, void **return_value);
-static struct acpi_gpe_xrupt_info *
-acpi_ev_get_gpe_xrupt_block (
- u32 interrupt_level);
+static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
+ interrupt_number);
static acpi_status
-acpi_ev_delete_gpe_xrupt (
- struct acpi_gpe_xrupt_info *gpe_xrupt);
+acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
static acpi_status
-acpi_ev_install_gpe_block (
- struct acpi_gpe_block_info *gpe_block,
- u32 interrupt_level);
+acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
+ u32 interrupt_number);
static acpi_status
-acpi_ev_create_gpe_info_blocks (
- struct acpi_gpe_block_info *gpe_block);
-
+acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block);
/*******************************************************************************
*
@@ -96,16 +84,12 @@ acpi_ev_create_gpe_info_blocks (
*
******************************************************************************/
-u8
-acpi_ev_valid_gpe_event (
- struct acpi_gpe_event_info *gpe_event_info)
+u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
{
- struct acpi_gpe_xrupt_info *gpe_xrupt_block;
- struct acpi_gpe_block_info *gpe_block;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_gpe_xrupt_info *gpe_xrupt_block;
+ struct acpi_gpe_block_info *gpe_block;
+ ACPI_FUNCTION_ENTRY();
/* No need for spin lock since we are not changing any list elements */
@@ -119,7 +103,10 @@ acpi_ev_valid_gpe_event (
while (gpe_block) {
if ((&gpe_block->event_info[0] <= gpe_event_info) &&
- (&gpe_block->event_info[((acpi_size) gpe_block->register_count) * 8] > gpe_event_info)) {
+ (&gpe_block->
+ event_info[((acpi_size) gpe_block->
+ register_count) * 8] >
+ gpe_event_info)) {
return (TRUE);
}
@@ -132,13 +119,11 @@ acpi_ev_valid_gpe_event (
return (FALSE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_walk_gpe_list
*
* PARAMETERS: gpe_walk_callback - Routine called for each GPE block
- * Flags - ACPI_NOT_ISR or ACPI_ISR
*
* RETURN: Status
*
@@ -146,20 +131,16 @@ acpi_ev_valid_gpe_event (
*
******************************************************************************/
-acpi_status
-acpi_ev_walk_gpe_list (
- ACPI_GPE_CALLBACK gpe_walk_callback,
- u32 flags)
+acpi_status acpi_ev_walk_gpe_list(ACPI_GPE_CALLBACK gpe_walk_callback)
{
- struct acpi_gpe_block_info *gpe_block;
- struct acpi_gpe_xrupt_info *gpe_xrupt_info;
- acpi_status status = AE_OK;
-
+ struct acpi_gpe_block_info *gpe_block;
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info;
+ acpi_status status = AE_OK;
+ u32 flags;
- ACPI_FUNCTION_TRACE ("ev_walk_gpe_list");
+ ACPI_FUNCTION_TRACE("ev_walk_gpe_list");
-
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, flags);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Walk the interrupt level descriptor list */
@@ -171,8 +152,8 @@ acpi_ev_walk_gpe_list (
while (gpe_block) {
/* One callback per GPE block */
- status = gpe_walk_callback (gpe_xrupt_info, gpe_block);
- if (ACPI_FAILURE (status)) {
+ status = gpe_walk_callback(gpe_xrupt_info, gpe_block);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
@@ -182,12 +163,11 @@ acpi_ev_walk_gpe_list (
gpe_xrupt_info = gpe_xrupt_info->next;
}
-unlock_and_exit:
- acpi_os_release_lock (acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_delete_gpe_handlers
@@ -203,17 +183,14 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_ev_delete_gpe_handlers (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block)
+acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block)
{
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_native_uint i;
- acpi_native_uint j;
-
-
- ACPI_FUNCTION_TRACE ("ev_delete_gpe_handlers");
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_native_uint i;
+ acpi_native_uint j;
+ ACPI_FUNCTION_TRACE("ev_delete_gpe_handlers");
/* Examine each GPE Register within the block */
@@ -221,21 +198,23 @@ acpi_ev_delete_gpe_handlers (
/* Now look at the individual GPEs in this byte register */
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
- gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info =
+ &gpe_block->
+ event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_HANDLER) {
- ACPI_MEM_FREE (gpe_event_info->dispatch.handler);
+ ACPI_GPE_DISPATCH_HANDLER) {
+ ACPI_MEM_FREE(gpe_event_info->dispatch.handler);
gpe_event_info->dispatch.handler = NULL;
- gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
+ gpe_event_info->flags &=
+ ~ACPI_GPE_DISPATCH_MASK;
}
}
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_save_method_info
@@ -259,30 +238,26 @@ acpi_ev_delete_gpe_handlers (
******************************************************************************/
static acpi_status
-acpi_ev_save_method_info (
- acpi_handle obj_handle,
- u32 level,
- void *obj_desc,
- void **return_value)
+acpi_ev_save_method_info(acpi_handle obj_handle,
+ u32 level, void *obj_desc, void **return_value)
{
- struct acpi_gpe_block_info *gpe_block = (void *) obj_desc;
- struct acpi_gpe_event_info *gpe_event_info;
- u32 gpe_number;
- char name[ACPI_NAME_SIZE + 1];
- u8 type;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_save_method_info");
+ struct acpi_gpe_block_info *gpe_block = (void *)obj_desc;
+ struct acpi_gpe_event_info *gpe_event_info;
+ u32 gpe_number;
+ char name[ACPI_NAME_SIZE + 1];
+ u8 type;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_save_method_info");
/*
* _Lxx and _Exx GPE method support
*
* 1) Extract the name from the object and convert to a string
*/
- ACPI_MOVE_32_TO_32 (name,
- &((struct acpi_namespace_node *) obj_handle)->name.integer);
+ ACPI_MOVE_32_TO_32(name,
+ &((struct acpi_namespace_node *)obj_handle)->name.
+ integer);
name[ACPI_NAME_SIZE] = 0;
/*
@@ -304,34 +279,36 @@ acpi_ev_save_method_info (
default:
/* Unknown method type, just ignore it! */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n",
- name));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n",
+ name));
+ return_ACPI_STATUS(AE_OK);
}
/* Convert the last two characters of the name to the GPE Number */
- gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
+ gpe_number = ACPI_STRTOUL(&name[2], NULL, 16);
if (gpe_number == ACPI_UINT32_MAX) {
/* Conversion failed; invalid method, just ignore it */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n",
- name));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n",
+ name));
+ return_ACPI_STATUS(AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
if ((gpe_number < gpe_block->block_base_number) ||
- (gpe_number >= (gpe_block->block_base_number + (gpe_block->register_count * 8)))) {
+ (gpe_number >=
+ (gpe_block->block_base_number +
+ (gpe_block->register_count * 8)))) {
/*
* Not valid for this GPE block, just ignore it
* However, it may be valid for a different GPE block, since GPE0 and GPE1
* methods both appear under \_GPE.
*/
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -339,24 +316,25 @@ acpi_ev_save_method_info (
* for use during dispatch of this GPE. Default type is RUNTIME, although
* this may change when the _PRW methods are executed later.
*/
- gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
+ gpe_event_info =
+ &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD |
- ACPI_GPE_TYPE_RUNTIME);
+ ACPI_GPE_TYPE_RUNTIME);
- gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *) obj_handle;
+ gpe_event_info->dispatch.method_node =
+ (struct acpi_namespace_node *)obj_handle;
/* Update enable mask, but don't enable the HW GPE as of yet */
- status = acpi_ev_enable_gpe (gpe_event_info, FALSE);
+ status = acpi_ev_enable_gpe(gpe_event_info, FALSE);
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
- "Registered GPE method %s as GPE number 0x%.2X\n",
- name, gpe_number));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
+ "Registered GPE method %s as GPE number 0x%.2X\n",
+ name, gpe_number));
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_match_prw_and_gpe
@@ -373,34 +351,29 @@ acpi_ev_save_method_info (
******************************************************************************/
static acpi_status
-acpi_ev_match_prw_and_gpe (
- acpi_handle obj_handle,
- u32 level,
- void *info,
- void **return_value)
+acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
+ u32 level, void *info, void **return_value)
{
- struct acpi_gpe_walk_info *gpe_info = (void *) info;
- struct acpi_namespace_node *gpe_device;
- struct acpi_gpe_block_info *gpe_block;
- struct acpi_namespace_node *target_gpe_device;
- struct acpi_gpe_event_info *gpe_event_info;
- union acpi_operand_object *pkg_desc;
- union acpi_operand_object *obj_desc;
- u32 gpe_number;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_match_prw_and_gpe");
-
+ struct acpi_gpe_walk_info *gpe_info = (void *)info;
+ struct acpi_namespace_node *gpe_device;
+ struct acpi_gpe_block_info *gpe_block;
+ struct acpi_namespace_node *target_gpe_device;
+ struct acpi_gpe_event_info *gpe_event_info;
+ union acpi_operand_object *pkg_desc;
+ union acpi_operand_object *obj_desc;
+ u32 gpe_number;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("ev_match_prw_and_gpe");
/* Check for a _PRW method under this device */
- status = acpi_ut_evaluate_object (obj_handle, METHOD_NAME__PRW,
- ACPI_BTYPE_PACKAGE, &pkg_desc);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_evaluate_object(obj_handle, METHOD_NAME__PRW,
+ ACPI_BTYPE_PACKAGE, &pkg_desc);
+ if (ACPI_FAILURE(status)) {
/* Ignore all errors from _PRW, we don't want to abort the subsystem */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* The returned _PRW package must have at least two elements */
@@ -420,7 +393,7 @@ acpi_ev_match_prw_and_gpe (
*/
obj_desc = pkg_desc->package.elements[0];
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
/* Use FADT-defined GPE device (from definition of _PRW) */
target_gpe_device = acpi_gbl_fadt_gpe_device;
@@ -428,22 +401,23 @@ acpi_ev_match_prw_and_gpe (
/* Integer is the GPE number in the FADT described GPE blocks */
gpe_number = (u32) obj_desc->integer.value;
- }
- else if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+ } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
/* Package contains a GPE reference and GPE number within a GPE block */
if ((obj_desc->package.count < 2) ||
- (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[0]) != ACPI_TYPE_LOCAL_REFERENCE) ||
- (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[1]) != ACPI_TYPE_INTEGER)) {
+ (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
+ ACPI_TYPE_LOCAL_REFERENCE)
+ || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
+ ACPI_TYPE_INTEGER)) {
goto cleanup;
}
/* Get GPE block reference and decode */
- target_gpe_device = obj_desc->package.elements[0]->reference.node;
+ target_gpe_device =
+ obj_desc->package.elements[0]->reference.node;
gpe_number = (u32) obj_desc->package.elements[1]->integer.value;
- }
- else {
+ } else {
/* Unknown type, just ignore it */
goto cleanup;
@@ -458,31 +432,37 @@ acpi_ev_match_prw_and_gpe (
* associated with the GPE device.
*/
if ((gpe_device == target_gpe_device) &&
- (gpe_number >= gpe_block->block_base_number) &&
- (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
+ (gpe_number >= gpe_block->block_base_number) &&
+ (gpe_number <
+ gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+ gpe_event_info =
+ &gpe_block->event_info[gpe_number -
+ gpe_block->block_base_number];
/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
- gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
- status = acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
- if (ACPI_FAILURE (status)) {
+ gpe_event_info->flags &=
+ ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+ status =
+ acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
+ status =
+ acpi_ev_update_gpe_enable_masks(gpe_event_info,
+ ACPI_GPE_DISABLE);
}
-cleanup:
- acpi_ut_remove_reference (pkg_desc);
- return_ACPI_STATUS (AE_OK);
+ cleanup:
+ acpi_ut_remove_reference(pkg_desc);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_xrupt_block
*
- * PARAMETERS: interrupt_level - Interrupt for a GPE block
+ * PARAMETERS: interrupt_number - Interrupt for a GPE block
*
* RETURN: A GPE interrupt block
*
@@ -493,24 +473,22 @@ cleanup:
*
******************************************************************************/
-static struct acpi_gpe_xrupt_info *
-acpi_ev_get_gpe_xrupt_block (
- u32 interrupt_level)
+static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
+ interrupt_number)
{
- struct acpi_gpe_xrupt_info *next_gpe_xrupt;
- struct acpi_gpe_xrupt_info *gpe_xrupt;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block");
+ struct acpi_gpe_xrupt_info *next_gpe_xrupt;
+ struct acpi_gpe_xrupt_info *gpe_xrupt;
+ acpi_status status;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("ev_get_gpe_xrupt_block");
/* No need for lock since we are not changing any list elements here */
next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
while (next_gpe_xrupt) {
- if (next_gpe_xrupt->interrupt_level == interrupt_level) {
- return_PTR (next_gpe_xrupt);
+ if (next_gpe_xrupt->interrupt_number == interrupt_number) {
+ return_PTR(next_gpe_xrupt);
}
next_gpe_xrupt = next_gpe_xrupt->next;
@@ -518,16 +496,16 @@ acpi_ev_get_gpe_xrupt_block (
/* Not found, must allocate a new xrupt descriptor */
- gpe_xrupt = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_xrupt_info));
+ gpe_xrupt = ACPI_MEM_CALLOCATE(sizeof(struct acpi_gpe_xrupt_info));
if (!gpe_xrupt) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
- gpe_xrupt->interrupt_level = interrupt_level;
+ gpe_xrupt->interrupt_number = interrupt_number;
/* Install new interrupt descriptor with spin lock */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
if (acpi_gbl_gpe_xrupt_list_head) {
next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
while (next_gpe_xrupt->next) {
@@ -536,29 +514,28 @@ acpi_ev_get_gpe_xrupt_block (
next_gpe_xrupt->next = gpe_xrupt;
gpe_xrupt->previous = next_gpe_xrupt;
- }
- else {
+ } else {
acpi_gbl_gpe_xrupt_list_head = gpe_xrupt;
}
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
/* Install new interrupt handler if not SCI_INT */
- if (interrupt_level != acpi_gbl_FADT->sci_int) {
- status = acpi_os_install_interrupt_handler (interrupt_level,
- acpi_ev_gpe_xrupt_handler, gpe_xrupt);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not install GPE interrupt handler at level 0x%X\n",
- interrupt_level));
- return_PTR (NULL);
+ if (interrupt_number != acpi_gbl_FADT->sci_int) {
+ status = acpi_os_install_interrupt_handler(interrupt_number,
+ acpi_ev_gpe_xrupt_handler,
+ gpe_xrupt);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not install GPE interrupt handler at level 0x%X\n",
+ interrupt_number));
+ return_PTR(NULL);
}
}
- return_PTR (gpe_xrupt);
+ return_PTR(gpe_xrupt);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_delete_gpe_xrupt
@@ -573,33 +550,31 @@ acpi_ev_get_gpe_xrupt_block (
******************************************************************************/
static acpi_status
-acpi_ev_delete_gpe_xrupt (
- struct acpi_gpe_xrupt_info *gpe_xrupt)
+acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_delete_gpe_xrupt");
+ acpi_status status;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("ev_delete_gpe_xrupt");
/* We never want to remove the SCI interrupt handler */
- if (gpe_xrupt->interrupt_level == acpi_gbl_FADT->sci_int) {
+ if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) {
gpe_xrupt->gpe_block_list_head = NULL;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Disable this interrupt */
- status = acpi_os_remove_interrupt_handler (gpe_xrupt->interrupt_level,
- acpi_ev_gpe_xrupt_handler);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
+ acpi_ev_gpe_xrupt_handler);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Unlink the interrupt block with lock */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
if (gpe_xrupt->previous) {
gpe_xrupt->previous->next = gpe_xrupt->next;
}
@@ -607,21 +582,20 @@ acpi_ev_delete_gpe_xrupt (
if (gpe_xrupt->next) {
gpe_xrupt->next->previous = gpe_xrupt->previous;
}
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
/* Free the block */
- ACPI_MEM_FREE (gpe_xrupt);
- return_ACPI_STATUS (AE_OK);
+ ACPI_MEM_FREE(gpe_xrupt);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_install_gpe_block
*
* PARAMETERS: gpe_block - New GPE block
- * interrupt_level - Level to be associated with this GPE block
+ * interrupt_number - Xrupt to be associated with this GPE block
*
* RETURN: Status
*
@@ -630,24 +604,22 @@ acpi_ev_delete_gpe_xrupt (
******************************************************************************/
static acpi_status
-acpi_ev_install_gpe_block (
- struct acpi_gpe_block_info *gpe_block,
- u32 interrupt_level)
+acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
+ u32 interrupt_number)
{
- struct acpi_gpe_block_info *next_gpe_block;
- struct acpi_gpe_xrupt_info *gpe_xrupt_block;
- acpi_status status;
+ struct acpi_gpe_block_info *next_gpe_block;
+ struct acpi_gpe_xrupt_info *gpe_xrupt_block;
+ acpi_status status;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("ev_install_gpe_block");
- ACPI_FUNCTION_TRACE ("ev_install_gpe_block");
-
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block (interrupt_level);
+ gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block(interrupt_number);
if (!gpe_xrupt_block) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
@@ -655,7 +627,7 @@ acpi_ev_install_gpe_block (
/* Install the new block at the end of the list with lock */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
if (gpe_xrupt_block->gpe_block_list_head) {
next_gpe_block = gpe_xrupt_block->gpe_block_list_head;
while (next_gpe_block->next) {
@@ -664,20 +636,18 @@ acpi_ev_install_gpe_block (
next_gpe_block->next = gpe_block;
gpe_block->previous = next_gpe_block;
- }
- else {
+ } else {
gpe_xrupt_block->gpe_block_list_head = gpe_block;
}
gpe_block->xrupt_block = gpe_xrupt_block;
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-unlock_and_exit:
- status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_delete_gpe_block
@@ -690,62 +660,57 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
-acpi_ev_delete_gpe_block (
- struct acpi_gpe_block_info *gpe_block)
+acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_install_gpe_block");
+ acpi_status status;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("ev_install_gpe_block");
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Disable all GPEs in this block */
- status = acpi_hw_disable_gpe_block (gpe_block->xrupt_block, gpe_block);
+ status = acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block);
if (!gpe_block->previous && !gpe_block->next) {
/* This is the last gpe_block on this interrupt */
- status = acpi_ev_delete_gpe_xrupt (gpe_block->xrupt_block);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- }
- else {
+ } else {
/* Remove the block on this interrupt with lock */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
if (gpe_block->previous) {
gpe_block->previous->next = gpe_block->next;
- }
- else {
- gpe_block->xrupt_block->gpe_block_list_head = gpe_block->next;
+ } else {
+ gpe_block->xrupt_block->gpe_block_list_head =
+ gpe_block->next;
}
if (gpe_block->next) {
gpe_block->next->previous = gpe_block->previous;
}
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
}
/* Free the gpe_block */
- ACPI_MEM_FREE (gpe_block->register_info);
- ACPI_MEM_FREE (gpe_block->event_info);
- ACPI_MEM_FREE (gpe_block);
+ ACPI_MEM_FREE(gpe_block->register_info);
+ ACPI_MEM_FREE(gpe_block->event_info);
+ ACPI_MEM_FREE(gpe_block);
-unlock_and_exit:
- status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_create_gpe_info_blocks
@@ -759,43 +724,41 @@ unlock_and_exit:
******************************************************************************/
static acpi_status
-acpi_ev_create_gpe_info_blocks (
- struct acpi_gpe_block_info *gpe_block)
+acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
{
- struct acpi_gpe_register_info *gpe_register_info = NULL;
- struct acpi_gpe_event_info *gpe_event_info = NULL;
- struct acpi_gpe_event_info *this_event;
- struct acpi_gpe_register_info *this_register;
- acpi_native_uint i;
- acpi_native_uint j;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_create_gpe_info_blocks");
+ struct acpi_gpe_register_info *gpe_register_info = NULL;
+ struct acpi_gpe_event_info *gpe_event_info = NULL;
+ struct acpi_gpe_event_info *this_event;
+ struct acpi_gpe_register_info *this_register;
+ acpi_native_uint i;
+ acpi_native_uint j;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_create_gpe_info_blocks");
/* Allocate the GPE register information block */
- gpe_register_info = ACPI_MEM_CALLOCATE (
- (acpi_size) gpe_block->register_count *
- sizeof (struct acpi_gpe_register_info));
+ gpe_register_info = ACPI_MEM_CALLOCATE((acpi_size) gpe_block->
+ register_count *
+ sizeof(struct
+ acpi_gpe_register_info));
if (!gpe_register_info) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not allocate the gpe_register_info table\n"));
- return_ACPI_STATUS (AE_NO_MEMORY);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not allocate the gpe_register_info table\n"));
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
* Allocate the GPE event_info block. There are eight distinct GPEs
* per register. Initialization to zeros is sufficient.
*/
- gpe_event_info = ACPI_MEM_CALLOCATE (
- ((acpi_size) gpe_block->register_count *
- ACPI_GPE_REGISTER_WIDTH) *
- sizeof (struct acpi_gpe_event_info));
+ gpe_event_info = ACPI_MEM_CALLOCATE(((acpi_size) gpe_block->
+ register_count *
+ ACPI_GPE_REGISTER_WIDTH) *
+ sizeof(struct acpi_gpe_event_info));
if (!gpe_event_info) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not allocate the gpe_event_info table\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not allocate the gpe_event_info table\n"));
status = AE_NO_MEMORY;
goto error_exit;
}
@@ -803,7 +766,7 @@ acpi_ev_create_gpe_info_blocks (
/* Save the new Info arrays in the GPE block */
gpe_block->register_info = gpe_register_info;
- gpe_block->event_info = gpe_event_info;
+ gpe_block->event_info = gpe_event_info;
/*
* Initialize the GPE Register and Event structures. A goal of these
@@ -812,29 +775,34 @@ acpi_ev_create_gpe_info_blocks (
* and the enable registers occupy the second half.
*/
this_register = gpe_register_info;
- this_event = gpe_event_info;
+ this_event = gpe_event_info;
for (i = 0; i < gpe_block->register_count; i++) {
/* Init the register_info for this GPE register (8 GPEs) */
- this_register->base_gpe_number = (u8) (gpe_block->block_base_number +
- (i * ACPI_GPE_REGISTER_WIDTH));
-
- ACPI_STORE_ADDRESS (this_register->status_address.address,
- (gpe_block->block_address.address
- + i));
-
- ACPI_STORE_ADDRESS (this_register->enable_address.address,
- (gpe_block->block_address.address
- + i
- + gpe_block->register_count));
-
- this_register->status_address.address_space_id = gpe_block->block_address.address_space_id;
- this_register->enable_address.address_space_id = gpe_block->block_address.address_space_id;
- this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
- this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
- this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
- this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+ this_register->base_gpe_number =
+ (u8) (gpe_block->block_base_number +
+ (i * ACPI_GPE_REGISTER_WIDTH));
+
+ ACPI_STORE_ADDRESS(this_register->status_address.address,
+ (gpe_block->block_address.address + i));
+
+ ACPI_STORE_ADDRESS(this_register->enable_address.address,
+ (gpe_block->block_address.address
+ + i + gpe_block->register_count));
+
+ this_register->status_address.address_space_id =
+ gpe_block->block_address.address_space_id;
+ this_register->enable_address.address_space_id =
+ gpe_block->block_address.address_space_id;
+ this_register->status_address.register_bit_width =
+ ACPI_GPE_REGISTER_WIDTH;
+ this_register->enable_address.register_bit_width =
+ ACPI_GPE_REGISTER_WIDTH;
+ this_register->status_address.register_bit_offset =
+ ACPI_GPE_REGISTER_WIDTH;
+ this_register->enable_address.register_bit_offset =
+ ACPI_GPE_REGISTER_WIDTH;
/* Init the event_info for each GPE within this register */
@@ -849,36 +817,36 @@ acpi_ev_create_gpe_info_blocks (
* are cleared by writing a '1', while enable registers are cleared
* by writing a '0'.
*/
- status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,
- &this_register->enable_address);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0x00,
+ &this_register->
+ enable_address);
+ if (ACPI_FAILURE(status)) {
goto error_exit;
}
- status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,
- &this_register->status_address);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0xFF,
+ &this_register->
+ status_address);
+ if (ACPI_FAILURE(status)) {
goto error_exit;
}
this_register++;
}
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(AE_OK);
-error_exit:
+ error_exit:
if (gpe_register_info) {
- ACPI_MEM_FREE (gpe_register_info);
+ ACPI_MEM_FREE(gpe_register_info);
}
if (gpe_event_info) {
- ACPI_MEM_FREE (gpe_event_info);
+ ACPI_MEM_FREE(gpe_event_info);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_create_gpe_block
@@ -887,7 +855,7 @@ error_exit:
* gpe_block_address - Address and space_iD
* register_count - Number of GPE register pairs in the block
* gpe_block_base_number - Starting GPE number for the block
- * interrupt_level - H/W interrupt for the block
+ * interrupt_number - H/W interrupt for the block
* return_gpe_block - Where the new block descriptor is returned
*
* RETURN: Status
@@ -897,68 +865,66 @@ error_exit:
******************************************************************************/
acpi_status
-acpi_ev_create_gpe_block (
- struct acpi_namespace_node *gpe_device,
- struct acpi_generic_address *gpe_block_address,
- u32 register_count,
- u8 gpe_block_base_number,
- u32 interrupt_level,
- struct acpi_gpe_block_info **return_gpe_block)
+acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
+ struct acpi_generic_address *gpe_block_address,
+ u32 register_count,
+ u8 gpe_block_base_number,
+ u32 interrupt_number,
+ struct acpi_gpe_block_info **return_gpe_block)
{
- struct acpi_gpe_block_info *gpe_block;
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_native_uint i;
- acpi_native_uint j;
- u32 wake_gpe_count;
- u32 gpe_enabled_count;
- acpi_status status;
- struct acpi_gpe_walk_info gpe_info;
-
-
- ACPI_FUNCTION_TRACE ("ev_create_gpe_block");
+ struct acpi_gpe_block_info *gpe_block;
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_native_uint i;
+ acpi_native_uint j;
+ u32 wake_gpe_count;
+ u32 gpe_enabled_count;
+ acpi_status status;
+ struct acpi_gpe_walk_info gpe_info;
+ ACPI_FUNCTION_TRACE("ev_create_gpe_block");
if (!register_count) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Allocate a new GPE block */
- gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info));
+ gpe_block = ACPI_MEM_CALLOCATE(sizeof(struct acpi_gpe_block_info));
if (!gpe_block) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize the new GPE block */
gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number;
- gpe_block->node = gpe_device;
+ gpe_block->node = gpe_device;
- ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address,
- sizeof (struct acpi_generic_address));
+ ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
+ sizeof(struct acpi_generic_address));
/* Create the register_info and event_info sub-structures */
- status = acpi_ev_create_gpe_info_blocks (gpe_block);
- if (ACPI_FAILURE (status)) {
- ACPI_MEM_FREE (gpe_block);
- return_ACPI_STATUS (status);
+ status = acpi_ev_create_gpe_info_blocks(gpe_block);
+ if (ACPI_FAILURE(status)) {
+ ACPI_MEM_FREE(gpe_block);
+ return_ACPI_STATUS(status);
}
/* Install the new block in the global list(s) */
- status = acpi_ev_install_gpe_block (gpe_block, interrupt_level);
- if (ACPI_FAILURE (status)) {
- ACPI_MEM_FREE (gpe_block);
- return_ACPI_STATUS (status);
+ status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
+ if (ACPI_FAILURE(status)) {
+ ACPI_MEM_FREE(gpe_block);
+ return_ACPI_STATUS(status);
}
/* Find all GPE methods (_Lxx, _Exx) for this block */
- status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
- ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info,
- gpe_block, NULL);
+ status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
+ acpi_ev_save_method_info, gpe_block,
+ NULL);
/*
* Runtime option: Should Wake GPEs be enabled at runtime? The default
@@ -974,9 +940,11 @@ acpi_ev_create_gpe_block (
gpe_info.gpe_block = gpe_block;
gpe_info.gpe_device = gpe_device;
- status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_match_prw_and_gpe,
- &gpe_info, NULL);
+ status =
+ acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
+ acpi_ev_match_prw_and_gpe, &gpe_info,
+ NULL);
}
/*
@@ -991,10 +959,14 @@ acpi_ev_create_gpe_block (
for (j = 0; j < 8; j++) {
/* Get the info block for this particular GPE */
- gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info =
+ &gpe_block->
+ event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
- if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) &&
- (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+ if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_METHOD)
+ && (gpe_event_info->
+ flags & ACPI_GPE_TYPE_RUNTIME)) {
gpe_enabled_count++;
}
@@ -1006,22 +978,22 @@ acpi_ev_create_gpe_block (
/* Dump info about this GPE block */
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
- (u32) gpe_block->block_base_number,
- (u32) (gpe_block->block_base_number +
- ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
- gpe_device->name.ascii,
- gpe_block->register_count,
- interrupt_level));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
+ (u32) gpe_block->block_base_number,
+ (u32) (gpe_block->block_base_number +
+ ((gpe_block->register_count *
+ ACPI_GPE_REGISTER_WIDTH) - 1)),
+ gpe_device->name.ascii, gpe_block->register_count,
+ interrupt_number));
/* Enable all valid GPEs found above */
- status = acpi_hw_enable_runtime_gpe_block (NULL, gpe_block);
+ status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block);
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
- wake_gpe_count, gpe_enabled_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
+ wake_gpe_count, gpe_enabled_count));
/* Return the new block */
@@ -1029,10 +1001,9 @@ acpi_ev_create_gpe_block (
(*return_gpe_block) = gpe_block;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_initialize
@@ -1045,22 +1016,18 @@ acpi_ev_create_gpe_block (
*
******************************************************************************/
-acpi_status
-acpi_ev_gpe_initialize (
- void)
+acpi_status acpi_ev_gpe_initialize(void)
{
- u32 register_count0 = 0;
- u32 register_count1 = 0;
- u32 gpe_number_max = 0;
- acpi_status status;
+ u32 register_count0 = 0;
+ u32 register_count1 = 0;
+ u32 gpe_number_max = 0;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_gpe_initialize");
- ACPI_FUNCTION_TRACE ("ev_gpe_initialize");
-
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -1088,29 +1055,29 @@ acpi_ev_gpe_initialize (
* If EITHER the register length OR the block address are zero, then that
* particular block is not supported.
*/
- if (acpi_gbl_FADT->gpe0_blk_len &&
- acpi_gbl_FADT->xgpe0_blk.address) {
+ if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) {
/* GPE block 0 exists (has both length and address > 0) */
register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2);
- gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
+ gpe_number_max =
+ (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
/* Install GPE Block 0 */
- status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device,
- &acpi_gbl_FADT->xgpe0_blk, register_count0, 0,
- acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
+ status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
+ &acpi_gbl_FADT->xgpe0_blk,
+ register_count0, 0,
+ acpi_gbl_FADT->sci_int,
+ &acpi_gbl_gpe_fadt_blocks[0]);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Could not create GPE Block 0, %s\n",
- acpi_format_exception (status)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not create GPE Block 0, %s\n",
+ acpi_format_exception(status)));
}
}
- if (acpi_gbl_FADT->gpe1_blk_len &&
- acpi_gbl_FADT->xgpe1_blk.address) {
+ if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) {
/* GPE block 1 exists (has both length and address > 0) */
register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2);
@@ -1118,29 +1085,26 @@ acpi_ev_gpe_initialize (
/* Check for GPE0/GPE1 overlap (if both banks exist) */
if ((register_count0) &&
- (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
- ACPI_REPORT_ERROR ((
- "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
- gpe_number_max, acpi_gbl_FADT->gpe1_base,
- acpi_gbl_FADT->gpe1_base +
- ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
+ (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
+ ACPI_REPORT_ERROR(("GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n", gpe_number_max, acpi_gbl_FADT->gpe1_base, acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
/* Ignore GPE1 block by setting the register count to zero */
register_count1 = 0;
- }
- else {
+ } else {
/* Install GPE Block 1 */
- status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device,
- &acpi_gbl_FADT->xgpe1_blk, register_count1,
- acpi_gbl_FADT->gpe1_base,
- acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[1]);
-
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Could not create GPE Block 1, %s\n",
- acpi_format_exception (status)));
+ status =
+ acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
+ &acpi_gbl_FADT->xgpe1_blk,
+ register_count1,
+ acpi_gbl_FADT->gpe1_base,
+ acpi_gbl_FADT->sci_int,
+ &acpi_gbl_gpe_fadt_blocks
+ [1]);
+
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not create GPE Block 1, %s\n", acpi_format_exception(status)));
}
/*
@@ -1148,7 +1112,7 @@ acpi_ev_gpe_initialize (
* space. However, GPE0 always starts at GPE number zero.
*/
gpe_number_max = acpi_gbl_FADT->gpe1_base +
- ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+ ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
}
}
@@ -1157,8 +1121,8 @@ acpi_ev_gpe_initialize (
if ((register_count0 + register_count1) == 0) {
/* GPEs are not required by ACPI, this is OK */
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "There are no GPE blocks defined in the FADT\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "There are no GPE blocks defined in the FADT\n"));
status = AE_OK;
goto cleanup;
}
@@ -1166,15 +1130,12 @@ acpi_ev_gpe_initialize (
/* Check for Max GPE number out-of-range */
if (gpe_number_max > ACPI_GPE_MAX) {
- ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
- gpe_number_max));
+ ACPI_REPORT_ERROR(("Maximum GPE number from FADT is too large: 0x%X\n", gpe_number_max));
status = AE_BAD_VALUE;
goto cleanup;
}
-cleanup:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (AE_OK);
+ cleanup:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 659e90956112..7e57b8470f55 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -47,12 +47,10 @@
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evmisc")
-
+ACPI_MODULE_NAME("evmisc")
#ifdef ACPI_DEBUG_OUTPUT
-static const char *acpi_notify_value_names[] =
-{
+static const char *acpi_notify_value_names[] = {
"Bus Check",
"Device Check",
"Device Wake",
@@ -66,18 +64,11 @@ static const char *acpi_notify_value_names[] =
/* Local prototypes */
-static void ACPI_SYSTEM_XFACE
-acpi_ev_notify_dispatch (
- void *context);
-
-static void ACPI_SYSTEM_XFACE
-acpi_ev_global_lock_thread (
- void *context);
+static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
-static u32
-acpi_ev_global_lock_handler (
- void *context);
+static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context);
+static u32 acpi_ev_global_lock_handler(void *context);
/*******************************************************************************
*
@@ -93,9 +84,7 @@ acpi_ev_global_lock_handler (
*
******************************************************************************/
-u8
-acpi_ev_is_notify_object (
- struct acpi_namespace_node *node)
+u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
{
switch (node->type) {
case ACPI_TYPE_DEVICE:
@@ -112,7 +101,6 @@ acpi_ev_is_notify_object (
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_queue_notify_request
@@ -128,18 +116,15 @@ acpi_ev_is_notify_object (
******************************************************************************/
acpi_status
-acpi_ev_queue_notify_request (
- struct acpi_namespace_node *node,
- u32 notify_value)
+acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
+ u32 notify_value)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *handler_obj = NULL;
- union acpi_generic_state *notify_info;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_NAME ("ev_queue_notify_request");
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *handler_obj = NULL;
+ union acpi_generic_state *notify_info;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_NAME("ev_queue_notify_request");
/*
* For value 3 (Ejection Request), some device method may need to be run.
@@ -148,22 +133,22 @@ acpi_ev_queue_notify_request (
* For value 0x80 (Status Change) on the power button or sleep button,
* initiate soft-off or sleep operation?
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Dispatching Notify(%X) on node %p\n", notify_value, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Dispatching Notify(%X) on node %p\n", notify_value,
+ node));
if (notify_value <= 7) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: %s\n",
- acpi_notify_value_names[notify_value]));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Notify value: 0x%2.2X **Device Specific**\n",
- notify_value));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n",
+ acpi_notify_value_names[notify_value]));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Notify value: 0x%2.2X **Device Specific**\n",
+ notify_value));
}
/* Get the notify object attached to the NS Node */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {
/* We have the notify object, Get the right handler */
@@ -174,10 +159,11 @@ acpi_ev_queue_notify_request (
case ACPI_TYPE_POWER:
if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
- handler_obj = obj_desc->common_notify.system_notify;
- }
- else {
- handler_obj = obj_desc->common_notify.device_notify;
+ handler_obj =
+ obj_desc->common_notify.system_notify;
+ } else {
+ handler_obj =
+ obj_desc->common_notify.device_notify;
}
break;
@@ -189,23 +175,25 @@ acpi_ev_queue_notify_request (
/* If there is any handler to run, schedule the dispatcher */
- if ((acpi_gbl_system_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
- (acpi_gbl_device_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
- handler_obj) {
- notify_info = acpi_ut_create_generic_state ();
+ if ((acpi_gbl_system_notify.handler
+ && (notify_value <= ACPI_MAX_SYS_NOTIFY))
+ || (acpi_gbl_device_notify.handler
+ && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+ notify_info = acpi_ut_create_generic_state();
if (!notify_info) {
return (AE_NO_MEMORY);
}
notify_info->common.data_type = ACPI_DESC_TYPE_STATE_NOTIFY;
- notify_info->notify.node = node;
- notify_info->notify.value = (u16) notify_value;
+ notify_info->notify.node = node;
+ notify_info->notify.value = (u16) notify_value;
notify_info->notify.handler_obj = handler_obj;
- status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH,
- acpi_ev_notify_dispatch, notify_info);
- if (ACPI_FAILURE (status)) {
- acpi_ut_delete_generic_state (notify_info);
+ status = acpi_os_queue_for_execution(OSD_PRIORITY_HIGH,
+ acpi_ev_notify_dispatch,
+ notify_info);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_delete_generic_state(notify_info);
}
}
@@ -214,15 +202,15 @@ acpi_ev_queue_notify_request (
* There is no per-device notify handler for this device.
* This may or may not be a problem.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "No notify handler for Notify(%4.4s, %X) node %p\n",
- acpi_ut_get_node_name (node), notify_value, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "No notify handler for Notify(%4.4s, %X) node %p\n",
+ acpi_ut_get_node_name(node), notify_value,
+ node));
}
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_notify_dispatch
@@ -236,18 +224,15 @@ acpi_ev_queue_notify_request (
*
******************************************************************************/
-static void ACPI_SYSTEM_XFACE
-acpi_ev_notify_dispatch (
- void *context)
+static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
{
- union acpi_generic_state *notify_info = (union acpi_generic_state *) context;
- acpi_notify_handler global_handler = NULL;
- void *global_context = NULL;
- union acpi_operand_object *handler_obj;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_generic_state *notify_info =
+ (union acpi_generic_state *)context;
+ acpi_notify_handler global_handler = NULL;
+ void *global_context = NULL;
+ union acpi_operand_object *handler_obj;
+ ACPI_FUNCTION_ENTRY();
/*
* We will invoke a global notify handler if installed.
@@ -261,8 +246,7 @@ acpi_ev_notify_dispatch (
global_handler = acpi_gbl_system_notify.handler;
global_context = acpi_gbl_system_notify.context;
}
- }
- else {
+ } else {
/* Global driver notification handler */
if (acpi_gbl_device_notify.handler) {
@@ -274,25 +258,24 @@ acpi_ev_notify_dispatch (
/* Invoke the system handler first, if present */
if (global_handler) {
- global_handler (notify_info->notify.node, notify_info->notify.value,
- global_context);
+ global_handler(notify_info->notify.node,
+ notify_info->notify.value, global_context);
}
/* Now invoke the per-device handler, if present */
handler_obj = notify_info->notify.handler_obj;
if (handler_obj) {
- handler_obj->notify.handler (notify_info->notify.node,
- notify_info->notify.value,
- handler_obj->notify.context);
+ handler_obj->notify.handler(notify_info->notify.node,
+ notify_info->notify.value,
+ handler_obj->notify.context);
}
/* All done with the info object */
- acpi_ut_delete_generic_state (notify_info);
+ acpi_ut_delete_generic_state(notify_info);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_global_lock_thread
@@ -307,27 +290,24 @@ acpi_ev_notify_dispatch (
*
******************************************************************************/
-static void ACPI_SYSTEM_XFACE
-acpi_ev_global_lock_thread (
- void *context)
+static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context)
{
- acpi_status status;
-
+ acpi_status status;
/* Signal threads that are waiting for the lock */
if (acpi_gbl_global_lock_thread_count) {
/* Send sufficient units to the semaphore */
- status = acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore,
- acpi_gbl_global_lock_thread_count);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n"));
+ status =
+ acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore,
+ acpi_gbl_global_lock_thread_count);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not signal Global Lock semaphore\n"));
}
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_global_lock_handler
@@ -342,20 +322,17 @@ acpi_ev_global_lock_thread (
*
******************************************************************************/
-static u32
-acpi_ev_global_lock_handler (
- void *context)
+static u32 acpi_ev_global_lock_handler(void *context)
{
- u8 acquired = FALSE;
- acpi_status status;
-
+ u8 acquired = FALSE;
+ acpi_status status;
/*
* Attempt to get the lock
* If we don't get it now, it will be marked pending and we will
* take another interrupt when it becomes free.
*/
- ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired);
+ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
if (acquired) {
/* Got the lock, now wake all threads waiting for it */
@@ -363,11 +340,11 @@ acpi_ev_global_lock_handler (
/* Run the Global Lock thread which will signal all waiting threads */
- status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH,
- acpi_ev_global_lock_thread, context);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not queue Global Lock thread, %s\n",
- acpi_format_exception (status)));
+ status = acpi_os_queue_for_execution(OSD_PRIORITY_HIGH,
+ acpi_ev_global_lock_thread,
+ context);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not queue Global Lock thread, %s\n", acpi_format_exception(status)));
return (ACPI_INTERRUPT_NOT_HANDLED);
}
@@ -376,7 +353,6 @@ acpi_ev_global_lock_handler (
return (ACPI_INTERRUPT_HANDLED);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_init_global_lock_handler
@@ -389,19 +365,16 @@ acpi_ev_global_lock_handler (
*
******************************************************************************/
-acpi_status
-acpi_ev_init_global_lock_handler (
- void)
+acpi_status acpi_ev_init_global_lock_handler(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_init_global_lock_handler");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_init_global_lock_handler");
acpi_gbl_global_lock_present = TRUE;
- status = acpi_install_fixed_event_handler (ACPI_EVENT_GLOBAL,
- acpi_ev_global_lock_handler, NULL);
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
+ acpi_ev_global_lock_handler,
+ NULL);
/*
* If the global lock does not exist on this platform, the attempt
@@ -411,14 +384,15 @@ acpi_ev_init_global_lock_handler (
* with an error.
*/
if (status == AE_NO_HARDWARE_RESPONSE) {
+ ACPI_REPORT_ERROR(("No response from Global Lock hardware, disabling lock\n"));
+
acpi_gbl_global_lock_present = FALSE;
status = AE_OK;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_ev_acquire_global_lock
@@ -431,22 +405,18 @@ acpi_ev_init_global_lock_handler (
*
*****************************************************************************/
-acpi_status
-acpi_ev_acquire_global_lock (
- u16 timeout)
+acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
- acpi_status status = AE_OK;
- u8 acquired = FALSE;
-
-
- ACPI_FUNCTION_TRACE ("ev_acquire_global_lock");
+ acpi_status status = AE_OK;
+ u8 acquired = FALSE;
+ ACPI_FUNCTION_TRACE("ev_acquire_global_lock");
#ifndef ACPI_APPLICATION
/* Make sure that we actually have a global lock */
if (!acpi_gbl_global_lock_present) {
- return_ACPI_STATUS (AE_NO_GLOBAL_LOCK);
+ return_ACPI_STATUS(AE_NO_GLOBAL_LOCK);
}
#endif
@@ -459,37 +429,37 @@ acpi_ev_acquire_global_lock (
* we are done
*/
if (acpi_gbl_global_lock_acquired) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* We must acquire the actual hardware lock */
- ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired);
+ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
if (acquired) {
- /* We got the lock */
+ /* We got the lock */
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Acquired the HW Global Lock\n"));
acpi_gbl_global_lock_acquired = TRUE;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
* Did not get the lock. The pending bit was set above, and we must now
* wait until we get the global lock released interrupt.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n"));
/*
* Acquire the global lock semaphore first.
* Since this wait will block, we must release the interpreter
*/
- status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore,
- timeout);
- return_ACPI_STATUS (status);
+ status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
+ timeout);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_release_global_lock
@@ -502,21 +472,16 @@ acpi_ev_acquire_global_lock (
*
******************************************************************************/
-acpi_status
-acpi_ev_release_global_lock (
- void)
+acpi_status acpi_ev_release_global_lock(void)
{
- u8 pending = FALSE;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ev_release_global_lock");
+ u8 pending = FALSE;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ev_release_global_lock");
if (!acpi_gbl_global_lock_thread_count) {
- ACPI_REPORT_WARNING((
- "Cannot release HW Global Lock, it has not been acquired\n"));
- return_ACPI_STATUS (AE_NOT_ACQUIRED);
+ ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n"));
+ return_ACPI_STATUS(AE_NOT_ACQUIRED);
}
/* One fewer thread has the global lock */
@@ -525,14 +490,14 @@ acpi_ev_release_global_lock (
if (acpi_gbl_global_lock_thread_count) {
/* There are still some threads holding the lock, cannot release */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
* No more threads holding lock, we can do the actual hardware
* release
*/
- ACPI_RELEASE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, pending);
+ ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, pending);
acpi_gbl_global_lock_acquired = FALSE;
/*
@@ -540,14 +505,13 @@ acpi_ev_release_global_lock (
* register
*/
if (pending) {
- status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
- 1, ACPI_MTX_LOCK);
+ status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+ 1, ACPI_MTX_LOCK);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_ev_terminate
@@ -560,16 +524,12 @@ acpi_ev_release_global_lock (
*
******************************************************************************/
-void
-acpi_ev_terminate (
- void)
+void acpi_ev_terminate(void)
{
- acpi_native_uint i;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_terminate");
+ acpi_native_uint i;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_terminate");
if (acpi_gbl_events_initialized) {
/*
@@ -580,38 +540,39 @@ acpi_ev_terminate (
/* Disable all fixed events */
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
- status = acpi_disable_event ((u32) i, 0);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not disable fixed event %d\n", (u32) i));
+ status = acpi_disable_event((u32) i, 0);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not disable fixed event %d\n",
+ (u32) i));
}
}
/* Disable all GPEs in all GPE blocks */
- status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, ACPI_NOT_ISR);
+ status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block);
/* Remove SCI handler */
- status = acpi_ev_remove_sci_handler ();
+ status = acpi_ev_remove_sci_handler();
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not remove SCI handler\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not remove SCI handler\n"));
}
}
/* Deallocate all handler objects installed within GPE info structs */
- status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers, ACPI_NOT_ISR);
+ status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers);
/* Return to original mode if necessary */
if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
- status = acpi_disable ();
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_disable failed\n"));
+ status = acpi_disable();
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "acpi_disable failed\n"));
}
}
return_VOID;
}
-
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index a1d7276c5742..84fad082d80d 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -41,39 +41,30 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acevents.h>
#include <acpi/acnamesp.h>
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evregion")
-
+ACPI_MODULE_NAME("evregion")
#define ACPI_NUM_DEFAULT_SPACES 4
-
-static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
- ACPI_ADR_SPACE_SYSTEM_MEMORY,
- ACPI_ADR_SPACE_SYSTEM_IO,
- ACPI_ADR_SPACE_PCI_CONFIG,
- ACPI_ADR_SPACE_DATA_TABLE};
+static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
+ ACPI_ADR_SPACE_SYSTEM_MEMORY,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_ADR_SPACE_DATA_TABLE
+};
/* Local prototypes */
static acpi_status
-acpi_ev_reg_run (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value);
+acpi_ev_reg_run(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value);
static acpi_status
-acpi_ev_install_handler (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value);
-
+acpi_ev_install_handler(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value);
/*******************************************************************************
*
@@ -87,19 +78,16 @@ acpi_ev_install_handler (
*
******************************************************************************/
-acpi_status
-acpi_ev_install_region_handlers (
- void) {
- acpi_status status;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_TRACE ("ev_install_region_handlers");
+acpi_status acpi_ev_install_region_handlers(void)
+{
+ acpi_status status;
+ acpi_native_uint i;
+ ACPI_FUNCTION_TRACE("ev_install_region_handlers");
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -121,9 +109,11 @@ acpi_ev_install_region_handlers (
* Similar for AE_SAME_HANDLER.
*/
for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
- status = acpi_ev_install_space_handler (acpi_gbl_root_node,
- acpi_gbl_default_address_spaces[i],
- ACPI_DEFAULT_HANDLER, NULL, NULL);
+ status = acpi_ev_install_space_handler(acpi_gbl_root_node,
+ acpi_gbl_default_address_spaces
+ [i],
+ ACPI_DEFAULT_HANDLER,
+ NULL, NULL);
switch (status) {
case AE_OK:
case AE_SAME_HANDLER:
@@ -140,12 +130,11 @@ acpi_ev_install_region_handlers (
}
}
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_initialize_op_regions
@@ -159,20 +148,16 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
-acpi_ev_initialize_op_regions (
- void)
+acpi_status acpi_ev_initialize_op_regions(void)
{
- acpi_status status;
- acpi_native_uint i;
-
+ acpi_status status;
+ acpi_native_uint i;
- ACPI_FUNCTION_TRACE ("ev_initialize_op_regions");
+ ACPI_FUNCTION_TRACE("ev_initialize_op_regions");
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -182,15 +167,15 @@ acpi_ev_initialize_op_regions (
/* TBD: Make sure handler is the DEFAULT handler, otherwise
* _REG will have already been run.
*/
- status = acpi_ev_execute_reg_methods (acpi_gbl_root_node,
- acpi_gbl_default_address_spaces[i]);
+ status = acpi_ev_execute_reg_methods(acpi_gbl_root_node,
+ acpi_gbl_default_address_spaces
+ [i]);
}
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_execute_reg_method
@@ -205,26 +190,22 @@ acpi_ev_initialize_op_regions (
******************************************************************************/
acpi_status
-acpi_ev_execute_reg_method (
- union acpi_operand_object *region_obj,
- u32 function)
+acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
{
- struct acpi_parameter_info info;
- union acpi_operand_object *params[3];
- union acpi_operand_object *region_obj2;
- acpi_status status;
-
+ struct acpi_parameter_info info;
+ union acpi_operand_object *params[3];
+ union acpi_operand_object *region_obj2;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("ev_execute_reg_method");
+ ACPI_FUNCTION_TRACE("ev_execute_reg_method");
-
- region_obj2 = acpi_ns_get_secondary_object (region_obj);
+ region_obj2 = acpi_ns_get_secondary_object(region_obj);
if (!region_obj2) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
if (region_obj2->extra.method_REG == NULL) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -237,12 +218,12 @@ acpi_ev_execute_reg_method (
* 0 for disconnecting the handler
* Passed as a parameter
*/
- params[0] = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ params[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!params[0]) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- params[1] = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ params[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!params[1]) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -260,19 +241,18 @@ acpi_ev_execute_reg_method (
/* Execute the method, no return value */
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (
- ACPI_TYPE_METHOD, info.node, NULL));
- status = acpi_ns_evaluate_by_handle (&info);
+ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
+ (ACPI_TYPE_METHOD, info.node, NULL));
+ status = acpi_ns_evaluate_by_handle(&info);
- acpi_ut_remove_reference (params[1]);
+ acpi_ut_remove_reference(params[1]);
-cleanup:
- acpi_ut_remove_reference (params[0]);
+ cleanup:
+ acpi_ut_remove_reference(params[0]);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_address_space_dispatch
@@ -291,40 +271,38 @@ cleanup:
******************************************************************************/
acpi_status
-acpi_ev_address_space_dispatch (
- union acpi_operand_object *region_obj,
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- void *value)
+acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
+ u32 function,
+ acpi_physical_address address,
+ u32 bit_width, void *value)
{
- acpi_status status;
- acpi_status status2;
- acpi_adr_space_handler handler;
- acpi_adr_space_setup region_setup;
- union acpi_operand_object *handler_desc;
- union acpi_operand_object *region_obj2;
- void *region_context = NULL;
+ acpi_status status;
+ acpi_status status2;
+ acpi_adr_space_handler handler;
+ acpi_adr_space_setup region_setup;
+ union acpi_operand_object *handler_desc;
+ union acpi_operand_object *region_obj2;
+ void *region_context = NULL;
+ ACPI_FUNCTION_TRACE("ev_address_space_dispatch");
- ACPI_FUNCTION_TRACE ("ev_address_space_dispatch");
-
-
- region_obj2 = acpi_ns_get_secondary_object (region_obj);
+ region_obj2 = acpi_ns_get_secondary_object(region_obj);
if (!region_obj2) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/* Ensure that there is a handler associated with this region */
handler_desc = region_obj->region.handler;
if (!handler_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "No handler for Region [%4.4s] (%p) [%s]\n",
- acpi_ut_get_node_name (region_obj->region.node),
- region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
-
- return_ACPI_STATUS (AE_NOT_EXIST);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No handler for Region [%4.4s] (%p) [%s]\n",
+ acpi_ut_get_node_name(region_obj->region.
+ node), region_obj,
+ acpi_ut_get_region_name(region_obj->region.
+ space_id)));
+
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/*
@@ -339,10 +317,13 @@ acpi_ev_address_space_dispatch (
if (!region_setup) {
/* No initialization routine, exit with error */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "No init routine for region(%p) [%s]\n",
- region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
- return_ACPI_STATUS (AE_NOT_EXIST);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No init routine for region(%p) [%s]\n",
+ region_obj,
+ acpi_ut_get_region_name(region_obj->
+ region.
+ space_id)));
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/*
@@ -350,25 +331,29 @@ acpi_ev_address_space_dispatch (
* setup will potentially execute control methods
* (e.g., _REG method for this region)
*/
- acpi_ex_exit_interpreter ();
+ acpi_ex_exit_interpreter();
- status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
- handler_desc->address_space.context, &region_context);
+ status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
+ handler_desc->address_space.context,
+ &region_context);
/* Re-enter the interpreter */
- status2 = acpi_ex_enter_interpreter ();
- if (ACPI_FAILURE (status2)) {
- return_ACPI_STATUS (status2);
+ status2 = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
}
/* Check for failure of the Region Setup */
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
- acpi_format_exception (status),
- acpi_ut_get_region_name (region_obj->region.space_id)));
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Region Init: %s [%s]\n",
+ acpi_format_exception(status),
+ acpi_ut_get_region_name(region_obj->
+ region.
+ space_id)));
+ return_ACPI_STATUS(status);
}
/*
@@ -380,14 +365,14 @@ acpi_ev_address_space_dispatch (
if (region_obj2->extra.region_context) {
/* The handler for this region was already installed */
- ACPI_MEM_FREE (region_context);
- }
- else {
+ ACPI_MEM_FREE(region_context);
+ } else {
/*
* Save the returned context for use in all accesses to
* this particular region
*/
- region_obj2->extra.region_context = region_context;
+ region_obj2->extra.region_context =
+ region_context;
}
}
}
@@ -396,13 +381,16 @@ acpi_ev_address_space_dispatch (
handler = handler_desc->address_space.handler;
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
- &region_obj->region.handler->address_space, handler,
- ACPI_FORMAT_UINT64 (address),
- acpi_ut_get_region_name (region_obj->region.space_id)));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+ &region_obj->region.handler->address_space, handler,
+ ACPI_FORMAT_UINT64(address),
+ acpi_ut_get_region_name(region_obj->region.
+ space_id)));
- if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ if (!
+ (handler_desc->address_space.
+ hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
/*
* For handlers other than the default (supplied) handlers, we must
* exit the interpreter because the handler *might* block -- we don't
@@ -413,31 +401,33 @@ acpi_ev_address_space_dispatch (
/* Call the handler */
- status = handler (function, address, bit_width, value,
+ status = handler(function, address, bit_width, value,
handler_desc->address_space.context,
region_obj2->extra.region_context);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Handler for [%s] returned %s\n",
- acpi_ut_get_region_name (region_obj->region.space_id),
- acpi_format_exception (status)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Handler for [%s] returned %s\n",
+ acpi_ut_get_region_name(region_obj->region.
+ space_id),
+ acpi_format_exception(status)));
}
- if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ if (!
+ (handler_desc->address_space.
+ hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
/*
* We just returned from a non-default handler, we must re-enter the
* interpreter
*/
- status2 = acpi_ex_enter_interpreter ();
- if (ACPI_FAILURE (status2)) {
- return_ACPI_STATUS (status2);
+ status2 = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_detach_region
@@ -453,23 +443,20 @@ acpi_ev_address_space_dispatch (
******************************************************************************/
void
-acpi_ev_detach_region(
- union acpi_operand_object *region_obj,
- u8 acpi_ns_is_locked)
+acpi_ev_detach_region(union acpi_operand_object *region_obj,
+ u8 acpi_ns_is_locked)
{
- union acpi_operand_object *handler_obj;
- union acpi_operand_object *obj_desc;
- union acpi_operand_object **last_obj_ptr;
- acpi_adr_space_setup region_setup;
- void **region_context;
- union acpi_operand_object *region_obj2;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_detach_region");
+ union acpi_operand_object *handler_obj;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object **last_obj_ptr;
+ acpi_adr_space_setup region_setup;
+ void **region_context;
+ union acpi_operand_object *region_obj2;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_detach_region");
- region_obj2 = acpi_ns_get_secondary_object (region_obj);
+ region_obj2 = acpi_ns_get_secondary_object(region_obj);
if (!region_obj2) {
return_VOID;
}
@@ -493,34 +480,39 @@ acpi_ev_detach_region(
/* Is this the correct Region? */
if (obj_desc == region_obj) {
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Removing Region %p from address handler %p\n",
- region_obj, handler_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Removing Region %p from address handler %p\n",
+ region_obj, handler_obj));
/* This is it, remove it from the handler's list */
*last_obj_ptr = obj_desc->region.next;
- obj_desc->region.next = NULL; /* Must clear field */
+ obj_desc->region.next = NULL; /* Must clear field */
if (acpi_ns_is_locked) {
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return_VOID;
}
}
/* Now stop region accesses by executing the _REG method */
- status = acpi_ev_execute_reg_method (region_obj, 0);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
- acpi_format_exception (status),
- acpi_ut_get_region_name (region_obj->region.space_id)));
+ status = acpi_ev_execute_reg_method(region_obj, 0);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%s from region _REG, [%s]\n",
+ acpi_format_exception(status),
+ acpi_ut_get_region_name
+ (region_obj->region.
+ space_id)));
}
if (acpi_ns_is_locked) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return_VOID;
}
}
@@ -528,15 +520,20 @@ acpi_ev_detach_region(
/* Call the setup handler with the deactivate notification */
region_setup = handler_obj->address_space.setup;
- status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
- handler_obj->address_space.context, region_context);
+ status =
+ region_setup(region_obj, ACPI_REGION_DEACTIVATE,
+ handler_obj->address_space.context,
+ region_context);
/* Init routine may fail, Just ignore errors */
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
- acpi_format_exception (status),
- acpi_ut_get_region_name (region_obj->region.space_id)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%s from region init, [%s]\n",
+ acpi_format_exception(status),
+ acpi_ut_get_region_name
+ (region_obj->region.
+ space_id)));
}
region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
@@ -552,7 +549,7 @@ acpi_ev_detach_region(
* this better be the region's handler
*/
region_obj->region.handler = NULL;
- acpi_ut_remove_reference (handler_obj);
+ acpi_ut_remove_reference(handler_obj);
return_VOID;
}
@@ -565,14 +562,13 @@ acpi_ev_detach_region(
/* If we get here, the region was not in the handler's region list */
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Cannot remove region %p from address handler %p\n",
- region_obj, handler_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Cannot remove region %p from address handler %p\n",
+ region_obj, handler_obj));
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_attach_region
@@ -589,20 +585,19 @@ acpi_ev_detach_region(
******************************************************************************/
acpi_status
-acpi_ev_attach_region (
- union acpi_operand_object *handler_obj,
- union acpi_operand_object *region_obj,
- u8 acpi_ns_is_locked)
+acpi_ev_attach_region(union acpi_operand_object *handler_obj,
+ union acpi_operand_object *region_obj,
+ u8 acpi_ns_is_locked)
{
- ACPI_FUNCTION_TRACE ("ev_attach_region");
-
+ ACPI_FUNCTION_TRACE("ev_attach_region");
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Adding Region [%4.4s] %p to address handler %p [%s]\n",
- acpi_ut_get_node_name (region_obj->region.node),
- region_obj, handler_obj,
- acpi_ut_get_region_name (region_obj->region.space_id)));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Adding Region [%4.4s] %p to address handler %p [%s]\n",
+ acpi_ut_get_node_name(region_obj->region.node),
+ region_obj, handler_obj,
+ acpi_ut_get_region_name(region_obj->region.
+ space_id)));
/* Link this region to the front of the handler's list */
@@ -612,16 +607,15 @@ acpi_ev_attach_region (
/* Install the region's handler */
if (region_obj->region.handler) {
- return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ return_ACPI_STATUS(AE_ALREADY_EXISTS);
}
region_obj->region.handler = handler_obj;
- acpi_ut_add_reference (handler_obj);
+ acpi_ut_add_reference(handler_obj);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_install_handler
@@ -640,23 +634,18 @@ acpi_ev_attach_region (
******************************************************************************/
static acpi_status
-acpi_ev_install_handler (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ev_install_handler(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value)
{
- union acpi_operand_object *handler_obj;
- union acpi_operand_object *next_handler_obj;
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- acpi_status status;
+ union acpi_operand_object *handler_obj;
+ union acpi_operand_object *next_handler_obj;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_NAME("ev_install_handler");
- ACPI_FUNCTION_NAME ("ev_install_handler");
-
-
- handler_obj = (union acpi_operand_object *) context;
+ handler_obj = (union acpi_operand_object *)context;
/* Parameter validation */
@@ -666,7 +655,7 @@ acpi_ev_install_handler (
/* Convert and validate the device handle */
- node = acpi_ns_map_handle_to_node (obj_handle);
+ node = acpi_ns_map_handle_to_node(obj_handle);
if (!node) {
return (AE_BAD_PARAMETER);
}
@@ -676,14 +665,13 @@ acpi_ev_install_handler (
* that are allowed to have address space handlers
*/
if ((node->type != ACPI_TYPE_DEVICE) &&
- (node->type != ACPI_TYPE_REGION) &&
- (node != acpi_gbl_root_node)) {
+ (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
return (AE_OK);
}
/* Check for an existing internal object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
/* No object, just exit */
@@ -692,18 +680,22 @@ acpi_ev_install_handler (
/* Devices are handled different than regions */
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
/* Check if this Device already has a handler for this address space */
next_handler_obj = obj_desc->device.handler;
while (next_handler_obj) {
/* Found a handler, is it for the same address space? */
- if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) {
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Found handler for region [%s] in device %p(%p) handler %p\n",
- acpi_ut_get_region_name (handler_obj->address_space.space_id),
- obj_desc, next_handler_obj, handler_obj));
+ if (next_handler_obj->address_space.space_id ==
+ handler_obj->address_space.space_id) {
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Found handler for region [%s] in device %p(%p) handler %p\n",
+ acpi_ut_get_region_name
+ (handler_obj->address_space.
+ space_id), obj_desc,
+ next_handler_obj,
+ handler_obj));
/*
* Since the object we found it on was a device, then it
@@ -744,15 +736,14 @@ acpi_ev_install_handler (
*
* First disconnect region for any previous handler (if any)
*/
- acpi_ev_detach_region (obj_desc, FALSE);
+ acpi_ev_detach_region(obj_desc, FALSE);
/* Connect the region to the new handler */
- status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
+ status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_install_space_handler
@@ -771,32 +762,27 @@ acpi_ev_install_handler (
******************************************************************************/
acpi_status
-acpi_ev_install_space_handler (
- struct acpi_namespace_node *node,
- acpi_adr_space_type space_id,
- acpi_adr_space_handler handler,
- acpi_adr_space_setup setup,
- void *context)
+acpi_ev_install_space_handler(struct acpi_namespace_node * node,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler,
+ acpi_adr_space_setup setup, void *context)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *handler_obj;
- acpi_status status;
- acpi_object_type type;
- u16 flags = 0;
-
-
- ACPI_FUNCTION_TRACE ("ev_install_space_handler");
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *handler_obj;
+ acpi_status status;
+ acpi_object_type type;
+ u16 flags = 0;
+ ACPI_FUNCTION_TRACE("ev_install_space_handler");
/*
* This registration is valid for only the types below
* and the root. This is where the default handlers
* get placed.
*/
- if ((node->type != ACPI_TYPE_DEVICE) &&
- (node->type != ACPI_TYPE_PROCESSOR) &&
- (node->type != ACPI_TYPE_THERMAL) &&
- (node != acpi_gbl_root_node)) {
+ if ((node->type != ACPI_TYPE_DEVICE) &&
+ (node->type != ACPI_TYPE_PROCESSOR) &&
+ (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
@@ -807,32 +793,32 @@ acpi_ev_install_space_handler (
switch (space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
handler = acpi_ex_system_memory_space_handler;
- setup = acpi_ev_system_memory_region_setup;
+ setup = acpi_ev_system_memory_region_setup;
break;
case ACPI_ADR_SPACE_SYSTEM_IO:
handler = acpi_ex_system_io_space_handler;
- setup = acpi_ev_io_space_region_setup;
+ setup = acpi_ev_io_space_region_setup;
break;
case ACPI_ADR_SPACE_PCI_CONFIG:
handler = acpi_ex_pci_config_space_handler;
- setup = acpi_ev_pci_config_region_setup;
+ setup = acpi_ev_pci_config_region_setup;
break;
case ACPI_ADR_SPACE_CMOS:
handler = acpi_ex_cmos_space_handler;
- setup = acpi_ev_cmos_region_setup;
+ setup = acpi_ev_cmos_region_setup;
break;
case ACPI_ADR_SPACE_PCI_BAR_TARGET:
handler = acpi_ex_pci_bar_space_handler;
- setup = acpi_ev_pci_bar_region_setup;
+ setup = acpi_ev_pci_bar_region_setup;
break;
case ACPI_ADR_SPACE_DATA_TABLE:
handler = acpi_ex_data_table_space_handler;
- setup = NULL;
+ setup = NULL;
break;
default:
@@ -849,7 +835,7 @@ acpi_ev_install_space_handler (
/* Check for an existing internal object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {
/*
* The attached device object already exists.
@@ -863,7 +849,8 @@ acpi_ev_install_space_handler (
/* Same space_id indicates a handler already installed */
if (handler_obj->address_space.space_id == space_id) {
- if (handler_obj->address_space.handler == handler) {
+ if (handler_obj->address_space.handler ==
+ handler) {
/*
* It is (relatively) OK to attempt to install the SAME
* handler twice. This can easily happen
@@ -871,8 +858,7 @@ acpi_ev_install_space_handler (
*/
status = AE_SAME_HANDLER;
goto unlock_and_exit;
- }
- else {
+ } else {
/* A handler is already installed */
status = AE_ALREADY_EXISTS;
@@ -884,21 +870,20 @@ acpi_ev_install_space_handler (
handler_obj = handler_obj->address_space.next;
}
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Creating object on Device %p while installing handler\n", node));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Creating object on Device %p while installing handler\n",
+ node));
/* obj_desc does not exist, create one */
if (node->type == ACPI_TYPE_ANY) {
type = ACPI_TYPE_DEVICE;
- }
- else {
+ } else {
type = node->type;
}
- obj_desc = acpi_ut_create_internal_object (type);
+ obj_desc = acpi_ut_create_internal_object(type);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
@@ -910,21 +895,21 @@ acpi_ev_install_space_handler (
/* Attach the new object to the Node */
- status = acpi_ns_attach_object (node, obj_desc, type);
+ status = acpi_ns_attach_object(node, obj_desc, type);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
- acpi_ut_get_region_name (space_id), space_id,
- acpi_ut_get_node_name (node), node, obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+ acpi_ut_get_region_name(space_id), space_id,
+ acpi_ut_get_node_name(node), node, obj_desc));
/*
* Install the handler
@@ -933,7 +918,8 @@ acpi_ev_install_space_handler (
* Just allocate the object for the handler and link it
* into the list.
*/
- handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+ handler_obj =
+ acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
if (!handler_obj) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
@@ -941,17 +927,17 @@ acpi_ev_install_space_handler (
/* Init handler obj */
- handler_obj->address_space.space_id = (u8) space_id;
- handler_obj->address_space.hflags = flags;
+ handler_obj->address_space.space_id = (u8) space_id;
+ handler_obj->address_space.hflags = flags;
handler_obj->address_space.region_list = NULL;
- handler_obj->address_space.node = node;
- handler_obj->address_space.handler = handler;
- handler_obj->address_space.context = context;
- handler_obj->address_space.setup = setup;
+ handler_obj->address_space.node = node;
+ handler_obj->address_space.handler = handler;
+ handler_obj->address_space.context = context;
+ handler_obj->address_space.setup = setup;
/* Install at head of Device.address_space list */
- handler_obj->address_space.next = obj_desc->device.handler;
+ handler_obj->address_space.next = obj_desc->device.handler;
/*
* The Device object is the first reference on the handler_obj.
@@ -971,15 +957,15 @@ acpi_ev_install_space_handler (
* In either case, back up and search down the remainder
* of the branch
*/
- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
- handler_obj, NULL);
+ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK,
+ acpi_ev_install_handler, handler_obj,
+ NULL);
-unlock_and_exit:
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_execute_reg_methods
@@ -995,15 +981,12 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_ev_execute_reg_methods (
- struct acpi_namespace_node *node,
- acpi_adr_space_type space_id)
+acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_execute_reg_methods");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_execute_reg_methods");
/*
* Run all _REG methods for all Operation Regions for this
@@ -1012,14 +995,13 @@ acpi_ev_execute_reg_methods (
* must be installed for all regions of this Space ID before we
* can run any _REG methods)
*/
- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
- &space_id, NULL);
+ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
+ &space_id, NULL);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_reg_run
@@ -1031,23 +1013,19 @@ acpi_ev_execute_reg_methods (
******************************************************************************/
static acpi_status
-acpi_ev_reg_run (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ev_reg_run(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value)
{
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- acpi_adr_space_type space_id;
- acpi_status status;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ acpi_adr_space_type space_id;
+ acpi_status status;
-
- space_id = *ACPI_CAST_PTR (acpi_adr_space_type, context);
+ space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
/* Convert and validate the device handle */
- node = acpi_ns_map_handle_to_node (obj_handle);
+ node = acpi_ns_map_handle_to_node(obj_handle);
if (!node) {
return (AE_BAD_PARAMETER);
}
@@ -1056,14 +1034,13 @@ acpi_ev_reg_run (
* We only care about regions.and objects
* that are allowed to have address space handlers
*/
- if ((node->type != ACPI_TYPE_REGION) &&
- (node != acpi_gbl_root_node)) {
+ if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
return (AE_OK);
}
/* Check for an existing internal object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
/* No object, just exit */
@@ -1080,7 +1057,6 @@ acpi_ev_reg_run (
return (AE_OK);
}
- status = acpi_ev_execute_reg_method (obj_desc, 1);
+ status = acpi_ev_execute_reg_method(obj_desc, 1);
return (status);
}
-
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 95bc09c73a6a..a1bd2da27c45 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -41,14 +41,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acevents.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evrgnini")
-
+ACPI_MODULE_NAME("evrgnini")
/*******************************************************************************
*
@@ -64,34 +62,31 @@
* DESCRIPTION: Setup a system_memory operation region
*
******************************************************************************/
-
acpi_status
-acpi_ev_system_memory_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context)
+acpi_ev_system_memory_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context)
{
- union acpi_operand_object *region_desc = (union acpi_operand_object *) handle;
- struct acpi_mem_space_context *local_region_context;
-
-
- ACPI_FUNCTION_TRACE ("ev_system_memory_region_setup");
+ union acpi_operand_object *region_desc =
+ (union acpi_operand_object *)handle;
+ struct acpi_mem_space_context *local_region_context;
+ ACPI_FUNCTION_TRACE("ev_system_memory_region_setup");
if (function == ACPI_REGION_DEACTIVATE) {
if (*region_context) {
- ACPI_MEM_FREE (*region_context);
+ ACPI_MEM_FREE(*region_context);
*region_context = NULL;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Create a new context */
- local_region_context = ACPI_MEM_CALLOCATE (sizeof (struct acpi_mem_space_context));
+ local_region_context =
+ ACPI_MEM_CALLOCATE(sizeof(struct acpi_mem_space_context));
if (!(local_region_context)) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Save the region length and address for use in the handler */
@@ -100,10 +95,9 @@ acpi_ev_system_memory_region_setup (
local_region_context->address = region_desc->region.address;
*region_context = local_region_context;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_io_space_region_setup
@@ -120,26 +114,21 @@ acpi_ev_system_memory_region_setup (
******************************************************************************/
acpi_status
-acpi_ev_io_space_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context)
+acpi_ev_io_space_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context)
{
- ACPI_FUNCTION_TRACE ("ev_io_space_region_setup");
-
+ ACPI_FUNCTION_TRACE("ev_io_space_region_setup");
if (function == ACPI_REGION_DEACTIVATE) {
*region_context = NULL;
- }
- else {
+ } else {
*region_context = handler_context;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_pci_config_region_setup
@@ -158,24 +147,21 @@ acpi_ev_io_space_region_setup (
******************************************************************************/
acpi_status
-acpi_ev_pci_config_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context)
+acpi_ev_pci_config_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context)
{
- acpi_status status = AE_OK;
- acpi_integer pci_value;
- struct acpi_pci_id *pci_id = *region_context;
- union acpi_operand_object *handler_obj;
- struct acpi_namespace_node *parent_node;
- struct acpi_namespace_node *pci_root_node;
- union acpi_operand_object *region_obj = (union acpi_operand_object *) handle;
- struct acpi_device_id object_hID;
-
-
- ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
-
+ acpi_status status = AE_OK;
+ acpi_integer pci_value;
+ struct acpi_pci_id *pci_id = *region_context;
+ union acpi_operand_object *handler_obj;
+ struct acpi_namespace_node *parent_node;
+ struct acpi_namespace_node *pci_root_node;
+ union acpi_operand_object *region_obj =
+ (union acpi_operand_object *)handle;
+ struct acpi_device_id object_hID;
+
+ ACPI_FUNCTION_TRACE("ev_pci_config_region_setup");
handler_obj = region_obj->region.handler;
if (!handler_obj) {
@@ -183,20 +169,21 @@ acpi_ev_pci_config_region_setup (
* No installed handler. This shouldn't happen because the dispatch
* routine checks before we get here, but we check again just in case.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Attempting to init a region %p, with no handler\n", region_obj));
- return_ACPI_STATUS (AE_NOT_EXIST);
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Attempting to init a region %p, with no handler\n",
+ region_obj));
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
*region_context = NULL;
if (function == ACPI_REGION_DEACTIVATE) {
if (pci_id) {
- ACPI_MEM_FREE (pci_id);
+ ACPI_MEM_FREE(pci_id);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
- parent_node = acpi_ns_get_parent_node (region_obj->region.node);
+ parent_node = acpi_ns_get_parent_node(region_obj->region.node);
/*
* Get the _SEG and _BBN values from the device upon which the handler
@@ -216,18 +203,28 @@ acpi_ev_pci_config_region_setup (
pci_root_node = parent_node;
while (pci_root_node != acpi_gbl_root_node) {
- status = acpi_ut_execute_HID (pci_root_node, &object_hID);
- if (ACPI_SUCCESS (status)) {
- /* Got a valid _HID, check if this is a PCI root */
-
- if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING,
- sizeof (PCI_ROOT_HID_STRING)))) {
+ status =
+ acpi_ut_execute_HID(pci_root_node, &object_hID);
+ if (ACPI_SUCCESS(status)) {
+ /*
+ * Got a valid _HID string, check if this is a PCI root.
+ * New for ACPI 3.0: check for a PCI Express root also.
+ */
+ if (!
+ (ACPI_STRNCMP
+ (object_hID.value, PCI_ROOT_HID_STRING,
+ sizeof(PCI_ROOT_HID_STRING))
+ ||
+ !(ACPI_STRNCMP
+ (object_hID.value,
+ PCI_EXPRESS_ROOT_HID_STRING,
+ sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
+ {
/* Install a handler for this PCI root bridge */
- status = acpi_install_address_space_handler ((acpi_handle) pci_root_node,
- ACPI_ADR_SPACE_PCI_CONFIG,
- ACPI_DEFAULT_HANDLER, NULL, NULL);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
+ if (ACPI_FAILURE(status)) {
if (status == AE_SAME_HANDLER) {
/*
* It is OK if the handler is already installed on the root
@@ -235,23 +232,19 @@ acpi_ev_pci_config_region_setup (
* new PCI_Config operation region, however.
*/
status = AE_OK;
- }
- else {
- ACPI_REPORT_ERROR ((
- "Could not install pci_config handler for Root Bridge %4.4s, %s\n",
- acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status)));
+ } else {
+ ACPI_REPORT_ERROR(("Could not install pci_config handler for Root Bridge %4.4s, %s\n", acpi_ut_get_node_name(pci_root_node), acpi_format_exception(status)));
}
}
break;
}
}
- pci_root_node = acpi_ns_get_parent_node (pci_root_node);
+ pci_root_node = acpi_ns_get_parent_node(pci_root_node);
}
/* PCI root bridge not found, use namespace root node */
- }
- else {
+ } else {
pci_root_node = handler_obj->address_space.node;
}
@@ -260,14 +253,14 @@ acpi_ev_pci_config_region_setup (
* (install_address_space_handler could have initialized it)
*/
if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Region is still not initialized. Create a new context */
- pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
+ pci_id = ACPI_MEM_CALLOCATE(sizeof(struct acpi_pci_id));
if (!pci_id) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
@@ -279,40 +272,45 @@ acpi_ev_pci_config_region_setup (
* Get the PCI device and function numbers from the _ADR object
* contained in the parent's scope.
*/
- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value);
+ status =
+ acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node,
+ &pci_value);
/*
* The default is zero, and since the allocation above zeroed
* the data, just do nothing on failure.
*/
- if (ACPI_SUCCESS (status)) {
- pci_id->device = ACPI_HIWORD (ACPI_LODWORD (pci_value));
- pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value));
+ if (ACPI_SUCCESS(status)) {
+ pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
+ pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
}
/* The PCI segment number comes from the _SEG method */
- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value);
- if (ACPI_SUCCESS (status)) {
- pci_id->segment = ACPI_LOWORD (pci_value);
+ status =
+ acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
+ &pci_value);
+ if (ACPI_SUCCESS(status)) {
+ pci_id->segment = ACPI_LOWORD(pci_value);
}
/* The PCI bus number comes from the _BBN method */
- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value);
- if (ACPI_SUCCESS (status)) {
- pci_id->bus = ACPI_LOWORD (pci_value);
+ status =
+ acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
+ &pci_value);
+ if (ACPI_SUCCESS(status)) {
+ pci_id->bus = ACPI_LOWORD(pci_value);
}
/* Complete this device's pci_id */
- acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id);
+ acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);
*region_context = pci_id;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_pci_bar_region_setup
@@ -331,19 +329,15 @@ acpi_ev_pci_config_region_setup (
******************************************************************************/
acpi_status
-acpi_ev_pci_bar_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context)
+acpi_ev_pci_bar_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context)
{
- ACPI_FUNCTION_TRACE ("ev_pci_bar_region_setup");
-
+ ACPI_FUNCTION_TRACE("ev_pci_bar_region_setup");
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_cmos_region_setup
@@ -362,19 +356,15 @@ acpi_ev_pci_bar_region_setup (
******************************************************************************/
acpi_status
-acpi_ev_cmos_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context)
+acpi_ev_cmos_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context)
{
- ACPI_FUNCTION_TRACE ("ev_cmos_region_setup");
-
+ ACPI_FUNCTION_TRACE("ev_cmos_region_setup");
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_default_region_setup
@@ -391,26 +381,21 @@ acpi_ev_cmos_region_setup (
******************************************************************************/
acpi_status
-acpi_ev_default_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context)
+acpi_ev_default_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context)
{
- ACPI_FUNCTION_TRACE ("ev_default_region_setup");
-
+ ACPI_FUNCTION_TRACE("ev_default_region_setup");
if (function == ACPI_REGION_DEACTIVATE) {
*region_context = NULL;
- }
- else {
+ } else {
*region_context = handler_context;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_initialize_region
@@ -434,37 +419,34 @@ acpi_ev_default_region_setup (
******************************************************************************/
acpi_status
-acpi_ev_initialize_region (
- union acpi_operand_object *region_obj,
- u8 acpi_ns_locked)
+acpi_ev_initialize_region(union acpi_operand_object *region_obj,
+ u8 acpi_ns_locked)
{
- union acpi_operand_object *handler_obj;
- union acpi_operand_object *obj_desc;
- acpi_adr_space_type space_id;
- struct acpi_namespace_node *node;
- acpi_status status;
- struct acpi_namespace_node *method_node;
- acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
- union acpi_operand_object *region_obj2;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ev_initialize_region", acpi_ns_locked);
+ union acpi_operand_object *handler_obj;
+ union acpi_operand_object *obj_desc;
+ acpi_adr_space_type space_id;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ struct acpi_namespace_node *method_node;
+ acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
+ union acpi_operand_object *region_obj2;
+ ACPI_FUNCTION_TRACE_U32("ev_initialize_region", acpi_ns_locked);
if (!region_obj) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
- region_obj2 = acpi_ns_get_secondary_object (region_obj);
+ region_obj2 = acpi_ns_get_secondary_object(region_obj);
if (!region_obj2) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
- node = acpi_ns_get_parent_node (region_obj->region.node);
+ node = acpi_ns_get_parent_node(region_obj->region.node);
space_id = region_obj->region.space_id;
/* Setup defaults */
@@ -476,9 +458,9 @@ acpi_ev_initialize_region (
/* Find any "_REG" method associated with this region definition */
- status = acpi_ns_search_node (*reg_name_ptr, node,
- ACPI_TYPE_METHOD, &method_node);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ns_search_node(*reg_name_ptr, node,
+ ACPI_TYPE_METHOD, &method_node);
+ if (ACPI_SUCCESS(status)) {
/*
* The _REG method is optional and there can be only one per region
* definition. This will be executed when the handler is attached
@@ -495,7 +477,7 @@ acpi_ev_initialize_region (
/* Check to see if a handler exists */
handler_obj = NULL;
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {
/* Can only be a handler if the object exists */
@@ -523,37 +505,50 @@ acpi_ev_initialize_region (
while (handler_obj) {
/* Is this handler of the correct type? */
- if (handler_obj->address_space.space_id == space_id) {
+ if (handler_obj->address_space.space_id ==
+ space_id) {
/* Found correct handler */
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Found handler %p for region %p in obj %p\n",
- handler_obj, region_obj, obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Found handler %p for region %p in obj %p\n",
+ handler_obj,
+ region_obj,
+ obj_desc));
- status = acpi_ev_attach_region (handler_obj, region_obj,
- acpi_ns_locked);
+ status =
+ acpi_ev_attach_region(handler_obj,
+ region_obj,
+ acpi_ns_locked);
/*
* Tell all users that this region is usable by running the _REG
* method
*/
if (acpi_ns_locked) {
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_release_mutex
+ (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS
+ (status);
}
}
- status = acpi_ev_execute_reg_method (region_obj, 1);
+ status =
+ acpi_ev_execute_reg_method
+ (region_obj, 1);
if (acpi_ns_locked) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_acquire_mutex
+ (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS
+ (status);
}
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Try next handler in the list */
@@ -566,15 +561,15 @@ acpi_ev_initialize_region (
* This node does not have the handler we need;
* Pop up one level
*/
- node = acpi_ns_get_parent_node (node);
+ node = acpi_ns_get_parent_node(node);
}
/* If we get here, there is no handler for this region */
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "No handler for region_type %s(%X) (region_obj %p)\n",
- acpi_ut_get_region_name (space_id), space_id, region_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "No handler for region_type %s(%X) (region_obj %p)\n",
+ acpi_ut_get_region_name(space_id), space_id,
+ region_obj));
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
-
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index f3123c26ae98..141835977002 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -45,16 +45,11 @@
#include <acpi/acpi.h>
#include <acpi/acevents.h>
-
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evsci")
+ACPI_MODULE_NAME("evsci")
/* Local prototypes */
-
-static u32 ACPI_SYSTEM_XFACE
-acpi_ev_sci_xrupt_handler (
- void *context);
-
+static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);
/*******************************************************************************
*
@@ -69,17 +64,13 @@ acpi_ev_sci_xrupt_handler (
*
******************************************************************************/
-static u32 ACPI_SYSTEM_XFACE
-acpi_ev_sci_xrupt_handler (
- void *context)
+static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
{
- struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
- u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
-
+ struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
+ u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
ACPI_FUNCTION_TRACE("ev_sci_xrupt_handler");
-
/*
* We are guaranteed by the ACPI CA initialization/shutdown code that
* if this interrupt handler is installed, ACPI is enabled.
@@ -89,18 +80,17 @@ acpi_ev_sci_xrupt_handler (
* Fixed Events:
* Check for and dispatch any Fixed Events that have occurred
*/
- interrupt_handled |= acpi_ev_fixed_event_detect ();
+ interrupt_handled |= acpi_ev_fixed_event_detect();
/*
* General Purpose Events:
* Check for and dispatch any GPEs that have occurred
*/
- interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list);
+ interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
- return_VALUE (interrupt_handled);
+ return_VALUE(interrupt_handled);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_xrupt_handler
@@ -113,17 +103,13 @@ acpi_ev_sci_xrupt_handler (
*
******************************************************************************/
-u32 ACPI_SYSTEM_XFACE
-acpi_ev_gpe_xrupt_handler (
- void *context)
+u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)
{
- struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
- u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
-
+ struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
+ u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
ACPI_FUNCTION_TRACE("ev_gpe_xrupt_handler");
-
/*
* We are guaranteed by the ACPI CA initialization/shutdown code that
* if this interrupt handler is installed, ACPI is enabled.
@@ -133,12 +119,11 @@ acpi_ev_gpe_xrupt_handler (
* GPEs:
* Check for and dispatch any GPEs that have occurred
*/
- interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list);
+ interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
- return_VALUE (interrupt_handled);
+ return_VALUE(interrupt_handled);
}
-
/******************************************************************************
*
* FUNCTION: acpi_ev_install_sci_handler
@@ -151,22 +136,18 @@ acpi_ev_gpe_xrupt_handler (
*
******************************************************************************/
-u32
-acpi_ev_install_sci_handler (
- void)
+u32 acpi_ev_install_sci_handler(void)
{
- u32 status = AE_OK;
-
+ u32 status = AE_OK;
- ACPI_FUNCTION_TRACE ("ev_install_sci_handler");
+ ACPI_FUNCTION_TRACE("ev_install_sci_handler");
-
- status = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
- acpi_ev_sci_xrupt_handler, acpi_gbl_gpe_xrupt_list_head);
- return_ACPI_STATUS (status);
+ status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int,
+ acpi_ev_sci_xrupt_handler,
+ acpi_gbl_gpe_xrupt_list_head);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_ev_remove_sci_handler
@@ -186,22 +167,16 @@ acpi_ev_install_sci_handler (
*
******************************************************************************/
-acpi_status
-acpi_ev_remove_sci_handler (
- void)
+acpi_status acpi_ev_remove_sci_handler(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ev_remove_sci_handler");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ev_remove_sci_handler");
/* Just let the OS remove the handler and disable the level */
- status = acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
- acpi_ev_sci_xrupt_handler);
+ status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int,
+ acpi_ev_sci_xrupt_handler);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 4092d47f6758..43b33d19cdf9 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -49,8 +49,7 @@
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evxface")
-
+ACPI_MODULE_NAME("evxface")
/*******************************************************************************
*
@@ -64,21 +63,16 @@
* DESCRIPTION: Saves the pointer to the handler function
*
******************************************************************************/
-
#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_install_exception_handler (
- acpi_exception_handler handler)
+acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
{
- acpi_status status;
-
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("acpi_install_exception_handler");
+ ACPI_FUNCTION_TRACE("acpi_install_exception_handler");
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Don't allow two handlers. */
@@ -92,12 +86,11 @@ acpi_install_exception_handler (
acpi_gbl_exception_handler = handler;
-cleanup:
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ cleanup:
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -116,26 +109,22 @@ cleanup:
******************************************************************************/
acpi_status
-acpi_install_fixed_event_handler (
- u32 event,
- acpi_event_handler handler,
- void *context)
+acpi_install_fixed_event_handler(u32 event,
+ acpi_event_handler handler, void *context)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_install_fixed_event_handler");
/* Parameter validation */
if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Don't allow two handlers. */
@@ -150,29 +139,29 @@ acpi_install_fixed_event_handler (
acpi_gbl_fixed_event_handlers[event].handler = handler;
acpi_gbl_fixed_event_handlers[event].context = context;
- status = acpi_clear_event (event);
+ status = acpi_clear_event(event);
if (ACPI_SUCCESS(status))
- status = acpi_enable_event (event, 0);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
+ status = acpi_enable_event(event, 0);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Could not enable fixed event.\n"));
/* Remove the handler */
acpi_gbl_fixed_event_handlers[event].handler = NULL;
acpi_gbl_fixed_event_handlers[event].context = NULL;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Enabled fixed event %X, Handler=%p\n", event, handler));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Enabled fixed event %X, Handler=%p\n", event,
+ handler));
}
-
-cleanup:
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ cleanup:
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_install_fixed_event_handler);
+EXPORT_SYMBOL(acpi_install_fixed_event_handler);
/*******************************************************************************
*
@@ -188,49 +177,45 @@ EXPORT_SYMBOL(acpi_install_fixed_event_handler);
******************************************************************************/
acpi_status
-acpi_remove_fixed_event_handler (
- u32 event,
- acpi_event_handler handler)
+acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("acpi_remove_fixed_event_handler");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("acpi_remove_fixed_event_handler");
/* Parameter validation */
if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Disable the event before removing the handler */
- status = acpi_disable_event (event, 0);
+ status = acpi_disable_event(event, 0);
/* Always Remove the handler */
acpi_gbl_fixed_event_handlers[event].handler = NULL;
acpi_gbl_fixed_event_handlers[event].context = NULL;
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
- "Could not write to fixed event enable register.\n"));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", event));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Could not write to fixed event enable register.\n"));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X.\n",
+ event));
}
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
+EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
/*******************************************************************************
*
@@ -251,37 +236,32 @@ EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
******************************************************************************/
acpi_status
-acpi_install_notify_handler (
- acpi_handle device,
- u32 handler_type,
- acpi_notify_handler handler,
- void *context)
+acpi_install_notify_handler(acpi_handle device,
+ u32 handler_type,
+ acpi_notify_handler handler, void *context)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *notify_obj;
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_install_notify_handler");
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *notify_obj;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_install_notify_handler");
/* Parameter validation */
- if ((!device) ||
- (!handler) ||
- (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((!device) ||
+ (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Convert and validate the device handle */
- node = acpi_ns_map_handle_to_node (device);
+ node = acpi_ns_map_handle_to_node(device);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -297,21 +277,21 @@ acpi_install_notify_handler (
/* Make sure the handler is not already installed */
if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
- acpi_gbl_system_notify.handler) ||
- ((handler_type & ACPI_DEVICE_NOTIFY) &&
- acpi_gbl_device_notify.handler)) {
+ acpi_gbl_system_notify.handler) ||
+ ((handler_type & ACPI_DEVICE_NOTIFY) &&
+ acpi_gbl_device_notify.handler)) {
status = AE_ALREADY_EXISTS;
goto unlock_and_exit;
}
if (handler_type & ACPI_SYSTEM_NOTIFY) {
- acpi_gbl_system_notify.node = node;
+ acpi_gbl_system_notify.node = node;
acpi_gbl_system_notify.handler = handler;
acpi_gbl_system_notify.context = context;
}
if (handler_type & ACPI_DEVICE_NOTIFY) {
- acpi_gbl_device_notify.node = node;
+ acpi_gbl_device_notify.node = node;
acpi_gbl_device_notify.handler = handler;
acpi_gbl_device_notify.context = context;
}
@@ -327,29 +307,28 @@ acpi_install_notify_handler (
else {
/* Notifies allowed on this object? */
- if (!acpi_ev_is_notify_object (node)) {
+ if (!acpi_ev_is_notify_object(node)) {
status = AE_TYPE;
goto unlock_and_exit;
}
/* Check for an existing internal object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {
/* Object exists - make sure there's no handler */
if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
- obj_desc->common_notify.system_notify) ||
- ((handler_type & ACPI_DEVICE_NOTIFY) &&
- obj_desc->common_notify.device_notify)) {
+ obj_desc->common_notify.system_notify) ||
+ ((handler_type & ACPI_DEVICE_NOTIFY) &&
+ obj_desc->common_notify.device_notify)) {
status = AE_ALREADY_EXISTS;
goto unlock_and_exit;
}
- }
- else {
+ } else {
/* Create a new object */
- obj_desc = acpi_ut_create_internal_object (node->type);
+ obj_desc = acpi_ut_create_internal_object(node->type);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
@@ -357,25 +336,27 @@ acpi_install_notify_handler (
/* Attach new object to the Node */
- status = acpi_ns_attach_object (device, obj_desc, node->type);
+ status =
+ acpi_ns_attach_object(device, obj_desc, node->type);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- if (ACPI_FAILURE (status)) {
+ acpi_ut_remove_reference(obj_desc);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
}
/* Install the handler */
- notify_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_NOTIFY);
+ notify_obj =
+ acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
if (!notify_obj) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
}
- notify_obj->notify.node = node;
+ notify_obj->notify.node = node;
notify_obj->notify.handler = handler;
notify_obj->notify.context = context;
@@ -390,17 +371,16 @@ acpi_install_notify_handler (
if (handler_type == ACPI_ALL_NOTIFY) {
/* Extra ref if installed in both */
- acpi_ut_add_reference (notify_obj);
+ acpi_ut_add_reference(notify_obj);
}
}
-
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_install_notify_handler);
+EXPORT_SYMBOL(acpi_install_notify_handler);
/*******************************************************************************
*
@@ -420,36 +400,31 @@ EXPORT_SYMBOL(acpi_install_notify_handler);
******************************************************************************/
acpi_status
-acpi_remove_notify_handler (
- acpi_handle device,
- u32 handler_type,
- acpi_notify_handler handler)
+acpi_remove_notify_handler(acpi_handle device,
+ u32 handler_type, acpi_notify_handler handler)
{
- union acpi_operand_object *notify_obj;
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_remove_notify_handler");
+ union acpi_operand_object *notify_obj;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_remove_notify_handler");
/* Parameter validation */
- if ((!device) ||
- (!handler) ||
- (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((!device) ||
+ (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Convert and validate the device handle */
- node = acpi_ns_map_handle_to_node (device);
+ node = acpi_ns_map_handle_to_node(device);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -458,34 +433,34 @@ acpi_remove_notify_handler (
/* Root Object */
if (device == ACPI_ROOT_OBJECT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Removing notify handler for ROOT object.\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Removing notify handler for ROOT object.\n"));
if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
- !acpi_gbl_system_notify.handler) ||
- ((handler_type & ACPI_DEVICE_NOTIFY) &&
- !acpi_gbl_device_notify.handler)) {
+ !acpi_gbl_system_notify.handler) ||
+ ((handler_type & ACPI_DEVICE_NOTIFY) &&
+ !acpi_gbl_device_notify.handler)) {
status = AE_NOT_EXIST;
goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
acpi_os_wait_events_complete(NULL);
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
if (handler_type & ACPI_SYSTEM_NOTIFY) {
- acpi_gbl_system_notify.node = NULL;
+ acpi_gbl_system_notify.node = NULL;
acpi_gbl_system_notify.handler = NULL;
acpi_gbl_system_notify.context = NULL;
}
if (handler_type & ACPI_DEVICE_NOTIFY) {
- acpi_gbl_device_notify.node = NULL;
+ acpi_gbl_device_notify.node = NULL;
acpi_gbl_device_notify.handler = NULL;
acpi_gbl_device_notify.context = NULL;
}
@@ -496,14 +471,14 @@ acpi_remove_notify_handler (
else {
/* Notifies allowed on this object? */
- if (!acpi_ev_is_notify_object (node)) {
+ if (!acpi_ev_is_notify_object(node)) {
status = AE_TYPE;
goto unlock_and_exit;
}
/* Check for an existing internal object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
status = AE_NOT_EXIST;
goto unlock_and_exit;
@@ -514,53 +489,52 @@ acpi_remove_notify_handler (
if (handler_type & ACPI_SYSTEM_NOTIFY) {
notify_obj = obj_desc->common_notify.system_notify;
if ((!notify_obj) ||
- (notify_obj->notify.handler != handler)) {
+ (notify_obj->notify.handler != handler)) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
acpi_os_wait_events_complete(NULL);
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
/* Remove the handler */
obj_desc->common_notify.system_notify = NULL;
- acpi_ut_remove_reference (notify_obj);
+ acpi_ut_remove_reference(notify_obj);
}
if (handler_type & ACPI_DEVICE_NOTIFY) {
notify_obj = obj_desc->common_notify.device_notify;
if ((!notify_obj) ||
- (notify_obj->notify.handler != handler)) {
+ (notify_obj->notify.handler != handler)) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
acpi_os_wait_events_complete(NULL);
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
/* Remove the handler */
obj_desc->common_notify.device_notify = NULL;
- acpi_ut_remove_reference (notify_obj);
+ acpi_ut_remove_reference(notify_obj);
}
}
-
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_remove_notify_handler);
+EXPORT_SYMBOL(acpi_remove_notify_handler);
/*******************************************************************************
*
@@ -581,35 +555,31 @@ EXPORT_SYMBOL(acpi_remove_notify_handler);
******************************************************************************/
acpi_status
-acpi_install_gpe_handler (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 type,
- acpi_event_handler address,
- void *context)
+acpi_install_gpe_handler(acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 type, acpi_event_handler address, void *context)
{
- struct acpi_gpe_event_info *gpe_event_info;
- struct acpi_handler_info *handler;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
+ struct acpi_gpe_event_info *gpe_event_info;
+ struct acpi_handler_info *handler;
+ acpi_status status;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("acpi_install_gpe_handler");
/* Parameter validation */
if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -617,49 +587,49 @@ acpi_install_gpe_handler (
/* Make sure that there isn't a handler there already */
- if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS;
goto unlock_and_exit;
}
/* Allocate and init handler object */
- handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info));
+ handler = ACPI_MEM_CALLOCATE(sizeof(struct acpi_handler_info));
if (!handler) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
}
- handler->address = address;
- handler->context = context;
+ handler->address = address;
+ handler->context = context;
handler->method_node = gpe_event_info->dispatch.method_node;
/* Disable the GPE before installing the handler */
- status = acpi_ev_disable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ev_disable_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Install the handler */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
gpe_event_info->dispatch.handler = handler;
/* Setup up dispatch flags to indicate handler (vs. method) */
- gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
+ gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
-
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_install_gpe_handler);
+EXPORT_SYMBOL(acpi_install_gpe_handler);
/*******************************************************************************
*
@@ -677,33 +647,30 @@ EXPORT_SYMBOL(acpi_install_gpe_handler);
******************************************************************************/
acpi_status
-acpi_remove_gpe_handler (
- acpi_handle gpe_device,
- u32 gpe_number,
- acpi_event_handler address)
+acpi_remove_gpe_handler(acpi_handle gpe_device,
+ u32 gpe_number, acpi_event_handler address)
{
- struct acpi_gpe_event_info *gpe_event_info;
- struct acpi_handler_info *handler;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
+ struct acpi_gpe_event_info *gpe_event_info;
+ struct acpi_handler_info *handler;
+ acpi_status status;
+ u32 flags;
+ ACPI_FUNCTION_TRACE("acpi_remove_gpe_handler");
/* Parameter validation */
if (!address) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -711,7 +678,8 @@ acpi_remove_gpe_handler (
/* Make sure that a handler is indeed installed */
- if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
+ ACPI_GPE_DISPATCH_HANDLER) {
status = AE_NOT_EXIST;
goto unlock_and_exit;
}
@@ -725,45 +693,44 @@ acpi_remove_gpe_handler (
/* Disable the GPE before removing the handler */
- status = acpi_ev_disable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ev_disable_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
acpi_os_wait_events_complete(NULL);
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
/* Remove the handler */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
handler = gpe_event_info->dispatch.handler;
/* Restore Method node (if any), set dispatch flags */
gpe_event_info->dispatch.method_node = handler->method_node;
- gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
+ gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
if (handler->method_node) {
gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
}
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
/* Now we can free the handler object */
- ACPI_MEM_FREE (handler);
+ ACPI_MEM_FREE(handler);
-
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_remove_gpe_handler);
+EXPORT_SYMBOL(acpi_remove_gpe_handler);
/*******************************************************************************
*
@@ -779,35 +746,31 @@ EXPORT_SYMBOL(acpi_remove_gpe_handler);
*
******************************************************************************/
-acpi_status
-acpi_acquire_global_lock (
- u16 timeout,
- u32 *handle)
+acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
{
- acpi_status status;
-
+ acpi_status status;
if (!handle) {
return (AE_BAD_PARAMETER);
}
- status = acpi_ex_enter_interpreter ();
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status)) {
return (status);
}
- status = acpi_ev_acquire_global_lock (timeout);
- acpi_ex_exit_interpreter ();
+ status = acpi_ev_acquire_global_lock(timeout);
+ acpi_ex_exit_interpreter();
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
acpi_gbl_global_lock_handle++;
*handle = acpi_gbl_global_lock_handle;
}
return (status);
}
-EXPORT_SYMBOL(acpi_acquire_global_lock);
+EXPORT_SYMBOL(acpi_acquire_global_lock);
/*******************************************************************************
*
@@ -821,19 +784,16 @@ EXPORT_SYMBOL(acpi_acquire_global_lock);
*
******************************************************************************/
-acpi_status
-acpi_release_global_lock (
- u32 handle)
+acpi_status acpi_release_global_lock(u32 handle)
{
- acpi_status status;
-
+ acpi_status status;
if (handle != acpi_gbl_global_lock_handle) {
return (AE_NOT_ACQUIRED);
}
- status = acpi_ev_release_global_lock ();
+ status = acpi_ev_release_global_lock();
return (status);
}
-EXPORT_SYMBOL(acpi_release_global_lock);
+EXPORT_SYMBOL(acpi_release_global_lock);
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index f337dc2cc569..887ff9f28a0d 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -48,8 +48,7 @@
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evxfevnt")
-
+ACPI_MODULE_NAME("evxfevnt")
/*******************************************************************************
*
@@ -62,44 +61,39 @@
* DESCRIPTION: Transfers the system into ACPI mode.
*
******************************************************************************/
-
-acpi_status
-acpi_enable (
- void)
+acpi_status acpi_enable(void)
{
- acpi_status status = AE_OK;
-
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE ("acpi_enable");
+ ACPI_FUNCTION_TRACE("acpi_enable");
-
- /* Make sure we have the FADT*/
+ /* Make sure we have the FADT */
if (!acpi_gbl_FADT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "No FADT information present!\n"));
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
- }
- else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "System is already in ACPI mode\n"));
+ } else {
/* Transition to ACPI mode */
- status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n"));
- return_ACPI_STATUS (status);
+ status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not transition to ACPI mode.\n"));
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "Transition to ACPI mode successful\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "Transition to ACPI mode successful\n"));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_disable
@@ -112,43 +106,38 @@ acpi_enable (
*
******************************************************************************/
-acpi_status
-acpi_disable (
- void)
+acpi_status acpi_disable(void)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("acpi_disable");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("acpi_disable");
if (!acpi_gbl_FADT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "No FADT information present!\n"));
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "System is already in legacy (non-ACPI) mode\n"));
- }
- else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "System is already in legacy (non-ACPI) mode\n"));
+ } else {
/* Transition to LEGACY mode */
- status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
+ status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not exit ACPI mode to legacy mode"));
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not exit ACPI mode to legacy mode"));
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_enable_event
@@ -162,52 +151,50 @@ acpi_disable (
*
******************************************************************************/
-acpi_status
-acpi_enable_event (
- u32 event,
- u32 flags)
+acpi_status acpi_enable_event(u32 event, u32 flags)
{
- acpi_status status = AE_OK;
- u32 value;
-
-
- ACPI_FUNCTION_TRACE ("acpi_enable_event");
+ acpi_status status = AE_OK;
+ u32 value;
+ ACPI_FUNCTION_TRACE("acpi_enable_event");
/* Decode the Fixed Event */
if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* Enable the requested fixed event (by writing a one to the
* enable register bit)
*/
- status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- 1, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_set_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, 1, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Make sure that the hardware responded */
- status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- &value, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_get_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (value != 1) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not enable %s event\n", acpi_ut_get_event_name (event)));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not enable %s event\n",
+ acpi_ut_get_event_name(event)));
+ return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_enable_event);
+EXPORT_SYMBOL(acpi_enable_event);
/*******************************************************************************
*
@@ -223,40 +210,34 @@ EXPORT_SYMBOL(acpi_enable_event);
*
******************************************************************************/
-acpi_status
-acpi_set_gpe_type (
- acpi_handle gpe_device,
- u32 gpe_number,
- u8 type)
+acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
-
-
- ACPI_FUNCTION_TRACE ("acpi_set_gpe_type");
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ ACPI_FUNCTION_TRACE("acpi_set_gpe_type");
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Set the new type (will disable GPE if currently enabled) */
- status = acpi_ev_set_gpe_type (gpe_event_info, type);
+ status = acpi_ev_set_gpe_type(gpe_event_info, type);
-unlock_and_exit:
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_set_gpe_type);
+EXPORT_SYMBOL(acpi_set_gpe_type);
/*******************************************************************************
*
@@ -273,31 +254,25 @@ EXPORT_SYMBOL(acpi_set_gpe_type);
*
******************************************************************************/
-acpi_status
-acpi_enable_gpe (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags)
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
-
-
- ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ ACPI_FUNCTION_TRACE("acpi_enable_gpe");
/* Use semaphore lock if not executing at interrupt level */
if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -305,16 +280,16 @@ acpi_enable_gpe (
/* Perform the enable */
- status = acpi_ev_enable_gpe (gpe_event_info, TRUE);
+ status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
-unlock_and_exit:
+ unlock_and_exit:
if (flags & ACPI_NOT_ISR) {
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_enable_gpe);
+EXPORT_SYMBOL(acpi_enable_gpe);
/*******************************************************************************
*
@@ -331,46 +306,39 @@ EXPORT_SYMBOL(acpi_enable_gpe);
*
******************************************************************************/
-acpi_status
-acpi_disable_gpe (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags)
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
-
-
- ACPI_FUNCTION_TRACE ("acpi_disable_gpe");
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ ACPI_FUNCTION_TRACE("acpi_disable_gpe");
/* Use semaphore lock if not executing at interrupt level */
if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
- status = acpi_ev_disable_gpe (gpe_event_info);
+ status = acpi_ev_disable_gpe(gpe_event_info);
-unlock_and_exit:
+ unlock_and_exit:
if (flags & ACPI_NOT_ISR) {
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_disable_event
@@ -384,50 +352,48 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
-acpi_disable_event (
- u32 event,
- u32 flags)
+acpi_status acpi_disable_event(u32 event, u32 flags)
{
- acpi_status status = AE_OK;
- u32 value;
-
-
- ACPI_FUNCTION_TRACE ("acpi_disable_event");
+ acpi_status status = AE_OK;
+ u32 value;
+ ACPI_FUNCTION_TRACE("acpi_disable_event");
/* Decode the Fixed Event */
if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* Disable the requested fixed event (by writing a zero to the
* enable register bit)
*/
- status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- 0, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_set_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, 0, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- &value, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_get_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (value != 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not disable %s events\n", acpi_ut_get_event_name (event)));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not disable %s events\n",
+ acpi_ut_get_event_name(event)));
+ return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_disable_event);
+EXPORT_SYMBOL(acpi_disable_event);
/*******************************************************************************
*
@@ -441,33 +407,30 @@ EXPORT_SYMBOL(acpi_disable_event);
*
******************************************************************************/
-acpi_status
-acpi_clear_event (
- u32 event)
+acpi_status acpi_clear_event(u32 event)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("acpi_clear_event");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("acpi_clear_event");
/* Decode the Fixed Event */
if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* Clear the requested fixed event (By writing a one to the
* status register bit)
*/
- status = acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
- 1, ACPI_MTX_LOCK);
+ status =
+ acpi_set_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, 1, ACPI_MTX_LOCK);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_clear_event);
+EXPORT_SYMBOL(acpi_clear_event);
/*******************************************************************************
*
@@ -483,46 +446,39 @@ EXPORT_SYMBOL(acpi_clear_event);
*
******************************************************************************/
-acpi_status
-acpi_clear_gpe (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags)
+acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
-
-
- ACPI_FUNCTION_TRACE ("acpi_clear_gpe");
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ ACPI_FUNCTION_TRACE("acpi_clear_gpe");
/* Use semaphore lock if not executing at interrupt level */
if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
- status = acpi_hw_clear_gpe (gpe_event_info);
+ status = acpi_hw_clear_gpe(gpe_event_info);
-unlock_and_exit:
+ unlock_and_exit:
if (flags & ACPI_NOT_ISR) {
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -538,36 +494,31 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
-acpi_get_event_status (
- u32 event,
- acpi_event_status *event_status)
+acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_event_status");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("acpi_get_event_status");
if (!event_status) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Decode the Fixed Event */
if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the status of the requested fixed event */
- status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id,
- event_status, ACPI_MTX_LOCK);
+ status =
+ acpi_get_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, event_status, ACPI_MTX_LOCK);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_gpe_status
@@ -585,31 +536,26 @@ acpi_get_event_status (
******************************************************************************/
acpi_status
-acpi_get_gpe_status (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags,
- acpi_event_status *event_status)
+acpi_get_gpe_status(acpi_handle gpe_device,
+ u32 gpe_number, u32 flags, acpi_event_status * event_status)
{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_gpe_status");
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ ACPI_FUNCTION_TRACE("acpi_get_gpe_status");
/* Use semaphore lock if not executing at interrupt level */
if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Ensure that we have a valid GPE number */
- gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -617,16 +563,15 @@ acpi_get_gpe_status (
/* Obtain status on the requested GPE number */
- status = acpi_hw_get_gpe_status (gpe_event_info, event_status);
+ status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
-unlock_and_exit:
+ unlock_and_exit:
if (flags & ACPI_NOT_ISR) {
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -635,7 +580,7 @@ unlock_and_exit:
* PARAMETERS: gpe_device - Handle to the parent GPE Block Device
* gpe_block_address - Address and space_iD
* register_count - Number of GPE register pairs in the block
- * interrupt_level - H/W interrupt for the block
+ * interrupt_number - H/W interrupt for the block
*
* RETURN: Status
*
@@ -644,33 +589,27 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_install_gpe_block (
- acpi_handle gpe_device,
- struct acpi_generic_address *gpe_block_address,
- u32 register_count,
- u32 interrupt_level)
+acpi_install_gpe_block(acpi_handle gpe_device,
+ struct acpi_generic_address *gpe_block_address,
+ u32 register_count, u32 interrupt_number)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- struct acpi_gpe_block_info *gpe_block;
-
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ struct acpi_gpe_block_info *gpe_block;
- ACPI_FUNCTION_TRACE ("acpi_install_gpe_block");
+ ACPI_FUNCTION_TRACE("acpi_install_gpe_block");
-
- if ((!gpe_device) ||
- (!gpe_block_address) ||
- (!register_count)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
- node = acpi_ns_map_handle_to_node (gpe_device);
+ node = acpi_ns_map_handle_to_node(gpe_device);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -680,31 +619,33 @@ acpi_install_gpe_block (
* For user-installed GPE Block Devices, the gpe_block_base_number
* is always zero
*/
- status = acpi_ev_create_gpe_block (node, gpe_block_address, register_count,
- 0, interrupt_level, &gpe_block);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
+ interrupt_number, &gpe_block);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Get the device_object attached to the node */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
/* No object, create a new one */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_DEVICE);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
}
- status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
+ status =
+ acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
}
@@ -713,13 +654,12 @@ acpi_install_gpe_block (
obj_desc->device.gpe_block = gpe_block;
-
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_install_gpe_block);
+EXPORT_SYMBOL(acpi_install_gpe_block);
/*******************************************************************************
*
@@ -733,28 +673,24 @@ EXPORT_SYMBOL(acpi_install_gpe_block);
*
******************************************************************************/
-acpi_status
-acpi_remove_gpe_block (
- acpi_handle gpe_device)
+acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
- struct acpi_namespace_node *node;
-
-
- ACPI_FUNCTION_TRACE ("acpi_remove_gpe_block");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ ACPI_FUNCTION_TRACE("acpi_remove_gpe_block");
if (!gpe_device) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
- node = acpi_ns_map_handle_to_node (gpe_device);
+ node = acpi_ns_map_handle_to_node(gpe_device);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -762,22 +698,21 @@ acpi_remove_gpe_block (
/* Get the device_object attached to the node */
- obj_desc = acpi_ns_get_attached_object (node);
- if (!obj_desc ||
- !obj_desc->device.gpe_block) {
- return_ACPI_STATUS (AE_NULL_OBJECT);
+ obj_desc = acpi_ns_get_attached_object(node);
+ if (!obj_desc || !obj_desc->device.gpe_block) {
+ return_ACPI_STATUS(AE_NULL_OBJECT);
}
/* Delete the GPE block (but not the device_object) */
- status = acpi_ev_delete_gpe_block (obj_desc->device.gpe_block);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
+ if (ACPI_SUCCESS(status)) {
obj_desc->device.gpe_block = NULL;
}
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
EXPORT_SYMBOL(acpi_remove_gpe_block);
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index d058587b3427..6f28ea2db5ba 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -49,8 +49,7 @@
#include <acpi/acevents.h>
#define _COMPONENT ACPI_EVENTS
- ACPI_MODULE_NAME ("evxfregn")
-
+ACPI_MODULE_NAME("evxfregn")
/*******************************************************************************
*
@@ -67,36 +66,31 @@
* DESCRIPTION: Install a handler for all op_regions of a given space_id.
*
******************************************************************************/
-
acpi_status
-acpi_install_address_space_handler (
- acpi_handle device,
- acpi_adr_space_type space_id,
- acpi_adr_space_handler handler,
- acpi_adr_space_setup setup,
- void *context)
+acpi_install_address_space_handler(acpi_handle device,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler,
+ acpi_adr_space_setup setup, void *context)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler");
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_install_address_space_handler");
/* Parameter validation */
if (!device) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Convert and validate the device handle */
- node = acpi_ns_map_handle_to_node (device);
+ node = acpi_ns_map_handle_to_node(device);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -104,21 +98,23 @@ acpi_install_address_space_handler (
/* Install the handler for all Regions for this Space ID */
- status = acpi_ev_install_space_handler (node, space_id, handler, setup, context);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ev_install_space_handler(node, space_id, handler, setup,
+ context);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Run all _REG methods for this address space */
- status = acpi_ev_execute_reg_methods (node, space_id);
+ status = acpi_ev_execute_reg_methods(node, space_id);
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_install_address_space_handler);
+EXPORT_SYMBOL(acpi_install_address_space_handler);
/*******************************************************************************
*
@@ -135,36 +131,33 @@ EXPORT_SYMBOL(acpi_install_address_space_handler);
******************************************************************************/
acpi_status
-acpi_remove_address_space_handler (
- acpi_handle device,
- acpi_adr_space_type space_id,
- acpi_adr_space_handler handler)
+acpi_remove_address_space_handler(acpi_handle device,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *handler_obj;
- union acpi_operand_object *region_obj;
- union acpi_operand_object **last_obj_ptr;
- struct acpi_namespace_node *node;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_remove_address_space_handler");
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *handler_obj;
+ union acpi_operand_object *region_obj;
+ union acpi_operand_object **last_obj_ptr;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_remove_address_space_handler");
/* Parameter validation */
if (!device) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Convert and validate the device handle */
- node = acpi_ns_map_handle_to_node (device);
+ node = acpi_ns_map_handle_to_node(device);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -172,7 +165,7 @@ acpi_remove_address_space_handler (
/* Make sure the internal object exists */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
status = AE_NOT_EXIST;
goto unlock_and_exit;
@@ -188,10 +181,11 @@ acpi_remove_address_space_handler (
if (handler_obj->address_space.space_id == space_id) {
/* Matched space_id, first dereference this in the Regions */
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
- handler_obj, handler, acpi_ut_get_region_name (space_id),
- node, obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+ handler_obj, handler,
+ acpi_ut_get_region_name(space_id),
+ node, obj_desc));
region_obj = handler_obj->address_space.region_list;
@@ -205,13 +199,14 @@ acpi_remove_address_space_handler (
* The region is just inaccessible as indicated to
* the _REG method
*/
- acpi_ev_detach_region (region_obj, TRUE);
+ acpi_ev_detach_region(region_obj, TRUE);
/*
* Walk the list: Just grab the head because the
* detach_region removed the previous head.
*/
- region_obj = handler_obj->address_space.region_list;
+ region_obj =
+ handler_obj->address_space.region_list;
}
@@ -221,7 +216,7 @@ acpi_remove_address_space_handler (
/* Now we can delete the handler object */
- acpi_ut_remove_reference (handler_obj);
+ acpi_ut_remove_reference(handler_obj);
goto unlock_and_exit;
}
@@ -233,15 +228,16 @@ acpi_remove_address_space_handler (
/* The handler does not exist */
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Unable to remove address handler %p for %s(%X), dev_node %p, obj %p\n",
- handler, acpi_ut_get_region_name (space_id), space_id, node, obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Unable to remove address handler %p for %s(%X), dev_node %p, obj %p\n",
+ handler, acpi_ut_get_region_name(space_id), space_id,
+ node, obj_desc));
status = AE_NOT_EXIST;
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_remove_address_space_handler);
+EXPORT_SYMBOL(acpi_remove_address_space_handler);
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 734b2f24af48..1ce365d651d8 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
@@ -50,18 +49,14 @@
#include <acpi/actables.h>
#include <acpi/acdispat.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exconfig")
+ACPI_MODULE_NAME("exconfig")
/* Local prototypes */
-
static acpi_status
-acpi_ex_add_table (
- struct acpi_table_header *table,
- struct acpi_namespace_node *parent_node,
- union acpi_operand_object **ddb_handle);
-
+acpi_ex_add_table(struct acpi_table_header *table,
+ struct acpi_namespace_node *parent_node,
+ union acpi_operand_object **ddb_handle);
/*******************************************************************************
*
@@ -79,64 +74,67 @@ acpi_ex_add_table (
******************************************************************************/
static acpi_status
-acpi_ex_add_table (
- struct acpi_table_header *table,
- struct acpi_namespace_node *parent_node,
- union acpi_operand_object **ddb_handle)
+acpi_ex_add_table(struct acpi_table_header *table,
+ struct acpi_namespace_node *parent_node,
+ union acpi_operand_object **ddb_handle)
{
- acpi_status status;
- struct acpi_table_desc table_info;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE ("ex_add_table");
+ acpi_status status;
+ struct acpi_table_desc table_info;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE("ex_add_table");
/* Create an object to be the table handle */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
+ /* Init the table handle */
+
+ obj_desc->reference.opcode = AML_LOAD_OP;
+ *ddb_handle = obj_desc;
+
/* Install the new table into the local data structures */
- ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
+ ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));
- table_info.type = ACPI_TABLE_SSDT;
- table_info.pointer = table;
- table_info.length = (acpi_size) table->length;
+ table_info.type = ACPI_TABLE_SSDT;
+ table_info.pointer = table;
+ table_info.length = (acpi_size) table->length;
table_info.allocation = ACPI_MEM_ALLOCATED;
- status = acpi_tb_install_table (&table_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_install_table(&table_info);
+ obj_desc->reference.object = table_info.installed_desc;
+
+ if (ACPI_FAILURE(status)) {
+ if (status == AE_ALREADY_EXISTS) {
+ /* Table already exists, just return the handle */
+
+ return_ACPI_STATUS(AE_OK);
+ }
goto cleanup;
}
/* Add the table to the namespace */
- status = acpi_ns_load_table (table_info.installed_desc, parent_node);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ns_load_table(table_info.installed_desc, parent_node);
+ if (ACPI_FAILURE(status)) {
/* Uninstall table on error */
- (void) acpi_tb_uninstall_table (table_info.installed_desc);
+ (void)acpi_tb_uninstall_table(table_info.installed_desc);
goto cleanup;
}
- /* Init the table handle */
+ return_ACPI_STATUS(AE_OK);
- obj_desc->reference.opcode = AML_LOAD_OP;
- obj_desc->reference.object = table_info.installed_desc;
- *ddb_handle = obj_desc;
- return_ACPI_STATUS (AE_OK);
-
-
-cleanup:
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ cleanup:
+ acpi_ut_remove_reference(obj_desc);
+ *ddb_handle = NULL;
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_load_table_op
@@ -151,56 +149,53 @@ cleanup:
******************************************************************************/
acpi_status
-acpi_ex_load_table_op (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object **return_desc)
+acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
+ union acpi_operand_object **return_desc)
{
- acpi_status status;
- union acpi_operand_object **operand = &walk_state->operands[0];
- struct acpi_table_header *table;
- struct acpi_namespace_node *parent_node;
- struct acpi_namespace_node *start_node;
- struct acpi_namespace_node *parameter_node = NULL;
- union acpi_operand_object *ddb_handle;
-
-
- ACPI_FUNCTION_TRACE ("ex_load_table_op");
+ acpi_status status;
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ struct acpi_table_header *table;
+ struct acpi_namespace_node *parent_node;
+ struct acpi_namespace_node *start_node;
+ struct acpi_namespace_node *parameter_node = NULL;
+ union acpi_operand_object *ddb_handle;
+ ACPI_FUNCTION_TRACE("ex_load_table_op");
#if 0
/*
* Make sure that the signature does not match one of the tables that
* is already loaded.
*/
- status = acpi_tb_match_signature (operand[0]->string.pointer, NULL);
+ status = acpi_tb_match_signature(operand[0]->string.pointer, NULL);
if (status == AE_OK) {
/* Signature matched -- don't allow override */
- return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ return_ACPI_STATUS(AE_ALREADY_EXISTS);
}
#endif
/* Find the ACPI table */
- status = acpi_tb_find_table (operand[0]->string.pointer,
- operand[1]->string.pointer,
- operand[2]->string.pointer, &table);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_find_table(operand[0]->string.pointer,
+ operand[1]->string.pointer,
+ operand[2]->string.pointer, &table);
+ if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) {
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Table not found, return an Integer=0 and AE_OK */
- ddb_handle = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!ddb_handle) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
ddb_handle->integer.value = 0;
*return_desc = ddb_handle;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Default nodes */
@@ -215,10 +210,12 @@ acpi_ex_load_table_op (
* Find the node referenced by the root_path_string. This is the
* location within the namespace where the table will be loaded.
*/
- status = acpi_ns_get_node_by_path (operand[3]->string.pointer, start_node,
- ACPI_NS_SEARCH_PARENT, &parent_node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_get_node_by_path(operand[3]->string.pointer,
+ start_node, ACPI_NS_SEARCH_PARENT,
+ &parent_node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -226,7 +223,7 @@ acpi_ex_load_table_op (
if (operand[4]->string.length > 0) {
if ((operand[4]->string.pointer[0] != '\\') &&
- (operand[4]->string.pointer[0] != '^')) {
+ (operand[4]->string.pointer[0] != '^')) {
/*
* Path is not absolute, so it will be relative to the node
* referenced by the root_path_string (or the NS root if omitted)
@@ -236,18 +233,20 @@ acpi_ex_load_table_op (
/* Find the node referenced by the parameter_path_string */
- status = acpi_ns_get_node_by_path (operand[4]->string.pointer, start_node,
- ACPI_NS_SEARCH_PARENT, &parameter_node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_get_node_by_path(operand[4]->string.pointer,
+ start_node, ACPI_NS_SEARCH_PARENT,
+ &parameter_node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Load the table into the namespace */
- status = acpi_ex_add_table (table, parent_node, &ddb_handle);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_add_table(table, parent_node, &ddb_handle);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Parameter Data (optional) */
@@ -255,20 +254,20 @@ acpi_ex_load_table_op (
if (parameter_node) {
/* Store the parameter data into the optional parameter object */
- status = acpi_ex_store (operand[5],
- ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
- walk_state);
- if (ACPI_FAILURE (status)) {
- (void) acpi_ex_unload_table (ddb_handle);
- return_ACPI_STATUS (status);
+ status = acpi_ex_store(operand[5],
+ ACPI_CAST_PTR(union acpi_operand_object,
+ parameter_node),
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ (void)acpi_ex_unload_table(ddb_handle);
+ return_ACPI_STATUS(status);
}
}
*return_desc = ddb_handle;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_load_op
@@ -285,38 +284,37 @@ acpi_ex_load_table_op (
******************************************************************************/
acpi_status
-acpi_ex_load_op (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *target,
- struct acpi_walk_state *walk_state)
+acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ union acpi_operand_object *target,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_operand_object *ddb_handle;
- union acpi_operand_object *buffer_desc = NULL;
- struct acpi_table_header *table_ptr = NULL;
- acpi_physical_address address;
- struct acpi_table_header table_header;
- u32 i;
-
- ACPI_FUNCTION_TRACE ("ex_load_op");
+ acpi_status status;
+ union acpi_operand_object *ddb_handle;
+ union acpi_operand_object *buffer_desc = NULL;
+ struct acpi_table_header *table_ptr = NULL;
+ acpi_physical_address address;
+ struct acpi_table_header table_header;
+ u32 i;
+ ACPI_FUNCTION_TRACE("ex_load_op");
/* Object can be either an op_region or a Field */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_REGION:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
- obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
+ obj_desc,
+ acpi_ut_get_object_type_name(obj_desc)));
/*
* If the Region Address and Length have not been previously evaluated,
* evaluate them now and save the results.
*/
if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
- status = acpi_ds_get_region_arguments (obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_get_region_arguments(obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -328,116 +326,127 @@ acpi_ex_load_op (
table_header.length = 0;
for (i = 0; i < 8; i++) {
- status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
- (acpi_physical_address) (i + address), 8,
- ((u8 *) &table_header) + i);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
+ (acpi_physical_address)
+ (i + address), 8,
+ ((u8 *) &
+ table_header) + i);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Sanity check the table length */
- if (table_header.length < sizeof (struct acpi_table_header)) {
- return_ACPI_STATUS (AE_BAD_HEADER);
+ if (table_header.length < sizeof(struct acpi_table_header)) {
+ return_ACPI_STATUS(AE_BAD_HEADER);
}
/* Allocate a buffer for the entire table */
- table_ptr = ACPI_MEM_ALLOCATE (table_header.length);
+ table_ptr = ACPI_MEM_ALLOCATE(table_header.length);
if (!table_ptr) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Get the entire table from the op region */
for (i = 0; i < table_header.length; i++) {
- status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
- (acpi_physical_address) (i + address), 8,
- ((u8 *) table_ptr + i));
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
+ (acpi_physical_address)
+ (i + address), 8,
+ ((u8 *) table_ptr +
+ i));
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
}
break;
-
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Field %p %s\n",
- obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Field %p %s\n",
+ obj_desc,
+ acpi_ut_get_object_type_name(obj_desc)));
/*
* The length of the field must be at least as large as the table.
* Read the entire field and thus the entire table. Buffer is
* allocated during the read.
*/
- status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc);
- if (ACPI_FAILURE (status)) {
- goto cleanup;
+ status =
+ acpi_ex_read_data_from_field(walk_state, obj_desc,
+ &buffer_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- table_ptr = ACPI_CAST_PTR (struct acpi_table_header,
- buffer_desc->buffer.pointer);
+ table_ptr = ACPI_CAST_PTR(struct acpi_table_header,
+ buffer_desc->buffer.pointer);
- /* Sanity check the table length */
+ /* All done with the buffer_desc, delete it */
- if (table_ptr->length < sizeof (struct acpi_table_header)) {
- return_ACPI_STATUS (AE_BAD_HEADER);
+ buffer_desc->buffer.pointer = NULL;
+ acpi_ut_remove_reference(buffer_desc);
+
+ /* Sanity check the table length */
+
+ if (table_ptr->length < sizeof(struct acpi_table_header)) {
+ status = AE_BAD_HEADER;
+ goto cleanup;
}
break;
-
default:
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* The table must be either an SSDT or a PSDT */
- if ((!ACPI_STRNCMP (table_ptr->signature,
- acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
- acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
- (!ACPI_STRNCMP (table_ptr->signature,
- acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
- acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
- table_ptr->signature));
+ if ((!ACPI_STRNCMP(table_ptr->signature,
+ acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
+ acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
+ (!ACPI_STRNCMP(table_ptr->signature,
+ acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
+ acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
+ table_ptr->signature));
status = AE_BAD_SIGNATURE;
goto cleanup;
}
/* Install the new table into the local data structures */
- status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle);
- if (ACPI_FAILURE (status)) {
- goto cleanup;
- }
-
- /* Store the ddb_handle into the Target operand */
+ status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle);
+ if (ACPI_FAILURE(status)) {
+ /* On error, table_ptr was deallocated above */
- status = acpi_ex_store (ddb_handle, target, walk_state);
- if (ACPI_FAILURE (status)) {
- (void) acpi_ex_unload_table (ddb_handle);
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS (status);
+ /* Store the ddb_handle into the Target operand */
+ status = acpi_ex_store(ddb_handle, target, walk_state);
+ if (ACPI_FAILURE(status)) {
+ (void)acpi_ex_unload_table(ddb_handle);
-cleanup:
+ /* table_ptr was deallocated above */
- if (buffer_desc) {
- acpi_ut_remove_reference (buffer_desc);
+ return_ACPI_STATUS(status);
}
- else {
- ACPI_MEM_FREE (table_ptr);
+
+ cleanup:
+ if (ACPI_FAILURE(status)) {
+ ACPI_MEM_FREE(table_ptr);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_unload_table
@@ -450,17 +459,13 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_unload_table (
- union acpi_operand_object *ddb_handle)
+acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *table_desc = ddb_handle;
- struct acpi_table_desc *table_info;
-
-
- ACPI_FUNCTION_TRACE ("ex_unload_table");
+ acpi_status status = AE_OK;
+ union acpi_operand_object *table_desc = ddb_handle;
+ struct acpi_table_desc *table_info;
+ ACPI_FUNCTION_TRACE("ex_unload_table");
/*
* Validate the handle
@@ -469,28 +474,28 @@ acpi_ex_unload_table (
* validated here.
*/
if ((!ddb_handle) ||
- (ACPI_GET_DESCRIPTOR_TYPE (ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE (ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
+ (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the actual table descriptor from the ddb_handle */
- table_info = (struct acpi_table_desc *) table_desc->reference.object;
+ table_info = (struct acpi_table_desc *)table_desc->reference.object;
/*
* Delete the entire namespace under this table Node
* (Offset contains the table_id)
*/
- acpi_ns_delete_namespace_by_owner (table_info->table_id);
+ acpi_ns_delete_namespace_by_owner(table_info->owner_id);
+ acpi_ut_release_owner_id(&table_info->owner_id);
/* Delete the table itself */
- (void) acpi_tb_uninstall_table (table_info->installed_desc);
+ (void)acpi_tb_uninstall_table(table_info->installed_desc);
/* Delete the table descriptor (ddb_handle) */
- acpi_ut_remove_reference (table_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(table_desc);
+ return_ACPI_STATUS(status);
}
-
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 97856c48bd74..04e5194989a6 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -41,24 +41,17 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exconvrt")
+ACPI_MODULE_NAME("exconvrt")
/* Local prototypes */
-
static u32
-acpi_ex_convert_to_ascii (
- acpi_integer integer,
- u16 base,
- u8 *string,
- u8 max_length);
-
+acpi_ex_convert_to_ascii(acpi_integer integer,
+ u16 base, u8 * string, u8 max_length);
/*******************************************************************************
*
@@ -76,29 +69,25 @@ acpi_ex_convert_to_ascii (
******************************************************************************/
acpi_status
-acpi_ex_convert_to_integer (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc,
- u32 flags)
+acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc, u32 flags)
{
- union acpi_operand_object *return_desc;
- u8 *pointer;
- acpi_integer result;
- u32 i;
- u32 count;
- acpi_status status;
-
+ union acpi_operand_object *return_desc;
+ u8 *pointer;
+ acpi_integer result;
+ u32 i;
+ u32 count;
+ acpi_status status;
- ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc);
+ ACPI_FUNCTION_TRACE_PTR("ex_convert_to_integer", obj_desc);
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_INTEGER:
/* No conversion necessary */
*result_desc = obj_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_STRING:
@@ -106,11 +95,11 @@ acpi_ex_convert_to_integer (
/* Note: Takes advantage of common buffer/string fields */
pointer = obj_desc->buffer.pointer;
- count = obj_desc->buffer.length;
+ count = obj_desc->buffer.length;
break;
default:
- return_ACPI_STATUS (AE_TYPE);
+ return_ACPI_STATUS(AE_TYPE);
}
/*
@@ -126,7 +115,7 @@ acpi_ex_convert_to_integer (
/* String conversion is different than Buffer conversion */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_STRING:
/*
@@ -135,19 +124,18 @@ acpi_ex_convert_to_integer (
* of ACPI 3.0) is that the to_integer() operator allows both decimal
* and hexadecimal strings (hex prefixed with "0x").
*/
- status = acpi_ut_strtoul64 ((char *) pointer, flags, &result);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_strtoul64((char *)pointer, flags, &result);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
break;
-
case ACPI_TYPE_BUFFER:
/* Check for zero-length buffer */
if (!count) {
- return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+ return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
}
/* Transfer no more than an integer's worth of data */
@@ -170,7 +158,6 @@ acpi_ex_convert_to_integer (
}
break;
-
default:
/* No other types can get here */
break;
@@ -178,20 +165,19 @@ acpi_ex_convert_to_integer (
/* Create a new integer */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Save the Result */
return_desc->integer.value = result;
- acpi_ex_truncate_for32bit_table (return_desc);
+ acpi_ex_truncate_for32bit_table(return_desc);
*result_desc = return_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_convert_to_buffer
@@ -207,25 +193,21 @@ acpi_ex_convert_to_integer (
******************************************************************************/
acpi_status
-acpi_ex_convert_to_buffer (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc)
+acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc)
{
- union acpi_operand_object *return_desc;
- u8 *new_buf;
+ union acpi_operand_object *return_desc;
+ u8 *new_buf;
+ ACPI_FUNCTION_TRACE_PTR("ex_convert_to_buffer", obj_desc);
- ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc);
-
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_BUFFER:
/* No conversion necessary */
*result_desc = obj_desc;
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(AE_OK);
case ACPI_TYPE_INTEGER:
@@ -233,20 +215,20 @@ acpi_ex_convert_to_buffer (
* Create a new Buffer object.
* Need enough space for one integer
*/
- return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
+ return_desc =
+ acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the integer to the buffer, LSB first */
new_buf = return_desc->buffer.pointer;
- ACPI_MEMCPY (new_buf,
- &obj_desc->integer.value,
- acpi_gbl_integer_byte_width);
+ ACPI_MEMCPY(new_buf,
+ &obj_desc->integer.value,
+ acpi_gbl_integer_byte_width);
break;
-
case ACPI_TYPE_STRING:
/*
@@ -258,32 +240,31 @@ acpi_ex_convert_to_buffer (
* ASL/AML code that depends on the null being transferred to the new
* buffer.
*/
- return_desc = acpi_ut_create_buffer_object (
- (acpi_size) obj_desc->string.length + 1);
+ return_desc = acpi_ut_create_buffer_object((acpi_size)
+ obj_desc->string.
+ length + 1);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the string to the buffer */
new_buf = return_desc->buffer.pointer;
- ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
- obj_desc->string.length);
+ ACPI_STRNCPY((char *)new_buf, (char *)obj_desc->string.pointer,
+ obj_desc->string.length);
break;
-
default:
- return_ACPI_STATUS (AE_TYPE);
+ return_ACPI_STATUS(AE_TYPE);
}
/* Mark buffer initialized */
return_desc->common.flags |= AOPOBJ_DATA_VALID;
*result_desc = return_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_convert_to_ascii
@@ -300,24 +281,19 @@ acpi_ex_convert_to_buffer (
******************************************************************************/
static u32
-acpi_ex_convert_to_ascii (
- acpi_integer integer,
- u16 base,
- u8 *string,
- u8 data_width)
+acpi_ex_convert_to_ascii(acpi_integer integer,
+ u16 base, u8 * string, u8 data_width)
{
- acpi_integer digit;
- acpi_native_uint i;
- acpi_native_uint j;
- acpi_native_uint k = 0;
- acpi_native_uint hex_length;
- acpi_native_uint decimal_length;
- u32 remainder;
- u8 supress_zeros;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_integer digit;
+ acpi_native_uint i;
+ acpi_native_uint j;
+ acpi_native_uint k = 0;
+ acpi_native_uint hex_length;
+ acpi_native_uint decimal_length;
+ u32 remainder;
+ u8 supress_zeros;
+ ACPI_FUNCTION_ENTRY();
switch (base) {
case 10:
@@ -339,7 +315,7 @@ acpi_ex_convert_to_ascii (
break;
}
- supress_zeros = TRUE; /* No leading zeros */
+ supress_zeros = TRUE; /* No leading zeros */
remainder = 0;
for (i = decimal_length; i > 0; i--) {
@@ -347,7 +323,8 @@ acpi_ex_convert_to_ascii (
digit = integer;
for (j = 0; j < i; j++) {
- (void) acpi_ut_short_divide (digit, 10, &digit, &remainder);
+ (void)acpi_ut_short_divide(digit, 10, &digit,
+ &remainder);
}
/* Handle leading zeros */
@@ -367,11 +344,13 @@ acpi_ex_convert_to_ascii (
/* hex_length: 2 ascii hex chars per data byte */
- hex_length = ACPI_MUL_2 (data_width);
- for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
+ hex_length = (acpi_native_uint) ACPI_MUL_2(data_width);
+ for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
/* Get one hex digit, most significant digits first */
- string[k] = (u8) acpi_ut_hex_to_ascii_char (integer, ACPI_MUL_4 (j));
+ string[k] =
+ (u8) acpi_ut_hex_to_ascii_char(integer,
+ ACPI_MUL_4(j));
k++;
}
break;
@@ -387,15 +366,14 @@ acpi_ex_convert_to_ascii (
* Finally, null terminate the string and return the length
*/
if (!k) {
- string [0] = ACPI_ASCII_ZERO;
+ string[0] = ACPI_ASCII_ZERO;
k = 1;
}
- string [k] = 0;
+ string[k] = 0;
return ((u32) k);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_convert_to_string
@@ -412,30 +390,25 @@ acpi_ex_convert_to_ascii (
******************************************************************************/
acpi_status
-acpi_ex_convert_to_string (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc,
- u32 type)
+acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
+ union acpi_operand_object ** result_desc, u32 type)
{
- union acpi_operand_object *return_desc;
- u8 *new_buf;
- u32 i;
- u32 string_length = 0;
- u16 base = 16;
- u8 separator = ',';
+ union acpi_operand_object *return_desc;
+ u8 *new_buf;
+ u32 i;
+ u32 string_length = 0;
+ u16 base = 16;
+ u8 separator = ',';
+ ACPI_FUNCTION_TRACE_PTR("ex_convert_to_string", obj_desc);
- ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
-
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_STRING:
/* No conversion necessary */
*result_desc = obj_desc;
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(AE_OK);
case ACPI_TYPE_INTEGER:
@@ -452,7 +425,7 @@ acpi_ex_convert_to_string (
/* Two hex string characters for each integer byte */
- string_length = ACPI_MUL_2 (acpi_gbl_integer_byte_width);
+ string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
break;
}
@@ -460,31 +433,33 @@ acpi_ex_convert_to_string (
* Create a new String
* Need enough space for one ASCII integer (plus null terminator)
*/
- return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
+ return_desc =
+ acpi_ut_create_string_object((acpi_size) string_length);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
new_buf = return_desc->buffer.pointer;
/* Convert integer to string */
- string_length = acpi_ex_convert_to_ascii (obj_desc->integer.value, base,
- new_buf, acpi_gbl_integer_byte_width);
+ string_length =
+ acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
+ new_buf,
+ acpi_gbl_integer_byte_width);
/* Null terminate at the correct place */
return_desc->string.length = string_length;
- new_buf [string_length] = 0;
+ new_buf[string_length] = 0;
break;
-
case ACPI_TYPE_BUFFER:
/* Setup string length, base, and separator */
switch (type) {
- case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string */
+ case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* decimal values separated by commas."
@@ -498,11 +473,9 @@ acpi_ex_convert_to_string (
for (i = 0; i < obj_desc->buffer.length; i++) {
if (obj_desc->buffer.pointer[i] >= 100) {
string_length += 4;
- }
- else if (obj_desc->buffer.pointer[i] >= 10) {
+ } else if (obj_desc->buffer.pointer[i] >= 10) {
string_length += 3;
- }
- else {
+ } else {
string_length += 2;
}
}
@@ -518,7 +491,7 @@ acpi_ex_convert_to_string (
string_length = (obj_desc->buffer.length * 3);
break;
- case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string */
+ case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* hexadecimal values separated by commas."
@@ -527,7 +500,7 @@ acpi_ex_convert_to_string (
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -535,15 +508,16 @@ acpi_ex_convert_to_string (
* (-1 because of extra separator included in string_length from above)
*/
string_length--;
- if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
- return_ACPI_STATUS (AE_AML_STRING_LIMIT);
+ if (string_length > ACPI_MAX_STRING_CONVERSION) { /* ACPI limit */
+ return_ACPI_STATUS(AE_AML_STRING_LIMIT);
}
/* Create a new string object and string buffer */
- return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
+ return_desc =
+ acpi_ut_create_string_object((acpi_size) string_length);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
new_buf = return_desc->buffer.pointer;
@@ -553,10 +527,11 @@ acpi_ex_convert_to_string (
* (separated by commas or spaces)
*/
for (i = 0; i < obj_desc->buffer.length; i++) {
- new_buf += acpi_ex_convert_to_ascii (
- (acpi_integer) obj_desc->buffer.pointer[i], base,
- new_buf, 1);
- *new_buf++ = separator; /* each separated by a comma or space */
+ new_buf += acpi_ex_convert_to_ascii((acpi_integer)
+ obj_desc->buffer.
+ pointer[i], base,
+ new_buf, 1);
+ *new_buf++ = separator; /* each separated by a comma or space */
}
/*
@@ -568,14 +543,13 @@ acpi_ex_convert_to_string (
break;
default:
- return_ACPI_STATUS (AE_TYPE);
+ return_ACPI_STATUS(AE_TYPE);
}
*result_desc = return_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_convert_to_target_type
@@ -592,17 +566,14 @@ acpi_ex_convert_to_string (
******************************************************************************/
acpi_status
-acpi_ex_convert_to_target_type (
- acpi_object_type destination_type,
- union acpi_operand_object *source_desc,
- union acpi_operand_object **result_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_convert_to_target_type(acpi_object_type destination_type,
+ union acpi_operand_object *source_desc,
+ union acpi_operand_object **result_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ex_convert_to_target_type");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ex_convert_to_target_type");
/* Default behavior */
@@ -612,10 +583,10 @@ acpi_ex_convert_to_target_type (
* If required by the target,
* perform implicit conversion on the source before we store it.
*/
- switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
+ switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
case ARGI_SIMPLE_TARGET:
case ARGI_FIXED_TARGET:
- case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
+ case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
switch (destination_type) {
case ACPI_TYPE_LOCAL_REGION_FIELD:
@@ -627,17 +598,19 @@ acpi_ex_convert_to_target_type (
default:
/* No conversion allowed for these types */
- if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Explicit operator, will store (%s) over existing type (%s)\n",
- acpi_ut_get_object_type_name (source_desc),
- acpi_ut_get_type_name (destination_type)));
+ if (destination_type !=
+ ACPI_GET_OBJECT_TYPE(source_desc)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Explicit operator, will store (%s) over existing type (%s)\n",
+ acpi_ut_get_object_type_name
+ (source_desc),
+ acpi_ut_get_type_name
+ (destination_type)));
status = AE_TYPE;
}
}
break;
-
case ARGI_TARGETREF:
switch (destination_type) {
@@ -649,55 +622,55 @@ acpi_ex_convert_to_target_type (
* These types require an Integer operand. We can convert
* a Buffer or a String to an Integer if necessary.
*/
- status = acpi_ex_convert_to_integer (source_desc, result_desc,
- 16);
+ status =
+ acpi_ex_convert_to_integer(source_desc, result_desc,
+ 16);
break;
-
case ACPI_TYPE_STRING:
/*
* The operand must be a String. We can convert an
* Integer or Buffer if necessary
*/
- status = acpi_ex_convert_to_string (source_desc, result_desc,
- ACPI_IMPLICIT_CONVERT_HEX);
+ status =
+ acpi_ex_convert_to_string(source_desc, result_desc,
+ ACPI_IMPLICIT_CONVERT_HEX);
break;
-
case ACPI_TYPE_BUFFER:
/*
* The operand must be a Buffer. We can convert an
* Integer or String if necessary
*/
- status = acpi_ex_convert_to_buffer (source_desc, result_desc);
+ status =
+ acpi_ex_convert_to_buffer(source_desc, result_desc);
break;
-
default:
- ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n",
- destination_type));
+ ACPI_REPORT_ERROR(("Bad destination type during conversion: %X\n", destination_type));
status = AE_AML_INTERNAL;
break;
}
break;
-
case ARGI_REFERENCE:
/*
* create_xxxx_field cases - we are storing the field object into the name
*/
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown Target type ID 0x%X Op %s dest_type %s\n",
- GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args),
- walk_state->op_info->name, acpi_ut_get_type_name (destination_type)));
-
- ACPI_REPORT_ERROR (("Bad Target Type (ARGI): %X\n",
- GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)))
- status = AE_AML_INTERNAL;
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown Target type ID 0x%X Op %s dest_type %s\n",
+ GET_CURRENT_ARG_TYPE(walk_state->op_info->
+ runtime_args),
+ walk_state->op_info->name,
+ acpi_ut_get_type_name(destination_type)));
+
+ ACPI_REPORT_ERROR(("Bad Target Type (ARGI): %X\n",
+ GET_CURRENT_ARG_TYPE(walk_state->op_info->
+ runtime_args)))
+ status = AE_AML_INTERNAL;
}
/*
@@ -710,7 +683,5 @@ acpi_ex_convert_to_target_type (
status = AE_OK;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 812cdcb2e370..91c49188fb07 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
@@ -49,10 +48,8 @@
#include <acpi/acevents.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("excreate")
-
+ACPI_MODULE_NAME("excreate")
#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
@@ -66,33 +63,30 @@
* DESCRIPTION: Create a new named alias
*
******************************************************************************/
-
-acpi_status
-acpi_ex_create_alias (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
{
- struct acpi_namespace_node *target_node;
- struct acpi_namespace_node *alias_node;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ex_create_alias");
+ struct acpi_namespace_node *target_node;
+ struct acpi_namespace_node *alias_node;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ex_create_alias");
/* Get the source/alias operands (both namespace nodes) */
- alias_node = (struct acpi_namespace_node *) walk_state->operands[0];
- target_node = (struct acpi_namespace_node *) walk_state->operands[1];
+ alias_node = (struct acpi_namespace_node *)walk_state->operands[0];
+ target_node = (struct acpi_namespace_node *)walk_state->operands[1];
if ((target_node->type == ACPI_TYPE_LOCAL_ALIAS) ||
- (target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
+ (target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
/*
* Dereference an existing alias so that we don't create a chain
* of aliases. With this code, we guarantee that an alias is
* always exactly one level of indirection away from the
* actual aliased name.
*/
- target_node = ACPI_CAST_PTR (struct acpi_namespace_node, target_node->object);
+ target_node =
+ ACPI_CAST_PTR(struct acpi_namespace_node,
+ target_node->object);
}
/*
@@ -115,7 +109,8 @@ acpi_ex_create_alias (
* types, the object can change dynamically via a Store.
*/
alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
- alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node);
+ alias_node->object =
+ ACPI_CAST_PTR(union acpi_operand_object, target_node);
break;
case ACPI_TYPE_METHOD:
@@ -126,7 +121,8 @@ acpi_ex_create_alias (
* types, the object can change dynamically via a Store.
*/
alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
- alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node);
+ alias_node->object =
+ ACPI_CAST_PTR(union acpi_operand_object, target_node);
break;
default:
@@ -139,17 +135,18 @@ acpi_ex_create_alias (
* additional reference to prevent deletion out from under either the
* target node or the alias Node
*/
- status = acpi_ns_attach_object (alias_node,
- acpi_ns_get_attached_object (target_node), target_node->type);
+ status = acpi_ns_attach_object(alias_node,
+ acpi_ns_get_attached_object
+ (target_node),
+ target_node->type);
break;
}
/* Since both operands are Nodes, we don't need to delete them */
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_event
@@ -162,18 +159,14 @@ acpi_ex_create_alias (
*
******************************************************************************/
-acpi_status
-acpi_ex_create_event (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE ("ex_create_event");
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE("ex_create_event");
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_EVENT);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_EVENT);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -183,27 +176,27 @@ acpi_ex_create_event (
* Create the actual OS semaphore, with zero initial units -- meaning
* that the event is created in an unsignalled state
*/
- status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0,
- &obj_desc->event.semaphore);
- if (ACPI_FAILURE (status)) {
+ status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
+ &obj_desc->event.semaphore);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Attach object to the Node */
- status = acpi_ns_attach_object ((struct acpi_namespace_node *) walk_state->operands[0],
- obj_desc, ACPI_TYPE_EVENT);
+ status =
+ acpi_ns_attach_object((struct acpi_namespace_node *)walk_state->
+ operands[0], obj_desc, ACPI_TYPE_EVENT);
-cleanup:
+ cleanup:
/*
* Remove local reference to the object (on error, will cause deletion
* of both object and semaphore if present.)
*/
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_mutex
@@ -218,20 +211,16 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_create_mutex (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_create_mutex", ACPI_WALK_OPERANDS);
+ acpi_status status = AE_OK;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE_PTR("ex_create_mutex", ACPI_WALK_OPERANDS);
/* Create the new mutex object */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_MUTEX);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_MUTEX);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -242,30 +231,30 @@ acpi_ex_create_mutex (
* One unit max to make it a mutex, with one initial unit to allow
* the mutex to be acquired.
*/
- status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore);
- if (ACPI_FAILURE (status)) {
+ status = acpi_os_create_semaphore(1, 1, &obj_desc->mutex.semaphore);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Init object and attach to NS node */
- obj_desc->mutex.sync_level = (u8) walk_state->operands[1]->integer.value;
- obj_desc->mutex.node = (struct acpi_namespace_node *) walk_state->operands[0];
-
- status = acpi_ns_attach_object (obj_desc->mutex.node,
- obj_desc, ACPI_TYPE_MUTEX);
+ obj_desc->mutex.sync_level =
+ (u8) walk_state->operands[1]->integer.value;
+ obj_desc->mutex.node =
+ (struct acpi_namespace_node *)walk_state->operands[0];
+ status = acpi_ns_attach_object(obj_desc->mutex.node,
+ obj_desc, ACPI_TYPE_MUTEX);
-cleanup:
+ cleanup:
/*
* Remove local reference to the object (on error, will cause deletion
* of both object and semaphore if present.)
*/
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_region
@@ -282,20 +271,16 @@ cleanup:
******************************************************************************/
acpi_status
-acpi_ex_create_region (
- u8 *aml_start,
- u32 aml_length,
- u8 region_space,
- struct acpi_walk_state *walk_state)
+acpi_ex_create_region(u8 * aml_start,
+ u32 aml_length,
+ u8 region_space, struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- union acpi_operand_object *region_obj2;
-
-
- ACPI_FUNCTION_TRACE ("ex_create_region");
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *region_obj2;
+ ACPI_FUNCTION_TRACE("ex_create_region");
/* Get the Namespace Node */
@@ -305,8 +290,8 @@ acpi_ex_create_region (
* If the region object is already attached to this node,
* just return
*/
- if (acpi_ns_get_attached_object (node)) {
- return_ACPI_STATUS (AE_OK);
+ if (acpi_ns_get_attached_object(node)) {
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -314,17 +299,18 @@ acpi_ex_create_region (
* range
*/
if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
- (region_space < ACPI_USER_REGION_BEGIN)) {
- ACPI_REPORT_ERROR (("Invalid address_space type %X\n", region_space));
- return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
+ (region_space < ACPI_USER_REGION_BEGIN)) {
+ ACPI_REPORT_ERROR(("Invalid address_space type %X\n",
+ region_space));
+ return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
- acpi_ut_get_region_name (region_space), region_space));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
+ acpi_ut_get_region_name(region_space), region_space));
/* Create the region descriptor */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -334,7 +320,7 @@ acpi_ex_create_region (
* Remember location in AML stream of address & length
* operands since they need to be evaluated at run time.
*/
- region_obj2 = obj_desc->common.next_object;
+ region_obj2 = obj_desc->common.next_object;
region_obj2->extra.aml_start = aml_start;
region_obj2->extra.aml_length = aml_length;
@@ -343,22 +329,20 @@ acpi_ex_create_region (
obj_desc->region.space_id = region_space;
obj_desc->region.address = 0;
obj_desc->region.length = 0;
- obj_desc->region.node = node;
+ obj_desc->region.node = node;
/* Install the new region object in the parent Node */
- status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION);
+ status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
-
-cleanup:
+ cleanup:
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_table_region
@@ -371,20 +355,16 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_create_table_region (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
{
- acpi_status status;
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- struct acpi_table_header *table;
- union acpi_operand_object *region_obj2;
-
-
- ACPI_FUNCTION_TRACE ("ex_create_table_region");
+ acpi_status status;
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ struct acpi_table_header *table;
+ union acpi_operand_object *region_obj2;
+ ACPI_FUNCTION_TRACE("ex_create_table_region");
/* Get the Node from the object stack */
@@ -394,66 +374,64 @@ acpi_ex_create_table_region (
* If the region object is already attached to this node,
* just return
*/
- if (acpi_ns_get_attached_object (node)) {
- return_ACPI_STATUS (AE_OK);
+ if (acpi_ns_get_attached_object(node)) {
+ return_ACPI_STATUS(AE_OK);
}
/* Find the ACPI table */
- status = acpi_tb_find_table (operand[1]->string.pointer,
- operand[2]->string.pointer,
- operand[3]->string.pointer, &table);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_find_table(operand[1]->string.pointer,
+ operand[2]->string.pointer,
+ operand[3]->string.pointer, &table);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Create the region descriptor */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- region_obj2 = obj_desc->common.next_object;
+ region_obj2 = obj_desc->common.next_object;
region_obj2->extra.region_context = NULL;
/* Init the region from the operands */
obj_desc->region.space_id = REGION_DATA_TABLE;
- obj_desc->region.address = (acpi_physical_address) ACPI_TO_INTEGER (table);
+ obj_desc->region.address =
+ (acpi_physical_address) ACPI_TO_INTEGER(table);
obj_desc->region.length = table->length;
- obj_desc->region.node = node;
- obj_desc->region.flags = AOPOBJ_DATA_VALID;
+ obj_desc->region.node = node;
+ obj_desc->region.flags = AOPOBJ_DATA_VALID;
/* Install the new region object in the parent Node */
- status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- status = acpi_ev_initialize_region (obj_desc, FALSE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ev_initialize_region(obj_desc, FALSE);
+ if (ACPI_FAILURE(status)) {
if (status == AE_NOT_EXIST) {
status = AE_OK;
- }
- else {
+ } else {
goto cleanup;
}
}
obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE;
-
-cleanup:
+ cleanup:
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_processor
@@ -468,43 +446,39 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_create_processor (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_create_processor", walk_state);
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ex_create_processor", walk_state);
/* Create the processor object */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PROCESSOR);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PROCESSOR);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize the processor object from the operands */
- obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
- obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value;
- obj_desc->processor.length = (u8) operand[3]->integer.value;
+ obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
+ obj_desc->processor.address =
+ (acpi_io_address) operand[2]->integer.value;
+ obj_desc->processor.length = (u8) operand[3]->integer.value;
/* Install the processor object in the parent Node */
- status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
- obj_desc, ACPI_TYPE_PROCESSOR);
+ status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
+ obj_desc, ACPI_TYPE_PROCESSOR);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_power_resource
@@ -519,43 +493,39 @@ acpi_ex_create_processor (
*
******************************************************************************/
-acpi_status
-acpi_ex_create_power_resource (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_create_power_resource(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- acpi_status status;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_create_power_resource", walk_state);
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE_PTR("ex_create_power_resource", walk_state);
/* Create the power resource object */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_POWER);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_POWER);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize the power object from the operands */
obj_desc->power_resource.system_level = (u8) operand[1]->integer.value;
- obj_desc->power_resource.resource_order = (u16) operand[2]->integer.value;
+ obj_desc->power_resource.resource_order =
+ (u16) operand[2]->integer.value;
/* Install the power resource object in the parent Node */
- status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
- obj_desc, ACPI_TYPE_POWER);
+ status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
+ obj_desc, ACPI_TYPE_POWER);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_method
@@ -571,25 +541,21 @@ acpi_ex_create_power_resource (
******************************************************************************/
acpi_status
-acpi_ex_create_method (
- u8 *aml_start,
- u32 aml_length,
- struct acpi_walk_state *walk_state)
+acpi_ex_create_method(u8 * aml_start,
+ u32 aml_length, struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *obj_desc;
- acpi_status status;
- u8 method_flags;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_create_method", walk_state);
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ u8 method_flags;
+ ACPI_FUNCTION_TRACE_PTR("ex_create_method", walk_state);
/* Create a new method object */
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_METHOD);
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Save the method's AML pointer and length */
@@ -603,8 +569,10 @@ acpi_ex_create_method (
*/
method_flags = (u8) operand[1]->integer.value;
- obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
- obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT);
+ obj_desc->method.method_flags =
+ (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
+ obj_desc->method.param_count =
+ (u8) (method_flags & AML_METHOD_ARG_COUNT);
/*
* Get the concurrency count. If required, a semaphore will be
@@ -613,32 +581,28 @@ acpi_ex_create_method (
if (acpi_gbl_all_methods_serialized) {
obj_desc->method.concurrency = 1;
obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
- }
- else if (method_flags & AML_METHOD_SERIALIZED) {
+ } else if (method_flags & AML_METHOD_SERIALIZED) {
/*
* ACPI 1.0: Concurrency = 1
* ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1)
*/
obj_desc->method.concurrency = (u8)
- (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
- }
- else {
+ (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
+ } else {
obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY;
}
/* Attach the new object to the method Node */
- status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
- obj_desc, ACPI_TYPE_METHOD);
+ status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
+ obj_desc, ACPI_TYPE_METHOD);
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
/* Remove a reference to the operand */
- acpi_ut_remove_reference (operand[1]);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(operand[1]);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 408500648114..bc2fa996047e 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
@@ -49,37 +48,27 @@
#include <acpi/acparser.h>
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exdump")
+ACPI_MODULE_NAME("exdump")
+/*
+ * The following routines are used for debug output only
+ */
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/* Local prototypes */
-
#ifdef ACPI_FUTURE_USAGE
-static void
-acpi_ex_out_string (
- char *title,
- char *value);
+static void acpi_ex_out_string(char *title, char *value);
-static void
-acpi_ex_out_pointer (
- char *title,
- void *value);
+static void acpi_ex_out_pointer(char *title, void *value);
-static void
-acpi_ex_out_integer (
- char *title,
- u32 value);
+static void acpi_ex_out_integer(char *title, u32 value);
-static void
-acpi_ex_out_address (
- char *title,
- acpi_physical_address value);
-#endif /* ACPI_FUTURE_USAGE */
+static void acpi_ex_out_address(char *title, acpi_physical_address value);
+static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc);
-/*
- * The following routines are used for debug output only
- */
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+static void
+acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index);
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -94,143 +83,140 @@ acpi_ex_out_address (
*
******************************************************************************/
-void
-acpi_ex_dump_operand (
- union acpi_operand_object *obj_desc,
- u32 depth)
+void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
{
- u32 length;
- u32 index;
-
+ u32 length;
+ u32 index;
- ACPI_FUNCTION_NAME ("ex_dump_operand")
+ ACPI_FUNCTION_NAME("ex_dump_operand")
-
- if (!((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
+ if (!
+ ((ACPI_LV_EXEC & acpi_dbg_level)
+ && (_COMPONENT & acpi_dbg_layer))) {
return;
}
if (!obj_desc) {
/* This could be a null element of a package */
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
return;
}
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc));
- ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC);
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Namespace Node: ",
+ obj_desc));
+ ACPI_DUMP_ENTRY(obj_desc, ACPI_LV_EXEC);
return;
}
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "%p is not a node or operand object: [%s]\n",
- obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
- ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object));
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "%p is not a node or operand object: [%s]\n",
+ obj_desc,
+ acpi_ut_get_descriptor_name(obj_desc)));
+ ACPI_DUMP_BUFFER(obj_desc, sizeof(union acpi_operand_object));
return;
}
/* obj_desc is a valid object */
if (depth > 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%*s[%u] %p ",
- depth, " ", depth, obj_desc));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%*s[%u] %p ",
+ depth, " ", depth, obj_desc));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p ", obj_desc));
}
/* Decode object type */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE:
switch (obj_desc->reference.opcode) {
case AML_DEBUG_OP:
- acpi_os_printf ("Reference: Debug\n");
+ acpi_os_printf("Reference: Debug\n");
break;
-
case AML_NAME_OP:
- ACPI_DUMP_PATHNAME (obj_desc->reference.object,
- "Reference: Name: ", ACPI_LV_INFO, _COMPONENT);
- ACPI_DUMP_ENTRY (obj_desc->reference.object, ACPI_LV_INFO);
+ ACPI_DUMP_PATHNAME(obj_desc->reference.object,
+ "Reference: Name: ", ACPI_LV_INFO,
+ _COMPONENT);
+ ACPI_DUMP_ENTRY(obj_desc->reference.object,
+ ACPI_LV_INFO);
break;
-
case AML_INDEX_OP:
- acpi_os_printf ("Reference: Index %p\n",
- obj_desc->reference.object);
+ acpi_os_printf("Reference: Index %p\n",
+ obj_desc->reference.object);
break;
-
case AML_REF_OF_OP:
- acpi_os_printf ("Reference: (ref_of) %p\n",
- obj_desc->reference.object);
+ acpi_os_printf("Reference: (ref_of) %p\n",
+ obj_desc->reference.object);
break;
-
case AML_ARG_OP:
- acpi_os_printf ("Reference: Arg%d",
- obj_desc->reference.offset);
+ acpi_os_printf("Reference: Arg%d",
+ obj_desc->reference.offset);
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
/* Value is an Integer */
- acpi_os_printf (" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+ acpi_os_printf(" value is [%8.8X%8.8x]",
+ ACPI_FORMAT_UINT64(obj_desc->
+ integer.
+ value));
}
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
break;
-
case AML_LOCAL_OP:
- acpi_os_printf ("Reference: Local%d",
- obj_desc->reference.offset);
+ acpi_os_printf("Reference: Local%d",
+ obj_desc->reference.offset);
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
/* Value is an Integer */
- acpi_os_printf (" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+ acpi_os_printf(" value is [%8.8X%8.8x]",
+ ACPI_FORMAT_UINT64(obj_desc->
+ integer.
+ value));
}
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
break;
-
case AML_INT_NAMEPATH_OP:
- acpi_os_printf ("Reference.Node->Name %X\n",
- obj_desc->reference.node->name.integer);
+ acpi_os_printf("Reference.Node->Name %X\n",
+ obj_desc->reference.node->name.integer);
break;
-
default:
/* Unknown opcode */
- acpi_os_printf ("Unknown Reference opcode=%X\n",
- obj_desc->reference.opcode);
+ acpi_os_printf("Unknown Reference opcode=%X\n",
+ obj_desc->reference.opcode);
break;
}
break;
-
case ACPI_TYPE_BUFFER:
- acpi_os_printf ("Buffer len %X @ %p \n",
- obj_desc->buffer.length, obj_desc->buffer.pointer);
+ acpi_os_printf("Buffer len %X @ %p \n",
+ obj_desc->buffer.length,
+ obj_desc->buffer.pointer);
length = obj_desc->buffer.length;
if (length > 64) {
@@ -240,178 +226,166 @@ acpi_ex_dump_operand (
/* Debug only -- dump the buffer contents */
if (obj_desc->buffer.pointer) {
- acpi_os_printf ("Buffer Contents: ");
+ acpi_os_printf("Buffer Contents: ");
for (index = 0; index < length; index++) {
- acpi_os_printf (" %02x", obj_desc->buffer.pointer[index]);
+ acpi_os_printf(" %02x",
+ obj_desc->buffer.pointer[index]);
}
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
}
break;
-
case ACPI_TYPE_INTEGER:
- acpi_os_printf ("Integer %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+ acpi_os_printf("Integer %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(obj_desc->integer.value));
break;
-
case ACPI_TYPE_PACKAGE:
- acpi_os_printf ("Package [Len %X] element_array %p\n",
- obj_desc->package.count, obj_desc->package.elements);
+ acpi_os_printf("Package [Len %X] element_array %p\n",
+ obj_desc->package.count,
+ obj_desc->package.elements);
/*
* If elements exist, package element pointer is valid,
* and debug_level exceeds 1, dump package's elements.
*/
if (obj_desc->package.count &&
- obj_desc->package.elements &&
- acpi_dbg_level > 1) {
- for (index = 0; index < obj_desc->package.count; index++) {
- acpi_ex_dump_operand (obj_desc->package.elements[index], depth+1);
+ obj_desc->package.elements && acpi_dbg_level > 1) {
+ for (index = 0; index < obj_desc->package.count;
+ index++) {
+ acpi_ex_dump_operand(obj_desc->package.
+ elements[index],
+ depth + 1);
}
}
break;
-
case ACPI_TYPE_REGION:
- acpi_os_printf ("Region %s (%X)",
- acpi_ut_get_region_name (obj_desc->region.space_id),
- obj_desc->region.space_id);
+ acpi_os_printf("Region %s (%X)",
+ acpi_ut_get_region_name(obj_desc->region.
+ space_id),
+ obj_desc->region.space_id);
/*
* If the address and length have not been evaluated,
* don't print them.
*/
if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
- acpi_os_printf ("\n");
- }
- else {
- acpi_os_printf (" base %8.8X%8.8X Length %X\n",
- ACPI_FORMAT_UINT64 (obj_desc->region.address),
- obj_desc->region.length);
+ acpi_os_printf("\n");
+ } else {
+ acpi_os_printf(" base %8.8X%8.8X Length %X\n",
+ ACPI_FORMAT_UINT64(obj_desc->region.
+ address),
+ obj_desc->region.length);
}
break;
-
case ACPI_TYPE_STRING:
- acpi_os_printf ("String length %X @ %p ",
- obj_desc->string.length,
- obj_desc->string.pointer);
+ acpi_os_printf("String length %X @ %p ",
+ obj_desc->string.length,
+ obj_desc->string.pointer);
- acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
- acpi_os_printf ("\n");
+ acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
+ acpi_os_printf("\n");
break;
-
case ACPI_TYPE_LOCAL_BANK_FIELD:
- acpi_os_printf ("bank_field\n");
+ acpi_os_printf("bank_field\n");
break;
-
case ACPI_TYPE_LOCAL_REGION_FIELD:
- acpi_os_printf (
- "region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
- obj_desc->field.bit_length,
- obj_desc->field.access_byte_width,
- obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
- obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
- obj_desc->field.base_byte_offset,
- obj_desc->field.start_field_bit_offset);
+ acpi_os_printf
+ ("region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
+ obj_desc->field.bit_length,
+ obj_desc->field.access_byte_width,
+ obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
+ obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
+ obj_desc->field.base_byte_offset,
+ obj_desc->field.start_field_bit_offset);
- acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
+ acpi_ex_dump_operand(obj_desc->field.region_obj, depth + 1);
break;
-
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- acpi_os_printf ("index_field\n");
+ acpi_os_printf("index_field\n");
break;
-
case ACPI_TYPE_BUFFER_FIELD:
- acpi_os_printf (
- "buffer_field: %X bits at byte %X bit %X of \n",
- obj_desc->buffer_field.bit_length,
- obj_desc->buffer_field.base_byte_offset,
- obj_desc->buffer_field.start_field_bit_offset);
+ acpi_os_printf("buffer_field: %X bits at byte %X bit %X of \n",
+ obj_desc->buffer_field.bit_length,
+ obj_desc->buffer_field.base_byte_offset,
+ obj_desc->buffer_field.start_field_bit_offset);
if (!obj_desc->buffer_field.buffer_obj) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n"));
- }
- else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) !=
- ACPI_TYPE_BUFFER) {
- acpi_os_printf ("*not a Buffer* \n");
- }
- else {
- acpi_ex_dump_operand (obj_desc->buffer_field.buffer_obj, depth+1);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL* \n"));
+ } else
+ if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
+ != ACPI_TYPE_BUFFER) {
+ acpi_os_printf("*not a Buffer* \n");
+ } else {
+ acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
+ depth + 1);
}
break;
-
case ACPI_TYPE_EVENT:
- acpi_os_printf ("Event\n");
+ acpi_os_printf("Event\n");
break;
-
case ACPI_TYPE_METHOD:
- acpi_os_printf ("Method(%X) @ %p:%X\n",
- obj_desc->method.param_count,
- obj_desc->method.aml_start,
- obj_desc->method.aml_length);
+ acpi_os_printf("Method(%X) @ %p:%X\n",
+ obj_desc->method.param_count,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length);
break;
-
case ACPI_TYPE_MUTEX:
- acpi_os_printf ("Mutex\n");
+ acpi_os_printf("Mutex\n");
break;
-
case ACPI_TYPE_DEVICE:
- acpi_os_printf ("Device\n");
+ acpi_os_printf("Device\n");
break;
-
case ACPI_TYPE_POWER:
- acpi_os_printf ("Power\n");
+ acpi_os_printf("Power\n");
break;
-
case ACPI_TYPE_PROCESSOR:
- acpi_os_printf ("Processor\n");
+ acpi_os_printf("Processor\n");
break;
-
case ACPI_TYPE_THERMAL:
- acpi_os_printf ("Thermal\n");
+ acpi_os_printf("Thermal\n");
break;
-
default:
/* Unknown Type */
- acpi_os_printf ("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE (obj_desc));
+ acpi_os_printf("Unknown Type %X\n",
+ ACPI_GET_OBJECT_TYPE(obj_desc));
break;
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_operands
@@ -429,20 +403,15 @@ acpi_ex_dump_operand (
******************************************************************************/
void
-acpi_ex_dump_operands (
- union acpi_operand_object **operands,
- acpi_interpreter_mode interpreter_mode,
- char *ident,
- u32 num_levels,
- char *note,
- char *module_name,
- u32 line_number)
+acpi_ex_dump_operands(union acpi_operand_object **operands,
+ acpi_interpreter_mode interpreter_mode,
+ char *ident,
+ u32 num_levels,
+ char *note, char *module_name, u32 line_number)
{
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_NAME ("ex_dump_operands");
+ acpi_native_uint i;
+ ACPI_FUNCTION_NAME("ex_dump_operands");
if (!ident) {
ident = "?";
@@ -452,9 +421,9 @@ acpi_ex_dump_operands (
note = "?";
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "************* Operand Stack Contents (Opcode [%s], %d Operands)\n",
- ident, num_levels));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "************* Operand Stack Contents (Opcode [%s], %d Operands)\n",
+ ident, num_levels));
if (num_levels == 0) {
num_levels = 1;
@@ -463,16 +432,15 @@ acpi_ex_dump_operands (
/* Dump the operand stack starting at the top */
for (i = 0; num_levels > 0; i--, num_levels--) {
- acpi_ex_dump_operand (operands[i], 0);
+ acpi_ex_dump_operand(operands[i], 0);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "************* Stack dump from %s(%d), %s\n",
- module_name, line_number, note));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "************* Operand Stack dump from %s(%d), %s\n",
+ module_name, line_number, note));
return;
}
-
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -487,44 +455,31 @@ acpi_ex_dump_operands (
*
******************************************************************************/
-static void
-acpi_ex_out_string (
- char *title,
- char *value)
+static void acpi_ex_out_string(char *title, char *value)
{
- acpi_os_printf ("%20s : %s\n", title, value);
+ acpi_os_printf("%20s : %s\n", title, value);
}
-static void
-acpi_ex_out_pointer (
- char *title,
- void *value)
+static void acpi_ex_out_pointer(char *title, void *value)
{
- acpi_os_printf ("%20s : %p\n", title, value);
+ acpi_os_printf("%20s : %p\n", title, value);
}
-static void
-acpi_ex_out_integer (
- char *title,
- u32 value)
+static void acpi_ex_out_integer(char *title, u32 value)
{
- acpi_os_printf ("%20s : %X\n", title, value);
+ acpi_os_printf("%20s : %.2X\n", title, value);
}
-static void
-acpi_ex_out_address (
- char *title,
- acpi_physical_address value)
+static void acpi_ex_out_address(char *title, acpi_physical_address value)
{
#if ACPI_MACHINE_WIDTH == 16
- acpi_os_printf ("%20s : %p\n", title, value);
+ acpi_os_printf("%20s : %p\n", title, value);
#else
- acpi_os_printf ("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64 (value));
+ acpi_os_printf("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
#endif
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_node
@@ -536,38 +491,161 @@ acpi_ex_out_address (
*
******************************************************************************/
-void
-acpi_ex_dump_node (
- struct acpi_namespace_node *node,
- u32 flags)
+void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
if (!flags) {
- if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
+ if (!
+ ((ACPI_LV_OBJECTS & acpi_dbg_level)
+ && (_COMPONENT & acpi_dbg_layer))) {
return;
}
}
- acpi_os_printf ("%20s : %4.4s\n", "Name", acpi_ut_get_node_name (node));
- acpi_ex_out_string ("Type", acpi_ut_get_type_name (node->type));
- acpi_ex_out_integer ("Flags", node->flags);
- acpi_ex_out_integer ("Owner Id", node->owner_id);
- acpi_ex_out_integer ("Reference Count", node->reference_count);
- acpi_ex_out_pointer ("Attached Object", acpi_ns_get_attached_object (node));
- acpi_ex_out_pointer ("child_list", node->child);
- acpi_ex_out_pointer ("next_peer", node->peer);
- acpi_ex_out_pointer ("Parent", acpi_ns_get_parent_node (node));
+ acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node));
+ acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type));
+ acpi_ex_out_integer("Flags", node->flags);
+ acpi_ex_out_integer("Owner Id", node->owner_id);
+ acpi_ex_out_integer("Reference Count", node->reference_count);
+ acpi_ex_out_pointer("Attached Object",
+ acpi_ns_get_attached_object(node));
+ acpi_ex_out_pointer("child_list", node->child);
+ acpi_ex_out_pointer("next_peer", node->peer);
+ acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node));
}
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ex_dump_reference
+ *
+ * PARAMETERS: Object - Descriptor to dump
+ *
+ * DESCRIPTION: Dumps a reference object
+ *
+ ******************************************************************************/
+
+static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc)
+{
+ struct acpi_buffer ret_buf;
+ acpi_status status;
+
+ if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) {
+ acpi_os_printf("Named Object %p ", obj_desc->reference.node);
+ ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ status =
+ acpi_ns_handle_to_pathname(obj_desc->reference.node,
+ &ret_buf);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_printf("Could not convert name to pathname\n");
+ } else {
+ acpi_os_printf("%s\n", (char *)ret_buf.pointer);
+ ACPI_MEM_FREE(ret_buf.pointer);
+ }
+ } else if (obj_desc->reference.object) {
+ acpi_os_printf("\nReferenced Object: %p\n",
+ obj_desc->reference.object);
+ }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ex_dump_package
+ *
+ * PARAMETERS: Object - Descriptor to dump
+ * Level - Indentation Level
+ * Index - Package index for this object
+ *
+ * DESCRIPTION: Dumps the elements of the package
+ *
+ ******************************************************************************/
+
+static void
+acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index)
+{
+ u32 i;
+
+ /* Indentation and index output */
+
+ if (level > 0) {
+ for (i = 0; i < level; i++) {
+ acpi_os_printf(" ");
+ }
+
+ acpi_os_printf("[%.2d] ", index);
+ }
+
+ acpi_os_printf("%p ", obj_desc);
+
+ /* Null package elements are allowed */
+
+ if (!obj_desc) {
+ acpi_os_printf("[Null Object]\n");
+ return;
+ }
+
+ /* Packages may only contain a few object types */
+
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ case ACPI_TYPE_INTEGER:
+
+ acpi_os_printf("[Integer] = %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(obj_desc->integer.value));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ acpi_os_printf("[String] Value: ");
+ for (i = 0; i < obj_desc->string.length; i++) {
+ acpi_os_printf("%c", obj_desc->string.pointer[i]);
+ }
+ acpi_os_printf("\n");
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ acpi_os_printf("[Buffer] Length %.2X = ",
+ obj_desc->buffer.length);
+ if (obj_desc->buffer.length) {
+ acpi_ut_dump_buffer((u8 *) obj_desc->buffer.pointer,
+ obj_desc->buffer.length,
+ DB_DWORD_DISPLAY, _COMPONENT);
+ } else {
+ acpi_os_printf("\n");
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ acpi_os_printf("[Package] Contains %d Elements: \n",
+ obj_desc->package.count);
+
+ for (i = 0; i < obj_desc->package.count; i++) {
+ acpi_ex_dump_package(obj_desc->package.elements[i],
+ level + 1, i);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ acpi_os_printf("[Object Reference] ");
+ acpi_ex_dump_reference(obj_desc);
+ break;
+
+ default:
+
+ acpi_os_printf("[Unknown Type] %X\n",
+ ACPI_GET_OBJECT_TYPE(obj_desc));
+ break;
+ }
+}
/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_object_descriptor
*
- * PARAMETERS: *Object - Descriptor to dump
+ * PARAMETERS: Object - Descriptor to dump
* Flags - Force display if TRUE
*
* DESCRIPTION: Dumps the members of the object descriptor given.
@@ -575,202 +653,213 @@ acpi_ex_dump_node (
******************************************************************************/
void
-acpi_ex_dump_object_descriptor (
- union acpi_operand_object *obj_desc,
- u32 flags)
+acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags)
{
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");
-
+ ACPI_FUNCTION_TRACE("ex_dump_object_descriptor");
if (!obj_desc) {
return_VOID;
}
if (!flags) {
- if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
+ if (!
+ ((ACPI_LV_OBJECTS & acpi_dbg_level)
+ && (_COMPONENT & acpi_dbg_layer))) {
return_VOID;
}
}
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
- acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags);
- acpi_os_printf ("\nAttached Object (%p):\n",
- ((struct acpi_namespace_node *) obj_desc)->object);
- acpi_ex_dump_object_descriptor (
- ((struct acpi_namespace_node *) obj_desc)->object, flags);
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
+ acpi_ex_dump_node((struct acpi_namespace_node *)obj_desc,
+ flags);
+ acpi_os_printf("\nAttached Object (%p):\n",
+ ((struct acpi_namespace_node *)obj_desc)->
+ object);
+ acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *)
+ obj_desc)->object, flags);
return_VOID;
}
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
- acpi_os_printf (
- "ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
- obj_desc, acpi_ut_get_descriptor_name (obj_desc));
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+ acpi_os_printf
+ ("ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
+ obj_desc, acpi_ut_get_descriptor_name(obj_desc));
return_VOID;
}
/* Common Fields */
- acpi_ex_out_string ("Type", acpi_ut_get_object_type_name (obj_desc));
- acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count);
- acpi_ex_out_integer ("Flags", obj_desc->common.flags);
+ acpi_ex_out_string("Type", acpi_ut_get_object_type_name(obj_desc));
+ acpi_ex_out_integer("Reference Count",
+ obj_desc->common.reference_count);
+ acpi_ex_out_integer("Flags", obj_desc->common.flags);
/* Object-specific Fields */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_INTEGER:
- acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value",
- ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+ acpi_os_printf("%20s : %8.8X%8.8X\n", "Value",
+ ACPI_FORMAT_UINT64(obj_desc->integer.value));
break;
-
case ACPI_TYPE_STRING:
- acpi_ex_out_integer ("Length", obj_desc->string.length);
+ acpi_ex_out_integer("Length", obj_desc->string.length);
- acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer);
- acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
- acpi_os_printf ("\n");
+ acpi_os_printf("%20s : %p ", "Pointer",
+ obj_desc->string.pointer);
+ acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
+ acpi_os_printf("\n");
break;
-
case ACPI_TYPE_BUFFER:
- acpi_ex_out_integer ("Length", obj_desc->buffer.length);
- acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer);
- ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length);
+ acpi_ex_out_integer("Length", obj_desc->buffer.length);
+ acpi_ex_out_pointer("Pointer", obj_desc->buffer.pointer);
+ ACPI_DUMP_BUFFER(obj_desc->buffer.pointer,
+ obj_desc->buffer.length);
break;
-
case ACPI_TYPE_PACKAGE:
- acpi_ex_out_integer ("Flags", obj_desc->package.flags);
- acpi_ex_out_integer ("Count", obj_desc->package.count);
- acpi_ex_out_pointer ("Elements", obj_desc->package.elements);
+ acpi_ex_out_integer("Flags", obj_desc->package.flags);
+ acpi_ex_out_integer("Elements", obj_desc->package.count);
+ acpi_ex_out_pointer("Element List", obj_desc->package.elements);
/* Dump the package contents */
- if (obj_desc->package.count > 0) {
- acpi_os_printf ("\nPackage Contents:\n");
- for (i = 0; i < obj_desc->package.count; i++) {
- acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]);
- if (obj_desc->package.elements[i]) {
- acpi_os_printf (" %s",
- acpi_ut_get_object_type_name (obj_desc->package.elements[i]));
- }
- acpi_os_printf ("\n");
- }
- }
+ acpi_os_printf("\nPackage Contents:\n");
+ acpi_ex_dump_package(obj_desc, 0, 0);
break;
-
case ACPI_TYPE_DEVICE:
- acpi_ex_out_pointer ("Handler", obj_desc->device.handler);
- acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
- acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
+ acpi_ex_out_pointer("Handler", obj_desc->device.handler);
+ acpi_ex_out_pointer("system_notify",
+ obj_desc->device.system_notify);
+ acpi_ex_out_pointer("device_notify",
+ obj_desc->device.device_notify);
break;
-
case ACPI_TYPE_EVENT:
- acpi_ex_out_pointer ("Semaphore", obj_desc->event.semaphore);
+ acpi_ex_out_pointer("Semaphore", obj_desc->event.semaphore);
break;
-
case ACPI_TYPE_METHOD:
- acpi_ex_out_integer ("param_count", obj_desc->method.param_count);
- acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency);
- acpi_ex_out_pointer ("Semaphore", obj_desc->method.semaphore);
- acpi_ex_out_integer ("owning_id", obj_desc->method.owning_id);
- acpi_ex_out_integer ("aml_length", obj_desc->method.aml_length);
- acpi_ex_out_pointer ("aml_start", obj_desc->method.aml_start);
+ acpi_ex_out_integer("param_count",
+ obj_desc->method.param_count);
+ acpi_ex_out_integer("Concurrency",
+ obj_desc->method.concurrency);
+ acpi_ex_out_pointer("Semaphore", obj_desc->method.semaphore);
+ acpi_ex_out_integer("owner_id", obj_desc->method.owner_id);
+ acpi_ex_out_integer("aml_length", obj_desc->method.aml_length);
+ acpi_ex_out_pointer("aml_start", obj_desc->method.aml_start);
break;
-
case ACPI_TYPE_MUTEX:
- acpi_ex_out_integer ("sync_level", obj_desc->mutex.sync_level);
- acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread);
- acpi_ex_out_integer ("acquire_depth", obj_desc->mutex.acquisition_depth);
- acpi_ex_out_pointer ("Semaphore", obj_desc->mutex.semaphore);
+ acpi_ex_out_integer("sync_level", obj_desc->mutex.sync_level);
+ acpi_ex_out_pointer("owner_thread",
+ obj_desc->mutex.owner_thread);
+ acpi_ex_out_integer("acquire_depth",
+ obj_desc->mutex.acquisition_depth);
+ acpi_ex_out_pointer("Semaphore", obj_desc->mutex.semaphore);
break;
-
case ACPI_TYPE_REGION:
- acpi_ex_out_integer ("space_id", obj_desc->region.space_id);
- acpi_ex_out_integer ("Flags", obj_desc->region.flags);
- acpi_ex_out_address ("Address", obj_desc->region.address);
- acpi_ex_out_integer ("Length", obj_desc->region.length);
- acpi_ex_out_pointer ("Handler", obj_desc->region.handler);
- acpi_ex_out_pointer ("Next", obj_desc->region.next);
+ acpi_ex_out_integer("space_id", obj_desc->region.space_id);
+ acpi_ex_out_integer("Flags", obj_desc->region.flags);
+ acpi_ex_out_address("Address", obj_desc->region.address);
+ acpi_ex_out_integer("Length", obj_desc->region.length);
+ acpi_ex_out_pointer("Handler", obj_desc->region.handler);
+ acpi_ex_out_pointer("Next", obj_desc->region.next);
break;
-
case ACPI_TYPE_POWER:
- acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
- acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
- acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
- acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
+ acpi_ex_out_integer("system_level",
+ obj_desc->power_resource.system_level);
+ acpi_ex_out_integer("resource_order",
+ obj_desc->power_resource.resource_order);
+ acpi_ex_out_pointer("system_notify",
+ obj_desc->power_resource.system_notify);
+ acpi_ex_out_pointer("device_notify",
+ obj_desc->power_resource.device_notify);
break;
-
case ACPI_TYPE_PROCESSOR:
- acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id);
- acpi_ex_out_integer ("Length", obj_desc->processor.length);
- acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address);
- acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
- acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
- acpi_ex_out_pointer ("Handler", obj_desc->processor.handler);
+ acpi_ex_out_integer("Processor ID",
+ obj_desc->processor.proc_id);
+ acpi_ex_out_integer("Length", obj_desc->processor.length);
+ acpi_ex_out_address("Address",
+ (acpi_physical_address) obj_desc->processor.
+ address);
+ acpi_ex_out_pointer("system_notify",
+ obj_desc->processor.system_notify);
+ acpi_ex_out_pointer("device_notify",
+ obj_desc->processor.device_notify);
+ acpi_ex_out_pointer("Handler", obj_desc->processor.handler);
break;
-
case ACPI_TYPE_THERMAL:
- acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
- acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
- acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler);
+ acpi_ex_out_pointer("system_notify",
+ obj_desc->thermal_zone.system_notify);
+ acpi_ex_out_pointer("device_notify",
+ obj_desc->thermal_zone.device_notify);
+ acpi_ex_out_pointer("Handler", obj_desc->thermal_zone.handler);
break;
-
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags);
- acpi_ex_out_integer ("access_byte_width",obj_desc->common_field.access_byte_width);
- acpi_ex_out_integer ("bit_length", obj_desc->common_field.bit_length);
- acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset);
- acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset);
- acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node);
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ acpi_ex_out_integer("field_flags",
+ obj_desc->common_field.field_flags);
+ acpi_ex_out_integer("access_byte_width",
+ obj_desc->common_field.access_byte_width);
+ acpi_ex_out_integer("bit_length",
+ obj_desc->common_field.bit_length);
+ acpi_ex_out_integer("fld_bit_offset",
+ obj_desc->common_field.
+ start_field_bit_offset);
+ acpi_ex_out_integer("base_byte_offset",
+ obj_desc->common_field.base_byte_offset);
+ acpi_ex_out_pointer("parent_node", obj_desc->common_field.node);
+
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_BUFFER_FIELD:
- acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj);
+ acpi_ex_out_pointer("buffer_obj",
+ obj_desc->buffer_field.buffer_obj);
break;
case ACPI_TYPE_LOCAL_REGION_FIELD:
- acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj);
+ acpi_ex_out_pointer("region_obj",
+ obj_desc->field.region_obj);
break;
case ACPI_TYPE_LOCAL_BANK_FIELD:
- acpi_ex_out_integer ("Value", obj_desc->bank_field.value);
- acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj);
- acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj);
+ acpi_ex_out_integer("Value",
+ obj_desc->bank_field.value);
+ acpi_ex_out_pointer("region_obj",
+ obj_desc->bank_field.region_obj);
+ acpi_ex_out_pointer("bank_obj",
+ obj_desc->bank_field.bank_obj);
break;
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- acpi_ex_out_integer ("Value", obj_desc->index_field.value);
- acpi_ex_out_pointer ("Index", obj_desc->index_field.index_obj);
- acpi_ex_out_pointer ("Data", obj_desc->index_field.data_obj);
+ acpi_ex_out_integer("Value",
+ obj_desc->index_field.value);
+ acpi_ex_out_pointer("Index",
+ obj_desc->index_field.index_obj);
+ acpi_ex_out_pointer("Data",
+ obj_desc->index_field.data_obj);
break;
default:
@@ -779,56 +868,52 @@ acpi_ex_dump_object_descriptor (
}
break;
-
case ACPI_TYPE_LOCAL_REFERENCE:
- acpi_ex_out_integer ("target_type", obj_desc->reference.target_type);
- acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (
- obj_desc->reference.opcode))->name);
- acpi_ex_out_integer ("Offset", obj_desc->reference.offset);
- acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object);
- acpi_ex_out_pointer ("Node", obj_desc->reference.node);
- acpi_ex_out_pointer ("Where", obj_desc->reference.where);
-
- if (obj_desc->reference.object) {
- acpi_os_printf ("\nReferenced Object:\n");
- acpi_ex_dump_object_descriptor (obj_desc->reference.object, flags);
- }
- break;
+ acpi_ex_out_integer("target_type",
+ obj_desc->reference.target_type);
+ acpi_ex_out_string("Opcode",
+ (acpi_ps_get_opcode_info
+ (obj_desc->reference.opcode))->name);
+ acpi_ex_out_integer("Offset", obj_desc->reference.offset);
+ acpi_ex_out_pointer("obj_desc", obj_desc->reference.object);
+ acpi_ex_out_pointer("Node", obj_desc->reference.node);
+ acpi_ex_out_pointer("Where", obj_desc->reference.where);
+ acpi_ex_dump_reference(obj_desc);
+ break;
case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
- acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id);
- acpi_ex_out_pointer ("Next", obj_desc->address_space.next);
- acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list);
- acpi_ex_out_pointer ("Node", obj_desc->address_space.node);
- acpi_ex_out_pointer ("Context", obj_desc->address_space.context);
+ acpi_ex_out_integer("space_id",
+ obj_desc->address_space.space_id);
+ acpi_ex_out_pointer("Next", obj_desc->address_space.next);
+ acpi_ex_out_pointer("region_list",
+ obj_desc->address_space.region_list);
+ acpi_ex_out_pointer("Node", obj_desc->address_space.node);
+ acpi_ex_out_pointer("Context", obj_desc->address_space.context);
break;
-
case ACPI_TYPE_LOCAL_NOTIFY:
- acpi_ex_out_pointer ("Node", obj_desc->notify.node);
- acpi_ex_out_pointer ("Context", obj_desc->notify.context);
+ acpi_ex_out_pointer("Node", obj_desc->notify.node);
+ acpi_ex_out_pointer("Context", obj_desc->notify.context);
break;
-
case ACPI_TYPE_LOCAL_ALIAS:
case ACPI_TYPE_LOCAL_METHOD_ALIAS:
case ACPI_TYPE_LOCAL_EXTRA:
case ACPI_TYPE_LOCAL_DATA:
default:
- acpi_os_printf (
- "ex_dump_object_descriptor: Display not implemented for object type %s\n",
- acpi_ut_get_object_type_name (obj_desc));
+ acpi_os_printf
+ ("ex_dump_object_descriptor: Display not implemented for object type %s\n",
+ acpi_ut_get_object_type_name(obj_desc));
break;
}
return_VOID;
}
-#endif /* ACPI_FUTURE_USAGE */
+#endif /* ACPI_FUTURE_USAGE */
#endif
-
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index 22c8fa480f60..ab1ba399aa28 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -41,15 +41,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exfield")
-
+ACPI_MODULE_NAME("exfield")
/*******************************************************************************
*
@@ -65,64 +62,70 @@
* Buffer, depending on the size of the field.
*
******************************************************************************/
-
acpi_status
-acpi_ex_read_data_from_field (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **ret_buffer_desc)
+acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object **ret_buffer_desc)
{
- acpi_status status;
- union acpi_operand_object *buffer_desc;
- acpi_size length;
- void *buffer;
- u8 locked;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_read_data_from_field", obj_desc);
+ acpi_status status;
+ union acpi_operand_object *buffer_desc;
+ acpi_size length;
+ void *buffer;
+ u8 locked;
+ ACPI_FUNCTION_TRACE_PTR("ex_read_data_from_field", obj_desc);
/* Parameter validation */
if (!obj_desc) {
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
+ }
+ if (!ret_buffer_desc) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
*/
if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
- status = acpi_ds_get_buffer_field_arguments (obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_get_buffer_field_arguments(obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
- }
- else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) &&
- (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) {
+ } else
+ if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
+ && (obj_desc->field.region_obj->region.space_id ==
+ ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus read. We must create a buffer to hold the data
* and directly access the region handler.
*/
- buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE);
+ buffer_desc =
+ acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE);
if (!buffer_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Lock entire transaction if requested */
- locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+ locked =
+ acpi_ex_acquire_global_lock(obj_desc->common_field.
+ field_flags);
/*
* Perform the read.
* Note: Smbus protocol value is passed in upper 16-bits of Function
*/
- status = acpi_ex_access_region (obj_desc, 0,
- ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
- ACPI_READ | (obj_desc->field.attribute << 16));
- acpi_ex_release_global_lock (locked);
+ status = acpi_ex_access_region(obj_desc, 0,
+ ACPI_CAST_PTR(acpi_integer,
+ buffer_desc->
+ buffer.pointer),
+ ACPI_READ | (obj_desc->field.
+ attribute << 16));
+ acpi_ex_release_global_lock(locked);
goto exit;
}
@@ -136,22 +139,22 @@ acpi_ex_read_data_from_field (
*
* Note: Field.length is in bits.
*/
- length = (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length);
+ length =
+ (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length);
if (length > acpi_gbl_integer_byte_width) {
/* Field is too large for an Integer, create a Buffer instead */
- buffer_desc = acpi_ut_create_buffer_object (length);
+ buffer_desc = acpi_ut_create_buffer_object(length);
if (!buffer_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
buffer = buffer_desc->buffer.pointer;
- }
- else {
+ } else {
/* Field will fit within an Integer (normal case) */
- buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!buffer_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
length = acpi_gbl_integer_byte_width;
@@ -159,37 +162,36 @@ acpi_ex_read_data_from_field (
buffer = &buffer_desc->integer.value;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n",
- obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length));
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n",
- obj_desc->common_field.bit_length,
- obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.base_byte_offset));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n",
+ obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+ (u32) length));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n",
+ obj_desc->common_field.bit_length,
+ obj_desc->common_field.start_field_bit_offset,
+ obj_desc->common_field.base_byte_offset));
/* Lock entire transaction if requested */
- locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+ locked =
+ acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
/* Read from the field */
- status = acpi_ex_extract_from_field (obj_desc, buffer, (u32) length);
- acpi_ex_release_global_lock (locked);
+ status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length);
+ acpi_ex_release_global_lock(locked);
-
-exit:
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (buffer_desc);
- }
- else if (ret_buffer_desc) {
+ exit:
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(buffer_desc);
+ } else {
*ret_buffer_desc = buffer_desc;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_write_data_to_field
@@ -205,97 +207,96 @@ exit:
******************************************************************************/
acpi_status
-acpi_ex_write_data_to_field (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc)
+acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc)
{
- acpi_status status;
- u32 length;
- u32 required_length;
- void *buffer;
- void *new_buffer;
- u8 locked;
- union acpi_operand_object *buffer_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_write_data_to_field", obj_desc);
+ acpi_status status;
+ u32 length;
+ u32 required_length;
+ void *buffer;
+ void *new_buffer;
+ u8 locked;
+ union acpi_operand_object *buffer_desc;
+ ACPI_FUNCTION_TRACE_PTR("ex_write_data_to_field", obj_desc);
/* Parameter validation */
if (!source_desc || !obj_desc) {
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
*/
if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
- status = acpi_ds_get_buffer_field_arguments (obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_get_buffer_field_arguments(obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
- }
- else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) &&
- (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) {
+ } else
+ if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
+ && (obj_desc->field.region_obj->region.space_id ==
+ ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus write. We will bypass the entire field mechanism
* and handoff the buffer directly to the handler.
*
* Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
*/
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
- ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n",
- acpi_ut_get_object_type_name (source_desc)));
+ if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ ACPI_REPORT_ERROR(("SMBus write requires Buffer, found type %s\n", acpi_ut_get_object_type_name(source_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
- ACPI_REPORT_ERROR ((
- "SMBus write requires Buffer of length %X, found length %X\n",
- ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
+ ACPI_REPORT_ERROR(("SMBus write requires Buffer of length %X, found length %X\n", ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
- return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+ return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
}
- buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE);
+ buffer_desc =
+ acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE);
if (!buffer_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
buffer = buffer_desc->buffer.pointer;
- ACPI_MEMCPY (buffer, source_desc->buffer.pointer,
- ACPI_SMBUS_BUFFER_SIZE);
+ ACPI_MEMCPY(buffer, source_desc->buffer.pointer,
+ ACPI_SMBUS_BUFFER_SIZE);
/* Lock entire transaction if requested */
- locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+ locked =
+ acpi_ex_acquire_global_lock(obj_desc->common_field.
+ field_flags);
/*
* Perform the write (returns status and perhaps data in the
* same buffer)
* Note: SMBus protocol type is passed in upper 16-bits of Function.
*/
- status = acpi_ex_access_region (obj_desc, 0,
- (acpi_integer *) buffer,
- ACPI_WRITE | (obj_desc->field.attribute << 16));
- acpi_ex_release_global_lock (locked);
+ status = acpi_ex_access_region(obj_desc, 0,
+ (acpi_integer *) buffer,
+ ACPI_WRITE | (obj_desc->field.
+ attribute << 16));
+ acpi_ex_release_global_lock(locked);
*result_desc = buffer_desc;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Get a pointer to the data to be written */
- switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
case ACPI_TYPE_INTEGER:
buffer = &source_desc->integer.value;
- length = sizeof (source_desc->integer.value);
+ length = sizeof(source_desc->integer.value);
break;
case ACPI_TYPE_BUFFER:
@@ -309,7 +310,7 @@ acpi_ex_write_data_to_field (
break;
default:
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/*
@@ -319,15 +320,15 @@ acpi_ex_write_data_to_field (
* the ACPI specification.
*/
new_buffer = NULL;
- required_length = ACPI_ROUND_BITS_UP_TO_BYTES (
- obj_desc->common_field.bit_length);
+ required_length =
+ ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
if (length < required_length) {
/* We need to create a new buffer */
- new_buffer = ACPI_MEM_CALLOCATE (required_length);
+ new_buffer = ACPI_MEM_CALLOCATE(required_length);
if (!new_buffer) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
@@ -335,40 +336,42 @@ acpi_ex_write_data_to_field (
* at Byte zero. All unused (upper) bytes of the
* buffer will be 0.
*/
- ACPI_MEMCPY ((char *) new_buffer, (char *) buffer, length);
+ ACPI_MEMCPY((char *)new_buffer, (char *)buffer, length);
buffer = new_buffer;
length = required_length;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
- source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)),
- ACPI_GET_OBJECT_TYPE (source_desc), buffer, length));
-
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
- obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)),
- ACPI_GET_OBJECT_TYPE (obj_desc),
- obj_desc->common_field.bit_length,
- obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.base_byte_offset));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
+ source_desc,
+ acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
+ (source_desc)),
+ ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
+ obj_desc,
+ acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
+ ACPI_GET_OBJECT_TYPE(obj_desc),
+ obj_desc->common_field.bit_length,
+ obj_desc->common_field.start_field_bit_offset,
+ obj_desc->common_field.base_byte_offset));
/* Lock entire transaction if requested */
- locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+ locked =
+ acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
/* Write to the field */
- status = acpi_ex_insert_into_field (obj_desc, buffer, length);
- acpi_ex_release_global_lock (locked);
+ status = acpi_ex_insert_into_field(obj_desc, buffer, length);
+ acpi_ex_release_global_lock(locked);
/* Free temporary buffer if we used one */
if (new_buffer) {
- ACPI_MEM_FREE (new_buffer);
+ ACPI_MEM_FREE(new_buffer);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 3c2f89e00f78..ba6e08843c29 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -41,36 +41,28 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#include <acpi/acevents.h>
#include <acpi/acdispat.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exfldio")
+ACPI_MODULE_NAME("exfldio")
/* Local prototypes */
-
static acpi_status
-acpi_ex_field_datum_io (
- union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset,
- acpi_integer *value,
- u32 read_write);
+acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset,
+ acpi_integer * value, u32 read_write);
static u8
-acpi_ex_register_overflow (
- union acpi_operand_object *obj_desc,
- acpi_integer value);
+acpi_ex_register_overflow(union acpi_operand_object *obj_desc,
+ acpi_integer value);
static acpi_status
-acpi_ex_setup_region (
- union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset);
-
+acpi_ex_setup_region(union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset);
/*******************************************************************************
*
@@ -89,27 +81,25 @@ acpi_ex_setup_region (
******************************************************************************/
static acpi_status
-acpi_ex_setup_region (
- union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset)
+acpi_ex_setup_region(union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *rgn_desc;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ex_setup_region", field_datum_byte_offset);
+ acpi_status status = AE_OK;
+ union acpi_operand_object *rgn_desc;
+ ACPI_FUNCTION_TRACE_U32("ex_setup_region", field_datum_byte_offset);
rgn_desc = obj_desc->common_field.region_obj;
/* We must have a valid region */
- if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n",
- ACPI_GET_OBJECT_TYPE (rgn_desc),
- acpi_ut_get_object_type_name (rgn_desc)));
+ if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed Region, found type %X (%s)\n",
+ ACPI_GET_OBJECT_TYPE(rgn_desc),
+ acpi_ut_get_object_type_name(rgn_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/*
@@ -117,26 +107,25 @@ acpi_ex_setup_region (
* evaluate them now and save the results.
*/
if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
- status = acpi_ds_get_region_arguments (rgn_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_get_region_arguments(rgn_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
/* SMBus has a non-linear address space */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
#ifdef ACPI_UNDER_DEVELOPMENT
/*
* If the Field access is any_acc, we can now compute the optimal
* access (because we know know the length of the parent region)
*/
if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
#endif
@@ -147,56 +136,64 @@ acpi_ex_setup_region (
* (Region length is specified in bytes)
*/
if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
- field_datum_byte_offset +
- obj_desc->common_field.access_byte_width)) {
+ field_datum_byte_offset +
+ obj_desc->common_field.
+ access_byte_width)) {
if (acpi_gbl_enable_interpreter_slack) {
/*
* Slack mode only: We will go ahead and allow access to this
* field if it is within the region length rounded up to the next
* access width boundary.
*/
- if (ACPI_ROUND_UP (rgn_desc->region.length,
- obj_desc->common_field.access_byte_width) >=
- (obj_desc->common_field.base_byte_offset +
- (acpi_native_uint) obj_desc->common_field.access_byte_width +
- field_datum_byte_offset)) {
- return_ACPI_STATUS (AE_OK);
+ if (ACPI_ROUND_UP(rgn_desc->region.length,
+ obj_desc->common_field.
+ access_byte_width) >=
+ (obj_desc->common_field.base_byte_offset +
+ (acpi_native_uint) obj_desc->common_field.
+ access_byte_width + field_datum_byte_offset)) {
+ return_ACPI_STATUS(AE_OK);
}
}
- if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
+ if (rgn_desc->region.length <
+ obj_desc->common_field.access_byte_width) {
/*
* This is the case where the access_type (acc_word, etc.) is wider
* than the region itself. For example, a region of length one
* byte, and a field with Dword access specified.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
- acpi_ut_get_node_name (obj_desc->common_field.node),
- obj_desc->common_field.access_byte_width,
- acpi_ut_get_node_name (rgn_desc->region.node),
- rgn_desc->region.length));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
+ acpi_ut_get_node_name(obj_desc->
+ common_field.
+ node),
+ obj_desc->common_field.
+ access_byte_width,
+ acpi_ut_get_node_name(rgn_desc->
+ region.node),
+ rgn_desc->region.length));
}
/*
* Offset rounded up to next multiple of field width
* exceeds region length, indicate an error
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
- acpi_ut_get_node_name (obj_desc->common_field.node),
- obj_desc->common_field.base_byte_offset,
- field_datum_byte_offset, obj_desc->common_field.access_byte_width,
- acpi_ut_get_node_name (rgn_desc->region.node),
- rgn_desc->region.length));
-
- return_ACPI_STATUS (AE_AML_REGION_LIMIT);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
+ acpi_ut_get_node_name(obj_desc->common_field.
+ node),
+ obj_desc->common_field.base_byte_offset,
+ field_datum_byte_offset,
+ obj_desc->common_field.access_byte_width,
+ acpi_ut_get_node_name(rgn_desc->region.node),
+ rgn_desc->region.length));
+
+ return_ACPI_STATUS(AE_AML_REGION_LIMIT);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_access_region
@@ -216,27 +213,23 @@ acpi_ex_setup_region (
******************************************************************************/
acpi_status
-acpi_ex_access_region (
- union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset,
- acpi_integer *value,
- u32 function)
+acpi_ex_access_region(union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset,
+ acpi_integer * value, u32 function)
{
- acpi_status status;
- union acpi_operand_object *rgn_desc;
- acpi_physical_address address;
-
-
- ACPI_FUNCTION_TRACE ("ex_access_region");
+ acpi_status status;
+ union acpi_operand_object *rgn_desc;
+ acpi_physical_address address;
+ ACPI_FUNCTION_TRACE("ex_access_region");
/*
* Ensure that the region operands are fully evaluated and verify
* the validity of the request
*/
- status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_setup_region(obj_desc, field_datum_byte_offset);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -248,50 +241,53 @@ acpi_ex_access_region (
*/
rgn_desc = obj_desc->common_field.region_obj;
address = rgn_desc->region.address +
- obj_desc->common_field.base_byte_offset +
- field_datum_byte_offset;
+ obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
if ((function & ACPI_IO_MASK) == ACPI_READ) {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[READ]"));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[WRITE]"));
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
- " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n",
- acpi_ut_get_region_name (rgn_desc->region.space_id),
- rgn_desc->region.space_id,
- obj_desc->common_field.access_byte_width,
- obj_desc->common_field.base_byte_offset,
- field_datum_byte_offset,
- ACPI_FORMAT_UINT64 (address)));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
+ " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n",
+ acpi_ut_get_region_name(rgn_desc->region.
+ space_id),
+ rgn_desc->region.space_id,
+ obj_desc->common_field.access_byte_width,
+ obj_desc->common_field.base_byte_offset,
+ field_datum_byte_offset,
+ ACPI_FORMAT_UINT64(address)));
/* Invoke the appropriate address_space/op_region handler */
- status = acpi_ev_address_space_dispatch (rgn_desc, function,
- address,
- ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
+ status = acpi_ev_address_space_dispatch(rgn_desc, function,
+ address,
+ ACPI_MUL_8(obj_desc->
+ common_field.
+ access_byte_width),
+ value);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
if (status == AE_NOT_IMPLEMENTED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Region %s(%X) not implemented\n",
- acpi_ut_get_region_name (rgn_desc->region.space_id),
- rgn_desc->region.space_id));
- }
- else if (status == AE_NOT_EXIST) {
- ACPI_REPORT_ERROR ((
- "Region %s(%X) has no handler\n",
- acpi_ut_get_region_name (rgn_desc->region.space_id),
- rgn_desc->region.space_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Region %s(%X) not implemented\n",
+ acpi_ut_get_region_name(rgn_desc->
+ region.
+ space_id),
+ rgn_desc->region.space_id));
+ } else if (status == AE_NOT_EXIST) {
+ ACPI_REPORT_ERROR(("Region %s(%X) has no handler\n",
+ acpi_ut_get_region_name(rgn_desc->
+ region.
+ space_id),
+ rgn_desc->region.space_id));
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_register_overflow
@@ -310,9 +306,8 @@ acpi_ex_access_region (
******************************************************************************/
static u8
-acpi_ex_register_overflow (
- union acpi_operand_object *obj_desc,
- acpi_integer value)
+acpi_ex_register_overflow(union acpi_operand_object *obj_desc,
+ acpi_integer value)
{
if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
@@ -336,7 +331,6 @@ acpi_ex_register_overflow (
return (FALSE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_field_datum_io
@@ -356,18 +350,14 @@ acpi_ex_register_overflow (
******************************************************************************/
static acpi_status
-acpi_ex_field_datum_io (
- union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset,
- acpi_integer *value,
- u32 read_write)
+acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset,
+ acpi_integer * value, u32 read_write)
{
- acpi_status status;
- acpi_integer local_value;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ex_field_datum_io", field_datum_byte_offset);
+ acpi_status status;
+ acpi_integer local_value;
+ ACPI_FUNCTION_TRACE_U32("ex_field_datum_io", field_datum_byte_offset);
if (read_write == ACPI_READ) {
if (!value) {
@@ -392,16 +382,16 @@ acpi_ex_field_datum_io (
* index_field - Write to an Index Register, then read/write from/to a
* Data Register
*/
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_BUFFER_FIELD:
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
*/
if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
- status = acpi_ds_get_buffer_field_arguments (obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_get_buffer_field_arguments(obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -410,47 +400,50 @@ acpi_ex_field_datum_io (
* Copy the data from the source buffer.
* Length is the field width in bytes.
*/
- ACPI_MEMCPY (value,
- (obj_desc->buffer_field.buffer_obj)->buffer.pointer +
- obj_desc->buffer_field.base_byte_offset +
- field_datum_byte_offset,
- obj_desc->common_field.access_byte_width);
- }
- else {
+ ACPI_MEMCPY(value,
+ (obj_desc->buffer_field.buffer_obj)->buffer.
+ pointer +
+ obj_desc->buffer_field.base_byte_offset +
+ field_datum_byte_offset,
+ obj_desc->common_field.access_byte_width);
+ } else {
/*
* Copy the data to the target buffer.
* Length is the field width in bytes.
*/
- ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer +
- obj_desc->buffer_field.base_byte_offset +
- field_datum_byte_offset,
- value, obj_desc->common_field.access_byte_width);
+ ACPI_MEMCPY((obj_desc->buffer_field.buffer_obj)->buffer.
+ pointer +
+ obj_desc->buffer_field.base_byte_offset +
+ field_datum_byte_offset, value,
+ obj_desc->common_field.access_byte_width);
}
status = AE_OK;
break;
-
case ACPI_TYPE_LOCAL_BANK_FIELD:
/*
* Ensure that the bank_value is not beyond the capacity of
* the register
*/
- if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj,
- (acpi_integer) obj_desc->bank_field.value)) {
- return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
+ if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj,
+ (acpi_integer) obj_desc->
+ bank_field.value)) {
+ return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
}
/*
* For bank_fields, we must write the bank_value to the bank_register
* (itself a region_field) before we can access the data.
*/
- status = acpi_ex_insert_into_field (obj_desc->bank_field.bank_obj,
- &obj_desc->bank_field.value,
- sizeof (obj_desc->bank_field.value));
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_insert_into_field(obj_desc->bank_field.bank_obj,
+ &obj_desc->bank_field.value,
+ sizeof(obj_desc->bank_field.
+ value));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -460,90 +453,92 @@ acpi_ex_field_datum_io (
/*lint -fallthrough */
-
case ACPI_TYPE_LOCAL_REGION_FIELD:
/*
* For simple region_fields, we just directly access the owning
* Operation Region.
*/
- status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value,
- read_write);
+ status =
+ acpi_ex_access_region(obj_desc, field_datum_byte_offset,
+ value, read_write);
break;
-
case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
/*
* Ensure that the index_value is not beyond the capacity of
* the register
*/
- if (acpi_ex_register_overflow (obj_desc->index_field.index_obj,
- (acpi_integer) obj_desc->index_field.value)) {
- return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
+ if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,
+ (acpi_integer) obj_desc->
+ index_field.value)) {
+ return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
}
/* Write the index value to the index_register (itself a region_field) */
field_datum_byte_offset += obj_desc->index_field.value;
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Write to Index Register: Value %8.8X\n",
- field_datum_byte_offset));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Write to Index Register: Value %8.8X\n",
+ field_datum_byte_offset));
- status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj,
- &field_datum_byte_offset,
- sizeof (field_datum_byte_offset));
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_insert_into_field(obj_desc->index_field.index_obj,
+ &field_datum_byte_offset,
+ sizeof(field_datum_byte_offset));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "I/O to Data Register: value_ptr %p\n",
- value));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "I/O to Data Register: value_ptr %p\n",
+ value));
if (read_write == ACPI_READ) {
/* Read the datum from the data_register */
- status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj,
- value, sizeof (acpi_integer));
- }
- else {
+ status =
+ acpi_ex_extract_from_field(obj_desc->index_field.
+ data_obj, value,
+ sizeof(acpi_integer));
+ } else {
/* Write the datum to the data_register */
- status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj,
- value, sizeof (acpi_integer));
+ status =
+ acpi_ex_insert_into_field(obj_desc->index_field.
+ data_obj, value,
+ sizeof(acpi_integer));
}
break;
-
default:
- ACPI_REPORT_ERROR (("Wrong object type in field I/O %X\n",
- ACPI_GET_OBJECT_TYPE (obj_desc)));
+ ACPI_REPORT_ERROR(("Wrong object type in field I/O %X\n",
+ ACPI_GET_OBJECT_TYPE(obj_desc)));
status = AE_AML_INTERNAL;
break;
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
if (read_write == ACPI_READ) {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Value Read %8.8X%8.8X, Width %d\n",
- ACPI_FORMAT_UINT64 (*value),
- obj_desc->common_field.access_byte_width));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Value Written %8.8X%8.8X, Width %d\n",
- ACPI_FORMAT_UINT64 (*value),
- obj_desc->common_field.access_byte_width));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Value Read %8.8X%8.8X, Width %d\n",
+ ACPI_FORMAT_UINT64(*value),
+ obj_desc->common_field.
+ access_byte_width));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Value Written %8.8X%8.8X, Width %d\n",
+ ACPI_FORMAT_UINT64(*value),
+ obj_desc->common_field.
+ access_byte_width));
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_write_with_update_rule
@@ -560,19 +555,16 @@ acpi_ex_field_datum_io (
******************************************************************************/
acpi_status
-acpi_ex_write_with_update_rule (
- union acpi_operand_object *obj_desc,
- acpi_integer mask,
- acpi_integer field_value,
- u32 field_datum_byte_offset)
+acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
+ acpi_integer mask,
+ acpi_integer field_value,
+ u32 field_datum_byte_offset)
{
- acpi_status status = AE_OK;
- acpi_integer merged_value;
- acpi_integer current_value;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask);
+ acpi_status status = AE_OK;
+ acpi_integer merged_value;
+ acpi_integer current_value;
+ ACPI_FUNCTION_TRACE_U32("ex_write_with_update_rule", mask);
/* Start with the new bits */
@@ -583,22 +575,27 @@ acpi_ex_write_with_update_rule (
if (mask != ACPI_INTEGER_MAX) {
/* Decode the update rule */
- switch (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK) {
+ switch (obj_desc->common_field.
+ field_flags & AML_FIELD_UPDATE_RULE_MASK) {
case AML_FIELD_UPDATE_PRESERVE:
/*
* Check if update rule needs to be applied (not if mask is all
* ones) The left shift drops the bits we want to ignore.
*/
- if ((~mask << (ACPI_MUL_8 (sizeof (mask)) -
- ACPI_MUL_8 (obj_desc->common_field.access_byte_width))) != 0) {
+ if ((~mask << (ACPI_MUL_8(sizeof(mask)) -
+ ACPI_MUL_8(obj_desc->common_field.
+ access_byte_width))) != 0) {
/*
* Read the current contents of the byte/word/dword containing
* the field, and merge with the new field value.
*/
- status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
- &current_value, ACPI_READ);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_field_datum_io(obj_desc,
+ field_datum_byte_offset,
+ &current_value,
+ ACPI_READ);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
merged_value |= (current_value & ~mask);
@@ -621,30 +618,31 @@ acpi_ex_write_with_update_rule (
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "write_with_update_rule: Unknown update_rule setting: %X\n",
- (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK)));
- return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "write_with_update_rule: Unknown update_rule setting: %X\n",
+ (obj_desc->common_field.
+ field_flags &
+ AML_FIELD_UPDATE_RULE_MASK)));
+ return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (mask),
- field_datum_byte_offset,
- obj_desc->common_field.access_byte_width,
- ACPI_FORMAT_UINT64 (field_value),
- ACPI_FORMAT_UINT64 (merged_value)));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(mask),
+ field_datum_byte_offset,
+ obj_desc->common_field.access_byte_width,
+ ACPI_FORMAT_UINT64(field_value),
+ ACPI_FORMAT_UINT64(merged_value)));
/* Write the merged value */
- status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
- &merged_value, ACPI_WRITE);
+ status = acpi_ex_field_datum_io(obj_desc, field_datum_byte_offset,
+ &merged_value, ACPI_WRITE);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_extract_from_field
@@ -660,54 +658,54 @@ acpi_ex_write_with_update_rule (
******************************************************************************/
acpi_status
-acpi_ex_extract_from_field (
- union acpi_operand_object *obj_desc,
- void *buffer,
- u32 buffer_length)
+acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
+ void *buffer, u32 buffer_length)
{
- acpi_status status;
- acpi_integer raw_datum;
- acpi_integer merged_datum;
- u32 field_offset = 0;
- u32 buffer_offset = 0;
- u32 buffer_tail_bits;
- u32 datum_count;
- u32 field_datum_count;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ex_extract_from_field");
-
+ acpi_status status;
+ acpi_integer raw_datum;
+ acpi_integer merged_datum;
+ u32 field_offset = 0;
+ u32 buffer_offset = 0;
+ u32 buffer_tail_bits;
+ u32 datum_count;
+ u32 field_datum_count;
+ u32 i;
+
+ ACPI_FUNCTION_TRACE("ex_extract_from_field");
/* Validate target buffer and clear it */
- if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
- obj_desc->common_field.bit_length)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Field size %X (bits) is too large for buffer (%X)\n",
- obj_desc->common_field.bit_length, buffer_length));
+ if (buffer_length <
+ ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Field size %X (bits) is too large for buffer (%X)\n",
+ obj_desc->common_field.bit_length,
+ buffer_length));
- return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
}
- ACPI_MEMSET (buffer, 0, buffer_length);
+ ACPI_MEMSET(buffer, 0, buffer_length);
/* Compute the number of datums (access width data items) */
- datum_count = ACPI_ROUND_UP_TO (
- obj_desc->common_field.bit_length,
- obj_desc->common_field.access_bit_width);
- field_datum_count = ACPI_ROUND_UP_TO (
- obj_desc->common_field.bit_length +
- obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.access_bit_width);
+ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
+ obj_desc->common_field.access_bit_width);
+ field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
+ obj_desc->common_field.
+ start_field_bit_offset,
+ obj_desc->common_field.
+ access_bit_width);
/* Priming read from the field */
- status = acpi_ex_field_datum_io (obj_desc, field_offset, &raw_datum, ACPI_READ);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,
+ ACPI_READ);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
+ merged_datum =
+ raw_datum >> obj_desc->common_field.start_field_bit_offset;
/* Read the rest of the field */
@@ -715,17 +713,17 @@ acpi_ex_extract_from_field (
/* Get next input datum from the field */
field_offset += obj_desc->common_field.access_byte_width;
- status = acpi_ex_field_datum_io (obj_desc, field_offset,
- &raw_datum, ACPI_READ);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_field_datum_io(obj_desc, field_offset,
+ &raw_datum, ACPI_READ);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Merge with previous datum if necessary */
merged_datum |= raw_datum <<
- (obj_desc->common_field.access_bit_width -
- obj_desc->common_field.start_field_bit_offset);
+ (obj_desc->common_field.access_bit_width -
+ obj_desc->common_field.start_field_bit_offset);
if (i == datum_count) {
break;
@@ -733,32 +731,32 @@ acpi_ex_extract_from_field (
/* Write merged datum to target buffer */
- ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
- ACPI_MIN(obj_desc->common_field.access_byte_width,
- buffer_length - buffer_offset));
+ ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
+ ACPI_MIN(obj_desc->common_field.access_byte_width,
+ buffer_length - buffer_offset));
buffer_offset += obj_desc->common_field.access_byte_width;
- merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
+ merged_datum =
+ raw_datum >> obj_desc->common_field.start_field_bit_offset;
}
/* Mask off any extra bits in the last datum */
buffer_tail_bits = obj_desc->common_field.bit_length %
- obj_desc->common_field.access_bit_width;
+ obj_desc->common_field.access_bit_width;
if (buffer_tail_bits) {
- merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
+ merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
}
/* Write the last datum to the buffer */
- ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
- ACPI_MIN(obj_desc->common_field.access_byte_width,
- buffer_length - buffer_offset));
+ ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
+ ACPI_MIN(obj_desc->common_field.access_byte_width,
+ buffer_length - buffer_offset));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_insert_into_field
@@ -774,53 +772,54 @@ acpi_ex_extract_from_field (
******************************************************************************/
acpi_status
-acpi_ex_insert_into_field (
- union acpi_operand_object *obj_desc,
- void *buffer,
- u32 buffer_length)
+acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
+ void *buffer, u32 buffer_length)
{
- acpi_status status;
- acpi_integer mask;
- acpi_integer merged_datum;
- acpi_integer raw_datum = 0;
- u32 field_offset = 0;
- u32 buffer_offset = 0;
- u32 buffer_tail_bits;
- u32 datum_count;
- u32 field_datum_count;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ex_insert_into_field");
-
+ acpi_status status;
+ acpi_integer mask;
+ acpi_integer merged_datum;
+ acpi_integer raw_datum = 0;
+ u32 field_offset = 0;
+ u32 buffer_offset = 0;
+ u32 buffer_tail_bits;
+ u32 datum_count;
+ u32 field_datum_count;
+ u32 i;
+
+ ACPI_FUNCTION_TRACE("ex_insert_into_field");
/* Validate input buffer */
- if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
- obj_desc->common_field.bit_length)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Field size %X (bits) is too large for buffer (%X)\n",
- obj_desc->common_field.bit_length, buffer_length));
+ if (buffer_length <
+ ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Field size %X (bits) is too large for buffer (%X)\n",
+ obj_desc->common_field.bit_length,
+ buffer_length));
- return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
}
/* Compute the number of datums (access width data items) */
- mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset);
- datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length,
- obj_desc->common_field.access_bit_width);
- field_datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length +
- obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.access_bit_width);
+ mask =
+ ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
+ datum_count =
+ ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
+ obj_desc->common_field.access_bit_width);
+ field_datum_count =
+ ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
+ obj_desc->common_field.start_field_bit_offset,
+ obj_desc->common_field.access_bit_width);
/* Get initial Datum from the input buffer */
- ACPI_MEMCPY (&raw_datum, buffer,
- ACPI_MIN(obj_desc->common_field.access_byte_width,
- buffer_length - buffer_offset));
+ ACPI_MEMCPY(&raw_datum, buffer,
+ ACPI_MIN(obj_desc->common_field.access_byte_width,
+ buffer_length - buffer_offset));
- merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset;
+ merged_datum =
+ raw_datum << obj_desc->common_field.start_field_bit_offset;
/* Write the entire field */
@@ -828,18 +827,19 @@ acpi_ex_insert_into_field (
/* Write merged datum to the target field */
merged_datum &= mask;
- status = acpi_ex_write_with_update_rule (obj_desc, mask,
- merged_datum, field_offset);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_write_with_update_rule(obj_desc, mask,
+ merged_datum,
+ field_offset);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Start new output datum by merging with previous input datum */
field_offset += obj_desc->common_field.access_byte_width;
merged_datum = raw_datum >>
- (obj_desc->common_field.access_bit_width -
- obj_desc->common_field.start_field_bit_offset);
+ (obj_desc->common_field.access_bit_width -
+ obj_desc->common_field.start_field_bit_offset);
mask = ACPI_INTEGER_MAX;
if (i == datum_count) {
@@ -849,28 +849,28 @@ acpi_ex_insert_into_field (
/* Get the next input datum from the buffer */
buffer_offset += obj_desc->common_field.access_byte_width;
- ACPI_MEMCPY (&raw_datum, ((char *) buffer) + buffer_offset,
- ACPI_MIN(obj_desc->common_field.access_byte_width,
- buffer_length - buffer_offset));
- merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset;
+ ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
+ ACPI_MIN(obj_desc->common_field.access_byte_width,
+ buffer_length - buffer_offset));
+ merged_datum |=
+ raw_datum << obj_desc->common_field.start_field_bit_offset;
}
/* Mask off any extra bits in the last datum */
buffer_tail_bits = (obj_desc->common_field.bit_length +
- obj_desc->common_field.start_field_bit_offset) %
- obj_desc->common_field.access_bit_width;
+ obj_desc->common_field.start_field_bit_offset) %
+ obj_desc->common_field.access_bit_width;
if (buffer_tail_bits) {
- mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
+ mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
}
/* Write the last datum to the field */
merged_datum &= mask;
- status = acpi_ex_write_with_update_rule (obj_desc,
- mask, merged_datum, field_offset);
+ status = acpi_ex_write_with_update_rule(obj_desc,
+ mask, merged_datum,
+ field_offset);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index 022f281345b8..a3f4d72bedc9 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -42,15 +42,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exmisc")
-
+ACPI_MODULE_NAME("exmisc")
/*******************************************************************************
*
@@ -66,27 +63,23 @@
* Common code for the ref_of_op and the cond_ref_of_op.
*
******************************************************************************/
-
acpi_status
-acpi_ex_get_object_reference (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **return_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **return_desc,
+ struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *reference_obj;
- union acpi_operand_object *referenced_obj;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_get_object_reference", obj_desc);
+ union acpi_operand_object *reference_obj;
+ union acpi_operand_object *referenced_obj;
+ ACPI_FUNCTION_TRACE_PTR("ex_get_object_reference", obj_desc);
*return_desc = NULL;
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+ switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
- if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/*
@@ -104,13 +97,11 @@ acpi_ex_get_object_reference (
default:
- ACPI_REPORT_ERROR (("Unknown Reference opcode in get_reference %X\n",
- obj_desc->reference.opcode));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("Unknown Reference opcode in get_reference %X\n", obj_desc->reference.opcode));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
break;
-
case ACPI_DESC_TYPE_NAMED:
/*
@@ -119,34 +110,32 @@ acpi_ex_get_object_reference (
referenced_obj = obj_desc;
break;
-
default:
- ACPI_REPORT_ERROR (("Invalid descriptor type in get_reference: %X\n",
- ACPI_GET_DESCRIPTOR_TYPE (obj_desc)));
- return_ACPI_STATUS (AE_TYPE);
+ ACPI_REPORT_ERROR(("Invalid descriptor type in get_reference: %X\n", ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
+ return_ACPI_STATUS(AE_TYPE);
}
-
/* Create a new reference object */
- reference_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
+ reference_obj =
+ acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
if (!reference_obj) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
reference_obj->reference.opcode = AML_REF_OF_OP;
reference_obj->reference.object = referenced_obj;
*return_desc = reference_obj;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Object %p Type [%s], returning Reference %p\n",
- obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Object %p Type [%s], returning Reference %p\n",
+ obj_desc, acpi_ut_get_object_type_name(obj_desc),
+ *return_desc));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_concat_template
@@ -163,63 +152,58 @@ acpi_ex_get_object_reference (
******************************************************************************/
acpi_status
-acpi_ex_concat_template (
- union acpi_operand_object *operand0,
- union acpi_operand_object *operand1,
- union acpi_operand_object **actual_return_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_concat_template(union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1,
+ union acpi_operand_object **actual_return_desc,
+ struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *return_desc;
- u8 *new_buf;
- u8 *end_tag1;
- u8 *end_tag2;
- acpi_size length1;
- acpi_size length2;
-
-
- ACPI_FUNCTION_TRACE ("ex_concat_template");
+ union acpi_operand_object *return_desc;
+ u8 *new_buf;
+ u8 *end_tag1;
+ u8 *end_tag2;
+ acpi_size length1;
+ acpi_size length2;
+ ACPI_FUNCTION_TRACE("ex_concat_template");
/* Find the end_tags in each resource template */
- end_tag1 = acpi_ut_get_resource_end_tag (operand0);
- end_tag2 = acpi_ut_get_resource_end_tag (operand1);
+ end_tag1 = acpi_ut_get_resource_end_tag(operand0);
+ end_tag2 = acpi_ut_get_resource_end_tag(operand1);
if (!end_tag1 || !end_tag2) {
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* Compute the length of each part */
- length1 = ACPI_PTR_DIFF (end_tag1, operand0->buffer.pointer);
- length2 = ACPI_PTR_DIFF (end_tag2, operand1->buffer.pointer) +
- 2; /* Size of END_TAG */
+ length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer);
+ length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2; /* Size of END_TAG */
/* Create a new buffer object for the result */
- return_desc = acpi_ut_create_buffer_object (length1 + length2);
+ return_desc = acpi_ut_create_buffer_object(length1 + length2);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the templates to the new descriptor */
new_buf = return_desc->buffer.pointer;
- ACPI_MEMCPY (new_buf, operand0->buffer.pointer, length1);
- ACPI_MEMCPY (new_buf + length1, operand1->buffer.pointer, length2);
+ ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1);
+ ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2);
/* Compute the new checksum */
new_buf[return_desc->buffer.length - 1] =
- acpi_ut_generate_checksum (return_desc->buffer.pointer,
- (return_desc->buffer.length - 1));
+ acpi_ut_generate_checksum(return_desc->buffer.pointer,
+ (return_desc->buffer.length - 1));
/* Return the completed template descriptor */
*actual_return_desc = return_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_do_concatenate
@@ -236,21 +220,18 @@ acpi_ex_concat_template (
******************************************************************************/
acpi_status
-acpi_ex_do_concatenate (
- union acpi_operand_object *operand0,
- union acpi_operand_object *operand1,
- union acpi_operand_object **actual_return_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_do_concatenate(union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1,
+ union acpi_operand_object **actual_return_desc,
+ struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *local_operand1 = operand1;
- union acpi_operand_object *return_desc;
- char *new_buf;
- acpi_status status;
- acpi_size new_length;
-
-
- ACPI_FUNCTION_TRACE ("ex_do_concatenate");
+ union acpi_operand_object *local_operand1 = operand1;
+ union acpi_operand_object *return_desc;
+ char *new_buf;
+ acpi_status status;
+ acpi_size new_length;
+ ACPI_FUNCTION_TRACE("ex_do_concatenate");
/*
* Convert the second operand if necessary. The first operand
@@ -259,27 +240,28 @@ acpi_ex_do_concatenate (
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+ switch (ACPI_GET_OBJECT_TYPE(operand0)) {
case ACPI_TYPE_INTEGER:
- status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16);
+ status =
+ acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
break;
case ACPI_TYPE_STRING:
- status = acpi_ex_convert_to_string (operand1, &local_operand1,
- ACPI_IMPLICIT_CONVERT_HEX);
+ status = acpi_ex_convert_to_string(operand1, &local_operand1,
+ ACPI_IMPLICIT_CONVERT_HEX);
break;
case ACPI_TYPE_BUFFER:
- status = acpi_ex_convert_to_buffer (operand1, &local_operand1);
+ status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
break;
default:
- ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
- ACPI_GET_OBJECT_TYPE (operand0)));
+ ACPI_REPORT_ERROR(("Concat - invalid obj type: %X\n",
+ ACPI_GET_OBJECT_TYPE(operand0)));
status = AE_AML_INTERNAL;
}
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -296,32 +278,33 @@ acpi_ex_do_concatenate (
* 2) Two Strings concatenated to produce a new String
* 3) Two Buffers concatenated to produce a new Buffer
*/
- switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+ switch (ACPI_GET_OBJECT_TYPE(operand0)) {
case ACPI_TYPE_INTEGER:
/* Result of two Integers is a Buffer */
/* Need enough buffer space for two integers */
- return_desc = acpi_ut_create_buffer_object (
- ACPI_MUL_2 (acpi_gbl_integer_byte_width));
+ return_desc = acpi_ut_create_buffer_object((acpi_size)
+ ACPI_MUL_2
+ (acpi_gbl_integer_byte_width));
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
- new_buf = (char *) return_desc->buffer.pointer;
+ new_buf = (char *)return_desc->buffer.pointer;
/* Copy the first integer, LSB first */
- ACPI_MEMCPY (new_buf,
- &operand0->integer.value,
- acpi_gbl_integer_byte_width);
+ ACPI_MEMCPY(new_buf,
+ &operand0->integer.value,
+ acpi_gbl_integer_byte_width);
/* Copy the second integer (LSB first) after the first */
- ACPI_MEMCPY (new_buf + acpi_gbl_integer_byte_width,
- &local_operand1->integer.value,
- acpi_gbl_integer_byte_width);
+ ACPI_MEMCPY(new_buf + acpi_gbl_integer_byte_width,
+ &local_operand1->integer.value,
+ acpi_gbl_integer_byte_width);
break;
case ACPI_TYPE_STRING:
@@ -329,13 +312,13 @@ acpi_ex_do_concatenate (
/* Result of two Strings is a String */
new_length = (acpi_size) operand0->string.length +
- (acpi_size) local_operand1->string.length;
+ (acpi_size) local_operand1->string.length;
if (new_length > ACPI_MAX_STRING_CONVERSION) {
status = AE_AML_STRING_LIMIT;
goto cleanup;
}
- return_desc = acpi_ut_create_string_object (new_length);
+ return_desc = acpi_ut_create_string_object(new_length);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -345,56 +328,56 @@ acpi_ex_do_concatenate (
/* Concatenate the strings */
- ACPI_STRCPY (new_buf,
- operand0->string.pointer);
- ACPI_STRCPY (new_buf + operand0->string.length,
- local_operand1->string.pointer);
+ ACPI_STRCPY(new_buf, operand0->string.pointer);
+ ACPI_STRCPY(new_buf + operand0->string.length,
+ local_operand1->string.pointer);
break;
case ACPI_TYPE_BUFFER:
/* Result of two Buffers is a Buffer */
- return_desc = acpi_ut_create_buffer_object (
- (acpi_size) operand0->buffer.length +
- (acpi_size) local_operand1->buffer.length);
+ return_desc = acpi_ut_create_buffer_object((acpi_size)
+ operand0->buffer.
+ length +
+ (acpi_size)
+ local_operand1->
+ buffer.length);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
- new_buf = (char *) return_desc->buffer.pointer;
+ new_buf = (char *)return_desc->buffer.pointer;
/* Concatenate the buffers */
- ACPI_MEMCPY (new_buf,
- operand0->buffer.pointer,
- operand0->buffer.length);
- ACPI_MEMCPY (new_buf + operand0->buffer.length,
- local_operand1->buffer.pointer,
- local_operand1->buffer.length);
+ ACPI_MEMCPY(new_buf,
+ operand0->buffer.pointer, operand0->buffer.length);
+ ACPI_MEMCPY(new_buf + operand0->buffer.length,
+ local_operand1->buffer.pointer,
+ local_operand1->buffer.length);
break;
default:
/* Invalid object type, should not happen here */
- ACPI_REPORT_ERROR (("Concatenate - Invalid object type: %X\n",
- ACPI_GET_OBJECT_TYPE (operand0)));
- status =AE_AML_INTERNAL;
+ ACPI_REPORT_ERROR(("Concatenate - Invalid object type: %X\n",
+ ACPI_GET_OBJECT_TYPE(operand0)));
+ status = AE_AML_INTERNAL;
goto cleanup;
}
*actual_return_desc = return_desc;
-cleanup:
+ cleanup:
if (local_operand1 != operand1) {
- acpi_ut_remove_reference (local_operand1);
+ acpi_ut_remove_reference(local_operand1);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_do_math_op
@@ -412,62 +395,49 @@ cleanup:
******************************************************************************/
acpi_integer
-acpi_ex_do_math_op (
- u16 opcode,
- acpi_integer integer0,
- acpi_integer integer1)
+acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
switch (opcode) {
- case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
+ case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
return (integer0 + integer1);
-
- case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
+ case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
return (integer0 & integer1);
-
- case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
+ case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
return (~(integer0 & integer1));
-
- case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
+ case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
return (integer0 | integer1);
-
- case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
+ case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
return (~(integer0 | integer1));
-
- case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
+ case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
return (integer0 ^ integer1);
-
- case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
+ case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
return (integer0 * integer1);
-
- case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result)*/
+ case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
return (integer0 << integer1);
-
- case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
+ case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
return (integer0 >> integer1);
-
- case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
+ case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
return (integer0 - integer1);
@@ -477,7 +447,6 @@ acpi_ex_do_math_op (
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_do_logical_numeric_op
@@ -499,28 +468,24 @@ acpi_ex_do_math_op (
******************************************************************************/
acpi_status
-acpi_ex_do_logical_numeric_op (
- u16 opcode,
- acpi_integer integer0,
- acpi_integer integer1,
- u8 *logical_result)
+acpi_ex_do_logical_numeric_op(u16 opcode,
+ acpi_integer integer0,
+ acpi_integer integer1, u8 * logical_result)
{
- acpi_status status = AE_OK;
- u8 local_result = FALSE;
-
-
- ACPI_FUNCTION_TRACE ("ex_do_logical_numeric_op");
+ acpi_status status = AE_OK;
+ u8 local_result = FALSE;
+ ACPI_FUNCTION_TRACE("ex_do_logical_numeric_op");
switch (opcode) {
- case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
+ case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
if (integer0 && integer1) {
local_result = TRUE;
}
break;
- case AML_LOR_OP: /* LOr (Integer0, Integer1) */
+ case AML_LOR_OP: /* LOr (Integer0, Integer1) */
if (integer0 || integer1) {
local_result = TRUE;
@@ -535,10 +500,9 @@ acpi_ex_do_logical_numeric_op (
/* Return the logical result and status */
*logical_result = local_result;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_do_logical_op
@@ -566,24 +530,20 @@ acpi_ex_do_logical_numeric_op (
******************************************************************************/
acpi_status
-acpi_ex_do_logical_op (
- u16 opcode,
- union acpi_operand_object *operand0,
- union acpi_operand_object *operand1,
- u8 *logical_result)
+acpi_ex_do_logical_op(u16 opcode,
+ union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1, u8 * logical_result)
{
- union acpi_operand_object *local_operand1 = operand1;
- acpi_integer integer0;
- acpi_integer integer1;
- u32 length0;
- u32 length1;
- acpi_status status = AE_OK;
- u8 local_result = FALSE;
- int compare;
-
-
- ACPI_FUNCTION_TRACE ("ex_do_logical_op");
+ union acpi_operand_object *local_operand1 = operand1;
+ acpi_integer integer0;
+ acpi_integer integer1;
+ u32 length0;
+ u32 length1;
+ acpi_status status = AE_OK;
+ u8 local_result = FALSE;
+ int compare;
+ ACPI_FUNCTION_TRACE("ex_do_logical_op");
/*
* Convert the second operand if necessary. The first operand
@@ -592,18 +552,19 @@ acpi_ex_do_logical_op (
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+ switch (ACPI_GET_OBJECT_TYPE(operand0)) {
case ACPI_TYPE_INTEGER:
- status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16);
+ status =
+ acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
break;
case ACPI_TYPE_STRING:
- status = acpi_ex_convert_to_string (operand1, &local_operand1,
- ACPI_IMPLICIT_CONVERT_HEX);
+ status = acpi_ex_convert_to_string(operand1, &local_operand1,
+ ACPI_IMPLICIT_CONVERT_HEX);
break;
case ACPI_TYPE_BUFFER:
- status = acpi_ex_convert_to_buffer (operand1, &local_operand1);
+ status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
break;
default:
@@ -611,14 +572,14 @@ acpi_ex_do_logical_op (
break;
}
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/*
* Two cases: 1) Both Integers, 2) Both Strings or Buffers
*/
- if (ACPI_GET_OBJECT_TYPE (operand0) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
/*
* 1) Both operands are of type integer
* Note: local_operand1 may have changed above
@@ -627,21 +588,21 @@ acpi_ex_do_logical_op (
integer1 = local_operand1->integer.value;
switch (opcode) {
- case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
+ case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
if (integer0 == integer1) {
local_result = TRUE;
}
break;
- case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
+ case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
if (integer0 > integer1) {
local_result = TRUE;
}
break;
- case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
+ case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
if (integer0 < integer1) {
local_result = TRUE;
@@ -652,8 +613,7 @@ acpi_ex_do_logical_op (
status = AE_AML_INTERNAL;
break;
}
- }
- else {
+ } else {
/*
* 2) Both operands are Strings or both are Buffers
* Note: Code below takes advantage of common Buffer/String
@@ -665,31 +625,31 @@ acpi_ex_do_logical_op (
/* Lexicographic compare: compare the data bytes */
- compare = ACPI_MEMCMP ((const char * ) operand0->buffer.pointer,
- (const char * ) local_operand1->buffer.pointer,
- (length0 > length1) ? length1 : length0);
+ compare = ACPI_MEMCMP((const char *)operand0->buffer.pointer,
+ (const char *)local_operand1->buffer.
+ pointer,
+ (length0 > length1) ? length1 : length0);
switch (opcode) {
- case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
+ case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
/* Length and all bytes must be equal */
- if ((length0 == length1) &&
- (compare == 0)) {
+ if ((length0 == length1) && (compare == 0)) {
/* Length and all bytes match ==> TRUE */
local_result = TRUE;
}
break;
- case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
+ case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
if (compare > 0) {
local_result = TRUE;
- goto cleanup; /* TRUE */
+ goto cleanup; /* TRUE */
}
if (compare < 0) {
- goto cleanup; /* FALSE */
+ goto cleanup; /* FALSE */
}
/* Bytes match (to shortest length), compare lengths */
@@ -699,14 +659,14 @@ acpi_ex_do_logical_op (
}
break;
- case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
+ case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
if (compare > 0) {
- goto cleanup; /* FALSE */
+ goto cleanup; /* FALSE */
}
if (compare < 0) {
local_result = TRUE;
- goto cleanup; /* TRUE */
+ goto cleanup; /* TRUE */
}
/* Bytes match (to shortest length), compare lengths */
@@ -722,18 +682,16 @@ acpi_ex_do_logical_op (
}
}
-cleanup:
+ cleanup:
/* New object was created if implicit conversion performed - delete */
if (local_operand1 != operand1) {
- acpi_ut_remove_reference (local_operand1);
+ acpi_ut_remove_reference(local_operand1);
}
/* Return the logical result and status */
*logical_result = local_result;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index c3cb714d2cba..ab47f6d8b5c0 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -42,20 +42,16 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exmutex")
+ACPI_MODULE_NAME("exmutex")
/* Local prototypes */
-
static void
-acpi_ex_link_mutex (
- union acpi_operand_object *obj_desc,
- struct acpi_thread_state *thread);
-
+acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
+ struct acpi_thread_state *thread);
/*******************************************************************************
*
@@ -69,12 +65,9 @@ acpi_ex_link_mutex (
*
******************************************************************************/
-void
-acpi_ex_unlink_mutex (
- union acpi_operand_object *obj_desc)
+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
{
- struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
-
+ struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
if (!thread) {
return;
@@ -88,13 +81,11 @@ acpi_ex_unlink_mutex (
if (obj_desc->mutex.prev) {
(obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
- }
- else {
+ } else {
thread->acquired_mutex_list = obj_desc->mutex.next;
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_link_mutex
@@ -109,12 +100,10 @@ acpi_ex_unlink_mutex (
******************************************************************************/
static void
-acpi_ex_link_mutex (
- union acpi_operand_object *obj_desc,
- struct acpi_thread_state *thread)
+acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
+ struct acpi_thread_state *thread)
{
- union acpi_operand_object *list_head;
-
+ union acpi_operand_object *list_head;
list_head = thread->acquired_mutex_list;
@@ -134,7 +123,6 @@ acpi_ex_link_mutex (
thread->acquired_mutex_list = obj_desc;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_acquire_mutex
@@ -150,27 +138,23 @@ acpi_ex_link_mutex (
******************************************************************************/
acpi_status
-acpi_ex_acquire_mutex (
- union acpi_operand_object *time_desc,
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
+ union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_acquire_mutex", obj_desc);
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ex_acquire_mutex", obj_desc);
if (!obj_desc) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Sanity check -- we must have a valid thread ID */
if (!walk_state->thread) {
- ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("Cannot acquire Mutex [%4.4s], null thread info\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/*
@@ -178,10 +162,8 @@ acpi_ex_acquire_mutex (
* mutex. This mechanism provides some deadlock prevention
*/
if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
- ACPI_REPORT_ERROR ((
- "Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
- return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+ ACPI_REPORT_ERROR(("Cannot acquire Mutex [%4.4s], incorrect sync_level\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+ return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
}
/* Support for multiple acquires by the owning thread */
@@ -190,43 +172,43 @@ acpi_ex_acquire_mutex (
/* Special case for Global Lock, allow all threads */
if ((obj_desc->mutex.owner_thread->thread_id ==
- walk_state->thread->thread_id) ||
- (obj_desc->mutex.semaphore ==
- acpi_gbl_global_lock_semaphore)) {
+ walk_state->thread->thread_id) ||
+ (obj_desc->mutex.semaphore ==
+ acpi_gbl_global_lock_semaphore)) {
/*
* The mutex is already owned by this thread,
* just increment the acquisition depth
*/
obj_desc->mutex.acquisition_depth++;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
}
/* Acquire the mutex, wait if necessary */
- status = acpi_ex_system_acquire_mutex (time_desc, obj_desc);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_system_acquire_mutex(time_desc, obj_desc);
+ if (ACPI_FAILURE(status)) {
/* Includes failure from a timeout on time_desc */
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Have the mutex: update mutex and walk info and save the sync_level */
- obj_desc->mutex.owner_thread = walk_state->thread;
+ obj_desc->mutex.owner_thread = walk_state->thread;
obj_desc->mutex.acquisition_depth = 1;
- obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level;
+ obj_desc->mutex.original_sync_level =
+ walk_state->thread->current_sync_level;
walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
/* Link the mutex to the current thread for force-unlock at method exit */
- acpi_ex_link_mutex (obj_desc, walk_state->thread);
+ acpi_ex_link_mutex(obj_desc, walk_state->thread);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_release_mutex
@@ -241,48 +223,40 @@ acpi_ex_acquire_mutex (
******************************************************************************/
acpi_status
-acpi_ex_release_mutex (
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ex_release_mutex");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ex_release_mutex");
if (!obj_desc) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* The mutex must have been previously acquired in order to release it */
if (!obj_desc->mutex.owner_thread) {
- ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
- return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
+ ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], not acquired\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+ return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
}
/* Sanity check -- we must have a valid thread ID */
if (!walk_state->thread) {
- ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], null thread info\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/*
* The Mutex is owned, but this thread must be the owner.
* Special case for Global Lock, any thread can release
*/
- if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) &&
- (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
- ACPI_REPORT_ERROR ((
- "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
- walk_state->thread->thread_id,
- acpi_ut_get_node_name (obj_desc->mutex.node),
- obj_desc->mutex.owner_thread->thread_id));
- return_ACPI_STATUS (AE_AML_NOT_OWNER);
+ if ((obj_desc->mutex.owner_thread->thread_id !=
+ walk_state->thread->thread_id)
+ && (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
+ ACPI_REPORT_ERROR(("Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), obj_desc->mutex.owner_thread->thread_id));
+ return_ACPI_STATUS(AE_AML_NOT_OWNER);
}
/*
@@ -290,10 +264,8 @@ acpi_ex_release_mutex (
* equal to the current sync level
*/
if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
- ACPI_REPORT_ERROR ((
- "Cannot release Mutex [%4.4s], incorrect sync_level\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
- return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+ ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], incorrect sync_level\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+ return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
}
/* Match multiple Acquires with multiple Releases */
@@ -302,26 +274,26 @@ acpi_ex_release_mutex (
if (obj_desc->mutex.acquisition_depth != 0) {
/* Just decrement the depth and return */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Unlink the mutex from the owner's list */
- acpi_ex_unlink_mutex (obj_desc);
+ acpi_ex_unlink_mutex(obj_desc);
/* Release the mutex */
- status = acpi_ex_system_release_mutex (obj_desc);
+ status = acpi_ex_system_release_mutex(obj_desc);
/* Update the mutex and walk state, restore sync_level before acquire */
obj_desc->mutex.owner_thread = NULL;
- walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level;
+ walk_state->thread->current_sync_level =
+ obj_desc->mutex.original_sync_level;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_release_all_mutexes
@@ -334,17 +306,13 @@ acpi_ex_release_mutex (
*
******************************************************************************/
-void
-acpi_ex_release_all_mutexes (
- struct acpi_thread_state *thread)
+void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
{
- union acpi_operand_object *next = thread->acquired_mutex_list;
- union acpi_operand_object *this;
- acpi_status status;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_operand_object *next = thread->acquired_mutex_list;
+ union acpi_operand_object *this;
+ acpi_status status;
+ ACPI_FUNCTION_ENTRY();
/* Traverse the list of owned mutexes, releasing each one */
@@ -353,13 +321,13 @@ acpi_ex_release_all_mutexes (
next = this->mutex.next;
this->mutex.acquisition_depth = 1;
- this->mutex.prev = NULL;
- this->mutex.next = NULL;
+ this->mutex.prev = NULL;
+ this->mutex.next = NULL;
- /* Release the mutex */
+ /* Release the mutex */
- status = acpi_ex_system_release_mutex (this);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_system_release_mutex(this);
+ if (ACPI_FAILURE(status)) {
continue;
}
@@ -372,5 +340,3 @@ acpi_ex_release_all_mutexes (
thread->current_sync_level = this->mutex.original_sync_level;
}
}
-
-
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
index 639f0bd3f6d8..239d8473e9a5 100644
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -42,26 +42,18 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exnames")
+ACPI_MODULE_NAME("exnames")
/* Local prototypes */
-
-static char *
-acpi_ex_allocate_name_string (
- u32 prefix_count,
- u32 num_name_segs);
+static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs);
static acpi_status
-acpi_ex_name_segment (
- u8 **in_aml_address,
- char *name_string);
-
+acpi_ex_name_segment(u8 ** in_aml_address, char *name_string);
/*******************************************************************************
*
@@ -79,17 +71,13 @@ acpi_ex_name_segment (
*
******************************************************************************/
-static char *
-acpi_ex_allocate_name_string (
- u32 prefix_count,
- u32 num_name_segs)
+static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs)
{
- char *temp_ptr;
- char *name_string;
- u32 size_needed;
-
- ACPI_FUNCTION_TRACE ("ex_allocate_name_string");
+ char *temp_ptr;
+ char *name_string;
+ u32 size_needed;
+ ACPI_FUNCTION_TRACE("ex_allocate_name_string");
/*
* Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix.
@@ -100,20 +88,19 @@ acpi_ex_allocate_name_string (
/* Special case for root */
size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
- }
- else {
- size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
+ } else {
+ size_needed =
+ prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
}
/*
* Allocate a buffer for the name.
* This buffer must be deleted by the caller!
*/
- name_string = ACPI_MEM_ALLOCATE (size_needed);
+ name_string = ACPI_MEM_ALLOCATE(size_needed);
if (!name_string) {
- ACPI_REPORT_ERROR ((
- "ex_allocate_name_string: Could not allocate size %d\n", size_needed));
- return_PTR (NULL);
+ ACPI_REPORT_ERROR(("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
+ return_PTR(NULL);
}
temp_ptr = name_string;
@@ -122,23 +109,20 @@ acpi_ex_allocate_name_string (
if (prefix_count == ACPI_UINT32_MAX) {
*temp_ptr++ = AML_ROOT_PREFIX;
- }
- else {
+ } else {
while (prefix_count--) {
*temp_ptr++ = AML_PARENT_PREFIX;
}
}
-
/* Set up Dual or Multi prefixes if needed */
if (num_name_segs > 2) {
/* Set up multi prefixes */
*temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
- *temp_ptr++ = (char) num_name_segs;
- }
- else if (2 == num_name_segs) {
+ *temp_ptr++ = (char)num_name_segs;
+ } else if (2 == num_name_segs) {
/* Set up dual prefixes */
*temp_ptr++ = AML_DUAL_NAME_PREFIX;
@@ -150,7 +134,7 @@ acpi_ex_allocate_name_string (
*/
*temp_ptr = 0;
- return_PTR (name_string);
+ return_PTR(name_string);
}
/*******************************************************************************
@@ -167,19 +151,14 @@ acpi_ex_allocate_name_string (
*
******************************************************************************/
-static acpi_status
-acpi_ex_name_segment (
- u8 **in_aml_address,
- char *name_string)
+static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string)
{
- char *aml_address = (void *) *in_aml_address;
- acpi_status status = AE_OK;
- u32 index;
- char char_buf[5];
-
-
- ACPI_FUNCTION_TRACE ("ex_name_segment");
+ char *aml_address = (void *)*in_aml_address;
+ acpi_status status = AE_OK;
+ u32 index;
+ char char_buf[5];
+ ACPI_FUNCTION_TRACE("ex_name_segment");
/*
* If first character is a digit, then we know that we aren't looking at a
@@ -188,20 +167,20 @@ acpi_ex_name_segment (
char_buf[0] = *aml_address;
if ('0' <= char_buf[0] && char_buf[0] <= '9') {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "leading digit: %c\n", char_buf[0]));
- return_ACPI_STATUS (AE_CTRL_PENDING);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "leading digit: %c\n",
+ char_buf[0]));
+ return_ACPI_STATUS(AE_CTRL_PENDING);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Bytes from stream:\n"));
for (index = 0;
- (index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_character (*aml_address));
- index++) {
+ (index < ACPI_NAME_SIZE)
+ && (acpi_ut_valid_acpi_character(*aml_address)); index++) {
char_buf[index] = *aml_address++;
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[index]));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "%c\n", char_buf[index]));
}
-
/* Valid name segment */
if (index == 4) {
@@ -210,41 +189,37 @@ acpi_ex_name_segment (
char_buf[4] = '\0';
if (name_string) {
- ACPI_STRCAT (name_string, char_buf);
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Appended to - %s \n", name_string));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "No Name string - %s \n", char_buf));
+ ACPI_STRCAT(name_string, char_buf);
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Appended to - %s \n", name_string));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "No Name string - %s \n", char_buf));
}
- }
- else if (index == 0) {
+ } else if (index == 0) {
/*
* First character was not a valid name character,
* so we are looking at something other than a name.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Leading character is not alpha: %02Xh (not a name)\n",
- char_buf[0]));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Leading character is not alpha: %02Xh (not a name)\n",
+ char_buf[0]));
status = AE_CTRL_PENDING;
- }
- else {
+ } else {
/*
* Segment started with one or more valid characters, but fewer than
* the required 4
*/
status = AE_AML_BAD_NAME;
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Bad character %02x in name, at %p\n",
- *aml_address, aml_address));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Bad character %02x in name, at %p\n",
+ *aml_address, aml_address));
}
*in_aml_address = (u8 *) aml_address;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_get_name_string
@@ -263,37 +238,32 @@ acpi_ex_name_segment (
******************************************************************************/
acpi_status
-acpi_ex_get_name_string (
- acpi_object_type data_type,
- u8 *in_aml_address,
- char **out_name_string,
- u32 *out_name_length)
+acpi_ex_get_name_string(acpi_object_type data_type,
+ u8 * in_aml_address,
+ char **out_name_string, u32 * out_name_length)
{
- acpi_status status = AE_OK;
- u8 *aml_address = in_aml_address;
- char *name_string = NULL;
- u32 num_segments;
- u32 prefix_count = 0;
- u8 has_prefix = FALSE;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_get_name_string", aml_address);
-
-
- if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type ||
- ACPI_TYPE_LOCAL_BANK_FIELD == data_type ||
- ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
+ acpi_status status = AE_OK;
+ u8 *aml_address = in_aml_address;
+ char *name_string = NULL;
+ u32 num_segments;
+ u32 prefix_count = 0;
+ u8 has_prefix = FALSE;
+
+ ACPI_FUNCTION_TRACE_PTR("ex_get_name_string", aml_address);
+
+ if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type ||
+ ACPI_TYPE_LOCAL_BANK_FIELD == data_type ||
+ ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
/* Disallow prefixes for types associated with field_unit names */
- name_string = acpi_ex_allocate_name_string (0, 1);
+ name_string = acpi_ex_allocate_name_string(0, 1);
if (!name_string) {
status = AE_NO_MEMORY;
+ } else {
+ status =
+ acpi_ex_name_segment(&aml_address, name_string);
}
- else {
- status = acpi_ex_name_segment (&aml_address, name_string);
- }
- }
- else {
+ } else {
/*
* data_type is not a field name.
* Examine first character of name for root or parent prefix operators
@@ -301,8 +271,9 @@ acpi_ex_get_name_string (
switch (*aml_address) {
case AML_ROOT_PREFIX:
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n",
- aml_address));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
+ "root_prefix(\\) at %p\n",
+ aml_address));
/*
* Remember that we have a root_prefix --
@@ -313,14 +284,14 @@ acpi_ex_get_name_string (
has_prefix = TRUE;
break;
-
case AML_PARENT_PREFIX:
/* Increment past possibly multiple parent prefixes */
do {
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n",
- aml_address));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
+ "parent_prefix (^) at %p\n",
+ aml_address));
aml_address++;
prefix_count++;
@@ -330,7 +301,6 @@ acpi_ex_get_name_string (
has_prefix = TRUE;
break;
-
default:
/* Not a prefix character */
@@ -343,11 +313,13 @@ acpi_ex_get_name_string (
switch (*aml_address) {
case AML_DUAL_NAME_PREFIX:
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n",
- aml_address));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
+ "dual_name_prefix at %p\n",
+ aml_address));
aml_address++;
- name_string = acpi_ex_allocate_name_string (prefix_count, 2);
+ name_string =
+ acpi_ex_allocate_name_string(prefix_count, 2);
if (!name_string) {
status = AE_NO_MEMORY;
break;
@@ -357,24 +329,29 @@ acpi_ex_get_name_string (
has_prefix = TRUE;
- status = acpi_ex_name_segment (&aml_address, name_string);
- if (ACPI_SUCCESS (status)) {
- status = acpi_ex_name_segment (&aml_address, name_string);
+ status =
+ acpi_ex_name_segment(&aml_address, name_string);
+ if (ACPI_SUCCESS(status)) {
+ status =
+ acpi_ex_name_segment(&aml_address,
+ name_string);
}
break;
-
case AML_MULTI_NAME_PREFIX_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n",
- aml_address));
+ ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
+ "multi_name_prefix at %p\n",
+ aml_address));
/* Fetch count of segments remaining in name path */
aml_address++;
num_segments = *aml_address;
- name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
+ name_string =
+ acpi_ex_allocate_name_string(prefix_count,
+ num_segments);
if (!name_string) {
status = AE_NO_MEMORY;
break;
@@ -386,27 +363,28 @@ acpi_ex_get_name_string (
has_prefix = TRUE;
while (num_segments &&
- (status = acpi_ex_name_segment (&aml_address, name_string)) ==
- AE_OK) {
+ (status =
+ acpi_ex_name_segment(&aml_address,
+ name_string)) == AE_OK) {
num_segments--;
}
break;
-
case 0:
/* null_name valid as of 8-12-98 ASL/AML Grammar Update */
if (prefix_count == ACPI_UINT32_MAX) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "name_seg is \"\\\" followed by NULL\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "name_seg is \"\\\" followed by NULL\n"));
}
/* Consume the NULL byte */
aml_address++;
- name_string = acpi_ex_allocate_name_string (prefix_count, 0);
+ name_string =
+ acpi_ex_allocate_name_string(prefix_count, 0);
if (!name_string) {
status = AE_NO_MEMORY;
break;
@@ -414,18 +392,19 @@ acpi_ex_get_name_string (
break;
-
default:
/* Name segment string */
- name_string = acpi_ex_allocate_name_string (prefix_count, 1);
+ name_string =
+ acpi_ex_allocate_name_string(prefix_count, 1);
if (!name_string) {
status = AE_NO_MEMORY;
break;
}
- status = acpi_ex_name_segment (&aml_address, name_string);
+ status =
+ acpi_ex_name_segment(&aml_address, name_string);
break;
}
}
@@ -433,15 +412,20 @@ acpi_ex_get_name_string (
if (AE_CTRL_PENDING == status && has_prefix) {
/* Ran out of segments after processing a prefix */
- ACPI_REPORT_ERROR (
- ("ex_do_name: Malformed Name at %p\n", name_string));
+ ACPI_REPORT_ERROR(("ex_do_name: Malformed Name at %p\n",
+ name_string));
status = AE_AML_BAD_NAME;
}
+ if (ACPI_FAILURE(status)) {
+ if (name_string) {
+ ACPI_MEM_FREE(name_string);
+ }
+ return_ACPI_STATUS(status);
+ }
+
*out_name_string = name_string;
*out_name_length = (u32) (aml_address - in_aml_address);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index dbdf8262ba00..97e34542f5e4 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/acdispat.h>
@@ -50,10 +49,8 @@
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exoparg1")
-
+ACPI_MODULE_NAME("exoparg1")
/*!
* Naming convention for AML interpreter execution routines.
@@ -76,7 +73,6 @@
* The AcpiExOpcode* functions are called via the Dispatcher component with
* fully resolved operands.
!*/
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_0A_0T_1R
@@ -88,59 +84,53 @@
* DESCRIPTION: Execute operator with no operands, one return value
*
******************************************************************************/
-
-acpi_status
-acpi_ex_opcode_0A_0T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *return_desc = NULL;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ acpi_status status = AE_OK;
+ union acpi_operand_object *return_desc = NULL;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_0A_0T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Examine the AML opcode */
switch (walk_state->opcode) {
- case AML_TIMER_OP: /* Timer () */
+ case AML_TIMER_OP: /* Timer () */
/* Create a return object of type Integer */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
-
- return_desc->integer.value = acpi_os_get_timer ();
+#if ACPI_MACHINE_WIDTH != 16
+ return_desc->integer.value = acpi_os_get_timer();
+#endif
break;
- default: /* Unknown opcode */
+ default: /* Unknown opcode */
- ACPI_REPORT_ERROR (("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
break;
}
-cleanup:
-
- if (!walk_state->result_obj) {
- walk_state->result_obj = return_desc;
- }
+ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
+ acpi_ut_remove_reference(return_desc);
+ } else {
+ /* Save the return value */
+
+ walk_state->result_obj = return_desc;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_1A_0T_0R
@@ -154,69 +144,58 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_1A_0T_0R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_0T_0R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Examine the AML opcode */
switch (walk_state->opcode) {
- case AML_RELEASE_OP: /* Release (mutex_object) */
+ case AML_RELEASE_OP: /* Release (mutex_object) */
- status = acpi_ex_release_mutex (operand[0], walk_state);
+ status = acpi_ex_release_mutex(operand[0], walk_state);
break;
+ case AML_RESET_OP: /* Reset (event_object) */
- case AML_RESET_OP: /* Reset (event_object) */
-
- status = acpi_ex_system_reset_event (operand[0]);
+ status = acpi_ex_system_reset_event(operand[0]);
break;
+ case AML_SIGNAL_OP: /* Signal (event_object) */
- case AML_SIGNAL_OP: /* Signal (event_object) */
-
- status = acpi_ex_system_signal_event (operand[0]);
+ status = acpi_ex_system_signal_event(operand[0]);
break;
+ case AML_SLEEP_OP: /* Sleep (msec_time) */
- case AML_SLEEP_OP: /* Sleep (msec_time) */
-
- status = acpi_ex_system_do_suspend (operand[0]->integer.value);
+ status = acpi_ex_system_do_suspend(operand[0]->integer.value);
break;
+ case AML_STALL_OP: /* Stall (usec_time) */
- case AML_STALL_OP: /* Stall (usec_time) */
-
- status = acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
+ status =
+ acpi_ex_system_do_stall((u32) operand[0]->integer.value);
break;
+ case AML_UNLOAD_OP: /* Unload (Handle) */
- case AML_UNLOAD_OP: /* Unload (Handle) */
-
- status = acpi_ex_unload_table (operand[0]);
+ status = acpi_ex_unload_table(operand[0]);
break;
+ default: /* Unknown opcode */
- default: /* Unknown opcode */
-
- ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_1A_1T_0R
@@ -230,41 +209,34 @@ acpi_ex_opcode_1A_0T_0R (
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_1A_1T_0R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object **operand = &walk_state->operands[0];
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ acpi_status status = AE_OK;
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_1T_0R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Examine the AML opcode */
switch (walk_state->opcode) {
case AML_LOAD_OP:
- status = acpi_ex_load_op (operand[0], operand[1], walk_state);
+ status = acpi_ex_load_op(operand[0], operand[1], walk_state);
break;
- default: /* Unknown opcode */
+ default: /* Unknown opcode */
- ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
+ cleanup:
-cleanup:
-
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_1A_1T_1R
@@ -278,23 +250,19 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_1A_1T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *return_desc = NULL;
- union acpi_operand_object *return_desc2 = NULL;
- u32 temp32;
- u32 i;
- acpi_integer power_of_ten;
- acpi_integer digit;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
-
+ acpi_status status = AE_OK;
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *return_desc = NULL;
+ union acpi_operand_object *return_desc2 = NULL;
+ u32 temp32;
+ u32 i;
+ acpi_integer power_of_ten;
+ acpi_integer digit;
+
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_1T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Examine the AML opcode */
@@ -308,20 +276,19 @@ acpi_ex_opcode_1A_1T_1R (
/* Create a return object of type Integer for these opcodes */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
switch (walk_state->opcode) {
- case AML_BIT_NOT_OP: /* Not (Operand, Result) */
+ case AML_BIT_NOT_OP: /* Not (Operand, Result) */
return_desc->integer.value = ~operand[0]->integer.value;
break;
-
- case AML_FIND_SET_LEFT_BIT_OP: /* find_set_left_bit (Operand, Result) */
+ case AML_FIND_SET_LEFT_BIT_OP: /* find_set_left_bit (Operand, Result) */
return_desc->integer.value = operand[0]->integer.value;
@@ -330,15 +297,14 @@ acpi_ex_opcode_1A_1T_1R (
* endian unsigned value, so this boundary condition is valid.
*/
for (temp32 = 0; return_desc->integer.value &&
- temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
+ temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
return_desc->integer.value >>= 1;
}
return_desc->integer.value = temp32;
break;
-
- case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
+ case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
return_desc->integer.value = operand[0]->integer.value;
@@ -347,18 +313,17 @@ acpi_ex_opcode_1A_1T_1R (
* endian unsigned value, so this boundary condition is valid.
*/
for (temp32 = 0; return_desc->integer.value &&
- temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
+ temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
return_desc->integer.value <<= 1;
}
/* Since the bit position is one-based, subtract from 33 (65) */
return_desc->integer.value = temp32 == 0 ? 0 :
- (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
+ (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
break;
-
- case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */
+ case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */
/*
* The 64-bit ACPI integer can hold 16 4-bit BCD characters
@@ -371,7 +336,9 @@ acpi_ex_opcode_1A_1T_1R (
/* Convert each BCD digit (each is one nybble wide) */
- for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
+ for (i = 0;
+ (i < acpi_gbl_integer_nybble_width) && (digit > 0);
+ i++) {
/* Get the least significant 4-bit BCD digit */
temp32 = ((u32) digit) & 0xF;
@@ -379,9 +346,9 @@ acpi_ex_opcode_1A_1T_1R (
/* Check the range of the digit */
if (temp32 > 9) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "BCD digit too large (not decimal): 0x%X\n",
- temp32));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "BCD digit too large (not decimal): 0x%X\n",
+ temp32));
status = AE_AML_NUMERIC_OVERFLOW;
goto cleanup;
@@ -389,8 +356,8 @@ acpi_ex_opcode_1A_1T_1R (
/* Sum the digit into the result with the current power of 10 */
- return_desc->integer.value += (((acpi_integer) temp32) *
- power_of_ten);
+ return_desc->integer.value +=
+ (((acpi_integer) temp32) * power_of_ten);
/* Shift to next BCD digit */
@@ -402,45 +369,50 @@ acpi_ex_opcode_1A_1T_1R (
}
break;
-
- case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */
+ case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */
return_desc->integer.value = 0;
digit = operand[0]->integer.value;
/* Each BCD digit is one nybble wide */
- for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
- (void) acpi_ut_short_divide (digit, 10, &digit, &temp32);
+ for (i = 0;
+ (i < acpi_gbl_integer_nybble_width) && (digit > 0);
+ i++) {
+ (void)acpi_ut_short_divide(digit, 10, &digit,
+ &temp32);
/*
* Insert the BCD digit that resides in the
* remainder from above
*/
- return_desc->integer.value |= (((acpi_integer) temp32) <<
- ACPI_MUL_4 (i));
+ return_desc->integer.value |=
+ (((acpi_integer) temp32) << ACPI_MUL_4(i));
}
/* Overflow if there is any data left in Digit */
if (digit > 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Integer too large to convert to BCD: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Integer too large to convert to BCD: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(operand
+ [0]->
+ integer.
+ value)));
status = AE_AML_NUMERIC_OVERFLOW;
goto cleanup;
}
break;
-
- case AML_COND_REF_OF_OP: /* cond_ref_of (source_object, Result) */
+ case AML_COND_REF_OF_OP: /* cond_ref_of (source_object, Result) */
/*
* This op is a little strange because the internal return value is
* different than the return value stored in the result descriptor
* (There are really two return values)
*/
- if ((struct acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
+ if ((struct acpi_namespace_node *)operand[0] ==
+ acpi_gbl_root_node) {
/*
* This means that the object does not exist in the namespace,
* return FALSE
@@ -451,38 +423,38 @@ acpi_ex_opcode_1A_1T_1R (
/* Get the object reference, store it, and remove our reference */
- status = acpi_ex_get_object_reference (operand[0],
- &return_desc2, walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_get_object_reference(operand[0],
+ &return_desc2,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- status = acpi_ex_store (return_desc2, operand[1], walk_state);
- acpi_ut_remove_reference (return_desc2);
+ status =
+ acpi_ex_store(return_desc2, operand[1], walk_state);
+ acpi_ut_remove_reference(return_desc2);
/* The object exists in the namespace, return TRUE */
return_desc->integer.value = ACPI_INTEGER_MAX;
goto cleanup;
-
default:
/* No other opcodes get here */
break;
}
break;
-
- case AML_STORE_OP: /* Store (Source, Target) */
+ case AML_STORE_OP: /* Store (Source, Target) */
/*
* A store operand is typically a number, string, buffer or lvalue
* Be careful about deleting the source object,
* since the object itself may have been stored.
*/
- status = acpi_ex_store (operand[0], operand[1], walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_store(operand[0], operand[1], walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* It is possible that the Store already produced a return object */
@@ -495,92 +467,84 @@ acpi_ex_opcode_1A_1T_1R (
* cancel out, and we simply don't do anything.
*/
walk_state->result_obj = operand[0];
- walk_state->operands[0] = NULL; /* Prevent deletion */
+ walk_state->operands[0] = NULL; /* Prevent deletion */
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
+ /*
+ * ACPI 2.0 Opcodes
+ */
+ case AML_COPY_OP: /* Copy (Source, Target) */
- /*
- * ACPI 2.0 Opcodes
- */
- case AML_COPY_OP: /* Copy (Source, Target) */
-
- status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc,
- walk_state);
+ status =
+ acpi_ut_copy_iobject_to_iobject(operand[0], &return_desc,
+ walk_state);
break;
+ case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */
- case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */
-
- status = acpi_ex_convert_to_string (operand[0], &return_desc,
- ACPI_EXPLICIT_CONVERT_DECIMAL);
+ status = acpi_ex_convert_to_string(operand[0], &return_desc,
+ ACPI_EXPLICIT_CONVERT_DECIMAL);
if (return_desc == operand[0]) {
/* No conversion performed, add ref to handle return value */
- acpi_ut_add_reference (return_desc);
+ acpi_ut_add_reference(return_desc);
}
break;
+ case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */
- case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */
-
- status = acpi_ex_convert_to_string (operand[0], &return_desc,
- ACPI_EXPLICIT_CONVERT_HEX);
+ status = acpi_ex_convert_to_string(operand[0], &return_desc,
+ ACPI_EXPLICIT_CONVERT_HEX);
if (return_desc == operand[0]) {
/* No conversion performed, add ref to handle return value */
- acpi_ut_add_reference (return_desc);
+ acpi_ut_add_reference(return_desc);
}
break;
+ case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */
- case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */
-
- status = acpi_ex_convert_to_buffer (operand[0], &return_desc);
+ status = acpi_ex_convert_to_buffer(operand[0], &return_desc);
if (return_desc == operand[0]) {
/* No conversion performed, add ref to handle return value */
- acpi_ut_add_reference (return_desc);
+ acpi_ut_add_reference(return_desc);
}
break;
+ case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
- case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
-
- status = acpi_ex_convert_to_integer (operand[0], &return_desc,
- ACPI_ANY_BASE);
+ status = acpi_ex_convert_to_integer(operand[0], &return_desc,
+ ACPI_ANY_BASE);
if (return_desc == operand[0]) {
/* No conversion performed, add ref to handle return value */
- acpi_ut_add_reference (return_desc);
+ acpi_ut_add_reference(return_desc);
}
break;
-
- case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */
- case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */
+ case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */
+ case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */
/* These are two obsolete opcodes */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "%s is obsolete and not implemented\n",
- acpi_ps_get_opcode_name (walk_state->opcode)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%s is obsolete and not implemented\n",
+ acpi_ps_get_opcode_name(walk_state->opcode)));
status = AE_SUPPORT;
goto cleanup;
+ default: /* Unknown opcode */
- default: /* Unknown opcode */
-
- ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/* Store the return value computed above into the target object */
- status = acpi_ex_store (return_desc, operand[1], walk_state);
+ status = acpi_ex_store(return_desc, operand[1], walk_state);
}
-
-cleanup:
+ cleanup:
if (!walk_state->result_obj) {
walk_state->result_obj = return_desc;
@@ -588,14 +552,13 @@ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(return_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_1A_0T_1R
@@ -608,28 +571,24 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_1A_0T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *temp_desc;
- union acpi_operand_object *return_desc = NULL;
- acpi_status status = AE_OK;
- u32 type;
- acpi_integer value;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *temp_desc;
+ union acpi_operand_object *return_desc = NULL;
+ acpi_status status = AE_OK;
+ u32 type;
+ acpi_integer value;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_0T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Examine the AML opcode */
switch (walk_state->opcode) {
- case AML_LNOT_OP: /* LNot (Operand) */
+ case AML_LNOT_OP: /* LNot (Operand) */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -644,15 +603,14 @@ acpi_ex_opcode_1A_0T_1R (
}
break;
-
- case AML_DECREMENT_OP: /* Decrement (Operand) */
- case AML_INCREMENT_OP: /* Increment (Operand) */
+ case AML_DECREMENT_OP: /* Decrement (Operand) */
+ case AML_INCREMENT_OP: /* Increment (Operand) */
/*
* Create a new integer. Can't just get the base integer and
* increment it because it may be an Arg or Field.
*/
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -663,10 +621,11 @@ acpi_ex_opcode_1A_0T_1R (
* NS Node or an internal object.
*/
temp_desc = operand[0];
- if (ACPI_GET_DESCRIPTOR_TYPE (temp_desc) == ACPI_DESC_TYPE_OPERAND) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(temp_desc) ==
+ ACPI_DESC_TYPE_OPERAND) {
/* Internal reference object - prevent deletion */
- acpi_ut_add_reference (temp_desc);
+ acpi_ut_add_reference(temp_desc);
}
/*
@@ -676,11 +635,15 @@ acpi_ex_opcode_1A_0T_1R (
* NOTE: We use LNOT_OP here in order to force resolution of the
* reference operand to an actual integer.
*/
- status = acpi_ex_resolve_operands (AML_LNOT_OP, &temp_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
- acpi_ps_get_opcode_name (walk_state->opcode),
- acpi_format_exception(status)));
+ status =
+ acpi_ex_resolve_operands(AML_LNOT_OP, &temp_desc,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%s: bad operand(s) %s\n",
+ acpi_ps_get_opcode_name(walk_state->
+ opcode),
+ acpi_format_exception(status)));
goto cleanup;
}
@@ -690,25 +653,25 @@ acpi_ex_opcode_1A_0T_1R (
* Perform the actual increment or decrement
*/
if (walk_state->opcode == AML_INCREMENT_OP) {
- return_desc->integer.value = temp_desc->integer.value +1;
- }
- else {
- return_desc->integer.value = temp_desc->integer.value -1;
+ return_desc->integer.value =
+ temp_desc->integer.value + 1;
+ } else {
+ return_desc->integer.value =
+ temp_desc->integer.value - 1;
}
/* Finished with this Integer object */
- acpi_ut_remove_reference (temp_desc);
+ acpi_ut_remove_reference(temp_desc);
/*
* Store the result back (indirectly) through the original
* Reference object
*/
- status = acpi_ex_store (return_desc, operand[0], walk_state);
+ status = acpi_ex_store(return_desc, operand[0], walk_state);
break;
-
- case AML_TYPE_OP: /* object_type (source_object) */
+ case AML_TYPE_OP: /* object_type (source_object) */
/*
* Note: The operand is not resolved at this point because we want to
@@ -719,13 +682,15 @@ acpi_ex_opcode_1A_0T_1R (
/* Get the type of the base object */
- status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_resolve_multiple(walk_state, operand[0], &type,
+ NULL);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Allocate a descriptor to hold the type. */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -734,8 +699,7 @@ acpi_ex_opcode_1A_0T_1R (
return_desc->integer.value = type;
break;
-
- case AML_SIZE_OF_OP: /* size_of (source_object) */
+ case AML_SIZE_OF_OP: /* size_of (source_object) */
/*
* Note: The operand is not resolved at this point because we want to
@@ -744,9 +708,10 @@ acpi_ex_opcode_1A_0T_1R (
/* Get the base object */
- status = acpi_ex_resolve_multiple (walk_state,
- operand[0], &type, &temp_desc);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_resolve_multiple(walk_state,
+ operand[0], &type,
+ &temp_desc);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -777,9 +742,9 @@ acpi_ex_opcode_1A_0T_1R (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
- acpi_ut_get_type_name (type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
+ acpi_ut_get_type_name(type)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
}
@@ -788,7 +753,7 @@ acpi_ex_opcode_1A_0T_1R (
* Now that we have the size of the object, create a result
* object to hold the value
*/
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -797,22 +762,23 @@ acpi_ex_opcode_1A_0T_1R (
return_desc->integer.value = value;
break;
+ case AML_REF_OF_OP: /* ref_of (source_object) */
- case AML_REF_OF_OP: /* ref_of (source_object) */
-
- status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_get_object_reference(operand[0], &return_desc,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
break;
-
- case AML_DEREF_OF_OP: /* deref_of (obj_reference | String) */
+ case AML_DEREF_OF_OP: /* deref_of (obj_reference | String) */
/* Check for a method local or argument, or standalone String */
- if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) != ACPI_DESC_TYPE_NAMED) {
- switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
+ ACPI_DESC_TYPE_NAMED) {
+ switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
case ACPI_TYPE_LOCAL_REFERENCE:
/*
* This is a deref_of (local_x | arg_x)
@@ -825,11 +791,12 @@ acpi_ex_opcode_1A_0T_1R (
/* Set Operand[0] to the value of the local/arg */
- status = acpi_ds_method_data_get_value (
- operand[0]->reference.opcode,
- operand[0]->reference.offset,
- walk_state, &temp_desc);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ds_method_data_get_value
+ (operand[0]->reference.opcode,
+ operand[0]->reference.offset,
+ walk_state, &temp_desc);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -837,7 +804,7 @@ acpi_ex_opcode_1A_0T_1R (
* Delete our reference to the input object and
* point to the object just retrieved
*/
- acpi_ut_remove_reference (operand[0]);
+ acpi_ut_remove_reference(operand[0]);
operand[0] = temp_desc;
break;
@@ -845,8 +812,9 @@ acpi_ex_opcode_1A_0T_1R (
/* Get the object to which the reference refers */
- temp_desc = operand[0]->reference.object;
- acpi_ut_remove_reference (operand[0]);
+ temp_desc =
+ operand[0]->reference.object;
+ acpi_ut_remove_reference(operand[0]);
operand[0] = temp_desc;
break;
@@ -857,7 +825,6 @@ acpi_ex_opcode_1A_0T_1R (
}
break;
-
case ACPI_TYPE_STRING:
/*
@@ -868,22 +835,28 @@ acpi_ex_opcode_1A_0T_1R (
* 2) Dereference the node to an actual object. Could be a
* Field, so we need to resolve the node to a value.
*/
- status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
- walk_state->scope_info->scope.node,
- ACPI_NS_SEARCH_PARENT,
- ACPI_CAST_INDIRECT_PTR (
- struct acpi_namespace_node, &return_desc));
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ns_get_node_by_path(operand[0]->string.
+ pointer,
+ walk_state->
+ scope_info->scope.
+ node,
+ ACPI_NS_SEARCH_PARENT,
+ ACPI_CAST_INDIRECT_PTR
+ (struct
+ acpi_namespace_node,
+ &return_desc));
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- status = acpi_ex_resolve_node_to_value (
- ACPI_CAST_INDIRECT_PTR (
- struct acpi_namespace_node, &return_desc),
- walk_state);
+ status =
+ acpi_ex_resolve_node_to_value
+ (ACPI_CAST_INDIRECT_PTR
+ (struct acpi_namespace_node, &return_desc),
+ walk_state);
goto cleanup;
-
default:
status = AE_AML_OPERAND_TYPE;
@@ -893,17 +866,20 @@ acpi_ex_opcode_1A_0T_1R (
/* Operand[0] may have changed from the code above */
- if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
+ ACPI_DESC_TYPE_NAMED) {
/*
* This is a deref_of (object_reference)
* Get the actual object from the Node (This is the dereference).
* This case may only happen when a local_x or arg_x is
* dereferenced above.
*/
- return_desc = acpi_ns_get_attached_object (
- (struct acpi_namespace_node *) operand[0]);
- }
- else {
+ return_desc = acpi_ns_get_attached_object((struct
+ acpi_namespace_node
+ *)
+ operand[0]);
+ acpi_ut_add_reference(return_desc);
+ } else {
/*
* This must be a reference object produced by either the
* Index() or ref_of() operator
@@ -918,7 +894,8 @@ acpi_ex_opcode_1A_0T_1R (
switch (operand[0]->reference.target_type) {
case ACPI_TYPE_BUFFER_FIELD:
- temp_desc = operand[0]->reference.object;
+ temp_desc =
+ operand[0]->reference.object;
/*
* Create a new object that contains one element of the
@@ -928,7 +905,9 @@ acpi_ex_opcode_1A_0T_1R (
* sub-buffer of the main buffer, it is only a pointer to a
* single element (byte) of the buffer!
*/
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc =
+ acpi_ut_create_internal_object
+ (ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -940,66 +919,63 @@ acpi_ex_opcode_1A_0T_1R (
* reference to the buffer itself.
*/
return_desc->integer.value =
- temp_desc->buffer.pointer[operand[0]->reference.offset];
+ temp_desc->buffer.
+ pointer[operand[0]->reference.
+ offset];
break;
-
case ACPI_TYPE_PACKAGE:
/*
* Return the referenced element of the package. We must
* add another reference to the referenced object, however.
*/
- return_desc = *(operand[0]->reference.where);
- if (!return_desc) {
- /*
- * We can't return a NULL dereferenced value. This is
- * an uninitialized package element and is thus a
- * severe error.
- */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "NULL package element obj %p\n",
- operand[0]));
- status = AE_AML_UNINITIALIZED_ELEMENT;
- goto cleanup;
+ return_desc =
+ *(operand[0]->reference.where);
+ if (return_desc) {
+ acpi_ut_add_reference
+ (return_desc);
}
- acpi_ut_add_reference (return_desc);
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown Index target_type %X in obj %p\n",
- operand[0]->reference.target_type, operand[0]));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown Index target_type %X in obj %p\n",
+ operand[0]->reference.
+ target_type,
+ operand[0]));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
}
break;
-
case AML_REF_OF_OP:
return_desc = operand[0]->reference.object;
- if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) ==
- ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(return_desc) ==
+ ACPI_DESC_TYPE_NAMED) {
- return_desc = acpi_ns_get_attached_object (
- (struct acpi_namespace_node *) return_desc);
+ return_desc =
+ acpi_ns_get_attached_object((struct
+ acpi_namespace_node
+ *)
+ return_desc);
}
/* Add another reference to the object! */
- acpi_ut_add_reference (return_desc);
+ acpi_ut_add_reference(return_desc);
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown opcode in ref(%p) - %X\n",
- operand[0], operand[0]->reference.opcode));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown opcode in ref(%p) - %X\n",
+ operand[0],
+ operand[0]->reference.
+ opcode));
status = AE_TYPE;
goto cleanup;
@@ -1007,25 +983,21 @@ acpi_ex_opcode_1A_0T_1R (
}
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
-
-cleanup:
+ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(return_desc);
}
walk_state->result_obj = return_desc;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 7429032c2b6c..8d70c6beef00 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -41,17 +41,14 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/acinterp.h>
#include <acpi/acevents.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exoparg2")
-
+ACPI_MODULE_NAME("exoparg2")
/*!
* Naming convention for AML interpreter execution routines.
@@ -74,8 +71,6 @@
* The AcpiExOpcode* functions are called via the Dispatcher component with
* fully resolved operands.
!*/
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_2A_0T_0R
@@ -90,29 +85,24 @@
* ALLOCATION: Deletes both operands
*
******************************************************************************/
-
-acpi_status
-acpi_ex_opcode_2A_0T_0R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- struct acpi_namespace_node *node;
- u32 value;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_0R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ struct acpi_namespace_node *node;
+ u32 value;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_0R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Examine the opcode */
switch (walk_state->opcode) {
- case AML_NOTIFY_OP: /* Notify (notify_object, notify_value) */
+ case AML_NOTIFY_OP: /* Notify (notify_object, notify_value) */
/* The first operand is a namespace node */
- node = (struct acpi_namespace_node *) operand[0];
+ node = (struct acpi_namespace_node *)operand[0];
/* Second value is the notify value */
@@ -120,15 +110,14 @@ acpi_ex_opcode_2A_0T_0R (
/* Are notifies allowed on this object? */
- if (!acpi_ev_is_notify_object (node)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unexpected notify object type [%s]\n",
- acpi_ut_get_type_name (node->type)));
+ if (!acpi_ev_is_notify_object(node)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unexpected notify object type [%s]\n",
+ acpi_ut_get_type_name(node->type)));
status = AE_AML_OPERAND_TYPE;
break;
}
-
#ifdef ACPI_GPE_NOTIFY_CHECK
/*
* GPE method wake/notify check. Here, we want to ensure that we
@@ -144,12 +133,14 @@ acpi_ex_opcode_2A_0T_0R (
* If all three cases are true, this is a wake-only GPE that should
* be disabled at runtime.
*/
- if (value == 2) /* device_wake */ {
- status = acpi_ev_check_for_wake_only_gpe (walk_state->gpe_event_info);
- if (ACPI_FAILURE (status)) {
+ if (value == 2) { /* device_wake */
+ status =
+ acpi_ev_check_for_wake_only_gpe(walk_state->
+ gpe_event_info);
+ if (ACPI_FAILURE(status)) {
/* AE_WAKE_ONLY_GPE only error, means ignore this notify */
- return_ACPI_STATUS (AE_OK)
+ return_ACPI_STATUS(AE_OK)
}
}
#endif
@@ -161,21 +152,18 @@ acpi_ex_opcode_2A_0T_0R (
* from this thread -- because handlers may in turn run other
* control methods.
*/
- status = acpi_ev_queue_notify_request (node, value);
+ status = acpi_ev_queue_notify_request(node, value);
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_2A_2T_1R
@@ -189,19 +177,15 @@ acpi_ex_opcode_2A_0T_0R (
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_2A_2T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *return_desc1 = NULL;
- union acpi_operand_object *return_desc2 = NULL;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *return_desc1 = NULL;
+ union acpi_operand_object *return_desc2 = NULL;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_2T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Execute the opcode */
@@ -210,13 +194,15 @@ acpi_ex_opcode_2A_2T_1R (
/* Divide (Dividend, Divisor, remainder_result quotient_result) */
- return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc1 =
+ acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc1) {
status = AE_NO_MEMORY;
goto cleanup;
}
- return_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc2 =
+ acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc2) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -224,33 +210,31 @@ acpi_ex_opcode_2A_2T_1R (
/* Quotient to return_desc1, remainder to return_desc2 */
- status = acpi_ut_divide (operand[0]->integer.value,
- operand[1]->integer.value,
- &return_desc1->integer.value,
- &return_desc2->integer.value);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_divide(operand[0]->integer.value,
+ operand[1]->integer.value,
+ &return_desc1->integer.value,
+ &return_desc2->integer.value);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
/* Store the results to the target reference operands */
- status = acpi_ex_store (return_desc2, operand[2], walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_store(return_desc2, operand[2], walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- status = acpi_ex_store (return_desc1, operand[3], walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_store(return_desc1, operand[3], walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -258,24 +242,22 @@ acpi_ex_opcode_2A_2T_1R (
walk_state->result_obj = return_desc1;
-
-cleanup:
+ cleanup:
/*
* Since the remainder is not returned indirectly, remove a reference to
* it. Only the quotient is returned indirectly.
*/
- acpi_ut_remove_reference (return_desc2);
+ acpi_ut_remove_reference(return_desc2);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
/* Delete the return object */
- acpi_ut_remove_reference (return_desc1);
+ acpi_ut_remove_reference(return_desc1);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_2A_1T_1R
@@ -289,42 +271,39 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_2A_1T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *return_desc = NULL;
- acpi_integer index;
- acpi_status status = AE_OK;
- acpi_size length;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *return_desc = NULL;
+ acpi_integer index;
+ acpi_status status = AE_OK;
+ acpi_size length;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_1T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Execute the opcode */
if (walk_state->op_info->flags & AML_MATH) {
/* All simple math opcodes (add, etc.) */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
- return_desc->integer.value = acpi_ex_do_math_op (walk_state->opcode,
- operand[0]->integer.value,
- operand[1]->integer.value);
+ return_desc->integer.value =
+ acpi_ex_do_math_op(walk_state->opcode,
+ operand[0]->integer.value,
+ operand[1]->integer.value);
goto store_result_to_target;
}
switch (walk_state->opcode) {
- case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
+ case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -332,21 +311,18 @@ acpi_ex_opcode_2A_1T_1R (
/* return_desc will contain the remainder */
- status = acpi_ut_divide (operand[0]->integer.value,
- operand[1]->integer.value,
- NULL,
- &return_desc->integer.value);
+ status = acpi_ut_divide(operand[0]->integer.value,
+ operand[1]->integer.value,
+ NULL, &return_desc->integer.value);
break;
+ case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
- case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
-
- status = acpi_ex_do_concatenate (operand[0], operand[1],
- &return_desc, walk_state);
+ status = acpi_ex_do_concatenate(operand[0], operand[1],
+ &return_desc, walk_state);
break;
-
- case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
+ case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
/*
* Input object is guaranteed to be a buffer at this point (it may have
@@ -365,8 +341,8 @@ acpi_ex_opcode_2A_1T_1R (
*/
length = 0;
while ((length < operand[0]->buffer.length) &&
- (length < operand[1]->integer.value) &&
- (operand[0]->buffer.pointer[length])) {
+ (length < operand[1]->integer.value) &&
+ (operand[0]->buffer.pointer[length])) {
length++;
if (length > ACPI_MAX_STRING_CONVERSION) {
status = AE_AML_STRING_LIMIT;
@@ -376,33 +352,32 @@ acpi_ex_opcode_2A_1T_1R (
/* Allocate a new string object */
- return_desc = acpi_ut_create_string_object (length);
+ return_desc = acpi_ut_create_string_object(length);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
- /* Copy the raw buffer data with no transform. NULL terminated already*/
+ /* Copy the raw buffer data with no transform. NULL terminated already */
- ACPI_MEMCPY (return_desc->string.pointer,
- operand[0]->buffer.pointer, length);
+ ACPI_MEMCPY(return_desc->string.pointer,
+ operand[0]->buffer.pointer, length);
break;
-
case AML_CONCAT_RES_OP:
/* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
- status = acpi_ex_concat_template (operand[0], operand[1],
- &return_desc, walk_state);
+ status = acpi_ex_concat_template(operand[0], operand[1],
+ &return_desc, walk_state);
break;
-
- case AML_INDEX_OP: /* Index (Source Index Result) */
+ case AML_INDEX_OP: /* Index (Source Index Result) */
/* Create the internal return object */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
+ return_desc =
+ acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -412,76 +387,75 @@ acpi_ex_opcode_2A_1T_1R (
/* At this point, the Source operand is a Package, Buffer, or String */
- if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
+ if (ACPI_GET_OBJECT_TYPE(operand[0]) == ACPI_TYPE_PACKAGE) {
/* Object to be indexed is a Package */
if (index >= operand[0]->package.count) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index value (%X%8.8X) beyond package end (%X)\n",
- ACPI_FORMAT_UINT64 (index), operand[0]->package.count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Index value (%X%8.8X) beyond package end (%X)\n",
+ ACPI_FORMAT_UINT64(index),
+ operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
}
return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
- return_desc->reference.object = operand[0];
- return_desc->reference.where = &operand[0]->package.elements [
- index];
- }
- else {
+ return_desc->reference.object = operand[0];
+ return_desc->reference.where =
+ &operand[0]->package.elements[index];
+ } else {
/* Object to be indexed is a Buffer/String */
if (index >= operand[0]->buffer.length) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index value (%X%8.8X) beyond end of buffer (%X)\n",
- ACPI_FORMAT_UINT64 (index), operand[0]->buffer.length));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Index value (%X%8.8X) beyond end of buffer (%X)\n",
+ ACPI_FORMAT_UINT64(index),
+ operand[0]->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
}
- return_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD;
- return_desc->reference.object = operand[0];
+ return_desc->reference.target_type =
+ ACPI_TYPE_BUFFER_FIELD;
+ return_desc->reference.object = operand[0];
}
/*
* Add a reference to the target package/buffer/string for the life
* of the index.
*/
- acpi_ut_add_reference (operand[0]);
+ acpi_ut_add_reference(operand[0]);
/* Complete the Index reference object */
- return_desc->reference.opcode = AML_INDEX_OP;
- return_desc->reference.offset = (u32) index;
+ return_desc->reference.opcode = AML_INDEX_OP;
+ return_desc->reference.offset = (u32) index;
/* Store the reference to the Target */
- status = acpi_ex_store (return_desc, operand[2], walk_state);
+ status = acpi_ex_store(return_desc, operand[2], walk_state);
/* Return the reference */
walk_state->result_obj = return_desc;
goto cleanup;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
break;
}
+ store_result_to_target:
-store_result_to_target:
-
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/*
* Store the result of the operation (which is now in return_desc) into
* the Target descriptor.
*/
- status = acpi_ex_store (return_desc, operand[2], walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_store(return_desc, operand[2], walk_state);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -490,19 +464,17 @@ store_result_to_target:
}
}
-
-cleanup:
+ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(return_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_2A_0T_1R
@@ -515,23 +487,19 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_2A_0T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *return_desc = NULL;
- acpi_status status = AE_OK;
- u8 logical_result = FALSE;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *return_desc = NULL;
+ acpi_status status = AE_OK;
+ u8 logical_result = FALSE;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
/* Create the internal return object */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -542,50 +510,48 @@ acpi_ex_opcode_2A_0T_1R (
if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) {
/* logical_op (Operand0, Operand1) */
- status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
- operand[0]->integer.value, operand[1]->integer.value,
- &logical_result);
+ status = acpi_ex_do_logical_numeric_op(walk_state->opcode,
+ operand[0]->integer.
+ value,
+ operand[1]->integer.
+ value, &logical_result);
goto store_logical_result;
- }
- else if (walk_state->op_info->flags & AML_LOGICAL) {
+ } else if (walk_state->op_info->flags & AML_LOGICAL) {
/* logical_op (Operand0, Operand1) */
- status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
- operand[1], &logical_result);
+ status = acpi_ex_do_logical_op(walk_state->opcode, operand[0],
+ operand[1], &logical_result);
goto store_logical_result;
}
switch (walk_state->opcode) {
- case AML_ACQUIRE_OP: /* Acquire (mutex_object, Timeout) */
+ case AML_ACQUIRE_OP: /* Acquire (mutex_object, Timeout) */
- status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state);
+ status =
+ acpi_ex_acquire_mutex(operand[1], operand[0], walk_state);
if (status == AE_TIME) {
- logical_result = TRUE; /* TRUE = Acquire timed out */
+ logical_result = TRUE; /* TRUE = Acquire timed out */
status = AE_OK;
}
break;
+ case AML_WAIT_OP: /* Wait (event_object, Timeout) */
- case AML_WAIT_OP: /* Wait (event_object, Timeout) */
-
- status = acpi_ex_system_wait_event (operand[1], operand[0]);
+ status = acpi_ex_system_wait_event(operand[1], operand[0]);
if (status == AE_TIME) {
- logical_result = TRUE; /* TRUE, Wait timed out */
+ logical_result = TRUE; /* TRUE, Wait timed out */
status = AE_OK;
}
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
-
-store_logical_result:
+ store_logical_result:
/*
* Set return value to according to logical_result. logical TRUE (all ones)
* Default is FALSE (zero)
@@ -596,16 +562,13 @@ store_logical_result:
walk_state->result_obj = return_desc;
-
-cleanup:
+ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(return_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index 23b068adbf58..483365777670 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -42,16 +42,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exoparg3")
-
+ACPI_MODULE_NAME("exoparg3")
/*!
* Naming convention for AML interpreter execution routines.
@@ -74,8 +71,6 @@
* The AcpiExOpcode* functions are called via the Dispatcher component with
* fully resolved operands.
!*/
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_3A_0T_0R
@@ -87,61 +82,53 @@
* DESCRIPTION: Execute Triadic operator (3 operands)
*
******************************************************************************/
-
-acpi_status
-acpi_ex_opcode_3A_0T_0R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- struct acpi_signal_fatal_info *fatal;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ struct acpi_signal_fatal_info *fatal;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_3A_0T_0R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
switch (walk_state->opcode) {
- case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
+ case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
- (u32) operand[0]->integer.value,
- (u32) operand[1]->integer.value,
- (u32) operand[2]->integer.value));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
+ (u32) operand[0]->integer.value,
+ (u32) operand[1]->integer.value,
+ (u32) operand[2]->integer.value));
- fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info));
+ fatal =
+ ACPI_MEM_ALLOCATE(sizeof(struct acpi_signal_fatal_info));
if (fatal) {
- fatal->type = (u32) operand[0]->integer.value;
- fatal->code = (u32) operand[1]->integer.value;
+ fatal->type = (u32) operand[0]->integer.value;
+ fatal->code = (u32) operand[1]->integer.value;
fatal->argument = (u32) operand[2]->integer.value;
}
/* Always signal the OS! */
- status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
+ status = acpi_os_signal(ACPI_SIGNAL_FATAL, fatal);
/* Might return while OS is shutting down, just continue */
- ACPI_MEM_FREE (fatal);
+ ACPI_MEM_FREE(fatal);
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
+ cleanup:
-cleanup:
-
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_3A_1T_1R
@@ -154,31 +141,28 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_3A_1T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *return_desc = NULL;
- char *buffer;
- acpi_status status = AE_OK;
- acpi_integer index;
- acpi_size length;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *return_desc = NULL;
+ char *buffer = NULL;
+ acpi_status status = AE_OK;
+ acpi_integer index;
+ acpi_size length;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_3A_1T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
switch (walk_state->opcode) {
- case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
+ case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
/*
* Create the return object. The Source operand is guaranteed to be
* either a String or a Buffer, so just use its type.
*/
- return_desc = acpi_ut_create_internal_object (
- ACPI_GET_OBJECT_TYPE (operand[0]));
+ return_desc =
+ acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
+ (operand[0]));
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -193,67 +177,92 @@ acpi_ex_opcode_3A_1T_1R (
* If the index is beyond the length of the String/Buffer, or if the
* requested length is zero, return a zero-length String/Buffer
*/
- if ((index < operand[0]->string.length) &&
- (length > 0)) {
- /* Truncate request if larger than the actual String/Buffer */
-
- if ((index + length) >
- operand[0]->string.length) {
- length = (acpi_size) operand[0]->string.length -
- (acpi_size) index;
- }
+ if (index >= operand[0]->string.length) {
+ length = 0;
+ }
+
+ /* Truncate request if larger than the actual String/Buffer */
+
+ else if ((index + length) > operand[0]->string.length) {
+ length = (acpi_size) operand[0]->string.length -
+ (acpi_size) index;
+ }
+
+ /* Strings always have a sub-pointer, not so for buffers */
+
+ switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ case ACPI_TYPE_STRING:
- /* Allocate a new buffer for the String/Buffer */
+ /* Always allocate a new buffer for the String */
- buffer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
+ buffer = ACPI_MEM_CALLOCATE((acpi_size) length + 1);
if (!buffer) {
status = AE_NO_MEMORY;
goto cleanup;
}
+ break;
- /* Copy the portion requested */
+ case ACPI_TYPE_BUFFER:
- ACPI_MEMCPY (buffer, operand[0]->string.pointer + index,
- length);
+ /* If the requested length is zero, don't allocate a buffer */
- /* Set the length of the new String/Buffer */
+ if (length > 0) {
+ /* Allocate a new buffer for the Buffer */
- return_desc->string.pointer = buffer;
- return_desc->string.length = (u32) length;
+ buffer = ACPI_MEM_CALLOCATE(length);
+ if (!buffer) {
+ status = AE_NO_MEMORY;
+ goto cleanup;
+ }
+ }
+ break;
+
+ default: /* Should not happen */
+
+ status = AE_AML_OPERAND_TYPE;
+ goto cleanup;
}
+ if (length > 0) {
+ /* Copy the portion requested */
+
+ ACPI_MEMCPY(buffer, operand[0]->string.pointer + index,
+ length);
+ }
+
+ /* Set the length of the new String/Buffer */
+
+ return_desc->string.pointer = buffer;
+ return_desc->string.length = (u32) length;
+
/* Mark buffer initialized */
return_desc->buffer.flags |= AOPOBJ_DATA_VALID;
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
/* Store the result in the target */
- status = acpi_ex_store (return_desc, operand[3], walk_state);
+ status = acpi_ex_store(return_desc, operand[3], walk_state);
-cleanup:
+ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if (ACPI_FAILURE(status) || walk_state->result_obj) {
+ acpi_ut_remove_reference(return_desc);
}
/* Set the return object and exit */
- if (!walk_state->result_obj) {
+ else {
walk_state->result_obj = return_desc;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index 17f81d42ee41..5dee77139576 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -42,16 +42,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exoparg6")
-
+ACPI_MODULE_NAME("exoparg6")
/*!
* Naming convention for AML interpreter execution routines.
@@ -74,15 +71,11 @@
* The AcpiExOpcode* functions are called via the Dispatcher component with
* fully resolved operands.
!*/
-
/* Local prototypes */
-
static u8
-acpi_ex_do_match (
- u32 match_op,
- union acpi_operand_object *package_obj,
- union acpi_operand_object *match_obj);
-
+acpi_ex_do_match(u32 match_op,
+ union acpi_operand_object *package_obj,
+ union acpi_operand_object *match_obj);
/*******************************************************************************
*
@@ -101,14 +94,12 @@ acpi_ex_do_match (
******************************************************************************/
static u8
-acpi_ex_do_match (
- u32 match_op,
- union acpi_operand_object *package_obj,
- union acpi_operand_object *match_obj)
+acpi_ex_do_match(u32 match_op,
+ union acpi_operand_object *package_obj,
+ union acpi_operand_object *match_obj)
{
- u8 logical_result = TRUE;
- acpi_status status;
-
+ u8 logical_result = TRUE;
+ acpi_status status;
/*
* Note: Since the package_obj/match_obj ordering is opposite to that of
@@ -133,9 +124,10 @@ acpi_ex_do_match (
* True if equal: (P[i] == M)
* Change to: (M == P[i])
*/
- status = acpi_ex_do_logical_op (AML_LEQUAL_OP, match_obj, package_obj,
- &logical_result);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_do_logical_op(AML_LEQUAL_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE(status)) {
return (FALSE);
}
break;
@@ -146,12 +138,13 @@ acpi_ex_do_match (
* True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
* Change to: (M >= P[i]) (M not_less than P[i])
*/
- status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
- &logical_result);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_do_logical_op(AML_LLESS_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE(status)) {
return (FALSE);
}
- logical_result = (u8) !logical_result;
+ logical_result = (u8) ! logical_result;
break;
case MATCH_MLT:
@@ -160,9 +153,10 @@ acpi_ex_do_match (
* True if less than: (P[i] < M)
* Change to: (M > P[i])
*/
- status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
- &logical_result);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_do_logical_op(AML_LGREATER_OP, match_obj,
+ package_obj, &logical_result);
+ if (ACPI_FAILURE(status)) {
return (FALSE);
}
break;
@@ -173,12 +167,13 @@ acpi_ex_do_match (
* True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
* Change to: (M <= P[i]) (M not_greater than P[i])
*/
- status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
- &logical_result);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_do_logical_op(AML_LGREATER_OP, match_obj,
+ package_obj, &logical_result);
+ if (ACPI_FAILURE(status)) {
return (FALSE);
}
- logical_result = (u8)!logical_result;
+ logical_result = (u8) ! logical_result;
break;
case MATCH_MGT:
@@ -187,9 +182,10 @@ acpi_ex_do_match (
* True if greater than: (P[i] > M)
* Change to: (M < P[i])
*/
- status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
- &logical_result);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_do_logical_op(AML_LLESS_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE(status)) {
return (FALSE);
}
break;
@@ -204,7 +200,6 @@ acpi_ex_do_match (
return logical_result;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_opcode_6A_0T_1R
@@ -217,20 +212,16 @@ acpi_ex_do_match (
*
******************************************************************************/
-acpi_status
-acpi_ex_opcode_6A_0T_1R (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
{
- union acpi_operand_object **operand = &walk_state->operands[0];
- union acpi_operand_object *return_desc = NULL;
- acpi_status status = AE_OK;
- acpi_integer index;
- union acpi_operand_object *this_element;
-
-
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R",
- acpi_ps_get_opcode_name (walk_state->opcode));
+ union acpi_operand_object **operand = &walk_state->operands[0];
+ union acpi_operand_object *return_desc = NULL;
+ acpi_status status = AE_OK;
+ acpi_integer index;
+ union acpi_operand_object *this_element;
+ ACPI_FUNCTION_TRACE_STR("ex_opcode_6A_0T_1R",
+ acpi_ps_get_opcode_name(walk_state->opcode));
switch (walk_state->opcode) {
case AML_MATCH_OP:
@@ -242,8 +233,9 @@ acpi_ex_opcode_6A_0T_1R (
/* Validate both Match Term Operators (MTR, MEQ, etc.) */
if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
- (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Match operator out of range\n"));
+ (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Match operator out of range\n"));
status = AE_AML_OPERAND_VALUE;
goto cleanup;
}
@@ -252,16 +244,17 @@ acpi_ex_opcode_6A_0T_1R (
index = operand[5]->integer.value;
if (index >= operand[0]->package.count) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index (%X%8.8X) beyond package end (%X)\n",
- ACPI_FORMAT_UINT64 (index), operand[0]->package.count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Index (%X%8.8X) beyond package end (%X)\n",
+ ACPI_FORMAT_UINT64(index),
+ operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
}
/* Create an integer for the return value */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -283,7 +276,7 @@ acpi_ex_opcode_6A_0T_1R (
* ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
* match was found.
*/
- for ( ; index < operand[0]->package.count; index++) {
+ for (; index < operand[0]->package.count; index++) {
/* Get the current package element */
this_element = operand[0]->package.elements[index];
@@ -299,13 +292,13 @@ acpi_ex_opcode_6A_0T_1R (
* (proceed to next iteration of enclosing for loop) signifies a
* non-match.
*/
- if (!acpi_ex_do_match ((u32) operand[1]->integer.value,
- this_element, operand[2])) {
+ if (!acpi_ex_do_match((u32) operand[1]->integer.value,
+ this_element, operand[2])) {
continue;
}
- if (!acpi_ex_do_match ((u32) operand[3]->integer.value,
- this_element, operand[4])) {
+ if (!acpi_ex_do_match((u32) operand[3]->integer.value,
+ this_element, operand[4])) {
continue;
}
@@ -316,31 +309,27 @@ acpi_ex_opcode_6A_0T_1R (
}
break;
-
case AML_LOAD_TABLE_OP:
- status = acpi_ex_load_table_op (walk_state, &return_desc);
+ status = acpi_ex_load_table_op(walk_state, &return_desc);
break;
-
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_6A_0T_1R: Unknown opcode %X\n",
- walk_state->opcode));
+ ACPI_REPORT_ERROR(("acpi_ex_opcode_6A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
walk_state->result_obj = return_desc;
-
-cleanup:
+ cleanup:
/* Delete return object on error */
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (return_desc);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(return_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index c9e3c68b5549..7476c363e407 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -42,32 +42,24 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exprep")
+ACPI_MODULE_NAME("exprep")
/* Local prototypes */
-
static u32
-acpi_ex_decode_field_access (
- union acpi_operand_object *obj_desc,
- u8 field_flags,
- u32 *return_byte_alignment);
-
+acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
+ u8 field_flags, u32 * return_byte_alignment);
#ifdef ACPI_UNDER_DEVELOPMENT
static u32
-acpi_ex_generate_access (
- u32 field_bit_offset,
- u32 field_bit_length,
- u32 region_length);
+acpi_ex_generate_access(u32 field_bit_offset,
+ u32 field_bit_length, u32 region_length);
/*******************************************************************************
*
@@ -92,39 +84,36 @@ acpi_ex_generate_access (
******************************************************************************/
static u32
-acpi_ex_generate_access (
- u32 field_bit_offset,
- u32 field_bit_length,
- u32 region_length)
+acpi_ex_generate_access(u32 field_bit_offset,
+ u32 field_bit_length, u32 region_length)
{
- u32 field_byte_length;
- u32 field_byte_offset;
- u32 field_byte_end_offset;
- u32 access_byte_width;
- u32 field_start_offset;
- u32 field_end_offset;
- u32 minimum_access_width = 0xFFFFFFFF;
- u32 minimum_accesses = 0xFFFFFFFF;
- u32 accesses;
-
-
- ACPI_FUNCTION_TRACE ("ex_generate_access");
-
+ u32 field_byte_length;
+ u32 field_byte_offset;
+ u32 field_byte_end_offset;
+ u32 access_byte_width;
+ u32 field_start_offset;
+ u32 field_end_offset;
+ u32 minimum_access_width = 0xFFFFFFFF;
+ u32 minimum_accesses = 0xFFFFFFFF;
+ u32 accesses;
+
+ ACPI_FUNCTION_TRACE("ex_generate_access");
/* Round Field start offset and length to "minimal" byte boundaries */
- field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8));
- field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length +
- field_bit_offset, 8));
- field_byte_length = field_byte_end_offset - field_byte_offset;
+ field_byte_offset = ACPI_DIV_8(ACPI_ROUND_DOWN(field_bit_offset, 8));
+ field_byte_end_offset = ACPI_DIV_8(ACPI_ROUND_UP(field_bit_length +
+ field_bit_offset, 8));
+ field_byte_length = field_byte_end_offset - field_byte_offset;
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Bit length %d, Bit offset %d\n",
- field_bit_length, field_bit_offset));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Bit length %d, Bit offset %d\n",
+ field_bit_length, field_bit_offset));
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Byte Length %d, Byte Offset %d, End Offset %d\n",
- field_byte_length, field_byte_offset, field_byte_end_offset));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Byte Length %d, Byte Offset %d, End Offset %d\n",
+ field_byte_length, field_byte_offset,
+ field_byte_end_offset));
/*
* Iterative search for the maximum access width that is both aligned
@@ -132,7 +121,8 @@ acpi_ex_generate_access (
*
* Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
*/
- for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) {
+ for (access_byte_width = 1; access_byte_width <= 8;
+ access_byte_width <<= 1) {
/*
* 1) Round end offset up to next access boundary and make sure that
* this does not go beyond the end of the parent region.
@@ -140,31 +130,37 @@ acpi_ex_generate_access (
* are done. (This does not optimize for the perfectly aligned
* case yet).
*/
- if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) {
+ if (ACPI_ROUND_UP(field_byte_end_offset, access_byte_width) <=
+ region_length) {
field_start_offset =
- ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
- access_byte_width;
+ ACPI_ROUND_DOWN(field_byte_offset,
+ access_byte_width) /
+ access_byte_width;
field_end_offset =
- ACPI_ROUND_UP ((field_byte_length + field_byte_offset),
- access_byte_width) / access_byte_width;
+ ACPI_ROUND_UP((field_byte_length +
+ field_byte_offset),
+ access_byte_width) /
+ access_byte_width;
accesses = field_end_offset - field_start_offset;
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "access_width %d end is within region\n", access_byte_width));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "access_width %d end is within region\n",
+ access_byte_width));
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Field Start %d, Field End %d -- requires %d accesses\n",
- field_start_offset, field_end_offset, accesses));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Field Start %d, Field End %d -- requires %d accesses\n",
+ field_start_offset, field_end_offset,
+ accesses));
/* Single access is optimal */
if (accesses <= 1) {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Entire field can be accessed with one operation of size %d\n",
- access_byte_width));
- return_VALUE (access_byte_width);
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Entire field can be accessed with one operation of size %d\n",
+ access_byte_width));
+ return_VALUE(access_byte_width);
}
/*
@@ -172,30 +168,30 @@ acpi_ex_generate_access (
* try the next wider access on next iteration
*/
if (accesses < minimum_accesses) {
- minimum_accesses = accesses;
+ minimum_accesses = accesses;
minimum_access_width = access_byte_width;
}
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "access_width %d end is NOT within region\n", access_byte_width));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "access_width %d end is NOT within region\n",
+ access_byte_width));
if (access_byte_width == 1) {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Field goes beyond end-of-region!\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Field goes beyond end-of-region!\n"));
/* Field does not fit in the region at all */
- return_VALUE (0);
+ return_VALUE(0);
}
/*
* This width goes beyond the end-of-region, back off to
* previous access
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Backing off to previous optimal access width of %d\n",
- minimum_access_width));
- return_VALUE (minimum_access_width);
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Backing off to previous optimal access width of %d\n",
+ minimum_access_width));
+ return_VALUE(minimum_access_width);
}
}
@@ -203,12 +199,11 @@ acpi_ex_generate_access (
* Could not read/write field with one operation,
* just use max access width
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Cannot access field in one operation, using width 8\n"));
- return_VALUE (8);
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Cannot access field in one operation, using width 8\n"));
+ return_VALUE(8);
}
-#endif /* ACPI_UNDER_DEVELOPMENT */
-
+#endif /* ACPI_UNDER_DEVELOPMENT */
/*******************************************************************************
*
@@ -226,18 +221,14 @@ acpi_ex_generate_access (
******************************************************************************/
static u32
-acpi_ex_decode_field_access (
- union acpi_operand_object *obj_desc,
- u8 field_flags,
- u32 *return_byte_alignment)
+acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
+ u8 field_flags, u32 * return_byte_alignment)
{
- u32 access;
- u32 byte_alignment;
- u32 bit_length;
-
-
- ACPI_FUNCTION_TRACE ("ex_decode_field_access");
+ u32 access;
+ u32 byte_alignment;
+ u32 bit_length;
+ ACPI_FUNCTION_TRACE("ex_decode_field_access");
access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
@@ -246,9 +237,12 @@ acpi_ex_decode_field_access (
#ifdef ACPI_UNDER_DEVELOPMENT
byte_alignment =
- acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.bit_length,
- 0xFFFFFFFF /* Temp until we pass region_length as parameter */);
+ acpi_ex_generate_access(obj_desc->common_field.
+ start_field_bit_offset,
+ obj_desc->common_field.bit_length,
+ 0xFFFFFFFF
+ /* Temp until we pass region_length as parameter */
+ );
bit_length = byte_alignment * 8;
#endif
@@ -257,36 +251,35 @@ acpi_ex_decode_field_access (
break;
case AML_FIELD_ACCESS_BYTE:
- case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
+ case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
byte_alignment = 1;
- bit_length = 8;
+ bit_length = 8;
break;
case AML_FIELD_ACCESS_WORD:
byte_alignment = 2;
- bit_length = 16;
+ bit_length = 16;
break;
case AML_FIELD_ACCESS_DWORD:
byte_alignment = 4;
- bit_length = 32;
+ bit_length = 32;
break;
- case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
+ case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
byte_alignment = 8;
- bit_length = 64;
+ bit_length = 64;
break;
default:
/* Invalid field access type */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown field access type %X\n",
- access));
- return_VALUE (0);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown field access type %X\n", access));
+ return_VALUE(0);
}
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
/*
* buffer_field access can be on any byte boundary, so the
* byte_alignment is always 1 byte -- regardless of any byte_alignment
@@ -296,10 +289,9 @@ acpi_ex_decode_field_access (
}
*return_byte_alignment = byte_alignment;
- return_VALUE (bit_length);
+ return_VALUE(bit_length);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_prep_common_field_object
@@ -322,20 +314,16 @@ acpi_ex_decode_field_access (
******************************************************************************/
acpi_status
-acpi_ex_prep_common_field_object (
- union acpi_operand_object *obj_desc,
- u8 field_flags,
- u8 field_attribute,
- u32 field_bit_position,
- u32 field_bit_length)
+acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
+ u8 field_flags,
+ u8 field_attribute,
+ u32 field_bit_position, u32 field_bit_length)
{
- u32 access_bit_width;
- u32 byte_alignment;
- u32 nearest_byte_address;
-
-
- ACPI_FUNCTION_TRACE ("ex_prep_common_field_object");
+ u32 access_bit_width;
+ u32 byte_alignment;
+ u32 nearest_byte_address;
+ ACPI_FUNCTION_TRACE("ex_prep_common_field_object");
/*
* Note: the structure being initialized is the
@@ -361,16 +349,16 @@ acpi_ex_prep_common_field_object (
* For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
* the same (equivalent) as the byte_alignment.
*/
- access_bit_width = acpi_ex_decode_field_access (obj_desc, field_flags,
- &byte_alignment);
+ access_bit_width = acpi_ex_decode_field_access(obj_desc, field_flags,
+ &byte_alignment);
if (!access_bit_width) {
- return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
}
/* Setup width (access granularity) fields */
obj_desc->common_field.access_byte_width = (u8)
- ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */
+ ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */
obj_desc->common_field.access_bit_width = (u8) access_bit_width;
@@ -385,30 +373,30 @@ acpi_ex_prep_common_field_object (
* region or buffer.
*/
nearest_byte_address =
- ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
+ ACPI_ROUND_BITS_DOWN_TO_BYTES(field_bit_position);
obj_desc->common_field.base_byte_offset = (u32)
- ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment);
+ ACPI_ROUND_DOWN(nearest_byte_address, byte_alignment);
/*
* start_field_bit_offset is the offset of the first bit of the field within
* a field datum.
*/
obj_desc->common_field.start_field_bit_offset = (u8)
- (field_bit_position - ACPI_MUL_8 (obj_desc->common_field.base_byte_offset));
+ (field_bit_position -
+ ACPI_MUL_8(obj_desc->common_field.base_byte_offset));
/*
* Does the entire field fit within a single field access element? (datum)
* (i.e., without crossing a datum boundary)
*/
- if ((obj_desc->common_field.start_field_bit_offset + field_bit_length) <=
- (u16) access_bit_width) {
+ if ((obj_desc->common_field.start_field_bit_offset +
+ field_bit_length) <= (u16) access_bit_width) {
obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_prep_field_value
@@ -422,51 +410,49 @@ acpi_ex_prep_common_field_object (
*
******************************************************************************/
-acpi_status
-acpi_ex_prep_field_value (
- struct acpi_create_field_info *info)
+acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
{
- union acpi_operand_object *obj_desc;
- u32 type;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ex_prep_field_value");
+ union acpi_operand_object *obj_desc;
+ u32 type;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ex_prep_field_value");
/* Parameter validation */
if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
if (!info->region_node) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null region_node\n"));
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null region_node\n"));
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
- type = acpi_ns_get_type (info->region_node);
+ type = acpi_ns_get_type(info->region_node);
if (type != ACPI_TYPE_REGION) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed Region, found type %X (%s)\n",
- type, acpi_ut_get_type_name (type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed Region, found type %X (%s)\n",
+ type, acpi_ut_get_type_name(type)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
}
/* Allocate a new field object */
- obj_desc = acpi_ut_create_internal_object (info->field_type);
+ obj_desc = acpi_ut_create_internal_object(info->field_type);
if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Initialize areas of the object that are common to all fields */
obj_desc->common_field.node = info->field_node;
- status = acpi_ex_prep_common_field_object (obj_desc, info->field_flags,
- info->attribute, info->field_bit_position, info->field_bit_length);
- if (ACPI_FAILURE (status)) {
- acpi_ut_delete_object_desc (obj_desc);
- return_ACPI_STATUS (status);
+ status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags,
+ info->attribute,
+ info->field_bit_position,
+ info->field_bit_length);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_delete_object_desc(obj_desc);
+ return_ACPI_STATUS(status);
}
/* Initialize areas of the object that are specific to the field type */
@@ -474,71 +460,73 @@ acpi_ex_prep_field_value (
switch (info->field_type) {
case ACPI_TYPE_LOCAL_REGION_FIELD:
- obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node);
+ obj_desc->field.region_obj =
+ acpi_ns_get_attached_object(info->region_node);
/* An additional reference for the container */
- acpi_ut_add_reference (obj_desc->field.region_obj);
+ acpi_ut_add_reference(obj_desc->field.region_obj);
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "region_field: bit_off %X, Off %X, Gran %X, Region %p\n",
- obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset,
- obj_desc->field.access_byte_width, obj_desc->field.region_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "region_field: bit_off %X, Off %X, Gran %X, Region %p\n",
+ obj_desc->field.start_field_bit_offset,
+ obj_desc->field.base_byte_offset,
+ obj_desc->field.access_byte_width,
+ obj_desc->field.region_obj));
break;
-
case ACPI_TYPE_LOCAL_BANK_FIELD:
- obj_desc->bank_field.value = info->bank_value;
- obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (
- info->region_node);
- obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (
- info->register_node);
+ obj_desc->bank_field.value = info->bank_value;
+ obj_desc->bank_field.region_obj =
+ acpi_ns_get_attached_object(info->region_node);
+ obj_desc->bank_field.bank_obj =
+ acpi_ns_get_attached_object(info->register_node);
/* An additional reference for the attached objects */
- acpi_ut_add_reference (obj_desc->bank_field.region_obj);
- acpi_ut_add_reference (obj_desc->bank_field.bank_obj);
+ acpi_ut_add_reference(obj_desc->bank_field.region_obj);
+ acpi_ut_add_reference(obj_desc->bank_field.bank_obj);
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n",
- obj_desc->bank_field.start_field_bit_offset,
- obj_desc->bank_field.base_byte_offset,
- obj_desc->field.access_byte_width,
- obj_desc->bank_field.region_obj,
- obj_desc->bank_field.bank_obj));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n",
+ obj_desc->bank_field.start_field_bit_offset,
+ obj_desc->bank_field.base_byte_offset,
+ obj_desc->field.access_byte_width,
+ obj_desc->bank_field.region_obj,
+ obj_desc->bank_field.bank_obj));
break;
-
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- obj_desc->index_field.index_obj = acpi_ns_get_attached_object (
- info->register_node);
- obj_desc->index_field.data_obj = acpi_ns_get_attached_object (
- info->data_register_node);
- obj_desc->index_field.value = (u32)
- (info->field_bit_position / ACPI_MUL_8 (
- obj_desc->field.access_byte_width));
-
- if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
- ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
- acpi_ut_delete_object_desc (obj_desc);
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ obj_desc->index_field.index_obj =
+ acpi_ns_get_attached_object(info->register_node);
+ obj_desc->index_field.data_obj =
+ acpi_ns_get_attached_object(info->data_register_node);
+ obj_desc->index_field.value = (u32)
+ (info->field_bit_position /
+ ACPI_MUL_8(obj_desc->field.access_byte_width));
+
+ if (!obj_desc->index_field.data_obj
+ || !obj_desc->index_field.index_obj) {
+ ACPI_REPORT_ERROR(("Null Index Object during field prep\n"));
+ acpi_ut_delete_object_desc(obj_desc);
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/* An additional reference for the attached objects */
- acpi_ut_add_reference (obj_desc->index_field.data_obj);
- acpi_ut_add_reference (obj_desc->index_field.index_obj);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
- obj_desc->index_field.start_field_bit_offset,
- obj_desc->index_field.base_byte_offset,
- obj_desc->index_field.value,
- obj_desc->field.access_byte_width,
- obj_desc->index_field.index_obj,
- obj_desc->index_field.data_obj));
+ acpi_ut_add_reference(obj_desc->index_field.data_obj);
+ acpi_ut_add_reference(obj_desc->index_field.index_obj);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
+ obj_desc->index_field.start_field_bit_offset,
+ obj_desc->index_field.base_byte_offset,
+ obj_desc->index_field.value,
+ obj_desc->field.access_byte_width,
+ obj_desc->index_field.index_obj,
+ obj_desc->index_field.data_obj));
break;
default:
@@ -550,15 +538,16 @@ acpi_ex_prep_field_value (
* Store the constructed descriptor (obj_desc) into the parent Node,
* preserving the current type of that named_obj.
*/
- status = acpi_ns_attach_object (info->field_node, obj_desc,
- acpi_ns_get_type (info->field_node));
+ status = acpi_ns_attach_object(info->field_node, obj_desc,
+ acpi_ns_get_type(info->field_node));
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n",
- info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+ "Set named_obj %p [%4.4s], obj_desc %p\n",
+ info->field_node,
+ acpi_ut_get_node_name(info->field_node), obj_desc));
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 723aaef4bb4a..9a2f5bea3afe 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -42,14 +42,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exregion")
-
+ACPI_MODULE_NAME("exregion")
/*******************************************************************************
*
@@ -68,27 +65,23 @@
* DESCRIPTION: Handler for the System Memory address space (Op Region)
*
******************************************************************************/
-
acpi_status
-acpi_ex_system_memory_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ex_system_memory_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
- void *logical_addr_ptr = NULL;
- struct acpi_mem_space_context *mem_info = region_context;
- u32 length;
- acpi_size window_size;
+ acpi_status status = AE_OK;
+ void *logical_addr_ptr = NULL;
+ struct acpi_mem_space_context *mem_info = region_context;
+ u32 length;
+ acpi_size window_size;
#ifndef ACPI_MISALIGNED_TRANSFERS
- u32 remainder;
+ u32 remainder;
#endif
- ACPI_FUNCTION_TRACE ("ex_system_memory_space_handler");
-
+ ACPI_FUNCTION_TRACE("ex_system_memory_space_handler");
/* Validate and translate the bit width */
@@ -110,9 +103,10 @@ acpi_ex_system_memory_space_handler (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid system_memory width %d\n",
- bit_width));
- return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid system_memory width %d\n",
+ bit_width));
+ return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
}
#ifndef ACPI_MISALIGNED_TRANSFERS
@@ -120,9 +114,10 @@ acpi_ex_system_memory_space_handler (
* Hardware does not support non-aligned data transfers, we must verify
* the request.
*/
- (void) acpi_ut_short_divide ((acpi_integer) address, length, NULL, &remainder);
+ (void)acpi_ut_short_divide((acpi_integer) address, length, NULL,
+ &remainder);
if (remainder != 0) {
- return_ACPI_STATUS (AE_AML_ALIGNMENT);
+ return_ACPI_STATUS(AE_AML_ALIGNMENT);
}
#endif
@@ -132,9 +127,10 @@ acpi_ex_system_memory_space_handler (
* 2) Address beyond the current mapping?
*/
if ((address < mem_info->mapped_physical_address) ||
- (((acpi_integer) address + length) >
- ((acpi_integer)
- mem_info->mapped_physical_address + mem_info->mapped_length))) {
+ (((acpi_integer) address + length) > ((acpi_integer)
+ mem_info->
+ mapped_physical_address +
+ mem_info->mapped_length))) {
/*
* The request cannot be resolved by the current memory mapping;
* Delete the existing mapping and create a new one.
@@ -142,8 +138,8 @@ acpi_ex_system_memory_space_handler (
if (mem_info->mapped_length) {
/* Valid mapping, delete it */
- acpi_os_unmap_memory (mem_info->mapped_logical_address,
- mem_info->mapped_length);
+ acpi_os_unmap_memory(mem_info->mapped_logical_address,
+ mem_info->mapped_length);
}
/*
@@ -151,7 +147,7 @@ acpi_ex_system_memory_space_handler (
* constrain the maximum mapping size to something reasonable.
*/
window_size = (acpi_size)
- ((mem_info->address + mem_info->length) - address);
+ ((mem_info->address + mem_info->length) - address);
if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
@@ -159,14 +155,16 @@ acpi_ex_system_memory_space_handler (
/* Create a new mapping starting at the address given */
- status = acpi_os_map_memory (address, window_size,
- (void **) &mem_info->mapped_logical_address);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not map memory at %8.8X%8.8X, size %X\n",
- ACPI_FORMAT_UINT64 (address), (u32) window_size));
+ status = acpi_os_map_memory(address, window_size,
+ (void **)&mem_info->
+ mapped_logical_address);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not map memory at %8.8X%8.8X, size %X\n",
+ ACPI_FORMAT_UINT64(address),
+ (u32) window_size));
mem_info->mapped_length = 0;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Save the physical address and mapping size */
@@ -180,42 +178,41 @@ acpi_ex_system_memory_space_handler (
* access
*/
logical_addr_ptr = mem_info->mapped_logical_address +
- ((acpi_integer) address -
- (acpi_integer) mem_info->mapped_physical_address);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "system_memory %d (%d width) Address=%8.8X%8.8X\n",
- function, bit_width,
- ACPI_FORMAT_UINT64 (address)));
-
- /*
- * Perform the memory read or write
- *
- * Note: For machines that do not support non-aligned transfers, the target
- * address was checked for alignment above. We do not attempt to break the
- * transfer up into smaller (byte-size) chunks because the AML specifically
- * asked for a transfer width that the hardware may require.
- */
+ ((acpi_integer) address -
+ (acpi_integer) mem_info->mapped_physical_address);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "system_memory %d (%d width) Address=%8.8X%8.8X\n",
+ function, bit_width, ACPI_FORMAT_UINT64(address)));
+
+ /*
+ * Perform the memory read or write
+ *
+ * Note: For machines that do not support non-aligned transfers, the target
+ * address was checked for alignment above. We do not attempt to break the
+ * transfer up into smaller (byte-size) chunks because the AML specifically
+ * asked for a transfer width that the hardware may require.
+ */
switch (function) {
case ACPI_READ:
*value = 0;
switch (bit_width) {
case 8:
- *value = (acpi_integer) *((u8 *) logical_addr_ptr);
+ *value = (acpi_integer) * ((u8 *) logical_addr_ptr);
break;
case 16:
- *value = (acpi_integer) *((u16 *) logical_addr_ptr);
+ *value = (acpi_integer) * ((u16 *) logical_addr_ptr);
break;
case 32:
- *value = (acpi_integer) *((u32 *) logical_addr_ptr);
+ *value = (acpi_integer) * ((u32 *) logical_addr_ptr);
break;
#if ACPI_MACHINE_WIDTH != 16
case 64:
- *value = (acpi_integer) *((u64 *) logical_addr_ptr);
+ *value = (acpi_integer) * ((u64 *) logical_addr_ptr);
break;
#endif
default:
@@ -228,20 +225,20 @@ acpi_ex_system_memory_space_handler (
switch (bit_width) {
case 8:
- *(u8 *) logical_addr_ptr = (u8) *value;
+ *(u8 *) logical_addr_ptr = (u8) * value;
break;
case 16:
- *(u16 *) logical_addr_ptr = (u16) *value;
+ *(u16 *) logical_addr_ptr = (u16) * value;
break;
case 32:
- *(u32 *) logical_addr_ptr = (u32) *value;
+ *(u32 *) logical_addr_ptr = (u32) * value;
break;
#if ACPI_MACHINE_WIDTH != 16
case 64:
- *(u64 *) logical_addr_ptr = (u64) *value;
+ *(u64 *) logical_addr_ptr = (u64) * value;
break;
#endif
@@ -256,10 +253,9 @@ acpi_ex_system_memory_space_handler (
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_io_space_handler
@@ -279,39 +275,35 @@ acpi_ex_system_memory_space_handler (
******************************************************************************/
acpi_status
-acpi_ex_system_io_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ex_system_io_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
- u32 value32;
+ acpi_status status = AE_OK;
+ u32 value32;
+ ACPI_FUNCTION_TRACE("ex_system_io_space_handler");
- ACPI_FUNCTION_TRACE ("ex_system_io_space_handler");
-
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
- ACPI_FORMAT_UINT64 (address)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "system_iO %d (%d width) Address=%8.8X%8.8X\n",
+ function, bit_width, ACPI_FORMAT_UINT64(address)));
/* Decode the function parameter */
switch (function) {
case ACPI_READ:
- status = acpi_os_read_port ((acpi_io_address) address,
- &value32, bit_width);
+ status = acpi_os_read_port((acpi_io_address) address,
+ &value32, bit_width);
*value = value32;
break;
case ACPI_WRITE:
- status = acpi_os_write_port ((acpi_io_address) address,
- (u32) *value, bit_width);
+ status = acpi_os_write_port((acpi_io_address) address,
+ (u32) * value, bit_width);
break;
default:
@@ -319,10 +311,9 @@ acpi_ex_system_io_space_handler (
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_pci_config_space_handler
@@ -342,21 +333,17 @@ acpi_ex_system_io_space_handler (
******************************************************************************/
acpi_status
-acpi_ex_pci_config_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ex_pci_config_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
- struct acpi_pci_id *pci_id;
- u16 pci_register;
-
-
- ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler");
+ acpi_status status = AE_OK;
+ struct acpi_pci_id *pci_id;
+ u16 pci_register;
+ ACPI_FUNCTION_TRACE("ex_pci_config_space_handler");
/*
* The arguments to acpi_os(Read|Write)pci_configuration are:
@@ -370,26 +357,26 @@ acpi_ex_pci_config_space_handler (
* Value - input value for write, output address for read
*
*/
- pci_id = (struct acpi_pci_id *) region_context;
+ pci_id = (struct acpi_pci_id *)region_context;
pci_register = (u16) (u32) address;
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
- function, bit_width, pci_id->segment, pci_id->bus, pci_id->device,
- pci_id->function, pci_register));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
+ function, bit_width, pci_id->segment, pci_id->bus,
+ pci_id->device, pci_id->function, pci_register));
switch (function) {
case ACPI_READ:
*value = 0;
- status = acpi_os_read_pci_configuration (pci_id, pci_register,
- value, bit_width);
+ status = acpi_os_read_pci_configuration(pci_id, pci_register,
+ value, bit_width);
break;
case ACPI_WRITE:
- status = acpi_os_write_pci_configuration (pci_id, pci_register,
- *value, bit_width);
+ status = acpi_os_write_pci_configuration(pci_id, pci_register,
+ *value, bit_width);
break;
default:
@@ -398,10 +385,9 @@ acpi_ex_pci_config_space_handler (
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_cmos_space_handler
@@ -421,24 +407,19 @@ acpi_ex_pci_config_space_handler (
******************************************************************************/
acpi_status
-acpi_ex_cmos_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ex_cmos_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
-
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE ("ex_cmos_space_handler");
+ ACPI_FUNCTION_TRACE("ex_cmos_space_handler");
-
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_pci_bar_space_handler
@@ -458,24 +439,19 @@ acpi_ex_cmos_space_handler (
******************************************************************************/
acpi_status
-acpi_ex_pci_bar_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ex_pci_bar_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
-
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler");
+ ACPI_FUNCTION_TRACE("ex_pci_bar_space_handler");
-
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_data_table_space_handler
@@ -495,24 +471,20 @@ acpi_ex_pci_bar_space_handler (
******************************************************************************/
acpi_status
-acpi_ex_data_table_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context)
+acpi_ex_data_table_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
- u32 byte_width = ACPI_DIV_8 (bit_width);
- u32 i;
- char *logical_addr_ptr;
-
+ acpi_status status = AE_OK;
+ u32 byte_width = ACPI_DIV_8(bit_width);
+ u32 i;
+ char *logical_addr_ptr;
- ACPI_FUNCTION_TRACE ("ex_data_table_space_handler");
+ ACPI_FUNCTION_TRACE("ex_data_table_space_handler");
-
- logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
+ logical_addr_ptr = ACPI_PHYSADDR_TO_PTR(address);
/* Perform the memory read or write */
@@ -520,17 +492,15 @@ acpi_ex_data_table_space_handler (
case ACPI_READ:
for (i = 0; i < byte_width; i++) {
- ((char *) value) [i] = logical_addr_ptr[i];
+ ((char *)value)[i] = logical_addr_ptr[i];
}
break;
case ACPI_WRITE:
default:
- return_ACPI_STATUS (AE_SUPPORT);
+ return_ACPI_STATUS(AE_SUPPORT);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index 21d5c74fa309..ff5d8f97e8eb 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
@@ -50,10 +49,8 @@
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exresnte")
-
+ACPI_MODULE_NAME("exresnte")
/*******************************************************************************
*
@@ -80,41 +77,37 @@
* ACPI_TYPE_PACKAGE
*
******************************************************************************/
-
acpi_status
-acpi_ex_resolve_node_to_value (
- struct acpi_namespace_node **object_ptr,
- struct acpi_walk_state *walk_state)
-
+acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *source_desc;
- union acpi_operand_object *obj_desc = NULL;
- struct acpi_namespace_node *node;
- acpi_object_type entry_type;
-
-
- ACPI_FUNCTION_TRACE ("ex_resolve_node_to_value");
+ acpi_status status = AE_OK;
+ union acpi_operand_object *source_desc;
+ union acpi_operand_object *obj_desc = NULL;
+ struct acpi_namespace_node *node;
+ acpi_object_type entry_type;
+ ACPI_FUNCTION_TRACE("ex_resolve_node_to_value");
/*
* The stack pointer points to a struct acpi_namespace_node (Node). Get the
* object that is attached to the Node.
*/
- node = *object_ptr;
- source_desc = acpi_ns_get_attached_object (node);
- entry_type = acpi_ns_get_type ((acpi_handle) node);
+ node = *object_ptr;
+ source_desc = acpi_ns_get_attached_object(node);
+ entry_type = acpi_ns_get_type((acpi_handle) node);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p source_desc=%p [%s]\n",
- node, source_desc, acpi_ut_get_type_name (entry_type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p source_desc=%p [%s]\n",
+ node, source_desc,
+ acpi_ut_get_type_name(entry_type)));
if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) ||
- (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
+ (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
/* There is always exactly one level of indirection */
- node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
- source_desc = acpi_ns_get_attached_object (node);
- entry_type = acpi_ns_get_type ((acpi_handle) node);
+ node = ACPI_CAST_PTR(struct acpi_namespace_node, node->object);
+ source_desc = acpi_ns_get_attached_object(node);
+ entry_type = acpi_ns_get_type((acpi_handle) node);
*object_ptr = node;
}
@@ -124,14 +117,14 @@ acpi_ex_resolve_node_to_value (
* 2) Method locals and arguments have a pseudo-Node
*/
if (entry_type == ACPI_TYPE_DEVICE ||
- (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
- return_ACPI_STATUS (AE_OK);
+ (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
+ return_ACPI_STATUS(AE_OK);
}
if (!source_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object attached to node %p\n",
- node));
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No object attached to node %p\n", node));
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
/*
@@ -141,83 +134,89 @@ acpi_ex_resolve_node_to_value (
switch (entry_type) {
case ACPI_TYPE_PACKAGE:
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_PACKAGE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n",
- acpi_ut_get_object_type_name (source_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Object not a Package, type %s\n",
+ acpi_ut_get_object_type_name
+ (source_desc)));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
- status = acpi_ds_get_package_arguments (source_desc);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ds_get_package_arguments(source_desc);
+ if (ACPI_SUCCESS(status)) {
/* Return an additional reference to the object */
obj_desc = source_desc;
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
}
break;
-
case ACPI_TYPE_BUFFER:
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n",
- acpi_ut_get_object_type_name (source_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Object not a Buffer, type %s\n",
+ acpi_ut_get_object_type_name
+ (source_desc)));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
- status = acpi_ds_get_buffer_arguments (source_desc);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ds_get_buffer_arguments(source_desc);
+ if (ACPI_SUCCESS(status)) {
/* Return an additional reference to the object */
obj_desc = source_desc;
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
}
break;
-
case ACPI_TYPE_STRING:
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n",
- acpi_ut_get_object_type_name (source_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Object not a String, type %s\n",
+ acpi_ut_get_object_type_name
+ (source_desc)));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* Return an additional reference to the object */
obj_desc = source_desc;
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
break;
-
case ACPI_TYPE_INTEGER:
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n",
- acpi_ut_get_object_type_name (source_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Object not a Integer, type %s\n",
+ acpi_ut_get_object_type_name
+ (source_desc)));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* Return an additional reference to the object */
obj_desc = source_desc;
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
break;
-
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "field_read Node=%p source_desc=%p Type=%X\n",
- node, source_desc, entry_type));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "field_read Node=%p source_desc=%p Type=%X\n",
+ node, source_desc, entry_type));
- status = acpi_ex_read_data_from_field (walk_state, source_desc, &obj_desc);
+ status =
+ acpi_ex_read_data_from_field(walk_state, source_desc,
+ &obj_desc);
break;
- /* For these objects, just return the object attached to the Node */
+ /* For these objects, just return the object attached to the Node */
case ACPI_TYPE_MUTEX:
case ACPI_TYPE_METHOD:
@@ -230,19 +229,18 @@ acpi_ex_resolve_node_to_value (
/* Return an additional reference to the object */
obj_desc = source_desc;
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
break;
- /* TYPE_ANY is untyped, and thus there is no object associated with it */
+ /* TYPE_ANY is untyped, and thus there is no object associated with it */
case ACPI_TYPE_ANY:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Untyped entry %p, no attached object!\n",
- node));
-
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Untyped entry %p, no attached object!\n",
+ node));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
case ACPI_TYPE_LOCAL_REFERENCE:
@@ -253,39 +251,37 @@ acpi_ex_resolve_node_to_value (
/* Return an additional reference to the object */
obj_desc = source_desc;
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
break;
default:
/* No named references are allowed here */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unsupported Reference opcode %X (%s)\n",
- source_desc->reference.opcode,
- acpi_ps_get_opcode_name (source_desc->reference.opcode)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unsupported Reference opcode %X (%s)\n",
+ source_desc->reference.opcode,
+ acpi_ps_get_opcode_name(source_desc->
+ reference.
+ opcode)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
break;
-
default:
/* Default case is for unknown types */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Node %p - Unknown object type %X\n",
- node, entry_type));
-
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Node %p - Unknown object type %X\n",
+ node, entry_type));
- } /* switch (entry_type) */
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+ } /* switch (entry_type) */
/* Return the object descriptor */
- *object_ptr = (void *) obj_desc;
- return_ACPI_STATUS (status);
+ *object_ptr = (void *)obj_desc;
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 3de45672379a..97eecbd3242d 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/amlcode.h>
#include <acpi/acdispat.h>
@@ -50,17 +49,13 @@
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exresolv")
+ACPI_MODULE_NAME("exresolv")
/* Local prototypes */
-
static acpi_status
-acpi_ex_resolve_object_to_value (
- union acpi_operand_object **stack_ptr,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
+ struct acpi_walk_state *walk_state);
/*******************************************************************************
*
@@ -78,19 +73,16 @@ acpi_ex_resolve_object_to_value (
******************************************************************************/
acpi_status
-acpi_ex_resolve_to_value (
- union acpi_operand_object **stack_ptr,
- struct acpi_walk_state *walk_state)
+acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_resolve_to_value", stack_ptr);
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ex_resolve_to_value", stack_ptr);
if (!stack_ptr || !*stack_ptr) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Internal - null pointer\n"));
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
/*
@@ -98,15 +90,16 @@ acpi_ex_resolve_to_value (
* 1) A valid union acpi_operand_object, or
* 2) A struct acpi_namespace_node (named_obj)
*/
- if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
- status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
+ status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (!*stack_ptr) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Internal - null pointer\n"));
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
}
@@ -114,20 +107,20 @@ acpi_ex_resolve_to_value (
* Object on the stack may have changed if acpi_ex_resolve_object_to_value()
* was called (i.e., we can't use an _else_ here.)
*/
- if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
- status = acpi_ex_resolve_node_to_value (
- ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, stack_ptr),
- walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
+ status =
+ acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
+ (struct acpi_namespace_node,
+ stack_ptr), walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_resolve_object_to_value
@@ -143,25 +136,22 @@ acpi_ex_resolve_to_value (
******************************************************************************/
static acpi_status
-acpi_ex_resolve_object_to_value (
- union acpi_operand_object **stack_ptr,
- struct acpi_walk_state *walk_state)
+acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *stack_desc;
- void *temp_node;
- union acpi_operand_object *obj_desc;
- u16 opcode;
-
-
- ACPI_FUNCTION_TRACE ("ex_resolve_object_to_value");
+ acpi_status status = AE_OK;
+ union acpi_operand_object *stack_desc;
+ void *temp_node;
+ union acpi_operand_object *obj_desc;
+ u16 opcode;
+ ACPI_FUNCTION_TRACE("ex_resolve_object_to_value");
stack_desc = *stack_ptr;
/* This is an union acpi_operand_object */
- switch (ACPI_GET_OBJECT_TYPE (stack_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE:
opcode = stack_desc->reference.opcode;
@@ -177,14 +167,13 @@ acpi_ex_resolve_object_to_value (
/* Delete the Reference Object */
- acpi_ut_remove_reference (stack_desc);
+ acpi_ut_remove_reference(stack_desc);
/* Return the namespace node */
(*stack_ptr) = temp_node;
break;
-
case AML_LOCAL_OP:
case AML_ARG_OP:
@@ -192,24 +181,28 @@ acpi_ex_resolve_object_to_value (
* Get the local from the method's state info
* Note: this increments the local's object reference count
*/
- status = acpi_ds_method_data_get_value (opcode,
- stack_desc->reference.offset, walk_state, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_method_data_get_value(opcode,
+ stack_desc->
+ reference.offset,
+ walk_state,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] value_obj is %p\n",
- stack_desc->reference.offset, obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Arg/Local %X] value_obj is %p\n",
+ stack_desc->reference.offset,
+ obj_desc));
/*
* Now we can delete the original Reference Object and
* replace it with the resolved value
*/
- acpi_ut_remove_reference (stack_desc);
+ acpi_ut_remove_reference(stack_desc);
*stack_ptr = obj_desc;
break;
-
case AML_INDEX_OP:
switch (stack_desc->reference.target_type) {
@@ -218,7 +211,6 @@ acpi_ex_resolve_object_to_value (
/* Just return - leave the Reference on the stack */
break;
-
case ACPI_TYPE_PACKAGE:
obj_desc = *stack_desc->reference.where;
@@ -228,36 +220,31 @@ acpi_ex_resolve_object_to_value (
* (i.e., dereference the package index)
* Delete the ref object, increment the returned object
*/
- acpi_ut_remove_reference (stack_desc);
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_remove_reference(stack_desc);
+ acpi_ut_add_reference(obj_desc);
*stack_ptr = obj_desc;
- }
- else {
+ } else {
/*
* A NULL object descriptor means an unitialized element of
* the package, can't dereference it
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Attempt to deref an Index to NULL pkg element Idx=%p\n",
- stack_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Attempt to deref an Index to NULL pkg element Idx=%p\n",
+ stack_desc));
status = AE_AML_UNINITIALIZED_ELEMENT;
}
break;
-
default:
/* Invalid reference object */
- ACPI_REPORT_ERROR ((
- "During resolve, Unknown target_type %X in Index/Reference obj %p\n",
- stack_desc->reference.target_type, stack_desc));
+ ACPI_REPORT_ERROR(("During resolve, Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc));
status = AE_AML_INTERNAL;
break;
}
break;
-
case AML_REF_OF_OP:
case AML_DEBUG_OP:
case AML_LOAD_OP:
@@ -266,60 +253,58 @@ acpi_ex_resolve_object_to_value (
break;
- case AML_INT_NAMEPATH_OP: /* Reference to a named object */
+ case AML_INT_NAMEPATH_OP: /* Reference to a named object */
/* Get the object pointed to by the namespace node */
*stack_ptr = (stack_desc->reference.node)->object;
- acpi_ut_add_reference (*stack_ptr);
- acpi_ut_remove_reference (stack_desc);
+ acpi_ut_add_reference(*stack_ptr);
+ acpi_ut_remove_reference(stack_desc);
break;
default:
- ACPI_REPORT_ERROR ((
- "During resolve, Unknown Reference opcode %X (%s) in %p\n",
- opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
+ ACPI_REPORT_ERROR(("During resolve, Unknown Reference opcode %X (%s) in %p\n", opcode, acpi_ps_get_opcode_name(opcode), stack_desc));
status = AE_AML_INTERNAL;
break;
}
break;
-
case ACPI_TYPE_BUFFER:
- status = acpi_ds_get_buffer_arguments (stack_desc);
+ status = acpi_ds_get_buffer_arguments(stack_desc);
break;
-
case ACPI_TYPE_PACKAGE:
- status = acpi_ds_get_package_arguments (stack_desc);
+ status = acpi_ds_get_package_arguments(stack_desc);
break;
-
- /* These cases may never happen here, but just in case.. */
+ /* These cases may never happen here, but just in case.. */
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read source_desc=%p Type=%X\n",
- stack_desc, ACPI_GET_OBJECT_TYPE (stack_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "field_read source_desc=%p Type=%X\n",
+ stack_desc,
+ ACPI_GET_OBJECT_TYPE(stack_desc)));
- status = acpi_ex_read_data_from_field (walk_state, stack_desc, &obj_desc);
- *stack_ptr = (void *) obj_desc;
+ status =
+ acpi_ex_read_data_from_field(walk_state, stack_desc,
+ &obj_desc);
+ *stack_ptr = (void *)obj_desc;
break;
default:
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_resolve_multiple
@@ -337,42 +322,44 @@ acpi_ex_resolve_object_to_value (
******************************************************************************/
acpi_status
-acpi_ex_resolve_multiple (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *operand,
- acpi_object_type *return_type,
- union acpi_operand_object **return_desc)
+acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *operand,
+ acpi_object_type * return_type,
+ union acpi_operand_object **return_desc)
{
- union acpi_operand_object *obj_desc = (void *) operand;
- struct acpi_namespace_node *node;
- acpi_object_type type;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
+ union acpi_operand_object *obj_desc = (void *)operand;
+ struct acpi_namespace_node *node;
+ acpi_object_type type;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_ex_resolve_multiple");
/* Operand can be either a namespace node or an operand descriptor */
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+ switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
type = obj_desc->common.type;
break;
case ACPI_DESC_TYPE_NAMED:
- type = ((struct acpi_namespace_node *) obj_desc)->type;
- obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
+ type = ((struct acpi_namespace_node *)obj_desc)->type;
+ obj_desc =
+ acpi_ns_get_attached_object((struct acpi_namespace_node *)
+ obj_desc);
/* If we had an Alias node, use the attached object for type info */
if (type == ACPI_TYPE_LOCAL_ALIAS) {
- type = ((struct acpi_namespace_node *) obj_desc)->type;
- obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
+ type = ((struct acpi_namespace_node *)obj_desc)->type;
+ obj_desc =
+ acpi_ns_get_attached_object((struct
+ acpi_namespace_node *)
+ obj_desc);
}
break;
default:
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* If type is anything other than a reference, we are done */
@@ -387,7 +374,7 @@ acpi_ex_resolve_multiple (
* of the object_type and size_of operators). This means traversing
* the list of possibly many nested references.
*/
- while (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+ while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
switch (obj_desc->reference.opcode) {
case AML_REF_OF_OP:
@@ -397,31 +384,29 @@ acpi_ex_resolve_multiple (
/* All "References" point to a NS node */
- if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
- ACPI_REPORT_ERROR ((
- "acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
- node, acpi_ut_get_descriptor_name (node)));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
+ ACPI_DESC_TYPE_NAMED) {
+ ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node)));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/* Get the attached object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
/* No object, use the NS node type */
- type = acpi_ns_get_type (node);
+ type = acpi_ns_get_type(node);
goto exit;
}
/* Check for circular references */
if (obj_desc == operand) {
- return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
+ return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
}
break;
-
case AML_INDEX_OP:
/* Get the type of this reference (index into another object) */
@@ -442,12 +427,11 @@ acpi_ex_resolve_multiple (
if (!obj_desc) {
/* NULL package elements are allowed */
- type = 0; /* Uninitialized */
+ type = 0; /* Uninitialized */
goto exit;
}
break;
-
case AML_INT_NAMEPATH_OP:
/* Dereference the reference pointer */
@@ -456,50 +440,61 @@ acpi_ex_resolve_multiple (
/* All "References" point to a NS node */
- if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
- ACPI_REPORT_ERROR ((
- "acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
- node, acpi_ut_get_descriptor_name (node)));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
+ ACPI_DESC_TYPE_NAMED) {
+ ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node)));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/* Get the attached object */
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
/* No object, use the NS node type */
- type = acpi_ns_get_type (node);
+ type = acpi_ns_get_type(node);
goto exit;
}
/* Check for circular references */
if (obj_desc == operand) {
- return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
+ return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
}
break;
-
case AML_LOCAL_OP:
case AML_ARG_OP:
if (return_desc) {
- status = acpi_ds_method_data_get_value (obj_desc->reference.opcode,
- obj_desc->reference.offset, walk_state, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ds_method_data_get_value(obj_desc->
+ reference.
+ opcode,
+ obj_desc->
+ reference.
+ offset,
+ walk_state,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- acpi_ut_remove_reference (obj_desc);
- }
- else {
- status = acpi_ds_method_data_get_node (obj_desc->reference.opcode,
- obj_desc->reference.offset, walk_state, &node);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ } else {
+ status =
+ acpi_ds_method_data_get_node(obj_desc->
+ reference.
+ opcode,
+ obj_desc->
+ reference.
+ offset,
+ walk_state,
+ &node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- obj_desc = acpi_ns_get_attached_object (node);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
type = ACPI_TYPE_ANY;
goto exit;
@@ -507,7 +502,6 @@ acpi_ex_resolve_multiple (
}
break;
-
case AML_DEBUG_OP:
/* The Debug Object is of type "debug_object" */
@@ -515,13 +509,10 @@ acpi_ex_resolve_multiple (
type = ACPI_TYPE_DEBUG_OBJECT;
goto exit;
-
default:
- ACPI_REPORT_ERROR ((
- "acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
- obj_desc->reference.opcode));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n", obj_desc->reference.opcode));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
}
@@ -529,10 +520,9 @@ acpi_ex_resolve_multiple (
* Now we are guaranteed to have an object that has not been created
* via the ref_of or Index operators.
*/
- type = ACPI_GET_OBJECT_TYPE (obj_desc);
+ type = ACPI_GET_OBJECT_TYPE(obj_desc);
-
-exit:
+ exit:
/* Convert internal types to external types */
switch (type) {
@@ -559,7 +549,5 @@ exit:
if (return_desc) {
*return_desc = obj_desc;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index d8b470eefe7a..ff064e79ab90 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -42,24 +42,18 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/amlcode.h>
#include <acpi/acparser.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exresop")
+ACPI_MODULE_NAME("exresop")
/* Local prototypes */
-
static acpi_status
-acpi_ex_check_object_type (
- acpi_object_type type_needed,
- acpi_object_type this_type,
- void *object);
-
+acpi_ex_check_object_type(acpi_object_type type_needed,
+ acpi_object_type this_type, void *object);
/*******************************************************************************
*
@@ -76,13 +70,10 @@ acpi_ex_check_object_type (
******************************************************************************/
static acpi_status
-acpi_ex_check_object_type (
- acpi_object_type type_needed,
- acpi_object_type this_type,
- void *object)
+acpi_ex_check_object_type(acpi_object_type type_needed,
+ acpi_object_type this_type, void *object)
{
- ACPI_FUNCTION_NAME ("ex_check_object_type");
-
+ ACPI_FUNCTION_NAME("ex_check_object_type");
if (type_needed == ACPI_TYPE_ANY) {
/* All types OK, so we don't perform any typechecks */
@@ -97,16 +88,17 @@ acpi_ex_check_object_type (
* specification, a store to a constant is a noop.)
*/
if ((this_type == ACPI_TYPE_INTEGER) &&
- (((union acpi_operand_object *) object)->common.flags & AOPOBJ_AML_CONSTANT)) {
+ (((union acpi_operand_object *)object)->common.
+ flags & AOPOBJ_AML_CONSTANT)) {
return (AE_OK);
}
}
if (type_needed != this_type) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [%s], found [%s] %p\n",
- acpi_ut_get_type_name (type_needed),
- acpi_ut_get_type_name (this_type), object));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [%s], found [%s] %p\n",
+ acpi_ut_get_type_name(type_needed),
+ acpi_ut_get_type_name(this_type), object));
return (AE_AML_OPERAND_TYPE);
}
@@ -114,7 +106,6 @@ acpi_ex_check_object_type (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_resolve_operands
@@ -137,41 +128,37 @@ acpi_ex_check_object_type (
******************************************************************************/
acpi_status
-acpi_ex_resolve_operands (
- u16 opcode,
- union acpi_operand_object **stack_ptr,
- struct acpi_walk_state *walk_state)
+acpi_ex_resolve_operands(u16 opcode,
+ union acpi_operand_object ** stack_ptr,
+ struct acpi_walk_state * walk_state)
{
- union acpi_operand_object *obj_desc;
- acpi_status status = AE_OK;
- u8 object_type;
- void *temp_node;
- u32 arg_types;
- const struct acpi_opcode_info *op_info;
- u32 this_arg_type;
- acpi_object_type type_needed;
- u16 target_op = 0;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ex_resolve_operands", opcode);
-
-
- op_info = acpi_ps_get_opcode_info (opcode);
+ union acpi_operand_object *obj_desc;
+ acpi_status status = AE_OK;
+ u8 object_type;
+ void *temp_node;
+ u32 arg_types;
+ const struct acpi_opcode_info *op_info;
+ u32 this_arg_type;
+ acpi_object_type type_needed;
+ u16 target_op = 0;
+
+ ACPI_FUNCTION_TRACE_U32("ex_resolve_operands", opcode);
+
+ op_info = acpi_ps_get_opcode_info(opcode);
if (op_info->class == AML_CLASS_UNKNOWN) {
- return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ return_ACPI_STATUS(AE_AML_BAD_OPCODE);
}
arg_types = op_info->runtime_args;
if (arg_types == ARGI_INVALID_OPCODE) {
- ACPI_REPORT_ERROR (("resolve_operands: %X is not a valid AML opcode\n",
- opcode));
+ ACPI_REPORT_ERROR(("resolve_operands: %X is not a valid AML opcode\n", opcode));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Opcode %X [%s] required_operand_types=%8.8X \n",
- opcode, op_info->name, arg_types));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Opcode %X [%s] required_operand_types=%8.8X \n",
+ opcode, op_info->name, arg_types));
/*
* Normal exit is with (arg_types == 0) at end of argument list.
@@ -180,12 +167,11 @@ acpi_ex_resolve_operands (
* to) the required type; if stack underflows; or upon
* finding a NULL stack entry (which should not happen).
*/
- while (GET_CURRENT_ARG_TYPE (arg_types)) {
+ while (GET_CURRENT_ARG_TYPE(arg_types)) {
if (!stack_ptr || !*stack_ptr) {
- ACPI_REPORT_ERROR (("resolve_operands: Null stack entry at %p\n",
- stack_ptr));
+ ACPI_REPORT_ERROR(("resolve_operands: Null stack entry at %p\n", stack_ptr));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/* Extract useful items */
@@ -194,37 +180,37 @@ acpi_ex_resolve_operands (
/* Decode the descriptor type */
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+ switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_NAMED:
/* Namespace Node */
- object_type = ((struct acpi_namespace_node *) obj_desc)->type;
+ object_type =
+ ((struct acpi_namespace_node *)obj_desc)->type;
break;
-
case ACPI_DESC_TYPE_OPERAND:
/* ACPI internal object */
- object_type = ACPI_GET_OBJECT_TYPE (obj_desc);
+ object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
/* Check for bad acpi_object_type */
- if (!acpi_ut_valid_object_type (object_type)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Bad operand object type [%X]\n",
- object_type));
+ if (!acpi_ut_valid_object_type(object_type)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Bad operand object type [%X]\n",
+ object_type));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
/* Decode the Reference */
- op_info = acpi_ps_get_opcode_info (opcode);
+ op_info = acpi_ps_get_opcode_info(opcode);
if (op_info->class == AML_CLASS_UNKNOWN) {
- return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ return_ACPI_STATUS(AE_AML_BAD_OPCODE);
}
switch (obj_desc->reference.opcode) {
@@ -238,51 +224,62 @@ acpi_ex_resolve_operands (
case AML_REF_OF_OP:
case AML_ARG_OP:
case AML_LOCAL_OP:
- case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
- case AML_INT_NAMEPATH_OP: /* Reference to a named object */
-
- ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Operand is a Reference, ref_opcode [%s]\n",
- (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)));
+ case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+ case AML_INT_NAMEPATH_OP: /* Reference to a named object */
+
+ ACPI_DEBUG_ONLY_MEMBERS(ACPI_DEBUG_PRINT
+ ((ACPI_DB_EXEC,
+ "Operand is a Reference, ref_opcode [%s]\n",
+ (acpi_ps_get_opcode_info
+ (obj_desc->
+ reference.
+ opcode))->
+ name)));
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Operand is a Reference, Unknown Reference Opcode %X [%s]\n",
- obj_desc->reference.opcode,
- (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name));
-
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Operand is a Reference, Unknown Reference Opcode %X [%s]\n",
+ obj_desc->reference.
+ opcode,
+ (acpi_ps_get_opcode_info
+ (obj_desc->reference.
+ opcode))->name));
+
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
}
break;
-
default:
/* Invalid descriptor */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid descriptor %p [%s]\n",
- obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid descriptor %p [%s]\n",
+ obj_desc,
+ acpi_ut_get_descriptor_name
+ (obj_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* Get one argument type, point to the next */
- this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
- INCREMENT_ARG_LIST (arg_types);
+ this_arg_type = GET_CURRENT_ARG_TYPE(arg_types);
+ INCREMENT_ARG_LIST(arg_types);
/*
* Handle cases where the object does not need to be
* resolved to a value
*/
switch (this_arg_type) {
- case ARGI_REF_OR_STRING: /* Can be a String or Reference */
+ case ARGI_REF_OR_STRING: /* Can be a String or Reference */
- if ((ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) &&
- (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_STRING)) {
+ if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
+ ACPI_DESC_TYPE_OPERAND)
+ && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
+ ACPI_TYPE_STRING)) {
/*
* String found - the string references a named object and
* must be resolved to a node
@@ -296,39 +293,40 @@ acpi_ex_resolve_operands (
*/
/*lint -fallthrough */
- case ARGI_REFERENCE: /* References: */
+ case ARGI_REFERENCE: /* References: */
case ARGI_INTEGER_REF:
case ARGI_OBJECT_REF:
case ARGI_DEVICE_REF:
- case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
- case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
- case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
+ case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
+ case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
+ case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
/*
* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
* A Namespace Node is OK as-is
*/
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
+ ACPI_DESC_TYPE_NAMED) {
goto next_operand;
}
- status = acpi_ex_check_object_type (ACPI_TYPE_LOCAL_REFERENCE,
- object_type, obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE,
+ object_type, obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (obj_desc->reference.opcode == AML_NAME_OP) {
/* Convert a named reference to the actual named object */
temp_node = obj_desc->reference.object;
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
(*stack_ptr) = temp_node;
}
goto next_operand;
-
- case ARGI_DATAREFOBJ: /* Store operator only */
+ case ARGI_DATAREFOBJ: /* Store operator only */
/*
* We don't want to resolve index_op reference objects during
@@ -337,8 +335,10 @@ acpi_ex_resolve_operands (
* -- All others must be resolved below.
*/
if ((opcode == AML_STORE_OP) &&
- (ACPI_GET_OBJECT_TYPE (*stack_ptr) == ACPI_TYPE_LOCAL_REFERENCE) &&
- ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
+ (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+ ACPI_TYPE_LOCAL_REFERENCE)
+ && ((*stack_ptr)->reference.opcode ==
+ AML_INDEX_OP)) {
goto next_operand;
}
break;
@@ -351,9 +351,9 @@ acpi_ex_resolve_operands (
/*
* Resolve this object to a value
*/
- status = acpi_ex_resolve_to_value (stack_ptr, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_resolve_to_value(stack_ptr, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the resolved object */
@@ -364,10 +364,10 @@ acpi_ex_resolve_operands (
* Check the resulting object (value) type
*/
switch (this_arg_type) {
- /*
- * For the simple cases, only one type of resolved object
- * is allowed
- */
+ /*
+ * For the simple cases, only one type of resolved object
+ * is allowed
+ */
case ARGI_MUTEX:
/* Need an operand of type ACPI_TYPE_MUTEX */
@@ -382,7 +382,7 @@ acpi_ex_resolve_operands (
type_needed = ACPI_TYPE_EVENT;
break;
- case ARGI_PACKAGE: /* Package */
+ case ARGI_PACKAGE: /* Package */
/* Need an operand of type ACPI_TYPE_PACKAGE */
@@ -403,10 +403,9 @@ acpi_ex_resolve_operands (
type_needed = ACPI_TYPE_LOCAL_REFERENCE;
break;
-
- /*
- * The more complex cases allow multiple resolved object types
- */
+ /*
+ * The more complex cases allow multiple resolved object types
+ */
case ARGI_INTEGER:
/*
@@ -414,20 +413,26 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a STRING or BUFFER
* Aka - "Implicit Source Operand Conversion"
*/
- status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, 16);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16);
+ if (ACPI_FAILURE(status)) {
if (status == AE_TYPE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Integer/String/Buffer], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Integer/String/Buffer], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc),
+ obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
- goto next_operand;
+ if (obj_desc != *stack_ptr) {
+ acpi_ut_remove_reference(obj_desc);
+ }
+ goto next_operand;
case ARGI_BUFFER:
@@ -436,20 +441,25 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a STRING or INTEGER
* Aka - "Implicit Source Operand Conversion"
*/
- status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);
+ if (ACPI_FAILURE(status)) {
if (status == AE_TYPE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Integer/String/Buffer], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Integer/String/Buffer], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc),
+ obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
- goto next_operand;
+ if (obj_desc != *stack_ptr) {
+ acpi_ut_remove_reference(obj_desc);
+ }
+ goto next_operand;
case ARGI_STRING:
@@ -458,75 +468,86 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a BUFFER or INTEGER
* Aka - "Implicit Source Operand Conversion"
*/
- status = acpi_ex_convert_to_string (obj_desc, stack_ptr,
- ACPI_IMPLICIT_CONVERT_HEX);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_convert_to_string(obj_desc, stack_ptr,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ if (ACPI_FAILURE(status)) {
if (status == AE_TYPE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Integer/String/Buffer], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Integer/String/Buffer], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc),
+ obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
- goto next_operand;
+ if (obj_desc != *stack_ptr) {
+ acpi_ut_remove_reference(obj_desc);
+ }
+ goto next_operand;
case ARGI_COMPUTEDATA:
/* Need an operand of type INTEGER, STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
/* Valid operand */
- break;
+ break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Integer/String/Buffer], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Integer/String/Buffer], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc), obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
goto next_operand;
-
case ARGI_BUFFER_OR_STRING:
/* Need an operand of type STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
/* Valid operand */
- break;
+ break;
case ACPI_TYPE_INTEGER:
/* Highest priority conversion is to type Buffer */
- status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_convert_to_buffer(obj_desc,
+ stack_ptr);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (obj_desc != *stack_ptr) {
+ acpi_ut_remove_reference(obj_desc);
}
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Integer/String/Buffer], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Integer/String/Buffer], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc), obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
goto next_operand;
-
case ARGI_DATAOBJECT:
/*
* ARGI_DATAOBJECT is only used by the size_of operator.
@@ -535,7 +556,7 @@ acpi_ex_resolve_operands (
* The only reference allowed here is a direct reference to
* a namespace node.
*/
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -545,20 +566,20 @@ acpi_ex_resolve_operands (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Buffer/String/Package/Reference], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Buffer/String/Package/Reference], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc), obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
goto next_operand;
-
case ARGI_COMPLEXOBJ:
/* Need a buffer or package or (ACPI 2.0) String */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -567,20 +588,20 @@ acpi_ex_resolve_operands (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Buffer/String/Package], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Buffer/String/Package], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc), obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
goto next_operand;
-
case ARGI_REGION_OR_FIELD:
/* Need an operand of type REGION or a FIELD in a region */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_REGION:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
@@ -590,20 +611,20 @@ acpi_ex_resolve_operands (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed [Region/region_field], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed [Region/region_field], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc), obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
goto next_operand;
-
case ARGI_DATAREFOBJ:
/* Used by the Store() operator only */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
@@ -635,47 +656,46 @@ acpi_ex_resolve_operands (
break;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
- acpi_ut_get_object_type_name (obj_desc), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
+ acpi_ut_get_object_type_name
+ (obj_desc), obj_desc));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
goto next_operand;
-
default:
/* Unknown type */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Internal - Unknown ARGI (required operand) type %X\n",
- this_arg_type));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Internal - Unknown ARGI (required operand) type %X\n",
+ this_arg_type));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* Make sure that the original object was resolved to the
* required object type (Simple cases only).
*/
- status = acpi_ex_check_object_type (type_needed,
- ACPI_GET_OBJECT_TYPE (*stack_ptr), *stack_ptr);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_check_object_type(type_needed,
+ ACPI_GET_OBJECT_TYPE
+ (*stack_ptr), *stack_ptr);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
-next_operand:
+ next_operand:
/*
* If more operands needed, decrement stack_ptr to point
* to next operand on stack
*/
- if (GET_CURRENT_ARG_TYPE (arg_types)) {
+ if (GET_CURRENT_ARG_TYPE(arg_types)) {
stack_ptr--;
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index 2725db0901b8..a7d8eea305c2 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
@@ -50,24 +49,18 @@
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exstore")
+ACPI_MODULE_NAME("exstore")
/* Local prototypes */
-
static void
-acpi_ex_do_debug_object (
- union acpi_operand_object *source_desc,
- u32 level,
- u32 index);
+acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
+ u32 level, u32 index);
static acpi_status
-acpi_ex_store_object_to_index (
- union acpi_operand_object *val_desc,
- union acpi_operand_object *dest_desc,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
+ union acpi_operand_object *dest_desc,
+ struct acpi_walk_state *walk_state);
/*******************************************************************************
*
@@ -84,136 +77,146 @@ acpi_ex_store_object_to_index (
******************************************************************************/
static void
-acpi_ex_do_debug_object (
- union acpi_operand_object *source_desc,
- u32 level,
- u32 index)
+acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
+ u32 level, u32 index)
{
- u32 i;
-
+ u32 i;
- ACPI_FUNCTION_TRACE_PTR ("ex_do_debug_object", source_desc);
+ ACPI_FUNCTION_TRACE_PTR("ex_do_debug_object", source_desc);
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
- level, " "));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
+ level, " "));
/* Display index for package output only */
if (index > 0) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
- "(%.2u) ", index -1));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
+ "(%.2u) ", index - 1));
}
if (!source_desc) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n"));
return_VOID;
}
- if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_OPERAND) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: ",
- acpi_ut_get_object_type_name (source_desc)));
+ if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: ",
+ acpi_ut_get_object_type_name
+ (source_desc)));
- if (!acpi_ut_valid_internal_object (source_desc)) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
- "%p, Invalid Internal Object!\n", source_desc));
- return_VOID;
+ if (!acpi_ut_valid_internal_object(source_desc)) {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
+ "%p, Invalid Internal Object!\n",
+ source_desc));
+ return_VOID;
}
- }
- else if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_NAMED) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
- acpi_ut_get_type_name (((struct acpi_namespace_node *) source_desc)->type),
- source_desc));
+ } else if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) ==
+ ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
+ acpi_ut_get_type_name(((struct
+ acpi_namespace_node
+ *)source_desc)->
+ type),
+ source_desc));
return_VOID;
- }
- else {
+ } else {
return_VOID;
}
- switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
case ACPI_TYPE_INTEGER:
/* Output correct integer width */
if (acpi_gbl_integer_byte_width == 4) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
- (u32) source_desc->integer.value));
- }
- else {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (source_desc->integer.value)));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
+ (u32) source_desc->integer.
+ value));
+ } else {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
+ "0x%8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(source_desc->
+ integer.
+ value)));
}
break;
case ACPI_TYPE_BUFFER:
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
- (u32) source_desc->buffer.length));
- ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
- (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
+ (u32) source_desc->buffer.length));
+ ACPI_DUMP_BUFFER(source_desc->buffer.pointer,
+ (source_desc->buffer.length <
+ 32) ? source_desc->buffer.length : 32);
break;
case ACPI_TYPE_STRING:
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
- source_desc->string.length, source_desc->string.pointer));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
+ source_desc->string.length,
+ source_desc->string.pointer));
break;
case ACPI_TYPE_PACKAGE:
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X Elements]\n",
- source_desc->package.count));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
+ "[0x%.2X Elements]\n",
+ source_desc->package.count));
/* Output the entire contents of the package */
for (i = 0; i < source_desc->package.count; i++) {
- acpi_ex_do_debug_object (source_desc->package.elements[i],
- level+4, i+1);
+ acpi_ex_do_debug_object(source_desc->package.
+ elements[i], level + 4, i + 1);
}
break;
case ACPI_TYPE_LOCAL_REFERENCE:
if (source_desc->reference.opcode == AML_INDEX_OP) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s, 0x%X]\n",
- acpi_ps_get_opcode_name (source_desc->reference.opcode),
- source_desc->reference.offset));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
+ "[%s, 0x%X]\n",
+ acpi_ps_get_opcode_name
+ (source_desc->reference.opcode),
+ source_desc->reference.offset));
+ } else {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]\n",
+ acpi_ps_get_opcode_name
+ (source_desc->reference.opcode)));
}
- else {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s]\n",
- acpi_ps_get_opcode_name (source_desc->reference.opcode)));
- }
-
if (source_desc->reference.object) {
- if (ACPI_GET_DESCRIPTOR_TYPE (source_desc->reference.object) ==
- ACPI_DESC_TYPE_NAMED) {
- acpi_ex_do_debug_object (((struct acpi_namespace_node *)
- source_desc->reference.object)->object,
- level+4, 0);
+ if (ACPI_GET_DESCRIPTOR_TYPE
+ (source_desc->reference.object) ==
+ ACPI_DESC_TYPE_NAMED) {
+ acpi_ex_do_debug_object(((struct
+ acpi_namespace_node *)
+ source_desc->reference.
+ object)->object,
+ level + 4, 0);
+ } else {
+ acpi_ex_do_debug_object(source_desc->reference.
+ object, level + 4, 0);
}
- else {
- acpi_ex_do_debug_object (source_desc->reference.object, level+4, 0);
- }
- }
- else if (source_desc->reference.node) {
- acpi_ex_do_debug_object ((source_desc->reference.node)->object,
- level+4, 0);
+ } else if (source_desc->reference.node) {
+ acpi_ex_do_debug_object((source_desc->reference.node)->
+ object, level + 4, 0);
}
break;
default:
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
- source_desc, acpi_ut_get_object_type_name (source_desc)));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
+ source_desc,
+ acpi_ut_get_object_type_name
+ (source_desc)));
break;
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n"));
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_store
@@ -235,42 +238,41 @@ acpi_ex_do_debug_object (
******************************************************************************/
acpi_status
-acpi_ex_store (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *dest_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_store(union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *ref_desc = dest_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_store", dest_desc);
+ acpi_status status = AE_OK;
+ union acpi_operand_object *ref_desc = dest_desc;
+ ACPI_FUNCTION_TRACE_PTR("ex_store", dest_desc);
/* Validate parameters */
if (!source_desc || !dest_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n"));
- return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null parameter\n"));
+ return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
/* dest_desc can be either a namespace node or an ACPI object */
- if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
/*
* Dest is a namespace node,
* Storing an object into a Named node.
*/
- status = acpi_ex_store_object_to_node (source_desc,
- (struct acpi_namespace_node *) dest_desc, walk_state,
- ACPI_IMPLICIT_CONVERSION);
+ status = acpi_ex_store_object_to_node(source_desc,
+ (struct
+ acpi_namespace_node *)
+ dest_desc, walk_state,
+ ACPI_IMPLICIT_CONVERSION);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Destination object must be a Reference or a Constant object */
- switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE:
break;
@@ -279,7 +281,7 @@ acpi_ex_store (
/* Allow stores to Constants -- a Noop as per ACPI spec */
if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*lint -fallthrough */
@@ -288,16 +290,18 @@ acpi_ex_store (
/* Destination is not a Reference object */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Target is not a Reference or Constant object - %s [%p]\n",
- acpi_ut_get_object_type_name (dest_desc), dest_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Target is not a Reference or Constant object - %s [%p]\n",
+ acpi_ut_get_object_type_name(dest_desc),
+ dest_desc));
- ACPI_DUMP_STACK_ENTRY (source_desc);
- ACPI_DUMP_STACK_ENTRY (dest_desc);
- ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "ex_store",
- 2, "Target is not a Reference or Constant object");
+ ACPI_DUMP_STACK_ENTRY(source_desc);
+ ACPI_DUMP_STACK_ENTRY(dest_desc);
+ ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ex_store",
+ 2,
+ "Target is not a Reference or Constant object");
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/*
@@ -314,58 +318,59 @@ acpi_ex_store (
/* Storing an object into a Name "container" */
- status = acpi_ex_store_object_to_node (source_desc,
- ref_desc->reference.object,
- walk_state, ACPI_IMPLICIT_CONVERSION);
+ status = acpi_ex_store_object_to_node(source_desc,
+ ref_desc->reference.
+ object, walk_state,
+ ACPI_IMPLICIT_CONVERSION);
break;
-
case AML_INDEX_OP:
/* Storing to an Index (pointer into a packager or buffer) */
- status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state);
+ status =
+ acpi_ex_store_object_to_index(source_desc, ref_desc,
+ walk_state);
break;
-
case AML_LOCAL_OP:
case AML_ARG_OP:
/* Store to a method local/arg */
- status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
- ref_desc->reference.offset, source_desc, walk_state);
+ status =
+ acpi_ds_store_object_to_local(ref_desc->reference.opcode,
+ ref_desc->reference.offset,
+ source_desc, walk_state);
break;
-
case AML_DEBUG_OP:
/*
* Storing to the Debug object causes the value stored to be
* displayed and otherwise has no effect -- see ACPI Specification
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "**** Write to Debug Object: Object %p %s ****:\n\n",
- source_desc, acpi_ut_get_object_type_name (source_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "**** Write to Debug Object: Object %p %s ****:\n\n",
+ source_desc,
+ acpi_ut_get_object_type_name(source_desc)));
- acpi_ex_do_debug_object (source_desc, 0, 0);
+ acpi_ex_do_debug_object(source_desc, 0, 0);
break;
-
default:
- ACPI_REPORT_ERROR (("ex_store: Unknown Reference opcode %X\n",
- ref_desc->reference.opcode));
- ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR);
+ ACPI_REPORT_ERROR(("ex_store: Unknown Reference opcode %X\n",
+ ref_desc->reference.opcode));
+ ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR);
status = AE_AML_INTERNAL;
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_store_object_to_index
@@ -381,20 +386,17 @@ acpi_ex_store (
******************************************************************************/
static acpi_status
-acpi_ex_store_object_to_index (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *index_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
+ union acpi_operand_object *index_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *new_desc;
- u8 value = 0;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ex_store_object_to_index");
+ acpi_status status = AE_OK;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *new_desc;
+ u8 value = 0;
+ u32 i;
+ ACPI_FUNCTION_TRACE("ex_store_object_to_index");
/*
* Destination must be a reference pointer, and
@@ -413,19 +415,20 @@ acpi_ex_store_object_to_index (
*/
obj_desc = *(index_desc->reference.where);
- status = acpi_ut_copy_iobject_to_iobject (source_desc, &new_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (obj_desc) {
/* Decrement reference count by the ref count of the parent package */
- for (i = 0;
- i < ((union acpi_operand_object *)
- index_desc->reference.object)->common.reference_count;
- i++) {
- acpi_ut_remove_reference (obj_desc);
+ for (i = 0; i < ((union acpi_operand_object *)
+ index_desc->reference.object)->common.
+ reference_count; i++) {
+ acpi_ut_remove_reference(obj_desc);
}
}
@@ -433,16 +436,14 @@ acpi_ex_store_object_to_index (
/* Increment ref count by the ref count of the parent package-1 */
- for (i = 1;
- i < ((union acpi_operand_object *)
- index_desc->reference.object)->common.reference_count;
- i++) {
- acpi_ut_add_reference (new_desc);
+ for (i = 1; i < ((union acpi_operand_object *)
+ index_desc->reference.object)->common.
+ reference_count; i++) {
+ acpi_ut_add_reference(new_desc);
}
break;
-
case ACPI_TYPE_BUFFER_FIELD:
/*
@@ -460,16 +461,16 @@ acpi_ex_store_object_to_index (
* by the INDEX_OP code.
*/
obj_desc = index_desc->reference.object;
- if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
+ (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/*
* The assignment of the individual elements will be slightly
* different for each source type.
*/
- switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
case ACPI_TYPE_INTEGER:
/* Use the least-significant byte of the integer */
@@ -489,10 +490,11 @@ acpi_ex_store_object_to_index (
/* All other types are invalid */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Source must be Integer/Buffer/String type, not %s\n",
- acpi_ut_get_object_type_name (source_desc)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Source must be Integer/Buffer/String type, not %s\n",
+ acpi_ut_get_object_type_name
+ (source_desc)));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* Store the source value into the target buffer byte */
@@ -500,18 +502,16 @@ acpi_ex_store_object_to_index (
obj_desc->buffer.pointer[index_desc->reference.offset] = value;
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Target is not a Package or buffer_field\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Target is not a Package or buffer_field\n"));
status = AE_AML_OPERAND_TYPE;
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_store_object_to_node
@@ -539,42 +539,40 @@ acpi_ex_store_object_to_index (
******************************************************************************/
acpi_status
-acpi_ex_store_object_to_node (
- union acpi_operand_object *source_desc,
- struct acpi_namespace_node *node,
- struct acpi_walk_state *walk_state,
- u8 implicit_conversion)
+acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
+ struct acpi_namespace_node *node,
+ struct acpi_walk_state *walk_state,
+ u8 implicit_conversion)
{
- acpi_status status = AE_OK;
- union acpi_operand_object *target_desc;
- union acpi_operand_object *new_desc;
- acpi_object_type target_type;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
+ acpi_status status = AE_OK;
+ union acpi_operand_object *target_desc;
+ union acpi_operand_object *new_desc;
+ acpi_object_type target_type;
+ ACPI_FUNCTION_TRACE_PTR("ex_store_object_to_node", source_desc);
/* Get current type of the node, and object attached to Node */
- target_type = acpi_ns_get_type (node);
- target_desc = acpi_ns_get_attached_object (node);
+ target_type = acpi_ns_get_type(node);
+ target_desc = acpi_ns_get_attached_object(node);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
- source_desc, acpi_ut_get_object_type_name (source_desc),
- node, acpi_ut_get_type_name (target_type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
+ source_desc,
+ acpi_ut_get_object_type_name(source_desc), node,
+ acpi_ut_get_type_name(target_type)));
/*
* Resolve the source object to an actual value
* (If it is a reference object)
*/
- status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* If no implicit conversion, drop into the default case below */
- if (!implicit_conversion) {
+ if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) {
/* Force execution of default (no implicit conversion) */
target_type = ACPI_TYPE_ANY;
@@ -590,11 +588,10 @@ acpi_ex_store_object_to_node (
/* For fields, copy the source data to the target field. */
- status = acpi_ex_write_data_to_field (source_desc, target_desc,
- &walk_state->result_obj);
+ status = acpi_ex_write_data_to_field(source_desc, target_desc,
+ &walk_state->result_obj);
break;
-
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -605,10 +602,11 @@ acpi_ex_store_object_to_node (
*
* Copy and/or convert the source object to a new target object
*/
- status = acpi_ex_store_object_to_object (source_desc, target_desc,
- &new_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_store_object_to_object(source_desc, target_desc,
+ &new_desc, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (new_desc != target_desc) {
@@ -621,30 +619,33 @@ acpi_ex_store_object_to_node (
* has been performed such that the node/object type has been
* changed.
*/
- status = acpi_ns_attach_object (node, new_desc, new_desc->common.type);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Store %s into %s via Convert/Attach\n",
- acpi_ut_get_object_type_name (source_desc),
- acpi_ut_get_object_type_name (new_desc)));
+ status =
+ acpi_ns_attach_object(node, new_desc,
+ new_desc->common.type);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Store %s into %s via Convert/Attach\n",
+ acpi_ut_get_object_type_name
+ (source_desc),
+ acpi_ut_get_object_type_name
+ (new_desc)));
}
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Storing %s (%p) directly into node (%p), no implicit conversion\n",
- acpi_ut_get_object_type_name (source_desc), source_desc, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
+ acpi_ut_get_object_type_name(source_desc),
+ source_desc, node));
/* No conversions for all other types. Just attach the source object */
- status = acpi_ns_attach_object (node, source_desc,
- ACPI_GET_OBJECT_TYPE (source_desc));
+ status = acpi_ns_attach_object(node, source_desc,
+ ACPI_GET_OBJECT_TYPE
+ (source_desc));
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index 120f30ed0bd4..382f63c14ea1 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -43,15 +43,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exstoren")
-
+ACPI_MODULE_NAME("exstoren")
/*******************************************************************************
*
@@ -67,19 +64,15 @@
* it and return the actual object in the source_desc_ptr.
*
******************************************************************************/
-
acpi_status
-acpi_ex_resolve_object (
- union acpi_operand_object **source_desc_ptr,
- acpi_object_type target_type,
- struct acpi_walk_state *walk_state)
+acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
+ acpi_object_type target_type,
+ struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *source_desc = *source_desc_ptr;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ex_resolve_object");
+ union acpi_operand_object *source_desc = *source_desc_ptr;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ex_resolve_object");
/* Ensure we have a Target that can be stored to */
@@ -102,11 +95,14 @@ acpi_ex_resolve_object (
* are all essentially the same. This case handles the
* "interchangeable" types Integer, String, and Buffer.
*/
- if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+ if (ACPI_GET_OBJECT_TYPE(source_desc) ==
+ ACPI_TYPE_LOCAL_REFERENCE) {
/* Resolve a reference object first */
- status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ex_resolve_to_value(source_desc_ptr,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
break;
}
}
@@ -119,31 +115,32 @@ acpi_ex_resolve_object (
/* Must have a Integer, Buffer, or String */
- if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) &&
- (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) &&
- !((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) {
+ if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
+ (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
+ (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
+ !((ACPI_GET_OBJECT_TYPE(source_desc) ==
+ ACPI_TYPE_LOCAL_REFERENCE)
+ && (source_desc->reference.opcode == AML_LOAD_OP))) {
/* Conversion successful but still not a valid type */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
- acpi_ut_get_object_type_name (source_desc),
- acpi_ut_get_type_name (target_type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
+ acpi_ut_get_object_type_name
+ (source_desc),
+ acpi_ut_get_type_name(target_type)));
status = AE_AML_OPERAND_TYPE;
}
break;
-
case ACPI_TYPE_LOCAL_ALIAS:
case ACPI_TYPE_LOCAL_METHOD_ALIAS:
/* Aliases are resolved by acpi_ex_prep_operands */
- ACPI_REPORT_ERROR (("Store into Alias - should never happen\n"));
+ ACPI_REPORT_ERROR(("Store into Alias - should never happen\n"));
status = AE_AML_INTERNAL;
break;
-
case ACPI_TYPE_PACKAGE:
default:
@@ -154,10 +151,9 @@ acpi_ex_resolve_object (
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_store_object_to_object
@@ -194,18 +190,15 @@ acpi_ex_resolve_object (
******************************************************************************/
acpi_status
-acpi_ex_store_object_to_object (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *dest_desc,
- union acpi_operand_object **new_desc,
- struct acpi_walk_state *walk_state)
+acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc,
+ union acpi_operand_object **new_desc,
+ struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *actual_src_desc;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
+ union acpi_operand_object *actual_src_desc;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ex_store_object_to_object", source_desc);
actual_src_desc = source_desc;
if (!dest_desc) {
@@ -214,11 +207,14 @@ acpi_ex_store_object_to_object (
* package element), so we can simply copy the source object
* creating a new destination object
*/
- status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, new_desc, walk_state);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
+ walk_state);
+ return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+ if (ACPI_GET_OBJECT_TYPE(source_desc) !=
+ ACPI_GET_OBJECT_TYPE(dest_desc)) {
/*
* The source type does not match the type of the destination.
* Perform the "implicit conversion" of the source to the current type
@@ -228,10 +224,13 @@ acpi_ex_store_object_to_object (
* Otherwise, actual_src_desc is a temporary object to hold the
* converted object.
*/
- status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc),
- source_desc, &actual_src_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
+ (dest_desc), source_desc,
+ &actual_src_desc,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (source_desc == actual_src_desc) {
@@ -240,7 +239,7 @@ acpi_ex_store_object_to_object (
* new object.
*/
*new_desc = source_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
}
@@ -248,42 +247,42 @@ acpi_ex_store_object_to_object (
* We now have two objects of identical types, and we can perform a
* copy of the *value* of the source object.
*/
- switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
case ACPI_TYPE_INTEGER:
dest_desc->integer.value = actual_src_desc->integer.value;
/* Truncate value if we are executing from a 32-bit ACPI table */
- acpi_ex_truncate_for32bit_table (dest_desc);
+ acpi_ex_truncate_for32bit_table(dest_desc);
break;
case ACPI_TYPE_STRING:
- status = acpi_ex_store_string_to_string (actual_src_desc, dest_desc);
+ status =
+ acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
break;
case ACPI_TYPE_BUFFER:
- /*
- * Note: There is different store behavior depending on the original
- * source type
- */
- status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
+ status =
+ acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
break;
case ACPI_TYPE_PACKAGE:
- status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc,
- walk_state);
+ status =
+ acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
+ walk_state);
break;
default:
/*
* All other types come here.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n",
- acpi_ut_get_object_type_name (dest_desc)));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Store into type %s not implemented\n",
+ acpi_ut_get_object_type_name(dest_desc)));
status = AE_NOT_IMPLEMENTED;
break;
@@ -292,11 +291,9 @@ acpi_ex_store_object_to_object (
if (actual_src_desc != source_desc) {
/* Delete the intermediate (temporary) source object */
- acpi_ut_remove_reference (actual_src_desc);
+ acpi_ut_remove_reference(actual_src_desc);
}
*new_desc = dest_desc;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index 12d1527669c8..c4ff654a6697 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -42,14 +42,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exstorob")
-
+ACPI_MODULE_NAME("exstorob")
/*******************************************************************************
*
@@ -63,18 +60,14 @@
* DESCRIPTION: Copy a buffer object to another buffer object.
*
******************************************************************************/
-
acpi_status
-acpi_ex_store_buffer_to_buffer (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc)
+acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc)
{
- u32 length;
- u8 *buffer;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc);
+ u32 length;
+ u8 *buffer;
+ ACPI_FUNCTION_TRACE_PTR("ex_store_buffer_to_buffer", source_desc);
/* We know that source_desc is a buffer by now */
@@ -86,10 +79,10 @@ acpi_ex_store_buffer_to_buffer (
* allocate a new buffer of the proper length
*/
if ((target_desc->buffer.length == 0) ||
- (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
- target_desc->buffer.pointer = ACPI_MEM_ALLOCATE (length);
+ (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
+ target_desc->buffer.pointer = ACPI_MEM_ALLOCATE(length);
if (!target_desc->buffer.pointer) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
target_desc->buffer.length = length;
@@ -100,8 +93,9 @@ acpi_ex_store_buffer_to_buffer (
if (length <= target_desc->buffer.length) {
/* Clear existing buffer and copy in the new one */
- ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
- ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
+ ACPI_MEMSET(target_desc->buffer.pointer, 0,
+ target_desc->buffer.length);
+ ACPI_MEMCPY(target_desc->buffer.pointer, buffer, length);
#ifdef ACPI_OBSOLETE_BEHAVIOR
/*
@@ -124,26 +118,24 @@ acpi_ex_store_buffer_to_buffer (
target_desc->buffer.length = length;
}
#endif
- }
- else {
+ } else {
/* Truncate the source, copy only what will fit */
- ACPI_MEMCPY (target_desc->buffer.pointer, buffer,
- target_desc->buffer.length);
+ ACPI_MEMCPY(target_desc->buffer.pointer, buffer,
+ target_desc->buffer.length);
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Truncating source buffer from %X to %X\n",
- length, target_desc->buffer.length));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Truncating source buffer from %X to %X\n",
+ length, target_desc->buffer.length));
}
/* Copy flags */
target_desc->buffer.flags = source_desc->buffer.flags;
target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_store_string_to_string
@@ -158,16 +150,13 @@ acpi_ex_store_buffer_to_buffer (
******************************************************************************/
acpi_status
-acpi_ex_store_string_to_string (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc)
+acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc)
{
- u32 length;
- u8 *buffer;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc);
+ u32 length;
+ u8 *buffer;
+ ACPI_FUNCTION_TRACE_PTR("ex_store_string_to_string", source_desc);
/* We know that source_desc is a string by now */
@@ -179,41 +168,38 @@ acpi_ex_store_string_to_string (
* pointer is not a static pointer (part of an ACPI table)
*/
if ((length < target_desc->string.length) &&
- (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+ (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
/*
* String will fit in existing non-static buffer.
* Clear old string and copy in the new one
*/
- ACPI_MEMSET (target_desc->string.pointer, 0,
- (acpi_size) target_desc->string.length + 1);
- ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
- }
- else {
+ ACPI_MEMSET(target_desc->string.pointer, 0,
+ (acpi_size) target_desc->string.length + 1);
+ ACPI_MEMCPY(target_desc->string.pointer, buffer, length);
+ } else {
/*
* Free the current buffer, then allocate a new buffer
* large enough to hold the value
*/
if (target_desc->string.pointer &&
- (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+ (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
/* Only free if not a pointer into the DSDT */
- ACPI_MEM_FREE (target_desc->string.pointer);
+ ACPI_MEM_FREE(target_desc->string.pointer);
}
- target_desc->string.pointer = ACPI_MEM_CALLOCATE (
- (acpi_size) length + 1);
+ target_desc->string.pointer = ACPI_MEM_CALLOCATE((acpi_size)
+ length + 1);
if (!target_desc->string.pointer) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
- ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
+ ACPI_MEMCPY(target_desc->string.pointer, buffer, length);
}
/* Set the new target length */
target_desc->string.length = length;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index cafa702108dc..8a88b841237d 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -42,14 +42,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/acevents.h>
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exsystem")
-
+ACPI_MODULE_NAME("exsystem")
/*******************************************************************************
*
@@ -65,49 +63,42 @@
* interpreter is released.
*
******************************************************************************/
-
-acpi_status
-acpi_ex_system_wait_semaphore (
- acpi_handle semaphore,
- u16 timeout)
+acpi_status acpi_ex_system_wait_semaphore(acpi_handle semaphore, u16 timeout)
{
- acpi_status status;
- acpi_status status2;
-
+ acpi_status status;
+ acpi_status status2;
- ACPI_FUNCTION_TRACE ("ex_system_wait_semaphore");
+ ACPI_FUNCTION_TRACE("ex_system_wait_semaphore");
-
- status = acpi_os_wait_semaphore (semaphore, 1, 0);
- if (ACPI_SUCCESS (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_os_wait_semaphore(semaphore, 1, 0);
+ if (ACPI_SUCCESS(status)) {
+ return_ACPI_STATUS(status);
}
if (status == AE_TIME) {
/* We must wait, so unlock the interpreter */
- acpi_ex_exit_interpreter ();
+ acpi_ex_exit_interpreter();
- status = acpi_os_wait_semaphore (semaphore, 1, timeout);
+ status = acpi_os_wait_semaphore(semaphore, 1, timeout);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "*** Thread awake after blocking, %s\n",
- acpi_format_exception (status)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "*** Thread awake after blocking, %s\n",
+ acpi_format_exception(status)));
/* Reacquire the interpreter */
- status2 = acpi_ex_enter_interpreter ();
- if (ACPI_FAILURE (status2)) {
+ status2 = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status2)) {
/* Report fatal error, could not acquire interpreter */
- return_ACPI_STATUS (status2);
+ return_ACPI_STATUS(status2);
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_do_stall
@@ -125,35 +116,29 @@ acpi_ex_system_wait_semaphore (
*
******************************************************************************/
-acpi_status
-acpi_ex_system_do_stall (
- u32 how_long)
+acpi_status acpi_ex_system_do_stall(u32 how_long)
{
- acpi_status status = AE_OK;
-
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
-
- if (how_long > 255) /* 255 microseconds */ {
+ if (how_long > 255) { /* 255 microseconds */
/*
* Longer than 255 usec, this is an error
*
* (ACPI specifies 100 usec as max, but this gives some slack in
* order to support existing BIOSs)
*/
- ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n",
- how_long));
+ ACPI_REPORT_ERROR(("Stall: Time parameter is too large (%d)\n",
+ how_long));
status = AE_AML_OPERAND_VALUE;
- }
- else {
- acpi_os_stall (how_long);
+ } else {
+ acpi_os_stall(how_long);
}
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_do_suspend
@@ -167,29 +152,24 @@ acpi_ex_system_do_stall (
*
******************************************************************************/
-acpi_status
-acpi_ex_system_do_suspend (
- acpi_integer how_long)
+acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_status status;
+ ACPI_FUNCTION_ENTRY();
/* Since this thread will sleep, we must release the interpreter */
- acpi_ex_exit_interpreter ();
+ acpi_ex_exit_interpreter();
- acpi_os_sleep (how_long);
+ acpi_os_sleep(how_long);
/* And now we must get the interpreter again */
- status = acpi_ex_enter_interpreter ();
+ status = acpi_ex_enter_interpreter();
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_acquire_mutex
@@ -206,33 +186,30 @@ acpi_ex_system_do_suspend (
******************************************************************************/
acpi_status
-acpi_ex_system_acquire_mutex (
- union acpi_operand_object *time_desc,
- union acpi_operand_object *obj_desc)
+acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc,
+ union acpi_operand_object * obj_desc)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc);
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ex_system_acquire_mutex", obj_desc);
if (!obj_desc) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Support for the _GL_ Mutex object -- go get the global lock */
if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
- status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
+ return_ACPI_STATUS(status);
}
- status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
- (u16) time_desc->integer.value);
- return_ACPI_STATUS (status);
+ status = acpi_ex_system_wait_semaphore(obj_desc->mutex.semaphore,
+ (u16) time_desc->integer.value);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_release_mutex
@@ -248,32 +225,27 @@ acpi_ex_system_acquire_mutex (
*
******************************************************************************/
-acpi_status
-acpi_ex_system_release_mutex (
- union acpi_operand_object *obj_desc)
+acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ex_system_release_mutex");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ex_system_release_mutex");
if (!obj_desc) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Support for the _GL_ Mutex object -- release the global lock */
if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
- status = acpi_ev_release_global_lock ();
- return_ACPI_STATUS (status);
+ status = acpi_ev_release_global_lock();
+ return_ACPI_STATUS(status);
}
- status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
- return_ACPI_STATUS (status);
+ status = acpi_os_signal_semaphore(obj_desc->mutex.semaphore, 1);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_signal_event
@@ -287,24 +259,19 @@ acpi_ex_system_release_mutex (
*
******************************************************************************/
-acpi_status
-acpi_ex_system_signal_event (
- union acpi_operand_object *obj_desc)
+acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ex_system_signal_event");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ex_system_signal_event");
if (obj_desc) {
- status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
+ status = acpi_os_signal_semaphore(obj_desc->event.semaphore, 1);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_wait_event
@@ -321,25 +288,23 @@ acpi_ex_system_signal_event (
******************************************************************************/
acpi_status
-acpi_ex_system_wait_event (
- union acpi_operand_object *time_desc,
- union acpi_operand_object *obj_desc)
+acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
+ union acpi_operand_object *obj_desc)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ex_system_wait_event");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ex_system_wait_event");
if (obj_desc) {
- status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
- (u16) time_desc->integer.value);
+ status =
+ acpi_ex_system_wait_semaphore(obj_desc->event.semaphore,
+ (u16) time_desc->integer.
+ value);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_reset_event
@@ -352,27 +317,23 @@ acpi_ex_system_wait_event (
*
******************************************************************************/
-acpi_status
-acpi_ex_system_reset_event (
- union acpi_operand_object *obj_desc)
+acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
{
- acpi_status status = AE_OK;
- void *temp_semaphore;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_status status = AE_OK;
+ void *temp_semaphore;
+ ACPI_FUNCTION_ENTRY();
/*
* We are going to simply delete the existing semaphore and
* create a new one!
*/
- status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
- if (ACPI_SUCCESS (status)) {
- (void) acpi_os_delete_semaphore (obj_desc->event.semaphore);
+ status =
+ acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
+ if (ACPI_SUCCESS(status)) {
+ (void)acpi_os_delete_semaphore(obj_desc->event.semaphore);
obj_desc->event.semaphore = temp_semaphore;
}
return (status);
}
-
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 5c7ec0c04177..1ee79d8c8f88 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -42,7 +42,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
/*
* DEFINE_AML_GLOBALS is tested in amlcode.h
* to determine whether certain global names should be "defined" or only
@@ -65,15 +64,10 @@
#include <acpi/acevents.h>
#define _COMPONENT ACPI_EXECUTER
- ACPI_MODULE_NAME ("exutils")
+ACPI_MODULE_NAME("exutils")
/* Local prototypes */
-
-static u32
-acpi_ex_digits_needed (
- acpi_integer value,
- u32 base);
-
+static u32 acpi_ex_digits_needed(acpi_integer value, u32 base);
#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
@@ -89,24 +83,20 @@ acpi_ex_digits_needed (
*
******************************************************************************/
-acpi_status
-acpi_ex_enter_interpreter (
- void)
+acpi_status acpi_ex_enter_interpreter(void)
{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE ("ex_enter_interpreter");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ex_enter_interpreter");
- status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not acquire interpreter mutex\n"));
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EXECUTE);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not acquire interpreter mutex\n"));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_exit_interpreter
@@ -129,25 +119,20 @@ acpi_ex_enter_interpreter (
*
******************************************************************************/
-void
-acpi_ex_exit_interpreter (
- void)
+void acpi_ex_exit_interpreter(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ex_exit_interpreter");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ex_exit_interpreter");
- status = acpi_ut_release_mutex (ACPI_MTX_EXECUTE);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not release interpreter mutex\n"));
+ status = acpi_ut_release_mutex(ACPI_MTX_EXECUTE);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not release interpreter mutex\n"));
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_truncate_for32bit_table
@@ -161,20 +146,17 @@ acpi_ex_exit_interpreter (
*
******************************************************************************/
-void
-acpi_ex_truncate_for32bit_table (
- union acpi_operand_object *obj_desc)
+void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
/*
* Object must be a valid number and we must be executing
* a control method
*/
if ((!obj_desc) ||
- (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER)) {
+ (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
return;
}
@@ -187,7 +169,6 @@ acpi_ex_truncate_for32bit_table (
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_acquire_global_lock
@@ -203,37 +184,31 @@ acpi_ex_truncate_for32bit_table (
*
******************************************************************************/
-u8
-acpi_ex_acquire_global_lock (
- u32 field_flags)
+u8 acpi_ex_acquire_global_lock(u32 field_flags)
{
- u8 locked = FALSE;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ex_acquire_global_lock");
+ u8 locked = FALSE;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ex_acquire_global_lock");
/* Only attempt lock if the always_lock bit is set */
if (field_flags & AML_FIELD_LOCK_RULE_MASK) {
/* We should attempt to get the lock, wait forever */
- status = acpi_ev_acquire_global_lock (ACPI_WAIT_FOREVER);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ev_acquire_global_lock(ACPI_WAIT_FOREVER);
+ if (ACPI_SUCCESS(status)) {
locked = TRUE;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not acquire Global Lock, %s\n",
- acpi_format_exception (status)));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not acquire Global Lock, %s\n",
+ acpi_format_exception(status)));
}
}
- return_VALUE (locked);
+ return_VALUE(locked);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_release_global_lock
@@ -247,34 +222,28 @@ acpi_ex_acquire_global_lock (
*
******************************************************************************/
-void
-acpi_ex_release_global_lock (
- u8 locked_by_me)
+void acpi_ex_release_global_lock(u8 locked_by_me)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ex_release_global_lock");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ex_release_global_lock");
/* Only attempt unlock if the caller locked it */
if (locked_by_me) {
/* OK, now release the lock */
- status = acpi_ev_release_global_lock ();
- if (ACPI_FAILURE (status)) {
+ status = acpi_ev_release_global_lock();
+ if (ACPI_FAILURE(status)) {
/* Report the error, but there isn't much else we can do */
- ACPI_REPORT_ERROR (("Could not release ACPI Global Lock, %s\n",
- acpi_format_exception (status)));
+ ACPI_REPORT_ERROR(("Could not release ACPI Global Lock, %s\n", acpi_format_exception(status)));
}
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_digits_needed
@@ -289,22 +258,17 @@ acpi_ex_release_global_lock (
*
******************************************************************************/
-static u32
-acpi_ex_digits_needed (
- acpi_integer value,
- u32 base)
+static u32 acpi_ex_digits_needed(acpi_integer value, u32 base)
{
- u32 num_digits;
- acpi_integer current_value;
-
-
- ACPI_FUNCTION_TRACE ("ex_digits_needed");
+ u32 num_digits;
+ acpi_integer current_value;
+ ACPI_FUNCTION_TRACE("ex_digits_needed");
/* acpi_integer is unsigned, so we don't worry about a '-' prefix */
if (value == 0) {
- return_VALUE (1);
+ return_VALUE(1);
}
current_value = value;
@@ -313,14 +277,14 @@ acpi_ex_digits_needed (
/* Count the digits in the requested base */
while (current_value) {
- (void) acpi_ut_short_divide (current_value, base, &current_value, NULL);
+ (void)acpi_ut_short_divide(current_value, base, &current_value,
+ NULL);
num_digits++;
}
- return_VALUE (num_digits);
+ return_VALUE(num_digits);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_eisa_id_to_string
@@ -334,32 +298,26 @@ acpi_ex_digits_needed (
*
******************************************************************************/
-void
-acpi_ex_eisa_id_to_string (
- u32 numeric_id,
- char *out_string)
+void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string)
{
- u32 eisa_id;
-
-
- ACPI_FUNCTION_ENTRY ();
+ u32 eisa_id;
+ ACPI_FUNCTION_ENTRY();
/* Swap ID to big-endian to get contiguous bits */
- eisa_id = acpi_ut_dword_byte_swap (numeric_id);
+ eisa_id = acpi_ut_dword_byte_swap(numeric_id);
- out_string[0] = (char) ('@' + (((unsigned long) eisa_id >> 26) & 0x1f));
- out_string[1] = (char) ('@' + ((eisa_id >> 21) & 0x1f));
- out_string[2] = (char) ('@' + ((eisa_id >> 16) & 0x1f));
- out_string[3] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 12);
- out_string[4] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 8);
- out_string[5] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 4);
- out_string[6] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 0);
+ out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f));
+ out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f));
+ out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f));
+ out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12);
+ out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8);
+ out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4);
+ out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0);
out_string[7] = 0;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ex_unsigned_integer_to_string
@@ -369,30 +327,25 @@ acpi_ex_eisa_id_to_string (
*
* RETURN: None, string
*
- * DESCRIPTOIN: Convert a number to string representation. Assumes string
+ * DESCRIPTION: Convert a number to string representation. Assumes string
* buffer is large enough to hold the string.
*
******************************************************************************/
-void
-acpi_ex_unsigned_integer_to_string (
- acpi_integer value,
- char *out_string)
+void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string)
{
- u32 count;
- u32 digits_needed;
- u32 remainder;
-
-
- ACPI_FUNCTION_ENTRY ();
+ u32 count;
+ u32 digits_needed;
+ u32 remainder;
+ ACPI_FUNCTION_ENTRY();
- digits_needed = acpi_ex_digits_needed (value, 10);
+ digits_needed = acpi_ex_digits_needed(value, 10);
out_string[digits_needed] = 0;
for (count = digits_needed; count > 0; count--) {
- (void) acpi_ut_short_divide (value, 10, &value, &remainder);
- out_string[count-1] = (char) ('0' + remainder);\
+ (void)acpi_ut_short_divide(value, 10, &value, &remainder);
+ out_string[count - 1] = (char)('0' + remainder);
}
}
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 14192ee55f8f..e8165c4f162a 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -34,52 +34,45 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define ACPI_FAN_COMPONENT 0x00200000
#define ACPI_FAN_CLASS "fan"
-#define ACPI_FAN_HID "PNP0C0B"
#define ACPI_FAN_DRIVER_NAME "ACPI Fan Driver"
-#define ACPI_FAN_DEVICE_NAME "Fan"
#define ACPI_FAN_FILE_STATE "state"
-#define ACPI_FAN_NOTIFY_STATUS 0x80
#define _COMPONENT ACPI_FAN_COMPONENT
-ACPI_MODULE_NAME ("acpi_fan")
+ACPI_MODULE_NAME("acpi_fan")
-MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME);
MODULE_LICENSE("GPL");
-static int acpi_fan_add (struct acpi_device *device);
-static int acpi_fan_remove (struct acpi_device *device, int type);
+static int acpi_fan_add(struct acpi_device *device);
+static int acpi_fan_remove(struct acpi_device *device, int type);
static struct acpi_driver acpi_fan_driver = {
- .name = ACPI_FAN_DRIVER_NAME,
- .class = ACPI_FAN_CLASS,
- .ids = ACPI_FAN_HID,
- .ops = {
- .add = acpi_fan_add,
- .remove = acpi_fan_remove,
- },
+ .name = ACPI_FAN_DRIVER_NAME,
+ .class = ACPI_FAN_CLASS,
+ .ids = "PNP0C0B",
+ .ops = {
+ .add = acpi_fan_add,
+ .remove = acpi_fan_remove,
+ },
};
struct acpi_fan {
- acpi_handle handle;
+ acpi_handle handle;
};
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_fan_dir;
+static struct proc_dir_entry *acpi_fan_dir;
-
-static int
-acpi_fan_read_state (struct seq_file *seq, void *offset)
+static int acpi_fan_read_state(struct seq_file *seq, void *offset)
{
- struct acpi_fan *fan = seq->private;
- int state = 0;
+ struct acpi_fan *fan = seq->private;
+ int state = 0;
ACPI_FUNCTION_TRACE("acpi_fan_read_state");
@@ -88,7 +81,7 @@ acpi_fan_read_state (struct seq_file *seq, void *offset)
seq_printf(seq, "status: ERROR\n");
else
seq_printf(seq, "status: %s\n",
- !state?"on":"off");
+ !state ? "on" : "off");
}
return_VALUE(0);
}
@@ -99,29 +92,26 @@ static int acpi_fan_state_open_fs(struct inode *inode, struct file *file)
}
static ssize_t
-acpi_fan_write_state (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_fan_write_state(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
{
- int result = 0;
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_fan *fan = (struct acpi_fan *) m->private;
- char state_string[12] = {'\0'};
+ int result = 0;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_fan *fan = (struct acpi_fan *)m->private;
+ char state_string[12] = { '\0' };
ACPI_FUNCTION_TRACE("acpi_fan_write_state");
if (!fan || (count > sizeof(state_string) - 1))
return_VALUE(-EINVAL);
-
+
if (copy_from_user(state_string, buffer, count))
return_VALUE(-EFAULT);
-
+
state_string[count] = '\0';
-
- result = acpi_bus_set_power(fan->handle,
- simple_strtoul(state_string, NULL, 0));
+
+ result = acpi_bus_set_power(fan->handle,
+ simple_strtoul(state_string, NULL, 0));
if (result)
return_VALUE(result);
@@ -129,19 +119,17 @@ acpi_fan_write_state (
}
static struct file_operations acpi_fan_state_ops = {
- .open = acpi_fan_state_open_fs,
- .read = seq_read,
- .write = acpi_fan_write_state,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_fan_state_open_fs,
+ .read = seq_read,
+ .write = acpi_fan_write_state,
+ .llseek = seq_lseek,
+ .release = single_release,
.owner = THIS_MODULE,
};
-static int
-acpi_fan_add_fs (
- struct acpi_device *device)
+static int acpi_fan_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_fan_add_fs");
@@ -150,7 +138,7 @@ acpi_fan_add_fs (
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_fan_dir);
+ acpi_fan_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
acpi_device_dir(device)->owner = THIS_MODULE;
@@ -158,11 +146,12 @@ acpi_fan_add_fs (
/* 'status' [R/W] */
entry = create_proc_entry(ACPI_FAN_FILE_STATE,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_FAN_FILE_STATE));
+ "Unable to create '%s' fs entry\n",
+ ACPI_FAN_FILE_STATE));
else {
entry->proc_fops = &acpi_fan_state_ops;
entry->data = acpi_driver_data(device);
@@ -172,16 +161,12 @@ acpi_fan_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_fan_remove_fs (
- struct acpi_device *device)
+static int acpi_fan_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_fan_remove_fs");
if (acpi_device_dir(device)) {
- remove_proc_entry(ACPI_FAN_FILE_STATE,
- acpi_device_dir(device));
+ remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device), acpi_fan_dir);
acpi_device_dir(device) = NULL;
}
@@ -189,18 +174,15 @@ acpi_fan_remove_fs (
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static int
-acpi_fan_add (
- struct acpi_device *device)
+static int acpi_fan_add(struct acpi_device *device)
{
- int result = 0;
- struct acpi_fan *fan = NULL;
- int state = 0;
+ int result = 0;
+ struct acpi_fan *fan = NULL;
+ int state = 0;
ACPI_FUNCTION_TRACE("acpi_fan_add");
@@ -213,14 +195,14 @@ acpi_fan_add (
memset(fan, 0, sizeof(struct acpi_fan));
fan->handle = device->handle;
- strcpy(acpi_device_name(device), ACPI_FAN_DEVICE_NAME);
+ strcpy(acpi_device_name(device), "Fan");
strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
acpi_driver_data(device) = fan;
result = acpi_bus_get_power(fan->handle, &state);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error reading power state\n"));
+ "Error reading power state\n"));
goto end;
}
@@ -229,30 +211,26 @@ acpi_fan_add (
goto end;
printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
- acpi_device_name(device), acpi_device_bid(device),
- !device->power.state?"on":"off");
+ acpi_device_name(device), acpi_device_bid(device),
+ !device->power.state ? "on" : "off");
-end:
+ end:
if (result)
kfree(fan);
return_VALUE(result);
}
-
-static int
-acpi_fan_remove (
- struct acpi_device *device,
- int type)
+static int acpi_fan_remove(struct acpi_device *device, int type)
{
- struct acpi_fan *fan = NULL;
+ struct acpi_fan *fan = NULL;
ACPI_FUNCTION_TRACE("acpi_fan_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- fan = (struct acpi_fan *) acpi_driver_data(device);
+ fan = (struct acpi_fan *)acpi_driver_data(device);
acpi_fan_remove_fs(device);
@@ -261,11 +239,9 @@ acpi_fan_remove (
return_VALUE(0);
}
-
-static int __init
-acpi_fan_init (void)
+static int __init acpi_fan_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_fan_init");
@@ -283,9 +259,7 @@ acpi_fan_init (void)
return_VALUE(0);
}
-
-static void __exit
-acpi_fan_exit (void)
+static void __exit acpi_fan_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_fan_exit");
@@ -296,7 +270,5 @@ acpi_fan_exit (void)
return_VOID;
}
-
module_init(acpi_fan_init);
module_exit(acpi_fan_exit);
-
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 770cfc8b17e0..3937adf4e5e5 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -29,7 +29,8 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
down_write(&bus_type_sem);
list_add_tail(&type->list, &bus_type_list);
up_write(&bus_type_sem);
- printk(KERN_INFO PREFIX "bus type %s registered\n", type->bus->name);
+ printk(KERN_INFO PREFIX "bus type %s registered\n",
+ type->bus->name);
return 0;
}
return -ENODEV;
@@ -45,7 +46,8 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
down_write(&bus_type_sem);
list_del_init(&type->list);
up_write(&bus_type_sem);
- printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", type->bus->name);
+ printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n",
+ type->bus->name);
return 0;
}
return -ENODEV;
@@ -94,7 +96,7 @@ struct acpi_find_pci_root {
static acpi_status
do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{
- int *busnr = (int *)data;
+ unsigned long *busnr = (unsigned long *)data;
struct acpi_resource_address64 address;
if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
@@ -113,13 +115,13 @@ do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
static int get_root_bridge_busnr(acpi_handle handle)
{
acpi_status status;
- int bus, bbn;
+ unsigned long bus, bbn;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
- (unsigned long *)&bbn);
+ &bbn);
if (status == AE_NOT_FOUND) {
/* Assume bus = 0 */
printk(KERN_INFO PREFIX
@@ -151,7 +153,7 @@ static int get_root_bridge_busnr(acpi_handle handle)
}
exit:
acpi_os_free(buffer.pointer);
- return bbn;
+ return (int)bbn;
}
static acpi_status
@@ -168,9 +170,6 @@ find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
if (status == AE_NOT_FOUND) {
/* Assume seg = 0 */
- printk(KERN_INFO PREFIX
- "Assume root bridge [%s] segment is 0\n",
- (char *)buffer.pointer);
status = AE_OK;
seg = 0;
}
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index b51001e74eea..1bb3463d7040 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -42,13 +42,10 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
-
#define _COMPONENT ACPI_HARDWARE
- ACPI_MODULE_NAME ("hwacpi")
-
+ACPI_MODULE_NAME("hwacpi")
/******************************************************************************
*
@@ -62,36 +59,30 @@
* the FADT.
*
******************************************************************************/
-
-acpi_status
-acpi_hw_initialize (
- void)
+acpi_status acpi_hw_initialize(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("hw_initialize");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("hw_initialize");
/* We must have the ACPI tables by the time we get here */
if (!acpi_gbl_FADT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT is present\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No FADT is present\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/* Sanity check the FADT for valid values */
- status = acpi_ut_validate_fadt ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_validate_fadt();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_set_mode
@@ -104,24 +95,21 @@ acpi_hw_initialize (
*
******************************************************************************/
-acpi_status
-acpi_hw_set_mode (
- u32 mode)
+acpi_status acpi_hw_set_mode(u32 mode)
{
- acpi_status status;
- u32 retry;
-
+ acpi_status status;
+ u32 retry;
- ACPI_FUNCTION_TRACE ("hw_set_mode");
+ ACPI_FUNCTION_TRACE("hw_set_mode");
/*
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT->smi_cmd) {
- ACPI_REPORT_ERROR (("No SMI_CMD in FADT, mode transition failed.\n"));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ ACPI_REPORT_ERROR(("No SMI_CMD in FADT, mode transition failed.\n"));
+ return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}
/*
@@ -132,9 +120,8 @@ acpi_hw_set_mode (
* transitions are not supported.
*/
if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
- ACPI_REPORT_ERROR ((
- "No ACPI mode transition supported in this system (enable/disable both zero)\n"));
- return_ACPI_STATUS (AE_OK);
+ ACPI_REPORT_ERROR(("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
+ return_ACPI_STATUS(AE_OK);
}
switch (mode) {
@@ -142,9 +129,11 @@ acpi_hw_set_mode (
/* BIOS should have disabled ALL fixed and GP events */
- status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
- (u32) acpi_gbl_FADT->acpi_enable, 8);
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n"));
+ status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
+ (u32) acpi_gbl_FADT->acpi_enable,
+ 8);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Attempting to enable ACPI mode\n"));
break;
case ACPI_SYS_MODE_LEGACY:
@@ -153,20 +142,21 @@ acpi_hw_set_mode (
* BIOS should clear all fixed status bits and restore fixed event
* enable bits to default
*/
- status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
- (u32) acpi_gbl_FADT->acpi_disable, 8);
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Attempting to enable Legacy (non-ACPI) mode\n"));
+ status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
+ (u32) acpi_gbl_FADT->acpi_disable,
+ 8);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Attempting to enable Legacy (non-ACPI) mode\n"));
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not write mode change, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not write mode change, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
/*
@@ -176,19 +166,19 @@ acpi_hw_set_mode (
retry = 3000;
while (retry) {
if (acpi_hw_get_mode() == mode) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n",
- mode));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Mode %X successfully enabled\n",
+ mode));
+ return_ACPI_STATUS(AE_OK);
}
acpi_os_stall(1000);
retry--;
}
- ACPI_REPORT_ERROR (("Hardware never changed modes\n"));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ ACPI_REPORT_ERROR(("Hardware never changed modes\n"));
+ return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_hw_get_mode
@@ -202,34 +192,30 @@ acpi_hw_set_mode (
*
******************************************************************************/
-u32
-acpi_hw_get_mode (
- void)
+u32 acpi_hw_get_mode(void)
{
- acpi_status status;
- u32 value;
-
-
- ACPI_FUNCTION_TRACE ("hw_get_mode");
+ acpi_status status;
+ u32 value;
+ ACPI_FUNCTION_TRACE("hw_get_mode");
/*
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT->smi_cmd) {
- return_VALUE (ACPI_SYS_MODE_ACPI);
+ return_VALUE(ACPI_SYS_MODE_ACPI);
}
- status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_VALUE (ACPI_SYS_MODE_LEGACY);
+ status =
+ acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_VALUE(ACPI_SYS_MODE_LEGACY);
}
if (value) {
- return_VALUE (ACPI_SYS_MODE_ACPI);
- }
- else {
- return_VALUE (ACPI_SYS_MODE_LEGACY);
+ return_VALUE(ACPI_SYS_MODE_ACPI);
+ } else {
+ return_VALUE(ACPI_SYS_MODE_LEGACY);
}
}
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 8daeabb2fc7a..5c8e5dfd024e 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -46,15 +46,12 @@
#include <acpi/acevents.h>
#define _COMPONENT ACPI_HARDWARE
- ACPI_MODULE_NAME ("hwgpe")
+ACPI_MODULE_NAME("hwgpe")
/* Local prototypes */
-
static acpi_status
-acpi_hw_enable_wakeup_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block);
-
+acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
/******************************************************************************
*
@@ -71,15 +68,12 @@ acpi_hw_enable_wakeup_gpe_block (
******************************************************************************/
acpi_status
-acpi_hw_write_gpe_enable_reg (
- struct acpi_gpe_event_info *gpe_event_info)
+acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info)
{
- struct acpi_gpe_register_info *gpe_register_info;
- acpi_status status;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+ ACPI_FUNCTION_ENTRY();
/* Get the info block for the entire GPE register */
@@ -90,13 +84,12 @@ acpi_hw_write_gpe_enable_reg (
/* Write the entire GPE (runtime) enable register */
- status = acpi_hw_low_level_write (8, gpe_register_info->enable_for_run,
- &gpe_register_info->enable_address);
+ status = acpi_hw_low_level_write(8, gpe_register_info->enable_for_run,
+ &gpe_register_info->enable_address);
return (status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_clear_gpe
@@ -109,27 +102,23 @@ acpi_hw_write_gpe_enable_reg (
*
******************************************************************************/
-acpi_status
-acpi_hw_clear_gpe (
- struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_status status;
+ ACPI_FUNCTION_ENTRY();
/*
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
- status = acpi_hw_low_level_write (8, gpe_event_info->register_bit,
- &gpe_event_info->register_info->status_address);
+ status = acpi_hw_low_level_write(8, gpe_event_info->register_bit,
+ &gpe_event_info->register_info->
+ status_address);
return (status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_get_gpe_status
@@ -145,19 +134,16 @@ acpi_hw_clear_gpe (
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_hw_get_gpe_status (
- struct acpi_gpe_event_info *gpe_event_info,
- acpi_event_status *event_status)
+acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
+ acpi_event_status * event_status)
{
- u32 in_byte;
- u8 register_bit;
- struct acpi_gpe_register_info *gpe_register_info;
- acpi_status status;
- acpi_event_status local_event_status = 0;
-
-
- ACPI_FUNCTION_ENTRY ();
+ u32 in_byte;
+ u8 register_bit;
+ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+ acpi_event_status local_event_status = 0;
+ ACPI_FUNCTION_ENTRY();
if (!event_status) {
return (AE_BAD_PARAMETER);
@@ -185,8 +171,10 @@ acpi_hw_get_gpe_status (
/* GPE currently active (status bit == 1)? */
- status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_read(8, &in_byte,
+ &gpe_register_info->status_address);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
@@ -198,12 +186,10 @@ acpi_hw_get_gpe_status (
(*event_status) = local_event_status;
-
-unlock_and_exit:
+ unlock_and_exit:
return (status);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/******************************************************************************
*
@@ -219,22 +205,21 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_hw_disable_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block)
+acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info,
+ struct acpi_gpe_block_info * gpe_block)
{
- u32 i;
- acpi_status status;
-
+ u32 i;
+ acpi_status status;
/* Examine each GPE Register within the block */
for (i = 0; i < gpe_block->register_count; i++) {
/* Disable all GPEs in this register */
- status = acpi_hw_low_level_write (8, 0x00,
- &gpe_block->register_info[i].enable_address);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_low_level_write(8, 0x00,
+ &gpe_block->register_info[i].
+ enable_address);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -242,7 +227,6 @@ acpi_hw_disable_gpe_block (
return (AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_clear_gpe_block
@@ -257,22 +241,21 @@ acpi_hw_disable_gpe_block (
******************************************************************************/
acpi_status
-acpi_hw_clear_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block)
+acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info,
+ struct acpi_gpe_block_info * gpe_block)
{
- u32 i;
- acpi_status status;
-
+ u32 i;
+ acpi_status status;
/* Examine each GPE Register within the block */
for (i = 0; i < gpe_block->register_count; i++) {
/* Clear status on all GPEs in this register */
- status = acpi_hw_low_level_write (8, 0xFF,
- &gpe_block->register_info[i].status_address);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_low_level_write(8, 0xFF,
+ &gpe_block->register_info[i].
+ status_address);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -280,7 +263,6 @@ acpi_hw_clear_gpe_block (
return (AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_enable_runtime_gpe_block
@@ -296,13 +278,11 @@ acpi_hw_clear_gpe_block (
******************************************************************************/
acpi_status
-acpi_hw_enable_runtime_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block)
+acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info,
+ struct acpi_gpe_block_info * gpe_block)
{
- u32 i;
- acpi_status status;
-
+ u32 i;
+ acpi_status status;
/* NOTE: assumes that all GPEs are currently disabled */
@@ -315,9 +295,13 @@ acpi_hw_enable_runtime_gpe_block (
/* Enable all "runtime" GPEs in this register */
- status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_run,
- &gpe_block->register_info[i].enable_address);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_write(8,
+ gpe_block->register_info[i].
+ enable_for_run,
+ &gpe_block->register_info[i].
+ enable_address);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -325,7 +309,6 @@ acpi_hw_enable_runtime_gpe_block (
return (AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_enable_wakeup_gpe_block
@@ -341,13 +324,11 @@ acpi_hw_enable_runtime_gpe_block (
******************************************************************************/
static acpi_status
-acpi_hw_enable_wakeup_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block)
+acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block)
{
- u32 i;
- acpi_status status;
-
+ u32 i;
+ acpi_status status;
/* Examine each GPE Register within the block */
@@ -358,10 +339,12 @@ acpi_hw_enable_wakeup_gpe_block (
/* Enable all "wake" GPEs in this register */
- status = acpi_hw_low_level_write (8,
- gpe_block->register_info[i].enable_for_wake,
- &gpe_block->register_info[i].enable_address);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_low_level_write(8,
+ gpe_block->register_info[i].
+ enable_for_wake,
+ &gpe_block->register_info[i].
+ enable_address);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
@@ -369,12 +352,11 @@ acpi_hw_enable_wakeup_gpe_block (
return (AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_disable_all_gpes
*
- * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR
+ * PARAMETERS: None
*
* RETURN: Status
*
@@ -382,27 +364,22 @@ acpi_hw_enable_wakeup_gpe_block (
*
******************************************************************************/
-acpi_status
-acpi_hw_disable_all_gpes (
- u32 flags)
+acpi_status acpi_hw_disable_all_gpes(void)
{
- acpi_status status;
-
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("hw_disable_all_gpes");
+ ACPI_FUNCTION_TRACE("hw_disable_all_gpes");
-
- status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, flags);
- status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, flags);
- return_ACPI_STATUS (status);
+ status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block);
+ status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_enable_all_runtime_gpes
*
- * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR
+ * PARAMETERS: None
*
* RETURN: Status
*
@@ -410,26 +387,21 @@ acpi_hw_disable_all_gpes (
*
******************************************************************************/
-acpi_status
-acpi_hw_enable_all_runtime_gpes (
- u32 flags)
+acpi_status acpi_hw_enable_all_runtime_gpes(void)
{
- acpi_status status;
-
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("hw_enable_all_runtime_gpes");
+ ACPI_FUNCTION_TRACE("hw_enable_all_runtime_gpes");
-
- status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block, flags);
- return_ACPI_STATUS (status);
+ status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_enable_all_wakeup_gpes
*
- * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR
+ * PARAMETERS: None
*
* RETURN: Status
*
@@ -437,17 +409,12 @@ acpi_hw_enable_all_runtime_gpes (
*
******************************************************************************/
-acpi_status
-acpi_hw_enable_all_wakeup_gpes (
- u32 flags)
+acpi_status acpi_hw_enable_all_wakeup_gpes(void)
{
- acpi_status status;
-
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("hw_enable_all_wakeup_gpes");
+ ACPI_FUNCTION_TRACE("hw_enable_all_wakeup_gpes");
-
- status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block, flags);
- return_ACPI_STATUS (status);
+ status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block);
+ return_ACPI_STATUS(status);
}
-
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 6d9e4eb84836..536a7aea80c9 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -50,8 +50,7 @@
#include <acpi/acevents.h>
#define _COMPONENT ACPI_HARDWARE
- ACPI_MODULE_NAME ("hwregs")
-
+ACPI_MODULE_NAME("hwregs")
/*******************************************************************************
*
@@ -65,57 +64,52 @@
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
*
******************************************************************************/
-
-acpi_status
-acpi_hw_clear_acpi_status (
- u32 flags)
+acpi_status acpi_hw_clear_acpi_status(u32 flags)
{
- acpi_status status;
-
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
+ ACPI_FUNCTION_TRACE("hw_clear_acpi_status");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
- ACPI_BITMASK_ALL_FIXED_STATUS,
- (u16) acpi_gbl_FADT->xpm1a_evt_blk.address));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+ ACPI_BITMASK_ALL_FIXED_STATUS,
+ (u16) acpi_gbl_FADT->xpm1a_evt_blk.address));
if (flags & ACPI_MTX_LOCK) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS,
- ACPI_BITMASK_ALL_FIXED_STATUS);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITMASK_ALL_FIXED_STATUS);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Clear the fixed events */
if (acpi_gbl_FADT->xpm1b_evt_blk.address) {
- status = acpi_hw_low_level_write (16, ACPI_BITMASK_ALL_FIXED_STATUS,
- &acpi_gbl_FADT->xpm1b_evt_blk);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS,
+ &acpi_gbl_FADT->xpm1b_evt_blk);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
}
/* Clear the GPE Bits in all GPE registers in all GPE blocks */
- status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, ACPI_ISR);
+ status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block);
-unlock_and_exit:
+ unlock_and_exit:
if (flags & ACPI_MTX_LOCK) {
- (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_sleep_type_data
@@ -132,53 +126,48 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_get_sleep_type_data (
- u8 sleep_state,
- u8 *sleep_type_a,
- u8 *sleep_type_b)
+acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
{
- acpi_status status = AE_OK;
- struct acpi_parameter_info info;
- char *sleep_state_name;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data");
+ acpi_status status = AE_OK;
+ struct acpi_parameter_info info;
+ char *sleep_state_name;
+ ACPI_FUNCTION_TRACE("acpi_get_sleep_type_data");
/* Validate parameters */
- if ((sleep_state > ACPI_S_STATES_MAX) ||
- !sleep_type_a || !sleep_type_b) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Evaluate the namespace object containing the values for this state */
info.parameters = NULL;
info.return_object = NULL;
- sleep_state_name = (char *) acpi_gbl_sleep_state_names[sleep_state];
+ sleep_state_name = (char *)acpi_gbl_sleep_state_names[sleep_state];
- status = acpi_ns_evaluate_by_name (sleep_state_name, &info);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "%s while evaluating sleep_state [%s]\n",
- acpi_format_exception (status), sleep_state_name));
+ status = acpi_ns_evaluate_by_name(sleep_state_name, &info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "%s while evaluating sleep_state [%s]\n",
+ acpi_format_exception(status),
+ sleep_state_name));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Must have a return object */
if (!info.return_object) {
- ACPI_REPORT_ERROR (("No Sleep State object returned from [%s]\n",
- sleep_state_name));
+ ACPI_REPORT_ERROR(("No Sleep State object returned from [%s]\n",
+ sleep_state_name));
status = AE_NOT_EXIST;
}
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) {
- ACPI_REPORT_ERROR (("Sleep State return object is not a Package\n"));
+ else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) {
+ ACPI_REPORT_ERROR(("Sleep State return object is not a Package\n"));
status = AE_AML_OPERAND_TYPE;
}
@@ -190,45 +179,41 @@ acpi_get_sleep_type_data (
* one per sleep type (A/B).
*/
else if (info.return_object->package.count < 2) {
- ACPI_REPORT_ERROR ((
- "Sleep State return package does not have at least two elements\n"));
+ ACPI_REPORT_ERROR(("Sleep State return package does not have at least two elements\n"));
status = AE_AML_NO_OPERAND;
}
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0])
- != ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1])
- != ACPI_TYPE_INTEGER)) {
- ACPI_REPORT_ERROR ((
- "Sleep State return package elements are not both Integers (%s, %s)\n",
- acpi_ut_get_object_type_name (info.return_object->package.elements[0]),
- acpi_ut_get_object_type_name (info.return_object->package.elements[1])));
+ else if ((ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[0])
+ != ACPI_TYPE_INTEGER) ||
+ (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1])
+ != ACPI_TYPE_INTEGER)) {
+ ACPI_REPORT_ERROR(("Sleep State return package elements are not both Integers (%s, %s)\n", acpi_ut_get_object_type_name(info.return_object->package.elements[0]), acpi_ut_get_object_type_name(info.return_object->package.elements[1])));
status = AE_AML_OPERAND_TYPE;
- }
- else {
+ } else {
/* Valid _Sx_ package size, type, and value */
*sleep_type_a = (u8)
- (info.return_object->package.elements[0])->integer.value;
+ (info.return_object->package.elements[0])->integer.value;
*sleep_type_b = (u8)
- (info.return_object->package.elements[1])->integer.value;
+ (info.return_object->package.elements[1])->integer.value;
}
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
- acpi_format_exception (status),
- sleep_state_name, info.return_object,
- acpi_ut_get_object_type_name (info.return_object)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
+ acpi_format_exception(status),
+ sleep_state_name, info.return_object,
+ acpi_ut_get_object_type_name(info.
+ return_object)));
}
- acpi_ut_remove_reference (info.return_object);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(info.return_object);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_sleep_type_data);
+EXPORT_SYMBOL(acpi_get_sleep_type_data);
/*******************************************************************************
*
@@ -242,22 +227,20 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data);
*
******************************************************************************/
-struct acpi_bit_register_info *
-acpi_hw_get_bit_register_info (
- u32 register_id)
+struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
{
- ACPI_FUNCTION_NAME ("hw_get_bit_register_info");
-
+ ACPI_FUNCTION_NAME("hw_get_bit_register_info");
if (register_id > ACPI_BITREG_MAX) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid bit_register ID: %X\n", register_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid bit_register ID: %X\n",
+ register_id));
return (NULL);
}
return (&acpi_gbl_bit_register_info[register_id]);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_register
@@ -273,59 +256,56 @@ acpi_hw_get_bit_register_info (
*
******************************************************************************/
-acpi_status
-acpi_get_register (
- u32 register_id,
- u32 *return_value,
- u32 flags)
+acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags)
{
- u32 register_value = 0;
- struct acpi_bit_register_info *bit_reg_info;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_register");
+ u32 register_value = 0;
+ struct acpi_bit_register_info *bit_reg_info;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_get_register");
/* Get the info structure corresponding to the requested ACPI Register */
- bit_reg_info = acpi_hw_get_bit_register_info (register_id);
+ bit_reg_info = acpi_hw_get_bit_register_info(register_id);
if (!bit_reg_info) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (flags & ACPI_MTX_LOCK) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Read from the register */
- status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
- bit_reg_info->parent_register, &register_value);
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ bit_reg_info->parent_register,
+ &register_value);
if (flags & ACPI_MTX_LOCK) {
- (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/* Normalize the value that was read */
- register_value = ((register_value & bit_reg_info->access_bit_mask)
- >> bit_reg_info->bit_position);
+ register_value =
+ ((register_value & bit_reg_info->access_bit_mask)
+ >> bit_reg_info->bit_position);
*return_value = register_value;
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %8.8X register %X\n",
- register_value, bit_reg_info->parent_register));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
+ register_value,
+ bit_reg_info->parent_register));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_register);
+EXPORT_SYMBOL(acpi_get_register);
/*******************************************************************************
*
@@ -342,40 +322,36 @@ EXPORT_SYMBOL(acpi_get_register);
*
******************************************************************************/
-acpi_status
-acpi_set_register (
- u32 register_id,
- u32 value,
- u32 flags)
+acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
{
- u32 register_value = 0;
- struct acpi_bit_register_info *bit_reg_info;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_U32 ("acpi_set_register", register_id);
+ u32 register_value = 0;
+ struct acpi_bit_register_info *bit_reg_info;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_U32("acpi_set_register", register_id);
/* Get the info structure corresponding to the requested ACPI Register */
- bit_reg_info = acpi_hw_get_bit_register_info (register_id);
+ bit_reg_info = acpi_hw_get_bit_register_info(register_id);
if (!bit_reg_info) {
- ACPI_REPORT_ERROR (("Bad ACPI HW register_id: %X\n", register_id));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("Bad ACPI HW register_id: %X\n",
+ register_id));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (flags & ACPI_MTX_LOCK) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Always do a register read first so we can insert the new bits */
- status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
- bit_reg_info->parent_register, &register_value);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ bit_reg_info->parent_register,
+ &register_value);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
@@ -395,26 +371,30 @@ acpi_set_register (
* information is the single bit we're interested in, all others should
* be written as 0 so they will be left unchanged.
*/
- value = ACPI_REGISTER_PREPARE_BITS (value,
- bit_reg_info->bit_position, bit_reg_info->access_bit_mask);
+ value = ACPI_REGISTER_PREPARE_BITS(value,
+ bit_reg_info->bit_position,
+ bit_reg_info->
+ access_bit_mask);
if (value) {
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS, (u16) value);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS,
+ (u16) value);
register_value = 0;
}
break;
-
case ACPI_REGISTER_PM1_ENABLE:
- ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask, value);
+ ACPI_REGISTER_INSERT_VALUE(register_value,
+ bit_reg_info->bit_position,
+ bit_reg_info->access_bit_mask,
+ value);
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_ENABLE, (u16) register_value);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_ENABLE,
+ (u16) register_value);
break;
-
case ACPI_REGISTER_PM1_CONTROL:
/*
@@ -422,65 +402,73 @@ acpi_set_register (
* Note that at this level, the fact that there are actually TWO
* registers (A and B - and B may not exist) is abstracted.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", register_value));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
+ register_value));
- ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask, value);
+ ACPI_REGISTER_INSERT_VALUE(register_value,
+ bit_reg_info->bit_position,
+ bit_reg_info->access_bit_mask,
+ value);
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
+ (u16) register_value);
break;
-
case ACPI_REGISTER_PM2_CONTROL:
- status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM2_CONTROL, &register_value);
- if (ACPI_FAILURE (status)) {
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM2_CONTROL,
+ &register_value);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64 (
- acpi_gbl_FADT->xpm2_cnt_blk.address)));
-
- ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask, value);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64 (
- acpi_gbl_FADT->xpm2_cnt_blk.address)));
-
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "PM2 control: Read %X from %8.8X%8.8X\n",
+ register_value,
+ ACPI_FORMAT_UINT64(acpi_gbl_FADT->
+ xpm2_cnt_blk.address)));
+
+ ACPI_REGISTER_INSERT_VALUE(register_value,
+ bit_reg_info->bit_position,
+ bit_reg_info->access_bit_mask,
+ value);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "About to write %4.4X to %8.8X%8.8X\n",
+ register_value,
+ ACPI_FORMAT_UINT64(acpi_gbl_FADT->
+ xpm2_cnt_blk.address)));
+
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM2_CONTROL,
+ (u8) (register_value));
break;
-
default:
break;
}
-
-unlock_and_exit:
+ unlock_and_exit:
if (flags & ACPI_MTX_LOCK) {
- (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
}
/* Normalize the value that was read */
- ACPI_DEBUG_EXEC (register_value =
- ((register_value & bit_reg_info->access_bit_mask) >>
- bit_reg_info->bit_position));
+ ACPI_DEBUG_EXEC(register_value =
+ ((register_value & bit_reg_info->access_bit_mask) >>
+ bit_reg_info->bit_position));
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n",
- value, register_value, bit_reg_info->parent_register));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "Set bits: %8.8X actual %8.8X register %X\n", value,
+ register_value, bit_reg_info->parent_register));
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_set_register);
+EXPORT_SYMBOL(acpi_set_register);
/******************************************************************************
*
@@ -498,103 +486,107 @@ EXPORT_SYMBOL(acpi_set_register);
******************************************************************************/
acpi_status
-acpi_hw_register_read (
- u8 use_lock,
- u32 register_id,
- u32 *return_value)
+acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
{
- u32 value1 = 0;
- u32 value2 = 0;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("hw_register_read");
+ u32 value1 = 0;
+ u32 value2 = 0;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("hw_register_read");
if (ACPI_MTX_LOCK == use_lock) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
+ case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
- status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_read(16, &value1,
+ &acpi_gbl_FADT->xpm1a_evt_blk);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* PM1B is optional */
- status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk);
+ status =
+ acpi_hw_low_level_read(16, &value2,
+ &acpi_gbl_FADT->xpm1b_evt_blk);
value1 |= value2;
break;
+ case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
-
- status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* PM1B is optional */
- status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_xpm1b_enable);
+ status =
+ acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable);
value1 |= value2;
break;
+ case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
-
- status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_read(16, &value1,
+ &acpi_gbl_FADT->xpm1a_cnt_blk);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk);
+ status =
+ acpi_hw_low_level_read(16, &value2,
+ &acpi_gbl_FADT->xpm1b_cnt_blk);
value1 |= value2;
break;
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
-
- status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk);
+ status =
+ acpi_hw_low_level_read(8, &value1,
+ &acpi_gbl_FADT->xpm2_cnt_blk);
break;
+ case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
- case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
-
- status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk);
+ status =
+ acpi_hw_low_level_read(32, &value1,
+ &acpi_gbl_FADT->xpm_tmr_blk);
break;
- case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
+ case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
- status = acpi_os_read_port (acpi_gbl_FADT->smi_cmd, &value1, 8);
+ status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8);
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n",
- register_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown Register ID: %X\n",
+ register_id));
status = AE_BAD_PARAMETER;
break;
}
-unlock_and_exit:
+ unlock_and_exit:
if (ACPI_MTX_LOCK == use_lock) {
- (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
*return_value = value1;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_register_write
@@ -610,109 +602,112 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
-acpi_hw_register_write (
- u8 use_lock,
- u32 register_id,
- u32 value)
+acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("hw_register_write");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("hw_register_write");
if (ACPI_MTX_LOCK == use_lock) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
+ case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_write(16, value,
+ &acpi_gbl_FADT->xpm1a_evt_blk);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* PM1B is optional */
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk);
+ status =
+ acpi_hw_low_level_write(16, value,
+ &acpi_gbl_FADT->xpm1b_evt_blk);
break;
+ case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/
-
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* PM1B is optional */
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1b_enable);
+ status =
+ acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable);
break;
+ case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
-
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_hw_low_level_write(16, value,
+ &acpi_gbl_FADT->xpm1a_cnt_blk);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
+ status =
+ acpi_hw_low_level_write(16, value,
+ &acpi_gbl_FADT->xpm1b_cnt_blk);
break;
+ case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
- case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
-
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
+ status =
+ acpi_hw_low_level_write(16, value,
+ &acpi_gbl_FADT->xpm1a_cnt_blk);
break;
+ case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
- case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
-
- status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
+ status =
+ acpi_hw_low_level_write(16, value,
+ &acpi_gbl_FADT->xpm1b_cnt_blk);
break;
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
-
- status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk);
+ status =
+ acpi_hw_low_level_write(8, value,
+ &acpi_gbl_FADT->xpm2_cnt_blk);
break;
+ case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
- case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
-
- status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk);
+ status =
+ acpi_hw_low_level_write(32, value,
+ &acpi_gbl_FADT->xpm_tmr_blk);
break;
-
- case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
+ case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
/* SMI_CMD is currently always in IO space */
- status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, value, 8);
+ status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8);
break;
-
default:
status = AE_BAD_PARAMETER;
break;
}
-unlock_and_exit:
+ unlock_and_exit:
if (ACPI_MTX_LOCK == use_lock) {
- (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_low_level_read
@@ -728,17 +723,12 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_hw_low_level_read (
- u32 width,
- u32 *value,
- struct acpi_generic_address *reg)
+acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
{
- u64 address;
- acpi_status status;
-
-
- ACPI_FUNCTION_NAME ("hw_low_level_read");
+ u64 address;
+ acpi_status status;
+ ACPI_FUNCTION_NAME("hw_low_level_read");
/*
* Must have a valid pointer to a GAS structure, and
@@ -751,7 +741,7 @@ acpi_hw_low_level_read (
/* Get a local copy of the address. Handles possible alignment issues */
- ACPI_MOVE_64_TO_64 (&address, &reg->address);
+ ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
return (AE_OK);
}
@@ -764,35 +754,32 @@ acpi_hw_low_level_read (
switch (reg->address_space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- status = acpi_os_read_memory (
- (acpi_physical_address) address,
- value, width);
+ status = acpi_os_read_memory((acpi_physical_address) address,
+ value, width);
break;
-
case ACPI_ADR_SPACE_SYSTEM_IO:
- status = acpi_os_read_port ((acpi_io_address) address,
- value, width);
+ status = acpi_os_read_port((acpi_io_address) address,
+ value, width);
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unsupported address space: %X\n", reg->address_space_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unsupported address space: %X\n",
+ reg->address_space_id));
return (AE_BAD_PARAMETER);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
- *value, width,
- ACPI_FORMAT_UINT64 (address),
- acpi_ut_get_region_name (reg->address_space_id)));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
+ *value, width,
+ ACPI_FORMAT_UINT64(address),
+ acpi_ut_get_region_name(reg->address_space_id)));
return (status);
}
-
/******************************************************************************
*
* FUNCTION: acpi_hw_low_level_write
@@ -808,17 +795,12 @@ acpi_hw_low_level_read (
******************************************************************************/
acpi_status
-acpi_hw_low_level_write (
- u32 width,
- u32 value,
- struct acpi_generic_address *reg)
+acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
{
- u64 address;
- acpi_status status;
-
-
- ACPI_FUNCTION_NAME ("hw_low_level_write");
+ u64 address;
+ acpi_status status;
+ ACPI_FUNCTION_NAME("hw_low_level_write");
/*
* Must have a valid pointer to a GAS structure, and
@@ -831,7 +813,7 @@ acpi_hw_low_level_write (
/* Get a local copy of the address. Handles possible alignment issues */
- ACPI_MOVE_64_TO_64 (&address, &reg->address);
+ ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
return (AE_OK);
}
@@ -843,30 +825,28 @@ acpi_hw_low_level_write (
switch (reg->address_space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- status = acpi_os_write_memory (
- (acpi_physical_address) address,
- value, width);
+ status = acpi_os_write_memory((acpi_physical_address) address,
+ value, width);
break;
-
case ACPI_ADR_SPACE_SYSTEM_IO:
- status = acpi_os_write_port ((acpi_io_address) address,
- value, width);
+ status = acpi_os_write_port((acpi_io_address) address,
+ value, width);
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unsupported address space: %X\n", reg->address_space_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unsupported address space: %X\n",
+ reg->address_space_id));
return (AE_BAD_PARAMETER);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
- value, width,
- ACPI_FORMAT_UINT64 (address),
- acpi_ut_get_region_name (reg->address_space_id)));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
+ value, width,
+ ACPI_FORMAT_UINT64(address),
+ acpi_ut_get_region_name(reg->address_space_id)));
return (status);
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 415d342aeab5..34519069050c 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -46,8 +46,7 @@
#include <acpi/acpi.h>
#define _COMPONENT ACPI_HARDWARE
- ACPI_MODULE_NAME ("hwsleep")
-
+ACPI_MODULE_NAME("hwsleep")
/*******************************************************************************
*
@@ -61,30 +60,25 @@
* DESCRIPTION: Access function for the firmware_waking_vector field in FACS
*
******************************************************************************/
-
acpi_status
-acpi_set_firmware_waking_vector (
- acpi_physical_address physical_address)
+acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
{
- ACPI_FUNCTION_TRACE ("acpi_set_firmware_waking_vector");
-
+ ACPI_FUNCTION_TRACE("acpi_set_firmware_waking_vector");
/* Set the vector */
if (acpi_gbl_common_fACS.vector_width == 32) {
- *(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector))
- = (u32) physical_address;
- }
- else {
- *acpi_gbl_common_fACS.firmware_waking_vector
- = physical_address;
+ *(ACPI_CAST_PTR
+ (u32, acpi_gbl_common_fACS.firmware_waking_vector))
+ = (u32) physical_address;
+ } else {
+ *acpi_gbl_common_fACS.firmware_waking_vector = physical_address;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_firmware_waking_vector
@@ -101,33 +95,31 @@ acpi_set_firmware_waking_vector (
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_get_firmware_waking_vector (
- acpi_physical_address *physical_address)
+acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
{
- ACPI_FUNCTION_TRACE ("acpi_get_firmware_waking_vector");
-
+ ACPI_FUNCTION_TRACE("acpi_get_firmware_waking_vector");
if (!physical_address) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the vector */
if (acpi_gbl_common_fACS.vector_width == 32) {
*physical_address = (acpi_physical_address)
- *(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector));
- }
- else {
+ *
+ (ACPI_CAST_PTR
+ (u32, acpi_gbl_common_fACS.firmware_waking_vector));
+ } else {
*physical_address =
- *acpi_gbl_common_fACS.firmware_waking_vector;
+ *acpi_gbl_common_fACS.firmware_waking_vector;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state_prep
@@ -143,25 +135,22 @@ acpi_get_firmware_waking_vector (
*
******************************************************************************/
-acpi_status
-acpi_enter_sleep_state_prep (
- u8 sleep_state)
+acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
{
- acpi_status status;
- struct acpi_object_list arg_list;
- union acpi_object arg;
-
-
- ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_prep");
+ acpi_status status;
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
+ ACPI_FUNCTION_TRACE("acpi_enter_sleep_state_prep");
/*
* _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
*/
- status = acpi_get_sleep_type_data (sleep_state,
- &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_get_sleep_type_data(sleep_state,
+ &acpi_gbl_sleep_type_a,
+ &acpi_gbl_sleep_type_b);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Setup parameter object */
@@ -174,14 +163,14 @@ acpi_enter_sleep_state_prep (
/* Run the _PTS and _GTS methods */
- status = acpi_evaluate_object (NULL, METHOD_NAME__PTS, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- return_ACPI_STATUS (status);
+ status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ return_ACPI_STATUS(status);
}
- status = acpi_evaluate_object (NULL, METHOD_NAME__GTS, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- return_ACPI_STATUS (status);
+ status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ return_ACPI_STATUS(status);
}
/* Setup the argument to _SST */
@@ -202,22 +191,21 @@ acpi_enter_sleep_state_prep (
break;
default:
- arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */
+ arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */
break;
}
/* Set the system indicators to show the desired sleep state. */
- status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
- acpi_format_exception (status)));
+ status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_REPORT_ERROR(("Method _SST failed, %s\n",
+ acpi_format_exception(status)));
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state
@@ -231,80 +219,82 @@ acpi_enter_sleep_state_prep (
*
******************************************************************************/
-acpi_status asmlinkage
-acpi_enter_sleep_state (
- u8 sleep_state)
+acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
{
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
- struct acpi_bit_register_info *sleep_type_reg_info;
- struct acpi_bit_register_info *sleep_enable_reg_info;
- u32 in_value;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state");
+ u32 PM1Acontrol;
+ u32 PM1Bcontrol;
+ struct acpi_bit_register_info *sleep_type_reg_info;
+ struct acpi_bit_register_info *sleep_enable_reg_info;
+ u32 in_value;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_enter_sleep_state");
if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
- (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
- ACPI_REPORT_ERROR (("Sleep values out of range: A=%X B=%X\n",
- acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
- return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
+ ACPI_REPORT_ERROR(("Sleep values out of range: A=%X B=%X\n",
+ acpi_gbl_sleep_type_a,
+ acpi_gbl_sleep_type_b));
+ return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
}
- sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
- sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
+ sleep_type_reg_info =
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ sleep_enable_reg_info =
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Clear wake status */
- status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Clear all fixed and general purpose status bits */
- status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs
*/
- status = acpi_hw_disable_all_gpes (ACPI_ISR);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_disable_all_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
acpi_gbl_system_awake_and_running = FALSE;
- status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_enable_all_wakeup_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get current value of PM1A control */
- status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "Entering sleep state [S%d]\n", sleep_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "Entering sleep state [S%d]\n", sleep_state));
/* Clear SLP_EN and SLP_TYP fields */
PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->access_bit_mask);
+ sleep_enable_reg_info->access_bit_mask);
PM1Bcontrol = PM1Acontrol;
/* Insert SLP_TYP bits */
- PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
- PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
+ PM1Acontrol |=
+ (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
+ PM1Bcontrol |=
+ (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
/*
* We split the writes of SLP_TYP and SLP_EN to workaround
@@ -313,16 +303,18 @@ acpi_enter_sleep_state (
/* Write #1: fill in SLP_TYP data */
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL,
+ PM1Acontrol);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL,
+ PM1Bcontrol);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Insert SLP_ENABLE bit */
@@ -332,18 +324,20 @@ acpi_enter_sleep_state (
/* Write #2: SLP_TYP + SLP_EN */
- ACPI_FLUSH_CPU_CACHE ();
+ ACPI_FLUSH_CPU_CACHE();
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL,
+ PM1Acontrol);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL,
+ PM1Bcontrol);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
if (sleep_state > ACPI_STATE_S3) {
@@ -358,33 +352,34 @@ acpi_enter_sleep_state (
* still read the right value. Ideally, this block would go
* away entirely.
*/
- acpi_os_stall (10000000);
-
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL,
- sleep_enable_reg_info->access_bit_mask);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ acpi_os_stall(10000000);
+
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
+ sleep_enable_reg_info->
+ access_bit_mask);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Wait until we enter sleep state */
do {
- status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value,
- ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value,
+ ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Spin until we wake */
} while (!in_value);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_enter_sleep_state);
+EXPORT_SYMBOL(acpi_enter_sleep_state);
/*******************************************************************************
*
@@ -399,60 +394,57 @@ EXPORT_SYMBOL(acpi_enter_sleep_state);
*
******************************************************************************/
-acpi_status asmlinkage
-acpi_enter_sleep_state_s4bios (
- void)
+acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
{
- u32 in_value;
- acpi_status status;
-
+ u32 in_value;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
+ ACPI_FUNCTION_TRACE("acpi_enter_sleep_state_s4bios");
-
- status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs
*/
- status = acpi_hw_disable_all_gpes (ACPI_ISR);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_disable_all_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
acpi_gbl_system_awake_and_running = FALSE;
- status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_enable_all_wakeup_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_FLUSH_CPU_CACHE ();
+ ACPI_FLUSH_CPU_CACHE();
- status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
- (u32) acpi_gbl_FADT->S4bios_req, 8);
+ status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
+ (u32) acpi_gbl_FADT->S4bios_req, 8);
do {
acpi_os_stall(1000);
- status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value,
- ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value,
+ ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
} while (!in_value);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
+EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
/*******************************************************************************
*
@@ -467,55 +459,62 @@ EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
*
******************************************************************************/
-acpi_status
-acpi_leave_sleep_state (
- u8 sleep_state)
+acpi_status acpi_leave_sleep_state(u8 sleep_state)
{
- struct acpi_object_list arg_list;
- union acpi_object arg;
- acpi_status status;
- struct acpi_bit_register_info *sleep_type_reg_info;
- struct acpi_bit_register_info *sleep_enable_reg_info;
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
-
-
- ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state");
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
+ acpi_status status;
+ struct acpi_bit_register_info *sleep_type_reg_info;
+ struct acpi_bit_register_info *sleep_enable_reg_info;
+ u32 PM1Acontrol;
+ u32 PM1Bcontrol;
+ ACPI_FUNCTION_TRACE("acpi_leave_sleep_state");
/*
* Set SLP_TYPE and SLP_EN to state S0.
* This is unclear from the ACPI Spec, but it is required
* by some machines.
*/
- status = acpi_get_sleep_type_data (ACPI_STATE_S0,
- &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b);
- if (ACPI_SUCCESS (status)) {
- sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
- sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
+ status = acpi_get_sleep_type_data(ACPI_STATE_S0,
+ &acpi_gbl_sleep_type_a,
+ &acpi_gbl_sleep_type_b);
+ if (ACPI_SUCCESS(status)) {
+ sleep_type_reg_info =
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ sleep_enable_reg_info =
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Get current value of PM1A control */
- status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
+ &PM1Acontrol);
+ if (ACPI_SUCCESS(status)) {
/* Clear SLP_EN and SLP_TYP fields */
PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->access_bit_mask);
+ sleep_enable_reg_info->
+ access_bit_mask);
PM1Bcontrol = PM1Acontrol;
/* Insert SLP_TYP bits */
- PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
- PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
+ PM1Acontrol |=
+ (acpi_gbl_sleep_type_a << sleep_type_reg_info->
+ bit_position);
+ PM1Bcontrol |=
+ (acpi_gbl_sleep_type_b << sleep_type_reg_info->
+ bit_position);
/* Just ignore any errors */
- (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
- (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+ (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL,
+ PM1Acontrol);
+ (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL,
+ PM1Bcontrol);
}
}
@@ -532,23 +531,23 @@ acpi_leave_sleep_state (
/* Ignore any errors from these methods */
arg.integer.value = ACPI_SST_WAKING;
- status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
- acpi_format_exception (status)));
+ status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_REPORT_ERROR(("Method _SST failed, %s\n",
+ acpi_format_exception(status)));
}
arg.integer.value = sleep_state;
- status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _BFS failed, %s\n",
- acpi_format_exception (status)));
+ status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_REPORT_ERROR(("Method _BFS failed, %s\n",
+ acpi_format_exception(status)));
}
- status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _WAK failed, %s\n",
- acpi_format_exception (status)));
+ status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_REPORT_ERROR(("Method _WAK failed, %s\n",
+ acpi_format_exception(status)));
}
/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
@@ -557,33 +556,35 @@ acpi_leave_sleep_state (
* 1) Disable/Clear all GPEs
* 2) Enable all runtime GPEs
*/
- status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_disable_all_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
acpi_gbl_system_awake_and_running = TRUE;
- status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_enable_all_runtime_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Enable power button */
- (void) acpi_set_register(
- acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
- 1, ACPI_MTX_DO_NOT_LOCK);
+ (void)
+ acpi_set_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1,
+ ACPI_MTX_DO_NOT_LOCK);
- (void) acpi_set_register(
- acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
- 1, ACPI_MTX_DO_NOT_LOCK);
+ (void)
+ acpi_set_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].status_register_id, 1,
+ ACPI_MTX_DO_NOT_LOCK);
arg.integer.value = ACPI_SST_WORKING;
- status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
- if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
- acpi_format_exception (status)));
+ status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_REPORT_ERROR(("Method _SST failed, %s\n",
+ acpi_format_exception(status)));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index 49d7b395322e..aff6dc141784 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -46,8 +46,7 @@
#include <acpi/acpi.h>
#define _COMPONENT ACPI_HARDWARE
- ACPI_MODULE_NAME ("hwtimer")
-
+ACPI_MODULE_NAME("hwtimer")
/******************************************************************************
*
@@ -60,29 +59,23 @@
* DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
*
******************************************************************************/
-
-acpi_status
-acpi_get_timer_resolution (
- u32 *resolution)
+acpi_status acpi_get_timer_resolution(u32 * resolution)
{
- ACPI_FUNCTION_TRACE ("acpi_get_timer_resolution");
-
+ ACPI_FUNCTION_TRACE("acpi_get_timer_resolution");
if (!resolution) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (0 == acpi_gbl_FADT->tmr_val_ext) {
*resolution = 24;
- }
- else {
+ } else {
*resolution = 32;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_get_timer
@@ -95,26 +88,22 @@ acpi_get_timer_resolution (
*
******************************************************************************/
-acpi_status
-acpi_get_timer (
- u32 *ticks)
+acpi_status acpi_get_timer(u32 * ticks)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_timer");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_get_timer");
if (!ticks) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
+ status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_timer);
+EXPORT_SYMBOL(acpi_get_timer);
/******************************************************************************
*
@@ -146,21 +135,16 @@ EXPORT_SYMBOL(acpi_get_timer);
******************************************************************************/
acpi_status
-acpi_get_timer_duration (
- u32 start_ticks,
- u32 end_ticks,
- u32 *time_elapsed)
+acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
{
- acpi_status status;
- u32 delta_ticks;
- acpi_integer quotient;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_timer_duration");
+ acpi_status status;
+ u32 delta_ticks;
+ acpi_integer quotient;
+ ACPI_FUNCTION_TRACE("acpi_get_timer_duration");
if (!time_elapsed) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -169,22 +153,22 @@ acpi_get_timer_duration (
*/
if (start_ticks < end_ticks) {
delta_ticks = end_ticks - start_ticks;
- }
- else if (start_ticks > end_ticks) {
+ } else if (start_ticks > end_ticks) {
if (0 == acpi_gbl_FADT->tmr_val_ext) {
/* 24-bit Timer */
- delta_ticks = (((0x00FFFFFF - start_ticks) + end_ticks) & 0x00FFFFFF);
- }
- else {
+ delta_ticks =
+ (((0x00FFFFFF - start_ticks) +
+ end_ticks) & 0x00FFFFFF);
+ } else {
/* 32-bit Timer */
delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks;
}
- }
- else /* start_ticks == end_ticks */ {
+ } else { /* start_ticks == end_ticks */
+
*time_elapsed = 0;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -192,12 +176,11 @@ acpi_get_timer_duration (
*
* time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY;
*/
- status = acpi_ut_short_divide (((u64) delta_ticks) * 1000000,
- PM_TIMER_FREQUENCY, &quotient, NULL);
+ status = acpi_ut_short_divide(((u64) delta_ticks) * 1000000,
+ PM_TIMER_FREQUENCY, &quotient, NULL);
*time_elapsed = (u32) quotient;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
EXPORT_SYMBOL(acpi_get_timer_duration);
-
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
index 1f76a40badec..2e2e4051dfa7 100644
--- a/drivers/acpi/hotkey.c
+++ b/drivers/acpi/hotkey.c
@@ -62,7 +62,7 @@
#define _COMPONENT ACPI_HOTKEY_COMPONENT
ACPI_MODULE_NAME("acpi_hotkey")
-MODULE_AUTHOR("luming.yu@intel.com");
+ MODULE_AUTHOR("luming.yu@intel.com");
MODULE_DESCRIPTION(ACPI_HOTK_NAME);
MODULE_LICENSE("GPL");
@@ -180,8 +180,8 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
static union acpi_hotkey *get_hotkey_by_event(struct
- acpi_hotkey_list
- *hotkey_list, int event);
+ acpi_hotkey_list
+ *hotkey_list, int event);
/* event based config */
static struct file_operations hotkey_config_fops = {
@@ -246,7 +246,7 @@ static int hotkey_info_open_fs(struct inode *inode, struct file *file)
static char *format_result(union acpi_object *object)
{
char *buf = NULL;
-
+
buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
if (buf)
memset(buf, 0, RESULT_STR_LEN);
@@ -256,7 +256,7 @@ static char *format_result(union acpi_object *object)
/* Now, just support integer type */
if (object->type == ACPI_TYPE_INTEGER)
sprintf(buf, "%d\n", (u32) object->integer.value);
-do_fail:
+ do_fail:
return (buf);
}
@@ -268,9 +268,9 @@ static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");
- if (poll_hotkey->poll_result){
+ if (poll_hotkey->poll_result) {
buf = format_result(poll_hotkey->poll_result);
- if(buf)
+ if (buf)
seq_printf(seq, "%s", buf);
kfree(buf);
}
@@ -299,7 +299,7 @@ static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
union acpi_hotkey *key =
container_of(entries, union acpi_hotkey, entries);
if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
- && key->event_hotkey.external_hotkey_num == event){
+ && key->event_hotkey.external_hotkey_num == event) {
val = key->link.hotkey_standard_num;
break;
}
@@ -343,7 +343,7 @@ static int auto_hotkey_remove(struct acpi_device *device, int type)
static int create_polling_proc(union acpi_hotkey *device)
{
struct proc_dir_entry *proc;
- char proc_name[80];
+ char proc_name[80];
mode_t mode;
ACPI_FUNCTION_TRACE("create_polling_proc");
@@ -351,8 +351,8 @@ static int create_polling_proc(union acpi_hotkey *device)
sprintf(proc_name, "%d", device->link.hotkey_standard_num);
/*
- strcat(proc_name, device->poll_hotkey.poll_method);
- */
+ strcat(proc_name, device->poll_hotkey.poll_method);
+ */
proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
if (!proc) {
@@ -415,50 +415,50 @@ static int hotkey_remove(union acpi_hotkey *device)
return_VALUE(0);
}
-static int hotkey_update(union acpi_hotkey *key)
+static int hotkey_update(union acpi_hotkey *key)
{
struct list_head *entries;
ACPI_FUNCTION_TRACE("hotkey_update");
list_for_each(entries, global_hotkey_list.entries) {
- union acpi_hotkey *tmp=
+ union acpi_hotkey *tmp =
container_of(entries, union acpi_hotkey, entries);
if (tmp->link.hotkey_standard_num ==
key->link.hotkey_standard_num) {
if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
free_hotkey_buffer(tmp);
tmp->event_hotkey.bus_handle =
- key->event_hotkey.bus_handle;
+ key->event_hotkey.bus_handle;
tmp->event_hotkey.external_hotkey_num =
- key->event_hotkey.external_hotkey_num;
+ key->event_hotkey.external_hotkey_num;
tmp->event_hotkey.action_handle =
- key->event_hotkey.action_handle;
+ key->event_hotkey.action_handle;
tmp->event_hotkey.action_method =
- key->event_hotkey.action_method;
+ key->event_hotkey.action_method;
kfree(key);
} else {
/*
- char proc_name[80];
+ char proc_name[80];
- sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
- strcat(proc_name, tmp->poll_hotkey.poll_method);
- remove_proc_entry(proc_name,hotkey_proc_dir);
- */
+ sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
+ strcat(proc_name, tmp->poll_hotkey.poll_method);
+ remove_proc_entry(proc_name,hotkey_proc_dir);
+ */
free_poll_hotkey_buffer(tmp);
tmp->poll_hotkey.poll_handle =
- key->poll_hotkey.poll_handle;
+ key->poll_hotkey.poll_handle;
tmp->poll_hotkey.poll_method =
- key->poll_hotkey.poll_method;
+ key->poll_hotkey.poll_method;
tmp->poll_hotkey.action_handle =
- key->poll_hotkey.action_handle;
+ key->poll_hotkey.action_handle;
tmp->poll_hotkey.action_method =
- key->poll_hotkey.action_method;
+ key->poll_hotkey.action_method;
tmp->poll_hotkey.poll_result =
- key->poll_hotkey.poll_result;
+ key->poll_hotkey.poll_result;
/*
- create_polling_proc(tmp);
- */
+ create_polling_proc(tmp);
+ */
kfree(key);
}
return_VALUE(0);
@@ -483,27 +483,25 @@ static void free_hotkey_device(union acpi_hotkey *key)
acpi_hotkey_notify_handler);
free_hotkey_buffer(key);
} else {
- char proc_name[80];
+ char proc_name[80];
sprintf(proc_name, "%d", key->link.hotkey_standard_num);
/*
- strcat(proc_name, key->poll_hotkey.poll_method);
- */
- remove_proc_entry(proc_name,hotkey_proc_dir);
+ strcat(proc_name, key->poll_hotkey.poll_method);
+ */
+ remove_proc_entry(proc_name, hotkey_proc_dir);
free_poll_hotkey_buffer(key);
}
kfree(key);
return_VOID;
}
-static void
-free_hotkey_buffer(union acpi_hotkey *key)
+static void free_hotkey_buffer(union acpi_hotkey *key)
{
kfree(key->event_hotkey.action_method);
}
-static void
-free_poll_hotkey_buffer(union acpi_hotkey *key)
+static void free_poll_hotkey_buffer(union acpi_hotkey *key)
{
kfree(key->poll_hotkey.action_method);
kfree(key->poll_hotkey.poll_method);
@@ -513,15 +511,15 @@ static int
init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
char *method, int std_num, int external_num)
{
- acpi_handle tmp_handle;
+ acpi_handle tmp_handle;
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("init_hotkey_device");
- if(std_num < 0 || IS_POLL(std_num) || !key )
+ if (std_num < 0 || IS_POLL(std_num) || !key)
goto do_fail;
- if(!bus_str || !action_str || !method)
+ if (!bus_str || !action_str || !method)
goto do_fail;
key->link.hotkey_type = ACPI_HOTKEY_EVENT;
@@ -529,19 +527,22 @@ init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
key->event_hotkey.flag = 0;
key->event_hotkey.action_method = method;
- status = acpi_get_handle(NULL,bus_str, &(key->event_hotkey.bus_handle));
- if(ACPI_FAILURE(status))
+ status =
+ acpi_get_handle(NULL, bus_str, &(key->event_hotkey.bus_handle));
+ if (ACPI_FAILURE(status))
goto do_fail;
key->event_hotkey.external_hotkey_num = external_num;
- status = acpi_get_handle(NULL,action_str, &(key->event_hotkey.action_handle));
- if(ACPI_FAILURE(status))
+ status =
+ acpi_get_handle(NULL, action_str,
+ &(key->event_hotkey.action_handle));
+ if (ACPI_FAILURE(status))
goto do_fail;
status = acpi_get_handle(key->event_hotkey.action_handle,
- method, &tmp_handle);
+ method, &tmp_handle);
if (ACPI_FAILURE(status))
goto do_fail;
return_VALUE(AE_OK);
-do_fail:
+ do_fail:
return_VALUE(-ENODEV);
}
@@ -552,14 +553,14 @@ init_poll_hotkey_device(union acpi_hotkey *key,
char *action_str, char *action_method, int std_num)
{
acpi_status status = AE_OK;
- acpi_handle tmp_handle;
+ acpi_handle tmp_handle;
ACPI_FUNCTION_TRACE("init_poll_hotkey_device");
- if(std_num < 0 || IS_EVENT(std_num) || !key)
+ if (std_num < 0 || IS_EVENT(std_num) || !key)
goto do_fail;
- if(!poll_str || !poll_method || !action_str || !action_method)
+ if (!poll_str || !poll_method || !action_str || !action_method)
goto do_fail;
key->link.hotkey_type = ACPI_HOTKEY_POLLING;
@@ -568,30 +569,32 @@ init_poll_hotkey_device(union acpi_hotkey *key,
key->poll_hotkey.poll_method = poll_method;
key->poll_hotkey.action_method = action_method;
- status = acpi_get_handle(NULL,poll_str, &(key->poll_hotkey.poll_handle));
- if(ACPI_FAILURE(status))
+ status =
+ acpi_get_handle(NULL, poll_str, &(key->poll_hotkey.poll_handle));
+ if (ACPI_FAILURE(status))
goto do_fail;
status = acpi_get_handle(key->poll_hotkey.poll_handle,
- poll_method, &tmp_handle);
- if (ACPI_FAILURE(status))
- goto do_fail;
- status = acpi_get_handle(NULL,action_str, &(key->poll_hotkey.action_handle));
+ poll_method, &tmp_handle);
+ if (ACPI_FAILURE(status))
+ goto do_fail;
+ status =
+ acpi_get_handle(NULL, action_str,
+ &(key->poll_hotkey.action_handle));
if (ACPI_FAILURE(status))
goto do_fail;
status = acpi_get_handle(key->poll_hotkey.action_handle,
- action_method, &tmp_handle);
+ action_method, &tmp_handle);
if (ACPI_FAILURE(status))
goto do_fail;
key->poll_hotkey.poll_result =
(union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
- if(!key->poll_hotkey.poll_result)
+ if (!key->poll_hotkey.poll_result)
goto do_fail;
return_VALUE(AE_OK);
-do_fail:
+ do_fail:
return_VALUE(-ENODEV);
}
-
static int hotkey_open_config(struct inode *inode, struct file *file)
{
ACPI_FUNCTION_TRACE("hotkey_open_config");
@@ -679,8 +682,9 @@ get_parms(char *config_record,
sscanf(config_record, "%d", cmd);
- if(*cmd == 1){
- if(sscanf(config_record, "%d:%d", cmd, internal_event_num)!=2)
+ if (*cmd == 1) {
+ if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
+ 2)
goto do_fail;
else
return (6);
@@ -694,8 +698,8 @@ get_parms(char *config_record,
goto do_fail;
count = tmp1 - tmp;
- *bus_handle = (char *) kmalloc(count+1, GFP_KERNEL);
- if(!*bus_handle)
+ *bus_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
+ if (!*bus_handle)
goto do_fail;
strncpy(*bus_handle, tmp, count);
*(*bus_handle + count) = 0;
@@ -706,8 +710,8 @@ get_parms(char *config_record,
if (!tmp1)
goto do_fail;
count = tmp1 - tmp;
- *bus_method = (char *) kmalloc(count+1, GFP_KERNEL);
- if(!*bus_method)
+ *bus_method = (char *)kmalloc(count + 1, GFP_KERNEL);
+ if (!*bus_method)
goto do_fail;
strncpy(*bus_method, tmp, count);
*(*bus_method + count) = 0;
@@ -718,7 +722,7 @@ get_parms(char *config_record,
if (!tmp1)
goto do_fail;
count = tmp1 - tmp;
- *action_handle = (char *) kmalloc(count+1, GFP_KERNEL);
+ *action_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
strncpy(*action_handle, tmp, count);
*(*action_handle + count) = 0;
@@ -728,17 +732,18 @@ get_parms(char *config_record,
if (!tmp1)
goto do_fail;
count = tmp1 - tmp;
- *method = (char *) kmalloc(count+1, GFP_KERNEL);
- if(!*method)
+ *method = (char *)kmalloc(count + 1, GFP_KERNEL);
+ if (!*method)
goto do_fail;
strncpy(*method, tmp, count);
*(*method + count) = 0;
- if(sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num)<=0)
+ if (sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num) <=
+ 0)
goto do_fail;
return_VALUE(6);
-do_fail:
+ do_fail:
return_VALUE(-1);
}
@@ -758,8 +763,8 @@ static ssize_t hotkey_write_config(struct file *file,
ACPI_FUNCTION_TRACE(("hotkey_write_config"));
- config_record = (char *) kmalloc(count+1, GFP_KERNEL);
- if(!config_record)
+ config_record = (char *)kmalloc(count + 1, GFP_KERNEL);
+ if (!config_record)
return_VALUE(-ENOMEM);
if (copy_from_user(config_record, buffer, count)) {
@@ -777,10 +782,10 @@ static ssize_t hotkey_write_config(struct file *file,
&method, &internal_event_num, &external_event_num);
kfree(config_record);
- if(IS_OTHERS(internal_event_num))
+ if (IS_OTHERS(internal_event_num))
goto do_fail;
if (ret != 6) {
-do_fail:
+ do_fail:
kfree(bus_handle);
kfree(bus_method);
kfree(action_handle);
@@ -791,14 +796,14 @@ do_fail:
}
key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
- if(!key)
+ if (!key)
goto do_fail;
memset(key, 0, sizeof(union acpi_hotkey));
- if(cmd == 1) {
+ if (cmd == 1) {
union acpi_hotkey *tmp = NULL;
tmp = get_hotkey_by_event(&global_hotkey_list,
- internal_event_num);
- if(!tmp)
+ internal_event_num);
+ if (!tmp)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid key"));
else
memcpy(key, tmp, sizeof(union acpi_hotkey));
@@ -807,15 +812,16 @@ do_fail:
if (IS_EVENT(internal_event_num)) {
kfree(bus_method);
ret = init_hotkey_device(key, bus_handle, action_handle, method,
- internal_event_num, external_event_num);
+ internal_event_num,
+ external_event_num);
} else
ret = init_poll_hotkey_device(key, bus_handle, bus_method,
- action_handle, method,
- internal_event_num);
+ action_handle, method,
+ internal_event_num);
if (ret) {
kfree(bus_handle);
kfree(action_handle);
- if(IS_EVENT(internal_event_num))
+ if (IS_EVENT(internal_event_num))
free_hotkey_buffer(key);
else
free_poll_hotkey_buffer(key);
@@ -824,13 +830,14 @@ do_fail:
return_VALUE(-EINVAL);
}
-cont_cmd:
+ cont_cmd:
kfree(bus_handle);
kfree(action_handle);
switch (cmd) {
case 0:
- if(get_hotkey_by_event(&global_hotkey_list,key->link.hotkey_standard_num))
+ if (get_hotkey_by_event
+ (&global_hotkey_list, key->link.hotkey_standard_num))
goto fail_out;
else
hotkey_add(key);
@@ -839,7 +846,7 @@ cont_cmd:
hotkey_remove(key);
break;
case 2:
- if(hotkey_update(key))
+ if (hotkey_update(key))
goto fail_out;
break;
default:
@@ -847,8 +854,8 @@ cont_cmd:
break;
}
return_VALUE(count);
-fail_out:
- if(IS_EVENT(internal_event_num))
+ fail_out:
+ if (IS_EVENT(internal_event_num))
free_hotkey_buffer(key);
else
free_poll_hotkey_buffer(key);
@@ -882,7 +889,8 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
return_VALUE(status == AE_OK);
}
-static int read_acpi_int(acpi_handle handle, const char *method, union acpi_object *val)
+static int read_acpi_int(acpi_handle handle, const char *method,
+ union acpi_object *val)
{
struct acpi_buffer output;
union acpi_object out_obj;
@@ -893,7 +901,7 @@ static int read_acpi_int(acpi_handle handle, const char *method, union acpi_obje
output.pointer = &out_obj;
status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
- if(val){
+ if (val) {
val->integer.value = out_obj.integer.value;
val->type = out_obj.type;
} else
@@ -903,8 +911,8 @@ static int read_acpi_int(acpi_handle handle, const char *method, union acpi_obje
}
static union acpi_hotkey *get_hotkey_by_event(struct
- acpi_hotkey_list
- *hotkey_list, int event)
+ acpi_hotkey_list
+ *hotkey_list, int event)
{
struct list_head *entries;
@@ -912,10 +920,10 @@ static union acpi_hotkey *get_hotkey_by_event(struct
union acpi_hotkey *key =
container_of(entries, union acpi_hotkey, entries);
if (key->link.hotkey_standard_num == event) {
- return(key);
+ return (key);
}
}
- return(NULL);
+ return (NULL);
}
/*
@@ -932,15 +940,15 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
{
struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
char *arg;
- int event,method_type,type, value;
+ int event, method_type, type, value;
union acpi_hotkey *key;
ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");
- arg = (char *) kmalloc(count+1, GFP_KERNEL);
- if(!arg)
+ arg = (char *)kmalloc(count + 1, GFP_KERNEL);
+ if (!arg)
return_VALUE(-ENOMEM);
- arg[count]=0;
+ arg[count] = 0;
if (copy_from_user(arg, buffer, count)) {
kfree(arg);
@@ -948,7 +956,8 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
return_VALUE(-EINVAL);
}
- if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != 4) {
+ if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) !=
+ 4) {
kfree(arg);
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3"));
return_VALUE(-EINVAL);
@@ -956,19 +965,21 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
kfree(arg);
if (type == ACPI_TYPE_INTEGER) {
key = get_hotkey_by_event(hotkey_list, event);
- if(!key)
+ if (!key)
goto do_fail;
if (IS_EVENT(event))
write_acpi_int(key->event_hotkey.action_handle,
- key->event_hotkey.action_method, value, NULL);
+ key->event_hotkey.action_method, value,
+ NULL);
else if (IS_POLL(event)) {
- if ( method_type == POLL_METHOD )
+ if (method_type == POLL_METHOD)
read_acpi_int(key->poll_hotkey.poll_handle,
- key->poll_hotkey.poll_method,
- key->poll_hotkey.poll_result);
- else if ( method_type == ACTION_METHOD )
+ key->poll_hotkey.poll_method,
+ key->poll_hotkey.poll_result);
+ else if (method_type == ACTION_METHOD)
write_acpi_int(key->poll_hotkey.action_handle,
- key->poll_hotkey.action_method, value, NULL);
+ key->poll_hotkey.action_method,
+ value, NULL);
else
goto do_fail;
@@ -978,7 +989,7 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
return_VALUE(-EINVAL);
}
return_VALUE(count);
-do_fail:
+ do_fail:
return_VALUE(-EINVAL);
}
@@ -1074,15 +1085,15 @@ static int __init hotkey_init(void)
return (0);
-do_fail5:
+ do_fail5:
remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
-do_fail4:
+ do_fail4:
remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
-do_fail3:
+ do_fail3:
remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
-do_fail2:
+ do_fail2:
remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
-do_fail1:
+ do_fail1:
remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
return (-ENODEV);
}
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index ad85e10001f4..5cc090326ddc 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -2,7 +2,7 @@
* ibm_acpi.c - IBM ThinkPad ACPI Extras
*
*
- * Copyright (C) 2004 Borislav Deianov
+ * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.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
@@ -17,38 +17,62 @@
* 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 IBM_VERSION "0.12a"
+
+/*
* Changelog:
- *
- * 2004-08-09 0.1 initial release, support for X series
- * 2004-08-14 0.2 support for T series, X20
- * bluetooth enable/disable
- * hotkey events disabled by default
- * removed fan control, currently useless
- * 2004-08-17 0.3 support for R40
- * lcd off, brightness control
- * thinklight on/off
- * 2004-09-16 0.4 support for module parameters
- * hotkey mask can be prefixed by 0x
- * video output switching
- * video expansion control
- * ultrabay eject support
- * removed lcd brightness/on/off control, didn't work
+ *
+ * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels
+ * 2005-03-17 0.11 support for 600e, 770x
+ * thanks to Jamie Lentin <lentinj@dial.pipex.com>
+ * support for 770e, G41
+ * G40 and G41 don't have a thinklight
+ * temperatures no longer experimental
+ * experimental brightness control
+ * experimental volume control
+ * experimental fan enable/disable
+ * 2005-01-16 0.10 fix module loading on R30, R31
+ * 2005-01-16 0.9 support for 570, R30, R31
+ * ultrabay support on A22p, A3x
+ * limit arg for cmos, led, beep, drop experimental status
+ * more capable led control on A21e, A22p, T20-22, X20
+ * experimental temperatures and fan speed
+ * experimental embedded controller register dump
+ * mark more functions as __init, drop incorrect __exit
+ * use MODULE_VERSION
+ * thanks to Henrik Brix Andersen <brix@gentoo.org>
+ * fix parameter passing on module loading
+ * thanks to Rusty Russell <rusty@rustcorp.com.au>
+ * thanks to Jim Radford <radford@blackbean.org>
+ * 2004-11-08 0.8 fix init error case, don't return from a macro
+ * thanks to Chris Wright <chrisw@osdl.org>
+ * 2004-10-23 0.7 fix module loading on A21e, A22p, T20, T21, X20
+ * fix led control on A21e
+ * 2004-10-19 0.6 use acpi_bus_register_driver() to claim HKEY device
* 2004-10-18 0.5 thinklight support on A21e, G40, R32, T20, T21, X20
* proc file format changed
* video_switch command
* experimental cmos control
* experimental led control
* experimental acpi sounds
- * 2004-10-19 0.6 use acpi_bus_register_driver() to claim HKEY device
- * 2004-10-23 0.7 fix module loading on A21e, A22p, T20, T21, X20
- * fix LED control on A21e
- * 2004-11-08 0.8 fix init error case, don't return from a macro
- * thanks to Chris Wright <chrisw@osdl.org>
+ * 2004-09-16 0.4 support for module parameters
+ * hotkey mask can be prefixed by 0x
+ * video output switching
+ * video expansion control
+ * ultrabay eject support
+ * removed lcd brightness/on/off control, didn't work
+ * 2004-08-17 0.3 support for R40
+ * lcd off, brightness control
+ * thinklight on/off
+ * 2004-08-14 0.2 support for T series, X20
+ * bluetooth enable/disable
+ * hotkey events disabled by default
+ * removed fan control, currently useless
+ * 2004-08-09 0.1 initial release, support for X series
*/
-#define IBM_VERSION "0.8"
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -64,6 +88,11 @@
#define IBM_FILE "ibm_acpi"
#define IBM_URL "http://ibm-acpi.sf.net/"
+MODULE_AUTHOR("Borislav Deianov");
+MODULE_DESCRIPTION(IBM_DESC);
+MODULE_VERSION(IBM_VERSION);
+MODULE_LICENSE("GPL");
+
#define IBM_DIR IBM_NAME
#define IBM_LOG IBM_FILE ": "
@@ -84,54 +113,122 @@ static acpi_handle root_handle = NULL;
#define IBM_HANDLE(object, parent, paths...) \
static acpi_handle object##_handle; \
static acpi_handle *object##_parent = &parent##_handle; \
+ static char *object##_path; \
static char *object##_paths[] = { paths }
-IBM_HANDLE(ec, root,
- "\\_SB.PCI0.ISA.EC", /* A21e, A22p, T20, T21, X20 */
- "\\_SB.PCI0.LPC.EC", /* all others */
-);
-
-IBM_HANDLE(vid, root,
- "\\_SB.PCI0.VID", /* A21e, G40, X30, X40 */
- "\\_SB.PCI0.AGP.VID", /* all others */
-);
-
-IBM_HANDLE(cmos, root,
- "\\UCMS", /* R50, R50p, R51, T4x, X31, X40 */
- "\\CMOS", /* A3x, G40, R32, T23, T30, X22, X24, X30 */
- "\\CMS", /* R40, R40e */
-); /* A21e, A22p, T20, T21, X20 */
-
-IBM_HANDLE(dock, root,
- "\\_SB.GDCK", /* X30, X31, X40 */
- "\\_SB.PCI0.DOCK", /* A22p, T20, T21, X20 */
- "\\_SB.PCI0.PCI1.DOCK", /* all others */
-); /* A21e, G40, R32, R40, R40e */
-
-IBM_HANDLE(bay, root,
- "\\_SB.PCI0.IDE0.SCND.MSTR"); /* all except A21e */
-IBM_HANDLE(bayej, root,
- "\\_SB.PCI0.IDE0.SCND.MSTR._EJ0"); /* all except A2x, A3x */
-
-IBM_HANDLE(lght, root, "\\LGHT"); /* A21e, A22p, T20, T21, X20 */
-IBM_HANDLE(hkey, ec, "HKEY"); /* all */
-IBM_HANDLE(led, ec, "LED"); /* all except A21e, A22p, T20, T21, X20 */
-IBM_HANDLE(sysl, ec, "SYSL"); /* A21e, A22p, T20, T21, X20 */
-IBM_HANDLE(bled, ec, "BLED"); /* A22p, T20, T21, X20 */
-IBM_HANDLE(beep, ec, "BEEP"); /* all models */
+/*
+ * The following models are supported to various degrees:
+ *
+ * 570, 600e, 600x, 770e, 770x
+ * A20m, A21e, A21m, A21p, A22p, A30, A30p, A31, A31p
+ * G40, G41
+ * R30, R31, R32, R40, R40e, R50, R50e, R50p, R51
+ * T20, T21, T22, T23, T30, T40, T40p, T41, T41p, T42, T42p, T43
+ * X20, X21, X22, X23, X24, X30, X31, X40
+ *
+ * The following models have no supported features:
+ *
+ * 240, 240x, i1400
+ *
+ * Still missing DSDTs for the following models:
+ *
+ * A20p, A22e, A22m
+ * R52
+ * S31
+ * T43p
+ */
+
+IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */
+ "\\_SB.PCI.ISA.EC", /* 570 */
+ "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */
+ "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */
+ "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */
+ "\\_SB.PCI0.ICH3.EC0", /* R31 */
+ "\\_SB.PCI0.LPC.EC", /* all others */
+ );
+
+IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
+ "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
+ "\\_SB.PCI0.VID0", /* 770e */
+ "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
+ "\\_SB.PCI0.AGP.VID", /* all others */
+ ); /* R30, R31 */
+
+IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */
+
+IBM_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, T4x, X31, X40 */
+ "\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */
+ "\\CMS", /* R40, R40e */
+ ); /* all others */
+
+IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
+ "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
+ "\\_SB.PCI0.PCI1.DOCK", /* all others */
+ "\\_SB.PCI.ISA.SLCE", /* 570 */
+ ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
+
+IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
+ "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
+ "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
+ ); /* A21e, R30, R31 */
+
+IBM_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */
+ "_EJ0", /* all others */
+ ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
+
+IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
+ "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */
+ ); /* all others */
+
+IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
+ "_EJ0", /* 770x */
+ ); /* all others */
+
+/* don't list other alternatives as we install a notify handler on the 570 */
+IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
+
+IBM_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */
+ "^HKEY", /* R30, R31 */
+ "HKEY", /* all others */
+ ); /* 570 */
+
+IBM_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */
+IBM_HANDLE(ledb, ec, "LEDB"); /* G4x */
+
+IBM_HANDLE(led, ec, "SLED", /* 570 */
+ "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+ "LED", /* all others */
+ ); /* R30, R31 */
+
+IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */
+IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */
+IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */
+IBM_HANDLE(fans, ec, "FANS"); /* X31, X40 */
+
+IBM_HANDLE(gfan, ec, "GFAN", /* 570 */
+ "\\FSPD", /* 600e/x, 770e, 770x */
+ ); /* all others */
+
+IBM_HANDLE(sfan, ec, "SFAN", /* 570 */
+ "JFNS", /* 770x-JL */
+ ); /* all others */
+
+#define IBM_HKEY_HID "IBM0068"
+#define IBM_PCI_HID "PNP0A03"
struct ibm_struct {
char *name;
+ char param[32];
char *hid;
struct acpi_driver *driver;
-
- int (*init) (struct ibm_struct *);
- int (*read) (struct ibm_struct *, char *);
- int (*write) (struct ibm_struct *, char *);
- void (*exit) (struct ibm_struct *);
- void (*notify) (struct ibm_struct *, u32);
+ int (*init) (void);
+ int (*read) (char *);
+ int (*write) (char *);
+ void (*exit) (void);
+
+ void (*notify) (struct ibm_struct *, u32);
acpi_handle *handle;
int type;
struct acpi_device *device;
@@ -141,17 +238,6 @@ struct ibm_struct {
int init_called;
int notify_installed;
- int supported;
- union {
- struct {
- int status;
- int mask;
- } hotkey;
- struct {
- int autoswitch;
- } video;
- } state;
-
int experimental;
};
@@ -165,15 +251,15 @@ static int acpi_evalf(acpi_handle handle,
void *res, char *method, char *fmt, ...)
{
char *fmt0 = fmt;
- struct acpi_object_list params;
- union acpi_object in_objs[IBM_MAX_ACPI_ARGS];
- struct acpi_buffer result;
- union acpi_object out_obj;
- acpi_status status;
- va_list ap;
- char res_type;
- int success;
- int quiet;
+ struct acpi_object_list params;
+ union acpi_object in_objs[IBM_MAX_ACPI_ARGS];
+ struct acpi_buffer result, *resultp;
+ union acpi_object out_obj;
+ acpi_status status;
+ va_list ap;
+ char res_type;
+ int success;
+ int quiet;
if (!*fmt) {
printk(IBM_ERR "acpi_evalf() called with empty format\n");
@@ -199,7 +285,7 @@ static int acpi_evalf(acpi_handle handle,
in_objs[params.count].integer.value = va_arg(ap, int);
in_objs[params.count++].type = ACPI_TYPE_INTEGER;
break;
- /* add more types as needed */
+ /* add more types as needed */
default:
printk(IBM_ERR "acpi_evalf() called "
"with invalid format character '%c'\n", c);
@@ -208,21 +294,25 @@ static int acpi_evalf(acpi_handle handle,
}
va_end(ap);
- result.length = sizeof(out_obj);
- result.pointer = &out_obj;
+ if (res_type != 'v') {
+ result.length = sizeof(out_obj);
+ result.pointer = &out_obj;
+ resultp = &result;
+ } else
+ resultp = NULL;
- status = acpi_evaluate_object(handle, method, &params, &result);
+ status = acpi_evaluate_object(handle, method, &params, resultp);
switch (res_type) {
- case 'd': /* int */
+ case 'd': /* int */
if (res)
*(int *)res = out_obj.integer.value;
success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER;
break;
- case 'v': /* void */
+ case 'v': /* void */
success = status == AE_OK;
break;
- /* add more types as needed */
+ /* add more types as needed */
default:
printk(IBM_ERR "acpi_evalf() called "
"with invalid format character '%c'\n", res_type);
@@ -262,7 +352,7 @@ static char *next_cmd(char **cmds)
return start;
}
-static int driver_init(struct ibm_struct *ibm)
+static int driver_init(void)
{
printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
printk(IBM_INFO "%s\n", IBM_URL);
@@ -270,7 +360,7 @@ static int driver_init(struct ibm_struct *ibm)
return 0;
}
-static int driver_read(struct ibm_struct *ibm, char *p)
+static int driver_read(char *p)
{
int len = 0;
@@ -280,67 +370,74 @@ static int driver_read(struct ibm_struct *ibm, char *p)
return len;
}
-static int hotkey_get(struct ibm_struct *ibm, int *status, int *mask)
+static int hotkey_supported;
+static int hotkey_mask_supported;
+static int hotkey_orig_status;
+static int hotkey_orig_mask;
+
+static int hotkey_get(int *status, int *mask)
{
if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
- return -EIO;
- if (ibm->supported) {
- if (!acpi_evalf(hkey_handle, mask, "DHKN", "qd"))
- return -EIO;
- } else {
- *mask = ibm->state.hotkey.mask;
- }
- return 0;
+ return 0;
+
+ if (hotkey_mask_supported)
+ if (!acpi_evalf(hkey_handle, mask, "DHKN", "d"))
+ return 0;
+
+ return 1;
}
-static int hotkey_set(struct ibm_struct *ibm, int status, int mask)
+static int hotkey_set(int status, int mask)
{
int i;
if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
- return -EIO;
-
- if (!ibm->supported)
return 0;
- for (i=0; i<32; i++) {
- int bit = ((1 << i) & mask) != 0;
- if (!acpi_evalf(hkey_handle, NULL, "MHKM", "vdd", i+1, bit))
- return -EIO;
- }
+ if (hotkey_mask_supported)
+ for (i = 0; i < 32; i++) {
+ int bit = ((1 << i) & mask) != 0;
+ if (!acpi_evalf(hkey_handle,
+ NULL, "MHKM", "vdd", i + 1, bit))
+ return 0;
+ }
- return 0;
+ return 1;
}
-static int hotkey_init(struct ibm_struct *ibm)
+static int hotkey_init(void)
{
- int ret;
+ /* hotkey not supported on 570 */
+ hotkey_supported = hkey_handle != NULL;
- ibm->supported = 1;
- ret = hotkey_get(ibm,
- &ibm->state.hotkey.status,
- &ibm->state.hotkey.mask);
- if (ret < 0) {
- /* mask not supported on A21e, A22p, T20, T21, X20, X22, X24 */
- ibm->supported = 0;
- ret = hotkey_get(ibm,
- &ibm->state.hotkey.status,
- &ibm->state.hotkey.mask);
+ if (hotkey_supported) {
+ /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
+ A30, R30, R31, T20-22, X20-21, X22-24 */
+ hotkey_mask_supported =
+ acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+
+ if (!hotkey_get(&hotkey_orig_status, &hotkey_orig_mask))
+ return -ENODEV;
}
- return ret;
-}
+ return 0;
+}
-static int hotkey_read(struct ibm_struct *ibm, char *p)
+static int hotkey_read(char *p)
{
int status, mask;
int len = 0;
- if (hotkey_get(ibm, &status, &mask) < 0)
+ if (!hotkey_supported) {
+ len += sprintf(p + len, "status:\t\tnot supported\n");
+ return len;
+ }
+
+ if (!hotkey_get(&status, &mask))
return -EIO;
len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
- if (ibm->supported) {
+ if (hotkey_mask_supported) {
len += sprintf(p + len, "mask:\t\t0x%04x\n", mask);
len += sprintf(p + len,
"commands:\tenable, disable, reset, <mask>\n");
@@ -352,23 +449,26 @@ static int hotkey_read(struct ibm_struct *ibm, char *p)
return len;
}
-static int hotkey_write(struct ibm_struct *ibm, char *buf)
+static int hotkey_write(char *buf)
{
int status, mask;
char *cmd;
int do_cmd = 0;
- if (hotkey_get(ibm, &status, &mask) < 0)
+ if (!hotkey_supported)
return -ENODEV;
+ if (!hotkey_get(&status, &mask))
+ return -EIO;
+
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
status = 1;
} else if (strlencmp(cmd, "disable") == 0) {
status = 0;
} else if (strlencmp(cmd, "reset") == 0) {
- status = ibm->state.hotkey.status;
- mask = ibm->state.hotkey.mask;
+ status = hotkey_orig_status;
+ mask = hotkey_orig_mask;
} else if (sscanf(cmd, "0x%x", &mask) == 1) {
/* mask set */
} else if (sscanf(cmd, "%x", &mask) == 1) {
@@ -378,15 +478,16 @@ static int hotkey_write(struct ibm_struct *ibm, char *buf)
do_cmd = 1;
}
- if (do_cmd && hotkey_set(ibm, status, mask) < 0)
+ if (do_cmd && !hotkey_set(status, mask))
return -EIO;
return 0;
-}
+}
-static void hotkey_exit(struct ibm_struct *ibm)
+static void hotkey_exit(void)
{
- hotkey_set(ibm, ibm->state.hotkey.status, ibm->state.hotkey.mask);
+ if (hotkey_supported)
+ hotkey_set(hotkey_orig_status, hotkey_orig_mask);
}
static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -398,33 +499,38 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
else {
printk(IBM_ERR "unknown hotkey event %d\n", event);
acpi_bus_generate_event(ibm->device, event, 0);
- }
+ }
}
-static int bluetooth_init(struct ibm_struct *ibm)
+static int bluetooth_supported;
+
+static int bluetooth_init(void)
{
- /* bluetooth not supported on A21e, G40, T20, T21, X20 */
- ibm->supported = acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
+ /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
+ G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
+ bluetooth_supported = hkey_handle &&
+ acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
return 0;
}
-static int bluetooth_status(struct ibm_struct *ibm)
+static int bluetooth_status(void)
{
int status;
- if (!ibm->supported || !acpi_evalf(hkey_handle, &status, "GBDC", "d"))
+ if (!bluetooth_supported ||
+ !acpi_evalf(hkey_handle, &status, "GBDC", "d"))
status = 0;
return status;
}
-static int bluetooth_read(struct ibm_struct *ibm, char *p)
+static int bluetooth_read(char *p)
{
int len = 0;
- int status = bluetooth_status(ibm);
+ int status = bluetooth_status();
- if (!ibm->supported)
+ if (!bluetooth_supported)
len += sprintf(p + len, "status:\t\tnot supported\n");
else if (!(status & 1))
len += sprintf(p + len, "status:\t\tnot installed\n");
@@ -436,14 +542,14 @@ static int bluetooth_read(struct ibm_struct *ibm, char *p)
return len;
}
-static int bluetooth_write(struct ibm_struct *ibm, char *buf)
+static int bluetooth_write(char *buf)
{
- int status = bluetooth_status(ibm);
+ int status = bluetooth_status();
char *cmd;
int do_cmd = 0;
- if (!ibm->supported)
- return -EINVAL;
+ if (!bluetooth_supported)
+ return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
@@ -456,64 +562,166 @@ static int bluetooth_write(struct ibm_struct *ibm, char *buf)
}
if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
- return -EIO;
+ return -EIO;
return 0;
}
-static int video_init(struct ibm_struct *ibm)
+static int video_supported;
+static int video_orig_autosw;
+
+#define VIDEO_570 1
+#define VIDEO_770 2
+#define VIDEO_NEW 3
+
+static int video_init(void)
{
- if (!acpi_evalf(vid_handle,
- &ibm->state.video.autoswitch, "^VDEE", "d"))
- return -ENODEV;
+ int ivga;
+
+ if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
+ /* G41, assume IVGA doesn't change */
+ vid_handle = vid2_handle;
+
+ if (!vid_handle)
+ /* video switching not supported on R30, R31 */
+ video_supported = 0;
+ else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
+ /* 570 */
+ video_supported = VIDEO_570;
+ else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
+ /* 600e/x, 770e, 770x */
+ video_supported = VIDEO_770;
+ else
+ /* all others */
+ video_supported = VIDEO_NEW;
return 0;
}
-static int video_status(struct ibm_struct *ibm)
+static int video_status(void)
{
int status = 0;
int i;
- acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
- if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
- status |= 0x02 * i;
+ if (video_supported == VIDEO_570) {
+ if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
+ status = i & 3;
+ } else if (video_supported == VIDEO_770) {
+ if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
+ status |= 0x01 * i;
+ if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
+ status |= 0x02 * i;
+ } else if (video_supported == VIDEO_NEW) {
+ acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
+ if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
+ status |= 0x02 * i;
+
+ acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0);
+ if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
+ status |= 0x01 * i;
+ if (acpi_evalf(NULL, &i, "\\VCDD", "d"))
+ status |= 0x08 * i;
+ }
+
+ return status;
+}
- acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0);
- if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
- status |= 0x01 * i;
- if (acpi_evalf(NULL, &i, "\\VCDD", "d"))
- status |= 0x08 * i;
+static int video_autosw(void)
+{
+ int autosw = 0;
- if (acpi_evalf(vid_handle, &i, "^VDEE", "d"))
- status |= 0x10 * (i & 1);
+ if (video_supported == VIDEO_570)
+ acpi_evalf(vid_handle, &autosw, "SWIT", "d");
+ else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW)
+ acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
- return status;
+ return autosw & 1;
}
-static int video_read(struct ibm_struct *ibm, char *p)
+static int video_read(char *p)
{
- int status = video_status(ibm);
+ int status = video_status();
+ int autosw = video_autosw();
int len = 0;
+ if (!video_supported) {
+ len += sprintf(p + len, "status:\t\tnot supported\n");
+ return len;
+ }
+
+ len += sprintf(p + len, "status:\t\tsupported\n");
len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
- len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
- len += sprintf(p + len, "auto:\t\t%s\n", enabled(status, 4));
- len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable, "
- "crt_enable, crt_disable\n");
- len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable, "
- "auto_enable, auto_disable\n");
+ if (video_supported == VIDEO_NEW)
+ len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
+ len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
+ len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
+ len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
+ if (video_supported == VIDEO_NEW)
+ len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
+ len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
return len;
}
-static int video_write(struct ibm_struct *ibm, char *buf)
+static int video_switch(void)
+{
+ int autosw = video_autosw();
+ int ret;
+
+ if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
+ return -EIO;
+ ret = video_supported == VIDEO_570 ?
+ acpi_evalf(ec_handle, NULL, "_Q16", "v") :
+ acpi_evalf(vid_handle, NULL, "VSWT", "v");
+ acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
+
+ return ret;
+}
+
+static int video_expand(void)
+{
+ if (video_supported == VIDEO_570)
+ return acpi_evalf(ec_handle, NULL, "_Q17", "v");
+ else if (video_supported == VIDEO_770)
+ return acpi_evalf(vid_handle, NULL, "VEXP", "v");
+ else
+ return acpi_evalf(NULL, NULL, "\\VEXP", "v");
+}
+
+static int video_switch2(int status)
+{
+ int ret;
+
+ if (video_supported == VIDEO_570) {
+ ret = acpi_evalf(NULL, NULL,
+ "\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
+ } else if (video_supported == VIDEO_770) {
+ int autosw = video_autosw();
+ if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
+ return -EIO;
+
+ ret = acpi_evalf(vid_handle, NULL,
+ "ASWT", "vdd", status * 0x100, 0);
+
+ acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
+ } else {
+ ret = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
+ acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
+ }
+
+ return ret;
+}
+
+static int video_write(char *buf)
{
char *cmd;
int enable, disable, status;
+ if (!video_supported)
+ return -ENODEV;
+
enable = disable = 0;
while ((cmd = next_cmd(&buf))) {
@@ -525,9 +733,11 @@ static int video_write(struct ibm_struct *ibm, char *buf)
enable |= 0x02;
} else if (strlencmp(cmd, "crt_disable") == 0) {
disable |= 0x02;
- } else if (strlencmp(cmd, "dvi_enable") == 0) {
+ } else if (video_supported == VIDEO_NEW &&
+ strlencmp(cmd, "dvi_enable") == 0) {
enable |= 0x08;
- } else if (strlencmp(cmd, "dvi_disable") == 0) {
+ } else if (video_supported == VIDEO_NEW &&
+ strlencmp(cmd, "dvi_disable") == 0) {
disable |= 0x08;
} else if (strlencmp(cmd, "auto_enable") == 0) {
if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
@@ -536,71 +746,75 @@ static int video_write(struct ibm_struct *ibm, char *buf)
if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 0))
return -EIO;
} else if (strlencmp(cmd, "video_switch") == 0) {
- int autoswitch;
- if (!acpi_evalf(vid_handle, &autoswitch, "^VDEE", "d"))
- return -EIO;
- if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
- return -EIO;
- if (!acpi_evalf(vid_handle, NULL, "VSWT", "v"))
- return -EIO;
- if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd",
- autoswitch))
+ if (!video_switch())
return -EIO;
} else if (strlencmp(cmd, "expand_toggle") == 0) {
- if (!acpi_evalf(NULL, NULL, "\\VEXP", "v"))
+ if (!video_expand())
return -EIO;
} else
return -EINVAL;
}
if (enable || disable) {
- status = (video_status(ibm) & 0x0f & ~disable) | enable;
- if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80))
- return -EIO;
- if (!acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1))
+ status = (video_status() & 0x0f & ~disable) | enable;
+ if (!video_switch2(status))
return -EIO;
}
return 0;
}
-static void video_exit(struct ibm_struct *ibm)
+static void video_exit(void)
{
- acpi_evalf(vid_handle, NULL, "_DOS", "vd",
- ibm->state.video.autoswitch);
+ acpi_evalf(vid_handle, NULL, "_DOS", "vd", video_orig_autosw);
}
-static int light_init(struct ibm_struct *ibm)
+static int light_supported;
+static int light_status_supported;
+
+static int light_init(void)
{
- /* kblt not supported on G40, R32, X20 */
- ibm->supported = acpi_evalf(ec_handle, NULL, "KBLT", "qv");
+ /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
+ light_supported = (cmos_handle || lght_handle) && !ledb_handle;
+
+ if (light_supported)
+ /* light status not supported on
+ 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */
+ light_status_supported = acpi_evalf(ec_handle, NULL,
+ "KBLT", "qv");
return 0;
}
-static int light_read(struct ibm_struct *ibm, char *p)
+static int light_read(char *p)
{
int len = 0;
int status = 0;
- if (ibm->supported) {
+ if (!light_supported) {
+ len += sprintf(p + len, "status:\t\tnot supported\n");
+ } else if (!light_status_supported) {
+ len += sprintf(p + len, "status:\t\tunknown\n");
+ len += sprintf(p + len, "commands:\ton, off\n");
+ } else {
if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
return -EIO;
len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
- } else
- len += sprintf(p + len, "status:\t\tunknown\n");
-
- len += sprintf(p + len, "commands:\ton, off\n");
+ len += sprintf(p + len, "commands:\ton, off\n");
+ }
return len;
}
-static int light_write(struct ibm_struct *ibm, char *buf)
+static int light_write(char *buf)
{
int cmos_cmd, lght_cmd;
char *cmd;
int success;
-
+
+ if (!light_supported)
+ return -ENODEV;
+
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "on") == 0) {
cmos_cmd = 0x0c;
@@ -610,10 +824,10 @@ static int light_write(struct ibm_struct *ibm, char *buf)
lght_cmd = 0;
} else
return -EINVAL;
-
+
success = cmos_handle ?
- acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
- acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
+ acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
+ acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
if (!success)
return -EIO;
}
@@ -633,7 +847,7 @@ static int _sta(acpi_handle handle)
#define dock_docked() (_sta(dock_handle) & 1)
-static int dock_read(struct ibm_struct *ibm, char *p)
+static int dock_read(char *p)
{
int len = 0;
int docked = dock_docked();
@@ -650,18 +864,17 @@ static int dock_read(struct ibm_struct *ibm, char *p)
return len;
}
-static int dock_write(struct ibm_struct *ibm, char *buf)
+static int dock_write(char *buf)
{
char *cmd;
if (!dock_docked())
- return -EINVAL;
+ return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "undock") == 0) {
- if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0))
- return -EIO;
- if (!acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
+ if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) ||
+ !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
return -EIO;
} else if (strlencmp(cmd, "dock") == 0) {
if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1))
@@ -671,90 +884,131 @@ static int dock_write(struct ibm_struct *ibm, char *buf)
}
return 0;
-}
+}
static void dock_notify(struct ibm_struct *ibm, u32 event)
{
int docked = dock_docked();
-
- if (event == 3 && docked)
- acpi_bus_generate_event(ibm->device, event, 1); /* button */
+ int pci = ibm->hid && strstr(ibm->hid, IBM_PCI_HID);
+
+ if (event == 1 && !pci) /* 570 */
+ acpi_bus_generate_event(ibm->device, event, 1); /* button */
+ else if (event == 1 && pci) /* 570 */
+ acpi_bus_generate_event(ibm->device, event, 3); /* dock */
+ else if (event == 3 && docked)
+ acpi_bus_generate_event(ibm->device, event, 1); /* button */
else if (event == 3 && !docked)
- acpi_bus_generate_event(ibm->device, event, 2); /* undock */
+ acpi_bus_generate_event(ibm->device, event, 2); /* undock */
else if (event == 0 && docked)
- acpi_bus_generate_event(ibm->device, event, 3); /* dock */
+ acpi_bus_generate_event(ibm->device, event, 3); /* dock */
else {
printk(IBM_ERR "unknown dock event %d, status %d\n",
event, _sta(dock_handle));
- acpi_bus_generate_event(ibm->device, event, 0); /* unknown */
+ acpi_bus_generate_event(ibm->device, event, 0); /* unknown */
}
}
-#define bay_occupied() (_sta(bay_handle) & 1)
+static int bay_status_supported;
+static int bay_status2_supported;
+static int bay_eject_supported;
+static int bay_eject2_supported;
-static int bay_init(struct ibm_struct *ibm)
+static int bay_init(void)
{
- /* bay not supported on A21e, A22p, A31, A31p, G40, R32, R40e */
- ibm->supported = bay_handle && bayej_handle &&
- acpi_evalf(bay_handle, NULL, "_STA", "qv");
+ bay_status_supported = bay_handle &&
+ acpi_evalf(bay_handle, NULL, "_STA", "qv");
+ bay_status2_supported = bay2_handle &&
+ acpi_evalf(bay2_handle, NULL, "_STA", "qv");
+
+ bay_eject_supported = bay_handle && bay_ej_handle &&
+ (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
+ bay_eject2_supported = bay2_handle && bay2_ej_handle &&
+ (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
return 0;
}
-static int bay_read(struct ibm_struct *ibm, char *p)
+#define bay_occupied(b) (_sta(b##_handle) & 1)
+
+static int bay_read(char *p)
{
int len = 0;
- int occupied = bay_occupied();
-
- if (!ibm->supported)
- len += sprintf(p + len, "status:\t\tnot supported\n");
- else if (!occupied)
- len += sprintf(p + len, "status:\t\tunoccupied\n");
- else {
- len += sprintf(p + len, "status:\t\toccupied\n");
+ int occupied = bay_occupied(bay);
+ int occupied2 = bay_occupied(bay2);
+ int eject, eject2;
+
+ len += sprintf(p + len, "status:\t\t%s\n", bay_status_supported ?
+ (occupied ? "occupied" : "unoccupied") :
+ "not supported");
+ if (bay_status2_supported)
+ len += sprintf(p + len, "status2:\t%s\n", occupied2 ?
+ "occupied" : "unoccupied");
+
+ eject = bay_eject_supported && occupied;
+ eject2 = bay_eject2_supported && occupied2;
+
+ if (eject && eject2)
+ len += sprintf(p + len, "commands:\teject, eject2\n");
+ else if (eject)
len += sprintf(p + len, "commands:\teject\n");
- }
+ else if (eject2)
+ len += sprintf(p + len, "commands:\teject2\n");
return len;
}
-static int bay_write(struct ibm_struct *ibm, char *buf)
+static int bay_write(char *buf)
{
char *cmd;
+ if (!bay_eject_supported && !bay_eject2_supported)
+ return -ENODEV;
+
while ((cmd = next_cmd(&buf))) {
- if (strlencmp(cmd, "eject") == 0) {
- if (!ibm->supported ||
- !acpi_evalf(bay_handle, NULL, "_EJ0", "vd", 1))
+ if (bay_eject_supported && strlencmp(cmd, "eject") == 0) {
+ if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1))
+ return -EIO;
+ } else if (bay_eject2_supported &&
+ strlencmp(cmd, "eject2") == 0) {
+ if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1))
return -EIO;
} else
return -EINVAL;
}
return 0;
-}
+}
static void bay_notify(struct ibm_struct *ibm, u32 event)
{
acpi_bus_generate_event(ibm->device, event, 0);
}
-static int cmos_read(struct ibm_struct *ibm, char *p)
+static int cmos_read(char *p)
{
int len = 0;
- /* cmos not supported on A21e, A22p, T20, T21, X20 */
+ /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
+ R30, R31, T20-22, X20-21 */
if (!cmos_handle)
len += sprintf(p + len, "status:\t\tnot supported\n");
else {
len += sprintf(p + len, "status:\t\tsupported\n");
- len += sprintf(p + len, "commands:\t<int>\n");
+ len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n");
}
return len;
}
-static int cmos_write(struct ibm_struct *ibm, char *buf)
+static int cmos_eval(int cmos_cmd)
+{
+ if (cmos_handle)
+ return acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd);
+ else
+ return 1;
+}
+
+static int cmos_write(char *buf)
{
char *cmd;
int cmos_cmd;
@@ -763,183 +1017,644 @@ static int cmos_write(struct ibm_struct *ibm, char *buf)
return -EINVAL;
while ((cmd = next_cmd(&buf))) {
- if (sscanf(cmd, "%u", &cmos_cmd) == 1) {
+ if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&
+ cmos_cmd >= 0 && cmos_cmd <= 21) {
/* cmos_cmd set */
} else
return -EINVAL;
- if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))
+ if (!cmos_eval(cmos_cmd))
return -EIO;
}
return 0;
-}
-
-static int led_read(struct ibm_struct *ibm, char *p)
+}
+
+static int led_supported;
+
+#define LED_570 1
+#define LED_OLD 2
+#define LED_NEW 3
+
+static int led_init(void)
+{
+ if (!led_handle)
+ /* led not supported on R30, R31 */
+ led_supported = 0;
+ else if (strlencmp(led_path, "SLED") == 0)
+ /* 570 */
+ led_supported = LED_570;
+ else if (strlencmp(led_path, "SYSL") == 0)
+ /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+ led_supported = LED_OLD;
+ else
+ /* all others */
+ led_supported = LED_NEW;
+
+ return 0;
+}
+
+#define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking"))
+
+static int led_read(char *p)
{
int len = 0;
+ if (!led_supported) {
+ len += sprintf(p + len, "status:\t\tnot supported\n");
+ return len;
+ }
+ len += sprintf(p + len, "status:\t\tsupported\n");
+
+ if (led_supported == LED_570) {
+ /* 570 */
+ int i, status;
+ for (i = 0; i < 8; i++) {
+ if (!acpi_evalf(ec_handle,
+ &status, "GLED", "dd", 1 << i))
+ return -EIO;
+ len += sprintf(p + len, "%d:\t\t%s\n",
+ i, led_status(status));
+ }
+ }
+
len += sprintf(p + len, "commands:\t"
- "<int> on, <int> off, <int> blink\n");
+ "<led> on, <led> off, <led> blink (<led> is 0-7)\n");
return len;
}
-static int led_write(struct ibm_struct *ibm, char *buf)
+/* off, on, blink */
+static const int led_sled_arg1[] = { 0, 1, 3 };
+static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */
+static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
+static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
+
+#define EC_HLCL 0x0c
+#define EC_HLBL 0x0d
+#define EC_HLMS 0x0e
+
+static int led_write(char *buf)
{
char *cmd;
- unsigned int led;
- int led_cmd, sysl_cmd, bled_a, bled_b;
+ int led, ind, ret;
+
+ if (!led_supported)
+ return -ENODEV;
while ((cmd = next_cmd(&buf))) {
- if (sscanf(cmd, "%u", &led) != 1)
+ if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7)
return -EINVAL;
- if (strstr(cmd, "blink")) {
- led_cmd = 0xc0;
- sysl_cmd = 2;
- bled_a = 2;
- bled_b = 1;
+ if (strstr(cmd, "off")) {
+ ind = 0;
} else if (strstr(cmd, "on")) {
- led_cmd = 0x80;
- sysl_cmd = 1;
- bled_a = 2;
- bled_b = 0;
- } else if (strstr(cmd, "off")) {
- led_cmd = sysl_cmd = bled_a = bled_b = 0;
+ ind = 1;
+ } else if (strstr(cmd, "blink")) {
+ ind = 2;
} else
return -EINVAL;
-
- if (led_handle) {
+
+ if (led_supported == LED_570) {
+ /* 570 */
+ led = 1 << led;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
- led, led_cmd))
+ led, led_sled_arg1[ind]))
return -EIO;
- } else if (led < 2) {
- if (acpi_evalf(sysl_handle, NULL, NULL, "vdd",
- led, sysl_cmd))
+ } else if (led_supported == LED_OLD) {
+ /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
+ led = 1 << led;
+ ret = ec_write(EC_HLMS, led);
+ if (ret >= 0)
+ ret =
+ ec_write(EC_HLBL, led * led_exp_hlbl[ind]);
+ if (ret >= 0)
+ ret =
+ ec_write(EC_HLCL, led * led_exp_hlcl[ind]);
+ if (ret < 0)
+ return ret;
+ } else {
+ /* all others */
+ if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+ led, led_led_arg1[ind]))
return -EIO;
- } else if (led == 2 && bled_handle) {
- if (acpi_evalf(bled_handle, NULL, NULL, "vdd",
- bled_a, bled_b))
+ }
+ }
+
+ return 0;
+}
+
+static int beep_read(char *p)
+{
+ int len = 0;
+
+ if (!beep_handle)
+ len += sprintf(p + len, "status:\t\tnot supported\n");
+ else {
+ len += sprintf(p + len, "status:\t\tsupported\n");
+ len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n");
+ }
+
+ return len;
+}
+
+static int beep_write(char *buf)
+{
+ char *cmd;
+ int beep_cmd;
+
+ if (!beep_handle)
+ return -ENODEV;
+
+ while ((cmd = next_cmd(&buf))) {
+ if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
+ beep_cmd >= 0 && beep_cmd <= 17) {
+ /* beep_cmd set */
+ } else
+ return -EINVAL;
+ if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0))
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int acpi_ec_read(int i, u8 * p)
+{
+ int v;
+
+ if (ecrd_handle) {
+ if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i))
+ return 0;
+ *p = v;
+ } else {
+ if (ec_read(i, p) < 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int acpi_ec_write(int i, u8 v)
+{
+ if (ecwr_handle) {
+ if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v))
+ return 0;
+ } else {
+ if (ec_write(i, v) < 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int thermal_tmp_supported;
+static int thermal_updt_supported;
+
+static int thermal_init(void)
+{
+ /* temperatures not supported on 570, G4x, R30, R31, R32 */
+ thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
+
+ /* 600e/x, 770e, 770x */
+ thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv");
+
+ return 0;
+}
+
+static int thermal_read(char *p)
+{
+ int len = 0;
+
+ if (!thermal_tmp_supported)
+ len += sprintf(p + len, "temperatures:\tnot supported\n");
+ else {
+ int i, t;
+ char tmpi[] = "TMPi";
+ s8 tmp[8];
+
+ if (thermal_updt_supported)
+ if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+ return -EIO;
+
+ for (i = 0; i < 8; i++) {
+ tmpi[3] = '0' + i;
+ if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
+ return -EIO;
+ if (thermal_updt_supported)
+ tmp[i] = (t - 2732 + 5) / 10;
+ else
+ tmp[i] = t;
+ }
+
+ len += sprintf(p + len,
+ "temperatures:\t%d %d %d %d %d %d %d %d\n",
+ tmp[0], tmp[1], tmp[2], tmp[3],
+ tmp[4], tmp[5], tmp[6], tmp[7]);
+ }
+
+ return len;
+}
+
+static u8 ecdump_regs[256];
+
+static int ecdump_read(char *p)
+{
+ int len = 0;
+ int i, j;
+ u8 v;
+
+ len += sprintf(p + len, "EC "
+ " +00 +01 +02 +03 +04 +05 +06 +07"
+ " +08 +09 +0a +0b +0c +0d +0e +0f\n");
+ for (i = 0; i < 256; i += 16) {
+ len += sprintf(p + len, "EC 0x%02x:", i);
+ for (j = 0; j < 16; j++) {
+ if (!acpi_ec_read(i + j, &v))
+ break;
+ if (v != ecdump_regs[i + j])
+ len += sprintf(p + len, " *%02x", v);
+ else
+ len += sprintf(p + len, " %02x", v);
+ ecdump_regs[i + j] = v;
+ }
+ len += sprintf(p + len, "\n");
+ if (j != 16)
+ break;
+ }
+
+ /* These are way too dangerous to advertise openly... */
+#if 0
+ len += sprintf(p + len, "commands:\t0x<offset> 0x<value>"
+ " (<offset> is 00-ff, <value> is 00-ff)\n");
+ len += sprintf(p + len, "commands:\t0x<offset> <value> "
+ " (<offset> is 00-ff, <value> is 0-255)\n");
+#endif
+ return len;
+}
+
+static int ecdump_write(char *buf)
+{
+ char *cmd;
+ int i, v;
+
+ while ((cmd = next_cmd(&buf))) {
+ if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) {
+ /* i and v set */
+ } else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) {
+ /* i and v set */
+ } else
+ return -EINVAL;
+ if (i >= 0 && i < 256 && v >= 0 && v < 256) {
+ if (!acpi_ec_write(i, v))
return -EIO;
} else
return -EINVAL;
}
return 0;
-}
-
-static int beep_read(struct ibm_struct *ibm, char *p)
+}
+
+static int brightness_offset = 0x31;
+
+static int brightness_read(char *p)
{
int len = 0;
+ u8 level;
- len += sprintf(p + len, "commands:\t<int>\n");
+ if (!acpi_ec_read(brightness_offset, &level)) {
+ len += sprintf(p + len, "level:\t\tunreadable\n");
+ } else {
+ len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
+ len += sprintf(p + len, "commands:\tup, down\n");
+ len += sprintf(p + len, "commands:\tlevel <level>"
+ " (<level> is 0-7)\n");
+ }
return len;
}
-static int beep_write(struct ibm_struct *ibm, char *buf)
+#define BRIGHTNESS_UP 4
+#define BRIGHTNESS_DOWN 5
+
+static int brightness_write(char *buf)
{
+ int cmos_cmd, inc, i;
+ u8 level;
+ int new_level;
char *cmd;
- int beep_cmd;
while ((cmd = next_cmd(&buf))) {
- if (sscanf(cmd, "%u", &beep_cmd) == 1) {
- /* beep_cmd set */
+ if (!acpi_ec_read(brightness_offset, &level))
+ return -EIO;
+ level &= 7;
+
+ if (strlencmp(cmd, "up") == 0) {
+ new_level = level == 7 ? 7 : level + 1;
+ } else if (strlencmp(cmd, "down") == 0) {
+ new_level = level == 0 ? 0 : level - 1;
+ } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
+ new_level >= 0 && new_level <= 7) {
+ /* new_level set */
+ } else
+ return -EINVAL;
+
+ cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
+ inc = new_level > level ? 1 : -1;
+ for (i = level; i != new_level; i += inc) {
+ if (!cmos_eval(cmos_cmd))
+ return -EIO;
+ if (!acpi_ec_write(brightness_offset, i + inc))
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int volume_offset = 0x30;
+
+static int volume_read(char *p)
+{
+ int len = 0;
+ u8 level;
+
+ if (!acpi_ec_read(volume_offset, &level)) {
+ len += sprintf(p + len, "level:\t\tunreadable\n");
+ } else {
+ len += sprintf(p + len, "level:\t\t%d\n", level & 0xf);
+ len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6));
+ len += sprintf(p + len, "commands:\tup, down, mute\n");
+ len += sprintf(p + len, "commands:\tlevel <level>"
+ " (<level> is 0-15)\n");
+ }
+
+ return len;
+}
+
+#define VOLUME_DOWN 0
+#define VOLUME_UP 1
+#define VOLUME_MUTE 2
+
+static int volume_write(char *buf)
+{
+ int cmos_cmd, inc, i;
+ u8 level, mute;
+ int new_level, new_mute;
+ char *cmd;
+
+ while ((cmd = next_cmd(&buf))) {
+ if (!acpi_ec_read(volume_offset, &level))
+ return -EIO;
+ new_mute = mute = level & 0x40;
+ new_level = level = level & 0xf;
+
+ if (strlencmp(cmd, "up") == 0) {
+ if (mute)
+ new_mute = 0;
+ else
+ new_level = level == 15 ? 15 : level + 1;
+ } else if (strlencmp(cmd, "down") == 0) {
+ if (mute)
+ new_mute = 0;
+ else
+ new_level = level == 0 ? 0 : level - 1;
+ } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
+ new_level >= 0 && new_level <= 15) {
+ /* new_level set */
+ } else if (strlencmp(cmd, "mute") == 0) {
+ new_mute = 0x40;
} else
return -EINVAL;
- if (!acpi_evalf(beep_handle, NULL, NULL, "vd", beep_cmd))
+ if (new_level != level) { /* mute doesn't change */
+ cmos_cmd = new_level > level ? VOLUME_UP : VOLUME_DOWN;
+ inc = new_level > level ? 1 : -1;
+
+ if (mute && (!cmos_eval(cmos_cmd) ||
+ !acpi_ec_write(volume_offset, level)))
+ return -EIO;
+
+ for (i = level; i != new_level; i += inc)
+ if (!cmos_eval(cmos_cmd) ||
+ !acpi_ec_write(volume_offset, i + inc))
+ return -EIO;
+
+ if (mute && (!cmos_eval(VOLUME_MUTE) ||
+ !acpi_ec_write(volume_offset,
+ new_level + mute)))
+ return -EIO;
+ }
+
+ if (new_mute != mute) { /* level doesn't change */
+ cmos_cmd = new_mute ? VOLUME_MUTE : VOLUME_UP;
+
+ if (!cmos_eval(cmos_cmd) ||
+ !acpi_ec_write(volume_offset, level + new_mute))
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int fan_status_offset = 0x2f;
+static int fan_rpm_offset = 0x84;
+
+static int fan_read(char *p)
+{
+ int len = 0;
+ int s;
+ u8 lo, hi, status;
+
+ if (gfan_handle) {
+ /* 570, 600e/x, 770e, 770x */
+ if (!acpi_evalf(gfan_handle, &s, NULL, "d"))
return -EIO;
+
+ len += sprintf(p + len, "level:\t\t%d\n", s);
+ } else {
+ /* all except 570, 600e/x, 770e, 770x */
+ if (!acpi_ec_read(fan_status_offset, &status))
+ len += sprintf(p + len, "status:\t\tunreadable\n");
+ else
+ len += sprintf(p + len, "status:\t\t%s\n",
+ enabled(status, 7));
+
+ if (!acpi_ec_read(fan_rpm_offset, &lo) ||
+ !acpi_ec_read(fan_rpm_offset + 1, &hi))
+ len += sprintf(p + len, "speed:\t\tunreadable\n");
+ else
+ len += sprintf(p + len, "speed:\t\t%d\n",
+ (hi << 8) + lo);
+ }
+
+ if (sfan_handle)
+ /* 570, 770x-JL */
+ len += sprintf(p + len, "commands:\tlevel <level>"
+ " (<level> is 0-7)\n");
+ if (!gfan_handle)
+ /* all except 570, 600e/x, 770e, 770x */
+ len += sprintf(p + len, "commands:\tenable, disable\n");
+ if (fans_handle)
+ /* X31, X40 */
+ len += sprintf(p + len, "commands:\tspeed <speed>"
+ " (<speed> is 0-65535)\n");
+
+ return len;
+}
+
+static int fan_write(char *buf)
+{
+ char *cmd;
+ int level, speed;
+
+ while ((cmd = next_cmd(&buf))) {
+ if (sfan_handle &&
+ sscanf(cmd, "level %d", &level) == 1 &&
+ level >= 0 && level <= 7) {
+ /* 570, 770x-JL */
+ if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
+ return -EIO;
+ } else if (!gfan_handle && strlencmp(cmd, "enable") == 0) {
+ /* all except 570, 600e/x, 770e, 770x */
+ if (!acpi_ec_write(fan_status_offset, 0x80))
+ return -EIO;
+ } else if (!gfan_handle && strlencmp(cmd, "disable") == 0) {
+ /* all except 570, 600e/x, 770e, 770x */
+ if (!acpi_ec_write(fan_status_offset, 0x00))
+ return -EIO;
+ } else if (fans_handle &&
+ sscanf(cmd, "speed %d", &speed) == 1 &&
+ speed >= 0 && speed <= 65535) {
+ /* X31, X40 */
+ if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
+ speed, speed, speed))
+ return -EIO;
+ } else
+ return -EINVAL;
}
return 0;
-}
-
+}
+
static struct ibm_struct ibms[] = {
{
- .name = "driver",
- .init = driver_init,
- .read = driver_read,
- },
+ .name = "driver",
+ .init = driver_init,
+ .read = driver_read,
+ },
+ {
+ .name = "hotkey",
+ .hid = IBM_HKEY_HID,
+ .init = hotkey_init,
+ .read = hotkey_read,
+ .write = hotkey_write,
+ .exit = hotkey_exit,
+ .notify = hotkey_notify,
+ .handle = &hkey_handle,
+ .type = ACPI_DEVICE_NOTIFY,
+ },
+ {
+ .name = "bluetooth",
+ .init = bluetooth_init,
+ .read = bluetooth_read,
+ .write = bluetooth_write,
+ },
+ {
+ .name = "video",
+ .init = video_init,
+ .read = video_read,
+ .write = video_write,
+ .exit = video_exit,
+ },
{
- .name = "hotkey",
- .hid = "IBM0068",
- .init = hotkey_init,
- .read = hotkey_read,
- .write = hotkey_write,
- .exit = hotkey_exit,
- .notify = hotkey_notify,
- .handle = &hkey_handle,
- .type = ACPI_DEVICE_NOTIFY,
- },
+ .name = "light",
+ .init = light_init,
+ .read = light_read,
+ .write = light_write,
+ },
{
- .name = "bluetooth",
- .init = bluetooth_init,
- .read = bluetooth_read,
- .write = bluetooth_write,
- },
+ .name = "dock",
+ .read = dock_read,
+ .write = dock_write,
+ .notify = dock_notify,
+ .handle = &dock_handle,
+ .type = ACPI_SYSTEM_NOTIFY,
+ },
{
- .name = "video",
- .init = video_init,
- .read = video_read,
- .write = video_write,
- .exit = video_exit,
- },
+ .name = "dock",
+ .hid = IBM_PCI_HID,
+ .notify = dock_notify,
+ .handle = &pci_handle,
+ .type = ACPI_SYSTEM_NOTIFY,
+ },
{
- .name = "light",
- .init = light_init,
- .read = light_read,
- .write = light_write,
- },
+ .name = "bay",
+ .init = bay_init,
+ .read = bay_read,
+ .write = bay_write,
+ .notify = bay_notify,
+ .handle = &bay_handle,
+ .type = ACPI_SYSTEM_NOTIFY,
+ },
{
- .name = "dock",
- .read = dock_read,
- .write = dock_write,
- .notify = dock_notify,
- .handle = &dock_handle,
- .type = ACPI_SYSTEM_NOTIFY,
- },
+ .name = "cmos",
+ .read = cmos_read,
+ .write = cmos_write,
+ },
{
- .name = "bay",
- .init = bay_init,
- .read = bay_read,
- .write = bay_write,
- .notify = bay_notify,
- .handle = &bay_handle,
- .type = ACPI_SYSTEM_NOTIFY,
- },
+ .name = "led",
+ .init = led_init,
+ .read = led_read,
+ .write = led_write,
+ },
{
- .name = "cmos",
- .read = cmos_read,
- .write = cmos_write,
- .experimental = 1,
- },
+ .name = "beep",
+ .read = beep_read,
+ .write = beep_write,
+ },
{
- .name = "led",
- .read = led_read,
- .write = led_write,
- .experimental = 1,
- },
+ .name = "thermal",
+ .init = thermal_init,
+ .read = thermal_read,
+ },
{
- .name = "beep",
- .read = beep_read,
- .write = beep_write,
- .experimental = 1,
- },
+ .name = "ecdump",
+ .read = ecdump_read,
+ .write = ecdump_write,
+ .experimental = 1,
+ },
+ {
+ .name = "brightness",
+ .read = brightness_read,
+ .write = brightness_write,
+ .experimental = 1,
+ },
+ {
+ .name = "volume",
+ .read = volume_read,
+ .write = volume_write,
+ .experimental = 1,
+ },
+ {
+ .name = "fan",
+ .read = fan_read,
+ .write = fan_write,
+ .experimental = 1,
+ },
};
-#define NUM_IBMS (sizeof(ibms)/sizeof(ibms[0]))
static int dispatch_read(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct ibm_struct *ibm = (struct ibm_struct *)data;
int len;
-
+
if (!ibm || !ibm->read)
return -EINVAL;
- len = ibm->read(ibm, page);
+ len = ibm->read(page);
if (len < 0)
return len;
@@ -955,7 +1670,7 @@ static int dispatch_read(char *page, char **start, off_t off, int count,
return len;
}
-static int dispatch_write(struct file *file, const char __user *userbuf,
+static int dispatch_write(struct file *file, const char __user * userbuf,
unsigned long count, void *data)
{
struct ibm_struct *ibm = (struct ibm_struct *)data;
@@ -969,20 +1684,20 @@ static int dispatch_write(struct file *file, const char __user *userbuf,
if (!kernbuf)
return -ENOMEM;
- if (copy_from_user(kernbuf, userbuf, count)) {
+ if (copy_from_user(kernbuf, userbuf, count)) {
kfree(kernbuf);
- return -EFAULT;
+ return -EFAULT;
}
kernbuf[count] = 0;
strcat(kernbuf, ",");
- ret = ibm->write(ibm, kernbuf);
+ ret = ibm->write(kernbuf);
if (ret == 0)
ret = count;
kfree(kernbuf);
- return ret;
+ return ret;
}
static void dispatch_notify(acpi_handle handle, u32 event, void *data)
@@ -995,7 +1710,7 @@ static void dispatch_notify(acpi_handle handle, u32 event, void *data)
ibm->notify(ibm, event);
}
-static int setup_notify(struct ibm_struct *ibm)
+static int __init setup_notify(struct ibm_struct *ibm)
{
acpi_status status;
int ret;
@@ -1020,17 +1735,15 @@ static int setup_notify(struct ibm_struct *ibm)
return -ENODEV;
}
- ibm->notify_installed = 1;
-
return 0;
}
-static int ibmacpi_device_add(struct acpi_device *device)
+static int __init ibm_device_add(struct acpi_device *device)
{
return 0;
}
-static int register_driver(struct ibm_struct *ibm)
+static int __init register_driver(struct ibm_struct *ibm)
{
int ret;
@@ -1043,7 +1756,7 @@ static int register_driver(struct ibm_struct *ibm)
memset(ibm->driver, 0, sizeof(struct acpi_driver));
sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
ibm->driver->ids = ibm->hid;
- ibm->driver->ops.add = &ibmacpi_device_add;
+ ibm->driver->ops.add = &ibm_device_add;
ret = acpi_bus_register_driver(ibm->driver);
if (ret < 0) {
@@ -1055,7 +1768,7 @@ static int register_driver(struct ibm_struct *ibm)
return ret;
}
-static int ibm_init(struct ibm_struct *ibm)
+static int __init ibm_init(struct ibm_struct *ibm)
{
int ret;
struct proc_dir_entry *entry;
@@ -1071,31 +1784,34 @@ static int ibm_init(struct ibm_struct *ibm)
}
if (ibm->init) {
- ret = ibm->init(ibm);
+ ret = ibm->init();
if (ret != 0)
return ret;
ibm->init_called = 1;
}
- entry = create_proc_entry(ibm->name, S_IFREG | S_IRUGO | S_IWUSR,
- proc_dir);
- if (!entry) {
- printk(IBM_ERR "unable to create proc entry %s\n", ibm->name);
- return -ENODEV;
- }
- entry->owner = THIS_MODULE;
- ibm->proc_created = 1;
-
- entry->data = ibm;
- if (ibm->read)
+ if (ibm->read) {
+ entry = create_proc_entry(ibm->name,
+ S_IFREG | S_IRUGO | S_IWUSR,
+ proc_dir);
+ if (!entry) {
+ printk(IBM_ERR "unable to create proc entry %s\n",
+ ibm->name);
+ return -ENODEV;
+ }
+ entry->owner = THIS_MODULE;
+ entry->data = ibm;
entry->read_proc = &dispatch_read;
- if (ibm->write)
- entry->write_proc = &dispatch_write;
+ if (ibm->write)
+ entry->write_proc = &dispatch_write;
+ ibm->proc_created = 1;
+ }
if (ibm->notify) {
ret = setup_notify(ibm);
if (ret < 0)
return ret;
+ ibm->notify_installed = 1;
}
return 0;
@@ -1111,7 +1827,7 @@ static void ibm_exit(struct ibm_struct *ibm)
remove_proc_entry(ibm->name, proc_dir);
if (ibm->init_called && ibm->exit)
- ibm->exit(ibm);
+ ibm->exit();
if (ibm->driver_registered) {
acpi_bus_unregister_driver(ibm->driver);
@@ -1119,60 +1835,66 @@ static void ibm_exit(struct ibm_struct *ibm)
}
}
-static int ibm_handle_init(char *name,
- acpi_handle *handle, acpi_handle parent,
- char **paths, int num_paths, int required)
+static void __init ibm_handle_init(char *name,
+ acpi_handle * handle, acpi_handle parent,
+ char **paths, int num_paths, char **path)
{
int i;
acpi_status status;
- for (i=0; i<num_paths; i++) {
+ for (i = 0; i < num_paths; i++) {
status = acpi_get_handle(parent, paths[i], handle);
- if (ACPI_SUCCESS(status))
- return 0;
- }
-
- *handle = NULL;
-
- if (required) {
- printk(IBM_ERR "%s object not found\n", name);
- return -1;
+ if (ACPI_SUCCESS(status)) {
+ *path = paths[i];
+ return;
+ }
}
- return 0;
+ *handle = NULL;
}
-#define IBM_HANDLE_INIT(object, required) \
+#define IBM_HANDLE_INIT(object) \
ibm_handle_init(#object, &object##_handle, *object##_parent, \
- object##_paths, sizeof(object##_paths)/sizeof(char*), required)
-
+ object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
static int set_ibm_param(const char *val, struct kernel_param *kp)
{
unsigned int i;
- char arg_with_comma[32];
-
- if (strlen(val) > 30)
- return -ENOSPC;
- strcpy(arg_with_comma, val);
- strcat(arg_with_comma, ",");
+ for (i = 0; i < ARRAY_SIZE(ibms); i++)
+ if (strcmp(ibms[i].name, kp->name) == 0 && ibms[i].write) {
+ if (strlen(val) > sizeof(ibms[i].param) - 2)
+ return -ENOSPC;
+ strcpy(ibms[i].param, val);
+ strcat(ibms[i].param, ",");
+ return 0;
+ }
- for (i=0; i<NUM_IBMS; i++)
- if (strcmp(ibms[i].name, kp->name) == 0)
- return ibms[i].write(&ibms[i], arg_with_comma);
- BUG();
return -EINVAL;
}
#define IBM_PARAM(feature) \
module_param_call(feature, set_ibm_param, NULL, NULL, 0)
+IBM_PARAM(hotkey);
+IBM_PARAM(bluetooth);
+IBM_PARAM(video);
+IBM_PARAM(light);
+IBM_PARAM(dock);
+IBM_PARAM(bay);
+IBM_PARAM(cmos);
+IBM_PARAM(led);
+IBM_PARAM(beep);
+IBM_PARAM(ecdump);
+IBM_PARAM(brightness);
+IBM_PARAM(volume);
+IBM_PARAM(fan);
+
static void acpi_ibm_exit(void)
{
int i;
- for (i=NUM_IBMS-1; i>=0; i--)
+ for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
ibm_exit(&ibms[i]);
remove_proc_entry(IBM_DIR, acpi_root_dir);
@@ -1185,30 +1907,40 @@ static int __init acpi_ibm_init(void)
if (acpi_disabled)
return -ENODEV;
- if (!acpi_specific_hotkey_enabled){
- printk(IBM_ERR "Using generic hotkey driver\n");
- return -ENODEV;
- }
- /* these handles are required */
- if (IBM_HANDLE_INIT(ec, 1) < 0 ||
- IBM_HANDLE_INIT(hkey, 1) < 0 ||
- IBM_HANDLE_INIT(vid, 1) < 0 ||
- IBM_HANDLE_INIT(beep, 1) < 0)
+ if (!acpi_specific_hotkey_enabled) {
+ printk(IBM_ERR "using generic hotkey driver\n");
return -ENODEV;
+ }
- /* these handles have alternatives */
- IBM_HANDLE_INIT(lght, 0);
- if (IBM_HANDLE_INIT(cmos, !lght_handle) < 0)
- return -ENODEV;
- IBM_HANDLE_INIT(sysl, 0);
- if (IBM_HANDLE_INIT(led, !sysl_handle) < 0)
+ /* ec is required because many other handles are relative to it */
+ IBM_HANDLE_INIT(ec);
+ if (!ec_handle) {
+ printk(IBM_ERR "ec object not found\n");
return -ENODEV;
+ }
/* these handles are not required */
- IBM_HANDLE_INIT(dock, 0);
- IBM_HANDLE_INIT(bay, 0);
- IBM_HANDLE_INIT(bayej, 0);
- IBM_HANDLE_INIT(bled, 0);
+ IBM_HANDLE_INIT(vid);
+ IBM_HANDLE_INIT(vid2);
+ IBM_HANDLE_INIT(ledb);
+ IBM_HANDLE_INIT(led);
+ IBM_HANDLE_INIT(hkey);
+ IBM_HANDLE_INIT(lght);
+ IBM_HANDLE_INIT(cmos);
+ IBM_HANDLE_INIT(dock);
+ IBM_HANDLE_INIT(pci);
+ IBM_HANDLE_INIT(bay);
+ if (bay_handle)
+ IBM_HANDLE_INIT(bay_ej);
+ IBM_HANDLE_INIT(bay2);
+ if (bay2_handle)
+ IBM_HANDLE_INIT(bay2_ej);
+ IBM_HANDLE_INIT(beep);
+ IBM_HANDLE_INIT(ecrd);
+ IBM_HANDLE_INIT(ecwr);
+ IBM_HANDLE_INIT(fans);
+ IBM_HANDLE_INIT(gfan);
+ IBM_HANDLE_INIT(sfan);
proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
if (!proc_dir) {
@@ -1216,9 +1948,11 @@ static int __init acpi_ibm_init(void)
return -ENODEV;
}
proc_dir->owner = THIS_MODULE;
-
- for (i=0; i<NUM_IBMS; i++) {
+
+ for (i = 0; i < ARRAY_SIZE(ibms); i++) {
ret = ibm_init(&ibms[i]);
+ if (ret >= 0 && *ibms[i].param)
+ ret = ibms[i].write(ibms[i].param);
if (ret < 0) {
acpi_ibm_exit();
return ret;
@@ -1230,17 +1964,3 @@ static int __init acpi_ibm_init(void)
module_init(acpi_ibm_init);
module_exit(acpi_ibm_exit);
-
-MODULE_AUTHOR("Borislav Deianov");
-MODULE_DESCRIPTION(IBM_DESC);
-MODULE_LICENSE("GPL");
-
-IBM_PARAM(hotkey);
-IBM_PARAM(bluetooth);
-IBM_PARAM(video);
-IBM_PARAM(light);
-IBM_PARAM(dock);
-IBM_PARAM(bay);
-IBM_PARAM(cmos);
-IBM_PARAM(led);
-IBM_PARAM(beep);
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
index 61ea70742d49..e928e8c2c6ec 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -30,12 +30,11 @@
#include <acpi/acpi_drivers.h>
#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("acpi_motherboard")
+ACPI_MODULE_NAME("acpi_motherboard")
/* Dell use PNP0C01 instead of PNP0C02 */
#define ACPI_MB_HID1 "PNP0C01"
#define ACPI_MB_HID2 "PNP0C02"
-
/**
* Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
* Doesn't care about the failure of 'request_region', since other may reserve
@@ -44,15 +43,12 @@ ACPI_MODULE_NAME ("acpi_motherboard")
#define IS_RESERVED_ADDR(base, len) \
(((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
&& ((base) + (len) > PCIBIOS_MIN_IO))
-
/*
* Clearing the flag (IORESOURCE_BUSY) allows drivers to use
* the io ports if they really know they can use it, while
* still preventing hotplug PCI devices from using it.
*/
-
-static acpi_status
-acpi_reserve_io_ranges (struct acpi_resource *res, void *data)
+static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
{
struct resource *requested_res = NULL;
@@ -63,22 +59,32 @@ acpi_reserve_io_ranges (struct acpi_resource *res, void *data)
if (io_res->min_base_address != io_res->max_base_address)
return_VALUE(AE_OK);
- if (IS_RESERVED_ADDR(io_res->min_base_address, io_res->range_length)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
- io_res->min_base_address,
- io_res->min_base_address + io_res->range_length));
- requested_res = request_region(io_res->min_base_address,
- io_res->range_length, "motherboard");
+ if (IS_RESERVED_ADDR
+ (io_res->min_base_address, io_res->range_length)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Motherboard resources 0x%08x - 0x%08x\n",
+ io_res->min_base_address,
+ io_res->min_base_address +
+ io_res->range_length));
+ requested_res =
+ request_region(io_res->min_base_address,
+ io_res->range_length, "motherboard");
}
} else if (res->id == ACPI_RSTYPE_FIXED_IO) {
- struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io;
-
- if (IS_RESERVED_ADDR(fixed_io_res->base_address, fixed_io_res->range_length)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
- fixed_io_res->base_address,
- fixed_io_res->base_address + fixed_io_res->range_length));
- requested_res = request_region(fixed_io_res->base_address,
- fixed_io_res->range_length, "motherboard");
+ struct acpi_resource_fixed_io *fixed_io_res =
+ &res->data.fixed_io;
+
+ if (IS_RESERVED_ADDR
+ (fixed_io_res->base_address, fixed_io_res->range_length)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Motherboard resources 0x%08x - 0x%08x\n",
+ fixed_io_res->base_address,
+ fixed_io_res->base_address +
+ fixed_io_res->range_length));
+ requested_res =
+ request_region(fixed_io_res->base_address,
+ fixed_io_res->range_length,
+ "motherboard");
}
} else {
/* Memory mapped IO? */
@@ -89,72 +95,70 @@ acpi_reserve_io_ranges (struct acpi_resource *res, void *data)
return_VALUE(AE_OK);
}
-static int acpi_motherboard_add (struct acpi_device *device)
+static int acpi_motherboard_add(struct acpi_device *device)
{
if (!device)
return -EINVAL;
- acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- acpi_reserve_io_ranges, NULL);
+ acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+ acpi_reserve_io_ranges, NULL);
return 0;
}
static struct acpi_driver acpi_motherboard_driver1 = {
- .name = "motherboard",
- .class = "",
- .ids = ACPI_MB_HID1,
- .ops = {
- .add = acpi_motherboard_add,
- },
+ .name = "motherboard",
+ .class = "",
+ .ids = ACPI_MB_HID1,
+ .ops = {
+ .add = acpi_motherboard_add,
+ },
};
static struct acpi_driver acpi_motherboard_driver2 = {
- .name = "motherboard",
- .class = "",
- .ids = ACPI_MB_HID2,
- .ops = {
- .add = acpi_motherboard_add,
- },
+ .name = "motherboard",
+ .class = "",
+ .ids = ACPI_MB_HID2,
+ .ops = {
+ .add = acpi_motherboard_add,
+ },
};
-static void __init
-acpi_reserve_resources (void)
+static void __init acpi_reserve_resources(void)
{
if (acpi_gbl_FADT->xpm1a_evt_blk.address && acpi_gbl_FADT->pm1_evt_len)
- request_region(acpi_gbl_FADT->xpm1a_evt_blk.address,
- acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK");
+ request_region(acpi_gbl_FADT->xpm1a_evt_blk.address,
+ acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK");
if (acpi_gbl_FADT->xpm1b_evt_blk.address && acpi_gbl_FADT->pm1_evt_len)
request_region(acpi_gbl_FADT->xpm1b_evt_blk.address,
- acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK");
+ acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK");
if (acpi_gbl_FADT->xpm1a_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len)
- request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address,
- acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK");
+ request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address,
+ acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK");
if (acpi_gbl_FADT->xpm1b_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len)
- request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address,
- acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK");
+ request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address,
+ acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK");
if (acpi_gbl_FADT->xpm_tmr_blk.address && acpi_gbl_FADT->pm_tm_len == 4)
- request_region(acpi_gbl_FADT->xpm_tmr_blk.address,
- 4, "PM_TMR");
+ request_region(acpi_gbl_FADT->xpm_tmr_blk.address, 4, "PM_TMR");
if (acpi_gbl_FADT->xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len)
request_region(acpi_gbl_FADT->xpm2_cnt_blk.address,
- acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK");
+ acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK");
/* Length of GPE blocks must be a non-negative multiple of 2 */
if (acpi_gbl_FADT->xgpe0_blk.address && acpi_gbl_FADT->gpe0_blk_len &&
- !(acpi_gbl_FADT->gpe0_blk_len & 0x1))
+ !(acpi_gbl_FADT->gpe0_blk_len & 0x1))
request_region(acpi_gbl_FADT->xgpe0_blk.address,
- acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK");
+ acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK");
if (acpi_gbl_FADT->xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len &&
- !(acpi_gbl_FADT->gpe1_blk_len & 0x1))
+ !(acpi_gbl_FADT->gpe1_blk_len & 0x1))
request_region(acpi_gbl_FADT->xgpe1_blk.address,
- acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK");
+ acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK");
}
static int __init acpi_motherboard_init(void)
@@ -166,7 +170,7 @@ static int __init acpi_motherboard_init(void)
* This module must run after scan.c
*/
if (!acpi_disabled)
- acpi_reserve_resources ();
+ acpi_reserve_resources();
return 0;
}
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index ece7a9dedd5c..edfbe34600f5 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -41,16 +41,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
#include <acpi/acdispat.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsaccess")
-
+ACPI_MODULE_NAME("nsaccess")
/*******************************************************************************
*
@@ -65,24 +62,19 @@
* MUTEX: Locks namespace for entire execution
*
******************************************************************************/
-
-acpi_status
-acpi_ns_root_initialize (
- void)
+acpi_status acpi_ns_root_initialize(void)
{
- acpi_status status;
+ acpi_status status;
const struct acpi_predefined_names *init_val = NULL;
- struct acpi_namespace_node *new_node;
- union acpi_operand_object *obj_desc;
- acpi_string val = NULL;
-
-
- ACPI_FUNCTION_TRACE ("ns_root_initialize");
+ struct acpi_namespace_node *new_node;
+ union acpi_operand_object *obj_desc;
+ acpi_string val = NULL;
+ ACPI_FUNCTION_TRACE("ns_root_initialize");
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -102,24 +94,26 @@ acpi_ns_root_initialize (
/* Enter the pre-defined names in the name table */
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Entering predefined entries into namespace\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Entering predefined entries into namespace\n"));
for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
/* _OSI is optional for now, will be permanent later */
- if (!ACPI_STRCMP (init_val->name, "_OSI") && !acpi_gbl_create_osi_method) {
+ if (!ACPI_STRCMP(init_val->name, "_OSI")
+ && !acpi_gbl_create_osi_method) {
continue;
}
- status = acpi_ns_lookup (NULL, init_val->name, init_val->type,
- ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
- NULL, &new_node);
+ status = acpi_ns_lookup(NULL, init_val->name, init_val->type,
+ ACPI_IMODE_LOAD_PASS2,
+ ACPI_NS_NO_UPSEARCH, NULL, &new_node);
- if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not create predefined name %s, %s\n",
- init_val->name, acpi_format_exception (status)));
+ if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not create predefined name %s, %s\n",
+ init_val->name,
+ acpi_format_exception(status)));
}
/*
@@ -128,11 +122,11 @@ acpi_ns_root_initialize (
* initial value, create the initial value.
*/
if (init_val->val) {
- status = acpi_os_predefined_override (init_val, &val);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not override predefined %s\n",
- init_val->name));
+ status = acpi_os_predefined_override(init_val, &val);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not override predefined %s\n",
+ init_val->name));
}
if (!val) {
@@ -143,7 +137,8 @@ acpi_ns_root_initialize (
* Entry requests an initial value, allocate a
* descriptor for it.
*/
- obj_desc = acpi_ut_create_internal_object (init_val->type);
+ obj_desc =
+ acpi_ut_create_internal_object(init_val->type);
if (!obj_desc) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
@@ -156,55 +151,62 @@ acpi_ns_root_initialize (
*/
switch (init_val->type) {
case ACPI_TYPE_METHOD:
- obj_desc->method.param_count = (u8) ACPI_TO_INTEGER (val);
+ obj_desc->method.param_count =
+ (u8) ACPI_TO_INTEGER(val);
obj_desc->common.flags |= AOPOBJ_DATA_VALID;
-#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_App)
+#if defined (ACPI_ASL_COMPILER)
- /*
- * i_aSL Compiler cheats by putting parameter count
- * in the owner_iD
- */
- new_node->owner_id = obj_desc->method.param_count;
+ /* save the parameter count for the i_aSL compiler */
+
+ new_node->value = obj_desc->method.param_count;
#else
/* Mark this as a very SPECIAL method */
- obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY;
- obj_desc->method.implementation = acpi_ut_osi_implementation;
+ obj_desc->method.method_flags =
+ AML_METHOD_INTERNAL_ONLY;
+
+#ifndef ACPI_DUMP_APP
+ obj_desc->method.implementation =
+ acpi_ut_osi_implementation;
+#endif
#endif
break;
case ACPI_TYPE_INTEGER:
- obj_desc->integer.value = ACPI_TO_INTEGER (val);
+ obj_desc->integer.value = ACPI_TO_INTEGER(val);
break;
-
case ACPI_TYPE_STRING:
/*
* Build an object around the static string
*/
- obj_desc->string.length = (u32) ACPI_STRLEN (val);
+ obj_desc->string.length =
+ (u32) ACPI_STRLEN(val);
obj_desc->string.pointer = val;
obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
break;
-
case ACPI_TYPE_MUTEX:
obj_desc->mutex.node = new_node;
- obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER (val) - 1);
+ obj_desc->mutex.sync_level =
+ (u8) (ACPI_TO_INTEGER(val) - 1);
- if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
+ if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
/*
* Create a counting semaphore for the
* global lock
*/
- status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
- 1, &obj_desc->mutex.semaphore);
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (obj_desc);
+ status =
+ acpi_os_create_semaphore
+ (ACPI_NO_UNIT_LIMIT, 1,
+ &obj_desc->mutex.semaphore);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference
+ (obj_desc);
goto unlock_and_exit;
}
@@ -212,56 +214,58 @@ acpi_ns_root_initialize (
* We just created the mutex for the
* global lock, save it
*/
- acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore;
- }
- else {
+ acpi_gbl_global_lock_semaphore =
+ obj_desc->mutex.semaphore;
+ } else {
/* Create a mutex */
- status = acpi_os_create_semaphore (1, 1,
- &obj_desc->mutex.semaphore);
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (obj_desc);
+ status = acpi_os_create_semaphore(1, 1,
+ &obj_desc->
+ mutex.
+ semaphore);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference
+ (obj_desc);
goto unlock_and_exit;
}
}
break;
-
default:
- ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
- init_val->type));
- acpi_ut_remove_reference (obj_desc);
+ ACPI_REPORT_ERROR(("Unsupported initial type value %X\n", init_val->type));
+ acpi_ut_remove_reference(obj_desc);
obj_desc = NULL;
continue;
}
/* Store pointer to value descriptor in the Node */
- status = acpi_ns_attach_object (new_node, obj_desc,
- ACPI_GET_OBJECT_TYPE (obj_desc));
+ status = acpi_ns_attach_object(new_node, obj_desc,
+ ACPI_GET_OBJECT_TYPE
+ (obj_desc));
/* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
}
}
-
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
/* Save a handle to "_GPE", it is always present */
- if (ACPI_SUCCESS (status)) {
- status = acpi_ns_get_node_by_path ("\\_GPE", NULL, ACPI_NS_NO_UPSEARCH,
- &acpi_gbl_fadt_gpe_device);
+ if (ACPI_SUCCESS(status)) {
+ status =
+ acpi_ns_get_node_by_path("\\_GPE", NULL,
+ ACPI_NS_NO_UPSEARCH,
+ &acpi_gbl_fadt_gpe_device);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_lookup
@@ -286,62 +290,57 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_ns_lookup (
- union acpi_generic_state *scope_info,
- char *pathname,
- acpi_object_type type,
- acpi_interpreter_mode interpreter_mode,
- u32 flags,
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node **return_node)
+acpi_ns_lookup(union acpi_generic_state *scope_info,
+ char *pathname,
+ acpi_object_type type,
+ acpi_interpreter_mode interpreter_mode,
+ u32 flags,
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node **return_node)
{
- acpi_status status;
- char *path = pathname;
- struct acpi_namespace_node *prefix_node;
- struct acpi_namespace_node *current_node = NULL;
- struct acpi_namespace_node *this_node = NULL;
- u32 num_segments;
- u32 num_carats;
- acpi_name simple_name;
- acpi_object_type type_to_check_for;
- acpi_object_type this_search_type;
- u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
- u32 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND |
- ACPI_NS_SEARCH_PARENT);
-
-
- ACPI_FUNCTION_TRACE ("ns_lookup");
-
+ acpi_status status;
+ char *path = pathname;
+ struct acpi_namespace_node *prefix_node;
+ struct acpi_namespace_node *current_node = NULL;
+ struct acpi_namespace_node *this_node = NULL;
+ u32 num_segments;
+ u32 num_carats;
+ acpi_name simple_name;
+ acpi_object_type type_to_check_for;
+ acpi_object_type this_search_type;
+ u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
+ u32 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND |
+ ACPI_NS_SEARCH_PARENT);
+
+ ACPI_FUNCTION_TRACE("ns_lookup");
if (!return_node) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
acpi_gbl_ns_lookup_count++;
*return_node = ACPI_ENTRY_NOT_FOUND;
if (!acpi_gbl_root_node) {
- return_ACPI_STATUS (AE_NO_NAMESPACE);
+ return_ACPI_STATUS(AE_NO_NAMESPACE);
}
/*
* Get the prefix scope.
* A null scope means use the root scope
*/
- if ((!scope_info) ||
- (!scope_info->scope.node)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Null scope prefix, using root node (%p)\n",
- acpi_gbl_root_node));
+ if ((!scope_info) || (!scope_info->scope.node)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Null scope prefix, using root node (%p)\n",
+ acpi_gbl_root_node));
prefix_node = acpi_gbl_root_node;
- }
- else {
+ } else {
prefix_node = scope_info->scope.node;
- if (ACPI_GET_DESCRIPTOR_TYPE (prefix_node) != ACPI_DESC_TYPE_NAMED) {
- ACPI_REPORT_ERROR (("ns_lookup: %p is not a namespace node [%s]\n",
- prefix_node, acpi_ut_get_descriptor_name (prefix_node)));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
+ ACPI_DESC_TYPE_NAMED) {
+ ACPI_REPORT_ERROR(("ns_lookup: %p is not a namespace node [%s]\n", prefix_node, acpi_ut_get_descriptor_name(prefix_node)));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
/*
@@ -349,9 +348,9 @@ acpi_ns_lookup (
* Device/Method, etc.) It could be a Package or other object node.
* Backup up the tree to find the containing scope node.
*/
- while (!acpi_ns_opens_scope (prefix_node->type) &&
- prefix_node->type != ACPI_TYPE_ANY) {
- prefix_node = acpi_ns_get_parent_node (prefix_node);
+ while (!acpi_ns_opens_scope(prefix_node->type) &&
+ prefix_node->type != ACPI_TYPE_ANY) {
+ prefix_node = acpi_ns_get_parent_node(prefix_node);
}
}
@@ -366,13 +365,13 @@ acpi_ns_lookup (
/* A Null name_path is allowed and refers to the root */
num_segments = 0;
- this_node = acpi_gbl_root_node;
- path = "";
+ this_node = acpi_gbl_root_node;
+ path = "";
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Null Pathname (Zero segments), Flags=%X\n", flags));
- }
- else {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Null Pathname (Zero segments), Flags=%X\n",
+ flags));
+ } else {
/*
* Name pointer is valid (and must be in internal name format)
*
@@ -396,15 +395,16 @@ acpi_ns_lookup (
path++;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Path is absolute from root [%p]\n", this_node));
- }
- else {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Path is absolute from root [%p]\n",
+ this_node));
+ } else {
/* Pathname is relative to current scope, start there */
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Searching relative to prefix scope [%4.4s] (%p)\n",
- acpi_ut_get_node_name (prefix_node), prefix_node));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Searching relative to prefix scope [%4.4s] (%p)\n",
+ acpi_ut_get_node_name(prefix_node),
+ prefix_node));
/*
* Handle multiple Parent Prefixes (carat) by just getting
@@ -425,20 +425,20 @@ acpi_ns_lookup (
/* Backup to the parent node */
num_carats++;
- this_node = acpi_ns_get_parent_node (this_node);
+ this_node = acpi_ns_get_parent_node(this_node);
if (!this_node) {
/* Current scope has no parent scope */
- ACPI_REPORT_ERROR (
- ("ACPI path has too many parent prefixes (^) - reached beyond root node\n"));
- return_ACPI_STATUS (AE_NOT_FOUND);
+ ACPI_REPORT_ERROR(("ACPI path has too many parent prefixes (^) - reached beyond root node\n"));
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
}
if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Search scope is [%4.4s], path has %d carat(s)\n",
- acpi_ut_get_node_name (this_node), num_carats));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Search scope is [%4.4s], path has %d carat(s)\n",
+ acpi_ut_get_node_name
+ (this_node), num_carats));
}
}
@@ -464,9 +464,9 @@ acpi_ns_lookup (
num_segments = 0;
type = this_node->type;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Prefix-only Pathname (Zero name segments), Flags=%X\n",
- flags));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Prefix-only Pathname (Zero name segments), Flags=%X\n",
+ flags));
break;
case AML_DUAL_NAME_PREFIX:
@@ -480,8 +480,9 @@ acpi_ns_lookup (
num_segments = 2;
path++;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Dual Pathname (2 segments, Flags=%X)\n", flags));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Dual Pathname (2 segments, Flags=%X)\n",
+ flags));
break;
case AML_MULTI_NAME_PREFIX_OP:
@@ -493,12 +494,12 @@ acpi_ns_lookup (
/* Extract segment count, point to first name segment */
path++;
- num_segments = (u32) (u8) *path;
+ num_segments = (u32) (u8) * path;
path++;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Multi Pathname (%d Segments, Flags=%X) \n",
- num_segments, flags));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Multi Pathname (%d Segments, Flags=%X) \n",
+ num_segments, flags));
break;
default:
@@ -508,15 +509,15 @@ acpi_ns_lookup (
*/
num_segments = 1;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Simple Pathname (1 segment, Flags=%X)\n", flags));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Simple Pathname (1 segment, Flags=%X)\n",
+ flags));
break;
}
- ACPI_DEBUG_EXEC (acpi_ns_print_pathname (num_segments, path));
+ ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
}
-
/*
* Search namespace for each segment of the name. Loop through and
* verify (or add to the namespace) each name segment.
@@ -540,7 +541,7 @@ acpi_ns_lookup (
* requested it AND we have a single, non-fully-qualified name_seg
*/
if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
- (flags & ACPI_NS_SEARCH_PARENT)) {
+ (flags & ACPI_NS_SEARCH_PARENT)) {
local_flags |= ACPI_NS_SEARCH_PARENT;
}
@@ -553,24 +554,28 @@ acpi_ns_lookup (
/* Extract one ACPI name from the front of the pathname */
- ACPI_MOVE_32_TO_32 (&simple_name, path);
+ ACPI_MOVE_32_TO_32(&simple_name, path);
/* Try to find the single (4 character) ACPI name */
- status = acpi_ns_search_and_enter (simple_name, walk_state, current_node,
- interpreter_mode, this_search_type, local_flags, &this_node);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ns_search_and_enter(simple_name, walk_state,
+ current_node, interpreter_mode,
+ this_search_type, local_flags,
+ &this_node);
+ if (ACPI_FAILURE(status)) {
if (status == AE_NOT_FOUND) {
/* Name not found in ACPI namespace */
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Name [%4.4s] not found in scope [%4.4s] %p\n",
- (char *) &simple_name, (char *) &current_node->name,
- current_node));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Name [%4.4s] not found in scope [%4.4s] %p\n",
+ (char *)&simple_name,
+ (char *)&current_node->name,
+ current_node));
}
*return_node = this_node;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/*
@@ -586,19 +591,16 @@ acpi_ns_lookup (
*
* Then we have a type mismatch. Just warn and ignore it.
*/
- if ((num_segments == 0) &&
- (type_to_check_for != ACPI_TYPE_ANY) &&
- (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
- (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) &&
- (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) &&
- (this_node->type != ACPI_TYPE_ANY) &&
- (this_node->type != type_to_check_for)) {
+ if ((num_segments == 0) &&
+ (type_to_check_for != ACPI_TYPE_ANY) &&
+ (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
+ (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) &&
+ (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) &&
+ (this_node->type != ACPI_TYPE_ANY) &&
+ (this_node->type != type_to_check_for)) {
/* Complain about a type mismatch */
- ACPI_REPORT_WARNING (
- ("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n",
- (char *) &simple_name, acpi_ut_get_type_name (this_node->type),
- acpi_ut_get_type_name (type_to_check_for)));
+ ACPI_REPORT_WARNING(("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n", (char *)&simple_name, acpi_ut_get_type_name(this_node->type), acpi_ut_get_type_name(type_to_check_for)));
}
/*
@@ -624,15 +626,16 @@ acpi_ns_lookup (
* If entry is a type which opens a scope, push the new scope on the
* scope stack.
*/
- if (acpi_ns_opens_scope (type)) {
- status = acpi_ds_scope_stack_push (this_node, type, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (acpi_ns_opens_scope(type)) {
+ status =
+ acpi_ds_scope_stack_push(this_node, type,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
}
*return_node = this_node;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index 5653a19d7172..cc7a85f8cfe6 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -41,20 +41,14 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsalloc")
+ACPI_MODULE_NAME("nsalloc")
/* Local prototypes */
-
-static void
-acpi_ns_remove_reference (
- struct acpi_namespace_node *node);
-
+static void acpi_ns_remove_reference(struct acpi_namespace_node *node);
/*******************************************************************************
*
@@ -68,31 +62,26 @@ acpi_ns_remove_reference (
*
******************************************************************************/
-struct acpi_namespace_node *
-acpi_ns_create_node (
- u32 name)
+struct acpi_namespace_node *acpi_ns_create_node(u32 name)
{
- struct acpi_namespace_node *node;
-
+ struct acpi_namespace_node *node;
- ACPI_FUNCTION_TRACE ("ns_create_node");
+ ACPI_FUNCTION_TRACE("ns_create_node");
-
- node = ACPI_MEM_CALLOCATE (sizeof (struct acpi_namespace_node));
+ node = ACPI_MEM_CALLOCATE(sizeof(struct acpi_namespace_node));
if (!node) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_allocated++);
+ ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
- node->name.integer = name;
+ node->name.integer = name;
node->reference_count = 1;
- ACPI_SET_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED);
+ ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
- return_PTR (node);
+ return_PTR(node);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_delete_node
@@ -105,19 +94,15 @@ acpi_ns_create_node (
*
******************************************************************************/
-void
-acpi_ns_delete_node (
- struct acpi_namespace_node *node)
+void acpi_ns_delete_node(struct acpi_namespace_node *node)
{
- struct acpi_namespace_node *parent_node;
- struct acpi_namespace_node *prev_node;
- struct acpi_namespace_node *next_node;
-
+ struct acpi_namespace_node *parent_node;
+ struct acpi_namespace_node *prev_node;
+ struct acpi_namespace_node *next_node;
- ACPI_FUNCTION_TRACE_PTR ("ns_delete_node", node);
+ ACPI_FUNCTION_TRACE_PTR("ns_delete_node", node);
-
- parent_node = acpi_ns_get_parent_node (node);
+ parent_node = acpi_ns_get_parent_node(node);
prev_node = NULL;
next_node = parent_node->child;
@@ -136,32 +121,29 @@ acpi_ns_delete_node (
if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
}
- }
- else {
+ } else {
/* Node is first child (has no previous peer) */
if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
/* No peers at all */
parent_node->child = NULL;
- }
- else { /* Link peer list to parent */
+ } else { /* Link peer list to parent */
parent_node->child = next_node->peer;
}
}
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);
+ ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
/*
* Detach an object if there is one then delete the node
*/
- acpi_ns_detach_object (node);
- ACPI_MEM_FREE (node);
+ acpi_ns_detach_object(node);
+ ACPI_MEM_FREE(node);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_install_node
@@ -176,30 +158,20 @@ acpi_ns_delete_node (
* DESCRIPTION: Initialize a new namespace node and install it amongst
* its peers.
*
- * Note: Current namespace lookup is linear search. However, the
- * nodes are linked in alphabetical order to 1) put all reserved
- * names (start with underscore) first, and to 2) make a readable
- * namespace dump.
+ * Note: Current namespace lookup is linear search. This appears
+ * to be sufficient as namespace searches consume only a small
+ * fraction of the execution time of the ACPI subsystem.
*
******************************************************************************/
-void
-acpi_ns_install_node (
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node *parent_node, /* Parent */
- struct acpi_namespace_node *node, /* New Child*/
- acpi_object_type type)
+void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namespace_node *parent_node, /* Parent */
+ struct acpi_namespace_node *node, /* New Child */
+ acpi_object_type type)
{
- u16 owner_id = 0;
- struct acpi_namespace_node *child_node;
-#ifdef ACPI_ALPHABETIC_NAMESPACE
-
- struct acpi_namespace_node *previous_child_node;
-#endif
-
-
- ACPI_FUNCTION_TRACE ("ns_install_node");
+ acpi_owner_id owner_id = 0;
+ struct acpi_namespace_node *child_node;
+ ACPI_FUNCTION_TRACE("ns_install_node");
/*
* Get the owner ID from the Walk state
@@ -217,59 +189,7 @@ acpi_ns_install_node (
parent_node->child = node;
node->flags |= ANOBJ_END_OF_PEER_LIST;
node->peer = parent_node;
- }
- else {
-#ifdef ACPI_ALPHABETIC_NAMESPACE
- /*
- * Walk the list whilst searching for the correct
- * alphabetic placement.
- */
- previous_child_node = NULL;
- while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node),
- acpi_ut_get_node_name (node)) < 0) {
- if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
- /* Last peer; Clear end-of-list flag */
-
- child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
-
- /* This node is the new peer to the child node */
-
- child_node->peer = node;
-
- /* This node is the new end-of-list */
-
- node->flags |= ANOBJ_END_OF_PEER_LIST;
- node->peer = parent_node;
- break;
- }
-
- /* Get next peer */
-
- previous_child_node = child_node;
- child_node = child_node->peer;
- }
-
- /* Did the node get inserted at the end-of-list? */
-
- if (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
- /*
- * Loop above terminated without reaching the end-of-list.
- * Insert the new node at the current location
- */
- if (previous_child_node) {
- /* Insert node alphabetically */
-
- node->peer = child_node;
- previous_child_node->peer = node;
- }
- else {
- /* Insert node alphabetically at start of list */
-
- node->peer = child_node;
- parent_node->child = node;
- }
- }
-#else
+ } else {
while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) {
child_node = child_node->peer;
}
@@ -279,9 +199,8 @@ acpi_ns_install_node (
/* Clear end-of-list flag */
child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
- node->flags |= ANOBJ_END_OF_PEER_LIST;
+ node->flags |= ANOBJ_END_OF_PEER_LIST;
node->peer = parent_node;
-#endif
}
/* Init the new entry */
@@ -289,24 +208,25 @@ acpi_ns_install_node (
node->owner_id = owner_id;
node->type = (u8) type;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
- acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id,
- acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type),
- parent_node));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
+ acpi_ut_get_node_name(node),
+ acpi_ut_get_type_name(node->type), node, owner_id,
+ acpi_ut_get_node_name(parent_node),
+ acpi_ut_get_type_name(parent_node->type),
+ parent_node));
/*
* Increment the reference count(s) of all parents up to
* the root!
*/
- while ((node = acpi_ns_get_parent_node (node)) != NULL) {
+ while ((node = acpi_ns_get_parent_node(node)) != NULL) {
node->reference_count++;
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_delete_children
@@ -320,18 +240,14 @@ acpi_ns_install_node (
*
******************************************************************************/
-void
-acpi_ns_delete_children (
- struct acpi_namespace_node *parent_node)
+void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
{
- struct acpi_namespace_node *child_node;
- struct acpi_namespace_node *next_node;
- struct acpi_namespace_node *node;
- u8 flags;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ns_delete_children", parent_node);
+ struct acpi_namespace_node *child_node;
+ struct acpi_namespace_node *next_node;
+ struct acpi_namespace_node *node;
+ u8 flags;
+ ACPI_FUNCTION_TRACE_PTR("ns_delete_children", parent_node);
if (!parent_node) {
return_VOID;
@@ -350,48 +266,48 @@ acpi_ns_delete_children (
do {
/* Get the things we need */
- next_node = child_node->peer;
- flags = child_node->flags;
+ next_node = child_node->peer;
+ flags = child_node->flags;
/* Grandchildren should have all been deleted already */
if (child_node->child) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n",
- parent_node, child_node));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Found a grandchild! P=%p C=%p\n",
+ parent_node, child_node));
}
/* Now we can free this child object */
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);
+ ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n",
- child_node, acpi_gbl_current_node_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Object %p, Remaining %X\n", child_node,
+ acpi_gbl_current_node_count));
/*
* Detach an object if there is one, then free the child node
*/
- acpi_ns_detach_object (child_node);
+ acpi_ns_detach_object(child_node);
/*
* Decrement the reference count(s) of all parents up to
* the root! (counts were incremented when the node was created)
*/
node = child_node;
- while ((node = acpi_ns_get_parent_node (node)) != NULL) {
+ while ((node = acpi_ns_get_parent_node(node)) != NULL) {
node->reference_count--;
}
/* There should be only one reference remaining on this node */
if (child_node->reference_count != 1) {
- ACPI_REPORT_WARNING ((
- "Existing references (%d) on node being deleted (%p)\n",
- child_node->reference_count, child_node));
+ ACPI_REPORT_WARNING(("Existing references (%d) on node being deleted (%p)\n", child_node->reference_count, child_node));
}
/* Now we can delete the node */
- ACPI_MEM_FREE (child_node);
+ ACPI_MEM_FREE(child_node);
/* And move on to the next child in the list */
@@ -399,7 +315,6 @@ acpi_ns_delete_children (
} while (!(flags & ANOBJ_END_OF_PEER_LIST));
-
/* Clear the parent's child pointer */
parent_node->child = NULL;
@@ -407,7 +322,6 @@ acpi_ns_delete_children (
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_delete_namespace_subtree
@@ -421,16 +335,12 @@ acpi_ns_delete_children (
*
******************************************************************************/
-void
-acpi_ns_delete_namespace_subtree (
- struct acpi_namespace_node *parent_node)
+void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
{
- struct acpi_namespace_node *child_node = NULL;
- u32 level = 1;
-
-
- ACPI_FUNCTION_TRACE ("ns_delete_namespace_subtree");
+ struct acpi_namespace_node *child_node = NULL;
+ u32 level = 1;
+ ACPI_FUNCTION_TRACE("ns_delete_namespace_subtree");
if (!parent_node) {
return_VOID;
@@ -443,16 +353,17 @@ acpi_ns_delete_namespace_subtree (
while (level > 0) {
/* Get the next node in this scope (NULL if none) */
- child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node,
- child_node);
+ child_node = acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
+ child_node);
if (child_node) {
/* Found a child node - detach any attached object */
- acpi_ns_detach_object (child_node);
+ acpi_ns_detach_object(child_node);
/* Check if this node has any children */
- if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
+ if (acpi_ns_get_next_node
+ (ACPI_TYPE_ANY, child_node, NULL)) {
/*
* There is at least one child of this node,
* visit the node
@@ -461,8 +372,7 @@ acpi_ns_delete_namespace_subtree (
parent_node = child_node;
child_node = NULL;
}
- }
- else {
+ } else {
/*
* No more children of this parent node.
* Move up to the grandparent.
@@ -473,7 +383,7 @@ acpi_ns_delete_namespace_subtree (
* Now delete all of the children of this parent
* all at the same time.
*/
- acpi_ns_delete_children (parent_node);
+ acpi_ns_delete_children(parent_node);
/* New "last child" is this parent node */
@@ -481,14 +391,13 @@ acpi_ns_delete_namespace_subtree (
/* Move up the tree to the grandparent */
- parent_node = acpi_ns_get_parent_node (parent_node);
+ parent_node = acpi_ns_get_parent_node(parent_node);
}
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_remove_reference
@@ -504,16 +413,12 @@ acpi_ns_delete_namespace_subtree (
*
******************************************************************************/
-static void
-acpi_ns_remove_reference (
- struct acpi_namespace_node *node)
+static void acpi_ns_remove_reference(struct acpi_namespace_node *node)
{
- struct acpi_namespace_node *parent_node;
- struct acpi_namespace_node *this_node;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_namespace_node *parent_node;
+ struct acpi_namespace_node *this_node;
+ ACPI_FUNCTION_ENTRY();
/*
* Decrement the reference count(s) of this node and all
@@ -523,7 +428,7 @@ acpi_ns_remove_reference (
while (this_node) {
/* Prepare to move up to parent */
- parent_node = acpi_ns_get_parent_node (this_node);
+ parent_node = acpi_ns_get_parent_node(this_node);
/* Decrement the reference count on this node */
@@ -534,15 +439,14 @@ acpi_ns_remove_reference (
if (!this_node->reference_count) {
/* Delete all children and delete the node */
- acpi_ns_delete_children (this_node);
- acpi_ns_delete_node (this_node);
+ acpi_ns_delete_children(this_node);
+ acpi_ns_delete_node(this_node);
}
this_node = parent_node;
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_delete_namespace_by_owner
@@ -557,23 +461,23 @@ acpi_ns_remove_reference (
*
******************************************************************************/
-void
-acpi_ns_delete_namespace_by_owner (
- u16 owner_id)
+void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
{
- struct acpi_namespace_node *child_node;
- struct acpi_namespace_node *deletion_node;
- u32 level;
- struct acpi_namespace_node *parent_node;
-
+ struct acpi_namespace_node *child_node;
+ struct acpi_namespace_node *deletion_node;
+ u32 level;
+ struct acpi_namespace_node *parent_node;
- ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id);
+ ACPI_FUNCTION_TRACE_U32("ns_delete_namespace_by_owner", owner_id);
+ if (owner_id == 0) {
+ return_VOID;
+ }
- parent_node = acpi_gbl_root_node;
- child_node = NULL;
+ parent_node = acpi_gbl_root_node;
+ child_node = NULL;
deletion_node = NULL;
- level = 1;
+ level = 1;
/*
* Traverse the tree of nodes until we bubble back up
@@ -584,10 +488,12 @@ acpi_ns_delete_namespace_by_owner (
* Get the next child of this parent node. When child_node is NULL,
* the first child of the parent is returned
*/
- child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node);
+ child_node =
+ acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
+ child_node);
if (deletion_node) {
- acpi_ns_remove_reference (deletion_node);
+ acpi_ns_remove_reference(deletion_node);
deletion_node = NULL;
}
@@ -595,12 +501,13 @@ acpi_ns_delete_namespace_by_owner (
if (child_node->owner_id == owner_id) {
/* Found a matching child node - detach any attached object */
- acpi_ns_detach_object (child_node);
+ acpi_ns_detach_object(child_node);
}
/* Check if this node has any children */
- if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
+ if (acpi_ns_get_next_node
+ (ACPI_TYPE_ANY, child_node, NULL)) {
/*
* There is at least one child of this node,
* visit the node
@@ -608,12 +515,10 @@ acpi_ns_delete_namespace_by_owner (
level++;
parent_node = child_node;
child_node = NULL;
- }
- else if (child_node->owner_id == owner_id) {
+ } else if (child_node->owner_id == owner_id) {
deletion_node = child_node;
}
- }
- else {
+ } else {
/*
* No more children of this parent node.
* Move up to the grandparent.
@@ -631,62 +536,9 @@ acpi_ns_delete_namespace_by_owner (
/* Move up the tree to the grandparent */
- parent_node = acpi_ns_get_parent_node (parent_node);
+ parent_node = acpi_ns_get_parent_node(parent_node);
}
}
return_VOID;
}
-
-
-#ifdef ACPI_ALPHABETIC_NAMESPACE
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_compare_names
- *
- * PARAMETERS: Name1 - First name to compare
- * Name2 - Second name to compare
- *
- * RETURN: value from strncmp
- *
- * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an
- * underscore are forced to be alphabetically first.
- *
- ******************************************************************************/
-
-int
-acpi_ns_compare_names (
- char *name1,
- char *name2)
-{
- char reversed_name1[ACPI_NAME_SIZE];
- char reversed_name2[ACPI_NAME_SIZE];
- u32 i;
- u32 j;
-
-
- /*
- * Replace all instances of "underscore" with a value that is smaller so
- * that all names that are prefixed with underscore(s) are alphabetically
- * first.
- *
- * Reverse the name bytewise so we can just do a 32-bit compare instead
- * of a strncmp.
- */
- for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) {
- reversed_name1[j] = name1[i];
- if (name1[i] == '_') {
- reversed_name1[j] = '*';
- }
-
- reversed_name2[j] = name2[i];
- if (name2[i] == '_') {
- reversed_name2[j] = '*';
- }
- }
-
- return (*(int *) reversed_name1 - *(int *) reversed_name2);
-}
-#endif
-
-
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 6c2aef0e0dd4..9faf1d5c86ed 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -41,31 +41,22 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsdump")
+ACPI_MODULE_NAME("nsdump")
/* Local prototypes */
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
-void
-acpi_ns_dump_root_devices (
- void);
+void acpi_ns_dump_root_devices(void);
static acpi_status
-acpi_ns_dump_one_device (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value);
+acpi_ns_dump_one_device(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value);
#endif
-
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/*******************************************************************************
*
@@ -80,36 +71,38 @@ acpi_ns_dump_one_device (
*
******************************************************************************/
-void
-acpi_ns_print_pathname (
- u32 num_segments,
- char *pathname)
+void acpi_ns_print_pathname(u32 num_segments, char *pathname)
{
- ACPI_FUNCTION_NAME ("ns_print_pathname");
+ acpi_native_uint i;
+ ACPI_FUNCTION_NAME("ns_print_pathname");
- if (!(acpi_dbg_level & ACPI_LV_NAMES) || !(acpi_dbg_layer & ACPI_NAMESPACE)) {
+ if (!(acpi_dbg_level & ACPI_LV_NAMES)
+ || !(acpi_dbg_layer & ACPI_NAMESPACE)) {
return;
}
/* Print the entire name */
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "["));
while (num_segments) {
- acpi_os_printf ("%4.4s", pathname);
- pathname += ACPI_NAME_SIZE;
+ for (i = 0; i < 4; i++) {
+ ACPI_IS_PRINT(pathname[i]) ?
+ acpi_os_printf("%c", pathname[i]) :
+ acpi_os_printf("?");
+ }
+ pathname += ACPI_NAME_SIZE;
num_segments--;
if (num_segments) {
- acpi_os_printf (".");
+ acpi_os_printf(".");
}
}
- acpi_os_printf ("]\n");
+ acpi_os_printf("]\n");
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_pathname
@@ -127,15 +120,10 @@ acpi_ns_print_pathname (
******************************************************************************/
void
-acpi_ns_dump_pathname (
- acpi_handle handle,
- char *msg,
- u32 level,
- u32 component)
+acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component)
{
- ACPI_FUNCTION_TRACE ("ns_dump_pathname");
-
+ ACPI_FUNCTION_TRACE("ns_dump_pathname");
/* Do this only if the requested debug level and component are enabled */
@@ -145,12 +133,11 @@ acpi_ns_dump_pathname (
/* Convert handle to a full pathname and print it (with supplied message) */
- acpi_ns_print_node_pathname (handle, msg);
- acpi_os_printf ("\n");
+ acpi_ns_print_node_pathname(handle, msg);
+ acpi_os_printf("\n");
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_one_object
@@ -168,24 +155,19 @@ acpi_ns_dump_pathname (
******************************************************************************/
acpi_status
-acpi_ns_dump_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ns_dump_one_object(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value)
{
- struct acpi_walk_info *info = (struct acpi_walk_info *) context;
- struct acpi_namespace_node *this_node;
- union acpi_operand_object *obj_desc = NULL;
- acpi_object_type obj_type;
- acpi_object_type type;
- u32 bytes_to_dump;
- u32 dbg_level;
- u32 i;
-
-
- ACPI_FUNCTION_NAME ("ns_dump_one_object");
+ struct acpi_walk_info *info = (struct acpi_walk_info *)context;
+ struct acpi_namespace_node *this_node;
+ union acpi_operand_object *obj_desc = NULL;
+ acpi_object_type obj_type;
+ acpi_object_type type;
+ u32 bytes_to_dump;
+ u32 dbg_level;
+ u32 i;
+ ACPI_FUNCTION_NAME("ns_dump_one_object");
/* Is output enabled? */
@@ -194,193 +176,215 @@ acpi_ns_dump_one_object (
}
if (!obj_handle) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n"));
return (AE_OK);
}
- this_node = acpi_ns_map_handle_to_node (obj_handle);
+ this_node = acpi_ns_map_handle_to_node(obj_handle);
type = this_node->type;
/* Check if the owner matches */
- if ((info->owner_id != ACPI_UINT32_MAX) &&
- (info->owner_id != this_node->owner_id)) {
+ if ((info->owner_id != ACPI_OWNER_ID_MAX) &&
+ (info->owner_id != this_node->owner_id)) {
return (AE_OK);
}
- /* Indent the object according to the level */
+ if (!(info->display_type & ACPI_DISPLAY_SHORT)) {
+ /* Indent the object according to the level */
- acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " ");
+ acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " ");
- /* Check the node type and name */
+ /* Check the node type and name */
- if (type > ACPI_TYPE_LOCAL_MAX) {
- ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type));
- }
+ if (type > ACPI_TYPE_LOCAL_MAX) {
+ ACPI_REPORT_WARNING(("Invalid ACPI Type %08X\n", type));
+ }
+
+ if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
+ ACPI_REPORT_WARNING(("Invalid ACPI Name %08X\n",
+ this_node->name.integer));
+ }
- if (!acpi_ut_valid_acpi_name (this_node->name.integer)) {
- ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n",
- this_node->name.integer));
+ acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
}
/*
* Now we can print out the pertinent information
*/
- acpi_os_printf ("%4.4s %-12s %p ",
- acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node);
+ acpi_os_printf(" %-12s %p ", acpi_ut_get_type_name(type), this_node);
dbg_level = acpi_dbg_level;
acpi_dbg_level = 0;
- obj_desc = acpi_ns_get_attached_object (this_node);
+ obj_desc = acpi_ns_get_attached_object(this_node);
acpi_dbg_level = dbg_level;
- switch (info->display_type) {
+ switch (info->display_type & ACPI_DISPLAY_MASK) {
case ACPI_DISPLAY_SUMMARY:
if (!obj_desc) {
/* No attached object, we are done */
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
return (AE_OK);
}
switch (type) {
case ACPI_TYPE_PROCESSOR:
- acpi_os_printf ("ID %X Len %.4X Addr %p\n",
- obj_desc->processor.proc_id, obj_desc->processor.length,
- (char *) obj_desc->processor.address);
+ acpi_os_printf("ID %X Len %.4X Addr %p\n",
+ obj_desc->processor.proc_id,
+ obj_desc->processor.length,
+ (char *)obj_desc->processor.address);
break;
-
case ACPI_TYPE_DEVICE:
- acpi_os_printf ("Notify Object: %p\n", obj_desc);
+ acpi_os_printf("Notify Object: %p\n", obj_desc);
break;
-
case ACPI_TYPE_METHOD:
- acpi_os_printf ("Args %X Len %.4X Aml %p\n",
- (u32) obj_desc->method.param_count,
- obj_desc->method.aml_length, obj_desc->method.aml_start);
+ acpi_os_printf("Args %X Len %.4X Aml %p\n",
+ (u32) obj_desc->method.param_count,
+ obj_desc->method.aml_length,
+ obj_desc->method.aml_start);
break;
-
case ACPI_TYPE_INTEGER:
- acpi_os_printf ("= %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+ acpi_os_printf("= %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(obj_desc->integer.
+ value));
break;
-
case ACPI_TYPE_PACKAGE:
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
- acpi_os_printf ("Elements %.2X\n",
- obj_desc->package.count);
- }
- else {
- acpi_os_printf ("[Length not yet evaluated]\n");
+ acpi_os_printf("Elements %.2X\n",
+ obj_desc->package.count);
+ } else {
+ acpi_os_printf("[Length not yet evaluated]\n");
}
break;
-
case ACPI_TYPE_BUFFER:
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
- acpi_os_printf ("Len %.2X",
- obj_desc->buffer.length);
+ acpi_os_printf("Len %.2X",
+ obj_desc->buffer.length);
/* Dump some of the buffer */
if (obj_desc->buffer.length > 0) {
- acpi_os_printf (" =");
- for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) {
- acpi_os_printf (" %.2hX", obj_desc->buffer.pointer[i]);
+ acpi_os_printf(" =");
+ for (i = 0;
+ (i < obj_desc->buffer.length
+ && i < 12); i++) {
+ acpi_os_printf(" %.2hX",
+ obj_desc->buffer.
+ pointer[i]);
}
}
- acpi_os_printf ("\n");
- }
- else {
- acpi_os_printf ("[Length not yet evaluated]\n");
+ acpi_os_printf("\n");
+ } else {
+ acpi_os_printf("[Length not yet evaluated]\n");
}
break;
-
case ACPI_TYPE_STRING:
- acpi_os_printf ("Len %.2X ", obj_desc->string.length);
- acpi_ut_print_string (obj_desc->string.pointer, 32);
- acpi_os_printf ("\n");
+ acpi_os_printf("Len %.2X ", obj_desc->string.length);
+ acpi_ut_print_string(obj_desc->string.pointer, 32);
+ acpi_os_printf("\n");
break;
-
case ACPI_TYPE_REGION:
- acpi_os_printf ("[%s]",
- acpi_ut_get_region_name (obj_desc->region.space_id));
+ acpi_os_printf("[%s]",
+ acpi_ut_get_region_name(obj_desc->region.
+ space_id));
if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
- acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n",
- ACPI_FORMAT_UINT64 (obj_desc->region.address),
- obj_desc->region.length);
- }
- else {
- acpi_os_printf (" [Address/Length not yet evaluated]\n");
+ acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n",
+ ACPI_FORMAT_UINT64(obj_desc->
+ region.
+ address),
+ obj_desc->region.length);
+ } else {
+ acpi_os_printf
+ (" [Address/Length not yet evaluated]\n");
}
break;
-
case ACPI_TYPE_LOCAL_REFERENCE:
- acpi_os_printf ("[%s]\n",
- acpi_ps_get_opcode_name (obj_desc->reference.opcode));
+ acpi_os_printf("[%s]\n",
+ acpi_ps_get_opcode_name(obj_desc->
+ reference.
+ opcode));
break;
-
case ACPI_TYPE_BUFFER_FIELD:
if (obj_desc->buffer_field.buffer_obj &&
- obj_desc->buffer_field.buffer_obj->buffer.node) {
- acpi_os_printf ("Buf [%4.4s]",
- acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node));
+ obj_desc->buffer_field.buffer_obj->buffer.node) {
+ acpi_os_printf("Buf [%4.4s]",
+ acpi_ut_get_node_name(obj_desc->
+ buffer_field.
+ buffer_obj->
+ buffer.
+ node));
}
break;
-
case ACPI_TYPE_LOCAL_REGION_FIELD:
- acpi_os_printf ("Rgn [%4.4s]",
- acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node));
+ acpi_os_printf("Rgn [%4.4s]",
+ acpi_ut_get_node_name(obj_desc->
+ common_field.
+ region_obj->region.
+ node));
break;
-
case ACPI_TYPE_LOCAL_BANK_FIELD:
- acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]",
- acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node),
- acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node));
+ acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]",
+ acpi_ut_get_node_name(obj_desc->
+ common_field.
+ region_obj->region.
+ node),
+ acpi_ut_get_node_name(obj_desc->
+ bank_field.
+ bank_obj->
+ common_field.
+ node));
break;
-
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]",
- acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node),
- acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node));
+ acpi_os_printf("Idx [%4.4s] Dat [%4.4s]",
+ acpi_ut_get_node_name(obj_desc->
+ index_field.
+ index_obj->
+ common_field.node),
+ acpi_ut_get_node_name(obj_desc->
+ index_field.
+ data_obj->
+ common_field.
+ node));
break;
-
case ACPI_TYPE_LOCAL_ALIAS:
case ACPI_TYPE_LOCAL_METHOD_ALIAS:
- acpi_os_printf ("Target %4.4s (%p)\n",
- acpi_ut_get_node_name (obj_desc), obj_desc);
+ acpi_os_printf("Target %4.4s (%p)\n",
+ acpi_ut_get_node_name(obj_desc),
+ obj_desc);
break;
default:
- acpi_os_printf ("Object %p\n", obj_desc);
+ acpi_os_printf("Object %p\n", obj_desc);
break;
}
@@ -392,11 +396,15 @@ acpi_ns_dump_one_object (
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n",
- (obj_desc->common_field.base_byte_offset * 8)
- + obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.bit_length,
- obj_desc->common_field.access_byte_width);
+ acpi_os_printf(" Off %.3X Len %.2X Acc %.2hd\n",
+ (obj_desc->common_field.
+ base_byte_offset * 8)
+ +
+ obj_desc->common_field.
+ start_field_bit_offset,
+ obj_desc->common_field.bit_length,
+ obj_desc->common_field.
+ access_byte_width);
break;
default:
@@ -404,56 +412,55 @@ acpi_ns_dump_one_object (
}
break;
-
case ACPI_DISPLAY_OBJECTS:
- acpi_os_printf ("O:%p", obj_desc);
+ acpi_os_printf("O:%p", obj_desc);
if (!obj_desc) {
/* No attached object, we are done */
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
return (AE_OK);
}
- acpi_os_printf ("(R%d)", obj_desc->common.reference_count);
+ acpi_os_printf("(R%d)", obj_desc->common.reference_count);
switch (type) {
case ACPI_TYPE_METHOD:
/* Name is a Method and its AML offset/length are set */
- acpi_os_printf (" M:%p-%X\n", obj_desc->method.aml_start,
- obj_desc->method.aml_length);
+ acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start,
+ obj_desc->method.aml_length);
break;
case ACPI_TYPE_INTEGER:
- acpi_os_printf (" I:%8.8X8.8%X\n",
- ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+ acpi_os_printf(" I:%8.8X8.8%X\n",
+ ACPI_FORMAT_UINT64(obj_desc->integer.
+ value));
break;
case ACPI_TYPE_STRING:
- acpi_os_printf (" S:%p-%X\n", obj_desc->string.pointer,
- obj_desc->string.length);
+ acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer,
+ obj_desc->string.length);
break;
case ACPI_TYPE_BUFFER:
- acpi_os_printf (" B:%p-%X\n", obj_desc->buffer.pointer,
- obj_desc->buffer.length);
+ acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer,
+ obj_desc->buffer.length);
break;
default:
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
break;
}
break;
-
default:
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
break;
}
@@ -463,61 +470,58 @@ acpi_ns_dump_one_object (
return (AE_OK);
}
-
/* If there is an attached object, display it */
- dbg_level = acpi_dbg_level;
+ dbg_level = acpi_dbg_level;
acpi_dbg_level = 0;
- obj_desc = acpi_ns_get_attached_object (this_node);
+ obj_desc = acpi_ns_get_attached_object(this_node);
acpi_dbg_level = dbg_level;
/* Dump attached objects */
while (obj_desc) {
obj_type = ACPI_TYPE_INVALID;
- acpi_os_printf (" Attached Object %p: ", obj_desc);
+ acpi_os_printf("Attached Object %p: ", obj_desc);
/* Decode the type of attached object and dump the contents */
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+ switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_NAMED:
- acpi_os_printf ("(Ptr to Node)\n");
- bytes_to_dump = sizeof (struct acpi_namespace_node);
+ acpi_os_printf("(Ptr to Node)\n");
+ bytes_to_dump = sizeof(struct acpi_namespace_node);
+ ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
break;
-
case ACPI_DESC_TYPE_OPERAND:
- obj_type = ACPI_GET_OBJECT_TYPE (obj_desc);
+ obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
if (obj_type > ACPI_TYPE_LOCAL_MAX) {
- acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n",
- obj_type);
+ acpi_os_printf
+ ("(Ptr to ACPI Object type %X [UNKNOWN])\n",
+ obj_type);
bytes_to_dump = 32;
+ } else {
+ acpi_os_printf
+ ("(Ptr to ACPI Object type %X [%s])\n",
+ obj_type, acpi_ut_get_type_name(obj_type));
+ bytes_to_dump =
+ sizeof(union acpi_operand_object);
}
- else {
- acpi_os_printf ("(Ptr to ACPI Object type %s, %X)\n",
- acpi_ut_get_type_name (obj_type), obj_type);
- bytes_to_dump = sizeof (union acpi_operand_object);
- }
- break;
+ ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
+ break;
default:
- acpi_os_printf (
- "(String or Buffer ptr - not an object descriptor) [%s]\n",
- acpi_ut_get_descriptor_name (obj_desc));
- bytes_to_dump = 16;
break;
}
- ACPI_DUMP_BUFFER (obj_desc, bytes_to_dump);
-
/* If value is NOT an internal object, we are done */
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
+ ACPI_DESC_TYPE_OPERAND) {
goto cleanup;
}
@@ -525,51 +529,56 @@ acpi_ns_dump_one_object (
* Valid object, get the pointer to next level, if any
*/
switch (obj_type) {
- case ACPI_TYPE_STRING:
- obj_desc = (void *) obj_desc->string.pointer;
- break;
-
case ACPI_TYPE_BUFFER:
- obj_desc = (void *) obj_desc->buffer.pointer;
- break;
+ case ACPI_TYPE_STRING:
+ /*
+ * NOTE: takes advantage of common fields between string/buffer
+ */
+ bytes_to_dump = obj_desc->string.length;
+ obj_desc = (void *)obj_desc->string.pointer;
+ acpi_os_printf("(Buffer/String pointer %p length %X)\n",
+ obj_desc, bytes_to_dump);
+ ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
+ goto cleanup;
case ACPI_TYPE_BUFFER_FIELD:
- obj_desc = (union acpi_operand_object *) obj_desc->buffer_field.buffer_obj;
+ obj_desc =
+ (union acpi_operand_object *)obj_desc->buffer_field.
+ buffer_obj;
break;
case ACPI_TYPE_PACKAGE:
- obj_desc = (void *) obj_desc->package.elements;
+ obj_desc = (void *)obj_desc->package.elements;
break;
case ACPI_TYPE_METHOD:
- obj_desc = (void *) obj_desc->method.aml_start;
+ obj_desc = (void *)obj_desc->method.aml_start;
break;
case ACPI_TYPE_LOCAL_REGION_FIELD:
- obj_desc = (void *) obj_desc->field.region_obj;
+ obj_desc = (void *)obj_desc->field.region_obj;
break;
case ACPI_TYPE_LOCAL_BANK_FIELD:
- obj_desc = (void *) obj_desc->bank_field.region_obj;
+ obj_desc = (void *)obj_desc->bank_field.region_obj;
break;
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- obj_desc = (void *) obj_desc->index_field.index_obj;
+ obj_desc = (void *)obj_desc->index_field.index_obj;
break;
default:
goto cleanup;
}
- obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */
+ obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */
}
-cleanup:
- acpi_os_printf ("\n");
+ cleanup:
+ acpi_os_printf("\n");
return (AE_OK);
}
-
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -591,29 +600,25 @@ cleanup:
******************************************************************************/
void
-acpi_ns_dump_objects (
- acpi_object_type type,
- u8 display_type,
- u32 max_depth,
- u32 owner_id,
- acpi_handle start_handle)
+acpi_ns_dump_objects(acpi_object_type type,
+ u8 display_type,
+ u32 max_depth,
+ acpi_owner_id owner_id, acpi_handle start_handle)
{
- struct acpi_walk_info info;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_walk_info info;
+ ACPI_FUNCTION_ENTRY();
info.debug_level = ACPI_LV_TABLES;
info.owner_id = owner_id;
info.display_type = display_type;
- (void) acpi_ns_walk_namespace (type, start_handle, max_depth,
- ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
- (void *) &info, NULL);
+ (void)acpi_ns_walk_namespace(type, start_handle, max_depth,
+ ACPI_NS_WALK_NO_UNLOCK,
+ acpi_ns_dump_one_object, (void *)&info,
+ NULL);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -628,26 +633,20 @@ acpi_ns_dump_objects (
*
******************************************************************************/
-void
-acpi_ns_dump_entry (
- acpi_handle handle,
- u32 debug_level)
+void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level)
{
- struct acpi_walk_info info;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_walk_info info;
+ ACPI_FUNCTION_ENTRY();
info.debug_level = debug_level;
- info.owner_id = ACPI_UINT32_MAX;
+ info.owner_id = ACPI_OWNER_ID_MAX;
info.display_type = ACPI_DISPLAY_SUMMARY;
- (void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
+ (void)acpi_ns_dump_one_object(handle, 1, &info, NULL);
}
-
-#ifdef _ACPI_ASL_COMPILER
+#ifdef ACPI_ASL_COMPILER
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_tables
@@ -663,23 +662,19 @@ acpi_ns_dump_entry (
*
******************************************************************************/
-void
-acpi_ns_dump_tables (
- acpi_handle search_base,
- u32 max_depth)
+void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth)
{
- acpi_handle search_handle = search_base;
-
-
- ACPI_FUNCTION_TRACE ("ns_dump_tables");
+ acpi_handle search_handle = search_base;
+ ACPI_FUNCTION_TRACE("ns_dump_tables");
if (!acpi_gbl_root_node) {
/*
* If the name space has not been initialized,
* there is nothing to dump.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "namespace not initialized!\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
+ "namespace not initialized!\n"));
return_VOID;
}
@@ -687,12 +682,12 @@ acpi_ns_dump_tables (
/* Entire namespace */
search_handle = acpi_gbl_root_node;
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n"));
}
- acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
- ACPI_UINT32_MAX, search_handle);
+ acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
+ ACPI_OWNER_ID_MAX, search_handle);
return_VOID;
}
-#endif /* _ACPI_ASL_COMPILER */
-#endif /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */
+#endif /* _ACPI_ASL_COMPILER */
+#endif /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index 27c4f7cd2a43..55de883943d6 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -41,20 +41,15 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
-
/* TBD: This entire module is apparently obsolete and should be removed */
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsdumpdv")
-
+ACPI_MODULE_NAME("nsdumpdv")
#ifdef ACPI_OBSOLETE_FUNCTIONS
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-
#include <acpi/acnamesp.h>
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_one_device
@@ -70,44 +65,39 @@
* This procedure is a user_function called by acpi_ns_walk_namespace.
*
******************************************************************************/
-
static acpi_status
-acpi_ns_dump_one_device (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ns_dump_one_device(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value)
{
- struct acpi_buffer buffer;
- struct acpi_device_info *info;
- acpi_status status;
- u32 i;
-
+ struct acpi_buffer buffer;
+ struct acpi_device_info *info;
+ acpi_status status;
+ u32 i;
- ACPI_FUNCTION_NAME ("ns_dump_one_device");
+ ACPI_FUNCTION_NAME("ns_dump_one_device");
-
- status = acpi_ns_dump_one_object (obj_handle, level, context, return_value);
+ status =
+ acpi_ns_dump_one_object(obj_handle, level, context, return_value);
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_get_object_info (obj_handle, &buffer);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_get_object_info(obj_handle, &buffer);
+ if (ACPI_SUCCESS(status)) {
info = buffer.pointer;
for (i = 0; i < level; i++) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " "));
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES,
- " HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
- info->hardware_id.value, ACPI_FORMAT_UINT64 (info->address),
- info->current_status));
- ACPI_MEM_FREE (info);
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES,
+ " HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
+ info->hardware_id.value,
+ ACPI_FORMAT_UINT64(info->address),
+ info->current_status));
+ ACPI_MEM_FREE(info);
}
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_root_devices
@@ -120,16 +110,12 @@ acpi_ns_dump_one_device (
*
******************************************************************************/
-void
-acpi_ns_dump_root_devices (
- void)
+void acpi_ns_dump_root_devices(void)
{
- acpi_handle sys_bus_handle;
- acpi_status status;
-
-
- ACPI_FUNCTION_NAME ("ns_dump_root_devices");
+ acpi_handle sys_bus_handle;
+ acpi_status status;
+ ACPI_FUNCTION_NAME("ns_dump_root_devices");
/* Only dump the table if tracing is enabled */
@@ -138,19 +124,17 @@ acpi_ns_dump_root_devices (
}
status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
return;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
- "Display of all devices in the namespace:\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
+ "Display of all devices in the namespace:\n"));
- status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle,
- ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
- acpi_ns_dump_one_device, NULL, NULL);
+ status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
+ acpi_ns_dump_one_device, NULL, NULL);
}
#endif
#endif
-
-
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 1ae89a1c8826..0191c7d92824 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -42,26 +42,19 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nseval")
+ACPI_MODULE_NAME("nseval")
/* Local prototypes */
-
static acpi_status
-acpi_ns_execute_control_method (
- struct acpi_parameter_info *info);
-
-static acpi_status
-acpi_ns_get_object_value (
- struct acpi_parameter_info *info);
+acpi_ns_execute_control_method(struct acpi_parameter_info *info);
+static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info);
/*******************************************************************************
*
@@ -85,48 +78,44 @@ acpi_ns_get_object_value (
******************************************************************************/
acpi_status
-acpi_ns_evaluate_relative (
- char *pathname,
- struct acpi_parameter_info *info)
+acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info)
{
- acpi_status status;
- struct acpi_namespace_node *node = NULL;
- union acpi_generic_state *scope_info;
- char *internal_path = NULL;
-
-
- ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
+ acpi_status status;
+ struct acpi_namespace_node *node = NULL;
+ union acpi_generic_state *scope_info;
+ char *internal_path = NULL;
+ ACPI_FUNCTION_TRACE("ns_evaluate_relative");
/*
* Must have a valid object handle
*/
if (!info || !info->node) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Build an internal name string for the method */
- status = acpi_ns_internalize_name (pathname, &internal_path);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_internalize_name(pathname, &internal_path);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- scope_info = acpi_ut_create_generic_state ();
+ scope_info = acpi_ut_create_generic_state();
if (!scope_info) {
goto cleanup1;
}
/* Get the prefix handle and Node */
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- info->node = acpi_ns_map_handle_to_node (info->node);
+ info->node = acpi_ns_map_handle_to_node(info->node);
if (!info->node) {
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
status = AE_BAD_PARAMETER;
goto cleanup;
}
@@ -134,39 +123,38 @@ acpi_ns_evaluate_relative (
/* Lookup the name in the namespace */
scope_info->scope.node = info->node;
- status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
- ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
- &node);
+ status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
+ &node);
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
- pathname, acpi_format_exception (status)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
+ pathname, acpi_format_exception(status)));
goto cleanup;
}
/*
* Now that we have a handle to the object, we can attempt to evaluate it.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
- pathname, node, acpi_ns_get_attached_object (node)));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
+ pathname, node, acpi_ns_get_attached_object(node)));
info->node = node;
- status = acpi_ns_evaluate_by_handle (info);
+ status = acpi_ns_evaluate_by_handle(info);
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
- pathname));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "*** Completed eval of object %s ***\n", pathname));
-cleanup:
- acpi_ut_delete_generic_state (scope_info);
+ cleanup:
+ acpi_ut_delete_generic_state(scope_info);
-cleanup1:
- ACPI_MEM_FREE (internal_path);
- return_ACPI_STATUS (status);
+ cleanup1:
+ ACPI_MEM_FREE(internal_path);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_evaluate_by_name
@@ -189,68 +177,63 @@ cleanup1:
******************************************************************************/
acpi_status
-acpi_ns_evaluate_by_name (
- char *pathname,
- struct acpi_parameter_info *info)
+acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
{
- acpi_status status;
- char *internal_path = NULL;
-
-
- ACPI_FUNCTION_TRACE ("ns_evaluate_by_name");
+ acpi_status status;
+ char *internal_path = NULL;
+ ACPI_FUNCTION_TRACE("ns_evaluate_by_name");
/* Build an internal name string for the method */
- status = acpi_ns_internalize_name (pathname, &internal_path);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_internalize_name(pathname, &internal_path);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Lookup the name in the namespace */
- status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
- ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
- &info->node);
+ status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
+ &info->node);
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Object at [%s] was not found, status=%.4X\n",
- pathname, status));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Object at [%s] was not found, status=%.4X\n",
+ pathname, status));
goto cleanup;
}
/*
* Now that we have a handle to the object, we can attempt to evaluate it.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
- pathname, info->node, acpi_ns_get_attached_object (info->node)));
-
- status = acpi_ns_evaluate_by_handle (info);
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
+ pathname, info->node,
+ acpi_ns_get_attached_object(info->node)));
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
- pathname));
+ status = acpi_ns_evaluate_by_handle(info);
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "*** Completed eval of object %s ***\n", pathname));
-cleanup:
+ cleanup:
/* Cleanup */
if (internal_path) {
- ACPI_MEM_FREE (internal_path);
+ ACPI_MEM_FREE(internal_path);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_evaluate_by_handle
@@ -275,26 +258,22 @@ cleanup:
*
******************************************************************************/
-acpi_status
-acpi_ns_evaluate_by_handle (
- struct acpi_parameter_info *info)
+acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_evaluate_by_handle");
/* Check if namespace has been initialized */
if (!acpi_gbl_root_node) {
- return_ACPI_STATUS (AE_NO_NAMESPACE);
+ return_ACPI_STATUS(AE_NO_NAMESPACE);
}
/* Parameter Validation */
if (!info) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Initialize the return value to an invalid object */
@@ -303,23 +282,25 @@ acpi_ns_evaluate_by_handle (
/* Get the prefix handle and Node */
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- info->node = acpi_ns_map_handle_to_node (info->node);
+ info->node = acpi_ns_map_handle_to_node(info->node);
if (!info->node) {
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* For a method alias, we must grab the actual method node so that proper
* scoping context will be established before execution.
*/
- if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
- info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object);
+ if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+ info->node =
+ ACPI_CAST_PTR(struct acpi_namespace_node,
+ info->node->object);
}
/*
@@ -329,17 +310,16 @@ acpi_ns_evaluate_by_handle (
*
* In both cases, the namespace is unlocked by the acpi_ns* procedure
*/
- if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) {
+ if (acpi_ns_get_type(info->node) == ACPI_TYPE_METHOD) {
/*
* Case 1) We have an actual control method to execute
*/
- status = acpi_ns_execute_control_method (info);
- }
- else {
+ status = acpi_ns_execute_control_method(info);
+ } else {
/*
* Case 2) Object is NOT a method, just return its current value
*/
- status = acpi_ns_get_object_value (info);
+ status = acpi_ns_get_object_value(info);
}
/*
@@ -355,16 +335,16 @@ acpi_ns_evaluate_by_handle (
* Namespace was unlocked by the handling acpi_ns* function, so we
* just return
*/
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_execute_control_method
*
* PARAMETERS: Info - Method info block, contains:
* Node - Method Node to execute
+ * obj_desc - Method object
* Parameters - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
@@ -383,31 +363,29 @@ acpi_ns_evaluate_by_handle (
******************************************************************************/
static acpi_status
-acpi_ns_execute_control_method (
- struct acpi_parameter_info *info)
+acpi_ns_execute_control_method(struct acpi_parameter_info *info)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE ("ns_execute_control_method");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_execute_control_method");
/* Verify that there is a method associated with this object */
- obj_desc = acpi_ns_get_attached_object (info->node);
- if (!obj_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
+ info->obj_desc = acpi_ns_get_attached_object(info->node);
+ if (!info->obj_desc) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No attached method object\n"));
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (AE_NULL_OBJECT);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(AE_NULL_OBJECT);
}
- ACPI_DUMP_PATHNAME (info->node, "Execute Method:",
- ACPI_LV_INFO, _COMPONENT);
+ ACPI_DUMP_PATHNAME(info->node, "Execute Method:",
+ ACPI_LV_INFO, _COMPONENT);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
- obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
+ info->obj_desc->method.aml_start + 1,
+ info->obj_desc->method.aml_length - 1));
/*
* Unlock the namespace before execution. This allows namespace access
@@ -416,27 +394,26 @@ acpi_ns_execute_control_method (
* interpreter locks to ensure that no thread is using the portion of the
* namespace that is being deleted.
*/
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* Execute the method via the interpreter. The interpreter is locked
* here before calling into the AML parser
*/
- status = acpi_ex_enter_interpreter ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_psx_execute (info);
- acpi_ex_exit_interpreter ();
+ status = acpi_ps_execute_method(info);
+ acpi_ex_exit_interpreter();
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_object_value
@@ -454,16 +431,12 @@ acpi_ns_execute_control_method (
*
******************************************************************************/
-static acpi_status
-acpi_ns_get_object_value (
- struct acpi_parameter_info *info)
+static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info)
{
- acpi_status status = AE_OK;
- struct acpi_namespace_node *resolved_node = info->node;
-
-
- ACPI_FUNCTION_TRACE ("ns_get_object_value");
+ acpi_status status = AE_OK;
+ struct acpi_namespace_node *resolved_node = info->node;
+ ACPI_FUNCTION_TRACE("ns_get_object_value");
/*
* Objects require additional resolution steps (e.g., the Node may be a
@@ -486,32 +459,33 @@ acpi_ns_get_object_value (
*
* We must release the namespace lock before entering the intepreter.
*/
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ex_enter_interpreter ();
- if (ACPI_SUCCESS (status)) {
- status = acpi_ex_resolve_node_to_value (&resolved_node, NULL);
+ status = acpi_ex_enter_interpreter();
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_ex_resolve_node_to_value(&resolved_node, NULL);
/*
* If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
* in resolved_node.
*/
- acpi_ex_exit_interpreter ();
+ acpi_ex_exit_interpreter();
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
status = AE_CTRL_RETURN_VALUE;
info->return_object = ACPI_CAST_PTR
- (union acpi_operand_object, resolved_node);
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
- info->return_object,
- acpi_ut_get_object_type_name (info->return_object)));
+ (union acpi_operand_object, resolved_node);
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Returning object %p [%s]\n",
+ info->return_object,
+ acpi_ut_get_object_type_name(info->
+ return_object)));
}
}
/* Namespace is unlocked */
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 362802ae29a2..0a08d2f04a06 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -41,31 +41,22 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsinit")
+ACPI_MODULE_NAME("nsinit")
/* Local prototypes */
-
static acpi_status
-acpi_ns_init_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value);
+acpi_ns_init_one_object(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value);
static acpi_status
-acpi_ns_init_one_device (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value);
-
+acpi_ns_init_one_device(acpi_handle obj_handle,
+ u32 nesting_level, void *context, void **return_value);
/*******************************************************************************
*
@@ -80,52 +71,48 @@ acpi_ns_init_one_device (
*
******************************************************************************/
-acpi_status
-acpi_ns_initialize_objects (
- void)
+acpi_status acpi_ns_initialize_objects(void)
{
- acpi_status status;
- struct acpi_init_walk_info info;
-
+ acpi_status status;
+ struct acpi_init_walk_info info;
- ACPI_FUNCTION_TRACE ("ns_initialize_objects");
+ ACPI_FUNCTION_TRACE("ns_initialize_objects");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "**** Starting initialization of namespace objects ****\n"));
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
- "Completing Region/Field/Buffer/Package initialization:"));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "**** Starting initialization of namespace objects ****\n"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+ "Completing Region/Field/Buffer/Package initialization:"));
/* Set all init info to zero */
- ACPI_MEMSET (&info, 0, sizeof (struct acpi_init_walk_info));
+ ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info));
/* Walk entire namespace from the supplied root */
- status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, acpi_ns_init_one_object,
- &info, NULL);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
- acpi_format_exception (status)));
+ status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, acpi_ns_init_one_object,
+ &info, NULL);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
+ acpi_format_exception(status)));
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
- "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
- info.op_region_init, info.op_region_count,
- info.field_init, info.field_count,
- info.buffer_init, info.buffer_count,
- info.package_init, info.package_count, info.object_count));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+ "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+ info.op_region_init, info.op_region_count,
+ info.field_init, info.field_count,
+ info.buffer_init, info.buffer_count,
+ info.package_init, info.package_count,
+ info.object_count));
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "%hd Control Methods found\n", info.method_count));
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "%hd Op Regions found\n", info.op_region_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "%hd Control Methods found\n", info.method_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+ "%hd Op Regions found\n", info.op_region_count));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_initialize_devices
@@ -142,16 +129,12 @@ acpi_ns_initialize_objects (
*
******************************************************************************/
-acpi_status
-acpi_ns_initialize_devices (
- void)
+acpi_status acpi_ns_initialize_devices(void)
{
- acpi_status status;
- struct acpi_device_walk_info info;
-
-
- ACPI_FUNCTION_TRACE ("ns_initialize_devices");
+ acpi_status status;
+ struct acpi_device_walk_info info;
+ ACPI_FUNCTION_TRACE("ns_initialize_devices");
/* Init counters */
@@ -159,34 +142,34 @@ acpi_ns_initialize_devices (
info.num_STA = 0;
info.num_INI = 0;
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
- "Executing all Device _STA and_INI methods:"));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+ "Executing all Device _STA and_INI methods:"));
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Walk namespace for all objects */
- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL);
+ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, TRUE,
+ acpi_ns_init_one_device, &info, NULL);
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
- acpi_format_exception (status)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
+ acpi_format_exception(status)));
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
- "\n%hd Devices found containing: %hd _STA, %hd _INI methods\n",
- info.device_count, info.num_STA, info.num_INI));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+ "\n%hd Devices found containing: %hd _STA, %hd _INI methods\n",
+ info.device_count, info.num_STA, info.num_INI));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_init_one_object
@@ -208,28 +191,25 @@ acpi_ns_initialize_devices (
******************************************************************************/
static acpi_status
-acpi_ns_init_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ns_init_one_object(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value)
{
- acpi_object_type type;
- acpi_status status;
- struct acpi_init_walk_info *info = (struct acpi_init_walk_info *) context;
- struct acpi_namespace_node *node = (struct acpi_namespace_node *) obj_handle;
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_NAME ("ns_init_one_object");
+ acpi_object_type type;
+ acpi_status status;
+ struct acpi_init_walk_info *info =
+ (struct acpi_init_walk_info *)context;
+ struct acpi_namespace_node *node =
+ (struct acpi_namespace_node *)obj_handle;
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_NAME("ns_init_one_object");
info->object_count++;
/* And even then, we are only interested in a few object types */
- type = acpi_ns_get_type (obj_handle);
- obj_desc = acpi_ns_get_attached_object (node);
+ type = acpi_ns_get_type(obj_handle);
+ obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
return (AE_OK);
}
@@ -269,8 +249,8 @@ acpi_ns_init_one_object (
/*
* Must lock the interpreter before executing AML code
*/
- status = acpi_ex_enter_interpreter ();
- if (ACPI_FAILURE (status)) {
+ status = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status)) {
return (status);
}
@@ -282,25 +262,25 @@ acpi_ns_init_one_object (
case ACPI_TYPE_REGION:
info->op_region_init++;
- status = acpi_ds_get_region_arguments (obj_desc);
+ status = acpi_ds_get_region_arguments(obj_desc);
break;
case ACPI_TYPE_BUFFER_FIELD:
info->field_init++;
- status = acpi_ds_get_buffer_field_arguments (obj_desc);
+ status = acpi_ds_get_buffer_field_arguments(obj_desc);
break;
case ACPI_TYPE_BUFFER:
info->buffer_init++;
- status = acpi_ds_get_buffer_arguments (obj_desc);
+ status = acpi_ds_get_buffer_arguments(obj_desc);
break;
case ACPI_TYPE_PACKAGE:
info->package_init++;
- status = acpi_ds_get_package_arguments (obj_desc);
+ status = acpi_ds_get_package_arguments(obj_desc);
break;
default:
@@ -308,12 +288,13 @@ acpi_ns_init_one_object (
break;
}
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n"));
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not execute arguments for [%4.4s] (%s), %s\n",
- acpi_ut_get_node_name (node), acpi_ut_get_type_name (type),
- acpi_format_exception (status)));
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_ERROR, "\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not execute arguments for [%4.4s] (%s), %s\n",
+ acpi_ut_get_node_name(node),
+ acpi_ut_get_type_name(type),
+ acpi_format_exception(status)));
}
/*
@@ -321,18 +302,17 @@ acpi_ns_init_one_object (
* pathname
*/
if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
}
/*
* We ignore errors from above, and always return OK, since we don't want
* to abort the walk on any single error.
*/
- acpi_ex_exit_interpreter ();
+ acpi_ex_exit_interpreter();
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_init_one_device
@@ -348,41 +328,37 @@ acpi_ns_init_one_object (
******************************************************************************/
static acpi_status
-acpi_ns_init_one_device (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
+acpi_ns_init_one_device(acpi_handle obj_handle,
+ u32 nesting_level, void *context, void **return_value)
{
- struct acpi_device_walk_info *info = (struct acpi_device_walk_info *) context;
- struct acpi_parameter_info pinfo;
- u32 flags;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ns_init_one_device");
+ struct acpi_device_walk_info *info =
+ (struct acpi_device_walk_info *)context;
+ struct acpi_parameter_info pinfo;
+ u32 flags;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_init_one_device");
pinfo.parameters = NULL;
pinfo.parameter_type = ACPI_PARAM_ARGS;
- pinfo.node = acpi_ns_map_handle_to_node (obj_handle);
+ pinfo.node = acpi_ns_map_handle_to_node(obj_handle);
if (!pinfo.node) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* We will run _STA/_INI on Devices, Processors and thermal_zones only
*/
- if ((pinfo.node->type != ACPI_TYPE_DEVICE) &&
- (pinfo.node->type != ACPI_TYPE_PROCESSOR) &&
- (pinfo.node->type != ACPI_TYPE_THERMAL)) {
- return_ACPI_STATUS (AE_OK);
+ if ((pinfo.node->type != ACPI_TYPE_DEVICE) &&
+ (pinfo.node->type != ACPI_TYPE_PROCESSOR) &&
+ (pinfo.node->type != ACPI_TYPE_THERMAL)) {
+ return_ACPI_STATUS(AE_OK);
}
if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
- (!(acpi_dbg_level & ACPI_LV_INFO))) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+ (!(acpi_dbg_level & ACPI_LV_INFO))) {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
}
info->device_count++;
@@ -390,20 +366,20 @@ acpi_ns_init_one_device (
/*
* Run _STA to determine if we can run _INI on the device.
*/
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
- pinfo.node, METHOD_NAME__STA));
- status = acpi_ut_execute_STA (pinfo.node, &flags);
+ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD,
+ pinfo.node,
+ METHOD_NAME__STA));
+ status = acpi_ut_execute_STA(pinfo.node, &flags);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
if (pinfo.node->type == ACPI_TYPE_DEVICE) {
/* Ignore error and move on to next device */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* _STA is not required for Processor or thermal_zone objects */
- }
- else {
+ } else {
info->num_STA++;
if (!(flags & 0x01)) {
@@ -416,32 +392,34 @@ acpi_ns_init_one_device (
/*
* The device is present. Run _INI.
*/
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
- pinfo.node, METHOD_NAME__INI));
- status = acpi_ns_evaluate_relative (METHOD_NAME__INI, &pinfo);
- if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD,
+ pinfo.node,
+ METHOD_NAME__INI));
+ status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo);
+ if (ACPI_FAILURE(status)) {
/* No _INI (AE_NOT_FOUND) means device requires no initialization */
if (status != AE_NOT_FOUND) {
/* Ignore error and move on to next device */
#ifdef ACPI_DEBUG_OUTPUT
- char *scope_name = acpi_ns_get_external_pathname (pinfo.node);
+ char *scope_name =
+ acpi_ns_get_external_pathname(pinfo.node);
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n",
- scope_name, acpi_format_exception (status)));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n",
+ scope_name,
+ acpi_format_exception(status)));
- ACPI_MEM_FREE (scope_name);
+ ACPI_MEM_FREE(scope_name);
#endif
}
status = AE_OK;
- }
- else {
+ } else {
/* Delete any return object (especially if implicit_return is enabled) */
if (pinfo.return_object) {
- acpi_ut_remove_reference (pinfo.return_object);
+ acpi_ut_remove_reference(pinfo.return_object);
}
/* Count of successful INIs */
@@ -452,8 +430,9 @@ acpi_ns_init_one_device (
if (acpi_gbl_init_handler) {
/* External initialization handler is present, call it */
- status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI);
+ status =
+ acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index 34e497016601..c28849de465a 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -41,32 +41,22 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acdispat.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsload")
+ACPI_MODULE_NAME("nsload")
/* Local prototypes */
-
-static acpi_status
-acpi_ns_load_table_by_type (
- acpi_table_type table_type);
+static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type);
#ifdef ACPI_FUTURE_IMPLEMENTATION
-acpi_status
-acpi_ns_unload_namespace (
- acpi_handle handle);
+acpi_status acpi_ns_unload_namespace(acpi_handle handle);
-static acpi_status
-acpi_ns_delete_subtree (
- acpi_handle start_handle);
+static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
#endif
-
#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
*
@@ -82,40 +72,39 @@ acpi_ns_delete_subtree (
******************************************************************************/
acpi_status
-acpi_ns_load_table (
- struct acpi_table_desc *table_desc,
- struct acpi_namespace_node *node)
+acpi_ns_load_table(struct acpi_table_desc *table_desc,
+ struct acpi_namespace_node *node)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ns_load_table");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_load_table");
/* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
- if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
+ if (!
+ (acpi_gbl_table_data[table_desc->type].
+ flags & ACPI_TABLE_EXECUTABLE)) {
/* Just ignore this table */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Check validity of the AML start and length */
if (!table_desc->aml_start) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null AML pointer\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null AML pointer\n"));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n",
- table_desc->aml_start));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n",
+ table_desc->aml_start));
/* Ignore table if there is no AML contained within */
if (!table_desc->aml_length) {
- ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n",
- table_desc->pointer->signature));
- return_ACPI_STATUS (AE_OK);
+ ACPI_REPORT_WARNING(("Zero-length AML block in table [%4.4s]\n",
+ table_desc->pointer->signature));
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -127,19 +116,19 @@ acpi_ns_load_table (
* to another control method, we can't continue parsing
* because we don't know how many arguments to parse next!
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "**** Loading table into namespace ****\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "**** Loading table into namespace ****\n"));
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ns_parse_table (table_desc, node->child);
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ status = acpi_ns_parse_table(table_desc, node->child);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -148,18 +137,17 @@ acpi_ns_load_table (
* just-in-time parsing, we delete the control method
* parse trees.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "**** Begin Table Method Parsing and Object Initialization ****\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "**** Begin Table Method Parsing and Object Initialization ****\n"));
- status = acpi_ds_initialize_objects (table_desc, node);
+ status = acpi_ds_initialize_objects(table_desc, node);
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "**** Completed Table Method Parsing and Object Initialization ****\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "**** Completed Table Method Parsing and Object Initialization ****\n"));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_load_table_by_type
@@ -174,21 +162,17 @@ acpi_ns_load_table (
*
******************************************************************************/
-static acpi_status
-acpi_ns_load_table_by_type (
- acpi_table_type table_type)
+static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type)
{
- u32 i;
- acpi_status status;
- struct acpi_table_desc *table_desc;
-
+ u32 i;
+ acpi_status status;
+ struct acpi_table_desc *table_desc;
- ACPI_FUNCTION_TRACE ("ns_load_table_by_type");
+ ACPI_FUNCTION_TRACE("ns_load_table_by_type");
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -198,7 +182,7 @@ acpi_ns_load_table_by_type (
switch (table_type) {
case ACPI_TABLE_DSDT:
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n"));
table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next;
@@ -210,57 +194,33 @@ acpi_ns_load_table_by_type (
/* Now load the single DSDT */
- status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ns_load_table(table_desc, acpi_gbl_root_node);
+ if (ACPI_SUCCESS(status)) {
table_desc->loaded_into_namespace = TRUE;
}
break;
-
case ACPI_TABLE_SSDT:
+ case ACPI_TABLE_PSDT:
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
- acpi_gbl_table_lists[ACPI_TABLE_SSDT].count));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Namespace load: %d SSDT or PSDTs\n",
+ acpi_gbl_table_lists[table_type].count));
/*
- * Traverse list of SSDT tables
+ * Traverse list of SSDT or PSDT tables
*/
- table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next;
- for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) {
+ table_desc = acpi_gbl_table_lists[table_type].next;
+ for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) {
/*
- * Only attempt to load table if it is not
+ * Only attempt to load table into namespace if it is not
* already loaded!
*/
if (!table_desc->loaded_into_namespace) {
- status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
- if (ACPI_FAILURE (status)) {
- break;
- }
-
- table_desc->loaded_into_namespace = TRUE;
- }
-
- table_desc = table_desc->next;
- }
- break;
-
-
- case ACPI_TABLE_PSDT:
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
- acpi_gbl_table_lists[ACPI_TABLE_PSDT].count));
-
- /*
- * Traverse list of PSDT tables
- */
- table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next;
-
- for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) {
- /* Only attempt to load table if it is not already loaded! */
-
- if (!table_desc->loaded_into_namespace) {
- status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ns_load_table(table_desc,
+ acpi_gbl_root_node);
+ if (ACPI_FAILURE(status)) {
break;
}
@@ -271,19 +231,16 @@ acpi_ns_load_table_by_type (
}
break;
-
default:
status = AE_SUPPORT;
break;
}
-
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_load_namespace
@@ -297,45 +254,40 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
-acpi_ns_load_namespace (
- void)
+acpi_status acpi_ns_load_namespace(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_load_name_space");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_load_name_space");
/* There must be at least a DSDT installed */
if (acpi_gbl_DSDT == NULL) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "DSDT is not in memory\n"));
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/*
* Load the namespace. The DSDT is required,
* but the SSDT and PSDT tables are optional.
*/
- status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_load_table_by_type(ACPI_TABLE_DSDT);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Ignore exceptions from these */
- (void) acpi_ns_load_table_by_type (ACPI_TABLE_SSDT);
- (void) acpi_ns_load_table_by_type (ACPI_TABLE_PSDT);
+ (void)acpi_ns_load_table_by_type(ACPI_TABLE_SSDT);
+ (void)acpi_ns_load_table_by_type(ACPI_TABLE_PSDT);
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
- "ACPI Namespace successfully loaded at root %p\n",
- acpi_gbl_root_node));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+ "ACPI Namespace successfully loaded at root %p\n",
+ acpi_gbl_root_node));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
#ifdef ACPI_FUTURE_IMPLEMENTATION
/*******************************************************************************
*
@@ -353,24 +305,20 @@ acpi_ns_load_namespace (
*
******************************************************************************/
-static acpi_status
-acpi_ns_delete_subtree (
- acpi_handle start_handle)
+static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)
{
- acpi_status status;
- acpi_handle child_handle;
- acpi_handle parent_handle;
- acpi_handle next_child_handle;
- acpi_handle dummy;
- u32 level;
-
-
- ACPI_FUNCTION_TRACE ("ns_delete_subtree");
+ acpi_status status;
+ acpi_handle child_handle;
+ acpi_handle parent_handle;
+ acpi_handle next_child_handle;
+ acpi_handle dummy;
+ u32 level;
+ ACPI_FUNCTION_TRACE("ns_delete_subtree");
parent_handle = start_handle;
child_handle = NULL;
- level = 1;
+ level = 1;
/*
* Traverse the tree of objects until we bubble back up
@@ -379,18 +327,19 @@ acpi_ns_delete_subtree (
while (level > 0) {
/* Attempt to get the next object in this scope */
- status = acpi_get_next_object (ACPI_TYPE_ANY, parent_handle,
- child_handle, &next_child_handle);
+ status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle,
+ child_handle, &next_child_handle);
child_handle = next_child_handle;
/* Did we get a new object? */
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/* Check if this object has any children */
- if (ACPI_SUCCESS (acpi_get_next_object (ACPI_TYPE_ANY, child_handle,
- NULL, &dummy))) {
+ if (ACPI_SUCCESS
+ (acpi_get_next_object
+ (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) {
/*
* There is at least one child of this object,
* visit the object
@@ -399,8 +348,7 @@ acpi_ns_delete_subtree (
parent_handle = child_handle;
child_handle = NULL;
}
- }
- else {
+ } else {
/*
* No more children in this object, go back up to
* the object's parent
@@ -409,24 +357,23 @@ acpi_ns_delete_subtree (
/* Delete all children now */
- acpi_ns_delete_children (child_handle);
+ acpi_ns_delete_children(child_handle);
child_handle = parent_handle;
- status = acpi_get_parent (parent_handle, &parent_handle);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_get_parent(parent_handle, &parent_handle);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
}
/* Now delete the starting object, and we are done */
- acpi_ns_delete_node (child_handle);
+ acpi_ns_delete_node(child_handle);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_unload_name_space
@@ -441,32 +388,27 @@ acpi_ns_delete_subtree (
*
******************************************************************************/
-acpi_status
-acpi_ns_unload_namespace (
- acpi_handle handle)
+acpi_status acpi_ns_unload_namespace(acpi_handle handle)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ns_unload_name_space");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_unload_name_space");
/* Parameter validation */
if (!acpi_gbl_root_node) {
- return_ACPI_STATUS (AE_NO_NAMESPACE);
+ return_ACPI_STATUS(AE_NO_NAMESPACE);
}
if (!handle) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* This function does the real work */
- status = acpi_ns_delete_subtree (handle);
+ status = acpi_ns_delete_subtree(handle);
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
#endif
#endif
-
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index d8ce7e39795f..d5e8dea61c27 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -41,23 +41,17 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsnames")
+ACPI_MODULE_NAME("nsnames")
/* Local prototypes */
-
static void
-acpi_ns_build_external_path (
- struct acpi_namespace_node *node,
- acpi_size size,
- char *name_buffer);
-
+acpi_ns_build_external_path(struct acpi_namespace_node *node,
+ acpi_size size, char *name_buffer);
/*******************************************************************************
*
@@ -75,17 +69,13 @@ acpi_ns_build_external_path (
******************************************************************************/
static void
-acpi_ns_build_external_path (
- struct acpi_namespace_node *node,
- acpi_size size,
- char *name_buffer)
+acpi_ns_build_external_path(struct acpi_namespace_node *node,
+ acpi_size size, char *name_buffer)
{
- acpi_size index;
- struct acpi_namespace_node *parent_node;
-
-
- ACPI_FUNCTION_NAME ("ns_build_external_path");
+ acpi_size index;
+ struct acpi_namespace_node *parent_node;
+ ACPI_FUNCTION_NAME("ns_build_external_path");
/* Special case for root */
@@ -106,8 +96,8 @@ acpi_ns_build_external_path (
/* Put the name into the buffer */
- ACPI_MOVE_32_TO_32 ((name_buffer + index), &parent_node->name);
- parent_node = acpi_ns_get_parent_node (parent_node);
+ ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name);
+ parent_node = acpi_ns_get_parent_node(parent_node);
/* Prefix name with the path separator */
@@ -120,15 +110,14 @@ acpi_ns_build_external_path (
name_buffer[index] = AML_ROOT_PREFIX;
if (index != 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not construct pathname; index=%X, size=%X, Path=%s\n",
- (u32) index, (u32) size, &name_buffer[size]));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not construct pathname; index=%X, size=%X, Path=%s\n",
+ (u32) index, (u32) size, &name_buffer[size]));
}
return;
}
-
#ifdef ACPI_DEBUG_OUTPUT
/*******************************************************************************
*
@@ -144,37 +133,32 @@ acpi_ns_build_external_path (
*
******************************************************************************/
-char *
-acpi_ns_get_external_pathname (
- struct acpi_namespace_node *node)
+char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
{
- char *name_buffer;
- acpi_size size;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ns_get_external_pathname", node);
+ char *name_buffer;
+ acpi_size size;
+ ACPI_FUNCTION_TRACE_PTR("ns_get_external_pathname", node);
/* Calculate required buffer size based on depth below root */
- size = acpi_ns_get_pathname_length (node);
+ size = acpi_ns_get_pathname_length(node);
/* Allocate a buffer to be returned to caller */
- name_buffer = ACPI_MEM_CALLOCATE (size);
+ name_buffer = ACPI_MEM_CALLOCATE(size);
if (!name_buffer) {
- ACPI_REPORT_ERROR (("ns_get_table_pathname: allocation failure\n"));
- return_PTR (NULL);
+ ACPI_REPORT_ERROR(("ns_get_table_pathname: allocation failure\n"));
+ return_PTR(NULL);
}
/* Build the path in the allocated buffer */
- acpi_ns_build_external_path (node, size, name_buffer);
- return_PTR (name_buffer);
+ acpi_ns_build_external_path(node, size, name_buffer);
+ return_PTR(name_buffer);
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_pathname_length
@@ -187,16 +171,12 @@ acpi_ns_get_external_pathname (
*
******************************************************************************/
-acpi_size
-acpi_ns_get_pathname_length (
- struct acpi_namespace_node *node)
+acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
{
- acpi_size size;
- struct acpi_namespace_node *next_node;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_size size;
+ struct acpi_namespace_node *next_node;
+ ACPI_FUNCTION_ENTRY();
/*
* Compute length of pathname as 5 * number of name segments.
@@ -207,17 +187,16 @@ acpi_ns_get_pathname_length (
while (next_node && (next_node != acpi_gbl_root_node)) {
size += ACPI_PATH_SEGMENT_LENGTH;
- next_node = acpi_ns_get_parent_node (next_node);
+ next_node = acpi_ns_get_parent_node(next_node);
}
if (!size) {
- size = 1; /* Root node case */
+ size = 1; /* Root node case */
}
- return (size + 1); /* +1 for null string terminator */
+ return (size + 1); /* +1 for null string terminator */
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_handle_to_pathname
@@ -233,41 +212,36 @@ acpi_ns_get_pathname_length (
******************************************************************************/
acpi_status
-acpi_ns_handle_to_pathname (
- acpi_handle target_handle,
- struct acpi_buffer *buffer)
+acpi_ns_handle_to_pathname(acpi_handle target_handle,
+ struct acpi_buffer * buffer)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- acpi_size required_size;
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ acpi_size required_size;
+ ACPI_FUNCTION_TRACE_PTR("ns_handle_to_pathname", target_handle);
- ACPI_FUNCTION_TRACE_PTR ("ns_handle_to_pathname", target_handle);
-
-
- node = acpi_ns_map_handle_to_node (target_handle);
+ node = acpi_ns_map_handle_to_node(target_handle);
if (!node) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Determine size required for the caller buffer */
- required_size = acpi_ns_get_pathname_length (node);
+ required_size = acpi_ns_get_pathname_length(node);
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (buffer, required_size);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_initialize_buffer(buffer, required_size);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Build the path in the caller buffer */
- acpi_ns_build_external_path (node, required_size, buffer->pointer);
+ acpi_ns_build_external_path(node, required_size, buffer->pointer);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X] \n",
- (char *) buffer->pointer, (u32) required_size));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X] \n",
+ (char *)buffer->pointer, (u32) required_size));
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
index 27258c1ca4f1..fc9be946ebed 100644
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -42,14 +42,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsobject")
-
+ACPI_MODULE_NAME("nsobject")
/*******************************************************************************
*
@@ -71,20 +68,15 @@
* MUTEX: Assumes namespace is locked
*
******************************************************************************/
-
acpi_status
-acpi_ns_attach_object (
- struct acpi_namespace_node *node,
- union acpi_operand_object *object,
- acpi_object_type type)
+acpi_ns_attach_object(struct acpi_namespace_node *node,
+ union acpi_operand_object *object, acpi_object_type type)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *last_obj_desc;
- acpi_object_type object_type = ACPI_TYPE_ANY;
-
-
- ACPI_FUNCTION_TRACE ("ns_attach_object");
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *last_obj_desc;
+ acpi_object_type object_type = ACPI_TYPE_ANY;
+ ACPI_FUNCTION_TRACE("ns_attach_object");
/*
* Parameter validation
@@ -92,40 +84,39 @@ acpi_ns_attach_object (
if (!node) {
/* Invalid handle */
- ACPI_REPORT_ERROR (("ns_attach_object: Null named_obj handle\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("ns_attach_object: Null named_obj handle\n"));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (!object && (ACPI_TYPE_ANY != type)) {
/* Null object */
- ACPI_REPORT_ERROR ((
- "ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
/* Not a name handle */
- ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle %p [%s]\n",
- node, acpi_ut_get_descriptor_name (node)));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("ns_attach_object: Invalid handle %p [%s]\n",
+ node, acpi_ut_get_descriptor_name(node)));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Check if this object is already attached */
if (node->object == object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Obj %p already installed in name_obj %p\n",
- object, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Obj %p already installed in name_obj %p\n",
+ object, node));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* If null object, we will just install it */
if (!object) {
- obj_desc = NULL;
+ obj_desc = NULL;
object_type = ACPI_TYPE_ANY;
}
@@ -133,14 +124,14 @@ acpi_ns_attach_object (
* If the source object is a namespace Node with an attached object,
* we will use that (attached) object
*/
- else if ((ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) &&
- ((struct acpi_namespace_node *) object)->object) {
+ else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
+ ((struct acpi_namespace_node *)object)->object) {
/*
* Value passed is a name handle and that name has a
* non-null value. Use that name's value and type.
*/
- obj_desc = ((struct acpi_namespace_node *) object)->object;
- object_type = ((struct acpi_namespace_node *) object)->type;
+ obj_desc = ((struct acpi_namespace_node *)object)->object;
+ object_type = ((struct acpi_namespace_node *)object)->type;
}
/*
@@ -148,20 +139,20 @@ acpi_ns_attach_object (
* it first
*/
else {
- obj_desc = (union acpi_operand_object *) object;
+ obj_desc = (union acpi_operand_object *)object;
/* Use the given type */
object_type = type;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
- obj_desc, node, acpi_ut_get_node_name (node)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
+ obj_desc, node, acpi_ut_get_node_name(node)));
/* Detach an existing attached object if present */
if (node->object) {
- acpi_ns_detach_object (node);
+ acpi_ns_detach_object(node);
}
if (obj_desc) {
@@ -169,7 +160,7 @@ acpi_ns_attach_object (
* Must increment the new value's reference count
* (if it is an internal object)
*/
- acpi_ut_add_reference (obj_desc);
+ acpi_ut_add_reference(obj_desc);
/*
* Handle objects with multiple descriptors - walk
@@ -185,13 +176,12 @@ acpi_ns_attach_object (
last_obj_desc->common.next_object = node->object;
}
- node->type = (u8) object_type;
- node->object = obj_desc;
+ node->type = (u8) object_type;
+ node->object = obj_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_detach_object
@@ -206,30 +196,27 @@ acpi_ns_attach_object (
*
******************************************************************************/
-void
-acpi_ns_detach_object (
- struct acpi_namespace_node *node)
+void acpi_ns_detach_object(struct acpi_namespace_node *node)
{
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE ("ns_detach_object");
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE("ns_detach_object");
obj_desc = node->object;
if (!obj_desc ||
- (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+ (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
return_VOID;
}
/* Clear the entry in all cases */
node->object = NULL;
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
node->object = obj_desc->common.next_object;
if (node->object &&
- (ACPI_GET_OBJECT_TYPE (node->object) != ACPI_TYPE_LOCAL_DATA)) {
+ (ACPI_GET_OBJECT_TYPE(node->object) !=
+ ACPI_TYPE_LOCAL_DATA)) {
node->object = node->object->common.next_object;
}
}
@@ -238,16 +225,15 @@ acpi_ns_detach_object (
node->type = ACPI_TYPE_ANY;
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
- node, acpi_ut_get_node_name (node), obj_desc));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
+ node, acpi_ut_get_node_name(node), obj_desc));
/* Remove one reference on the object (and all subobjects) */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_attached_object
@@ -261,29 +247,28 @@ acpi_ns_detach_object (
*
******************************************************************************/
-union acpi_operand_object *
-acpi_ns_get_attached_object (
- struct acpi_namespace_node *node)
+union acpi_operand_object *acpi_ns_get_attached_object(struct
+ acpi_namespace_node
+ *node)
{
- ACPI_FUNCTION_TRACE_PTR ("ns_get_attached_object", node);
-
+ ACPI_FUNCTION_TRACE_PTR("ns_get_attached_object", node);
if (!node) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Null Node ptr\n"));
- return_PTR (NULL);
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Null Node ptr\n"));
+ return_PTR(NULL);
}
if (!node->object ||
- ((ACPI_GET_DESCRIPTOR_TYPE (node->object) != ACPI_DESC_TYPE_OPERAND) &&
- (ACPI_GET_DESCRIPTOR_TYPE (node->object) != ACPI_DESC_TYPE_NAMED)) ||
- (ACPI_GET_OBJECT_TYPE (node->object) == ACPI_TYPE_LOCAL_DATA)) {
- return_PTR (NULL);
+ ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
+ && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
+ ACPI_DESC_TYPE_NAMED))
+ || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+ return_PTR(NULL);
}
- return_PTR (node->object);
+ return_PTR(node->object);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_secondary_object
@@ -297,24 +282,23 @@ acpi_ns_get_attached_object (
*
******************************************************************************/
-union acpi_operand_object *
-acpi_ns_get_secondary_object (
- union acpi_operand_object *obj_desc)
+union acpi_operand_object *acpi_ns_get_secondary_object(union
+ acpi_operand_object
+ *obj_desc)
{
- ACPI_FUNCTION_TRACE_PTR ("ns_get_secondary_object", obj_desc);
-
-
- if ((!obj_desc) ||
- (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
- (!obj_desc->common.next_object) ||
- (ACPI_GET_OBJECT_TYPE (obj_desc->common.next_object) == ACPI_TYPE_LOCAL_DATA)) {
- return_PTR (NULL);
+ ACPI_FUNCTION_TRACE_PTR("ns_get_secondary_object", obj_desc);
+
+ if ((!obj_desc) ||
+ (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+ (!obj_desc->common.next_object) ||
+ (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+ ACPI_TYPE_LOCAL_DATA)) {
+ return_PTR(NULL);
}
- return_PTR (obj_desc->common.next_object);
+ return_PTR(obj_desc->common.next_object);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_attach_data
@@ -330,23 +314,20 @@ acpi_ns_get_secondary_object (
******************************************************************************/
acpi_status
-acpi_ns_attach_data (
- struct acpi_namespace_node *node,
- acpi_object_handler handler,
- void *data)
+acpi_ns_attach_data(struct acpi_namespace_node *node,
+ acpi_object_handler handler, void *data)
{
- union acpi_operand_object *prev_obj_desc;
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *data_desc;
-
+ union acpi_operand_object *prev_obj_desc;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *data_desc;
/* We only allow one attachment per handler */
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
- (obj_desc->data.handler == handler)) {
+ if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ (obj_desc->data.handler == handler)) {
return (AE_ALREADY_EXISTS);
}
@@ -356,7 +337,7 @@ acpi_ns_attach_data (
/* Create an internal object for the data */
- data_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_DATA);
+ data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA);
if (!data_desc) {
return (AE_NO_MEMORY);
}
@@ -368,15 +349,13 @@ acpi_ns_attach_data (
if (prev_obj_desc) {
prev_obj_desc->common.next_object = data_desc;
- }
- else {
+ } else {
node->object = data_desc;
}
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_detach_data
@@ -392,27 +371,25 @@ acpi_ns_attach_data (
******************************************************************************/
acpi_status
-acpi_ns_detach_data (
- struct acpi_namespace_node *node,
- acpi_object_handler handler)
+acpi_ns_detach_data(struct acpi_namespace_node * node,
+ acpi_object_handler handler)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *prev_obj_desc;
-
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *prev_obj_desc;
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
- (obj_desc->data.handler == handler)) {
+ if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ (obj_desc->data.handler == handler)) {
if (prev_obj_desc) {
- prev_obj_desc->common.next_object = obj_desc->common.next_object;
- }
- else {
+ prev_obj_desc->common.next_object =
+ obj_desc->common.next_object;
+ } else {
node->object = obj_desc->common.next_object;
}
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
return (AE_OK);
}
@@ -423,7 +400,6 @@ acpi_ns_detach_data (
return (AE_NOT_FOUND);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_attached_data
@@ -440,18 +416,15 @@ acpi_ns_detach_data (
******************************************************************************/
acpi_status
-acpi_ns_get_attached_data (
- struct acpi_namespace_node *node,
- acpi_object_handler handler,
- void **data)
+acpi_ns_get_attached_data(struct acpi_namespace_node * node,
+ acpi_object_handler handler, void **data)
{
- union acpi_operand_object *obj_desc;
-
+ union acpi_operand_object *obj_desc;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
- (obj_desc->data.handler == handler)) {
+ if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ (obj_desc->data.handler == handler)) {
*data = obj_desc->data.pointer;
return (AE_OK);
}
@@ -461,5 +434,3 @@ acpi_ns_get_attached_data (
return (AE_NOT_FOUND);
}
-
-
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index a0e13e8d3764..433442a9ec74 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -41,16 +41,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
#include <acpi/acdispat.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsparse")
-
+ACPI_MODULE_NAME("nsparse")
/*******************************************************************************
*
@@ -64,54 +61,50 @@
* DESCRIPTION: Perform one complete parse of an ACPI/AML table.
*
******************************************************************************/
-
acpi_status
-acpi_ns_one_complete_parse (
- u32 pass_number,
- struct acpi_table_desc *table_desc)
+acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc * table_desc)
{
- union acpi_parse_object *parse_root;
- acpi_status status;
- struct acpi_walk_state *walk_state;
-
-
- ACPI_FUNCTION_TRACE ("ns_one_complete_parse");
+ union acpi_parse_object *parse_root;
+ acpi_status status;
+ struct acpi_walk_state *walk_state;
+ ACPI_FUNCTION_TRACE("ns_one_complete_parse");
/* Create and init a Root Node */
- parse_root = acpi_ps_create_scope_op ();
+ parse_root = acpi_ps_create_scope_op();
if (!parse_root) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Create and initialize a new walk state */
- walk_state = acpi_ds_create_walk_state (table_desc->table_id,
- NULL, NULL, NULL);
+ walk_state = acpi_ds_create_walk_state(table_desc->owner_id,
+ NULL, NULL, NULL);
if (!walk_state) {
- acpi_ps_free_op (parse_root);
- return_ACPI_STATUS (AE_NO_MEMORY);
+ acpi_ps_free_op(parse_root);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL,
- table_desc->aml_start, table_desc->aml_length,
- NULL, pass_number);
- if (ACPI_FAILURE (status)) {
- acpi_ds_delete_walk_state (walk_state);
- return_ACPI_STATUS (status);
+ status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
+ table_desc->aml_start,
+ table_desc->aml_length, NULL,
+ pass_number);
+ if (ACPI_FAILURE(status)) {
+ acpi_ds_delete_walk_state(walk_state);
+ return_ACPI_STATUS(status);
}
/* Parse the AML */
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", pass_number));
- status = acpi_ps_parse_aml (walk_state);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n",
+ pass_number));
+ status = acpi_ps_parse_aml(walk_state);
- acpi_ps_delete_parse_tree (parse_root);
- return_ACPI_STATUS (status);
+ acpi_ps_delete_parse_tree(parse_root);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_parse_table
@@ -126,15 +119,12 @@ acpi_ns_one_complete_parse (
******************************************************************************/
acpi_status
-acpi_ns_parse_table (
- struct acpi_table_desc *table_desc,
- struct acpi_namespace_node *start_node)
+acpi_ns_parse_table(struct acpi_table_desc *table_desc,
+ struct acpi_namespace_node *start_node)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ns_parse_table");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_parse_table");
/*
* AML Parse, pass 1
@@ -146,9 +136,10 @@ acpi_ns_parse_table (
* to service the entire parse. The second pass of the parse then
* performs another complete parse of the AML..
*/
- status = acpi_ns_one_complete_parse (1, table_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
+ status = acpi_ns_one_complete_parse(1, table_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -160,12 +151,11 @@ acpi_ns_parse_table (
* overhead of this is compensated for by the fact that the
* parse objects are all cached.
*/
- status = acpi_ns_one_complete_parse (2, table_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
+ status = acpi_ns_one_complete_parse(2, table_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index af8aaa9cc4f3..50a3ca5470ed 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -41,23 +41,18 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nssearch")
+ACPI_MODULE_NAME("nssearch")
/* Local prototypes */
-
static acpi_status
-acpi_ns_search_parent_tree (
- u32 target_name,
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_namespace_node **return_node);
-
+acpi_ns_search_parent_tree(u32 target_name,
+ struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_namespace_node **return_node);
/*******************************************************************************
*
@@ -87,30 +82,28 @@ acpi_ns_search_parent_tree (
******************************************************************************/
acpi_status
-acpi_ns_search_node (
- u32 target_name,
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_namespace_node **return_node)
+acpi_ns_search_node(u32 target_name,
+ struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_namespace_node **return_node)
{
- struct acpi_namespace_node *next_node;
-
-
- ACPI_FUNCTION_TRACE ("ns_search_node");
+ struct acpi_namespace_node *next_node;
+ ACPI_FUNCTION_TRACE("ns_search_node");
#ifdef ACPI_DEBUG_OUTPUT
if (ACPI_LV_NAMES & acpi_dbg_level) {
- char *scope_name;
+ char *scope_name;
- scope_name = acpi_ns_get_external_pathname (node);
+ scope_name = acpi_ns_get_external_pathname(node);
if (scope_name) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Searching %s (%p) For [%4.4s] (%s)\n",
- scope_name, node, (char *) &target_name,
- acpi_ut_get_type_name (type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Searching %s (%p) For [%4.4s] (%s)\n",
+ scope_name, node,
+ (char *)&target_name,
+ acpi_ut_get_type_name(type)));
- ACPI_MEM_FREE (scope_name);
+ ACPI_MEM_FREE(scope_name);
}
}
#endif
@@ -126,20 +119,26 @@ acpi_ns_search_node (
if (next_node->name.integer == target_name) {
/* Resolve a control method alias if any */
- if (acpi_ns_get_type (next_node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
- next_node = ACPI_CAST_PTR (struct acpi_namespace_node, next_node->object);
+ if (acpi_ns_get_type(next_node) ==
+ ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+ next_node =
+ ACPI_CAST_PTR(struct acpi_namespace_node,
+ next_node->object);
}
/*
* Found matching entry.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
- (char *) &target_name, acpi_ut_get_type_name (next_node->type),
- next_node, acpi_ut_get_node_name (node), node));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
+ (char *)&target_name,
+ acpi_ut_get_type_name(next_node->
+ type),
+ next_node,
+ acpi_ut_get_node_name(node), node));
*return_node = next_node;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -159,15 +158,14 @@ acpi_ns_search_node (
/* Searched entire namespace level, not found */
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
- (char *) &target_name, acpi_ut_get_type_name (type),
- acpi_ut_get_node_name (node), node, node->child));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+ (char *)&target_name, acpi_ut_get_type_name(type),
+ acpi_ut_get_node_name(node), node, node->child));
- return_ACPI_STATUS (AE_NOT_FOUND);
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_search_parent_tree
@@ -194,43 +192,42 @@ acpi_ns_search_node (
******************************************************************************/
static acpi_status
-acpi_ns_search_parent_tree (
- u32 target_name,
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_namespace_node **return_node)
+acpi_ns_search_parent_tree(u32 target_name,
+ struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_namespace_node **return_node)
{
- acpi_status status;
- struct acpi_namespace_node *parent_node;
+ acpi_status status;
+ struct acpi_namespace_node *parent_node;
+ ACPI_FUNCTION_TRACE("ns_search_parent_tree");
- ACPI_FUNCTION_TRACE ("ns_search_parent_tree");
-
-
- parent_node = acpi_ns_get_parent_node (node);
+ parent_node = acpi_ns_get_parent_node(node);
/*
* If there is no parent (i.e., we are at the root) or type is "local",
* we won't be searching the parent tree.
*/
if (!parent_node) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
- (char *) &target_name));
- return_ACPI_STATUS (AE_NOT_FOUND);
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
+ (char *)&target_name));
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
- if (acpi_ns_local (type)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
- (char *) &target_name, acpi_ut_get_type_name (type)));
- return_ACPI_STATUS (AE_NOT_FOUND);
+ if (acpi_ns_local(type)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
+ (char *)&target_name,
+ acpi_ut_get_type_name(type)));
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
/* Search the parent tree */
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Searching parent [%4.4s] for [%4.4s]\n",
- acpi_ut_get_node_name (parent_node), (char *) &target_name));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "Searching parent [%4.4s] for [%4.4s]\n",
+ acpi_ut_get_node_name(parent_node),
+ (char *)&target_name));
/*
* Search parents until target is found or we have backed up to the root
@@ -241,25 +238,24 @@ acpi_ns_search_parent_tree (
* object type at this point, we only care about the existence of
* the actual name we are searching for. Typechecking comes later.
*/
- status = acpi_ns_search_node (target_name, parent_node,
- ACPI_TYPE_ANY, return_node);
- if (ACPI_SUCCESS (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_search_node(target_name, parent_node,
+ ACPI_TYPE_ANY, return_node);
+ if (ACPI_SUCCESS(status)) {
+ return_ACPI_STATUS(status);
}
/*
* Not found here, go up another level
* (until we reach the root)
*/
- parent_node = acpi_ns_get_parent_node (parent_node);
+ parent_node = acpi_ns_get_parent_node(parent_node);
}
/* Not found in parent tree */
- return_ACPI_STATUS (AE_NOT_FOUND);
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_search_and_enter
@@ -286,52 +282,46 @@ acpi_ns_search_parent_tree (
******************************************************************************/
acpi_status
-acpi_ns_search_and_enter (
- u32 target_name,
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node *node,
- acpi_interpreter_mode interpreter_mode,
- acpi_object_type type,
- u32 flags,
- struct acpi_namespace_node **return_node)
+acpi_ns_search_and_enter(u32 target_name,
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node *node,
+ acpi_interpreter_mode interpreter_mode,
+ acpi_object_type type,
+ u32 flags, struct acpi_namespace_node **return_node)
{
- acpi_status status;
- struct acpi_namespace_node *new_node;
-
-
- ACPI_FUNCTION_TRACE ("ns_search_and_enter");
+ acpi_status status;
+ struct acpi_namespace_node *new_node;
+ ACPI_FUNCTION_TRACE("ns_search_and_enter");
/* Parameter validation */
if (!node || !target_name || !return_node) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null param: Node %p Name %X return_node %p\n",
- node, target_name, return_node));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Null param: Node %p Name %X return_node %p\n",
+ node, target_name, return_node));
- ACPI_REPORT_ERROR (("ns_search_and_enter: Null parameter\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("ns_search_and_enter: Null parameter\n"));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Name must consist of printable characters */
- if (!acpi_ut_valid_acpi_name (target_name)) {
- ACPI_REPORT_ERROR (("ns_search_and_enter: Bad character in ACPI Name: %X\n",
- target_name));
- return_ACPI_STATUS (AE_BAD_CHARACTER);
+ if (!acpi_ut_valid_acpi_name(target_name)) {
+ ACPI_REPORT_ERROR(("ns_search_and_enter: Bad character in ACPI Name: %X\n", target_name));
+ return_ACPI_STATUS(AE_BAD_CHARACTER);
}
/* Try to find the name in the namespace level specified by the caller */
*return_node = ACPI_ENTRY_NOT_FOUND;
- status = acpi_ns_search_node (target_name, node, type, return_node);
+ status = acpi_ns_search_node(target_name, node, type, return_node);
if (status != AE_NOT_FOUND) {
/*
* If we found it AND the request specifies that a find is an error,
* return the error
*/
- if ((status == AE_OK) &&
- (flags & ACPI_NS_ERROR_IF_FOUND)) {
+ if ((status == AE_OK) && (flags & ACPI_NS_ERROR_IF_FOUND)) {
status = AE_ALREADY_EXISTS;
}
@@ -339,7 +329,7 @@ acpi_ns_search_and_enter (
* Either found it or there was an error
* -- finished either way
*/
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/*
@@ -351,14 +341,16 @@ acpi_ns_search_and_enter (
* and during the execution phase.
*/
if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) &&
- (flags & ACPI_NS_SEARCH_PARENT)) {
+ (flags & ACPI_NS_SEARCH_PARENT)) {
/*
* Not found at this level - search parent tree according to the
* ACPI specification
*/
- status = acpi_ns_search_parent_tree (target_name, node, type, return_node);
- if (ACPI_SUCCESS (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ns_search_parent_tree(target_name, node, type,
+ return_node);
+ if (ACPI_SUCCESS(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -366,25 +358,24 @@ acpi_ns_search_and_enter (
* In execute mode, just search, never add names. Exit now.
*/
if (interpreter_mode == ACPI_IMODE_EXECUTE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "%4.4s Not found in %p [Not adding]\n",
- (char *) &target_name, node));
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+ "%4.4s Not found in %p [Not adding]\n",
+ (char *)&target_name, node));
- return_ACPI_STATUS (AE_NOT_FOUND);
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
/* Create the new named object */
- new_node = acpi_ns_create_node (target_name);
+ new_node = acpi_ns_create_node(target_name);
if (!new_node) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Install the new object into the parent's list of children */
- acpi_ns_install_node (walk_state, node, new_node, type);
+ acpi_ns_install_node(walk_state, node, new_node, type);
*return_node = new_node;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index c53b82e94ce3..ebec036423c9 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -42,28 +42,21 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/amlcode.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsutils")
+ACPI_MODULE_NAME("nsutils")
/* Local prototypes */
-
-static u8
-acpi_ns_valid_path_separator (
- char sep);
+static u8 acpi_ns_valid_path_separator(char sep);
#ifdef ACPI_OBSOLETE_FUNCTIONS
-acpi_name
-acpi_ns_find_parent_name (
- struct acpi_namespace_node *node_to_search);
+acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_report_error
@@ -81,51 +74,45 @@ acpi_ns_find_parent_name (
******************************************************************************/
void
-acpi_ns_report_error (
- char *module_name,
- u32 line_number,
- u32 component_id,
- char *internal_name,
- acpi_status lookup_status)
+acpi_ns_report_error(char *module_name,
+ u32 line_number,
+ u32 component_id,
+ char *internal_name, acpi_status lookup_status)
{
- acpi_status status;
- char *name = NULL;
-
+ acpi_status status;
+ char *name = NULL;
- acpi_os_printf ("%8s-%04d: *** Error: Looking up ",
- module_name, line_number);
+ acpi_os_printf("%8s-%04d: *** Error: Looking up ",
+ module_name, line_number);
if (lookup_status == AE_BAD_CHARACTER) {
/* There is a non-ascii character in the name */
- acpi_os_printf ("[0x%4.4X] (NON-ASCII)\n",
- *(ACPI_CAST_PTR (u32, internal_name)));
- }
- else {
+ acpi_os_printf("[0x%4.4X] (NON-ASCII)\n",
+ *(ACPI_CAST_PTR(u32, internal_name)));
+ } else {
/* Convert path to external format */
- status = acpi_ns_externalize_name (ACPI_UINT32_MAX,
- internal_name, NULL, &name);
+ status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
+ internal_name, NULL, &name);
/* Print target name */
- if (ACPI_SUCCESS (status)) {
- acpi_os_printf ("[%s]", name);
- }
- else {
- acpi_os_printf ("[COULD NOT EXTERNALIZE NAME]");
+ if (ACPI_SUCCESS(status)) {
+ acpi_os_printf("[%s]", name);
+ } else {
+ acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
}
if (name) {
- ACPI_MEM_FREE (name);
+ ACPI_MEM_FREE(name);
}
}
- acpi_os_printf (" in namespace, %s\n",
- acpi_format_exception (lookup_status));
+ acpi_os_printf(" in namespace, %s\n",
+ acpi_format_exception(lookup_status));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_report_method_error
@@ -145,34 +132,31 @@ acpi_ns_report_error (
******************************************************************************/
void
-acpi_ns_report_method_error (
- char *module_name,
- u32 line_number,
- u32 component_id,
- char *message,
- struct acpi_namespace_node *prefix_node,
- char *path,
- acpi_status method_status)
+acpi_ns_report_method_error(char *module_name,
+ u32 line_number,
+ u32 component_id,
+ char *message,
+ struct acpi_namespace_node *prefix_node,
+ char *path, acpi_status method_status)
{
- acpi_status status;
- struct acpi_namespace_node *node = prefix_node;
-
+ acpi_status status;
+ struct acpi_namespace_node *node = prefix_node;
if (path) {
- status = acpi_ns_get_node_by_path (path, prefix_node,
- ACPI_NS_NO_UPSEARCH, &node);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("report_method_error: Could not get node\n");
+ status = acpi_ns_get_node_by_path(path, prefix_node,
+ ACPI_NS_NO_UPSEARCH, &node);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_printf
+ ("report_method_error: Could not get node\n");
return;
}
}
- acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
- acpi_ns_print_node_pathname (node, message);
- acpi_os_printf (", %s\n", acpi_format_exception (method_status));
+ acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number);
+ acpi_ns_print_node_pathname(node, message);
+ acpi_os_printf(", %s\n", acpi_format_exception(method_status));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_print_node_pathname
@@ -186,16 +170,13 @@ acpi_ns_report_method_error (
******************************************************************************/
void
-acpi_ns_print_node_pathname (
- struct acpi_namespace_node *node,
- char *message)
+acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message)
{
- struct acpi_buffer buffer;
- acpi_status status;
-
+ struct acpi_buffer buffer;
+ acpi_status status;
if (!node) {
- acpi_os_printf ("[NULL NAME]");
+ acpi_os_printf("[NULL NAME]");
return;
}
@@ -203,18 +184,17 @@ acpi_ns_print_node_pathname (
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_ns_handle_to_pathname (node, &buffer);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ns_handle_to_pathname(node, &buffer);
+ if (ACPI_SUCCESS(status)) {
if (message) {
- acpi_os_printf ("%s ", message);
+ acpi_os_printf("%s ", message);
}
- acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
- ACPI_MEM_FREE (buffer.pointer);
+ acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node);
+ ACPI_MEM_FREE(buffer.pointer);
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_valid_root_prefix
@@ -227,15 +207,12 @@ acpi_ns_print_node_pathname (
*
******************************************************************************/
-u8
-acpi_ns_valid_root_prefix (
- char prefix)
+u8 acpi_ns_valid_root_prefix(char prefix)
{
return ((u8) (prefix == '\\'));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_valid_path_separator
@@ -248,15 +225,12 @@ acpi_ns_valid_root_prefix (
*
******************************************************************************/
-static u8
-acpi_ns_valid_path_separator (
- char sep)
+static u8 acpi_ns_valid_path_separator(char sep)
{
return ((u8) (sep == '.'));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_type
@@ -269,22 +243,18 @@ acpi_ns_valid_path_separator (
*
******************************************************************************/
-acpi_object_type
-acpi_ns_get_type (
- struct acpi_namespace_node *node)
+acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)
{
- ACPI_FUNCTION_TRACE ("ns_get_type");
-
+ ACPI_FUNCTION_TRACE("ns_get_type");
if (!node) {
- ACPI_REPORT_WARNING (("ns_get_type: Null Node input pointer\n"));
- return_VALUE (ACPI_TYPE_ANY);
+ ACPI_REPORT_WARNING(("ns_get_type: Null Node input pointer\n"));
+ return_VALUE(ACPI_TYPE_ANY);
}
- return_VALUE ((acpi_object_type) node->type);
+ return_VALUE((acpi_object_type) node->type);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_local
@@ -298,24 +268,20 @@ acpi_ns_get_type (
*
******************************************************************************/
-u32
-acpi_ns_local (
- acpi_object_type type)
+u32 acpi_ns_local(acpi_object_type type)
{
- ACPI_FUNCTION_TRACE ("ns_local");
-
+ ACPI_FUNCTION_TRACE("ns_local");
- if (!acpi_ut_valid_object_type (type)) {
+ if (!acpi_ut_valid_object_type(type)) {
/* Type code out of range */
- ACPI_REPORT_WARNING (("ns_local: Invalid Object Type\n"));
- return_VALUE (ACPI_NS_NORMAL);
+ ACPI_REPORT_WARNING(("ns_local: Invalid Object Type\n"));
+ return_VALUE(ACPI_NS_NORMAL);
}
- return_VALUE ((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
+ return_VALUE((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_internal_name_length
@@ -330,16 +296,12 @@ acpi_ns_local (
*
******************************************************************************/
-void
-acpi_ns_get_internal_name_length (
- struct acpi_namestring_info *info)
+void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
{
- char *next_external_char;
- u32 i;
-
-
- ACPI_FUNCTION_ENTRY ();
+ char *next_external_char;
+ u32 i;
+ ACPI_FUNCTION_ENTRY();
next_external_char = info->external_name;
info->num_carats = 0;
@@ -353,11 +315,10 @@ acpi_ns_get_internal_name_length (
*
* strlen() + 1 covers the first name_seg, which has no path separator
*/
- if (acpi_ns_valid_root_prefix (next_external_char[0])) {
+ if (acpi_ns_valid_root_prefix(next_external_char[0])) {
info->fully_qualified = TRUE;
next_external_char++;
- }
- else {
+ } else {
/*
* Handle Carat prefixes
*/
@@ -375,19 +336,18 @@ acpi_ns_get_internal_name_length (
if (*next_external_char) {
info->num_segments = 1;
for (i = 0; next_external_char[i]; i++) {
- if (acpi_ns_valid_path_separator (next_external_char[i])) {
+ if (acpi_ns_valid_path_separator(next_external_char[i])) {
info->num_segments++;
}
}
}
info->length = (ACPI_NAME_SIZE * info->num_segments) +
- 4 + info->num_carats;
+ 4 + info->num_carats;
info->next_external_char = next_external_char;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_build_internal_name
@@ -401,19 +361,15 @@ acpi_ns_get_internal_name_length (
*
******************************************************************************/
-acpi_status
-acpi_ns_build_internal_name (
- struct acpi_namestring_info *info)
+acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
{
- u32 num_segments = info->num_segments;
- char *internal_name = info->internal_name;
- char *external_name = info->next_external_char;
- char *result = NULL;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_TRACE ("ns_build_internal_name");
+ u32 num_segments = info->num_segments;
+ char *internal_name = info->internal_name;
+ char *external_name = info->next_external_char;
+ char *result = NULL;
+ acpi_native_uint i;
+ ACPI_FUNCTION_TRACE("ns_build_internal_name");
/* Setup the correct prefixes, counts, and pointers */
@@ -422,18 +378,15 @@ acpi_ns_build_internal_name (
if (num_segments <= 1) {
result = &internal_name[1];
- }
- else if (num_segments == 2) {
+ } else if (num_segments == 2) {
internal_name[1] = AML_DUAL_NAME_PREFIX;
result = &internal_name[2];
- }
- else {
+ } else {
internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
- internal_name[2] = (char) num_segments;
+ internal_name[2] = (char)num_segments;
result = &internal_name[3];
}
- }
- else {
+ } else {
/*
* Not fully qualified.
* Handle Carats first, then append the name segments
@@ -447,15 +400,14 @@ acpi_ns_build_internal_name (
if (num_segments <= 1) {
result = &internal_name[i];
- }
- else if (num_segments == 2) {
+ } else if (num_segments == 2) {
internal_name[i] = AML_DUAL_NAME_PREFIX;
- result = &internal_name[(acpi_native_uint) (i+1)];
- }
- else {
+ result = &internal_name[(acpi_native_uint) (i + 1)];
+ } else {
internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
- internal_name[(acpi_native_uint) (i+1)] = (char) num_segments;
- result = &internal_name[(acpi_native_uint) (i+2)];
+ internal_name[(acpi_native_uint) (i + 1)] =
+ (char)num_segments;
+ result = &internal_name[(acpi_native_uint) (i + 2)];
}
}
@@ -463,25 +415,25 @@ acpi_ns_build_internal_name (
for (; num_segments; num_segments--) {
for (i = 0; i < ACPI_NAME_SIZE; i++) {
- if (acpi_ns_valid_path_separator (*external_name) ||
- (*external_name == 0)) {
+ if (acpi_ns_valid_path_separator(*external_name) ||
+ (*external_name == 0)) {
/* Pad the segment with underscore(s) if segment is short */
result[i] = '_';
- }
- else {
+ } else {
/* Convert the character to uppercase and save it */
- result[i] = (char) ACPI_TOUPPER ((int) *external_name);
+ result[i] =
+ (char)ACPI_TOUPPER((int)*external_name);
external_name++;
}
}
/* Now we must have a path separator, or the pathname is bad */
- if (!acpi_ns_valid_path_separator (*external_name) &&
- (*external_name != 0)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (!acpi_ns_valid_path_separator(*external_name) &&
+ (*external_name != 0)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Move on the next segment */
@@ -495,18 +447,17 @@ acpi_ns_build_internal_name (
*result = 0;
if (info->fully_qualified) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
- internal_name, internal_name));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
- internal_name, internal_name));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Returning [%p] (abs) \"\\%s\"\n",
+ internal_name, internal_name));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
+ internal_name, internal_name));
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_internalize_name
@@ -522,51 +473,43 @@ acpi_ns_build_internal_name (
*
*******************************************************************************/
-acpi_status
-acpi_ns_internalize_name (
- char *external_name,
- char **converted_name)
+acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name)
{
- char *internal_name;
- struct acpi_namestring_info info;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ns_internalize_name");
+ char *internal_name;
+ struct acpi_namestring_info info;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ns_internalize_name");
- if ((!external_name) ||
- (*external_name == 0) ||
- (!converted_name)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((!external_name) || (*external_name == 0) || (!converted_name)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the length of the new internal name */
info.external_name = external_name;
- acpi_ns_get_internal_name_length (&info);
+ acpi_ns_get_internal_name_length(&info);
/* We need a segment to store the internal name */
- internal_name = ACPI_MEM_CALLOCATE (info.length);
+ internal_name = ACPI_MEM_CALLOCATE(info.length);
if (!internal_name) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Build the name */
info.internal_name = internal_name;
- status = acpi_ns_build_internal_name (&info);
- if (ACPI_FAILURE (status)) {
- ACPI_MEM_FREE (internal_name);
- return_ACPI_STATUS (status);
+ status = acpi_ns_build_internal_name(&info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_MEM_FREE(internal_name);
+ return_ACPI_STATUS(status);
}
*converted_name = internal_name;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_externalize_name
@@ -585,27 +528,21 @@ acpi_ns_internalize_name (
******************************************************************************/
acpi_status
-acpi_ns_externalize_name (
- u32 internal_name_length,
- char *internal_name,
- u32 *converted_name_length,
- char **converted_name)
+acpi_ns_externalize_name(u32 internal_name_length,
+ char *internal_name,
+ u32 * converted_name_length, char **converted_name)
{
- acpi_native_uint names_index = 0;
- acpi_native_uint num_segments = 0;
- acpi_native_uint required_length;
- acpi_native_uint prefix_length = 0;
- acpi_native_uint i = 0;
- acpi_native_uint j = 0;
-
+ acpi_native_uint names_index = 0;
+ acpi_native_uint num_segments = 0;
+ acpi_native_uint required_length;
+ acpi_native_uint prefix_length = 0;
+ acpi_native_uint i = 0;
+ acpi_native_uint j = 0;
- ACPI_FUNCTION_TRACE ("ns_externalize_name");
+ ACPI_FUNCTION_TRACE("ns_externalize_name");
-
- if (!internal_name_length ||
- !internal_name ||
- !converted_name) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (!internal_name_length || !internal_name || !converted_name) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -620,8 +557,7 @@ acpi_ns_externalize_name (
for (i = 0; i < internal_name_length; i++) {
if (internal_name[i] == '^') {
prefix_length = i + 1;
- }
- else {
+ } else {
break;
}
}
@@ -648,7 +584,8 @@ acpi_ns_externalize_name (
names_index = prefix_length + 2;
num_segments = (acpi_native_uint) (u8)
- internal_name[(acpi_native_uint) (prefix_length + 1)];
+ internal_name[(acpi_native_uint)
+ (prefix_length + 1)];
break;
case AML_DUAL_NAME_PREFIX:
@@ -683,23 +620,23 @@ acpi_ns_externalize_name (
* punctuation ('.') between object names, plus the NULL terminator.
*/
required_length = prefix_length + (4 * num_segments) +
- ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
+ ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
/*
* Check to see if we're still in bounds. If not, there's a problem
* with internal_name (invalid format).
*/
if (required_length > internal_name_length) {
- ACPI_REPORT_ERROR (("ns_externalize_name: Invalid internal name\n"));
- return_ACPI_STATUS (AE_BAD_PATHNAME);
+ ACPI_REPORT_ERROR(("ns_externalize_name: Invalid internal name\n"));
+ return_ACPI_STATUS(AE_BAD_PATHNAME);
}
/*
* Build converted_name
*/
- *converted_name = ACPI_MEM_CALLOCATE (required_length);
+ *converted_name = ACPI_MEM_CALLOCATE(required_length);
if (!(*converted_name)) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
j = 0;
@@ -725,10 +662,9 @@ acpi_ns_externalize_name (
*converted_name_length = (u32) required_length;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_map_handle_to_node
@@ -745,13 +681,10 @@ acpi_ns_externalize_name (
*
******************************************************************************/
-struct acpi_namespace_node *
-acpi_ns_map_handle_to_node (
- acpi_handle handle)
+struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
/*
* Simple implementation.
@@ -766,14 +699,13 @@ acpi_ns_map_handle_to_node (
/* We can at least attempt to verify the handle */
- if (ACPI_GET_DESCRIPTOR_TYPE (handle) != ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) {
return (NULL);
}
- return ((struct acpi_namespace_node *) handle);
+ return ((struct acpi_namespace_node *)handle);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_convert_entry_to_handle
@@ -786,18 +718,14 @@ acpi_ns_map_handle_to_node (
*
******************************************************************************/
-acpi_handle
-acpi_ns_convert_entry_to_handle (
- struct acpi_namespace_node *node)
+acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node)
{
-
/*
* Simple implementation for now;
*/
return ((acpi_handle) node);
-
/* Example future implementation ---------------------
if (!Node)
@@ -810,12 +738,10 @@ acpi_ns_convert_entry_to_handle (
return (ACPI_ROOT_OBJECT);
}
-
return ((acpi_handle) Node);
------------------------------------------------------*/
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_terminate
@@ -828,42 +754,37 @@ acpi_ns_convert_entry_to_handle (
*
******************************************************************************/
-void
-acpi_ns_terminate (
- void)
+void acpi_ns_terminate(void)
{
- union acpi_operand_object *obj_desc;
-
-
- ACPI_FUNCTION_TRACE ("ns_terminate");
+ union acpi_operand_object *obj_desc;
+ ACPI_FUNCTION_TRACE("ns_terminate");
/*
* 1) Free the entire namespace -- all nodes and objects
*
* Delete all object descriptors attached to namepsace nodes
*/
- acpi_ns_delete_namespace_subtree (acpi_gbl_root_node);
+ acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
/* Detach any objects attached to the root */
- obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node);
+ obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
if (obj_desc) {
- acpi_ns_detach_object (acpi_gbl_root_node);
+ acpi_ns_detach_object(acpi_gbl_root_node);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
/*
* 2) Now we can delete the ACPI tables
*/
- acpi_tb_delete_all_tables ();
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
+ acpi_tb_delete_all_tables();
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_opens_scope
@@ -875,24 +796,21 @@ acpi_ns_terminate (
*
******************************************************************************/
-u32
-acpi_ns_opens_scope (
- acpi_object_type type)
+u32 acpi_ns_opens_scope(acpi_object_type type)
{
- ACPI_FUNCTION_TRACE_STR ("ns_opens_scope", acpi_ut_get_type_name (type));
-
+ ACPI_FUNCTION_TRACE_STR("ns_opens_scope", acpi_ut_get_type_name(type));
- if (!acpi_ut_valid_object_type (type)) {
+ if (!acpi_ut_valid_object_type(type)) {
/* type code out of range */
- ACPI_REPORT_WARNING (("ns_opens_scope: Invalid Object Type %X\n", type));
- return_VALUE (ACPI_NS_NORMAL);
+ ACPI_REPORT_WARNING(("ns_opens_scope: Invalid Object Type %X\n",
+ type));
+ return_VALUE(ACPI_NS_NORMAL);
}
- return_VALUE (((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
+ return_VALUE(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_node_by_path
@@ -916,33 +834,29 @@ acpi_ns_opens_scope (
******************************************************************************/
acpi_status
-acpi_ns_get_node_by_path (
- char *pathname,
- struct acpi_namespace_node *start_node,
- u32 flags,
- struct acpi_namespace_node **return_node)
+acpi_ns_get_node_by_path(char *pathname,
+ struct acpi_namespace_node *start_node,
+ u32 flags, struct acpi_namespace_node **return_node)
{
- union acpi_generic_state scope_info;
- acpi_status status;
- char *internal_path = NULL;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ns_get_node_by_path", pathname);
+ union acpi_generic_state scope_info;
+ acpi_status status;
+ char *internal_path = NULL;
+ ACPI_FUNCTION_TRACE_PTR("ns_get_node_by_path", pathname);
if (pathname) {
/* Convert path to internal representation */
- status = acpi_ns_internalize_name (pathname, &internal_path);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_internalize_name(pathname, &internal_path);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Must lock namespace during lookup */
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -952,25 +866,25 @@ acpi_ns_get_node_by_path (
/* Lookup the name in the namespace */
- status = acpi_ns_lookup (&scope_info, internal_path,
- ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- (flags | ACPI_NS_DONT_OPEN_SCOPE),
- NULL, return_node);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n",
- internal_path, acpi_format_exception (status)));
+ status = acpi_ns_lookup(&scope_info, internal_path,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ (flags | ACPI_NS_DONT_OPEN_SCOPE),
+ NULL, return_node);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+ internal_path,
+ acpi_format_exception(status)));
}
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-cleanup:
+ cleanup:
if (internal_path) {
- ACPI_MEM_FREE (internal_path);
+ ACPI_MEM_FREE(internal_path);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_parent_node
@@ -983,12 +897,10 @@ cleanup:
*
******************************************************************************/
-struct acpi_namespace_node *
-acpi_ns_get_parent_node (
- struct acpi_namespace_node *node)
+struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node
+ *node)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
if (!node) {
return (NULL);
@@ -1006,7 +918,6 @@ acpi_ns_get_parent_node (
return (node->peer);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_next_valid_node
@@ -1021,9 +932,9 @@ acpi_ns_get_parent_node (
*
******************************************************************************/
-struct acpi_namespace_node *
-acpi_ns_get_next_valid_node (
- struct acpi_namespace_node *node)
+struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct
+ acpi_namespace_node
+ *node)
{
/* If we are at the end of this peer list, return NULL */
@@ -1037,7 +948,6 @@ acpi_ns_get_next_valid_node (
return (node->peer);
}
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
*
@@ -1053,38 +963,36 @@ acpi_ns_get_next_valid_node (
*
******************************************************************************/
-acpi_name
-acpi_ns_find_parent_name (
- struct acpi_namespace_node *child_node)
+acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node)
{
- struct acpi_namespace_node *parent_node;
-
-
- ACPI_FUNCTION_TRACE ("ns_find_parent_name");
+ struct acpi_namespace_node *parent_node;
+ ACPI_FUNCTION_TRACE("ns_find_parent_name");
if (child_node) {
/* Valid entry. Get the parent Node */
- parent_node = acpi_ns_get_parent_node (child_node);
+ parent_node = acpi_ns_get_parent_node(child_node);
if (parent_node) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Parent of %p [%4.4s] is %p [%4.4s]\n",
- child_node, acpi_ut_get_node_name (child_node),
- parent_node, acpi_ut_get_node_name (parent_node)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Parent of %p [%4.4s] is %p [%4.4s]\n",
+ child_node,
+ acpi_ut_get_node_name(child_node),
+ parent_node,
+ acpi_ut_get_node_name(parent_node)));
if (parent_node->name.integer) {
- return_VALUE ((acpi_name) parent_node->name.integer);
+ return_VALUE((acpi_name) parent_node->name.
+ integer);
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Unable to find parent of %p (%4.4s)\n",
- child_node, acpi_ut_get_node_name (child_node)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Unable to find parent of %p (%4.4s)\n",
+ child_node,
+ acpi_ut_get_node_name(child_node)));
}
- return_VALUE (ACPI_UNKNOWN_NAME);
+ return_VALUE(ACPI_UNKNOWN_NAME);
}
#endif
-
-
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
index f9a7277dca6e..5f164c0df33b 100644
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -41,14 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nswalk")
-
+ACPI_MODULE_NAME("nswalk")
/*******************************************************************************
*
@@ -68,18 +65,15 @@
* within Scope is returned.
*
******************************************************************************/
-
-struct acpi_namespace_node *
-acpi_ns_get_next_node (
- acpi_object_type type,
- struct acpi_namespace_node *parent_node,
- struct acpi_namespace_node *child_node)
+struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type,
+ struct acpi_namespace_node
+ *parent_node,
+ struct acpi_namespace_node
+ *child_node)
{
- struct acpi_namespace_node *next_node = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_namespace_node *next_node = NULL;
+ ACPI_FUNCTION_ENTRY();
if (!child_node) {
/* It's really the parent's _scope_ that we want */
@@ -92,7 +86,7 @@ acpi_ns_get_next_node (
else {
/* Start search at the NEXT node */
- next_node = acpi_ns_get_next_valid_node (child_node);
+ next_node = acpi_ns_get_next_valid_node(child_node);
}
/* If any type is OK, we are done */
@@ -114,7 +108,7 @@ acpi_ns_get_next_node (
/* Otherwise, move on to the next node */
- next_node = acpi_ns_get_next_valid_node (next_node);
+ next_node = acpi_ns_get_next_valid_node(next_node);
}
/* Not found */
@@ -122,7 +116,6 @@ acpi_ns_get_next_node (
return (NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_walk_namespace
@@ -154,25 +147,21 @@ acpi_ns_get_next_node (
******************************************************************************/
acpi_status
-acpi_ns_walk_namespace (
- acpi_object_type type,
- acpi_handle start_node,
- u32 max_depth,
- u8 unlock_before_callback,
- acpi_walk_callback user_function,
- void *context,
- void **return_value)
+acpi_ns_walk_namespace(acpi_object_type type,
+ acpi_handle start_node,
+ u32 max_depth,
+ u8 unlock_before_callback,
+ acpi_walk_callback user_function,
+ void *context, void **return_value)
{
- acpi_status status;
- acpi_status mutex_status;
- struct acpi_namespace_node *child_node;
- struct acpi_namespace_node *parent_node;
- acpi_object_type child_type;
- u32 level;
-
-
- ACPI_FUNCTION_TRACE ("ns_walk_namespace");
+ acpi_status status;
+ acpi_status mutex_status;
+ struct acpi_namespace_node *child_node;
+ struct acpi_namespace_node *parent_node;
+ acpi_object_type child_type;
+ u32 level;
+ ACPI_FUNCTION_TRACE("ns_walk_namespace");
/* Special case for the namespace Root Node */
@@ -183,9 +172,9 @@ acpi_ns_walk_namespace (
/* Null child means "get first node" */
parent_node = start_node;
- child_node = NULL;
- child_type = ACPI_TYPE_ANY;
- level = 1;
+ child_node = NULL;
+ child_type = ACPI_TYPE_ANY;
+ level = 1;
/*
* Traverse the tree of nodes until we bubble back up to where we
@@ -196,7 +185,9 @@ acpi_ns_walk_namespace (
/* Get the next node in this scope. Null if not found */
status = AE_OK;
- child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node);
+ child_node =
+ acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
+ child_node);
if (child_node) {
/*
* Found node, Get the type if we are not
@@ -212,19 +203,25 @@ acpi_ns_walk_namespace (
* callback function
*/
if (unlock_before_callback) {
- mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (mutex_status)) {
- return_ACPI_STATUS (mutex_status);
+ mutex_status =
+ acpi_ut_release_mutex
+ (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(mutex_status)) {
+ return_ACPI_STATUS
+ (mutex_status);
}
}
- status = user_function (child_node, level,
- context, return_value);
+ status = user_function(child_node, level,
+ context, return_value);
if (unlock_before_callback) {
- mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (mutex_status)) {
- return_ACPI_STATUS (mutex_status);
+ mutex_status =
+ acpi_ut_acquire_mutex
+ (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(mutex_status)) {
+ return_ACPI_STATUS
+ (mutex_status);
}
}
@@ -239,13 +236,13 @@ acpi_ns_walk_namespace (
/* Exit now, with OK status */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
default:
/* All others are valid exceptions */
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
}
@@ -258,7 +255,8 @@ acpi_ns_walk_namespace (
* maximum depth has been reached.
*/
if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
- if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
+ if (acpi_ns_get_next_node
+ (ACPI_TYPE_ANY, child_node, NULL)) {
/*
* There is at least one child of this
* node, visit the onde
@@ -268,8 +266,7 @@ acpi_ns_walk_namespace (
child_node = NULL;
}
}
- }
- else {
+ } else {
/*
* No more children of this node (acpi_ns_get_next_node
* failed), go back upwards in the namespace tree to
@@ -277,13 +274,11 @@ acpi_ns_walk_namespace (
*/
level--;
child_node = parent_node;
- parent_node = acpi_ns_get_parent_node (parent_node);
+ parent_node = acpi_ns_get_parent_node(parent_node);
}
}
/* Complete walk, not terminated by user function */
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 12ea202257fa..c07b046659ff 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -48,10 +48,8 @@
#include <acpi/acnamesp.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsxfeval")
-
+ACPI_MODULE_NAME("nsxfeval")
/*******************************************************************************
*
@@ -73,27 +71,23 @@
* be valid (non-null)
*
******************************************************************************/
-
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_evaluate_object_typed (
- acpi_handle handle,
- acpi_string pathname,
- struct acpi_object_list *external_params,
- struct acpi_buffer *return_buffer,
- acpi_object_type return_type)
+acpi_evaluate_object_typed(acpi_handle handle,
+ acpi_string pathname,
+ struct acpi_object_list *external_params,
+ struct acpi_buffer *return_buffer,
+ acpi_object_type return_type)
{
- acpi_status status;
- u8 must_free = FALSE;
-
-
- ACPI_FUNCTION_TRACE ("acpi_evaluate_object_typed");
+ acpi_status status;
+ u8 must_free = FALSE;
+ ACPI_FUNCTION_TRACE("acpi_evaluate_object_typed");
/* Return buffer must be valid */
if (!return_buffer) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
@@ -102,51 +96,52 @@ acpi_evaluate_object_typed (
/* Evaluate the object */
- status = acpi_evaluate_object (handle, pathname, external_params, return_buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_evaluate_object(handle, pathname, external_params,
+ return_buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Type ANY means "don't care" */
if (return_type == ACPI_TYPE_ANY) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
if (return_buffer->length == 0) {
/* Error because caller specifically asked for a return value */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "No return value\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No return value\n"));
- return_ACPI_STATUS (AE_NULL_OBJECT);
+ return_ACPI_STATUS(AE_NULL_OBJECT);
}
/* Examine the object type returned from evaluate_object */
- if (((union acpi_object *) return_buffer->pointer)->type == return_type) {
- return_ACPI_STATUS (AE_OK);
+ if (((union acpi_object *)return_buffer->pointer)->type == return_type) {
+ return_ACPI_STATUS(AE_OK);
}
/* Return object type does not match requested type */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Incorrect return type [%s] requested [%s]\n",
- acpi_ut_get_type_name (((union acpi_object *) return_buffer->pointer)->type),
- acpi_ut_get_type_name (return_type)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Incorrect return type [%s] requested [%s]\n",
+ acpi_ut_get_type_name(((union acpi_object *)
+ return_buffer->pointer)->type),
+ acpi_ut_get_type_name(return_type)));
if (must_free) {
/* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
- acpi_os_free (return_buffer->pointer);
+ acpi_os_free(return_buffer->pointer);
return_buffer->pointer = NULL;
}
return_buffer->length = 0;
- return_ACPI_STATUS (AE_TYPE);
+ return_ACPI_STATUS(AE_TYPE);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -169,21 +164,18 @@ acpi_evaluate_object_typed (
******************************************************************************/
acpi_status
-acpi_evaluate_object (
- acpi_handle handle,
- acpi_string pathname,
- struct acpi_object_list *external_params,
- struct acpi_buffer *return_buffer)
+acpi_evaluate_object(acpi_handle handle,
+ acpi_string pathname,
+ struct acpi_object_list *external_params,
+ struct acpi_buffer *return_buffer)
{
- acpi_status status;
- acpi_status status2;
- struct acpi_parameter_info info;
- acpi_size buffer_space_needed;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("acpi_evaluate_object");
+ acpi_status status;
+ acpi_status status2;
+ struct acpi_parameter_info info;
+ acpi_size buffer_space_needed;
+ u32 i;
+ ACPI_FUNCTION_TRACE("acpi_evaluate_object");
info.node = handle;
info.parameters = NULL;
@@ -200,11 +192,11 @@ acpi_evaluate_object (
* Allocate a new parameter block for the internal objects
* Add 1 to count to allow for null terminated internal list
*/
- info.parameters = ACPI_MEM_CALLOCATE (
- ((acpi_size) external_params->count + 1) *
- sizeof (void *));
+ info.parameters = ACPI_MEM_CALLOCATE(((acpi_size)
+ external_params->count +
+ 1) * sizeof(void *));
if (!info.parameters) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
@@ -212,48 +204,47 @@ acpi_evaluate_object (
* internal object
*/
for (i = 0; i < external_params->count; i++) {
- status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
- &info.parameters[i]);
- if (ACPI_FAILURE (status)) {
- acpi_ut_delete_internal_object_list (info.parameters);
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_copy_eobject_to_iobject(&external_params->
+ pointer[i],
+ &info.
+ parameters[i]);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_delete_internal_object_list(info.
+ parameters);
+ return_ACPI_STATUS(status);
}
}
info.parameters[external_params->count] = NULL;
}
-
/*
* Three major cases:
* 1) Fully qualified pathname
* 2) No handle, not fully qualified pathname (error)
* 3) Valid handle
*/
- if ((pathname) &&
- (acpi_ns_valid_root_prefix (pathname[0]))) {
+ if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) {
/*
* The path is fully qualified, just evaluate by name
*/
- status = acpi_ns_evaluate_by_name (pathname, &info);
- }
- else if (!handle) {
+ status = acpi_ns_evaluate_by_name(pathname, &info);
+ } else if (!handle) {
/*
* A handle is optional iff a fully qualified pathname
* is specified. Since we've already handled fully
* qualified names above, this is an error
*/
if (!pathname) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Both Handle and Pathname are NULL\n"));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Handle is NULL and Pathname is relative\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Both Handle and Pathname are NULL\n"));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Handle is NULL and Pathname is relative\n"));
}
status = AE_BAD_PARAMETER;
- }
- else {
+ } else {
/*
* We get here if we have a handle -- and if we have a
* pathname it is relative. The handle will be validated
@@ -264,17 +255,15 @@ acpi_evaluate_object (
* The null pathname case means the handle is for
* the actual object to be evaluated
*/
- status = acpi_ns_evaluate_by_handle (&info);
- }
- else {
- /*
- * Both a Handle and a relative Pathname
- */
- status = acpi_ns_evaluate_relative (pathname, &info);
+ status = acpi_ns_evaluate_by_handle(&info);
+ } else {
+ /*
+ * Both a Handle and a relative Pathname
+ */
+ status = acpi_ns_evaluate_relative(pathname, &info);
}
}
-
/*
* If we are expecting a return value, and all went well above,
* copy the return value to an external object.
@@ -282,9 +271,9 @@ acpi_evaluate_object (
if (return_buffer) {
if (!info.return_object) {
return_buffer->length = 0;
- }
- else {
- if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
+ } else {
+ if (ACPI_GET_DESCRIPTOR_TYPE(info.return_object) ==
+ ACPI_DESC_TYPE_NAMED) {
/*
* If we received a NS Node as a return object, this means that
* the object we are evaluating has nothing interesting to
@@ -294,37 +283,43 @@ acpi_evaluate_object (
* support for various types at a later date if necessary.
*/
status = AE_TYPE;
- info.return_object = NULL; /* No need to delete a NS Node */
+ info.return_object = NULL; /* No need to delete a NS Node */
return_buffer->length = 0;
}
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/*
* Find out how large a buffer is needed
* to contain the returned object
*/
- status = acpi_ut_get_object_size (info.return_object,
- &buffer_space_needed);
- if (ACPI_SUCCESS (status)) {
+ status =
+ acpi_ut_get_object_size(info.return_object,
+ &buffer_space_needed);
+ if (ACPI_SUCCESS(status)) {
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (return_buffer,
- buffer_space_needed);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_initialize_buffer
+ (return_buffer,
+ buffer_space_needed);
+ if (ACPI_FAILURE(status)) {
/*
* Caller's buffer is too small or a new one can't be allocated
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Needed buffer size %X, %s\n",
- (u32) buffer_space_needed,
- acpi_format_exception (status)));
- }
- else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Needed buffer size %X, %s\n",
+ (u32)
+ buffer_space_needed,
+ acpi_format_exception
+ (status)));
+ } else {
/*
* We have enough space for the object, build it
*/
- status = acpi_ut_copy_iobject_to_eobject (info.return_object,
- return_buffer);
+ status =
+ acpi_ut_copy_iobject_to_eobject
+ (info.return_object,
+ return_buffer);
}
}
}
@@ -336,14 +331,14 @@ acpi_evaluate_object (
* Delete the internal return object. NOTE: Interpreter
* must be locked to avoid race condition.
*/
- status2 = acpi_ex_enter_interpreter ();
- if (ACPI_SUCCESS (status2)) {
+ status2 = acpi_ex_enter_interpreter();
+ if (ACPI_SUCCESS(status2)) {
/*
* Delete the internal return object. (Or at least
* decrement the reference count by one)
*/
- acpi_ut_remove_reference (info.return_object);
- acpi_ex_exit_interpreter ();
+ acpi_ut_remove_reference(info.return_object);
+ acpi_ex_exit_interpreter();
}
}
@@ -353,13 +348,13 @@ acpi_evaluate_object (
if (info.parameters) {
/* Free the allocated parameter block */
- acpi_ut_delete_internal_object_list (info.parameters);
+ acpi_ut_delete_internal_object_list(info.parameters);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_evaluate_object);
+EXPORT_SYMBOL(acpi_evaluate_object);
/*******************************************************************************
*
@@ -392,26 +387,20 @@ EXPORT_SYMBOL(acpi_evaluate_object);
******************************************************************************/
acpi_status
-acpi_walk_namespace (
- acpi_object_type type,
- acpi_handle start_object,
- u32 max_depth,
- acpi_walk_callback user_function,
- void *context,
- void **return_value)
+acpi_walk_namespace(acpi_object_type type,
+ acpi_handle start_object,
+ u32 max_depth,
+ acpi_walk_callback user_function,
+ void *context, void **return_value)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_walk_namespace");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_walk_namespace");
/* Parameter validation */
- if ((type > ACPI_TYPE_EXTERNAL_MAX) ||
- (!max_depth) ||
- (!user_function)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((type > ACPI_TYPE_EXTERNAL_MAX) || (!max_depth) || (!user_function)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -420,20 +409,20 @@ acpi_walk_namespace (
* to the user function - since this function
* must be allowed to make Acpi calls itself.
*/
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ns_walk_namespace (type, start_object, max_depth,
- ACPI_NS_WALK_UNLOCK,
- user_function, context, return_value);
+ status = acpi_ns_walk_namespace(type, start_object, max_depth,
+ ACPI_NS_WALK_UNLOCK,
+ user_function, context, return_value);
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_walk_namespace);
+EXPORT_SYMBOL(acpi_walk_namespace);
/*******************************************************************************
*
@@ -450,29 +439,26 @@ EXPORT_SYMBOL(acpi_walk_namespace);
******************************************************************************/
static acpi_status
-acpi_ns_get_device_callback (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
+acpi_ns_get_device_callback(acpi_handle obj_handle,
+ u32 nesting_level,
+ void *context, void **return_value)
{
- struct acpi_get_devices_info *info = context;
- acpi_status status;
- struct acpi_namespace_node *node;
- u32 flags;
- struct acpi_device_id hid;
+ struct acpi_get_devices_info *info = context;
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ u32 flags;
+ struct acpi_device_id hid;
struct acpi_compatible_id_list *cid;
- acpi_native_uint i;
-
+ acpi_native_uint i;
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
- node = acpi_ns_map_handle_to_node (obj_handle);
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ node = acpi_ns_map_handle_to_node(obj_handle);
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
@@ -482,8 +468,8 @@ acpi_ns_get_device_callback (
/* Run _STA to determine if device is present */
- status = acpi_ut_execute_STA (node, &flags);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_execute_STA(node, &flags);
+ if (ACPI_FAILURE(status)) {
return (AE_CTRL_DEPTH);
}
@@ -496,44 +482,43 @@ acpi_ns_get_device_callback (
/* Filter based on device HID & CID */
if (info->hid != NULL) {
- status = acpi_ut_execute_HID (node, &hid);
+ status = acpi_ut_execute_HID(node, &hid);
if (status == AE_NOT_FOUND) {
return (AE_OK);
- }
- else if (ACPI_FAILURE (status)) {
+ } else if (ACPI_FAILURE(status)) {
return (AE_CTRL_DEPTH);
}
- if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) {
+ if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) {
/* Get the list of Compatible IDs */
- status = acpi_ut_execute_CID (node, &cid);
+ status = acpi_ut_execute_CID(node, &cid);
if (status == AE_NOT_FOUND) {
return (AE_OK);
- }
- else if (ACPI_FAILURE (status)) {
+ } else if (ACPI_FAILURE(status)) {
return (AE_CTRL_DEPTH);
}
/* Walk the CID list */
for (i = 0; i < cid->count; i++) {
- if (ACPI_STRNCMP (cid->id[i].value, info->hid,
- sizeof (struct acpi_compatible_id)) != 0) {
- ACPI_MEM_FREE (cid);
+ if (ACPI_STRNCMP(cid->id[i].value, info->hid,
+ sizeof(struct
+ acpi_compatible_id)) !=
+ 0) {
+ ACPI_MEM_FREE(cid);
return (AE_OK);
}
}
- ACPI_MEM_FREE (cid);
+ ACPI_MEM_FREE(cid);
}
}
- status = info->user_function (obj_handle, nesting_level, info->context,
- return_value);
+ status = info->user_function(obj_handle, nesting_level, info->context,
+ return_value);
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_devices
@@ -560,32 +545,28 @@ acpi_ns_get_device_callback (
******************************************************************************/
acpi_status
-acpi_get_devices (
- char *HID,
- acpi_walk_callback user_function,
- void *context,
- void **return_value)
+acpi_get_devices(char *HID,
+ acpi_walk_callback user_function,
+ void *context, void **return_value)
{
- acpi_status status;
- struct acpi_get_devices_info info;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_devices");
+ acpi_status status;
+ struct acpi_get_devices_info info;
+ ACPI_FUNCTION_TRACE("acpi_get_devices");
/* Parameter validation */
if (!user_function) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
* We're going to call their callback from OUR callback, so we need
* to know what it is, and their context parameter.
*/
- info.context = context;
+ info.context = context;
info.user_function = user_function;
- info.hid = HID;
+ info.hid = HID;
/*
* Lock the namespace around the walk.
@@ -593,22 +574,22 @@ acpi_get_devices (
* to the user function - since this function
* must be allowed to make Acpi calls itself.
*/
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE,
- ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK,
- acpi_ns_get_device_callback, &info,
- return_value);
+ status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE,
+ ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK,
+ acpi_ns_get_device_callback, &info,
+ return_value);
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (status);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_devices);
+EXPORT_SYMBOL(acpi_get_devices);
/*******************************************************************************
*
@@ -625,44 +606,38 @@ EXPORT_SYMBOL(acpi_get_devices);
******************************************************************************/
acpi_status
-acpi_attach_data (
- acpi_handle obj_handle,
- acpi_object_handler handler,
- void *data)
+acpi_attach_data(acpi_handle obj_handle,
+ acpi_object_handler handler, void *data)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
+ struct acpi_namespace_node *node;
+ acpi_status status;
/* Parameter validation */
- if (!obj_handle ||
- !handler ||
- !data) {
+ if (!obj_handle || !handler || !data) {
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
/* Convert and validate the handle */
- node = acpi_ns_map_handle_to_node (obj_handle);
+ node = acpi_ns_map_handle_to_node(obj_handle);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
- status = acpi_ns_attach_data (node, handler, data);
+ status = acpi_ns_attach_data(node, handler, data);
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_detach_data
@@ -677,42 +652,37 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_detach_data (
- acpi_handle obj_handle,
- acpi_object_handler handler)
+acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
+ struct acpi_namespace_node *node;
+ acpi_status status;
/* Parameter validation */
- if (!obj_handle ||
- !handler) {
+ if (!obj_handle || !handler) {
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
/* Convert and validate the handle */
- node = acpi_ns_map_handle_to_node (obj_handle);
+ node = acpi_ns_map_handle_to_node(obj_handle);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
- status = acpi_ns_detach_data (node, handler);
+ status = acpi_ns_detach_data(node, handler);
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_data
@@ -728,41 +698,33 @@ unlock_and_exit:
******************************************************************************/
acpi_status
-acpi_get_data (
- acpi_handle obj_handle,
- acpi_object_handler handler,
- void **data)
+acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
+ struct acpi_namespace_node *node;
+ acpi_status status;
/* Parameter validation */
- if (!obj_handle ||
- !handler ||
- !data) {
+ if (!obj_handle || !handler || !data) {
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
/* Convert and validate the handle */
- node = acpi_ns_map_handle_to_node (obj_handle);
+ node = acpi_ns_map_handle_to_node(obj_handle);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
- status = acpi_ns_get_attached_data (node, handler, data);
+ status = acpi_ns_get_attached_data(node, handler, data);
-unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
-
-
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 8d097914c49a..6b5f8d4481d1 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -47,10 +47,8 @@
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsxfname")
-
+ACPI_MODULE_NAME("nsxfname")
/******************************************************************************
*
@@ -69,20 +67,15 @@
* namespace handle.
*
******************************************************************************/
-
acpi_status
-acpi_get_handle (
- acpi_handle parent,
- acpi_string pathname,
- acpi_handle *ret_handle)
+acpi_get_handle(acpi_handle parent,
+ acpi_string pathname, acpi_handle * ret_handle)
{
- acpi_status status;
- struct acpi_namespace_node *node = NULL;
- struct acpi_namespace_node *prefix_node = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_status status;
+ struct acpi_namespace_node *node = NULL;
+ struct acpi_namespace_node *prefix_node = NULL;
+ ACPI_FUNCTION_ENTRY();
/* Parameter Validation */
@@ -93,45 +86,47 @@ acpi_get_handle (
/* Convert a parent handle to a prefix node */
if (parent) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
- prefix_node = acpi_ns_map_handle_to_node (parent);
+ prefix_node = acpi_ns_map_handle_to_node(parent);
if (!prefix_node) {
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
}
/* Special case for root, since we can't search for it */
- if (ACPI_STRCMP (pathname, ACPI_NS_ROOT_PATH) == 0) {
- *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node);
+ if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) {
+ *ret_handle =
+ acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
return (AE_OK);
}
/*
* Find the Node and convert to a handle
*/
- status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
- &node);
+ status =
+ acpi_ns_get_node_by_path(pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
+ &node);
*ret_handle = NULL;
- if (ACPI_SUCCESS (status)) {
- *ret_handle = acpi_ns_convert_entry_to_handle (node);
+ if (ACPI_SUCCESS(status)) {
+ *ret_handle = acpi_ns_convert_entry_to_handle(node);
}
return (status);
}
-EXPORT_SYMBOL(acpi_get_handle);
+EXPORT_SYMBOL(acpi_get_handle);
/******************************************************************************
*
@@ -150,14 +145,10 @@ EXPORT_SYMBOL(acpi_get_handle);
******************************************************************************/
acpi_status
-acpi_get_name (
- acpi_handle handle,
- u32 name_type,
- struct acpi_buffer *buffer)
+acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
{
- acpi_status status;
- struct acpi_namespace_node *node;
-
+ acpi_status status;
+ struct acpi_namespace_node *node;
/* Parameter validation */
@@ -165,15 +156,15 @@ acpi_get_name (
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_validate_buffer (buffer);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_validate_buffer(buffer);
+ if (ACPI_FAILURE(status)) {
return (status);
}
if (name_type == ACPI_FULL_PATHNAME) {
/* Get the full pathname (From the namespace root) */
- status = acpi_ns_handle_to_pathname (handle, buffer);
+ status = acpi_ns_handle_to_pathname(handle, buffer);
return (status);
}
@@ -181,12 +172,12 @@ acpi_get_name (
* Wants the single segment ACPI name.
* Validate handle and convert to a namespace Node
*/
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
- node = acpi_ns_map_handle_to_node (handle);
+ node = acpi_ns_map_handle_to_node(handle);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -194,26 +185,25 @@ acpi_get_name (
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
+ if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/* Just copy the ACPI name from the Node and zero terminate it */
- ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node),
- ACPI_NAME_SIZE);
- ((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0;
+ ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node),
+ ACPI_NAME_SIZE);
+ ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
status = AE_OK;
+ unlock_and_exit:
-unlock_and_exit:
-
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
-EXPORT_SYMBOL(acpi_get_name);
+EXPORT_SYMBOL(acpi_get_name);
/******************************************************************************
*
@@ -231,17 +221,14 @@ EXPORT_SYMBOL(acpi_get_name);
******************************************************************************/
acpi_status
-acpi_get_object_info (
- acpi_handle handle,
- struct acpi_buffer *buffer)
+acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- struct acpi_device_info *info;
- struct acpi_device_info *return_info;
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ struct acpi_device_info *info;
+ struct acpi_device_info *return_info;
struct acpi_compatible_id_list *cid_list = NULL;
- acpi_size size;
-
+ acpi_size size;
/* Parameter validation */
@@ -249,37 +236,37 @@ acpi_get_object_info (
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_validate_buffer (buffer);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_validate_buffer(buffer);
+ if (ACPI_FAILURE(status)) {
return (status);
}
- info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_device_info));
+ info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_device_info));
if (!info) {
return (AE_NO_MEMORY);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- node = acpi_ns_map_handle_to_node (handle);
+ node = acpi_ns_map_handle_to_node(handle);
if (!node) {
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
goto cleanup;
}
/* Init return structure */
- size = sizeof (struct acpi_device_info);
+ size = sizeof(struct acpi_device_info);
- info->type = node->type;
- info->name = node->name.integer;
+ info->type = node->type;
+ info->name = node->name.integer;
info->valid = 0;
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -297,73 +284,73 @@ acpi_get_object_info (
/* Execute the Device._HID method */
- status = acpi_ut_execute_HID (node, &info->hardware_id);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ut_execute_HID(node, &info->hardware_id);
+ if (ACPI_SUCCESS(status)) {
info->valid |= ACPI_VALID_HID;
}
/* Execute the Device._UID method */
- status = acpi_ut_execute_UID (node, &info->unique_id);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ut_execute_UID(node, &info->unique_id);
+ if (ACPI_SUCCESS(status)) {
info->valid |= ACPI_VALID_UID;
}
/* Execute the Device._CID method */
- status = acpi_ut_execute_CID (node, &cid_list);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ut_execute_CID(node, &cid_list);
+ if (ACPI_SUCCESS(status)) {
size += ((acpi_size) cid_list->count - 1) *
- sizeof (struct acpi_compatible_id);
+ sizeof(struct acpi_compatible_id);
info->valid |= ACPI_VALID_CID;
}
/* Execute the Device._STA method */
- status = acpi_ut_execute_STA (node, &info->current_status);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ut_execute_STA(node, &info->current_status);
+ if (ACPI_SUCCESS(status)) {
info->valid |= ACPI_VALID_STA;
}
/* Execute the Device._ADR method */
- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
- &info->address);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
+ &info->address);
+ if (ACPI_SUCCESS(status)) {
info->valid |= ACPI_VALID_ADR;
}
/* Execute the Device._sx_d methods */
- status = acpi_ut_execute_sxds (node, info->highest_dstates);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ut_execute_sxds(node, info->highest_dstates);
+ if (ACPI_SUCCESS(status)) {
info->valid |= ACPI_VALID_SXDS;
}
}
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (buffer, size);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_initialize_buffer(buffer, size);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Populate the return buffer */
return_info = buffer->pointer;
- ACPI_MEMCPY (return_info, info, sizeof (struct acpi_device_info));
+ ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info));
if (cid_list) {
- ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
+ ACPI_MEMCPY(&return_info->compatibility_id, cid_list,
+ cid_list->size);
}
-
-cleanup:
- ACPI_MEM_FREE (info);
+ cleanup:
+ ACPI_MEM_FREE(info);
if (cid_list) {
- ACPI_MEM_FREE (cid_list);
+ ACPI_MEM_FREE(cid_list);
}
return (status);
}
-EXPORT_SYMBOL(acpi_get_object_info);
+EXPORT_SYMBOL(acpi_get_object_info);
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index 363e1f6cfb18..0856d42e6909 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -47,9 +47,8 @@
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_NAMESPACE
- ACPI_MODULE_NAME ("nsxfobj")
+ACPI_MODULE_NAME("nsxfobj")
/*******************************************************************************
*
@@ -63,15 +62,10 @@
* DESCRIPTION: This routine returns the type associatd with a particular handle
*
******************************************************************************/
-
-acpi_status
-acpi_get_type (
- acpi_handle handle,
- acpi_object_type *ret_type)
+acpi_status acpi_get_type(acpi_handle handle, acpi_object_type * ret_type)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
+ struct acpi_namespace_node *node;
+ acpi_status status;
/* Parameter Validation */
@@ -88,27 +82,26 @@ acpi_get_type (
return (AE_OK);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
/* Convert and validate the handle */
- node = acpi_ns_map_handle_to_node (handle);
+ node = acpi_ns_map_handle_to_node(handle);
if (!node) {
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (AE_BAD_PARAMETER);
}
*ret_type = node->type;
-
- status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
-EXPORT_SYMBOL(acpi_get_type);
+EXPORT_SYMBOL(acpi_get_type);
/*******************************************************************************
*
@@ -124,14 +117,10 @@ EXPORT_SYMBOL(acpi_get_type);
*
******************************************************************************/
-acpi_status
-acpi_get_parent (
- acpi_handle handle,
- acpi_handle *ret_handle)
+acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
{
- struct acpi_namespace_node *node;
- acpi_status status;
-
+ struct acpi_namespace_node *node;
+ acpi_status status;
if (!ret_handle) {
return (AE_BAD_PARAMETER);
@@ -143,14 +132,14 @@ acpi_get_parent (
return (AE_NULL_ENTRY);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
/* Convert and validate the handle */
- node = acpi_ns_map_handle_to_node (handle);
+ node = acpi_ns_map_handle_to_node(handle);
if (!node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -159,22 +148,21 @@ acpi_get_parent (
/* Get the parent entry */
*ret_handle =
- acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_node (node));
+ acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node));
/* Return exception if parent is null */
- if (!acpi_ns_get_parent_node (node)) {
+ if (!acpi_ns_get_parent_node(node)) {
status = AE_NULL_ENTRY;
}
+ unlock_and_exit:
-unlock_and_exit:
-
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
-EXPORT_SYMBOL(acpi_get_parent);
+EXPORT_SYMBOL(acpi_get_parent);
/*******************************************************************************
*
@@ -195,17 +183,14 @@ EXPORT_SYMBOL(acpi_get_parent);
******************************************************************************/
acpi_status
-acpi_get_next_object (
- acpi_object_type type,
- acpi_handle parent,
- acpi_handle child,
- acpi_handle *ret_handle)
+acpi_get_next_object(acpi_object_type type,
+ acpi_handle parent,
+ acpi_handle child, acpi_handle * ret_handle)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- struct acpi_namespace_node *parent_node = NULL;
- struct acpi_namespace_node *child_node = NULL;
-
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ struct acpi_namespace_node *parent_node = NULL;
+ struct acpi_namespace_node *child_node = NULL;
/* Parameter validation */
@@ -213,8 +198,8 @@ acpi_get_next_object (
return (AE_BAD_PARAMETER);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
return (status);
}
@@ -223,17 +208,16 @@ acpi_get_next_object (
if (!child) {
/* Start search at the beginning of the specified scope */
- parent_node = acpi_ns_map_handle_to_node (parent);
+ parent_node = acpi_ns_map_handle_to_node(parent);
if (!parent_node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
- }
- else {
+ } else {
/* Non-null handle, ignore the parent */
/* Convert and validate the handle */
- child_node = acpi_ns_map_handle_to_node (child);
+ child_node = acpi_ns_map_handle_to_node(child);
if (!child_node) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
@@ -242,20 +226,19 @@ acpi_get_next_object (
/* Internal function does the real work */
- node = acpi_ns_get_next_node (type, parent_node, child_node);
+ node = acpi_ns_get_next_node(type, parent_node, child_node);
if (!node) {
status = AE_NOT_FOUND;
goto unlock_and_exit;
}
if (ret_handle) {
- *ret_handle = acpi_ns_convert_entry_to_handle (node);
+ *ret_handle = acpi_ns_convert_entry_to_handle(node);
}
+ unlock_and_exit:
-unlock_and_exit:
-
- (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return (status);
}
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index a82834b32752..64b98e82feb7 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -34,16 +34,18 @@
#define ACPI_NUMA 0x80000000
#define _COMPONENT ACPI_NUMA
- ACPI_MODULE_NAME ("numa")
+ACPI_MODULE_NAME("numa")
-extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries);
+extern int __init acpi_table_parse_madt_family(enum acpi_table_id id,
+ unsigned long madt_size,
+ int entry_id,
+ acpi_madt_entry_handler handler,
+ unsigned int max_entries);
-void __init
-acpi_table_print_srat_entry (
- acpi_table_entry_header *header)
+void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
{
- ACPI_FUNCTION_NAME ("acpi_table_print_srat_entry");
+ ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
if (!header)
return;
@@ -52,48 +54,55 @@ acpi_table_print_srat_entry (
case ACPI_SRAT_PROCESSOR_AFFINITY:
#ifdef ACPI_DEBUG_OUTPUT
- {
- struct acpi_table_processor_affinity *p =
- (struct acpi_table_processor_affinity*) header;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
- p->apic_id, p->lsapic_eid, p->proximity_domain,
- p->flags.enabled?"enabled":"disabled"));
- }
-#endif /* ACPI_DEBUG_OUTPUT */
+ {
+ struct acpi_table_processor_affinity *p =
+ (struct acpi_table_processor_affinity *)header;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
+ p->apic_id, p->lsapic_eid,
+ p->proximity_domain,
+ p->flags.
+ enabled ? "enabled" : "disabled"));
+ }
+#endif /* ACPI_DEBUG_OUTPUT */
break;
case ACPI_SRAT_MEMORY_AFFINITY:
#ifdef ACPI_DEBUG_OUTPUT
- {
- struct acpi_table_memory_affinity *p =
- (struct acpi_table_memory_affinity*) header;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
- p->base_addr_hi, p->base_addr_lo, p->length_hi, p->length_lo,
- p->memory_type, p->proximity_domain,
- p->flags.enabled ? "enabled" : "disabled",
- p->flags.hot_pluggable ? " hot-pluggable" : ""));
- }
-#endif /* ACPI_DEBUG_OUTPUT */
+ {
+ struct acpi_table_memory_affinity *p =
+ (struct acpi_table_memory_affinity *)header;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
+ p->base_addr_hi, p->base_addr_lo,
+ p->length_hi, p->length_lo,
+ p->memory_type, p->proximity_domain,
+ p->flags.
+ enabled ? "enabled" : "disabled",
+ p->flags.
+ hot_pluggable ? " hot-pluggable" :
+ ""));
+ }
+#endif /* ACPI_DEBUG_OUTPUT */
break;
default:
- printk(KERN_WARNING PREFIX "Found unsupported SRAT entry (type = 0x%x)\n",
- header->type);
+ printk(KERN_WARNING PREFIX
+ "Found unsupported SRAT entry (type = 0x%x)\n",
+ header->type);
break;
}
}
-
-static int __init
-acpi_parse_slit (unsigned long phys_addr, unsigned long size)
+static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size)
{
- struct acpi_table_slit *slit;
- u32 localities;
+ struct acpi_table_slit *slit;
+ u32 localities;
if (!phys_addr || !size)
return -EINVAL;
- slit = (struct acpi_table_slit *) __va(phys_addr);
+ slit = (struct acpi_table_slit *)__va(phys_addr);
/* downcast just for %llu vs %lu for i386/ia64 */
localities = (u32) slit->localities;
@@ -103,15 +112,13 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size)
return 0;
}
-
static int __init
-acpi_parse_processor_affinity (
- acpi_table_entry_header *header,
- const unsigned long end)
+acpi_parse_processor_affinity(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_processor_affinity *processor_affinity;
- processor_affinity = (struct acpi_table_processor_affinity*) header;
+ processor_affinity = (struct acpi_table_processor_affinity *)header;
if (!processor_affinity)
return -EINVAL;
@@ -123,15 +130,13 @@ acpi_parse_processor_affinity (
return 0;
}
-
static int __init
-acpi_parse_memory_affinity (
- acpi_table_entry_header *header,
- const unsigned long end)
+acpi_parse_memory_affinity(acpi_table_entry_header * header,
+ const unsigned long end)
{
struct acpi_table_memory_affinity *memory_affinity;
- memory_affinity = (struct acpi_table_memory_affinity*) header;
+ memory_affinity = (struct acpi_table_memory_affinity *)header;
if (!memory_affinity)
return -EINVAL;
@@ -143,36 +148,30 @@ acpi_parse_memory_affinity (
return 0;
}
-
-static int __init
-acpi_parse_srat (unsigned long phys_addr, unsigned long size)
+static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size)
{
- struct acpi_table_srat *srat;
+ struct acpi_table_srat *srat;
if (!phys_addr || !size)
return -EINVAL;
- srat = (struct acpi_table_srat *) __va(phys_addr);
+ srat = (struct acpi_table_srat *)__va(phys_addr);
return 0;
}
-
int __init
-acpi_table_parse_srat (
- enum acpi_srat_entry_id id,
- acpi_madt_entry_handler handler,
- unsigned int max_entries)
+acpi_table_parse_srat(enum acpi_srat_entry_id id,
+ acpi_madt_entry_handler handler, unsigned int max_entries)
{
- return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat),
- id, handler, max_entries);
+ return acpi_table_parse_madt_family(ACPI_SRAT,
+ sizeof(struct acpi_table_srat), id,
+ handler, max_entries);
}
-
-int __init
-acpi_numa_init(void)
+int __init acpi_numa_init(void)
{
- int result;
+ int result;
/* SRAT: Static Resource Affinity Table */
result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat);
@@ -181,9 +180,7 @@ acpi_numa_init(void)
result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY,
acpi_parse_processor_affinity,
NR_CPUS);
- result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY,
- acpi_parse_memory_affinity,
- NR_NODE_MEMBLKS); // IA64 specific
+ result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific
}
/* SLIT: System Locality Information Table */
@@ -193,8 +190,7 @@ acpi_numa_init(void)
return 0;
}
-int
-acpi_get_pxm(acpi_handle h)
+int acpi_get_pxm(acpi_handle h)
{
unsigned long pxm;
acpi_status status;
@@ -207,7 +203,8 @@ acpi_get_pxm(acpi_handle h)
if (ACPI_SUCCESS(status))
return (int)pxm;
status = acpi_get_parent(handle, &phandle);
- } while(ACPI_SUCCESS(status));
+ } while (ACPI_SUCCESS(status));
return -1;
}
+
EXPORT_SYMBOL(acpi_get_pxm);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 0d11d6e6abd6..d528c750a380 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -45,16 +45,12 @@
#include <linux/efi.h>
-
#define _COMPONENT ACPI_OS_SERVICES
-ACPI_MODULE_NAME ("osl")
-
+ACPI_MODULE_NAME("osl")
#define PREFIX "ACPI: "
-
-struct acpi_os_dpc
-{
- acpi_osd_exec_callback function;
- void *context;
+struct acpi_os_dpc {
+ acpi_osd_exec_callback function;
+ void *context;
};
#ifdef CONFIG_ACPI_CUSTOM_DSDT
@@ -69,7 +65,7 @@ int acpi_in_debugger;
EXPORT_SYMBOL(acpi_in_debugger);
extern char line_buf[80];
-#endif /*ENABLE_DEBUGGER*/
+#endif /*ENABLE_DEBUGGER */
int acpi_specific_hotkey_enabled = TRUE;
EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
@@ -79,33 +75,29 @@ static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
static struct workqueue_struct *kacpid_wq;
-acpi_status
-acpi_os_initialize(void)
+acpi_status acpi_os_initialize(void)
{
return AE_OK;
}
-acpi_status
-acpi_os_initialize1(void)
+acpi_status acpi_os_initialize1(void)
{
/*
* Initialize PCI configuration space access, as we'll need to access
* it while walking the namespace (bus 0 and root bridges w/ _BBNs).
*/
-#ifdef CONFIG_ACPI_PCI
if (!raw_pci_ops) {
- printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n");
+ printk(KERN_ERR PREFIX
+ "Access to PCI configuration space unavailable\n");
return AE_NULL_ENTRY;
}
-#endif
kacpid_wq = create_singlethread_workqueue("kacpid");
BUG_ON(!kacpid_wq);
return AE_OK;
}
-acpi_status
-acpi_os_terminate(void)
+acpi_status acpi_os_terminate(void)
{
if (acpi_irq_handler) {
acpi_os_remove_interrupt_handler(acpi_irq_irq,
@@ -117,21 +109,20 @@ acpi_os_terminate(void)
return AE_OK;
}
-void
-acpi_os_printf(const char *fmt,...)
+void acpi_os_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
acpi_os_vprintf(fmt, args);
va_end(args);
}
+
EXPORT_SYMBOL(acpi_os_printf);
-void
-acpi_os_vprintf(const char *fmt, va_list args)
+void acpi_os_vprintf(const char *fmt, va_list args)
{
static char buffer[512];
-
+
vsprintf(buffer, fmt, args);
#ifdef ENABLE_DEBUGGER
@@ -146,8 +137,7 @@ acpi_os_vprintf(const char *fmt, va_list args)
}
extern int acpi_in_resume;
-void *
-acpi_os_allocate(acpi_size size)
+void *acpi_os_allocate(acpi_size size)
{
if (acpi_in_resume)
return kmalloc(size, GFP_ATOMIC);
@@ -155,31 +145,32 @@ acpi_os_allocate(acpi_size size)
return kmalloc(size, GFP_KERNEL);
}
-void
-acpi_os_free(void *ptr)
+void acpi_os_free(void *ptr)
{
kfree(ptr);
}
+
EXPORT_SYMBOL(acpi_os_free);
-acpi_status
-acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
+acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
{
if (efi_enabled) {
addr->pointer_type = ACPI_PHYSICAL_POINTER;
if (efi.acpi20)
addr->pointer.physical =
- (acpi_physical_address) virt_to_phys(efi.acpi20);
+ (acpi_physical_address) virt_to_phys(efi.acpi20);
else if (efi.acpi)
addr->pointer.physical =
- (acpi_physical_address) virt_to_phys(efi.acpi);
+ (acpi_physical_address) virt_to_phys(efi.acpi);
else {
- printk(KERN_ERR PREFIX "System description tables not found\n");
+ printk(KERN_ERR PREFIX
+ "System description tables not found\n");
return AE_NOT_FOUND;
}
} else {
if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) {
- printk(KERN_ERR PREFIX "System description tables not found\n");
+ printk(KERN_ERR PREFIX
+ "System description tables not found\n");
return AE_NOT_FOUND;
}
}
@@ -188,11 +179,12 @@ acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
}
acpi_status
-acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void __iomem **virt)
+acpi_os_map_memory(acpi_physical_address phys, acpi_size size,
+ void __iomem ** virt)
{
if (efi_enabled) {
if (EFI_MEMORY_WB & efi_mem_attributes(phys)) {
- *virt = (void __iomem *) phys_to_virt(phys);
+ *virt = (void __iomem *)phys_to_virt(phys);
} else {
*virt = ioremap(phys, size);
}
@@ -202,9 +194,9 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void __iomem **vi
return AE_BAD_PARAMETER;
}
/*
- * ioremap checks to ensure this is in reserved space
- */
- *virt = ioremap((unsigned long) phys, size);
+ * ioremap checks to ensure this is in reserved space
+ */
+ *virt = ioremap((unsigned long)phys, size);
}
if (!*virt)
@@ -213,17 +205,16 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void __iomem **vi
return AE_OK;
}
-void
-acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
{
iounmap(virt);
}
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
+acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
{
- if(!phys || !virt)
+ if (!phys || !virt)
return AE_BAD_PARAMETER;
*phys = virt_to_phys(virt);
@@ -237,16 +228,16 @@ acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
acpi_status
-acpi_os_predefined_override (const struct acpi_predefined_names *init_val,
- acpi_string *new_val)
+acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
+ acpi_string * new_val)
{
if (!init_val || !new_val)
return AE_BAD_PARAMETER;
*new_val = NULL;
- if (!memcmp (init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
+ if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
- acpi_os_name);
+ acpi_os_name);
*new_val = acpi_os_name;
}
@@ -254,15 +245,15 @@ acpi_os_predefined_override (const struct acpi_predefined_names *init_val,
}
acpi_status
-acpi_os_table_override (struct acpi_table_header *existing_table,
- struct acpi_table_header **new_table)
+acpi_os_table_override(struct acpi_table_header * existing_table,
+ struct acpi_table_header ** new_table)
{
if (!existing_table || !new_table)
return AE_BAD_PARAMETER;
#ifdef CONFIG_ACPI_CUSTOM_DSDT
if (strncmp(existing_table->signature, "DSDT", 4) == 0)
- *new_table = (struct acpi_table_header*)AmlCode;
+ *new_table = (struct acpi_table_header *)AmlCode;
else
*new_table = NULL;
#else
@@ -271,14 +262,14 @@ acpi_os_table_override (struct acpi_table_header *existing_table,
return AE_OK;
}
-static irqreturn_t
-acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
{
- return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
+ return (*acpi_irq_handler) (acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
}
acpi_status
-acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *context)
+acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
+ void *context)
{
unsigned int irq;
@@ -305,8 +296,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *conte
return AE_OK;
}
-acpi_status
-acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
+acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
{
if (irq) {
free_irq(irq, acpi_irq);
@@ -321,16 +311,15 @@ acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
* Running in interpreter thread context, safe to sleep
*/
-void
-acpi_os_sleep(acpi_integer ms)
+void acpi_os_sleep(acpi_integer ms)
{
current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(((signed long) ms * HZ) / 1000);
+ schedule_timeout(((signed long)ms * HZ) / 1000);
}
+
EXPORT_SYMBOL(acpi_os_sleep);
-void
-acpi_os_stall(u32 us)
+void acpi_os_stall(u32 us)
{
while (us) {
u32 delay = 1000;
@@ -342,6 +331,7 @@ acpi_os_stall(u32 us)
us -= delay;
}
}
+
EXPORT_SYMBOL(acpi_os_stall);
/*
@@ -349,8 +339,7 @@ EXPORT_SYMBOL(acpi_os_stall);
* Returns 64-bit free-running, monotonically increasing timer
* with 100ns granularity
*/
-u64
-acpi_os_get_timer (void)
+u64 acpi_os_get_timer(void)
{
static u64 t;
@@ -367,27 +356,22 @@ acpi_os_get_timer (void)
return ++t;
}
-acpi_status
-acpi_os_read_port(
- acpi_io_address port,
- u32 *value,
- u32 width)
+acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
{
u32 dummy;
if (!value)
value = &dummy;
- switch (width)
- {
+ switch (width) {
case 8:
- *(u8*) value = inb(port);
+ *(u8 *) value = inb(port);
break;
case 16:
- *(u16*) value = inw(port);
+ *(u16 *) value = inw(port);
break;
case 32:
- *(u32*) value = inl(port);
+ *(u32 *) value = inl(port);
break;
default:
BUG();
@@ -395,16 +379,12 @@ acpi_os_read_port(
return AE_OK;
}
+
EXPORT_SYMBOL(acpi_os_read_port);
-acpi_status
-acpi_os_write_port(
- acpi_io_address port,
- u32 value,
- u32 width)
+acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
{
- switch (width)
- {
+ switch (width) {
case 8:
outb(value, port);
break;
@@ -420,40 +400,38 @@ acpi_os_write_port(
return AE_OK;
}
+
EXPORT_SYMBOL(acpi_os_write_port);
acpi_status
-acpi_os_read_memory(
- acpi_physical_address phys_addr,
- u32 *value,
- u32 width)
+acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
{
- u32 dummy;
- void __iomem *virt_addr;
- int iomem = 0;
+ u32 dummy;
+ void __iomem *virt_addr;
+ int iomem = 0;
if (efi_enabled) {
if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
/* HACK ALERT! We can use readb/w/l on real memory too.. */
- virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+ virt_addr = (void __iomem *)phys_to_virt(phys_addr);
} else {
iomem = 1;
virt_addr = ioremap(phys_addr, width);
}
} else
- virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+ virt_addr = (void __iomem *)phys_to_virt(phys_addr);
if (!value)
value = &dummy;
switch (width) {
case 8:
- *(u8*) value = readb(virt_addr);
+ *(u8 *) value = readb(virt_addr);
break;
case 16:
- *(u16*) value = readw(virt_addr);
+ *(u16 *) value = readw(virt_addr);
break;
case 32:
- *(u32*) value = readl(virt_addr);
+ *(u32 *) value = readl(virt_addr);
break;
default:
BUG();
@@ -468,24 +446,21 @@ acpi_os_read_memory(
}
acpi_status
-acpi_os_write_memory(
- acpi_physical_address phys_addr,
- u32 value,
- u32 width)
+acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
{
- void __iomem *virt_addr;
- int iomem = 0;
+ void __iomem *virt_addr;
+ int iomem = 0;
if (efi_enabled) {
if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
/* HACK ALERT! We can use writeb/w/l on real memory too */
- virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+ virt_addr = (void __iomem *)phys_to_virt(phys_addr);
} else {
iomem = 1;
virt_addr = ioremap(phys_addr, width);
}
} else
- virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+ virt_addr = (void __iomem *)phys_to_virt(phys_addr);
switch (width) {
case 8:
@@ -507,10 +482,9 @@ acpi_os_write_memory(
return AE_OK;
}
-#ifdef CONFIG_ACPI_PCI
-
acpi_status
-acpi_os_read_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, void *value, u32 width)
+acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+ void *value, u32 width)
{
int result, size;
@@ -534,15 +508,17 @@ acpi_os_read_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, void *value
BUG_ON(!raw_pci_ops);
result = raw_pci_ops->read(pci_id->segment, pci_id->bus,
- PCI_DEVFN(pci_id->device, pci_id->function),
- reg, size, value);
+ PCI_DEVFN(pci_id->device, pci_id->function),
+ reg, size, value);
return (result ? AE_ERROR : AE_OK);
}
+
EXPORT_SYMBOL(acpi_os_read_pci_configuration);
acpi_status
-acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integer value, u32 width)
+acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+ acpi_integer value, u32 width)
{
int result, size;
@@ -563,56 +539,62 @@ acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integ
BUG_ON(!raw_pci_ops);
result = raw_pci_ops->write(pci_id->segment, pci_id->bus,
- PCI_DEVFN(pci_id->device, pci_id->function),
- reg, size, value);
+ PCI_DEVFN(pci_id->device, pci_id->function),
+ reg, size, value);
return (result ? AE_ERROR : AE_OK);
}
/* TODO: Change code to take advantage of driver model more */
-static void
-acpi_os_derive_pci_id_2 (
- acpi_handle rhandle, /* upper bound */
- acpi_handle chandle, /* current node */
- struct acpi_pci_id **id,
- int *is_bridge,
- u8 *bus_number)
+static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */
+ acpi_handle chandle, /* current node */
+ struct acpi_pci_id **id,
+ int *is_bridge, u8 * bus_number)
{
- acpi_handle handle;
- struct acpi_pci_id *pci_id = *id;
- acpi_status status;
- unsigned long temp;
- acpi_object_type type;
- u8 tu8;
+ acpi_handle handle;
+ struct acpi_pci_id *pci_id = *id;
+ acpi_status status;
+ unsigned long temp;
+ acpi_object_type type;
+ u8 tu8;
acpi_get_parent(chandle, &handle);
if (handle != rhandle) {
- acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, bus_number);
+ acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
+ bus_number);
status = acpi_get_type(handle, &type);
- if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) )
+ if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
return;
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &temp);
+ status =
+ acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
+ &temp);
if (ACPI_SUCCESS(status)) {
- pci_id->device = ACPI_HIWORD (ACPI_LODWORD (temp));
- pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
+ pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
+ pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));
if (*is_bridge)
pci_id->bus = *bus_number;
/* any nicer way to get bus number of bridge ? */
- status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8);
- if (ACPI_SUCCESS(status) &&
- ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
- status = acpi_os_read_pci_configuration(pci_id, 0x18, &tu8, 8);
+ status =
+ acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8,
+ 8);
+ if (ACPI_SUCCESS(status)
+ && ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
+ status =
+ acpi_os_read_pci_configuration(pci_id, 0x18,
+ &tu8, 8);
if (!ACPI_SUCCESS(status)) {
/* Certainly broken... FIX ME */
return;
}
*is_bridge = 1;
pci_id->bus = tu8;
- status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8);
+ status =
+ acpi_os_read_pci_configuration(pci_id, 0x19,
+ &tu8, 8);
if (ACPI_SUCCESS(status)) {
*bus_number = tu8;
}
@@ -622,11 +604,9 @@ acpi_os_derive_pci_id_2 (
}
}
-void
-acpi_os_derive_pci_id (
- acpi_handle rhandle, /* upper bound */
- acpi_handle chandle, /* current node */
- struct acpi_pci_id **id)
+void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
+ acpi_handle chandle, /* current node */
+ struct acpi_pci_id **id)
{
int is_bridge = 1;
u8 bus_number = (*id)->bus;
@@ -634,49 +614,15 @@ acpi_os_derive_pci_id (
acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
}
-#else /*!CONFIG_ACPI_PCI*/
-
-acpi_status
-acpi_os_write_pci_configuration (
- struct acpi_pci_id *pci_id,
- u32 reg,
- acpi_integer value,
- u32 width)
-{
- return AE_SUPPORT;
-}
-
-acpi_status
-acpi_os_read_pci_configuration (
- struct acpi_pci_id *pci_id,
- u32 reg,
- void *value,
- u32 width)
-{
- return AE_SUPPORT;
-}
-
-void
-acpi_os_derive_pci_id (
- acpi_handle rhandle, /* upper bound */
- acpi_handle chandle, /* current node */
- struct acpi_pci_id **id)
-{
-}
-
-#endif /*CONFIG_ACPI_PCI*/
-
-static void
-acpi_os_execute_deferred (
- void *context)
+static void acpi_os_execute_deferred(void *context)
{
- struct acpi_os_dpc *dpc = NULL;
+ struct acpi_os_dpc *dpc = NULL;
- ACPI_FUNCTION_TRACE ("os_execute_deferred");
+ ACPI_FUNCTION_TRACE("os_execute_deferred");
- dpc = (struct acpi_os_dpc *) context;
+ dpc = (struct acpi_os_dpc *)context;
if (!dpc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
return_VOID;
}
@@ -688,21 +634,21 @@ acpi_os_execute_deferred (
}
acpi_status
-acpi_os_queue_for_execution(
- u32 priority,
- acpi_osd_exec_callback function,
- void *context)
+acpi_os_queue_for_execution(u32 priority,
+ acpi_osd_exec_callback function, void *context)
{
- acpi_status status = AE_OK;
- struct acpi_os_dpc *dpc;
- struct work_struct *task;
+ acpi_status status = AE_OK;
+ struct acpi_os_dpc *dpc;
+ struct work_struct *task;
- ACPI_FUNCTION_TRACE ("os_queue_for_execution");
+ ACPI_FUNCTION_TRACE("os_queue_for_execution");
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Scheduling function [%p(%p)] for deferred execution.\n",
+ function, context));
if (!function)
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
/*
* Allocate/initialize DPC structure. Note that this memory will be
@@ -715,146 +661,94 @@ acpi_os_queue_for_execution(
* from the same memory.
*/
- dpc = kmalloc(sizeof(struct acpi_os_dpc)+sizeof(struct work_struct), GFP_ATOMIC);
+ dpc =
+ kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct),
+ GFP_ATOMIC);
if (!dpc)
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
dpc->function = function;
dpc->context = context;
- task = (void *)(dpc+1);
- INIT_WORK(task, acpi_os_execute_deferred, (void*)dpc);
+ task = (void *)(dpc + 1);
+ INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
if (!queue_work(kacpid_wq, task)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to queue_work() failed.\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Call to queue_work() failed.\n"));
kfree(dpc);
status = AE_ERROR;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
+
EXPORT_SYMBOL(acpi_os_queue_for_execution);
-void
-acpi_os_wait_events_complete(
- void *context)
+void acpi_os_wait_events_complete(void *context)
{
flush_workqueue(kacpid_wq);
}
+
EXPORT_SYMBOL(acpi_os_wait_events_complete);
/*
* Allocate the memory for a spinlock and initialize it.
*/
-acpi_status
-acpi_os_create_lock (
- acpi_handle *out_handle)
+acpi_status acpi_os_create_lock(acpi_handle * out_handle)
{
spinlock_t *lock_ptr;
- ACPI_FUNCTION_TRACE ("os_create_lock");
+ ACPI_FUNCTION_TRACE("os_create_lock");
lock_ptr = acpi_os_allocate(sizeof(spinlock_t));
spin_lock_init(lock_ptr);
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr));
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr));
*out_handle = lock_ptr;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*
* Deallocate the memory for a spinlock.
*/
-void
-acpi_os_delete_lock (
- acpi_handle handle)
+void acpi_os_delete_lock(acpi_handle handle)
{
- ACPI_FUNCTION_TRACE ("os_create_lock");
+ ACPI_FUNCTION_TRACE("os_create_lock");
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle));
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle));
acpi_os_free(handle);
return_VOID;
}
-/*
- * Acquire a spinlock.
- *
- * handle is a pointer to the spinlock_t.
- * flags is *not* the result of save_flags - it is an ACPI-specific flag variable
- * that indicates whether we are at interrupt level.
- */
-void
-acpi_os_acquire_lock (
- acpi_handle handle,
- u32 flags)
-{
- ACPI_FUNCTION_TRACE ("os_acquire_lock");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquiring spinlock[%p] from %s level\n", handle,
- ((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));
-
- if (flags & ACPI_NOT_ISR)
- ACPI_DISABLE_IRQS();
-
- spin_lock((spinlock_t *)handle);
-
- return_VOID;
-}
-
-
-/*
- * Release a spinlock. See above.
- */
-void
-acpi_os_release_lock (
- acpi_handle handle,
- u32 flags)
-{
- ACPI_FUNCTION_TRACE ("os_release_lock");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Releasing spinlock[%p] from %s level\n", handle,
- ((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));
-
- spin_unlock((spinlock_t *)handle);
-
- if (flags & ACPI_NOT_ISR)
- ACPI_ENABLE_IRQS();
-
- return_VOID;
-}
-
-
acpi_status
-acpi_os_create_semaphore(
- u32 max_units,
- u32 initial_units,
- acpi_handle *handle)
+acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
{
- struct semaphore *sem = NULL;
+ struct semaphore *sem = NULL;
- ACPI_FUNCTION_TRACE ("os_create_semaphore");
+ ACPI_FUNCTION_TRACE("os_create_semaphore");
sem = acpi_os_allocate(sizeof(struct semaphore));
if (!sem)
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
memset(sem, 0, sizeof(struct semaphore));
sema_init(sem, initial_units);
- *handle = (acpi_handle*)sem;
+ *handle = (acpi_handle *) sem;
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n", *handle, initial_units));
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
+ *handle, initial_units));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_os_create_semaphore);
+EXPORT_SYMBOL(acpi_os_create_semaphore);
/*
* TODO: A better way to delete semaphores? Linux doesn't have a
@@ -863,25 +757,24 @@ EXPORT_SYMBOL(acpi_os_create_semaphore);
* we at least check for blocked threads and signal/cancel them?
*/
-acpi_status
-acpi_os_delete_semaphore(
- acpi_handle handle)
+acpi_status acpi_os_delete_semaphore(acpi_handle handle)
{
- struct semaphore *sem = (struct semaphore*) handle;
+ struct semaphore *sem = (struct semaphore *)handle;
- ACPI_FUNCTION_TRACE ("os_delete_semaphore");
+ ACPI_FUNCTION_TRACE("os_delete_semaphore");
if (!sem)
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
- acpi_os_free(sem); sem = NULL;
+ acpi_os_free(sem);
+ sem = NULL;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_os_delete_semaphore);
+EXPORT_SYMBOL(acpi_os_delete_semaphore);
/*
* TODO: The kernel doesn't have a 'down_timeout' function -- had to
@@ -892,31 +785,27 @@ EXPORT_SYMBOL(acpi_os_delete_semaphore);
*
* TODO: Support for units > 1?
*/
-acpi_status
-acpi_os_wait_semaphore(
- acpi_handle handle,
- u32 units,
- u16 timeout)
+acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
{
- acpi_status status = AE_OK;
- struct semaphore *sem = (struct semaphore*)handle;
- int ret = 0;
+ acpi_status status = AE_OK;
+ struct semaphore *sem = (struct semaphore *)handle;
+ int ret = 0;
- ACPI_FUNCTION_TRACE ("os_wait_semaphore");
+ ACPI_FUNCTION_TRACE("os_wait_semaphore");
if (!sem || (units < 1))
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
if (units > 1)
- return_ACPI_STATUS (AE_SUPPORT);
+ return_ACPI_STATUS(AE_SUPPORT);
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
+ handle, units, timeout));
if (in_atomic())
timeout = 0;
- switch (timeout)
- {
+ switch (timeout) {
/*
* No Wait:
* --------
@@ -924,8 +813,8 @@ acpi_os_wait_semaphore(
* acquire the semaphore if available otherwise return AE_TIME
* (a.k.a. 'would block').
*/
- case 0:
- if(down_trylock(sem))
+ case 0:
+ if (down_trylock(sem))
status = AE_TIME;
break;
@@ -933,7 +822,7 @@ acpi_os_wait_semaphore(
* Wait Indefinitely:
* ------------------
*/
- case ACPI_WAIT_FOREVER:
+ case ACPI_WAIT_FOREVER:
down(sem);
break;
@@ -941,11 +830,11 @@ acpi_os_wait_semaphore(
* Wait w/ Timeout:
* ----------------
*/
- default:
+ default:
// TODO: A better timeout algorithm?
{
int i = 0;
- static const int quantum_ms = 1000/HZ;
+ static const int quantum_ms = 1000 / HZ;
ret = down_trylock(sem);
for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
@@ -953,7 +842,7 @@ acpi_os_wait_semaphore(
schedule_timeout(1);
ret = down_trylock(sem);
}
-
+
if (ret != 0)
status = AE_TIME;
}
@@ -961,47 +850,48 @@ acpi_os_wait_semaphore(
}
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Failed to acquire semaphore[%p|%d|%d], %s\n",
- handle, units, timeout, acpi_format_exception(status)));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Failed to acquire semaphore[%p|%d|%d], %s\n",
+ handle, units, timeout,
+ acpi_format_exception(status)));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
+ "Acquired semaphore[%p|%d|%d]\n", handle,
+ units, timeout));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_os_wait_semaphore);
+EXPORT_SYMBOL(acpi_os_wait_semaphore);
/*
* TODO: Support for units > 1?
*/
-acpi_status
-acpi_os_signal_semaphore(
- acpi_handle handle,
- u32 units)
+acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
{
- struct semaphore *sem = (struct semaphore *) handle;
+ struct semaphore *sem = (struct semaphore *)handle;
- ACPI_FUNCTION_TRACE ("os_signal_semaphore");
+ ACPI_FUNCTION_TRACE("os_signal_semaphore");
if (!sem || (units < 1))
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
if (units > 1)
- return_ACPI_STATUS (AE_SUPPORT);
+ return_ACPI_STATUS(AE_SUPPORT);
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle, units));
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
+ units));
up(sem);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
+
EXPORT_SYMBOL(acpi_os_signal_semaphore);
#ifdef ACPI_FUTURE_USAGE
-u32
-acpi_os_get_line(char *buffer)
+u32 acpi_os_get_line(char *buffer)
{
#ifdef ENABLE_DEBUGGER
@@ -1018,22 +908,21 @@ acpi_os_get_line(char *buffer)
return 0;
}
-#endif /* ACPI_FUTURE_USAGE */
+#endif /* ACPI_FUTURE_USAGE */
/* Assumes no unreadable holes inbetween */
-u8
-acpi_os_readable(void *ptr, acpi_size len)
+u8 acpi_os_readable(void *ptr, acpi_size len)
{
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
char tmp;
- return !__get_user(tmp, (char __user *)ptr) && !__get_user(tmp, (char __user *)ptr + len - 1);
+ return !__get_user(tmp, (char __user *)ptr)
+ && !__get_user(tmp, (char __user *)ptr + len - 1);
#endif
return 1;
}
#ifdef ACPI_FUTURE_USAGE
-u8
-acpi_os_writable(void *ptr, acpi_size len)
+u8 acpi_os_writable(void *ptr, acpi_size len)
{
/* could do dummy write (racy) or a kernel page table lookup.
The later may be difficult at early boot when kmap doesn't work yet. */
@@ -1041,8 +930,7 @@ acpi_os_writable(void *ptr, acpi_size len)
}
#endif
-u32
-acpi_os_get_thread_id (void)
+u32 acpi_os_get_thread_id(void)
{
if (!in_atomic())
return current->pid;
@@ -1050,13 +938,9 @@ acpi_os_get_thread_id (void)
return 0;
}
-acpi_status
-acpi_os_signal (
- u32 function,
- void *info)
+acpi_status acpi_os_signal(u32 function, void *info)
{
- switch (function)
- {
+ switch (function) {
case ACPI_SIGNAL_FATAL:
printk(KERN_ERR PREFIX "Fatal opcode executed\n");
break;
@@ -1076,13 +960,13 @@ acpi_os_signal (
return AE_OK;
}
+
EXPORT_SYMBOL(acpi_os_signal);
-static int __init
-acpi_os_name_setup(char *str)
+static int __init acpi_os_name_setup(char *str)
{
char *p = acpi_os_name;
- int count = ACPI_MAX_OVERRIDE_LEN-1;
+ int count = ACPI_MAX_OVERRIDE_LEN - 1;
if (!str || !*str)
return 0;
@@ -1098,7 +982,7 @@ acpi_os_name_setup(char *str)
*p = 0;
return 1;
-
+
}
__setup("acpi_os_name=", acpi_os_name_setup);
@@ -1108,16 +992,15 @@ __setup("acpi_os_name=", acpi_os_name_setup);
* empty string disables _OSI
* TBD additional string adds to _OSI
*/
-static int __init
-acpi_osi_setup(char *str)
+static int __init acpi_osi_setup(char *str)
{
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
- } else
- {
+ } else {
/* TBD */
- printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n", str);
+ printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n",
+ str);
}
return 1;
@@ -1126,8 +1009,7 @@ acpi_osi_setup(char *str)
__setup("acpi_osi=", acpi_osi_setup);
/* enable serialization to combat AE_ALREADY_EXISTS errors */
-static int __init
-acpi_serialize_setup(char *str)
+static int __init acpi_serialize_setup(char *str)
{
printk(KERN_INFO PREFIX "serialize enabled\n");
@@ -1147,8 +1029,7 @@ __setup("acpi_serialize", acpi_serialize_setup);
* Run-time events on the same GPE this flag is available
* to tell Linux to keep the wake-time GPEs enabled at run-time.
*/
-static int __init
-acpi_wake_gpes_always_on_setup(char *str)
+static int __init acpi_wake_gpes_always_on_setup(char *str)
{
printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
@@ -1159,8 +1040,7 @@ acpi_wake_gpes_always_on_setup(char *str)
__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
-int __init
-acpi_hotkey_setup(char *str)
+static int __init acpi_hotkey_setup(char *str)
{
acpi_specific_hotkey_enabled = FALSE;
return 1;
@@ -1174,5 +1054,132 @@ __setup("acpi_generic_hotkey", acpi_hotkey_setup);
*/
unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
-
EXPORT_SYMBOL(max_cstate);
+
+/*
+ * Acquire a spinlock.
+ *
+ * handle is a pointer to the spinlock_t.
+ * flags is *not* the result of save_flags - it is an ACPI-specific flag variable
+ * that indicates whether we are at interrupt level.
+ */
+
+unsigned long acpi_os_acquire_lock(acpi_handle handle)
+{
+ unsigned long flags;
+ spin_lock_irqsave((spinlock_t *) handle, flags);
+ return flags;
+}
+
+/*
+ * Release a spinlock. See above.
+ */
+
+void acpi_os_release_lock(acpi_handle handle, unsigned long flags)
+{
+ spin_unlock_irqrestore((spinlock_t *) handle, flags);
+}
+
+#ifndef ACPI_USE_LOCAL_CACHE
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_create_cache
+ *
+ * PARAMETERS: CacheName - Ascii name for the cache
+ * ObjectSize - Size of each cached object
+ * MaxDepth - Maximum depth of the cache (in objects)
+ * ReturnCache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a cache object
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
+{
+ *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL);
+ return AE_OK;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_purge_cache
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
+{
+ (void)kmem_cache_shrink(cache);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_delete_cache
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache and delete the
+ * cache object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
+{
+ (void)kmem_cache_destroy(cache);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_release_object
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ * Object - The object to be released
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release an object to the specified cache. If cache is full,
+ * the object is deleted.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
+{
+ kmem_cache_free(cache, object);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_acquire_object
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ * ReturnObject - Where the object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an object from the specified cache. If cache is empty,
+ * the object is allocated.
+ *
+ ******************************************************************************/
+
+void *acpi_os_acquire_object(acpi_cache_t * cache)
+{
+ void *object = kmem_cache_alloc(cache, GFP_KERNEL);
+ WARN_ON(!object);
+ return object;
+}
+
+#endif
diff --git a/drivers/acpi/parser/Makefile b/drivers/acpi/parser/Makefile
index bbdd286c660d..db24ee09cf11 100644
--- a/drivers/acpi/parser/Makefile
+++ b/drivers/acpi/parser/Makefile
@@ -2,7 +2,7 @@
# Makefile for all Linux ACPI interpreter subdirectories
#
-obj-y := psargs.o psparse.o pstree.o pswalk.o \
+obj-y := psargs.o psparse.o psloop.o pstree.o pswalk.o \
psopcode.o psscope.o psutils.o psxface.o
EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index b7ac68cc9e1c..5858188f94a6 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -41,25 +41,20 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("psargs")
+ACPI_MODULE_NAME("psargs")
/* Local prototypes */
-
static u32
-acpi_ps_get_next_package_length (
- struct acpi_parse_state *parser_state);
-
-static union acpi_parse_object *
-acpi_ps_get_next_field (
- struct acpi_parse_state *parser_state);
+acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
+static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
+ *parser_state);
/*******************************************************************************
*
@@ -75,49 +70,43 @@ acpi_ps_get_next_field (
******************************************************************************/
static u32
-acpi_ps_get_next_package_length (
- struct acpi_parse_state *parser_state)
+acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
{
- u32 encoded_length;
- u32 length = 0;
+ u32 encoded_length;
+ u32 length = 0;
+ ACPI_FUNCTION_TRACE("ps_get_next_package_length");
- ACPI_FUNCTION_TRACE ("ps_get_next_package_length");
-
-
- encoded_length = (u32) ACPI_GET8 (parser_state->aml);
+ encoded_length = (u32) ACPI_GET8(parser_state->aml);
parser_state->aml++;
- switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */ {
- case 0: /* 1-byte encoding (bits 0-5) */
+ switch (encoded_length >> 6) { /* bits 6-7 contain encoding scheme */
+ case 0: /* 1-byte encoding (bits 0-5) */
length = (encoded_length & 0x3F);
break;
+ case 1: /* 2-byte encoding (next byte + bits 0-3) */
- case 1: /* 2-byte encoding (next byte + bits 0-3) */
-
- length = ((ACPI_GET8 (parser_state->aml) << 04) |
- (encoded_length & 0x0F));
+ length = ((ACPI_GET8(parser_state->aml) << 04) |
+ (encoded_length & 0x0F));
parser_state->aml++;
break;
+ case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
- case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
-
- length = ((ACPI_GET8 (parser_state->aml + 1) << 12) |
- (ACPI_GET8 (parser_state->aml) << 04) |
- (encoded_length & 0x0F));
+ length = ((ACPI_GET8(parser_state->aml + 1) << 12) |
+ (ACPI_GET8(parser_state->aml) << 04) |
+ (encoded_length & 0x0F));
parser_state->aml += 2;
break;
+ case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
- case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
-
- length = ((ACPI_GET8 (parser_state->aml + 2) << 20) |
- (ACPI_GET8 (parser_state->aml + 1) << 12) |
- (ACPI_GET8 (parser_state->aml) << 04) |
- (encoded_length & 0x0F));
+ length = ((ACPI_GET8(parser_state->aml + 2) << 20) |
+ (ACPI_GET8(parser_state->aml + 1) << 12) |
+ (ACPI_GET8(parser_state->aml) << 04) |
+ (encoded_length & 0x0F));
parser_state->aml += 3;
break;
@@ -127,10 +116,9 @@ acpi_ps_get_next_package_length (
break;
}
- return_VALUE (length);
+ return_VALUE(length);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_package_end
@@ -144,25 +132,21 @@ acpi_ps_get_next_package_length (
*
******************************************************************************/
-u8 *
-acpi_ps_get_next_package_end (
- struct acpi_parse_state *parser_state)
+u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
{
- u8 *start = parser_state->aml;
- acpi_native_uint length;
-
-
- ACPI_FUNCTION_TRACE ("ps_get_next_package_end");
+ u8 *start = parser_state->aml;
+ acpi_native_uint length;
+ ACPI_FUNCTION_TRACE("ps_get_next_package_end");
/* Function below changes parser_state->Aml */
- length = (acpi_native_uint) acpi_ps_get_next_package_length (parser_state);
+ length =
+ (acpi_native_uint) acpi_ps_get_next_package_length(parser_state);
- return_PTR (start + length); /* end of package */
+ return_PTR(start + length); /* end of package */
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_namestring
@@ -178,20 +162,16 @@ acpi_ps_get_next_package_end (
*
******************************************************************************/
-char *
-acpi_ps_get_next_namestring (
- struct acpi_parse_state *parser_state)
+char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
{
- u8 *start = parser_state->aml;
- u8 *end = parser_state->aml;
-
-
- ACPI_FUNCTION_TRACE ("ps_get_next_namestring");
+ u8 *start = parser_state->aml;
+ u8 *end = parser_state->aml;
+ ACPI_FUNCTION_TRACE("ps_get_next_namestring");
/* Handle multiple prefix characters */
- while (acpi_ps_is_prefix_char (ACPI_GET8 (end))) {
+ while (acpi_ps_is_prefix_char(ACPI_GET8(end))) {
/* Include prefix '\\' or '^' */
end++;
@@ -199,7 +179,7 @@ acpi_ps_get_next_namestring (
/* Decode the path */
- switch (ACPI_GET8 (end)) {
+ switch (ACPI_GET8(end)) {
case 0:
/* null_name */
@@ -221,7 +201,7 @@ acpi_ps_get_next_namestring (
/* Multiple name segments, 4 chars each */
- end += 2 + ((acpi_size) ACPI_GET8 (end + 1) * ACPI_NAME_SIZE);
+ end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE);
break;
default:
@@ -232,11 +212,10 @@ acpi_ps_get_next_namestring (
break;
}
- parser_state->aml = (u8*) end;
- return_PTR ((char *) start);
+ parser_state->aml = (u8 *) end;
+ return_PTR((char *)start);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_namepath
@@ -259,24 +238,20 @@ acpi_ps_get_next_namestring (
******************************************************************************/
acpi_status
-acpi_ps_get_next_namepath (
- struct acpi_walk_state *walk_state,
- struct acpi_parse_state *parser_state,
- union acpi_parse_object *arg,
- u8 method_call)
+acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
+ struct acpi_parse_state *parser_state,
+ union acpi_parse_object *arg, u8 method_call)
{
- char *path;
- union acpi_parse_object *name_op;
- acpi_status status = AE_OK;
- union acpi_operand_object *method_desc;
- struct acpi_namespace_node *node;
- union acpi_generic_state scope_info;
+ char *path;
+ union acpi_parse_object *name_op;
+ acpi_status status = AE_OK;
+ union acpi_operand_object *method_desc;
+ struct acpi_namespace_node *node;
+ union acpi_generic_state scope_info;
+ ACPI_FUNCTION_TRACE("ps_get_next_namepath");
- ACPI_FUNCTION_TRACE ("ps_get_next_namepath");
-
-
- path = acpi_ps_get_next_namestring (parser_state);
+ path = acpi_ps_get_next_namestring(parser_state);
/* Null path case is allowed */
@@ -296,49 +271,50 @@ acpi_ps_get_next_namepath (
* parent tree, but don't open a new scope -- we just want to lookup the
* object (MUST BE mode EXECUTE to perform upsearch)
*/
- status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY,
- ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
- NULL, &node);
- if (ACPI_SUCCESS (status) && method_call) {
+ status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT |
+ ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
+ if (ACPI_SUCCESS(status) && method_call) {
if (node->type == ACPI_TYPE_METHOD) {
/* This name is actually a control method invocation */
- method_desc = acpi_ns_get_attached_object (node);
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Control Method - %p Desc %p Path=%p\n",
- node, method_desc, path));
+ method_desc = acpi_ns_get_attached_object(node);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Control Method - %p Desc %p Path=%p\n",
+ node, method_desc, path));
- name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
+ name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
if (!name_op) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Change arg into a METHOD CALL and attach name to it */
- acpi_ps_init_op (arg, AML_INT_METHODCALL_OP);
+ acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
name_op->common.value.name = path;
/* Point METHODCALL/NAME to the METHOD Node */
name_op->common.node = node;
- acpi_ps_append_arg (arg, name_op);
+ acpi_ps_append_arg(arg, name_op);
if (!method_desc) {
- ACPI_REPORT_ERROR ((
- "ps_get_next_namepath: Control Method %p has no attached object\n",
- node));
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node));
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Control Method - %p Args %X\n",
- node, method_desc->method.param_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Control Method - %p Args %X\n",
+ node,
+ method_desc->method.
+ param_count));
/* Get the number of arguments to expect */
- walk_state->arg_count = method_desc->method.param_count;
- return_ACPI_STATUS (AE_OK);
+ walk_state->arg_count =
+ method_desc->method.param_count;
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -348,25 +324,26 @@ acpi_ps_get_next_namepath (
*/
}
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
/*
* 1) Any error other than NOT_FOUND is always severe
* 2) NOT_FOUND is only important if we are executing a method.
* 3) If executing a cond_ref_of opcode, NOT_FOUND is ok.
*/
- if ((((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
- (status == AE_NOT_FOUND) &&
- (walk_state->op->common.aml_opcode != AML_COND_REF_OF_OP)) ||
-
- (status != AE_NOT_FOUND)) {
- ACPI_REPORT_NSERROR (path, status);
-
- acpi_os_printf ("search_node %p start_node %p return_node %p\n",
- scope_info.scope.node, parser_state->start_node, node);
-
-
- }
- else {
+ if ((((walk_state->
+ parse_flags & ACPI_PARSE_MODE_MASK) ==
+ ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND)
+ && (walk_state->op->common.aml_opcode !=
+ AML_COND_REF_OF_OP))
+ || (status != AE_NOT_FOUND)) {
+ ACPI_REPORT_NSERROR(path, status);
+
+ acpi_os_printf
+ ("search_node %p start_node %p return_node %p\n",
+ scope_info.scope.node,
+ parser_state->start_node, node);
+
+ } else {
/*
* We got a NOT_FOUND during table load or we encountered
* a cond_ref_of(x) where the target does not exist.
@@ -381,13 +358,12 @@ acpi_ps_get_next_namepath (
* Regardless of success/failure above,
* Just initialize the Op with the pathname.
*/
- acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
+ acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
arg->common.value.name = path;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_simple_arg
@@ -403,87 +379,81 @@ acpi_ps_get_next_namepath (
******************************************************************************/
void
-acpi_ps_get_next_simple_arg (
- struct acpi_parse_state *parser_state,
- u32 arg_type,
- union acpi_parse_object *arg)
+acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
+ u32 arg_type, union acpi_parse_object *arg)
{
- ACPI_FUNCTION_TRACE_U32 ("ps_get_next_simple_arg", arg_type);
-
+ ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type);
switch (arg_type) {
case ARGP_BYTEDATA:
- acpi_ps_init_op (arg, AML_BYTE_OP);
- arg->common.value.integer = (u32) ACPI_GET8 (parser_state->aml);
+ acpi_ps_init_op(arg, AML_BYTE_OP);
+ arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml);
parser_state->aml++;
break;
-
case ARGP_WORDDATA:
- acpi_ps_init_op (arg, AML_WORD_OP);
+ acpi_ps_init_op(arg, AML_WORD_OP);
/* Get 2 bytes from the AML stream */
- ACPI_MOVE_16_TO_32 (&arg->common.value.integer, parser_state->aml);
+ ACPI_MOVE_16_TO_32(&arg->common.value.integer,
+ parser_state->aml);
parser_state->aml += 2;
break;
-
case ARGP_DWORDDATA:
- acpi_ps_init_op (arg, AML_DWORD_OP);
+ acpi_ps_init_op(arg, AML_DWORD_OP);
/* Get 4 bytes from the AML stream */
- ACPI_MOVE_32_TO_32 (&arg->common.value.integer, parser_state->aml);
+ ACPI_MOVE_32_TO_32(&arg->common.value.integer,
+ parser_state->aml);
parser_state->aml += 4;
break;
-
case ARGP_QWORDDATA:
- acpi_ps_init_op (arg, AML_QWORD_OP);
+ acpi_ps_init_op(arg, AML_QWORD_OP);
/* Get 8 bytes from the AML stream */
- ACPI_MOVE_64_TO_64 (&arg->common.value.integer, parser_state->aml);
+ ACPI_MOVE_64_TO_64(&arg->common.value.integer,
+ parser_state->aml);
parser_state->aml += 8;
break;
-
case ARGP_CHARLIST:
- acpi_ps_init_op (arg, AML_STRING_OP);
- arg->common.value.string = (char *) parser_state->aml;
+ acpi_ps_init_op(arg, AML_STRING_OP);
+ arg->common.value.string = (char *)parser_state->aml;
- while (ACPI_GET8 (parser_state->aml) != '\0') {
+ while (ACPI_GET8(parser_state->aml) != '\0') {
parser_state->aml++;
}
parser_state->aml++;
break;
-
case ARGP_NAME:
case ARGP_NAMESTRING:
- acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
- arg->common.value.name = acpi_ps_get_next_namestring (parser_state);
+ acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
+ arg->common.value.name =
+ acpi_ps_get_next_namestring(parser_state);
break;
-
default:
- ACPI_REPORT_ERROR (("Invalid arg_type %X\n", arg_type));
+ ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type));
break;
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_field
@@ -496,24 +466,21 @@ acpi_ps_get_next_simple_arg (
*
******************************************************************************/
-static union acpi_parse_object *
-acpi_ps_get_next_field (
- struct acpi_parse_state *parser_state)
+static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
+ *parser_state)
{
- u32 aml_offset = (u32)
- ACPI_PTR_DIFF (parser_state->aml,
- parser_state->aml_start);
- union acpi_parse_object *field;
- u16 opcode;
- u32 name;
-
-
- ACPI_FUNCTION_TRACE ("ps_get_next_field");
+ u32 aml_offset = (u32)
+ ACPI_PTR_DIFF(parser_state->aml,
+ parser_state->aml_start);
+ union acpi_parse_object *field;
+ u16 opcode;
+ u32 name;
+ ACPI_FUNCTION_TRACE("ps_get_next_field");
/* Determine field type */
- switch (ACPI_GET8 (parser_state->aml)) {
+ switch (ACPI_GET8(parser_state->aml)) {
default:
opcode = AML_INT_NAMEDFIELD_OP;
@@ -534,9 +501,9 @@ acpi_ps_get_next_field (
/* Allocate a new field op */
- field = acpi_ps_alloc_op (opcode);
+ field = acpi_ps_alloc_op(opcode);
if (!field) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
field->common.aml_offset = aml_offset;
@@ -548,33 +515,34 @@ acpi_ps_get_next_field (
/* Get the 4-character name */
- ACPI_MOVE_32_TO_32 (&name, parser_state->aml);
- acpi_ps_set_name (field, name);
+ ACPI_MOVE_32_TO_32(&name, parser_state->aml);
+ acpi_ps_set_name(field, name);
parser_state->aml += ACPI_NAME_SIZE;
/* Get the length which is encoded as a package length */
- field->common.value.size = acpi_ps_get_next_package_length (parser_state);
+ field->common.value.size =
+ acpi_ps_get_next_package_length(parser_state);
break;
-
case AML_INT_RESERVEDFIELD_OP:
/* Get the length which is encoded as a package length */
- field->common.value.size = acpi_ps_get_next_package_length (parser_state);
+ field->common.value.size =
+ acpi_ps_get_next_package_length(parser_state);
break;
-
case AML_INT_ACCESSFIELD_OP:
/*
* Get access_type and access_attrib and merge into the field Op
* access_type is first operand, access_attribute is second
*/
- field->common.value.integer = (ACPI_GET8 (parser_state->aml) << 8);
+ field->common.value.integer =
+ (ACPI_GET8(parser_state->aml) << 8);
parser_state->aml++;
- field->common.value.integer |= ACPI_GET8 (parser_state->aml);
+ field->common.value.integer |= ACPI_GET8(parser_state->aml);
parser_state->aml++;
break;
@@ -584,10 +552,9 @@ acpi_ps_get_next_field (
break;
}
- return_PTR (field);
+ return_PTR(field);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_arg
@@ -605,21 +572,17 @@ acpi_ps_get_next_field (
******************************************************************************/
acpi_status
-acpi_ps_get_next_arg (
- struct acpi_walk_state *walk_state,
- struct acpi_parse_state *parser_state,
- u32 arg_type,
- union acpi_parse_object **return_arg)
+acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
+ struct acpi_parse_state *parser_state,
+ u32 arg_type, union acpi_parse_object **return_arg)
{
- union acpi_parse_object *arg = NULL;
- union acpi_parse_object *prev = NULL;
- union acpi_parse_object *field;
- u32 subop;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_get_next_arg", parser_state);
+ union acpi_parse_object *arg = NULL;
+ union acpi_parse_object *prev = NULL;
+ union acpi_parse_object *field;
+ u32 subop;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ps_get_next_arg", parser_state);
switch (arg_type) {
case ARGP_BYTEDATA:
@@ -631,37 +594,35 @@ acpi_ps_get_next_arg (
/* Constants, strings, and namestrings are all the same size */
- arg = acpi_ps_alloc_op (AML_BYTE_OP);
+ arg = acpi_ps_alloc_op(AML_BYTE_OP);
if (!arg) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- acpi_ps_get_next_simple_arg (parser_state, arg_type, arg);
+ acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
break;
-
case ARGP_PKGLENGTH:
/* Package length, nothing returned */
- parser_state->pkg_end = acpi_ps_get_next_package_end (parser_state);
+ parser_state->pkg_end =
+ acpi_ps_get_next_package_end(parser_state);
break;
-
case ARGP_FIELDLIST:
if (parser_state->aml < parser_state->pkg_end) {
/* Non-empty list */
while (parser_state->aml < parser_state->pkg_end) {
- field = acpi_ps_get_next_field (parser_state);
+ field = acpi_ps_get_next_field(parser_state);
if (!field) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
if (prev) {
prev->common.next = field;
- }
- else {
+ } else {
arg = field;
}
prev = field;
@@ -673,21 +634,21 @@ acpi_ps_get_next_arg (
}
break;
-
case ARGP_BYTELIST:
if (parser_state->aml < parser_state->pkg_end) {
/* Non-empty list */
- arg = acpi_ps_alloc_op (AML_INT_BYTELIST_OP);
+ arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP);
if (!arg) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Fill in bytelist data */
arg->common.value.size = (u32)
- ACPI_PTR_DIFF (parser_state->pkg_end, parser_state->aml);
+ ACPI_PTR_DIFF(parser_state->pkg_end,
+ parser_state->aml);
arg->named.data = parser_state->aml;
/* Skip to End of byte data */
@@ -696,32 +657,31 @@ acpi_ps_get_next_arg (
}
break;
-
case ARGP_TARGET:
case ARGP_SUPERNAME:
case ARGP_SIMPLENAME:
- subop = acpi_ps_peek_opcode (parser_state);
- if (subop == 0 ||
- acpi_ps_is_leading_char (subop) ||
- acpi_ps_is_prefix_char (subop)) {
+ subop = acpi_ps_peek_opcode(parser_state);
+ if (subop == 0 ||
+ acpi_ps_is_leading_char(subop) ||
+ acpi_ps_is_prefix_char(subop)) {
/* null_name or name_string */
- arg = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
+ arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
if (!arg) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- status = acpi_ps_get_next_namepath (walk_state, parser_state, arg, 0);
- }
- else {
+ status =
+ acpi_ps_get_next_namepath(walk_state, parser_state,
+ arg, 0);
+ } else {
/* Single complex argument, nothing returned */
walk_state->arg_count = 1;
}
break;
-
case ARGP_DATAOBJ:
case ARGP_TERMARG:
@@ -730,7 +690,6 @@ acpi_ps_get_next_arg (
walk_state->arg_count = 1;
break;
-
case ARGP_DATAOBJLIST:
case ARGP_TERMLIST:
case ARGP_OBJLIST:
@@ -742,14 +701,13 @@ acpi_ps_get_next_arg (
}
break;
-
default:
- ACPI_REPORT_ERROR (("Invalid arg_type: %X\n", arg_type));
+ ACPI_REPORT_ERROR(("Invalid arg_type: %X\n", arg_type));
status = AE_AML_OPERAND_TYPE;
break;
}
*return_arg = arg;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
new file mode 100644
index 000000000000..088d33999d90
--- /dev/null
+++ b/drivers/acpi/parser/psloop.c
@@ -0,0 +1,874 @@
+/******************************************************************************
+ *
+ * Module Name: psloop - Main AML parse loop
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * Parse the AML and build an operation tree as most interpreters,
+ * like Perl, do. Parsing is done by hand rather than with a YACC
+ * generated parser to tightly constrain stack and dynamic memory
+ * usage. At the same time, parsing is kept flexible and the code
+ * fairly compact by parsing based on a list of AML opcode
+ * templates in aml_op_info[]
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/amlcode.h>
+
+#define _COMPONENT ACPI_PARSER
+ACPI_MODULE_NAME("psloop")
+
+static u32 acpi_gbl_depth = 0;
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ps_parse_loop
+ *
+ * PARAMETERS: walk_state - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
+ * a tree of ops.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
+{
+ acpi_status status = AE_OK;
+ acpi_status status2;
+ union acpi_parse_object *op = NULL; /* current op */
+ union acpi_parse_object *arg = NULL;
+ union acpi_parse_object *pre_op = NULL;
+ struct acpi_parse_state *parser_state;
+ u8 *aml_op_start = NULL;
+
+ ACPI_FUNCTION_TRACE_PTR("ps_parse_loop", walk_state);
+
+ if (walk_state->descending_callback == NULL) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ parser_state = &walk_state->parser_state;
+ walk_state->arg_types = 0;
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
+ if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
+ /* We are restarting a preempted control method */
+
+ if (acpi_ps_has_completed_scope(parser_state)) {
+ /*
+ * We must check if a predicate to an IF or WHILE statement
+ * was just completed
+ */
+ if ((parser_state->scope->parse_scope.op) &&
+ ((parser_state->scope->parse_scope.op->common.
+ aml_opcode == AML_IF_OP)
+ || (parser_state->scope->parse_scope.op->common.
+ aml_opcode == AML_WHILE_OP))
+ && (walk_state->control_state)
+ && (walk_state->control_state->common.state ==
+ ACPI_CONTROL_PREDICATE_EXECUTING)) {
+ /*
+ * A predicate was just completed, get the value of the
+ * predicate and branch based on that value
+ */
+ walk_state->op = NULL;
+ status =
+ acpi_ds_get_predicate_value(walk_state,
+ ACPI_TO_POINTER
+ (TRUE));
+ if (ACPI_FAILURE(status)
+ && ((status & AE_CODE_MASK) !=
+ AE_CODE_CONTROL)) {
+ if (status == AE_AML_NO_RETURN_VALUE) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invoked method did not return a value, %s\n",
+ acpi_format_exception
+ (status)));
+
+ }
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "get_predicate Failed, %s\n",
+ acpi_format_exception
+ (status)));
+ return_ACPI_STATUS(status);
+ }
+
+ status =
+ acpi_ps_next_parse_state(walk_state, op,
+ status);
+ }
+
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Popped scope, Op=%p\n", op));
+ } else if (walk_state->prev_op) {
+ /* We were in the middle of an op */
+
+ op = walk_state->prev_op;
+ walk_state->arg_types = walk_state->prev_arg_types;
+ }
+ }
+#endif
+
+ /* Iterative parsing loop, while there is more AML to process: */
+
+ while ((parser_state->aml < parser_state->aml_end) || (op)) {
+ aml_op_start = parser_state->aml;
+ if (!op) {
+ /* Get the next opcode from the AML stream */
+
+ walk_state->aml_offset =
+ (u32) ACPI_PTR_DIFF(parser_state->aml,
+ parser_state->aml_start);
+ walk_state->opcode = acpi_ps_peek_opcode(parser_state);
+
+ /*
+ * First cut to determine what we have found:
+ * 1) A valid AML opcode
+ * 2) A name string
+ * 3) An unknown/invalid opcode
+ */
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(walk_state->opcode);
+ switch (walk_state->op_info->class) {
+ case AML_CLASS_ASCII:
+ case AML_CLASS_PREFIX:
+ /*
+ * Starts with a valid prefix or ASCII char, this is a name
+ * string. Convert the bare name string to a namepath.
+ */
+ walk_state->opcode = AML_INT_NAMEPATH_OP;
+ walk_state->arg_types = ARGP_NAMESTRING;
+ break;
+
+ case AML_CLASS_UNKNOWN:
+
+ /* The opcode is unrecognized. Just skip unknown opcodes */
+
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
+ walk_state->opcode,
+ parser_state->aml,
+ walk_state->aml_offset));
+
+ ACPI_DUMP_BUFFER(parser_state->aml, 128);
+
+ /* Assume one-byte bad opcode */
+
+ parser_state->aml++;
+ continue;
+
+ default:
+
+ /* Found opcode info, this is a normal opcode */
+
+ parser_state->aml +=
+ acpi_ps_get_opcode_size(walk_state->opcode);
+ walk_state->arg_types =
+ walk_state->op_info->parse_args;
+ break;
+ }
+
+ /* Create Op structure and append to parent's argument list */
+
+ if (walk_state->op_info->flags & AML_NAMED) {
+ /* Allocate a new pre_op if necessary */
+
+ if (!pre_op) {
+ pre_op =
+ acpi_ps_alloc_op(walk_state->
+ opcode);
+ if (!pre_op) {
+ status = AE_NO_MEMORY;
+ goto close_this_op;
+ }
+ }
+
+ pre_op->common.value.arg = NULL;
+ pre_op->common.aml_opcode = walk_state->opcode;
+
+ /*
+ * Get and append arguments until we find the node that contains
+ * the name (the type ARGP_NAME).
+ */
+ while (GET_CURRENT_ARG_TYPE
+ (walk_state->arg_types)
+ &&
+ (GET_CURRENT_ARG_TYPE
+ (walk_state->arg_types) != ARGP_NAME)) {
+ status =
+ acpi_ps_get_next_arg(walk_state,
+ parser_state,
+ GET_CURRENT_ARG_TYPE
+ (walk_state->
+ arg_types),
+ &arg);
+ if (ACPI_FAILURE(status)) {
+ goto close_this_op;
+ }
+
+ acpi_ps_append_arg(pre_op, arg);
+ INCREMENT_ARG_LIST(walk_state->
+ arg_types);
+ }
+
+ /*
+ * Make sure that we found a NAME and didn't run out of
+ * arguments
+ */
+ if (!GET_CURRENT_ARG_TYPE
+ (walk_state->arg_types)) {
+ status = AE_AML_NO_OPERAND;
+ goto close_this_op;
+ }
+
+ /* We know that this arg is a name, move to next arg */
+
+ INCREMENT_ARG_LIST(walk_state->arg_types);
+
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ walk_state->op = NULL;
+
+ status =
+ walk_state->descending_callback(walk_state,
+ &op);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "During name lookup/catalog, %s\n",
+ acpi_format_exception
+ (status)));
+ goto close_this_op;
+ }
+
+ if (!op) {
+ continue;
+ }
+
+ status =
+ acpi_ps_next_parse_state(walk_state, op,
+ status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }
+
+ if (ACPI_FAILURE(status)) {
+ goto close_this_op;
+ }
+
+ acpi_ps_append_arg(op,
+ pre_op->common.value.arg);
+ acpi_gbl_depth++;
+
+ if (op->common.aml_opcode == AML_REGION_OP) {
+ /*
+ * Defer final parsing of an operation_region body,
+ * because we don't have enough info in the first pass
+ * to parse it correctly (i.e., there may be method
+ * calls within the term_arg elements of the body.)
+ *
+ * However, we must continue parsing because
+ * the opregion is not a standalone package --
+ * we don't know where the end is at this point.
+ *
+ * (Length is unknown until parse of the body complete)
+ */
+ op->named.data = aml_op_start;
+ op->named.length = 0;
+ }
+ } else {
+ /* Not a named opcode, just allocate Op and append to parent */
+
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(walk_state->opcode);
+ op = acpi_ps_alloc_op(walk_state->opcode);
+ if (!op) {
+ status = AE_NO_MEMORY;
+ goto close_this_op;
+ }
+
+ if (walk_state->op_info->flags & AML_CREATE) {
+ /*
+ * Backup to beginning of create_xXXfield declaration
+ * body_length is unknown until we parse the body
+ */
+ op->named.data = aml_op_start;
+ op->named.length = 0;
+ }
+
+ acpi_ps_append_arg(acpi_ps_get_parent_scope
+ (parser_state), op);
+
+ if ((walk_state->descending_callback != NULL)) {
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ walk_state->op = op;
+
+ status =
+ walk_state->
+ descending_callback(walk_state,
+ &op);
+ status =
+ acpi_ps_next_parse_state(walk_state,
+ op,
+ status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }
+
+ if (ACPI_FAILURE(status)) {
+ goto close_this_op;
+ }
+ }
+ }
+
+ op->common.aml_offset = walk_state->aml_offset;
+
+ if (walk_state->op_info) {
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
+ (u32) op->common.aml_opcode,
+ walk_state->op_info->name, op,
+ parser_state->aml,
+ op->common.aml_offset));
+ }
+ }
+
+ /*
+ * Start arg_count at zero because we don't know if there are
+ * any args yet
+ */
+ walk_state->arg_count = 0;
+
+ /* Are there any arguments that must be processed? */
+
+ if (walk_state->arg_types) {
+ /* Get arguments */
+
+ switch (op->common.aml_opcode) {
+ case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
+ case AML_WORD_OP: /* AML_WORDDATA_ARG */
+ case AML_DWORD_OP: /* AML_DWORDATA_ARG */
+ case AML_QWORD_OP: /* AML_QWORDATA_ARG */
+ case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
+
+ /* Fill in constant or string argument directly */
+
+ acpi_ps_get_next_simple_arg(parser_state,
+ GET_CURRENT_ARG_TYPE
+ (walk_state->
+ arg_types), op);
+ break;
+
+ case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
+
+ status =
+ acpi_ps_get_next_namepath(walk_state,
+ parser_state, op,
+ 1);
+ if (ACPI_FAILURE(status)) {
+ goto close_this_op;
+ }
+
+ walk_state->arg_types = 0;
+ break;
+
+ default:
+ /*
+ * Op is not a constant or string, append each argument
+ * to the Op
+ */
+ while (GET_CURRENT_ARG_TYPE
+ (walk_state->arg_types)
+ && !walk_state->arg_count) {
+ walk_state->aml_offset = (u32)
+ ACPI_PTR_DIFF(parser_state->aml,
+ parser_state->
+ aml_start);
+
+ status =
+ acpi_ps_get_next_arg(walk_state,
+ parser_state,
+ GET_CURRENT_ARG_TYPE
+ (walk_state->
+ arg_types),
+ &arg);
+ if (ACPI_FAILURE(status)) {
+ goto close_this_op;
+ }
+
+ if (arg) {
+ arg->common.aml_offset =
+ walk_state->aml_offset;
+ acpi_ps_append_arg(op, arg);
+ }
+ INCREMENT_ARG_LIST(walk_state->
+ arg_types);
+ }
+
+ /* Special processing for certain opcodes */
+
+ /* TBD (remove): Temporary mechanism to disable this code if needed */
+
+#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
+
+ if ((walk_state->pass_number <=
+ ACPI_IMODE_LOAD_PASS1)
+ &&
+ ((walk_state->
+ parse_flags & ACPI_PARSE_DISASSEMBLE) ==
+ 0)) {
+ /*
+ * We want to skip If/Else/While constructs during Pass1
+ * because we want to actually conditionally execute the
+ * code during Pass2.
+ *
+ * Except for disassembly, where we always want to
+ * walk the If/Else/While packages
+ */
+ switch (op->common.aml_opcode) {
+ case AML_IF_OP:
+ case AML_ELSE_OP:
+ case AML_WHILE_OP:
+
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Pass1: Skipping an If/Else/While body\n"));
+
+ /* Skip body of if/else/while in pass 1 */
+
+ parser_state->aml =
+ parser_state->pkg_end;
+ walk_state->arg_count = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+#endif
+ switch (op->common.aml_opcode) {
+ case AML_METHOD_OP:
+
+ /*
+ * Skip parsing of control method
+ * because we don't have enough info in the first pass
+ * to parse it correctly.
+ *
+ * Save the length and address of the body
+ */
+ op->named.data = parser_state->aml;
+ op->named.length =
+ (u32) (parser_state->pkg_end -
+ parser_state->aml);
+
+ /* Skip body of method */
+
+ parser_state->aml =
+ parser_state->pkg_end;
+ walk_state->arg_count = 0;
+ break;
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ if ((op->common.parent) &&
+ (op->common.parent->common.
+ aml_opcode == AML_NAME_OP)
+ && (walk_state->pass_number <=
+ ACPI_IMODE_LOAD_PASS2)) {
+ /*
+ * Skip parsing of Buffers and Packages
+ * because we don't have enough info in the first pass
+ * to parse them correctly.
+ */
+ op->named.data = aml_op_start;
+ op->named.length =
+ (u32) (parser_state->
+ pkg_end -
+ aml_op_start);
+
+ /* Skip body */
+
+ parser_state->aml =
+ parser_state->pkg_end;
+ walk_state->arg_count = 0;
+ }
+ break;
+
+ case AML_WHILE_OP:
+
+ if (walk_state->control_state) {
+ walk_state->control_state->
+ control.package_end =
+ parser_state->pkg_end;
+ }
+ break;
+
+ default:
+
+ /* No action for all other opcodes */
+ break;
+ }
+ break;
+ }
+ }
+
+ /* Check for arguments that need to be processed */
+
+ if (walk_state->arg_count) {
+ /*
+ * There are arguments (complex ones), push Op and
+ * prepare for argument
+ */
+ status = acpi_ps_push_scope(parser_state, op,
+ walk_state->arg_types,
+ walk_state->arg_count);
+ if (ACPI_FAILURE(status)) {
+ goto close_this_op;
+ }
+ op = NULL;
+ continue;
+ }
+
+ /*
+ * All arguments have been processed -- Op is complete,
+ * prepare for next
+ */
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(op->common.aml_opcode);
+ if (walk_state->op_info->flags & AML_NAMED) {
+ if (acpi_gbl_depth) {
+ acpi_gbl_depth--;
+ }
+
+ if (op->common.aml_opcode == AML_REGION_OP) {
+ /*
+ * Skip parsing of control method or opregion body,
+ * because we don't have enough info in the first pass
+ * to parse them correctly.
+ *
+ * Completed parsing an op_region declaration, we now
+ * know the length.
+ */
+ op->named.length =
+ (u32) (parser_state->aml - op->named.data);
+ }
+ }
+
+ if (walk_state->op_info->flags & AML_CREATE) {
+ /*
+ * Backup to beginning of create_xXXfield declaration (1 for
+ * Opcode)
+ *
+ * body_length is unknown until we parse the body
+ */
+ op->named.length =
+ (u32) (parser_state->aml - op->named.data);
+ }
+
+ /* This op complete, notify the dispatcher */
+
+ if (walk_state->ascending_callback != NULL) {
+ walk_state->op = op;
+ walk_state->opcode = op->common.aml_opcode;
+
+ status = walk_state->ascending_callback(walk_state);
+ status =
+ acpi_ps_next_parse_state(walk_state, op, status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }
+ }
+
+ close_this_op:
+ /*
+ * Finished one argument of the containing scope
+ */
+ parser_state->scope->parse_scope.arg_count--;
+
+ /* Finished with pre_op */
+
+ if (pre_op) {
+ acpi_ps_free_op(pre_op);
+ pre_op = NULL;
+ }
+
+ /* Close this Op (will result in parse subtree deletion) */
+
+ status2 = acpi_ps_complete_this_op(walk_state, op);
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
+ }
+ op = NULL;
+
+ switch (status) {
+ case AE_OK:
+ break;
+
+ case AE_CTRL_TRANSFER:
+
+ /* We are about to transfer to a called method. */
+
+ walk_state->prev_op = op;
+ walk_state->prev_arg_types = walk_state->arg_types;
+ return_ACPI_STATUS(status);
+
+ case AE_CTRL_END:
+
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+
+ if (op) {
+ walk_state->op = op;
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(op->common.
+ aml_opcode);
+ walk_state->opcode = op->common.aml_opcode;
+
+ status =
+ walk_state->ascending_callback(walk_state);
+ status =
+ acpi_ps_next_parse_state(walk_state, op,
+ status);
+
+ status2 =
+ acpi_ps_complete_this_op(walk_state, op);
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
+ }
+ op = NULL;
+ }
+ status = AE_OK;
+ break;
+
+ case AE_CTRL_BREAK:
+ case AE_CTRL_CONTINUE:
+
+ /* Pop off scopes until we find the While */
+
+ while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+ }
+
+ /* Close this iteration of the While loop */
+
+ walk_state->op = op;
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(op->common.aml_opcode);
+ walk_state->opcode = op->common.aml_opcode;
+
+ status = walk_state->ascending_callback(walk_state);
+ status =
+ acpi_ps_next_parse_state(walk_state, op, status);
+
+ status2 = acpi_ps_complete_this_op(walk_state, op);
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
+ }
+ op = NULL;
+
+ status = AE_OK;
+ break;
+
+ case AE_CTRL_TERMINATE:
+
+ status = AE_OK;
+
+ /* Clean up */
+ do {
+ if (op) {
+ status2 =
+ acpi_ps_complete_this_op(walk_state,
+ op);
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
+ }
+ }
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+
+ } while (op);
+
+ return_ACPI_STATUS(status);
+
+ default: /* All other non-AE_OK status */
+
+ do {
+ if (op) {
+ status2 =
+ acpi_ps_complete_this_op(walk_state,
+ op);
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
+ }
+ }
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+
+ } while (op);
+
+ /*
+ * TBD: Cleanup parse ops on error
+ */
+#if 0
+ if (op == NULL) {
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+ }
+#endif
+ walk_state->prev_op = op;
+ walk_state->prev_arg_types = walk_state->arg_types;
+ return_ACPI_STATUS(status);
+ }
+
+ /* This scope complete? */
+
+ if (acpi_ps_has_completed_scope(parser_state)) {
+ acpi_ps_pop_scope(parser_state, &op,
+ &walk_state->arg_types,
+ &walk_state->arg_count);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Popped scope, Op=%p\n", op));
+ } else {
+ op = NULL;
+ }
+
+ } /* while parser_state->Aml */
+
+ /*
+ * Complete the last Op (if not completed), and clear the scope stack.
+ * It is easily possible to end an AML "package" with an unbounded number
+ * of open scopes (such as when several ASL blocks are closed with
+ * sequential closing braces). We want to terminate each one cleanly.
+ */
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
+ op));
+ do {
+ if (op) {
+ if (walk_state->ascending_callback != NULL) {
+ walk_state->op = op;
+ walk_state->op_info =
+ acpi_ps_get_opcode_info(op->common.
+ aml_opcode);
+ walk_state->opcode = op->common.aml_opcode;
+
+ status =
+ walk_state->ascending_callback(walk_state);
+ status =
+ acpi_ps_next_parse_state(walk_state, op,
+ status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }
+
+ if (status == AE_CTRL_TERMINATE) {
+ status = AE_OK;
+
+ /* Clean up */
+ do {
+ if (op) {
+ status2 =
+ acpi_ps_complete_this_op
+ (walk_state, op);
+ if (ACPI_FAILURE
+ (status2)) {
+ return_ACPI_STATUS
+ (status2);
+ }
+ }
+
+ acpi_ps_pop_scope(parser_state,
+ &op,
+ &walk_state->
+ arg_types,
+ &walk_state->
+ arg_count);
+
+ } while (op);
+
+ return_ACPI_STATUS(status);
+ }
+
+ else if (ACPI_FAILURE(status)) {
+ /* First error is most important */
+
+ (void)
+ acpi_ps_complete_this_op(walk_state,
+ op);
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ status2 = acpi_ps_complete_this_op(walk_state, op);
+ if (ACPI_FAILURE(status2)) {
+ return_ACPI_STATUS(status2);
+ }
+ }
+
+ acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types,
+ &walk_state->arg_count);
+
+ } while (op);
+
+ return_ACPI_STATUS(status);
+}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 5744673568c0..229ae86afe8b 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -41,16 +41,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/acopcode.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("psopcode")
-
+ACPI_MODULE_NAME("psopcode")
/*******************************************************************************
*
@@ -62,7 +59,6 @@
* the operand type.
*
******************************************************************************/
-
/*
* Summary of opcode types/flags
*
@@ -180,156 +176,468 @@
AML_CREATE_QWORD_FIELD_OP
******************************************************************************/
-
-
/*
* Master Opcode information table. A summary of everything we know about each
* opcode, all in one place.
*/
-const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
-{
+const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
/*! [Begin] no source code translation */
/* Index Name Parser Args Interpreter Args ObjectType Class Type Flags */
-/* 00 */ ACPI_OP ("Zero", ARGP_ZERO_OP, ARGI_ZERO_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
-/* 01 */ ACPI_OP ("One", ARGP_ONE_OP, ARGI_ONE_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
-/* 02 */ ACPI_OP ("Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP, ACPI_TYPE_LOCAL_ALIAS, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 03 */ ACPI_OP ("Name", ARGP_NAME_OP, ARGI_NAME_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 04 */ ACPI_OP ("ByteConst", ARGP_BYTE_OP, ARGI_BYTE_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
-/* 05 */ ACPI_OP ("WordConst", ARGP_WORD_OP, ARGI_WORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
-/* 06 */ ACPI_OP ("DwordConst", ARGP_DWORD_OP, ARGI_DWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
-/* 07 */ ACPI_OP ("String", ARGP_STRING_OP, ARGI_STRING_OP, ACPI_TYPE_STRING, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
-/* 08 */ ACPI_OP ("Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_LOCAL_SCOPE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 09 */ ACPI_OP ("Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP, ACPI_TYPE_BUFFER, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
-/* 0A */ ACPI_OP ("Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
-/* 0B */ ACPI_OP ("Method", ARGP_METHOD_OP, ARGI_METHOD_OP, ACPI_TYPE_METHOD, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
-/* 0C */ ACPI_OP ("Local0", ARGP_LOCAL0, ARGI_LOCAL0, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 0D */ ACPI_OP ("Local1", ARGP_LOCAL1, ARGI_LOCAL1, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 0E */ ACPI_OP ("Local2", ARGP_LOCAL2, ARGI_LOCAL2, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 0F */ ACPI_OP ("Local3", ARGP_LOCAL3, ARGI_LOCAL3, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 10 */ ACPI_OP ("Local4", ARGP_LOCAL4, ARGI_LOCAL4, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 11 */ ACPI_OP ("Local5", ARGP_LOCAL5, ARGI_LOCAL5, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 12 */ ACPI_OP ("Local6", ARGP_LOCAL6, ARGI_LOCAL6, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 13 */ ACPI_OP ("Local7", ARGP_LOCAL7, ARGI_LOCAL7, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
-/* 14 */ ACPI_OP ("Arg0", ARGP_ARG0, ARGI_ARG0, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 15 */ ACPI_OP ("Arg1", ARGP_ARG1, ARGI_ARG1, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 16 */ ACPI_OP ("Arg2", ARGP_ARG2, ARGI_ARG2, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 17 */ ACPI_OP ("Arg3", ARGP_ARG3, ARGI_ARG3, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 18 */ ACPI_OP ("Arg4", ARGP_ARG4, ARGI_ARG4, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 19 */ ACPI_OP ("Arg5", ARGP_ARG5, ARGI_ARG5, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 1A */ ACPI_OP ("Arg6", ARGP_ARG6, ARGI_ARG6, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
-/* 1B */ ACPI_OP ("Store", ARGP_STORE_OP, ARGI_STORE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
-/* 1C */ ACPI_OP ("RefOf", ARGP_REF_OF_OP, ARGI_REF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
-/* 1D */ ACPI_OP ("Add", ARGP_ADD_OP, ARGI_ADD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 1E */ ACPI_OP ("Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
-/* 1F */ ACPI_OP ("Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 20 */ ACPI_OP ("Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
-/* 21 */ ACPI_OP ("Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
-/* 22 */ ACPI_OP ("Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 23 */ ACPI_OP ("Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_2T_1R, AML_FLAGS_EXEC_2A_2T_1R | AML_CONSTANT),
-/* 24 */ ACPI_OP ("ShiftLeft", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 25 */ ACPI_OP ("ShiftRight", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 26 */ ACPI_OP ("And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 27 */ ACPI_OP ("NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 28 */ ACPI_OP ("Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 29 */ ACPI_OP ("NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 2A */ ACPI_OP ("XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
-/* 2B */ ACPI_OP ("Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 2C */ ACPI_OP ("FindSetLeftBit", ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 2D */ ACPI_OP ("FindSetRightBit", ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 2E */ ACPI_OP ("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
-/* 2F */ ACPI_OP ("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R),
-/* 30 */ ACPI_OP ("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
-/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R),
-/* 32 */ ACPI_OP ("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
-/* 33 */ ACPI_OP ("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
-/* 34 */ ACPI_OP ("CreateWordField", ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
-/* 35 */ ACPI_OP ("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
-/* 36 */ ACPI_OP ("CreateBitField", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
-/* 37 */ ACPI_OP ("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
-/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
-/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
-/* 3A */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
-/* 3B */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
-/* 3C */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
-/* 3D */ ACPI_OP ("LLess", ARGP_LLESS_OP, ARGI_LLESS_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
-/* 3E */ ACPI_OP ("If", ARGP_IF_OP, ARGI_IF_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
-/* 3F */ ACPI_OP ("Else", ARGP_ELSE_OP, ARGI_ELSE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
-/* 40 */ ACPI_OP ("While", ARGP_WHILE_OP, ARGI_WHILE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
-/* 41 */ ACPI_OP ("Noop", ARGP_NOOP_OP, ARGI_NOOP_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
-/* 42 */ ACPI_OP ("Return", ARGP_RETURN_OP, ARGI_RETURN_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
-/* 43 */ ACPI_OP ("Break", ARGP_BREAK_OP, ARGI_BREAK_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
-/* 44 */ ACPI_OP ("BreakPoint", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
-/* 45 */ ACPI_OP ("Ones", ARGP_ONES_OP, ARGI_ONES_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
+/* 00 */ ACPI_OP("Zero", ARGP_ZERO_OP, ARGI_ZERO_OP, ACPI_TYPE_INTEGER,
+ AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
+/* 01 */ ACPI_OP("One", ARGP_ONE_OP, ARGI_ONE_OP, ACPI_TYPE_INTEGER,
+ AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
+/* 02 */ ACPI_OP("Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP,
+ ACPI_TYPE_LOCAL_ALIAS, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_SIMPLE,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 03 */ ACPI_OP("Name", ARGP_NAME_OP, ARGI_NAME_OP, ACPI_TYPE_ANY,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 04 */ ACPI_OP("ByteConst", ARGP_BYTE_OP, ARGI_BYTE_OP,
+ ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, AML_CONSTANT),
+/* 05 */ ACPI_OP("WordConst", ARGP_WORD_OP, ARGI_WORD_OP,
+ ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, AML_CONSTANT),
+/* 06 */ ACPI_OP("DwordConst", ARGP_DWORD_OP, ARGI_DWORD_OP,
+ ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, AML_CONSTANT),
+/* 07 */ ACPI_OP("String", ARGP_STRING_OP, ARGI_STRING_OP,
+ ACPI_TYPE_STRING, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, AML_CONSTANT),
+/* 08 */ ACPI_OP("Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
+ ACPI_TYPE_LOCAL_SCOPE, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_NO_OBJ,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 09 */ ACPI_OP("Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP,
+ ACPI_TYPE_BUFFER, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_OBJECT,
+ AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
+/* 0A */ ACPI_OP("Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP,
+ ACPI_TYPE_PACKAGE, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_OBJECT,
+ AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
+/* 0B */ ACPI_OP("Method", ARGP_METHOD_OP, ARGI_METHOD_OP,
+ ACPI_TYPE_METHOD, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_COMPLEX,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 0C */ ACPI_OP("Local0", ARGP_LOCAL0, ARGI_LOCAL0,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 0D */ ACPI_OP("Local1", ARGP_LOCAL1, ARGI_LOCAL1,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 0E */ ACPI_OP("Local2", ARGP_LOCAL2, ARGI_LOCAL2,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 0F */ ACPI_OP("Local3", ARGP_LOCAL3, ARGI_LOCAL3,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 10 */ ACPI_OP("Local4", ARGP_LOCAL4, ARGI_LOCAL4,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 11 */ ACPI_OP("Local5", ARGP_LOCAL5, ARGI_LOCAL5,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 12 */ ACPI_OP("Local6", ARGP_LOCAL6, ARGI_LOCAL6,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 13 */ ACPI_OP("Local7", ARGP_LOCAL7, ARGI_LOCAL7,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LOCAL_VARIABLE, 0),
+/* 14 */ ACPI_OP("Arg0", ARGP_ARG0, ARGI_ARG0,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 15 */ ACPI_OP("Arg1", ARGP_ARG1, ARGI_ARG1,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 16 */ ACPI_OP("Arg2", ARGP_ARG2, ARGI_ARG2,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 17 */ ACPI_OP("Arg3", ARGP_ARG3, ARGI_ARG3,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 18 */ ACPI_OP("Arg4", ARGP_ARG4, ARGI_ARG4,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 19 */ ACPI_OP("Arg5", ARGP_ARG5, ARGI_ARG5,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 1A */ ACPI_OP("Arg6", ARGP_ARG6, ARGI_ARG6,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_METHOD_ARGUMENT, 0),
+/* 1B */ ACPI_OP("Store", ARGP_STORE_OP, ARGI_STORE_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R),
+/* 1C */ ACPI_OP("RefOf", ARGP_REF_OF_OP, ARGI_REF_OF_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R,
+ AML_FLAGS_EXEC_1A_0T_1R),
+/* 1D */ ACPI_OP("Add", ARGP_ADD_OP, ARGI_ADD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 1E */ ACPI_OP("Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 1F */ ACPI_OP("Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 20 */ ACPI_OP("Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_1R,
+ AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 21 */ ACPI_OP("Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_1R,
+ AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 22 */ ACPI_OP("Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 23 */ ACPI_OP("Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_2T_1R,
+ AML_FLAGS_EXEC_2A_2T_1R | AML_CONSTANT),
+/* 24 */ ACPI_OP("ShiftLeft", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 25 */ ACPI_OP("ShiftRight", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 26 */ ACPI_OP("And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 27 */ ACPI_OP("NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 28 */ ACPI_OP("Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 29 */ ACPI_OP("NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 2A */ ACPI_OP("XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 2B */ ACPI_OP("Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2C */ ACPI_OP("FindSetLeftBit", ARGP_FIND_SET_LEFT_BIT_OP,
+ ARGI_FIND_SET_LEFT_BIT_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2D */ ACPI_OP("FindSetRightBit", ARGP_FIND_SET_RIGHT_BIT_OP,
+ ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2E */ ACPI_OP("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
+/* 2F */ ACPI_OP("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R),
+/* 30 */ ACPI_OP("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_1R,
+ AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
+/* 31 */ ACPI_OP("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R),
+/* 32 */ ACPI_OP("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R,
+ AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
+/* 33 */ ACPI_OP("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,
+ ARGI_CREATE_DWORD_FIELD_OP,
+ ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
+ AML_DEFER | AML_CREATE),
+/* 34 */ ACPI_OP("CreateWordField", ARGP_CREATE_WORD_FIELD_OP,
+ ARGI_CREATE_WORD_FIELD_OP,
+ ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
+ AML_DEFER | AML_CREATE),
+/* 35 */ ACPI_OP("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP,
+ ARGI_CREATE_BYTE_FIELD_OP,
+ ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
+ AML_DEFER | AML_CREATE),
+/* 36 */ ACPI_OP("CreateBitField", ARGP_CREATE_BIT_FIELD_OP,
+ ARGI_CREATE_BIT_FIELD_OP,
+ ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
+ AML_DEFER | AML_CREATE),
+/* 37 */ ACPI_OP("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_1R,
+ AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
+/* 38 */ ACPI_OP("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC |
+ AML_CONSTANT),
+/* 39 */ ACPI_OP("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC |
+ AML_CONSTANT),
+/* 3A */ ACPI_OP("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R,
+ AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 3B */ ACPI_OP("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_0T_1R,
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3C */ ACPI_OP("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_0T_1R,
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3D */ ACPI_OP("LLess", ARGP_LLESS_OP, ARGI_LLESS_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3E */ ACPI_OP("If", ARGP_IF_OP, ARGI_IF_OP, ACPI_TYPE_ANY,
+ AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 3F */ ACPI_OP("Else", ARGP_ELSE_OP, ARGI_ELSE_OP, ACPI_TYPE_ANY,
+ AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 40 */ ACPI_OP("While", ARGP_WHILE_OP, ARGI_WHILE_OP, ACPI_TYPE_ANY,
+ AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 41 */ ACPI_OP("Noop", ARGP_NOOP_OP, ARGI_NOOP_OP, ACPI_TYPE_ANY,
+ AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 42 */ ACPI_OP("Return", ARGP_RETURN_OP, ARGI_RETURN_OP,
+ ACPI_TYPE_ANY, AML_CLASS_CONTROL,
+ AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 43 */ ACPI_OP("Break", ARGP_BREAK_OP, ARGI_BREAK_OP, ACPI_TYPE_ANY,
+ AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 44 */ ACPI_OP("BreakPoint", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP,
+ ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 45 */ ACPI_OP("Ones", ARGP_ONES_OP, ARGI_ONES_OP, ACPI_TYPE_INTEGER,
+ AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
/* Prefixed opcodes (Two-byte opcodes with a prefix op) */
-/* 46 */ ACPI_OP ("Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP, ACPI_TYPE_MUTEX, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 47 */ ACPI_OP ("Event", ARGP_EVENT_OP, ARGI_EVENT_OP, ACPI_TYPE_EVENT, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ),
-/* 48 */ ACPI_OP ("CondRefOf", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
-/* 49 */ ACPI_OP ("CreateField", ARGP_CREATE_FIELD_OP, ARGI_CREATE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_FIELD | AML_CREATE),
-/* 4A */ ACPI_OP ("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R, AML_FLAGS_EXEC_1A_1T_0R),
-/* 4B */ ACPI_OP ("Stall", ARGP_STALL_OP, ARGI_STALL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
-/* 4C */ ACPI_OP ("Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
-/* 4D */ ACPI_OP ("Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R),
-/* 4E */ ACPI_OP ("Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
-/* 4F */ ACPI_OP ("Wait", ARGP_WAIT_OP, ARGI_WAIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R),
-/* 50 */ ACPI_OP ("Reset", ARGP_RESET_OP, ARGI_RESET_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
-/* 51 */ ACPI_OP ("Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
-/* 52 */ ACPI_OP ("FromBCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 53 */ ACPI_OP ("ToBCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 54 */ ACPI_OP ("Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
-/* 55 */ ACPI_OP ("Revision", ARGP_REVISION_OP, ARGI_REVISION_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0),
-/* 56 */ ACPI_OP ("Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0),
-/* 57 */ ACPI_OP ("Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_0T_0R, AML_FLAGS_EXEC_3A_0T_0R),
-/* 58 */ ACPI_OP ("OperationRegion", ARGP_REGION_OP, ARGI_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
-/* 59 */ ACPI_OP ("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
-/* 5A */ ACPI_OP ("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP, ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 5B */ ACPI_OP ("Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP, ACPI_TYPE_PROCESSOR, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 5C */ ACPI_OP ("PowerResource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP, ACPI_TYPE_POWER, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 5D */ ACPI_OP ("ThermalZone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP, ACPI_TYPE_THERMAL, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 5E */ ACPI_OP ("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
-/* 5F */ ACPI_OP ("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+/* 46 */ ACPI_OP("Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP, ACPI_TYPE_MUTEX,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 47 */ ACPI_OP("Event", ARGP_EVENT_OP, ARGI_EVENT_OP, ACPI_TYPE_EVENT,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE,
+ AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 48 */ ACPI_OP("CondRefOf", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
+/* 49 */ ACPI_OP("CreateField", ARGP_CREATE_FIELD_OP,
+ ARGI_CREATE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD,
+ AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
+ AML_DEFER | AML_FIELD | AML_CREATE),
+/* 4A */ ACPI_OP("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R,
+ AML_FLAGS_EXEC_1A_1T_0R),
+/* 4B */ ACPI_OP("Stall", ARGP_STALL_OP, ARGI_STALL_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R,
+ AML_FLAGS_EXEC_1A_0T_0R),
+/* 4C */ ACPI_OP("Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R,
+ AML_FLAGS_EXEC_1A_0T_0R),
+/* 4D */ ACPI_OP("Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R),
+/* 4E */ ACPI_OP("Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 4F */ ACPI_OP("Wait", ARGP_WAIT_OP, ARGI_WAIT_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
+ AML_FLAGS_EXEC_2A_0T_1R),
+/* 50 */ ACPI_OP("Reset", ARGP_RESET_OP, ARGI_RESET_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R,
+ AML_FLAGS_EXEC_1A_0T_0R),
+/* 51 */ ACPI_OP("Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 52 */ ACPI_OP("FromBCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 53 */ ACPI_OP("ToBCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 54 */ ACPI_OP("Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 55 */ ACPI_OP("Revision", ARGP_REVISION_OP, ARGI_REVISION_OP,
+ ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
+ AML_TYPE_CONSTANT, 0),
+/* 56 */ ACPI_OP("Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_CONSTANT, 0),
+/* 57 */ ACPI_OP("Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_0T_0R,
+ AML_FLAGS_EXEC_3A_0T_0R),
+/* 58 */ ACPI_OP("OperationRegion", ARGP_REGION_OP, ARGI_REGION_OP,
+ ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_COMPLEX,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 59 */ ACPI_OP("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_FIELD),
+/* 5A */ ACPI_OP("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP,
+ ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_NO_OBJ,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 5B */ ACPI_OP("Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP,
+ ACPI_TYPE_PROCESSOR, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_SIMPLE,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 5C */ ACPI_OP("PowerResource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP,
+ ACPI_TYPE_POWER, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_SIMPLE,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 5D */ ACPI_OP("ThermalZone", ARGP_THERMAL_ZONE_OP,
+ ARGI_THERMAL_ZONE_OP, ACPI_TYPE_THERMAL,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 5E */ ACPI_OP("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP,
+ ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_FIELD),
+/* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP,
+ ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_FIELD),
/* Internal opcodes that map to invalid AML opcodes */
-/* 60 */ ACPI_OP ("LNotEqual", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
-/* 61 */ ACPI_OP ("LLessEqual", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
-/* 62 */ ACPI_OP ("LGreaterEqual", ARGP_LGREATEREQUAL_OP, ARGI_LGREATEREQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
-/* 63 */ ACPI_OP ("-NamePath-", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_NSOBJECT | AML_NSNODE ),
-/* 64 */ ACPI_OP ("-MethodCall-", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP, ACPI_TYPE_METHOD, AML_CLASS_METHOD_CALL, AML_TYPE_METHOD_CALL, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE),
-/* 65 */ ACPI_OP ("-ByteList-", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP, ACPI_TYPE_ANY, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0),
-/* 66 */ ACPI_OP ("-ReservedField-", ARGP_RESERVEDFIELD_OP, ARGI_RESERVEDFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
-/* 67 */ ACPI_OP ("-NamedField-", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ),
-/* 68 */ ACPI_OP ("-AccessField-", ARGP_ACCESSFIELD_OP, ARGI_ACCESSFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
-/* 69 */ ACPI_OP ("-StaticString", ARGP_STATICSTRING_OP, ARGI_STATICSTRING_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
-/* 6A */ ACPI_OP ("-Return Value-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_RETURN_VALUE, AML_TYPE_RETURN, AML_HAS_ARGS | AML_HAS_RETVAL),
-/* 6B */ ACPI_OP ("-UNKNOWN_OP-", ARG_NONE, ARG_NONE, ACPI_TYPE_INVALID, AML_CLASS_UNKNOWN, AML_TYPE_BOGUS, AML_HAS_ARGS),
-/* 6C */ ACPI_OP ("-ASCII_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS),
-/* 6D */ ACPI_OP ("-PREFIX_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS),
+/* 60 */ ACPI_OP("LNotEqual", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP,
+ ACPI_TYPE_ANY, AML_CLASS_INTERNAL,
+ AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
+/* 61 */ ACPI_OP("LLessEqual", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP,
+ ACPI_TYPE_ANY, AML_CLASS_INTERNAL,
+ AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
+/* 62 */ ACPI_OP("LGreaterEqual", ARGP_LGREATEREQUAL_OP,
+ ARGI_LGREATEREQUAL_OP, ACPI_TYPE_ANY,
+ AML_CLASS_INTERNAL, AML_TYPE_BOGUS,
+ AML_HAS_ARGS | AML_CONSTANT),
+/* 63 */ ACPI_OP("-NamePath-", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP,
+ ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, AML_NSOBJECT | AML_NSNODE),
+/* 64 */ ACPI_OP("-MethodCall-", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP,
+ ACPI_TYPE_METHOD, AML_CLASS_METHOD_CALL,
+ AML_TYPE_METHOD_CALL,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE),
+/* 65 */ ACPI_OP("-ByteList-", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP,
+ ACPI_TYPE_ANY, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, 0),
+/* 66 */ ACPI_OP("-ReservedField-", ARGP_RESERVEDFIELD_OP,
+ ARGI_RESERVEDFIELD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+/* 67 */ ACPI_OP("-NamedField-", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP,
+ ACPI_TYPE_ANY, AML_CLASS_INTERNAL,
+ AML_TYPE_BOGUS,
+ AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 68 */ ACPI_OP("-AccessField-", ARGP_ACCESSFIELD_OP,
+ ARGI_ACCESSFIELD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+/* 69 */ ACPI_OP("-StaticString", ARGP_STATICSTRING_OP,
+ ARGI_STATICSTRING_OP, ACPI_TYPE_ANY,
+ AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+/* 6A */ ACPI_OP("-Return Value-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY,
+ AML_CLASS_RETURN_VALUE, AML_TYPE_RETURN,
+ AML_HAS_ARGS | AML_HAS_RETVAL),
+/* 6B */ ACPI_OP("-UNKNOWN_OP-", ARG_NONE, ARG_NONE, ACPI_TYPE_INVALID,
+ AML_CLASS_UNKNOWN, AML_TYPE_BOGUS, AML_HAS_ARGS),
+/* 6C */ ACPI_OP("-ASCII_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY,
+ AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS),
+/* 6D */ ACPI_OP("-PREFIX_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY,
+ AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS),
/* ACPI 2.0 opcodes */
-/* 6E */ ACPI_OP ("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
-/* 6F */ ACPI_OP ("Package /*Var*/", ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER),
-/* 70 */ ACPI_OP ("ConcatenateResTemplate", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
-/* 71 */ ACPI_OP ("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
-/* 72 */ ACPI_OP ("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
-/* 73 */ ACPI_OP ("ToBuffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 74 */ ACPI_OP ("ToDecimalString", ARGP_TO_DEC_STR_OP, ARGI_TO_DEC_STR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 75 */ ACPI_OP ("ToHexString", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 76 */ ACPI_OP ("ToInteger", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
-/* 77 */ ACPI_OP ("ToString", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
-/* 78 */ ACPI_OP ("CopyObject", ARGP_COPY_OP, ARGI_COPY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
-/* 79 */ ACPI_OP ("Mid", ARGP_MID_OP, ARGI_MID_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_1T_1R, AML_FLAGS_EXEC_3A_1T_1R | AML_CONSTANT),
-/* 7A */ ACPI_OP ("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
-/* 7B */ ACPI_OP ("LoadTable", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R),
-/* 7C */ ACPI_OP ("DataTableRegion", ARGP_DATA_REGION_OP, ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
-/* 7D */ ACPI_OP ("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE),
+/* 6E */ ACPI_OP("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP,
+ ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
+ AML_TYPE_LITERAL, AML_CONSTANT),
+ /* 6F */ ACPI_OP("Package", /* Var */ ARGP_VAR_PACKAGE_OP,
+ ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE,
+ AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT,
+ AML_HAS_ARGS | AML_DEFER),
+/* 70 */ ACPI_OP("ConcatenateResTemplate", ARGP_CONCAT_RES_OP,
+ ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 71 */ ACPI_OP("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 72 */ ACPI_OP("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,
+ ARGI_CREATE_QWORD_FIELD_OP,
+ ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
+ AML_TYPE_CREATE_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
+ AML_DEFER | AML_CREATE),
+/* 73 */ ACPI_OP("ToBuffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 74 */ ACPI_OP("ToDecimalString", ARGP_TO_DEC_STR_OP,
+ ARGI_TO_DEC_STR_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 75 */ ACPI_OP("ToHexString", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 76 */ ACPI_OP("ToInteger", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_1T_1R,
+ AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 77 */ ACPI_OP("ToString", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_2A_1T_1R,
+ AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 78 */ ACPI_OP("CopyObject", ARGP_COPY_OP, ARGI_COPY_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
+/* 79 */ ACPI_OP("Mid", ARGP_MID_OP, ARGI_MID_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_1T_1R,
+ AML_FLAGS_EXEC_3A_1T_1R | AML_CONSTANT),
+/* 7A */ ACPI_OP("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 7B */ ACPI_OP("LoadTable", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
+ AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R),
+/* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP,
+ ARGI_DATA_REGION_OP, ACPI_TYPE_REGION,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE | AML_NAMED),
+/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
+ ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
+ AML_TYPE_NAMED_NO_OBJ,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE),
/* ACPI 3.0 opcodes */
-/* 7E */ ACPI_OP ("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, AML_FLAGS_EXEC_0A_0T_1R)
+/* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
+ AML_FLAGS_EXEC_0A_0T_1R)
/*! [End] no source code translation !*/
};
@@ -338,73 +646,70 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
* This table is directly indexed by the opcodes, and returns an
* index into the table above
*/
-static const u8 acpi_gbl_short_op_index[256] =
-{
+static const u8 acpi_gbl_short_op_index[256] = {
/* 0 1 2 3 4 5 6 7 */
/* 8 9 A B C D E F */
-/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
-/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
-/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
-/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
-/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
-/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
-/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
-/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
-/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
-/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
-/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
-/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
-/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
-/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
-/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
-/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
-/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
+/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
+/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
+/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
+/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
+/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
+/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
+/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
+/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
+/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
+/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
+/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
+/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
+/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
+/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
};
/*
* This table is indexed by the second opcode of the extended opcode
* pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
*/
-static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] =
-{
+static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
/* 0 1 2 3 4 5 6 7 */
/* 8 9 A B C D E F */
-/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
-/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
-/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
-/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
-/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-/* 0x88 */ 0x7C,
+/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
+/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
+/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+/* 0x88 */ 0x7C,
};
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_opcode_info
@@ -418,48 +723,36 @@ static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] =
*
******************************************************************************/
-const struct acpi_opcode_info *
-acpi_ps_get_opcode_info (
- u16 opcode)
+const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode)
{
- ACPI_FUNCTION_NAME ("ps_get_opcode_info");
-
+ ACPI_FUNCTION_NAME("ps_get_opcode_info");
/*
* Detect normal 8-bit opcode or extended 16-bit opcode
*/
- switch ((u8) (opcode >> 8)) {
- case 0:
-
+ if (!(opcode & 0xFF00)) {
/* Simple (8-bit) opcode: 0-255, can't index beyond table */
- return (&acpi_gbl_aml_op_info [acpi_gbl_short_op_index [(u8) opcode]]);
-
- case AML_EXTOP:
-
- /* Extended (16-bit, prefix+opcode) opcode */
-
- if (((u8) opcode) <= MAX_EXTENDED_OPCODE) {
- return (&acpi_gbl_aml_op_info [acpi_gbl_long_op_index [(u8) opcode]]);
- }
-
- /* Else fall through to error case below */
- /*lint -fallthrough */
+ return (&acpi_gbl_aml_op_info
+ [acpi_gbl_short_op_index[(u8) opcode]]);
+ }
- default:
+ if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
+ (((u8) opcode) <= MAX_EXTENDED_OPCODE)) {
+ /* Valid extended (16-bit) opcode */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown AML opcode [%4.4X]\n", opcode));
- break;
+ return (&acpi_gbl_aml_op_info
+ [acpi_gbl_long_op_index[(u8) opcode]]);
}
+ /* Unknown AML opcode */
- /* Default is "unknown opcode" */
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown AML opcode [%4.4X]\n", opcode));
- return (&acpi_gbl_aml_op_info [_UNK]);
+ return (&acpi_gbl_aml_op_info[_UNK]);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_opcode_name
@@ -473,16 +766,13 @@ acpi_ps_get_opcode_info (
*
******************************************************************************/
-char *
-acpi_ps_get_opcode_name (
- u16 opcode)
+char *acpi_ps_get_opcode_name(u16 opcode)
{
#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
- const struct acpi_opcode_info *op;
+ const struct acpi_opcode_info *op;
-
- op = acpi_ps_get_opcode_info (opcode);
+ op = acpi_ps_get_opcode_info(opcode);
/* Always guaranteed to return a valid pointer */
@@ -493,4 +783,3 @@ acpi_ps_get_opcode_name (
#endif
}
-
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index bbfdc1a58c27..76d4d640d83c 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
/*
* Parse the AML and build an operation tree as most interpreters,
* like Perl, do. Parsing is done by hand rather than with a YACC
@@ -59,28 +58,7 @@
#include <acpi/acinterp.h>
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("psparse")
-
-
-static u32 acpi_gbl_depth = 0;
-
-/* Local prototypes */
-
-static void
-acpi_ps_complete_this_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
-
-static acpi_status
-acpi_ps_next_parse_state (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- acpi_status callback_status);
-
-static acpi_status
-acpi_ps_parse_loop (
- struct acpi_walk_state *walk_state);
-
+ACPI_MODULE_NAME("psparse")
/*******************************************************************************
*
@@ -93,10 +71,7 @@ acpi_ps_parse_loop (
* DESCRIPTION: Get the size of the current opcode.
*
******************************************************************************/
-
-u32
-acpi_ps_get_opcode_size (
- u32 opcode)
+u32 acpi_ps_get_opcode_size(u32 opcode)
{
/* Extended (2-byte) opcode if > 255 */
@@ -110,7 +85,6 @@ acpi_ps_get_opcode_size (
return (1);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_peek_opcode
@@ -123,28 +97,24 @@ acpi_ps_get_opcode_size (
*
******************************************************************************/
-u16
-acpi_ps_peek_opcode (
- struct acpi_parse_state *parser_state)
+u16 acpi_ps_peek_opcode(struct acpi_parse_state * parser_state)
{
- u8 *aml;
- u16 opcode;
-
+ u8 *aml;
+ u16 opcode;
aml = parser_state->aml;
- opcode = (u16) ACPI_GET8 (aml);
+ opcode = (u16) ACPI_GET8(aml);
- if (opcode == AML_EXTOP) {
- /* Extended opcode */
+ if (opcode == AML_EXTENDED_OP_PREFIX) {
+ /* Extended opcode, get the second opcode byte */
aml++;
- opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml));
+ opcode = (u16) ((opcode << 8) | ACPI_GET8(aml));
}
return (opcode);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_complete_this_op
@@ -152,47 +122,54 @@ acpi_ps_peek_opcode (
* PARAMETERS: walk_state - Current State
* Op - Op to complete
*
- * RETURN: None.
+ * RETURN: Status
*
* DESCRIPTION: Perform any cleanup at the completion of an Op.
*
******************************************************************************/
-static void
-acpi_ps_complete_this_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
+acpi_status
+acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
+ union acpi_parse_object * op)
{
- union acpi_parse_object *prev;
- union acpi_parse_object *next;
- const struct acpi_opcode_info *parent_info;
- union acpi_parse_object *replacement_op = NULL;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_complete_this_op", op);
+ union acpi_parse_object *prev;
+ union acpi_parse_object *next;
+ const struct acpi_opcode_info *parent_info;
+ union acpi_parse_object *replacement_op = NULL;
+ ACPI_FUNCTION_TRACE_PTR("ps_complete_this_op", op);
/* Check for null Op, can happen if AML code is corrupt */
if (!op) {
- return_VOID;
+ return_ACPI_STATUS(AE_OK); /* OK for now */
}
/* Delete this op and the subtree below it if asked to */
- if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
- (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
- return_VOID;
+ if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=
+ ACPI_PARSE_DELETE_TREE)
+ || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
+ return_ACPI_STATUS(AE_OK);
}
/* Make sure that we only delete this subtree */
if (op->common.parent) {
+ prev = op->common.parent->common.value.arg;
+ if (!prev) {
+ /* Nothing more to do */
+
+ goto cleanup;
+ }
+
/*
* Check if we need to replace the operator and its subtree
* with a return value op (placeholder op)
*/
- parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
+ parent_info =
+ acpi_ps_get_opcode_info(op->common.parent->common.
+ aml_opcode);
switch (parent_info->class) {
case AML_CLASS_CONTROL:
@@ -204,9 +181,10 @@ acpi_ps_complete_this_op (
* These opcodes contain term_arg operands. The current
* op must be replaced by a placeholder return op
*/
- replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
+ replacement_op =
+ acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
- goto cleanup;
+ goto allocate_error;
}
break;
@@ -216,91 +194,117 @@ acpi_ps_complete_this_op (
* These opcodes contain term_arg operands. The current
* op must be replaced by a placeholder return op
*/
- if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
- (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
- (op->common.parent->common.aml_opcode == AML_BUFFER_OP) ||
- (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
- (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
- replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
+ if ((op->common.parent->common.aml_opcode ==
+ AML_REGION_OP)
+ || (op->common.parent->common.aml_opcode ==
+ AML_DATA_REGION_OP)
+ || (op->common.parent->common.aml_opcode ==
+ AML_BUFFER_OP)
+ || (op->common.parent->common.aml_opcode ==
+ AML_PACKAGE_OP)
+ || (op->common.parent->common.aml_opcode ==
+ AML_VAR_PACKAGE_OP)) {
+ replacement_op =
+ acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
- goto cleanup;
+ goto allocate_error;
}
- }
-
- if ((op->common.parent->common.aml_opcode == AML_NAME_OP) &&
- (walk_state->descending_callback != acpi_ds_exec_begin_op)) {
- if ((op->common.aml_opcode == AML_BUFFER_OP) ||
- (op->common.aml_opcode == AML_PACKAGE_OP) ||
- (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
- replacement_op = acpi_ps_alloc_op (op->common.aml_opcode);
+ } else
+ if ((op->common.parent->common.aml_opcode ==
+ AML_NAME_OP)
+ && (walk_state->pass_number <=
+ ACPI_IMODE_LOAD_PASS2)) {
+ if ((op->common.aml_opcode == AML_BUFFER_OP)
+ || (op->common.aml_opcode == AML_PACKAGE_OP)
+ || (op->common.aml_opcode ==
+ AML_VAR_PACKAGE_OP)) {
+ replacement_op =
+ acpi_ps_alloc_op(op->common.
+ aml_opcode);
if (!replacement_op) {
- goto cleanup;
+ goto allocate_error;
}
- replacement_op->named.data = op->named.data;
- replacement_op->named.length = op->named.length;
+ replacement_op->named.data =
+ op->named.data;
+ replacement_op->named.length =
+ op->named.length;
}
}
break;
default:
- replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
+
+ replacement_op =
+ acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
- goto cleanup;
+ goto allocate_error;
}
}
/* We must unlink this op from the parent tree */
- prev = op->common.parent->common.value.arg;
if (prev == op) {
/* This op is the first in the list */
if (replacement_op) {
- replacement_op->common.parent = op->common.parent;
- replacement_op->common.value.arg = NULL;
- replacement_op->common.node = op->common.node;
- op->common.parent->common.value.arg = replacement_op;
- replacement_op->common.next = op->common.next;
- }
- else {
- op->common.parent->common.value.arg = op->common.next;
+ replacement_op->common.parent =
+ op->common.parent;
+ replacement_op->common.value.arg = NULL;
+ replacement_op->common.node = op->common.node;
+ op->common.parent->common.value.arg =
+ replacement_op;
+ replacement_op->common.next = op->common.next;
+ } else {
+ op->common.parent->common.value.arg =
+ op->common.next;
}
}
/* Search the parent list */
- else while (prev) {
- /* Traverse all siblings in the parent's argument list */
-
- next = prev->common.next;
- if (next == op) {
- if (replacement_op) {
- replacement_op->common.parent = op->common.parent;
- replacement_op->common.value.arg = NULL;
- replacement_op->common.node = op->common.node;
- prev->common.next = replacement_op;
- replacement_op->common.next = op->common.next;
- next = NULL;
- }
- else {
- prev->common.next = op->common.next;
- next = NULL;
+ else
+ while (prev) {
+ /* Traverse all siblings in the parent's argument list */
+
+ next = prev->common.next;
+ if (next == op) {
+ if (replacement_op) {
+ replacement_op->common.parent =
+ op->common.parent;
+ replacement_op->common.value.
+ arg = NULL;
+ replacement_op->common.node =
+ op->common.node;
+ prev->common.next =
+ replacement_op;
+ replacement_op->common.next =
+ op->common.next;
+ next = NULL;
+ } else {
+ prev->common.next =
+ op->common.next;
+ next = NULL;
+ }
}
+ prev = next;
}
- prev = next;
- }
}
-
-cleanup:
+ cleanup:
/* Now we can actually delete the subtree rooted at Op */
- acpi_ps_delete_parse_tree (op);
- return_VOID;
-}
+ acpi_ps_delete_parse_tree(op);
+ return_ACPI_STATUS(AE_OK);
+ allocate_error:
+
+ /* Always delete the subtree, even on error */
+
+ acpi_ps_delete_parse_tree(op);
+ return_ACPI_STATUS(AE_NO_MEMORY);
+}
/*******************************************************************************
*
@@ -317,18 +321,15 @@ cleanup:
*
******************************************************************************/
-static acpi_status
-acpi_ps_next_parse_state (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- acpi_status callback_status)
+acpi_status
+acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ acpi_status callback_status)
{
- struct acpi_parse_state *parser_state = &walk_state->parser_state;
- acpi_status status = AE_CTRL_PENDING;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_next_parse_state", op);
+ struct acpi_parse_state *parser_state = &walk_state->parser_state;
+ acpi_status status = AE_CTRL_PENDING;
+ ACPI_FUNCTION_TRACE_PTR("ps_next_parse_state", op);
switch (callback_status) {
case AE_CTRL_TERMINATE:
@@ -341,7 +342,6 @@ acpi_ps_next_parse_state (
status = AE_CTRL_TERMINATE;
break;
-
case AE_CTRL_BREAK:
parser_state->aml = walk_state->aml_last_while;
@@ -351,7 +351,6 @@ acpi_ps_next_parse_state (
case AE_CTRL_CONTINUE:
-
parser_state->aml = walk_state->aml_last_while;
status = AE_CTRL_CONTINUE;
break;
@@ -375,10 +374,9 @@ acpi_ps_next_parse_state (
* Predicate of an IF was true, and we are at the matching ELSE.
* Just close out this package
*/
- parser_state->aml = acpi_ps_get_next_package_end (parser_state);
+ parser_state->aml = acpi_ps_get_next_package_end(parser_state);
break;
-
case AE_CTRL_FALSE:
/*
@@ -396,7 +394,6 @@ acpi_ps_next_parse_state (
status = AE_CTRL_END;
break;
-
case AE_CTRL_TRANSFER:
/* A method call (invocation) -- transfer control */
@@ -404,14 +401,15 @@ acpi_ps_next_parse_state (
status = AE_CTRL_TRANSFER;
walk_state->prev_op = op;
walk_state->method_call_op = op;
- walk_state->method_call_node = (op->common.value.arg)->common.node;
+ walk_state->method_call_node =
+ (op->common.value.arg)->common.node;
/* Will return value (if any) be used by the caller? */
- walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
+ walk_state->return_used =
+ acpi_ds_is_result_used(op, walk_state);
break;
-
default:
status = callback_status;
@@ -421,667 +419,9 @@ acpi_ps_next_parse_state (
break;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ps_parse_loop
- *
- * PARAMETERS: walk_state - Current state
- *
- * RETURN: Status
- *
- * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
- * a tree of ops.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ps_parse_loop (
- struct acpi_walk_state *walk_state)
-{
- acpi_status status = AE_OK;
- union acpi_parse_object *op = NULL; /* current op */
- union acpi_parse_object *arg = NULL;
- union acpi_parse_object *pre_op = NULL;
- struct acpi_parse_state *parser_state;
- u8 *aml_op_start = NULL;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state);
-
- if (walk_state->descending_callback == NULL) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- parser_state = &walk_state->parser_state;
- walk_state->arg_types = 0;
-
-#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
-
- if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
- /* We are restarting a preempted control method */
-
- if (acpi_ps_has_completed_scope (parser_state)) {
- /*
- * We must check if a predicate to an IF or WHILE statement
- * was just completed
- */
- if ((parser_state->scope->parse_scope.op) &&
- ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) ||
- (parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) &&
- (walk_state->control_state) &&
- (walk_state->control_state->common.state ==
- ACPI_CONTROL_PREDICATE_EXECUTING)) {
- /*
- * A predicate was just completed, get the value of the
- * predicate and branch based on that value
- */
- walk_state->op = NULL;
- status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE));
- if (ACPI_FAILURE (status) &&
- ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
- if (status == AE_AML_NO_RETURN_VALUE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invoked method did not return a value, %s\n",
- acpi_format_exception (status)));
-
- }
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "get_predicate Failed, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
- }
-
- status = acpi_ps_next_parse_state (walk_state, op, status);
- }
-
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
- }
- else if (walk_state->prev_op) {
- /* We were in the middle of an op */
-
- op = walk_state->prev_op;
- walk_state->arg_types = walk_state->prev_arg_types;
- }
- }
-#endif
-
- /* Iterative parsing loop, while there is more AML to process: */
-
- while ((parser_state->aml < parser_state->aml_end) || (op)) {
- aml_op_start = parser_state->aml;
- if (!op) {
- /* Get the next opcode from the AML stream */
-
- walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
- parser_state->aml_start);
- walk_state->opcode = acpi_ps_peek_opcode (parser_state);
-
- /*
- * First cut to determine what we have found:
- * 1) A valid AML opcode
- * 2) A name string
- * 3) An unknown/invalid opcode
- */
- walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
- switch (walk_state->op_info->class) {
- case AML_CLASS_ASCII:
- case AML_CLASS_PREFIX:
- /*
- * Starts with a valid prefix or ASCII char, this is a name
- * string. Convert the bare name string to a namepath.
- */
- walk_state->opcode = AML_INT_NAMEPATH_OP;
- walk_state->arg_types = ARGP_NAMESTRING;
- break;
-
- case AML_CLASS_UNKNOWN:
-
- /* The opcode is unrecognized. Just skip unknown opcodes */
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
- walk_state->opcode, parser_state->aml, walk_state->aml_offset));
-
- ACPI_DUMP_BUFFER (parser_state->aml, 128);
-
- /* Assume one-byte bad opcode */
-
- parser_state->aml++;
- continue;
-
- default:
-
- /* Found opcode info, this is a normal opcode */
-
- parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
- walk_state->arg_types = walk_state->op_info->parse_args;
- break;
- }
-
- /* Create Op structure and append to parent's argument list */
-
- if (walk_state->op_info->flags & AML_NAMED) {
- /* Allocate a new pre_op if necessary */
-
- if (!pre_op) {
- pre_op = acpi_ps_alloc_op (walk_state->opcode);
- if (!pre_op) {
- status = AE_NO_MEMORY;
- goto close_this_op;
- }
- }
-
- pre_op->common.value.arg = NULL;
- pre_op->common.aml_opcode = walk_state->opcode;
-
- /*
- * Get and append arguments until we find the node that contains
- * the name (the type ARGP_NAME).
- */
- while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
- (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) {
- status = acpi_ps_get_next_arg (walk_state, parser_state,
- GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
- if (ACPI_FAILURE (status)) {
- goto close_this_op;
- }
-
- acpi_ps_append_arg (pre_op, arg);
- INCREMENT_ARG_LIST (walk_state->arg_types);
- }
-
- /*
- * Make sure that we found a NAME and didn't run out of
- * arguments
- */
- if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
- status = AE_AML_NO_OPERAND;
- goto close_this_op;
- }
-
- /* We know that this arg is a name, move to next arg */
-
- INCREMENT_ARG_LIST (walk_state->arg_types);
-
- /*
- * Find the object. This will either insert the object into
- * the namespace or simply look it up
- */
- walk_state->op = NULL;
-
- status = walk_state->descending_callback (walk_state, &op);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "During name lookup/catalog, %s\n",
- acpi_format_exception (status)));
- goto close_this_op;
- }
-
- if (!op) {
- continue;
- }
-
- status = acpi_ps_next_parse_state (walk_state, op, status);
- if (status == AE_CTRL_PENDING) {
- status = AE_OK;
- goto close_this_op;
- }
-
- if (ACPI_FAILURE (status)) {
- goto close_this_op;
- }
-
- acpi_ps_append_arg (op, pre_op->common.value.arg);
- acpi_gbl_depth++;
-
- if (op->common.aml_opcode == AML_REGION_OP) {
- /*
- * Defer final parsing of an operation_region body,
- * because we don't have enough info in the first pass
- * to parse it correctly (i.e., there may be method
- * calls within the term_arg elements of the body.)
- *
- * However, we must continue parsing because
- * the opregion is not a standalone package --
- * we don't know where the end is at this point.
- *
- * (Length is unknown until parse of the body complete)
- */
- op->named.data = aml_op_start;
- op->named.length = 0;
- }
- }
- else {
- /* Not a named opcode, just allocate Op and append to parent */
-
- walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
- op = acpi_ps_alloc_op (walk_state->opcode);
- if (!op) {
- status = AE_NO_MEMORY;
- goto close_this_op;
- }
-
- if (walk_state->op_info->flags & AML_CREATE) {
- /*
- * Backup to beginning of create_xXXfield declaration
- * body_length is unknown until we parse the body
- */
- op->named.data = aml_op_start;
- op->named.length = 0;
- }
-
- acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
-
- if ((walk_state->descending_callback != NULL)) {
- /*
- * Find the object. This will either insert the object into
- * the namespace or simply look it up
- */
- walk_state->op = op;
-
- status = walk_state->descending_callback (walk_state, &op);
- status = acpi_ps_next_parse_state (walk_state, op, status);
- if (status == AE_CTRL_PENDING) {
- status = AE_OK;
- goto close_this_op;
- }
-
- if (ACPI_FAILURE (status)) {
- goto close_this_op;
- }
- }
- }
-
- op->common.aml_offset = walk_state->aml_offset;
-
- if (walk_state->op_info) {
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
- (u32) op->common.aml_opcode, walk_state->op_info->name,
- op, parser_state->aml, op->common.aml_offset));
- }
- }
-
-
- /*
- * Start arg_count at zero because we don't know if there are
- * any args yet
- */
- walk_state->arg_count = 0;
-
- /* Are there any arguments that must be processed? */
-
- if (walk_state->arg_types) {
- /* Get arguments */
-
- switch (op->common.aml_opcode) {
- case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
- case AML_WORD_OP: /* AML_WORDDATA_ARG */
- case AML_DWORD_OP: /* AML_DWORDATA_ARG */
- case AML_QWORD_OP: /* AML_QWORDATA_ARG */
- case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
-
- /* Fill in constant or string argument directly */
-
- acpi_ps_get_next_simple_arg (parser_state,
- GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
- break;
-
- case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
-
- status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1);
- if (ACPI_FAILURE (status)) {
- goto close_this_op;
- }
-
- walk_state->arg_types = 0;
- break;
-
- default:
-
- /*
- * Op is not a constant or string, append each argument
- * to the Op
- */
- while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
- !walk_state->arg_count) {
- walk_state->aml_offset = (u32)
- ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
-
- status = acpi_ps_get_next_arg (walk_state, parser_state,
- GET_CURRENT_ARG_TYPE (walk_state->arg_types),
- &arg);
- if (ACPI_FAILURE (status)) {
- goto close_this_op;
- }
-
- if (arg) {
- arg->common.aml_offset = walk_state->aml_offset;
- acpi_ps_append_arg (op, arg);
- }
- INCREMENT_ARG_LIST (walk_state->arg_types);
- }
-
- /* Special processing for certain opcodes */
-
- switch (op->common.aml_opcode) {
- case AML_METHOD_OP:
-
- /*
- * Skip parsing of control method
- * because we don't have enough info in the first pass
- * to parse it correctly.
- *
- * Save the length and address of the body
- */
- op->named.data = parser_state->aml;
- op->named.length = (u32) (parser_state->pkg_end -
- parser_state->aml);
-
- /* Skip body of method */
-
- parser_state->aml = parser_state->pkg_end;
- walk_state->arg_count = 0;
- break;
-
- case AML_BUFFER_OP:
- case AML_PACKAGE_OP:
- case AML_VAR_PACKAGE_OP:
-
- if ((op->common.parent) &&
- (op->common.parent->common.aml_opcode == AML_NAME_OP) &&
- (walk_state->descending_callback != acpi_ds_exec_begin_op)) {
- /*
- * Skip parsing of Buffers and Packages
- * because we don't have enough info in the first pass
- * to parse them correctly.
- */
- op->named.data = aml_op_start;
- op->named.length = (u32) (parser_state->pkg_end -
- aml_op_start);
-
- /* Skip body */
-
- parser_state->aml = parser_state->pkg_end;
- walk_state->arg_count = 0;
- }
- break;
-
- case AML_WHILE_OP:
-
- if (walk_state->control_state) {
- walk_state->control_state->control.package_end =
- parser_state->pkg_end;
- }
- break;
-
- default:
-
- /* No action for all other opcodes */
- break;
- }
- break;
- }
- }
-
- /* Check for arguments that need to be processed */
-
- if (walk_state->arg_count) {
- /*
- * There are arguments (complex ones), push Op and
- * prepare for argument
- */
- status = acpi_ps_push_scope (parser_state, op,
- walk_state->arg_types, walk_state->arg_count);
- if (ACPI_FAILURE (status)) {
- goto close_this_op;
- }
- op = NULL;
- continue;
- }
-
- /*
- * All arguments have been processed -- Op is complete,
- * prepare for next
- */
- walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
- if (walk_state->op_info->flags & AML_NAMED) {
- if (acpi_gbl_depth) {
- acpi_gbl_depth--;
- }
-
- if (op->common.aml_opcode == AML_REGION_OP) {
- /*
- * Skip parsing of control method or opregion body,
- * because we don't have enough info in the first pass
- * to parse them correctly.
- *
- * Completed parsing an op_region declaration, we now
- * know the length.
- */
- op->named.length = (u32) (parser_state->aml - op->named.data);
- }
- }
-
- if (walk_state->op_info->flags & AML_CREATE) {
- /*
- * Backup to beginning of create_xXXfield declaration (1 for
- * Opcode)
- *
- * body_length is unknown until we parse the body
- */
- op->named.length = (u32) (parser_state->aml - op->named.data);
- }
-
- /* This op complete, notify the dispatcher */
-
- if (walk_state->ascending_callback != NULL) {
- walk_state->op = op;
- walk_state->opcode = op->common.aml_opcode;
-
- status = walk_state->ascending_callback (walk_state);
- status = acpi_ps_next_parse_state (walk_state, op, status);
- if (status == AE_CTRL_PENDING) {
- status = AE_OK;
- goto close_this_op;
- }
- }
-
-
-close_this_op:
- /*
- * Finished one argument of the containing scope
- */
- parser_state->scope->parse_scope.arg_count--;
-
- /* Close this Op (will result in parse subtree deletion) */
-
- acpi_ps_complete_this_op (walk_state, op);
- op = NULL;
- if (pre_op) {
- acpi_ps_free_op (pre_op);
- pre_op = NULL;
- }
-
- switch (status) {
- case AE_OK:
- break;
-
-
- case AE_CTRL_TRANSFER:
-
- /* We are about to transfer to a called method. */
-
- walk_state->prev_op = op;
- walk_state->prev_arg_types = walk_state->arg_types;
- return_ACPI_STATUS (status);
-
-
- case AE_CTRL_END:
-
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
-
- if (op) {
- walk_state->op = op;
- walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
- walk_state->opcode = op->common.aml_opcode;
-
- status = walk_state->ascending_callback (walk_state);
- status = acpi_ps_next_parse_state (walk_state, op, status);
-
- acpi_ps_complete_this_op (walk_state, op);
- op = NULL;
- }
- status = AE_OK;
- break;
-
-
- case AE_CTRL_BREAK:
- case AE_CTRL_CONTINUE:
-
- /* Pop off scopes until we find the While */
-
- while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
- }
-
- /* Close this iteration of the While loop */
-
- walk_state->op = op;
- walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
- walk_state->opcode = op->common.aml_opcode;
-
- status = walk_state->ascending_callback (walk_state);
- status = acpi_ps_next_parse_state (walk_state, op, status);
-
- acpi_ps_complete_this_op (walk_state, op);
- op = NULL;
-
- status = AE_OK;
- break;
-
-
- case AE_CTRL_TERMINATE:
-
- status = AE_OK;
-
- /* Clean up */
- do {
- if (op) {
- acpi_ps_complete_this_op (walk_state, op);
- }
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
-
- } while (op);
-
- return_ACPI_STATUS (status);
-
-
- default: /* All other non-AE_OK status */
-
- do {
- if (op) {
- acpi_ps_complete_this_op (walk_state, op);
- }
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
-
- } while (op);
-
-
- /*
- * TBD: Cleanup parse ops on error
- */
-#if 0
- if (op == NULL) {
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
- }
-#endif
- walk_state->prev_op = op;
- walk_state->prev_arg_types = walk_state->arg_types;
- return_ACPI_STATUS (status);
- }
-
- /* This scope complete? */
-
- if (acpi_ps_has_completed_scope (parser_state)) {
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
- }
- else {
- op = NULL;
- }
-
- } /* while parser_state->Aml */
-
-
- /*
- * Complete the last Op (if not completed), and clear the scope stack.
- * It is easily possible to end an AML "package" with an unbounded number
- * of open scopes (such as when several ASL blocks are closed with
- * sequential closing braces). We want to terminate each one cleanly.
- */
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
- do {
- if (op) {
- if (walk_state->ascending_callback != NULL) {
- walk_state->op = op;
- walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
- walk_state->opcode = op->common.aml_opcode;
-
- status = walk_state->ascending_callback (walk_state);
- status = acpi_ps_next_parse_state (walk_state, op, status);
- if (status == AE_CTRL_PENDING) {
- status = AE_OK;
- goto close_this_op;
- }
-
- if (status == AE_CTRL_TERMINATE) {
- status = AE_OK;
-
- /* Clean up */
- do {
- if (op) {
- acpi_ps_complete_this_op (walk_state, op);
- }
-
- acpi_ps_pop_scope (parser_state, &op,
- &walk_state->arg_types, &walk_state->arg_count);
-
- } while (op);
-
- return_ACPI_STATUS (status);
- }
-
- else if (ACPI_FAILURE (status)) {
- acpi_ps_complete_this_op (walk_state, op);
- return_ACPI_STATUS (status);
- }
- }
-
- acpi_ps_complete_this_op (walk_state, op);
- }
-
- acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
- &walk_state->arg_count);
-
- } while (op);
-
- return_ACPI_STATUS (status);
-}
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_parse_aml
@@ -1095,34 +435,29 @@ close_this_op:
*
******************************************************************************/
-acpi_status
-acpi_ps_parse_aml (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
{
- acpi_status status;
- acpi_status terminate_status;
- struct acpi_thread_state *thread;
- struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list;
- struct acpi_walk_state *previous_walk_state;
+ acpi_status status;
+ struct acpi_thread_state *thread;
+ struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list;
+ struct acpi_walk_state *previous_walk_state;
+ ACPI_FUNCTION_TRACE("ps_parse_aml");
- ACPI_FUNCTION_TRACE ("ps_parse_aml");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Entered with walk_state=%p Aml=%p size=%X\n",
- walk_state, walk_state->parser_state.aml,
- walk_state->parser_state.aml_size));
-
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Entered with walk_state=%p Aml=%p size=%X\n",
+ walk_state, walk_state->parser_state.aml,
+ walk_state->parser_state.aml_size));
/* Create and initialize a new thread state */
- thread = acpi_ut_create_thread_state ();
+ thread = acpi_ut_create_thread_state();
if (!thread) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
walk_state->thread = thread;
- acpi_ds_push_walk_state (walk_state, thread);
+ acpi_ds_push_walk_state(walk_state, thread);
/*
* This global allows the AML debugger to get a handle to the currently
@@ -1134,130 +469,136 @@ acpi_ps_parse_aml (
* Execute the walk loop as long as there is a valid Walk State. This
* handles nested control method invocations without recursion.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "State=%p\n", walk_state));
status = AE_OK;
while (walk_state) {
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/*
* The parse_loop executes AML until the method terminates
* or calls another method.
*/
- status = acpi_ps_parse_loop (walk_state);
+ status = acpi_ps_parse_loop(walk_state);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Completed one call to walk loop, %s State=%p\n",
- acpi_format_exception (status), walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Completed one call to walk loop, %s State=%p\n",
+ acpi_format_exception(status), walk_state));
if (status == AE_CTRL_TRANSFER) {
/*
* A method call was detected.
* Transfer control to the called control method
*/
- status = acpi_ds_call_control_method (thread, walk_state, NULL);
+ status =
+ acpi_ds_call_control_method(thread, walk_state,
+ NULL);
/*
* If the transfer to the new method method call worked, a new walk
* state was created -- get it
*/
- walk_state = acpi_ds_get_current_walk_state (thread);
+ walk_state = acpi_ds_get_current_walk_state(thread);
continue;
- }
- else if (status == AE_CTRL_TERMINATE) {
+ } else if (status == AE_CTRL_TERMINATE) {
status = AE_OK;
- }
- else if ((status != AE_OK) && (walk_state->method_desc)) {
- ACPI_REPORT_METHOD_ERROR ("Method execution failed",
- walk_state->method_node, NULL, status);
+ } else if ((status != AE_OK) && (walk_state->method_desc)) {
+ ACPI_REPORT_METHOD_ERROR("Method execution failed",
+ walk_state->method_node, NULL,
+ status);
+
+ /* Ensure proper cleanup */
+
+ walk_state->parse_flags |= ACPI_PARSE_EXECUTE;
/* Check for possible multi-thread reentrancy problem */
if ((status == AE_ALREADY_EXISTS) &&
- (!walk_state->method_desc->method.semaphore)) {
+ (!walk_state->method_desc->method.semaphore)) {
/*
* This method is marked not_serialized, but it tried to create
* a named object, causing the second thread entrance to fail.
* We will workaround this by marking the method permanently
* as Serialized.
*/
- walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;
+ walk_state->method_desc->method.method_flags |=
+ AML_METHOD_SERIALIZED;
walk_state->method_desc->method.concurrency = 1;
}
}
- if (walk_state->method_desc) {
- /* Decrement the thread count on the method parse tree */
-
- if (walk_state->method_desc->method.thread_count) {
- walk_state->method_desc->method.thread_count--;
- }
- }
-
/* We are done with this walk, move on to the parent if any */
- walk_state = acpi_ds_pop_walk_state (thread);
+ walk_state = acpi_ds_pop_walk_state(thread);
/* Reset the current scope to the beginning of scope stack */
- acpi_ds_scope_stack_clear (walk_state);
+ acpi_ds_scope_stack_clear(walk_state);
/*
* If we just returned from the execution of a control method,
* there's lots of cleanup to do
*/
- if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
- terminate_status = acpi_ds_terminate_control_method (walk_state);
- if (ACPI_FAILURE (terminate_status)) {
- ACPI_REPORT_ERROR ((
- "Could not terminate control method properly\n"));
+ if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
+ ACPI_PARSE_EXECUTE) {
+ if (walk_state->method_desc) {
+ /* Decrement the thread count on the method parse tree */
- /* Ignore error and continue */
+ walk_state->method_desc->method.thread_count--;
}
+
+ acpi_ds_terminate_control_method(walk_state);
}
/* Delete this walk state and all linked control states */
- acpi_ps_cleanup_scope (&walk_state->parser_state);
+ acpi_ps_cleanup_scope(&walk_state->parser_state);
previous_walk_state = walk_state;
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "return_value=%p, implicit_value=%p State=%p\n",
- walk_state->return_desc, walk_state->implicit_return_obj, walk_state));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "return_value=%p, implicit_value=%p State=%p\n",
+ walk_state->return_desc,
+ walk_state->implicit_return_obj, walk_state));
/* Check if we have restarted a preempted walk */
- walk_state = acpi_ds_get_current_walk_state (thread);
+ walk_state = acpi_ds_get_current_walk_state(thread);
if (walk_state) {
- if (ACPI_SUCCESS (status)) {
+ if (ACPI_SUCCESS(status)) {
/*
* There is another walk state, restart it.
* If the method return value is not used by the parent,
* The object is deleted
*/
if (!previous_walk_state->return_desc) {
- status = acpi_ds_restart_control_method (walk_state,
- previous_walk_state->implicit_return_obj);
- }
- else {
+ status =
+ acpi_ds_restart_control_method
+ (walk_state,
+ previous_walk_state->
+ implicit_return_obj);
+ } else {
/*
* We have a valid return value, delete any implicit
* return value.
*/
- acpi_ds_clear_implicit_return (previous_walk_state);
+ acpi_ds_clear_implicit_return
+ (previous_walk_state);
- status = acpi_ds_restart_control_method (walk_state,
- previous_walk_state->return_desc);
+ status =
+ acpi_ds_restart_control_method
+ (walk_state,
+ previous_walk_state->return_desc);
}
- if (ACPI_SUCCESS (status)) {
- walk_state->walk_type |= ACPI_WALK_METHOD_RESTART;
+ if (ACPI_SUCCESS(status)) {
+ walk_state->walk_type |=
+ ACPI_WALK_METHOD_RESTART;
}
- }
- else {
+ } else {
/* On error, delete any return object */
- acpi_ut_remove_reference (previous_walk_state->return_desc);
+ acpi_ut_remove_reference(previous_walk_state->
+ return_desc);
}
}
@@ -1268,37 +609,36 @@ acpi_ps_parse_aml (
else if (previous_walk_state->caller_return_desc) {
if (previous_walk_state->implicit_return_obj) {
*(previous_walk_state->caller_return_desc) =
- previous_walk_state->implicit_return_obj;
- }
- else {
- /* NULL if no return value */
+ previous_walk_state->implicit_return_obj;
+ } else {
+ /* NULL if no return value */
*(previous_walk_state->caller_return_desc) =
- previous_walk_state->return_desc;
+ previous_walk_state->return_desc;
}
- }
- else {
+ } else {
if (previous_walk_state->return_desc) {
/* Caller doesn't want it, must delete it */
- acpi_ut_remove_reference (previous_walk_state->return_desc);
+ acpi_ut_remove_reference(previous_walk_state->
+ return_desc);
}
if (previous_walk_state->implicit_return_obj) {
/* Caller doesn't want it, must delete it */
- acpi_ut_remove_reference (previous_walk_state->implicit_return_obj);
+ acpi_ut_remove_reference(previous_walk_state->
+ implicit_return_obj);
}
}
- acpi_ds_delete_walk_state (previous_walk_state);
+ acpi_ds_delete_walk_state(previous_walk_state);
}
/* Normal exit */
- acpi_ex_release_all_mutexes (thread);
- acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread));
+ acpi_ex_release_all_mutexes(thread);
+ acpi_ut_delete_generic_state(ACPI_CAST_PTR
+ (union acpi_generic_state, thread));
acpi_gbl_current_walk_list = prev_walk_list;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
index 8dcd1b1e7131..1c953b6f1af1 100644
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("psscope")
-
+ACPI_MODULE_NAME("psscope")
/*******************************************************************************
*
@@ -60,16 +58,13 @@
* DESCRIPTION: Get parent of current op being parsed
*
******************************************************************************/
-
-union acpi_parse_object *
-acpi_ps_get_parent_scope (
- struct acpi_parse_state *parser_state)
+union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
+ *parser_state)
{
return (parser_state->scope->parse_scope.op);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_has_completed_scope
@@ -84,17 +79,14 @@ acpi_ps_get_parent_scope (
*
******************************************************************************/
-u8
-acpi_ps_has_completed_scope (
- struct acpi_parse_state *parser_state)
+u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)
{
return ((u8)
- ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
- !parser_state->scope->parse_scope.arg_count)));
+ ((parser_state->aml >= parser_state->scope->parse_scope.arg_end
+ || !parser_state->scope->parse_scope.arg_count)));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_init_scope
@@ -109,34 +101,30 @@ acpi_ps_has_completed_scope (
******************************************************************************/
acpi_status
-acpi_ps_init_scope (
- struct acpi_parse_state *parser_state,
- union acpi_parse_object *root_op)
+acpi_ps_init_scope(struct acpi_parse_state * parser_state,
+ union acpi_parse_object * root_op)
{
- union acpi_generic_state *scope;
+ union acpi_generic_state *scope;
+ ACPI_FUNCTION_TRACE_PTR("ps_init_scope", root_op);
- ACPI_FUNCTION_TRACE_PTR ("ps_init_scope", root_op);
-
-
- scope = acpi_ut_create_generic_state ();
+ scope = acpi_ut_create_generic_state();
if (!scope) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- scope->common.data_type = ACPI_DESC_TYPE_STATE_RPSCOPE;
- scope->parse_scope.op = root_op;
+ scope->common.data_type = ACPI_DESC_TYPE_STATE_RPSCOPE;
+ scope->parse_scope.op = root_op;
scope->parse_scope.arg_count = ACPI_VAR_ARGS;
- scope->parse_scope.arg_end = parser_state->aml_end;
- scope->parse_scope.pkg_end = parser_state->aml_end;
+ scope->parse_scope.arg_end = parser_state->aml_end;
+ scope->parse_scope.pkg_end = parser_state->aml_end;
- parser_state->scope = scope;
- parser_state->start_op = root_op;
+ parser_state->scope = scope;
+ parser_state->start_op = root_op;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_push_scope
@@ -153,48 +141,42 @@ acpi_ps_init_scope (
******************************************************************************/
acpi_status
-acpi_ps_push_scope (
- struct acpi_parse_state *parser_state,
- union acpi_parse_object *op,
- u32 remaining_args,
- u32 arg_count)
+acpi_ps_push_scope(struct acpi_parse_state *parser_state,
+ union acpi_parse_object *op,
+ u32 remaining_args, u32 arg_count)
{
- union acpi_generic_state *scope;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_push_scope", op);
+ union acpi_generic_state *scope;
+ ACPI_FUNCTION_TRACE_PTR("ps_push_scope", op);
- scope = acpi_ut_create_generic_state ();
+ scope = acpi_ut_create_generic_state();
if (!scope) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE;
- scope->parse_scope.op = op;
+ scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE;
+ scope->parse_scope.op = op;
scope->parse_scope.arg_list = remaining_args;
scope->parse_scope.arg_count = arg_count;
scope->parse_scope.pkg_end = parser_state->pkg_end;
/* Push onto scope stack */
- acpi_ut_push_generic_state (&parser_state->scope, scope);
+ acpi_ut_push_generic_state(&parser_state->scope, scope);
if (arg_count == ACPI_VAR_ARGS) {
/* Multiple arguments */
scope->parse_scope.arg_end = parser_state->pkg_end;
- }
- else {
+ } else {
/* Single argument */
- scope->parse_scope.arg_end = ACPI_TO_POINTER (ACPI_MAX_PTR);
+ scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_pop_scope
@@ -212,48 +194,41 @@ acpi_ps_push_scope (
******************************************************************************/
void
-acpi_ps_pop_scope (
- struct acpi_parse_state *parser_state,
- union acpi_parse_object **op,
- u32 *arg_list,
- u32 *arg_count)
+acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
+ union acpi_parse_object **op, u32 * arg_list, u32 * arg_count)
{
- union acpi_generic_state *scope = parser_state->scope;
-
-
- ACPI_FUNCTION_TRACE ("ps_pop_scope");
+ union acpi_generic_state *scope = parser_state->scope;
+ ACPI_FUNCTION_TRACE("ps_pop_scope");
/* Only pop the scope if there is in fact a next scope */
if (scope->common.next) {
- scope = acpi_ut_pop_generic_state (&parser_state->scope);
+ scope = acpi_ut_pop_generic_state(&parser_state->scope);
/* return to parsing previous op */
- *op = scope->parse_scope.op;
- *arg_list = scope->parse_scope.arg_list;
- *arg_count = scope->parse_scope.arg_count;
+ *op = scope->parse_scope.op;
+ *arg_list = scope->parse_scope.arg_list;
+ *arg_count = scope->parse_scope.arg_count;
parser_state->pkg_end = scope->parse_scope.pkg_end;
/* All done with this scope state structure */
- acpi_ut_delete_generic_state (scope);
- }
- else {
+ acpi_ut_delete_generic_state(scope);
+ } else {
/* empty parse stack, prepare to fetch next opcode */
- *op = NULL;
+ *op = NULL;
*arg_list = 0;
*arg_count = 0;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Popped Op %p Args %X\n", *op, *arg_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Popped Op %p Args %X\n", *op, *arg_count));
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_cleanup_scope
@@ -267,15 +242,11 @@ acpi_ps_pop_scope (
*
******************************************************************************/
-void
-acpi_ps_cleanup_scope (
- struct acpi_parse_state *parser_state)
+void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state)
{
- union acpi_generic_state *scope;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state);
+ union acpi_generic_state *scope;
+ ACPI_FUNCTION_TRACE_PTR("ps_cleanup_scope", parser_state);
if (!parser_state) {
return_VOID;
@@ -284,10 +255,9 @@ acpi_ps_cleanup_scope (
/* Delete anything on the scope stack */
while (parser_state->scope) {
- scope = acpi_ut_pop_generic_state (&parser_state->scope);
- acpi_ut_delete_generic_state (scope);
+ scope = acpi_ut_pop_generic_state(&parser_state->scope);
+ acpi_ut_delete_generic_state(scope);
}
return_VOID;
}
-
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index d5aafe73fca0..f0e755884eea 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -41,23 +41,18 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("pstree")
+ACPI_MODULE_NAME("pstree")
/* Local prototypes */
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
-union acpi_parse_object *
-acpi_ps_get_child (
- union acpi_parse_object *op);
+union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op);
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_arg
@@ -71,21 +66,16 @@ acpi_ps_get_child (
*
******************************************************************************/
-union acpi_parse_object *
-acpi_ps_get_arg (
- union acpi_parse_object *op,
- u32 argn)
+union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
{
- union acpi_parse_object *arg = NULL;
- const struct acpi_opcode_info *op_info;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_parse_object *arg = NULL;
+ const struct acpi_opcode_info *op_info;
+ ACPI_FUNCTION_ENTRY();
/* Get the info structure for this opcode */
- op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+ op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
if (op_info->class == AML_CLASS_UNKNOWN) {
/* Invalid opcode or ASCII character */
@@ -111,7 +101,6 @@ acpi_ps_get_arg (
return (arg);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_append_arg
@@ -126,16 +115,12 @@ acpi_ps_get_arg (
******************************************************************************/
void
-acpi_ps_append_arg (
- union acpi_parse_object *op,
- union acpi_parse_object *arg)
+acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
{
- union acpi_parse_object *prev_arg;
- const struct acpi_opcode_info *op_info;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_parse_object *prev_arg;
+ const struct acpi_opcode_info *op_info;
+ ACPI_FUNCTION_ENTRY();
if (!op) {
return;
@@ -143,12 +128,11 @@ acpi_ps_append_arg (
/* Get the info structure for this opcode */
- op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+ op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
if (op_info->class == AML_CLASS_UNKNOWN) {
/* Invalid opcode */
- ACPI_REPORT_ERROR (("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n",
- op->common.aml_opcode));
+ ACPI_REPORT_ERROR(("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", op->common.aml_opcode));
return;
}
@@ -170,8 +154,7 @@ acpi_ps_append_arg (
prev_arg = prev_arg->common.next;
}
prev_arg->common.next = arg;
- }
- else {
+ } else {
/* No argument list, this will be the first argument */
op->common.value.arg = arg;
@@ -185,7 +168,6 @@ acpi_ps_append_arg (
}
}
-
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -201,18 +183,14 @@ acpi_ps_append_arg (
*
******************************************************************************/
-union acpi_parse_object *
-acpi_ps_get_depth_next (
- union acpi_parse_object *origin,
- union acpi_parse_object *op)
+union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
+ union acpi_parse_object *op)
{
- union acpi_parse_object *next = NULL;
- union acpi_parse_object *parent;
- union acpi_parse_object *arg;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_parse_object *next = NULL;
+ union acpi_parse_object *parent;
+ union acpi_parse_object *arg;
+ ACPI_FUNCTION_ENTRY();
if (!op) {
return (NULL);
@@ -220,7 +198,7 @@ acpi_ps_get_depth_next (
/* Look for an argument or child */
- next = acpi_ps_get_arg (op, 0);
+ next = acpi_ps_get_arg(op, 0);
if (next) {
return (next);
}
@@ -237,7 +215,7 @@ acpi_ps_get_depth_next (
parent = op->common.parent;
while (parent) {
- arg = acpi_ps_get_arg (parent, 0);
+ arg = acpi_ps_get_arg(parent, 0);
while (arg && (arg != origin) && (arg != op)) {
arg = arg->common.next;
}
@@ -261,7 +239,6 @@ acpi_ps_get_depth_next (
return (next);
}
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
*
@@ -275,15 +252,11 @@ acpi_ps_get_depth_next (
*
******************************************************************************/
-union acpi_parse_object *
-acpi_ps_get_child (
- union acpi_parse_object *op)
+union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
{
- union acpi_parse_object *child = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_parse_object *child = NULL;
+ ACPI_FUNCTION_ENTRY();
switch (op->common.aml_opcode) {
case AML_SCOPE_OP:
@@ -292,10 +265,9 @@ acpi_ps_get_child (
case AML_THERMAL_ZONE_OP:
case AML_INT_METHODCALL_OP:
- child = acpi_ps_get_arg (op, 0);
+ child = acpi_ps_get_arg(op, 0);
break;
-
case AML_BUFFER_OP:
case AML_PACKAGE_OP:
case AML_METHOD_OP:
@@ -303,24 +275,21 @@ acpi_ps_get_child (
case AML_WHILE_OP:
case AML_FIELD_OP:
- child = acpi_ps_get_arg (op, 1);
+ child = acpi_ps_get_arg(op, 1);
break;
-
case AML_POWER_RES_OP:
case AML_INDEX_FIELD_OP:
- child = acpi_ps_get_arg (op, 2);
+ child = acpi_ps_get_arg(op, 2);
break;
-
case AML_PROCESSOR_OP:
case AML_BANK_FIELD_OP:
- child = acpi_ps_get_arg (op, 3);
+ child = acpi_ps_get_arg(op, 3);
break;
-
default:
/* All others have no children */
break;
@@ -330,5 +299,4 @@ acpi_ps_get_child (
}
#endif
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index a10f88715d43..2075efbb4324 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -41,14 +41,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("psutils")
-
+ACPI_MODULE_NAME("psutils")
/*******************************************************************************
*
@@ -61,15 +59,11 @@
* DESCRIPTION: Create a Scope and associated namepath op with the root name
*
******************************************************************************/
-
-union acpi_parse_object *
-acpi_ps_create_scope_op (
- void)
+union acpi_parse_object *acpi_ps_create_scope_op(void)
{
- union acpi_parse_object *scope_op;
+ union acpi_parse_object *scope_op;
-
- scope_op = acpi_ps_alloc_op (AML_SCOPE_OP);
+ scope_op = acpi_ps_alloc_op(AML_SCOPE_OP);
if (!scope_op) {
return (NULL);
}
@@ -78,7 +72,6 @@ acpi_ps_create_scope_op (
return (scope_op);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_init_op
@@ -92,23 +85,19 @@ acpi_ps_create_scope_op (
*
******************************************************************************/
-void
-acpi_ps_init_op (
- union acpi_parse_object *op,
- u16 opcode)
+void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
op->common.data_type = ACPI_DESC_TYPE_PARSER;
op->common.aml_opcode = opcode;
- ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name,
- (acpi_ps_get_opcode_info (opcode))->name,
- sizeof (op->common.aml_op_name)));
+ ACPI_DISASM_ONLY_MEMBERS(ACPI_STRNCPY(op->common.aml_op_name,
+ (acpi_ps_get_opcode_info
+ (opcode))->name,
+ sizeof(op->common.aml_op_name)));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_alloc_op
@@ -123,29 +112,23 @@ acpi_ps_init_op (
*
******************************************************************************/
-union acpi_parse_object*
-acpi_ps_alloc_op (
- u16 opcode)
+union acpi_parse_object *acpi_ps_alloc_op(u16 opcode)
{
- union acpi_parse_object *op;
- const struct acpi_opcode_info *op_info;
- u8 flags = ACPI_PARSEOP_GENERIC;
-
+ union acpi_parse_object *op;
+ const struct acpi_opcode_info *op_info;
+ u8 flags = ACPI_PARSEOP_GENERIC;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
-
- op_info = acpi_ps_get_opcode_info (opcode);
+ op_info = acpi_ps_get_opcode_info(opcode);
/* Determine type of parse_op required */
if (op_info->flags & AML_DEFER) {
flags = ACPI_PARSEOP_DEFERRED;
- }
- else if (op_info->flags & AML_NAMED) {
+ } else if (op_info->flags & AML_NAMED) {
flags = ACPI_PARSEOP_NAMED;
- }
- else if (opcode == AML_INT_BYTELIST_OP) {
+ } else if (opcode == AML_INT_BYTELIST_OP) {
flags = ACPI_PARSEOP_BYTELIST;
}
@@ -154,25 +137,25 @@ acpi_ps_alloc_op (
if (flags == ACPI_PARSEOP_GENERIC) {
/* The generic op (default) is by far the most common (16 to 1) */
- op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE);
- }
- else {
+ op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
+ memset(op, 0, sizeof(struct acpi_parse_obj_common));
+ } else {
/* Extended parseop */
- op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT);
+ op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
+ memset(op, 0, sizeof(struct acpi_parse_obj_named));
}
/* Initialize the Op */
if (op) {
- acpi_ps_init_op (op, opcode);
+ acpi_ps_init_op(op, opcode);
op->common.flags = flags;
}
return (op);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_free_op
@@ -186,53 +169,22 @@ acpi_ps_alloc_op (
*
******************************************************************************/
-void
-acpi_ps_free_op (
- union acpi_parse_object *op)
+void acpi_ps_free_op(union acpi_parse_object *op)
{
- ACPI_FUNCTION_NAME ("ps_free_op");
-
+ ACPI_FUNCTION_NAME("ps_free_op");
if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", op));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n",
+ op));
}
if (op->common.flags & ACPI_PARSEOP_GENERIC) {
- acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op);
- }
- else {
- acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op);
+ (void)acpi_os_release_object(acpi_gbl_ps_node_cache, op);
+ } else {
+ (void)acpi_os_release_object(acpi_gbl_ps_node_ext_cache, op);
}
}
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-/*******************************************************************************
- *
- * FUNCTION: acpi_ps_delete_parse_cache
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Free all objects that are on the parse cache list.
- *
- ******************************************************************************/
-
-void
-acpi_ps_delete_parse_cache (
- void)
-{
- ACPI_FUNCTION_TRACE ("ps_delete_parse_cache");
-
-
- acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE);
- acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE_EXT);
- return_VOID;
-}
-#endif
-
-
/*******************************************************************************
*
* FUNCTION: Utility functions
@@ -241,36 +193,27 @@ acpi_ps_delete_parse_cache (
*
******************************************************************************/
-
/*
* Is "c" a namestring lead character?
*/
-u8
-acpi_ps_is_leading_char (
- u32 c)
+u8 acpi_ps_is_leading_char(u32 c)
{
return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
}
-
/*
* Is "c" a namestring prefix character?
*/
-u8
-acpi_ps_is_prefix_char (
- u32 c)
+u8 acpi_ps_is_prefix_char(u32 c)
{
return ((u8) (c == '\\' || c == '^'));
}
-
/*
* Get op's name (4-byte name segment) or 0 if unnamed
*/
#ifdef ACPI_FUTURE_USAGE
-u32
-acpi_ps_get_name (
- union acpi_parse_object *op)
+u32 acpi_ps_get_name(union acpi_parse_object * op)
{
/* The "generic" object has no name associated with it */
@@ -283,16 +226,12 @@ acpi_ps_get_name (
return (op->named.name);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*
* Set op's name
*/
-void
-acpi_ps_set_name (
- union acpi_parse_object *op,
- u32 name)
+void acpi_ps_set_name(union acpi_parse_object *op, u32 name)
{
/* The "generic" object has no name associated with it */
@@ -303,4 +242,3 @@ acpi_ps_set_name (
op->named.name = name;
}
-
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index 9d20cb2ceb51..08f2321b6ded 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("pswalk")
-
+ACPI_MODULE_NAME("pswalk")
/*******************************************************************************
*
@@ -60,18 +58,13 @@
* DESCRIPTION: Delete a portion of or an entire parse tree.
*
******************************************************************************/
-
-void
-acpi_ps_delete_parse_tree (
- union acpi_parse_object *subtree_root)
+void acpi_ps_delete_parse_tree(union acpi_parse_object *subtree_root)
{
- union acpi_parse_object *op = subtree_root;
- union acpi_parse_object *next = NULL;
- union acpi_parse_object *parent = NULL;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
+ union acpi_parse_object *op = subtree_root;
+ union acpi_parse_object *next = NULL;
+ union acpi_parse_object *parent = NULL;
+ ACPI_FUNCTION_TRACE_PTR("ps_delete_parse_tree", subtree_root);
/* Visit all nodes in the subtree */
@@ -81,7 +74,7 @@ acpi_ps_delete_parse_tree (
if (op != parent) {
/* Look for an argument or child of the current op */
- next = acpi_ps_get_arg (op, 0);
+ next = acpi_ps_get_arg(op, 0);
if (next) {
/* Still going downward in tree (Op is not completed yet) */
@@ -95,7 +88,7 @@ acpi_ps_delete_parse_tree (
next = op->common.next;
parent = op->common.parent;
- acpi_ps_free_op (op);
+ acpi_ps_free_op(op);
/* If we are back to the starting point, the walk is complete. */
@@ -104,8 +97,7 @@ acpi_ps_delete_parse_tree (
}
if (next) {
op = next;
- }
- else {
+ } else {
op = parent;
}
}
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index dba893648e84..4dcbd443160e 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -41,24 +41,27 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
-#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_PARSER
- ACPI_MODULE_NAME ("psxface")
+ACPI_MODULE_NAME("psxface")
+
+/* Local Prototypes */
+static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info);
+static void
+acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action);
/*******************************************************************************
*
- * FUNCTION: acpi_psx_execute
+ * FUNCTION: acpi_ps_execute_method
*
* PARAMETERS: Info - Method info block, contains:
* Node - Method Node to execute
+ * obj_desc - Method object
* Parameters - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
@@ -67,6 +70,7 @@
* parameter_type - Type of Parameter list
* return_object - Where to put method's return value (if
* any). If NULL, no value is returned.
+ * pass_number - Parse or execute pass
*
* RETURN: Status
*
@@ -74,173 +78,170 @@
*
******************************************************************************/
-acpi_status
-acpi_psx_execute (
- struct acpi_parameter_info *info)
+acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
{
- acpi_status status;
- union acpi_operand_object *obj_desc;
- u32 i;
- union acpi_parse_object *op;
- struct acpi_walk_state *walk_state;
-
-
- ACPI_FUNCTION_TRACE ("psx_execute");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ps_execute_method");
- /* Validate the Node and get the attached object */
+ /* Validate the Info and method Node */
if (!info || !info->node) {
- return_ACPI_STATUS (AE_NULL_ENTRY);
- }
-
- obj_desc = acpi_ns_get_attached_object (info->node);
- if (!obj_desc) {
- return_ACPI_STATUS (AE_NULL_OBJECT);
+ return_ACPI_STATUS(AE_NULL_ENTRY);
}
/* Init for new method, wait on concurrency semaphore */
- status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- if ((info->parameter_type == ACPI_PARAM_ARGS) &&
- (info->parameters)) {
- /*
- * The caller "owns" the parameters, so give each one an extra
- * reference
- */
- for (i = 0; info->parameters[i]; i++) {
- acpi_ut_add_reference (info->parameters[i]);
- }
- }
+ /*
+ * The caller "owns" the parameters, so give each one an extra
+ * reference
+ */
+ acpi_ps_update_parameter_list(info, REF_INCREMENT);
/*
* 1) Perform the first pass parse of the method to enter any
- * named objects that it creates into the namespace
+ * named objects that it creates into the namespace
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "**** Begin Method Parse **** Entry=%p obj=%p\n",
- info->node, obj_desc));
-
- /* Create and init a Root Node */
-
- op = acpi_ps_create_scope_op ();
- if (!op) {
- status = AE_NO_MEMORY;
- goto cleanup1;
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "**** Begin Method Parse **** Entry=%p obj=%p\n",
+ info->node, info->obj_desc));
+
+ info->pass_number = 1;
+ status = acpi_ps_execute_pass(info);
+ if (ACPI_FAILURE(status)) {
+ goto cleanup;
}
/*
- * Get a new owner_id for objects created by this method. Namespace
- * objects (such as Operation Regions) can be created during the
- * first pass parse.
+ * 2) Execute the method. Performs second pass parse simultaneously
*/
- obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "**** Begin Method Execution **** Entry=%p obj=%p\n",
+ info->node, info->obj_desc));
- /* Create and initialize a new walk state */
+ info->pass_number = 3;
+ status = acpi_ps_execute_pass(info);
- walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
- NULL, NULL, NULL);
- if (!walk_state) {
- status = AE_NO_MEMORY;
- goto cleanup2;
- }
+ cleanup:
+ /* Take away the extra reference that we gave the parameters above */
- status = acpi_ds_init_aml_walk (walk_state, op, info->node,
- obj_desc->method.aml_start,
- obj_desc->method.aml_length, NULL, 1);
- if (ACPI_FAILURE (status)) {
- goto cleanup3;
- }
+ acpi_ps_update_parameter_list(info, REF_DECREMENT);
- /* Parse the AML */
+ /* Exit now if error above */
- status = acpi_ps_parse_aml (walk_state);
- acpi_ps_delete_parse_tree (op);
- if (ACPI_FAILURE (status)) {
- goto cleanup1; /* Walk state is already deleted */
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
- * 2) Execute the method. Performs second pass parse simultaneously
+ * If the method has returned an object, signal this to the caller with
+ * a control exception code
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "**** Begin Method Execution **** Entry=%p obj=%p\n",
- info->node, obj_desc));
-
- /* Create and init a Root Node */
+ if (info->return_object) {
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+ "Method returned obj_desc=%p\n",
+ info->return_object));
+ ACPI_DUMP_STACK_ENTRY(info->return_object);
- op = acpi_ps_create_scope_op ();
- if (!op) {
- status = AE_NO_MEMORY;
- goto cleanup1;
+ status = AE_CTRL_RETURN_VALUE;
}
- /* Init new op with the method name and pointer back to the NS node */
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ps_update_parameter_list
+ *
+ * PARAMETERS: Info - See struct acpi_parameter_info
+ * (Used: parameter_type and Parameters)
+ * Action - Add or Remove reference
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Update reference count on all method parameter objects
+ *
+ ******************************************************************************/
- acpi_ps_set_name (op, info->node->name.integer);
- op->common.node = info->node;
+static void
+acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action)
+{
+ acpi_native_uint i;
- /* Create and initialize a new walk state */
+ if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) {
+ /* Update reference count for each parameter */
- walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
- if (!walk_state) {
- status = AE_NO_MEMORY;
- goto cleanup2;
- }
+ for (i = 0; info->parameters[i]; i++) {
+ /* Ignore errors, just do them all */
- status = acpi_ds_init_aml_walk (walk_state, op, info->node,
- obj_desc->method.aml_start,
- obj_desc->method.aml_length, info, 3);
- if (ACPI_FAILURE (status)) {
- goto cleanup3;
+ (void)acpi_ut_update_object_reference(info->
+ parameters[i],
+ action);
+ }
}
+}
- /* The walk of the parse tree is where we actually execute the method */
-
- status = acpi_ps_parse_aml (walk_state);
- goto cleanup2; /* Walk state already deleted */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ps_execute_pass
+ *
+ * PARAMETERS: Info - See struct acpi_parameter_info
+ * (Used: pass_number, Node, and obj_desc)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Single AML pass: Parse or Execute a control method
+ *
+ ******************************************************************************/
+static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info)
+{
+ acpi_status status;
+ union acpi_parse_object *op;
+ struct acpi_walk_state *walk_state;
-cleanup3:
- acpi_ds_delete_walk_state (walk_state);
+ ACPI_FUNCTION_TRACE("ps_execute_pass");
-cleanup2:
- acpi_ps_delete_parse_tree (op);
+ /* Create and init a Root Node */
-cleanup1:
- if ((info->parameter_type == ACPI_PARAM_ARGS) &&
- (info->parameters)) {
- /* Take away the extra reference that we gave the parameters above */
+ op = acpi_ps_create_scope_op();
+ if (!op) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
- for (i = 0; info->parameters[i]; i++) {
- /* Ignore errors, just do them all */
+ /* Create and initialize a new walk state */
- (void) acpi_ut_update_object_reference (
- info->parameters[i], REF_DECREMENT);
- }
+ walk_state =
+ acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
+ NULL, NULL);
+ if (!walk_state) {
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ds_init_aml_walk(walk_state, op, info->node,
+ info->obj_desc->method.aml_start,
+ info->obj_desc->method.aml_length,
+ info->pass_number == 1 ? NULL : info,
+ info->pass_number);
+ if (ACPI_FAILURE(status)) {
+ acpi_ds_delete_walk_state(walk_state);
+ goto cleanup;
}
- /*
- * If the method has returned an object, signal this to the caller with
- * a control exception code
- */
- if (info->return_object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n",
- info->return_object));
- ACPI_DUMP_STACK_ENTRY (info->return_object);
-
- status = AE_CTRL_RETURN_VALUE;
- }
+ /* Parse the AML */
- return_ACPI_STATUS (status);
-}
+ status = acpi_ps_parse_aml(walk_state);
+ /* Walk state was deleted by parse_aml */
+ cleanup:
+ acpi_ps_delete_parse_tree(op);
+ return_ACPI_STATUS(status);
+}
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 5148f3c10b5c..2a718df769b5 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -35,22 +35,17 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME ("pci_bind")
+ACPI_MODULE_NAME("pci_bind")
struct acpi_pci_data {
- struct acpi_pci_id id;
- struct pci_bus *bus;
- struct pci_dev *dev;
+ struct acpi_pci_id id;
+ struct pci_bus *bus;
+ struct pci_dev *dev;
};
-
-void
-acpi_pci_data_handler (
- acpi_handle handle,
- u32 function,
- void *context)
+static void acpi_pci_data_handler(acpi_handle handle, u32 function,
+ void *context)
{
ACPI_FUNCTION_TRACE("acpi_pci_data_handler");
@@ -59,7 +54,6 @@ acpi_pci_data_handler (
return_VOID;
}
-
/**
* acpi_get_pci_id
* ------------------
@@ -67,15 +61,12 @@ acpi_pci_data_handler (
* to resolve PCI information for ACPI-PCI devices defined in the namespace.
* This typically occurs when resolving PCI operation region information.
*/
-acpi_status
-acpi_get_pci_id (
- acpi_handle handle,
- struct acpi_pci_id *id)
+acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_device *device = NULL;
- struct acpi_pci_data *data = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_device *device = NULL;
+ struct acpi_pci_data *data = NULL;
ACPI_FUNCTION_TRACE("acpi_get_pci_id");
@@ -84,52 +75,50 @@ acpi_get_pci_id (
result = acpi_bus_get_device(handle, &device);
if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Invalid ACPI Bus context for device %s\n",
- acpi_device_bid(device)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid ACPI Bus context for device %s\n",
+ acpi_device_bid(device)));
return_ACPI_STATUS(AE_NOT_EXIST);
}
- status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
+ status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data);
if (ACPI_FAILURE(status) || !data) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Invalid ACPI-PCI context for device %s\n",
- acpi_device_bid(device)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid ACPI-PCI context for device %s\n",
+ acpi_device_bid(device)));
return_ACPI_STATUS(status);
}
*id = data->id;
-
+
/*
- id->segment = data->id.segment;
- id->bus = data->id.bus;
- id->device = data->id.device;
- id->function = data->id.function;
- */
+ id->segment = data->id.segment;
+ id->bus = data->id.bus;
+ id->device = data->id.device;
+ id->function = data->id.function;
+ */
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Device %s has PCI address %02x:%02x:%02x.%02x\n",
- acpi_device_bid(device), id->segment, id->bus,
- id->device, id->function));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Device %s has PCI address %02x:%02x:%02x.%02x\n",
+ acpi_device_bid(device), id->segment, id->bus,
+ id->device, id->function));
return_ACPI_STATUS(AE_OK);
}
+
EXPORT_SYMBOL(acpi_get_pci_id);
-
-int
-acpi_pci_bind (
- struct acpi_device *device)
+int acpi_pci_bind(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_pci_data *data = NULL;
- struct acpi_pci_data *pdata = NULL;
- char *pathname = NULL;
- struct acpi_buffer buffer = {0, NULL};
- acpi_handle handle = NULL;
- struct pci_dev *dev;
- struct pci_bus *bus;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_pci_data *data = NULL;
+ struct acpi_pci_data *pdata = NULL;
+ char *pathname = NULL;
+ struct acpi_buffer buffer = { 0, NULL };
+ acpi_handle handle = NULL;
+ struct pci_dev *dev;
+ struct pci_bus *bus;
ACPI_FUNCTION_TRACE("acpi_pci_bind");
@@ -137,34 +126,34 @@ acpi_pci_bind (
return_VALUE(-EINVAL);
pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
- if(!pathname)
+ if (!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = ACPI_PATHNAME_MAX;
buffer.pointer = pathname;
data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
- if (!data){
- kfree (pathname);
+ if (!data) {
+ kfree(pathname);
return_VALUE(-ENOMEM);
}
memset(data, 0, sizeof(struct acpi_pci_data));
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
- pathname));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
+ pathname));
/*
* Segment & Bus
* -------------
* These are obtained via the parent device's ACPI-PCI context.
*/
- status = acpi_get_data(device->parent->handle, acpi_pci_data_handler,
- (void**) &pdata);
+ status = acpi_get_data(device->parent->handle, acpi_pci_data_handler,
+ (void **)&pdata);
if (ACPI_FAILURE(status) || !pdata || !pdata->bus) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Invalid ACPI-PCI context for parent device %s\n",
- acpi_device_bid(device->parent)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid ACPI-PCI context for parent device %s\n",
+ acpi_device_bid(device->parent)));
result = -ENODEV;
goto end;
}
@@ -181,8 +170,8 @@ acpi_pci_bind (
data->id.function = device->pnp.bus_address & 0xFFFF;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
- data->id.segment, data->id.bus, data->id.device,
- data->id.function));
+ data->id.segment, data->id.bus, data->id.device,
+ data->id.function));
/*
* TBD: Support slot devices (e.g. function=0xFFFF).
@@ -202,25 +191,25 @@ acpi_pci_bind (
if (bus) {
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->devfn == PCI_DEVFN(data->id.device,
- data->id.function)) {
+ data->id.function)) {
data->dev = dev;
break;
}
}
}
if (!data->dev) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
- data->id.segment, data->id.bus,
- data->id.device, data->id.function));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
+ data->id.segment, data->id.bus,
+ data->id.device, data->id.function));
result = -ENODEV;
goto end;
}
if (!data->dev->bus) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
- data->id.segment, data->id.bus,
- data->id.device, data->id.function));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
+ data->id.segment, data->id.bus,
+ data->id.device, data->id.function));
result = -ENODEV;
goto end;
}
@@ -232,10 +221,10 @@ acpi_pci_bind (
* facilitate callbacks for all of its children.
*/
if (data->dev->subordinate) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
- data->id.segment, data->id.bus,
- data->id.device, data->id.function));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
+ data->id.segment, data->id.bus,
+ data->id.device, data->id.function));
data->bus = data->dev->subordinate;
device->ops.bind = acpi_pci_bind;
device->ops.unbind = acpi_pci_unbind;
@@ -249,8 +238,8 @@ acpi_pci_bind (
status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to attach ACPI-PCI context to device %s\n",
- acpi_device_bid(device)));
+ "Unable to attach ACPI-PCI context to device %s\n",
+ acpi_device_bid(device)));
result = -ENODEV;
goto end;
}
@@ -267,15 +256,15 @@ acpi_pci_bind (
*/
status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
if (ACPI_SUCCESS(status)) {
- if (data->bus) /* PCI-PCI bridge */
- acpi_pci_irq_add_prt(device->handle, data->id.segment,
- data->bus->number);
- else /* non-bridge PCI device */
+ if (data->bus) /* PCI-PCI bridge */
acpi_pci_irq_add_prt(device->handle, data->id.segment,
- data->id.bus);
+ data->bus->number);
+ else /* non-bridge PCI device */
+ acpi_pci_irq_add_prt(device->handle, data->id.segment,
+ data->id.bus);
}
-end:
+ end:
kfree(pathname);
if (result)
kfree(data);
@@ -283,22 +272,21 @@ end:
return_VALUE(result);
}
-int acpi_pci_unbind(
- struct acpi_device *device)
+int acpi_pci_unbind(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_pci_data *data = NULL;
- char *pathname = NULL;
- struct acpi_buffer buffer = {0, NULL};
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_pci_data *data = NULL;
+ char *pathname = NULL;
+ struct acpi_buffer buffer = { 0, NULL };
ACPI_FUNCTION_TRACE("acpi_pci_unbind");
if (!device || !device->parent)
return_VALUE(-EINVAL);
- pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
- if(!pathname)
+ pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ if (!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
@@ -306,14 +294,16 @@ int acpi_pci_unbind(
buffer.pointer = pathname;
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
- pathname));
+ pathname));
kfree(pathname);
- status = acpi_get_data(device->handle, acpi_pci_data_handler, (void**)&data);
+ status =
+ acpi_get_data(device->handle, acpi_pci_data_handler,
+ (void **)&data);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to get data from device %s\n",
- acpi_device_bid(device)));
+ "Unable to get data from device %s\n",
+ acpi_device_bid(device)));
result = -ENODEV;
goto end;
}
@@ -321,8 +311,8 @@ int acpi_pci_unbind(
status = acpi_detach_data(device->handle, acpi_pci_data_handler);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to detach data from device %s\n",
- acpi_device_bid(device)));
+ "Unable to detach data from device %s\n",
+ acpi_device_bid(device)));
result = -ENODEV;
goto end;
}
@@ -331,39 +321,37 @@ int acpi_pci_unbind(
}
kfree(data);
-end:
+ end:
return_VALUE(result);
}
-int
-acpi_pci_bind_root (
- struct acpi_device *device,
- struct acpi_pci_id *id,
- struct pci_bus *bus)
+int
+acpi_pci_bind_root(struct acpi_device *device,
+ struct acpi_pci_id *id, struct pci_bus *bus)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_pci_data *data = NULL;
- char *pathname = NULL;
- struct acpi_buffer buffer = {0, NULL};
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_pci_data *data = NULL;
+ char *pathname = NULL;
+ struct acpi_buffer buffer = { 0, NULL };
ACPI_FUNCTION_TRACE("acpi_pci_bind_root");
pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
- if(!pathname)
+ if (!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = ACPI_PATHNAME_MAX;
buffer.pointer = pathname;
- if (!device || !id || !bus){
+ if (!device || !id || !bus) {
kfree(pathname);
return_VALUE(-EINVAL);
}
data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
- if (!data){
+ if (!data) {
kfree(pathname);
return_VALUE(-ENOMEM);
}
@@ -377,18 +365,18 @@ acpi_pci_bind_root (
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
- "%02x:%02x\n", pathname, id->segment, id->bus));
+ "%02x:%02x\n", pathname, id->segment, id->bus));
status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to attach ACPI-PCI context to device %s\n",
- pathname));
+ "Unable to attach ACPI-PCI context to device %s\n",
+ pathname));
result = -ENODEV;
goto end;
}
-end:
+ end:
kfree(pathname);
if (result != 0)
kfree(data);
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index bb973d2109a1..09567c2edcfb 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -38,26 +38,22 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME ("pci_irq")
+ACPI_MODULE_NAME("pci_irq")
-static struct acpi_prt_list acpi_prt;
+static struct acpi_prt_list acpi_prt;
static DEFINE_SPINLOCK(acpi_prt_lock);
/* --------------------------------------------------------------------------
PCI IRQ Routing Table (PRT) Support
-------------------------------------------------------------------------- */
-static struct acpi_prt_entry *
-acpi_pci_irq_find_prt_entry (
- int segment,
- int bus,
- int device,
- int pin)
+static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
+ int bus,
+ int device, int pin)
{
- struct list_head *node = NULL;
- struct acpi_prt_entry *entry = NULL;
+ struct list_head *node = NULL;
+ struct acpi_prt_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry");
@@ -72,10 +68,10 @@ acpi_pci_irq_find_prt_entry (
spin_lock(&acpi_prt_lock);
list_for_each(node, &acpi_prt.entries) {
entry = list_entry(node, struct acpi_prt_entry, node);
- if ((segment == entry->id.segment)
- && (bus == entry->id.bus)
- && (device == entry->id.device)
- && (pin == entry->pin)) {
+ if ((segment == entry->id.segment)
+ && (bus == entry->id.bus)
+ && (device == entry->id.device)
+ && (pin == entry->pin)) {
spin_unlock(&acpi_prt_lock);
return_PTR(entry);
}
@@ -85,15 +81,11 @@ acpi_pci_irq_find_prt_entry (
return_PTR(NULL);
}
-
static int
-acpi_pci_irq_add_entry (
- acpi_handle handle,
- int segment,
- int bus,
- struct acpi_pci_routing_table *prt)
+acpi_pci_irq_add_entry(acpi_handle handle,
+ int segment, int bus, struct acpi_pci_routing_table *prt)
{
- struct acpi_prt_entry *entry = NULL;
+ struct acpi_prt_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_irq_add_entry");
@@ -139,9 +131,10 @@ acpi_pci_irq_add_entry (
entry->link.index = prt->source_index;
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
- " %02X:%02X:%02X[%c] -> %s[%d]\n",
- entry->id.segment, entry->id.bus, entry->id.device,
- ('A' + entry->pin), prt->source, entry->link.index));
+ " %02X:%02X:%02X[%c] -> %s[%d]\n",
+ entry->id.segment, entry->id.bus,
+ entry->id.device, ('A' + entry->pin), prt->source,
+ entry->link.index));
spin_lock(&acpi_prt_lock);
list_add_tail(&entry->node, &acpi_prt.entries);
@@ -151,38 +144,29 @@ acpi_pci_irq_add_entry (
return_VALUE(0);
}
-
static void
-acpi_pci_irq_del_entry (
- int segment,
- int bus,
- struct acpi_prt_entry *entry)
+acpi_pci_irq_del_entry(int segment, int bus, struct acpi_prt_entry *entry)
{
- if (segment == entry->id.segment && bus == entry->id.bus){
+ if (segment == entry->id.segment && bus == entry->id.bus) {
acpi_prt.count--;
list_del(&entry->node);
kfree(entry);
}
}
-
-int
-acpi_pci_irq_add_prt (
- acpi_handle handle,
- int segment,
- int bus)
+int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
{
- acpi_status status = AE_OK;
- char *pathname = NULL;
- struct acpi_buffer buffer = {0, NULL};
- struct acpi_pci_routing_table *prt = NULL;
- struct acpi_pci_routing_table *entry = NULL;
- static int first_time = 1;
+ acpi_status status = AE_OK;
+ char *pathname = NULL;
+ struct acpi_buffer buffer = { 0, NULL };
+ struct acpi_pci_routing_table *prt = NULL;
+ struct acpi_pci_routing_table *entry = NULL;
+ static int first_time = 1;
ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt");
- pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
- if(!pathname)
+ pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ if (!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
@@ -202,7 +186,7 @@ acpi_pci_irq_add_prt (
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
- pathname);
+ pathname);
/*
* Evaluate this _PRT and add its entries to our global list (acpi_prt).
@@ -214,12 +198,12 @@ acpi_pci_irq_add_prt (
status = acpi_get_irq_routing_table(handle, &buffer);
if (status != AE_BUFFER_OVERFLOW) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
- acpi_format_exception(status)));
+ acpi_format_exception(status)));
return_VALUE(-ENODEV);
}
prt = kmalloc(buffer.length, GFP_KERNEL);
- if (!prt){
+ if (!prt) {
return_VALUE(-ENOMEM);
}
memset(prt, 0, buffer.length);
@@ -228,7 +212,7 @@ acpi_pci_irq_add_prt (
status = acpi_get_irq_routing_table(handle, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
- acpi_format_exception(status)));
+ acpi_format_exception(status)));
kfree(buffer.pointer);
return_VALUE(-ENODEV);
}
@@ -238,7 +222,7 @@ acpi_pci_irq_add_prt (
while (entry && (entry->length > 0)) {
acpi_pci_irq_add_entry(handle, segment, bus, entry);
entry = (struct acpi_pci_routing_table *)
- ((unsigned long) entry + entry->length);
+ ((unsigned long)entry + entry->length);
}
kfree(prt);
@@ -246,18 +230,18 @@ acpi_pci_irq_add_prt (
return_VALUE(0);
}
-void
-acpi_pci_irq_del_prt (int segment, int bus)
+void acpi_pci_irq_del_prt(int segment, int bus)
{
- struct list_head *node = NULL, *n = NULL;
- struct acpi_prt_entry *entry = NULL;
+ struct list_head *node = NULL, *n = NULL;
+ struct acpi_prt_entry *entry = NULL;
- if (!acpi_prt.count) {
+ if (!acpi_prt.count) {
return;
}
- printk(KERN_DEBUG "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n",
- segment, bus);
+ printk(KERN_DEBUG
+ "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n", segment,
+ bus);
spin_lock(&acpi_prt_lock);
list_for_each_safe(node, n, &acpi_prt.entries) {
entry = list_entry(node, struct acpi_prt_entry, node);
@@ -266,26 +250,27 @@ acpi_pci_irq_del_prt (int segment, int bus)
}
spin_unlock(&acpi_prt_lock);
}
+
/* --------------------------------------------------------------------------
PCI Interrupt Routing Support
-------------------------------------------------------------------------- */
-typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **);
+typedef int (*irq_lookup_func) (struct acpi_prt_entry *, int *, int *, char **);
static int
acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
- int *edge_level,
- int *active_high_low,
- char **link)
+ int *edge_level, int *active_high_low, char **link)
{
- int irq;
+ int irq;
ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq");
if (entry->link.handle) {
irq = acpi_pci_link_allocate_irq(entry->link.handle,
- entry->link.index, edge_level, active_high_low, link);
+ entry->link.index, edge_level,
+ active_high_low, link);
if (irq < 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid IRQ link routing entry\n"));
return_VALUE(-1);
}
} else {
@@ -300,11 +285,9 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
static int
acpi_pci_free_irq(struct acpi_prt_entry *entry,
- int *edge_level,
- int *active_high_low,
- char **link)
+ int *edge_level, int *active_high_low, char **link)
{
- int irq;
+ int irq;
ACPI_FUNCTION_TRACE("acpi_pci_free_irq");
if (entry->link.handle) {
@@ -314,38 +297,36 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry,
}
return_VALUE(irq);
}
+
/*
* acpi_pci_irq_lookup
* success: return IRQ >= 0
* failure: return -1
*/
static int
-acpi_pci_irq_lookup (
- struct pci_bus *bus,
- int device,
- int pin,
- int *edge_level,
- int *active_high_low,
- char **link,
- irq_lookup_func func)
+acpi_pci_irq_lookup(struct pci_bus *bus,
+ int device,
+ int pin,
+ int *edge_level,
+ int *active_high_low, char **link, irq_lookup_func func)
{
- struct acpi_prt_entry *entry = NULL;
+ struct acpi_prt_entry *entry = NULL;
int segment = pci_domain_nr(bus);
int bus_nr = bus->number;
int ret;
ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Searching for PRT entry for %02x:%02x:%02x[%c]\n",
- segment, bus_nr, device, ('A' + pin)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Searching for PRT entry for %02x:%02x:%02x[%c]\n",
+ segment, bus_nr, device, ('A' + pin)));
- entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin);
+ entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin);
if (!entry) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
return_VALUE(-1);
}
-
+
ret = func(entry, edge_level, active_high_low, link);
return_VALUE(ret);
}
@@ -356,17 +337,14 @@ acpi_pci_irq_lookup (
* failure: return < 0
*/
static int
-acpi_pci_irq_derive (
- struct pci_dev *dev,
- int pin,
- int *edge_level,
- int *active_high_low,
- char **link,
- irq_lookup_func func)
+acpi_pci_irq_derive(struct pci_dev *dev,
+ int pin,
+ int *edge_level,
+ int *active_high_low, char **link, irq_lookup_func func)
{
- struct pci_dev *bridge = dev;
- int irq = -1;
- u8 bridge_pin = 0;
+ struct pci_dev *bridge = dev;
+ int irq = -1;
+ u8 bridge_pin = 0;
ACPI_FUNCTION_TRACE("acpi_pci_irq_derive");
@@ -383,28 +361,33 @@ acpi_pci_irq_derive (
if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
/* PC card has the same IRQ as its cardbridge */
- pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, &bridge_pin);
+ pci_read_config_byte(bridge, PCI_INTERRUPT_PIN,
+ &bridge_pin);
if (!bridge_pin) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "No interrupt pin configured for device %s\n", pci_name(bridge)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "No interrupt pin configured for device %s\n",
+ pci_name(bridge)));
return_VALUE(-1);
}
/* Pin is from 0 to 3 */
- bridge_pin --;
+ bridge_pin--;
pin = bridge_pin;
}
irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
- pin, edge_level, active_high_low, link, func);
+ pin, edge_level, active_high_low,
+ link, func);
}
if (irq < 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", pci_name(dev)));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Unable to derive IRQ for device %s\n",
+ pci_name(dev)));
return_VALUE(-1);
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n",
- irq, pci_name(dev), pci_name(bridge)));
+ irq, pci_name(dev), pci_name(bridge)));
return_VALUE(irq);
}
@@ -415,30 +398,32 @@ acpi_pci_irq_derive (
* failure: return < 0
*/
-int
-acpi_pci_irq_enable (
- struct pci_dev *dev)
+int acpi_pci_irq_enable(struct pci_dev *dev)
{
- int irq = 0;
- u8 pin = 0;
- int edge_level = ACPI_LEVEL_SENSITIVE;
- int active_high_low = ACPI_ACTIVE_LOW;
- char *link = NULL;
+ int irq = 0;
+ u8 pin = 0;
+ int edge_level = ACPI_LEVEL_SENSITIVE;
+ int active_high_low = ACPI_ACTIVE_LOW;
+ char *link = NULL;
+ int rc;
ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
if (!dev)
return_VALUE(-EINVAL);
-
+
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (!pin) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", pci_name(dev)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "No interrupt pin configured for device %s\n",
+ pci_name(dev)));
return_VALUE(0);
}
pin--;
if (!dev->bus) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) 'bus' field\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid (NULL) 'bus' field\n"));
return_VALUE(-ENODEV);
}
@@ -446,69 +431,76 @@ acpi_pci_irq_enable (
* First we check the PCI IRQ routing table (PRT) for an IRQ. PRT
* values override any BIOS-assigned IRQs set during boot.
*/
- irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
- &edge_level, &active_high_low, &link, acpi_pci_allocate_irq);
+ irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+ &edge_level, &active_high_low, &link,
+ acpi_pci_allocate_irq);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if (irq < 0)
- irq = acpi_pci_irq_derive(dev, pin, &edge_level,
- &active_high_low, &link, acpi_pci_allocate_irq);
-
+ irq = acpi_pci_irq_derive(dev, pin, &edge_level,
+ &active_high_low, &link,
+ acpi_pci_allocate_irq);
+
/*
* No IRQ known to the ACPI subsystem - maybe the BIOS /
* driver reported one, then use it. Exit in any case.
*/
if (irq < 0) {
printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
- pci_name(dev), ('A' + pin));
+ pci_name(dev), ('A' + pin));
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq > 0 && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq);
- acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
+ acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE,
+ ACPI_ACTIVE_LOW);
return_VALUE(0);
- }
- else {
+ } else {
printk("\n");
return_VALUE(0);
}
- }
+ }
- dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
+ rc = acpi_register_gsi(irq, edge_level, active_high_low);
+ if (rc < 0) {
+ printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed "
+ "to register GSI\n", pci_name(dev), ('A' + pin));
+ return_VALUE(rc);
+ }
+ dev->irq = rc;
printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
- pci_name(dev), 'A' + pin);
+ pci_name(dev), 'A' + pin);
if (link)
printk("Link [%s] -> ", link);
printk("GSI %u (%s, %s) -> IRQ %d\n", irq,
- (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
- (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
- dev->irq);
+ (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+ (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_pci_irq_enable);
+EXPORT_SYMBOL(acpi_pci_irq_enable);
/* FIXME: implement x86/x86_64 version */
-void __attribute__((weak)) acpi_unregister_gsi(u32 i) {}
+void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
+{
+}
-void
-acpi_pci_irq_disable (
- struct pci_dev *dev)
+void acpi_pci_irq_disable(struct pci_dev *dev)
{
- int gsi = 0;
- u8 pin = 0;
- int edge_level = ACPI_LEVEL_SENSITIVE;
- int active_high_low = ACPI_ACTIVE_LOW;
+ int gsi = 0;
+ u8 pin = 0;
+ int edge_level = ACPI_LEVEL_SENSITIVE;
+ int active_high_low = ACPI_ACTIVE_LOW;
ACPI_FUNCTION_TRACE("acpi_pci_irq_disable");
- if (!dev)
+ if (!dev || !dev->bus)
return_VOID;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -516,21 +508,20 @@ acpi_pci_irq_disable (
return_VOID;
pin--;
- if (!dev->bus)
- return_VOID;
-
/*
* First we check the PCI IRQ routing table (PRT) for an IRQ.
*/
- gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
- &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
+ gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+ &edge_level, &active_high_low, NULL,
+ acpi_pci_free_irq);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if (gsi < 0)
- gsi = acpi_pci_irq_derive(dev, pin,
- &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
+ gsi = acpi_pci_irq_derive(dev, pin,
+ &edge_level, &active_high_low, NULL,
+ acpi_pci_free_irq);
if (gsi < 0)
return_VOID;
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 834c2ceff1aa..82292b77e5c6 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -42,30 +42,26 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME ("pci_link")
-
+ACPI_MODULE_NAME("pci_link")
#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
#define ACPI_PCI_LINK_HID "PNP0C0F"
#define ACPI_PCI_LINK_DRIVER_NAME "ACPI PCI Interrupt Link Driver"
#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
#define ACPI_PCI_LINK_FILE_INFO "info"
#define ACPI_PCI_LINK_FILE_STATUS "state"
-
#define ACPI_PCI_LINK_MAX_POSSIBLE 16
-
-static int acpi_pci_link_add (struct acpi_device *device);
-static int acpi_pci_link_remove (struct acpi_device *device, int type);
+static int acpi_pci_link_add(struct acpi_device *device);
+static int acpi_pci_link_remove(struct acpi_device *device, int type);
static struct acpi_driver acpi_pci_link_driver = {
- .name = ACPI_PCI_LINK_DRIVER_NAME,
- .class = ACPI_PCI_LINK_CLASS,
- .ids = ACPI_PCI_LINK_HID,
- .ops = {
- .add = acpi_pci_link_add,
- .remove = acpi_pci_link_remove,
- },
+ .name = ACPI_PCI_LINK_DRIVER_NAME,
+ .class = ACPI_PCI_LINK_CLASS,
+ .ids = ACPI_PCI_LINK_HID,
+ .ops = {
+ .add = acpi_pci_link_add,
+ .remove = acpi_pci_link_remove,
+ },
};
/*
@@ -73,31 +69,30 @@ static struct acpi_driver acpi_pci_link_driver = {
* later even the link is disable. Instead, we just repick the active irq
*/
struct acpi_pci_link_irq {
- u8 active; /* Current IRQ */
- u8 edge_level; /* All IRQs */
- u8 active_high_low; /* All IRQs */
- u8 resource_type;
- u8 possible_count;
- u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
- u8 initialized:1;
- u8 reserved:7;
+ u8 active; /* Current IRQ */
+ u8 edge_level; /* All IRQs */
+ u8 active_high_low; /* All IRQs */
+ u8 resource_type;
+ u8 possible_count;
+ u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+ u8 initialized:1;
+ u8 reserved:7;
};
struct acpi_pci_link {
- struct list_head node;
- struct acpi_device *device;
- acpi_handle handle;
+ struct list_head node;
+ struct acpi_device *device;
+ acpi_handle handle;
struct acpi_pci_link_irq irq;
- int refcnt;
+ int refcnt;
};
static struct {
- int count;
- struct list_head entries;
-} acpi_link;
+ int count;
+ struct list_head entries;
+} acpi_link;
DECLARE_MUTEX(acpi_link_lock);
-
/* --------------------------------------------------------------------------
PCI Link Device Management
-------------------------------------------------------------------------- */
@@ -106,12 +101,10 @@ DECLARE_MUTEX(acpi_link_lock);
* set context (link) possible list from resource list
*/
static acpi_status
-acpi_pci_link_check_possible (
- struct acpi_resource *resource,
- void *context)
+acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
{
- struct acpi_pci_link *link = (struct acpi_pci_link *) context;
- u32 i = 0;
+ struct acpi_pci_link *link = (struct acpi_pci_link *)context;
+ u32 i = 0;
ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
@@ -119,61 +112,68 @@ acpi_pci_link_check_possible (
case ACPI_RSTYPE_START_DPF:
return_ACPI_STATUS(AE_OK);
case ACPI_RSTYPE_IRQ:
- {
- struct acpi_resource_irq *p = &resource->data.irq;
- if (!p || !p->number_of_interrupts) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n"));
- return_ACPI_STATUS(AE_OK);
- }
- for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
- if (!p->interrupts[i]) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i]));
- continue;
+ {
+ struct acpi_resource_irq *p = &resource->data.irq;
+ if (!p || !p->number_of_interrupts) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Blank IRQ resource\n"));
+ return_ACPI_STATUS(AE_OK);
}
- link->irq.possible[i] = p->interrupts[i];
- link->irq.possible_count++;
+ for (i = 0;
+ (i < p->number_of_interrupts
+ && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
+ if (!p->interrupts[i]) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid IRQ %d\n",
+ p->interrupts[i]));
+ continue;
+ }
+ link->irq.possible[i] = p->interrupts[i];
+ link->irq.possible_count++;
+ }
+ link->irq.edge_level = p->edge_level;
+ link->irq.active_high_low = p->active_high_low;
+ link->irq.resource_type = ACPI_RSTYPE_IRQ;
+ break;
}
- link->irq.edge_level = p->edge_level;
- link->irq.active_high_low = p->active_high_low;
- link->irq.resource_type = ACPI_RSTYPE_IRQ;
- break;
- }
case ACPI_RSTYPE_EXT_IRQ:
- {
- struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
- if (!p || !p->number_of_interrupts) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "Blank EXT IRQ resource\n"));
- return_ACPI_STATUS(AE_OK);
- }
- for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
- if (!p->interrupts[i]) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i]));
- continue;
+ {
+ struct acpi_resource_ext_irq *p =
+ &resource->data.extended_irq;
+ if (!p || !p->number_of_interrupts) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Blank EXT IRQ resource\n"));
+ return_ACPI_STATUS(AE_OK);
+ }
+ for (i = 0;
+ (i < p->number_of_interrupts
+ && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
+ if (!p->interrupts[i]) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid IRQ %d\n",
+ p->interrupts[i]));
+ continue;
+ }
+ link->irq.possible[i] = p->interrupts[i];
+ link->irq.possible_count++;
}
- link->irq.possible[i] = p->interrupts[i];
- link->irq.possible_count++;
+ link->irq.edge_level = p->edge_level;
+ link->irq.active_high_low = p->active_high_low;
+ link->irq.resource_type = ACPI_RSTYPE_EXT_IRQ;
+ break;
}
- link->irq.edge_level = p->edge_level;
- link->irq.active_high_low = p->active_high_low;
- link->irq.resource_type = ACPI_RSTYPE_EXT_IRQ;
- break;
- }
default:
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Resource is not an IRQ entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Resource is not an IRQ entry\n"));
return_ACPI_STATUS(AE_OK);
}
return_ACPI_STATUS(AE_CTRL_TERMINATE);
}
-
-static int
-acpi_pci_link_get_possible (
- struct acpi_pci_link *link)
+static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
{
- acpi_status status;
+ acpi_status status;
ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible");
@@ -181,62 +181,60 @@ acpi_pci_link_get_possible (
return_VALUE(-EINVAL);
status = acpi_walk_resources(link->handle, METHOD_NAME__PRS,
- acpi_pci_link_check_possible, link);
+ acpi_pci_link_check_possible, link);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
return_VALUE(-ENODEV);
}
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Found %d possible IRQs\n", link->irq.possible_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found %d possible IRQs\n",
+ link->irq.possible_count));
return_VALUE(0);
}
-
static acpi_status
-acpi_pci_link_check_current (
- struct acpi_resource *resource,
- void *context)
+acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
{
- int *irq = (int *) context;
+ int *irq = (int *)context;
ACPI_FUNCTION_TRACE("acpi_pci_link_check_current");
switch (resource->id) {
case ACPI_RSTYPE_IRQ:
- {
- struct acpi_resource_irq *p = &resource->data.irq;
- if (!p || !p->number_of_interrupts) {
- /*
- * IRQ descriptors may have no IRQ# bits set,
- * particularly those those w/ _STA disabled
- */
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Blank IRQ resource\n"));
- return_ACPI_STATUS(AE_OK);
+ {
+ struct acpi_resource_irq *p = &resource->data.irq;
+ if (!p || !p->number_of_interrupts) {
+ /*
+ * IRQ descriptors may have no IRQ# bits set,
+ * particularly those those w/ _STA disabled
+ */
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Blank IRQ resource\n"));
+ return_ACPI_STATUS(AE_OK);
+ }
+ *irq = p->interrupts[0];
+ break;
}
- *irq = p->interrupts[0];
- break;
- }
case ACPI_RSTYPE_EXT_IRQ:
- {
- struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
- if (!p || !p->number_of_interrupts) {
- /*
- * extended IRQ descriptors must
- * return at least 1 IRQ
- */
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "Blank EXT IRQ resource\n"));
- return_ACPI_STATUS(AE_OK);
+ {
+ struct acpi_resource_ext_irq *p =
+ &resource->data.extended_irq;
+ if (!p || !p->number_of_interrupts) {
+ /*
+ * extended IRQ descriptors must
+ * return at least 1 IRQ
+ */
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Blank EXT IRQ resource\n"));
+ return_ACPI_STATUS(AE_OK);
+ }
+ *irq = p->interrupts[0];
+ break;
}
- *irq = p->interrupts[0];
- break;
- }
default:
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Resource isn't an IRQ\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource isn't an IRQ\n"));
return_ACPI_STATUS(AE_OK);
}
return_ACPI_STATUS(AE_CTRL_TERMINATE);
@@ -249,13 +247,11 @@ acpi_pci_link_check_current (
* 0 - success
* !0 - failure
*/
-static int
-acpi_pci_link_get_current (
- struct acpi_pci_link *link)
+static int acpi_pci_link_get_current(struct acpi_pci_link *link)
{
- int result = 0;
- acpi_status status = AE_OK;
- int irq = 0;
+ int result = 0;
+ acpi_status status = AE_OK;
+ int irq = 0;
ACPI_FUNCTION_TRACE("acpi_pci_link_get_current");
@@ -269,7 +265,8 @@ acpi_pci_link_get_current (
/* Query _STA, set link->device->status */
result = acpi_bus_get_status(link->device);
if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to read status\n"));
goto end;
}
@@ -284,7 +281,7 @@ acpi_pci_link_get_current (
*/
status = acpi_walk_resources(link->handle, METHOD_NAME__CRS,
- acpi_pci_link_check_current, &irq);
+ acpi_pci_link_check_current, &irq);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n"));
result = -ENODEV;
@@ -300,58 +297,61 @@ acpi_pci_link_get_current (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
-end:
+ end:
return_VALUE(result);
}
-static int
-acpi_pci_link_set (
- struct acpi_pci_link *link,
- int irq)
+static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
{
- int result = 0;
- acpi_status status = AE_OK;
+ int result = 0;
+ acpi_status status = AE_OK;
struct {
- struct acpi_resource res;
- struct acpi_resource end;
- } *resource;
- struct acpi_buffer buffer = {0, NULL};
+ struct acpi_resource res;
+ struct acpi_resource end;
+ } *resource;
+ struct acpi_buffer buffer = { 0, NULL };
ACPI_FUNCTION_TRACE("acpi_pci_link_set");
if (!link || !irq)
return_VALUE(-EINVAL);
- resource = kmalloc( sizeof(*resource)+1, GFP_KERNEL);
- if(!resource)
+ resource = kmalloc(sizeof(*resource) + 1, GFP_KERNEL);
+ if (!resource)
return_VALUE(-ENOMEM);
- memset(resource, 0, sizeof(*resource)+1);
- buffer.length = sizeof(*resource) +1;
+ memset(resource, 0, sizeof(*resource) + 1);
+ buffer.length = sizeof(*resource) + 1;
buffer.pointer = resource;
- switch(link->irq.resource_type) {
+ switch (link->irq.resource_type) {
case ACPI_RSTYPE_IRQ:
resource->res.id = ACPI_RSTYPE_IRQ;
resource->res.length = sizeof(struct acpi_resource);
resource->res.data.irq.edge_level = link->irq.edge_level;
- resource->res.data.irq.active_high_low = link->irq.active_high_low;
+ resource->res.data.irq.active_high_low =
+ link->irq.active_high_low;
if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
- resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+ resource->res.data.irq.shared_exclusive =
+ ACPI_EXCLUSIVE;
else
resource->res.data.irq.shared_exclusive = ACPI_SHARED;
resource->res.data.irq.number_of_interrupts = 1;
resource->res.data.irq.interrupts[0] = irq;
break;
-
+
case ACPI_RSTYPE_EXT_IRQ:
resource->res.id = ACPI_RSTYPE_EXT_IRQ;
resource->res.length = sizeof(struct acpi_resource);
- resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
- resource->res.data.extended_irq.edge_level = link->irq.edge_level;
- resource->res.data.extended_irq.active_high_low = link->irq.active_high_low;
+ resource->res.data.extended_irq.producer_consumer =
+ ACPI_CONSUMER;
+ resource->res.data.extended_irq.edge_level =
+ link->irq.edge_level;
+ resource->res.data.extended_irq.active_high_low =
+ link->irq.active_high_low;
if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
- resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+ resource->res.data.irq.shared_exclusive =
+ ACPI_EXCLUSIVE;
else
resource->res.data.irq.shared_exclusive = ACPI_SHARED;
resource->res.data.extended_irq.number_of_interrupts = 1;
@@ -384,9 +384,9 @@ acpi_pci_link_set (
}
if (!link->device->status.enabled) {
printk(KERN_WARNING PREFIX
- "%s [%s] disabled and referenced, BIOS bug.\n",
- acpi_device_name(link->device),
- acpi_device_bid(link->device));
+ "%s [%s] disabled and referenced, BIOS bug.\n",
+ acpi_device_name(link->device),
+ acpi_device_bid(link->device));
}
/* Query _CRS, set link->irq.active */
@@ -404,22 +404,20 @@ acpi_pci_link_set (
* policy: when _CRS doesn't return what we just _SRS
* assume _SRS worked and override _CRS value.
*/
- printk(KERN_WARNING PREFIX
- "%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
- acpi_device_name(link->device),
- acpi_device_bid(link->device),
- link->irq.active, irq);
+ printk(KERN_WARNING PREFIX
+ "%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
+ acpi_device_name(link->device),
+ acpi_device_bid(link->device), link->irq.active, irq);
link->irq.active = irq;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
-
-end:
+
+ end:
kfree(resource);
return_VALUE(result);
}
-
/* --------------------------------------------------------------------------
PCI Link IRQ Management
-------------------------------------------------------------------------- */
@@ -469,8 +467,8 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */
- PIRQ_PENALTY_ISA_TYPICAL, /* IRQ3 serial */
- PIRQ_PENALTY_ISA_TYPICAL, /* IRQ4 serial */
+ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ3 serial */
+ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ4 serial */
PIRQ_PENALTY_ISA_TYPICAL, /* IRQ5 sometimes SoundBlaster */
PIRQ_PENALTY_ISA_TYPICAL, /* IRQ6 */
PIRQ_PENALTY_ISA_TYPICAL, /* IRQ7 parallel, spurious */
@@ -482,15 +480,14 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
- /* >IRQ15 */
+ /* >IRQ15 */
};
-int __init
-acpi_irq_penalty_init(void)
+int __init acpi_irq_penalty_init(void)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
- int i = 0;
+ struct list_head *node = NULL;
+ struct acpi_pci_link *link = NULL;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_irq_penalty_init");
@@ -501,7 +498,8 @@ acpi_irq_penalty_init(void)
link = list_entry(node, struct acpi_pci_link, node);
if (!link) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid link context\n"));
continue;
}
@@ -510,15 +508,20 @@ acpi_irq_penalty_init(void)
* useful for breaking ties.
*/
if (link->irq.possible_count) {
- int penalty = PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count;
+ int penalty =
+ PIRQ_PENALTY_PCI_POSSIBLE /
+ link->irq.possible_count;
for (i = 0; i < link->irq.possible_count; i++) {
if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
- acpi_irq_penalty[link->irq.possible[i]] += penalty;
+ acpi_irq_penalty[link->irq.
+ possible[i]] +=
+ penalty;
}
} else if (link->irq.active) {
- acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_POSSIBLE;
+ acpi_irq_penalty[link->irq.active] +=
+ PIRQ_PENALTY_PCI_POSSIBLE;
}
}
/* Add a penalty for the SCI */
@@ -529,11 +532,10 @@ acpi_irq_penalty_init(void)
static int acpi_irq_balance; /* 0: static, 1: balance */
-static int acpi_pci_link_allocate(
- struct acpi_pci_link *link)
+static int acpi_pci_link_allocate(struct acpi_pci_link *link)
{
- int irq;
- int i;
+ int irq;
+ int i;
ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
@@ -557,7 +559,7 @@ static int acpi_pci_link_allocate(
if (i == link->irq.possible_count) {
if (acpi_strict)
printk(KERN_WARNING PREFIX "_CRS %d not found"
- " in _PRS\n", link->irq.active);
+ " in _PRS\n", link->irq.active);
link->irq.active = 0;
}
@@ -576,23 +578,25 @@ static int acpi_pci_link_allocate(
* the use of IRQs 9, 10, 11, and >15.
*/
for (i = (link->irq.possible_count - 1); i >= 0; i--) {
- if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
+ if (acpi_irq_penalty[irq] >
+ acpi_irq_penalty[link->irq.possible[i]])
irq = link->irq.possible[i];
}
}
/* Attempt to enable the link device at this IRQ. */
if (acpi_pci_link_set(link, irq)) {
- printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS).\n"
- "Try pci=noacpi or acpi=off\n",
- acpi_device_name(link->device),
- acpi_device_bid(link->device));
+ printk(PREFIX
+ "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS).\n"
+ "Try pci=noacpi or acpi=off\n",
+ acpi_device_name(link->device),
+ acpi_device_bid(link->device));
return_VALUE(-ENODEV);
} else {
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
- printk(PREFIX "%s [%s] enabled at IRQ %d\n",
- acpi_device_name(link->device),
- acpi_device_bid(link->device), link->irq.active);
+ printk(PREFIX "%s [%s] enabled at IRQ %d\n",
+ acpi_device_name(link->device),
+ acpi_device_bid(link->device), link->irq.active);
}
link->irq.initialized = 1;
@@ -607,16 +611,13 @@ static int acpi_pci_link_allocate(
*/
int
-acpi_pci_link_allocate_irq (
- acpi_handle handle,
- int index,
- int *edge_level,
- int *active_high_low,
- char **name)
+acpi_pci_link_allocate_irq(acpi_handle handle,
+ int index,
+ int *edge_level, int *active_high_low, char **name)
{
- int result = 0;
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
+ struct acpi_pci_link *link = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_link_allocate_irq");
@@ -626,7 +627,7 @@ acpi_pci_link_allocate_irq (
return_VALUE(-1);
}
- link = (struct acpi_pci_link *) acpi_driver_data(device);
+ link = (struct acpi_pci_link *)acpi_driver_data(device);
if (!link) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
return_VALUE(-1);
@@ -643,20 +644,24 @@ acpi_pci_link_allocate_irq (
up(&acpi_link_lock);
return_VALUE(-1);
}
-
+
if (!link->irq.active) {
up(&acpi_link_lock);
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
return_VALUE(-1);
}
- link->refcnt ++;
+ link->refcnt++;
up(&acpi_link_lock);
- if (edge_level) *edge_level = link->irq.edge_level;
- if (active_high_low) *active_high_low = link->irq.active_high_low;
- if (name) *name = acpi_device_bid(link->device);
+ if (edge_level)
+ *edge_level = link->irq.edge_level;
+ if (active_high_low)
+ *active_high_low = link->irq.active_high_low;
+ if (name)
+ *name = acpi_device_bid(link->device);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Link %s is referenced\n", acpi_device_bid(link->device)));
+ "Link %s is referenced\n",
+ acpi_device_bid(link->device)));
return_VALUE(link->irq.active);
}
@@ -664,12 +669,11 @@ acpi_pci_link_allocate_irq (
* We don't change link's irq information here. After it is reenabled, we
* continue use the info
*/
-int
-acpi_pci_link_free_irq(acpi_handle handle)
+int acpi_pci_link_free_irq(acpi_handle handle)
{
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
- acpi_status result;
+ struct acpi_device *device = NULL;
+ struct acpi_pci_link *link = NULL;
+ acpi_status result;
ACPI_FUNCTION_TRACE("acpi_pci_link_free_irq");
@@ -679,7 +683,7 @@ acpi_pci_link_free_irq(acpi_handle handle)
return_VALUE(-1);
}
- link = (struct acpi_pci_link *) acpi_driver_data(device);
+ link = (struct acpi_pci_link *)acpi_driver_data(device);
if (!link) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
return_VALUE(-1);
@@ -691,7 +695,6 @@ acpi_pci_link_free_irq(acpi_handle handle)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link isn't initialized\n"));
return_VALUE(-1);
}
-
#ifdef FUTURE_USE
/*
* The Link reference count allows us to _DISable an unused link
@@ -702,10 +705,11 @@ acpi_pci_link_free_irq(acpi_handle handle)
* to prevent duplicate acpi_pci_link_set()
* which would harm some systems
*/
- link->refcnt --;
+ link->refcnt--;
#endif
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Link %s is dereferenced\n", acpi_device_bid(link->device)));
+ "Link %s is dereferenced\n",
+ acpi_device_bid(link->device)));
if (link->refcnt == 0) {
acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
@@ -713,18 +717,17 @@ acpi_pci_link_free_irq(acpi_handle handle)
up(&acpi_link_lock);
return_VALUE(link->irq.active);
}
+
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static int
-acpi_pci_link_add (
- struct acpi_device *device)
+static int acpi_pci_link_add(struct acpi_device *device)
{
- int result = 0;
- struct acpi_pci_link *link = NULL;
- int i = 0;
- int found = 0;
+ int result = 0;
+ struct acpi_pci_link *link = NULL;
+ int i = 0;
+ int found = 0;
ACPI_FUNCTION_TRACE("acpi_pci_link_add");
@@ -751,13 +754,12 @@ acpi_pci_link_add (
acpi_pci_link_get_current(link);
printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device),
- acpi_device_bid(device));
+ acpi_device_bid(device));
for (i = 0; i < link->irq.possible_count; i++) {
if (link->irq.active == link->irq.possible[i]) {
printk(" *%d", link->irq.possible[i]);
found = 1;
- }
- else
+ } else
printk(" %d", link->irq.possible[i]);
}
@@ -766,7 +768,7 @@ acpi_pci_link_add (
if (!found)
printk(" *%d", link->irq.active);
- if(!link->device->status.enabled)
+ if (!link->device->status.enabled)
printk(", disabled.");
printk("\n");
@@ -775,7 +777,7 @@ acpi_pci_link_add (
list_add_tail(&link->node, &acpi_link.entries);
acpi_link.count++;
-end:
+ end:
/* disable all links -- to be activated on use */
acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
up(&acpi_link_lock);
@@ -786,9 +788,7 @@ end:
return_VALUE(result);
}
-static int
-acpi_pci_link_resume(
- struct acpi_pci_link *link)
+static int acpi_pci_link_resume(struct acpi_pci_link *link)
{
ACPI_FUNCTION_TRACE("acpi_pci_link_resume");
@@ -803,12 +803,10 @@ acpi_pci_link_resume(
* after every device calls pci_disable_device in .resume.
*/
int acpi_in_resume;
-static int
-irqrouter_resume(
- struct sys_device *dev)
+static int irqrouter_resume(struct sys_device *dev)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
+ struct list_head *node = NULL;
+ struct acpi_pci_link *link = NULL;
ACPI_FUNCTION_TRACE("irqrouter_resume");
@@ -817,7 +815,7 @@ irqrouter_resume(
link = list_entry(node, struct acpi_pci_link, node);
if (!link) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Invalid link context\n"));
+ "Invalid link context\n"));
continue;
}
acpi_pci_link_resume(link);
@@ -826,11 +824,7 @@ irqrouter_resume(
return_VALUE(0);
}
-
-static int
-acpi_pci_link_remove (
- struct acpi_device *device,
- int type)
+static int acpi_pci_link_remove(struct acpi_device *device, int type)
{
struct acpi_pci_link *link = NULL;
@@ -839,7 +833,7 @@ acpi_pci_link_remove (
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- link = (struct acpi_pci_link *) acpi_driver_data(device);
+ link = (struct acpi_pci_link *)acpi_driver_data(device);
down(&acpi_link_lock);
list_del(&link->node);
@@ -861,14 +855,14 @@ static int __init acpi_irq_penalty_update(char *str, int used)
int retval;
int irq;
- retval = get_option(&str,&irq);
+ retval = get_option(&str, &irq);
if (!retval)
break; /* no number found */
if (irq < 0)
continue;
-
+
if (irq >= ACPI_MAX_IRQS)
continue;
@@ -907,6 +901,7 @@ static int __init acpi_irq_isa(char *str)
{
return acpi_irq_penalty_update(str, 1);
}
+
__setup("acpi_irq_isa=", acpi_irq_isa);
/*
@@ -918,6 +913,7 @@ static int __init acpi_irq_pci(char *str)
{
return acpi_irq_penalty_update(str, 0);
}
+
__setup("acpi_irq_pci=", acpi_irq_pci);
static int __init acpi_irq_nobalance_set(char *str)
@@ -925,6 +921,7 @@ static int __init acpi_irq_nobalance_set(char *str)
acpi_irq_balance = 0;
return 1;
}
+
__setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
int __init acpi_irq_balance_set(char *str)
@@ -932,22 +929,20 @@ int __init acpi_irq_balance_set(char *str)
acpi_irq_balance = 1;
return 1;
}
-__setup("acpi_irq_balance", acpi_irq_balance_set);
+__setup("acpi_irq_balance", acpi_irq_balance_set);
/* FIXME: we will remove this interface after all drivers call pci_disable_device */
static struct sysdev_class irqrouter_sysdev_class = {
- set_kset_name("irqrouter"),
- .resume = irqrouter_resume,
+ set_kset_name("irqrouter"),
+ .resume = irqrouter_resume,
};
-
static struct sys_device device_irqrouter = {
- .id = 0,
- .cls = &irqrouter_sysdev_class,
+ .id = 0,
+ .cls = &irqrouter_sysdev_class,
};
-
static int __init irqrouter_init_sysfs(void)
{
int error;
@@ -962,12 +957,11 @@ static int __init irqrouter_init_sysfs(void)
error = sysdev_register(&device_irqrouter);
return_VALUE(error);
-}
+}
device_initcall(irqrouter_init_sysfs);
-
-static int __init acpi_pci_link_init (void)
+static int __init acpi_pci_link_init(void)
{
ACPI_FUNCTION_TRACE("acpi_pci_link_init");
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5d2f77fcd50c..0fd9988c283d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -35,35 +35,32 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME ("pci_root")
-
+ACPI_MODULE_NAME("pci_root")
#define ACPI_PCI_ROOT_CLASS "pci_bridge"
#define ACPI_PCI_ROOT_HID "PNP0A03"
#define ACPI_PCI_ROOT_DRIVER_NAME "ACPI PCI Root Bridge Driver"
#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge"
-
-static int acpi_pci_root_add (struct acpi_device *device);
-static int acpi_pci_root_remove (struct acpi_device *device, int type);
-static int acpi_pci_root_start (struct acpi_device *device);
+static int acpi_pci_root_add(struct acpi_device *device);
+static int acpi_pci_root_remove(struct acpi_device *device, int type);
+static int acpi_pci_root_start(struct acpi_device *device);
static struct acpi_driver acpi_pci_root_driver = {
- .name = ACPI_PCI_ROOT_DRIVER_NAME,
- .class = ACPI_PCI_ROOT_CLASS,
- .ids = ACPI_PCI_ROOT_HID,
- .ops = {
- .add = acpi_pci_root_add,
- .remove = acpi_pci_root_remove,
- .start = acpi_pci_root_start,
- },
+ .name = ACPI_PCI_ROOT_DRIVER_NAME,
+ .class = ACPI_PCI_ROOT_CLASS,
+ .ids = ACPI_PCI_ROOT_HID,
+ .ops = {
+ .add = acpi_pci_root_add,
+ .remove = acpi_pci_root_remove,
+ .start = acpi_pci_root_start,
+ },
};
struct acpi_pci_root {
- struct list_head node;
- acpi_handle handle;
- struct acpi_pci_id id;
- struct pci_bus *bus;
+ struct list_head node;
+ acpi_handle handle;
+ struct acpi_pci_id id;
+ struct pci_bus *bus;
};
static LIST_HEAD(acpi_pci_roots);
@@ -92,6 +89,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver)
return n;
}
+
EXPORT_SYMBOL(acpi_pci_register_driver);
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
@@ -115,10 +113,11 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
driver->remove(root->handle);
}
}
+
EXPORT_SYMBOL(acpi_pci_unregister_driver);
static acpi_status
-get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
+get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{
int *busnr = (int *)data;
struct acpi_resource_address64 address;
@@ -129,20 +128,21 @@ get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
return AE_OK;
acpi_resource_to_address64(resource, &address);
- if ((address.address_length > 0) &&
- (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+ if ((address.address_length > 0) &&
+ (address.resource_type == ACPI_BUS_NUMBER_RANGE))
*busnr = address.min_address_range;
return AE_OK;
}
-static acpi_status
-try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
+static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
{
acpi_status status;
*busnum = -1;
- status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum);
+ status =
+ acpi_walk_resources(handle, METHOD_NAME__CRS,
+ get_root_bridge_busnr_callback, busnum);
if (ACPI_FAILURE(status))
return status;
/* Check if we really get a bus number from _CRS */
@@ -151,16 +151,14 @@ try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
return AE_OK;
}
-static int
-acpi_pci_root_add (
- struct acpi_device *device)
+static int acpi_pci_root_add(struct acpi_device *device)
{
- int result = 0;
- struct acpi_pci_root *root = NULL;
- struct acpi_pci_root *tmp;
- acpi_status status = AE_OK;
- unsigned long value = 0;
- acpi_handle handle = NULL;
+ int result = 0;
+ struct acpi_pci_root *root = NULL;
+ struct acpi_pci_root *tmp;
+ acpi_status status = AE_OK;
+ unsigned long value = 0;
+ acpi_handle handle = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_root_add");
@@ -188,15 +186,15 @@ acpi_pci_root_add (
* -------
* Obtained via _SEG, if exists, otherwise assumed to be zero (0).
*/
- status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL,
- &value);
+ status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL,
+ &value);
switch (status) {
case AE_OK:
root->id.segment = (u16) value;
break;
case AE_NOT_FOUND:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Assuming segment 0 (no _SEG)\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Assuming segment 0 (no _SEG)\n"));
root->id.segment = 0;
break;
default:
@@ -210,8 +208,8 @@ acpi_pci_root_add (
* ---
* Obtained via _BBN, if exists, otherwise assumed to be zero (0).
*/
- status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL,
- &value);
+ status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL,
+ &value);
switch (status) {
case AE_OK:
root->id.bus = (u16) value;
@@ -229,18 +227,19 @@ acpi_pci_root_add (
/* Some systems have wrong _BBN */
list_for_each_entry(tmp, &acpi_pci_roots, node) {
if ((tmp->id.segment == root->id.segment)
- && (tmp->id.bus == root->id.bus)) {
+ && (tmp->id.bus == root->id.bus)) {
int bus = 0;
acpi_status status;
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
status = try_get_root_bridge_busnr(root->handle, &bus);
if (ACPI_FAILURE(status))
break;
if (bus != root->id.bus) {
- printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus);
+ printk(KERN_INFO PREFIX
+ "PCI _CRS %d overrides _BBN 0\n", bus);
root->id.bus = bus;
}
break;
@@ -258,12 +257,12 @@ acpi_pci_root_add (
* TBD: Need PCI interface for enumeration/configuration of roots.
*/
- /* TBD: Locking */
- list_add_tail(&root->node, &acpi_pci_roots);
+ /* TBD: Locking */
+ list_add_tail(&root->node, &acpi_pci_roots);
- printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n",
- acpi_device_name(device), acpi_device_bid(device),
- root->id.segment, root->id.bus);
+ printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n",
+ acpi_device_name(device), acpi_device_bid(device),
+ root->id.segment, root->id.bus);
/*
* Scan the Root Bridge
@@ -274,9 +273,9 @@ acpi_pci_root_add (
*/
root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus);
if (!root->bus) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Bus %04x:%02x not present in PCI namespace\n",
- root->id.segment, root->id.bus));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Bus %04x:%02x not present in PCI namespace\n",
+ root->id.segment, root->id.bus));
result = -ENODEV;
goto end;
}
@@ -298,9 +297,9 @@ acpi_pci_root_add (
status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle);
if (ACPI_SUCCESS(status))
result = acpi_pci_irq_add_prt(root->handle, root->id.segment,
- root->id.bus);
+ root->id.bus);
-end:
+ end:
if (result) {
if (!list_empty(&root->node))
list_del(&root->node);
@@ -310,11 +309,9 @@ end:
return_VALUE(result);
}
-static int
-acpi_pci_root_start (
- struct acpi_device *device)
+static int acpi_pci_root_start(struct acpi_device *device)
{
- struct acpi_pci_root *root;
+ struct acpi_pci_root *root;
ACPI_FUNCTION_TRACE("acpi_pci_root_start");
@@ -327,27 +324,23 @@ acpi_pci_root_start (
return_VALUE(-ENODEV);
}
-static int
-acpi_pci_root_remove (
- struct acpi_device *device,
- int type)
+static int acpi_pci_root_remove(struct acpi_device *device, int type)
{
- struct acpi_pci_root *root = NULL;
+ struct acpi_pci_root *root = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_root_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- root = (struct acpi_pci_root *) acpi_driver_data(device);
+ root = (struct acpi_pci_root *)acpi_driver_data(device);
kfree(root);
return_VALUE(0);
}
-
-static int __init acpi_pci_root_init (void)
+static int __init acpi_pci_root_init(void)
{
ACPI_FUNCTION_TRACE("acpi_pci_root_init");
@@ -355,8 +348,8 @@ static int __init acpi_pci_root_init (void)
return_VALUE(0);
/* DEBUG:
- acpi_dbg_layer = ACPI_PCI_COMPONENT;
- acpi_dbg_level = 0xFFFFFFFF;
+ acpi_dbg_layer = ACPI_PCI_COMPONENT;
+ acpi_dbg_level = 0xFFFFFFFF;
*/
if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
@@ -366,4 +359,3 @@ static int __init acpi_pci_root_init (void)
}
subsys_initcall(acpi_pci_root_init);
-
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 373a3a95bb4e..62a5595ed8bc 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -44,10 +44,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_POWER_COMPONENT
-ACPI_MODULE_NAME ("acpi_power")
-
+ACPI_MODULE_NAME("acpi_power")
#define ACPI_POWER_COMPONENT 0x00800000
#define ACPI_POWER_CLASS "power_resource"
#define ACPI_POWER_DRIVER_NAME "ACPI Power Resource Driver"
@@ -57,38 +55,36 @@ ACPI_MODULE_NAME ("acpi_power")
#define ACPI_POWER_RESOURCE_STATE_OFF 0x00
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-
-static int acpi_power_add (struct acpi_device *device);
-static int acpi_power_remove (struct acpi_device *device, int type);
+static int acpi_power_add(struct acpi_device *device);
+static int acpi_power_remove(struct acpi_device *device, int type);
static int acpi_power_open_fs(struct inode *inode, struct file *file);
static struct acpi_driver acpi_power_driver = {
- .name = ACPI_POWER_DRIVER_NAME,
- .class = ACPI_POWER_CLASS,
- .ids = ACPI_POWER_HID,
- .ops = {
- .add = acpi_power_add,
- .remove = acpi_power_remove,
- },
+ .name = ACPI_POWER_DRIVER_NAME,
+ .class = ACPI_POWER_CLASS,
+ .ids = ACPI_POWER_HID,
+ .ops = {
+ .add = acpi_power_add,
+ .remove = acpi_power_remove,
+ },
};
-struct acpi_power_resource
-{
- acpi_handle handle;
- acpi_bus_id name;
- u32 system_level;
- u32 order;
- int state;
- int references;
+struct acpi_power_resource {
+ acpi_handle handle;
+ acpi_bus_id name;
+ u32 system_level;
+ u32 order;
+ int state;
+ int references;
};
-static struct list_head acpi_power_resource_list;
+static struct list_head acpi_power_resource_list;
static struct file_operations acpi_power_fops = {
- .open = acpi_power_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_power_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
/* --------------------------------------------------------------------------
@@ -96,12 +92,11 @@ static struct file_operations acpi_power_fops = {
-------------------------------------------------------------------------- */
static int
-acpi_power_get_context (
- acpi_handle handle,
- struct acpi_power_resource **resource)
+acpi_power_get_context(acpi_handle handle,
+ struct acpi_power_resource **resource)
{
- int result = 0;
- struct acpi_device *device = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_power_get_context");
@@ -111,24 +106,21 @@ acpi_power_get_context (
result = acpi_bus_get_device(handle, &device);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context [%p]\n",
- handle));
+ handle));
return_VALUE(result);
}
- *resource = (struct acpi_power_resource *) acpi_driver_data(device);
+ *resource = (struct acpi_power_resource *)acpi_driver_data(device);
if (!resource)
return_VALUE(-ENODEV);
return_VALUE(0);
}
-
-static int
-acpi_power_get_state (
- struct acpi_power_resource *resource)
+static int acpi_power_get_state(struct acpi_power_resource *resource)
{
- acpi_status status = AE_OK;
- unsigned long sta = 0;
+ acpi_status status = AE_OK;
+ unsigned long sta = 0;
ACPI_FUNCTION_TRACE("acpi_power_get_state");
@@ -145,20 +137,16 @@ acpi_power_get_state (
resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
- resource->name, resource->state?"on":"off"));
+ resource->name, resource->state ? "on" : "off"));
return_VALUE(0);
}
-
-static int
-acpi_power_get_list_state (
- struct acpi_handle_list *list,
- int *state)
+static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
{
- int result = 0;
+ int result = 0;
struct acpi_power_resource *resource = NULL;
- u32 i = 0;
+ u32 i = 0;
ACPI_FUNCTION_TRACE("acpi_power_get_list_state");
@@ -167,7 +155,7 @@ acpi_power_get_list_state (
/* The state of the list is 'on' IFF all resources are 'on'. */
- for (i=0; i<list->count; i++) {
+ for (i = 0; i < list->count; i++) {
result = acpi_power_get_context(list->handles[i], &resource);
if (result)
return_VALUE(result);
@@ -182,19 +170,16 @@ acpi_power_get_list_state (
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
- *state?"on":"off"));
+ *state ? "on" : "off"));
return_VALUE(result);
}
-
-static int
-acpi_power_on (
- acpi_handle handle)
+static int acpi_power_on(acpi_handle handle)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_device *device = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_device *device = NULL;
struct acpi_power_resource *resource = NULL;
ACPI_FUNCTION_TRACE("acpi_power_on");
@@ -205,10 +190,10 @@ acpi_power_on (
resource->references++;
- if ((resource->references > 1)
- || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
+ if ((resource->references > 1)
+ || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
- resource->name));
+ resource->name));
return_VALUE(0);
}
@@ -229,19 +214,16 @@ acpi_power_on (
device->power.state = ACPI_STATE_D0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
- resource->name));
+ resource->name));
return_VALUE(0);
}
-
-static int
-acpi_power_off_device (
- acpi_handle handle)
+static int acpi_power_off_device(acpi_handle handle)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_device *device = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_device *device = NULL;
struct acpi_power_resource *resource = NULL;
ACPI_FUNCTION_TRACE("acpi_power_off_device");
@@ -254,15 +236,15 @@ acpi_power_off_device (
resource->references--;
if (resource->references) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Resource [%s] is still in use, dereferencing\n",
- device->pnp.bus_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Resource [%s] is still in use, dereferencing\n",
+ device->pnp.bus_id));
return_VALUE(0);
}
if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
- device->pnp.bus_id));
+ device->pnp.bus_id));
return_VALUE(0);
}
@@ -283,7 +265,7 @@ acpi_power_off_device (
device->power.state = ACPI_STATE_D3;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
- resource->name));
+ resource->name));
return_VALUE(0);
}
@@ -293,13 +275,13 @@ acpi_power_off_device (
* 1. Power on the power resources required for the wakeup device
* 2. Enable _PSW (power state wake) for the device if present
*/
-int acpi_enable_wakeup_device_power (struct acpi_device *dev)
+int acpi_enable_wakeup_device_power(struct acpi_device *dev)
{
- union acpi_object arg = {ACPI_TYPE_INTEGER};
- struct acpi_object_list arg_list = {1, &arg};
- acpi_status status = AE_OK;
- int i;
- int ret = 0;
+ union acpi_object arg = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg };
+ acpi_status status = AE_OK;
+ int i;
+ int ret = 0;
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_power");
if (!dev || !dev->wakeup.flags.valid)
@@ -310,8 +292,8 @@ int acpi_enable_wakeup_device_power (struct acpi_device *dev)
for (i = 0; i < dev->wakeup.resources.count; i++) {
ret = acpi_power_on(dev->wakeup.resources.handles[i]);
if (ret) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error transition power state\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error transition power state\n"));
dev->wakeup.flags.valid = 0;
return_VALUE(-1);
}
@@ -333,20 +315,20 @@ int acpi_enable_wakeup_device_power (struct acpi_device *dev)
* 1. Disable _PSW (power state wake)
* 2. Shutdown down the power resources
*/
-int acpi_disable_wakeup_device_power (struct acpi_device *dev)
+int acpi_disable_wakeup_device_power(struct acpi_device *dev)
{
- union acpi_object arg = {ACPI_TYPE_INTEGER};
- struct acpi_object_list arg_list = {1, &arg};
- acpi_status status = AE_OK;
- int i;
- int ret = 0;
+ union acpi_object arg = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg };
+ acpi_status status = AE_OK;
+ int i;
+ int ret = 0;
ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device_power");
if (!dev || !dev->wakeup.flags.valid)
return_VALUE(-1);
- arg.integer.value = 0;
+ arg.integer.value = 0;
/* Execute PSW */
status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
@@ -359,8 +341,8 @@ int acpi_disable_wakeup_device_power (struct acpi_device *dev)
for (i = 0; i < dev->wakeup.resources.count; i++) {
ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
if (ret) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error transition power state\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error transition power state\n"));
dev->wakeup.flags.valid = 0;
return_VALUE(-1);
}
@@ -373,14 +355,12 @@ int acpi_disable_wakeup_device_power (struct acpi_device *dev)
Device Power Management
-------------------------------------------------------------------------- */
-int
-acpi_power_get_inferred_state (
- struct acpi_device *device)
+int acpi_power_get_inferred_state(struct acpi_device *device)
{
- int result = 0;
- struct acpi_handle_list *list = NULL;
- int list_state = 0;
- int i = 0;
+ int result = 0;
+ struct acpi_handle_list *list = NULL;
+ int list_state = 0;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_power_get_inferred_state");
@@ -393,7 +373,7 @@ acpi_power_get_inferred_state (
* We know a device's inferred power state when all the resources
* required for a given D-state are 'on'.
*/
- for (i=ACPI_STATE_D0; i<ACPI_STATE_D3; i++) {
+ for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) {
list = &device->power.states[i].resources;
if (list->count < 1)
continue;
@@ -413,23 +393,20 @@ acpi_power_get_inferred_state (
return_VALUE(0);
}
-
-int
-acpi_power_transition (
- struct acpi_device *device,
- int state)
+int acpi_power_transition(struct acpi_device *device, int state)
{
- int result = 0;
- struct acpi_handle_list *cl = NULL; /* Current Resources */
- struct acpi_handle_list *tl = NULL; /* Target Resources */
- int i = 0;
+ int result = 0;
+ struct acpi_handle_list *cl = NULL; /* Current Resources */
+ struct acpi_handle_list *tl = NULL; /* Target Resources */
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_power_transition");
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return_VALUE(-EINVAL);
- if ((device->power.state < ACPI_STATE_D0) || (device->power.state > ACPI_STATE_D3))
+ if ((device->power.state < ACPI_STATE_D0)
+ || (device->power.state > ACPI_STATE_D3))
return_VALUE(-ENODEV);
cl = &device->power.states[device->power.state].resources;
@@ -448,7 +425,7 @@ acpi_power_transition (
* First we reference all power resources required in the target list
* (e.g. so the device doesn't lose power while transitioning).
*/
- for (i=0; i<tl->count; i++) {
+ for (i = 0; i < tl->count; i++) {
result = acpi_power_on(tl->handles[i]);
if (result)
goto end;
@@ -457,7 +434,7 @@ acpi_power_transition (
/*
* Then we dereference all power resources used in the current list.
*/
- for (i=0; i<cl->count; i++) {
+ for (i = 0; i < cl->count; i++) {
result = acpi_power_off_device(cl->handles[i]);
if (result)
goto end;
@@ -465,21 +442,20 @@ acpi_power_transition (
/* We shouldn't change the state till all above operations succeed */
device->power.state = state;
-end:
+ end:
if (result)
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "Error transitioning device [%s] to D%d\n",
- device->pnp.bus_id, state));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Error transitioning device [%s] to D%d\n",
+ device->pnp.bus_id, state));
return_VALUE(result);
}
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_power_dir;
+static struct proc_dir_entry *acpi_power_dir;
static int acpi_power_seq_show(struct seq_file *seq, void *offset)
{
@@ -506,13 +482,12 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "system level: S%d\n"
- "order: %d\n"
- "reference count: %d\n",
- resource->system_level,
- resource->order,
- resource->references);
+ "order: %d\n"
+ "reference count: %d\n",
+ resource->system_level,
+ resource->order, resource->references);
-end:
+ end:
return_VALUE(0);
}
@@ -521,11 +496,9 @@ static int acpi_power_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_power_seq_show, PDE(inode)->data);
}
-static int
-acpi_power_add_fs (
- struct acpi_device *device)
+static int acpi_power_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_power_add_fs");
@@ -534,18 +507,18 @@ acpi_power_add_fs (
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_power_dir);
+ acpi_power_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
}
/* 'status' [R] */
entry = create_proc_entry(ACPI_POWER_FILE_STATUS,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_POWER_FILE_STATUS));
+ "Unable to create '%s' fs entry\n",
+ ACPI_POWER_FILE_STATUS));
else {
entry->proc_fops = &acpi_power_fops;
entry->data = acpi_driver_data(device);
@@ -554,10 +527,7 @@ acpi_power_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_power_remove_fs (
- struct acpi_device *device)
+static int acpi_power_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_power_remove_fs");
@@ -571,20 +541,17 @@ acpi_power_remove_fs (
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static int
-acpi_power_add (
- struct acpi_device *device)
+static int acpi_power_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
+ int result = 0;
+ acpi_status status = AE_OK;
struct acpi_power_resource *resource = NULL;
- union acpi_object acpi_object;
- struct acpi_buffer buffer = {sizeof(acpi_object), &acpi_object};
+ union acpi_object acpi_object;
+ struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
ACPI_FUNCTION_TRACE("acpi_power_add");
@@ -630,22 +597,18 @@ acpi_power_add (
result = acpi_power_add_fs(device);
if (result)
goto end;
-
+
printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
- acpi_device_bid(device), resource->state?"on":"off");
+ acpi_device_bid(device), resource->state ? "on" : "off");
-end:
+ end:
if (result)
kfree(resource);
-
+
return_VALUE(result);
}
-
-static int
-acpi_power_remove (
- struct acpi_device *device,
- int type)
+static int acpi_power_remove(struct acpi_device *device, int type)
{
struct acpi_power_resource *resource = NULL;
@@ -654,7 +617,7 @@ acpi_power_remove (
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- resource = (struct acpi_power_resource *) acpi_driver_data(device);
+ resource = (struct acpi_power_resource *)acpi_driver_data(device);
acpi_power_remove_fs(device);
@@ -663,10 +626,9 @@ acpi_power_remove (
return_VALUE(0);
}
-
-static int __init acpi_power_init (void)
+static int __init acpi_power_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_power_init");
@@ -689,4 +651,3 @@ static int __init acpi_power_init (void)
}
subsys_initcall(acpi_power_init);
-
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index d56a439ac614..421792562642 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -58,7 +58,6 @@
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
-
#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
@@ -75,59 +74,53 @@
#define ACPI_STA_PRESENT 0x00000001
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME ("acpi_processor")
+ACPI_MODULE_NAME("acpi_processor")
-MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
MODULE_LICENSE("GPL");
-
-static int acpi_processor_add (struct acpi_device *device);
-static int acpi_processor_start (struct acpi_device *device);
-static int acpi_processor_remove (struct acpi_device *device, int type);
+static int acpi_processor_add(struct acpi_device *device);
+static int acpi_processor_start(struct acpi_device *device);
+static int acpi_processor_remove(struct acpi_device *device, int type);
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static void acpi_processor_notify ( acpi_handle handle, u32 event, void *data);
+static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
static int acpi_processor_handle_eject(struct acpi_processor *pr);
static struct acpi_driver acpi_processor_driver = {
- .name = ACPI_PROCESSOR_DRIVER_NAME,
- .class = ACPI_PROCESSOR_CLASS,
- .ids = ACPI_PROCESSOR_HID,
- .ops = {
- .add = acpi_processor_add,
- .remove = acpi_processor_remove,
- .start = acpi_processor_start,
- },
+ .name = ACPI_PROCESSOR_DRIVER_NAME,
+ .class = ACPI_PROCESSOR_CLASS,
+ .ids = ACPI_PROCESSOR_HID,
+ .ops = {
+ .add = acpi_processor_add,
+ .remove = acpi_processor_remove,
+ .start = acpi_processor_start,
+ },
};
#define INSTALL_NOTIFY_HANDLER 1
#define UNINSTALL_NOTIFY_HANDLER 2
-
static struct file_operations acpi_processor_info_fops = {
- .open = acpi_processor_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_processor_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-
-struct acpi_processor *processors[NR_CPUS];
+struct acpi_processor *processors[NR_CPUS];
struct acpi_processor_errata errata;
-
/* --------------------------------------------------------------------------
Errata Handling
-------------------------------------------------------------------------- */
-static int
-acpi_processor_errata_piix4 (
- struct pci_dev *dev)
+static int acpi_processor_errata_piix4(struct pci_dev *dev)
{
- u8 rev = 0;
- u8 value1 = 0;
- u8 value2 = 0;
+ u8 rev = 0;
+ u8 value1 = 0;
+ u8 value2 = 0;
ACPI_FUNCTION_TRACE("acpi_processor_errata_piix4");
@@ -188,8 +181,8 @@ acpi_processor_errata_piix4 (
* DMA activity.
*/
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB,
- PCI_ANY_ID, PCI_ANY_ID, NULL);
+ PCI_DEVICE_ID_INTEL_82371AB,
+ PCI_ANY_ID, PCI_ANY_ID, NULL);
if (dev) {
errata.piix4.bmisx = pci_resource_start(dev, 4);
pci_dev_put(dev);
@@ -205,8 +198,8 @@ acpi_processor_errata_piix4 (
* devices won't operate well if fast DMA is disabled.
*/
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_0,
- PCI_ANY_ID, PCI_ANY_ID, NULL);
+ PCI_DEVICE_ID_INTEL_82371AB_0,
+ PCI_ANY_ID, PCI_ANY_ID, NULL);
if (dev) {
pci_read_config_byte(dev, 0x76, &value1);
pci_read_config_byte(dev, 0x77, &value2);
@@ -220,21 +213,18 @@ acpi_processor_errata_piix4 (
if (errata.piix4.bmisx)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Bus master activity detection (BM-IDE) erratum enabled\n"));
+ "Bus master activity detection (BM-IDE) erratum enabled\n"));
if (errata.piix4.fdma)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Type-F DMA livelock erratum (C3 disabled)\n"));
+ "Type-F DMA livelock erratum (C3 disabled)\n"));
return_VALUE(0);
}
-
-int
-acpi_processor_errata (
- struct acpi_processor *pr)
+static int acpi_processor_errata(struct acpi_processor *pr)
{
- int result = 0;
- struct pci_dev *dev = NULL;
+ int result = 0;
+ struct pci_dev *dev = NULL;
ACPI_FUNCTION_TRACE("acpi_processor_errata");
@@ -245,7 +235,8 @@ acpi_processor_errata (
* PIIX4
*/
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL);
+ PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
+ PCI_ANY_ID, NULL);
if (dev) {
result = acpi_processor_errata_piix4(dev);
pci_dev_put(dev);
@@ -254,7 +245,6 @@ acpi_processor_errata (
return_VALUE(result);
}
-
/* --------------------------------------------------------------------------
Common ACPI processor fucntions
-------------------------------------------------------------------------- */
@@ -265,13 +255,13 @@ acpi_processor_errata (
*/
int acpi_processor_set_pdc(struct acpi_processor *pr,
- struct acpi_object_list *pdc_in)
+ struct acpi_object_list *pdc_in)
{
- acpi_status status = AE_OK;
- u32 arg0_buf[3];
- union acpi_object arg0 = {ACPI_TYPE_BUFFER};
- struct acpi_object_list no_object = {1, &arg0};
- struct acpi_object_list *pdc;
+ acpi_status status = AE_OK;
+ u32 arg0_buf[3];
+ union acpi_object arg0 = { ACPI_TYPE_BUFFER };
+ struct acpi_object_list no_object = { 1, &arg0 };
+ struct acpi_object_list *pdc;
ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
@@ -286,21 +276,21 @@ int acpi_processor_set_pdc(struct acpi_processor *pr,
status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
if ((ACPI_FAILURE(status)) && (pdc_in))
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Error evaluating _PDC, using legacy perf. control...\n"));
return_VALUE(status);
}
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_processor_dir = NULL;
+static struct proc_dir_entry *acpi_processor_dir = NULL;
static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ struct acpi_processor *pr = (struct acpi_processor *)seq->private;
ACPI_FUNCTION_TRACE("acpi_processor_info_seq_show");
@@ -308,40 +298,37 @@ static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
goto end;
seq_printf(seq, "processor id: %d\n"
- "acpi id: %d\n"
- "bus mastering control: %s\n"
- "power management: %s\n"
- "throttling control: %s\n"
- "limit interface: %s\n",
- pr->id,
- pr->acpi_id,
- pr->flags.bm_control ? "yes" : "no",
- pr->flags.power ? "yes" : "no",
- pr->flags.throttling ? "yes" : "no",
- pr->flags.limit ? "yes" : "no");
-
-end:
+ "acpi id: %d\n"
+ "bus mastering control: %s\n"
+ "power management: %s\n"
+ "throttling control: %s\n"
+ "limit interface: %s\n",
+ pr->id,
+ pr->acpi_id,
+ pr->flags.bm_control ? "yes" : "no",
+ pr->flags.power ? "yes" : "no",
+ pr->flags.throttling ? "yes" : "no",
+ pr->flags.limit ? "yes" : "no");
+
+ end:
return_VALUE(0);
}
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_info_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
-
-static int
-acpi_processor_add_fs (
- struct acpi_device *device)
+static int acpi_processor_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_processor_add_fs");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_processor_dir);
+ acpi_processor_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
}
@@ -349,11 +336,11 @@ acpi_processor_add_fs (
/* 'info' [R] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_PROCESSOR_FILE_INFO));
+ "Unable to create '%s' fs entry\n",
+ ACPI_PROCESSOR_FILE_INFO));
else {
entry->proc_fops = &acpi_processor_info_fops;
entry->data = acpi_driver_data(device);
@@ -362,11 +349,12 @@ acpi_processor_add_fs (
/* 'throttling' [R/W] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_PROCESSOR_FILE_THROTTLING));
+ "Unable to create '%s' fs entry\n",
+ ACPI_PROCESSOR_FILE_THROTTLING));
else {
entry->proc_fops = &acpi_processor_throttling_fops;
entry->proc_fops->write = acpi_processor_write_throttling;
@@ -376,11 +364,12 @@ acpi_processor_add_fs (
/* 'limit' [R/W] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_PROCESSOR_FILE_LIMIT));
+ "Unable to create '%s' fs entry\n",
+ ACPI_PROCESSOR_FILE_LIMIT));
else {
entry->proc_fops = &acpi_processor_limit_fops;
entry->proc_fops->write = acpi_processor_write_limit;
@@ -391,18 +380,17 @@ acpi_processor_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_processor_remove_fs (
- struct acpi_device *device)
+static int acpi_processor_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_processor_remove_fs");
if (acpi_device_dir(device)) {
- remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,acpi_device_dir(device));
+ remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
+ acpi_device_dir(device));
remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
- acpi_device_dir(device));
- remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device));
+ acpi_device_dir(device));
+ remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
+ acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
acpi_device_dir(device) = NULL;
}
@@ -446,15 +434,13 @@ static u8 convert_acpiid_to_cpu(u8 acpi_id)
Driver Interface
-------------------------------------------------------------------------- */
-static int
-acpi_processor_get_info (
- struct acpi_processor *pr)
+static int acpi_processor_get_info(struct acpi_processor *pr)
{
- acpi_status status = 0;
- union acpi_object object = {0};
- struct acpi_buffer buffer = {sizeof(union acpi_object), &object};
- u8 cpu_index;
- static int cpu0_initialized;
+ acpi_status status = 0;
+ union acpi_object object = { 0 };
+ struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+ u8 cpu_index;
+ static int cpu0_initialized;
ACPI_FUNCTION_TRACE("acpi_processor_get_info");
@@ -473,11 +459,10 @@ acpi_processor_get_info (
if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) {
pr->flags.bm_control = 1;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Bus mastering arbitration control present\n"));
- }
- else
+ "Bus mastering arbitration control present\n"));
+ } else
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "No bus mastering arbitration control\n"));
+ "No bus mastering arbitration control\n"));
/*
* Evalute the processor object. Note that it is common on SMP to
@@ -487,50 +472,51 @@ acpi_processor_get_info (
status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error evaluating processor object\n"));
+ "Error evaluating processor object\n"));
return_VALUE(-ENODEV);
}
/*
* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
- * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
+ * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
*/
pr->acpi_id = object.processor.proc_id;
cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
- /* Handle UP system running SMP kernel, with no LAPIC in MADT */
- if ( !cpu0_initialized && (cpu_index == 0xff) &&
- (num_online_cpus() == 1)) {
- cpu_index = 0;
- }
-
- cpu0_initialized = 1;
-
- pr->id = cpu_index;
-
- /*
- * Extra Processor objects may be enumerated on MP systems with
- * less than the max # of CPUs. They should be ignored _iff
- * they are physically not present.
- */
- if (cpu_index >= NR_CPUS) {
- if (ACPI_FAILURE(acpi_processor_hotadd_init(pr->handle, &pr->id))) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error getting cpuindex for acpiid 0x%x\n",
- pr->acpi_id));
- return_VALUE(-ENODEV);
- }
- }
+ /* Handle UP system running SMP kernel, with no LAPIC in MADT */
+ if (!cpu0_initialized && (cpu_index == 0xff) &&
+ (num_online_cpus() == 1)) {
+ cpu_index = 0;
+ }
+
+ cpu0_initialized = 1;
+
+ pr->id = cpu_index;
+
+ /*
+ * Extra Processor objects may be enumerated on MP systems with
+ * less than the max # of CPUs. They should be ignored _iff
+ * they are physically not present.
+ */
+ if (cpu_index >= NR_CPUS) {
+ if (ACPI_FAILURE
+ (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error getting cpuindex for acpiid 0x%x\n",
+ pr->acpi_id));
+ return_VALUE(-ENODEV);
+ }
+ }
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
- pr->acpi_id));
+ pr->acpi_id));
if (!object.processor.pblk_address)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
else if (object.processor.pblk_length != 6)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
- object.processor.pblk_length));
+ object.processor.pblk_length));
else {
pr->throttling.address = object.processor.pblk_address;
pr->throttling.duty_offset = acpi_fadt.duty_offset;
@@ -557,13 +543,11 @@ acpi_processor_get_info (
return_VALUE(0);
}
-static int
-acpi_processor_start(
- struct acpi_device *device)
+static int acpi_processor_start(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_processor *pr;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_processor *pr;
ACPI_FUNCTION_TRACE("acpi_processor_start");
@@ -584,36 +568,30 @@ acpi_processor_start(
goto end;
status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify, pr);
+ acpi_processor_notify, pr);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing device notify handler\n"));
+ "Error installing device notify handler\n"));
}
acpi_processor_power_init(pr, device);
if (pr->flags.throttling) {
printk(KERN_INFO PREFIX "%s [%s] (supports",
- acpi_device_name(device), acpi_device_bid(device));
+ acpi_device_name(device), acpi_device_bid(device));
printk(" %d throttling states", pr->throttling.state_count);
printk(")\n");
}
-end:
+ end:
return_VALUE(result);
}
-
-
-static void
-acpi_processor_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_processor *pr = (struct acpi_processor *) data;
- struct acpi_device *device = NULL;
+ struct acpi_processor *pr = (struct acpi_processor *)data;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_processor_notify");
@@ -627,7 +605,7 @@ acpi_processor_notify (
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
acpi_processor_ppc_has_changed(pr);
acpi_bus_generate_event(device, event,
- pr->performance_platform_limit);
+ pr->performance_platform_limit);
break;
case ACPI_PROCESSOR_NOTIFY_POWER:
acpi_processor_cst_has_changed(pr);
@@ -635,19 +613,16 @@ acpi_processor_notify (
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-
-static int
-acpi_processor_add (
- struct acpi_device *device)
+static int acpi_processor_add(struct acpi_device *device)
{
- struct acpi_processor *pr = NULL;
+ struct acpi_processor *pr = NULL;
ACPI_FUNCTION_TRACE("acpi_processor_add");
@@ -667,21 +642,17 @@ acpi_processor_add (
return_VALUE(0);
}
-
-static int
-acpi_processor_remove (
- struct acpi_device *device,
- int type)
+static int acpi_processor_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
- struct acpi_processor *pr = NULL;
+ acpi_status status = AE_OK;
+ struct acpi_processor *pr = NULL;
ACPI_FUNCTION_TRACE("acpi_processor_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- pr = (struct acpi_processor *) acpi_driver_data(device);
+ pr = (struct acpi_processor *)acpi_driver_data(device);
if (pr->id >= NR_CPUS) {
kfree(pr);
@@ -696,10 +667,10 @@ acpi_processor_remove (
acpi_processor_power_exit(pr, device);
status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify);
+ acpi_processor_notify);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
}
acpi_processor_remove_fs(device);
@@ -718,33 +689,28 @@ acpi_processor_remove (
static int is_processor_present(acpi_handle handle);
-static int
-is_processor_present(
- acpi_handle handle)
+static int is_processor_present(acpi_handle handle)
{
- acpi_status status;
- unsigned long sta = 0;
+ acpi_status status;
+ unsigned long sta = 0;
ACPI_FUNCTION_TRACE("is_processor_present");
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_PRESENT)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Processor Device is not present\n"));
+ "Processor Device is not present\n"));
return_VALUE(0);
}
return_VALUE(1);
}
-
static
-int acpi_processor_device_add(
- acpi_handle handle,
- struct acpi_device **device)
+int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
{
- acpi_handle phandle;
- struct acpi_device *pdev;
- struct acpi_processor *pr;
+ acpi_handle phandle;
+ struct acpi_device *pdev;
+ struct acpi_processor *pr;
ACPI_FUNCTION_TRACE("acpi_processor_device_add");
@@ -766,21 +732,17 @@ int acpi_processor_device_add(
if (!pr)
return_VALUE(-ENODEV);
- if ((pr->id >=0) && (pr->id < NR_CPUS)) {
+ if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
}
return_VALUE(0);
}
-
static void
-acpi_processor_hotplug_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_processor *pr;
- struct acpi_device *device = NULL;
+ struct acpi_processor *pr;
+ struct acpi_device *device = NULL;
int result;
ACPI_FUNCTION_TRACE("acpi_processor_hotplug_notify");
@@ -789,8 +751,8 @@ acpi_processor_hotplug_notify (
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
printk("Processor driver received %s event\n",
- (event==ACPI_NOTIFY_BUS_CHECK)?
- "ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+ (event == ACPI_NOTIFY_BUS_CHECK) ?
+ "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
if (!is_processor_present(handle))
break;
@@ -799,14 +761,14 @@ acpi_processor_hotplug_notify (
result = acpi_processor_device_add(handle, &device);
if (result)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to add the device\n"));
+ "Unable to add the device\n"));
break;
}
pr = acpi_driver_data(device);
if (!pr) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Driver data is NULL\n"));
+ "Driver data is NULL\n"));
break;
}
@@ -816,24 +778,27 @@ acpi_processor_hotplug_notify (
}
result = acpi_processor_start(device);
- if ((!result) && ((pr->id >=0) && (pr->id < NR_CPUS))) {
+ if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
kobject_hotplug(&device->kobj, KOBJ_ONLINE);
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Device [%s] failed to start\n",
- acpi_device_bid(device)));
+ "Device [%s] failed to start\n",
+ acpi_device_bid(device)));
}
- break;
+ break;
case ACPI_NOTIFY_EJECT_REQUEST:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,"received ACPI_NOTIFY_EJECT_REQUEST\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "received ACPI_NOTIFY_EJECT_REQUEST\n"));
if (acpi_bus_get_device(handle, &device)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Device don't exist, dropping EJECT\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Device don't exist, dropping EJECT\n"));
break;
}
pr = acpi_driver_data(device);
if (!pr) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Driver data is NULL, dropping EJECT\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Driver data is NULL, dropping EJECT\n"));
return_VOID;
}
@@ -842,7 +807,7 @@ acpi_processor_hotplug_notify (
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
@@ -851,45 +816,39 @@ acpi_processor_hotplug_notify (
static acpi_status
processor_walk_namespace_cb(acpi_handle handle,
- u32 lvl,
- void *context,
- void **rv)
+ u32 lvl, void *context, void **rv)
{
- acpi_status status;
+ acpi_status status;
int *action = context;
- acpi_object_type type = 0;
+ acpi_object_type type = 0;
status = acpi_get_type(handle, &type);
if (ACPI_FAILURE(status))
- return(AE_OK);
+ return (AE_OK);
if (type != ACPI_TYPE_PROCESSOR)
- return(AE_OK);
+ return (AE_OK);
- switch(*action) {
+ switch (*action) {
case INSTALL_NOTIFY_HANDLER:
acpi_install_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify,
- NULL);
+ ACPI_SYSTEM_NOTIFY,
+ acpi_processor_hotplug_notify,
+ NULL);
break;
case UNINSTALL_NOTIFY_HANDLER:
acpi_remove_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify);
+ ACPI_SYSTEM_NOTIFY,
+ acpi_processor_hotplug_notify);
break;
default:
break;
}
- return(AE_OK);
+ return (AE_OK);
}
-
-static acpi_status
-acpi_processor_hotadd_init(
- acpi_handle handle,
- int *p_cpu)
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
{
ACPI_FUNCTION_TRACE("acpi_processor_hotadd_init");
@@ -908,57 +867,47 @@ acpi_processor_hotadd_init(
return_VALUE(AE_OK);
}
-
-static int
-acpi_processor_handle_eject(struct acpi_processor *pr)
+static int acpi_processor_handle_eject(struct acpi_processor *pr)
{
if (cpu_online(pr->id)) {
- return(-EINVAL);
+ return (-EINVAL);
}
arch_unregister_cpu(pr->id);
acpi_unmap_lsapic(pr->id);
- return(0);
+ return (0);
}
#else
-static acpi_status
-acpi_processor_hotadd_init(
- acpi_handle handle,
- int *p_cpu)
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
{
return AE_ERROR;
}
-static int
-acpi_processor_handle_eject(struct acpi_processor *pr)
+static int acpi_processor_handle_eject(struct acpi_processor *pr)
{
- return(-EINVAL);
+ return (-EINVAL);
}
#endif
-
static
void acpi_processor_install_hotplug_notify(void)
{
#ifdef CONFIG_ACPI_HOTPLUG_CPU
int action = INSTALL_NOTIFY_HANDLER;
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb,
- &action, NULL);
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ processor_walk_namespace_cb, &action, NULL);
#endif
}
-
static
void acpi_processor_uninstall_hotplug_notify(void)
{
#ifdef CONFIG_ACPI_HOTPLUG_CPU
int action = UNINSTALL_NOTIFY_HANDLER;
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb,
- &action, NULL);
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ processor_walk_namespace_cb, &action, NULL);
#endif
}
@@ -968,10 +917,9 @@ void acpi_processor_uninstall_hotplug_notify(void)
* ACPI, but needs symbols from this driver
*/
-static int __init
-acpi_processor_init (void)
+static int __init acpi_processor_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_processor_init");
@@ -998,9 +946,7 @@ acpi_processor_init (void)
return_VALUE(0);
}
-
-static void __exit
-acpi_processor_exit (void)
+static void __exit acpi_processor_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_processor_exit");
@@ -1017,7 +963,6 @@ acpi_processor_exit (void)
return_VOID;
}
-
module_init(acpi_processor_init);
module_exit(acpi_processor_exit);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2c04740c6543..26a3a4016115 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -48,15 +48,12 @@
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME ("acpi_processor")
-
+ACPI_MODULE_NAME("acpi_processor")
#define ACPI_PROCESSOR_FILE_POWER "power"
-
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-
-static void (*pm_idle_save)(void);
+static void (*pm_idle_save) (void);
module_param(max_cstate, uint, 0644);
static unsigned int nocst = 0;
@@ -69,7 +66,8 @@ module_param(nocst, uint, 0000);
* 100 HZ: 0x0000000F: 4 jiffies = 40ms
* reduce history for more aggressive entry into C3
*/
-static unsigned int bm_history = (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
+static unsigned int bm_history =
+ (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
module_param(bm_history, uint, 0644);
/* --------------------------------------------------------------------------
Power Management
@@ -87,34 +85,36 @@ static int set_max_cstate(struct dmi_system_id *id)
return 0;
printk(KERN_NOTICE PREFIX "%s detected - limiting to C%ld max_cstate."
- " Override with \"processor.max_cstate=%d\"\n", id->ident,
- (long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1);
+ " Override with \"processor.max_cstate=%d\"\n", id->ident,
+ (long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1);
max_cstate = (long)id->driver_data;
return 0;
}
-
static struct dmi_system_id __initdata processor_power_dmi_table[] = {
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
- { set_max_cstate, "Medion 41700", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }, (void*)1},
- { set_max_cstate, "Clevo 5600D", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307") },
- (void*)2},
+ {set_max_cstate, "IBM ThinkPad R40e", {
+ DMI_MATCH(DMI_BIOS_VENDOR,
+ "IBM"),
+ DMI_MATCH(DMI_BIOS_VERSION,
+ "1SET60WW")},
+ (void *)1},
+ {set_max_cstate, "Medion 41700", {
+ DMI_MATCH(DMI_BIOS_VENDOR,
+ "Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_BIOS_VERSION,
+ "R01-A1J")}, (void *)1},
+ {set_max_cstate, "Clevo 5600D", {
+ DMI_MATCH(DMI_BIOS_VENDOR,
+ "Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_BIOS_VERSION,
+ "SHE845M0.86C.0013.D.0302131307")},
+ (void *)2},
{},
};
-
-static inline u32
-ticks_elapsed (
- u32 t1,
- u32 t2)
+static inline u32 ticks_elapsed(u32 t1, u32 t2)
{
if (t2 >= t1)
return (t2 - t1);
@@ -124,13 +124,11 @@ ticks_elapsed (
return ((0xFFFFFFFF - t1) + t2);
}
-
static void
-acpi_processor_power_activate (
- struct acpi_processor *pr,
- struct acpi_processor_cx *new)
+acpi_processor_power_activate(struct acpi_processor *pr,
+ struct acpi_processor_cx *new)
{
- struct acpi_processor_cx *old;
+ struct acpi_processor_cx *old;
if (!pr || !new)
return;
@@ -139,7 +137,7 @@ acpi_processor_power_activate (
if (old)
old->promotion.count = 0;
- new->demotion.count = 0;
+ new->demotion.count = 0;
/* Cleanup from old state. */
if (old) {
@@ -147,7 +145,8 @@ acpi_processor_power_activate (
case ACPI_STATE_C3:
/* Disable bus master reload */
if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
+ ACPI_MTX_DO_NOT_LOCK);
break;
}
}
@@ -157,7 +156,8 @@ acpi_processor_power_activate (
case ACPI_STATE_C3:
/* Enable bus master reload */
if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1,
+ ACPI_MTX_DO_NOT_LOCK);
break;
}
@@ -166,17 +166,15 @@ acpi_processor_power_activate (
return;
}
+static atomic_t c3_cpu_count;
-static atomic_t c3_cpu_count;
-
-
-static void acpi_processor_idle (void)
+static void acpi_processor_idle(void)
{
- struct acpi_processor *pr = NULL;
+ struct acpi_processor *pr = NULL;
struct acpi_processor_cx *cx = NULL;
struct acpi_processor_cx *next_state = NULL;
- int sleep_ticks = 0;
- u32 t1, t2 = 0;
+ int sleep_ticks = 0;
+ u32 t1, t2 = 0;
pr = processors[raw_smp_processor_id()];
if (!pr)
@@ -208,8 +206,8 @@ static void acpi_processor_idle (void)
* for demotion.
*/
if (pr->flags.bm_check) {
- u32 bm_status = 0;
- unsigned long diff = jiffies - pr->power.bm_check_timestamp;
+ u32 bm_status = 0;
+ unsigned long diff = jiffies - pr->power.bm_check_timestamp;
if (diff > 32)
diff = 32;
@@ -223,11 +221,11 @@ static void acpi_processor_idle (void)
}
acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
- &bm_status, ACPI_MTX_DO_NOT_LOCK);
+ &bm_status, ACPI_MTX_DO_NOT_LOCK);
if (bm_status) {
pr->power.bm_activity++;
acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
- 1, ACPI_MTX_DO_NOT_LOCK);
+ 1, ACPI_MTX_DO_NOT_LOCK);
}
/*
* PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
@@ -236,7 +234,7 @@ static void acpi_processor_idle (void)
*/
else if (errata.piix4.bmisx) {
if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+ || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
pr->power.bm_activity++;
}
@@ -281,7 +279,7 @@ static void acpi_processor_idle (void)
else
safe_halt();
/*
- * TBD: Can't get time duration while in C1, as resumes
+ * TBD: Can't get time duration while in C1, as resumes
* go to an ISR rather than here. Need to instrument
* base interrupt handler.
*/
@@ -300,26 +298,27 @@ static void acpi_processor_idle (void)
/* Re-enable interrupts */
local_irq_enable();
/* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
+ sleep_ticks =
+ ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
break;
case ACPI_STATE_C3:
-
+
if (pr->flags.bm_check) {
if (atomic_inc_return(&c3_cpu_count) ==
- num_online_cpus()) {
+ num_online_cpus()) {
/*
* All CPUs are trying to go to C3
* Disable bus master arbitration
*/
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
- ACPI_MTX_DO_NOT_LOCK);
+ ACPI_MTX_DO_NOT_LOCK);
}
} else {
/* SMP with no shared cache... Invalidate cache */
ACPI_FLUSH_CPU_CACHE();
}
-
+
/* Get start time (ticks) */
t1 = inl(acpi_fadt.xpm_tmr_blk.address);
/* Invoke C3 */
@@ -331,13 +330,15 @@ static void acpi_processor_idle (void)
if (pr->flags.bm_check) {
/* Enable bus master arbitration */
atomic_dec(&c3_cpu_count);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
+ ACPI_MTX_DO_NOT_LOCK);
}
/* Re-enable interrupts */
local_irq_enable();
/* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
+ sleep_ticks =
+ ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
break;
default:
@@ -359,15 +360,18 @@ static void acpi_processor_idle (void)
((cx->promotion.state - pr->power.states) <= max_cstate)) {
if (sleep_ticks > cx->promotion.threshold.ticks) {
cx->promotion.count++;
- cx->demotion.count = 0;
- if (cx->promotion.count >= cx->promotion.threshold.count) {
+ cx->demotion.count = 0;
+ if (cx->promotion.count >=
+ cx->promotion.threshold.count) {
if (pr->flags.bm_check) {
- if (!(pr->power.bm_activity & cx->promotion.threshold.bm)) {
- next_state = cx->promotion.state;
+ if (!
+ (pr->power.bm_activity & cx->
+ promotion.threshold.bm)) {
+ next_state =
+ cx->promotion.state;
goto end;
}
- }
- else {
+ } else {
next_state = cx->promotion.state;
goto end;
}
@@ -392,7 +396,7 @@ static void acpi_processor_idle (void)
}
}
-end:
+ end:
/*
* Demote if current state exceeds max_cstate
*/
@@ -412,7 +416,7 @@ end:
return;
- easy_out:
+ easy_out:
/* do C1 instead of busy loop */
if (pm_idle_save)
pm_idle_save();
@@ -421,10 +425,7 @@ end:
return;
}
-
-static int
-acpi_processor_set_power_policy (
- struct acpi_processor *pr)
+static int acpi_processor_set_power_policy(struct acpi_processor *pr)
{
unsigned int i;
unsigned int state_is_set = 0;
@@ -432,7 +433,7 @@ acpi_processor_set_power_policy (
struct acpi_processor_cx *higher = NULL;
struct acpi_processor_cx *cx;
- ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy");
+ ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy");
if (!pr)
return_VALUE(-EINVAL);
@@ -447,7 +448,7 @@ acpi_processor_set_power_policy (
*/
/* startup state */
- for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
cx = &pr->power.states[i];
if (!cx->valid)
continue;
@@ -456,13 +457,13 @@ acpi_processor_set_power_policy (
pr->power.state = cx;
state_is_set++;
break;
- }
+ }
if (!state_is_set)
return_VALUE(-ENODEV);
/* demotion */
- for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
cx = &pr->power.states[i];
if (!cx->valid)
continue;
@@ -485,7 +486,7 @@ acpi_processor_set_power_policy (
continue;
if (higher) {
- cx->promotion.state = higher;
+ cx->promotion.state = higher;
cx->promotion.threshold.ticks = cx->latency_ticks;
if (cx->type >= ACPI_STATE_C2)
cx->promotion.threshold.count = 4;
@@ -498,11 +499,10 @@ acpi_processor_set_power_policy (
higher = cx;
}
- return_VALUE(0);
+ return_VALUE(0);
}
-
-static int acpi_processor_get_power_info_fadt (struct acpi_processor *pr)
+static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
int i;
@@ -543,15 +543,14 @@ static int acpi_processor_get_power_info_fadt (struct acpi_processor *pr)
return_VALUE(0);
}
-
-static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
+static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
{
int i;
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(&(pr->power.states[i]), 0,
+ memset(&(pr->power.states[i]), 0,
sizeof(struct acpi_processor_cx));
/* if info is obtained from pblk/fadt, type equals state */
@@ -567,14 +566,13 @@ static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
return_VALUE(0);
}
-
-static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
+static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
{
- acpi_status status = 0;
- acpi_integer count;
- int i;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *cst;
+ acpi_status status = 0;
+ acpi_integer count;
+ int i;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *cst;
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_cst");
@@ -583,20 +581,21 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
pr->power.count = 0;
for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(&(pr->power.states[i]), 0,
+ memset(&(pr->power.states[i]), 0,
sizeof(struct acpi_processor_cx));
status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No _CST, giving up\n"));
return_VALUE(-ENODEV);
- }
+ }
- cst = (union acpi_object *) buffer.pointer;
+ cst = (union acpi_object *)buffer.pointer;
/* There must be at least 2 elements */
if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "not enough elements in _CST\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "not enough elements in _CST\n"));
status = -EFAULT;
goto end;
}
@@ -605,15 +604,19 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
/* Validate number of power states. */
if (count < 1 || count != cst->package.count - 1) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "count given by _CST is not valid\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "count given by _CST is not valid\n"));
status = -EFAULT;
goto end;
}
/* We support up to ACPI_PROCESSOR_MAX_POWER. */
if (count > ACPI_PROCESSOR_MAX_POWER) {
- printk(KERN_WARNING "Limiting number of power states to max (%d)\n", ACPI_PROCESSOR_MAX_POWER);
- printk(KERN_WARNING "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
+ printk(KERN_WARNING
+ "Limiting number of power states to max (%d)\n",
+ ACPI_PROCESSOR_MAX_POWER);
+ printk(KERN_WARNING
+ "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
count = ACPI_PROCESSOR_MAX_POWER;
}
@@ -628,29 +631,29 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
memset(&cx, 0, sizeof(cx));
- element = (union acpi_object *) &(cst->package.elements[i]);
+ element = (union acpi_object *)&(cst->package.elements[i]);
if (element->type != ACPI_TYPE_PACKAGE)
continue;
if (element->package.count != 4)
continue;
- obj = (union acpi_object *) &(element->package.elements[0]);
+ obj = (union acpi_object *)&(element->package.elements[0]);
if (obj->type != ACPI_TYPE_BUFFER)
continue;
- reg = (struct acpi_power_register *) obj->buffer.pointer;
+ reg = (struct acpi_power_register *)obj->buffer.pointer;
if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO &&
- (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
+ (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
continue;
cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
- 0 : reg->address;
+ 0 : reg->address;
/* There should be an easy way to extract an integer... */
- obj = (union acpi_object *) &(element->package.elements[1]);
+ obj = (union acpi_object *)&(element->package.elements[1]);
if (obj->type != ACPI_TYPE_INTEGER)
continue;
@@ -660,17 +663,16 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
(reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
continue;
- if ((cx.type < ACPI_STATE_C1) ||
- (cx.type > ACPI_STATE_C3))
+ if ((cx.type < ACPI_STATE_C1) || (cx.type > ACPI_STATE_C3))
continue;
- obj = (union acpi_object *) &(element->package.elements[2]);
+ obj = (union acpi_object *)&(element->package.elements[2]);
if (obj->type != ACPI_TYPE_INTEGER)
continue;
cx.latency = obj->integer.value;
- obj = (union acpi_object *) &(element->package.elements[3]);
+ obj = (union acpi_object *)&(element->package.elements[3]);
if (obj->type != ACPI_TYPE_INTEGER)
continue;
@@ -680,19 +682,19 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx));
}
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", pr->power.count));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n",
+ pr->power.count));
/* Validate number of power states discovered */
if (pr->power.count < 2)
status = -ENODEV;
-end:
+ end:
acpi_os_free(buffer.pointer);
return_VALUE(status);
}
-
static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
{
ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c2");
@@ -706,8 +708,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
*/
else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "latency too large [%d]\n",
- cx->latency));
+ "latency too large [%d]\n", cx->latency));
return_VOID;
}
@@ -721,10 +722,8 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
return_VOID;
}
-
-static void acpi_processor_power_verify_c3(
- struct acpi_processor *pr,
- struct acpi_processor_cx *cx)
+static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
+ struct acpi_processor_cx *cx)
{
static int bm_check_flag;
@@ -739,8 +738,7 @@ static void acpi_processor_power_verify_c3(
*/
else if (cx->latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "latency too large [%d]\n",
- cx->latency));
+ "latency too large [%d]\n", cx->latency));
return_VOID;
}
@@ -753,7 +751,7 @@ static void acpi_processor_power_verify_c3(
*/
else if (errata.piix4.fdma) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "C3 not supported on PIIX4 with Type-F DMA\n"));
+ "C3 not supported on PIIX4 with Type-F DMA\n"));
return_VOID;
}
@@ -770,7 +768,7 @@ static void acpi_processor_power_verify_c3(
/* bus mastering control is necessary */
if (!pr->flags.bm_control) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "C3 support requires bus mastering control\n"));
+ "C3 support requires bus mastering control\n"));
return_VOID;
}
} else {
@@ -780,12 +778,12 @@ static void acpi_processor_power_verify_c3(
*/
if (acpi_fadt.wb_invd != 1) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cache invalidation should work properly"
- " for C3 to be enabled on SMP systems\n"));
+ "Cache invalidation should work properly"
+ " for C3 to be enabled on SMP systems\n"));
return_VOID;
}
acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD,
- 0, ACPI_MTX_DO_NOT_LOCK);
+ 0, ACPI_MTX_DO_NOT_LOCK);
}
/*
@@ -800,13 +798,12 @@ static void acpi_processor_power_verify_c3(
return_VOID;
}
-
static int acpi_processor_power_verify(struct acpi_processor *pr)
{
unsigned int i;
unsigned int working = 0;
- for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
struct acpi_processor_cx *cx = &pr->power.states[i];
switch (cx->type) {
@@ -830,8 +827,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
return (working);
}
-static int acpi_processor_get_power_info (
- struct acpi_processor *pr)
+static int acpi_processor_get_power_info(struct acpi_processor *pr)
{
unsigned int i;
int result;
@@ -874,16 +870,16 @@ static int acpi_processor_get_power_info (
return_VALUE(0);
}
-int acpi_processor_cst_has_changed (struct acpi_processor *pr)
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_processor_cst_has_changed");
if (!pr)
- return_VALUE(-EINVAL);
+ return_VALUE(-EINVAL);
- if ( nocst) {
+ if (nocst) {
return_VALUE(-ENODEV);
}
@@ -892,7 +888,7 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr)
/* Fall back to the default idle loop */
pm_idle = pm_idle_save;
- synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
+ synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
pr->flags.power = 0;
result = acpi_processor_get_power_info(pr);
@@ -906,8 +902,8 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr)
static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
- unsigned int i;
+ struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ unsigned int i;
ACPI_FUNCTION_TRACE("acpi_processor_power_seq_show");
@@ -915,17 +911,17 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
goto end;
seq_printf(seq, "active state: C%zd\n"
- "max_cstate: C%d\n"
- "bus master activity: %08x\n",
- pr->power.state ? pr->power.state - pr->power.states : 0,
- max_cstate,
- (unsigned)pr->power.bm_activity);
+ "max_cstate: C%d\n"
+ "bus master activity: %08x\n",
+ pr->power.state ? pr->power.state - pr->power.states : 0,
+ max_cstate, (unsigned)pr->power.bm_activity);
seq_puts(seq, "states:\n");
for (i = 1; i <= pr->power.count; i++) {
seq_printf(seq, " %cC%d: ",
- (&pr->power.states[i] == pr->power.state?'*':' '), i);
+ (&pr->power.states[i] ==
+ pr->power.state ? '*' : ' '), i);
if (!pr->power.states[i].valid) {
seq_puts(seq, "<not supported>\n");
@@ -949,45 +945,46 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
if (pr->power.states[i].promotion.state)
seq_printf(seq, "promotion[C%zd] ",
- (pr->power.states[i].promotion.state -
- pr->power.states));
+ (pr->power.states[i].promotion.state -
+ pr->power.states));
else
seq_puts(seq, "promotion[--] ");
if (pr->power.states[i].demotion.state)
seq_printf(seq, "demotion[C%zd] ",
- (pr->power.states[i].demotion.state -
- pr->power.states));
+ (pr->power.states[i].demotion.state -
+ pr->power.states));
else
seq_puts(seq, "demotion[--] ");
seq_printf(seq, "latency[%03d] usage[%08d]\n",
- pr->power.states[i].latency,
- pr->power.states[i].usage);
+ pr->power.states[i].latency,
+ pr->power.states[i].usage);
}
-end:
+ end:
return_VALUE(0);
}
static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_power_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
static struct file_operations acpi_processor_power_fops = {
- .open = acpi_processor_power_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_processor_power_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device)
+int acpi_processor_power_init(struct acpi_processor *pr,
+ struct acpi_device *device)
{
- acpi_status status = 0;
- static int first_run = 0;
- struct proc_dir_entry *entry = NULL;
+ acpi_status status = 0;
+ static int first_run = 0;
+ struct proc_dir_entry *entry = NULL;
unsigned int i;
ACPI_FUNCTION_TRACE("acpi_processor_power_init");
@@ -995,7 +992,9 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
if (!first_run) {
dmi_check_system(processor_power_dmi_table);
if (max_cstate < ACPI_C_STATES_MAX)
- printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", max_cstate);
+ printk(KERN_NOTICE
+ "ACPI: processor limited to max C-state %d\n",
+ max_cstate);
first_run++;
}
@@ -1003,7 +1002,8 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
return_VALUE(-EINVAL);
if (acpi_fadt.cst_cnt && !nocst) {
- status = acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8);
+ status =
+ acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Notifying BIOS of _CST ability failed\n"));
@@ -1023,7 +1023,8 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
for (i = 1; i <= pr->power.count; i++)
if (pr->power.states[i].valid)
- printk(" C%d[C%d]", i, pr->power.states[i].type);
+ printk(" C%d[C%d]", i,
+ pr->power.states[i].type);
printk(")\n");
if (pr->id == 0) {
@@ -1034,11 +1035,11 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
/* 'power' [R] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_PROCESSOR_FILE_POWER));
+ "Unable to create '%s' fs entry\n",
+ ACPI_PROCESSOR_FILE_POWER));
else {
entry->proc_fops = &acpi_processor_power_fops;
entry->data = acpi_driver_data(device);
@@ -1050,14 +1051,16 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
return_VALUE(0);
}
-int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device)
+int acpi_processor_power_exit(struct acpi_processor *pr,
+ struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_processor_power_exit");
pr->flags.power_setup_done = 0;
if (acpi_device_dir(device))
- remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device));
+ remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
+ acpi_device_dir(device));
/* Unregister the idle handler when processor #0 is removed. */
if (pr->id == 0) {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 1f0d6256302f..22c7bb66c200 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -26,7 +26,6 @@
*
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -42,14 +41,12 @@
#include <acpi/acpi_bus.h>
#include <acpi/processor.h>
-
#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME ("acpi_processor")
-
+ACPI_MODULE_NAME("acpi_processor")
static DECLARE_MUTEX(performance_sem);
@@ -69,8 +66,7 @@ static DECLARE_MUTEX(performance_sem);
static int acpi_processor_ppc_status = 0;
static int acpi_processor_ppc_notifier(struct notifier_block *nb,
- unsigned long event,
- void *data)
+ unsigned long event, void *data)
{
struct cpufreq_policy *policy = data;
struct acpi_processor *pr;
@@ -85,7 +81,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
if (!pr || !pr->performance)
goto out;
- ppc = (unsigned int) pr->performance_platform_limit;
+ ppc = (unsigned int)pr->performance_platform_limit;
if (!ppc)
goto out;
@@ -93,26 +89,23 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
goto out;
cpufreq_verify_within_limits(policy, 0,
- pr->performance->states[ppc].core_frequency * 1000);
+ pr->performance->states[ppc].
+ core_frequency * 1000);
- out:
+ out:
up(&performance_sem);
return 0;
}
-
static struct notifier_block acpi_ppc_notifier_block = {
.notifier_call = acpi_processor_ppc_notifier,
};
-
-static int
-acpi_processor_get_platform_limit (
- struct acpi_processor* pr)
+static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
{
- acpi_status status = 0;
- unsigned long ppc = 0;
+ acpi_status status = 0;
+ unsigned long ppc = 0;
ACPI_FUNCTION_TRACE("acpi_processor_get_platform_limit");
@@ -128,19 +121,17 @@ acpi_processor_get_platform_limit (
if (status != AE_NOT_FOUND)
acpi_processor_ppc_status |= PPC_IN_USE;
- if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n"));
return_VALUE(-ENODEV);
}
- pr->performance_platform_limit = (int) ppc;
+ pr->performance_platform_limit = (int)ppc;
return_VALUE(0);
}
-
-int acpi_processor_ppc_has_changed(
- struct acpi_processor *pr)
+int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
{
int ret = acpi_processor_get_platform_limit(pr);
if (ret < 0)
@@ -149,44 +140,44 @@ int acpi_processor_ppc_has_changed(
return cpufreq_update_policy(pr->id);
}
-
-void acpi_processor_ppc_init(void) {
- if (!cpufreq_register_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
+void acpi_processor_ppc_init(void)
+{
+ if (!cpufreq_register_notifier
+ (&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
acpi_processor_ppc_status |= PPC_REGISTERED;
else
- printk(KERN_DEBUG "Warning: Processor Platform Limit not supported.\n");
+ printk(KERN_DEBUG
+ "Warning: Processor Platform Limit not supported.\n");
}
-
-void acpi_processor_ppc_exit(void) {
+void acpi_processor_ppc_exit(void)
+{
if (acpi_processor_ppc_status & PPC_REGISTERED)
- cpufreq_unregister_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+ cpufreq_unregister_notifier(&acpi_ppc_notifier_block,
+ CPUFREQ_POLICY_NOTIFIER);
acpi_processor_ppc_status &= ~PPC_REGISTERED;
}
-
-static int
-acpi_processor_get_performance_control (
- struct acpi_processor *pr)
+static int acpi_processor_get_performance_control(struct acpi_processor *pr)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *pct = NULL;
- union acpi_object obj = {0};
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *pct = NULL;
+ union acpi_object obj = { 0 };
ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
- if(ACPI_FAILURE(status)) {
+ if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
return_VALUE(-ENODEV);
}
- pct = (union acpi_object *) buffer.pointer;
+ pct = (union acpi_object *)buffer.pointer;
if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
- || (pct->package.count != 2)) {
+ || (pct->package.count != 2)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
result = -EFAULT;
goto end;
@@ -199,15 +190,15 @@ acpi_processor_get_performance_control (
obj = pct->package.elements[0];
if ((obj.type != ACPI_TYPE_BUFFER)
- || (obj.buffer.length < sizeof(struct acpi_pct_register))
- || (obj.buffer.pointer == NULL)) {
+ || (obj.buffer.length < sizeof(struct acpi_pct_register))
+ || (obj.buffer.pointer == NULL)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Invalid _PCT data (control_register)\n"));
+ "Invalid _PCT data (control_register)\n"));
result = -EFAULT;
goto end;
}
- memcpy(&pr->performance->control_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
-
+ memcpy(&pr->performance->control_register, obj.buffer.pointer,
+ sizeof(struct acpi_pct_register));
/*
* status_register
@@ -216,44 +207,42 @@ acpi_processor_get_performance_control (
obj = pct->package.elements[1];
if ((obj.type != ACPI_TYPE_BUFFER)
- || (obj.buffer.length < sizeof(struct acpi_pct_register))
- || (obj.buffer.pointer == NULL)) {
+ || (obj.buffer.length < sizeof(struct acpi_pct_register))
+ || (obj.buffer.pointer == NULL)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Invalid _PCT data (status_register)\n"));
+ "Invalid _PCT data (status_register)\n"));
result = -EFAULT;
goto end;
}
- memcpy(&pr->performance->status_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+ memcpy(&pr->performance->status_register, obj.buffer.pointer,
+ sizeof(struct acpi_pct_register));
-end:
+ end:
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
-
-static int
-acpi_processor_get_performance_states (
- struct acpi_processor *pr)
+static int acpi_processor_get_performance_states(struct acpi_processor *pr)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_buffer format = {sizeof("NNNNNN"), "NNNNNN"};
- struct acpi_buffer state = {0, NULL};
- union acpi_object *pss = NULL;
- int i;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer format = { sizeof("NNNNNN"), "NNNNNN" };
+ struct acpi_buffer state = { 0, NULL };
+ union acpi_object *pss = NULL;
+ int i;
ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
- if(ACPI_FAILURE(status)) {
+ if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
return_VALUE(-ENODEV);
}
- pss = (union acpi_object *) buffer.pointer;
+ pss = (union acpi_object *)buffer.pointer;
if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
result = -EFAULT;
@@ -261,10 +250,12 @@ acpi_processor_get_performance_states (
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
- pss->package.count));
+ pss->package.count));
pr->performance->state_count = pss->package.count;
- pr->performance->states = kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, GFP_KERNEL);
+ pr->performance->states =
+ kmalloc(sizeof(struct acpi_processor_px) * pss->package.count,
+ GFP_KERNEL);
if (!pr->performance->states) {
result = -ENOMEM;
goto end;
@@ -280,46 +271,44 @@ acpi_processor_get_performance_states (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
status = acpi_extract_package(&(pss->package.elements[i]),
- &format, &state);
+ &format, &state);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid _PSS data\n"));
result = -EFAULT;
kfree(pr->performance->states);
goto end;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
- i,
- (u32) px->core_frequency,
- (u32) px->power,
- (u32) px->transition_latency,
- (u32) px->bus_master_latency,
- (u32) px->control,
- (u32) px->status));
+ "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
+ i,
+ (u32) px->core_frequency,
+ (u32) px->power,
+ (u32) px->transition_latency,
+ (u32) px->bus_master_latency,
+ (u32) px->control, (u32) px->status));
if (!px->core_frequency) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data: freq is zero\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid _PSS data: freq is zero\n"));
result = -EFAULT;
kfree(pr->performance->states);
goto end;
}
}
-end:
+ end:
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
-
-static int
-acpi_processor_get_performance_info (
- struct acpi_processor *pr)
+static int acpi_processor_get_performance_info(struct acpi_processor *pr)
{
- int result = 0;
- acpi_status status = AE_OK;
- acpi_handle handle = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ acpi_handle handle = NULL;
ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
@@ -331,7 +320,7 @@ acpi_processor_get_performance_info (
status = acpi_get_handle(pr->handle, "_PCT", &handle);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "ACPI-based processor performance control unavailable\n"));
+ "ACPI-based processor performance control unavailable\n"));
return_VALUE(-ENODEV);
}
@@ -350,10 +339,10 @@ acpi_processor_get_performance_info (
return_VALUE(0);
}
-
-int acpi_processor_notify_smm(struct module *calling_module) {
- acpi_status status;
- static int is_done = 0;
+int acpi_processor_notify_smm(struct module *calling_module)
+{
+ acpi_status status;
+ static int is_done = 0;
ACPI_FUNCTION_TRACE("acpi_processor_notify_smm");
@@ -371,8 +360,7 @@ int acpi_processor_notify_smm(struct module *calling_module) {
if (is_done > 0) {
module_put(calling_module);
return_VALUE(0);
- }
- else if (is_done < 0) {
+ } else if (is_done < 0) {
module_put(calling_module);
return_VALUE(is_done);
}
@@ -380,28 +368,30 @@ int acpi_processor_notify_smm(struct module *calling_module) {
is_done = -EIO;
/* Can't write pstate_cnt to smi_cmd if either value is zero */
- if ((!acpi_fadt.smi_cmd) ||
- (!acpi_fadt.pstate_cnt)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "No SMI port or pstate_cnt\n"));
+ if ((!acpi_fadt.smi_cmd) || (!acpi_fadt.pstate_cnt)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_cnt\n"));
module_put(calling_module);
return_VALUE(0);
}
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n",
+ acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
/* FADT v1 doesn't support pstate_cnt, many BIOS vendors use
* it anyway, so we need to support it... */
if (acpi_fadt_is_v1) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Using v1.0 FADT reserved value for pstate_cnt\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Using v1.0 FADT reserved value for pstate_cnt\n"));
}
- status = acpi_os_write_port (acpi_fadt.smi_cmd,
- (u32) acpi_fadt.pstate_cnt, 8);
- if (ACPI_FAILURE (status)) {
+ status = acpi_os_write_port(acpi_fadt.smi_cmd,
+ (u32) acpi_fadt.pstate_cnt, 8);
+ if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Failed to write pstate_cnt [0x%x] to "
- "smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
+ "smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt,
+ acpi_fadt.smi_cmd));
module_put(calling_module);
return_VALUE(status);
}
@@ -415,24 +405,24 @@ int acpi_processor_notify_smm(struct module *calling_module) {
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_processor_notify_smm);
+EXPORT_SYMBOL(acpi_processor_notify_smm);
#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
/* /proc/acpi/processor/../performance interface (DEPRECATED) */
static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_processor_perf_fops = {
- .open = acpi_processor_perf_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_processor_perf_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
- int i;
+ struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ int i;
ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
@@ -445,42 +435,40 @@ static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "state count: %d\n"
- "active state: P%d\n",
- pr->performance->state_count,
- pr->performance->state);
+ "active state: P%d\n",
+ pr->performance->state_count, pr->performance->state);
seq_puts(seq, "states:\n");
for (i = 0; i < pr->performance->state_count; i++)
- seq_printf(seq, " %cP%d: %d MHz, %d mW, %d uS\n",
- (i == pr->performance->state?'*':' '), i,
- (u32) pr->performance->states[i].core_frequency,
- (u32) pr->performance->states[i].power,
- (u32) pr->performance->states[i].transition_latency);
-
-end:
+ seq_printf(seq,
+ " %cP%d: %d MHz, %d mW, %d uS\n",
+ (i == pr->performance->state ? '*' : ' '), i,
+ (u32) pr->performance->states[i].core_frequency,
+ (u32) pr->performance->states[i].power,
+ (u32) pr->performance->states[i].transition_latency);
+
+ end:
return_VALUE(0);
}
static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_perf_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
static ssize_t
-acpi_processor_write_performance (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+acpi_processor_write_performance(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- int result = 0;
- struct seq_file *m = (struct seq_file *) file->private_data;
- struct acpi_processor *pr = (struct acpi_processor *) m->private;
+ int result = 0;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_processor *pr = (struct acpi_processor *)m->private;
struct acpi_processor_performance *perf;
- char state_string[12] = {'\0'};
- unsigned int new_state = 0;
- struct cpufreq_policy policy;
+ char state_string[12] = { '\0' };
+ unsigned int new_state = 0;
+ struct cpufreq_policy policy;
ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
@@ -513,12 +501,10 @@ acpi_processor_write_performance (
return_VALUE(count);
}
-static void
-acpi_cpufreq_add_file (
- struct acpi_processor *pr)
+static void acpi_cpufreq_add_file(struct acpi_processor *pr)
{
- struct proc_dir_entry *entry = NULL;
- struct acpi_device *device = NULL;
+ struct proc_dir_entry *entry = NULL;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
@@ -527,11 +513,12 @@ acpi_cpufreq_add_file (
/* add file 'performance' [R/W] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_PROCESSOR_FILE_PERFORMANCE));
+ "Unable to create '%s' fs entry\n",
+ ACPI_PROCESSOR_FILE_PERFORMANCE));
else {
entry->proc_fops = &acpi_processor_perf_fops;
entry->proc_fops->write = acpi_processor_write_performance;
@@ -541,11 +528,9 @@ acpi_cpufreq_add_file (
return_VOID;
}
-static void
-acpi_cpufreq_remove_file (
- struct acpi_processor *pr)
+static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
{
- struct acpi_device *device = NULL;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
@@ -554,21 +539,25 @@ acpi_cpufreq_remove_file (
/* remove file 'performance' */
remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
- acpi_device_dir(device));
+ acpi_device_dir(device));
return_VOID;
}
#else
-static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
-static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
-#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
+static void acpi_cpufreq_add_file(struct acpi_processor *pr)
+{
+ return;
+}
+static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
+{
+ return;
+}
+#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
int
-acpi_processor_register_performance (
- struct acpi_processor_performance * performance,
- unsigned int cpu)
+acpi_processor_register_performance(struct acpi_processor_performance
+ *performance, unsigned int cpu)
{
struct acpi_processor *pr;
@@ -603,13 +592,12 @@ acpi_processor_register_performance (
up(&performance_sem);
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_processor_register_performance);
+EXPORT_SYMBOL(acpi_processor_register_performance);
void
-acpi_processor_unregister_performance (
- struct acpi_processor_performance * performance,
- unsigned int cpu)
+acpi_processor_unregister_performance(struct acpi_processor_performance
+ *performance, unsigned int cpu)
{
struct acpi_processor *pr;
@@ -632,4 +620,5 @@ acpi_processor_unregister_performance (
return_VOID;
}
+
EXPORT_SYMBOL(acpi_processor_unregister_performance);
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 12bd980a12e9..37528c3b64b0 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -43,20 +43,16 @@
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME ("acpi_processor")
-
+ACPI_MODULE_NAME("acpi_processor")
/* --------------------------------------------------------------------------
Limit Interface
-------------------------------------------------------------------------- */
-
-static int
-acpi_processor_apply_limit (
- struct acpi_processor* pr)
+static int acpi_processor_apply_limit(struct acpi_processor *pr)
{
- int result = 0;
- u16 px = 0;
- u16 tx = 0;
+ int result = 0;
+ u16 px = 0;
+ u16 tx = 0;
ACPI_FUNCTION_TRACE("acpi_processor_apply_limit");
@@ -80,19 +76,17 @@ acpi_processor_apply_limit (
pr->limit.state.px = px;
pr->limit.state.tx = tx;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d] limit set to (P%d:T%d)\n",
- pr->id,
- pr->limit.state.px,
- pr->limit.state.tx));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Processor [%d] limit set to (P%d:T%d)\n", pr->id,
+ pr->limit.state.px, pr->limit.state.tx));
-end:
+ end:
if (result)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n"));
return_VALUE(result);
}
-
#ifdef CONFIG_CPU_FREQ
/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
@@ -104,7 +98,6 @@ end:
static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
static unsigned int acpi_thermal_cpufreq_is_init = 0;
-
static int cpu_has_cpufreq(unsigned int cpu)
{
struct cpufreq_policy policy;
@@ -115,7 +108,6 @@ static int cpu_has_cpufreq(unsigned int cpu)
return 0;
}
-
static int acpi_thermal_cpufreq_increase(unsigned int cpu)
{
if (!cpu_has_cpufreq(cpu))
@@ -130,7 +122,6 @@ static int acpi_thermal_cpufreq_increase(unsigned int cpu)
return -ERANGE;
}
-
static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
{
if (!cpu_has_cpufreq(cpu))
@@ -145,11 +136,8 @@ static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
return -ERANGE;
}
-
-static int acpi_thermal_cpufreq_notifier(
- struct notifier_block *nb,
- unsigned long event,
- void *data)
+static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
{
struct cpufreq_policy *policy = data;
unsigned long max_freq = 0;
@@ -157,68 +145,74 @@ static int acpi_thermal_cpufreq_notifier(
if (event != CPUFREQ_ADJUST)
goto out;
- max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
+ max_freq =
+ (policy->cpuinfo.max_freq *
+ (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
cpufreq_verify_within_limits(policy, 0, max_freq);
- out:
+ out:
return 0;
}
-
static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
.notifier_call = acpi_thermal_cpufreq_notifier,
};
-
-void acpi_thermal_cpufreq_init(void) {
+void acpi_thermal_cpufreq_init(void)
+{
int i;
- for (i=0; i<NR_CPUS; i++)
+ for (i = 0; i < NR_CPUS; i++)
cpufreq_thermal_reduction_pctg[i] = 0;
- i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+ i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
+ CPUFREQ_POLICY_NOTIFIER);
if (!i)
acpi_thermal_cpufreq_is_init = 1;
}
-void acpi_thermal_cpufreq_exit(void) {
+void acpi_thermal_cpufreq_exit(void)
+{
if (acpi_thermal_cpufreq_is_init)
- cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+ cpufreq_unregister_notifier
+ (&acpi_thermal_cpufreq_notifier_block,
+ CPUFREQ_POLICY_NOTIFIER);
acpi_thermal_cpufreq_is_init = 0;
}
-#else /* ! CONFIG_CPU_FREQ */
-
-static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
+#else /* ! CONFIG_CPU_FREQ */
+static int acpi_thermal_cpufreq_increase(unsigned int cpu)
+{
+ return -ENODEV;
+}
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
+{
+ return -ENODEV;
+}
#endif
-
-int
-acpi_processor_set_thermal_limit (
- acpi_handle handle,
- int type)
+int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
{
- int result = 0;
- struct acpi_processor *pr = NULL;
- struct acpi_device *device = NULL;
- int tx = 0;
+ int result = 0;
+ struct acpi_processor *pr = NULL;
+ struct acpi_device *device = NULL;
+ int tx = 0;
ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
if ((type < ACPI_PROCESSOR_LIMIT_NONE)
- || (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
+ || (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
return_VALUE(-EINVAL);
result = acpi_bus_get_device(handle, &device);
if (result)
return_VALUE(result);
- pr = (struct acpi_processor *) acpi_driver_data(device);
+ pr = (struct acpi_processor *)acpi_driver_data(device);
if (!pr)
return_VALUE(-ENODEV);
@@ -250,12 +244,12 @@ acpi_processor_set_thermal_limit (
goto end;
else if (result == -ERANGE)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "At maximum performance state\n"));
+ "At maximum performance state\n"));
if (pr->flags.throttling) {
if (tx == (pr->throttling.state_count - 1))
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "At maximum throttling state\n"));
+ "At maximum throttling state\n"));
else
tx++;
}
@@ -267,7 +261,7 @@ acpi_processor_set_thermal_limit (
if (pr->flags.throttling) {
if (tx == 0)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "At minimum throttling state\n"));
+ "At minimum throttling state\n"));
else {
tx--;
goto end;
@@ -277,12 +271,12 @@ acpi_processor_set_thermal_limit (
result = acpi_thermal_cpufreq_decrease(pr->id);
if (result == -ERANGE)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "At minimum performance state\n"));
+ "At minimum performance state\n"));
break;
}
-end:
+ end:
if (pr->flags.throttling) {
pr->limit.thermal.px = 0;
pr->limit.thermal.tx = tx;
@@ -293,18 +287,14 @@ end:
"Unable to set thermal limit\n"));
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
- pr->limit.thermal.px,
- pr->limit.thermal.tx));
+ pr->limit.thermal.px, pr->limit.thermal.tx));
} else
result = 0;
return_VALUE(result);
}
-
-int
-acpi_processor_get_limit_info (
- struct acpi_processor *pr)
+int acpi_processor_get_limit_info(struct acpi_processor *pr)
{
ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info");
@@ -317,12 +307,11 @@ acpi_processor_get_limit_info (
return_VALUE(0);
}
-
/* /proc interface */
static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ struct acpi_processor *pr = (struct acpi_processor *)seq->private;
ACPI_FUNCTION_TRACE("acpi_processor_limit_seq_show");
@@ -335,34 +324,32 @@ static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "active limit: P%d:T%d\n"
- "user limit: P%d:T%d\n"
- "thermal limit: P%d:T%d\n",
- pr->limit.state.px, pr->limit.state.tx,
- pr->limit.user.px, pr->limit.user.tx,
- pr->limit.thermal.px, pr->limit.thermal.tx);
+ "user limit: P%d:T%d\n"
+ "thermal limit: P%d:T%d\n",
+ pr->limit.state.px, pr->limit.state.tx,
+ pr->limit.user.px, pr->limit.user.tx,
+ pr->limit.thermal.px, pr->limit.thermal.tx);
-end:
+ end:
return_VALUE(0);
}
static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_limit_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
-ssize_t acpi_processor_write_limit (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+ssize_t acpi_processor_write_limit(struct file * file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- int result = 0;
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_processor *pr = (struct acpi_processor *)m->private;
- char limit_string[25] = {'\0'};
- int px = 0;
- int tx = 0;
+ int result = 0;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_processor *pr = (struct acpi_processor *)m->private;
+ char limit_string[25] = { '\0' };
+ int px = 0;
+ int tx = 0;
ACPI_FUNCTION_TRACE("acpi_processor_write_limit");
@@ -396,11 +383,9 @@ ssize_t acpi_processor_write_limit (
return_VALUE(count);
}
-
struct file_operations acpi_processor_limit_fops = {
- .open = acpi_processor_limit_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_processor_limit_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index be9f569d39d3..74a52d4e79ae 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -43,21 +43,17 @@
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME ("acpi_processor")
-
+ACPI_MODULE_NAME("acpi_processor")
/* --------------------------------------------------------------------------
Throttling Control
-------------------------------------------------------------------------- */
-
-static int
-acpi_processor_get_throttling (
- struct acpi_processor *pr)
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
{
- int state = 0;
- u32 value = 0;
- u32 duty_mask = 0;
- u32 duty_value = 0;
+ int state = 0;
+ u32 value = 0;
+ u32 duty_mask = 0;
+ u32 duty_value = 0;
ACPI_FUNCTION_TRACE("acpi_processor_get_throttling");
@@ -86,7 +82,7 @@ acpi_processor_get_throttling (
duty_value >>= pr->throttling.duty_offset;
if (duty_value)
- state = pr->throttling.state_count-duty_value;
+ state = pr->throttling.state_count - duty_value;
}
pr->throttling.state = state;
@@ -94,20 +90,17 @@ acpi_processor_get_throttling (
local_irq_enable();
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Throttling state is T%d (%d%% throttling applied)\n",
- state, pr->throttling.states[state].performance));
+ "Throttling state is T%d (%d%% throttling applied)\n",
+ state, pr->throttling.states[state].performance));
return_VALUE(0);
}
-
-int acpi_processor_set_throttling (
- struct acpi_processor *pr,
- int state)
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
{
- u32 value = 0;
- u32 duty_mask = 0;
- u32 duty_value = 0;
+ u32 value = 0;
+ u32 duty_mask = 0;
+ u32 duty_value = 0;
ACPI_FUNCTION_TRACE("acpi_processor_set_throttling");
@@ -168,28 +161,26 @@ int acpi_processor_set_throttling (
local_irq_enable();
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Throttling state set to T%d (%d%%)\n", state,
- (pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0)));
+ "Throttling state set to T%d (%d%%)\n", state,
+ (pr->throttling.states[state].performance ? pr->
+ throttling.states[state].performance / 10 : 0)));
return_VALUE(0);
}
-
-int
-acpi_processor_get_throttling_info (
- struct acpi_processor *pr)
+int acpi_processor_get_throttling_info(struct acpi_processor *pr)
{
- int result = 0;
- int step = 0;
- int i = 0;
+ int result = 0;
+ int step = 0;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info");
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
- pr->throttling.address,
- pr->throttling.duty_offset,
- pr->throttling.duty_width));
+ "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
+ pr->throttling.address,
+ pr->throttling.duty_offset,
+ pr->throttling.duty_width));
if (!pr)
return_VALUE(-EINVAL);
@@ -199,14 +190,12 @@ acpi_processor_get_throttling_info (
if (!pr->throttling.address) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
return_VALUE(0);
- }
- else if (!pr->throttling.duty_width) {
+ } else if (!pr->throttling.duty_width) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
return_VALUE(0);
}
/* TBD: Support duty_cycle values that span bit 4. */
- else if ((pr->throttling.duty_offset
- + pr->throttling.duty_width) > 4) {
+ else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n"));
return_VALUE(0);
}
@@ -218,7 +207,7 @@ acpi_processor_get_throttling_info (
*/
if (errata.piix4.throttle) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Throttling not supported on PIIX4 A- or B-step\n"));
+ "Throttling not supported on PIIX4 A- or B-step\n"));
return_VALUE(0);
}
@@ -232,13 +221,13 @@ acpi_processor_get_throttling_info (
step = (1000 / pr->throttling.state_count);
- for (i=0; i<pr->throttling.state_count; i++) {
+ for (i = 0; i < pr->throttling.state_count; i++) {
pr->throttling.states[i].performance = step * i;
pr->throttling.states[i].power = step * i;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
- pr->throttling.state_count));
+ pr->throttling.state_count));
pr->flags.throttling = 1;
@@ -253,28 +242,29 @@ acpi_processor_get_throttling_info (
goto end;
if (pr->throttling.state) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n",
- pr->throttling.state));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Disabling throttling (was T%d)\n",
+ pr->throttling.state));
result = acpi_processor_set_throttling(pr, 0);
if (result)
goto end;
}
-end:
+ end:
if (result)
pr->flags.throttling = 0;
return_VALUE(result);
}
-
/* proc interface */
-static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset)
+static int acpi_processor_throttling_seq_show(struct seq_file *seq,
+ void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
- int i = 0;
- int result = 0;
+ struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ int i = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_processor_throttling_seq_show");
@@ -289,41 +279,41 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset
result = acpi_processor_get_throttling(pr);
if (result) {
- seq_puts(seq, "Could not determine current throttling state.\n");
+ seq_puts(seq,
+ "Could not determine current throttling state.\n");
goto end;
}
seq_printf(seq, "state count: %d\n"
- "active state: T%d\n",
- pr->throttling.state_count,
- pr->throttling.state);
+ "active state: T%d\n",
+ pr->throttling.state_count, pr->throttling.state);
seq_puts(seq, "states:\n");
for (i = 0; i < pr->throttling.state_count; i++)
seq_printf(seq, " %cT%d: %02d%%\n",
- (i == pr->throttling.state?'*':' '), i,
- (pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0));
+ (i == pr->throttling.state ? '*' : ' '), i,
+ (pr->throttling.states[i].performance ? pr->
+ throttling.states[i].performance / 10 : 0));
-end:
+ end:
return_VALUE(0);
}
-static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
+static int acpi_processor_throttling_open_fs(struct inode *inode,
+ struct file *file)
{
return single_open(file, acpi_processor_throttling_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
-ssize_t acpi_processor_write_throttling (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+ssize_t acpi_processor_write_throttling(struct file * file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- int result = 0;
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_processor *pr = (struct acpi_processor *)m->private;
- char state_string[12] = {'\0'};
+ int result = 0;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_processor *pr = (struct acpi_processor *)m->private;
+ char state_string[12] = { '\0' };
ACPI_FUNCTION_TRACE("acpi_processor_write_throttling");
@@ -336,7 +326,8 @@ ssize_t acpi_processor_write_throttling (
state_string[count] = '\0';
result = acpi_processor_set_throttling(pr,
- simple_strtoul(state_string, NULL, 0));
+ simple_strtoul(state_string,
+ NULL, 0));
if (result)
return_VALUE(result);
@@ -344,8 +335,8 @@ ssize_t acpi_processor_write_throttling (
}
struct file_operations acpi_processor_throttling_fops = {
- .open = acpi_processor_throttling_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_processor_throttling_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 55d264771c48..23b54baa0cb2 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -41,13 +41,185 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsaddr")
+ACPI_MODULE_NAME("rsaddr")
+
+/* Local prototypes */
+static void
+acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags);
+
+static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource);
+
+static void
+acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags);
+
+static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource);
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_decode_general_flags
+ *
+ * PARAMETERS: Resource - Address resource data struct
+ * Flags - Actual flag byte
+ *
+ * RETURN: Decoded flag bits in resource struct
+ *
+ * DESCRIPTION: Decode a general flag byte to an address resource struct
+ *
+ ******************************************************************************/
+
+static void
+acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags)
+{
+ ACPI_FUNCTION_ENTRY();
+
+ /* Producer / Consumer - flag bit[0] */
+
+ resource->address.producer_consumer = (u32) (flags & 0x01);
+
+ /* Decode (_DEC) - flag bit[1] */
+ resource->address.decode = (u32) ((flags >> 1) & 0x01);
+
+ /* Min Address Fixed (_MIF) - flag bit[2] */
+
+ resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01);
+
+ /* Max Address Fixed (_MAF) - flag bit[3] */
+
+ resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_encode_general_flags
+ *
+ * PARAMETERS: Resource - Address resource data struct
+ *
+ * RETURN: Encoded general flag byte
+ *
+ * DESCRIPTION: Construct a general flag byte from an address resource struct
+ *
+ ******************************************************************************/
+
+static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource)
+{
+ u8 flags;
+
+ ACPI_FUNCTION_ENTRY();
+
+ /* Producer / Consumer - flag bit[0] */
+
+ flags = (u8) (resource->address.producer_consumer & 0x01);
+
+ /* Decode (_DEC) - flag bit[1] */
+
+ flags |= (u8) ((resource->address.decode & 0x01) << 1);
+
+ /* Min Address Fixed (_MIF) - flag bit[2] */
+
+ flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2);
+
+ /* Max Address Fixed (_MAF) - flag bit[3] */
+
+ flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3);
+
+ return (flags);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_decode_specific_flags
+ *
+ * PARAMETERS: Resource - Address resource data struct
+ * Flags - Actual flag byte
+ *
+ * RETURN: Decoded flag bits in attribute struct
+ *
+ * DESCRIPTION: Decode a type-specific flag byte to an attribute struct.
+ * Type-specific flags are only defined for the Memory and IO
+ * resource types.
+ *
+ ******************************************************************************/
+
+static void
+acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags)
+{
+ ACPI_FUNCTION_ENTRY();
+
+ if (resource->address.resource_type == ACPI_MEMORY_RANGE) {
+ /* Write Status (_RW) - flag bit[0] */
+
+ resource->address.attribute.memory.read_write_attribute =
+ (u16) (flags & 0x01);
+
+ /* Memory Attributes (_MEM) - flag bits[2:1] */
+
+ resource->address.attribute.memory.cache_attribute =
+ (u16) ((flags >> 1) & 0x03);
+ } else if (resource->address.resource_type == ACPI_IO_RANGE) {
+ /* Ranges (_RNG) - flag bits[1:0] */
+
+ resource->address.attribute.io.range_attribute =
+ (u16) (flags & 0x03);
+
+ /* Translations (_TTP and _TRS) - flag bits[5:4] */
+
+ resource->address.attribute.io.translation_attribute =
+ (u16) ((flags >> 4) & 0x03);
+ }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_encode_specific_flags
+ *
+ * PARAMETERS: Resource - Address resource data struct
+ *
+ * RETURN: Encoded type-specific flag byte
+ *
+ * DESCRIPTION: Construct a type-specific flag byte from an attribute struct.
+ * Type-specific flags are only defined for the Memory and IO
+ * resource types.
+ *
+ ******************************************************************************/
+
+static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource)
+{
+ u8 flags = 0;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (resource->address.resource_type == ACPI_MEMORY_RANGE) {
+ /* Write Status (_RW) - flag bit[0] */
+
+ flags = (u8)
+ (resource->address.attribute.memory.
+ read_write_attribute & 0x01);
+
+ /* Memory Attributes (_MEM) - flag bits[2:1] */
+
+ flags |= (u8)
+ ((resource->address.attribute.memory.
+ cache_attribute & 0x03) << 1);
+ } else if (resource->address.resource_type == ACPI_IO_RANGE) {
+ /* Ranges (_RNG) - flag bits[1:0] */
+
+ flags = (u8)
+ (resource->address.attribute.io.range_attribute & 0x03);
+
+ /* Translations (_TTP and _TRS) - flag bits[5:4] */
+
+ flags |= (u8)
+ ((resource->address.attribute.io.
+ translation_attribute & 0x03) << 4);
+ }
+
+ return (flags);
+}
/*******************************************************************************
*
@@ -71,34 +243,30 @@
******************************************************************************/
acpi_status
-acpi_rs_address16_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_address16_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u32 index;
- u16 temp16;
- u8 temp8;
- u8 *temp_ptr;
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_address16);
-
+ u32 index;
+ u16 temp16;
+ u8 temp8;
+ u8 *temp_ptr;
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16);
- ACPI_FUNCTION_TRACE ("rs_address16_resource");
+ ACPI_FUNCTION_TRACE("rs_address16_resource");
-
- /* Point past the Descriptor to get the number of bytes consumed */
+ /* Get the Descriptor Length field */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 13) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
@@ -112,7 +280,7 @@ acpi_rs_address16_resource (
/* Values 0-2 and 0xC0-0xFF are valid */
if ((temp8 > 2) && (temp8 < 0xC0)) {
- return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
output_struct->data.address16.resource_type = temp8;
@@ -120,73 +288,41 @@ acpi_rs_address16_resource (
/* Get the General Flags (Byte4) */
buffer += 1;
- temp8 = *buffer;
-
- /* Producer / Consumer */
-
- output_struct->data.address16.producer_consumer = temp8 & 0x01;
-
- /* Decode */
-
- output_struct->data.address16.decode = (temp8 >> 1) & 0x01;
-
- /* Min Address Fixed */
-
- output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01;
-
- /* Max Address Fixed */
-
- output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
+ acpi_rs_decode_general_flags(&output_struct->data, *buffer);
/* Get the Type Specific Flags (Byte5) */
buffer += 1;
- temp8 = *buffer;
-
- if (ACPI_MEMORY_RANGE == output_struct->data.address16.resource_type) {
- output_struct->data.address16.attribute.memory.read_write_attribute =
- (u16) (temp8 & 0x01);
- output_struct->data.address16.attribute.memory.cache_attribute =
- (u16) ((temp8 >> 1) & 0x03);
- }
- else {
- if (ACPI_IO_RANGE == output_struct->data.address16.resource_type) {
- output_struct->data.address16.attribute.io.range_attribute =
- (u16) (temp8 & 0x03);
- output_struct->data.address16.attribute.io.translation_attribute =
- (u16) ((temp8 >> 4) & 0x03);
- }
- else {
- /* BUS_NUMBER_RANGE == Address16.Data->resource_type */
- /* Nothing needs to be filled in */
- }
- }
+ acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
/* Get Granularity (Bytes 6-7) */
buffer += 1;
- ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer);
+ ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer);
/* Get min_address_range (Bytes 8-9) */
buffer += 2;
- ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer);
+ ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range,
+ buffer);
/* Get max_address_range (Bytes 10-11) */
buffer += 2;
- ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer);
+ ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range,
+ buffer);
/* Get address_translation_offset (Bytes 12-13) */
buffer += 2;
- ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset,
- buffer);
+ ACPI_MOVE_16_TO_32(&output_struct->data.address16.
+ address_translation_offset, buffer);
/* Get address_length (Bytes 14-15) */
buffer += 2;
- ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer);
+ ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length,
+ buffer);
/* Resource Source Index (if present) */
@@ -205,8 +341,8 @@ acpi_rs_address16_resource (
if (*bytes_consumed > (16 + 1)) {
/* Dereference the Index */
- temp8 = *buffer;
- output_struct->data.address16.resource_source.index = (u32) temp8;
+ output_struct->data.address16.resource_source.index =
+ (u32) * buffer;
/* Point to the String */
@@ -215,28 +351,27 @@ acpi_rs_address16_resource (
/* Point the String pointer to the end of this structure */
output_struct->data.address16.resource_source.string_ptr =
- (char *)((u8 * )output_struct + struct_size);
+ (char *)((u8 *) output_struct + struct_size);
temp_ptr = (u8 *)
- output_struct->data.address16.resource_source.string_ptr;
+ output_struct->data.address16.resource_source.string_ptr;
- /* Copy the string into the buffer */
+ /* Copy the resource_source string into the buffer */
index = 0;
-
- while (0x00 != *buffer) {
+ while (*buffer) {
*temp_ptr = *buffer;
- temp_ptr += 1;
- buffer += 1;
- index += 1;
+ temp_ptr++;
+ buffer++;
+ index++;
}
- /* Add the terminating null */
-
- *temp_ptr = 0x00;
+ /* Add the terminating null and set the string length */
- output_struct->data.address16.resource_source.string_length = index + 1;
+ *temp_ptr = 0;
+ output_struct->data.address16.resource_source.string_length =
+ index + 1;
/*
* In order for the struct_size to fall on a 32-bit boundary,
@@ -244,10 +379,9 @@ acpi_rs_address16_resource (
* struct_size to the next 32-bit boundary.
*/
temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
- }
- else {
- output_struct->data.address16.resource_source.index = 0x00;
+ struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
+ } else {
+ output_struct->data.address16.resource_source.index = 0;
output_struct->data.address16.resource_source.string_length = 0;
output_struct->data.address16.resource_source.string_ptr = NULL;
}
@@ -259,10 +393,9 @@ acpi_rs_address16_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_address16_stream
@@ -280,24 +413,18 @@ acpi_rs_address16_resource (
******************************************************************************/
acpi_status
-acpi_rs_address16_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_address16_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u8 *length_field;
- u8 temp8;
- char *temp_pointer = NULL;
- acpi_size actual_bytes;
-
-
- ACPI_FUNCTION_TRACE ("rs_address16_stream");
+ u8 *buffer = *output_buffer;
+ u8 *length_field;
+ acpi_size actual_bytes;
+ ACPI_FUNCTION_TRACE("rs_address16_stream");
- /* The descriptor field is static */
+ /* Set the Descriptor Type field */
- *buffer = 0x88;
+ *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE;
buffer += 1;
/* Save a pointer to the Length field - to be filled in later */
@@ -307,98 +434,74 @@ acpi_rs_address16_stream (
/* Set the Resource Type (Memory, Io, bus_number) */
- temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
- *buffer = temp8;
+ *buffer = (u8) (linked_list->data.address16.resource_type & 0x03);
buffer += 1;
/* Set the general flags */
- temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
-
- temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
- temp8 |= (linked_list->data.address16.min_address_fixed & 0x01) << 2;
- temp8 |= (linked_list->data.address16.max_address_fixed & 0x01) << 3;
-
- *buffer = temp8;
+ *buffer = acpi_rs_encode_general_flags(&linked_list->data);
buffer += 1;
/* Set the type specific flags */
- temp8 = 0;
-
- if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) {
- temp8 = (u8)
- (linked_list->data.address16.attribute.memory.read_write_attribute &
- 0x01);
-
- temp8 |=
- (linked_list->data.address16.attribute.memory.cache_attribute &
- 0x03) << 1;
- }
- else if (ACPI_IO_RANGE == linked_list->data.address16.resource_type) {
- temp8 = (u8)
- (linked_list->data.address16.attribute.io.range_attribute &
- 0x03);
- temp8 |=
- (linked_list->data.address16.attribute.io.translation_attribute &
- 0x03) << 4;
- }
-
- *buffer = temp8;
+ *buffer = acpi_rs_encode_specific_flags(&linked_list->data);
buffer += 1;
/* Set the address space granularity */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity);
+ ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity);
buffer += 2;
/* Set the address range minimum */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range);
+ ACPI_MOVE_32_TO_16(buffer,
+ &linked_list->data.address16.min_address_range);
buffer += 2;
/* Set the address range maximum */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range);
+ ACPI_MOVE_32_TO_16(buffer,
+ &linked_list->data.address16.max_address_range);
buffer += 2;
/* Set the address translation offset */
- ACPI_MOVE_32_TO_16 (buffer,
- &linked_list->data.address16.address_translation_offset);
+ ACPI_MOVE_32_TO_16(buffer,
+ &linked_list->data.address16.
+ address_translation_offset);
buffer += 2;
/* Set the address length */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length);
+ ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length);
buffer += 2;
/* Resource Source Index and Resource Source are optional */
- if (0 != linked_list->data.address16.resource_source.string_length) {
- temp8 = (u8) linked_list->data.address16.resource_source.index;
-
- *buffer = temp8;
+ if (linked_list->data.address16.resource_source.string_length) {
+ *buffer =
+ (u8) linked_list->data.address16.resource_source.index;
buffer += 1;
- temp_pointer = (char *) buffer;
-
- /* Copy the string */
+ /* Copy the resource_source string */
- ACPI_STRCPY (temp_pointer,
- linked_list->data.address16.resource_source.string_ptr);
+ ACPI_STRCPY((char *)buffer,
+ linked_list->data.address16.resource_source.
+ string_ptr);
/*
- * Buffer needs to be set to the length of the sting + one for the
+ * Buffer needs to be set to the length of the string + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (
- linked_list->data.address16.resource_source.string_ptr) + 1);
+ buffer +=
+ (acpi_size) (ACPI_STRLEN
+ (linked_list->data.address16.resource_source.
+ string_ptr) + 1);
}
/* Return the number of bytes consumed in this operation */
- actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer);
+ actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer);
*bytes_consumed = actual_bytes;
/*
@@ -406,11 +509,10 @@ acpi_rs_address16_stream (
* minus the header size (3 bytes)
*/
actual_bytes -= 3;
- ACPI_MOVE_SIZE_TO_16 (length_field, &actual_bytes);
- return_ACPI_STATUS (AE_OK);
+ ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_address32_resource
@@ -433,36 +535,30 @@ acpi_rs_address16_stream (
******************************************************************************/
acpi_status
-acpi_rs_address32_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_address32_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer;
- struct acpi_resource *output_struct= (void *) *output_buffer;
- u16 temp16;
- u8 temp8;
- u8 *temp_ptr;
- acpi_size struct_size;
- u32 index;
-
-
- ACPI_FUNCTION_TRACE ("rs_address32_resource");
+ u16 temp16;
+ u8 temp8;
+ u8 *temp_ptr;
+ u32 index;
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32);
+ ACPI_FUNCTION_TRACE("rs_address32_resource");
- buffer = byte_stream_buffer;
- struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32);
-
- /* Point past the Descriptor to get the number of bytes consumed */
+ /* Get the Descriptor Length field */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 23) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
@@ -476,7 +572,7 @@ acpi_rs_address32_resource (
/* Values 0-2 and 0xC0-0xFF are valid */
if ((temp8 > 2) && (temp8 < 0xC0)) {
- return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
output_struct->data.address32.resource_type = temp8;
@@ -484,74 +580,41 @@ acpi_rs_address32_resource (
/* Get the General Flags (Byte4) */
buffer += 1;
- temp8 = *buffer;
-
- /* Producer / Consumer */
-
- output_struct->data.address32.producer_consumer = temp8 & 0x01;
-
- /* Decode */
-
- output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
-
- /* Min Address Fixed */
-
- output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
-
- /* Max Address Fixed */
-
- output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
+ acpi_rs_decode_general_flags(&output_struct->data, *buffer);
/* Get the Type Specific Flags (Byte5) */
buffer += 1;
- temp8 = *buffer;
-
- if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) {
- output_struct->data.address32.attribute.memory.read_write_attribute =
- (u16) (temp8 & 0x01);
-
- output_struct->data.address32.attribute.memory.cache_attribute =
- (u16) ((temp8 >> 1) & 0x03);
- }
- else {
- if (ACPI_IO_RANGE == output_struct->data.address32.resource_type) {
- output_struct->data.address32.attribute.io.range_attribute =
- (u16) (temp8 & 0x03);
- output_struct->data.address32.attribute.io.translation_attribute =
- (u16) ((temp8 >> 4) & 0x03);
- }
- else {
- /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */
- /* Nothing needs to be filled in */
- }
- }
+ acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
/* Get Granularity (Bytes 6-9) */
buffer += 1;
- ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer);
/* Get min_address_range (Bytes 10-13) */
buffer += 4;
- ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range,
+ buffer);
/* Get max_address_range (Bytes 14-17) */
buffer += 4;
- ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range,
+ buffer);
/* Get address_translation_offset (Bytes 18-21) */
buffer += 4;
- ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset,
- buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.address32.
+ address_translation_offset, buffer);
/* Get address_length (Bytes 22-25) */
buffer += 4;
- ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length,
+ buffer);
/* Resource Source Index (if present) */
@@ -568,9 +631,8 @@ acpi_rs_address32_resource (
if (*bytes_consumed > (26 + 1)) {
/* Dereference the Index */
- temp8 = *buffer;
output_struct->data.address32.resource_source.index =
- (u32) temp8;
+ (u32) * buffer;
/* Point to the String */
@@ -579,26 +641,27 @@ acpi_rs_address32_resource (
/* Point the String pointer to the end of this structure */
output_struct->data.address32.resource_source.string_ptr =
- (char *)((u8 *)output_struct + struct_size);
+ (char *)((u8 *) output_struct + struct_size);
temp_ptr = (u8 *)
- output_struct->data.address32.resource_source.string_ptr;
+ output_struct->data.address32.resource_source.string_ptr;
- /* Copy the string into the buffer */
+ /* Copy the resource_source string into the buffer */
index = 0;
- while (0x00 != *buffer) {
+ while (*buffer) {
*temp_ptr = *buffer;
- temp_ptr += 1;
- buffer += 1;
- index += 1;
+ temp_ptr++;
+ buffer++;
+ index++;
}
- /* Add the terminating null */
+ /* Add the terminating null and set the string length */
- *temp_ptr = 0x00;
- output_struct->data.address32.resource_source.string_length = index + 1;
+ *temp_ptr = 0;
+ output_struct->data.address32.resource_source.string_length =
+ index + 1;
/*
* In order for the struct_size to fall on a 32-bit boundary,
@@ -606,10 +669,9 @@ acpi_rs_address32_resource (
* struct_size to the next 32-bit boundary.
*/
temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
- }
- else {
- output_struct->data.address32.resource_source.index = 0x00;
+ struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
+ } else {
+ output_struct->data.address32.resource_source.index = 0;
output_struct->data.address32.resource_source.string_length = 0;
output_struct->data.address32.resource_source.string_ptr = NULL;
}
@@ -621,10 +683,9 @@ acpi_rs_address32_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_address32_stream
@@ -642,136 +703,105 @@ acpi_rs_address32_resource (
******************************************************************************/
acpi_status
-acpi_rs_address32_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_address32_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer;
- u16 *length_field;
- u8 temp8;
- char *temp_pointer;
-
-
- ACPI_FUNCTION_TRACE ("rs_address32_stream");
+ u8 *buffer;
+ u16 *length_field;
+ ACPI_FUNCTION_TRACE("rs_address32_stream");
buffer = *output_buffer;
- /* The descriptor field is static */
+ /* Set the Descriptor Type field */
- *buffer = 0x87;
+ *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE;
buffer += 1;
- /* Set a pointer to the Length field - to be filled in later */
+ /* Save a pointer to the Length field - to be filled in later */
- length_field = ACPI_CAST_PTR (u16, buffer);
+ length_field = ACPI_CAST_PTR(u16, buffer);
buffer += 2;
/* Set the Resource Type (Memory, Io, bus_number) */
- temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
-
- *buffer = temp8;
+ *buffer = (u8) (linked_list->data.address32.resource_type & 0x03);
buffer += 1;
/* Set the general flags */
- temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
- temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
- temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
- temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3;
-
- *buffer = temp8;
+ *buffer = acpi_rs_encode_general_flags(&linked_list->data);
buffer += 1;
/* Set the type specific flags */
- temp8 = 0;
-
- if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
- temp8 = (u8)
- (linked_list->data.address32.attribute.memory.read_write_attribute &
- 0x01);
-
- temp8 |=
- (linked_list->data.address32.attribute.memory.cache_attribute &
- 0x03) << 1;
- }
- else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) {
- temp8 = (u8)
- (linked_list->data.address32.attribute.io.range_attribute &
- 0x03);
- temp8 |=
- (linked_list->data.address32.attribute.io.translation_attribute &
- 0x03) << 4;
- }
-
- *buffer = temp8;
+ *buffer = acpi_rs_encode_specific_flags(&linked_list->data);
buffer += 1;
/* Set the address space granularity */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity);
+ ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity);
buffer += 4;
/* Set the address range minimum */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.address32.min_address_range);
buffer += 4;
/* Set the address range maximum */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.address32.max_address_range);
buffer += 4;
/* Set the address translation offset */
- ACPI_MOVE_32_TO_32 (buffer,
- &linked_list->data.address32.address_translation_offset);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.address32.
+ address_translation_offset);
buffer += 4;
/* Set the address length */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length);
+ ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length);
buffer += 4;
/* Resource Source Index and Resource Source are optional */
- if (0 != linked_list->data.address32.resource_source.string_length) {
- temp8 = (u8) linked_list->data.address32.resource_source.index;
-
- *buffer = temp8;
+ if (linked_list->data.address32.resource_source.string_length) {
+ *buffer =
+ (u8) linked_list->data.address32.resource_source.index;
buffer += 1;
- temp_pointer = (char *) buffer;
-
- /* Copy the string */
+ /* Copy the resource_source string */
- ACPI_STRCPY (temp_pointer,
- linked_list->data.address32.resource_source.string_ptr);
+ ACPI_STRCPY((char *)buffer,
+ linked_list->data.address32.resource_source.
+ string_ptr);
/*
- * Buffer needs to be set to the length of the sting + one for the
+ * Buffer needs to be set to the length of the string + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (
- linked_list->data.address32.resource_source.string_ptr) + 1);
+ buffer +=
+ (acpi_size) (ACPI_STRLEN
+ (linked_list->data.address32.resource_source.
+ string_ptr) + 1);
}
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
/*
* Set the length field to the number of bytes consumed
- * minus the header size (3 bytes)
+ * minus the header size (3 bytes)
*/
*length_field = (u16) (*bytes_consumed - 3);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_address64_resource
@@ -794,38 +824,35 @@ acpi_rs_address32_stream (
******************************************************************************/
acpi_status
-acpi_rs_address64_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_address64_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16;
- u8 temp8;
- u8 resource_type;
- u8 *temp_ptr;
- acpi_size struct_size;
- u32 index;
-
+ u16 temp16;
+ u8 temp8;
+ u8 resource_type;
+ u8 *temp_ptr;
+ u32 index;
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64);
- ACPI_FUNCTION_TRACE ("rs_address64_resource");
+ ACPI_FUNCTION_TRACE("rs_address64_resource");
+ /* Get the Descriptor Type */
- buffer = byte_stream_buffer;
- struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
resource_type = *buffer;
- /* Point past the Descriptor to get the number of bytes consumed */
+ /* Get the Descriptor Length field */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 43) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
@@ -839,7 +866,7 @@ acpi_rs_address64_resource (
/* Values 0-2 and 0xC0-0xFF are valid */
if ((temp8 > 2) && (temp8 < 0xC0)) {
- return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
output_struct->data.address64.resource_type = temp8;
@@ -847,48 +874,12 @@ acpi_rs_address64_resource (
/* Get the General Flags (Byte4) */
buffer += 1;
- temp8 = *buffer;
-
- /* Producer / Consumer */
-
- output_struct->data.address64.producer_consumer = temp8 & 0x01;
-
- /* Decode */
-
- output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
-
- /* Min Address Fixed */
-
- output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
-
- /* Max Address Fixed */
-
- output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
+ acpi_rs_decode_general_flags(&output_struct->data, *buffer);
/* Get the Type Specific Flags (Byte5) */
buffer += 1;
- temp8 = *buffer;
-
- if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) {
- output_struct->data.address64.attribute.memory.read_write_attribute =
- (u16) (temp8 & 0x01);
-
- output_struct->data.address64.attribute.memory.cache_attribute =
- (u16) ((temp8 >> 1) & 0x03);
- }
- else {
- if (ACPI_IO_RANGE == output_struct->data.address64.resource_type) {
- output_struct->data.address64.attribute.io.range_attribute =
- (u16) (temp8 & 0x03);
- output_struct->data.address64.attribute.io.translation_attribute =
- (u16) ((temp8 >> 4) & 0x03);
- }
- else {
- /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */
- /* Nothing needs to be filled in */
- }
- }
+ acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
/* Move past revision_id and Reserved byte */
@@ -899,30 +890,33 @@ acpi_rs_address64_resource (
/* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
buffer += 1;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
+ ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer);
/* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
buffer += 8;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
+ ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range,
+ buffer);
/* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
buffer += 8;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
+ ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range,
+ buffer);
/* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
buffer += 8;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset,
- buffer);
+ ACPI_MOVE_64_TO_64(&output_struct->data.address64.
+ address_translation_offset, buffer);
/* Get address_length (Bytes 38-45) or (Bytes 40-47) */
buffer += 8;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
+ ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length,
+ buffer);
- output_struct->data.address64.resource_source.index = 0x00;
+ output_struct->data.address64.resource_source.index = 0;
output_struct->data.address64.resource_source.string_length = 0;
output_struct->data.address64.resource_source.string_ptr = NULL;
@@ -930,11 +924,9 @@ acpi_rs_address64_resource (
/* Get type_specific_attribute (Bytes 48-55) */
buffer += 8;
- ACPI_MOVE_64_TO_64 (
- &output_struct->data.address64.type_specific_attributes,
- buffer);
- }
- else {
+ ACPI_MOVE_64_TO_64(&output_struct->data.address64.
+ type_specific_attributes, buffer);
+ } else {
output_struct->data.address64.type_specific_attributes = 0;
/* Resource Source Index (if present) */
@@ -954,9 +946,8 @@ acpi_rs_address64_resource (
if (*bytes_consumed > (46 + 1)) {
/* Dereference the Index */
- temp8 = *buffer;
output_struct->data.address64.resource_source.index =
- (u32) temp8;
+ (u32) * buffer;
/* Point to the String */
@@ -964,29 +955,31 @@ acpi_rs_address64_resource (
/* Point the String pointer to the end of this structure */
- output_struct->data.address64.resource_source.string_ptr =
- (char *)((u8 *)output_struct + struct_size);
+ output_struct->data.address64.resource_source.
+ string_ptr =
+ (char *)((u8 *) output_struct + struct_size);
temp_ptr = (u8 *)
- output_struct->data.address64.resource_source.string_ptr;
+ output_struct->data.address64.resource_source.
+ string_ptr;
- /* Copy the string into the buffer */
+ /* Copy the resource_source string into the buffer */
index = 0;
- while (0x00 != *buffer) {
+ while (*buffer) {
*temp_ptr = *buffer;
- temp_ptr += 1;
- buffer += 1;
- index += 1;
+ temp_ptr++;
+ buffer++;
+ index++;
}
/*
- * Add the terminating null
+ * Add the terminating null and set the string length
*/
- *temp_ptr = 0x00;
- output_struct->data.address64.resource_source.string_length =
- index + 1;
+ *temp_ptr = 0;
+ output_struct->data.address64.resource_source.
+ string_length = index + 1;
/*
* In order for the struct_size to fall on a 32-bit boundary,
@@ -994,7 +987,7 @@ acpi_rs_address64_resource (
* struct_size to the next 32-bit boundary.
*/
temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+ struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
}
}
@@ -1005,10 +998,9 @@ acpi_rs_address64_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_address64_stream
@@ -1026,132 +1018,101 @@ acpi_rs_address64_resource (
******************************************************************************/
acpi_status
-acpi_rs_address64_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_address64_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer;
- u16 *length_field;
- u8 temp8;
- char *temp_pointer;
-
-
- ACPI_FUNCTION_TRACE ("rs_address64_stream");
+ u8 *buffer;
+ u16 *length_field;
+ ACPI_FUNCTION_TRACE("rs_address64_stream");
buffer = *output_buffer;
- /* The descriptor field is static */
+ /* Set the Descriptor Type field */
- *buffer = 0x8A;
+ *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE;
buffer += 1;
- /* Set a pointer to the Length field - to be filled in later */
+ /* Save a pointer to the Length field - to be filled in later */
- length_field = ACPI_CAST_PTR (u16, buffer);
+ length_field = ACPI_CAST_PTR(u16, buffer);
buffer += 2;
/* Set the Resource Type (Memory, Io, bus_number) */
- temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
-
- *buffer = temp8;
+ *buffer = (u8) (linked_list->data.address64.resource_type & 0x03);
buffer += 1;
/* Set the general flags */
- temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
- temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
- temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
- temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
-
- *buffer = temp8;
+ *buffer = acpi_rs_encode_general_flags(&linked_list->data);
buffer += 1;
/* Set the type specific flags */
- temp8 = 0;
-
- if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
- temp8 = (u8)
- (linked_list->data.address64.attribute.memory.read_write_attribute &
- 0x01);
-
- temp8 |=
- (linked_list->data.address64.attribute.memory.cache_attribute &
- 0x03) << 1;
- }
- else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) {
- temp8 = (u8)
- (linked_list->data.address64.attribute.io.range_attribute &
- 0x03);
- temp8 |=
- (linked_list->data.address64.attribute.io.range_attribute &
- 0x03) << 4;
- }
-
- *buffer = temp8;
+ *buffer = acpi_rs_encode_specific_flags(&linked_list->data);
buffer += 1;
/* Set the address space granularity */
- ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity);
+ ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity);
buffer += 8;
/* Set the address range minimum */
- ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range);
+ ACPI_MOVE_64_TO_64(buffer,
+ &linked_list->data.address64.min_address_range);
buffer += 8;
/* Set the address range maximum */
- ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range);
+ ACPI_MOVE_64_TO_64(buffer,
+ &linked_list->data.address64.max_address_range);
buffer += 8;
/* Set the address translation offset */
- ACPI_MOVE_64_TO_64 (buffer,
- &linked_list->data.address64.address_translation_offset);
+ ACPI_MOVE_64_TO_64(buffer,
+ &linked_list->data.address64.
+ address_translation_offset);
buffer += 8;
/* Set the address length */
- ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length);
+ ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length);
buffer += 8;
/* Resource Source Index and Resource Source are optional */
- if (0 != linked_list->data.address64.resource_source.string_length) {
- temp8 = (u8) linked_list->data.address64.resource_source.index;
-
- *buffer = temp8;
+ if (linked_list->data.address64.resource_source.string_length) {
+ *buffer =
+ (u8) linked_list->data.address64.resource_source.index;
buffer += 1;
- temp_pointer = (char *) buffer;
+ /* Copy the resource_source string */
- /* Copy the string */
-
- ACPI_STRCPY (temp_pointer,
- linked_list->data.address64.resource_source.string_ptr);
+ ACPI_STRCPY((char *)buffer,
+ linked_list->data.address64.resource_source.
+ string_ptr);
/*
- * Buffer needs to be set to the length of the sting + one for the
+ * Buffer needs to be set to the length of the string + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (
- linked_list->data.address64.resource_source.string_ptr) + 1);
+ buffer +=
+ (acpi_size) (ACPI_STRLEN
+ (linked_list->data.address64.resource_source.
+ string_ptr) + 1);
}
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
/*
* Set the length field to the number of bytes consumed
* minus the header size (3 bytes)
*/
*length_field = (u16) (*bytes_consumed - 3);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 98176f2fcb5d..378f58390fc1 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -41,15 +41,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rscalc")
-
+ACPI_MODULE_NAME("rscalc")
/*******************************************************************************
*
@@ -66,19 +64,15 @@
* the resource data.
*
******************************************************************************/
-
acpi_status
-acpi_rs_get_byte_stream_length (
- struct acpi_resource *linked_list,
- acpi_size *size_needed)
+acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list,
+ acpi_size * size_needed)
{
- acpi_size byte_stream_size_needed = 0;
- acpi_size segment_size;
- u8 done = FALSE;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_byte_stream_length");
+ acpi_size byte_stream_size_needed = 0;
+ acpi_size segment_size;
+ u8 done = FALSE;
+ ACPI_FUNCTION_TRACE("rs_get_byte_stream_length");
while (!done) {
/* Init the variable that will hold the size to add to the total. */
@@ -145,11 +139,11 @@ acpi_rs_get_byte_stream_length (
*/
if (linked_list->data.vendor_specific.length > 7) {
segment_size = 3;
- }
- else {
+ } else {
segment_size = 1;
}
- segment_size += linked_list->data.vendor_specific.length;
+ segment_size +=
+ linked_list->data.vendor_specific.length;
break;
case ACPI_RSTYPE_END_TAG:
@@ -194,9 +188,11 @@ acpi_rs_get_byte_stream_length (
*/
segment_size = 16;
- if (linked_list->data.address16.resource_source.string_ptr) {
+ if (linked_list->data.address16.resource_source.
+ string_ptr) {
segment_size +=
- linked_list->data.address16.resource_source.string_length;
+ linked_list->data.address16.resource_source.
+ string_length;
segment_size++;
}
break;
@@ -211,9 +207,11 @@ acpi_rs_get_byte_stream_length (
*/
segment_size = 26;
- if (linked_list->data.address32.resource_source.string_ptr) {
+ if (linked_list->data.address32.resource_source.
+ string_ptr) {
segment_size +=
- linked_list->data.address32.resource_source.string_length;
+ linked_list->data.address32.resource_source.
+ string_length;
segment_size++;
}
break;
@@ -227,9 +225,11 @@ acpi_rs_get_byte_stream_length (
*/
segment_size = 46;
- if (linked_list->data.address64.resource_source.string_ptr) {
+ if (linked_list->data.address64.resource_source.
+ string_ptr) {
segment_size +=
- linked_list->data.address64.resource_source.string_length;
+ linked_list->data.address64.resource_source.
+ string_length;
segment_size++;
}
break;
@@ -244,11 +244,14 @@ acpi_rs_get_byte_stream_length (
* Resource Source + 1 for the null.
*/
segment_size = 9 + (((acpi_size)
- linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
+ linked_list->data.extended_irq.
+ number_of_interrupts - 1) * 4);
- if (linked_list->data.extended_irq.resource_source.string_ptr) {
+ if (linked_list->data.extended_irq.resource_source.
+ string_ptr) {
segment_size +=
- linked_list->data.extended_irq.resource_source.string_length;
+ linked_list->data.extended_irq.
+ resource_source.string_length;
segment_size++;
}
break;
@@ -257,9 +260,9 @@ acpi_rs_get_byte_stream_length (
/* If we get here, everything is out of sync, exit with error */
- return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
- } /* switch (linked_list->Id) */
+ } /* switch (linked_list->Id) */
/* Update the total */
@@ -267,17 +270,16 @@ acpi_rs_get_byte_stream_length (
/* Point to the next object */
- linked_list = ACPI_PTR_ADD (struct acpi_resource,
- linked_list, linked_list->length);
+ linked_list = ACPI_PTR_ADD(struct acpi_resource,
+ linked_list, linked_list->length);
}
/* This is the data the caller needs */
*size_needed = byte_stream_size_needed;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_list_length
@@ -297,32 +299,28 @@ acpi_rs_get_byte_stream_length (
******************************************************************************/
acpi_status
-acpi_rs_get_list_length (
- u8 *byte_stream_buffer,
- u32 byte_stream_buffer_length,
- acpi_size *size_needed)
+acpi_rs_get_list_length(u8 * byte_stream_buffer,
+ u32 byte_stream_buffer_length, acpi_size * size_needed)
{
- u32 buffer_size = 0;
- u32 bytes_parsed = 0;
- u8 number_of_interrupts = 0;
- u8 number_of_channels = 0;
- u8 resource_type;
- u32 structure_size;
- u32 bytes_consumed;
- u8 *buffer;
- u8 temp8;
- u16 temp16;
- u8 index;
- u8 additional_bytes;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_list_length");
-
+ u32 buffer_size = 0;
+ u32 bytes_parsed = 0;
+ u8 number_of_interrupts = 0;
+ u8 number_of_channels = 0;
+ u8 resource_type;
+ u32 structure_size;
+ u32 bytes_consumed;
+ u8 *buffer;
+ u8 temp8;
+ u16 temp16;
+ u8 index;
+ u8 additional_bytes;
+
+ ACPI_FUNCTION_TRACE("rs_get_list_length");
while (bytes_parsed < byte_stream_buffer_length) {
/* The next byte in the stream is the resource type */
- resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
+ resource_type = acpi_rs_get_resource_type(*byte_stream_buffer);
switch (resource_type) {
case ACPI_RDESC_TYPE_MEMORY_24:
@@ -331,10 +329,10 @@ acpi_rs_get_list_length (
*/
bytes_consumed = 12;
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24);
break;
-
case ACPI_RDESC_TYPE_LARGE_VENDOR:
/*
* Vendor Defined Resource
@@ -342,38 +340,39 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
++buffer;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
bytes_consumed = temp16 + 3;
/* Ensure a 32-bit boundary for the structure */
- temp16 = (u16) ACPI_ROUND_UP_to_32_bITS (temp16);
+ temp16 = (u16) ACPI_ROUND_UP_to_32_bITS(temp16);
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
- (temp16 * sizeof (u8));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) +
+ (temp16 * sizeof(u8));
break;
-
case ACPI_RDESC_TYPE_MEMORY_32:
/*
* 32-Bit Memory Range Resource
*/
bytes_consumed = 20;
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32);
break;
-
case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
/*
* 32-Bit Fixed Memory Resource
*/
bytes_consumed = 12;
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct
+ acpi_resource_fixed_mem32);
break;
-
case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
/*
* 64-Bit Address Resource
@@ -381,13 +380,14 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
++buffer;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
bytes_consumed = temp16 + 3;
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct
+ acpi_resource_address64);
break;
-
case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
/*
* 64-Bit Address Resource
@@ -395,7 +395,7 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
++buffer;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
bytes_consumed = temp16 + 3;
@@ -409,20 +409,19 @@ acpi_rs_get_list_length (
*/
if (43 < temp16) {
temp8 = (u8) (temp16 - 44);
- }
- else {
+ } else {
temp8 = 0;
}
/* Ensure a 64-bit boundary for the structure */
- temp8 = (u8) ACPI_ROUND_UP_to_64_bITS (temp8);
+ temp8 = (u8) ACPI_ROUND_UP_to_64_bITS(temp8);
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64) +
- (temp8 * sizeof (u8));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)
+ + (temp8 * sizeof(u8));
break;
-
case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
/*
* 32-Bit Address Resource
@@ -430,7 +429,7 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
++buffer;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
bytes_consumed = temp16 + 3;
@@ -444,20 +443,19 @@ acpi_rs_get_list_length (
*/
if (23 < temp16) {
temp8 = (u8) (temp16 - 24);
- }
- else {
+ } else {
temp8 = 0;
}
/* Ensure a 32-bit boundary for the structure */
- temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+ temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32) +
- (temp8 * sizeof (u8));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32)
+ + (temp8 * sizeof(u8));
break;
-
case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
/*
* 16-Bit Address Resource
@@ -465,7 +463,7 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
++buffer;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
bytes_consumed = temp16 + 3;
@@ -479,20 +477,19 @@ acpi_rs_get_list_length (
*/
if (13 < temp16) {
temp8 = (u8) (temp16 - 14);
- }
- else {
+ } else {
temp8 = 0;
}
/* Ensure a 32-bit boundary for the structure */
- temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+ temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16) +
- (temp8 * sizeof (u8));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16)
+ + (temp8 * sizeof(u8));
break;
-
case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
/*
* Extended IRQ
@@ -500,7 +497,7 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
++buffer;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
bytes_consumed = temp16 + 3;
@@ -527,21 +524,20 @@ acpi_rs_get_list_length (
*/
if (9 + additional_bytes < temp16) {
temp8 = (u8) (temp16 - (9 + additional_bytes));
- }
- else {
+ } else {
temp8 = 0;
}
/* Ensure a 32-bit boundary for the structure */
- temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+ temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq) +
- (additional_bytes * sizeof (u8)) +
- (temp8 * sizeof (u8));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq) +
+ (additional_bytes * sizeof(u8)) +
+ (temp8 * sizeof(u8));
break;
-
case ACPI_RDESC_TYPE_IRQ_FORMAT:
/*
* IRQ Resource.
@@ -550,10 +546,9 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
temp8 = *buffer;
- if(temp8 & 0x01) {
+ if (temp8 & 0x01) {
bytes_consumed = 4;
- }
- else {
+ } else {
bytes_consumed = 3;
}
@@ -563,7 +558,7 @@ acpi_rs_get_list_length (
/* Look at the number of bits set */
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
for (index = 0; index < 16; index++) {
if (temp16 & 0x1) {
@@ -573,11 +568,11 @@ acpi_rs_get_list_length (
temp16 >>= 1;
}
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io) +
- (number_of_interrupts * sizeof (u32));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_io) +
+ (number_of_interrupts * sizeof(u32));
break;
-
case ACPI_RDESC_TYPE_DMA_FORMAT:
/*
* DMA Resource
@@ -593,19 +588,19 @@ acpi_rs_get_list_length (
temp8 = *buffer;
- for(index = 0; index < 8; index++) {
- if(temp8 & 0x1) {
+ for (index = 0; index < 8; index++) {
+ if (temp8 & 0x1) {
++number_of_channels;
}
temp8 >>= 1;
}
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma) +
- (number_of_channels * sizeof (u32));
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma) +
+ (number_of_channels * sizeof(u32));
break;
-
case ACPI_RDESC_TYPE_START_DEPENDENT:
/*
* Start Dependent Functions Resource
@@ -614,17 +609,17 @@ acpi_rs_get_list_length (
buffer = byte_stream_buffer;
temp8 = *buffer;
- if(temp8 & 0x01) {
+ if (temp8 & 0x01) {
bytes_consumed = 2;
- }
- else {
+ } else {
bytes_consumed = 1;
}
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct
+ acpi_resource_start_dpf);
break;
-
case ACPI_RDESC_TYPE_END_DEPENDENT:
/*
* End Dependent Functions Resource
@@ -633,25 +628,24 @@ acpi_rs_get_list_length (
structure_size = ACPI_RESOURCE_LENGTH;
break;
-
case ACPI_RDESC_TYPE_IO_PORT:
/*
* IO Port Resource
*/
bytes_consumed = 8;
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_io);
break;
-
case ACPI_RDESC_TYPE_FIXED_IO_PORT:
/*
* Fixed IO Port Resource
*/
bytes_consumed = 4;
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io);
break;
-
case ACPI_RDESC_TYPE_SMALL_VENDOR:
/*
* Vendor Specific Resource
@@ -664,12 +658,12 @@ acpi_rs_get_list_length (
/* Ensure a 32-bit boundary for the structure */
- temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
- structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
- (temp8 * sizeof (u8));
+ temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
+ structure_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) +
+ (temp8 * sizeof(u8));
break;
-
case ACPI_RDESC_TYPE_END_TAG:
/*
* End Tag
@@ -679,18 +673,17 @@ acpi_rs_get_list_length (
byte_stream_buffer_length = bytes_parsed;
break;
-
default:
/*
* If we get here, everything is out of sync,
* exit with an error
*/
- return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
/* Update the return value and counter */
- buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+ buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(structure_size);
bytes_parsed += bytes_consumed;
/* Set the byte stream to point to the next resource */
@@ -701,10 +694,9 @@ acpi_rs_get_list_length (
/* This is the data the caller needs */
*size_needed = buffer_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_pci_routing_table_length
@@ -723,22 +715,19 @@ acpi_rs_get_list_length (
******************************************************************************/
acpi_status
-acpi_rs_get_pci_routing_table_length (
- union acpi_operand_object *package_object,
- acpi_size *buffer_size_needed)
+acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
+ acpi_size * buffer_size_needed)
{
- u32 number_of_elements;
- acpi_size temp_size_needed = 0;
- union acpi_operand_object **top_object_list;
- u32 index;
- union acpi_operand_object *package_element;
- union acpi_operand_object **sub_object_list;
- u8 name_found;
- u32 table_index;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_pci_routing_table_length");
+ u32 number_of_elements;
+ acpi_size temp_size_needed = 0;
+ union acpi_operand_object **top_object_list;
+ u32 index;
+ union acpi_operand_object *package_element;
+ union acpi_operand_object **sub_object_list;
+ u8 name_found;
+ u32 table_index;
+ ACPI_FUNCTION_TRACE("rs_get_pci_routing_table_length");
number_of_elements = package_object->package.count;
@@ -769,53 +758,51 @@ acpi_rs_get_pci_routing_table_length (
name_found = FALSE;
- for (table_index = 0; table_index < 4 && !name_found; table_index++) {
+ for (table_index = 0; table_index < 4 && !name_found;
+ table_index++) {
if ((ACPI_TYPE_STRING ==
- ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
-
- ((ACPI_TYPE_LOCAL_REFERENCE ==
- ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
-
- ((*sub_object_list)->reference.opcode ==
- AML_INT_NAMEPATH_OP))) {
+ ACPI_GET_OBJECT_TYPE(*sub_object_list))
+ ||
+ ((ACPI_TYPE_LOCAL_REFERENCE ==
+ ACPI_GET_OBJECT_TYPE(*sub_object_list))
+ && ((*sub_object_list)->reference.opcode ==
+ AML_INT_NAMEPATH_OP))) {
name_found = TRUE;
- }
- else {
+ } else {
/* Look at the next element */
sub_object_list++;
}
}
- temp_size_needed += (sizeof (struct acpi_pci_routing_table) - 4);
+ temp_size_needed += (sizeof(struct acpi_pci_routing_table) - 4);
/* Was a String type found? */
if (name_found) {
- if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) {
+ if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
+ ACPI_TYPE_STRING) {
/*
* The length String.Length field does not include the
* terminating NULL, add 1
*/
temp_size_needed += ((acpi_size)
- (*sub_object_list)->string.length + 1);
+ (*sub_object_list)->string.
+ length + 1);
+ } else {
+ temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
}
- else {
- temp_size_needed += acpi_ns_get_pathname_length (
- (*sub_object_list)->reference.node);
- }
- }
- else {
+ } else {
/*
* If no name was found, then this is a NULL, which is
* translated as a u32 zero.
*/
- temp_size_needed += sizeof (u32);
+ temp_size_needed += sizeof(u32);
}
/* Round up the size since each element must be aligned */
- temp_size_needed = ACPI_ROUND_UP_to_64_bITS (temp_size_needed);
+ temp_size_needed = ACPI_ROUND_UP_to_64_bITS(temp_size_needed);
/* Point to the next union acpi_operand_object */
@@ -826,6 +813,7 @@ acpi_rs_get_pci_routing_table_length (
* Adding an extra element to the end of the list, essentially a
* NULL terminator
*/
- *buffer_size_needed = temp_size_needed + sizeof (struct acpi_pci_routing_table);
- return_ACPI_STATUS (AE_OK);
+ *buffer_size_needed =
+ temp_size_needed + sizeof(struct acpi_pci_routing_table);
+ return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 8e0eae0d50bb..0911526b7ad8 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -41,15 +41,13 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rscreate")
-
+ACPI_MODULE_NAME("rscreate")
/*******************************************************************************
*
@@ -68,24 +66,20 @@
* of device resources.
*
******************************************************************************/
-
acpi_status
-acpi_rs_create_resource_list (
- union acpi_operand_object *byte_stream_buffer,
- struct acpi_buffer *output_buffer)
+acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer,
+ struct acpi_buffer *output_buffer)
{
- acpi_status status;
- u8 *byte_stream_start;
- acpi_size list_size_needed = 0;
- u32 byte_stream_buffer_length;
+ acpi_status status;
+ u8 *byte_stream_start;
+ acpi_size list_size_needed = 0;
+ u32 byte_stream_buffer_length;
+ ACPI_FUNCTION_TRACE("rs_create_resource_list");
- ACPI_FUNCTION_TRACE ("rs_create_resource_list");
-
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
- byte_stream_buffer));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
+ byte_stream_buffer));
/* Params already validated, so we don't re-validate here */
@@ -96,36 +90,39 @@ acpi_rs_create_resource_list (
* Pass the byte_stream_buffer into a module that can calculate
* the buffer size needed for the linked list
*/
- status = acpi_rs_get_list_length (byte_stream_start, byte_stream_buffer_length,
- &list_size_needed);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n",
- status, (u32) list_size_needed));
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_rs_get_list_length(byte_stream_start,
+ byte_stream_buffer_length,
+ &list_size_needed);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n",
+ status, (u32) list_size_needed));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (output_buffer, list_size_needed);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_initialize_buffer(output_buffer, list_size_needed);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Do the conversion */
- status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length,
- output_buffer->pointer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_rs_byte_stream_to_list(byte_stream_start,
+ byte_stream_buffer_length,
+ output_buffer->pointer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
- output_buffer->pointer, (u32) output_buffer->length));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "output_buffer %p Length %X\n",
+ output_buffer->pointer, (u32) output_buffer->length));
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_create_pci_routing_table
@@ -148,44 +145,41 @@ acpi_rs_create_resource_list (
******************************************************************************/
acpi_status
-acpi_rs_create_pci_routing_table (
- union acpi_operand_object *package_object,
- struct acpi_buffer *output_buffer)
+acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
+ struct acpi_buffer *output_buffer)
{
- u8 *buffer;
- union acpi_operand_object **top_object_list;
- union acpi_operand_object **sub_object_list;
- union acpi_operand_object *obj_desc;
- acpi_size buffer_size_needed = 0;
- u32 number_of_elements;
- u32 index;
- struct acpi_pci_routing_table *user_prt;
- struct acpi_namespace_node *node;
- acpi_status status;
- struct acpi_buffer path_buffer;
-
-
- ACPI_FUNCTION_TRACE ("rs_create_pci_routing_table");
-
+ u8 *buffer;
+ union acpi_operand_object **top_object_list;
+ union acpi_operand_object **sub_object_list;
+ union acpi_operand_object *obj_desc;
+ acpi_size buffer_size_needed = 0;
+ u32 number_of_elements;
+ u32 index;
+ struct acpi_pci_routing_table *user_prt;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+ struct acpi_buffer path_buffer;
+
+ ACPI_FUNCTION_TRACE("rs_create_pci_routing_table");
/* Params already validated, so we don't re-validate here */
/* Get the required buffer length */
- status = acpi_rs_get_pci_routing_table_length (package_object,
- &buffer_size_needed);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_rs_get_pci_routing_table_length(package_object,
+ &buffer_size_needed);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "buffer_size_needed = %X\n",
- (u32) buffer_size_needed));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "buffer_size_needed = %X\n",
+ (u32) buffer_size_needed));
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (output_buffer, buffer_size_needed);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_initialize_buffer(output_buffer, buffer_size_needed);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -193,10 +187,10 @@ acpi_rs_create_pci_routing_table (
* should be a package that in turn contains an
* acpi_integer Address, a u8 Pin, a Name and a u8 source_index.
*/
- top_object_list = package_object->package.elements;
+ top_object_list = package_object->package.elements;
number_of_elements = package_object->package.count;
- buffer = output_buffer->pointer;
- user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+ buffer = output_buffer->pointer;
+ user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
for (index = 0; index < number_of_elements; index++) {
/*
@@ -206,31 +200,34 @@ acpi_rs_create_pci_routing_table (
* be zero because we cleared the return buffer earlier
*/
buffer += user_prt->length;
- user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+ user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
/*
* Fill in the Length field with the information we have at this point.
* The minus four is to subtract the size of the u8 Source[4] member
* because it is added below.
*/
- user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4);
+ user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
/* Each element of the top-level package must also be a package */
- if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X]) Need sub-package, found %s\n",
- index, acpi_ut_get_object_type_name (*top_object_list)));
- return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X]) Need sub-package, found %s\n",
+ index,
+ acpi_ut_get_object_type_name
+ (*top_object_list)));
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* Each sub-package must be of length 4 */
if ((*top_object_list)->package.count != 4) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X]) Need package of length 4, found length %d\n",
- index, (*top_object_list)->package.count));
- return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X]) Need package of length 4, found length %d\n",
+ index,
+ (*top_object_list)->package.count));
+ return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT);
}
/*
@@ -243,40 +240,43 @@ acpi_rs_create_pci_routing_table (
/* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0];
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->address = obj_desc->integer.value;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X].Address) Need Integer, found %s\n",
- index, acpi_ut_get_object_type_name (obj_desc)));
- return_ACPI_STATUS (AE_BAD_DATA);
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X].Address) Need Integer, found %s\n",
+ index,
+ acpi_ut_get_object_type_name
+ (obj_desc)));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
/* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1];
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->pin = (u32) obj_desc->integer.value;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X].Pin) Need Integer, found %s\n",
- index, acpi_ut_get_object_type_name (obj_desc)));
- return_ACPI_STATUS (AE_BAD_DATA);
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X].Pin) Need Integer, found %s\n",
+ index,
+ acpi_ut_get_object_type_name
+ (obj_desc)));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
/* 3) Third subobject: Dereference the PRT.source_name */
obj_desc = sub_object_list[2];
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE:
if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X].Source) Need name, found reference op %X\n",
- index, obj_desc->reference.opcode));
- return_ACPI_STATUS (AE_BAD_DATA);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X].Source) Need name, found reference op %X\n",
+ index,
+ obj_desc->reference.opcode));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
node = obj_desc->reference.node;
@@ -284,21 +284,23 @@ acpi_rs_create_pci_routing_table (
/* Use *remaining* length of the buffer as max for pathname */
path_buffer.length = output_buffer->length -
- (u32) ((u8 *) user_prt->source -
- (u8 *) output_buffer->pointer);
+ (u32) ((u8 *) user_prt->source -
+ (u8 *) output_buffer->pointer);
path_buffer.pointer = user_prt->source;
- status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer);
+ status =
+ acpi_ns_handle_to_pathname((acpi_handle) node,
+ &path_buffer);
/* +1 to include null terminator */
- user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1;
+ user_prt->length +=
+ (u32) ACPI_STRLEN(user_prt->source) + 1;
break;
-
case ACPI_TYPE_STRING:
- ACPI_STRCPY (user_prt->source, obj_desc->string.pointer);
+ ACPI_STRCPY(user_prt->source, obj_desc->string.pointer);
/*
* Add to the Length field the length of the string
@@ -307,7 +309,6 @@ acpi_rs_create_pci_routing_table (
user_prt->length += obj_desc->string.length + 1;
break;
-
case ACPI_TYPE_INTEGER:
/*
* If this is a number, then the Source Name is NULL, since the
@@ -315,33 +316,36 @@ acpi_rs_create_pci_routing_table (
*
* Add to the Length field the length of the u32 NULL
*/
- user_prt->length += sizeof (u32);
+ user_prt->length += sizeof(u32);
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X].Source) Need Ref/String/Integer, found %s\n",
- index, acpi_ut_get_object_type_name (obj_desc)));
- return_ACPI_STATUS (AE_BAD_DATA);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X].Source) Need Ref/String/Integer, found %s\n",
+ index,
+ acpi_ut_get_object_type_name
+ (obj_desc)));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
/* Now align the current length */
- user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
+ user_prt->length =
+ (u32) ACPI_ROUND_UP_to_64_bITS(user_prt->length);
/* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[3];
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->source_index = (u32) obj_desc->integer.value;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "(PRT[%X].source_index) Need Integer, found %s\n",
- index, acpi_ut_get_object_type_name (obj_desc)));
- return_ACPI_STATUS (AE_BAD_DATA);
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "(PRT[%X].source_index) Need Integer, found %s\n",
+ index,
+ acpi_ut_get_object_type_name
+ (obj_desc)));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
/* Point to the next union acpi_operand_object in the top level package */
@@ -349,12 +353,11 @@ acpi_rs_create_pci_routing_table (
top_object_list++;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
- output_buffer->pointer, (u32) output_buffer->length));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "output_buffer %p Length %X\n",
+ output_buffer->pointer, (u32) output_buffer->length));
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_create_byte_stream
@@ -374,19 +377,16 @@ acpi_rs_create_pci_routing_table (
******************************************************************************/
acpi_status
-acpi_rs_create_byte_stream (
- struct acpi_resource *linked_list_buffer,
- struct acpi_buffer *output_buffer)
+acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer,
+ struct acpi_buffer *output_buffer)
{
- acpi_status status;
- acpi_size byte_stream_size_needed = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_create_byte_stream");
+ acpi_status status;
+ acpi_size byte_stream_size_needed = 0;
+ ACPI_FUNCTION_TRACE("rs_create_byte_stream");
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "linked_list_buffer = %p\n",
- linked_list_buffer));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n",
+ linked_list_buffer));
/*
* Params already validated, so we don't re-validate here
@@ -394,32 +394,35 @@ acpi_rs_create_byte_stream (
* Pass the linked_list_buffer into a module that calculates
* the buffer size needed for the byte stream.
*/
- status = acpi_rs_get_byte_stream_length (linked_list_buffer,
- &byte_stream_size_needed);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n",
- (u32) byte_stream_size_needed, acpi_format_exception (status)));
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_rs_get_byte_stream_length(linked_list_buffer,
+ &byte_stream_size_needed);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n",
+ (u32) byte_stream_size_needed,
+ acpi_format_exception(status)));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (output_buffer, byte_stream_size_needed);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_initialize_buffer(output_buffer, byte_stream_size_needed);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Do the conversion */
- status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed,
- output_buffer->pointer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_rs_list_to_byte_stream(linked_list_buffer,
+ byte_stream_size_needed,
+ output_buffer->pointer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
- output_buffer->pointer, (u32) output_buffer->length));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "output_buffer %p Length %X\n",
+ output_buffer->pointer, (u32) output_buffer->length));
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index 1935dab2ab51..75bd34d1783f 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -41,69 +41,40 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsdump")
+ACPI_MODULE_NAME("rsdump")
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/* Local prototypes */
+static void acpi_rs_dump_irq(union acpi_resource_data *data);
-static void
-acpi_rs_dump_irq (
- union acpi_resource_data *data);
-
-static void
-acpi_rs_dump_address16 (
- union acpi_resource_data *data);
-
-static void
-acpi_rs_dump_address32 (
- union acpi_resource_data *data);
+static void acpi_rs_dump_address16(union acpi_resource_data *data);
-static void
-acpi_rs_dump_address64 (
- union acpi_resource_data *data);
+static void acpi_rs_dump_address32(union acpi_resource_data *data);
-static void
-acpi_rs_dump_dma (
- union acpi_resource_data *data);
+static void acpi_rs_dump_address64(union acpi_resource_data *data);
-static void
-acpi_rs_dump_io (
- union acpi_resource_data *data);
+static void acpi_rs_dump_dma(union acpi_resource_data *data);
-static void
-acpi_rs_dump_extended_irq (
- union acpi_resource_data *data);
+static void acpi_rs_dump_io(union acpi_resource_data *data);
-static void
-acpi_rs_dump_fixed_io (
- union acpi_resource_data *data);
+static void acpi_rs_dump_extended_irq(union acpi_resource_data *data);
-static void
-acpi_rs_dump_fixed_memory32 (
- union acpi_resource_data *data);
+static void acpi_rs_dump_fixed_io(union acpi_resource_data *data);
-static void
-acpi_rs_dump_memory24 (
- union acpi_resource_data *data);
+static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data);
-static void
-acpi_rs_dump_memory32 (
- union acpi_resource_data *data);
+static void acpi_rs_dump_memory24(union acpi_resource_data *data);
-static void
-acpi_rs_dump_start_depend_fns (
- union acpi_resource_data *data);
+static void acpi_rs_dump_memory32(union acpi_resource_data *data);
-static void
-acpi_rs_dump_vendor_specific (
- union acpi_resource_data *data);
+static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data);
+static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data);
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_irq
@@ -116,39 +87,37 @@ acpi_rs_dump_vendor_specific (
*
******************************************************************************/
-static void
-acpi_rs_dump_irq (
- union acpi_resource_data *data)
+static void acpi_rs_dump_irq(union acpi_resource_data *data)
{
- struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *) data;
- u8 index = 0;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *)data;
+ u8 index = 0;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("IRQ Resource\n");
+ acpi_os_printf("IRQ Resource\n");
- acpi_os_printf (" %s Triggered\n",
- ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
+ acpi_os_printf(" %s Triggered\n",
+ ACPI_LEVEL_SENSITIVE ==
+ irq_data->edge_level ? "Level" : "Edge");
- acpi_os_printf (" Active %s\n",
- ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
+ acpi_os_printf(" Active %s\n",
+ ACPI_ACTIVE_LOW ==
+ irq_data->active_high_low ? "Low" : "High");
- acpi_os_printf (" %s\n",
- ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
+ acpi_os_printf(" %s\n",
+ ACPI_SHARED ==
+ irq_data->shared_exclusive ? "Shared" : "Exclusive");
- acpi_os_printf (" %X Interrupts ( ", irq_data->number_of_interrupts);
+ acpi_os_printf(" %X Interrupts ( ", irq_data->number_of_interrupts);
for (index = 0; index < irq_data->number_of_interrupts; index++) {
- acpi_os_printf ("%X ", irq_data->interrupts[index]);
+ acpi_os_printf("%X ", irq_data->interrupts[index]);
}
- acpi_os_printf (")\n");
+ acpi_os_printf(")\n");
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_dma
@@ -161,75 +130,69 @@ acpi_rs_dump_irq (
*
******************************************************************************/
-static void
-acpi_rs_dump_dma (
- union acpi_resource_data *data)
+static void acpi_rs_dump_dma(union acpi_resource_data *data)
{
- struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *) data;
- u8 index = 0;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *)data;
+ u8 index = 0;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("DMA Resource\n");
+ acpi_os_printf("DMA Resource\n");
switch (dma_data->type) {
case ACPI_COMPATIBILITY:
- acpi_os_printf (" Compatibility mode\n");
+ acpi_os_printf(" Compatibility mode\n");
break;
case ACPI_TYPE_A:
- acpi_os_printf (" Type A\n");
+ acpi_os_printf(" Type A\n");
break;
case ACPI_TYPE_B:
- acpi_os_printf (" Type B\n");
+ acpi_os_printf(" Type B\n");
break;
case ACPI_TYPE_F:
- acpi_os_printf (" Type F\n");
+ acpi_os_printf(" Type F\n");
break;
default:
- acpi_os_printf (" Invalid DMA type\n");
+ acpi_os_printf(" Invalid DMA type\n");
break;
}
- acpi_os_printf (" %sBus Master\n",
- ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
-
+ acpi_os_printf(" %sBus Master\n",
+ ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
switch (dma_data->transfer) {
case ACPI_TRANSFER_8:
- acpi_os_printf (" 8-bit only transfer\n");
+ acpi_os_printf(" 8-bit only transfer\n");
break;
case ACPI_TRANSFER_8_16:
- acpi_os_printf (" 8 and 16-bit transfer\n");
+ acpi_os_printf(" 8 and 16-bit transfer\n");
break;
case ACPI_TRANSFER_16:
- acpi_os_printf (" 16 bit only transfer\n");
+ acpi_os_printf(" 16 bit only transfer\n");
break;
default:
- acpi_os_printf (" Invalid transfer preference\n");
+ acpi_os_printf(" Invalid transfer preference\n");
break;
}
- acpi_os_printf (" Number of Channels: %X ( ",
- dma_data->number_of_channels);
+ acpi_os_printf(" Number of Channels: %X ( ",
+ dma_data->number_of_channels);
for (index = 0; index < dma_data->number_of_channels; index++) {
- acpi_os_printf ("%X ", dma_data->channels[index]);
+ acpi_os_printf("%X ", dma_data->channels[index]);
}
- acpi_os_printf (")\n");
+ acpi_os_printf(")\n");
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_start_depend_fns
@@ -242,58 +205,54 @@ acpi_rs_dump_dma (
*
******************************************************************************/
-static void
-acpi_rs_dump_start_depend_fns (
- union acpi_resource_data *data)
+static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data)
{
- struct acpi_resource_start_dpf *sdf_data = (struct acpi_resource_start_dpf *) data;
-
+ struct acpi_resource_start_dpf *sdf_data =
+ (struct acpi_resource_start_dpf *)data;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
-
- acpi_os_printf ("Start Dependent Functions Resource\n");
+ acpi_os_printf("Start Dependent Functions Resource\n");
switch (sdf_data->compatibility_priority) {
case ACPI_GOOD_CONFIGURATION:
- acpi_os_printf (" Good configuration\n");
+ acpi_os_printf(" Good configuration\n");
break;
case ACPI_ACCEPTABLE_CONFIGURATION:
- acpi_os_printf (" Acceptable configuration\n");
+ acpi_os_printf(" Acceptable configuration\n");
break;
case ACPI_SUB_OPTIMAL_CONFIGURATION:
- acpi_os_printf (" Sub-optimal configuration\n");
+ acpi_os_printf(" Sub-optimal configuration\n");
break;
default:
- acpi_os_printf (" Invalid compatibility priority\n");
+ acpi_os_printf(" Invalid compatibility priority\n");
break;
}
- switch(sdf_data->performance_robustness) {
+ switch (sdf_data->performance_robustness) {
case ACPI_GOOD_CONFIGURATION:
- acpi_os_printf (" Good configuration\n");
+ acpi_os_printf(" Good configuration\n");
break;
case ACPI_ACCEPTABLE_CONFIGURATION:
- acpi_os_printf (" Acceptable configuration\n");
+ acpi_os_printf(" Acceptable configuration\n");
break;
case ACPI_SUB_OPTIMAL_CONFIGURATION:
- acpi_os_printf (" Sub-optimal configuration\n");
+ acpi_os_printf(" Sub-optimal configuration\n");
break;
default:
- acpi_os_printf (" Invalid performance robustness preference\n");
+ acpi_os_printf(" Invalid performance robustness preference\n");
break;
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_io
@@ -306,33 +265,30 @@ acpi_rs_dump_start_depend_fns (
*
******************************************************************************/
-static void
-acpi_rs_dump_io (
- union acpi_resource_data *data)
+static void acpi_rs_dump_io(union acpi_resource_data *data)
{
- struct acpi_resource_io *io_data = (struct acpi_resource_io *) data;
-
+ struct acpi_resource_io *io_data = (struct acpi_resource_io *)data;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
+ acpi_os_printf("Io Resource\n");
- acpi_os_printf ("Io Resource\n");
+ acpi_os_printf(" %d bit decode\n",
+ ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
- acpi_os_printf (" %d bit decode\n",
- ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
+ acpi_os_printf(" Range minimum base: %08X\n",
+ io_data->min_base_address);
- acpi_os_printf (" Range minimum base: %08X\n", io_data->min_base_address);
+ acpi_os_printf(" Range maximum base: %08X\n",
+ io_data->max_base_address);
- acpi_os_printf (" Range maximum base: %08X\n", io_data->max_base_address);
+ acpi_os_printf(" Alignment: %08X\n", io_data->alignment);
- acpi_os_printf (" Alignment: %08X\n", io_data->alignment);
-
- acpi_os_printf (" Range Length: %08X\n", io_data->range_length);
+ acpi_os_printf(" Range Length: %08X\n", io_data->range_length);
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_fixed_io
@@ -345,25 +301,22 @@ acpi_rs_dump_io (
*
******************************************************************************/
-static void
-acpi_rs_dump_fixed_io (
- union acpi_resource_data *data)
+static void acpi_rs_dump_fixed_io(union acpi_resource_data *data)
{
- struct acpi_resource_fixed_io *fixed_io_data = (struct acpi_resource_fixed_io *) data;
-
+ struct acpi_resource_fixed_io *fixed_io_data =
+ (struct acpi_resource_fixed_io *)data;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
+ acpi_os_printf("Fixed Io Resource\n");
+ acpi_os_printf(" Range base address: %08X",
+ fixed_io_data->base_address);
- acpi_os_printf ("Fixed Io Resource\n");
- acpi_os_printf (" Range base address: %08X", fixed_io_data->base_address);
-
- acpi_os_printf (" Range length: %08X", fixed_io_data->range_length);
+ acpi_os_printf(" Range length: %08X", fixed_io_data->range_length);
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_vendor_specific
@@ -376,30 +329,26 @@ acpi_rs_dump_fixed_io (
*
******************************************************************************/
-static void
-acpi_rs_dump_vendor_specific (
- union acpi_resource_data *data)
+static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data)
{
- struct acpi_resource_vendor *vendor_data = (struct acpi_resource_vendor *) data;
- u16 index = 0;
-
+ struct acpi_resource_vendor *vendor_data =
+ (struct acpi_resource_vendor *)data;
+ u16 index = 0;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
+ acpi_os_printf("Vendor Specific Resource\n");
- acpi_os_printf ("Vendor Specific Resource\n");
-
- acpi_os_printf (" Length: %08X\n", vendor_data->length);
+ acpi_os_printf(" Length: %08X\n", vendor_data->length);
for (index = 0; index < vendor_data->length; index++) {
- acpi_os_printf (" Byte %X: %08X\n",
- index, vendor_data->reserved[index]);
+ acpi_os_printf(" Byte %X: %08X\n",
+ index, vendor_data->reserved[index]);
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_memory24
@@ -412,37 +361,33 @@ acpi_rs_dump_vendor_specific (
*
******************************************************************************/
-static void
-acpi_rs_dump_memory24 (
- union acpi_resource_data *data)
+static void acpi_rs_dump_memory24(union acpi_resource_data *data)
{
- struct acpi_resource_mem24 *memory24_data = (struct acpi_resource_mem24 *) data;
-
+ struct acpi_resource_mem24 *memory24_data =
+ (struct acpi_resource_mem24 *)data;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
+ acpi_os_printf("24-Bit Memory Range Resource\n");
- acpi_os_printf ("24-Bit Memory Range Resource\n");
+ acpi_os_printf(" Read%s\n",
+ ACPI_READ_WRITE_MEMORY ==
+ memory24_data->read_write_attribute ?
+ "/Write" : " only");
- acpi_os_printf (" Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- memory24_data->read_write_attribute ?
- "/Write" : " only");
+ acpi_os_printf(" Range minimum base: %08X\n",
+ memory24_data->min_base_address);
- acpi_os_printf (" Range minimum base: %08X\n",
- memory24_data->min_base_address);
+ acpi_os_printf(" Range maximum base: %08X\n",
+ memory24_data->max_base_address);
- acpi_os_printf (" Range maximum base: %08X\n",
- memory24_data->max_base_address);
+ acpi_os_printf(" Alignment: %08X\n", memory24_data->alignment);
- acpi_os_printf (" Alignment: %08X\n", memory24_data->alignment);
-
- acpi_os_printf (" Range length: %08X\n", memory24_data->range_length);
+ acpi_os_printf(" Range length: %08X\n", memory24_data->range_length);
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_memory32
@@ -455,37 +400,33 @@ acpi_rs_dump_memory24 (
*
******************************************************************************/
-static void
-acpi_rs_dump_memory32 (
- union acpi_resource_data *data)
+static void acpi_rs_dump_memory32(union acpi_resource_data *data)
{
- struct acpi_resource_mem32 *memory32_data = (struct acpi_resource_mem32 *) data;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_mem32 *memory32_data =
+ (struct acpi_resource_mem32 *)data;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("32-Bit Memory Range Resource\n");
+ acpi_os_printf("32-Bit Memory Range Resource\n");
- acpi_os_printf (" Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- memory32_data->read_write_attribute ?
- "/Write" : " only");
+ acpi_os_printf(" Read%s\n",
+ ACPI_READ_WRITE_MEMORY ==
+ memory32_data->read_write_attribute ?
+ "/Write" : " only");
- acpi_os_printf (" Range minimum base: %08X\n",
- memory32_data->min_base_address);
+ acpi_os_printf(" Range minimum base: %08X\n",
+ memory32_data->min_base_address);
- acpi_os_printf (" Range maximum base: %08X\n",
- memory32_data->max_base_address);
+ acpi_os_printf(" Range maximum base: %08X\n",
+ memory32_data->max_base_address);
- acpi_os_printf (" Alignment: %08X\n", memory32_data->alignment);
+ acpi_os_printf(" Alignment: %08X\n", memory32_data->alignment);
- acpi_os_printf (" Range length: %08X\n", memory32_data->range_length);
+ acpi_os_printf(" Range length: %08X\n", memory32_data->range_length);
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_fixed_memory32
@@ -498,33 +439,29 @@ acpi_rs_dump_memory32 (
*
******************************************************************************/
-static void
-acpi_rs_dump_fixed_memory32 (
- union acpi_resource_data *data)
+static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data)
{
- struct acpi_resource_fixed_mem32 *fixed_memory32_data =
- (struct acpi_resource_fixed_mem32 *) data;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_fixed_mem32 *fixed_memory32_data =
+ (struct acpi_resource_fixed_mem32 *)data;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n");
+ acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n");
- acpi_os_printf (" Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- fixed_memory32_data->read_write_attribute ? "/Write" : " Only");
+ acpi_os_printf(" Read%s\n",
+ ACPI_READ_WRITE_MEMORY ==
+ fixed_memory32_data->
+ read_write_attribute ? "/Write" : " Only");
- acpi_os_printf (" Range base address: %08X\n",
- fixed_memory32_data->range_base_address);
+ acpi_os_printf(" Range base address: %08X\n",
+ fixed_memory32_data->range_base_address);
- acpi_os_printf (" Range length: %08X\n",
- fixed_memory32_data->range_length);
+ acpi_os_printf(" Range length: %08X\n",
+ fixed_memory32_data->range_length);
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_address16
@@ -537,134 +474,136 @@ acpi_rs_dump_fixed_memory32 (
*
******************************************************************************/
-static void
-acpi_rs_dump_address16 (
- union acpi_resource_data *data)
+static void acpi_rs_dump_address16(union acpi_resource_data *data)
{
- struct acpi_resource_address16 *address16_data = (struct acpi_resource_address16 *) data;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_address16 *address16_data =
+ (struct acpi_resource_address16 *)data;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("16-Bit Address Space Resource\n");
- acpi_os_printf (" Resource Type: ");
+ acpi_os_printf("16-Bit Address Space Resource\n");
+ acpi_os_printf(" Resource Type: ");
switch (address16_data->resource_type) {
case ACPI_MEMORY_RANGE:
- acpi_os_printf ("Memory Range\n");
+ acpi_os_printf("Memory Range\n");
switch (address16_data->attribute.memory.cache_attribute) {
case ACPI_NON_CACHEABLE_MEMORY:
- acpi_os_printf (" Type Specific: Noncacheable memory\n");
+ acpi_os_printf
+ (" Type Specific: Noncacheable memory\n");
break;
case ACPI_CACHABLE_MEMORY:
- acpi_os_printf (" Type Specific: Cacheable memory\n");
+ acpi_os_printf(" Type Specific: Cacheable memory\n");
break;
case ACPI_WRITE_COMBINING_MEMORY:
- acpi_os_printf (" Type Specific: Write-combining memory\n");
+ acpi_os_printf
+ (" Type Specific: Write-combining memory\n");
break;
case ACPI_PREFETCHABLE_MEMORY:
- acpi_os_printf (" Type Specific: Prefetchable memory\n");
+ acpi_os_printf
+ (" Type Specific: Prefetchable memory\n");
break;
default:
- acpi_os_printf (" Type Specific: Invalid cache attribute\n");
+ acpi_os_printf
+ (" Type Specific: Invalid cache attribute\n");
break;
}
- acpi_os_printf (" Type Specific: Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- address16_data->attribute.memory.read_write_attribute ?
- "/Write" : " Only");
+ acpi_os_printf(" Type Specific: Read%s\n",
+ ACPI_READ_WRITE_MEMORY ==
+ address16_data->attribute.memory.
+ read_write_attribute ? "/Write" : " Only");
break;
case ACPI_IO_RANGE:
- acpi_os_printf ("I/O Range\n");
+ acpi_os_printf("I/O Range\n");
switch (address16_data->attribute.io.range_attribute) {
case ACPI_NON_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: Non-ISA Io Addresses\n");
+ acpi_os_printf
+ (" Type Specific: Non-ISA Io Addresses\n");
break;
case ACPI_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: ISA Io Addresses\n");
+ acpi_os_printf(" Type Specific: ISA Io Addresses\n");
break;
case ACPI_ENTIRE_RANGE:
- acpi_os_printf (" Type Specific: ISA and non-ISA Io Addresses\n");
+ acpi_os_printf
+ (" Type Specific: ISA and non-ISA Io Addresses\n");
break;
default:
- acpi_os_printf (" Type Specific: Invalid range attribute\n");
+ acpi_os_printf
+ (" Type Specific: Invalid range attribute\n");
break;
}
- acpi_os_printf (" Type Specific: %s Translation\n",
- ACPI_SPARSE_TRANSLATION ==
- address16_data->attribute.io.translation_attribute ?
- "Sparse" : "Dense");
+ acpi_os_printf(" Type Specific: %s Translation\n",
+ ACPI_SPARSE_TRANSLATION ==
+ address16_data->attribute.io.
+ translation_attribute ? "Sparse" : "Dense");
break;
case ACPI_BUS_NUMBER_RANGE:
- acpi_os_printf ("Bus Number Range\n");
+ acpi_os_printf("Bus Number Range\n");
break;
default:
- acpi_os_printf ("0x%2.2X\n", address16_data->resource_type);
+ acpi_os_printf("0x%2.2X\n", address16_data->resource_type);
break;
}
- acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == address16_data->producer_consumer ?
- "Consumer" : "Producer");
+ acpi_os_printf(" Resource %s\n",
+ ACPI_CONSUMER == address16_data->producer_consumer ?
+ "Consumer" : "Producer");
- acpi_os_printf (" %s decode\n",
- ACPI_SUB_DECODE == address16_data->decode ?
- "Subtractive" : "Positive");
+ acpi_os_printf(" %s decode\n",
+ ACPI_SUB_DECODE == address16_data->decode ?
+ "Subtractive" : "Positive");
- acpi_os_printf (" Min address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
- "" : "not");
+ acpi_os_printf(" Min address is %s fixed\n",
+ ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
+ "" : "not");
- acpi_os_printf (" Max address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
- "" : "not");
+ acpi_os_printf(" Max address is %s fixed\n",
+ ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
+ "" : "not");
- acpi_os_printf (" Granularity: %08X\n",
- address16_data->granularity);
+ acpi_os_printf(" Granularity: %08X\n", address16_data->granularity);
- acpi_os_printf (" Address range min: %08X\n",
- address16_data->min_address_range);
+ acpi_os_printf(" Address range min: %08X\n",
+ address16_data->min_address_range);
- acpi_os_printf (" Address range max: %08X\n",
- address16_data->max_address_range);
+ acpi_os_printf(" Address range max: %08X\n",
+ address16_data->max_address_range);
- acpi_os_printf (" Address translation offset: %08X\n",
- address16_data->address_translation_offset);
+ acpi_os_printf(" Address translation offset: %08X\n",
+ address16_data->address_translation_offset);
- acpi_os_printf (" Address Length: %08X\n",
- address16_data->address_length);
+ acpi_os_printf(" Address Length: %08X\n",
+ address16_data->address_length);
if (0xFF != address16_data->resource_source.index) {
- acpi_os_printf (" Resource Source Index: %X\n",
- address16_data->resource_source.index);
+ acpi_os_printf(" Resource Source Index: %X\n",
+ address16_data->resource_source.index);
- acpi_os_printf (" Resource Source: %s\n",
- address16_data->resource_source.string_ptr);
+ acpi_os_printf(" Resource Source: %s\n",
+ address16_data->resource_source.string_ptr);
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_address32
@@ -677,134 +616,136 @@ acpi_rs_dump_address16 (
*
******************************************************************************/
-static void
-acpi_rs_dump_address32 (
- union acpi_resource_data *data)
+static void acpi_rs_dump_address32(union acpi_resource_data *data)
{
- struct acpi_resource_address32 *address32_data = (struct acpi_resource_address32 *) data;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_address32 *address32_data =
+ (struct acpi_resource_address32 *)data;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("32-Bit Address Space Resource\n");
+ acpi_os_printf("32-Bit Address Space Resource\n");
switch (address32_data->resource_type) {
case ACPI_MEMORY_RANGE:
- acpi_os_printf (" Resource Type: Memory Range\n");
+ acpi_os_printf(" Resource Type: Memory Range\n");
switch (address32_data->attribute.memory.cache_attribute) {
case ACPI_NON_CACHEABLE_MEMORY:
- acpi_os_printf (" Type Specific: Noncacheable memory\n");
+ acpi_os_printf
+ (" Type Specific: Noncacheable memory\n");
break;
case ACPI_CACHABLE_MEMORY:
- acpi_os_printf (" Type Specific: Cacheable memory\n");
+ acpi_os_printf(" Type Specific: Cacheable memory\n");
break;
case ACPI_WRITE_COMBINING_MEMORY:
- acpi_os_printf (" Type Specific: Write-combining memory\n");
+ acpi_os_printf
+ (" Type Specific: Write-combining memory\n");
break;
case ACPI_PREFETCHABLE_MEMORY:
- acpi_os_printf (" Type Specific: Prefetchable memory\n");
+ acpi_os_printf
+ (" Type Specific: Prefetchable memory\n");
break;
default:
- acpi_os_printf (" Type Specific: Invalid cache attribute\n");
+ acpi_os_printf
+ (" Type Specific: Invalid cache attribute\n");
break;
}
- acpi_os_printf (" Type Specific: Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- address32_data->attribute.memory.read_write_attribute ?
- "/Write" : " Only");
+ acpi_os_printf(" Type Specific: Read%s\n",
+ ACPI_READ_WRITE_MEMORY ==
+ address32_data->attribute.memory.
+ read_write_attribute ? "/Write" : " Only");
break;
case ACPI_IO_RANGE:
- acpi_os_printf (" Resource Type: Io Range\n");
+ acpi_os_printf(" Resource Type: Io Range\n");
switch (address32_data->attribute.io.range_attribute) {
case ACPI_NON_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: Non-ISA Io Addresses\n");
+ acpi_os_printf
+ (" Type Specific: Non-ISA Io Addresses\n");
break;
case ACPI_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: ISA Io Addresses\n");
+ acpi_os_printf(" Type Specific: ISA Io Addresses\n");
break;
case ACPI_ENTIRE_RANGE:
- acpi_os_printf (" Type Specific: ISA and non-ISA Io Addresses\n");
+ acpi_os_printf
+ (" Type Specific: ISA and non-ISA Io Addresses\n");
break;
default:
- acpi_os_printf (" Type Specific: Invalid Range attribute");
+ acpi_os_printf
+ (" Type Specific: Invalid Range attribute");
break;
}
- acpi_os_printf (" Type Specific: %s Translation\n",
- ACPI_SPARSE_TRANSLATION ==
- address32_data->attribute.io.translation_attribute ?
- "Sparse" : "Dense");
+ acpi_os_printf(" Type Specific: %s Translation\n",
+ ACPI_SPARSE_TRANSLATION ==
+ address32_data->attribute.io.
+ translation_attribute ? "Sparse" : "Dense");
break;
case ACPI_BUS_NUMBER_RANGE:
- acpi_os_printf (" Resource Type: Bus Number Range\n");
+ acpi_os_printf(" Resource Type: Bus Number Range\n");
break;
default:
- acpi_os_printf (" Resource Type: 0x%2.2X\n",
- address32_data->resource_type);
+ acpi_os_printf(" Resource Type: 0x%2.2X\n",
+ address32_data->resource_type);
break;
}
- acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == address32_data->producer_consumer ?
- "Consumer" : "Producer");
+ acpi_os_printf(" Resource %s\n",
+ ACPI_CONSUMER == address32_data->producer_consumer ?
+ "Consumer" : "Producer");
- acpi_os_printf (" %s decode\n",
- ACPI_SUB_DECODE == address32_data->decode ?
- "Subtractive" : "Positive");
+ acpi_os_printf(" %s decode\n",
+ ACPI_SUB_DECODE == address32_data->decode ?
+ "Subtractive" : "Positive");
- acpi_os_printf (" Min address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
- "" : "not ");
+ acpi_os_printf(" Min address is %s fixed\n",
+ ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
+ "" : "not ");
- acpi_os_printf (" Max address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
- "" : "not ");
+ acpi_os_printf(" Max address is %s fixed\n",
+ ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
+ "" : "not ");
- acpi_os_printf (" Granularity: %08X\n",
- address32_data->granularity);
+ acpi_os_printf(" Granularity: %08X\n", address32_data->granularity);
- acpi_os_printf (" Address range min: %08X\n",
- address32_data->min_address_range);
+ acpi_os_printf(" Address range min: %08X\n",
+ address32_data->min_address_range);
- acpi_os_printf (" Address range max: %08X\n",
- address32_data->max_address_range);
+ acpi_os_printf(" Address range max: %08X\n",
+ address32_data->max_address_range);
- acpi_os_printf (" Address translation offset: %08X\n",
- address32_data->address_translation_offset);
+ acpi_os_printf(" Address translation offset: %08X\n",
+ address32_data->address_translation_offset);
- acpi_os_printf (" Address Length: %08X\n",
- address32_data->address_length);
+ acpi_os_printf(" Address Length: %08X\n",
+ address32_data->address_length);
- if(0xFF != address32_data->resource_source.index) {
- acpi_os_printf (" Resource Source Index: %X\n",
- address32_data->resource_source.index);
+ if (0xFF != address32_data->resource_source.index) {
+ acpi_os_printf(" Resource Source Index: %X\n",
+ address32_data->resource_source.index);
- acpi_os_printf (" Resource Source: %s\n",
- address32_data->resource_source.string_ptr);
+ acpi_os_printf(" Resource Source: %s\n",
+ address32_data->resource_source.string_ptr);
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_address64
@@ -817,137 +758,142 @@ acpi_rs_dump_address32 (
*
******************************************************************************/
-static void
-acpi_rs_dump_address64 (
- union acpi_resource_data *data)
+static void acpi_rs_dump_address64(union acpi_resource_data *data)
{
- struct acpi_resource_address64 *address64_data = (struct acpi_resource_address64 *) data;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_address64 *address64_data =
+ (struct acpi_resource_address64 *)data;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("64-Bit Address Space Resource\n");
+ acpi_os_printf("64-Bit Address Space Resource\n");
switch (address64_data->resource_type) {
case ACPI_MEMORY_RANGE:
- acpi_os_printf (" Resource Type: Memory Range\n");
+ acpi_os_printf(" Resource Type: Memory Range\n");
switch (address64_data->attribute.memory.cache_attribute) {
case ACPI_NON_CACHEABLE_MEMORY:
- acpi_os_printf (" Type Specific: Noncacheable memory\n");
+ acpi_os_printf
+ (" Type Specific: Noncacheable memory\n");
break;
case ACPI_CACHABLE_MEMORY:
- acpi_os_printf (" Type Specific: Cacheable memory\n");
+ acpi_os_printf(" Type Specific: Cacheable memory\n");
break;
case ACPI_WRITE_COMBINING_MEMORY:
- acpi_os_printf (" Type Specific: Write-combining memory\n");
+ acpi_os_printf
+ (" Type Specific: Write-combining memory\n");
break;
case ACPI_PREFETCHABLE_MEMORY:
- acpi_os_printf (" Type Specific: Prefetchable memory\n");
+ acpi_os_printf
+ (" Type Specific: Prefetchable memory\n");
break;
default:
- acpi_os_printf (" Type Specific: Invalid cache attribute\n");
+ acpi_os_printf
+ (" Type Specific: Invalid cache attribute\n");
break;
}
- acpi_os_printf (" Type Specific: Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- address64_data->attribute.memory.read_write_attribute ?
- "/Write" : " Only");
+ acpi_os_printf(" Type Specific: Read%s\n",
+ ACPI_READ_WRITE_MEMORY ==
+ address64_data->attribute.memory.
+ read_write_attribute ? "/Write" : " Only");
break;
case ACPI_IO_RANGE:
- acpi_os_printf (" Resource Type: Io Range\n");
+ acpi_os_printf(" Resource Type: Io Range\n");
switch (address64_data->attribute.io.range_attribute) {
case ACPI_NON_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: Non-ISA Io Addresses\n");
+ acpi_os_printf
+ (" Type Specific: Non-ISA Io Addresses\n");
break;
case ACPI_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: ISA Io Addresses\n");
+ acpi_os_printf(" Type Specific: ISA Io Addresses\n");
break;
case ACPI_ENTIRE_RANGE:
- acpi_os_printf (" Type Specific: ISA and non-ISA Io Addresses\n");
+ acpi_os_printf
+ (" Type Specific: ISA and non-ISA Io Addresses\n");
break;
default:
- acpi_os_printf (" Type Specific: Invalid Range attribute");
+ acpi_os_printf
+ (" Type Specific: Invalid Range attribute");
break;
}
- acpi_os_printf (" Type Specific: %s Translation\n",
- ACPI_SPARSE_TRANSLATION ==
- address64_data->attribute.io.translation_attribute ?
- "Sparse" : "Dense");
+ acpi_os_printf(" Type Specific: %s Translation\n",
+ ACPI_SPARSE_TRANSLATION ==
+ address64_data->attribute.io.
+ translation_attribute ? "Sparse" : "Dense");
break;
case ACPI_BUS_NUMBER_RANGE:
- acpi_os_printf (" Resource Type: Bus Number Range\n");
+ acpi_os_printf(" Resource Type: Bus Number Range\n");
break;
default:
- acpi_os_printf (" Resource Type: 0x%2.2X\n",
- address64_data->resource_type);
+ acpi_os_printf(" Resource Type: 0x%2.2X\n",
+ address64_data->resource_type);
break;
}
- acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == address64_data->producer_consumer ?
- "Consumer" : "Producer");
+ acpi_os_printf(" Resource %s\n",
+ ACPI_CONSUMER == address64_data->producer_consumer ?
+ "Consumer" : "Producer");
- acpi_os_printf (" %s decode\n",
- ACPI_SUB_DECODE == address64_data->decode ?
- "Subtractive" : "Positive");
+ acpi_os_printf(" %s decode\n",
+ ACPI_SUB_DECODE == address64_data->decode ?
+ "Subtractive" : "Positive");
- acpi_os_printf (" Min address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
- "" : "not ");
+ acpi_os_printf(" Min address is %s fixed\n",
+ ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
+ "" : "not ");
- acpi_os_printf (" Max address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
- "" : "not ");
+ acpi_os_printf(" Max address is %s fixed\n",
+ ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
+ "" : "not ");
- acpi_os_printf (" Granularity: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->granularity));
+ acpi_os_printf(" Granularity: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(address64_data->granularity));
- acpi_os_printf (" Address range min: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->min_address_range));
+ acpi_os_printf(" Address range min: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(address64_data->min_address_range));
- acpi_os_printf (" Address range max: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->max_address_range));
+ acpi_os_printf(" Address range max: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(address64_data->max_address_range));
- acpi_os_printf (" Address translation offset: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
+ acpi_os_printf(" Address translation offset: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(address64_data->
+ address_translation_offset));
- acpi_os_printf (" Address Length: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->address_length));
+ acpi_os_printf(" Address Length: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(address64_data->address_length));
- acpi_os_printf (" Type Specific Attributes: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
+ acpi_os_printf(" Type Specific Attributes: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(address64_data->
+ type_specific_attributes));
if (0xFF != address64_data->resource_source.index) {
- acpi_os_printf (" Resource Source Index: %X\n",
- address64_data->resource_source.index);
+ acpi_os_printf(" Resource Source Index: %X\n",
+ address64_data->resource_source.index);
- acpi_os_printf (" Resource Source: %s\n",
- address64_data->resource_source.string_ptr);
+ acpi_os_printf(" Resource Source: %s\n",
+ address64_data->resource_source.string_ptr);
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_extended_irq
@@ -960,55 +906,52 @@ acpi_rs_dump_address64 (
*
******************************************************************************/
-static void
-acpi_rs_dump_extended_irq (
- union acpi_resource_data *data)
+static void acpi_rs_dump_extended_irq(union acpi_resource_data *data)
{
- struct acpi_resource_ext_irq *ext_irq_data = (struct acpi_resource_ext_irq *) data;
- u8 index = 0;
-
-
- ACPI_FUNCTION_ENTRY ();
+ struct acpi_resource_ext_irq *ext_irq_data =
+ (struct acpi_resource_ext_irq *)data;
+ u8 index = 0;
+ ACPI_FUNCTION_ENTRY();
- acpi_os_printf ("Extended IRQ Resource\n");
+ acpi_os_printf("Extended IRQ Resource\n");
- acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == ext_irq_data->producer_consumer ?
- "Consumer" : "Producer");
+ acpi_os_printf(" Resource %s\n",
+ ACPI_CONSUMER == ext_irq_data->producer_consumer ?
+ "Consumer" : "Producer");
- acpi_os_printf (" %s\n",
- ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
- "Level" : "Edge");
+ acpi_os_printf(" %s\n",
+ ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
+ "Level" : "Edge");
- acpi_os_printf (" Active %s\n",
- ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
- "low" : "high");
+ acpi_os_printf(" Active %s\n",
+ ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
+ "low" : "high");
- acpi_os_printf (" %s\n",
- ACPI_SHARED == ext_irq_data->shared_exclusive ?
- "Shared" : "Exclusive");
+ acpi_os_printf(" %s\n",
+ ACPI_SHARED == ext_irq_data->shared_exclusive ?
+ "Shared" : "Exclusive");
- acpi_os_printf (" Interrupts : %X ( ", ext_irq_data->number_of_interrupts);
+ acpi_os_printf(" Interrupts : %X ( ",
+ ext_irq_data->number_of_interrupts);
for (index = 0; index < ext_irq_data->number_of_interrupts; index++) {
- acpi_os_printf ("%X ", ext_irq_data->interrupts[index]);
+ acpi_os_printf("%X ", ext_irq_data->interrupts[index]);
}
- acpi_os_printf (")\n");
+ acpi_os_printf(")\n");
- if(0xFF != ext_irq_data->resource_source.index) {
- acpi_os_printf (" Resource Source Index: %X",
- ext_irq_data->resource_source.index);
+ if (0xFF != ext_irq_data->resource_source.index) {
+ acpi_os_printf(" Resource Source Index: %X",
+ ext_irq_data->resource_source.index);
- acpi_os_printf (" Resource Source: %s",
- ext_irq_data->resource_source.string_ptr);
+ acpi_os_printf(" Resource Source: %s",
+ ext_irq_data->resource_source.string_ptr);
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_resource_list
@@ -1021,92 +964,91 @@ acpi_rs_dump_extended_irq (
*
******************************************************************************/
-void
-acpi_rs_dump_resource_list (
- struct acpi_resource *resource)
+void acpi_rs_dump_resource_list(struct acpi_resource *resource)
{
- u8 count = 0;
- u8 done = FALSE;
-
-
- ACPI_FUNCTION_ENTRY ();
+ u8 count = 0;
+ u8 done = FALSE;
+ ACPI_FUNCTION_ENTRY();
if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
while (!done) {
- acpi_os_printf ("Resource structure %X.\n", count++);
+ acpi_os_printf("Resource structure %X.\n", count++);
switch (resource->id) {
case ACPI_RSTYPE_IRQ:
- acpi_rs_dump_irq (&resource->data);
+ acpi_rs_dump_irq(&resource->data);
break;
case ACPI_RSTYPE_DMA:
- acpi_rs_dump_dma (&resource->data);
+ acpi_rs_dump_dma(&resource->data);
break;
case ACPI_RSTYPE_START_DPF:
- acpi_rs_dump_start_depend_fns (&resource->data);
+ acpi_rs_dump_start_depend_fns(&resource->data);
break;
case ACPI_RSTYPE_END_DPF:
- acpi_os_printf ("end_dependent_functions Resource\n");
- /* acpi_rs_dump_end_dependent_functions (Resource->Data);*/
+ acpi_os_printf
+ ("end_dependent_functions Resource\n");
+ /* acpi_rs_dump_end_dependent_functions (Resource->Data); */
break;
case ACPI_RSTYPE_IO:
- acpi_rs_dump_io (&resource->data);
+ acpi_rs_dump_io(&resource->data);
break;
case ACPI_RSTYPE_FIXED_IO:
- acpi_rs_dump_fixed_io (&resource->data);
+ acpi_rs_dump_fixed_io(&resource->data);
break;
case ACPI_RSTYPE_VENDOR:
- acpi_rs_dump_vendor_specific (&resource->data);
+ acpi_rs_dump_vendor_specific(&resource->data);
break;
case ACPI_RSTYPE_END_TAG:
- /*rs_dump_end_tag (Resource->Data);*/
- acpi_os_printf ("end_tag Resource\n");
+ /*rs_dump_end_tag (Resource->Data); */
+ acpi_os_printf("end_tag Resource\n");
done = TRUE;
break;
case ACPI_RSTYPE_MEM24:
- acpi_rs_dump_memory24 (&resource->data);
+ acpi_rs_dump_memory24(&resource->data);
break;
case ACPI_RSTYPE_MEM32:
- acpi_rs_dump_memory32 (&resource->data);
+ acpi_rs_dump_memory32(&resource->data);
break;
case ACPI_RSTYPE_FIXED_MEM32:
- acpi_rs_dump_fixed_memory32 (&resource->data);
+ acpi_rs_dump_fixed_memory32(&resource->data);
break;
case ACPI_RSTYPE_ADDRESS16:
- acpi_rs_dump_address16 (&resource->data);
+ acpi_rs_dump_address16(&resource->data);
break;
case ACPI_RSTYPE_ADDRESS32:
- acpi_rs_dump_address32 (&resource->data);
+ acpi_rs_dump_address32(&resource->data);
break;
case ACPI_RSTYPE_ADDRESS64:
- acpi_rs_dump_address64 (&resource->data);
+ acpi_rs_dump_address64(&resource->data);
break;
case ACPI_RSTYPE_EXT_IRQ:
- acpi_rs_dump_extended_irq (&resource->data);
+ acpi_rs_dump_extended_irq(&resource->data);
break;
default:
- acpi_os_printf ("Invalid resource type\n");
+ acpi_os_printf("Invalid resource type\n");
break;
}
- resource = ACPI_PTR_ADD (struct acpi_resource, resource, resource->length);
+ resource =
+ ACPI_PTR_ADD(struct acpi_resource, resource,
+ resource->length);
}
}
@@ -1125,36 +1067,38 @@ acpi_rs_dump_resource_list (
*
******************************************************************************/
-void
-acpi_rs_dump_irq_list (
- u8 *route_table)
+void acpi_rs_dump_irq_list(u8 * route_table)
{
- u8 *buffer = route_table;
- u8 count = 0;
- u8 done = FALSE;
- struct acpi_pci_routing_table *prt_element;
-
-
- ACPI_FUNCTION_ENTRY ();
+ u8 *buffer = route_table;
+ u8 count = 0;
+ u8 done = FALSE;
+ struct acpi_pci_routing_table *prt_element;
+ ACPI_FUNCTION_ENTRY();
if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
- prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+ prt_element =
+ ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
while (!done) {
- acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
+ acpi_os_printf("PCI IRQ Routing Table structure %X.\n",
+ count++);
- acpi_os_printf (" Address: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (prt_element->address));
+ acpi_os_printf(" Address: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(prt_element->
+ address));
- acpi_os_printf (" Pin: %X\n", prt_element->pin);
+ acpi_os_printf(" Pin: %X\n", prt_element->pin);
- acpi_os_printf (" Source: %s\n", prt_element->source);
+ acpi_os_printf(" Source: %s\n", prt_element->source);
- acpi_os_printf (" source_index: %X\n", prt_element->source_index);
+ acpi_os_printf(" source_index: %X\n",
+ prt_element->source_index);
buffer += prt_element->length;
- prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+ prt_element =
+ ACPI_CAST_PTR(struct acpi_pci_routing_table,
+ buffer);
if (0 == prt_element->length) {
done = TRUE;
}
@@ -1165,4 +1109,3 @@ acpi_rs_dump_irq_list (
}
#endif
-
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
index 23a4d149fac8..d53bbe89e851 100644
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsio")
-
+ACPI_MODULE_NAME("rsio")
/*******************************************************************************
*
@@ -69,24 +67,18 @@
* number of bytes consumed from the byte stream.
*
******************************************************************************/
-
acpi_status
-acpi_rs_io_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_io_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_io);
-
-
- ACPI_FUNCTION_TRACE ("rs_io_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io);
+ ACPI_FUNCTION_TRACE("rs_io_resource");
/* The number of bytes consumed are Constant */
@@ -104,14 +96,14 @@ acpi_rs_io_resource (
/* Check min_base Address */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
output_struct->data.io.min_base_address = temp16;
/* Check max_base Address */
buffer += 2;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
output_struct->data.io.max_base_address = temp16;
@@ -136,10 +128,9 @@ acpi_rs_io_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_fixed_io_resource
@@ -162,22 +153,18 @@ acpi_rs_io_resource (
******************************************************************************/
acpi_status
-acpi_rs_fixed_io_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_fixed_io_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_fixed_io);
-
-
- ACPI_FUNCTION_TRACE ("rs_fixed_io_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io);
+ ACPI_FUNCTION_TRACE("rs_fixed_io_resource");
/* The number of bytes consumed are Constant */
@@ -188,7 +175,7 @@ acpi_rs_fixed_io_resource (
/* Check Range Base Address */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
output_struct->data.fixed_io.base_address = temp16;
@@ -206,10 +193,9 @@ acpi_rs_fixed_io_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_io_stream
@@ -227,18 +213,14 @@ acpi_rs_fixed_io_resource (
******************************************************************************/
acpi_status
-acpi_rs_io_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_io_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_io_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_io_stream");
/* The descriptor field is static */
@@ -256,14 +238,14 @@ acpi_rs_io_stream (
temp16 = (u16) linked_list->data.io.min_base_address;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the Range maximum base address */
temp16 = (u16) linked_list->data.io.max_base_address;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the base alignment */
@@ -282,11 +264,10 @@ acpi_rs_io_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_fixed_io_stream
@@ -304,18 +285,14 @@ acpi_rs_io_stream (
******************************************************************************/
acpi_status
-acpi_rs_fixed_io_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_fixed_io_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_fixed_io_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_fixed_io_stream");
/* The descriptor field is static */
@@ -327,7 +304,7 @@ acpi_rs_fixed_io_stream (
temp16 = (u16) linked_list->data.fixed_io.base_address;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the range length */
@@ -339,11 +316,10 @@ acpi_rs_fixed_io_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dma_resource
@@ -366,23 +342,18 @@ acpi_rs_fixed_io_stream (
******************************************************************************/
acpi_status
-acpi_rs_dma_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_dma_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u8 temp8 = 0;
- u8 index;
- u8 i;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_dma);
-
-
- ACPI_FUNCTION_TRACE ("rs_dma_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u8 temp8 = 0;
+ u8 index;
+ u8 i;
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma);
+ ACPI_FUNCTION_TRACE("rs_dma_resource");
/* The number of bytes consumed are Constant */
@@ -422,9 +393,9 @@ acpi_rs_dma_resource (
output_struct->data.dma.transfer = temp8 & 0x03;
if (0x03 == output_struct->data.dma.transfer) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid DMA.Transfer preference (3)\n"));
- return_ACPI_STATUS (AE_BAD_DATA);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid DMA.Transfer preference (3)\n"));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
/* Get bus master preference (Bit[2]) */
@@ -442,10 +413,9 @@ acpi_rs_dma_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_dma_stream
@@ -463,19 +433,15 @@ acpi_rs_dma_resource (
******************************************************************************/
acpi_status
-acpi_rs_dma_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_dma_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u8 index;
-
-
- ACPI_FUNCTION_TRACE ("rs_dma_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ u8 index;
+ ACPI_FUNCTION_TRACE("rs_dma_stream");
/* The descriptor field is static */
@@ -486,8 +452,7 @@ acpi_rs_dma_stream (
/* Loop through all of the Channels and set the mask bits */
for (index = 0;
- index < linked_list->data.dma.number_of_channels;
- index++) {
+ index < linked_list->data.dma.number_of_channels; index++) {
temp16 = (u16) linked_list->data.dma.channels[index];
temp8 |= 0x1 << temp16;
}
@@ -506,7 +471,6 @@ acpi_rs_dma_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index 8a2b630be45b..56043fee96cb 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsirq")
-
+ACPI_MODULE_NAME("rsirq")
/*******************************************************************************
*
@@ -69,26 +67,20 @@
* number of bytes consumed from the byte stream.
*
******************************************************************************/
-
acpi_status
-acpi_rs_irq_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_irq_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u8 index;
- u8 i;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_irq);
-
-
- ACPI_FUNCTION_TRACE ("rs_irq_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ u8 index;
+ u8 i;
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq);
+ ACPI_FUNCTION_TRACE("rs_irq_resource");
/*
* The number of bytes consumed are contained in the descriptor
@@ -101,7 +93,7 @@ acpi_rs_irq_resource (
/* Point to the 16-bits of Bytes 1 and 2 */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
output_struct->data.irq.number_of_interrupts = 0;
@@ -132,14 +124,18 @@ acpi_rs_irq_resource (
/* Check for HE, LL interrupts */
switch (temp8 & 0x09) {
- case 0x01: /* HE */
- output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
- output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
+ case 0x01: /* HE */
+ output_struct->data.irq.edge_level =
+ ACPI_EDGE_SENSITIVE;
+ output_struct->data.irq.active_high_low =
+ ACPI_ACTIVE_HIGH;
break;
- case 0x08: /* LL */
- output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
- output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
+ case 0x08: /* LL */
+ output_struct->data.irq.edge_level =
+ ACPI_LEVEL_SENSITIVE;
+ output_struct->data.irq.active_high_low =
+ ACPI_ACTIVE_LOW;
break;
default:
@@ -148,17 +144,16 @@ acpi_rs_irq_resource (
* are allowed (ACPI spec, section "IRQ Format")
* so 0x00 and 0x09 are illegal.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid interrupt polarity/trigger in resource list, %X\n",
- temp8));
- return_ACPI_STATUS (AE_BAD_DATA);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid interrupt polarity/trigger in resource list, %X\n",
+ temp8));
+ return_ACPI_STATUS(AE_BAD_DATA);
}
/* Check for sharable */
output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01;
- }
- else {
+ } else {
/*
* Assume Edge Sensitive, Active High, Non-Sharable
* per ACPI Specification
@@ -175,10 +170,9 @@ acpi_rs_irq_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_irq_stream
@@ -196,32 +190,27 @@ acpi_rs_irq_resource (
******************************************************************************/
acpi_status
-acpi_rs_irq_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_irq_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u8 index;
- u8 IRqinfo_byte_needed;
-
-
- ACPI_FUNCTION_TRACE ("rs_irq_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ u8 index;
+ u8 IRqinfo_byte_needed;
+ ACPI_FUNCTION_TRACE("rs_irq_stream");
/*
* The descriptor field is set based upon whether a third byte is
* needed to contain the IRQ Information.
*/
if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level &&
- ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low &&
- ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) {
+ ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low &&
+ ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) {
*buffer = 0x22;
IRqinfo_byte_needed = FALSE;
- }
- else {
+ } else {
*buffer = 0x23;
IRqinfo_byte_needed = TRUE;
}
@@ -231,14 +220,13 @@ acpi_rs_irq_stream (
/* Loop through all of the interrupts and set the mask bits */
- for(index = 0;
- index < linked_list->data.irq.number_of_interrupts;
- index++) {
+ for (index = 0;
+ index < linked_list->data.irq.number_of_interrupts; index++) {
temp8 = (u8) linked_list->data.irq.interrupts[index];
temp16 |= 0x1 << temp8;
}
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the IRQ Info byte if needed. */
@@ -246,13 +234,12 @@ acpi_rs_irq_stream (
if (IRqinfo_byte_needed) {
temp8 = 0;
temp8 = (u8) ((linked_list->data.irq.shared_exclusive &
- 0x01) << 4);
+ 0x01) << 4);
if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level &&
- ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) {
+ ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) {
temp8 |= 0x08;
- }
- else {
+ } else {
temp8 |= 0x01;
}
@@ -262,11 +249,10 @@ acpi_rs_irq_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_extended_irq_resource
@@ -289,34 +275,30 @@ acpi_rs_irq_stream (
******************************************************************************/
acpi_status
-acpi_rs_extended_irq_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_extended_irq_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u8 *temp_ptr;
- u8 index;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_ext_irq);
-
-
- ACPI_FUNCTION_TRACE ("rs_extended_irq_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ u8 *temp_ptr;
+ u8 index;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq);
+ ACPI_FUNCTION_TRACE("rs_extended_irq_resource");
- /* Point past the Descriptor to get the number of bytes consumed */
+ /* Get the Descriptor Length field */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 6) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
@@ -338,7 +320,7 @@ acpi_rs_extended_irq_resource (
* - Edge/Level are defined opposite in the table vs the headers
*/
output_struct->data.extended_irq.edge_level =
- (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+ (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
/* Check Interrupt Polarity */
@@ -356,7 +338,7 @@ acpi_rs_extended_irq_resource (
/* Must have at least one IRQ */
if (temp8 < 1) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
}
output_struct->data.extended_irq.number_of_interrupts = temp8;
@@ -374,8 +356,8 @@ acpi_rs_extended_irq_resource (
/* Cycle through every IRQ in the table */
for (index = 0; index < temp8; index++) {
- ACPI_MOVE_32_TO_32 (
- &output_struct->data.extended_irq.interrupts[index], buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq.
+ interrupts[index], buffer);
/* Point to the next IRQ */
@@ -393,12 +375,13 @@ acpi_rs_extended_irq_resource (
* we add 1 to the length.
*/
if (*bytes_consumed >
- ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) +
- (5 + 1)) {
+ ((acpi_size) output_struct->data.extended_irq.number_of_interrupts *
+ 4) + (5 + 1)) {
/* Dereference the Index */
temp8 = *buffer;
- output_struct->data.extended_irq.resource_source.index = (u32) temp8;
+ output_struct->data.extended_irq.resource_source.index =
+ (u32) temp8;
/* Point to the String */
@@ -407,15 +390,15 @@ acpi_rs_extended_irq_resource (
/* Point the String pointer to the end of this structure. */
output_struct->data.extended_irq.resource_source.string_ptr =
- (char *)((char *) output_struct + struct_size);
+ (char *)((char *)output_struct + struct_size);
temp_ptr = (u8 *)
- output_struct->data.extended_irq.resource_source.string_ptr;
+ output_struct->data.extended_irq.resource_source.string_ptr;
/* Copy the string into the buffer */
index = 0;
- while (0x00 != *buffer) {
+ while (*buffer) {
*temp_ptr = *buffer;
temp_ptr += 1;
@@ -425,8 +408,9 @@ acpi_rs_extended_irq_resource (
/* Add the terminating null */
- *temp_ptr = 0x00;
- output_struct->data.extended_irq.resource_source.string_length = index + 1;
+ *temp_ptr = 0;
+ output_struct->data.extended_irq.resource_source.string_length =
+ index + 1;
/*
* In order for the struct_size to fall on a 32-bit boundary,
@@ -434,12 +418,13 @@ acpi_rs_extended_irq_resource (
* struct_size to the next 32-bit boundary.
*/
temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
- }
- else {
- output_struct->data.extended_irq.resource_source.index = 0x00;
- output_struct->data.extended_irq.resource_source.string_length = 0;
- output_struct->data.extended_irq.resource_source.string_ptr = NULL;
+ struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
+ } else {
+ output_struct->data.extended_irq.resource_source.index = 0;
+ output_struct->data.extended_irq.resource_source.string_length =
+ 0;
+ output_struct->data.extended_irq.resource_source.string_ptr =
+ NULL;
}
/* Set the Length parameter */
@@ -449,10 +434,9 @@ acpi_rs_extended_irq_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_extended_irq_stream
@@ -470,35 +454,31 @@ acpi_rs_extended_irq_resource (
******************************************************************************/
acpi_status
-acpi_rs_extended_irq_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_extended_irq_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 *length_field;
- u8 temp8 = 0;
- u8 index;
- char *temp_pointer = NULL;
-
-
- ACPI_FUNCTION_TRACE ("rs_extended_irq_stream");
+ u8 *buffer = *output_buffer;
+ u16 *length_field;
+ u8 temp8 = 0;
+ u8 index;
+ ACPI_FUNCTION_TRACE("rs_extended_irq_stream");
- /* The descriptor field is static */
+ /* Set the Descriptor Type field */
- *buffer = 0x89;
+ *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT;
buffer += 1;
- /* Set a pointer to the Length field - to be filled in later */
+ /* Save a pointer to the Length field - to be filled in later */
- length_field = ACPI_CAST_PTR (u16, buffer);
+ length_field = ACPI_CAST_PTR(u16, buffer);
buffer += 2;
/* Set the Interrupt vector flags */
- temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01);
- temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
+ temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01);
+ temp8 |=
+ ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
/*
* Set the Interrupt Mode
@@ -527,43 +507,46 @@ acpi_rs_extended_irq_stream (
*buffer = temp8;
buffer += 1;
- for (index = 0; index < linked_list->data.extended_irq.number_of_interrupts;
- index++) {
- ACPI_MOVE_32_TO_32 (buffer,
- &linked_list->data.extended_irq.interrupts[index]);
+ for (index = 0;
+ index < linked_list->data.extended_irq.number_of_interrupts;
+ index++) {
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.extended_irq.
+ interrupts[index]);
buffer += 4;
}
/* Resource Source Index and Resource Source are optional */
if (0 != linked_list->data.extended_irq.resource_source.string_length) {
- *buffer = (u8) linked_list->data.extended_irq.resource_source.index;
+ *buffer =
+ (u8) linked_list->data.extended_irq.resource_source.index;
buffer += 1;
- temp_pointer = (char *) buffer;
-
/* Copy the string */
- ACPI_STRCPY (temp_pointer,
- linked_list->data.extended_irq.resource_source.string_ptr);
+ ACPI_STRCPY((char *)buffer,
+ linked_list->data.extended_irq.resource_source.
+ string_ptr);
/*
- * Buffer needs to be set to the length of the sting + one for the
+ * Buffer needs to be set to the length of the string + one for the
* terminating null
*/
- buffer += (acpi_size) (ACPI_STRLEN (
- linked_list->data.extended_irq.resource_source.string_ptr) + 1);
+ buffer +=
+ (acpi_size) (ACPI_STRLEN
+ (linked_list->data.extended_irq.
+ resource_source.string_ptr) + 1);
}
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
/*
* Set the length field to the number of bytes consumed
* minus the header size (3 bytes)
*/
*length_field = (u16) (*bytes_consumed - 3);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index db7bcb4e60e3..103eb31c284e 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rslist")
-
+ACPI_MODULE_NAME("rslist")
/*******************************************************************************
*
@@ -61,14 +59,10 @@
* a resource descriptor.
*
******************************************************************************/
-
-u8
-acpi_rs_get_resource_type (
- u8 resource_start_byte)
+u8 acpi_rs_get_resource_type(u8 resource_start_byte)
{
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
/* Determine if this is a small or large resource */
@@ -79,14 +73,12 @@ acpi_rs_get_resource_type (
return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
-
case ACPI_RDESC_TYPE_LARGE:
/* Large Resource Type -- All bits are valid */
return (resource_start_byte);
-
default:
/* Invalid type */
break;
@@ -95,7 +87,6 @@ acpi_rs_get_resource_type (
return (0xFF);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_byte_stream_to_list
@@ -113,176 +104,189 @@ acpi_rs_get_resource_type (
******************************************************************************/
acpi_status
-acpi_rs_byte_stream_to_list (
- u8 *byte_stream_buffer,
- u32 byte_stream_buffer_length,
- u8 *output_buffer)
+acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
+ u32 byte_stream_buffer_length, u8 * output_buffer)
{
- acpi_status status;
- acpi_size bytes_parsed = 0;
- u8 resource_type = 0;
- acpi_size bytes_consumed = 0;
- u8 *buffer = output_buffer;
- acpi_size structure_size = 0;
- u8 end_tag_processed = FALSE;
- struct acpi_resource *resource;
-
- ACPI_FUNCTION_TRACE ("rs_byte_stream_to_list");
-
-
- while (bytes_parsed < byte_stream_buffer_length &&
- !end_tag_processed) {
+ acpi_status status;
+ acpi_size bytes_parsed = 0;
+ u8 resource_type = 0;
+ acpi_size bytes_consumed = 0;
+ u8 *buffer = output_buffer;
+ acpi_size structure_size = 0;
+ u8 end_tag_processed = FALSE;
+ struct acpi_resource *resource;
+
+ ACPI_FUNCTION_TRACE("rs_byte_stream_to_list");
+
+ while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) {
/* The next byte in the stream is the resource type */
- resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
+ resource_type = acpi_rs_get_resource_type(*byte_stream_buffer);
switch (resource_type) {
case ACPI_RDESC_TYPE_MEMORY_24:
/*
* 24-Bit Memory Resource
*/
- status = acpi_rs_memory24_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_memory24_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_LARGE_VENDOR:
/*
* Vendor Defined Resource
*/
- status = acpi_rs_vendor_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_vendor_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_MEMORY_32:
/*
* 32-Bit Memory Range Resource
*/
- status = acpi_rs_memory32_range_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status =
+ acpi_rs_memory32_range_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
/*
* 32-Bit Fixed Memory Resource
*/
- status = acpi_rs_fixed_memory32_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status =
+ acpi_rs_fixed_memory32_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
/*
* 64-Bit Address Resource
*/
- status = acpi_rs_address64_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_address64_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
/*
* 32-Bit Address Resource
*/
- status = acpi_rs_address32_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_address32_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
/*
* 16-Bit Address Resource
*/
- status = acpi_rs_address16_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_address16_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
/*
* Extended IRQ
*/
- status = acpi_rs_extended_irq_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status =
+ acpi_rs_extended_irq_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_IRQ_FORMAT:
/*
* IRQ Resource
*/
- status = acpi_rs_irq_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_irq_resource(byte_stream_buffer,
+ &bytes_consumed, &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_DMA_FORMAT:
/*
* DMA Resource
*/
- status = acpi_rs_dma_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_dma_resource(byte_stream_buffer,
+ &bytes_consumed, &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_START_DEPENDENT:
/*
* Start Dependent Functions Resource
*/
- status = acpi_rs_start_depend_fns_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status =
+ acpi_rs_start_depend_fns_resource
+ (byte_stream_buffer, &bytes_consumed, &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_END_DEPENDENT:
/*
* End Dependent Functions Resource
*/
- status = acpi_rs_end_depend_fns_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status =
+ acpi_rs_end_depend_fns_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_IO_PORT:
/*
* IO Port Resource
*/
- status = acpi_rs_io_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_io_resource(byte_stream_buffer,
+ &bytes_consumed, &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_FIXED_IO_PORT:
/*
* Fixed IO Port Resource
*/
- status = acpi_rs_fixed_io_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_fixed_io_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_SMALL_VENDOR:
/*
* Vendor Specific Resource
*/
- status = acpi_rs_vendor_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_vendor_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
case ACPI_RDESC_TYPE_END_TAG:
/*
* End Tag
*/
end_tag_processed = TRUE;
- status = acpi_rs_end_tag_resource (byte_stream_buffer,
- &bytes_consumed, &buffer, &structure_size);
+ status = acpi_rs_end_tag_resource(byte_stream_buffer,
+ &bytes_consumed,
+ &buffer,
+ &structure_size);
break;
-
default:
/*
* Invalid/Unknown resource type
@@ -291,8 +295,8 @@ acpi_rs_byte_stream_to_list (
break;
}
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Update the return value and counter */
@@ -305,21 +309,21 @@ acpi_rs_byte_stream_to_list (
/* Set the Buffer to the next structure */
- resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
- resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
- buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+ resource = ACPI_CAST_PTR(struct acpi_resource, buffer);
+ resource->length =
+ (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length);
+ buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
}
/* Check the reason for exiting the while loop */
if (!end_tag_processed) {
- return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_list_to_byte_stream
@@ -342,19 +346,16 @@ acpi_rs_byte_stream_to_list (
******************************************************************************/
acpi_status
-acpi_rs_list_to_byte_stream (
- struct acpi_resource *linked_list,
- acpi_size byte_stream_size_needed,
- u8 *output_buffer)
+acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list,
+ acpi_size byte_stream_size_needed,
+ u8 * output_buffer)
{
- acpi_status status;
- u8 *buffer = output_buffer;
- acpi_size bytes_consumed = 0;
- u8 done = FALSE;
-
-
- ACPI_FUNCTION_TRACE ("rs_list_to_byte_stream");
+ acpi_status status;
+ u8 *buffer = output_buffer;
+ acpi_size bytes_consumed = 0;
+ u8 done = FALSE;
+ ACPI_FUNCTION_TRACE("rs_list_to_byte_stream");
while (!done) {
switch (linked_list->id) {
@@ -362,58 +363,72 @@ acpi_rs_list_to_byte_stream (
/*
* IRQ Resource
*/
- status = acpi_rs_irq_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_irq_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_DMA:
/*
* DMA Resource
*/
- status = acpi_rs_dma_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_dma_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_START_DPF:
/*
* Start Dependent Functions Resource
*/
- status = acpi_rs_start_depend_fns_stream (linked_list,
- &buffer, &bytes_consumed);
+ status = acpi_rs_start_depend_fns_stream(linked_list,
+ &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_END_DPF:
/*
* End Dependent Functions Resource
*/
- status = acpi_rs_end_depend_fns_stream (linked_list,
- &buffer, &bytes_consumed);
+ status = acpi_rs_end_depend_fns_stream(linked_list,
+ &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_IO:
/*
* IO Port Resource
*/
- status = acpi_rs_io_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_io_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_FIXED_IO:
/*
* Fixed IO Port Resource
*/
- status = acpi_rs_fixed_io_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_fixed_io_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_VENDOR:
/*
* Vendor Defined Resource
*/
- status = acpi_rs_vendor_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_vendor_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_END_TAG:
/*
* End Tag
*/
- status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_end_tag_stream(linked_list, &buffer,
+ &bytes_consumed);
/* An End Tag indicates the end of the Resource Template */
@@ -424,55 +439,60 @@ acpi_rs_list_to_byte_stream (
/*
* 24-Bit Memory Resource
*/
- status = acpi_rs_memory24_stream (linked_list, &buffer, &bytes_consumed);
+ status =
+ acpi_rs_memory24_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_MEM32:
/*
* 32-Bit Memory Range Resource
*/
- status = acpi_rs_memory32_range_stream (linked_list, &buffer,
- &bytes_consumed);
+ status =
+ acpi_rs_memory32_range_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_FIXED_MEM32:
/*
* 32-Bit Fixed Memory Resource
*/
- status = acpi_rs_fixed_memory32_stream (linked_list, &buffer,
- &bytes_consumed);
+ status =
+ acpi_rs_fixed_memory32_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_ADDRESS16:
/*
* 16-Bit Address Descriptor Resource
*/
- status = acpi_rs_address16_stream (linked_list, &buffer,
- &bytes_consumed);
+ status = acpi_rs_address16_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_ADDRESS32:
/*
* 32-Bit Address Descriptor Resource
*/
- status = acpi_rs_address32_stream (linked_list, &buffer,
- &bytes_consumed);
+ status = acpi_rs_address32_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_ADDRESS64:
/*
* 64-Bit Address Descriptor Resource
*/
- status = acpi_rs_address64_stream (linked_list, &buffer,
- &bytes_consumed);
+ status = acpi_rs_address64_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
case ACPI_RSTYPE_EXT_IRQ:
/*
* Extended IRQ Resource
*/
- status = acpi_rs_extended_irq_stream (linked_list, &buffer,
- &bytes_consumed);
+ status =
+ acpi_rs_extended_irq_stream(linked_list, &buffer,
+ &bytes_consumed);
break;
default:
@@ -480,15 +500,15 @@ acpi_rs_list_to_byte_stream (
* If we get here, everything is out of sync,
* so exit with an error
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid descriptor type (%X) in resource list\n",
- linked_list->id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid descriptor type (%X) in resource list\n",
+ linked_list->id));
status = AE_BAD_DATA;
break;
}
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Set the Buffer to point to the open byte */
@@ -497,10 +517,9 @@ acpi_rs_list_to_byte_stream (
/* Point to the next object */
- linked_list = ACPI_PTR_ADD (struct acpi_resource,
- linked_list, linked_list->length);
+ linked_list = ACPI_PTR_ADD(struct acpi_resource,
+ linked_list, linked_list->length);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
index 91d0207f01ac..daba1a1ed46d 100644
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsmemory")
-
+ACPI_MODULE_NAME("rsmemory")
/*******************************************************************************
*
@@ -69,30 +67,25 @@
* number of bytes consumed from the byte stream.
*
******************************************************************************/
-
acpi_status
-acpi_rs_memory24_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_memory24_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_mem24);
-
-
- ACPI_FUNCTION_TRACE ("rs_memory24_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24);
+ ACPI_FUNCTION_TRACE("rs_memory24_resource");
/* Point past the Descriptor to get the number of bytes consumed */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
buffer += 2;
*bytes_consumed = (acpi_size) temp16 + 3;
output_struct->id = ACPI_RSTYPE_MEM24;
@@ -105,25 +98,25 @@ acpi_rs_memory24_resource (
/* Get min_base_address (Bytes 4-5) */
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
buffer += 2;
output_struct->data.memory24.min_base_address = temp16;
/* Get max_base_address (Bytes 6-7) */
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
buffer += 2;
output_struct->data.memory24.max_base_address = temp16;
/* Get Alignment (Bytes 8-9) */
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
buffer += 2;
output_struct->data.memory24.alignment = temp16;
/* Get range_length (Bytes 10-11) */
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
output_struct->data.memory24.range_length = temp16;
/* Set the Length parameter */
@@ -133,10 +126,9 @@ acpi_rs_memory24_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_memory24_stream
@@ -154,18 +146,14 @@ acpi_rs_memory24_resource (
******************************************************************************/
acpi_status
-acpi_rs_memory24_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_memory24_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_memory24_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_memory24_stream");
/* The descriptor field is static */
@@ -175,7 +163,7 @@ acpi_rs_memory24_stream (
/* The length field is static */
temp16 = 0x09;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the Information Byte */
@@ -186,31 +174,32 @@ acpi_rs_memory24_stream (
/* Set the Range minimum base address */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.min_base_address);
+ ACPI_MOVE_32_TO_16(buffer,
+ &linked_list->data.memory24.min_base_address);
buffer += 2;
/* Set the Range maximum base address */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.max_base_address);
+ ACPI_MOVE_32_TO_16(buffer,
+ &linked_list->data.memory24.max_base_address);
buffer += 2;
/* Set the base alignment */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.alignment);
+ ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.alignment);
buffer += 2;
/* Set the range length */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.range_length);
+ ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.range_length);
buffer += 2;
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_memory32_range_resource
@@ -233,28 +222,24 @@ acpi_rs_memory24_stream (
******************************************************************************/
acpi_status
-acpi_rs_memory32_range_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_memory32_range_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_mem32);
-
-
- ACPI_FUNCTION_TRACE ("rs_memory32_range_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32);
+ ACPI_FUNCTION_TRACE("rs_memory32_range_resource");
/* Point past the Descriptor to get the number of bytes consumed */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
buffer += 2;
*bytes_consumed = (acpi_size) temp16 + 3;
@@ -279,22 +264,24 @@ acpi_rs_memory32_range_resource (
/* Get min_base_address (Bytes 4-7) */
- ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.min_base_address, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.memory32.min_base_address,
+ buffer);
buffer += 4;
/* Get max_base_address (Bytes 8-11) */
- ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.max_base_address, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.memory32.max_base_address,
+ buffer);
buffer += 4;
/* Get Alignment (Bytes 12-15) */
- ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.alignment, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.memory32.alignment, buffer);
buffer += 4;
/* Get range_length (Bytes 16-19) */
- ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.range_length, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.memory32.range_length, buffer);
/* Set the Length parameter */
@@ -303,10 +290,9 @@ acpi_rs_memory32_range_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_fixed_memory32_resource
@@ -329,27 +315,23 @@ acpi_rs_memory32_range_resource (
******************************************************************************/
acpi_status
-acpi_rs_fixed_memory32_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_fixed_mem32);
-
-
- ACPI_FUNCTION_TRACE ("rs_fixed_memory32_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32);
+ ACPI_FUNCTION_TRACE("rs_fixed_memory32_resource");
/* Point past the Descriptor to get the number of bytes consumed */
buffer += 1;
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
buffer += 2;
*bytes_consumed = (acpi_size) temp16 + 3;
@@ -364,13 +346,14 @@ acpi_rs_fixed_memory32_resource (
/* Get range_base_address (Bytes 4-7) */
- ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address,
- buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.
+ range_base_address, buffer);
buffer += 4;
/* Get range_length (Bytes 8-11) */
- ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_length, buffer);
+ ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.range_length,
+ buffer);
/* Set the Length parameter */
@@ -379,10 +362,9 @@ acpi_rs_fixed_memory32_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_memory32_range_stream
@@ -400,18 +382,14 @@ acpi_rs_fixed_memory32_resource (
******************************************************************************/
acpi_status
-acpi_rs_memory32_range_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_memory32_range_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_memory32_range_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_memory32_range_stream");
/* The descriptor field is static */
@@ -422,7 +400,7 @@ acpi_rs_memory32_range_stream (
temp16 = 0x11;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the Information Byte */
@@ -433,31 +411,32 @@ acpi_rs_memory32_range_stream (
/* Set the Range minimum base address */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.min_base_address);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.memory32.min_base_address);
buffer += 4;
/* Set the Range maximum base address */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.max_base_address);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.memory32.max_base_address);
buffer += 4;
/* Set the base alignment */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.alignment);
+ ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.alignment);
buffer += 4;
/* Set the range length */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.range_length);
+ ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.range_length);
buffer += 4;
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_fixed_memory32_stream
@@ -475,18 +454,14 @@ acpi_rs_memory32_range_stream (
******************************************************************************/
acpi_status
-acpi_rs_fixed_memory32_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_fixed_memory32_stream");
/* The descriptor field is static */
@@ -497,30 +472,31 @@ acpi_rs_fixed_memory32_stream (
temp16 = 0x09;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
/* Set the Information Byte */
- temp8 = (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
+ temp8 =
+ (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
*buffer = temp8;
buffer += 1;
/* Set the Range base address */
- ACPI_MOVE_32_TO_32 (buffer,
- &linked_list->data.fixed_memory32.range_base_address);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.fixed_memory32.
+ range_base_address);
buffer += 4;
/* Set the range length */
- ACPI_MOVE_32_TO_32 (buffer,
- &linked_list->data.fixed_memory32.range_length);
+ ACPI_MOVE_32_TO_32(buffer,
+ &linked_list->data.fixed_memory32.range_length);
buffer += 4;
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index a1f1741f0d83..7a8a34e757f5 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -41,13 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsmisc")
-
+ACPI_MODULE_NAME("rsmisc")
/*******************************************************************************
*
@@ -69,20 +67,15 @@
* number of bytes consumed from the byte stream.
*
******************************************************************************/
-
acpi_status
-acpi_rs_end_tag_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_end_tag_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- struct acpi_resource *output_struct = (void *) *output_buffer;
- acpi_size struct_size = ACPI_RESOURCE_LENGTH;
-
-
- ACPI_FUNCTION_TRACE ("rs_end_tag_resource");
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ acpi_size struct_size = ACPI_RESOURCE_LENGTH;
+ ACPI_FUNCTION_TRACE("rs_end_tag_resource");
/* The number of bytes consumed is static */
@@ -99,10 +92,9 @@ acpi_rs_end_tag_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_end_tag_stream
@@ -120,17 +112,13 @@ acpi_rs_end_tag_resource (
******************************************************************************/
acpi_status
-acpi_rs_end_tag_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_end_tag_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_end_tag_stream");
+ u8 *buffer = *output_buffer;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_end_tag_stream");
/* The descriptor field is static */
@@ -148,11 +136,10 @@ acpi_rs_end_tag_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_vendor_resource
@@ -175,23 +162,19 @@ acpi_rs_end_tag_stream (
******************************************************************************/
acpi_status
-acpi_rs_vendor_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_vendor_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u8 index;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_vendor);
-
-
- ACPI_FUNCTION_TRACE ("rs_vendor_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ u8 index;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor);
+ ACPI_FUNCTION_TRACE("rs_vendor_resource");
/* Dereference the Descriptor to find if this is a large or small item. */
@@ -204,7 +187,7 @@ acpi_rs_vendor_resource (
/* Dereference */
- ACPI_MOVE_16_TO_16 (&temp16, buffer);
+ ACPI_MOVE_16_TO_16(&temp16, buffer);
/* Calculate bytes consumed */
@@ -213,11 +196,10 @@ acpi_rs_vendor_resource (
/* Point to the first vendor byte */
buffer += 2;
- }
- else {
+ } else {
/* Small Item, dereference the size */
- temp16 = (u8)(*buffer & 0x07);
+ temp16 = (u8) (*buffer & 0x07);
/* Calculate bytes consumed */
@@ -241,7 +223,7 @@ acpi_rs_vendor_resource (
* calculate the length of the vendor string and expand the
* struct_size to the next 32-bit boundary.
*/
- struct_size += ACPI_ROUND_UP_to_32_bITS (temp16);
+ struct_size += ACPI_ROUND_UP_to_32_bITS(temp16);
/* Set the Length parameter */
@@ -250,10 +232,9 @@ acpi_rs_vendor_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_vendor_stream
@@ -271,23 +252,19 @@ acpi_rs_vendor_resource (
******************************************************************************/
acpi_status
-acpi_rs_vendor_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_vendor_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u8 index;
-
-
- ACPI_FUNCTION_TRACE ("rs_vendor_stream");
+ u8 *buffer = *output_buffer;
+ u16 temp16 = 0;
+ u8 temp8 = 0;
+ u8 index;
+ ACPI_FUNCTION_TRACE("rs_vendor_stream");
/* Dereference the length to find if this is a large or small item. */
- if(linked_list->data.vendor_specific.length > 7) {
+ if (linked_list->data.vendor_specific.length > 7) {
/* Large Item, Set the descriptor field and length bytes */
*buffer = 0x84;
@@ -295,10 +272,9 @@ acpi_rs_vendor_stream (
temp16 = (u16) linked_list->data.vendor_specific.length;
- ACPI_MOVE_16_TO_16 (buffer, &temp16);
+ ACPI_MOVE_16_TO_16(buffer, &temp16);
buffer += 2;
- }
- else {
+ } else {
/* Small Item, Set the descriptor field */
temp8 = 0x70;
@@ -310,7 +286,8 @@ acpi_rs_vendor_stream (
/* Loop through all of the Vendor Specific fields */
- for (index = 0; index < linked_list->data.vendor_specific.length; index++) {
+ for (index = 0; index < linked_list->data.vendor_specific.length;
+ index++) {
temp8 = linked_list->data.vendor_specific.reserved[index];
*buffer = temp8;
@@ -319,11 +296,10 @@ acpi_rs_vendor_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_start_depend_fns_resource
@@ -346,21 +322,18 @@ acpi_rs_vendor_stream (
******************************************************************************/
acpi_status
-acpi_rs_start_depend_fns_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer,
+ acpi_size * structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
- struct acpi_resource_start_dpf);
-
-
- ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource");
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ u8 temp8 = 0;
+ acpi_size struct_size =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf);
+ ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource");
/* The number of bytes consumed are found in the descriptor (Bits:0-1) */
@@ -378,26 +351,27 @@ acpi_rs_start_depend_fns_resource (
/* Check Compatibility priority */
- output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03;
+ output_struct->data.start_dpf.compatibility_priority =
+ temp8 & 0x03;
if (3 == output_struct->data.start_dpf.compatibility_priority) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
}
/* Check Performance/Robustness preference */
- output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03;
+ output_struct->data.start_dpf.performance_robustness =
+ (temp8 >> 2) & 0x03;
if (3 == output_struct->data.start_dpf.performance_robustness) {
- return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
}
- }
- else {
+ } else {
output_struct->data.start_dpf.compatibility_priority =
- ACPI_ACCEPTABLE_CONFIGURATION;
+ ACPI_ACCEPTABLE_CONFIGURATION;
output_struct->data.start_dpf.performance_robustness =
- ACPI_ACCEPTABLE_CONFIGURATION;
+ ACPI_ACCEPTABLE_CONFIGURATION;
}
/* Set the Length parameter */
@@ -407,10 +381,9 @@ acpi_rs_start_depend_fns_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_end_depend_fns_resource
@@ -433,18 +406,14 @@ acpi_rs_start_depend_fns_resource (
******************************************************************************/
acpi_status
-acpi_rs_end_depend_fns_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size)
+acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size)
{
- struct acpi_resource *output_struct = (void *) *output_buffer;
- acpi_size struct_size = ACPI_RESOURCE_LENGTH;
-
-
- ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource");
+ struct acpi_resource *output_struct = (void *)*output_buffer;
+ acpi_size struct_size = ACPI_RESOURCE_LENGTH;
+ ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource");
/* The number of bytes consumed is static */
@@ -461,10 +430,9 @@ acpi_rs_end_depend_fns_resource (
/* Return the final size of the structure */
*structure_size = struct_size;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_start_depend_fns_stream
@@ -483,39 +451,35 @@ acpi_rs_end_depend_fns_resource (
******************************************************************************/
acpi_status
-acpi_rs_start_depend_fns_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
- u8 temp8 = 0;
-
-
- ACPI_FUNCTION_TRACE ("rs_start_depend_fns_stream");
+ u8 *buffer = *output_buffer;
+ u8 temp8 = 0;
+ ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream");
/*
* The descriptor field is set based upon whether a byte is needed
* to contain Priority data.
*/
if (ACPI_ACCEPTABLE_CONFIGURATION ==
- linked_list->data.start_dpf.compatibility_priority &&
- ACPI_ACCEPTABLE_CONFIGURATION ==
- linked_list->data.start_dpf.performance_robustness) {
+ linked_list->data.start_dpf.compatibility_priority &&
+ ACPI_ACCEPTABLE_CONFIGURATION ==
+ linked_list->data.start_dpf.performance_robustness) {
*buffer = 0x30;
- }
- else {
+ } else {
*buffer = 0x31;
buffer += 1;
/* Set the Priority Byte Definition */
temp8 = 0;
- temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness &
- 0x03) << 2);
- temp8 |= (linked_list->data.start_dpf.compatibility_priority &
- 0x03);
+ temp8 =
+ (u8) ((linked_list->data.start_dpf.
+ performance_robustness & 0x03) << 2);
+ temp8 |=
+ (linked_list->data.start_dpf.compatibility_priority & 0x03);
*buffer = temp8;
}
@@ -523,11 +487,10 @@ acpi_rs_start_depend_fns_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_end_depend_fns_stream
@@ -545,16 +508,12 @@ acpi_rs_start_depend_fns_stream (
******************************************************************************/
acpi_status
-acpi_rs_end_depend_fns_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed)
+acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed)
{
- u8 *buffer = *output_buffer;
-
-
- ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream");
+ u8 *buffer = *output_buffer;
+ ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream");
/* The descriptor field is static */
@@ -563,7 +522,6 @@ acpi_rs_end_depend_fns_stream (
/* Return the number of bytes consumed in this operation */
- *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
- return_ACPI_STATUS (AE_OK);
+ *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 700cf7d65d76..4446778eaf79 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -41,15 +41,12 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acresrc.h>
-
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsutils")
-
+ACPI_MODULE_NAME("rsutils")
/*******************************************************************************
*
@@ -68,42 +65,36 @@
* and the contents of the callers buffer is undefined.
*
******************************************************************************/
-
acpi_status
-acpi_rs_get_prt_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer)
+acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_prt_method_data");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("rs_get_prt_method_data");
/* Parameters guaranteed valid by caller */
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object (handle, METHOD_NAME__PRT,
- ACPI_BTYPE_PACKAGE, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRT,
+ ACPI_BTYPE_PACKAGE, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* Create a resource linked list from the byte stream buffer that comes
* back from the _CRS method execution.
*/
- status = acpi_rs_create_pci_routing_table (obj_desc, ret_buffer);
+ status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
/* On exit, we must delete the object returned by evaluate_object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_crs_method_data
@@ -123,25 +114,21 @@ acpi_rs_get_prt_method_data (
******************************************************************************/
acpi_status
-acpi_rs_get_crs_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer)
+acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_crs_method_data");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("rs_get_crs_method_data");
/* Parameters guaranteed valid by caller */
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object (handle, METHOD_NAME__CRS,
- ACPI_BTYPE_BUFFER, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(handle, METHOD_NAME__CRS,
+ ACPI_BTYPE_BUFFER, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -149,15 +136,14 @@ acpi_rs_get_crs_method_data (
* byte stream buffer that comes back from the _CRS method
* execution.
*/
- status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+ status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
/* on exit, we must delete the object returned by evaluate_object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_prs_method_data
@@ -178,25 +164,21 @@ acpi_rs_get_crs_method_data (
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_rs_get_prs_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer)
+acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_prs_method_data");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("rs_get_prs_method_data");
/* Parameters guaranteed valid by caller */
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object (handle, METHOD_NAME__PRS,
- ACPI_BTYPE_BUFFER, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRS,
+ ACPI_BTYPE_BUFFER, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -204,15 +186,14 @@ acpi_rs_get_prs_method_data (
* byte stream buffer that comes back from the _CRS method
* execution.
*/
- status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+ status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
/* on exit, we must delete the object returned by evaluate_object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -234,25 +215,22 @@ acpi_rs_get_prs_method_data (
******************************************************************************/
acpi_status
-acpi_rs_get_method_data (
- acpi_handle handle,
- char *path,
- struct acpi_buffer *ret_buffer)
+acpi_rs_get_method_data(acpi_handle handle,
+ char *path, struct acpi_buffer *ret_buffer)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("rs_get_method_data");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("rs_get_method_data");
/* Parameters guaranteed valid by caller */
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_evaluate_object(handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -260,12 +238,12 @@ acpi_rs_get_method_data (
* byte stream buffer that comes back from the method
* execution.
*/
- status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+ status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
/* On exit, we must delete the object returned by evaluate_object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -287,18 +265,14 @@ acpi_rs_get_method_data (
******************************************************************************/
acpi_status
-acpi_rs_set_srs_method_data (
- acpi_handle handle,
- struct acpi_buffer *in_buffer)
+acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer)
{
- struct acpi_parameter_info info;
- union acpi_operand_object *params[2];
- acpi_status status;
- struct acpi_buffer buffer;
-
-
- ACPI_FUNCTION_TRACE ("rs_set_srs_method_data");
+ struct acpi_parameter_info info;
+ union acpi_operand_object *params[2];
+ acpi_status status;
+ struct acpi_buffer buffer;
+ ACPI_FUNCTION_TRACE("rs_set_srs_method_data");
/* Parameters guaranteed valid by caller */
@@ -310,24 +284,24 @@ acpi_rs_set_srs_method_data (
* Convert the linked list into a byte stream
*/
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_rs_create_byte_stream (in_buffer->pointer, &buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_rs_create_byte_stream(in_buffer->pointer, &buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Init the param object */
- params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+ params[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
if (!params[0]) {
- acpi_os_free (buffer.pointer);
- return_ACPI_STATUS (AE_NO_MEMORY);
+ acpi_os_free(buffer.pointer);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Set up the parameter object */
- params[0]->buffer.length = (u32) buffer.length;
+ params[0]->buffer.length = (u32) buffer.length;
params[0]->buffer.pointer = buffer.pointer;
- params[0]->common.flags = AOPOBJ_DATA_VALID;
+ params[0]->common.flags = AOPOBJ_DATA_VALID;
params[1] = NULL;
info.node = handle;
@@ -336,18 +310,17 @@ acpi_rs_set_srs_method_data (
/* Execute the method, no return value */
- status = acpi_ns_evaluate_relative (METHOD_NAME__SRS, &info);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_ns_evaluate_relative(METHOD_NAME__SRS, &info);
+ if (ACPI_SUCCESS(status)) {
/* Delete any return object (especially if implicit_return is enabled) */
if (info.return_object) {
- acpi_ut_remove_reference (info.return_object);
+ acpi_ut_remove_reference(info.return_object);
}
}
/* Clean up and return the status from acpi_ns_evaluate_relative */
- acpi_ut_remove_reference (params[0]);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(params[0]);
+ return_ACPI_STATUS(status);
}
-
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 83c944b8b097..ee5a5c509199 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -47,10 +47,9 @@
#include <acpi/acresrc.h>
#define _COMPONENT ACPI_RESOURCES
- ACPI_MODULE_NAME ("rsxface")
+ACPI_MODULE_NAME("rsxface")
/* Local macros for 16,32-bit to 64-bit conversion */
-
#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
#define ACPI_COPY_ADDRESS(out, in) \
ACPI_COPY_FIELD(out, in, resource_type); \
@@ -65,8 +64,6 @@
ACPI_COPY_FIELD(out, in, address_translation_offset); \
ACPI_COPY_FIELD(out, in, address_length); \
ACPI_COPY_FIELD(out, in, resource_source);
-
-
/*******************************************************************************
*
* FUNCTION: acpi_get_irq_routing_table
@@ -89,17 +86,13 @@
* the object indicated by the passed device_handle.
*
******************************************************************************/
-
acpi_status
-acpi_get_irq_routing_table (
- acpi_handle device_handle,
- struct acpi_buffer *ret_buffer)
+acpi_get_irq_routing_table(acpi_handle device_handle,
+ struct acpi_buffer *ret_buffer)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_irq_routing_table ");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_get_irq_routing_table ");
/*
* Must have a valid handle and buffer, So we have to have a handle
@@ -108,19 +101,18 @@ acpi_get_irq_routing_table (
* we'll be returning the needed buffer size, so keep going.
*/
if (!device_handle) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_validate_buffer (ret_buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_validate_buffer(ret_buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_rs_get_prt_method_data (device_handle, ret_buffer);
- return_ACPI_STATUS (status);
+ status = acpi_rs_get_prt_method_data(device_handle, ret_buffer);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_current_resources
@@ -146,15 +138,12 @@ acpi_get_irq_routing_table (
******************************************************************************/
acpi_status
-acpi_get_current_resources (
- acpi_handle device_handle,
- struct acpi_buffer *ret_buffer)
+acpi_get_current_resources(acpi_handle device_handle,
+ struct acpi_buffer *ret_buffer)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_current_resources");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_get_current_resources");
/*
* Must have a valid handle and buffer, So we have to have a handle
@@ -163,19 +152,19 @@ acpi_get_current_resources (
* we'll be returning the needed buffer size, so keep going.
*/
if (!device_handle) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_validate_buffer (ret_buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_validate_buffer(ret_buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_rs_get_crs_method_data (device_handle, ret_buffer);
- return_ACPI_STATUS (status);
+ status = acpi_rs_get_crs_method_data(device_handle, ret_buffer);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_current_resources);
+EXPORT_SYMBOL(acpi_get_current_resources);
/*******************************************************************************
*
@@ -200,15 +189,12 @@ EXPORT_SYMBOL(acpi_get_current_resources);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_get_possible_resources (
- acpi_handle device_handle,
- struct acpi_buffer *ret_buffer)
+acpi_get_possible_resources(acpi_handle device_handle,
+ struct acpi_buffer *ret_buffer)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_possible_resources");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_get_possible_resources");
/*
* Must have a valid handle and buffer, So we have to have a handle
@@ -217,20 +203,20 @@ acpi_get_possible_resources (
* we'll be returning the needed buffer size, so keep going.
*/
if (!device_handle) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_validate_buffer (ret_buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_validate_buffer(ret_buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_rs_get_prs_method_data (device_handle, ret_buffer);
- return_ACPI_STATUS (status);
+ status = acpi_rs_get_prs_method_data(device_handle, ret_buffer);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_possible_resources);
-#endif /* ACPI_FUTURE_USAGE */
+EXPORT_SYMBOL(acpi_get_possible_resources);
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -252,37 +238,33 @@ EXPORT_SYMBOL(acpi_get_possible_resources);
******************************************************************************/
acpi_status
-acpi_walk_resources (
- acpi_handle device_handle,
- char *path,
- ACPI_WALK_RESOURCE_CALLBACK user_function,
- void *context)
+acpi_walk_resources(acpi_handle device_handle,
+ char *path,
+ ACPI_WALK_RESOURCE_CALLBACK user_function, void *context)
{
- acpi_status status;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_resource *resource;
- struct acpi_resource *buffer_end;
-
-
- ACPI_FUNCTION_TRACE ("acpi_walk_resources");
+ acpi_status status;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_resource *resource;
+ struct acpi_resource *buffer_end;
+ ACPI_FUNCTION_TRACE("acpi_walk_resources");
if (!device_handle ||
- (ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) &&
- ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) &&
+ ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_rs_get_method_data (device_handle, path, &buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_rs_get_method_data(device_handle, path, &buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Setup pointers */
- resource = (struct acpi_resource *) buffer.pointer;
- buffer_end = ACPI_CAST_PTR (struct acpi_resource,
- ((u8 *) buffer.pointer + buffer.length));
+ resource = (struct acpi_resource *)buffer.pointer;
+ buffer_end = ACPI_CAST_PTR(struct acpi_resource,
+ ((u8 *) buffer.pointer + buffer.length));
/* Walk the resource list */
@@ -291,7 +273,7 @@ acpi_walk_resources (
break;
}
- status = user_function (resource, context);
+ status = user_function(resource, context);
switch (status) {
case AE_OK:
@@ -318,7 +300,7 @@ acpi_walk_resources (
/* Get the next resource descriptor */
- resource = ACPI_NEXT_RESOURCE (resource);
+ resource = ACPI_NEXT_RESOURCE(resource);
/* Check for end-of-buffer */
@@ -327,13 +309,13 @@ acpi_walk_resources (
}
}
-cleanup:
+ cleanup:
- acpi_os_free (buffer.pointer);
- return_ACPI_STATUS (status);
+ acpi_os_free(buffer.pointer);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_walk_resources);
+EXPORT_SYMBOL(acpi_walk_resources);
/*******************************************************************************
*
@@ -354,30 +336,25 @@ EXPORT_SYMBOL(acpi_walk_resources);
******************************************************************************/
acpi_status
-acpi_set_current_resources (
- acpi_handle device_handle,
- struct acpi_buffer *in_buffer)
+acpi_set_current_resources(acpi_handle device_handle,
+ struct acpi_buffer *in_buffer)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_set_current_resources");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_set_current_resources");
/* Must have a valid handle and buffer */
- if ((!device_handle) ||
- (!in_buffer) ||
- (!in_buffer->pointer) ||
- (!in_buffer->length)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((!device_handle) ||
+ (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
- return_ACPI_STATUS (status);
+ status = acpi_rs_set_srs_method_data(device_handle, in_buffer);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_set_current_resources);
+EXPORT_SYMBOL(acpi_set_current_resources);
/******************************************************************************
*
@@ -398,41 +375,38 @@ EXPORT_SYMBOL(acpi_set_current_resources);
******************************************************************************/
acpi_status
-acpi_resource_to_address64 (
- struct acpi_resource *resource,
- struct acpi_resource_address64 *out)
+acpi_resource_to_address64(struct acpi_resource *resource,
+ struct acpi_resource_address64 *out)
{
- struct acpi_resource_address16 *address16;
- struct acpi_resource_address32 *address32;
-
+ struct acpi_resource_address16 *address16;
+ struct acpi_resource_address32 *address32;
switch (resource->id) {
case ACPI_RSTYPE_ADDRESS16:
- address16 = (struct acpi_resource_address16 *) &resource->data;
- ACPI_COPY_ADDRESS (out, address16);
+ address16 = (struct acpi_resource_address16 *)&resource->data;
+ ACPI_COPY_ADDRESS(out, address16);
break;
-
case ACPI_RSTYPE_ADDRESS32:
- address32 = (struct acpi_resource_address32 *) &resource->data;
- ACPI_COPY_ADDRESS (out, address32);
+ address32 = (struct acpi_resource_address32 *)&resource->data;
+ ACPI_COPY_ADDRESS(out, address32);
break;
-
case ACPI_RSTYPE_ADDRESS64:
/* Simple copy for 64 bit source */
- ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64));
+ ACPI_MEMCPY(out, &resource->data,
+ sizeof(struct acpi_resource_address64));
break;
-
default:
return (AE_BAD_PARAMETER);
}
return (AE_OK);
}
+
EXPORT_SYMBOL(acpi_resource_to_address64);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index cbcda30c172d..c6db591479de 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -9,14 +9,10 @@
#include <acpi/acpi_drivers.h>
#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
-
#define _COMPONENT ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME ("scan")
-
+ACPI_MODULE_NAME("scan")
#define STRUCT_TO_INT(s) (*((int*)&s))
-
-extern struct acpi_device *acpi_root;
-
+extern struct acpi_device *acpi_root;
#define ACPI_BUS_CLASS "system_bus"
#define ACPI_BUS_HID "ACPI_BUS"
@@ -27,13 +23,11 @@ static LIST_HEAD(acpi_device_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
-static int
-acpi_bus_trim(struct acpi_device *start,
- int rmdevice);
+static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
-static void acpi_device_release(struct kobject * kobj)
+static void acpi_device_release(struct kobject *kobj)
{
- struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
+ struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
if (dev->pnp.cid_list)
kfree(dev->pnp.cid_list);
kfree(dev);
@@ -41,34 +35,34 @@ static void acpi_device_release(struct kobject * kobj)
struct acpi_device_attribute {
struct attribute attr;
- ssize_t (*show)(struct acpi_device *, char *);
- ssize_t (*store)(struct acpi_device *, const char *, size_t);
+ ssize_t(*show) (struct acpi_device *, char *);
+ ssize_t(*store) (struct acpi_device *, const char *, size_t);
};
typedef void acpi_device_sysfs_files(struct kobject *,
- const struct attribute *);
+ const struct attribute *);
static void setup_sys_fs_device_files(struct acpi_device *dev,
- acpi_device_sysfs_files *func);
+ acpi_device_sysfs_files * func);
#define create_sysfs_device_files(dev) \
setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file)
#define remove_sysfs_device_files(dev) \
setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
-
#define to_acpi_device(n) container_of(n, struct acpi_device, kobj)
#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr);
static ssize_t acpi_device_attr_show(struct kobject *kobj,
- struct attribute *attr, char *buf)
+ struct attribute *attr, char *buf)
{
struct acpi_device *device = to_acpi_device(kobj);
struct acpi_device_attribute *attribute = to_handle_attr(attr);
return attribute->show ? attribute->show(device, buf) : -EIO;
}
static ssize_t acpi_device_attr_store(struct kobject *kobj,
- struct attribute *attr, const char *buf, size_t len)
+ struct attribute *attr, const char *buf,
+ size_t len)
{
struct acpi_device *device = to_acpi_device(kobj);
struct acpi_device_attribute *attribute = to_handle_attr(attr);
@@ -76,13 +70,13 @@ static ssize_t acpi_device_attr_store(struct kobject *kobj,
}
static struct sysfs_ops acpi_device_sysfs_ops = {
- .show = acpi_device_attr_show,
- .store = acpi_device_attr_store,
+ .show = acpi_device_attr_show,
+ .store = acpi_device_attr_store,
};
static struct kobj_type ktype_acpi_ns = {
- .sysfs_ops = &acpi_device_sysfs_ops,
- .release = acpi_device_release,
+ .sysfs_ops = &acpi_device_sysfs_ops,
+ .release = acpi_device_release,
};
static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
@@ -110,16 +104,16 @@ static struct kset_hotplug_ops namespace_hotplug_ops = {
};
static struct kset acpi_namespace_kset = {
- .kobj = {
- .name = "namespace",
- },
+ .kobj = {
+ .name = "namespace",
+ },
.subsys = &acpi_subsys,
- .ktype = &ktype_acpi_ns,
+ .ktype = &ktype_acpi_ns,
.hotplug_ops = &namespace_hotplug_ops,
};
-
-static void acpi_device_register(struct acpi_device * device, struct acpi_device * parent)
+static void acpi_device_register(struct acpi_device *device,
+ struct acpi_device *parent)
{
/*
* Linkage
@@ -134,14 +128,14 @@ static void acpi_device_register(struct acpi_device * device, struct acpi_device
spin_lock(&acpi_device_lock);
if (device->parent) {
list_add_tail(&device->node, &device->parent->children);
- list_add_tail(&device->g_list,&device->parent->g_list);
+ list_add_tail(&device->g_list, &device->parent->g_list);
} else
- list_add_tail(&device->g_list,&acpi_device_list);
+ list_add_tail(&device->g_list, &acpi_device_list);
if (device->wakeup.flags.valid)
- list_add_tail(&device->wakeup_list,&acpi_wakeup_device_list);
+ list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
spin_unlock(&acpi_device_lock);
- strlcpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN);
+ strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN);
if (parent)
device->kobj.parent = &parent->kobj;
device->kobj.ktype = &ktype_acpi_ns;
@@ -150,10 +144,7 @@ static void acpi_device_register(struct acpi_device * device, struct acpi_device
create_sysfs_device_files(device);
}
-static int
-acpi_device_unregister (
- struct acpi_device *device,
- int type)
+static int acpi_device_unregister(struct acpi_device *device, int type)
{
spin_lock(&acpi_device_lock);
if (device->parent) {
@@ -172,11 +163,7 @@ acpi_device_unregister (
return 0;
}
-void
-acpi_bus_data_handler (
- acpi_handle handle,
- u32 function,
- void *context)
+void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
{
ACPI_FUNCTION_TRACE("acpi_bus_data_handler");
@@ -185,13 +172,11 @@ acpi_bus_data_handler (
return_VOID;
}
-static int
-acpi_bus_get_power_flags (
- struct acpi_device *device)
+static int acpi_bus_get_power_flags(struct acpi_device *device)
{
- acpi_status status = 0;
- acpi_handle handle = NULL;
- u32 i = 0;
+ acpi_status status = 0;
+ acpi_handle handle = NULL;
+ u32 i = 0;
ACPI_FUNCTION_TRACE("acpi_bus_get_power_flags");
@@ -210,11 +195,11 @@ acpi_bus_get_power_flags (
*/
for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
struct acpi_device_power_state *ps = &device->power.states[i];
- char object_name[5] = {'_','P','R','0'+i,'\0'};
+ char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
/* Evaluate "_PRx" to se if power resources are referenced */
acpi_evaluate_reference(device->handle, object_name, NULL,
- &ps->resources);
+ &ps->resources);
if (ps->resources.count) {
device->power.flags.power_resources = 1;
ps->flags.valid = 1;
@@ -232,7 +217,7 @@ acpi_bus_get_power_flags (
if (ps->resources.count || ps->flags.explicit_set)
ps->flags.valid = 1;
- ps->power = -1; /* Unknown - driver assigned */
+ ps->power = -1; /* Unknown - driver assigned */
ps->latency = -1; /* Unknown - driver assigned */
}
@@ -249,13 +234,10 @@ acpi_bus_get_power_flags (
return_VALUE(0);
}
-int
-acpi_match_ids (
- struct acpi_device *device,
- char *ids)
+int acpi_match_ids(struct acpi_device *device, char *ids)
{
int error = 0;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
if (device->flags.hardware_id)
if (strstr(ids, device->pnp.hardware_id))
@@ -266,27 +248,25 @@ acpi_match_ids (
int i;
/* compare multiple _CID entries against driver ids */
- for (i = 0; i < cid_list->count; i++)
- {
+ for (i = 0; i < cid_list->count; i++) {
if (strstr(ids, cid_list->id[i].value))
goto Done;
}
}
error = -ENOENT;
- Done:
+ Done:
if (buffer.pointer)
acpi_os_free(buffer.pointer);
return error;
}
static acpi_status
-acpi_bus_extract_wakeup_device_power_package (
- struct acpi_device *device,
- union acpi_object *package)
+acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
+ union acpi_object *package)
{
- int i = 0;
- union acpi_object *element = NULL;
+ int i = 0;
+ union acpi_object *element = NULL;
if (!device || !package || (package->package.count < 2))
return AE_BAD_PARAMETER;
@@ -296,14 +276,17 @@ acpi_bus_extract_wakeup_device_power_package (
return AE_BAD_PARAMETER;
if (element->type == ACPI_TYPE_PACKAGE) {
if ((element->package.count < 2) ||
- (element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) ||
- (element->package.elements[1].type != ACPI_TYPE_INTEGER))
+ (element->package.elements[0].type !=
+ ACPI_TYPE_LOCAL_REFERENCE)
+ || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
return AE_BAD_DATA;
- device->wakeup.gpe_device = element->package.elements[0].reference.handle;
- device->wakeup.gpe_number = (u32)element->package.elements[1].integer.value;
- }else if (element->type == ACPI_TYPE_INTEGER) {
+ device->wakeup.gpe_device =
+ element->package.elements[0].reference.handle;
+ device->wakeup.gpe_number =
+ (u32) element->package.elements[1].integer.value;
+ } else if (element->type == ACPI_TYPE_INTEGER) {
device->wakeup.gpe_number = element->integer.value;
- }else
+ } else
return AE_BAD_DATA;
element = &(package->package.elements[1]);
@@ -316,9 +299,9 @@ acpi_bus_extract_wakeup_device_power_package (
return AE_NO_MEMORY;
}
device->wakeup.resources.count = package->package.count - 2;
- for (i=0; i < device->wakeup.resources.count; i++) {
+ for (i = 0; i < device->wakeup.resources.count; i++) {
element = &(package->package.elements[i + 2]);
- if (element->type != ACPI_TYPE_ANY ) {
+ if (element->type != ACPI_TYPE_ANY) {
return AE_BAD_DATA;
}
@@ -328,13 +311,11 @@ acpi_bus_extract_wakeup_device_power_package (
return AE_OK;
}
-static int
-acpi_bus_get_wakeup_device_flags (
- struct acpi_device *device)
+static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
{
- acpi_status status = 0;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *package = NULL;
+ acpi_status status = 0;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *package = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags");
@@ -345,21 +326,22 @@ acpi_bus_get_wakeup_device_flags (
goto end;
}
- package = (union acpi_object *) buffer.pointer;
+ package = (union acpi_object *)buffer.pointer;
status = acpi_bus_extract_wakeup_device_power_package(device, package);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _PRW package\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error extracting _PRW package\n"));
goto end;
}
acpi_os_free(buffer.pointer);
device->wakeup.flags.valid = 1;
- /* Power button, Lid switch always enable wakeup*/
+ /* Power button, Lid switch always enable wakeup */
if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
device->wakeup.flags.run_wake = 1;
-end:
+ end:
if (ACPI_FAILURE(status))
device->flags.wake_capable = 0;
return_VALUE(0);
@@ -368,8 +350,8 @@ end:
/* --------------------------------------------------------------------------
ACPI hotplug sysfs device file support
-------------------------------------------------------------------------- */
-static ssize_t acpi_eject_store(struct acpi_device *device,
- const char *buf, size_t count);
+static ssize_t acpi_eject_store(struct acpi_device *device,
+ const char *buf, size_t count);
#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
static struct acpi_device_attribute acpi_device_attr_##_name = \
@@ -383,12 +365,11 @@ ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
* @func: function pointer to create or destroy the device file
*/
static void
-setup_sys_fs_device_files (
- struct acpi_device *dev,
- acpi_device_sysfs_files *func)
+setup_sys_fs_device_files(struct acpi_device *dev,
+ acpi_device_sysfs_files * func)
{
- acpi_status status;
- acpi_handle temp = NULL;
+ acpi_status status;
+ acpi_handle temp = NULL;
/*
* If device has _EJ0, 'eject' file is created that is used to trigger
@@ -396,11 +377,10 @@ setup_sys_fs_device_files (
*/
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
- (*(func))(&dev->kobj,&acpi_device_attr_eject.attr);
+ (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr);
}
-static int
-acpi_eject_operation(acpi_handle handle, int lockable)
+static int acpi_eject_operation(acpi_handle handle, int lockable)
{
struct acpi_object_list arg_list;
union acpi_object arg;
@@ -429,27 +409,25 @@ acpi_eject_operation(acpi_handle handle, int lockable)
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status)) {
- return(-ENODEV);
+ return (-ENODEV);
}
- return(0);
+ return (0);
}
-
static ssize_t
acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
{
- int result;
- int ret = count;
- int islockable;
- acpi_status status;
- acpi_handle handle;
- acpi_object_type type = 0;
+ int result;
+ int ret = count;
+ int islockable;
+ acpi_status status;
+ acpi_handle handle;
+ acpi_object_type type = 0;
if ((!count) || (buf[0] != '1')) {
return -EINVAL;
}
-
#ifndef FORCE_EJECT
if (device->driver == NULL) {
ret = -ENODEV;
@@ -457,7 +435,7 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
}
#endif
status = acpi_get_type(device->handle, &type);
- if (ACPI_FAILURE(status) || (!device->flags.ejectable) ) {
+ if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
ret = -ENODEV;
goto err;
}
@@ -476,18 +454,15 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
if (result) {
ret = -EBUSY;
}
-err:
+ err:
return ret;
}
-
/* --------------------------------------------------------------------------
Performance Management
-------------------------------------------------------------------------- */
-static int
-acpi_bus_get_perf_flags (
- struct acpi_device *device)
+static int acpi_bus_get_perf_flags(struct acpi_device *device)
{
device->performance.state = ACPI_STATE_UNKNOWN;
return 0;
@@ -500,7 +475,6 @@ acpi_bus_get_perf_flags (
static LIST_HEAD(acpi_bus_drivers);
static DECLARE_MUTEX(acpi_bus_drivers_lock);
-
/**
* acpi_bus_match
* --------------
@@ -508,16 +482,13 @@ static DECLARE_MUTEX(acpi_bus_drivers_lock);
* matches the specified driver's criteria.
*/
static int
-acpi_bus_match (
- struct acpi_device *device,
- struct acpi_driver *driver)
+acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
{
if (driver && driver->ops.match)
return driver->ops.match(device, driver);
return acpi_match_ids(device, driver->ids);
}
-
/**
* acpi_bus_driver_init
* --------------------
@@ -525,11 +496,9 @@ acpi_bus_match (
* driver is bound to a device. Invokes the driver's add() and start() ops.
*/
static int
-acpi_bus_driver_init (
- struct acpi_device *device,
- struct acpi_driver *driver)
+acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_bus_driver_init");
@@ -553,13 +522,12 @@ acpi_bus_driver_init (
* upon possible configuration and currently allocated resources.
*/
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Driver successfully bound to device\n"));
return_VALUE(0);
}
-int
-acpi_start_single_object (
- struct acpi_device *device)
+static int acpi_start_single_object(struct acpi_device *device)
{
int result = 0;
struct acpi_driver *driver;
@@ -578,16 +546,17 @@ acpi_start_single_object (
return_VALUE(result);
}
-static int acpi_driver_attach(struct acpi_driver * drv)
+static int acpi_driver_attach(struct acpi_driver *drv)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
int count = 0;
ACPI_FUNCTION_TRACE("acpi_driver_attach");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_device_list) {
- struct acpi_device * dev = container_of(node, struct acpi_device, g_list);
+ struct acpi_device *dev =
+ container_of(node, struct acpi_device, g_list);
if (dev->driver || !dev->status.present)
continue;
@@ -598,7 +567,8 @@ static int acpi_driver_attach(struct acpi_driver * drv)
acpi_start_single_object(dev);
atomic_inc(&drv->references);
count++;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found driver [%s] for device [%s]\n",
drv->name, dev->pnp.bus_id));
}
}
@@ -608,20 +578,21 @@ static int acpi_driver_attach(struct acpi_driver * drv)
return_VALUE(count);
}
-static int acpi_driver_detach(struct acpi_driver * drv)
+static int acpi_driver_detach(struct acpi_driver *drv)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
ACPI_FUNCTION_TRACE("acpi_driver_detach");
spin_lock(&acpi_device_lock);
- list_for_each_safe(node,next,&acpi_device_list) {
- struct acpi_device * dev = container_of(node,struct acpi_device,g_list);
+ list_for_each_safe(node, next, &acpi_device_list) {
+ struct acpi_device *dev =
+ container_of(node, struct acpi_device, g_list);
if (dev->driver == drv) {
spin_unlock(&acpi_device_lock);
if (drv->ops.remove)
- drv->ops.remove(dev,ACPI_BUS_REMOVAL_NORMAL);
+ drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
spin_lock(&acpi_device_lock);
dev->driver = NULL;
dev->driver_data = NULL;
@@ -640,9 +611,7 @@ static int acpi_driver_detach(struct acpi_driver * drv)
* number of devices that were claimed by the driver, or a negative
* error status for failure.
*/
-int
-acpi_bus_register_driver (
- struct acpi_driver *driver)
+int acpi_bus_register_driver(struct acpi_driver *driver)
{
int count;
@@ -661,8 +630,8 @@ acpi_bus_register_driver (
return_VALUE(count);
}
-EXPORT_SYMBOL(acpi_bus_register_driver);
+EXPORT_SYMBOL(acpi_bus_register_driver);
/**
* acpi_bus_unregister_driver
@@ -670,9 +639,7 @@ EXPORT_SYMBOL(acpi_bus_register_driver);
* Unregisters a driver with the ACPI bus. Searches the namespace for all
* devices that match the driver's criteria and unbinds.
*/
-int
-acpi_bus_unregister_driver (
- struct acpi_driver *driver)
+int acpi_bus_unregister_driver(struct acpi_driver *driver)
{
int error = 0;
@@ -685,11 +652,12 @@ acpi_bus_unregister_driver (
spin_lock(&acpi_device_lock);
list_del_init(&driver->node);
spin_unlock(&acpi_device_lock);
- }
- } else
+ }
+ } else
error = -EINVAL;
return_VALUE(error);
}
+
EXPORT_SYMBOL(acpi_bus_unregister_driver);
/**
@@ -698,18 +666,17 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver);
* Parses the list of registered drivers looking for a driver applicable for
* the specified device.
*/
-static int
-acpi_bus_find_driver (
- struct acpi_device *device)
+static int acpi_bus_find_driver(struct acpi_device *device)
{
- int result = 0;
- struct list_head * node, *next;
+ int result = 0;
+ struct list_head *node, *next;
ACPI_FUNCTION_TRACE("acpi_bus_find_driver");
spin_lock(&acpi_device_lock);
- list_for_each_safe(node,next,&acpi_bus_drivers) {
- struct acpi_driver * driver = container_of(node,struct acpi_driver,node);
+ list_for_each_safe(node, next, &acpi_bus_drivers) {
+ struct acpi_driver *driver =
+ container_of(node, struct acpi_driver, node);
atomic_inc(&driver->references);
spin_unlock(&acpi_device_lock);
@@ -723,21 +690,18 @@ acpi_bus_find_driver (
}
spin_unlock(&acpi_device_lock);
- Done:
+ Done:
return_VALUE(result);
}
-
/* --------------------------------------------------------------------------
Device Enumeration
-------------------------------------------------------------------------- */
-static int
-acpi_bus_get_flags (
- struct acpi_device *device)
+static int acpi_bus_get_flags(struct acpi_device *device)
{
- acpi_status status = AE_OK;
- acpi_handle temp = NULL;
+ acpi_status status = AE_OK;
+ acpi_handle temp = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_get_flags");
@@ -788,11 +752,12 @@ acpi_bus_get_flags (
return_VALUE(0);
}
-static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handle, int type)
+static void acpi_device_get_busid(struct acpi_device *device,
+ acpi_handle handle, int type)
{
- char bus_id[5] = {'?',0};
- struct acpi_buffer buffer = {sizeof(bus_id), bus_id};
- int i = 0;
+ char bus_id[5] = { '?', 0 };
+ struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
+ int i = 0;
/*
* Bus ID
@@ -824,21 +789,22 @@ static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handl
}
}
-static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * parent,
- acpi_handle handle, int type)
+static void acpi_device_set_id(struct acpi_device *device,
+ struct acpi_device *parent, acpi_handle handle,
+ int type)
{
- struct acpi_device_info *info;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- char *hid = NULL;
- char *uid = NULL;
+ struct acpi_device_info *info;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ char *hid = NULL;
+ char *uid = NULL;
struct acpi_compatible_id_list *cid_list = NULL;
- acpi_status status;
+ acpi_status status;
switch (type) {
case ACPI_BUS_TYPE_DEVICE:
status = acpi_get_object_info(handle, &buffer);
if (ACPI_FAILURE(status)) {
- printk("%s: Error reading device info\n",__FUNCTION__);
+ printk("%s: Error reading device info\n", __FUNCTION__);
return;
}
@@ -904,7 +870,7 @@ static void acpi_device_set_id(struct acpi_device * device, struct acpi_device *
acpi_os_free(buffer.pointer);
}
-static int acpi_device_set_context(struct acpi_device * device, int type)
+static int acpi_device_set_context(struct acpi_device *device, int type)
{
acpi_status status = AE_OK;
int result = 0;
@@ -916,10 +882,10 @@ static int acpi_device_set_context(struct acpi_device * device, int type)
* to be careful with fixed-feature devices as they all attach to the
* root object.
*/
- if (type != ACPI_BUS_TYPE_POWER_BUTTON &&
+ if (type != ACPI_BUS_TYPE_POWER_BUTTON &&
type != ACPI_BUS_TYPE_SLEEP_BUTTON) {
status = acpi_attach_data(device->handle,
- acpi_bus_data_handler, device);
+ acpi_bus_data_handler, device);
if (ACPI_FAILURE(status)) {
printk("Error attaching device data\n");
@@ -929,12 +895,13 @@ static int acpi_device_set_context(struct acpi_device * device, int type)
return result;
}
-static void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
+static void acpi_device_get_debug_info(struct acpi_device *device,
+ acpi_handle handle, int type)
{
#ifdef CONFIG_ACPI_DEBUG_OUTPUT
- char *type_string = NULL;
- char name[80] = {'?','\0'};
- struct acpi_buffer buffer = {sizeof(name), name};
+ char *type_string = NULL;
+ char name[80] = { '?', '\0' };
+ struct acpi_buffer buffer = { sizeof(name), name };
switch (type) {
case ACPI_BUS_TYPE_DEVICE:
@@ -968,18 +935,14 @@ static void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle
}
printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle);
-#endif /*CONFIG_ACPI_DEBUG_OUTPUT*/
+#endif /*CONFIG_ACPI_DEBUG_OUTPUT */
}
-
-static int
-acpi_bus_remove (
- struct acpi_device *dev,
- int rmdevice)
+static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
{
- int result = 0;
- struct acpi_driver *driver;
-
+ int result = 0;
+ struct acpi_driver *driver;
+
ACPI_FUNCTION_TRACE("acpi_bus_remove");
if (!dev)
@@ -1012,22 +975,18 @@ acpi_bus_remove (
if ((dev->parent) && (dev->parent->ops.unbind))
dev->parent->ops.unbind(dev);
}
-
+
acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
return_VALUE(0);
}
-
static int
-acpi_add_single_object (
- struct acpi_device **child,
- struct acpi_device *parent,
- acpi_handle handle,
- int type)
+acpi_add_single_object(struct acpi_device **child,
+ struct acpi_device *parent, acpi_handle handle, int type)
{
- int result = 0;
- struct acpi_device *device = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_add_single_object");
@@ -1044,7 +1003,7 @@ acpi_add_single_object (
device->handle = handle;
device->parent = parent;
- acpi_device_get_busid(device,handle,type);
+ acpi_device_get_busid(device, handle, type);
/*
* Flags
@@ -1092,7 +1051,7 @@ acpi_add_single_object (
* Hardware ID, Unique ID, & Bus Address
* -------------------------------------
*/
- acpi_device_set_id(device,parent,handle,type);
+ acpi_device_set_id(device, parent, handle, type);
/*
* Power Management
@@ -1104,7 +1063,7 @@ acpi_add_single_object (
goto end;
}
- /*
+ /*
* Wakeup device management
*-----------------------
*/
@@ -1124,12 +1083,12 @@ acpi_add_single_object (
goto end;
}
- if ((result = acpi_device_set_context(device,type)))
+ if ((result = acpi_device_set_context(device, type)))
goto end;
- acpi_device_get_debug_info(device,handle,type);
+ acpi_device_get_debug_info(device, handle, type);
- acpi_device_register(device,parent);
+ acpi_device_register(device, parent);
/*
* Bind _ADR-Based Devices
@@ -1154,7 +1113,7 @@ acpi_add_single_object (
*/
result = acpi_bus_find_driver(device);
-end:
+ end:
if (!result)
*child = device;
else {
@@ -1166,17 +1125,15 @@ end:
return_VALUE(result);
}
-
-static int acpi_bus_scan (struct acpi_device *start,
- struct acpi_bus_ops *ops)
+static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
{
- acpi_status status = AE_OK;
- struct acpi_device *parent = NULL;
- struct acpi_device *child = NULL;
- acpi_handle phandle = NULL;
- acpi_handle chandle = NULL;
- acpi_object_type type = 0;
- u32 level = 1;
+ acpi_status status = AE_OK;
+ struct acpi_device *parent = NULL;
+ struct acpi_device *child = NULL;
+ acpi_handle phandle = NULL;
+ acpi_handle chandle = NULL;
+ acpi_object_type type = 0;
+ u32 level = 1;
ACPI_FUNCTION_TRACE("acpi_bus_scan");
@@ -1185,7 +1142,7 @@ static int acpi_bus_scan (struct acpi_device *start,
parent = start;
phandle = start->handle;
-
+
/*
* Parse through the ACPI namespace, identify all 'devices', and
* create a new 'struct acpi_device' for each.
@@ -1193,7 +1150,7 @@ static int acpi_bus_scan (struct acpi_device *start,
while ((level > 0) && parent) {
status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
- chandle, &chandle);
+ chandle, &chandle);
/*
* If this scope is exhausted then move our way back up.
@@ -1243,12 +1200,12 @@ static int acpi_bus_scan (struct acpi_device *start,
if (ops->acpi_op_add)
status = acpi_add_single_object(&child, parent,
- chandle, type);
- else
+ chandle, type);
+ else
status = acpi_bus_get_device(chandle, &child);
- if (ACPI_FAILURE(status))
- continue;
+ if (ACPI_FAILURE(status))
+ continue;
if (ops->acpi_op_start) {
status = acpi_start_single_object(child);
@@ -1264,7 +1221,7 @@ static int acpi_bus_scan (struct acpi_device *start,
* which will be enumerated when the parent is inserted).
*
* TBD: Need notifications and other detection mechanisms
- * in place before we can fully implement this.
+ * in place before we can fully implement this.
*/
if (child->status.present) {
status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
@@ -1282,11 +1239,8 @@ static int acpi_bus_scan (struct acpi_device *start,
}
int
-acpi_bus_add (
- struct acpi_device **child,
- struct acpi_device *parent,
- acpi_handle handle,
- int type)
+acpi_bus_add(struct acpi_device **child,
+ struct acpi_device *parent, acpi_handle handle, int type)
{
int result;
struct acpi_bus_ops ops;
@@ -1301,11 +1255,10 @@ acpi_bus_add (
}
return_VALUE(result);
}
+
EXPORT_SYMBOL(acpi_bus_add);
-int
-acpi_bus_start (
- struct acpi_device *device)
+int acpi_bus_start(struct acpi_device *device)
{
int result;
struct acpi_bus_ops ops;
@@ -1323,26 +1276,25 @@ acpi_bus_start (
}
return_VALUE(result);
}
+
EXPORT_SYMBOL(acpi_bus_start);
-static int
-acpi_bus_trim(struct acpi_device *start,
- int rmdevice)
+static int acpi_bus_trim(struct acpi_device *start, int rmdevice)
{
- acpi_status status;
- struct acpi_device *parent, *child;
- acpi_handle phandle, chandle;
- acpi_object_type type;
- u32 level = 1;
- int err = 0;
-
- parent = start;
+ acpi_status status;
+ struct acpi_device *parent, *child;
+ acpi_handle phandle, chandle;
+ acpi_object_type type;
+ u32 level = 1;
+ int err = 0;
+
+ parent = start;
phandle = start->handle;
child = chandle = NULL;
while ((level > 0) && parent && (!err)) {
status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
- chandle, &chandle);
+ chandle, &chandle);
/*
* If this scope is exhausted then move our way back up.
@@ -1381,12 +1333,10 @@ acpi_bus_trim(struct acpi_device *start,
return err;
}
-static int
-acpi_bus_scan_fixed (
- struct acpi_device *root)
+static int acpi_bus_scan_fixed(struct acpi_device *root)
{
- int result = 0;
- struct acpi_device *device = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed");
@@ -1398,14 +1348,16 @@ acpi_bus_scan_fixed (
*/
if (acpi_fadt.pwr_button == 0) {
result = acpi_add_single_object(&device, acpi_root,
- NULL, ACPI_BUS_TYPE_POWER_BUTTON);
+ NULL,
+ ACPI_BUS_TYPE_POWER_BUTTON);
if (!result)
result = acpi_start_single_object(device);
}
if (acpi_fadt.sleep_button == 0) {
result = acpi_add_single_object(&device, acpi_root,
- NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+ NULL,
+ ACPI_BUS_TYPE_SLEEP_BUTTON);
if (!result)
result = acpi_start_single_object(device);
}
@@ -1413,7 +1365,6 @@ acpi_bus_scan_fixed (
return_VALUE(result);
}
-
static int __init acpi_scan_init(void)
{
int result;
@@ -1430,7 +1381,7 @@ static int __init acpi_scan_init(void)
* Create the root device in the bus's device tree
*/
result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
- ACPI_BUS_TYPE_SYSTEM);
+ ACPI_BUS_TYPE_SYSTEM);
if (result)
goto Done;
@@ -1450,7 +1401,7 @@ static int __init acpi_scan_init(void)
if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
- Done:
+ Done:
return_VALUE(result);
}
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 7249ba2b7a27..aee50b453265 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -23,7 +23,6 @@ u8 sleep_states[ACPI_S_STATE_COUNT];
static struct pm_ops acpi_pm_ops;
-extern void do_suspend_lowlevel_s4bios(void);
extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = {
@@ -98,8 +97,6 @@ static int acpi_pm_enter(suspend_state_t pm_state)
case PM_SUSPEND_DISK:
if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM)
status = acpi_enter_sleep_state(acpi_state);
- else
- do_suspend_lowlevel_s4bios();
break;
case PM_SUSPEND_MAX:
acpi_power_off();
@@ -206,11 +203,6 @@ static int __init acpi_sleep_init(void)
printk(" S%d", i);
}
if (i == ACPI_STATE_S4) {
- if (acpi_gbl_FACS->S4bios_f) {
- sleep_states[i] = 1;
- printk(" S4bios");
- acpi_pm_ops.pm_disk_mode = PM_DISK_FIRMWARE;
- }
if (sleep_states[i])
acpi_pm_ops.pm_disk_mode = PM_DISK_PLATFORM;
}
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index f93d2ee54800..af7935a95bcc 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -21,9 +21,7 @@ int acpi_sleep_prepare(u32 acpi_state)
{
#ifdef CONFIG_ACPI_SLEEP
/* do we have a wakeup address for S2 and S3? */
- /* Here, we support only S4BIOS, those we set the wakeup address */
- /* S4OS is only supported for now via swsusp.. */
- if (acpi_state == ACPI_STATE_S3 || acpi_state == ACPI_STATE_S4) {
+ if (acpi_state == ACPI_STATE_S3) {
if (!acpi_wakeup_address) {
return -EFAULT;
}
@@ -95,4 +93,4 @@ static int acpi_poweroff_init(void)
late_initcall(acpi_poweroff_init);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM */
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 1be99f0996d6..4696a85a98b9 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -13,29 +13,18 @@
#include "sleep.h"
-#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
-#define ACPI_SYSTEM_FILE_SLEEP "sleep"
-#endif
-
-#define ACPI_SYSTEM_FILE_ALARM "alarm"
-#define ACPI_SYSTEM_FILE_WAKEUP_DEVICE "wakeup"
-
#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("sleep")
-
+ACPI_MODULE_NAME("sleep")
#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
-
static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
{
- int i;
+ int i;
ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
for (i = 0; i <= ACPI_STATE_S5; i++) {
if (sleep_states[i]) {
- seq_printf(seq,"S%d ", i);
- if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
- seq_printf(seq, "S4bios ");
+ seq_printf(seq, "S%d ", i);
}
}
@@ -50,24 +39,21 @@ static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
}
static ssize_t
-acpi_system_write_sleep (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_system_write_sleep(struct file *file,
+ const char __user * buffer, size_t count, loff_t * ppos)
{
- char str[12];
- u32 state = 0;
- int error = 0;
+ char str[12];
+ u32 state = 0;
+ int error = 0;
if (count > sizeof(str) - 1)
goto Done;
- memset(str,0,sizeof(str));
+ memset(str, 0, sizeof(str));
if (copy_from_user(str, buffer, count))
return -EFAULT;
/* Check for S4 bios request */
- if (!strcmp(str,"4b")) {
+ if (!strcmp(str, "4b")) {
error = acpi_suspend(4);
goto Done;
}
@@ -79,17 +65,17 @@ acpi_system_write_sleep (
}
#endif
error = acpi_suspend(state);
- Done:
+ Done:
return error ? error : count;
}
-#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{
- u32 sec, min, hr;
- u32 day, mo, yr;
- unsigned char rtc_control = 0;
- unsigned long flags;
+ u32 sec, min, hr;
+ u32 day, mo, yr;
+ unsigned char rtc_control = 0;
+ unsigned long flags;
ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
@@ -105,13 +91,14 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
/* ACPI spec: only low 6 its should be cared */
day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F;
else
- day = CMOS_READ(RTC_DAY_OF_MONTH);
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
if (acpi_gbl_FADT->mon_alrm)
mo = CMOS_READ(acpi_gbl_FADT->mon_alrm);
else
mo = CMOS_READ(RTC_MONTH);
if (acpi_gbl_FADT->century)
- yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
+ yr = CMOS_READ(acpi_gbl_FADT->century) * 100 +
+ CMOS_READ(RTC_YEAR);
else
yr = CMOS_READ(RTC_YEAR);
@@ -126,33 +113,33 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
BCD_TO_BIN(yr);
}
- /* we're trusting the FADT (see above)*/
+ /* we're trusting the FADT (see above) */
if (!acpi_gbl_FADT->century)
- /* If we're not trusting the FADT, we should at least make it
- * right for _this_ century... ehm, what is _this_ century?
- *
- * TBD:
- * ASAP: find piece of code in the kernel, e.g. star tracker driver,
- * which we can trust to determine the century correctly. Atom
- * watch driver would be nice, too...
- *
- * if that has not happened, change for first release in 2050:
- * if (yr<50)
- * yr += 2100;
- * else
- * yr += 2000; // current line of code
- *
- * if that has not happened either, please do on 2099/12/31:23:59:59
- * s/2000/2100
- *
- */
+ /* If we're not trusting the FADT, we should at least make it
+ * right for _this_ century... ehm, what is _this_ century?
+ *
+ * TBD:
+ * ASAP: find piece of code in the kernel, e.g. star tracker driver,
+ * which we can trust to determine the century correctly. Atom
+ * watch driver would be nice, too...
+ *
+ * if that has not happened, change for first release in 2050:
+ * if (yr<50)
+ * yr += 2100;
+ * else
+ * yr += 2000; // current line of code
+ *
+ * if that has not happened either, please do on 2099/12/31:23:59:59
+ * s/2000/2100
+ *
+ */
yr += 2000;
- seq_printf(seq,"%4.4u-", yr);
- (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
- (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day);
- (hr > 23) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", hr);
- (min > 59) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", min);
+ seq_printf(seq, "%4.4u-", yr);
+ (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
+ (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day);
+ (hr > 23) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", hr);
+ (min > 59) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", min);
(sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec);
return 0;
@@ -163,15 +150,11 @@ static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data);
}
-
-static int
-get_date_field (
- char **p,
- u32 *value)
+static int get_date_field(char **p, u32 * value)
{
- char *next = NULL;
- char *string_end = NULL;
- int result = -EINVAL;
+ char *next = NULL;
+ char *string_end = NULL;
+ int result = -EINVAL;
/*
* Try to find delimeter, only to insert null. The end of the
@@ -193,26 +176,22 @@ get_date_field (
return result;
}
-
static ssize_t
-acpi_system_write_alarm (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_system_write_alarm(struct file *file,
+ const char __user * buffer, size_t count, loff_t * ppos)
{
- int result = 0;
- char alarm_string[30] = {'\0'};
- char *p = alarm_string;
- u32 sec, min, hr, day, mo, yr;
- int adjust = 0;
- unsigned char rtc_control = 0;
+ int result = 0;
+ char alarm_string[30] = { '\0' };
+ char *p = alarm_string;
+ u32 sec, min, hr, day, mo, yr;
+ int adjust = 0;
+ unsigned char rtc_control = 0;
ACPI_FUNCTION_TRACE("acpi_system_write_alarm");
if (count > sizeof(alarm_string) - 1)
return_VALUE(-EINVAL);
-
+
if (copy_from_user(alarm_string, buffer, count))
return_VALUE(-EFAULT);
@@ -271,10 +250,10 @@ acpi_system_write_alarm (
}
if (adjust) {
- yr += CMOS_READ(RTC_YEAR);
- mo += CMOS_READ(RTC_MONTH);
+ yr += CMOS_READ(RTC_YEAR);
+ mo += CMOS_READ(RTC_MONTH);
day += CMOS_READ(RTC_DAY_OF_MONTH);
- hr += CMOS_READ(RTC_HOURS);
+ hr += CMOS_READ(RTC_HOURS);
min += CMOS_READ(RTC_MINUTES);
sec += CMOS_READ(RTC_SECONDS);
}
@@ -343,7 +322,7 @@ acpi_system_write_alarm (
if (acpi_gbl_FADT->mon_alrm)
CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
if (acpi_gbl_FADT->century)
- CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
+ CMOS_WRITE(yr / 100, acpi_gbl_FADT->century);
/* enable the rtc alarm interrupt */
rtc_control |= RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
@@ -357,35 +336,33 @@ acpi_system_write_alarm (
*ppos += count;
result = 0;
-end:
+ end:
return_VALUE(result ? result : count);
}
-extern struct list_head acpi_wakeup_device_list;
+extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
static int
acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
seq_printf(seq, "Device Sleep state Status\n");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
+ struct acpi_device *dev =
+ container_of(node, struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid)
continue;
spin_unlock(&acpi_device_lock);
- if (dev->wakeup.flags.run_wake)
- seq_printf(seq, "%4s %4d %8s\n",
- dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
- dev->wakeup.state.enabled ? "*enabled" : "*disabled");
- else
- seq_printf(seq, "%4s %4d %8s\n",
- dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
- dev->wakeup.state.enabled ? "enabled" : "disabled");
+ seq_printf(seq, "%4s %4d %s%8s\n",
+ dev->pnp.bus_id,
+ (u32) dev->wakeup.sleep_state,
+ dev->wakeup.flags.run_wake ? "*" : "",
+ dev->wakeup.state.enabled ? "enabled" : "disabled");
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
@@ -393,19 +370,18 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
}
static ssize_t
-acpi_system_write_wakeup_device (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_system_write_wakeup_device(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
- struct list_head * node, * next;
- char strbuf[5];
- char str[5] = "";
- int len = count;
+ struct list_head *node, *next;
+ char strbuf[5];
+ char str[5] = "";
+ int len = count;
struct acpi_device *found_dev = NULL;
- if (len > 4) len = 4;
+ if (len > 4)
+ len = 4;
if (copy_from_user(strbuf, buffer, len))
return -EFAULT;
@@ -414,28 +390,36 @@ acpi_system_write_wakeup_device (
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
+ struct acpi_device *dev =
+ container_of(node, struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid)
continue;
if (!strncmp(dev->pnp.bus_id, str, 4)) {
- dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1;
+ dev->wakeup.state.enabled =
+ dev->wakeup.state.enabled ? 0 : 1;
found_dev = dev;
break;
}
}
if (found_dev) {
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node,
- struct acpi_device, wakeup_list);
+ struct acpi_device *dev = container_of(node,
+ struct
+ acpi_device,
+ wakeup_list);
if ((dev != found_dev) &&
- (dev->wakeup.gpe_number == found_dev->wakeup.gpe_number) &&
- (dev->wakeup.gpe_device == found_dev->wakeup.gpe_device)) {
- printk(KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, "
- "can't disable/enable one seperately\n",
- dev->pnp.bus_id, found_dev->pnp.bus_id);
- dev->wakeup.state.enabled = found_dev->wakeup.state.enabled;
+ (dev->wakeup.gpe_number ==
+ found_dev->wakeup.gpe_number)
+ && (dev->wakeup.gpe_device ==
+ found_dev->wakeup.gpe_device)) {
+ printk(KERN_WARNING
+ "ACPI: '%s' and '%s' have the same GPE, "
+ "can't disable/enable one seperately\n",
+ dev->pnp.bus_id, found_dev->pnp.bus_id);
+ dev->wakeup.state.enabled =
+ found_dev->wakeup.state.enabled;
}
}
}
@@ -446,37 +430,37 @@ acpi_system_write_wakeup_device (
static int
acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
{
- return single_open(file, acpi_system_wakeup_device_seq_show, PDE(inode)->data);
+ return single_open(file, acpi_system_wakeup_device_seq_show,
+ PDE(inode)->data);
}
static struct file_operations acpi_system_wakeup_device_fops = {
- .open = acpi_system_wakeup_device_open_fs,
- .read = seq_read,
- .write = acpi_system_write_wakeup_device,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_system_wakeup_device_open_fs,
+ .read = seq_read,
+ .write = acpi_system_write_wakeup_device,
+ .llseek = seq_lseek,
+ .release = single_release,
};
#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
static struct file_operations acpi_system_sleep_fops = {
- .open = acpi_system_sleep_open_fs,
- .read = seq_read,
- .write = acpi_system_write_sleep,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_system_sleep_open_fs,
+ .read = seq_read,
+ .write = acpi_system_write_sleep,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
static struct file_operations acpi_system_alarm_fops = {
- .open = acpi_system_alarm_open_fs,
- .read = seq_read,
- .write = acpi_system_write_alarm,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_system_alarm_open_fs,
+ .read = seq_read,
+ .write = acpi_system_write_alarm,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-
-static u32 rtc_handler(void * context)
+static u32 rtc_handler(void *context)
{
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
@@ -486,28 +470,31 @@ static u32 rtc_handler(void * context)
static int acpi_sleep_proc_init(void)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
if (acpi_disabled)
return 0;
-
+
#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
- /* 'sleep' [R/W]*/
- entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+ /* 'sleep' [R/W] */
+ entry =
+ create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_sleep_fops;
#endif
/* 'alarm' [R/W] */
- entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+ entry =
+ create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_alarm_fops;
- /* 'wakeup device' [R/W]*/
- entry = create_proc_entry(ACPI_SYSTEM_FILE_WAKEUP_DEVICE,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+ /* 'wakeup device' [R/W] */
+ entry =
+ create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_wakeup_device_fops;
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index d9b199969d5d..4134ed43d026 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -12,9 +12,9 @@
#include "sleep.h"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("wakeup_devices")
+ACPI_MODULE_NAME("wakeup_devices")
-extern struct list_head acpi_wakeup_device_list;
+extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
#ifdef CONFIG_ACPI_SLEEP
@@ -25,22 +25,21 @@ extern spinlock_t acpi_device_lock;
* is higher than requested sleep level
*/
-void
-acpi_enable_wakeup_device_prep(
- u8 sleep_state)
+void acpi_enable_wakeup_device_prep(u8 sleep_state)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node,
- struct acpi_device, wakeup_list);
-
- if (!dev->wakeup.flags.valid ||
- !dev->wakeup.state.enabled ||
- (sleep_state > (u32) dev->wakeup.sleep_state))
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
+
+ if (!dev->wakeup.flags.valid ||
+ !dev->wakeup.state.enabled ||
+ (sleep_state > (u32) dev->wakeup.sleep_state))
continue;
spin_unlock(&acpi_device_lock);
@@ -55,11 +54,9 @@ acpi_enable_wakeup_device_prep(
* @sleep_state: ACPI state
* Enable all wakup devices's GPE
*/
-void
-acpi_enable_wakeup_device(
- u8 sleep_state)
+void acpi_enable_wakeup_device(u8 sleep_state)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
/*
* Caution: this routine must be invoked when interrupt is disabled
@@ -68,33 +65,35 @@ acpi_enable_wakeup_device(
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node,
- struct acpi_device, wakeup_list);
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
/* If users want to disable run-wake GPE,
* we only disable it for wake and leave it for runtime
*/
if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_RUNTIME);
/* Re-enable it, since set_gpe_type will disable it */
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_ISR);
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_ISR);
spin_lock(&acpi_device_lock);
continue;
}
if (!dev->wakeup.flags.valid ||
- !dev->wakeup.state.enabled ||
- (sleep_state > (u32) dev->wakeup.sleep_state))
+ !dev->wakeup.state.enabled ||
+ (sleep_state > (u32) dev->wakeup.sleep_state))
continue;
spin_unlock(&acpi_device_lock);
/* run-wake GPE has been enabled */
if (!dev->wakeup.flags.run_wake)
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_ISR);
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_ISR);
dev->wakeup.state.active = 1;
spin_lock(&acpi_device_lock);
}
@@ -106,43 +105,43 @@ acpi_enable_wakeup_device(
* @sleep_state: ACPI state
* Disable all wakup devices's GPE and wakeup capability
*/
-void
-acpi_disable_wakeup_device (
- u8 sleep_state)
+void acpi_disable_wakeup_device(u8 sleep_state)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node,
- struct acpi_device, wakeup_list);
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
/* Re-enable it, since set_gpe_type will disable it */
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
spin_lock(&acpi_device_lock);
continue;
}
- if (!dev->wakeup.flags.valid ||
- !dev->wakeup.state.active ||
- (sleep_state > (u32) dev->wakeup.sleep_state))
+ if (!dev->wakeup.flags.valid ||
+ !dev->wakeup.state.active ||
+ (sleep_state > (u32) dev->wakeup.sleep_state))
continue;
spin_unlock(&acpi_device_lock);
acpi_disable_wakeup_device_power(dev);
/* Never disable run-wake GPE */
if (!dev->wakeup.flags.run_wake) {
- acpi_disable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
- acpi_clear_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ acpi_disable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ acpi_clear_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
}
dev->wakeup.state.active = 0;
spin_lock(&acpi_device_lock);
@@ -152,7 +151,7 @@ acpi_disable_wakeup_device (
static int __init acpi_wakeup_device_init(void)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
if (acpi_disabled)
return 0;
@@ -160,16 +159,18 @@ static int __init acpi_wakeup_device_init(void)
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node,
- struct acpi_device, wakeup_list);
-
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
+
/* In case user doesn't load button driver */
if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
dev->wakeup.state.enabled = 1;
spin_lock(&acpi_device_lock);
}
@@ -193,17 +194,19 @@ late_initcall(acpi_wakeup_device_init);
*/
void acpi_wakeup_gpe_poweroff_prepare(void)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device * dev = container_of(node,
- struct acpi_device, wakeup_list);
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
/* The GPE can wakeup system from S5, don't touch it */
- if ((u32)dev->wakeup.sleep_state == ACPI_STATE_S5)
+ if ((u32) dev->wakeup.sleep_state == ACPI_STATE_S5)
continue;
/* acpi_set_gpe_type will automatically disable GPE */
acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME);
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_RUNTIME);
}
}
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 8925a6ca5f87..e4308c7a6743 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -30,10 +30,8 @@
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("acpi_system")
-
+ACPI_MODULE_NAME("acpi_system")
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver"
#define ACPI_SYSTEM_DEVICE_NAME "System"
@@ -41,15 +39,13 @@ ACPI_MODULE_NAME ("acpi_system")
#define ACPI_SYSTEM_FILE_EVENT "event"
#define ACPI_SYSTEM_FILE_DSDT "dsdt"
#define ACPI_SYSTEM_FILE_FADT "fadt"
-
-extern FADT_DESCRIPTOR acpi_fadt;
+extern FADT_DESCRIPTOR acpi_fadt;
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static int
-acpi_system_read_info (struct seq_file *seq, void *offset)
+static int acpi_system_read_info(struct seq_file *seq, void *offset)
{
ACPI_FUNCTION_TRACE("acpi_system_read_info");
@@ -63,28 +59,26 @@ static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
}
static struct file_operations acpi_system_info_ops = {
- .open = acpi_system_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_system_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static ssize_t acpi_system_read_dsdt (struct file*, char __user *, size_t, loff_t*);
+static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
+ loff_t *);
static struct file_operations acpi_system_dsdt_ops = {
- .read = acpi_system_read_dsdt,
+ .read = acpi_system_read_dsdt,
};
static ssize_t
-acpi_system_read_dsdt (
- struct file *file,
- char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_system_read_dsdt(struct file *file,
+ char __user * buffer, size_t count, loff_t * ppos)
{
- acpi_status status = AE_OK;
- struct acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER, NULL};
- ssize_t res;
+ acpi_status status = AE_OK;
+ struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
+ ssize_t res;
ACPI_FUNCTION_TRACE("acpi_system_read_dsdt");
@@ -99,23 +93,20 @@ acpi_system_read_dsdt (
return_VALUE(res);
}
-
-static ssize_t acpi_system_read_fadt (struct file*, char __user *, size_t, loff_t*);
+static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
+ loff_t *);
static struct file_operations acpi_system_fadt_ops = {
- .read = acpi_system_read_fadt,
+ .read = acpi_system_read_fadt,
};
static ssize_t
-acpi_system_read_fadt (
- struct file *file,
- char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_system_read_fadt(struct file *file,
+ char __user * buffer, size_t count, loff_t * ppos)
{
- acpi_status status = AE_OK;
- struct acpi_buffer fadt = {ACPI_ALLOCATE_BUFFER, NULL};
- ssize_t res;
+ acpi_status status = AE_OK;
+ struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL };
+ ssize_t res;
ACPI_FUNCTION_TRACE("acpi_system_read_fadt");
@@ -130,12 +121,11 @@ acpi_system_read_fadt (
return_VALUE(res);
}
-
-static int __init acpi_system_init (void)
+static int __init acpi_system_init(void)
{
- struct proc_dir_entry *entry;
+ struct proc_dir_entry *entry;
int error = 0;
- char * name;
+ char *name;
ACPI_FUNCTION_TRACE("acpi_system_init");
@@ -144,8 +134,7 @@ static int __init acpi_system_init (void)
/* 'info' [R] */
name = ACPI_SYSTEM_FILE_INFO;
- entry = create_proc_entry(name,
- S_IRUGO, acpi_root_dir);
+ entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
if (!entry)
goto Error;
else {
@@ -157,7 +146,7 @@ static int __init acpi_system_init (void)
entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_dsdt_ops;
- else
+ else
goto Error;
/* 'fadt' [R] */
@@ -168,12 +157,12 @@ static int __init acpi_system_init (void)
else
goto Error;
- Done:
+ Done:
return_VALUE(error);
- Error:
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' proc fs entry\n", name));
+ Error:
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create '%s' proc fs entry\n", name));
remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
@@ -183,5 +172,4 @@ static int __init acpi_system_init (void)
goto Done;
}
-
subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index fb64bd5d2e18..a2bf25b05e1c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -40,25 +40,25 @@
#define ACPI_MAX_TABLES 256
static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
- [ACPI_TABLE_UNKNOWN] = "????",
- [ACPI_APIC] = "APIC",
- [ACPI_BOOT] = "BOOT",
- [ACPI_DBGP] = "DBGP",
- [ACPI_DSDT] = "DSDT",
- [ACPI_ECDT] = "ECDT",
- [ACPI_ETDT] = "ETDT",
- [ACPI_FADT] = "FACP",
- [ACPI_FACS] = "FACS",
- [ACPI_OEMX] = "OEM",
- [ACPI_PSDT] = "PSDT",
- [ACPI_SBST] = "SBST",
- [ACPI_SLIT] = "SLIT",
- [ACPI_SPCR] = "SPCR",
- [ACPI_SRAT] = "SRAT",
- [ACPI_SSDT] = "SSDT",
- [ACPI_SPMI] = "SPMI",
- [ACPI_HPET] = "HPET",
- [ACPI_MCFG] = "MCFG",
+ [ACPI_TABLE_UNKNOWN] = "????",
+ [ACPI_APIC] = "APIC",
+ [ACPI_BOOT] = "BOOT",
+ [ACPI_DBGP] = "DBGP",
+ [ACPI_DSDT] = "DSDT",
+ [ACPI_ECDT] = "ECDT",
+ [ACPI_ETDT] = "ETDT",
+ [ACPI_FADT] = "FACP",
+ [ACPI_FACS] = "FACS",
+ [ACPI_OEMX] = "OEM",
+ [ACPI_PSDT] = "PSDT",
+ [ACPI_SBST] = "SBST",
+ [ACPI_SLIT] = "SLIT",
+ [ACPI_SPCR] = "SPCR",
+ [ACPI_SRAT] = "SRAT",
+ [ACPI_SSDT] = "SSDT",
+ [ACPI_SPMI] = "SPMI",
+ [ACPI_HPET] = "HPET",
+ [ACPI_MCFG] = "MCFG",
};
static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
@@ -66,52 +66,44 @@ static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
/* System Description Table (RSDT/XSDT) */
struct acpi_table_sdt {
- unsigned long pa;
- enum acpi_table_id id;
- unsigned long size;
+ unsigned long pa;
+ enum acpi_table_id id;
+ unsigned long size;
} __attribute__ ((packed));
-static unsigned long sdt_pa; /* Physical Address */
-static unsigned long sdt_count; /* Table count */
+static unsigned long sdt_pa; /* Physical Address */
+static unsigned long sdt_count; /* Table count */
-static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES];
+static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES];
-void
-acpi_table_print (
- struct acpi_table_header *header,
- unsigned long phys_addr)
+void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr)
{
- char *name = NULL;
+ char *name = NULL;
if (!header)
return;
/* Some table signatures aren't good table names */
- if (!strncmp((char *) &header->signature,
- acpi_table_signatures[ACPI_APIC],
- sizeof(header->signature))) {
+ if (!strncmp((char *)&header->signature,
+ acpi_table_signatures[ACPI_APIC],
+ sizeof(header->signature))) {
name = "MADT";
- }
- else if (!strncmp((char *) &header->signature,
- acpi_table_signatures[ACPI_FADT],
- sizeof(header->signature))) {
+ } else if (!strncmp((char *)&header->signature,
+ acpi_table_signatures[ACPI_FADT],
+ sizeof(header->signature))) {
name = "FADT";
- }
- else
+ } else
name = header->signature;
- printk(KERN_DEBUG PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n",
- name, header->revision, header->oem_id,
- header->oem_table_id, header->oem_revision,
- header->asl_compiler_id, header->asl_compiler_revision,
- (void *) phys_addr);
+ printk(KERN_DEBUG PREFIX
+ "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name,
+ header->revision, header->oem_id, header->oem_table_id,
+ header->oem_revision, header->asl_compiler_id,
+ header->asl_compiler_revision, (void *)phys_addr);
}
-
-void
-acpi_table_print_madt_entry (
- acpi_table_entry_header *header)
+void acpi_table_print_madt_entry(acpi_table_entry_header * header)
{
if (!header)
return;
@@ -119,113 +111,127 @@ acpi_table_print_madt_entry (
switch (header->type) {
case ACPI_MADT_LAPIC:
- {
- struct acpi_table_lapic *p =
- (struct acpi_table_lapic*) header;
- printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
- p->acpi_id, p->id, p->flags.enabled?"enabled":"disabled");
- }
+ {
+ struct acpi_table_lapic *p =
+ (struct acpi_table_lapic *)header;
+ printk(KERN_INFO PREFIX
+ "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
+ p->acpi_id, p->id,
+ p->flags.enabled ? "enabled" : "disabled");
+ }
break;
case ACPI_MADT_IOAPIC:
- {
- struct acpi_table_ioapic *p =
- (struct acpi_table_ioapic*) header;
- printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
- p->id, p->address, p->global_irq_base);
- }
+ {
+ struct acpi_table_ioapic *p =
+ (struct acpi_table_ioapic *)header;
+ printk(KERN_INFO PREFIX
+ "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
+ p->id, p->address, p->global_irq_base);
+ }
break;
case ACPI_MADT_INT_SRC_OVR:
- {
- struct acpi_table_int_src_ovr *p =
- (struct acpi_table_int_src_ovr*) header;
- printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
- p->bus, p->bus_irq, p->global_irq,
- mps_inti_flags_polarity[p->flags.polarity],
- mps_inti_flags_trigger[p->flags.trigger]);
- if(p->flags.reserved)
- printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
- p->flags.reserved);
+ {
+ struct acpi_table_int_src_ovr *p =
+ (struct acpi_table_int_src_ovr *)header;
+ printk(KERN_INFO PREFIX
+ "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
+ p->bus, p->bus_irq, p->global_irq,
+ mps_inti_flags_polarity[p->flags.polarity],
+ mps_inti_flags_trigger[p->flags.trigger]);
+ if (p->flags.reserved)
+ printk(KERN_INFO PREFIX
+ "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
+ p->flags.reserved);
- }
+ }
break;
case ACPI_MADT_NMI_SRC:
- {
- struct acpi_table_nmi_src *p =
- (struct acpi_table_nmi_src*) header;
- printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n",
- mps_inti_flags_polarity[p->flags.polarity],
- mps_inti_flags_trigger[p->flags.trigger], p->global_irq);
- }
+ {
+ struct acpi_table_nmi_src *p =
+ (struct acpi_table_nmi_src *)header;
+ printk(KERN_INFO PREFIX
+ "NMI_SRC (%s %s global_irq %d)\n",
+ mps_inti_flags_polarity[p->flags.polarity],
+ mps_inti_flags_trigger[p->flags.trigger],
+ p->global_irq);
+ }
break;
case ACPI_MADT_LAPIC_NMI:
- {
- struct acpi_table_lapic_nmi *p =
- (struct acpi_table_lapic_nmi*) header;
- printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
- p->acpi_id,
- mps_inti_flags_polarity[p->flags.polarity],
- mps_inti_flags_trigger[p->flags.trigger], p->lint);
- }
+ {
+ struct acpi_table_lapic_nmi *p =
+ (struct acpi_table_lapic_nmi *)header;
+ printk(KERN_INFO PREFIX
+ "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
+ p->acpi_id,
+ mps_inti_flags_polarity[p->flags.polarity],
+ mps_inti_flags_trigger[p->flags.trigger],
+ p->lint);
+ }
break;
case ACPI_MADT_LAPIC_ADDR_OVR:
- {
- struct acpi_table_lapic_addr_ovr *p =
- (struct acpi_table_lapic_addr_ovr*) header;
- printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n",
- (void *) (unsigned long) p->address);
- }
+ {
+ struct acpi_table_lapic_addr_ovr *p =
+ (struct acpi_table_lapic_addr_ovr *)header;
+ printk(KERN_INFO PREFIX
+ "LAPIC_ADDR_OVR (address[%p])\n",
+ (void *)(unsigned long)p->address);
+ }
break;
case ACPI_MADT_IOSAPIC:
- {
- struct acpi_table_iosapic *p =
- (struct acpi_table_iosapic*) header;
- printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
- p->id, (void *) (unsigned long) p->address, p->global_irq_base);
- }
+ {
+ struct acpi_table_iosapic *p =
+ (struct acpi_table_iosapic *)header;
+ printk(KERN_INFO PREFIX
+ "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
+ p->id, (void *)(unsigned long)p->address,
+ p->global_irq_base);
+ }
break;
case ACPI_MADT_LSAPIC:
- {
- struct acpi_table_lsapic *p =
- (struct acpi_table_lsapic*) header;
- printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
- p->acpi_id, p->id, p->eid, p->flags.enabled?"enabled":"disabled");
- }
+ {
+ struct acpi_table_lsapic *p =
+ (struct acpi_table_lsapic *)header;
+ printk(KERN_INFO PREFIX
+ "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
+ p->acpi_id, p->id, p->eid,
+ p->flags.enabled ? "enabled" : "disabled");
+ }
break;
case ACPI_MADT_PLAT_INT_SRC:
- {
- struct acpi_table_plat_int_src *p =
- (struct acpi_table_plat_int_src*) header;
- printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
- mps_inti_flags_polarity[p->flags.polarity],
- mps_inti_flags_trigger[p->flags.trigger],
- p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
- }
+ {
+ struct acpi_table_plat_int_src *p =
+ (struct acpi_table_plat_int_src *)header;
+ printk(KERN_INFO PREFIX
+ "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
+ mps_inti_flags_polarity[p->flags.polarity],
+ mps_inti_flags_trigger[p->flags.trigger],
+ p->type, p->id, p->eid, p->iosapic_vector,
+ p->global_irq);
+ }
break;
default:
- printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n",
- header->type);
+ printk(KERN_WARNING PREFIX
+ "Found unsupported MADT entry (type = 0x%x)\n",
+ header->type);
break;
}
}
-
static int
-acpi_table_compute_checksum (
- void *table_pointer,
- unsigned long length)
+acpi_table_compute_checksum(void *table_pointer, unsigned long length)
{
- u8 *p = (u8 *) table_pointer;
- unsigned long remains = length;
- unsigned long sum = 0;
+ u8 *p = (u8 *) table_pointer;
+ unsigned long remains = length;
+ unsigned long sum = 0;
if (!p || !length)
return -EINVAL;
@@ -241,9 +247,8 @@ acpi_table_compute_checksum (
* for acpi_blacklisted(), acpi_table_get_sdt()
*/
int __init
-acpi_get_table_header_early (
- enum acpi_table_id id,
- struct acpi_table_header **header)
+acpi_get_table_header_early(enum acpi_table_id id,
+ struct acpi_table_header **header)
{
unsigned int i;
enum acpi_table_id temp_id;
@@ -260,7 +265,7 @@ acpi_get_table_header_early (
if (sdt_entry[i].id != temp_id)
continue;
*header = (void *)
- __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+ __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
if (!*header) {
printk(KERN_WARNING PREFIX "Unable to map %s\n",
acpi_table_signatures[temp_id]);
@@ -277,14 +282,17 @@ acpi_get_table_header_early (
/* Map the DSDT header via the pointer in the FADT */
if (id == ACPI_DSDT) {
- struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header;
+ struct fadt_descriptor_rev2 *fadt =
+ (struct fadt_descriptor_rev2 *)*header;
if (fadt->revision == 3 && fadt->Xdsdt) {
- *header = (void *) __acpi_map_table(fadt->Xdsdt,
- sizeof(struct acpi_table_header));
+ *header = (void *)__acpi_map_table(fadt->Xdsdt,
+ sizeof(struct
+ acpi_table_header));
} else if (fadt->V1_dsdt) {
- *header = (void *) __acpi_map_table(fadt->V1_dsdt,
- sizeof(struct acpi_table_header));
+ *header = (void *)__acpi_map_table(fadt->V1_dsdt,
+ sizeof(struct
+ acpi_table_header));
} else
*header = NULL;
@@ -296,21 +304,19 @@ acpi_get_table_header_early (
return 0;
}
-
int __init
-acpi_table_parse_madt_family (
- enum acpi_table_id id,
- unsigned long madt_size,
- int entry_id,
- acpi_madt_entry_handler handler,
- unsigned int max_entries)
+acpi_table_parse_madt_family(enum acpi_table_id id,
+ unsigned long madt_size,
+ int entry_id,
+ acpi_madt_entry_handler handler,
+ unsigned int max_entries)
{
- void *madt = NULL;
- acpi_table_entry_header *entry;
- unsigned int count = 0;
- unsigned long madt_end;
- unsigned int i;
+ void *madt = NULL;
+ acpi_table_entry_header *entry;
+ unsigned int count = 0;
+ unsigned long madt_end;
+ unsigned int i;
if (!handler)
return -EINVAL;
@@ -321,7 +327,7 @@ acpi_table_parse_madt_family (
if (sdt_entry[i].id != id)
continue;
madt = (void *)
- __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+ __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
if (!madt) {
printk(KERN_WARNING PREFIX "Unable to map %s\n",
acpi_table_signatures[id]);
@@ -336,21 +342,22 @@ acpi_table_parse_madt_family (
return -ENODEV;
}
- madt_end = (unsigned long) madt + sdt_entry[i].size;
+ madt_end = (unsigned long)madt + sdt_entry[i].size;
/* Parse all entries looking for a match. */
entry = (acpi_table_entry_header *)
- ((unsigned long) madt + madt_size);
+ ((unsigned long)madt + madt_size);
- while (((unsigned long) entry) + sizeof(acpi_table_entry_header) < madt_end) {
- if (entry->type == entry_id &&
- (!max_entries || count++ < max_entries))
+ while (((unsigned long)entry) + sizeof(acpi_table_entry_header) <
+ madt_end) {
+ if (entry->type == entry_id
+ && (!max_entries || count++ < max_entries))
if (handler(entry, madt_end))
return -EINVAL;
entry = (acpi_table_entry_header *)
- ((unsigned long) entry + entry->length);
+ ((unsigned long)entry + entry->length);
}
if (max_entries && count > max_entries) {
printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of "
@@ -361,25 +368,19 @@ acpi_table_parse_madt_family (
return count;
}
-
int __init
-acpi_table_parse_madt (
- enum acpi_madt_entry_id id,
- acpi_madt_entry_handler handler,
- unsigned int max_entries)
+acpi_table_parse_madt(enum acpi_madt_entry_id id,
+ acpi_madt_entry_handler handler, unsigned int max_entries)
{
- return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt),
- id, handler, max_entries);
+ return acpi_table_parse_madt_family(ACPI_APIC,
+ sizeof(struct acpi_table_madt), id,
+ handler, max_entries);
}
-
-int __init
-acpi_table_parse (
- enum acpi_table_id id,
- acpi_table_handler handler)
+int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler)
{
- int count = 0;
- unsigned int i = 0;
+ int count = 0;
+ unsigned int i = 0;
if (!handler)
return -EINVAL;
@@ -392,20 +393,18 @@ acpi_table_parse (
handler(sdt_entry[i].pa, sdt_entry[i].size);
else
- printk(KERN_WARNING PREFIX "%d duplicate %s table ignored.\n",
- count, acpi_table_signatures[id]);
+ printk(KERN_WARNING PREFIX
+ "%d duplicate %s table ignored.\n", count,
+ acpi_table_signatures[id]);
}
return count;
}
-
-static int __init
-acpi_table_get_sdt (
- struct acpi_table_rsdp *rsdp)
+static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp)
{
struct acpi_table_header *header = NULL;
- unsigned int i, id = 0;
+ unsigned int i, id = 0;
if (!rsdp)
return -EINVAL;
@@ -413,24 +412,25 @@ acpi_table_get_sdt (
/* First check XSDT (but only on ACPI 2.0-compatible systems) */
if ((rsdp->revision >= 2) &&
- (((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) {
-
- struct acpi_table_xsdt *mapped_xsdt = NULL;
+ (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) {
+
+ struct acpi_table_xsdt *mapped_xsdt = NULL;
- sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
+ sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address;
/* map in just the header */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
+ __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
if (!header) {
- printk(KERN_WARNING PREFIX "Unable to map XSDT header\n");
+ printk(KERN_WARNING PREFIX
+ "Unable to map XSDT header\n");
return -ENODEV;
}
/* remap in the entire table before processing */
mapped_xsdt = (struct acpi_table_xsdt *)
- __acpi_map_table(sdt_pa, header->length);
+ __acpi_map_table(sdt_pa, header->length);
if (!mapped_xsdt) {
printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
return -ENODEV;
@@ -438,7 +438,8 @@ acpi_table_get_sdt (
header = &mapped_xsdt->header;
if (strncmp(header->signature, "XSDT", 4)) {
- printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
+ printk(KERN_WARNING PREFIX
+ "XSDT signature incorrect\n");
return -ENODEV;
}
@@ -447,36 +448,39 @@ acpi_table_get_sdt (
return -ENODEV;
}
- sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3;
+ sdt_count =
+ (header->length - sizeof(struct acpi_table_header)) >> 3;
if (sdt_count > ACPI_MAX_TABLES) {
- printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n",
- (sdt_count - ACPI_MAX_TABLES));
+ printk(KERN_WARNING PREFIX
+ "Truncated %lu XSDT entries\n",
+ (sdt_count - ACPI_MAX_TABLES));
sdt_count = ACPI_MAX_TABLES;
}
for (i = 0; i < sdt_count; i++)
- sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
+ sdt_entry[i].pa = (unsigned long)mapped_xsdt->entry[i];
}
/* Then check RSDT */
else if (rsdp->rsdt_address) {
- struct acpi_table_rsdt *mapped_rsdt = NULL;
+ struct acpi_table_rsdt *mapped_rsdt = NULL;
sdt_pa = rsdp->rsdt_address;
/* map in just the header */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
+ __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
if (!header) {
- printk(KERN_WARNING PREFIX "Unable to map RSDT header\n");
+ printk(KERN_WARNING PREFIX
+ "Unable to map RSDT header\n");
return -ENODEV;
}
/* remap in the entire table before processing */
mapped_rsdt = (struct acpi_table_rsdt *)
- __acpi_map_table(sdt_pa, header->length);
+ __acpi_map_table(sdt_pa, header->length);
if (!mapped_rsdt) {
printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
return -ENODEV;
@@ -484,7 +488,8 @@ acpi_table_get_sdt (
header = &mapped_rsdt->header;
if (strncmp(header->signature, "RSDT", 4)) {
- printk(KERN_WARNING PREFIX "RSDT signature incorrect\n");
+ printk(KERN_WARNING PREFIX
+ "RSDT signature incorrect\n");
return -ENODEV;
}
@@ -493,19 +498,22 @@ acpi_table_get_sdt (
return -ENODEV;
}
- sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2;
+ sdt_count =
+ (header->length - sizeof(struct acpi_table_header)) >> 2;
if (sdt_count > ACPI_MAX_TABLES) {
- printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n",
- (sdt_count - ACPI_MAX_TABLES));
+ printk(KERN_WARNING PREFIX
+ "Truncated %lu RSDT entries\n",
+ (sdt_count - ACPI_MAX_TABLES));
sdt_count = ACPI_MAX_TABLES;
}
for (i = 0; i < sdt_count; i++)
- sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
+ sdt_entry[i].pa = (unsigned long)mapped_rsdt->entry[i];
}
else {
- printk(KERN_WARNING PREFIX "No System Description Table (RSDT/XSDT) specified in RSDP\n");
+ printk(KERN_WARNING PREFIX
+ "No System Description Table (RSDT/XSDT) specified in RSDP\n");
return -ENODEV;
}
@@ -515,18 +523,17 @@ acpi_table_get_sdt (
/* map in just the header */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt_entry[i].pa,
- sizeof(struct acpi_table_header));
+ __acpi_map_table(sdt_entry[i].pa,
+ sizeof(struct acpi_table_header));
if (!header)
continue;
/* remap in the entire table before processing */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt_entry[i].pa,
- header->length);
+ __acpi_map_table(sdt_entry[i].pa, header->length);
if (!header)
continue;
-
+
acpi_table_print(header, sdt_entry[i].pa);
if (acpi_table_compute_checksum(header, header->length)) {
@@ -537,9 +544,9 @@ acpi_table_get_sdt (
sdt_entry[i].size = header->length;
for (id = 0; id < ACPI_TABLE_COUNT; id++) {
- if (!strncmp((char *) &header->signature,
- acpi_table_signatures[id],
- sizeof(header->signature))) {
+ if (!strncmp((char *)&header->signature,
+ acpi_table_signatures[id],
+ sizeof(header->signature))) {
sdt_entry[i].id = id;
}
}
@@ -551,7 +558,7 @@ acpi_table_get_sdt (
* against. Unfortunately, we don't know the phys_addr, so just
* print 0. Maybe no one will notice.
*/
- if(!acpi_get_table_header_early(ACPI_DSDT, &header))
+ if (!acpi_get_table_header_early(ACPI_DSDT, &header))
acpi_table_print(header, 0);
return 0;
@@ -566,12 +573,11 @@ acpi_table_get_sdt (
* result: sdt_entry[] is initialized
*/
-int __init
-acpi_table_init (void)
+int __init acpi_table_init(void)
{
- struct acpi_table_rsdp *rsdp = NULL;
- unsigned long rsdp_phys = 0;
- int result = 0;
+ struct acpi_table_rsdp *rsdp = NULL;
+ unsigned long rsdp_phys = 0;
+ int result = 0;
/* Locate and map the Root System Description Table (RSDP) */
@@ -581,19 +587,25 @@ acpi_table_init (void)
return -ENODEV;
}
- rsdp = (struct acpi_table_rsdp *) __va(rsdp_phys);
+ rsdp = (struct acpi_table_rsdp *)__va(rsdp_phys);
if (!rsdp) {
printk(KERN_WARNING PREFIX "Unable to map RSDP\n");
return -ENODEV;
}
- printk(KERN_DEBUG PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
- rsdp->revision, rsdp->oem_id, (void *) rsdp_phys);
+ printk(KERN_DEBUG PREFIX
+ "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
+ rsdp->revision, rsdp->oem_id, (void *)rsdp_phys);
if (rsdp->revision < 2)
- result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp));
+ result =
+ acpi_table_compute_checksum(rsdp,
+ sizeof(struct acpi_table_rsdp));
else
- result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length);
+ result =
+ acpi_table_compute_checksum(rsdp,
+ ((struct acpi20_table_rsdp *)
+ rsdp)->length);
if (result) {
printk(KERN_WARNING " >>> ERROR: Invalid checksum\n");
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index 92e0c31539be..a03939399fa9 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -46,28 +46,22 @@
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbconvrt")
+ACPI_MODULE_NAME("tbconvrt")
/* Local prototypes */
-
static void
-acpi_tb_init_generic_address (
- struct acpi_generic_address *new_gas_struct,
- u8 register_bit_width,
- acpi_physical_address address);
+acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
+ u8 register_bit_width,
+ acpi_physical_address address);
static void
-acpi_tb_convert_fadt1 (
- struct fadt_descriptor_rev2 *local_fadt,
- struct fadt_descriptor_rev1 *original_fadt);
+acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt,
+ struct fadt_descriptor_rev1 *original_fadt);
static void
-acpi_tb_convert_fadt2 (
- struct fadt_descriptor_rev2 *local_fadt,
- struct fadt_descriptor_rev2 *original_fadt);
-
+acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt,
+ struct fadt_descriptor_rev2 *original_fadt);
u8 acpi_fadt_is_v1;
EXPORT_SYMBOL(acpi_fadt_is_v1);
@@ -87,21 +81,19 @@ EXPORT_SYMBOL(acpi_fadt_is_v1);
******************************************************************************/
u32
-acpi_tb_get_table_count (
- struct rsdp_descriptor *RSDP,
- struct acpi_table_header *RSDT)
+acpi_tb_get_table_count(struct rsdp_descriptor *RSDP,
+ struct acpi_table_header *RSDT)
{
- u32 pointer_size;
+ u32 pointer_size;
+ ACPI_FUNCTION_ENTRY();
- ACPI_FUNCTION_ENTRY ();
+ /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
-
- if (RSDP->revision < 2) {
- pointer_size = sizeof (u32);
- }
- else {
- pointer_size = sizeof (u64);
+ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
+ pointer_size = sizeof(u32);
+ } else {
+ pointer_size = sizeof(u64);
}
/*
@@ -110,10 +102,10 @@ acpi_tb_get_table_count (
* pointers contained within the RSDT/XSDT. The size of the pointers
* is architecture-dependent.
*/
- return ((RSDT->length - sizeof (struct acpi_table_header)) / pointer_size);
+ return ((RSDT->length -
+ sizeof(struct acpi_table_header)) / pointer_size);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_convert_to_xsdt
@@ -126,64 +118,65 @@ acpi_tb_get_table_count (
*
******************************************************************************/
-acpi_status
-acpi_tb_convert_to_xsdt (
- struct acpi_table_desc *table_info)
+acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info)
{
- acpi_size table_size;
- u32 i;
- XSDT_DESCRIPTOR *new_table;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_size table_size;
+ u32 i;
+ XSDT_DESCRIPTOR *new_table;
+ ACPI_FUNCTION_ENTRY();
/* Compute size of the converted XSDT */
- table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) +
- sizeof (struct acpi_table_header);
+ table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) +
+ sizeof(struct acpi_table_header);
/* Allocate an XSDT */
- new_table = ACPI_MEM_CALLOCATE (table_size);
+ new_table = ACPI_MEM_CALLOCATE(table_size);
if (!new_table) {
return (AE_NO_MEMORY);
}
/* Copy the header and set the length */
- ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header));
+ ACPI_MEMCPY(new_table, table_info->pointer,
+ sizeof(struct acpi_table_header));
new_table->length = (u32) table_size;
/* Copy the table pointers */
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
- if (acpi_gbl_RSDP->revision < 2) {
- ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
- (ACPI_CAST_PTR (struct rsdt_descriptor_rev1,
- table_info->pointer))->table_offset_entry[i]);
- }
- else {
+ /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
+
+ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
+ ACPI_STORE_ADDRESS(new_table->table_offset_entry[i],
+ (ACPI_CAST_PTR
+ (struct rsdt_descriptor_rev1,
+ table_info->pointer))->
+ table_offset_entry[i]);
+ } else {
new_table->table_offset_entry[i] =
- (ACPI_CAST_PTR (XSDT_DESCRIPTOR,
- table_info->pointer))->table_offset_entry[i];
+ (ACPI_CAST_PTR(XSDT_DESCRIPTOR,
+ table_info->pointer))->
+ table_offset_entry[i];
}
}
/* Delete the original table (either mapped or in a buffer) */
- acpi_tb_delete_single_table (table_info);
+ acpi_tb_delete_single_table(table_info);
/* Point the table descriptor to the new table */
- table_info->pointer = ACPI_CAST_PTR (struct acpi_table_header, new_table);
- table_info->length = table_size;
- table_info->allocation = ACPI_MEM_ALLOCATED;
+ table_info->pointer =
+ ACPI_CAST_PTR(struct acpi_table_header, new_table);
+ table_info->length = table_size;
+ table_info->allocation = ACPI_MEM_ALLOCATED;
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_init_generic_address
@@ -199,21 +192,19 @@ acpi_tb_convert_to_xsdt (
******************************************************************************/
static void
-acpi_tb_init_generic_address (
- struct acpi_generic_address *new_gas_struct,
- u8 register_bit_width,
- acpi_physical_address address)
+acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
+ u8 register_bit_width,
+ acpi_physical_address address)
{
- ACPI_STORE_ADDRESS (new_gas_struct->address, address);
+ ACPI_STORE_ADDRESS(new_gas_struct->address, address);
new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
new_gas_struct->register_bit_width = register_bit_width;
new_gas_struct->register_bit_offset = 0;
- new_gas_struct->access_width = 0;
+ new_gas_struct->access_width = 0;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_convert_fadt1
@@ -228,9 +219,8 @@ acpi_tb_init_generic_address (
******************************************************************************/
static void
-acpi_tb_convert_fadt1 (
- struct fadt_descriptor_rev2 *local_fadt,
- struct fadt_descriptor_rev1 *original_fadt)
+acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt,
+ struct fadt_descriptor_rev1 *original_fadt)
{
/* ACPI 1.0 FACS */
@@ -243,12 +233,14 @@ acpi_tb_convert_fadt1 (
* The 2.0 table is an extension of the 1.0 table, so the entire 1.0
* table can be copied first, then expand some fields to 64 bits.
*/
- ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev1));
+ ACPI_MEMCPY(local_fadt, original_fadt,
+ sizeof(struct fadt_descriptor_rev1));
/* Convert table pointers to 64-bit fields */
- ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
- ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
+ ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl,
+ local_fadt->V1_firmware_ctrl);
+ ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt);
/*
* System Interrupt Model isn't used in ACPI 2.0
@@ -283,17 +275,17 @@ acpi_tb_convert_fadt1 (
* It primarily adds the FADT reset mechanism.
*/
if ((original_fadt->revision == 2) &&
- (original_fadt->length == sizeof (struct fadt_descriptor_rev2_minus))) {
+ (original_fadt->length ==
+ sizeof(struct fadt_descriptor_rev2_minus))) {
/*
* Grab the entire generic address struct, plus the 1-byte reset value
* that immediately follows.
*/
- ACPI_MEMCPY (&local_fadt->reset_register,
- &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus,
- original_fadt))->reset_register,
- sizeof (struct acpi_generic_address) + 1);
- }
- else {
+ ACPI_MEMCPY(&local_fadt->reset_register,
+ &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus,
+ original_fadt))->reset_register,
+ sizeof(struct acpi_generic_address) + 1);
+ } else {
/*
* Since there isn't any equivalence in 1.0 and since it is highly
* likely that a 1.0 system has legacy support.
@@ -304,43 +296,60 @@ acpi_tb_convert_fadt1 (
/*
* Convert the V1.0 block addresses to V2.0 GAS structures
*/
- acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len,
- (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
- acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len,
- (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
- acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len,
- (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
- acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len,
- (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
- acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len,
- (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
- acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len,
- (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
- acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0,
- (acpi_physical_address) local_fadt->V1_gpe0_blk);
- acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0,
- (acpi_physical_address) local_fadt->V1_gpe1_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk,
+ local_fadt->pm1_evt_len,
+ (acpi_physical_address) local_fadt->
+ V1_pm1a_evt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk,
+ local_fadt->pm1_evt_len,
+ (acpi_physical_address) local_fadt->
+ V1_pm1b_evt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk,
+ local_fadt->pm1_cnt_len,
+ (acpi_physical_address) local_fadt->
+ V1_pm1a_cnt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk,
+ local_fadt->pm1_cnt_len,
+ (acpi_physical_address) local_fadt->
+ V1_pm1b_cnt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk,
+ local_fadt->pm2_cnt_len,
+ (acpi_physical_address) local_fadt->
+ V1_pm2_cnt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk,
+ local_fadt->pm_tm_len,
+ (acpi_physical_address) local_fadt->
+ V1_pm_tmr_blk);
+ acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0,
+ (acpi_physical_address) local_fadt->
+ V1_gpe0_blk);
+ acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0,
+ (acpi_physical_address) local_fadt->
+ V1_gpe1_blk);
/* Create separate GAS structs for the PM1 Enable registers */
- acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
- (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address)
- (local_fadt->xpm1a_evt_blk.address +
- ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
+ (u8) ACPI_DIV_2(acpi_gbl_FADT->
+ pm1_evt_len),
+ (acpi_physical_address)
+ (local_fadt->xpm1a_evt_blk.address +
+ ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len)));
/* PM1B is optional; leave null if not present */
if (local_fadt->xpm1b_evt_blk.address) {
- acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
- (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address)
- (local_fadt->xpm1b_evt_blk.address +
- ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
+ (u8) ACPI_DIV_2(acpi_gbl_FADT->
+ pm1_evt_len),
+ (acpi_physical_address)
+ (local_fadt->xpm1b_evt_blk.
+ address +
+ ACPI_DIV_2(acpi_gbl_FADT->
+ pm1_evt_len)));
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_convert_fadt2
@@ -356,14 +365,14 @@ acpi_tb_convert_fadt1 (
******************************************************************************/
static void
-acpi_tb_convert_fadt2 (
- struct fadt_descriptor_rev2 *local_fadt,
- struct fadt_descriptor_rev2 *original_fadt)
+acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt,
+ struct fadt_descriptor_rev2 *original_fadt)
{
/* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
- ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev2));
+ ACPI_MEMCPY(local_fadt, original_fadt,
+ sizeof(struct fadt_descriptor_rev2));
/*
* "X" fields are optional extensions to the original V1.0 fields, so
@@ -371,86 +380,99 @@ acpi_tb_convert_fadt2 (
* is zero.
*/
if (!(local_fadt->xfirmware_ctrl)) {
- ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl,
- local_fadt->V1_firmware_ctrl);
+ ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl,
+ local_fadt->V1_firmware_ctrl);
}
if (!(local_fadt->Xdsdt)) {
- ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
+ ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt);
}
if (!(local_fadt->xpm1a_evt_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
- local_fadt->pm1_evt_len,
- (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk,
+ local_fadt->pm1_evt_len,
+ (acpi_physical_address)
+ local_fadt->V1_pm1a_evt_blk);
}
if (!(local_fadt->xpm1b_evt_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
- local_fadt->pm1_evt_len,
- (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk,
+ local_fadt->pm1_evt_len,
+ (acpi_physical_address)
+ local_fadt->V1_pm1b_evt_blk);
}
if (!(local_fadt->xpm1a_cnt_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
- local_fadt->pm1_cnt_len,
- (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk,
+ local_fadt->pm1_cnt_len,
+ (acpi_physical_address)
+ local_fadt->V1_pm1a_cnt_blk);
}
if (!(local_fadt->xpm1b_cnt_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
- local_fadt->pm1_cnt_len,
- (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk,
+ local_fadt->pm1_cnt_len,
+ (acpi_physical_address)
+ local_fadt->V1_pm1b_cnt_blk);
}
if (!(local_fadt->xpm2_cnt_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
- local_fadt->pm2_cnt_len,
- (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk,
+ local_fadt->pm2_cnt_len,
+ (acpi_physical_address)
+ local_fadt->V1_pm2_cnt_blk);
}
if (!(local_fadt->xpm_tmr_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
- local_fadt->pm_tm_len,
- (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
+ acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk,
+ local_fadt->pm_tm_len,
+ (acpi_physical_address)
+ local_fadt->V1_pm_tmr_blk);
}
if (!(local_fadt->xgpe0_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xgpe0_blk,
- 0, (acpi_physical_address) local_fadt->V1_gpe0_blk);
+ acpi_tb_init_generic_address(&local_fadt->xgpe0_blk,
+ 0,
+ (acpi_physical_address)
+ local_fadt->V1_gpe0_blk);
}
if (!(local_fadt->xgpe1_blk.address)) {
- acpi_tb_init_generic_address (&local_fadt->xgpe1_blk,
- 0, (acpi_physical_address) local_fadt->V1_gpe1_blk);
+ acpi_tb_init_generic_address(&local_fadt->xgpe1_blk,
+ 0,
+ (acpi_physical_address)
+ local_fadt->V1_gpe1_blk);
}
/* Create separate GAS structs for the PM1 Enable registers */
- acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
- (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address)
- (local_fadt->xpm1a_evt_blk.address +
- ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
+ (u8) ACPI_DIV_2(acpi_gbl_FADT->
+ pm1_evt_len),
+ (acpi_physical_address)
+ (local_fadt->xpm1a_evt_blk.address +
+ ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len)));
acpi_gbl_xpm1a_enable.address_space_id =
- local_fadt->xpm1a_evt_blk.address_space_id;
+ local_fadt->xpm1a_evt_blk.address_space_id;
/* PM1B is optional; leave null if not present */
if (local_fadt->xpm1b_evt_blk.address) {
- acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
- (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address)
- (local_fadt->xpm1b_evt_blk.address +
- ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
+ (u8) ACPI_DIV_2(acpi_gbl_FADT->
+ pm1_evt_len),
+ (acpi_physical_address)
+ (local_fadt->xpm1b_evt_blk.
+ address +
+ ACPI_DIV_2(acpi_gbl_FADT->
+ pm1_evt_len)));
acpi_gbl_xpm1b_enable.address_space_id =
- local_fadt->xpm1b_evt_blk.address_space_id;
+ local_fadt->xpm1b_evt_blk.address_space_id;
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_convert_table_fadt
@@ -467,83 +489,76 @@ acpi_tb_convert_fadt2 (
*
******************************************************************************/
-acpi_status
-acpi_tb_convert_table_fadt (
- void)
+acpi_status acpi_tb_convert_table_fadt(void)
{
- struct fadt_descriptor_rev2 *local_fadt;
- struct acpi_table_desc *table_desc;
-
-
- ACPI_FUNCTION_TRACE ("tb_convert_table_fadt");
+ struct fadt_descriptor_rev2 *local_fadt;
+ struct acpi_table_desc *table_desc;
+ ACPI_FUNCTION_TRACE("tb_convert_table_fadt");
/*
* acpi_gbl_FADT is valid. Validate the FADT length. The table must be
* at least as long as the version 1.0 FADT
*/
- if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
- ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n",
- acpi_gbl_FADT->length));
- return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) {
+ ACPI_REPORT_ERROR(("FADT is invalid, too short: 0x%X\n",
+ acpi_gbl_FADT->length));
+ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
}
/* Allocate buffer for the ACPI 2.0(+) FADT */
- local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2));
+ local_fadt = ACPI_MEM_CALLOCATE(sizeof(struct fadt_descriptor_rev2));
if (!local_fadt) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) {
- if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
+ if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev2)) {
/* Length is too short to be a V2.0 table */
- ACPI_REPORT_WARNING ((
- "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
- acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
+ ACPI_REPORT_WARNING(("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
- acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
- }
- else {
+ acpi_tb_convert_fadt1(local_fadt,
+ (void *)acpi_gbl_FADT);
+ } else {
/* Valid V2.0 table */
- acpi_tb_convert_fadt2 (local_fadt, acpi_gbl_FADT);
+ acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT);
}
- }
- else {
+ } else {
/* Valid V1.0 table */
- acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
+ acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT);
}
/* Global FADT pointer will point to the new common V2.0 FADT */
acpi_gbl_FADT = local_fadt;
- acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
+ acpi_gbl_FADT->length = sizeof(FADT_DESCRIPTOR);
/* Free the original table */
table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
- acpi_tb_delete_single_table (table_desc);
+ acpi_tb_delete_single_table(table_desc);
/* Install the new table */
- table_desc->pointer = ACPI_CAST_PTR (struct acpi_table_header, acpi_gbl_FADT);
- table_desc->allocation = ACPI_MEM_ALLOCATED;
- table_desc->length = sizeof (struct fadt_descriptor_rev2);
+ table_desc->pointer =
+ ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT);
+ table_desc->allocation = ACPI_MEM_ALLOCATED;
+ table_desc->length = sizeof(struct fadt_descriptor_rev2);
/* Dump the entire FADT */
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
- "Hex dump of common internal FADT, size %d (%X)\n",
- acpi_gbl_FADT->length, acpi_gbl_FADT->length));
- ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
+ "Hex dump of common internal FADT, size %d (%X)\n",
+ acpi_gbl_FADT->length, acpi_gbl_FADT->length));
+ ACPI_DUMP_BUFFER((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_build_common_facs
@@ -557,26 +572,21 @@ acpi_tb_convert_table_fadt (
*
******************************************************************************/
-acpi_status
-acpi_tb_build_common_facs (
- struct acpi_table_desc *table_info)
+acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info)
{
- ACPI_FUNCTION_TRACE ("tb_build_common_facs");
-
+ ACPI_FUNCTION_TRACE("tb_build_common_facs");
/* Absolute minimum length is 24, but the ACPI spec says 64 */
if (acpi_gbl_FACS->length < 24) {
- ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n",
- acpi_gbl_FACS->length));
- return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ ACPI_REPORT_ERROR(("Invalid FACS table length: 0x%X\n",
+ acpi_gbl_FACS->length));
+ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
}
if (acpi_gbl_FACS->length < 64) {
- ACPI_REPORT_WARNING ((
- "FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
- acpi_gbl_FACS->length));
+ ACPI_REPORT_WARNING(("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n", acpi_gbl_FACS->length));
}
/* Copy fields to the new FACS */
@@ -584,22 +594,22 @@ acpi_tb_build_common_facs (
acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock);
if ((acpi_gbl_RSDP->revision < 2) ||
- (acpi_gbl_FACS->length < 32) ||
- (!(acpi_gbl_FACS->xfirmware_waking_vector))) {
+ (acpi_gbl_FACS->length < 32) ||
+ (!(acpi_gbl_FACS->xfirmware_waking_vector))) {
/* ACPI 1.0 FACS or short table or optional X_ field is zero */
- acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64,
- &(acpi_gbl_FACS->firmware_waking_vector));
+ acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64,
+ &
+ (acpi_gbl_FACS->
+ firmware_waking_vector));
acpi_gbl_common_fACS.vector_width = 32;
- }
- else {
+ } else {
/* ACPI 2.0 FACS with valid X_ field */
- acpi_gbl_common_fACS.firmware_waking_vector = &acpi_gbl_FACS->xfirmware_waking_vector;
+ acpi_gbl_common_fACS.firmware_waking_vector =
+ &acpi_gbl_FACS->xfirmware_waking_vector;
acpi_gbl_common_fACS.vector_width = 64;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
-
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 4ab2aadc6133..6acd5aeb093e 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -41,27 +41,21 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbget")
+ACPI_MODULE_NAME("tbget")
/* Local prototypes */
-
static acpi_status
-acpi_tb_get_this_table (
- struct acpi_pointer *address,
- struct acpi_table_header *header,
- struct acpi_table_desc *table_info);
+acpi_tb_get_this_table(struct acpi_pointer *address,
+ struct acpi_table_header *header,
+ struct acpi_table_desc *table_info);
static acpi_status
-acpi_tb_table_override (
- struct acpi_table_header *header,
- struct acpi_table_desc *table_info);
-
+acpi_tb_table_override(struct acpi_table_header *header,
+ struct acpi_table_desc *table_info);
/*******************************************************************************
*
@@ -78,37 +72,34 @@ acpi_tb_table_override (
******************************************************************************/
acpi_status
-acpi_tb_get_table (
- struct acpi_pointer *address,
- struct acpi_table_desc *table_info)
+acpi_tb_get_table(struct acpi_pointer *address,
+ struct acpi_table_desc *table_info)
{
- acpi_status status;
- struct acpi_table_header header;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_table");
+ acpi_status status;
+ struct acpi_table_header header;
+ ACPI_FUNCTION_TRACE("tb_get_table");
/* Get the header in order to get signature and table size */
- status = acpi_tb_get_table_header (address, &header);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_header(address, &header);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the entire table */
- status = acpi_tb_get_table_body (address, &header, table_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
- header.length, acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_body(address, &header, table_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not get ACPI table (size %X), %s\n",
+ header.length,
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_table_header
@@ -127,16 +118,13 @@ acpi_tb_get_table (
******************************************************************************/
acpi_status
-acpi_tb_get_table_header (
- struct acpi_pointer *address,
- struct acpi_table_header *return_header)
+acpi_tb_get_table_header(struct acpi_pointer *address,
+ struct acpi_table_header *return_header)
{
- acpi_status status = AE_OK;
- struct acpi_table_header *header = NULL;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_table_header");
+ acpi_status status = AE_OK;
+ struct acpi_table_header *header = NULL;
+ ACPI_FUNCTION_TRACE("tb_get_table_header");
/*
* Flags contains the current processor mode (Virtual or Physical
@@ -148,46 +136,42 @@ acpi_tb_get_table_header (
/* Pointer matches processor mode, copy the header */
- ACPI_MEMCPY (return_header, address->pointer.logical,
- sizeof (struct acpi_table_header));
+ ACPI_MEMCPY(return_header, address->pointer.logical,
+ sizeof(struct acpi_table_header));
break;
-
case ACPI_LOGMODE_PHYSPTR:
- /* Create a logical address for the physical pointer*/
+ /* Create a logical address for the physical pointer */
- status = acpi_os_map_memory (address->pointer.physical,
- sizeof (struct acpi_table_header), (void *) &header);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Could not map memory at %8.8X%8.8X for length %X\n",
- ACPI_FORMAT_UINT64 (address->pointer.physical),
- sizeof (struct acpi_table_header)));
- return_ACPI_STATUS (status);
+ status = acpi_os_map_memory(address->pointer.physical,
+ sizeof(struct acpi_table_header),
+ (void *)&header);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not map memory at %8.8X%8.8X for length %X\n", ACPI_FORMAT_UINT64(address->pointer.physical), sizeof(struct acpi_table_header)));
+ return_ACPI_STATUS(status);
}
/* Copy header and delete mapping */
- ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header));
- acpi_os_unmap_memory (header, sizeof (struct acpi_table_header));
+ ACPI_MEMCPY(return_header, header,
+ sizeof(struct acpi_table_header));
+ acpi_os_unmap_memory(header, sizeof(struct acpi_table_header));
break;
-
default:
- ACPI_REPORT_ERROR (("Invalid address flags %X\n",
- address->pointer_type));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_REPORT_ERROR(("Invalid address flags %X\n",
+ address->pointer_type));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
- return_header->signature));
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
+ return_header->signature));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_table_body
@@ -209,37 +193,33 @@ acpi_tb_get_table_header (
******************************************************************************/
acpi_status
-acpi_tb_get_table_body (
- struct acpi_pointer *address,
- struct acpi_table_header *header,
- struct acpi_table_desc *table_info)
+acpi_tb_get_table_body(struct acpi_pointer *address,
+ struct acpi_table_header *header,
+ struct acpi_table_desc *table_info)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_table_body");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("tb_get_table_body");
if (!table_info || !address) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Attempt table override. */
- status = acpi_tb_table_override (header, table_info);
- if (ACPI_SUCCESS (status)) {
+ status = acpi_tb_table_override(header, table_info);
+ if (ACPI_SUCCESS(status)) {
/* Table was overridden by the host OS */
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* No override, get the original table */
- status = acpi_tb_get_this_table (address, header, table_info);
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_this_table(address, header, table_info);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_table_override
@@ -255,61 +235,57 @@ acpi_tb_get_table_body (
******************************************************************************/
static acpi_status
-acpi_tb_table_override (
- struct acpi_table_header *header,
- struct acpi_table_desc *table_info)
+acpi_tb_table_override(struct acpi_table_header *header,
+ struct acpi_table_desc *table_info)
{
- struct acpi_table_header *new_table;
- acpi_status status;
- struct acpi_pointer address;
-
-
- ACPI_FUNCTION_TRACE ("tb_table_override");
+ struct acpi_table_header *new_table;
+ acpi_status status;
+ struct acpi_pointer address;
+ ACPI_FUNCTION_TRACE("tb_table_override");
/*
* The OSL will examine the header and decide whether to override this
* table. If it decides to override, a table will be returned in new_table,
* which we will then copy.
*/
- status = acpi_os_table_override (header, &new_table);
- if (ACPI_FAILURE (status)) {
+ status = acpi_os_table_override(header, &new_table);
+ if (ACPI_FAILURE(status)) {
/* Some severe error from the OSL, but we basically ignore it */
- ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ ACPI_REPORT_ERROR(("Could not override ACPI table, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
if (!new_table) {
/* No table override */
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/*
* We have a new table to override the old one. Get a copy of
* the new one. We know that the new table has a logical pointer.
*/
- address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
+ address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
address.pointer.logical = new_table;
- status = acpi_tb_get_this_table (&address, new_table, table_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_this_table(&address, new_table, table_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not copy override ACPI table, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
/* Copy the table info */
- ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
- table_info->pointer->signature));
+ ACPI_REPORT_INFO(("Table [%4.4s] replaced by host OS\n",
+ table_info->pointer->signature));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_this_table
@@ -329,18 +305,15 @@ acpi_tb_table_override (
******************************************************************************/
static acpi_status
-acpi_tb_get_this_table (
- struct acpi_pointer *address,
- struct acpi_table_header *header,
- struct acpi_table_desc *table_info)
+acpi_tb_get_this_table(struct acpi_pointer *address,
+ struct acpi_table_header *header,
+ struct acpi_table_desc *table_info)
{
- struct acpi_table_header *full_table = NULL;
- u8 allocation;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_this_table");
+ struct acpi_table_header *full_table = NULL;
+ u8 allocation;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("tb_get_this_table");
/*
* Flags contains the current processor mode (Virtual or Physical
@@ -352,38 +325,33 @@ acpi_tb_get_this_table (
/* Pointer matches processor mode, copy the table to a new buffer */
- full_table = ACPI_MEM_ALLOCATE (header->length);
+ full_table = ACPI_MEM_ALLOCATE(header->length);
if (!full_table) {
- ACPI_REPORT_ERROR ((
- "Could not allocate table memory for [%4.4s] length %X\n",
- header->signature, header->length));
- return_ACPI_STATUS (AE_NO_MEMORY);
+ ACPI_REPORT_ERROR(("Could not allocate table memory for [%4.4s] length %X\n", header->signature, header->length));
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the entire table (including header) to the local buffer */
- ACPI_MEMCPY (full_table, address->pointer.logical, header->length);
+ ACPI_MEMCPY(full_table, address->pointer.logical,
+ header->length);
/* Save allocation type */
allocation = ACPI_MEM_ALLOCATED;
break;
-
case ACPI_LOGMODE_PHYSPTR:
/*
* Just map the table's physical memory
* into our address space.
*/
- status = acpi_os_map_memory (address->pointer.physical,
- (acpi_size) header->length, (void *) &full_table);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
- header->signature,
- ACPI_FORMAT_UINT64 (address->pointer.physical),
- header->length));
+ status = acpi_os_map_memory(address->pointer.physical,
+ (acpi_size) header->length,
+ (void *)&full_table);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n", header->signature, ACPI_FORMAT_UINT64(address->pointer.physical), header->length));
return (status);
}
@@ -392,12 +360,11 @@ acpi_tb_get_this_table (
allocation = ACPI_MEM_MAPPED;
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
- address->pointer_type));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid address flags %X\n",
+ address->pointer_type));
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -405,10 +372,10 @@ acpi_tb_get_this_table (
* even the ones whose signature we don't recognize
*/
if (table_info->type != ACPI_TABLE_FACS) {
- status = acpi_tb_verify_table_checksum (full_table);
+ status = acpi_tb_verify_table_checksum(full_table);
#if (!ACPI_CHECKSUM_ABORT)
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
/* Ignore the error if configuration says so */
status = AE_OK;
@@ -418,19 +385,19 @@ acpi_tb_get_this_table (
/* Return values */
- table_info->pointer = full_table;
- table_info->length = (acpi_size) header->length;
- table_info->allocation = allocation;
+ table_info->pointer = full_table;
+ table_info->length = (acpi_size) header->length;
+ table_info->allocation = allocation;
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
- full_table->signature,
- ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
+ full_table->signature,
+ ACPI_FORMAT_UINT64(address->pointer.physical),
+ full_table));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_table_ptr
@@ -447,24 +414,20 @@ acpi_tb_get_this_table (
******************************************************************************/
acpi_status
-acpi_tb_get_table_ptr (
- acpi_table_type table_type,
- u32 instance,
- struct acpi_table_header **table_ptr_loc)
+acpi_tb_get_table_ptr(acpi_table_type table_type,
+ u32 instance, struct acpi_table_header **table_ptr_loc)
{
- struct acpi_table_desc *table_desc;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_table_ptr");
+ struct acpi_table_desc *table_desc;
+ u32 i;
+ ACPI_FUNCTION_TRACE("tb_get_table_ptr");
if (!acpi_gbl_DSDT) {
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
if (table_type > ACPI_TABLE_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -476,15 +439,16 @@ acpi_tb_get_table_ptr (
*table_ptr_loc = NULL;
if (acpi_gbl_table_lists[table_type].next) {
- *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
+ *table_ptr_loc =
+ acpi_gbl_table_lists[table_type].next->pointer;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Check for instance out of range */
if (instance > acpi_gbl_table_lists[table_type].count) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/* Walk the list to get the desired table
@@ -503,6 +467,5 @@ acpi_tb_get_table_ptr (
*table_ptr_loc = table_desc->pointer;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
index eea5b8cb5ebb..8d72343537e7 100644
--- a/drivers/acpi/tables/tbgetall.c
+++ b/drivers/acpi/tables/tbgetall.c
@@ -41,27 +41,21 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbgetall")
+ACPI_MODULE_NAME("tbgetall")
/* Local prototypes */
-
static acpi_status
-acpi_tb_get_primary_table (
- struct acpi_pointer *address,
- struct acpi_table_desc *table_info);
+acpi_tb_get_primary_table(struct acpi_pointer *address,
+ struct acpi_table_desc *table_info);
static acpi_status
-acpi_tb_get_secondary_table (
- struct acpi_pointer *address,
- acpi_string signature,
- struct acpi_table_desc *table_info);
-
+acpi_tb_get_secondary_table(struct acpi_pointer *address,
+ acpi_string signature,
+ struct acpi_table_desc *table_info);
/*******************************************************************************
*
@@ -77,58 +71,54 @@ acpi_tb_get_secondary_table (
******************************************************************************/
static acpi_status
-acpi_tb_get_primary_table (
- struct acpi_pointer *address,
- struct acpi_table_desc *table_info)
+acpi_tb_get_primary_table(struct acpi_pointer *address,
+ struct acpi_table_desc *table_info)
{
- acpi_status status;
- struct acpi_table_header header;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_primary_table");
+ acpi_status status;
+ struct acpi_table_header header;
+ ACPI_FUNCTION_TRACE("tb_get_primary_table");
/* Ignore a NULL address in the RSDT */
if (!address->pointer.value) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Get the header in order to get signature and table size */
- status = acpi_tb_get_table_header (address, &header);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_header(address, &header);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Clear the table_info */
- ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc));
+ ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc));
/*
* Check the table signature and make sure it is recognized.
* Also checks the header checksum
*/
table_info->pointer = &header;
- status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the entire table */
- status = acpi_tb_get_table_body (address, &header, table_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_body(address, &header, table_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Install the table */
- status = acpi_tb_install_table (table_info);
- return_ACPI_STATUS (status);
+ status = acpi_tb_install_table(table_info);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_secondary_table
@@ -143,32 +133,27 @@ acpi_tb_get_primary_table (
******************************************************************************/
static acpi_status
-acpi_tb_get_secondary_table (
- struct acpi_pointer *address,
- acpi_string signature,
- struct acpi_table_desc *table_info)
+acpi_tb_get_secondary_table(struct acpi_pointer *address,
+ acpi_string signature,
+ struct acpi_table_desc *table_info)
{
- acpi_status status;
- struct acpi_table_header header;
-
-
- ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature);
+ acpi_status status;
+ struct acpi_table_header header;
+ ACPI_FUNCTION_TRACE_STR("tb_get_secondary_table", signature);
/* Get the header in order to match the signature */
- status = acpi_tb_get_table_header (address, &header);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_header(address, &header);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Signature must match request */
- if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
- ACPI_REPORT_ERROR ((
- "Incorrect table signature - wanted [%s] found [%4.4s]\n",
- signature, header.signature));
- return_ACPI_STATUS (AE_BAD_SIGNATURE);
+ if (ACPI_STRNCMP(header.signature, signature, ACPI_NAME_SIZE)) {
+ ACPI_REPORT_ERROR(("Incorrect table signature - wanted [%s] found [%4.4s]\n", signature, header.signature));
+ return_ACPI_STATUS(AE_BAD_SIGNATURE);
}
/*
@@ -176,25 +161,24 @@ acpi_tb_get_secondary_table (
* Also checks the header checksum
*/
table_info->pointer = &header;
- status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_recognize_table(table_info, ACPI_TABLE_SECONDARY);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the entire table */
- status = acpi_tb_get_table_body (address, &header, table_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_body(address, &header, table_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Install the table */
- status = acpi_tb_install_table (table_info);
- return_ACPI_STATUS (status);
+ status = acpi_tb_install_table(table_info);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_required_tables
@@ -214,23 +198,19 @@ acpi_tb_get_secondary_table (
*
******************************************************************************/
-acpi_status
-acpi_tb_get_required_tables (
- void)
+acpi_status acpi_tb_get_required_tables(void)
{
- acpi_status status = AE_OK;
- u32 i;
- struct acpi_table_desc table_info;
- struct acpi_pointer address;
-
+ acpi_status status = AE_OK;
+ u32 i;
+ struct acpi_table_desc table_info;
+ struct acpi_pointer address;
- ACPI_FUNCTION_TRACE ("tb_get_required_tables");
+ ACPI_FUNCTION_TRACE("tb_get_required_tables");
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
- acpi_gbl_rsdt_table_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
+ acpi_gbl_rsdt_table_count));
-
- address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
+ address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
/*
* Loop through all table pointers found in RSDT.
@@ -243,84 +223,79 @@ acpi_tb_get_required_tables (
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
/* Get the table address from the common internal XSDT */
- address.pointer.value =
- acpi_gbl_XSDT->table_offset_entry[i];
+ address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
/*
* Get the tables needed by this subsystem (FADT and any SSDTs).
* NOTE: All other tables are completely ignored at this time.
*/
- status = acpi_tb_get_primary_table (&address, &table_info);
+ status = acpi_tb_get_primary_table(&address, &table_info);
if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
- ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
- acpi_format_exception (status),
- ACPI_FORMAT_UINT64 (address.pointer.value)));
+ ACPI_REPORT_WARNING(("%s, while getting table at %8.8X%8.8X\n", acpi_format_exception(status), ACPI_FORMAT_UINT64(address.pointer.value)));
}
}
/* We must have a FADT to continue */
if (!acpi_gbl_FADT) {
- ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ ACPI_REPORT_ERROR(("No FADT present in RSDT/XSDT\n"));
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/*
* Convert the FADT to a common format. This allows earlier revisions of
* the table to coexist with newer versions, using common access code.
*/
- status = acpi_tb_convert_table_fadt ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "Could not convert FADT to internal common format\n"));
- return_ACPI_STATUS (status);
+ status = acpi_tb_convert_table_fadt();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not convert FADT to internal common format\n"));
+ return_ACPI_STATUS(status);
}
/* Get the FACS (Pointed to by the FADT) */
address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
- status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not get/install the FACS, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
/*
* Create the common FACS pointer table
* (Contains pointers to the original table)
*/
- status = acpi_tb_build_common_facs (&table_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_build_common_facs(&table_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get/install the DSDT (Pointed to by the FADT) */
address.pointer.value = acpi_gbl_FADT->Xdsdt;
- status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not get/install the DSDT\n"));
+ return_ACPI_STATUS(status);
}
/* Set Integer Width (32/64) based upon DSDT revision */
- acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
+ acpi_ut_set_integer_width(acpi_gbl_DSDT->revision);
/* Dump the entire DSDT */
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
- "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
- acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
- ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
+ "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
+ acpi_gbl_DSDT->length, acpi_gbl_DSDT->length,
+ acpi_gbl_integer_bit_width));
+ ACPI_DUMP_BUFFER((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
/* Always delete the RSDP mapping, we are done with it */
- acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
- return_ACPI_STATUS (status);
+ acpi_tb_delete_tables_by_type(ACPI_TABLE_RSDP);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 629b64c8193d..10db8484e462 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -41,22 +41,16 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbinstal")
+ACPI_MODULE_NAME("tbinstal")
/* Local prototypes */
-
static acpi_status
-acpi_tb_match_signature (
- char *signature,
- struct acpi_table_desc *table_info,
- u8 search_type);
-
+acpi_tb_match_signature(char *signature,
+ struct acpi_table_desc *table_info, u8 search_type);
/*******************************************************************************
*
@@ -74,16 +68,12 @@ acpi_tb_match_signature (
******************************************************************************/
static acpi_status
-acpi_tb_match_signature (
- char *signature,
- struct acpi_table_desc *table_info,
- u8 search_type)
+acpi_tb_match_signature(char *signature,
+ struct acpi_table_desc *table_info, u8 search_type)
{
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_TRACE ("tb_match_signature");
+ acpi_native_uint i;
+ ACPI_FUNCTION_TRACE("tb_match_signature");
/* Search for a signature match among the known table types */
@@ -92,30 +82,30 @@ acpi_tb_match_signature (
continue;
}
- if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature,
- acpi_gbl_table_data[i].sig_length)) {
+ if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature,
+ acpi_gbl_table_data[i].sig_length)) {
/* Found a signature match, return index if requested */
if (table_info) {
table_info->type = (u8) i;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
- (char *) acpi_gbl_table_data[i].signature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
+ (char *)acpi_gbl_table_data[i].
+ signature));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
- (char *) signature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
+ (char *)signature));
- return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED);
+ return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_install_table
@@ -124,46 +114,52 @@ acpi_tb_match_signature (
*
* RETURN: Status
*
- * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must
- * already be loaded and validated.
- * Install the table into the global data structs.
+ * DESCRIPTION: Install the table into the global data structures.
*
******************************************************************************/
-acpi_status
-acpi_tb_install_table (
- struct acpi_table_desc *table_info)
+acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info)
{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE ("tb_install_table");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("tb_install_table");
/* Lock tables while installing */
- status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n",
- table_info->pointer->signature, acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not acquire table mutex, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * Ignore a table that is already installed. For example, some BIOS
+ * ASL code will repeatedly attempt to load the same SSDT.
+ */
+ status = acpi_tb_is_table_installed(table_info);
+ if (ACPI_FAILURE(status)) {
+ goto unlock_and_exit;
}
/* Install the table into the global data structure */
- status = acpi_tb_init_table_descriptor (table_info->type, table_info);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n",
- table_info->pointer->signature, acpi_format_exception (status)));
+ status = acpi_tb_init_table_descriptor(table_info->type, table_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Could not install table [%4.4s], %s\n",
+ table_info->pointer->signature,
+ acpi_format_exception(status)));
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
- acpi_gbl_table_data[table_info->type].name, table_info->pointer));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n",
+ acpi_gbl_table_data[table_info->type].name,
+ table_info->pointer));
- (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_recognize_table
@@ -186,22 +182,18 @@ acpi_tb_install_table (
******************************************************************************/
acpi_status
-acpi_tb_recognize_table (
- struct acpi_table_desc *table_info,
- u8 search_type)
+acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type)
{
- struct acpi_table_header *table_header;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("tb_recognize_table");
+ struct acpi_table_header *table_header;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("tb_recognize_table");
/* Ensure that we have a valid table pointer */
- table_header = (struct acpi_table_header *) table_info->pointer;
+ table_header = (struct acpi_table_header *)table_info->pointer;
if (!table_header) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/*
@@ -212,25 +204,24 @@ acpi_tb_recognize_table (
* This can be any one of many valid ACPI tables, it just isn't one of
* the tables that is consumed by the core subsystem
*/
- status = acpi_tb_match_signature (table_header->signature,
- table_info, search_type);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_match_signature(table_header->signature,
+ table_info, search_type);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- status = acpi_tb_validate_table_header (table_header);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_validate_table_header(table_header);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Return the table type and length via the info struct */
table_info->length = (acpi_size) table_header->length;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_init_table_descriptor
@@ -245,22 +236,27 @@ acpi_tb_recognize_table (
******************************************************************************/
acpi_status
-acpi_tb_init_table_descriptor (
- acpi_table_type table_type,
- struct acpi_table_desc *table_info)
+acpi_tb_init_table_descriptor(acpi_table_type table_type,
+ struct acpi_table_desc *table_info)
{
- struct acpi_table_list *list_head;
- struct acpi_table_desc *table_desc;
-
-
- ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);
+ struct acpi_table_list *list_head;
+ struct acpi_table_desc *table_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_U32("tb_init_table_descriptor", table_type);
/* Allocate a descriptor for this table */
- table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+ table_desc = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc));
if (!table_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ /* Get a new owner ID for the table */
+
+ status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Install the table into the global data structure */
@@ -272,14 +268,14 @@ acpi_tb_init_table_descriptor (
* includes most ACPI tables such as the DSDT. 2) Multiple instances of
* the table are allowed. This includes SSDT and PSDTs.
*/
- if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
+ if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) {
/*
* Only one table allowed, and a table has alread been installed
* at this location, so return an error.
*/
if (list_head->next) {
- ACPI_MEM_FREE (table_desc);
- return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ ACPI_MEM_FREE(table_desc);
+ return_ACPI_STATUS(AE_ALREADY_EXISTS);
}
table_desc->next = list_head->next;
@@ -290,8 +286,7 @@ acpi_tb_init_table_descriptor (
}
list_head->count++;
- }
- else {
+ } else {
/*
* Link the new table in to the list of tables of this type.
* Insert at the end of the list, order IS IMPORTANT.
@@ -302,8 +297,7 @@ acpi_tb_init_table_descriptor (
if (!list_head->next) {
list_head->next = table_desc;
- }
- else {
+ } else {
table_desc->next = list_head->next;
while (table_desc->next->next) {
@@ -318,15 +312,14 @@ acpi_tb_init_table_descriptor (
/* Finish initialization of the table descriptor */
- table_desc->type = (u8) table_type;
- table_desc->pointer = table_info->pointer;
- table_desc->length = table_info->length;
- table_desc->allocation = table_info->allocation;
- table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
- table_desc->aml_length = (u32) (table_desc->length -
- (u32) sizeof (struct acpi_table_header));
- table_desc->table_id = acpi_ut_allocate_owner_id (
- ACPI_OWNER_TYPE_TABLE);
+ table_desc->type = (u8) table_type;
+ table_desc->pointer = table_info->pointer;
+ table_desc->length = table_info->length;
+ table_desc->allocation = table_info->allocation;
+ table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
+ table_desc->aml_length = (u32) (table_desc->length -
+ (u32) sizeof(struct
+ acpi_table_header));
table_desc->loaded_into_namespace = FALSE;
/*
@@ -334,18 +327,18 @@ acpi_tb_init_table_descriptor (
* newly installed table
*/
if (acpi_gbl_table_data[table_type].global_ptr) {
- *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
+ *(acpi_gbl_table_data[table_type].global_ptr) =
+ table_info->pointer;
}
/* Return Data */
- table_info->table_id = table_desc->table_id;
- table_info->installed_desc = table_desc;
+ table_info->owner_id = table_desc->owner_id;
+ table_info->installed_desc = table_desc;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_delete_all_tables
@@ -358,23 +351,19 @@ acpi_tb_init_table_descriptor (
*
******************************************************************************/
-void
-acpi_tb_delete_all_tables (
- void)
+void acpi_tb_delete_all_tables(void)
{
- acpi_table_type type;
-
+ acpi_table_type type;
/*
* Free memory allocated for ACPI tables
* Memory can either be mapped or allocated
*/
for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
- acpi_tb_delete_tables_by_type (type);
+ acpi_tb_delete_tables_by_type(type);
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_delete_tables_by_type
@@ -388,23 +377,19 @@ acpi_tb_delete_all_tables (
*
******************************************************************************/
-void
-acpi_tb_delete_tables_by_type (
- acpi_table_type type)
+void acpi_tb_delete_tables_by_type(acpi_table_type type)
{
- struct acpi_table_desc *table_desc;
- u32 count;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type);
+ struct acpi_table_desc *table_desc;
+ u32 count;
+ u32 i;
+ ACPI_FUNCTION_TRACE_U32("tb_delete_tables_by_type", type);
if (type > ACPI_TABLE_MAX) {
return_VOID;
}
- if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_TABLES))) {
+ if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) {
return;
}
@@ -442,21 +427,20 @@ acpi_tb_delete_tables_by_type (
* 1) Get the head of the list
*/
table_desc = acpi_gbl_table_lists[type].next;
- count = acpi_gbl_table_lists[type].count;
+ count = acpi_gbl_table_lists[type].count;
/*
* 2) Walk the entire list, deleting both the allocated tables
* and the table descriptors
*/
for (i = 0; i < count; i++) {
- table_desc = acpi_tb_uninstall_table (table_desc);
+ table_desc = acpi_tb_uninstall_table(table_desc);
}
- (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_delete_single_table
@@ -470,15 +454,12 @@ acpi_tb_delete_tables_by_type (
*
******************************************************************************/
-void
-acpi_tb_delete_single_table (
- struct acpi_table_desc *table_desc)
+void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc)
{
/* Must have a valid table descriptor and pointer */
- if ((!table_desc) ||
- (!table_desc->pointer)) {
+ if ((!table_desc) || (!table_desc->pointer)) {
return;
}
@@ -490,12 +471,12 @@ acpi_tb_delete_single_table (
case ACPI_MEM_ALLOCATED:
- ACPI_MEM_FREE (table_desc->pointer);
+ ACPI_MEM_FREE(table_desc->pointer);
break;
case ACPI_MEM_MAPPED:
- acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
+ acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
break;
default:
@@ -503,7 +484,6 @@ acpi_tb_delete_single_table (
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_uninstall_table
@@ -518,26 +498,22 @@ acpi_tb_delete_single_table (
*
******************************************************************************/
-struct acpi_table_desc *
-acpi_tb_uninstall_table (
- struct acpi_table_desc *table_desc)
+struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc
+ *table_desc)
{
- struct acpi_table_desc *next_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc);
+ struct acpi_table_desc *next_desc;
+ ACPI_FUNCTION_TRACE_PTR("tb_uninstall_table", table_desc);
if (!table_desc) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
/* Unlink the descriptor from the doubly linked list */
if (table_desc->prev) {
table_desc->prev->next = table_desc->next;
- }
- else {
+ } else {
/* Is first on list, update list head */
acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
@@ -549,16 +525,14 @@ acpi_tb_uninstall_table (
/* Free the memory allocated for the table itself */
- acpi_tb_delete_single_table (table_desc);
+ acpi_tb_delete_single_table(table_desc);
/* Free the table descriptor */
next_desc = table_desc->next;
- ACPI_MEM_FREE (table_desc);
+ ACPI_MEM_FREE(table_desc);
/* Return pointer to the next descriptor */
- return_PTR (next_desc);
+ return_PTR(next_desc);
}
-
-
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index b7ffe39c3626..ad0252c2f7db 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -41,14 +41,11 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbrsdt")
-
+ACPI_MODULE_NAME("tbrsdt")
/*******************************************************************************
*
@@ -61,18 +58,13 @@
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
*
******************************************************************************/
-
-acpi_status
-acpi_tb_verify_rsdp (
- struct acpi_pointer *address)
+acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address)
{
- struct acpi_table_desc table_info;
- acpi_status status;
- struct rsdp_descriptor *rsdp;
-
-
- ACPI_FUNCTION_TRACE ("tb_verify_rsdp");
+ struct acpi_table_desc table_info;
+ acpi_status status;
+ struct rsdp_descriptor *rsdp;
+ ACPI_FUNCTION_TRACE("tb_verify_rsdp");
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
@@ -84,73 +76,53 @@ acpi_tb_verify_rsdp (
/*
* Obtain access to the RSDP structure
*/
- status = acpi_os_map_memory (address->pointer.physical,
- sizeof (struct rsdp_descriptor),
- (void *) &rsdp);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_os_map_memory(address->pointer.physical,
+ sizeof(struct rsdp_descriptor),
+ (void *)&rsdp);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
break;
default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /*
- * The signature and checksum must both be correct
- */
- if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
- /* Nope, BAD Signature */
+ /* Verify RSDP signature and checksum */
- status = AE_BAD_SIGNATURE;
+ status = acpi_tb_validate_rsdp(rsdp);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- /* Check the standard checksum */
-
- if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
- status = AE_BAD_CHECKSUM;
- goto cleanup;
- }
-
- /* Check extended checksum if table version >= 2 */
-
- if (rsdp->revision >= 2) {
- if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
- status = AE_BAD_CHECKSUM;
- goto cleanup;
- }
- }
-
/* The RSDP supplied is OK */
- table_info.pointer = ACPI_CAST_PTR (struct acpi_table_header, rsdp);
- table_info.length = sizeof (struct rsdp_descriptor);
- table_info.allocation = ACPI_MEM_MAPPED;
+ table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp);
+ table_info.length = sizeof(struct rsdp_descriptor);
+ table_info.allocation = ACPI_MEM_MAPPED;
/* Save the table pointers and allocation info */
- status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_init_table_descriptor(ACPI_TABLE_RSDP, &table_info);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Save the RSDP in a global for easy access */
- acpi_gbl_RSDP = ACPI_CAST_PTR (struct rsdp_descriptor, table_info.pointer);
- return_ACPI_STATUS (status);
-
+ acpi_gbl_RSDP =
+ ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer);
+ return_ACPI_STATUS(status);
/* Error exit */
-cleanup:
+ cleanup:
if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
- acpi_os_unmap_memory (rsdp, sizeof (struct rsdp_descriptor));
+ acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor));
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_rsdt_address
@@ -159,35 +131,35 @@ cleanup:
*
* RETURN: None, Address
*
- * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
- * version of the RSDP
+ * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the
+ * version of the RSDP and whether the XSDT pointer is valid
*
******************************************************************************/
-void
-acpi_tb_get_rsdt_address (
- struct acpi_pointer *out_address)
+void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address)
{
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
+ out_address->pointer_type =
+ acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
- out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
+ /* Use XSDT if it is present */
- /*
- * For RSDP revision 0 or 1, we use the RSDT.
- * For RSDP revision 2 (and above), we use the XSDT
- */
- if (acpi_gbl_RSDP->revision < 2) {
- out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
- }
- else {
+ if ((acpi_gbl_RSDP->revision >= 2) &&
+ acpi_gbl_RSDP->xsdt_physical_address) {
out_address->pointer.value =
- acpi_gbl_RSDP->xsdt_physical_address;
+ acpi_gbl_RSDP->xsdt_physical_address;
+ acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT;
+ } else {
+ /* No XSDT, use the RSDT */
+
+ out_address->pointer.value =
+ acpi_gbl_RSDP->rsdt_physical_address;
+ acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT;
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_rsdt
@@ -200,50 +172,43 @@ acpi_tb_get_rsdt_address (
*
******************************************************************************/
-acpi_status
-acpi_tb_validate_rsdt (
- struct acpi_table_header *table_ptr)
+acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
{
- int no_match;
-
-
- ACPI_FUNCTION_NAME ("tb_validate_rsdt");
+ int no_match;
+ ACPI_FUNCTION_NAME("tb_validate_rsdt");
/*
- * For RSDP revision 0 or 1, we use the RSDT.
- * For RSDP revision 2 and above, we use the XSDT
+ * Search for appropriate signature, RSDT or XSDT
*/
- if (acpi_gbl_RSDP->revision < 2) {
- no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
- sizeof (RSDT_SIG) -1);
- }
- else {
- no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
- sizeof (XSDT_SIG) -1);
+ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
+ no_match = ACPI_STRNCMP((char *)table_ptr, RSDT_SIG,
+ sizeof(RSDT_SIG) - 1);
+ } else {
+ no_match = ACPI_STRNCMP((char *)table_ptr, XSDT_SIG,
+ sizeof(XSDT_SIG) - 1);
}
if (no_match) {
/* Invalid RSDT or XSDT signature */
- ACPI_REPORT_ERROR ((
- "Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+ ACPI_REPORT_ERROR(("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
- ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
+ ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20);
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
- "RSDT/XSDT signature at %X (%p) is invalid\n",
- acpi_gbl_RSDP->rsdt_physical_address,
- (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_ERROR,
+ "RSDT/XSDT signature at %X (%p) is invalid\n",
+ acpi_gbl_RSDP->rsdt_physical_address,
+ (void *)(acpi_native_uint) acpi_gbl_RSDP->
+ rsdt_physical_address));
- if (acpi_gbl_RSDP->revision < 2) {
- ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n"))
- }
- else {
- ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n"))
+ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
+ ACPI_REPORT_ERROR(("Looking for RSDT\n"))
+ } else {
+ ACPI_REPORT_ERROR(("Looking for XSDT\n"))
}
- ACPI_DUMP_BUFFER ((char *) table_ptr, 48);
+ ACPI_DUMP_BUFFER((char *)table_ptr, 48);
return (AE_BAD_SIGNATURE);
}
@@ -251,7 +216,6 @@ acpi_tb_validate_rsdt (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_table_rsdt
@@ -264,66 +228,61 @@ acpi_tb_validate_rsdt (
*
******************************************************************************/
-acpi_status
-acpi_tb_get_table_rsdt (
- void)
+acpi_status acpi_tb_get_table_rsdt(void)
{
- struct acpi_table_desc table_info;
- acpi_status status;
- struct acpi_pointer address;
-
-
- ACPI_FUNCTION_TRACE ("tb_get_table_rsdt");
+ struct acpi_table_desc table_info;
+ acpi_status status;
+ struct acpi_pointer address;
+ ACPI_FUNCTION_TRACE("tb_get_table_rsdt");
/* Get the RSDT/XSDT via the RSDP */
- acpi_tb_get_rsdt_address (&address);
+ acpi_tb_get_rsdt_address(&address);
table_info.type = ACPI_TABLE_XSDT;
- status = acpi_tb_get_table (&address, &table_info);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
- acpi_format_exception (status)));
+ status = acpi_tb_get_table(&address, &table_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not get the RSDT/XSDT, %s\n",
+ acpi_format_exception(status)));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
- acpi_gbl_RSDP,
- ACPI_FORMAT_UINT64 (address.pointer.value)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
+ acpi_gbl_RSDP,
+ ACPI_FORMAT_UINT64(address.pointer.value)));
/* Check the RSDT or XSDT signature */
- status = acpi_tb_validate_rsdt (table_info.pointer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_validate_rsdt(table_info.pointer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the number of tables defined in the RSDT or XSDT */
- acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP,
- table_info.pointer);
+ acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP,
+ table_info.pointer);
/* Convert and/or copy to an XSDT structure */
- status = acpi_tb_convert_to_xsdt (&table_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_convert_to_xsdt(&table_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Save the table pointers and allocation info */
- status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_init_table_descriptor(ACPI_TABLE_XSDT, &table_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- acpi_gbl_XSDT = ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info.pointer);
+ acpi_gbl_XSDT = ACPI_CAST_PTR(XSDT_DESCRIPTOR, table_info.pointer);
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index e69d01d443d2..4b2fbb592f49 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -41,23 +41,84 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbutils")
+ACPI_MODULE_NAME("tbutils")
/* Local prototypes */
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
acpi_status
-acpi_tb_handle_to_object (
- u16 table_id,
- struct acpi_table_desc **table_desc);
+acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc);
#endif
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_is_table_installed
+ *
+ * PARAMETERS: new_table_desc - Descriptor for new table being installed
+ *
+ * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed
+ *
+ * DESCRIPTION: Determine if an ACPI table is already installed
+ *
+ * MUTEX: Table data structures should be locked
+ *
+ ******************************************************************************/
+
+acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc)
+{
+ struct acpi_table_desc *table_desc;
+
+ ACPI_FUNCTION_TRACE("tb_is_table_installed");
+
+ /* Get the list descriptor and first table descriptor */
+
+ table_desc = acpi_gbl_table_lists[new_table_desc->type].next;
+
+ /* Examine all installed tables of this type */
+
+ while (table_desc) {
+ /*
+ * If the table lengths match, perform a full bytewise compare. This
+ * means that we will allow tables with duplicate oem_table_id(s), as
+ * long as the tables are different in some way.
+ *
+ * Checking if the table has been loaded into the namespace means that
+ * we don't check for duplicate tables during the initial installation
+ * of tables within the RSDT/XSDT.
+ */
+ if ((table_desc->loaded_into_namespace) &&
+ (table_desc->pointer->length ==
+ new_table_desc->pointer->length)
+ &&
+ (!ACPI_MEMCMP
+ ((const char *)table_desc->pointer,
+ (const char *)new_table_desc->pointer,
+ (acpi_size) new_table_desc->pointer->length))) {
+ /* Match: this table is already installed */
+
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
+ "Table [%4.4s] already installed: Rev %X oem_table_id [%8.8s]\n",
+ new_table_desc->pointer->signature,
+ new_table_desc->pointer->revision,
+ new_table_desc->pointer->
+ oem_table_id));
+
+ new_table_desc->owner_id = table_desc->owner_id;
+ new_table_desc->installed_desc = table_desc;
+
+ return_ACPI_STATUS(AE_ALREADY_EXISTS);
+ }
+
+ /* Get next table on the list */
+
+ table_desc = table_desc->next;
+ }
+
+ return_ACPI_STATUS(AE_OK);
+}
/*******************************************************************************
*
@@ -80,57 +141,55 @@ acpi_tb_handle_to_object (
******************************************************************************/
acpi_status
-acpi_tb_validate_table_header (
- struct acpi_table_header *table_header)
+acpi_tb_validate_table_header(struct acpi_table_header *table_header)
{
- acpi_name signature;
-
-
- ACPI_FUNCTION_NAME ("tb_validate_table_header");
+ acpi_name signature;
+ ACPI_FUNCTION_NAME("tb_validate_table_header");
/* Verify that this is a valid address */
- if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Cannot read table header at %p\n", table_header));
+ if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Cannot read table header at %p\n",
+ table_header));
return (AE_BAD_ADDRESS);
}
/* Ensure that the signature is 4 ASCII characters */
- ACPI_MOVE_32_TO_32 (&signature, table_header->signature);
- if (!acpi_ut_valid_acpi_name (signature)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Table signature at %p [%p] has invalid characters\n",
- table_header, &signature));
+ ACPI_MOVE_32_TO_32(&signature, table_header->signature);
+ if (!acpi_ut_valid_acpi_name(signature)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Table signature at %p [%p] has invalid characters\n",
+ table_header, &signature));
- ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
- (char *) &signature));
+ ACPI_REPORT_WARNING(("Invalid table signature found: [%4.4s]\n",
+ (char *)&signature));
- ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
+ ACPI_DUMP_BUFFER(table_header,
+ sizeof(struct acpi_table_header));
return (AE_BAD_SIGNATURE);
}
/* Validate the table length */
- if (table_header->length < sizeof (struct acpi_table_header)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid length in table header %p name %4.4s\n",
- table_header, (char *) &signature));
+ if (table_header->length < sizeof(struct acpi_table_header)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid length in table header %p name %4.4s\n",
+ table_header, (char *)&signature));
- ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
- (u32) table_header->length));
+ ACPI_REPORT_WARNING(("Invalid table header length (0x%X) found\n", (u32) table_header->length));
- ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
+ ACPI_DUMP_BUFFER(table_header,
+ sizeof(struct acpi_table_header));
return (AE_BAD_HEADER);
}
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_verify_table_checksum
@@ -145,37 +204,31 @@ acpi_tb_validate_table_header (
******************************************************************************/
acpi_status
-acpi_tb_verify_table_checksum (
- struct acpi_table_header *table_header)
+acpi_tb_verify_table_checksum(struct acpi_table_header * table_header)
{
- u8 checksum;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("tb_verify_table_checksum");
+ u8 checksum;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("tb_verify_table_checksum");
/* Compute the checksum on the table */
- checksum = acpi_tb_checksum (table_header, table_header->length);
+ checksum =
+ acpi_tb_generate_checksum(table_header, table_header->length);
/* Return the appropriate exception */
if (checksum) {
- ACPI_REPORT_WARNING ((
- "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
- table_header->signature, (u32) table_header->checksum,
- (u32) checksum));
+ ACPI_REPORT_WARNING(("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n", table_header->signature, (u32) table_header->checksum, (u32) checksum));
status = AE_BAD_CHECKSUM;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
- * FUNCTION: acpi_tb_checksum
+ * FUNCTION: acpi_tb_generate_checksum
*
* PARAMETERS: Buffer - Buffer to checksum
* Length - Size of the buffer
@@ -186,15 +239,11 @@ acpi_tb_verify_table_checksum (
*
******************************************************************************/
-u8
-acpi_tb_checksum (
- void *buffer,
- u32 length)
+u8 acpi_tb_generate_checksum(void *buffer, u32 length)
{
- const u8 *limit;
- const u8 *rover;
- u8 sum = 0;
-
+ const u8 *limit;
+ const u8 *rover;
+ u8 sum = 0;
if (buffer && length) {
/* Buffer and Length are valid */
@@ -208,7 +257,6 @@ acpi_tb_checksum (
return (sum);
}
-
#ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
*
@@ -224,16 +272,13 @@ acpi_tb_checksum (
******************************************************************************/
acpi_status
-acpi_tb_handle_to_object (
- u16 table_id,
- struct acpi_table_desc **return_table_desc)
+acpi_tb_handle_to_object(u16 table_id,
+ struct acpi_table_desc ** return_table_desc)
{
- u32 i;
- struct acpi_table_desc *table_desc;
-
-
- ACPI_FUNCTION_NAME ("tb_handle_to_object");
+ u32 i;
+ struct acpi_table_desc *table_desc;
+ ACPI_FUNCTION_NAME("tb_handle_to_object");
for (i = 0; i < ACPI_TABLE_MAX; i++) {
table_desc = acpi_gbl_table_lists[i].next;
@@ -247,9 +292,8 @@ acpi_tb_handle_to_object (
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "table_id=%X does not exist\n",
+ table_id));
return (AE_BAD_PARAMETER);
}
#endif
-
-
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 0c0b9085dbeb..3f96a4909aad 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -48,10 +48,8 @@
#include <acpi/acnamesp.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbxface")
-
+ACPI_MODULE_NAME("tbxface")
/*******************************************************************************
*
@@ -65,25 +63,20 @@
* provided RSDT
*
******************************************************************************/
-
-acpi_status
-acpi_load_tables (
- void)
+acpi_status acpi_load_tables(void)
{
- struct acpi_pointer rsdp_address;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_load_tables");
+ struct acpi_pointer rsdp_address;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_load_tables");
/* Get the RSDP */
- status = acpi_os_get_root_pointer (ACPI_LOGICAL_ADDRESSING,
- &rsdp_address);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("acpi_load_tables: Could not get RSDP, %s\n",
- acpi_format_exception (status)));
+ status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING,
+ &rsdp_address);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_load_tables: Could not get RSDP, %s\n",
+ acpi_format_exception(status)));
goto error_exit;
}
@@ -91,54 +84,47 @@ acpi_load_tables (
acpi_gbl_table_flags = rsdp_address.pointer_type;
- status = acpi_tb_verify_rsdp (&rsdp_address);
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("acpi_load_tables: RSDP Failed validation: %s\n",
- acpi_format_exception (status)));
+ status = acpi_tb_verify_rsdp(&rsdp_address);
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_load_tables: RSDP Failed validation: %s\n", acpi_format_exception(status)));
goto error_exit;
}
/* Get the RSDT via the RSDP */
- status = acpi_tb_get_table_rsdt ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("acpi_load_tables: Could not load RSDT: %s\n",
- acpi_format_exception (status)));
+ status = acpi_tb_get_table_rsdt();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_load_tables: Could not load RSDT: %s\n", acpi_format_exception(status)));
goto error_exit;
}
/* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */
- status = acpi_tb_get_required_tables ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR ((
- "acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
- acpi_format_exception (status)));
+ status = acpi_tb_get_required_tables();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", acpi_format_exception(status)));
goto error_exit;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
/* Load the namespace from the tables */
- status = acpi_ns_load_namespace ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("acpi_load_tables: Could not load namespace: %s\n",
- acpi_format_exception (status)));
+ status = acpi_ns_load_namespace();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("acpi_load_tables: Could not load namespace: %s\n", acpi_format_exception(status)));
goto error_exit;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
+ error_exit:
+ ACPI_REPORT_ERROR(("acpi_load_tables: Could not load tables: %s\n",
+ acpi_format_exception(status)));
-error_exit:
- ACPI_REPORT_ERROR (("acpi_load_tables: Could not load tables: %s\n",
- acpi_format_exception (status)));
-
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -156,40 +142,49 @@ error_exit:
*
******************************************************************************/
-acpi_status
-acpi_load_table (
- struct acpi_table_header *table_ptr)
+acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
{
- acpi_status status;
- struct acpi_table_desc table_info;
- struct acpi_pointer address;
-
-
- ACPI_FUNCTION_TRACE ("acpi_load_table");
+ acpi_status status;
+ struct acpi_table_desc table_info;
+ struct acpi_pointer address;
+ ACPI_FUNCTION_TRACE("acpi_load_table");
if (!table_ptr) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Copy the table to a local buffer */
- address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
+ address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
address.pointer.logical = table_ptr;
- status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_body(&address, table_ptr, &table_info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /* Check signature for a valid table type */
+
+ status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Install the new table into the local data structures */
- status = acpi_tb_install_table (&table_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_install_table(&table_info);
+ if (ACPI_FAILURE(status)) {
+ if (status == AE_ALREADY_EXISTS) {
+ /* Table already exists, no error */
+
+ status = AE_OK;
+ }
+
/* Free table allocated by acpi_tb_get_table_body */
- acpi_tb_delete_single_table (&table_info);
- return_ACPI_STATUS (status);
+ acpi_tb_delete_single_table(&table_info);
+ return_ACPI_STATUS(status);
}
/* Convert the table to common format if necessary */
@@ -197,31 +192,32 @@ acpi_load_table (
switch (table_info.type) {
case ACPI_TABLE_FADT:
- status = acpi_tb_convert_table_fadt ();
+ status = acpi_tb_convert_table_fadt();
break;
case ACPI_TABLE_FACS:
- status = acpi_tb_build_common_facs (&table_info);
+ status = acpi_tb_build_common_facs(&table_info);
break;
default:
/* Load table into namespace if it contains executable AML */
- status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
+ status =
+ acpi_ns_load_table(table_info.installed_desc,
+ acpi_gbl_root_node);
break;
}
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE(status)) {
/* Uninstall table and free the buffer */
- (void) acpi_tb_uninstall_table (table_info.installed_desc);
+ (void)acpi_tb_uninstall_table(table_info.installed_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_unload_table
@@ -234,20 +230,16 @@ acpi_load_table (
*
******************************************************************************/
-acpi_status
-acpi_unload_table (
- acpi_table_type table_type)
+acpi_status acpi_unload_table(acpi_table_type table_type)
{
- struct acpi_table_desc *table_desc;
-
-
- ACPI_FUNCTION_TRACE ("acpi_unload_table");
+ struct acpi_table_desc *table_desc;
+ ACPI_FUNCTION_TRACE("acpi_unload_table");
/* Parameter validation */
if (table_type > ACPI_TABLE_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Find all tables of the requested type */
@@ -260,18 +252,17 @@ acpi_unload_table (
* "Scope" operator. Thus, we need to track ownership by an ID, not
* simply a position within the hierarchy
*/
- acpi_ns_delete_namespace_by_owner (table_desc->table_id);
-
+ acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
+ acpi_ut_release_owner_id(&table_desc->owner_id);
table_desc = table_desc->next;
}
/* Delete (or unmap) all tables of this type */
- acpi_tb_delete_tables_by_type (table_type);
- return_ACPI_STATUS (AE_OK);
+ acpi_tb_delete_tables_by_type(table_type);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_table_header
@@ -294,54 +285,49 @@ acpi_unload_table (
******************************************************************************/
acpi_status
-acpi_get_table_header (
- acpi_table_type table_type,
- u32 instance,
- struct acpi_table_header *out_table_header)
+acpi_get_table_header(acpi_table_type table_type,
+ u32 instance, struct acpi_table_header *out_table_header)
{
- struct acpi_table_header *tbl_ptr;
- acpi_status status;
+ struct acpi_table_header *tbl_ptr;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_get_table_header");
- ACPI_FUNCTION_TRACE ("acpi_get_table_header");
-
-
- if ((instance == 0) ||
- (table_type == ACPI_TABLE_RSDP) ||
- (!out_table_header)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((instance == 0) ||
+ (table_type == ACPI_TABLE_RSDP) || (!out_table_header)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Check the table type and instance */
- if ((table_type > ACPI_TABLE_MAX) ||
- (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
- instance > 1)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((table_type > ACPI_TABLE_MAX) ||
+ (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) &&
+ instance > 1)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get a pointer to the entire table */
- status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* The function will return a NULL pointer if the table is not loaded */
if (tbl_ptr == NULL) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/* Copy the header to the caller's buffer */
- ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
- sizeof (struct acpi_table_header));
+ ACPI_MEMCPY((void *)out_table_header, (void *)tbl_ptr,
+ sizeof(struct acpi_table_header));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-#endif /* ACPI_FUTURE_USAGE */
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -367,43 +353,39 @@ acpi_get_table_header (
******************************************************************************/
acpi_status
-acpi_get_table (
- acpi_table_type table_type,
- u32 instance,
- struct acpi_buffer *ret_buffer)
+acpi_get_table(acpi_table_type table_type,
+ u32 instance, struct acpi_buffer *ret_buffer)
{
- struct acpi_table_header *tbl_ptr;
- acpi_status status;
- acpi_size table_length;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_table");
+ struct acpi_table_header *tbl_ptr;
+ acpi_status status;
+ acpi_size table_length;
+ ACPI_FUNCTION_TRACE("acpi_get_table");
/* Parameter validation */
if (instance == 0) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_ut_validate_buffer (ret_buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_validate_buffer(ret_buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Check the table type and instance */
- if ((table_type > ACPI_TABLE_MAX) ||
- (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
- instance > 1)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((table_type > ACPI_TABLE_MAX) ||
+ (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) &&
+ instance > 1)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get a pointer to the entire table */
- status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -411,7 +393,7 @@ acpi_get_table (
* table is not loaded.
*/
if (tbl_ptr == NULL) {
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
/* Get the table length */
@@ -419,23 +401,22 @@ acpi_get_table (
if (table_type == ACPI_TABLE_RSDP) {
/* RSD PTR is the only "table" without a header */
- table_length = sizeof (struct rsdp_descriptor);
- }
- else {
+ table_length = sizeof(struct rsdp_descriptor);
+ } else {
table_length = (acpi_size) tbl_ptr->length;
}
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (ret_buffer, table_length);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_initialize_buffer(ret_buffer, table_length);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Copy the table to the buffer */
- ACPI_MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, table_length);
- return_ACPI_STATUS (AE_OK);
+ ACPI_MEMCPY((void *)ret_buffer->pointer, (void *)tbl_ptr, table_length);
+ return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_get_table);
+EXPORT_SYMBOL(acpi_get_table);
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index dc3c3f6a9f62..3b8a7e063e8a 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -46,22 +46,56 @@
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
- ACPI_MODULE_NAME ("tbxfroot")
+ACPI_MODULE_NAME("tbxfroot")
/* Local prototypes */
-
static acpi_status
-acpi_tb_find_rsdp (
- struct acpi_table_desc *table_info,
- u32 flags);
+acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags);
-static u8 *
-acpi_tb_scan_memory_for_rsdp (
- u8 *start_address,
- u32 length);
+static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_validate_rsdp
+ *
+ * PARAMETERS: Rsdp - Pointer to unvalidated RSDP
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate the RSDP (ptr)
+ *
+ ******************************************************************************/
+
+acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
+{
+ ACPI_FUNCTION_ENTRY();
+
+ /*
+ * The signature and checksum must both be correct
+ */
+ if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) {
+ /* Nope, BAD Signature */
+
+ return (AE_BAD_SIGNATURE);
+ }
+
+ /* Check the standard checksum */
+
+ if (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
+ return (AE_BAD_CHECKSUM);
+ }
+
+ /* Check extended checksum if table version >= 2 */
+
+ if ((rsdp->revision >= 2) &&
+ (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) !=
+ 0)) {
+ return (AE_BAD_CHECKSUM);
+ }
+
+ return (AE_OK);
+}
/*******************************************************************************
*
@@ -80,28 +114,24 @@ acpi_tb_scan_memory_for_rsdp (
******************************************************************************/
acpi_status
-acpi_tb_find_table (
- char *signature,
- char *oem_id,
- char *oem_table_id,
- struct acpi_table_header **table_ptr)
+acpi_tb_find_table(char *signature,
+ char *oem_id,
+ char *oem_table_id, struct acpi_table_header ** table_ptr)
{
- acpi_status status;
- struct acpi_table_header *table;
-
-
- ACPI_FUNCTION_TRACE ("tb_find_table");
+ acpi_status status;
+ struct acpi_table_header *table;
+ ACPI_FUNCTION_TRACE("tb_find_table");
/* Validate string lengths */
- if ((ACPI_STRLEN (signature) > ACPI_NAME_SIZE) ||
- (ACPI_STRLEN (oem_id) > sizeof (table->oem_id)) ||
- (ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) {
- return_ACPI_STATUS (AE_AML_STRING_LIMIT);
+ if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) ||
+ (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) ||
+ (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) {
+ return_ACPI_STATUS(AE_AML_STRING_LIMIT);
}
- if (!ACPI_STRNCMP (signature, DSDT_SIG, ACPI_NAME_SIZE)) {
+ if (!ACPI_STRNCMP(signature, DSDT_SIG, ACPI_NAME_SIZE)) {
/*
* The DSDT pointer is contained in the FADT, not the RSDT.
* This code should suffice, because the only code that would perform
@@ -110,40 +140,36 @@ acpi_tb_find_table (
* If this becomes insufficient, the FADT will have to be found first.
*/
if (!acpi_gbl_DSDT) {
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
table = acpi_gbl_DSDT;
- }
- else {
+ } else {
/* Find the table */
- status = acpi_get_firmware_table (signature, 1,
- ACPI_LOGICAL_ADDRESSING, &table);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_get_firmware_table(signature, 1,
+ ACPI_LOGICAL_ADDRESSING,
+ &table);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Check oem_id and oem_table_id */
- if ((oem_id[0] && ACPI_STRNCMP (
- oem_id, table->oem_id,
- sizeof (table->oem_id))) ||
-
- (oem_table_id[0] && ACPI_STRNCMP (
- oem_table_id, table->oem_table_id,
- sizeof (table->oem_table_id)))) {
- return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
+ if ((oem_id[0] && ACPI_STRNCMP(oem_id, table->oem_id,
+ sizeof(table->oem_id))) ||
+ (oem_table_id[0] && ACPI_STRNCMP(oem_table_id, table->oem_table_id,
+ sizeof(table->oem_table_id)))) {
+ return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
- table->signature));
+ ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n",
+ table->signature));
*table_ptr = table;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_firmware_table
@@ -164,34 +190,28 @@ acpi_tb_find_table (
******************************************************************************/
acpi_status
-acpi_get_firmware_table (
- acpi_string signature,
- u32 instance,
- u32 flags,
- struct acpi_table_header **table_pointer)
+acpi_get_firmware_table(acpi_string signature,
+ u32 instance,
+ u32 flags, struct acpi_table_header **table_pointer)
{
- acpi_status status;
- struct acpi_pointer address;
- struct acpi_table_header *header = NULL;
- struct acpi_table_desc *table_info = NULL;
- struct acpi_table_desc *rsdt_info;
- u32 table_count;
- u32 i;
- u32 j;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_firmware_table");
+ acpi_status status;
+ struct acpi_pointer address;
+ struct acpi_table_header *header = NULL;
+ struct acpi_table_desc *table_info = NULL;
+ struct acpi_table_desc *rsdt_info;
+ u32 table_count;
+ u32 i;
+ u32 j;
+ ACPI_FUNCTION_TRACE("acpi_get_firmware_table");
/*
* Ensure that at least the table manager is initialized. We don't
* require that the entire ACPI subsystem is up for this interface.
* If we have a buffer, we must have a length too
*/
- if ((instance == 0) ||
- (!signature) ||
- (!table_pointer)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if ((instance == 0) || (!signature) || (!table_pointer)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Ensure that we have a RSDP */
@@ -199,48 +219,41 @@ acpi_get_firmware_table (
if (!acpi_gbl_RSDP) {
/* Get the RSDP */
- status = acpi_os_get_root_pointer (flags, &address);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ status = acpi_os_get_root_pointer(flags, &address);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n"));
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/* Map and validate the RSDP */
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
- status = acpi_os_map_memory (address.pointer.physical,
- sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_os_map_memory(address.pointer.physical,
+ sizeof(struct
+ rsdp_descriptor),
+ (void *)&acpi_gbl_RSDP);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- }
- else {
+ } else {
acpi_gbl_RSDP = address.pointer.logical;
}
- /* The signature and checksum must both be correct */
-
- if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG,
- sizeof (RSDP_SIG)-1) != 0) {
- /* Nope, BAD Signature */
+ /* The RDSP signature and checksum must both be correct */
- return_ACPI_STATUS (AE_BAD_SIGNATURE);
- }
-
- if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
- /* Nope, BAD Checksum */
-
- return_ACPI_STATUS (AE_BAD_CHECKSUM);
+ status = acpi_tb_validate_rsdp(acpi_gbl_RSDP);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Get the RSDT address via the RSDP */
- acpi_tb_get_rsdt_address (&address);
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
- acpi_gbl_RSDP,
- ACPI_FORMAT_UINT64 (address.pointer.value)));
+ acpi_tb_get_rsdt_address(&address);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
+ acpi_gbl_RSDP,
+ ACPI_FORMAT_UINT64(address.pointer.value)));
/* Insert processor_mode flags */
@@ -248,30 +261,30 @@ acpi_get_firmware_table (
/* Get and validate the RSDT */
- rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+ rsdt_info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc));
if (!rsdt_info) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
- status = acpi_tb_get_table (&address, rsdt_info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_get_table(&address, rsdt_info);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
- status = acpi_tb_validate_rsdt (rsdt_info->pointer);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_validate_rsdt(rsdt_info->pointer);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Allocate a scratch table header and table descriptor */
- header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header));
+ header = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_header));
if (!header) {
status = AE_NO_MEMORY;
goto cleanup;
}
- table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc));
+ table_info = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_desc));
if (!table_info) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -279,7 +292,8 @@ acpi_get_firmware_table (
/* Get the number of table pointers within the RSDT */
- table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer);
+ table_count =
+ acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer);
address.pointer_type = acpi_gbl_table_flags | flags;
/*
@@ -287,35 +301,42 @@ acpi_get_firmware_table (
* requested table
*/
for (i = 0, j = 0; i < table_count; i++) {
- /* Get the next table pointer, handle RSDT vs. XSDT */
-
- if (acpi_gbl_RSDP->revision < 2) {
- address.pointer.value = (ACPI_CAST_PTR (
- RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
- }
- else {
- address.pointer.value = (ACPI_CAST_PTR (
- XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
+ /*
+ * Get the next table pointer, handle RSDT vs. XSDT
+ * RSDT pointers are 32 bits, XSDT pointers are 64 bits
+ */
+ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
+ address.pointer.value =
+ (ACPI_CAST_PTR
+ (RSDT_DESCRIPTOR,
+ rsdt_info->pointer))->table_offset_entry[i];
+ } else {
+ address.pointer.value =
+ (ACPI_CAST_PTR
+ (XSDT_DESCRIPTOR,
+ rsdt_info->pointer))->table_offset_entry[i];
}
/* Get the table header */
- status = acpi_tb_get_table_header (&address, header);
- if (ACPI_FAILURE (status)) {
+ status = acpi_tb_get_table_header(&address, header);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Compare table signatures and table instance */
- if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) {
+ if (!ACPI_STRNCMP(header->signature, signature, ACPI_NAME_SIZE)) {
/* An instance of the table was found */
j++;
if (j >= instance) {
/* Found the correct instance, get the entire table */
- status = acpi_tb_get_table_body (&address, header, table_info);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_tb_get_table_body(&address, header,
+ table_info);
+ if (ACPI_FAILURE(status)) {
goto cleanup;
}
@@ -329,22 +350,23 @@ acpi_get_firmware_table (
status = AE_NOT_EXIST;
-
-cleanup:
- acpi_os_unmap_memory (rsdt_info->pointer,
- (acpi_size) rsdt_info->pointer->length);
- ACPI_MEM_FREE (rsdt_info);
+ cleanup:
+ if (rsdt_info->pointer) {
+ acpi_os_unmap_memory(rsdt_info->pointer,
+ (acpi_size) rsdt_info->pointer->length);
+ }
+ ACPI_MEM_FREE(rsdt_info);
if (header) {
- ACPI_MEM_FREE (header);
+ ACPI_MEM_FREE(header);
}
if (table_info) {
- ACPI_MEM_FREE (table_info);
+ ACPI_MEM_FREE(table_info);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_get_firmware_table);
+EXPORT_SYMBOL(acpi_get_firmware_table);
/* TBD: Move to a new file */
@@ -363,35 +385,29 @@ EXPORT_SYMBOL(acpi_get_firmware_table);
*
******************************************************************************/
-acpi_status
-acpi_find_root_pointer (
- u32 flags,
- struct acpi_pointer *rsdp_address)
+acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address)
{
- struct acpi_table_desc table_info;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_find_root_pointer");
+ struct acpi_table_desc table_info;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_find_root_pointer");
/* Get the RSDP */
- status = acpi_tb_find_rsdp (&table_info, flags);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "RSDP structure not found, %s Flags=%X\n",
- acpi_format_exception (status), flags));
+ status = acpi_tb_find_rsdp(&table_info, flags);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "RSDP structure not found, %s Flags=%X\n",
+ acpi_format_exception(status), flags));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER;
rsdp_address->pointer.physical = table_info.physical_address;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_scan_memory_for_rsdp
@@ -405,68 +421,45 @@ acpi_find_root_pointer (
*
******************************************************************************/
-static u8 *
-acpi_tb_scan_memory_for_rsdp (
- u8 *start_address,
- u32 length)
+static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
{
- u8 *mem_rover;
- u8 *end_address;
- u8 checksum;
-
-
- ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
+ acpi_status status;
+ u8 *mem_rover;
+ u8 *end_address;
+ ACPI_FUNCTION_TRACE("tb_scan_memory_for_rsdp");
end_address = start_address + length;
/* Search from given start address for the requested length */
for (mem_rover = start_address; mem_rover < end_address;
- mem_rover += ACPI_RSDP_SCAN_STEP) {
- /* The signature and checksum must both be correct */
-
- if (ACPI_STRNCMP ((char *) mem_rover,
- RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) {
- /* No signature match, keep looking */
-
- continue;
- }
-
- /* Signature matches, check the appropriate checksum */
-
- if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
- /* ACPI version 1.0 */
-
- checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
- }
- else {
- /* Post ACPI 1.0, use extended_checksum */
-
- checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
+ mem_rover += ACPI_RSDP_SCAN_STEP) {
+ /* The RSDP signature and checksum must both be correct */
+
+ status =
+ acpi_tb_validate_rsdp(ACPI_CAST_PTR
+ (struct rsdp_descriptor, mem_rover));
+ if (ACPI_SUCCESS(status)) {
+ /* Sig and checksum valid, we have found a real RSDP */
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "RSDP located at physical address %p\n",
+ mem_rover));
+ return_PTR(mem_rover);
}
- if (checksum == 0) {
- /* Checksum valid, we have found a valid RSDP */
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "RSDP located at physical address %p\n", mem_rover));
- return_PTR (mem_rover);
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Found an RSDP at physical address %p, but it has a bad checksum\n",
- mem_rover));
+ /* No sig match or bad checksum, keep searching */
}
/* Searched entire block, no RSDP was found */
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Searched entire block, no valid RSDP was found.\n"));
- return_PTR (NULL);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Searched entire block from %p, valid RSDP was not found\n",
+ start_address));
+ return_PTR(NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_tb_find_rsdp
@@ -490,18 +483,14 @@ acpi_tb_scan_memory_for_rsdp (
******************************************************************************/
static acpi_status
-acpi_tb_find_rsdp (
- struct acpi_table_desc *table_info,
- u32 flags)
+acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags)
{
- u8 *table_ptr;
- u8 *mem_rover;
- u32 physical_address;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("tb_find_rsdp");
+ u8 *table_ptr;
+ u8 *mem_rover;
+ u32 physical_address;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("tb_find_rsdp");
/*
* Scan supports either logical addressing or physical addressing
@@ -509,23 +498,25 @@ acpi_tb_find_rsdp (
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
- status = acpi_os_map_memory (
- (acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
- ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not map memory at %8.8X for length %X\n",
- ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
-
- return_ACPI_STATUS (status);
+ status = acpi_os_map_memory((acpi_physical_address)
+ ACPI_EBDA_PTR_LOCATION,
+ ACPI_EBDA_PTR_LENGTH,
+ (void *)&table_ptr);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not map memory at %8.8X for length %X\n",
+ ACPI_EBDA_PTR_LOCATION,
+ ACPI_EBDA_PTR_LENGTH));
+
+ return_ACPI_STATUS(status);
}
- ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
+ ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
/* Convert segment part to physical address */
physical_address <<= 4;
- acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
+ acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
/* EBDA present? */
@@ -534,59 +525,67 @@ acpi_tb_find_rsdp (
* 1b) Search EBDA paragraphs (EBDa is required to be a
* minimum of 1_k length)
*/
- status = acpi_os_map_memory (
- (acpi_physical_address) physical_address,
- ACPI_EBDA_WINDOW_SIZE, (void *) &table_ptr);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not map memory at %8.8X for length %X\n",
- physical_address, ACPI_EBDA_WINDOW_SIZE));
-
- return_ACPI_STATUS (status);
+ status = acpi_os_map_memory((acpi_physical_address)
+ physical_address,
+ ACPI_EBDA_WINDOW_SIZE,
+ (void *)&table_ptr);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not map memory at %8.8X for length %X\n",
+ physical_address,
+ ACPI_EBDA_WINDOW_SIZE));
+
+ return_ACPI_STATUS(status);
}
- mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr,
- ACPI_EBDA_WINDOW_SIZE);
- acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+ mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr,
+ ACPI_EBDA_WINDOW_SIZE);
+ acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
- /* Found it, return the physical address */
+ /* Return the physical address */
- physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
+ physical_address +=
+ ACPI_PTR_DIFF(mem_rover, table_ptr);
table_info->physical_address =
- (acpi_physical_address) physical_address;
- return_ACPI_STATUS (AE_OK);
+ (acpi_physical_address) physical_address;
+ return_ACPI_STATUS(AE_OK);
}
}
/*
* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
*/
- status = acpi_os_map_memory (
- (acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
- ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr);
-
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not map memory at %8.8X for length %X\n",
- ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
-
- return_ACPI_STATUS (status);
+ status = acpi_os_map_memory((acpi_physical_address)
+ ACPI_HI_RSDP_WINDOW_BASE,
+ ACPI_HI_RSDP_WINDOW_SIZE,
+ (void *)&table_ptr);
+
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Could not map memory at %8.8X for length %X\n",
+ ACPI_HI_RSDP_WINDOW_BASE,
+ ACPI_HI_RSDP_WINDOW_SIZE));
+
+ return_ACPI_STATUS(status);
}
- mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
- acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
+ mem_rover =
+ acpi_tb_scan_memory_for_rsdp(table_ptr,
+ ACPI_HI_RSDP_WINDOW_SIZE);
+ acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
if (mem_rover) {
- /* Found it, return the physical address */
+ /* Return the physical address */
physical_address =
- ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
+ ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF(mem_rover,
+ table_ptr);
table_info->physical_address =
- (acpi_physical_address) physical_address;
- return_ACPI_STATUS (AE_OK);
+ (acpi_physical_address) physical_address;
+ return_ACPI_STATUS(AE_OK);
}
}
@@ -596,8 +595,8 @@ acpi_tb_find_rsdp (
else {
/* 1a) Get the location of the EBDA */
- ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
- physical_address <<= 4; /* Convert segment to physical address */
+ ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION);
+ physical_address <<= 4; /* Convert segment to physical address */
/* EBDA present? */
@@ -606,34 +605,38 @@ acpi_tb_find_rsdp (
* 1b) Search EBDA paragraphs (EBDa is required to be a minimum of
* 1_k length)
*/
- mem_rover = acpi_tb_scan_memory_for_rsdp (
- ACPI_PHYSADDR_TO_PTR (physical_address),
- ACPI_EBDA_WINDOW_SIZE);
+ mem_rover =
+ acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR
+ (physical_address),
+ ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
- /* Found it, return the physical address */
+ /* Return the physical address */
- table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
- return_ACPI_STATUS (AE_OK);
+ table_info->physical_address =
+ ACPI_TO_INTEGER(mem_rover);
+ return_ACPI_STATUS(AE_OK);
}
}
/* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
- mem_rover = acpi_tb_scan_memory_for_rsdp (
- ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
- ACPI_HI_RSDP_WINDOW_SIZE);
+ mem_rover =
+ acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR
+ (ACPI_HI_RSDP_WINDOW_BASE),
+ ACPI_HI_RSDP_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
- table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
- return_ACPI_STATUS (AE_OK);
+ table_info->physical_address =
+ ACPI_TO_INTEGER(mem_rover);
+ return_ACPI_STATUS(AE_OK);
}
}
- /* RSDP signature was not found */
+ /* A valid RSDP was not found */
- return_ACPI_STATUS (AE_NOT_FOUND);
+ ACPI_REPORT_ERROR(("No valid RSDP was found\n"));
+ return_ACPI_STATUS(AE_NOT_FOUND);
}
#endif
-
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 79c3a686bc44..a24847c08f7f 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -70,9 +70,9 @@
#define CELSIUS_TO_KELVIN(t) ((t+273)*10)
#define _COMPONENT ACPI_THERMAL_COMPONENT
-ACPI_MODULE_NAME ("acpi_thermal")
+ACPI_MODULE_NAME("acpi_thermal")
-MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
MODULE_LICENSE("GPL");
@@ -80,143 +80,145 @@ static int tzp;
module_param(tzp, int, 0);
MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
-
-static int acpi_thermal_add (struct acpi_device *device);
-static int acpi_thermal_remove (struct acpi_device *device, int type);
+static int acpi_thermal_add(struct acpi_device *device);
+static int acpi_thermal_remove(struct acpi_device *device, int type);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
-static ssize_t acpi_thermal_write_trip_points (struct file*,const char __user *,size_t,loff_t *);
+static ssize_t acpi_thermal_write_trip_points(struct file *,
+ const char __user *, size_t,
+ loff_t *);
static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
-static ssize_t acpi_thermal_write_cooling_mode (struct file*,const char __user *,size_t,loff_t *);
+static ssize_t acpi_thermal_write_cooling_mode(struct file *,
+ const char __user *, size_t,
+ loff_t *);
static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
-static ssize_t acpi_thermal_write_polling(struct file*,const char __user *,size_t,loff_t *);
+static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
+ size_t, loff_t *);
static struct acpi_driver acpi_thermal_driver = {
- .name = ACPI_THERMAL_DRIVER_NAME,
- .class = ACPI_THERMAL_CLASS,
- .ids = ACPI_THERMAL_HID,
- .ops = {
- .add = acpi_thermal_add,
- .remove = acpi_thermal_remove,
- },
+ .name = ACPI_THERMAL_DRIVER_NAME,
+ .class = ACPI_THERMAL_CLASS,
+ .ids = ACPI_THERMAL_HID,
+ .ops = {
+ .add = acpi_thermal_add,
+ .remove = acpi_thermal_remove,
+ },
};
struct acpi_thermal_state {
- u8 critical:1;
- u8 hot:1;
- u8 passive:1;
- u8 active:1;
- u8 reserved:4;
- int active_index;
+ u8 critical:1;
+ u8 hot:1;
+ u8 passive:1;
+ u8 active:1;
+ u8 reserved:4;
+ int active_index;
};
struct acpi_thermal_state_flags {
- u8 valid:1;
- u8 enabled:1;
- u8 reserved:6;
+ u8 valid:1;
+ u8 enabled:1;
+ u8 reserved:6;
};
struct acpi_thermal_critical {
struct acpi_thermal_state_flags flags;
- unsigned long temperature;
+ unsigned long temperature;
};
struct acpi_thermal_hot {
struct acpi_thermal_state_flags flags;
- unsigned long temperature;
+ unsigned long temperature;
};
struct acpi_thermal_passive {
struct acpi_thermal_state_flags flags;
- unsigned long temperature;
- unsigned long tc1;
- unsigned long tc2;
- unsigned long tsp;
- struct acpi_handle_list devices;
+ unsigned long temperature;
+ unsigned long tc1;
+ unsigned long tc2;
+ unsigned long tsp;
+ struct acpi_handle_list devices;
};
struct acpi_thermal_active {
struct acpi_thermal_state_flags flags;
- unsigned long temperature;
- struct acpi_handle_list devices;
+ unsigned long temperature;
+ struct acpi_handle_list devices;
};
struct acpi_thermal_trips {
struct acpi_thermal_critical critical;
- struct acpi_thermal_hot hot;
+ struct acpi_thermal_hot hot;
struct acpi_thermal_passive passive;
struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
};
struct acpi_thermal_flags {
- u8 cooling_mode:1; /* _SCP */
- u8 devices:1; /* _TZD */
- u8 reserved:6;
+ u8 cooling_mode:1; /* _SCP */
+ u8 devices:1; /* _TZD */
+ u8 reserved:6;
};
struct acpi_thermal {
- acpi_handle handle;
- acpi_bus_id name;
- unsigned long temperature;
- unsigned long last_temperature;
- unsigned long polling_frequency;
- u8 cooling_mode;
- volatile u8 zombie;
+ acpi_handle handle;
+ acpi_bus_id name;
+ unsigned long temperature;
+ unsigned long last_temperature;
+ unsigned long polling_frequency;
+ u8 cooling_mode;
+ volatile u8 zombie;
struct acpi_thermal_flags flags;
struct acpi_thermal_state state;
struct acpi_thermal_trips trips;
- struct acpi_handle_list devices;
- struct timer_list timer;
+ struct acpi_handle_list devices;
+ struct timer_list timer;
};
static struct file_operations acpi_thermal_state_fops = {
- .open = acpi_thermal_state_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_thermal_state_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static struct file_operations acpi_thermal_temp_fops = {
- .open = acpi_thermal_temp_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_thermal_temp_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static struct file_operations acpi_thermal_trip_fops = {
- .open = acpi_thermal_trip_open_fs,
- .read = seq_read,
- .write = acpi_thermal_write_trip_points,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_thermal_trip_open_fs,
+ .read = seq_read,
+ .write = acpi_thermal_write_trip_points,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static struct file_operations acpi_thermal_cooling_fops = {
- .open = acpi_thermal_cooling_open_fs,
- .read = seq_read,
- .write = acpi_thermal_write_cooling_mode,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_thermal_cooling_open_fs,
+ .read = seq_read,
+ .write = acpi_thermal_write_cooling_mode,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static struct file_operations acpi_thermal_polling_fops = {
- .open = acpi_thermal_polling_open_fs,
- .read = seq_read,
- .write = acpi_thermal_write_polling,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_thermal_polling_open_fs,
+ .read = seq_read,
+ .write = acpi_thermal_write_polling,
+ .llseek = seq_lseek,
+ .release = single_release,
};
/* --------------------------------------------------------------------------
Thermal Zone Management
-------------------------------------------------------------------------- */
-static int
-acpi_thermal_get_temperature (
- struct acpi_thermal *tz)
+static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
{
- acpi_status status = AE_OK;
+ acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature");
@@ -225,41 +227,39 @@ acpi_thermal_get_temperature (
tz->last_temperature = tz->temperature;
- status = acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature);
+ status =
+ acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", tz->temperature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
+ tz->temperature));
return_VALUE(0);
}
-
-static int
-acpi_thermal_get_polling_frequency (
- struct acpi_thermal *tz)
+static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
{
- acpi_status status = AE_OK;
+ acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency");
if (!tz)
return_VALUE(-EINVAL);
- status = acpi_evaluate_integer(tz->handle, "_TZP", NULL, &tz->polling_frequency);
+ status =
+ acpi_evaluate_integer(tz->handle, "_TZP", NULL,
+ &tz->polling_frequency);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", tz->polling_frequency));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
+ tz->polling_frequency));
return_VALUE(0);
}
-
-static int
-acpi_thermal_set_polling (
- struct acpi_thermal *tz,
- int seconds)
+static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
{
ACPI_FUNCTION_TRACE("acpi_thermal_set_polling");
@@ -268,21 +268,19 @@ acpi_thermal_set_polling (
tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency set to %lu seconds\n", tz->polling_frequency));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Polling frequency set to %lu seconds\n",
+ tz->polling_frequency));
return_VALUE(0);
}
-
-static int
-acpi_thermal_set_cooling_mode (
- struct acpi_thermal *tz,
- int mode)
+static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
{
- acpi_status status = AE_OK;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list arg_list = {1, &arg0};
- acpi_handle handle = NULL;
+ acpi_status status = AE_OK;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg0 };
+ acpi_handle handle = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode");
@@ -303,19 +301,16 @@ acpi_thermal_set_cooling_mode (
tz->cooling_mode = mode;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n",
- mode?"passive":"active"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n",
+ mode ? "passive" : "active"));
return_VALUE(0);
}
-
-static int
-acpi_thermal_get_trip_points (
- struct acpi_thermal *tz)
+static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
{
- acpi_status status = AE_OK;
- int i = 0;
+ acpi_status status = AE_OK;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points");
@@ -324,111 +319,128 @@ acpi_thermal_get_trip_points (
/* Critical Shutdown (required) */
- status = acpi_evaluate_integer(tz->handle, "_CRT", NULL,
- &tz->trips.critical.temperature);
+ status = acpi_evaluate_integer(tz->handle, "_CRT", NULL,
+ &tz->trips.critical.temperature);
if (ACPI_FAILURE(status)) {
tz->trips.critical.flags.valid = 0;
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n"));
return_VALUE(-ENODEV);
- }
- else {
+ } else {
tz->trips.critical.flags.valid = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found critical threshold [%lu]\n", tz->trips.critical.temperature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found critical threshold [%lu]\n",
+ tz->trips.critical.temperature));
}
/* Critical Sleep (optional) */
- status = acpi_evaluate_integer(tz->handle, "_HOT", NULL, &tz->trips.hot.temperature);
+ status =
+ acpi_evaluate_integer(tz->handle, "_HOT", NULL,
+ &tz->trips.hot.temperature);
if (ACPI_FAILURE(status)) {
tz->trips.hot.flags.valid = 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n"));
- }
- else {
+ } else {
tz->trips.hot.flags.valid = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", tz->trips.hot.temperature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n",
+ tz->trips.hot.temperature));
}
/* Passive: Processors (optional) */
- status = acpi_evaluate_integer(tz->handle, "_PSV", NULL, &tz->trips.passive.temperature);
+ status =
+ acpi_evaluate_integer(tz->handle, "_PSV", NULL,
+ &tz->trips.passive.temperature);
if (ACPI_FAILURE(status)) {
tz->trips.passive.flags.valid = 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
- }
- else {
+ } else {
tz->trips.passive.flags.valid = 1;
- status = acpi_evaluate_integer(tz->handle, "_TC1", NULL, &tz->trips.passive.tc1);
+ status =
+ acpi_evaluate_integer(tz->handle, "_TC1", NULL,
+ &tz->trips.passive.tc1);
if (ACPI_FAILURE(status))
tz->trips.passive.flags.valid = 0;
- status = acpi_evaluate_integer(tz->handle, "_TC2", NULL, &tz->trips.passive.tc2);
+ status =
+ acpi_evaluate_integer(tz->handle, "_TC2", NULL,
+ &tz->trips.passive.tc2);
if (ACPI_FAILURE(status))
tz->trips.passive.flags.valid = 0;
- status = acpi_evaluate_integer(tz->handle, "_TSP", NULL, &tz->trips.passive.tsp);
+ status =
+ acpi_evaluate_integer(tz->handle, "_TSP", NULL,
+ &tz->trips.passive.tsp);
if (ACPI_FAILURE(status))
tz->trips.passive.flags.valid = 0;
- status = acpi_evaluate_reference(tz->handle, "_PSL", NULL, &tz->trips.passive.devices);
+ status =
+ acpi_evaluate_reference(tz->handle, "_PSL", NULL,
+ &tz->trips.passive.devices);
if (ACPI_FAILURE(status))
tz->trips.passive.flags.valid = 0;
if (!tz->trips.passive.flags.valid)
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid passive threshold\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid passive threshold\n"));
else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found passive threshold [%lu]\n", tz->trips.passive.temperature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found passive threshold [%lu]\n",
+ tz->trips.passive.temperature));
}
/* Active: Fans, etc. (optional) */
- for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) {
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- char name[5] = {'_','A','C',('0'+i),'\0'};
+ char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
- status = acpi_evaluate_integer(tz->handle, name, NULL, &tz->trips.active[i].temperature);
+ status =
+ acpi_evaluate_integer(tz->handle, name, NULL,
+ &tz->trips.active[i].temperature);
if (ACPI_FAILURE(status))
break;
name[2] = 'L';
- status = acpi_evaluate_reference(tz->handle, name, NULL, &tz->trips.active[i].devices);
+ status =
+ acpi_evaluate_reference(tz->handle, name, NULL,
+ &tz->trips.active[i].devices);
if (ACPI_SUCCESS(status)) {
tz->trips.active[i].flags.valid = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found active threshold [%d]:[%lu]\n", i, tz->trips.active[i].temperature));
- }
- else
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid active threshold [%d]\n", i));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found active threshold [%d]:[%lu]\n",
+ i, tz->trips.active[i].temperature));
+ } else
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid active threshold [%d]\n",
+ i));
}
return_VALUE(0);
}
-
-static int
-acpi_thermal_get_devices (
- struct acpi_thermal *tz)
+static int acpi_thermal_get_devices(struct acpi_thermal *tz)
{
- acpi_status status = AE_OK;
+ acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("acpi_thermal_get_devices");
if (!tz)
return_VALUE(-EINVAL);
- status = acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices);
+ status =
+ acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
return_VALUE(0);
}
-
-static int
-acpi_thermal_call_usermode (
- char *path)
+static int acpi_thermal_call_usermode(char *path)
{
- char *argv[2] = {NULL, NULL};
- char *envp[3] = {NULL, NULL, NULL};
+ char *argv[2] = { NULL, NULL };
+ char *envp[3] = { NULL, NULL, NULL };
ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode");
@@ -440,19 +452,16 @@ acpi_thermal_call_usermode (
/* minimal command environment */
envp[0] = "HOME=/";
envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
+
call_usermodehelper(argv[0], argv, envp, 0);
return_VALUE(0);
}
-
-static int
-acpi_thermal_critical (
- struct acpi_thermal *tz)
+static int acpi_thermal_critical(struct acpi_thermal *tz)
{
- int result = 0;
- struct acpi_device *device = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_critical");
@@ -462,29 +471,28 @@ acpi_thermal_critical (
if (tz->temperature >= tz->trips.critical.temperature) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n"));
tz->trips.critical.flags.enabled = 1;
- }
- else if (tz->trips.critical.flags.enabled)
+ } else if (tz->trips.critical.flags.enabled)
tz->trips.critical.flags.enabled = 0;
result = acpi_bus_get_device(tz->handle, &device);
if (result)
return_VALUE(result);
- printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature));
- acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled);
+ printk(KERN_EMERG
+ "Critical temperature reached (%ld C), shutting down.\n",
+ KELVIN_TO_CELSIUS(tz->temperature));
+ acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL,
+ tz->trips.critical.flags.enabled);
acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF);
return_VALUE(0);
}
-
-static int
-acpi_thermal_hot (
- struct acpi_thermal *tz)
+static int acpi_thermal_hot(struct acpi_thermal *tz)
{
- int result = 0;
- struct acpi_device *device = NULL;
+ int result = 0;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_hot");
@@ -494,30 +502,27 @@ acpi_thermal_hot (
if (tz->temperature >= tz->trips.hot.temperature) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n"));
tz->trips.hot.flags.enabled = 1;
- }
- else if (tz->trips.hot.flags.enabled)
+ } else if (tz->trips.hot.flags.enabled)
tz->trips.hot.flags.enabled = 0;
result = acpi_bus_get_device(tz->handle, &device);
if (result)
return_VALUE(result);
- acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled);
+ acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT,
+ tz->trips.hot.flags.enabled);
/* TBD: Call user-mode "sleep(S4)" function */
return_VALUE(0);
}
-
-static int
-acpi_thermal_passive (
- struct acpi_thermal *tz)
+static int acpi_thermal_passive(struct acpi_thermal *tz)
{
- int result = 0;
+ int result = 0;
struct acpi_thermal_passive *passive = NULL;
- int trend = 0;
- int i = 0;
+ int trend = 0;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_passive");
@@ -534,25 +539,29 @@ acpi_thermal_passive (
* accordingly. Note that we assume symmetry.
*/
if (tz->temperature >= passive->temperature) {
- trend = (passive->tc1 * (tz->temperature - tz->last_temperature)) + (passive->tc2 * (tz->temperature - passive->temperature));
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
- trend, passive->tc1, tz->temperature,
- tz->last_temperature, passive->tc2,
- tz->temperature, passive->temperature));
+ trend =
+ (passive->tc1 * (tz->temperature - tz->last_temperature)) +
+ (passive->tc2 * (tz->temperature - passive->temperature));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
+ trend, passive->tc1, tz->temperature,
+ tz->last_temperature, passive->tc2,
+ tz->temperature, passive->temperature));
tz->trips.passive.flags.enabled = 1;
/* Heating up? */
if (trend > 0)
- for (i=0; i<passive->devices.count; i++)
- acpi_processor_set_thermal_limit(
- passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_INCREMENT);
+ for (i = 0; i < passive->devices.count; i++)
+ acpi_processor_set_thermal_limit(passive->
+ devices.
+ handles[i],
+ ACPI_PROCESSOR_LIMIT_INCREMENT);
/* Cooling off? */
else if (trend < 0)
- for (i=0; i<passive->devices.count; i++)
- acpi_processor_set_thermal_limit(
- passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT);
+ for (i = 0; i < passive->devices.count; i++)
+ acpi_processor_set_thermal_limit(passive->
+ devices.
+ handles[i],
+ ACPI_PROCESSOR_LIMIT_DECREMENT);
}
/*
@@ -563,37 +572,35 @@ acpi_thermal_passive (
* assume symmetry.
*/
else if (tz->trips.passive.flags.enabled) {
- for (i=0; i<passive->devices.count; i++)
- result = acpi_processor_set_thermal_limit(
- passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT);
+ for (i = 0; i < passive->devices.count; i++)
+ result =
+ acpi_processor_set_thermal_limit(passive->devices.
+ handles[i],
+ ACPI_PROCESSOR_LIMIT_DECREMENT);
if (result == 1) {
tz->trips.passive.flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling (zone is cool)\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Disabling passive cooling (zone is cool)\n"));
}
}
return_VALUE(0);
}
-
-static int
-acpi_thermal_active (
- struct acpi_thermal *tz)
+static int acpi_thermal_active(struct acpi_thermal *tz)
{
- int result = 0;
+ int result = 0;
struct acpi_thermal_active *active = NULL;
- int i = 0;
- int j = 0;
- unsigned long maxtemp = 0;
+ int i = 0;
+ int j = 0;
+ unsigned long maxtemp = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_active");
if (!tz)
return_VALUE(-EINVAL);
- for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) {
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
active = &(tz->trips.active[i]);
if (!active || !active->flags.valid)
@@ -607,16 +614,27 @@ acpi_thermal_active (
*/
if (tz->temperature >= active->temperature) {
if (active->temperature > maxtemp)
- tz->state.active_index = i, maxtemp = active->temperature;
+ tz->state.active_index = i, maxtemp =
+ active->temperature;
if (!active->flags.enabled) {
for (j = 0; j < active->devices.count; j++) {
- result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D0);
+ result =
+ acpi_bus_set_power(active->devices.
+ handles[j],
+ ACPI_STATE_D0);
if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'on'\n", active->devices.handles[j]));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Unable to turn cooling device [%p] 'on'\n",
+ active->
+ devices.
+ handles[j]));
continue;
}
active->flags.enabled = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'on'\n", active->devices.handles[j]));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Cooling device [%p] now 'on'\n",
+ active->devices.
+ handles[j]));
}
}
}
@@ -628,13 +646,21 @@ acpi_thermal_active (
*/
else if (active->flags.enabled) {
for (j = 0; j < active->devices.count; j++) {
- result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D3);
+ result =
+ acpi_bus_set_power(active->devices.
+ handles[j],
+ ACPI_STATE_D3);
if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'off'\n", active->devices.handles[j]));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Unable to turn cooling device [%p] 'off'\n",
+ active->devices.
+ handles[j]));
continue;
}
active->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'off'\n", active->devices.handles[j]));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Cooling device [%p] now 'off'\n",
+ active->devices.handles[j]));
}
}
}
@@ -642,28 +668,22 @@ acpi_thermal_active (
return_VALUE(0);
}
+static void acpi_thermal_check(void *context);
-static void acpi_thermal_check (void *context);
-
-static void
-acpi_thermal_run (
- unsigned long data)
+static void acpi_thermal_run(unsigned long data)
{
struct acpi_thermal *tz = (struct acpi_thermal *)data;
if (!tz->zombie)
- acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
- acpi_thermal_check, (void *) data);
+ acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+ acpi_thermal_check, (void *)data);
}
-
-static void
-acpi_thermal_check (
- void *data)
+static void acpi_thermal_check(void *data)
{
- int result = 0;
- struct acpi_thermal *tz = (struct acpi_thermal *) data;
- unsigned long sleep_time = 0;
- int i = 0;
+ int result = 0;
+ struct acpi_thermal *tz = (struct acpi_thermal *)data;
+ unsigned long sleep_time = 0;
+ int i = 0;
struct acpi_thermal_state state;
ACPI_FUNCTION_TRACE("acpi_thermal_check");
@@ -678,9 +698,9 @@ acpi_thermal_check (
result = acpi_thermal_get_temperature(tz);
if (result)
return_VOID;
-
+
memset(&tz->state, 0, sizeof(tz->state));
-
+
/*
* Check Trip Points
* -----------------
@@ -690,14 +710,18 @@ acpi_thermal_check (
* individual policy decides when it is exited (e.g. hysteresis).
*/
if (tz->trips.critical.flags.valid)
- state.critical |= (tz->temperature >= tz->trips.critical.temperature);
+ state.critical |=
+ (tz->temperature >= tz->trips.critical.temperature);
if (tz->trips.hot.flags.valid)
state.hot |= (tz->temperature >= tz->trips.hot.temperature);
if (tz->trips.passive.flags.valid)
- state.passive |= (tz->temperature >= tz->trips.passive.temperature);
- for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++)
+ state.passive |=
+ (tz->temperature >= tz->trips.passive.temperature);
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
if (tz->trips.active[i].flags.valid)
- state.active |= (tz->temperature >= tz->trips.active[i].temperature);
+ state.active |=
+ (tz->temperature >=
+ tz->trips.active[i].temperature);
/*
* Invoke Policy
@@ -726,7 +750,7 @@ acpi_thermal_check (
tz->state.hot = 1;
if (tz->trips.passive.flags.enabled)
tz->state.passive = 1;
- for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++)
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
if (tz->trips.active[i].flags.enabled)
tz->state.active = 1;
@@ -744,8 +768,8 @@ acpi_thermal_check (
else if (tz->polling_frequency > 0)
sleep_time = tz->polling_frequency * 100;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
- tz->name, tz->temperature, sleep_time));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
+ tz->name, tz->temperature, sleep_time));
/*
* Schedule Next Poll
@@ -754,12 +778,11 @@ acpi_thermal_check (
if (!sleep_time) {
if (timer_pending(&(tz->timer)))
del_timer(&(tz->timer));
- }
- else {
+ } else {
if (timer_pending(&(tz->timer)))
mod_timer(&(tz->timer), (HZ * sleep_time) / 1000);
else {
- tz->timer.data = (unsigned long) tz;
+ tz->timer.data = (unsigned long)tz;
tz->timer.function = acpi_thermal_run;
tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
add_timer(&(tz->timer));
@@ -769,16 +792,15 @@ acpi_thermal_check (
return_VOID;
}
-
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_thermal_dir;
+static struct proc_dir_entry *acpi_thermal_dir;
static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+ struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
ACPI_FUNCTION_TRACE("acpi_thermal_state_seq_show");
@@ -787,7 +809,8 @@ static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
seq_puts(seq, "state: ");
- if (!tz->state.critical && !tz->state.hot && !tz->state.passive && !tz->state.active)
+ if (!tz->state.critical && !tz->state.hot && !tz->state.passive
+ && !tz->state.active)
seq_puts(seq, "ok\n");
else {
if (tz->state.critical)
@@ -801,7 +824,7 @@ static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
seq_puts(seq, "\n");
}
-end:
+ end:
return_VALUE(0);
}
@@ -810,11 +833,10 @@ static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
}
-
static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
{
- int result = 0;
- struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+ int result = 0;
+ struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
ACPI_FUNCTION_TRACE("acpi_thermal_temp_seq_show");
@@ -825,10 +847,10 @@ static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
if (result)
goto end;
- seq_printf(seq, "temperature: %ld C\n",
- KELVIN_TO_CELSIUS(tz->temperature));
+ seq_printf(seq, "temperature: %ld C\n",
+ KELVIN_TO_CELSIUS(tz->temperature));
-end:
+ end:
return_VALUE(0);
}
@@ -837,12 +859,11 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
}
-
static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
- int i = 0;
- int j = 0;
+ struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+ int i = 0;
+ int j = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_trip_seq_show");
@@ -851,21 +872,22 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
if (tz->trips.critical.flags.valid)
seq_printf(seq, "critical (S5): %ld C\n",
- KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
+ KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
if (tz->trips.hot.flags.valid)
seq_printf(seq, "hot (S4): %ld C\n",
- KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
+ KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
if (tz->trips.passive.flags.valid) {
- seq_printf(seq, "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
- KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
- tz->trips.passive.tc1,
- tz->trips.passive.tc2,
- tz->trips.passive.tsp);
- for (j=0; j<tz->trips.passive.devices.count; j++) {
-
- seq_printf(seq, "0x%p ", tz->trips.passive.devices.handles[j]);
+ seq_printf(seq,
+ "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
+ KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
+ tz->trips.passive.tc1, tz->trips.passive.tc2,
+ tz->trips.passive.tsp);
+ for (j = 0; j < tz->trips.passive.devices.count; j++) {
+
+ seq_printf(seq, "0x%p ",
+ tz->trips.passive.devices.handles[j]);
}
seq_puts(seq, "\n");
}
@@ -874,14 +896,15 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
if (!(tz->trips.active[i].flags.valid))
break;
seq_printf(seq, "active[%d]: %ld C: devices=",
- i, KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
- for (j = 0; j < tz->trips.active[i].devices.count; j++)
+ i,
+ KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
+ for (j = 0; j < tz->trips.active[i].devices.count; j++)
seq_printf(seq, "0x%p ",
- tz->trips.active[i].devices.handles[j]);
+ tz->trips.active[i].devices.handles[j]);
seq_puts(seq, "\n");
}
-end:
+ end:
return_VALUE(0);
}
@@ -891,30 +914,28 @@ static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
}
static ssize_t
-acpi_thermal_write_trip_points (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_thermal_write_trip_points(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
- char *limit_string;
- int num, critical, hot, passive;
- int *active;
- int i = 0;
+ char *limit_string;
+ int num, critical, hot, passive;
+ int *active;
+ int i = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
- if(!limit_string)
+ if (!limit_string)
return_VALUE(-ENOMEM);
memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
- active = kmalloc(ACPI_THERMAL_MAX_ACTIVE *sizeof(int), GFP_KERNEL);
- if(!active)
+ active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL);
+ if (!active)
return_VALUE(-ENOMEM);
if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) {
@@ -922,20 +943,21 @@ acpi_thermal_write_trip_points (
count = -EINVAL;
goto end;
}
-
+
if (copy_from_user(limit_string, buffer, count)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
count = -EFAULT;
goto end;
}
-
+
limit_string[count] = '\0';
num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
- &critical, &hot, &passive,
- &active[0], &active[1], &active[2], &active[3], &active[4],
- &active[5], &active[6], &active[7], &active[8], &active[9]);
- if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
+ &critical, &hot, &passive,
+ &active[0], &active[1], &active[2], &active[3], &active[4],
+ &active[5], &active[6], &active[7], &active[8],
+ &active[9]);
+ if (!(num >= 5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
count = -EINVAL;
goto end;
@@ -949,17 +971,16 @@ acpi_thermal_write_trip_points (
break;
tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
}
-
-end:
+
+ end:
kfree(active);
kfree(limit_string);
return_VALUE(count);
}
-
static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+ struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
ACPI_FUNCTION_TRACE("acpi_thermal_cooling_seq_show");
@@ -970,33 +991,31 @@ static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
seq_puts(seq, "<setting not supported>\n");
}
- if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL )
+ if (tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL)
seq_printf(seq, "cooling mode: critical\n");
else
seq_printf(seq, "cooling mode: %s\n",
- tz->cooling_mode?"passive":"active");
+ tz->cooling_mode ? "passive" : "active");
-end:
+ end:
return_VALUE(0);
}
static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_thermal_cooling_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
static ssize_t
-acpi_thermal_write_cooling_mode (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_thermal_write_cooling_mode(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
- int result = 0;
- char mode_string[12] = {'\0'};
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
+ int result = 0;
+ char mode_string[12] = { '\0' };
ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode");
@@ -1008,11 +1027,12 @@ acpi_thermal_write_cooling_mode (
if (copy_from_user(mode_string, buffer, count))
return_VALUE(-EFAULT);
-
+
mode_string[count] = '\0';
-
- result = acpi_thermal_set_cooling_mode(tz,
- simple_strtoul(mode_string, NULL, 0));
+
+ result = acpi_thermal_set_cooling_mode(tz,
+ simple_strtoul(mode_string, NULL,
+ 0));
if (result)
return_VALUE(result);
@@ -1021,10 +1041,9 @@ acpi_thermal_write_cooling_mode (
return_VALUE(count);
}
-
static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+ struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
ACPI_FUNCTION_TRACE("acpi_thermal_polling_seq_show");
@@ -1037,43 +1056,41 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "polling frequency: %lu seconds\n",
- (tz->polling_frequency / 10));
+ (tz->polling_frequency / 10));
-end:
+ end:
return_VALUE(0);
}
static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_thermal_polling_seq_show,
- PDE(inode)->data);
+ PDE(inode)->data);
}
static ssize_t
-acpi_thermal_write_polling (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *ppos)
+acpi_thermal_write_polling(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
- struct seq_file *m = (struct seq_file *)file->private_data;
- struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
- int result = 0;
- char polling_string[12] = {'\0'};
- int seconds = 0;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
+ int result = 0;
+ char polling_string[12] = { '\0' };
+ int seconds = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_write_polling");
if (!tz || (count > sizeof(polling_string) - 1))
return_VALUE(-EINVAL);
-
+
if (copy_from_user(polling_string, buffer, count))
return_VALUE(-EFAULT);
-
+
polling_string[count] = '\0';
seconds = simple_strtoul(polling_string, NULL, 0);
-
+
result = acpi_thermal_set_polling(tz, seconds);
if (result)
return_VALUE(result);
@@ -1083,18 +1100,15 @@ acpi_thermal_write_polling (
return_VALUE(count);
}
-
-static int
-acpi_thermal_add_fs (
- struct acpi_device *device)
+static int acpi_thermal_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_add_fs");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_thermal_dir);
+ acpi_thermal_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
acpi_device_dir(device)->owner = THIS_MODULE;
@@ -1102,11 +1116,11 @@ acpi_thermal_add_fs (
/* 'state' [R] */
entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_THERMAL_FILE_STATE));
+ "Unable to create '%s' fs entry\n",
+ ACPI_THERMAL_FILE_STATE));
else {
entry->proc_fops = &acpi_thermal_state_fops;
entry->data = acpi_driver_data(device);
@@ -1115,11 +1129,11 @@ acpi_thermal_add_fs (
/* 'temperature' [R] */
entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
- S_IRUGO, acpi_device_dir(device));
+ S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_THERMAL_FILE_TEMPERATURE));
+ "Unable to create '%s' fs entry\n",
+ ACPI_THERMAL_FILE_TEMPERATURE));
else {
entry->proc_fops = &acpi_thermal_temp_fops;
entry->data = acpi_driver_data(device);
@@ -1128,11 +1142,12 @@ acpi_thermal_add_fs (
/* 'trip_points' [R/W] */
entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_THERMAL_FILE_TRIP_POINTS));
+ "Unable to create '%s' fs entry\n",
+ ACPI_THERMAL_FILE_TRIP_POINTS));
else {
entry->proc_fops = &acpi_thermal_trip_fops;
entry->data = acpi_driver_data(device);
@@ -1141,11 +1156,12 @@ acpi_thermal_add_fs (
/* 'cooling_mode' [R/W] */
entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_THERMAL_FILE_COOLING_MODE));
+ "Unable to create '%s' fs entry\n",
+ ACPI_THERMAL_FILE_COOLING_MODE));
else {
entry->proc_fops = &acpi_thermal_cooling_fops;
entry->data = acpi_driver_data(device);
@@ -1154,11 +1170,12 @@ acpi_thermal_add_fs (
/* 'polling_frequency' [R/W] */
entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_THERMAL_FILE_POLLING_FREQ));
+ "Unable to create '%s' fs entry\n",
+ ACPI_THERMAL_FILE_POLLING_FREQ));
else {
entry->proc_fops = &acpi_thermal_polling_fops;
entry->data = acpi_driver_data(device);
@@ -1168,10 +1185,7 @@ acpi_thermal_add_fs (
return_VALUE(0);
}
-
-static int
-acpi_thermal_remove_fs (
- struct acpi_device *device)
+static int acpi_thermal_remove_fs(struct acpi_device *device)
{
ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs");
@@ -1193,19 +1207,14 @@ acpi_thermal_remove_fs (
return_VALUE(0);
}
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static void
-acpi_thermal_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_thermal *tz = (struct acpi_thermal *) data;
- struct acpi_device *device = NULL;
+ struct acpi_thermal *tz = (struct acpi_thermal *)data;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_notify");
@@ -1231,19 +1240,16 @@ acpi_thermal_notify (
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-
-static int
-acpi_thermal_get_info (
- struct acpi_thermal *tz)
+static int acpi_thermal_get_info(struct acpi_thermal *tz)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_get_info");
@@ -1262,20 +1268,24 @@ acpi_thermal_get_info (
/* Set the cooling mode [_SCP] to active cooling (default) */
result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
- if (!result)
+ if (!result)
tz->flags.cooling_mode = 1;
- else {
+ else {
/* Oh,we have not _SCP method.
- Generally show cooling_mode by _ACx, _PSV,spec 12.2*/
+ Generally show cooling_mode by _ACx, _PSV,spec 12.2 */
tz->flags.cooling_mode = 0;
- if ( tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) {
- if ( tz->trips.passive.temperature > tz->trips.active[0].temperature )
+ if (tz->trips.active[0].flags.valid
+ && tz->trips.passive.flags.valid) {
+ if (tz->trips.passive.temperature >
+ tz->trips.active[0].temperature)
tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
- else
+ else
tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
- } else if ( !tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) {
+ } else if (!tz->trips.active[0].flags.valid
+ && tz->trips.passive.flags.valid) {
tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
- } else if ( tz->trips.active[0].flags.valid && !tz->trips.passive.flags.valid ) {
+ } else if (tz->trips.active[0].flags.valid
+ && !tz->trips.passive.flags.valid) {
tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
} else {
/* _ACx and _PSV are optional, but _CRT is required */
@@ -1297,14 +1307,11 @@ acpi_thermal_get_info (
return_VALUE(0);
}
-
-static int
-acpi_thermal_add (
- struct acpi_device *device)
+static int acpi_thermal_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_thermal *tz = NULL;
+ int result = 0;
+ acpi_status status = AE_OK;
+ struct acpi_thermal *tz = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_add");
@@ -1335,19 +1342,20 @@ acpi_thermal_add (
acpi_thermal_check(tz);
status = acpi_install_notify_handler(tz->handle,
- ACPI_DEVICE_NOTIFY, acpi_thermal_notify, tz);
+ ACPI_DEVICE_NOTIFY,
+ acpi_thermal_notify, tz);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
result = -ENODEV;
goto end;
}
printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
- acpi_device_name(device), acpi_device_bid(device),
- KELVIN_TO_CELSIUS(tz->temperature));
+ acpi_device_name(device), acpi_device_bid(device),
+ KELVIN_TO_CELSIUS(tz->temperature));
-end:
+ end:
if (result) {
acpi_thermal_remove_fs(device);
kfree(tz);
@@ -1356,21 +1364,17 @@ end:
return_VALUE(result);
}
-
-static int
-acpi_thermal_remove (
- struct acpi_device *device,
- int type)
+static int acpi_thermal_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
- struct acpi_thermal *tz = NULL;
+ acpi_status status = AE_OK;
+ struct acpi_thermal *tz = NULL;
ACPI_FUNCTION_TRACE("acpi_thermal_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- tz = (struct acpi_thermal *) acpi_driver_data(device);
+ tz = (struct acpi_thermal *)acpi_driver_data(device);
/* avoid timer adding new defer task */
tz->zombie = 1;
@@ -1382,19 +1386,19 @@ acpi_thermal_remove (
del_timer_sync(&(tz->timer));
status = acpi_remove_notify_handler(tz->handle,
- ACPI_DEVICE_NOTIFY, acpi_thermal_notify);
+ ACPI_DEVICE_NOTIFY,
+ acpi_thermal_notify);
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
/* Terminate policy */
- if (tz->trips.passive.flags.valid
- && tz->trips.passive.flags.enabled) {
+ if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
tz->trips.passive.flags.enabled = 0;
acpi_thermal_passive(tz);
}
if (tz->trips.active[0].flags.valid
- && tz->trips.active[0].flags.enabled) {
+ && tz->trips.active[0].flags.enabled) {
tz->trips.active[0].flags.enabled = 0;
acpi_thermal_active(tz);
}
@@ -1405,11 +1409,9 @@ acpi_thermal_remove (
return_VALUE(0);
}
-
-static int __init
-acpi_thermal_init (void)
+static int __init acpi_thermal_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_init");
@@ -1427,9 +1429,7 @@ acpi_thermal_init (void)
return_VALUE(0);
}
-
-static void __exit
-acpi_thermal_exit (void)
+static void __exit acpi_thermal_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_thermal_exit");
@@ -1440,6 +1440,5 @@ acpi_thermal_exit (void)
return_VOID;
}
-
module_init(acpi_thermal_init);
module_exit(acpi_thermal_exit);
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 73b1d8aeae9d..7fe0b7ae9733 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -100,8 +100,7 @@ MODULE_LICENSE("GPL");
/* utility
*/
-static __inline__ void
-_set_bit(u32* word, u32 mask, int value)
+static __inline__ void _set_bit(u32 * word, u32 mask, int value)
{
*word = (*word & ~mask) | (mask * value);
}
@@ -109,35 +108,32 @@ _set_bit(u32* word, u32 mask, int value)
/* acpi interface wrappers
*/
-static int
-is_valid_acpi_path(const char* methodName)
+static int is_valid_acpi_path(const char *methodName)
{
acpi_handle handle;
acpi_status status;
- status = acpi_get_handle(NULL, (char*)methodName, &handle);
+ status = acpi_get_handle(NULL, (char *)methodName, &handle);
return !ACPI_FAILURE(status);
}
-static int
-write_acpi_int(const char* methodName, int val)
+static int write_acpi_int(const char *methodName, int val)
{
struct acpi_object_list params;
union acpi_object in_objs[1];
acpi_status status;
- params.count = sizeof(in_objs)/sizeof(in_objs[0]);
+ params.count = sizeof(in_objs) / sizeof(in_objs[0]);
params.pointer = in_objs;
in_objs[0].type = ACPI_TYPE_INTEGER;
in_objs[0].integer.value = val;
- status = acpi_evaluate_object(NULL, (char*)methodName, &params, NULL);
+ status = acpi_evaluate_object(NULL, (char *)methodName, &params, NULL);
return (status == AE_OK);
}
#if 0
-static int
-read_acpi_int(const char* methodName, int* pVal)
+static int read_acpi_int(const char *methodName, int *pVal)
{
struct acpi_buffer results;
union acpi_object out_objs[1];
@@ -146,25 +142,24 @@ read_acpi_int(const char* methodName, int* pVal)
results.length = sizeof(out_objs);
results.pointer = out_objs;
- status = acpi_evaluate_object(0, (char*)methodName, 0, &results);
+ status = acpi_evaluate_object(0, (char *)methodName, 0, &results);
*pVal = out_objs[0].integer.value;
return (status == AE_OK) && (out_objs[0].type == ACPI_TYPE_INTEGER);
}
#endif
-static const char* method_hci /*= 0*/;
+static const char *method_hci /*= 0*/ ;
/* Perform a raw HCI call. Here we don't care about input or output buffer
* format.
*/
-static acpi_status
-hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
+static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
{
struct acpi_object_list params;
union acpi_object in_objs[HCI_WORDS];
struct acpi_buffer results;
- union acpi_object out_objs[HCI_WORDS+1];
+ union acpi_object out_objs[HCI_WORDS + 1];
acpi_status status;
int i;
@@ -178,8 +173,8 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
results.length = sizeof(out_objs);
results.pointer = out_objs;
- status = acpi_evaluate_object(NULL, (char*)method_hci, &params,
- &results);
+ status = acpi_evaluate_object(NULL, (char *)method_hci, &params,
+ &results);
if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
for (i = 0; i < out_objs->package.count; ++i) {
out[i] = out_objs->package.elements[i].integer.value;
@@ -195,8 +190,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
* may be useful (such as "not supported").
*/
-static acpi_status
-hci_write1(u32 reg, u32 in1, u32* result)
+static acpi_status hci_write1(u32 reg, u32 in1, u32 * result)
{
u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 };
u32 out[HCI_WORDS];
@@ -205,8 +199,7 @@ hci_write1(u32 reg, u32 in1, u32* result)
return status;
}
-static acpi_status
-hci_read1(u32 reg, u32* out1, u32* result)
+static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
{
u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 };
u32 out[HCI_WORDS];
@@ -216,26 +209,25 @@ hci_read1(u32 reg, u32* out1, u32* result)
return status;
}
-static struct proc_dir_entry* toshiba_proc_dir /*= 0*/;
-static int force_fan;
-static int last_key_event;
-static int key_event_valid;
+static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
+static int force_fan;
+static int last_key_event;
+static int key_event_valid;
-typedef struct _ProcItem
-{
- const char* name;
- char* (*read_func)(char*);
- unsigned long (*write_func)(const char*, unsigned long);
+typedef struct _ProcItem {
+ const char *name;
+ char *(*read_func) (char *);
+ unsigned long (*write_func) (const char *, unsigned long);
} ProcItem;
/* proc file handlers
*/
static int
-dispatch_read(char* page, char** start, off_t off, int count, int* eof,
- ProcItem* item)
+dispatch_read(char *page, char **start, off_t off, int count, int *eof,
+ ProcItem * item)
{
- char* p = page;
+ char *p = page;
int len;
if (off == 0)
@@ -243,33 +235,35 @@ dispatch_read(char* page, char** start, off_t off, int count, int* eof,
/* ISSUE: I don't understand this code */
len = (p - page);
- if (len <= off+count) *eof = 1;
+ if (len <= off + count)
+ *eof = 1;
*start = page + off;
len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
return len;
}
static int
-dispatch_write(struct file* file, const char __user * buffer,
- unsigned long count, ProcItem* item)
+dispatch_write(struct file *file, const char __user * buffer,
+ unsigned long count, ProcItem * item)
{
int result;
- char* tmp_buffer;
+ char *tmp_buffer;
/* Arg buffer points to userspace memory, which can't be accessed
* directly. Since we're making a copy, zero-terminate the
* destination so that sscanf can be used on it safely.
*/
tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
- if(!tmp_buffer)
+ if (!tmp_buffer)
return -ENOMEM;
if (copy_from_user(tmp_buffer, buffer, count)) {
result = -EFAULT;
- }
- else {
+ } else {
tmp_buffer[count] = 0;
result = item->write_func(tmp_buffer, count);
}
@@ -277,8 +271,7 @@ dispatch_write(struct file* file, const char __user * buffer,
return result;
}
-static char*
-read_lcd(char* p)
+static char *read_lcd(char *p)
{
u32 hci_result;
u32 value;
@@ -288,7 +281,7 @@ read_lcd(char* p)
value = value >> HCI_LCD_BRIGHTNESS_SHIFT;
p += sprintf(p, "brightness: %d\n", value);
p += sprintf(p, "brightness_levels: %d\n",
- HCI_LCD_BRIGHTNESS_LEVELS);
+ HCI_LCD_BRIGHTNESS_LEVELS);
} else {
printk(MY_ERR "Error reading LCD brightness\n");
}
@@ -296,14 +289,13 @@ read_lcd(char* p)
return p;
}
-static unsigned long
-write_lcd(const char* buffer, unsigned long count)
+static unsigned long write_lcd(const char *buffer, unsigned long count)
{
int value;
u32 hci_result;
if (sscanf(buffer, " brightness : %i", &value) == 1 &&
- value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
+ value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
value = value << HCI_LCD_BRIGHTNESS_SHIFT;
hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
if (hci_result != HCI_SUCCESS)
@@ -315,8 +307,7 @@ write_lcd(const char* buffer, unsigned long count)
return count;
}
-static char*
-read_video(char* p)
+static char *read_video(char *p)
{
u32 hci_result;
u32 value;
@@ -325,7 +316,7 @@ read_video(char* p)
if (hci_result == HCI_SUCCESS) {
int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
- int is_tv = (value & HCI_VIDEO_OUT_TV ) ? 1 : 0;
+ int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
p += sprintf(p, "lcd_out: %d\n", is_lcd);
p += sprintf(p, "crt_out: %d\n", is_crt);
p += sprintf(p, "tv_out: %d\n", is_tv);
@@ -336,8 +327,7 @@ read_video(char* p)
return p;
}
-static unsigned long
-write_video(const char* buffer, unsigned long count)
+static unsigned long write_video(const char *buffer, unsigned long count)
{
int value;
int remain = count;
@@ -363,7 +353,7 @@ write_video(const char* buffer, unsigned long count)
++buffer;
--remain;
}
- while (remain && *(buffer-1) != ';');
+ while (remain && *(buffer - 1) != ';');
}
hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
@@ -386,8 +376,7 @@ write_video(const char* buffer, unsigned long count)
return count;
}
-static char*
-read_fan(char* p)
+static char *read_fan(char *p)
{
u32 hci_result;
u32 value;
@@ -403,14 +392,13 @@ read_fan(char* p)
return p;
}
-static unsigned long
-write_fan(const char* buffer, unsigned long count)
+static unsigned long write_fan(const char *buffer, unsigned long count)
{
int value;
u32 hci_result;
if (sscanf(buffer, " force_on : %i", &value) == 1 &&
- value >= 0 && value <= 1) {
+ value >= 0 && value <= 1) {
hci_write1(HCI_FAN, value, &hci_result);
if (hci_result != HCI_SUCCESS)
return -EFAULT;
@@ -423,8 +411,7 @@ write_fan(const char* buffer, unsigned long count)
return count;
}
-static char*
-read_keys(char* p)
+static char *read_keys(char *p)
{
u32 hci_result;
u32 value;
@@ -451,17 +438,15 @@ read_keys(char* p)
p += sprintf(p, "hotkey_ready: %d\n", key_event_valid);
p += sprintf(p, "hotkey: 0x%04x\n", last_key_event);
-end:
+ end:
return p;
}
-static unsigned long
-write_keys(const char* buffer, unsigned long count)
+static unsigned long write_keys(const char *buffer, unsigned long count)
{
int value;
- if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 &&
- value == 0) {
+ if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) {
key_event_valid = 0;
} else {
return -EINVAL;
@@ -470,12 +455,11 @@ write_keys(const char* buffer, unsigned long count)
return count;
}
-static char*
-read_version(char* p)
+static char *read_version(char *p)
{
p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION);
p += sprintf(p, "proc_interface: %d\n",
- PROC_INTERFACE_VERSION);
+ PROC_INTERFACE_VERSION);
return p;
}
@@ -484,48 +468,45 @@ read_version(char* p)
#define PROC_TOSHIBA "toshiba"
-static ProcItem proc_items[] =
-{
- { "lcd" , read_lcd , write_lcd },
- { "video" , read_video , write_video },
- { "fan" , read_fan , write_fan },
- { "keys" , read_keys , write_keys },
- { "version" , read_version , NULL },
- { NULL }
+static ProcItem proc_items[] = {
+ {"lcd", read_lcd, write_lcd},
+ {"video", read_video, write_video},
+ {"fan", read_fan, write_fan},
+ {"keys", read_keys, write_keys},
+ {"version", read_version, NULL},
+ {NULL}
};
-static acpi_status __init
-add_device(void)
+static acpi_status __init add_device(void)
{
- struct proc_dir_entry* proc;
- ProcItem* item;
+ struct proc_dir_entry *proc;
+ ProcItem *item;
- for (item = proc_items; item->name; ++item)
- {
+ for (item = proc_items; item->name; ++item) {
proc = create_proc_read_entry(item->name,
- S_IFREG | S_IRUGO | S_IWUSR,
- toshiba_proc_dir, (read_proc_t*)dispatch_read, item);
+ S_IFREG | S_IRUGO | S_IWUSR,
+ toshiba_proc_dir,
+ (read_proc_t *) dispatch_read,
+ item);
if (proc)
proc->owner = THIS_MODULE;
if (proc && item->write_func)
- proc->write_proc = (write_proc_t*)dispatch_write;
+ proc->write_proc = (write_proc_t *) dispatch_write;
}
return AE_OK;
}
-static acpi_status __exit
-remove_device(void)
+static acpi_status __exit remove_device(void)
{
- ProcItem* item;
+ ProcItem *item;
for (item = proc_items; item->name; ++item)
remove_proc_entry(item->name, toshiba_proc_dir);
return AE_OK;
}
-static int __init
-toshiba_acpi_init(void)
+static int __init toshiba_acpi_init(void)
{
acpi_status status = AE_OK;
u32 hci_result;
@@ -533,9 +514,9 @@ toshiba_acpi_init(void)
if (acpi_disabled)
return -ENODEV;
- if (!acpi_specific_hotkey_enabled){
+ if (!acpi_specific_hotkey_enabled) {
printk(MY_INFO "Using generic hotkey driver\n");
- return -ENODEV;
+ return -ENODEV;
}
/* simple device detection: look for HCI method */
if (is_valid_acpi_path(METHOD_HCI_1))
@@ -546,7 +527,7 @@ toshiba_acpi_init(void)
return -ENODEV;
printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
- TOSHIBA_ACPI_VERSION);
+ TOSHIBA_ACPI_VERSION);
printk(MY_INFO " HCI method: %s\n", method_hci);
force_fan = 0;
@@ -568,8 +549,7 @@ toshiba_acpi_init(void)
return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
}
-static void __exit
-toshiba_acpi_exit(void)
+static void __exit toshiba_acpi_exit(void)
{
remove_device();
diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile
index 939c447dd52a..e87108b7338a 100644
--- a/drivers/acpi/utilities/Makefile
+++ b/drivers/acpi/utilities/Makefile
@@ -3,6 +3,6 @@
#
obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
- utcopy.o utdelete.o utglobal.o utmath.o utobject.o
+ utcopy.o utdelete.o utglobal.o utmath.o utobject.o utstate.o utmutex.o utobject.o utcache.o
EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index c4e7f989a2bd..068450b36475 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Module Name: utalloc - local cache and memory allocation routines
+ * Module Name: utalloc - local memory allocation routines
*
*****************************************************************************/
@@ -41,232 +41,134 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utalloc")
+ACPI_MODULE_NAME("utalloc")
/* Local prototypes */
-
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-static struct acpi_debug_mem_block *
-acpi_ut_find_allocation (
- u32 list_id,
- void *allocation);
+static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation);
static acpi_status
-acpi_ut_track_allocation (
- u32 list_id,
- struct acpi_debug_mem_block *address,
- acpi_size size,
- u8 alloc_type,
- u32 component,
- char *module,
- u32 line);
+acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
+ acpi_size size,
+ u8 alloc_type, u32 component, char *module, u32 line);
static acpi_status
-acpi_ut_remove_allocation (
- u32 list_id,
- struct acpi_debug_mem_block *address,
- u32 component,
- char *module,
- u32 line);
-#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
+ u32 component, char *module, u32 line);
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+static acpi_status
+acpi_ut_create_list(char *list_name,
+ u16 object_size, struct acpi_memory_list **return_cache);
+#endif
/*******************************************************************************
*
- * FUNCTION: acpi_ut_release_to_cache
+ * FUNCTION: acpi_ut_create_caches
*
- * PARAMETERS: list_id - Memory list/cache ID
- * Object - The object to be released
+ * PARAMETERS: None
*
- * RETURN: None
+ * RETURN: Status
*
- * DESCRIPTION: Release an object to the specified cache. If cache is full,
- * the object is deleted.
+ * DESCRIPTION: Create all local caches
*
******************************************************************************/
-void
-acpi_ut_release_to_cache (
- u32 list_id,
- void *object)
+acpi_status acpi_ut_create_caches(void)
{
- struct acpi_memory_list *cache_info;
-
+ acpi_status status;
- ACPI_FUNCTION_ENTRY ();
-
-
- cache_info = &acpi_gbl_memory_lists[list_id];
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- /* If walk cache is full, just free this wallkstate object */
+ /* Memory allocation lists */
- if (cache_info->cache_depth >= cache_info->max_cache_depth) {
- ACPI_MEM_FREE (object);
- ACPI_MEM_TRACKING (cache_info->total_freed++);
+ status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
+ if (ACPI_FAILURE(status)) {
+ return (status);
}
- /* Otherwise put this object back into the cache */
-
- else {
- if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
- return;
- }
-
- /* Mark the object as cached */
-
- ACPI_MEMSET (object, 0xCA, cache_info->object_size);
- ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED);
-
- /* Put the object at the head of the cache list */
-
- * (ACPI_CAST_INDIRECT_PTR (char,
- &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
- cache_info->list_head = object;
- cache_info->cache_depth++;
-
- (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
+ status =
+ acpi_ut_create_list("Acpi-Namespace",
+ sizeof(struct acpi_namespace_node),
+ &acpi_gbl_ns_node_list);
+ if (ACPI_FAILURE(status)) {
+ return (status);
}
-
-#else
-
- /* Object cache is disabled; just free the object */
-
- ACPI_MEM_FREE (object);
- ACPI_MEM_TRACKING (cache_info->total_freed++);
#endif
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_acquire_from_cache
- *
- * PARAMETERS: list_id - Memory list ID
- *
- * RETURN: A requested object. NULL if the object could not be
- * allocated.
- *
- * DESCRIPTION: Get an object from the specified cache. If cache is empty,
- * the object is allocated.
- *
- ******************************************************************************/
-
-void *
-acpi_ut_acquire_from_cache (
- u32 list_id)
-{
- struct acpi_memory_list *cache_info;
- void *object;
+ /* Object Caches, for frequently used objects */
- ACPI_FUNCTION_NAME ("ut_acquire_from_cache");
-
-
- cache_info = &acpi_gbl_memory_lists[list_id];
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-
- if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
- return (NULL);
+ status =
+ acpi_os_create_cache("acpi_state", sizeof(union acpi_generic_state),
+ ACPI_MAX_STATE_CACHE_DEPTH,
+ &acpi_gbl_state_cache);
+ if (ACPI_FAILURE(status)) {
+ return (status);
}
- ACPI_MEM_TRACKING (cache_info->cache_requests++);
-
- /* Check the cache first */
-
- if (cache_info->list_head) {
- /* There is an object available, use it */
-
- object = cache_info->list_head;
- cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char,
- &(((char *) object)[cache_info->link_offset])));
-
- ACPI_MEM_TRACKING (cache_info->cache_hits++);
- cache_info->cache_depth--;
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n",
- object, acpi_gbl_memory_lists[list_id].list_name));
-#endif
-
- if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
- return (NULL);
- }
-
- /* Clear (zero) the previously used Object */
-
- ACPI_MEMSET (object, 0, cache_info->object_size);
+ status =
+ acpi_os_create_cache("acpi_parse",
+ sizeof(struct acpi_parse_obj_common),
+ ACPI_MAX_PARSE_CACHE_DEPTH,
+ &acpi_gbl_ps_node_cache);
+ if (ACPI_FAILURE(status)) {
+ return (status);
}
- else {
- /* The cache is empty, create a new object */
-
- /* Avoid deadlock with ACPI_MEM_CALLOCATE */
-
- if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
- return (NULL);
- }
-
- object = ACPI_MEM_CALLOCATE (cache_info->object_size);
- ACPI_MEM_TRACKING (cache_info->total_allocated++);
+ status =
+ acpi_os_create_cache("acpi_parse_ext",
+ sizeof(struct acpi_parse_obj_named),
+ ACPI_MAX_EXTPARSE_CACHE_DEPTH,
+ &acpi_gbl_ps_node_ext_cache);
+ if (ACPI_FAILURE(status)) {
+ return (status);
}
-#else
-
- /* Object cache is disabled; just allocate the object */
-
- object = ACPI_MEM_CALLOCATE (cache_info->object_size);
- ACPI_MEM_TRACKING (cache_info->total_allocated++);
-#endif
+ status =
+ acpi_os_create_cache("acpi_operand",
+ sizeof(union acpi_operand_object),
+ ACPI_MAX_OBJECT_CACHE_DEPTH,
+ &acpi_gbl_operand_cache);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
- return (object);
+ return (AE_OK);
}
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
/*******************************************************************************
*
- * FUNCTION: acpi_ut_delete_generic_cache
+ * FUNCTION: acpi_ut_delete_caches
*
- * PARAMETERS: list_id - Memory list ID
+ * PARAMETERS: None
*
- * RETURN: None
+ * RETURN: Status
*
- * DESCRIPTION: Free all objects within the requested cache.
+ * DESCRIPTION: Purge and delete all local caches
*
******************************************************************************/
-void
-acpi_ut_delete_generic_cache (
- u32 list_id)
+acpi_status acpi_ut_delete_caches(void)
{
- struct acpi_memory_list *cache_info;
- char *next;
-
- ACPI_FUNCTION_ENTRY ();
+ (void)acpi_os_delete_cache(acpi_gbl_state_cache);
+ acpi_gbl_state_cache = NULL;
+ (void)acpi_os_delete_cache(acpi_gbl_operand_cache);
+ acpi_gbl_operand_cache = NULL;
- cache_info = &acpi_gbl_memory_lists[list_id];
- while (cache_info->list_head) {
- /* Delete one cached state object */
+ (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
+ acpi_gbl_ps_node_cache = NULL;
- next = *(ACPI_CAST_INDIRECT_PTR (char,
- &(((char *) cache_info->list_head)[cache_info->link_offset])));
- ACPI_MEM_FREE (cache_info->list_head);
+ (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
+ acpi_gbl_ps_node_ext_cache = NULL;
- cache_info->list_head = next;
- cache_info->cache_depth--;
- }
+ return (AE_OK);
}
-#endif
-
/*******************************************************************************
*
@@ -280,9 +182,7 @@ acpi_ut_delete_generic_cache (
*
******************************************************************************/
-acpi_status
-acpi_ut_validate_buffer (
- struct acpi_buffer *buffer)
+acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer)
{
/* Obviously, the structure pointer must be valid */
@@ -293,9 +193,9 @@ acpi_ut_validate_buffer (
/* Special semantics for the length */
- if ((buffer->length == ACPI_NO_BUFFER) ||
- (buffer->length == ACPI_ALLOCATE_BUFFER) ||
- (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
+ if ((buffer->length == ACPI_NO_BUFFER) ||
+ (buffer->length == ACPI_ALLOCATE_BUFFER) ||
+ (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
return (AE_OK);
}
@@ -308,7 +208,6 @@ acpi_ut_validate_buffer (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_initialize_buffer
@@ -324,12 +223,10 @@ acpi_ut_validate_buffer (
******************************************************************************/
acpi_status
-acpi_ut_initialize_buffer (
- struct acpi_buffer *buffer,
- acpi_size required_length)
+acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
+ acpi_size required_length)
{
- acpi_status status = AE_OK;
-
+ acpi_status status = AE_OK;
switch (buffer->length) {
case ACPI_NO_BUFFER:
@@ -339,33 +236,30 @@ acpi_ut_initialize_buffer (
status = AE_BUFFER_OVERFLOW;
break;
-
case ACPI_ALLOCATE_BUFFER:
/* Allocate a new buffer */
- buffer->pointer = acpi_os_allocate (required_length);
+ buffer->pointer = acpi_os_allocate(required_length);
if (!buffer->pointer) {
return (AE_NO_MEMORY);
}
/* Clear the buffer */
- ACPI_MEMSET (buffer->pointer, 0, required_length);
+ ACPI_MEMSET(buffer->pointer, 0, required_length);
break;
-
case ACPI_ALLOCATE_LOCAL_BUFFER:
/* Allocate a new buffer with local interface to allow tracking */
- buffer->pointer = ACPI_MEM_CALLOCATE (required_length);
+ buffer->pointer = ACPI_MEM_CALLOCATE(required_length);
if (!buffer->pointer) {
return (AE_NO_MEMORY);
}
break;
-
default:
/* Existing buffer: Validate the size of the buffer */
@@ -377,7 +271,7 @@ acpi_ut_initialize_buffer (
/* Clear the buffer */
- ACPI_MEMSET (buffer->pointer, 0, required_length);
+ ACPI_MEMSET(buffer->pointer, 0, required_length);
break;
}
@@ -385,7 +279,6 @@ acpi_ut_initialize_buffer (
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_allocate
@@ -401,41 +294,34 @@ acpi_ut_initialize_buffer (
*
******************************************************************************/
-void *
-acpi_ut_allocate (
- acpi_size size,
- u32 component,
- char *module,
- u32 line)
+void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line)
{
- void *allocation;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
+ void *allocation;
+ ACPI_FUNCTION_TRACE_U32("ut_allocate", size);
/* Check for an inadvertent size of zero bytes */
if (!size) {
- _ACPI_REPORT_ERROR (module, line, component,
- ("ut_allocate: Attempt to allocate zero bytes\n"));
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("ut_allocate: Attempt to allocate zero bytes\n"));
size = 1;
}
- allocation = acpi_os_allocate (size);
+ allocation = acpi_os_allocate(size);
if (!allocation) {
/* Report allocation error */
- _ACPI_REPORT_ERROR (module, line, component,
- ("ut_allocate: Could not allocate size %X\n", (u32) size));
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("ut_allocate: Could not allocate size %X\n",
+ (u32) size));
- return_PTR (NULL);
+ return_PTR(NULL);
}
- return_PTR (allocation);
+ return_PTR(allocation);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_callocate
@@ -451,43 +337,36 @@ acpi_ut_allocate (
*
******************************************************************************/
-void *
-acpi_ut_callocate (
- acpi_size size,
- u32 component,
- char *module,
- u32 line)
+void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line)
{
- void *allocation;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
+ void *allocation;
+ ACPI_FUNCTION_TRACE_U32("ut_callocate", size);
/* Check for an inadvertent size of zero bytes */
if (!size) {
- _ACPI_REPORT_ERROR (module, line, component,
- ("ut_callocate: Attempt to allocate zero bytes\n"));
- return_PTR (NULL);
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("ut_callocate: Attempt to allocate zero bytes\n"));
+ return_PTR(NULL);
}
- allocation = acpi_os_allocate (size);
+ allocation = acpi_os_allocate(size);
if (!allocation) {
/* Report allocation error */
- _ACPI_REPORT_ERROR (module, line, component,
- ("ut_callocate: Could not allocate size %X\n", (u32) size));
- return_PTR (NULL);
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("ut_callocate: Could not allocate size %X\n",
+ (u32) size));
+ return_PTR(NULL);
}
/* Clear the memory block */
- ACPI_MEMSET (allocation, 0, size);
- return_PTR (allocation);
+ ACPI_MEMSET(allocation, 0, size);
+ return_PTR(allocation);
}
-
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
/*
* These procedures are used for tracking memory leaks in the subsystem, and
@@ -500,6 +379,39 @@ acpi_ut_callocate (
* occurs in the body of acpi_ut_free.
*/
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_list
+ *
+ * PARAMETERS: cache_name - Ascii name for the cache
+ * object_size - Size of each cached object
+ * return_cache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a local memory list for tracking purposed
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_create_list(char *list_name,
+ u16 object_size, struct acpi_memory_list **return_cache)
+{
+ struct acpi_memory_list *cache;
+
+ cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
+ if (!cache) {
+ return (AE_NO_MEMORY);
+ }
+
+ ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
+
+ cache->list_name = list_name;
+ cache->object_size = object_size;
+
+ *return_cache = cache;
+ return (AE_OK);
+}
/*******************************************************************************
*
@@ -516,37 +428,33 @@ acpi_ut_callocate (
*
******************************************************************************/
-void *
-acpi_ut_allocate_and_track (
- acpi_size size,
- u32 component,
- char *module,
- u32 line)
+void *acpi_ut_allocate_and_track(acpi_size size,
+ u32 component, char *module, u32 line)
{
- struct acpi_debug_mem_block *allocation;
- acpi_status status;
-
+ struct acpi_debug_mem_block *allocation;
+ acpi_status status;
- allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header),
- component, module, line);
+ allocation =
+ acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header),
+ component, module, line);
if (!allocation) {
return (NULL);
}
- status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
- ACPI_MEM_MALLOC, component, module, line);
- if (ACPI_FAILURE (status)) {
- acpi_os_free (allocation);
+ status = acpi_ut_track_allocation(allocation, size,
+ ACPI_MEM_MALLOC, component, module,
+ line);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_free(allocation);
return (NULL);
}
- acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
+ acpi_gbl_global_list->total_allocated++;
+ acpi_gbl_global_list->current_total_size += (u32) size;
- return ((void *) &allocation->user_space);
+ return ((void *)&allocation->user_space);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_callocate_and_track
@@ -562,41 +470,38 @@ acpi_ut_allocate_and_track (
*
******************************************************************************/
-void *
-acpi_ut_callocate_and_track (
- acpi_size size,
- u32 component,
- char *module,
- u32 line)
+void *acpi_ut_callocate_and_track(acpi_size size,
+ u32 component, char *module, u32 line)
{
- struct acpi_debug_mem_block *allocation;
- acpi_status status;
-
+ struct acpi_debug_mem_block *allocation;
+ acpi_status status;
- allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header),
- component, module, line);
+ allocation =
+ acpi_ut_callocate(size + sizeof(struct acpi_debug_mem_header),
+ component, module, line);
if (!allocation) {
/* Report allocation error */
- _ACPI_REPORT_ERROR (module, line, component,
- ("ut_callocate: Could not allocate size %X\n", (u32) size));
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("ut_callocate: Could not allocate size %X\n",
+ (u32) size));
return (NULL);
}
- status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
- ACPI_MEM_CALLOC, component, module, line);
- if (ACPI_FAILURE (status)) {
- acpi_os_free (allocation);
+ status = acpi_ut_track_allocation(allocation, size,
+ ACPI_MEM_CALLOC, component, module,
+ line);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_free(allocation);
return (NULL);
}
- acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
+ acpi_gbl_global_list->total_allocated++;
+ acpi_gbl_global_list->current_total_size += (u32) size;
- return ((void *) &allocation->user_space);
+ return ((void *)&allocation->user_space);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_free_and_track
@@ -613,53 +518,46 @@ acpi_ut_callocate_and_track (
******************************************************************************/
void
-acpi_ut_free_and_track (
- void *allocation,
- u32 component,
- char *module,
- u32 line)
+acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line)
{
- struct acpi_debug_mem_block *debug_block;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
+ struct acpi_debug_mem_block *debug_block;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE_PTR("ut_free", allocation);
if (NULL == allocation) {
- _ACPI_REPORT_ERROR (module, line, component,
- ("acpi_ut_free: Attempt to delete a NULL address\n"));
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("acpi_ut_free: Attempt to delete a NULL address\n"));
return_VOID;
}
- debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
- (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
+ debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
+ (((char *)allocation) -
+ sizeof(struct acpi_debug_mem_header)));
- acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size;
+ acpi_gbl_global_list->total_freed++;
+ acpi_gbl_global_list->current_total_size -= debug_block->size;
- status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block,
- component, module, line);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
- acpi_format_exception (status)));
+ status = acpi_ut_remove_allocation(debug_block,
+ component, module, line);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Could not free memory, %s\n",
+ acpi_format_exception(status)));
}
- acpi_os_free (debug_block);
+ acpi_os_free(debug_block);
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_find_allocation
*
- * PARAMETERS: list_id - Memory list to search
- * Allocation - Address of allocated memory
+ * PARAMETERS: Allocation - Address of allocated memory
*
* RETURN: A list element if found; NULL otherwise.
*
@@ -667,22 +565,13 @@ acpi_ut_free_and_track (
*
******************************************************************************/
-static struct acpi_debug_mem_block *
-acpi_ut_find_allocation (
- u32 list_id,
- void *allocation)
+static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation)
{
- struct acpi_debug_mem_block *element;
-
+ struct acpi_debug_mem_block *element;
- ACPI_FUNCTION_ENTRY ();
-
-
- if (list_id > ACPI_MEM_LIST_MAX) {
- return (NULL);
- }
+ ACPI_FUNCTION_ENTRY();
- element = acpi_gbl_memory_lists[list_id].list_head;
+ element = acpi_gbl_global_list->list_head;
/* Search for the address. */
@@ -697,13 +586,11 @@ acpi_ut_find_allocation (
return (NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_track_allocation
*
- * PARAMETERS: list_id - Memory list to search
- * Allocation - Address of allocated memory
+ * PARAMETERS: Allocation - Address of allocated memory
* Size - Size of the allocation
* alloc_type - MEM_MALLOC or MEM_CALLOC
* Component - Component type of caller
@@ -717,64 +604,51 @@ acpi_ut_find_allocation (
******************************************************************************/
static acpi_status
-acpi_ut_track_allocation (
- u32 list_id,
- struct acpi_debug_mem_block *allocation,
- acpi_size size,
- u8 alloc_type,
- u32 component,
- char *module,
- u32 line)
+acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
+ acpi_size size,
+ u8 alloc_type, u32 component, char *module, u32 line)
{
- struct acpi_memory_list *mem_list;
- struct acpi_debug_mem_block *element;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
+ struct acpi_memory_list *mem_list;
+ struct acpi_debug_mem_block *element;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ut_track_allocation", allocation);
- if (list_id > ACPI_MEM_LIST_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- mem_list = &acpi_gbl_memory_lists[list_id];
- status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ mem_list = acpi_gbl_global_list;
+ status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* Search list for this address to make sure it is not already on the list.
* This will catch several kinds of problems.
*/
-
- element = acpi_ut_find_allocation (list_id, allocation);
+ element = acpi_ut_find_allocation(allocation);
if (element) {
- ACPI_REPORT_ERROR ((
- "ut_track_allocation: Allocation already present in list! (%p)\n",
- allocation));
+ ACPI_REPORT_ERROR(("ut_track_allocation: Allocation already present in list! (%p)\n", allocation));
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n",
- element, allocation));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Element %p Address %p\n",
+ element, allocation));
goto unlock_and_exit;
}
/* Fill in the instance data. */
- allocation->size = (u32) size;
+ allocation->size = (u32) size;
allocation->alloc_type = alloc_type;
allocation->component = component;
- allocation->line = line;
+ allocation->line = line;
- ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
- allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
+ ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME);
+ allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
/* Insert at list head */
if (mem_list->list_head) {
- ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
+ ((struct acpi_debug_mem_block *)(mem_list->list_head))->
+ previous = allocation;
}
allocation->next = mem_list->list_head;
@@ -782,19 +656,16 @@ acpi_ut_track_allocation (
mem_list->list_head = allocation;
-
-unlock_and_exit:
- status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
- return_ACPI_STATUS (status);
+ unlock_and_exit:
+ status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_remove_allocation
*
- * PARAMETERS: list_id - Memory list to search
- * Allocation - Address of allocated memory
+ * PARAMETERS: Allocation - Address of allocated memory
* Component - Component type of caller
* Module - Source file name of caller
* Line - Line number of caller
@@ -806,45 +677,34 @@ unlock_and_exit:
******************************************************************************/
static acpi_status
-acpi_ut_remove_allocation (
- u32 list_id,
- struct acpi_debug_mem_block *allocation,
- u32 component,
- char *module,
- u32 line)
+acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
+ u32 component, char *module, u32 line)
{
- struct acpi_memory_list *mem_list;
- acpi_status status;
-
+ struct acpi_memory_list *mem_list;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("ut_remove_allocation");
+ ACPI_FUNCTION_TRACE("ut_remove_allocation");
-
- if (list_id > ACPI_MEM_LIST_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- mem_list = &acpi_gbl_memory_lists[list_id];
+ mem_list = acpi_gbl_global_list;
if (NULL == mem_list->list_head) {
/* No allocations! */
- _ACPI_REPORT_ERROR (module, line, component,
- ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
+ _ACPI_REPORT_ERROR(module, line, component,
+ ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
- status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Unlink */
if (allocation->previous) {
(allocation->previous)->next = allocation->next;
- }
- else {
+ } else {
mem_list->list_head = allocation->next;
}
@@ -854,16 +714,15 @@ acpi_ut_remove_allocation (
/* Mark the segment as deleted */
- ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
+ ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size);
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
- allocation->size));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
+ allocation->size));
- status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
- return_ACPI_STATUS (status);
+ status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_dump_allocation_info
@@ -877,15 +736,13 @@ acpi_ut_remove_allocation (
******************************************************************************/
#ifdef ACPI_FUTURE_USAGE
-void
-acpi_ut_dump_allocation_info (
- void)
+void acpi_ut_dump_allocation_info(void)
{
/*
struct acpi_memory_list *mem_list;
*/
- ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
+ ACPI_FUNCTION_TRACE("ut_dump_allocation_info");
/*
ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
@@ -898,7 +755,6 @@ acpi_ut_dump_allocation_info (
mem_list->max_concurrent_count,
ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
-
ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
running_object_count,
@@ -909,7 +765,6 @@ acpi_ut_dump_allocation_info (
running_alloc_count,
ROUND_UP_TO_1K (running_alloc_size)));
-
ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
("%30s: %4d (%3d Kb)\n", "Current Nodes",
acpi_gbl_current_node_count,
@@ -923,8 +778,7 @@ acpi_ut_dump_allocation_info (
*/
return_VOID;
}
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
@@ -939,84 +793,87 @@ acpi_ut_dump_allocation_info (
*
******************************************************************************/
-void
-acpi_ut_dump_allocations (
- u32 component,
- char *module)
+void acpi_ut_dump_allocations(u32 component, char *module)
{
- struct acpi_debug_mem_block *element;
- union acpi_descriptor *descriptor;
- u32 num_outstanding = 0;
-
-
- ACPI_FUNCTION_TRACE ("ut_dump_allocations");
+ struct acpi_debug_mem_block *element;
+ union acpi_descriptor *descriptor;
+ u32 num_outstanding = 0;
+ ACPI_FUNCTION_TRACE("ut_dump_allocations");
/*
* Walk the allocation list.
*/
- if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
+ if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
return;
}
- element = acpi_gbl_memory_lists[0].list_head;
+ element = acpi_gbl_global_list->list_head;
while (element) {
if ((element->component & component) &&
- ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
+ ((module == NULL)
+ || (0 == ACPI_STRCMP(module, element->module)))) {
/* Ignore allocated objects that are in a cache */
- descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
+ descriptor =
+ ACPI_CAST_PTR(union acpi_descriptor,
+ &element->user_space);
if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
- acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
- descriptor, element->size, element->module,
- element->line, acpi_ut_get_descriptor_name (descriptor));
+ acpi_os_printf("%p Len %04X %9.9s-%d [%s] ",
+ descriptor, element->size,
+ element->module, element->line,
+ acpi_ut_get_descriptor_name
+ (descriptor));
/* Most of the elements will be Operand objects. */
- switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
+ switch (ACPI_GET_DESCRIPTOR_TYPE(descriptor)) {
case ACPI_DESC_TYPE_OPERAND:
- acpi_os_printf ("%12.12s R%hd",
- acpi_ut_get_type_name (descriptor->object.common.type),
- descriptor->object.common.reference_count);
+ acpi_os_printf("%12.12s R%hd",
+ acpi_ut_get_type_name
+ (descriptor->object.
+ common.type),
+ descriptor->object.
+ common.reference_count);
break;
case ACPI_DESC_TYPE_PARSER:
- acpi_os_printf ("aml_opcode %04hX",
- descriptor->op.asl.aml_opcode);
+ acpi_os_printf("aml_opcode %04hX",
+ descriptor->op.asl.
+ aml_opcode);
break;
case ACPI_DESC_TYPE_NAMED:
- acpi_os_printf ("%4.4s",
- acpi_ut_get_node_name (&descriptor->node));
+ acpi_os_printf("%4.4s",
+ acpi_ut_get_node_name
+ (&descriptor->node));
break;
default:
break;
}
- acpi_os_printf ( "\n");
+ acpi_os_printf("\n");
num_outstanding++;
}
}
element = element->next;
}
- (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+ (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
/* Print summary */
if (!num_outstanding) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "No outstanding allocations.\n"));
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "%d(%X) Outstanding allocations\n",
- num_outstanding, num_outstanding));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No outstanding allocations.\n"));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%d(%X) Outstanding allocations\n",
+ num_outstanding, num_outstanding));
}
return_VOID;
}
-#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
-
+#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c
new file mode 100644
index 000000000000..93d48681d276
--- /dev/null
+++ b/drivers/acpi/utilities/utcache.c
@@ -0,0 +1,305 @@
+/******************************************************************************
+ *
+ * Module Name: utcache - local cache allocation routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utcache")
+
+#ifdef ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_create_cache
+ *
+ * PARAMETERS: cache_name - Ascii name for the cache
+ * object_size - Size of each cached object
+ * max_depth - Maximum depth of the cache (in objects)
+ * return_cache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a cache object
+ *
+ ******************************************************************************/
+acpi_status
+acpi_os_create_cache(char *cache_name,
+ u16 object_size,
+ u16 max_depth, struct acpi_memory_list **return_cache)
+{
+ struct acpi_memory_list *cache;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!cache_name || !return_cache || (object_size < 16)) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Create the cache object */
+
+ cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
+ if (!cache) {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Populate the cache object and return it */
+
+ ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
+ cache->link_offset = 8;
+ cache->list_name = cache_name;
+ cache->object_size = object_size;
+ cache->max_depth = max_depth;
+
+ *return_cache = cache;
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_purge_cache
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache)
+{
+ char *next;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!cache) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Walk the list of objects in this cache */
+
+ while (cache->list_head) {
+ /* Delete and unlink one cached state object */
+
+ next = *(ACPI_CAST_INDIRECT_PTR(char,
+ &(((char *)cache->
+ list_head)[cache->
+ link_offset])));
+ ACPI_MEM_FREE(cache->list_head);
+
+ cache->list_head = next;
+ cache->current_depth--;
+ }
+
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_delete_cache
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache and delete the
+ * cache object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+ /* Purge all objects in the cache */
+
+ status = acpi_os_purge_cache(cache);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Now we can delete the cache object */
+
+ acpi_os_free(cache);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_release_object
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ * Object - The object to be released
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release an object to the specified cache. If cache is full,
+ * the object is deleted.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_os_release_object(struct acpi_memory_list * cache, void *object)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!cache || !object) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* If cache is full, just free this object */
+
+ if (cache->current_depth >= cache->max_depth) {
+ ACPI_MEM_FREE(object);
+ ACPI_MEM_TRACKING(cache->total_freed++);
+ }
+
+ /* Otherwise put this object back into the cache */
+
+ else {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Mark the object as cached */
+
+ ACPI_MEMSET(object, 0xCA, cache->object_size);
+ ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED);
+
+ /* Put the object at the head of the cache list */
+
+ *(ACPI_CAST_INDIRECT_PTR(char,
+ &(((char *)object)[cache->
+ link_offset]))) =
+ cache->list_head;
+ cache->list_head = object;
+ cache->current_depth++;
+
+ (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ }
+
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_acquire_object
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: the acquired object. NULL on error
+ *
+ * DESCRIPTION: Get an object from the specified cache. If cache is empty,
+ * the object is allocated.
+ *
+ ******************************************************************************/
+
+void *acpi_os_acquire_object(struct acpi_memory_list *cache)
+{
+ acpi_status status;
+ void *object;
+
+ ACPI_FUNCTION_NAME("os_acquire_object");
+
+ if (!cache) {
+ return (NULL);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (NULL);
+ }
+
+ ACPI_MEM_TRACKING(cache->requests++);
+
+ /* Check the cache first */
+
+ if (cache->list_head) {
+ /* There is an object available, use it */
+
+ object = cache->list_head;
+ cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char,
+ &(((char *)
+ object)[cache->
+ link_offset])));
+
+ cache->current_depth--;
+
+ ACPI_MEM_TRACKING(cache->hits++);
+ ACPI_MEM_TRACKING(ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Object %p from %s cache\n",
+ object, cache->list_name)));
+
+ status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (NULL);
+ }
+
+ /* Clear (zero) the previously used Object */
+
+ ACPI_MEMSET(object, 0, cache->object_size);
+ } else {
+ /* The cache is empty, create a new object */
+
+ ACPI_MEM_TRACKING(cache->total_allocated++);
+
+ /* Avoid deadlock with ACPI_MEM_CALLOCATE */
+
+ status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (NULL);
+ }
+
+ object = ACPI_MEM_CALLOCATE(cache->object_size);
+ if (!object) {
+ return (NULL);
+ }
+ }
+
+ return (object);
+}
+#endif /* ACPI_USE_LOCAL_CACHE */
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 11e884957162..5442b32de611 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -41,59 +41,46 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utcopy")
+ACPI_MODULE_NAME("utcopy")
/* Local prototypes */
-
static acpi_status
-acpi_ut_copy_isimple_to_esimple (
- union acpi_operand_object *internal_object,
- union acpi_object *external_object,
- u8 *data_space,
- acpi_size *buffer_space_used);
+acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
+ union acpi_object *external_object,
+ u8 * data_space, acpi_size * buffer_space_used);
static acpi_status
-acpi_ut_copy_ielement_to_ielement (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context);
+acpi_ut_copy_ielement_to_ielement(u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context);
static acpi_status
-acpi_ut_copy_ipackage_to_epackage (
- union acpi_operand_object *internal_object,
- u8 *buffer,
- acpi_size *space_used);
+acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
+ u8 * buffer, acpi_size * space_used);
static acpi_status
-acpi_ut_copy_esimple_to_isimple(
- union acpi_object *user_obj,
- union acpi_operand_object **return_obj);
+acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
+ union acpi_operand_object **return_obj);
static acpi_status
-acpi_ut_copy_simple_object (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *dest_desc);
+acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc);
static acpi_status
-acpi_ut_copy_ielement_to_eelement (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context);
+acpi_ut_copy_ielement_to_eelement(u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context);
static acpi_status
-acpi_ut_copy_ipackage_to_ipackage (
- union acpi_operand_object *source_obj,
- union acpi_operand_object *dest_obj,
- struct acpi_walk_state *walk_state);
-
+acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
+ union acpi_operand_object *dest_obj,
+ struct acpi_walk_state *walk_state);
/*******************************************************************************
*
@@ -116,17 +103,13 @@ acpi_ut_copy_ipackage_to_ipackage (
******************************************************************************/
static acpi_status
-acpi_ut_copy_isimple_to_esimple (
- union acpi_operand_object *internal_object,
- union acpi_object *external_object,
- u8 *data_space,
- acpi_size *buffer_space_used)
+acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
+ union acpi_object *external_object,
+ u8 * data_space, acpi_size * buffer_space_used)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ut_copy_isimple_to_esimple");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ut_copy_isimple_to_esimple");
*buffer_space_used = 0;
@@ -135,54 +118,54 @@ acpi_ut_copy_isimple_to_esimple (
* package element)
*/
if (!internal_object) {
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Always clear the external object */
- ACPI_MEMSET (external_object, 0, sizeof (union acpi_object));
+ ACPI_MEMSET(external_object, 0, sizeof(union acpi_object));
/*
* In general, the external object will be the same type as
* the internal object
*/
- external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
+ external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
/* However, only a limited number of external types are supported */
- switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
+ switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
case ACPI_TYPE_STRING:
- external_object->string.pointer = (char *) data_space;
+ external_object->string.pointer = (char *)data_space;
external_object->string.length = internal_object->string.length;
- *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (
- (acpi_size) internal_object->string.length + 1);
-
- ACPI_MEMCPY ((void *) data_space,
- (void *) internal_object->string.pointer,
- (acpi_size) internal_object->string.length + 1);
+ *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
+ internal_object->
+ string.
+ length + 1);
+
+ ACPI_MEMCPY((void *)data_space,
+ (void *)internal_object->string.pointer,
+ (acpi_size) internal_object->string.length + 1);
break;
-
case ACPI_TYPE_BUFFER:
external_object->buffer.pointer = data_space;
external_object->buffer.length = internal_object->buffer.length;
- *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (
- internal_object->string.length);
+ *buffer_space_used =
+ ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
+ length);
- ACPI_MEMCPY ((void *) data_space,
- (void *) internal_object->buffer.pointer,
- internal_object->buffer.length);
+ ACPI_MEMCPY((void *)data_space,
+ (void *)internal_object->buffer.pointer,
+ internal_object->buffer.length);
break;
-
case ACPI_TYPE_INTEGER:
external_object->integer.value = internal_object->integer.value;
break;
-
case ACPI_TYPE_LOCAL_REFERENCE:
/*
@@ -199,41 +182,41 @@ acpi_ut_copy_isimple_to_esimple (
* to object containing a handle to an ACPI named object.
*/
external_object->type = ACPI_TYPE_ANY;
- external_object->reference.handle = internal_object->reference.node;
+ external_object->reference.handle =
+ internal_object->reference.node;
break;
}
break;
-
case ACPI_TYPE_PROCESSOR:
- external_object->processor.proc_id = internal_object->processor.proc_id;
- external_object->processor.pblk_address = internal_object->processor.address;
- external_object->processor.pblk_length = internal_object->processor.length;
+ external_object->processor.proc_id =
+ internal_object->processor.proc_id;
+ external_object->processor.pblk_address =
+ internal_object->processor.address;
+ external_object->processor.pblk_length =
+ internal_object->processor.length;
break;
-
case ACPI_TYPE_POWER:
external_object->power_resource.system_level =
- internal_object->power_resource.system_level;
+ internal_object->power_resource.system_level;
external_object->power_resource.resource_order =
- internal_object->power_resource.resource_order;
+ internal_object->power_resource.resource_order;
break;
-
default:
/*
* There is no corresponding external object type
*/
- return_ACPI_STATUS (AE_SUPPORT);
+ return_ACPI_STATUS(AE_SUPPORT);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_ielement_to_eelement
@@ -247,25 +230,23 @@ acpi_ut_copy_isimple_to_esimple (
******************************************************************************/
static acpi_status
-acpi_ut_copy_ielement_to_eelement (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context)
+acpi_ut_copy_ielement_to_eelement(u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context)
{
- acpi_status status = AE_OK;
- struct acpi_pkg_info *info = (struct acpi_pkg_info *) context;
- acpi_size object_space;
- u32 this_index;
- union acpi_object *target_object;
+ acpi_status status = AE_OK;
+ struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
+ acpi_size object_space;
+ u32 this_index;
+ union acpi_object *target_object;
+ ACPI_FUNCTION_ENTRY();
- ACPI_FUNCTION_ENTRY ();
-
-
- this_index = state->pkg.index;
+ this_index = state->pkg.index;
target_object = (union acpi_object *)
- &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
+ &((union acpi_object *)(state->pkg.dest_object))->package.
+ elements[this_index];
switch (object_type) {
case ACPI_COPY_TYPE_SIMPLE:
@@ -273,23 +254,24 @@ acpi_ut_copy_ielement_to_eelement (
/*
* This is a simple or null object
*/
- status = acpi_ut_copy_isimple_to_esimple (source_object,
- target_object, info->free_space, &object_space);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_copy_isimple_to_esimple(source_object,
+ target_object,
+ info->free_space,
+ &object_space);
+ if (ACPI_FAILURE(status)) {
return (status);
}
break;
-
case ACPI_COPY_TYPE_PACKAGE:
/*
* Build the package object
*/
- target_object->type = ACPI_TYPE_PACKAGE;
- target_object->package.count = source_object->package.count;
+ target_object->type = ACPI_TYPE_PACKAGE;
+ target_object->package.count = source_object->package.count;
target_object->package.elements =
- ACPI_CAST_PTR (union acpi_object, info->free_space);
+ ACPI_CAST_PTR(union acpi_object, info->free_space);
/*
* Pass the new package object back to the package walk routine
@@ -300,22 +282,22 @@ acpi_ut_copy_ielement_to_eelement (
* Save space for the array of objects (Package elements)
* update the buffer length counter
*/
- object_space = ACPI_ROUND_UP_TO_NATIVE_WORD (
- (acpi_size) target_object->package.count *
- sizeof (union acpi_object));
+ object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
+ target_object->
+ package.count *
+ sizeof(union
+ acpi_object));
break;
-
default:
return (AE_BAD_PARAMETER);
}
- info->free_space += object_space;
- info->length += object_space;
+ info->free_space += object_space;
+ info->length += object_space;
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_ipackage_to_epackage
@@ -336,55 +318,51 @@ acpi_ut_copy_ielement_to_eelement (
******************************************************************************/
static acpi_status
-acpi_ut_copy_ipackage_to_epackage (
- union acpi_operand_object *internal_object,
- u8 *buffer,
- acpi_size *space_used)
+acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
+ u8 * buffer, acpi_size * space_used)
{
- union acpi_object *external_object;
- acpi_status status;
- struct acpi_pkg_info info;
-
-
- ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_epackage");
+ union acpi_object *external_object;
+ acpi_status status;
+ struct acpi_pkg_info info;
+ ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_epackage");
/*
* First package at head of the buffer
*/
- external_object = ACPI_CAST_PTR (union acpi_object, buffer);
+ external_object = ACPI_CAST_PTR(union acpi_object, buffer);
/*
* Free space begins right after the first package
*/
- info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
- info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
- sizeof (union acpi_object));
+ info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
+ info.free_space =
+ buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
info.object_space = 0;
info.num_packages = 1;
- external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
- external_object->package.count = internal_object->package.count;
- external_object->package.elements = ACPI_CAST_PTR (union acpi_object,
- info.free_space);
+ external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->package.count = internal_object->package.count;
+ external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
+ info.free_space);
/*
* Leave room for an array of ACPI_OBJECTS in the buffer
* and move the free space past it
*/
- info.length += (acpi_size) external_object->package.count *
- ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+ info.length += (acpi_size) external_object->package.count *
+ ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
info.free_space += external_object->package.count *
- ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+ ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
- status = acpi_ut_walk_package_tree (internal_object, external_object,
- acpi_ut_copy_ielement_to_eelement, &info);
+ status = acpi_ut_walk_package_tree(internal_object, external_object,
+ acpi_ut_copy_ielement_to_eelement,
+ &info);
*space_used = info.length;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_iobject_to_eobject
@@ -400,44 +378,45 @@ acpi_ut_copy_ipackage_to_epackage (
******************************************************************************/
acpi_status
-acpi_ut_copy_iobject_to_eobject (
- union acpi_operand_object *internal_object,
- struct acpi_buffer *ret_buffer)
+acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
+ struct acpi_buffer *ret_buffer)
{
- acpi_status status;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ut_copy_iobject_to_eobject");
- ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_eobject");
-
-
- if (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE) {
+ if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
/*
* Package object: Copy all subobjects (including
* nested packages)
*/
- status = acpi_ut_copy_ipackage_to_epackage (internal_object,
- ret_buffer->pointer, &ret_buffer->length);
- }
- else {
+ status = acpi_ut_copy_ipackage_to_epackage(internal_object,
+ ret_buffer->pointer,
+ &ret_buffer->length);
+ } else {
/*
* Build a simple object (no nested objects)
*/
- status = acpi_ut_copy_isimple_to_esimple (internal_object,
- (union acpi_object *) ret_buffer->pointer,
- ((u8 *) ret_buffer->pointer +
- ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
- &ret_buffer->length);
+ status = acpi_ut_copy_isimple_to_esimple(internal_object,
+ (union acpi_object *)
+ ret_buffer->pointer,
+ ((u8 *) ret_buffer->
+ pointer +
+ ACPI_ROUND_UP_TO_NATIVE_WORD
+ (sizeof
+ (union
+ acpi_object))),
+ &ret_buffer->length);
/*
* build simple does not include the object size in the length
* so we add it in here
*/
- ret_buffer->length += sizeof (union acpi_object);
+ ret_buffer->length += sizeof(union acpi_object);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_esimple_to_isimple
@@ -455,15 +434,12 @@ acpi_ut_copy_iobject_to_eobject (
******************************************************************************/
static acpi_status
-acpi_ut_copy_esimple_to_isimple (
- union acpi_object *external_object,
- union acpi_operand_object **ret_internal_object)
+acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
+ union acpi_operand_object **ret_internal_object)
{
- union acpi_operand_object *internal_object;
-
-
- ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple");
+ union acpi_operand_object *internal_object;
+ ACPI_FUNCTION_TRACE("ut_copy_esimple_to_isimple");
/*
* Simple types supported are: String, Buffer, Integer
@@ -473,58 +449,57 @@ acpi_ut_copy_esimple_to_isimple (
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_INTEGER:
- internal_object = acpi_ut_create_internal_object (
- (u8) external_object->type);
+ internal_object = acpi_ut_create_internal_object((u8)
+ external_object->
+ type);
if (!internal_object) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
break;
default:
/* All other types are not supported */
- return_ACPI_STATUS (AE_SUPPORT);
+ return_ACPI_STATUS(AE_SUPPORT);
}
-
/* Must COPY string and buffer contents */
switch (external_object->type) {
case ACPI_TYPE_STRING:
internal_object->string.pointer =
- ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1);
+ ACPI_MEM_CALLOCATE((acpi_size) external_object->string.
+ length + 1);
if (!internal_object->string.pointer) {
goto error_exit;
}
- ACPI_MEMCPY (internal_object->string.pointer,
- external_object->string.pointer,
- external_object->string.length);
+ ACPI_MEMCPY(internal_object->string.pointer,
+ external_object->string.pointer,
+ external_object->string.length);
internal_object->string.length = external_object->string.length;
break;
-
case ACPI_TYPE_BUFFER:
internal_object->buffer.pointer =
- ACPI_MEM_CALLOCATE (external_object->buffer.length);
+ ACPI_MEM_CALLOCATE(external_object->buffer.length);
if (!internal_object->buffer.pointer) {
goto error_exit;
}
- ACPI_MEMCPY (internal_object->buffer.pointer,
- external_object->buffer.pointer,
- external_object->buffer.length);
+ ACPI_MEMCPY(internal_object->buffer.pointer,
+ external_object->buffer.pointer,
+ external_object->buffer.length);
internal_object->buffer.length = external_object->buffer.length;
break;
-
case ACPI_TYPE_INTEGER:
- internal_object->integer.value = external_object->integer.value;
+ internal_object->integer.value = external_object->integer.value;
break;
default:
@@ -533,15 +508,13 @@ acpi_ut_copy_esimple_to_isimple (
}
*ret_internal_object = internal_object;
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(AE_OK);
-error_exit:
- acpi_ut_remove_reference (internal_object);
- return_ACPI_STATUS (AE_NO_MEMORY);
+ error_exit:
+ acpi_ut_remove_reference(internal_object);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
-
#ifdef ACPI_FUTURE_IMPLEMENTATION
/* Code to convert packages that are parameters to control methods */
@@ -565,22 +538,18 @@ error_exit:
******************************************************************************/
static acpi_status
-acpi_ut_copy_epackage_to_ipackage (
- union acpi_operand_object *internal_object,
- u8 *buffer,
- u32 *space_used)
+acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object,
+ u8 * buffer, u32 * space_used)
{
- u8 *free_space;
- union acpi_object *external_object;
- u32 length = 0;
- u32 this_index;
- u32 object_space = 0;
- union acpi_operand_object *this_internal_obj;
- union acpi_object *this_external_obj;
-
-
- ACPI_FUNCTION_TRACE ("ut_copy_epackage_to_ipackage");
+ u8 *free_space;
+ union acpi_object *external_object;
+ u32 length = 0;
+ u32 this_index;
+ u32 object_space = 0;
+ union acpi_operand_object *this_internal_obj;
+ union acpi_object *this_external_obj;
+ ACPI_FUNCTION_TRACE("ut_copy_epackage_to_ipackage");
/*
* First package at head of the buffer
@@ -592,24 +561,22 @@ acpi_ut_copy_epackage_to_ipackage (
*/
free_space = buffer + sizeof(union acpi_object);
-
- external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
- external_object->package.count = internal_object->package.count;
- external_object->package.elements = (union acpi_object *)free_space;
+ external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->package.count = internal_object->package.count;
+ external_object->package.elements = (union acpi_object *)free_space;
/*
* Build an array of ACPI_OBJECTS in the buffer
* and move the free space past it
*/
- free_space += external_object->package.count * sizeof(union acpi_object);
-
+ free_space +=
+ external_object->package.count * sizeof(union acpi_object);
/* Call walk_package */
}
-#endif /* Future implementation */
-
+#endif /* Future implementation */
/*******************************************************************************
*
@@ -625,37 +592,35 @@ acpi_ut_copy_epackage_to_ipackage (
******************************************************************************/
acpi_status
-acpi_ut_copy_eobject_to_iobject (
- union acpi_object *external_object,
- union acpi_operand_object **internal_object)
+acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
+ union acpi_operand_object **internal_object)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ut_copy_eobject_to_iobject");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ut_copy_eobject_to_iobject");
if (external_object->type == ACPI_TYPE_PACKAGE) {
/*
* Packages as external input to control methods are not supported,
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Packages as parameters not implemented!\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Packages as parameters not implemented!\n"));
- return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+ return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
}
else {
/*
* Build a simple object (no nested objects)
*/
- status = acpi_ut_copy_esimple_to_isimple (external_object, internal_object);
+ status =
+ acpi_ut_copy_esimple_to_isimple(external_object,
+ internal_object);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_simple_object
@@ -671,83 +636,75 @@ acpi_ut_copy_eobject_to_iobject (
******************************************************************************/
static acpi_status
-acpi_ut_copy_simple_object (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *dest_desc)
+acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc)
{
- u16 reference_count;
- union acpi_operand_object *next_object;
-
+ u16 reference_count;
+ union acpi_operand_object *next_object;
/* Save fields from destination that we don't want to overwrite */
reference_count = dest_desc->common.reference_count;
next_object = dest_desc->common.next_object;
- /* Copy the entire source object over the destination object*/
+ /* Copy the entire source object over the destination object */
- ACPI_MEMCPY ((char *) dest_desc, (char *) source_desc,
- sizeof (union acpi_operand_object));
+ ACPI_MEMCPY((char *)dest_desc, (char *)source_desc,
+ sizeof(union acpi_operand_object));
/* Restore the saved fields */
dest_desc->common.reference_count = reference_count;
dest_desc->common.next_object = next_object;
- /* Handle the objects with extra data */
+ /* New object is not static, regardless of source */
- switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
- case ACPI_TYPE_BUFFER:
+ dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
- dest_desc->buffer.node = NULL;
- dest_desc->common.flags = source_desc->common.flags;
+ /* Handle the objects with extra data */
+ switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ case ACPI_TYPE_BUFFER:
/*
* Allocate and copy the actual buffer if and only if:
* 1) There is a valid buffer pointer
- * 2) The buffer is not static (not in an ACPI table) (in this case,
- * the actual pointer was already copied above)
+ * 2) The buffer has a length > 0
*/
if ((source_desc->buffer.pointer) &&
- (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
- dest_desc->buffer.pointer = NULL;
-
- /* Create an actual buffer only if length > 0 */
-
- if (source_desc->buffer.length) {
- dest_desc->buffer.pointer =
- ACPI_MEM_ALLOCATE (source_desc->buffer.length);
- if (!dest_desc->buffer.pointer) {
- return (AE_NO_MEMORY);
- }
+ (source_desc->buffer.length)) {
+ dest_desc->buffer.pointer =
+ ACPI_MEM_ALLOCATE(source_desc->buffer.length);
+ if (!dest_desc->buffer.pointer) {
+ return (AE_NO_MEMORY);
+ }
- /* Copy the actual buffer data */
+ /* Copy the actual buffer data */
- ACPI_MEMCPY (dest_desc->buffer.pointer,
- source_desc->buffer.pointer,
- source_desc->buffer.length);
- }
+ ACPI_MEMCPY(dest_desc->buffer.pointer,
+ source_desc->buffer.pointer,
+ source_desc->buffer.length);
}
break;
case ACPI_TYPE_STRING:
-
/*
* Allocate and copy the actual string if and only if:
* 1) There is a valid string pointer
- * 2) The string is not static (not in an ACPI table) (in this case,
- * the actual pointer was already copied above)
+ * (Pointer to a NULL string is allowed)
*/
- if ((source_desc->string.pointer) &&
- (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+ if (source_desc->string.pointer) {
dest_desc->string.pointer =
- ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
+ ACPI_MEM_ALLOCATE((acpi_size) source_desc->string.
+ length + 1);
if (!dest_desc->string.pointer) {
return (AE_NO_MEMORY);
}
- ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer,
- (acpi_size) source_desc->string.length + 1);
+ /* Copy the actual string data */
+
+ ACPI_MEMCPY(dest_desc->string.pointer,
+ source_desc->string.pointer,
+ (acpi_size) source_desc->string.length + 1);
}
break;
@@ -756,7 +713,7 @@ acpi_ut_copy_simple_object (
* We copied the reference object, so we now must add a reference
* to the object pointed to by the reference
*/
- acpi_ut_add_reference (source_desc->reference.object);
+ acpi_ut_add_reference(source_desc->reference.object);
break;
default:
@@ -767,7 +724,6 @@ acpi_ut_copy_simple_object (
return (AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_ielement_to_ielement
@@ -781,24 +737,21 @@ acpi_ut_copy_simple_object (
******************************************************************************/
static acpi_status
-acpi_ut_copy_ielement_to_ielement (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context)
+acpi_ut_copy_ielement_to_ielement(u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context)
{
- acpi_status status = AE_OK;
- u32 this_index;
- union acpi_operand_object **this_target_ptr;
- union acpi_operand_object *target_object;
-
+ acpi_status status = AE_OK;
+ u32 this_index;
+ union acpi_operand_object **this_target_ptr;
+ union acpi_operand_object *target_object;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
-
- this_index = state->pkg.index;
+ this_index = state->pkg.index;
this_target_ptr = (union acpi_operand_object **)
- &state->pkg.dest_object->package.elements[this_index];
+ &state->pkg.dest_object->package.elements[this_index];
switch (object_type) {
case ACPI_COPY_TYPE_SIMPLE:
@@ -809,34 +762,36 @@ acpi_ut_copy_ielement_to_ielement (
/*
* This is a simple object, just copy it
*/
- target_object = acpi_ut_create_internal_object (
- ACPI_GET_OBJECT_TYPE (source_object));
+ target_object =
+ acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
+ (source_object));
if (!target_object) {
return (AE_NO_MEMORY);
}
- status = acpi_ut_copy_simple_object (source_object, target_object);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_copy_simple_object(source_object,
+ target_object);
+ if (ACPI_FAILURE(status)) {
goto error_exit;
}
*this_target_ptr = target_object;
- }
- else {
+ } else {
/* Pass through a null element */
*this_target_ptr = NULL;
}
break;
-
case ACPI_COPY_TYPE_PACKAGE:
/*
* This object is a package - go down another nesting level
* Create and build the package object
*/
- target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+ target_object =
+ acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
if (!target_object) {
return (AE_NO_MEMORY);
}
@@ -848,8 +803,8 @@ acpi_ut_copy_ielement_to_ielement (
* Create the object array
*/
target_object->package.elements =
- ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) *
- sizeof (void *));
+ ACPI_MEM_CALLOCATE(((acpi_size) source_object->package.
+ count + 1) * sizeof(void *));
if (!target_object->package.elements) {
status = AE_NO_MEMORY;
goto error_exit;
@@ -866,19 +821,17 @@ acpi_ut_copy_ielement_to_ielement (
*this_target_ptr = target_object;
break;
-
default:
return (AE_BAD_PARAMETER);
}
return (status);
-error_exit:
- acpi_ut_remove_reference (target_object);
+ error_exit:
+ acpi_ut_remove_reference(target_object);
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_ipackage_to_ipackage
@@ -894,49 +847,46 @@ error_exit:
******************************************************************************/
static acpi_status
-acpi_ut_copy_ipackage_to_ipackage (
- union acpi_operand_object *source_obj,
- union acpi_operand_object *dest_obj,
- struct acpi_walk_state *walk_state)
+acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
+ union acpi_operand_object *dest_obj,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
-
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage");
+ ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_ipackage");
-
- dest_obj->common.type = ACPI_GET_OBJECT_TYPE (source_obj);
- dest_obj->common.flags = source_obj->common.flags;
+ dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+ dest_obj->common.flags = source_obj->common.flags;
dest_obj->package.count = source_obj->package.count;
/*
* Create the object array and walk the source package tree
*/
- dest_obj->package.elements = ACPI_MEM_CALLOCATE (
- ((acpi_size) source_obj->package.count + 1) *
- sizeof (void *));
+ dest_obj->package.elements = ACPI_MEM_CALLOCATE(((acpi_size)
+ source_obj->package.
+ count +
+ 1) * sizeof(void *));
if (!dest_obj->package.elements) {
- ACPI_REPORT_ERROR (
- ("aml_build_copy_internal_package_object: Package allocation failure\n"));
- return_ACPI_STATUS (AE_NO_MEMORY);
+ ACPI_REPORT_ERROR(("aml_build_copy_internal_package_object: Package allocation failure\n"));
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
* Copy the package element-by-element by walking the package "tree".
* This handles nested packages of arbitrary depth.
*/
- status = acpi_ut_walk_package_tree (source_obj, dest_obj,
- acpi_ut_copy_ielement_to_ielement, walk_state);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_walk_package_tree(source_obj, dest_obj,
+ acpi_ut_copy_ielement_to_ielement,
+ walk_state);
+ if (ACPI_FAILURE(status)) {
/* On failure, delete the destination package object */
- acpi_ut_remove_reference (dest_obj);
+ acpi_ut_remove_reference(dest_obj);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_iobject_to_iobject
@@ -952,35 +902,31 @@ acpi_ut_copy_ipackage_to_ipackage (
******************************************************************************/
acpi_status
-acpi_ut_copy_iobject_to_iobject (
- union acpi_operand_object *source_desc,
- union acpi_operand_object **dest_desc,
- struct acpi_walk_state *walk_state)
+acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
+ union acpi_operand_object **dest_desc,
+ struct acpi_walk_state *walk_state)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_iobject");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("ut_copy_iobject_to_iobject");
/* Create the top level object */
- *dest_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_desc));
+ *dest_desc =
+ acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
if (!*dest_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the object and possible subobjects */
- if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_PACKAGE) {
- status = acpi_ut_copy_ipackage_to_ipackage (source_desc, *dest_desc,
- walk_state);
- }
- else {
- status = acpi_ut_copy_simple_object (source_desc, *dest_desc);
+ if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+ status =
+ acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
+ walk_state);
+ } else {
+ status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
-
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 794c7df3f2ad..d80e92639932 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -46,15 +46,16 @@
#include <acpi/acpi.h>
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utdebug")
-
+ACPI_MODULE_NAME("utdebug")
#ifdef ACPI_DEBUG_OUTPUT
+static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF;
+static char *acpi_gbl_fn_entry_str = "----Entry";
+static char *acpi_gbl_fn_exit_str = "----Exit-";
-static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF;
-static char *acpi_gbl_fn_entry_str = "----Entry";
-static char *acpi_gbl_fn_exit_str = "----Exit-";
+/* Local prototypes */
+static const char *acpi_ut_trim_function_name(const char *function_name);
/*******************************************************************************
*
@@ -68,17 +69,13 @@ static char *acpi_gbl_fn_exit_str = "----Exit-";
*
******************************************************************************/
-void
-acpi_ut_init_stack_ptr_trace (
- void)
+void acpi_ut_init_stack_ptr_trace(void)
{
- u32 current_sp;
-
+ u32 current_sp;
- acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (&current_sp, NULL);
+ acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF(&current_sp, NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_track_stack_ptr
@@ -91,14 +88,11 @@ acpi_ut_init_stack_ptr_trace (
*
******************************************************************************/
-void
-acpi_ut_track_stack_ptr (
- void)
+void acpi_ut_track_stack_ptr(void)
{
- acpi_size current_sp;
-
+ acpi_size current_sp;
- current_sp = ACPI_PTR_DIFF (&current_sp, NULL);
+ current_sp = ACPI_PTR_DIFF(&current_sp, NULL);
if (current_sp < acpi_gbl_lowest_stack_pointer) {
acpi_gbl_lowest_stack_pointer = current_sp;
@@ -109,6 +103,39 @@ acpi_ut_track_stack_ptr (
}
}
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_trim_function_name
+ *
+ * PARAMETERS: function_name - Ascii string containing a procedure name
+ *
+ * RETURN: Updated pointer to the function name
+ *
+ * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
+ * This allows compiler macros such as __FUNCTION__ to be used
+ * with no change to the debug output.
+ *
+ ******************************************************************************/
+
+static const char *acpi_ut_trim_function_name(const char *function_name)
+{
+
+ /* All Function names are longer than 4 chars, check is safe */
+
+ if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_MIXED) {
+ /* This is the case where the original source has not been modified */
+
+ return (function_name + 4);
+ }
+
+ if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_LOWER) {
+ /* This is the case where the source has been 'linuxized' */
+
+ return (function_name + 5);
+ }
+
+ return (function_name);
+}
/*******************************************************************************
*
@@ -116,10 +143,9 @@ acpi_ut_track_stack_ptr (
*
* PARAMETERS: requested_debug_level - Requested debug print level
* line_number - Caller's line number (for error output)
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Format - Printf format field
* ... - Optional printf arguments
*
@@ -130,36 +156,33 @@ acpi_ut_track_stack_ptr (
*
******************************************************************************/
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_debug_print (
- u32 requested_debug_level,
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- char *format,
- ...)
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print(u32 requested_debug_level,
+ u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, char *format, ...)
{
- u32 thread_id;
- va_list args;
-
+ u32 thread_id;
+ va_list args;
/*
* Stay silent if the debug level or component ID is disabled
*/
if (!(requested_debug_level & acpi_dbg_level) ||
- !(dbg_info->component_id & acpi_dbg_layer)) {
+ !(component_id & acpi_dbg_layer)) {
return;
}
/*
* Thread tracking and context switch notification
*/
- thread_id = acpi_os_get_thread_id ();
+ thread_id = acpi_os_get_thread_id();
if (thread_id != acpi_gbl_prev_thread_id) {
if (ACPI_LV_THREADS & acpi_dbg_level) {
- acpi_os_printf (
- "\n**** Context Switch from TID %X to TID %X ****\n\n",
- acpi_gbl_prev_thread_id, thread_id);
+ acpi_os_printf
+ ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+ acpi_gbl_prev_thread_id, thread_id);
}
acpi_gbl_prev_thread_id = thread_id;
@@ -169,17 +192,18 @@ acpi_ut_debug_print (
* Display the module name, current line number, thread ID (if requested),
* current procedure nesting level, and the current procedure name
*/
- acpi_os_printf ("%8s-%04ld ", dbg_info->module_name, line_number);
+ acpi_os_printf("%8s-%04ld ", module_name, line_number);
if (ACPI_LV_THREADS & acpi_dbg_level) {
- acpi_os_printf ("[%04lX] ", thread_id);
+ acpi_os_printf("[%04lX] ", thread_id);
}
- acpi_os_printf ("[%02ld] %-22.22s: ",
- acpi_gbl_nesting_level, dbg_info->proc_name);
+ acpi_os_printf("[%02ld] %-22.22s: ",
+ acpi_gbl_nesting_level,
+ acpi_ut_trim_function_name(function_name));
- va_start (args, format);
- acpi_os_vprintf (format, args);
+ va_start(args, format);
+ acpi_os_vprintf(format, args);
}
EXPORT_SYMBOL(acpi_ut_debug_print);
@@ -190,10 +214,9 @@ EXPORT_SYMBOL(acpi_ut_debug_print);
*
* PARAMETERS: requested_debug_level - Requested debug print level
* line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Format - Printf format field
* ... - Optional printf arguments
*
@@ -204,37 +227,33 @@ EXPORT_SYMBOL(acpi_ut_debug_print);
*
******************************************************************************/
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_debug_print_raw (
- u32 requested_debug_level,
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- char *format,
- ...)
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print_raw(u32 requested_debug_level,
+ u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, char *format, ...)
{
- va_list args;
-
+ va_list args;
if (!(requested_debug_level & acpi_dbg_level) ||
- !(dbg_info->component_id & acpi_dbg_layer)) {
+ !(component_id & acpi_dbg_layer)) {
return;
}
- va_start (args, format);
- acpi_os_vprintf (format, args);
+ va_start(args, format);
+ acpi_os_vprintf(format, args);
}
-EXPORT_SYMBOL(acpi_ut_debug_print_raw);
+EXPORT_SYMBOL(acpi_ut_debug_print_raw);
/*******************************************************************************
*
* FUNCTION: acpi_ut_trace
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
*
* RETURN: None
*
@@ -244,29 +263,28 @@ EXPORT_SYMBOL(acpi_ut_debug_print_raw);
******************************************************************************/
void
-acpi_ut_trace (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info)
+acpi_ut_trace(u32 line_number,
+ const char *function_name, char *module_name, u32 component_id)
{
acpi_gbl_nesting_level++;
- acpi_ut_track_stack_ptr ();
+ acpi_ut_track_stack_ptr();
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s\n", acpi_gbl_fn_entry_str);
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s\n", acpi_gbl_fn_entry_str);
}
-EXPORT_SYMBOL(acpi_ut_trace);
+EXPORT_SYMBOL(acpi_ut_trace);
/*******************************************************************************
*
* FUNCTION: acpi_ut_trace_ptr
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Pointer - Pointer to display
*
* RETURN: None
@@ -277,28 +295,27 @@ EXPORT_SYMBOL(acpi_ut_trace);
******************************************************************************/
void
-acpi_ut_trace_ptr (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- void *pointer)
+acpi_ut_trace_ptr(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, void *pointer)
{
acpi_gbl_nesting_level++;
- acpi_ut_track_stack_ptr ();
+ acpi_ut_track_stack_ptr();
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s %p\n", acpi_gbl_fn_entry_str, pointer);
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s %p\n", acpi_gbl_fn_entry_str,
+ pointer);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_trace_str
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* String - Additional string to display
*
* RETURN: None
@@ -309,29 +326,28 @@ acpi_ut_trace_ptr (
******************************************************************************/
void
-acpi_ut_trace_str (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- char *string)
+acpi_ut_trace_str(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, char *string)
{
acpi_gbl_nesting_level++;
- acpi_ut_track_stack_ptr ();
+ acpi_ut_track_stack_ptr();
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s %s\n", acpi_gbl_fn_entry_str, string);
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s %s\n", acpi_gbl_fn_entry_str,
+ string);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_trace_u32
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Integer - Integer to display
*
* RETURN: None
@@ -342,29 +358,28 @@ acpi_ut_trace_str (
******************************************************************************/
void
-acpi_ut_trace_u32 (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- u32 integer)
+acpi_ut_trace_u32(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, u32 integer)
{
acpi_gbl_nesting_level++;
- acpi_ut_track_stack_ptr ();
+ acpi_ut_track_stack_ptr();
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s %08X\n", acpi_gbl_fn_entry_str, integer);
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s %08X\n", acpi_gbl_fn_entry_str,
+ integer);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_exit
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
*
* RETURN: None
*
@@ -374,28 +389,27 @@ acpi_ut_trace_u32 (
******************************************************************************/
void
-acpi_ut_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info)
+acpi_ut_exit(u32 line_number,
+ const char *function_name, char *module_name, u32 component_id)
{
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s\n", acpi_gbl_fn_exit_str);
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s\n", acpi_gbl_fn_exit_str);
acpi_gbl_nesting_level--;
}
-EXPORT_SYMBOL(acpi_ut_exit);
+EXPORT_SYMBOL(acpi_ut_exit);
/*******************************************************************************
*
* FUNCTION: acpi_ut_status_exit
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Status - Exit status code
*
* RETURN: None
@@ -406,37 +420,38 @@ EXPORT_SYMBOL(acpi_ut_exit);
******************************************************************************/
void
-acpi_ut_status_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- acpi_status status)
+acpi_ut_status_exit(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, acpi_status status)
{
- if (ACPI_SUCCESS (status)) {
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s %s\n", acpi_gbl_fn_exit_str,
- acpi_format_exception (status));
- }
- else {
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s ****Exception****: %s\n", acpi_gbl_fn_exit_str,
- acpi_format_exception (status));
+ if (ACPI_SUCCESS(status)) {
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s %s\n",
+ acpi_gbl_fn_exit_str,
+ acpi_format_exception(status));
+ } else {
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s ****Exception****: %s\n",
+ acpi_gbl_fn_exit_str,
+ acpi_format_exception(status));
}
acpi_gbl_nesting_level--;
}
-EXPORT_SYMBOL(acpi_ut_status_exit);
+EXPORT_SYMBOL(acpi_ut_status_exit);
/*******************************************************************************
*
* FUNCTION: acpi_ut_value_exit
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Value - Value to be printed with exit msg
*
* RETURN: None
@@ -447,30 +462,29 @@ EXPORT_SYMBOL(acpi_ut_status_exit);
******************************************************************************/
void
-acpi_ut_value_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- acpi_integer value)
+acpi_ut_value_exit(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, acpi_integer value)
{
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
- ACPI_FORMAT_UINT64 (value));
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s %8.8X%8.8X\n",
+ acpi_gbl_fn_exit_str, ACPI_FORMAT_UINT64(value));
acpi_gbl_nesting_level--;
}
-EXPORT_SYMBOL(acpi_ut_value_exit);
+EXPORT_SYMBOL(acpi_ut_value_exit);
/*******************************************************************************
*
* FUNCTION: acpi_ut_ptr_exit
*
* PARAMETERS: line_number - Caller's line number
- * dbg_info - Contains:
- * proc_name - Caller's procedure name
- * module_name - Caller's module name
- * component_id - Caller's component ID
+ * function_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Ptr - Pointer to display
*
* RETURN: None
@@ -481,21 +495,20 @@ EXPORT_SYMBOL(acpi_ut_value_exit);
******************************************************************************/
void
-acpi_ut_ptr_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- u8 *ptr)
+acpi_ut_ptr_exit(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, u8 * ptr)
{
- acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
- "%s %p\n", acpi_gbl_fn_exit_str, ptr);
+ acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
+ line_number, function_name, module_name,
+ component_id, "%s %p\n", acpi_gbl_fn_exit_str, ptr);
acpi_gbl_nesting_level--;
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_dump_buffer
@@ -511,23 +524,17 @@ acpi_ut_ptr_exit (
*
******************************************************************************/
-void
-acpi_ut_dump_buffer (
- u8 *buffer,
- u32 count,
- u32 display,
- u32 component_id)
+void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id)
{
- acpi_native_uint i = 0;
- acpi_native_uint j;
- u32 temp32;
- u8 buf_char;
-
+ acpi_native_uint i = 0;
+ acpi_native_uint j;
+ u32 temp32;
+ u8 buf_char;
/* Only dump the buffer if tracing is enabled */
if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
- (component_id & acpi_dbg_layer))) {
+ (component_id & acpi_dbg_layer))) {
return;
}
@@ -540,7 +547,7 @@ acpi_ut_dump_buffer (
while (i < count) {
/* Print current offset */
- acpi_os_printf ("%6.4X: ", (u32) i);
+ acpi_os_printf("%6.4X: ", (u32) i);
/* Print 16 hex chars */
@@ -548,73 +555,66 @@ acpi_ut_dump_buffer (
if (i + j >= count) {
/* Dump fill spaces */
- acpi_os_printf ("%*s", ((display * 2) + 1), " ");
- j += display;
+ acpi_os_printf("%*s", ((display * 2) + 1), " ");
+ j += (acpi_native_uint) display;
continue;
}
switch (display) {
- default: /* Default is BYTE display */
+ default: /* Default is BYTE display */
- acpi_os_printf ("%02X ", buffer[i + j]);
+ acpi_os_printf("%02X ", buffer[i + j]);
break;
-
case DB_WORD_DISPLAY:
- ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]);
- acpi_os_printf ("%04X ", temp32);
+ ACPI_MOVE_16_TO_32(&temp32, &buffer[i + j]);
+ acpi_os_printf("%04X ", temp32);
break;
-
case DB_DWORD_DISPLAY:
- ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
- acpi_os_printf ("%08X ", temp32);
+ ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]);
+ acpi_os_printf("%08X ", temp32);
break;
-
case DB_QWORD_DISPLAY:
- ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
- acpi_os_printf ("%08X", temp32);
+ ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]);
+ acpi_os_printf("%08X", temp32);
- ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]);
- acpi_os_printf ("%08X ", temp32);
+ ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j + 4]);
+ acpi_os_printf("%08X ", temp32);
break;
}
- j += display;
+ j += (acpi_native_uint) display;
}
/*
- * Print the ASCII equivalent characters
- * But watch out for the bad unprintable ones...
+ * Print the ASCII equivalent characters but watch out for the bad
+ * unprintable ones (printable chars are 0x20 through 0x7E)
*/
- acpi_os_printf (" ");
+ acpi_os_printf(" ");
for (j = 0; j < 16; j++) {
if (i + j >= count) {
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
return;
}
buf_char = buffer[i + j];
- if ((buf_char > 0x1F && buf_char < 0x2E) ||
- (buf_char > 0x2F && buf_char < 0x61) ||
- (buf_char > 0x60 && buf_char < 0x7F)) {
- acpi_os_printf ("%c", buf_char);
- }
- else {
- acpi_os_printf (".");
+ if (ACPI_IS_PRINT(buf_char)) {
+ acpi_os_printf("%c", buf_char);
+ } else {
+ acpi_os_printf(".");
}
}
/* Done with that line. */
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
i += 16;
}
return;
}
-
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index bc5403022681..2bc878f7a127 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -41,7 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
@@ -49,19 +48,13 @@
#include <acpi/amlcode.h>
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utdelete")
+ACPI_MODULE_NAME("utdelete")
/* Local prototypes */
+static void acpi_ut_delete_internal_obj(union acpi_operand_object *object);
static void
-acpi_ut_delete_internal_obj (
- union acpi_operand_object *object);
-
-static void
-acpi_ut_update_ref_count (
- union acpi_operand_object *object,
- u32 action);
-
+acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action);
/*******************************************************************************
*
@@ -76,18 +69,14 @@ acpi_ut_update_ref_count (
*
******************************************************************************/
-static void
-acpi_ut_delete_internal_obj (
- union acpi_operand_object *object)
+static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
{
- void *obj_pointer = NULL;
- union acpi_operand_object *handler_desc;
- union acpi_operand_object *second_desc;
- union acpi_operand_object *next_desc;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
+ void *obj_pointer = NULL;
+ union acpi_operand_object *handler_desc;
+ union acpi_operand_object *second_desc;
+ union acpi_operand_object *next_desc;
+ ACPI_FUNCTION_TRACE_PTR("ut_delete_internal_obj", object);
if (!object) {
return_VOID;
@@ -97,11 +86,12 @@ acpi_ut_delete_internal_obj (
* Must delete or free any pointers within the object that are not
* actual ACPI objects (for example, a raw buffer pointer).
*/
- switch (ACPI_GET_OBJECT_TYPE (object)) {
+ switch (ACPI_GET_OBJECT_TYPE(object)) {
case ACPI_TYPE_STRING:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
- object, object->string.pointer));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "**** String %p, ptr %p\n", object,
+ object->string.pointer));
/* Free the actual string buffer */
@@ -112,11 +102,11 @@ acpi_ut_delete_internal_obj (
}
break;
-
case ACPI_TYPE_BUFFER:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
- object, object->buffer.pointer));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "**** Buffer %p, ptr %p\n", object,
+ object->buffer.pointer));
/* Free the actual buffer */
@@ -127,11 +117,11 @@ acpi_ut_delete_internal_obj (
}
break;
-
case ACPI_TYPE_PACKAGE:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
- object->package.count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ " **** Package of count %X\n",
+ object->package.count));
/*
* Elements of the package are not handled here, they are deleted
@@ -143,11 +133,11 @@ acpi_ut_delete_internal_obj (
obj_pointer = object->package.elements;
break;
-
case ACPI_TYPE_DEVICE:
if (object->device.gpe_block) {
- (void) acpi_ev_delete_gpe_block (object->device.gpe_block);
+ (void)acpi_ev_delete_gpe_block(object->device.
+ gpe_block);
}
/* Walk the handler list for this device */
@@ -155,54 +145,51 @@ acpi_ut_delete_internal_obj (
handler_desc = object->device.handler;
while (handler_desc) {
next_desc = handler_desc->address_space.next;
- acpi_ut_remove_reference (handler_desc);
+ acpi_ut_remove_reference(handler_desc);
handler_desc = next_desc;
}
break;
-
case ACPI_TYPE_MUTEX:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "***** Mutex %p, Semaphore %p\n",
- object, object->mutex.semaphore));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "***** Mutex %p, Semaphore %p\n",
+ object, object->mutex.semaphore));
- acpi_ex_unlink_mutex (object);
- (void) acpi_os_delete_semaphore (object->mutex.semaphore);
+ acpi_ex_unlink_mutex(object);
+ (void)acpi_os_delete_semaphore(object->mutex.semaphore);
break;
-
case ACPI_TYPE_EVENT:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "***** Event %p, Semaphore %p\n",
- object, object->event.semaphore));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "***** Event %p, Semaphore %p\n",
+ object, object->event.semaphore));
- (void) acpi_os_delete_semaphore (object->event.semaphore);
+ (void)acpi_os_delete_semaphore(object->event.semaphore);
object->event.semaphore = NULL;
break;
-
case ACPI_TYPE_METHOD:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "***** Method %p\n", object));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "***** Method %p\n", object));
/* Delete the method semaphore if it exists */
if (object->method.semaphore) {
- (void) acpi_os_delete_semaphore (object->method.semaphore);
+ (void)acpi_os_delete_semaphore(object->method.
+ semaphore);
object->method.semaphore = NULL;
}
break;
-
case ACPI_TYPE_REGION:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "***** Region %p\n", object));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "***** Region %p\n", object));
- second_desc = acpi_ns_get_secondary_object (object);
+ second_desc = acpi_ns_get_secondary_object(object);
if (second_desc) {
/*
* Free the region_context if and only if the handler is one of the
@@ -211,32 +198,33 @@ acpi_ut_delete_internal_obj (
*/
handler_desc = object->region.handler;
if (handler_desc) {
- if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
- obj_pointer = second_desc->extra.region_context;
+ if (handler_desc->address_space.
+ hflags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+ obj_pointer =
+ second_desc->extra.region_context;
}
- acpi_ut_remove_reference (handler_desc);
+ acpi_ut_remove_reference(handler_desc);
}
/* Now we can free the Extra object */
- acpi_ut_delete_object_desc (second_desc);
+ acpi_ut_delete_object_desc(second_desc);
}
break;
-
case ACPI_TYPE_BUFFER_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "***** Buffer Field %p\n", object));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "***** Buffer Field %p\n", object));
- second_desc = acpi_ns_get_secondary_object (object);
+ second_desc = acpi_ns_get_secondary_object(object);
if (second_desc) {
- acpi_ut_delete_object_desc (second_desc);
+ acpi_ut_delete_object_desc(second_desc);
}
break;
-
default:
break;
}
@@ -244,21 +232,20 @@ acpi_ut_delete_internal_obj (
/* Free any allocated memory (pointer within the object) found above */
if (obj_pointer) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
- obj_pointer));
- ACPI_MEM_FREE (obj_pointer);
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Deleting Object Subptr %p\n", obj_pointer));
+ ACPI_MEM_FREE(obj_pointer);
}
/* Now the object can be safely deleted */
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
- object, acpi_ut_get_object_type_name (object)));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
+ object, acpi_ut_get_object_type_name(object)));
- acpi_ut_delete_object_desc (object);
+ acpi_ut_delete_object_desc(object);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_delete_internal_object_list
@@ -272,29 +259,24 @@ acpi_ut_delete_internal_obj (
*
******************************************************************************/
-void
-acpi_ut_delete_internal_object_list (
- union acpi_operand_object **obj_list)
+void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
{
- union acpi_operand_object **internal_obj;
-
-
- ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list");
+ union acpi_operand_object **internal_obj;
+ ACPI_FUNCTION_TRACE("ut_delete_internal_object_list");
/* Walk the null-terminated internal list */
for (internal_obj = obj_list; *internal_obj; internal_obj++) {
- acpi_ut_remove_reference (*internal_obj);
+ acpi_ut_remove_reference(*internal_obj);
}
/* Free the combined parameter pointer list and object array */
- ACPI_MEM_FREE (obj_list);
+ ACPI_MEM_FREE(obj_list);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_update_ref_count
@@ -309,16 +291,12 @@ acpi_ut_delete_internal_object_list (
******************************************************************************/
static void
-acpi_ut_update_ref_count (
- union acpi_operand_object *object,
- u32 action)
+acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
{
- u16 count;
- u16 new_count;
-
-
- ACPI_FUNCTION_NAME ("ut_update_ref_count");
+ u16 count;
+ u16 new_count;
+ ACPI_FUNCTION_NAME("ut_update_ref_count");
if (!object) {
return;
@@ -338,58 +316,55 @@ acpi_ut_update_ref_count (
new_count++;
object->common.reference_count = new_count;
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, [Incremented]\n",
- object, new_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, [Incremented]\n",
+ object, new_count));
break;
-
case REF_DECREMENT:
if (count < 1) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
- object, new_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
+ object, new_count));
new_count = 0;
- }
- else {
+ } else {
new_count--;
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, [Decremented]\n",
- object, new_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, [Decremented]\n",
+ object, new_count));
}
- if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Method Obj %p Refs=%X, [Decremented]\n",
- object, new_count));
+ if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Method Obj %p Refs=%X, [Decremented]\n",
+ object, new_count));
}
object->common.reference_count = new_count;
if (new_count == 0) {
- acpi_ut_delete_internal_obj (object);
+ acpi_ut_delete_internal_obj(object);
}
break;
-
case REF_FORCE_DELETE:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, Force delete! (Set to 0)\n",
- object, count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, Force delete! (Set to 0)\n",
+ object, count));
new_count = 0;
object->common.reference_count = new_count;
- acpi_ut_delete_internal_obj (object);
+ acpi_ut_delete_internal_obj(object);
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", action));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown action (%X)\n",
+ action));
break;
}
@@ -399,15 +374,14 @@ acpi_ut_update_ref_count (
*/
if (count > ACPI_MAX_REFERENCE_COUNT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
- "**** Warning **** Large Reference Count (%X) in object %p\n\n",
- count, object));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "**** Warning **** Large Reference Count (%X) in object %p\n\n",
+ count, object));
}
return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_update_object_reference
@@ -431,65 +405,42 @@ acpi_ut_update_ref_count (
******************************************************************************/
acpi_status
-acpi_ut_update_object_reference (
- union acpi_operand_object *object,
- u16 action)
+acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action)
{
- acpi_status status;
- u32 i;
- union acpi_generic_state *state_list = NULL;
- union acpi_generic_state *state;
- union acpi_operand_object *tmp;
-
- ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);
+ acpi_status status = AE_OK;
+ union acpi_generic_state *state_list = NULL;
+ union acpi_operand_object *next_object = NULL;
+ union acpi_generic_state *state;
+ acpi_native_uint i;
+ ACPI_FUNCTION_TRACE_PTR("ut_update_object_reference", object);
- /* Ignore a null object ptr */
+ while (object) {
+ /* Make sure that this isn't a namespace handle */
- if (!object) {
- return_ACPI_STATUS (AE_OK);
- }
-
- /* Make sure that this isn't a namespace handle */
-
- if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Object %p is NS handle\n", object));
- return_ACPI_STATUS (AE_OK);
- }
-
- state = acpi_ut_create_update_state (object, action);
-
- while (state) {
- object = state->update.object;
- action = state->update.value;
- acpi_ut_delete_generic_state (state);
+ if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Object %p is NS handle\n", object));
+ return_ACPI_STATUS(AE_OK);
+ }
/*
* All sub-objects must have their reference count incremented also.
* Different object types have different subobjects.
*/
- switch (ACPI_GET_OBJECT_TYPE (object)) {
+ switch (ACPI_GET_OBJECT_TYPE(object)) {
case ACPI_TYPE_DEVICE:
- tmp = object->device.system_notify;
- if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->device.system_notify = NULL;
- acpi_ut_update_ref_count (tmp, action);
-
- tmp = object->device.device_notify;
- if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->device.device_notify = NULL;
- acpi_ut_update_ref_count (tmp, action);
-
+ acpi_ut_update_ref_count(object->device.system_notify,
+ action);
+ acpi_ut_update_ref_count(object->device.device_notify,
+ action);
break;
-
case ACPI_TYPE_PACKAGE:
-
/*
- * We must update all the sub-objects of the package
- * (Each of whom may have their own sub-objects, etc.
+ * We must update all the sub-objects of the package,
+ * each of whom may have their own sub-objects.
*/
for (i = 0; i < object->package.count; i++) {
/*
@@ -497,116 +448,67 @@ acpi_ut_update_object_reference (
* Note: There can be null elements within the package,
* these are simply ignored
*/
- status = acpi_ut_create_update_state_and_push (
- object->package.elements[i], action, &state_list);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_create_update_state_and_push
+ (object->package.elements[i], action,
+ &state_list);
+ if (ACPI_FAILURE(status)) {
goto error_exit;
}
-
- tmp = object->package.elements[i];
- if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->package.elements[i] = NULL;
}
break;
-
case ACPI_TYPE_BUFFER_FIELD:
- status = acpi_ut_create_update_state_and_push (
- object->buffer_field.buffer_obj, action, &state_list);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
-
- tmp = object->buffer_field.buffer_obj;
- if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->buffer_field.buffer_obj = NULL;
+ next_object = object->buffer_field.buffer_obj;
break;
-
case ACPI_TYPE_LOCAL_REGION_FIELD:
- status = acpi_ut_create_update_state_and_push (
- object->field.region_obj, action, &state_list);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
-
- tmp = object->field.region_obj;
- if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->field.region_obj = NULL;
- break;
-
+ next_object = object->field.region_obj;
+ break;
case ACPI_TYPE_LOCAL_BANK_FIELD:
- status = acpi_ut_create_update_state_and_push (
- object->bank_field.bank_obj, action, &state_list);
- if (ACPI_FAILURE (status)) {
+ next_object = object->bank_field.bank_obj;
+ status =
+ acpi_ut_create_update_state_and_push(object->
+ bank_field.
+ region_obj,
+ action,
+ &state_list);
+ if (ACPI_FAILURE(status)) {
goto error_exit;
}
-
- tmp = object->bank_field.bank_obj;
- if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->bank_field.bank_obj = NULL;
-
- status = acpi_ut_create_update_state_and_push (
- object->bank_field.region_obj, action, &state_list);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
-
- tmp = object->bank_field.region_obj;
- if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->bank_field.region_obj = NULL;
break;
-
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- status = acpi_ut_create_update_state_and_push (
- object->index_field.index_obj, action, &state_list);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
-
- tmp = object->index_field.index_obj;
- if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->index_field.index_obj = NULL;
-
- status = acpi_ut_create_update_state_and_push (
- object->index_field.data_obj, action, &state_list);
- if (ACPI_FAILURE (status)) {
+ next_object = object->index_field.index_obj;
+ status =
+ acpi_ut_create_update_state_and_push(object->
+ index_field.
+ data_obj,
+ action,
+ &state_list);
+ if (ACPI_FAILURE(status)) {
goto error_exit;
}
-
- tmp = object->index_field.data_obj;
- if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
- object->index_field.data_obj = NULL;
break;
-
case ACPI_TYPE_LOCAL_REFERENCE:
-
/*
* The target of an Index (a package, string, or buffer) must track
* changes to the ref count of the index.
*/
if (object->reference.opcode == AML_INDEX_OP) {
- status = acpi_ut_create_update_state_and_push (
- object->reference.object, action, &state_list);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
+ next_object = object->reference.object;
}
break;
-
case ACPI_TYPE_REGION:
default:
-
- /* No subobjects */
- break;
+ break; /* No subobjects */
}
/*
@@ -614,25 +516,31 @@ acpi_ut_update_object_reference (
* happen after we update the sub-objects in case this causes the
* main object to be deleted.
*/
- acpi_ut_update_ref_count (object, action);
+ acpi_ut_update_ref_count(object, action);
+ object = NULL;
/* Move on to the next object to be updated */
- state = acpi_ut_pop_generic_state (&state_list);
+ if (next_object) {
+ object = next_object;
+ next_object = NULL;
+ } else if (state_list) {
+ state = acpi_ut_pop_generic_state(&state_list);
+ object = state->update.object;
+ acpi_ut_delete_generic_state(state);
+ }
}
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(AE_OK);
-error_exit:
+ error_exit:
- ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
- acpi_format_exception (status)));
+ ACPI_REPORT_ERROR(("Could not update object reference count, %s\n",
+ acpi_format_exception(status)));
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_add_reference
@@ -646,31 +554,27 @@ error_exit:
*
******************************************************************************/
-void
-acpi_ut_add_reference (
- union acpi_operand_object *object)
+void acpi_ut_add_reference(union acpi_operand_object *object)
{
- ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
-
+ ACPI_FUNCTION_TRACE_PTR("ut_add_reference", object);
/* Ensure that we have a valid object */
- if (!acpi_ut_valid_internal_object (object)) {
+ if (!acpi_ut_valid_internal_object(object)) {
return_VOID;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Current Refs=%X [To Be Incremented]\n",
- object, object->common.reference_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Obj %p Current Refs=%X [To Be Incremented]\n",
+ object, object->common.reference_count));
/* Increment the reference count */
- (void) acpi_ut_update_object_reference (object, REF_INCREMENT);
+ (void)acpi_ut_update_object_reference(object, REF_INCREMENT);
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_remove_reference
@@ -683,13 +587,10 @@ acpi_ut_add_reference (
*
******************************************************************************/
-void
-acpi_ut_remove_reference (
- union acpi_operand_object *object)
+void acpi_ut_remove_reference(union acpi_operand_object *object)
{
- ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
-
+ ACPI_FUNCTION_TRACE_PTR("ut_remove_reference", object);
/*
* Allow a NULL pointer to be passed in, just ignore it. This saves
@@ -697,27 +598,25 @@ acpi_ut_remove_reference (
*
*/
if (!object ||
- (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) {
+ (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
return_VOID;
}
/* Ensure that we have a valid object */
- if (!acpi_ut_valid_internal_object (object)) {
+ if (!acpi_ut_valid_internal_object(object)) {
return_VOID;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Current Refs=%X [To Be Decremented]\n",
- object, object->common.reference_count));
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
+ "Obj %p Current Refs=%X [To Be Decremented]\n",
+ object, object->common.reference_count));
/*
* Decrement the reference count, and only actually delete the object
* if the reference count becomes 0. (Must also decrement the ref count
* of all subobjects!)
*/
- (void) acpi_ut_update_object_reference (object, REF_DECREMENT);
+ (void)acpi_ut_update_object_reference(object, REF_DECREMENT);
return_VOID;
}
-
-
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 00046dd5d925..7b81d5ef3c32 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -41,28 +41,20 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acinterp.h>
-
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("uteval")
+ACPI_MODULE_NAME("uteval")
/* Local prototypes */
-
static void
-acpi_ut_copy_id_string (
- char *destination,
- char *source,
- acpi_size max_length);
+acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
static acpi_status
-acpi_ut_translate_one_cid (
- union acpi_operand_object *obj_desc,
- struct acpi_compatible_id *one_cid);
-
+acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
+ struct acpi_compatible_id *one_cid);
/*******************************************************************************
*
@@ -77,37 +69,33 @@ acpi_ut_translate_one_cid (
*
******************************************************************************/
-acpi_status
-acpi_ut_osi_implementation (
- struct acpi_walk_state *walk_state)
+acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
{
- union acpi_operand_object *string_desc;
- union acpi_operand_object *return_desc;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_TRACE ("ut_osi_implementation");
+ union acpi_operand_object *string_desc;
+ union acpi_operand_object *return_desc;
+ acpi_native_uint i;
+ ACPI_FUNCTION_TRACE("ut_osi_implementation");
/* Validate the string input argument */
string_desc = walk_state->arguments[0].object;
if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
- return_ACPI_STATUS (AE_TYPE);
+ return_ACPI_STATUS(AE_TYPE);
}
/* Create a return object (Default value = 0) */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!return_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Compare input string to table of supported strings */
for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
- if (!ACPI_STRCMP (string_desc->string.pointer,
- (char *) acpi_gbl_valid_osi_strings[i])) {
+ if (!ACPI_STRCMP(string_desc->string.pointer,
+ (char *)acpi_gbl_valid_osi_strings[i])) {
/* This string is supported */
return_desc->integer.value = 0xFFFFFFFF;
@@ -116,10 +104,9 @@ acpi_ut_osi_implementation (
}
walk_state->return_desc = return_desc;
- return_ACPI_STATUS (AE_CTRL_TERMINATE);
+ return_ACPI_STATUS(AE_CTRL_TERMINATE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_evaluate_object
@@ -140,19 +127,16 @@ acpi_ut_osi_implementation (
******************************************************************************/
acpi_status
-acpi_ut_evaluate_object (
- struct acpi_namespace_node *prefix_node,
- char *path,
- u32 expected_return_btypes,
- union acpi_operand_object **return_desc)
+acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
+ char *path,
+ u32 expected_return_btypes,
+ union acpi_operand_object **return_desc)
{
- struct acpi_parameter_info info;
- acpi_status status;
- u32 return_btype;
-
-
- ACPI_FUNCTION_TRACE ("ut_evaluate_object");
+ struct acpi_parameter_info info;
+ acpi_status status;
+ u32 return_btype;
+ ACPI_FUNCTION_TRACE("ut_evaluate_object");
info.node = prefix_node;
info.parameters = NULL;
@@ -160,36 +144,38 @@ acpi_ut_evaluate_object (
/* Evaluate the object/method */
- status = acpi_ns_evaluate_relative (path, &info);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ns_evaluate_relative(path, &info);
+ if (ACPI_FAILURE(status)) {
if (status == AE_NOT_FOUND) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
- acpi_ut_get_node_name (prefix_node), path));
- }
- else {
- ACPI_REPORT_METHOD_ERROR ("Method execution failed",
- prefix_node, path, status);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[%4.4s.%s] was not found\n",
+ acpi_ut_get_node_name(prefix_node),
+ path));
+ } else {
+ ACPI_REPORT_METHOD_ERROR("Method execution failed",
+ prefix_node, path, status);
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Did we get a return object? */
if (!info.return_object) {
if (expected_return_btypes) {
- ACPI_REPORT_METHOD_ERROR ("No object was returned from",
- prefix_node, path, AE_NOT_EXIST);
+ ACPI_REPORT_METHOD_ERROR("No object was returned from",
+ prefix_node, path,
+ AE_NOT_EXIST);
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Map the return object type to the bitmapped type */
- switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
+ switch (ACPI_GET_OBJECT_TYPE(info.return_object)) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_BTYPE_INTEGER;
break;
@@ -211,41 +197,41 @@ acpi_ut_evaluate_object (
break;
}
- if ((acpi_gbl_enable_interpreter_slack) &&
- (!expected_return_btypes)) {
+ if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
/*
* We received a return object, but one was not expected. This can
* happen frequently if the "implicit return" feature is enabled.
* Just delete the return object and return AE_OK.
*/
- acpi_ut_remove_reference (info.return_object);
- return_ACPI_STATUS (AE_OK);
+ acpi_ut_remove_reference(info.return_object);
+ return_ACPI_STATUS(AE_OK);
}
/* Is the return object one of the expected types? */
if (!(expected_return_btypes & return_btype)) {
- ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
- prefix_node, path, AE_TYPE);
+ ACPI_REPORT_METHOD_ERROR("Return object type is incorrect",
+ prefix_node, path, AE_TYPE);
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Type returned from %s was incorrect: %s, expected Btypes: %X\n",
- path, acpi_ut_get_object_type_name (info.return_object),
- expected_return_btypes));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Type returned from %s was incorrect: %s, expected Btypes: %X\n",
+ path,
+ acpi_ut_get_object_type_name(info.
+ return_object),
+ expected_return_btypes));
/* On error exit, we must delete the return object */
- acpi_ut_remove_reference (info.return_object);
- return_ACPI_STATUS (AE_TYPE);
+ acpi_ut_remove_reference(info.return_object);
+ return_ACPI_STATUS(AE_TYPE);
}
/* Object type is OK, return it */
*return_desc = info.return_object;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_evaluate_numeric_object
@@ -264,22 +250,19 @@ acpi_ut_evaluate_object (
******************************************************************************/
acpi_status
-acpi_ut_evaluate_numeric_object (
- char *object_name,
- struct acpi_namespace_node *device_node,
- acpi_integer *address)
+acpi_ut_evaluate_numeric_object(char *object_name,
+ struct acpi_namespace_node *device_node,
+ acpi_integer * address)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object");
+ ACPI_FUNCTION_TRACE("ut_evaluate_numeric_object");
-
- status = acpi_ut_evaluate_object (device_node, object_name,
- ACPI_BTYPE_INTEGER, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(device_node, object_name,
+ ACPI_BTYPE_INTEGER, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the returned Integer */
@@ -288,11 +271,10 @@ acpi_ut_evaluate_numeric_object (
/* On exit, we must delete the return object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_id_string
@@ -310,10 +292,7 @@ acpi_ut_evaluate_numeric_object (
******************************************************************************/
static void
-acpi_ut_copy_id_string (
- char *destination,
- char *source,
- acpi_size max_length)
+acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
{
/*
@@ -328,10 +307,9 @@ acpi_ut_copy_id_string (
/* Do the actual copy */
- ACPI_STRNCPY (destination, source, max_length);
+ ACPI_STRNCPY(destination, source, max_length);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_HID
@@ -349,42 +327,39 @@ acpi_ut_copy_id_string (
******************************************************************************/
acpi_status
-acpi_ut_execute_HID (
- struct acpi_namespace_node *device_node,
- struct acpi_device_id *hid)
+acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
+ struct acpi_device_id *hid)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("ut_execute_HID");
+ ACPI_FUNCTION_TRACE("ut_execute_HID");
-
- status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
- ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
/* Convert the Numeric HID to string */
- acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
- }
- else {
+ acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
+ hid->value);
+ } else {
/* Copy the String HID from the returned object */
- acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
- sizeof (hid->value));
+ acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
+ sizeof(hid->value));
}
/* On exit, we must delete the return object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_translate_one_cid
@@ -403,18 +378,17 @@ acpi_ut_execute_HID (
******************************************************************************/
static acpi_status
-acpi_ut_translate_one_cid (
- union acpi_operand_object *obj_desc,
- struct acpi_compatible_id *one_cid)
+acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
+ struct acpi_compatible_id *one_cid)
{
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_INTEGER:
/* Convert the Numeric CID to string */
- acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
+ acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
+ one_cid->value);
return (AE_OK);
case ACPI_TYPE_STRING:
@@ -425,8 +399,8 @@ acpi_ut_translate_one_cid (
/* Copy the String CID from the returned object */
- acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
- ACPI_MAX_CID_LENGTH);
+ acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
+ ACPI_MAX_CID_LENGTH);
return (AE_OK);
default:
@@ -435,7 +409,6 @@ acpi_ut_translate_one_cid (
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_CID
@@ -453,45 +426,42 @@ acpi_ut_translate_one_cid (
******************************************************************************/
acpi_status
-acpi_ut_execute_CID (
- struct acpi_namespace_node *device_node,
- struct acpi_compatible_id_list **return_cid_list)
+acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
+ struct acpi_compatible_id_list ** return_cid_list)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
- u32 count;
- u32 size;
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ u32 count;
+ u32 size;
struct acpi_compatible_id_list *cid_list;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_TRACE ("ut_execute_CID");
+ acpi_native_uint i;
+ ACPI_FUNCTION_TRACE("ut_execute_CID");
/* Evaluate the _CID method for this device */
- status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
- ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
- &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
+ | ACPI_BTYPE_PACKAGE, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Get the number of _CIDs returned */
count = 1;
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
count = obj_desc->package.count;
}
/* Allocate a worst-case buffer for the _CIDs */
- size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
- sizeof (struct acpi_compatible_id_list));
+ size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
+ sizeof(struct acpi_compatible_id_list));
- cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
+ cid_list = ACPI_MEM_CALLOCATE((acpi_size) size);
if (!cid_list) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Init CID list */
@@ -508,39 +478,38 @@ acpi_ut_execute_CID (
/* The _CID object can be either a single CID or a package (list) of CIDs */
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
/* Translate each package element */
for (i = 0; i < count; i++) {
- status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
- &cid_list->id[i]);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_translate_one_cid(obj_desc->package.
+ elements[i],
+ &cid_list->id[i]);
+ if (ACPI_FAILURE(status)) {
break;
}
}
- }
- else {
+ } else {
/* Only one CID, translate to a string */
- status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
+ status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
}
/* Cleanup on error */
- if (ACPI_FAILURE (status)) {
- ACPI_MEM_FREE (cid_list);
- }
- else {
+ if (ACPI_FAILURE(status)) {
+ ACPI_MEM_FREE(cid_list);
+ } else {
*return_cid_list = cid_list;
}
/* On exit, we must delete the _CID return object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_UID
@@ -558,42 +527,39 @@ acpi_ut_execute_CID (
******************************************************************************/
acpi_status
-acpi_ut_execute_UID (
- struct acpi_namespace_node *device_node,
- struct acpi_device_id *uid)
+acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
+ struct acpi_device_id *uid)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ut_execute_UID");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("ut_execute_UID");
- status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
- ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
/* Convert the Numeric UID to string */
- acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
- }
- else {
+ acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
+ uid->value);
+ } else {
/* Copy the String UID from the returned object */
- acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
- sizeof (uid->value));
+ acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
+ sizeof(uid->value));
}
/* On exit, we must delete the return object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_STA
@@ -611,30 +577,26 @@ acpi_ut_execute_UID (
******************************************************************************/
acpi_status
-acpi_ut_execute_STA (
- struct acpi_namespace_node *device_node,
- u32 *flags)
+acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
-
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
- ACPI_FUNCTION_TRACE ("ut_execute_STA");
+ ACPI_FUNCTION_TRACE("ut_execute_STA");
-
- status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
- ACPI_BTYPE_INTEGER, &obj_desc);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
+ ACPI_BTYPE_INTEGER, &obj_desc);
+ if (ACPI_FAILURE(status)) {
if (AE_NOT_FOUND == status) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "_STA on %4.4s was not found, assuming device is present\n",
- acpi_ut_get_node_name (device_node)));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "_STA on %4.4s was not found, assuming device is present\n",
+ acpi_ut_get_node_name(device_node)));
*flags = 0x0F;
status = AE_OK;
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/* Extract the status flags */
@@ -643,11 +605,10 @@ acpi_ut_execute_STA (
/* On exit, we must delete the return object */
- acpi_ut_remove_reference (obj_desc);
- return_ACPI_STATUS (status);
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_Sxds
@@ -665,44 +626,45 @@ acpi_ut_execute_STA (
******************************************************************************/
acpi_status
-acpi_ut_execute_sxds (
- struct acpi_namespace_node *device_node,
- u8 *highest)
+acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
{
- union acpi_operand_object *obj_desc;
- acpi_status status;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ u32 i;
+ ACPI_FUNCTION_TRACE("ut_execute_Sxds");
for (i = 0; i < 4; i++) {
highest[i] = 0xFF;
- status = acpi_ut_evaluate_object (device_node,
- (char *) acpi_gbl_highest_dstate_names[i],
- ACPI_BTYPE_INTEGER, &obj_desc);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ut_evaluate_object(device_node,
+ (char *)
+ acpi_gbl_highest_dstate_names
+ [i], ACPI_BTYPE_INTEGER,
+ &obj_desc);
+ if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "%s on Device %4.4s, %s\n",
- (char *) acpi_gbl_highest_dstate_names[i],
- acpi_ut_get_node_name (device_node),
- acpi_format_exception (status)));
-
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "%s on Device %4.4s, %s\n",
+ (char *)
+ acpi_gbl_highest_dstate_names
+ [i],
+ acpi_ut_get_node_name
+ (device_node),
+ acpi_format_exception
+ (status)));
+
+ return_ACPI_STATUS(status);
}
- }
- else {
+ } else {
/* Extract the Dstate value */
highest[i] = (u8) obj_desc->integer.value;
/* Delete the return object */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference(obj_desc);
}
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 4146019b543f..399e64b51886 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -48,8 +48,7 @@
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utglobal")
-
+ACPI_MODULE_NAME("utglobal")
/*******************************************************************************
*
@@ -63,17 +62,12 @@
* DESCRIPTION: This function translates an ACPI exception into an ASCII string.
*
******************************************************************************/
-
-const char *
-acpi_format_exception (
- acpi_status status)
+const char *acpi_format_exception(acpi_status status)
{
- acpi_status sub_status;
- const char *exception = NULL;
-
-
- ACPI_FUNCTION_NAME ("format_exception");
+ acpi_status sub_status;
+ const char *exception = NULL;
+ ACPI_FUNCTION_NAME("format_exception");
sub_status = (status & ~AE_CODE_MASK);
@@ -81,35 +75,39 @@ acpi_format_exception (
case AE_CODE_ENVIRONMENTAL:
if (sub_status <= AE_CODE_ENV_MAX) {
- exception = acpi_gbl_exception_names_env [sub_status];
+ exception = acpi_gbl_exception_names_env[sub_status];
}
break;
case AE_CODE_PROGRAMMER:
if (sub_status <= AE_CODE_PGM_MAX) {
- exception = acpi_gbl_exception_names_pgm [sub_status -1];
+ exception =
+ acpi_gbl_exception_names_pgm[sub_status - 1];
}
break;
case AE_CODE_ACPI_TABLES:
if (sub_status <= AE_CODE_TBL_MAX) {
- exception = acpi_gbl_exception_names_tbl [sub_status -1];
+ exception =
+ acpi_gbl_exception_names_tbl[sub_status - 1];
}
break;
case AE_CODE_AML:
if (sub_status <= AE_CODE_AML_MAX) {
- exception = acpi_gbl_exception_names_aml [sub_status -1];
+ exception =
+ acpi_gbl_exception_names_aml[sub_status - 1];
}
break;
case AE_CODE_CONTROL:
if (sub_status <= AE_CODE_CTRL_MAX) {
- exception = acpi_gbl_exception_names_ctrl [sub_status -1];
+ exception =
+ acpi_gbl_exception_names_ctrl[sub_status - 1];
}
break;
@@ -120,16 +118,15 @@ acpi_format_exception (
if (!exception) {
/* Exception code was not recognized */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown exception code: 0x%8.8X\n", status));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unknown exception code: 0x%8.8X\n", status));
- return ((const char *) "UNKNOWN_STATUS_CODE");
+ return ((const char *)"UNKNOWN_STATUS_CODE");
}
- return ((const char *) exception);
+ return ((const char *)exception);
}
-
/*******************************************************************************
*
* Static global variable initialization.
@@ -142,34 +139,32 @@ acpi_format_exception (
*/
/* Debug switch - level and trace mask */
-u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT;
+u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT;
EXPORT_SYMBOL(acpi_dbg_level);
/* Debug switch - layer (component) mask */
-u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
+u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
EXPORT_SYMBOL(acpi_dbg_layer);
-u32 acpi_gbl_nesting_level = 0;
-
+u32 acpi_gbl_nesting_level = 0;
/* Debugger globals */
-u8 acpi_gbl_db_terminate_threads = FALSE;
-u8 acpi_gbl_abort_method = FALSE;
-u8 acpi_gbl_method_executing = FALSE;
+u8 acpi_gbl_db_terminate_threads = FALSE;
+u8 acpi_gbl_abort_method = FALSE;
+u8 acpi_gbl_method_executing = FALSE;
/* System flags */
-u32 acpi_gbl_startup_flags = 0;
+u32 acpi_gbl_startup_flags = 0;
/* System starts uninitialized */
-u8 acpi_gbl_shutdown = TRUE;
+u8 acpi_gbl_shutdown = TRUE;
-const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
+const u8 acpi_gbl_decode_to8bit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
-const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] =
-{
+const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
"\\_S0_",
"\\_S1_",
"\\_S2_",
@@ -178,8 +173,7 @@ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COU
"\\_S5_"
};
-const char *acpi_gbl_highest_dstate_names[4] =
-{
+const char *acpi_gbl_highest_dstate_names[4] = {
"_S1D",
"_S2D",
"_S3D",
@@ -190,8 +184,7 @@ const char *acpi_gbl_highest_dstate_names[4] =
* Strings supported by the _OSI predefined (internal) method.
* When adding strings, be sure to update ACPI_NUM_OSI_STRINGS.
*/
-const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
-{
+const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = {
/* Operating System Vendor Strings */
"Linux",
@@ -209,7 +202,6 @@ const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STR
"Extended Address Space Descriptor"
};
-
/*******************************************************************************
*
* Namespace globals
@@ -225,74 +217,70 @@ const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STR
* 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
* perform a Notify() operation on it.
*/
-const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
-{ {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
- {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
- {"_SB_", ACPI_TYPE_DEVICE, NULL},
- {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
- {"_TZ_", ACPI_TYPE_THERMAL, NULL},
- {"_REV", ACPI_TYPE_INTEGER, (char *) ACPI_CA_SUPPORT_LEVEL},
- {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
- {"_GL_", ACPI_TYPE_MUTEX, (char *) 1},
+const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
+ { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
+{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+{"_SB_", ACPI_TYPE_DEVICE, NULL},
+{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+{"_TZ_", ACPI_TYPE_THERMAL, NULL},
+{"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
+{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
+{"_GL_", ACPI_TYPE_MUTEX, (char *)1},
#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
- {"_OSI", ACPI_TYPE_METHOD, (char *) 1},
+{"_OSI", ACPI_TYPE_METHOD, (char *)1},
#endif
/* Table terminator */
- {NULL, ACPI_TYPE_ANY, NULL}
+{NULL, ACPI_TYPE_ANY, NULL}
};
/*
* Properties of the ACPI Object Types, both internal and external.
* The table is indexed by values of acpi_object_type
*/
-const u8 acpi_gbl_ns_properties[] =
-{
- ACPI_NS_NORMAL, /* 00 Any */
- ACPI_NS_NORMAL, /* 01 Number */
- ACPI_NS_NORMAL, /* 02 String */
- ACPI_NS_NORMAL, /* 03 Buffer */
- ACPI_NS_NORMAL, /* 04 Package */
- ACPI_NS_NORMAL, /* 05 field_unit */
- ACPI_NS_NEWSCOPE, /* 06 Device */
- ACPI_NS_NORMAL, /* 07 Event */
- ACPI_NS_NEWSCOPE, /* 08 Method */
- ACPI_NS_NORMAL, /* 09 Mutex */
- ACPI_NS_NORMAL, /* 10 Region */
- ACPI_NS_NEWSCOPE, /* 11 Power */
- ACPI_NS_NEWSCOPE, /* 12 Processor */
- ACPI_NS_NEWSCOPE, /* 13 Thermal */
- ACPI_NS_NORMAL, /* 14 buffer_field */
- ACPI_NS_NORMAL, /* 15 ddb_handle */
- ACPI_NS_NORMAL, /* 16 Debug Object */
- ACPI_NS_NORMAL, /* 17 def_field */
- ACPI_NS_NORMAL, /* 18 bank_field */
- ACPI_NS_NORMAL, /* 19 index_field */
- ACPI_NS_NORMAL, /* 20 Reference */
- ACPI_NS_NORMAL, /* 21 Alias */
- ACPI_NS_NORMAL, /* 22 method_alias */
- ACPI_NS_NORMAL, /* 23 Notify */
- ACPI_NS_NORMAL, /* 24 Address Handler */
- ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
- ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
- ACPI_NS_NEWSCOPE, /* 27 Scope */
- ACPI_NS_NORMAL, /* 28 Extra */
- ACPI_NS_NORMAL, /* 29 Data */
- ACPI_NS_NORMAL /* 30 Invalid */
+const u8 acpi_gbl_ns_properties[] = {
+ ACPI_NS_NORMAL, /* 00 Any */
+ ACPI_NS_NORMAL, /* 01 Number */
+ ACPI_NS_NORMAL, /* 02 String */
+ ACPI_NS_NORMAL, /* 03 Buffer */
+ ACPI_NS_NORMAL, /* 04 Package */
+ ACPI_NS_NORMAL, /* 05 field_unit */
+ ACPI_NS_NEWSCOPE, /* 06 Device */
+ ACPI_NS_NORMAL, /* 07 Event */
+ ACPI_NS_NEWSCOPE, /* 08 Method */
+ ACPI_NS_NORMAL, /* 09 Mutex */
+ ACPI_NS_NORMAL, /* 10 Region */
+ ACPI_NS_NEWSCOPE, /* 11 Power */
+ ACPI_NS_NEWSCOPE, /* 12 Processor */
+ ACPI_NS_NEWSCOPE, /* 13 Thermal */
+ ACPI_NS_NORMAL, /* 14 buffer_field */
+ ACPI_NS_NORMAL, /* 15 ddb_handle */
+ ACPI_NS_NORMAL, /* 16 Debug Object */
+ ACPI_NS_NORMAL, /* 17 def_field */
+ ACPI_NS_NORMAL, /* 18 bank_field */
+ ACPI_NS_NORMAL, /* 19 index_field */
+ ACPI_NS_NORMAL, /* 20 Reference */
+ ACPI_NS_NORMAL, /* 21 Alias */
+ ACPI_NS_NORMAL, /* 22 method_alias */
+ ACPI_NS_NORMAL, /* 23 Notify */
+ ACPI_NS_NORMAL, /* 24 Address Handler */
+ ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
+ ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
+ ACPI_NS_NEWSCOPE, /* 27 Scope */
+ ACPI_NS_NORMAL, /* 28 Extra */
+ ACPI_NS_NORMAL, /* 29 Data */
+ ACPI_NS_NORMAL /* 30 Invalid */
};
-
/* Hex to ASCII conversion table */
-static const char acpi_gbl_hex_to_ascii[] =
-{
- '0','1','2','3','4','5','6','7',
- '8','9','A','B','C','D','E','F'
+static const char acpi_gbl_hex_to_ascii[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_hex_to_ascii_char
@@ -307,16 +295,12 @@ static const char acpi_gbl_hex_to_ascii[] =
*
******************************************************************************/
-char
-acpi_ut_hex_to_ascii_char (
- acpi_integer integer,
- u32 position)
+char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position)
{
return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
}
-
/*******************************************************************************
*
* Table name globals
@@ -330,67 +314,139 @@ acpi_ut_hex_to_ascii_char (
*
******************************************************************************/
-struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
-struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
-{
+struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] = {
/*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
- /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
- /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
- /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
- /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
- /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
- /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
- /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
+ /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1,
+ ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}
+ ,
+ /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *)&acpi_gbl_DSDT,
+ sizeof(DSDT_SIG) - 1,
+ ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE |
+ ACPI_TABLE_EXECUTABLE}
+ ,
+ /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *)&acpi_gbl_FADT,
+ sizeof(FADT_SIG) - 1,
+ ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE}
+ ,
+ /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *)&acpi_gbl_FACS,
+ sizeof(FACS_SIG) - 1,
+ ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE}
+ ,
+ /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof(PSDT_SIG) - 1,
+ ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE |
+ ACPI_TABLE_EXECUTABLE}
+ ,
+ /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof(SSDT_SIG) - 1,
+ ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE |
+ ACPI_TABLE_EXECUTABLE}
+ ,
+ /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof(RSDT_SIG) - 1,
+ ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}
+ ,
};
-
/******************************************************************************
*
* Event and Hardware globals
*
******************************************************************************/
-struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] =
-{
+struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
/* Name Parent Register Register Bit Position Register Bit Mask */
- /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_TIMER_STATUS, ACPI_BITMASK_TIMER_STATUS},
- /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_BUS_MASTER_STATUS, ACPI_BITMASK_BUS_MASTER_STATUS},
- /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_STATUS},
- /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_STATUS},
- /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS},
- /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS},
- /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS},
- /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, ACPI_BITMASK_PCIEXP_WAKE_STATUS},
-
- /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE},
- /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
- /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_ENABLE},
- /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
- /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE},
- /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0},
- /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
-
- /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE},
- /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD},
- /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
- /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X},
- /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X},
- /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_ENABLE, ACPI_BITMASK_SLEEP_ENABLE},
-
- /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, ACPI_BITPOSITION_ARB_DISABLE, ACPI_BITMASK_ARB_DISABLE}
+ /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_TIMER_STATUS,
+ ACPI_BITMASK_TIMER_STATUS},
+ /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_BUS_MASTER_STATUS,
+ ACPI_BITMASK_BUS_MASTER_STATUS},
+ /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_GLOBAL_LOCK_STATUS,
+ ACPI_BITMASK_GLOBAL_LOCK_STATUS},
+ /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_POWER_BUTTON_STATUS,
+ ACPI_BITMASK_POWER_BUTTON_STATUS},
+ /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_SLEEP_BUTTON_STATUS,
+ ACPI_BITMASK_SLEEP_BUTTON_STATUS},
+ /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_RT_CLOCK_STATUS,
+ ACPI_BITMASK_RT_CLOCK_STATUS},
+ /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_WAKE_STATUS,
+ ACPI_BITMASK_WAKE_STATUS},
+ /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITPOSITION_PCIEXP_WAKE_STATUS,
+ ACPI_BITMASK_PCIEXP_WAKE_STATUS},
+
+ /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
+ ACPI_BITPOSITION_TIMER_ENABLE,
+ ACPI_BITMASK_TIMER_ENABLE},
+ /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
+ ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE,
+ ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+ /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
+ ACPI_BITPOSITION_POWER_BUTTON_ENABLE,
+ ACPI_BITMASK_POWER_BUTTON_ENABLE},
+ /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
+ ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE,
+ ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+ /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
+ ACPI_BITPOSITION_RT_CLOCK_ENABLE,
+ ACPI_BITMASK_RT_CLOCK_ENABLE},
+ /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0},
+ /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE,
+ ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE,
+ ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
+
+ /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SCI_ENABLE,
+ ACPI_BITMASK_SCI_ENABLE},
+ /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_BUS_MASTER_RLD,
+ ACPI_BITMASK_BUS_MASTER_RLD},
+ /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
+ ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
+ /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SLEEP_TYPE_X,
+ ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SLEEP_TYPE_X,
+ ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SLEEP_ENABLE,
+ ACPI_BITMASK_SLEEP_ENABLE},
+
+ /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL,
+ ACPI_BITPOSITION_ARB_DISABLE,
+ ACPI_BITMASK_ARB_DISABLE}
};
-
-struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
-{
- /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS, ACPI_BITREG_TIMER_ENABLE, ACPI_BITMASK_TIMER_STATUS, ACPI_BITMASK_TIMER_ENABLE},
- /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, ACPI_BITREG_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
- /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_ENABLE},
- /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
- /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE},
+struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = {
+ /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS,
+ ACPI_BITREG_TIMER_ENABLE,
+ ACPI_BITMASK_TIMER_STATUS,
+ ACPI_BITMASK_TIMER_ENABLE},
+ /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS,
+ ACPI_BITREG_GLOBAL_LOCK_ENABLE,
+ ACPI_BITMASK_GLOBAL_LOCK_STATUS,
+ ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+ /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS,
+ ACPI_BITREG_POWER_BUTTON_ENABLE,
+ ACPI_BITMASK_POWER_BUTTON_STATUS,
+ ACPI_BITMASK_POWER_BUTTON_ENABLE},
+ /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS,
+ ACPI_BITREG_SLEEP_BUTTON_ENABLE,
+ ACPI_BITMASK_SLEEP_BUTTON_STATUS,
+ ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+ /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS,
+ ACPI_BITREG_RT_CLOCK_ENABLE,
+ ACPI_BITMASK_RT_CLOCK_STATUS,
+ ACPI_BITMASK_RT_CLOCK_ENABLE},
};
/*******************************************************************************
@@ -407,8 +463,7 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVE
/* Region type decoding */
-const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] =
-{
+const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
/*! [Begin] no source code translation (keep these ASL Keywords as-is) */
"SystemMemory",
"SystemIO",
@@ -421,25 +476,18 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] =
/*! [End] no source code translation !*/
};
-
-char *
-acpi_ut_get_region_name (
- u8 space_id)
+char *acpi_ut_get_region_name(u8 space_id)
{
- if (space_id >= ACPI_USER_REGION_BEGIN)
- {
+ if (space_id >= ACPI_USER_REGION_BEGIN) {
return ("user_defined_region");
- }
- else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS)
- {
+ } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
return ("invalid_space_id");
}
- return ((char *) acpi_gbl_region_types[space_id]);
+ return ((char *)acpi_gbl_region_types[space_id]);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_event_name
@@ -454,8 +502,7 @@ acpi_ut_get_region_name (
/* Event type decoding */
-static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] =
-{
+static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
"PM_Timer",
"global_lock",
"power_button",
@@ -463,21 +510,16 @@ static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] =
"real_time_clock",
};
-
-char *
-acpi_ut_get_event_name (
- u32 event_id)
+char *acpi_ut_get_event_name(u32 event_id)
{
- if (event_id > ACPI_EVENT_MAX)
- {
+ if (event_id > ACPI_EVENT_MAX) {
return ("invalid_event_iD");
}
- return ((char *) acpi_gbl_event_types[event_id]);
+ return ((char *)acpi_gbl_event_types[event_id]);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_type_name
@@ -498,12 +540,11 @@ acpi_ut_get_event_name (
* when stored in a table it really means that we have thus far seen no
* evidence to indicate what type is actually going to be stored for this entry.
*/
-static const char acpi_gbl_bad_type[] = "UNDEFINED";
+static const char acpi_gbl_bad_type[] = "UNDEFINED";
/* Printable names of the ACPI object types */
-static const char *acpi_gbl_ns_type_names[] =
-{
+static const char *acpi_gbl_ns_type_names[] = {
/* 00 */ "Untyped",
/* 01 */ "Integer",
/* 02 */ "String",
@@ -537,35 +578,26 @@ static const char *acpi_gbl_ns_type_names[] =
/* 30 */ "Invalid"
};
-
-char *
-acpi_ut_get_type_name (
- acpi_object_type type)
+char *acpi_ut_get_type_name(acpi_object_type type)
{
- if (type > ACPI_TYPE_INVALID)
- {
- return ((char *) acpi_gbl_bad_type);
+ if (type > ACPI_TYPE_INVALID) {
+ return ((char *)acpi_gbl_bad_type);
}
- return ((char *) acpi_gbl_ns_type_names[type]);
+ return ((char *)acpi_gbl_ns_type_names[type]);
}
-
-char *
-acpi_ut_get_object_type_name (
- union acpi_operand_object *obj_desc)
+char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
{
- if (!obj_desc)
- {
+ if (!obj_desc) {
return ("[NULL Object Descriptor]");
}
- return (acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)));
+ return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_node_name
@@ -578,39 +610,31 @@ acpi_ut_get_object_type_name (
*
******************************************************************************/
-char *
-acpi_ut_get_node_name (
- void *object)
+char *acpi_ut_get_node_name(void *object)
{
- struct acpi_namespace_node *node = (struct acpi_namespace_node *) object;
-
+ struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
/* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
- if (!object)
- {
+ if (!object) {
return ("NULL");
}
/* Check for Root node */
- if ((object == ACPI_ROOT_OBJECT) ||
- (object == acpi_gbl_root_node))
- {
+ if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) {
return ("\"\\\" ");
}
/* Descriptor must be a namespace node */
- if (node->descriptor != ACPI_DESC_TYPE_NAMED)
- {
+ if (node->descriptor != ACPI_DESC_TYPE_NAMED) {
return ("####");
}
/* Name must be a valid ACPI name */
- if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii))
- {
+ if (!acpi_ut_valid_acpi_name(*(u32 *) node->name.ascii)) {
return ("????");
}
@@ -619,7 +643,6 @@ acpi_ut_get_node_name (
return (node->name.ascii);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_descriptor_name
@@ -634,8 +657,7 @@ acpi_ut_get_node_name (
/* Printable names of object descriptor types */
-static const char *acpi_gbl_desc_type_names[] =
-{
+static const char *acpi_gbl_desc_type_names[] = {
/* 00 */ "Invalid",
/* 01 */ "Cached",
/* 02 */ "State-Generic",
@@ -654,27 +676,22 @@ static const char *acpi_gbl_desc_type_names[] =
/* 15 */ "Node"
};
-
-char *
-acpi_ut_get_descriptor_name (
- void *object)
+char *acpi_ut_get_descriptor_name(void *object)
{
- if (!object)
- {
+ if (!object) {
return ("NULL OBJECT");
}
- if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX)
- {
- return ((char *) acpi_gbl_bad_type);
+ if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
+ return ((char *)acpi_gbl_bad_type);
}
- return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]);
+ return ((char *)
+ acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE(object)]);
}
-
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/*
* Strings and procedures used for debug only
@@ -693,13 +710,10 @@ acpi_ut_get_descriptor_name (
*
******************************************************************************/
-char *
-acpi_ut_get_mutex_name (
- u32 mutex_id)
+char *acpi_ut_get_mutex_name(u32 mutex_id)
{
- if (mutex_id > MAX_MUTEX)
- {
+ if (mutex_id > MAX_MUTEX) {
return ("Invalid Mutex ID");
}
@@ -707,7 +721,6 @@ acpi_ut_get_mutex_name (
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_valid_object_type
@@ -720,13 +733,10 @@ acpi_ut_get_mutex_name (
*
******************************************************************************/
-u8
-acpi_ut_valid_object_type (
- acpi_object_type type)
+u8 acpi_ut_valid_object_type(acpi_object_type type)
{
- if (type > ACPI_TYPE_LOCAL_MAX)
- {
+ if (type > ACPI_TYPE_LOCAL_MAX) {
/* Note: Assumes all TYPEs are contiguous (external/local) */
return (FALSE);
@@ -735,74 +745,6 @@ acpi_ut_valid_object_type (
return (TRUE);
}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_allocate_owner_id
- *
- * PARAMETERS: id_type - Type of ID (method or table)
- *
- * DESCRIPTION: Allocate a table or method owner id
- *
- * NOTE: this algorithm has a wraparound problem at 64_k method invocations, and
- * should be revisited (TBD)
- *
- ******************************************************************************/
-
-acpi_owner_id
-acpi_ut_allocate_owner_id (
- u32 id_type)
-{
- acpi_owner_id owner_id = 0xFFFF;
-
-
- ACPI_FUNCTION_TRACE ("ut_allocate_owner_id");
-
-
- if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES)))
- {
- return (0);
- }
-
- switch (id_type)
- {
- case ACPI_OWNER_TYPE_TABLE:
-
- owner_id = acpi_gbl_next_table_owner_id;
- acpi_gbl_next_table_owner_id++;
-
- /* Check for wraparound */
-
- if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
- {
- acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
- ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
- }
- break;
-
-
- case ACPI_OWNER_TYPE_METHOD:
-
- owner_id = acpi_gbl_next_method_owner_id;
- acpi_gbl_next_method_owner_id++;
-
- if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
- {
- /* Check for wraparound */
-
- acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
- }
- break;
-
- default:
- break;
- }
-
- (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
- return_VALUE (owner_id);
-}
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_init_globals
@@ -816,129 +758,96 @@ acpi_ut_allocate_owner_id (
*
******************************************************************************/
-void
-acpi_ut_init_globals (
- void)
+void acpi_ut_init_globals(void)
{
- u32 i;
+ acpi_status status;
+ u32 i;
+ ACPI_FUNCTION_TRACE("ut_init_globals");
- ACPI_FUNCTION_TRACE ("ut_init_globals");
+ /* Create all memory caches */
-
- /* Memory allocation and cache lists */
-
- ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS);
-
- acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_generic_state *) NULL)->common.next), NULL);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_operand_object *) NULL)->cache.next), NULL);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset = (u16) ACPI_PTR_DIFF (&(((struct acpi_walk_state *) NULL)->next), NULL);
-
- acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size = sizeof (struct acpi_namespace_node);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size = sizeof (union acpi_generic_state);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size = sizeof (struct acpi_parse_obj_common);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (struct acpi_parse_obj_named);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size = sizeof (union acpi_operand_object);
- acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size = sizeof (struct acpi_walk_state);
-
- acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth = ACPI_MAX_STATE_CACHE_DEPTH;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH;
- acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth = ACPI_MAX_WALK_CACHE_DEPTH;
-
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name = "Global Memory Allocation");
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name = "Namespace Nodes");
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].list_name = "State Object Cache");
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].list_name = "Parse Node Cache");
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].list_name = "Extended Parse Node Cache");
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].list_name = "Operand Object Cache");
- ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].list_name = "Tree Walk Node Cache");
+ status = acpi_ut_create_caches();
+ if (ACPI_FAILURE(status)) {
+ return;
+ }
/* ACPI table structure */
- for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
- {
- acpi_gbl_table_lists[i].next = NULL;
- acpi_gbl_table_lists[i].count = 0;
+ for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+ acpi_gbl_table_lists[i].next = NULL;
+ acpi_gbl_table_lists[i].count = 0;
}
/* Mutex locked flags */
- for (i = 0; i < NUM_MUTEX; i++)
- {
- acpi_gbl_mutex_info[i].mutex = NULL;
- acpi_gbl_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
- acpi_gbl_mutex_info[i].use_count = 0;
+ for (i = 0; i < NUM_MUTEX; i++) {
+ acpi_gbl_mutex_info[i].mutex = NULL;
+ acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
+ acpi_gbl_mutex_info[i].use_count = 0;
}
/* GPE support */
- acpi_gbl_gpe_xrupt_list_head = NULL;
- acpi_gbl_gpe_fadt_blocks[0] = NULL;
- acpi_gbl_gpe_fadt_blocks[1] = NULL;
+ acpi_gbl_gpe_xrupt_list_head = NULL;
+ acpi_gbl_gpe_fadt_blocks[0] = NULL;
+ acpi_gbl_gpe_fadt_blocks[1] = NULL;
/* Global notify handlers */
- acpi_gbl_system_notify.handler = NULL;
- acpi_gbl_device_notify.handler = NULL;
- acpi_gbl_exception_handler = NULL;
- acpi_gbl_init_handler = NULL;
+ acpi_gbl_system_notify.handler = NULL;
+ acpi_gbl_device_notify.handler = NULL;
+ acpi_gbl_exception_handler = NULL;
+ acpi_gbl_init_handler = NULL;
/* Global "typed" ACPI table pointers */
- acpi_gbl_RSDP = NULL;
- acpi_gbl_XSDT = NULL;
- acpi_gbl_FACS = NULL;
- acpi_gbl_FADT = NULL;
- acpi_gbl_DSDT = NULL;
+ acpi_gbl_RSDP = NULL;
+ acpi_gbl_XSDT = NULL;
+ acpi_gbl_FACS = NULL;
+ acpi_gbl_FADT = NULL;
+ acpi_gbl_DSDT = NULL;
/* Global Lock support */
- acpi_gbl_global_lock_acquired = FALSE;
- acpi_gbl_global_lock_thread_count = 0;
- acpi_gbl_global_lock_handle = 0;
+ acpi_gbl_global_lock_acquired = FALSE;
+ acpi_gbl_global_lock_thread_count = 0;
+ acpi_gbl_global_lock_handle = 0;
/* Miscellaneous variables */
- acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER;
- acpi_gbl_rsdp_original_location = 0;
- acpi_gbl_cm_single_step = FALSE;
- acpi_gbl_db_terminate_threads = FALSE;
- acpi_gbl_shutdown = FALSE;
- acpi_gbl_ns_lookup_count = 0;
- acpi_gbl_ps_find_count = 0;
- acpi_gbl_acpi_hardware_present = TRUE;
- acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
- acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
- acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
- acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+ acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER;
+ acpi_gbl_rsdp_original_location = 0;
+ acpi_gbl_cm_single_step = FALSE;
+ acpi_gbl_db_terminate_threads = FALSE;
+ acpi_gbl_shutdown = FALSE;
+ acpi_gbl_ns_lookup_count = 0;
+ acpi_gbl_ps_find_count = 0;
+ acpi_gbl_acpi_hardware_present = TRUE;
+ acpi_gbl_owner_id_mask = 0;
+ acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
+ acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
/* Hardware oriented */
- acpi_gbl_events_initialized = FALSE;
- acpi_gbl_system_awake_and_running = TRUE;
+ acpi_gbl_events_initialized = FALSE;
+ acpi_gbl_system_awake_and_running = TRUE;
/* Namespace */
- acpi_gbl_root_node = NULL;
+ acpi_gbl_root_node = NULL;
acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED;
- acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
- acpi_gbl_root_node_struct.child = NULL;
- acpi_gbl_root_node_struct.peer = NULL;
- acpi_gbl_root_node_struct.object = NULL;
- acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
-
+ acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
+ acpi_gbl_root_node_struct.child = NULL;
+ acpi_gbl_root_node_struct.peer = NULL;
+ acpi_gbl_root_node_struct.object = NULL;
+ acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
#ifdef ACPI_DEBUG_OUTPUT
- acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX;
+ acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX;
#endif
return_VOID;
}
-
-
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index 7f3713889ff0..9dde82b0beaf 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -41,25 +41,18 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utinit")
+ACPI_MODULE_NAME("utinit")
/* Local prototypes */
-
static void
-acpi_ut_fadt_register_error (
- char *register_name,
- u32 value,
- acpi_size offset);
-
-static void acpi_ut_terminate (
- void);
+acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset);
+static void acpi_ut_terminate(void);
/*******************************************************************************
*
@@ -76,18 +69,14 @@ static void acpi_ut_terminate (
******************************************************************************/
static void
-acpi_ut_fadt_register_error (
- char *register_name,
- u32 value,
- acpi_size offset)
+acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset)
{
- ACPI_REPORT_WARNING (
- ("Invalid FADT value %s=%X at offset %X FADT=%p\n",
- register_name, value, (u32) offset, acpi_gbl_FADT));
+ ACPI_REPORT_WARNING(("Invalid FADT value %s=%X at offset %X FADT=%p\n",
+ register_name, value, (u32) offset,
+ acpi_gbl_FADT));
}
-
/******************************************************************************
*
* FUNCTION: acpi_ut_validate_fadt
@@ -100,9 +89,7 @@ acpi_ut_fadt_register_error (
*
******************************************************************************/
-acpi_status
-acpi_ut_validate_fadt (
- void)
+acpi_status acpi_ut_validate_fadt(void)
{
/*
@@ -110,64 +97,66 @@ acpi_ut_validate_fadt (
* but don't abort on any problems, just display error
*/
if (acpi_gbl_FADT->pm1_evt_len < 4) {
- acpi_ut_fadt_register_error ("PM1_EVT_LEN",
- (u32) acpi_gbl_FADT->pm1_evt_len,
- ACPI_FADT_OFFSET (pm1_evt_len));
+ acpi_ut_fadt_register_error("PM1_EVT_LEN",
+ (u32) acpi_gbl_FADT->pm1_evt_len,
+ ACPI_FADT_OFFSET(pm1_evt_len));
}
if (!acpi_gbl_FADT->pm1_cnt_len) {
- acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0,
- ACPI_FADT_OFFSET (pm1_cnt_len));
+ acpi_ut_fadt_register_error("PM1_CNT_LEN", 0,
+ ACPI_FADT_OFFSET(pm1_cnt_len));
}
if (!acpi_gbl_FADT->xpm1a_evt_blk.address) {
- acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0,
- ACPI_FADT_OFFSET (xpm1a_evt_blk.address));
+ acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0,
+ ACPI_FADT_OFFSET(xpm1a_evt_blk.
+ address));
}
if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) {
- acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0,
- ACPI_FADT_OFFSET (xpm1a_cnt_blk.address));
+ acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0,
+ ACPI_FADT_OFFSET(xpm1a_cnt_blk.
+ address));
}
if (!acpi_gbl_FADT->xpm_tmr_blk.address) {
- acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0,
- ACPI_FADT_OFFSET (xpm_tmr_blk.address));
+ acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0,
+ ACPI_FADT_OFFSET(xpm_tmr_blk.
+ address));
}
if ((acpi_gbl_FADT->xpm2_cnt_blk.address &&
- !acpi_gbl_FADT->pm2_cnt_len)) {
- acpi_ut_fadt_register_error ("PM2_CNT_LEN",
- (u32) acpi_gbl_FADT->pm2_cnt_len,
- ACPI_FADT_OFFSET (pm2_cnt_len));
+ !acpi_gbl_FADT->pm2_cnt_len)) {
+ acpi_ut_fadt_register_error("PM2_CNT_LEN",
+ (u32) acpi_gbl_FADT->pm2_cnt_len,
+ ACPI_FADT_OFFSET(pm2_cnt_len));
}
if (acpi_gbl_FADT->pm_tm_len < 4) {
- acpi_ut_fadt_register_error ("PM_TM_LEN",
- (u32) acpi_gbl_FADT->pm_tm_len,
- ACPI_FADT_OFFSET (pm_tm_len));
+ acpi_ut_fadt_register_error("PM_TM_LEN",
+ (u32) acpi_gbl_FADT->pm_tm_len,
+ ACPI_FADT_OFFSET(pm_tm_len));
}
/* Length of GPE blocks must be a multiple of 2 */
if (acpi_gbl_FADT->xgpe0_blk.address &&
- (acpi_gbl_FADT->gpe0_blk_len & 1)) {
- acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN",
- (u32) acpi_gbl_FADT->gpe0_blk_len,
- ACPI_FADT_OFFSET (gpe0_blk_len));
+ (acpi_gbl_FADT->gpe0_blk_len & 1)) {
+ acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN",
+ (u32) acpi_gbl_FADT->gpe0_blk_len,
+ ACPI_FADT_OFFSET(gpe0_blk_len));
}
if (acpi_gbl_FADT->xgpe1_blk.address &&
- (acpi_gbl_FADT->gpe1_blk_len & 1)) {
- acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN",
- (u32) acpi_gbl_FADT->gpe1_blk_len,
- ACPI_FADT_OFFSET (gpe1_blk_len));
+ (acpi_gbl_FADT->gpe1_blk_len & 1)) {
+ acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN",
+ (u32) acpi_gbl_FADT->gpe1_blk_len,
+ ACPI_FADT_OFFSET(gpe1_blk_len));
}
return (AE_OK);
}
-
/******************************************************************************
*
* FUNCTION: acpi_ut_terminate
@@ -180,18 +169,14 @@ acpi_ut_validate_fadt (
*
******************************************************************************/
-static void
-acpi_ut_terminate (
- void)
+static void acpi_ut_terminate(void)
{
- struct acpi_gpe_block_info *gpe_block;
- struct acpi_gpe_block_info *next_gpe_block;
- struct acpi_gpe_xrupt_info *gpe_xrupt_info;
- struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
-
-
- ACPI_FUNCTION_TRACE ("ut_terminate");
+ struct acpi_gpe_block_info *gpe_block;
+ struct acpi_gpe_block_info *next_gpe_block;
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info;
+ struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
+ ACPI_FUNCTION_TRACE("ut_terminate");
/* Free global tables, etc. */
/* Free global GPE blocks and related info structures */
@@ -201,21 +186,20 @@ acpi_ut_terminate (
gpe_block = gpe_xrupt_info->gpe_block_list_head;
while (gpe_block) {
next_gpe_block = gpe_block->next;
- ACPI_MEM_FREE (gpe_block->event_info);
- ACPI_MEM_FREE (gpe_block->register_info);
- ACPI_MEM_FREE (gpe_block);
+ ACPI_MEM_FREE(gpe_block->event_info);
+ ACPI_MEM_FREE(gpe_block->register_info);
+ ACPI_MEM_FREE(gpe_block);
gpe_block = next_gpe_block;
}
next_gpe_xrupt_info = gpe_xrupt_info->next;
- ACPI_MEM_FREE (gpe_xrupt_info);
+ ACPI_MEM_FREE(gpe_xrupt_info);
gpe_xrupt_info = next_gpe_xrupt_info;
}
return_VOID;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_subsystem_shutdown
@@ -229,50 +213,45 @@ acpi_ut_terminate (
*
******************************************************************************/
-void
-acpi_ut_subsystem_shutdown (
- void)
+void acpi_ut_subsystem_shutdown(void)
{
- ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown");
+ ACPI_FUNCTION_TRACE("ut_subsystem_shutdown");
/* Just exit if subsystem is already shutdown */
if (acpi_gbl_shutdown) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "ACPI Subsystem is already terminated\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "ACPI Subsystem is already terminated\n"));
return_VOID;
}
/* Subsystem appears active, go ahead and shut it down */
acpi_gbl_shutdown = TRUE;
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Shutting down ACPI Subsystem...\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n"));
/* Close the acpi_event Handling */
- acpi_ev_terminate ();
+ acpi_ev_terminate();
/* Close the Namespace */
- acpi_ns_terminate ();
+ acpi_ns_terminate();
/* Close the globals */
- acpi_ut_terminate ();
+ acpi_ut_terminate();
/* Purge the local caches */
- (void) acpi_purge_cached_objects ();
+ (void)acpi_ut_delete_caches();
/* Debug only - display leftover memory allocation, if any */
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- acpi_ut_dump_allocations (ACPI_UINT32_MAX, NULL);
+ acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
#endif
return_VOID;
}
-
-
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
index 0d527c91543c..68a0a6f94129 100644
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -41,19 +41,16 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
-
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utmath")
+ACPI_MODULE_NAME("utmath")
/*
* Support for double-precision integer divide. This code is included here
* in order to support kernel environments where the double-precision math
* library is not available.
*/
-
#ifndef ACPI_USE_NATIVE_DIVIDE
/*******************************************************************************
*
@@ -71,27 +68,22 @@
* 32-bit remainder.
*
******************************************************************************/
-
acpi_status
-acpi_ut_short_divide (
- acpi_integer dividend,
- u32 divisor,
- acpi_integer *out_quotient,
- u32 *out_remainder)
+acpi_ut_short_divide(acpi_integer dividend,
+ u32 divisor,
+ acpi_integer * out_quotient, u32 * out_remainder)
{
- union uint64_overlay dividend_ovl;
- union uint64_overlay quotient;
- u32 remainder32;
-
-
- ACPI_FUNCTION_TRACE ("ut_short_divide");
+ union uint64_overlay dividend_ovl;
+ union uint64_overlay quotient;
+ u32 remainder32;
+ ACPI_FUNCTION_TRACE("ut_short_divide");
/* Always check for a zero divisor */
if (divisor == 0) {
- ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
- return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ ACPI_REPORT_ERROR(("acpi_ut_short_divide: Divide by zero\n"));
+ return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
}
dividend_ovl.full = dividend;
@@ -100,9 +92,9 @@ acpi_ut_short_divide (
* The quotient is 64 bits, the remainder is always 32 bits,
* and is generated by the second divide.
*/
- ACPI_DIV_64_BY_32 (0, dividend_ovl.part.hi, divisor,
+ ACPI_DIV_64_BY_32(0, dividend_ovl.part.hi, divisor,
quotient.part.hi, remainder32);
- ACPI_DIV_64_BY_32 (remainder32, dividend_ovl.part.lo, divisor,
+ ACPI_DIV_64_BY_32(remainder32, dividend_ovl.part.lo, divisor,
quotient.part.lo, remainder32);
/* Return only what was requested */
@@ -114,10 +106,9 @@ acpi_ut_short_divide (
*out_remainder = remainder32;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_divide
@@ -134,34 +125,30 @@ acpi_ut_short_divide (
******************************************************************************/
acpi_status
-acpi_ut_divide (
- acpi_integer in_dividend,
- acpi_integer in_divisor,
- acpi_integer *out_quotient,
- acpi_integer *out_remainder)
+acpi_ut_divide(acpi_integer in_dividend,
+ acpi_integer in_divisor,
+ acpi_integer * out_quotient, acpi_integer * out_remainder)
{
- union uint64_overlay dividend;
- union uint64_overlay divisor;
- union uint64_overlay quotient;
- union uint64_overlay remainder;
- union uint64_overlay normalized_dividend;
- union uint64_overlay normalized_divisor;
- u32 partial1;
- union uint64_overlay partial2;
- union uint64_overlay partial3;
-
-
- ACPI_FUNCTION_TRACE ("ut_divide");
-
+ union uint64_overlay dividend;
+ union uint64_overlay divisor;
+ union uint64_overlay quotient;
+ union uint64_overlay remainder;
+ union uint64_overlay normalized_dividend;
+ union uint64_overlay normalized_divisor;
+ u32 partial1;
+ union uint64_overlay partial2;
+ union uint64_overlay partial3;
+
+ ACPI_FUNCTION_TRACE("ut_divide");
/* Always check for a zero divisor */
if (in_divisor == 0) {
- ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
- return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ ACPI_REPORT_ERROR(("acpi_ut_divide: Divide by zero\n"));
+ return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
}
- divisor.full = in_divisor;
+ divisor.full = in_divisor;
dividend.full = in_dividend;
if (divisor.part.hi == 0) {
/*
@@ -174,9 +161,9 @@ acpi_ut_divide (
* The quotient is 64 bits, the remainder is always 32 bits,
* and is generated by the second divide.
*/
- ACPI_DIV_64_BY_32 (0, dividend.part.hi, divisor.part.lo,
+ ACPI_DIV_64_BY_32(0, dividend.part.hi, divisor.part.lo,
quotient.part.hi, partial1);
- ACPI_DIV_64_BY_32 (partial1, dividend.part.lo, divisor.part.lo,
+ ACPI_DIV_64_BY_32(partial1, dividend.part.lo, divisor.part.lo,
quotient.part.lo, remainder.part.lo);
}
@@ -185,23 +172,23 @@ acpi_ut_divide (
* 2) The general case where the divisor is a full 64 bits
* is more difficult
*/
- quotient.part.hi = 0;
+ quotient.part.hi = 0;
normalized_dividend = dividend;
normalized_divisor = divisor;
/* Normalize the operands (shift until the divisor is < 32 bits) */
do {
- ACPI_SHIFT_RIGHT_64 (normalized_divisor.part.hi,
- normalized_divisor.part.lo);
- ACPI_SHIFT_RIGHT_64 (normalized_dividend.part.hi,
- normalized_dividend.part.lo);
+ ACPI_SHIFT_RIGHT_64(normalized_divisor.part.hi,
+ normalized_divisor.part.lo);
+ ACPI_SHIFT_RIGHT_64(normalized_dividend.part.hi,
+ normalized_dividend.part.lo);
} while (normalized_divisor.part.hi != 0);
/* Partial divide */
- ACPI_DIV_64_BY_32 (normalized_dividend.part.hi,
+ ACPI_DIV_64_BY_32(normalized_dividend.part.hi,
normalized_dividend.part.lo,
normalized_divisor.part.lo,
quotient.part.lo, partial1);
@@ -210,8 +197,9 @@ acpi_ut_divide (
* The quotient is always 32 bits, and simply requires adjustment.
* The 64-bit remainder must be generated.
*/
- partial1 = quotient.part.lo * divisor.part.hi;
- partial2.full = (acpi_integer) quotient.part.lo * divisor.part.lo;
+ partial1 = quotient.part.lo * divisor.part.hi;
+ partial2.full =
+ (acpi_integer) quotient.part.lo * divisor.part.lo;
partial3.full = (acpi_integer) partial2.part.hi + partial1;
remainder.part.hi = partial3.part.lo;
@@ -224,16 +212,15 @@ acpi_ut_divide (
quotient.part.lo--;
remainder.full -= divisor.full;
}
- }
- else {
+ } else {
quotient.part.lo--;
remainder.full -= divisor.full;
}
}
- remainder.full = remainder.full - dividend.full;
- remainder.part.hi = (u32) -((s32) remainder.part.hi);
- remainder.part.lo = (u32) -((s32) remainder.part.lo);
+ remainder.full = remainder.full - dividend.full;
+ remainder.part.hi = (u32) - ((s32) remainder.part.hi);
+ remainder.part.lo = (u32) - ((s32) remainder.part.lo);
if (remainder.part.lo) {
remainder.part.hi--;
@@ -250,11 +237,10 @@ acpi_ut_divide (
*out_remainder = remainder.full;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
#else
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_short_divide, acpi_ut_divide
@@ -269,23 +255,19 @@ acpi_ut_divide (
* perform the divide.
*
******************************************************************************/
-
acpi_status
-acpi_ut_short_divide (
- acpi_integer in_dividend,
- u32 divisor,
- acpi_integer *out_quotient,
- u32 *out_remainder)
+acpi_ut_short_divide(acpi_integer in_dividend,
+ u32 divisor,
+ acpi_integer * out_quotient, u32 * out_remainder)
{
- ACPI_FUNCTION_TRACE ("ut_short_divide");
-
+ ACPI_FUNCTION_TRACE("ut_short_divide");
/* Always check for a zero divisor */
if (divisor == 0) {
- ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
- return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ ACPI_REPORT_ERROR(("acpi_ut_short_divide: Divide by zero\n"));
+ return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
}
/* Return only what was requested */
@@ -297,27 +279,23 @@ acpi_ut_short_divide (
*out_remainder = (u32) in_dividend % divisor;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
acpi_status
-acpi_ut_divide (
- acpi_integer in_dividend,
- acpi_integer in_divisor,
- acpi_integer *out_quotient,
- acpi_integer *out_remainder)
+acpi_ut_divide(acpi_integer in_dividend,
+ acpi_integer in_divisor,
+ acpi_integer * out_quotient, acpi_integer * out_remainder)
{
- ACPI_FUNCTION_TRACE ("ut_divide");
-
+ ACPI_FUNCTION_TRACE("ut_divide");
/* Always check for a zero divisor */
if (in_divisor == 0) {
- ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
- return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ ACPI_REPORT_ERROR(("acpi_ut_divide: Divide by zero\n"));
+ return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
}
-
/* Return only what was requested */
if (out_quotient) {
@@ -327,9 +305,7 @@ acpi_ut_divide (
*out_remainder = in_dividend % in_divisor;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
#endif
-
-
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index f6de4ed3d527..0c5abc536c7a 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -41,24 +41,130 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
-
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utmisc")
+ACPI_MODULE_NAME("utmisc")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate_owner_id
+ *
+ * PARAMETERS: owner_id - Where the new owner ID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
+ * track objects created by the table or method, to be deleted
+ * when the method exits or the table is unloaded.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
+{
+ acpi_native_uint i;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("ut_allocate_owner_id");
+
+ /* Guard against multiple allocations of ID to the same location */
+
+ if (*owner_id) {
+ ACPI_REPORT_ERROR(("Owner ID [%2.2X] already exists\n",
+ *owner_id));
+ return_ACPI_STATUS(AE_ALREADY_EXISTS);
+ }
+
+ /* Mutex for the global ID mask */
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
-/* Local prototypes */
+ /* Find a free owner ID */
-static acpi_status
-acpi_ut_create_mutex (
- acpi_mutex_handle mutex_id);
+ for (i = 0; i < 32; i++) {
+ if (!(acpi_gbl_owner_id_mask & (1 << i))) {
+ ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
+ "Current owner_id mask: %8.8X New ID: %2.2X\n",
+ acpi_gbl_owner_id_mask,
+ (unsigned int)(i + 1)));
-static acpi_status
-acpi_ut_delete_mutex (
- acpi_mutex_handle mutex_id);
+ acpi_gbl_owner_id_mask |= (1 << i);
+ *owner_id = (acpi_owner_id) (i + 1);
+ goto exit;
+ }
+ }
+ /*
+ * If we are here, all owner_ids have been allocated. This probably should
+ * not happen since the IDs are reused after deallocation. The IDs are
+ * allocated upon table load (one per table) and method execution, and
+ * they are released when a table is unloaded or a method completes
+ * execution.
+ */
+ *owner_id = 0;
+ status = AE_OWNER_ID_LIMIT;
+ ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n"));
+
+ exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_release_owner_id
+ *
+ * PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_iD
+ *
+ * RETURN: None. No error is returned because we are either exiting a
+ * control method or unloading a table. Either way, we would
+ * ignore any error anyway.
+ *
+ * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32
+ *
+ ******************************************************************************/
+
+void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
+{
+ acpi_owner_id owner_id = *owner_id_ptr;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id);
+
+ /* Always clear the input owner_id (zero is an invalid ID) */
+
+ *owner_id_ptr = 0;
+
+ /* Zero is not a valid owner_iD */
+
+ if ((owner_id == 0) || (owner_id > 32)) {
+ ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
+ return_VOID;
+ }
+
+ /* Mutex for the global ID mask */
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return_VOID;
+ }
+
+ /* Normalize the ID to zero */
+
+ owner_id--;
+
+ /* Free the owner ID only if it is valid */
+
+ if (acpi_gbl_owner_id_mask & (1 << owner_id)) {
+ acpi_gbl_owner_id_mask ^= (1 << owner_id);
+ }
+
+ (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ return_VOID;
+}
/*******************************************************************************
*
@@ -66,7 +172,7 @@ acpi_ut_delete_mutex (
*
* PARAMETERS: src_string - The source string to convert
*
- * RETURN: Converted src_string (same as input pointer)
+ * RETURN: None
*
* DESCRIPTION: Convert string to uppercase
*
@@ -74,26 +180,25 @@ acpi_ut_delete_mutex (
*
******************************************************************************/
-char *
-acpi_ut_strupr (
- char *src_string)
+void acpi_ut_strupr(char *src_string)
{
- char *string;
-
+ char *string;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
+ if (!src_string) {
+ return;
+ }
/* Walk entire string, uppercasing the letters */
for (string = src_string; *string; string++) {
- *string = (char) ACPI_TOUPPER (*string);
+ *string = (char)ACPI_TOUPPER(*string);
}
- return (src_string);
+ return;
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_print_string
@@ -108,85 +213,77 @@ acpi_ut_strupr (
*
******************************************************************************/
-void
-acpi_ut_print_string (
- char *string,
- u8 max_length)
+void acpi_ut_print_string(char *string, u8 max_length)
{
- u32 i;
-
+ u32 i;
if (!string) {
- acpi_os_printf ("<\"NULL STRING PTR\">");
+ acpi_os_printf("<\"NULL STRING PTR\">");
return;
}
- acpi_os_printf ("\"");
+ acpi_os_printf("\"");
for (i = 0; string[i] && (i < max_length); i++) {
/* Escape sequences */
switch (string[i]) {
case 0x07:
- acpi_os_printf ("\\a"); /* BELL */
+ acpi_os_printf("\\a"); /* BELL */
break;
case 0x08:
- acpi_os_printf ("\\b"); /* BACKSPACE */
+ acpi_os_printf("\\b"); /* BACKSPACE */
break;
case 0x0C:
- acpi_os_printf ("\\f"); /* FORMFEED */
+ acpi_os_printf("\\f"); /* FORMFEED */
break;
case 0x0A:
- acpi_os_printf ("\\n"); /* LINEFEED */
+ acpi_os_printf("\\n"); /* LINEFEED */
break;
case 0x0D:
- acpi_os_printf ("\\r"); /* CARRIAGE RETURN*/
+ acpi_os_printf("\\r"); /* CARRIAGE RETURN */
break;
case 0x09:
- acpi_os_printf ("\\t"); /* HORIZONTAL TAB */
+ acpi_os_printf("\\t"); /* HORIZONTAL TAB */
break;
case 0x0B:
- acpi_os_printf ("\\v"); /* VERTICAL TAB */
+ acpi_os_printf("\\v"); /* VERTICAL TAB */
break;
- case '\'': /* Single Quote */
- case '\"': /* Double Quote */
- case '\\': /* Backslash */
- acpi_os_printf ("\\%c", (int) string[i]);
+ case '\'': /* Single Quote */
+ case '\"': /* Double Quote */
+ case '\\': /* Backslash */
+ acpi_os_printf("\\%c", (int)string[i]);
break;
default:
/* Check for printable character or hex escape */
- if (ACPI_IS_PRINT (string[i]))
- {
+ if (ACPI_IS_PRINT(string[i])) {
/* This is a normal character */
- acpi_os_printf ("%c", (int) string[i]);
- }
- else
- {
+ acpi_os_printf("%c", (int)string[i]);
+ } else {
/* All others will be Hex escapes */
- acpi_os_printf ("\\x%2.2X", (s32) string[i]);
+ acpi_os_printf("\\x%2.2X", (s32) string[i]);
}
break;
}
}
- acpi_os_printf ("\"");
+ acpi_os_printf("\"");
if (i == max_length && string[i]) {
- acpi_os_printf ("...");
+ acpi_os_printf("...");
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_dword_byte_swap
@@ -199,22 +296,18 @@ acpi_ut_print_string (
*
******************************************************************************/
-u32
-acpi_ut_dword_byte_swap (
- u32 value)
+u32 acpi_ut_dword_byte_swap(u32 value)
{
union {
- u32 value;
- u8 bytes[4];
+ u32 value;
+ u8 bytes[4];
} out;
union {
- u32 value;
- u8 bytes[4];
+ u32 value;
+ u8 bytes[4];
} in;
-
- ACPI_FUNCTION_ENTRY ();
-
+ ACPI_FUNCTION_ENTRY();
in.value = value;
@@ -226,7 +319,6 @@ acpi_ut_dword_byte_swap (
return (out.value);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_set_integer_width
@@ -242,24 +334,20 @@ acpi_ut_dword_byte_swap (
*
******************************************************************************/
-void
-acpi_ut_set_integer_width (
- u8 revision)
+void acpi_ut_set_integer_width(u8 revision)
{
if (revision <= 1) {
acpi_gbl_integer_bit_width = 32;
acpi_gbl_integer_nybble_width = 8;
acpi_gbl_integer_byte_width = 4;
- }
- else {
+ } else {
acpi_gbl_integer_bit_width = 64;
acpi_gbl_integer_nybble_width = 16;
acpi_gbl_integer_byte_width = 8;
}
}
-
#ifdef ACPI_DEBUG_OUTPUT
/*******************************************************************************
*
@@ -277,17 +365,14 @@ acpi_ut_set_integer_width (
******************************************************************************/
void
-acpi_ut_display_init_pathname (
- u8 type,
- struct acpi_namespace_node *obj_handle,
- char *path)
+acpi_ut_display_init_pathname(u8 type,
+ struct acpi_namespace_node *obj_handle,
+ char *path)
{
- acpi_status status;
- struct acpi_buffer buffer;
-
-
- ACPI_FUNCTION_ENTRY ();
+ acpi_status status;
+ struct acpi_buffer buffer;
+ ACPI_FUNCTION_ENTRY();
/* Only print the path if the appropriate debug level is enabled */
@@ -298,8 +383,8 @@ acpi_ut_display_init_pathname (
/* Get the full pathname to the node */
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
- if (ACPI_FAILURE (status)) {
+ status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
+ if (ACPI_FAILURE(status)) {
return;
}
@@ -307,31 +392,30 @@ acpi_ut_display_init_pathname (
switch (type) {
case ACPI_TYPE_METHOD:
- acpi_os_printf ("Executing ");
+ acpi_os_printf("Executing ");
break;
default:
- acpi_os_printf ("Initializing ");
+ acpi_os_printf("Initializing ");
break;
}
/* Print the object type and pathname */
- acpi_os_printf ("%-12s %s",
- acpi_ut_get_type_name (type), (char *) buffer.pointer);
+ acpi_os_printf("%-12s %s",
+ acpi_ut_get_type_name(type), (char *)buffer.pointer);
/* Extra path is used to append names like _STA, _INI, etc. */
if (path) {
- acpi_os_printf (".%s", path);
+ acpi_os_printf(".%s", path);
}
- acpi_os_printf ("\n");
+ acpi_os_printf("\n");
- ACPI_MEM_FREE (buffer.pointer);
+ ACPI_MEM_FREE(buffer.pointer);
}
#endif
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_valid_acpi_name
@@ -347,25 +431,21 @@ acpi_ut_display_init_pathname (
*
******************************************************************************/
-u8
-acpi_ut_valid_acpi_name (
- u32 name)
+u8 acpi_ut_valid_acpi_name(u32 name)
{
- char *name_ptr = (char *) &name;
- char character;
- acpi_native_uint i;
-
-
- ACPI_FUNCTION_ENTRY ();
+ char *name_ptr = (char *)&name;
+ char character;
+ acpi_native_uint i;
+ ACPI_FUNCTION_ENTRY();
for (i = 0; i < ACPI_NAME_SIZE; i++) {
character = *name_ptr;
name_ptr++;
if (!((character == '_') ||
- (character >= 'A' && character <= 'Z') ||
- (character >= '0' && character <= '9'))) {
+ (character >= 'A' && character <= 'Z') ||
+ (character >= '0' && character <= '9'))) {
return (FALSE);
}
}
@@ -373,7 +453,6 @@ acpi_ut_valid_acpi_name (
return (TRUE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_valid_acpi_character
@@ -386,19 +465,16 @@ acpi_ut_valid_acpi_name (
*
******************************************************************************/
-u8
-acpi_ut_valid_acpi_character (
- char character)
+u8 acpi_ut_valid_acpi_character(char character)
{
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_ENTRY();
- return ((u8) ((character == '_') ||
- (character >= 'A' && character <= 'Z') ||
- (character >= '0' && character <= '9')));
+ return ((u8) ((character == '_') ||
+ (character >= 'A' && character <= 'Z') ||
+ (character >= '0' && character <= '9')));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_strtoul64
@@ -415,18 +491,13 @@ acpi_ut_valid_acpi_character (
******************************************************************************/
acpi_status
-acpi_ut_strtoul64 (
- char *string,
- u32 base,
- acpi_integer *ret_integer)
+acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
{
- u32 this_digit = 0;
- acpi_integer return_value = 0;
- acpi_integer quotient;
-
-
- ACPI_FUNCTION_TRACE ("ut_stroul64");
+ u32 this_digit = 0;
+ acpi_integer return_value = 0;
+ acpi_integer quotient;
+ ACPI_FUNCTION_TRACE("ut_stroul64");
if ((!string) || !(*string)) {
goto error_exit;
@@ -440,12 +511,12 @@ acpi_ut_strtoul64 (
default:
/* Invalid Base */
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Skip over any white space in the buffer */
- while (ACPI_IS_SPACE (*string) || *string == '\t') {
+ while (ACPI_IS_SPACE(*string) || *string == '\t') {
string++;
}
@@ -454,12 +525,10 @@ acpi_ut_strtoul64 (
* determine if it is decimal or hexadecimal:
*/
if (base == 0) {
- if ((*string == '0') &&
- (ACPI_TOLOWER (*(string + 1)) == 'x')) {
+ if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
base = 16;
string += 2;
- }
- else {
+ } else {
base = 10;
}
}
@@ -469,8 +538,7 @@ acpi_ut_strtoul64 (
* 0 or 0x, if they are present.
*/
if ((base == 16) &&
- (*string == '0') &&
- (ACPI_TOLOWER (*(string + 1)) == 'x')) {
+ (*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
string += 2;
}
@@ -483,25 +551,23 @@ acpi_ut_strtoul64 (
/* Main loop: convert the string to a 64-bit integer */
while (*string) {
- if (ACPI_IS_DIGIT (*string)) {
+ if (ACPI_IS_DIGIT(*string)) {
/* Convert ASCII 0-9 to Decimal value */
- this_digit = ((u8) *string) - '0';
- }
- else {
+ this_digit = ((u8) * string) - '0';
+ } else {
if (base == 10) {
/* Digit is out of range */
goto error_exit;
}
- this_digit = (u8) ACPI_TOUPPER (*string);
- if (ACPI_IS_XDIGIT ((char) this_digit)) {
+ this_digit = (u8) ACPI_TOUPPER(*string);
+ if (ACPI_IS_XDIGIT((char)this_digit)) {
/* Convert ASCII Hex char to value */
this_digit = this_digit - 'A' + 10;
- }
- else {
+ } else {
/*
* We allow non-hex chars, just stop now, same as end-of-string.
* See ACPI spec, string-to-integer conversion.
@@ -512,8 +578,10 @@ acpi_ut_strtoul64 (
/* Divide the digit into the correct position */
- (void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit),
- base, &quotient, NULL);
+ (void)
+ acpi_ut_short_divide((ACPI_INTEGER_MAX -
+ (acpi_integer) this_digit), base,
+ &quotient, NULL);
if (return_value > quotient) {
goto error_exit;
}
@@ -526,335 +594,18 @@ acpi_ut_strtoul64 (
/* All done, normal exit */
*ret_integer = return_value;
- return_ACPI_STATUS (AE_OK);
-
+ return_ACPI_STATUS(AE_OK);
-error_exit:
+ error_exit:
/* Base was set/validated above */
if (base == 10) {
- return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
- }
- else {
- return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_mutex_initialize
- *
- * PARAMETERS: None.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create the system mutex objects.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ut_mutex_initialize (
- void)
-{
- u32 i;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("ut_mutex_initialize");
-
-
- /*
- * Create each of the predefined mutex objects
- */
- for (i = 0; i < NUM_MUTEX; i++) {
- status = acpi_ut_create_mutex (i);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
- }
-
- status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
- return_ACPI_STATUS (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_mutex_terminate
- *
- * PARAMETERS: None.
- *
- * RETURN: None.
- *
- * DESCRIPTION: Delete all of the system mutex objects.
- *
- ******************************************************************************/
-
-void
-acpi_ut_mutex_terminate (
- void)
-{
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("ut_mutex_terminate");
-
-
- /*
- * Delete each predefined mutex object
- */
- for (i = 0; i < NUM_MUTEX; i++) {
- (void) acpi_ut_delete_mutex (i);
- }
-
- acpi_os_delete_lock (acpi_gbl_gpe_lock);
- return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_mutex
- *
- * PARAMETERS: mutex_iD - ID of the mutex to be created
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create a mutex object.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ut_create_mutex (
- acpi_mutex_handle mutex_id)
-{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
-
-
- if (mutex_id > MAX_MUTEX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- if (!acpi_gbl_mutex_info[mutex_id].mutex) {
- status = acpi_os_create_semaphore (1, 1,
- &acpi_gbl_mutex_info[mutex_id].mutex);
- acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
- acpi_gbl_mutex_info[mutex_id].use_count = 0;
- }
-
- return_ACPI_STATUS (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_delete_mutex
- *
- * PARAMETERS: mutex_iD - ID of the mutex to be deleted
- *
- * RETURN: Status
- *
- * DESCRIPTION: Delete a mutex object.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ut_delete_mutex (
- acpi_mutex_handle mutex_id)
-{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
-
-
- if (mutex_id > MAX_MUTEX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
-
- acpi_gbl_mutex_info[mutex_id].mutex = NULL;
- acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
-
- return_ACPI_STATUS (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_acquire_mutex
- *
- * PARAMETERS: mutex_iD - ID of the mutex to be acquired
- *
- * RETURN: Status
- *
- * DESCRIPTION: Acquire a mutex object.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ut_acquire_mutex (
- acpi_mutex_handle mutex_id)
-{
- acpi_status status;
- u32 this_thread_id;
-
-
- ACPI_FUNCTION_NAME ("ut_acquire_mutex");
-
-
- if (mutex_id > MAX_MUTEX) {
- return (AE_BAD_PARAMETER);
- }
-
- this_thread_id = acpi_os_get_thread_id ();
-
-#ifdef ACPI_MUTEX_DEBUG
- {
- u32 i;
- /*
- * Mutex debug code, for internal debugging only.
- *
- * Deadlock prevention. Check if this thread owns any mutexes of value
- * greater than or equal to this one. If so, the thread has violated
- * the mutex ordering rule. This indicates a coding error somewhere in
- * the ACPI subsystem code.
- */
- for (i = mutex_id; i < MAX_MUTEX; i++) {
- if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
- if (i == mutex_id) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Mutex [%s] already acquired by this thread [%X]\n",
- acpi_ut_get_mutex_name (mutex_id), this_thread_id));
-
- return (AE_ALREADY_ACQUIRED);
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (i),
- acpi_ut_get_mutex_name (mutex_id)));
-
- return (AE_ACQUIRE_DEADLOCK);
- }
- }
- }
-#endif
-
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
- "Thread %X attempting to acquire Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
-
- status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
- 1, ACPI_WAIT_FOREVER);
- if (ACPI_SUCCESS (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
-
- acpi_gbl_mutex_info[mutex_id].use_count++;
- acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Thread %X could not acquire Mutex [%s] %s\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id),
- acpi_format_exception (status)));
- }
-
- return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_release_mutex
- *
- * PARAMETERS: mutex_iD - ID of the mutex to be released
- *
- * RETURN: Status
- *
- * DESCRIPTION: Release a mutex object.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ut_release_mutex (
- acpi_mutex_handle mutex_id)
-{
- acpi_status status;
- u32 i;
- u32 this_thread_id;
-
-
- ACPI_FUNCTION_NAME ("ut_release_mutex");
-
-
- this_thread_id = acpi_os_get_thread_id ();
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
- "Thread %X releasing Mutex [%s]\n", this_thread_id,
- acpi_ut_get_mutex_name (mutex_id)));
-
- if (mutex_id > MAX_MUTEX) {
- return (AE_BAD_PARAMETER);
- }
-
- /*
- * Mutex must be acquired in order to release it!
- */
- if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Mutex [%s] is not acquired, cannot release\n",
- acpi_ut_get_mutex_name (mutex_id)));
-
- return (AE_NOT_ACQUIRED);
- }
-
- /*
- * Deadlock prevention. Check if this thread owns any mutexes of value
- * greater than this one. If so, the thread has violated the mutex
- * ordering rule. This indicates a coding error somewhere in
- * the ACPI subsystem code.
- */
- for (i = mutex_id; i < MAX_MUTEX; i++) {
- if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
- if (i == mutex_id) {
- continue;
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid release order: owns [%s], releasing [%s]\n",
- acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
-
- return (AE_RELEASE_DEADLOCK);
- }
- }
-
- /* Mark unlocked FIRST */
-
- acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
-
- status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
-
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Thread %X could not release Mutex [%s] %s\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id),
- acpi_format_exception (status)));
+ return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
+ } else {
+ return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
}
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
- }
-
- return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_create_update_state_and_push
@@ -870,16 +621,13 @@ acpi_ut_release_mutex (
******************************************************************************/
acpi_status
-acpi_ut_create_update_state_and_push (
- union acpi_operand_object *object,
- u16 action,
- union acpi_generic_state **state_list)
+acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
+ u16 action,
+ union acpi_generic_state **state_list)
{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_ENTRY ();
+ union acpi_generic_state *state;
+ ACPI_FUNCTION_ENTRY();
/* Ignore null objects; these are expected */
@@ -887,371 +635,15 @@ acpi_ut_create_update_state_and_push (
return (AE_OK);
}
- state = acpi_ut_create_update_state (object, action);
+ state = acpi_ut_create_update_state(object, action);
if (!state) {
return (AE_NO_MEMORY);
}
- acpi_ut_push_generic_state (state_list, state);
+ acpi_ut_push_generic_state(state_list, state);
return (AE_OK);
}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_pkg_state_and_push
- *
- * PARAMETERS: Object - Object to be added to the new state
- * Action - Increment/Decrement
- * state_list - List the state will be added to
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create a new state and push it
- *
- ******************************************************************************/
-
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_ut_create_pkg_state_and_push (
- void *internal_object,
- void *external_object,
- u16 index,
- union acpi_generic_state **state_list)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- state = acpi_ut_create_pkg_state (internal_object, external_object, index);
- if (!state) {
- return (AE_NO_MEMORY);
- }
-
- acpi_ut_push_generic_state (state_list, state);
- return (AE_OK);
-}
-#endif /* ACPI_FUTURE_USAGE */
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_push_generic_state
- *
- * PARAMETERS: list_head - Head of the state stack
- * State - State object to push
- *
- * RETURN: None
- *
- * DESCRIPTION: Push a state object onto a state stack
- *
- ******************************************************************************/
-
-void
-acpi_ut_push_generic_state (
- union acpi_generic_state **list_head,
- union acpi_generic_state *state)
-{
- ACPI_FUNCTION_TRACE ("ut_push_generic_state");
-
-
- /* Push the state object onto the front of the list (stack) */
-
- state->common.next = *list_head;
- *list_head = state;
-
- return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_pop_generic_state
- *
- * PARAMETERS: list_head - Head of the state stack
- *
- * RETURN: The popped state object
- *
- * DESCRIPTION: Pop a state object from a state stack
- *
- ******************************************************************************/
-
-union acpi_generic_state *
-acpi_ut_pop_generic_state (
- union acpi_generic_state **list_head)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_TRACE ("ut_pop_generic_state");
-
-
- /* Remove the state object at the head of the list (stack) */
-
- state = *list_head;
- if (state) {
- /* Update the list head */
-
- *list_head = state->common.next;
- }
-
- return_PTR (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_generic_state
- *
- * PARAMETERS: None
- *
- * RETURN: The new state object. NULL on failure.
- *
- * DESCRIPTION: Create a generic state object. Attempt to obtain one from
- * the global state cache; If none available, create a new one.
- *
- ******************************************************************************/
-
-union acpi_generic_state *
-acpi_ut_create_generic_state (
- void)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE);
-
- /* Initialize */
-
- if (state) {
- state->common.data_type = ACPI_DESC_TYPE_STATE;
- }
-
- return (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_thread_state
- *
- * PARAMETERS: None
- *
- * RETURN: New Thread State. NULL on failure
- *
- * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
- * to track per-thread info during method execution
- *
- ******************************************************************************/
-
-struct acpi_thread_state *
-acpi_ut_create_thread_state (
- void)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_TRACE ("ut_create_thread_state");
-
-
- /* Create the generic state object */
-
- state = acpi_ut_create_generic_state ();
- if (!state) {
- return_PTR (NULL);
- }
-
- /* Init fields specific to the update struct */
-
- state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD;
- state->thread.thread_id = acpi_os_get_thread_id ();
-
- return_PTR ((struct acpi_thread_state *) state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_update_state
- *
- * PARAMETERS: Object - Initial Object to be installed in the state
- * Action - Update action to be performed
- *
- * RETURN: New state object, null on failure
- *
- * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
- * to update reference counts and delete complex objects such
- * as packages.
- *
- ******************************************************************************/
-
-union acpi_generic_state *
-acpi_ut_create_update_state (
- union acpi_operand_object *object,
- u16 action)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object);
-
-
- /* Create the generic state object */
-
- state = acpi_ut_create_generic_state ();
- if (!state) {
- return_PTR (NULL);
- }
-
- /* Init fields specific to the update struct */
-
- state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE;
- state->update.object = object;
- state->update.value = action;
-
- return_PTR (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_pkg_state
- *
- * PARAMETERS: Object - Initial Object to be installed in the state
- * Action - Update action to be performed
- *
- * RETURN: New state object, null on failure
- *
- * DESCRIPTION: Create a "Package State"
- *
- ******************************************************************************/
-
-union acpi_generic_state *
-acpi_ut_create_pkg_state (
- void *internal_object,
- void *external_object,
- u16 index)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object);
-
-
- /* Create the generic state object */
-
- state = acpi_ut_create_generic_state ();
- if (!state) {
- return_PTR (NULL);
- }
-
- /* Init fields specific to the update struct */
-
- state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE;
- state->pkg.source_object = (union acpi_operand_object *) internal_object;
- state->pkg.dest_object = external_object;
- state->pkg.index = index;
- state->pkg.num_packages = 1;
-
- return_PTR (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_create_control_state
- *
- * PARAMETERS: None
- *
- * RETURN: New state object, null on failure
- *
- * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
- * to support nested IF/WHILE constructs in the AML.
- *
- ******************************************************************************/
-
-union acpi_generic_state *
-acpi_ut_create_control_state (
- void)
-{
- union acpi_generic_state *state;
-
-
- ACPI_FUNCTION_TRACE ("ut_create_control_state");
-
-
- /* Create the generic state object */
-
- state = acpi_ut_create_generic_state ();
- if (!state) {
- return_PTR (NULL);
- }
-
- /* Init fields specific to the control struct */
-
- state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL;
- state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
-
- return_PTR (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_delete_generic_state
- *
- * PARAMETERS: State - The state object to be deleted
- *
- * RETURN: None
- *
- * DESCRIPTION: Put a state object back into the global state cache. The object
- * is not actually freed at this time.
- *
- ******************************************************************************/
-
-void
-acpi_ut_delete_generic_state (
- union acpi_generic_state *state)
-{
- ACPI_FUNCTION_TRACE ("ut_delete_generic_state");
-
-
- acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state);
- return_VOID;
-}
-
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_delete_generic_state_cache
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Purge the global state object cache. Used during subsystem
- * termination.
- *
- ******************************************************************************/
-
-void
-acpi_ut_delete_generic_state_cache (
- void)
-{
- ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache");
-
-
- acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE);
- return_VOID;
-}
-#endif
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_walk_package_tree
@@ -1268,33 +660,29 @@ acpi_ut_delete_generic_state_cache (
******************************************************************************/
acpi_status
-acpi_ut_walk_package_tree (
- union acpi_operand_object *source_object,
- void *target_object,
- acpi_pkg_callback walk_callback,
- void *context)
+acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
+ void *target_object,
+ acpi_pkg_callback walk_callback, void *context)
{
- acpi_status status = AE_OK;
- union acpi_generic_state *state_list = NULL;
- union acpi_generic_state *state;
- u32 this_index;
- union acpi_operand_object *this_source_obj;
-
-
- ACPI_FUNCTION_TRACE ("ut_walk_package_tree");
+ acpi_status status = AE_OK;
+ union acpi_generic_state *state_list = NULL;
+ union acpi_generic_state *state;
+ u32 this_index;
+ union acpi_operand_object *this_source_obj;
+ ACPI_FUNCTION_TRACE("ut_walk_package_tree");
- state = acpi_ut_create_pkg_state (source_object, target_object, 0);
+ state = acpi_ut_create_pkg_state(source_object, target_object, 0);
if (!state) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
while (state) {
/* Get one element of the package */
- this_index = state->pkg.index;
+ this_index = state->pkg.index;
this_source_obj = (union acpi_operand_object *)
- state->pkg.source_object->package.elements[this_index];
+ state->pkg.source_object->package.elements[this_index];
/*
* Check for:
@@ -1305,16 +693,20 @@ acpi_ut_walk_package_tree (
* case below.
*/
if ((!this_source_obj) ||
- (ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) {
- status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
- state, context);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
+ ACPI_DESC_TYPE_OPERAND)
+ || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
+ ACPI_TYPE_PACKAGE)) {
+ status =
+ walk_callback(ACPI_COPY_TYPE_SIMPLE,
+ this_source_obj, state, context);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
state->pkg.index++;
- while (state->pkg.index >= state->pkg.source_object->package.count) {
+ while (state->pkg.index >=
+ state->pkg.source_object->package.count) {
/*
* We've handled all of the objects at this level, This means
* that we have just completed a package. That package may
@@ -1322,8 +714,8 @@ acpi_ut_walk_package_tree (
*
* Delete this state and pop the previous state (package).
*/
- acpi_ut_delete_generic_state (state);
- state = acpi_ut_pop_generic_state (&state_list);
+ acpi_ut_delete_generic_state(state);
+ state = acpi_ut_pop_generic_state(&state_list);
/* Finished when there are no more states */
@@ -1333,7 +725,7 @@ acpi_ut_walk_package_tree (
* package just add the length of the package objects
* and exit
*/
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/*
@@ -1342,35 +734,35 @@ acpi_ut_walk_package_tree (
*/
state->pkg.index++;
}
- }
- else {
+ } else {
/* This is a subobject of type package */
- status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
- state, context);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ walk_callback(ACPI_COPY_TYPE_PACKAGE,
+ this_source_obj, state, context);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* Push the current state and create a new one
* The callback above returned a new target package object.
*/
- acpi_ut_push_generic_state (&state_list, state);
- state = acpi_ut_create_pkg_state (this_source_obj,
- state->pkg.this_target_obj, 0);
+ acpi_ut_push_generic_state(&state_list, state);
+ state = acpi_ut_create_pkg_state(this_source_obj,
+ state->pkg.
+ this_target_obj, 0);
if (!state) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS(AE_NO_MEMORY);
}
}
}
/* We should never get here */
- return_ACPI_STATUS (AE_AML_INTERNAL);
+ return_ACPI_STATUS(AE_AML_INTERNAL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_generate_checksum
@@ -1384,23 +776,18 @@ acpi_ut_walk_package_tree (
*
******************************************************************************/
-u8
-acpi_ut_generate_checksum (
- u8 *buffer,
- u32 length)
+u8 acpi_ut_generate_checksum(u8 * buffer, u32 length)
{
- u32 i;
- signed char sum = 0;
-
+ u32 i;
+ signed char sum = 0;
for (i = 0; i < length; i++) {
- sum = (signed char) (sum + buffer[i]);
+ sum = (signed char)(sum + buffer[i]);
}
return ((u8) (0 - sum));
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_resource_end_tag
@@ -1413,17 +800,13 @@ acpi_ut_generate_checksum (
*
******************************************************************************/
-
-u8 *
-acpi_ut_get_resource_end_tag (
- union acpi_operand_object *obj_desc)
+u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc)
{
- u8 buffer_byte;
- u8 *buffer;
- u8 *end_buffer;
-
+ u8 buffer_byte;
+ u8 *buffer;
+ u8 *end_buffer;
- buffer = obj_desc->buffer.pointer;
+ buffer = obj_desc->buffer.pointer;
end_buffer = buffer + obj_desc->buffer.length;
while (buffer < end_buffer) {
@@ -1431,12 +814,12 @@ acpi_ut_get_resource_end_tag (
if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
/* Large Descriptor - Length is next 2 bytes */
- buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3);
- }
- else {
+ buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3);
+ } else {
/* Small Descriptor. End Tag will be found here */
- if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) {
+ if ((buffer_byte & ACPI_RDESC_SMALL_MASK) ==
+ ACPI_RDESC_TYPE_END_TAG) {
/* Found the end tag descriptor, all done. */
return (buffer);
@@ -1453,7 +836,6 @@ acpi_ut_get_resource_end_tag (
return (NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_report_error
@@ -1468,17 +850,12 @@ acpi_ut_get_resource_end_tag (
*
******************************************************************************/
-void
-acpi_ut_report_error (
- char *module_name,
- u32 line_number,
- u32 component_id)
+void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id)
{
- acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
+ acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_report_warning
@@ -1494,16 +871,12 @@ acpi_ut_report_error (
******************************************************************************/
void
-acpi_ut_report_warning (
- char *module_name,
- u32 line_number,
- u32 component_id)
+acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id)
{
- acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number);
+ acpi_os_printf("%8s-%04d: *** Warning: ", module_name, line_number);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_report_info
@@ -1518,14 +891,8 @@ acpi_ut_report_warning (
*
******************************************************************************/
-void
-acpi_ut_report_info (
- char *module_name,
- u32 line_number,
- u32 component_id)
+void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id)
{
- acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
+ acpi_os_printf("%8s-%04d: *** Info: ", module_name, line_number);
}
-
-
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
new file mode 100644
index 000000000000..90134c56ece9
--- /dev/null
+++ b/drivers/acpi/utilities/utmutex.c
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ *
+ * Module Name: utmutex - local mutex support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utmutex")
+
+/* Local prototypes */
+static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
+
+static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_mutex_initialize
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the system mutex objects.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_mutex_initialize(void)
+{
+ u32 i;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("ut_mutex_initialize");
+
+ /*
+ * Create each of the predefined mutex objects
+ */
+ for (i = 0; i < NUM_MUTEX; i++) {
+ status = acpi_ut_create_mutex(i);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ status = acpi_os_create_lock(&acpi_gbl_gpe_lock);
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_mutex_terminate
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Delete all of the system mutex objects.
+ *
+ ******************************************************************************/
+
+void acpi_ut_mutex_terminate(void)
+{
+ u32 i;
+
+ ACPI_FUNCTION_TRACE("ut_mutex_terminate");
+
+ /*
+ * Delete each predefined mutex object
+ */
+ for (i = 0; i < NUM_MUTEX; i++) {
+ (void)acpi_ut_delete_mutex(i);
+ }
+
+ acpi_os_delete_lock(acpi_gbl_gpe_lock);
+ return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be created
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a mutex object.
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
+{
+ acpi_status status = AE_OK;
+
+ ACPI_FUNCTION_TRACE_U32("ut_create_mutex", mutex_id);
+
+ if (mutex_id > MAX_MUTEX) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ if (!acpi_gbl_mutex_info[mutex_id].mutex) {
+ status = acpi_os_create_semaphore(1, 1,
+ &acpi_gbl_mutex_info
+ [mutex_id].mutex);
+ acpi_gbl_mutex_info[mutex_id].thread_id =
+ ACPI_MUTEX_NOT_ACQUIRED;
+ acpi_gbl_mutex_info[mutex_id].use_count = 0;
+ }
+
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be deleted
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete a mutex object.
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE_U32("ut_delete_mutex", mutex_id);
+
+ if (mutex_id > MAX_MUTEX) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ status = acpi_os_delete_semaphore(acpi_gbl_mutex_info[mutex_id].mutex);
+
+ acpi_gbl_mutex_info[mutex_id].mutex = NULL;
+ acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be acquired
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
+{
+ acpi_status status;
+ u32 this_thread_id;
+
+ ACPI_FUNCTION_NAME("ut_acquire_mutex");
+
+ if (mutex_id > MAX_MUTEX) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ this_thread_id = acpi_os_get_thread_id();
+
+#ifdef ACPI_MUTEX_DEBUG
+ {
+ u32 i;
+ /*
+ * Mutex debug code, for internal debugging only.
+ *
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than or equal to this one. If so, the thread has violated
+ * the mutex ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+ for (i = mutex_id; i < MAX_MUTEX; i++) {
+ if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+ if (i == mutex_id) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Mutex [%s] already acquired by this thread [%X]\n",
+ acpi_ut_get_mutex_name
+ (mutex_id),
+ this_thread_id));
+
+ return (AE_ALREADY_ACQUIRED);
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
+ this_thread_id,
+ acpi_ut_get_mutex_name(i),
+ acpi_ut_get_mutex_name
+ (mutex_id)));
+
+ return (AE_ACQUIRE_DEADLOCK);
+ }
+ }
+ }
+#endif
+
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
+ "Thread %X attempting to acquire Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
+
+ status = acpi_os_wait_semaphore(acpi_gbl_mutex_info[mutex_id].mutex,
+ 1, ACPI_WAIT_FOREVER);
+ if (ACPI_SUCCESS(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
+ "Thread %X acquired Mutex [%s]\n",
+ this_thread_id,
+ acpi_ut_get_mutex_name(mutex_id)));
+
+ acpi_gbl_mutex_info[mutex_id].use_count++;
+ acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Thread %X could not acquire Mutex [%s] %s\n",
+ this_thread_id,
+ acpi_ut_get_mutex_name(mutex_id),
+ acpi_format_exception(status)));
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_release_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be released
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
+{
+ acpi_status status;
+ u32 this_thread_id;
+
+ ACPI_FUNCTION_NAME("ut_release_mutex");
+
+ this_thread_id = acpi_os_get_thread_id();
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
+ "Thread %X releasing Mutex [%s]\n", this_thread_id,
+ acpi_ut_get_mutex_name(mutex_id)));
+
+ if (mutex_id > MAX_MUTEX) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Mutex must be acquired in order to release it!
+ */
+ if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Mutex [%s] is not acquired, cannot release\n",
+ acpi_ut_get_mutex_name(mutex_id)));
+
+ return (AE_NOT_ACQUIRED);
+ }
+#ifdef ACPI_MUTEX_DEBUG
+ {
+ u32 i;
+ /*
+ * Mutex debug code, for internal debugging only.
+ *
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than this one. If so, the thread has violated the mutex
+ * ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+ for (i = mutex_id; i < MAX_MUTEX; i++) {
+ if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+ if (i == mutex_id) {
+ continue;
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid release order: owns [%s], releasing [%s]\n",
+ acpi_ut_get_mutex_name(i),
+ acpi_ut_get_mutex_name
+ (mutex_id)));
+
+ return (AE_RELEASE_DEADLOCK);
+ }
+ }
+ }
+#endif
+
+ /* Mark unlocked FIRST */
+
+ acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+ status =
+ acpi_os_signal_semaphore(acpi_gbl_mutex_info[mutex_id].mutex, 1);
+
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Thread %X could not release Mutex [%s] %s\n",
+ this_thread_id,
+ acpi_ut_get_mutex_name(mutex_id),
+ acpi_format_exception(status)));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
+ "Thread %X released Mutex [%s]\n",
+ this_thread_id,
+ acpi_ut_get_mutex_name(mutex_id)));
+ }
+
+ return (status);
+}
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index cd3899b9cc5a..3015e1540053 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -41,34 +41,26 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/amlcode.h>
-
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utobject")
+ACPI_MODULE_NAME("utobject")
/* Local prototypes */
-
static acpi_status
-acpi_ut_get_simple_object_size (
- union acpi_operand_object *obj,
- acpi_size *obj_length);
+acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
+ acpi_size * obj_length);
static acpi_status
-acpi_ut_get_package_object_size (
- union acpi_operand_object *obj,
- acpi_size *obj_length);
+acpi_ut_get_package_object_size(union acpi_operand_object *obj,
+ acpi_size * obj_length);
static acpi_status
-acpi_ut_get_element_length (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context);
-
+acpi_ut_get_element_length(u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state, void *context);
/*******************************************************************************
*
@@ -91,26 +83,25 @@ acpi_ut_get_element_length (
*
******************************************************************************/
-union acpi_operand_object *
-acpi_ut_create_internal_object_dbg (
- char *module_name,
- u32 line_number,
- u32 component_id,
- acpi_object_type type)
+union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
+ u32 line_number,
+ u32 component_id,
+ acpi_object_type
+ type)
{
- union acpi_operand_object *object;
- union acpi_operand_object *second_object;
-
-
- ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg",
- acpi_ut_get_type_name (type));
+ union acpi_operand_object *object;
+ union acpi_operand_object *second_object;
+ ACPI_FUNCTION_TRACE_STR("ut_create_internal_object_dbg",
+ acpi_ut_get_type_name(type));
/* Allocate the raw object descriptor */
- object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+ object =
+ acpi_ut_allocate_object_desc_dbg(module_name, line_number,
+ component_id);
if (!object) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
switch (type) {
@@ -119,11 +110,12 @@ acpi_ut_create_internal_object_dbg (
/* These types require a secondary object */
- second_object = acpi_ut_allocate_object_desc_dbg (module_name,
- line_number, component_id);
+ second_object = acpi_ut_allocate_object_desc_dbg(module_name,
+ line_number,
+ component_id);
if (!second_object) {
- acpi_ut_delete_object_desc (object);
- return_PTR (NULL);
+ acpi_ut_delete_object_desc(object);
+ return_PTR(NULL);
}
second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
@@ -149,10 +141,9 @@ acpi_ut_create_internal_object_dbg (
/* Any per-type initialization should go here */
- return_PTR (object);
+ return_PTR(object);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_create_buffer_object
@@ -165,22 +156,18 @@ acpi_ut_create_internal_object_dbg (
*
******************************************************************************/
-union acpi_operand_object *
-acpi_ut_create_buffer_object (
- acpi_size buffer_size)
+union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
{
- union acpi_operand_object *buffer_desc;
- u8 *buffer = NULL;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
+ union acpi_operand_object *buffer_desc;
+ u8 *buffer = NULL;
+ ACPI_FUNCTION_TRACE_U32("ut_create_buffer_object", buffer_size);
/* Create a new Buffer object */
- buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+ buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
if (!buffer_desc) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
/* Create an actual buffer only if size > 0 */
@@ -188,12 +175,11 @@ acpi_ut_create_buffer_object (
if (buffer_size > 0) {
/* Allocate the actual buffer */
- buffer = ACPI_MEM_CALLOCATE (buffer_size);
+ buffer = ACPI_MEM_CALLOCATE(buffer_size);
if (!buffer) {
- ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
- (u32) buffer_size));
- acpi_ut_remove_reference (buffer_desc);
- return_PTR (NULL);
+ ACPI_REPORT_ERROR(("create_buffer: could not allocate size %X\n", (u32) buffer_size));
+ acpi_ut_remove_reference(buffer_desc);
+ return_PTR(NULL);
}
}
@@ -205,10 +191,9 @@ acpi_ut_create_buffer_object (
/* Return the new buffer descriptor */
- return_PTR (buffer_desc);
+ return_PTR(buffer_desc);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_create_string_object
@@ -223,34 +208,29 @@ acpi_ut_create_buffer_object (
*
******************************************************************************/
-union acpi_operand_object *
-acpi_ut_create_string_object (
- acpi_size string_size)
+union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
{
- union acpi_operand_object *string_desc;
- char *string;
-
-
- ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size);
+ union acpi_operand_object *string_desc;
+ char *string;
+ ACPI_FUNCTION_TRACE_U32("ut_create_string_object", string_size);
/* Create a new String object */
- string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+ string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
if (!string_desc) {
- return_PTR (NULL);
+ return_PTR(NULL);
}
/*
* Allocate the actual string buffer -- (Size + 1) for NULL terminator.
* NOTE: Zero-length strings are NULL terminated
*/
- string = ACPI_MEM_CALLOCATE (string_size + 1);
+ string = ACPI_MEM_CALLOCATE(string_size + 1);
if (!string) {
- ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n",
- (u32) string_size));
- acpi_ut_remove_reference (string_desc);
- return_PTR (NULL);
+ ACPI_REPORT_ERROR(("create_string: could not allocate size %X\n", (u32) string_size));
+ acpi_ut_remove_reference(string_desc);
+ return_PTR(NULL);
}
/* Complete string object initialization */
@@ -260,10 +240,9 @@ acpi_ut_create_string_object (
/* Return the new string descriptor */
- return_PTR (string_desc);
+ return_PTR(string_desc);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_valid_internal_object
@@ -276,24 +255,21 @@ acpi_ut_create_string_object (
*
******************************************************************************/
-u8
-acpi_ut_valid_internal_object (
- void *object)
+u8 acpi_ut_valid_internal_object(void *object)
{
- ACPI_FUNCTION_NAME ("ut_valid_internal_object");
-
+ ACPI_FUNCTION_NAME("ut_valid_internal_object");
/* Check for a null pointer */
if (!object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
return (FALSE);
}
/* Check the descriptor type field */
- switch (ACPI_GET_DESCRIPTOR_TYPE (object)) {
+ switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
case ACPI_DESC_TYPE_OPERAND:
/* The object appears to be a valid union acpi_operand_object */
@@ -301,16 +277,15 @@ acpi_ut_valid_internal_object (
return (TRUE);
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "%p is not not an ACPI operand obj [%s]\n",
- object, acpi_ut_get_descriptor_name (object)));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "%p is not not an ACPI operand obj [%s]\n",
+ object, acpi_ut_get_descriptor_name(object)));
break;
}
return (FALSE);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_allocate_object_desc_dbg
@@ -326,37 +301,31 @@ acpi_ut_valid_internal_object (
*
******************************************************************************/
-void *
-acpi_ut_allocate_object_desc_dbg (
- char *module_name,
- u32 line_number,
- u32 component_id)
+void *acpi_ut_allocate_object_desc_dbg(char *module_name,
+ u32 line_number, u32 component_id)
{
- union acpi_operand_object *object;
+ union acpi_operand_object *object;
+ ACPI_FUNCTION_TRACE("ut_allocate_object_desc_dbg");
- ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg");
-
-
- object = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_OPERAND);
+ object = acpi_os_acquire_object(acpi_gbl_operand_cache);
if (!object) {
- _ACPI_REPORT_ERROR (module_name, line_number, component_id,
- ("Could not allocate an object descriptor\n"));
+ _ACPI_REPORT_ERROR(module_name, line_number, component_id,
+ ("Could not allocate an object descriptor\n"));
- return_PTR (NULL);
+ return_PTR(NULL);
}
/* Mark the descriptor type */
+ memset(object, 0, sizeof(union acpi_operand_object));
+ ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
- ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND);
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
+ object, (u32) sizeof(union acpi_operand_object)));
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
- object, (u32) sizeof (union acpi_operand_object)));
-
- return_PTR (object);
+ return_PTR(object);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_delete_object_desc
@@ -369,54 +338,22 @@ acpi_ut_allocate_object_desc_dbg (
*
******************************************************************************/
-void
-acpi_ut_delete_object_desc (
- union acpi_operand_object *object)
+void acpi_ut_delete_object_desc(union acpi_operand_object *object)
{
- ACPI_FUNCTION_TRACE_PTR ("ut_delete_object_desc", object);
-
+ ACPI_FUNCTION_TRACE_PTR("ut_delete_object_desc", object);
/* Object must be an union acpi_operand_object */
- if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "%p is not an ACPI Operand object [%s]\n", object,
- acpi_ut_get_descriptor_name (object)));
+ if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "%p is not an ACPI Operand object [%s]\n",
+ object, acpi_ut_get_descriptor_name(object)));
return_VOID;
}
- acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object);
-
- return_VOID;
-}
-
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_delete_object_cache
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Purge the global state object cache. Used during subsystem
- * termination.
- *
- ******************************************************************************/
-
-void
-acpi_ut_delete_object_cache (
- void)
-{
- ACPI_FUNCTION_TRACE ("ut_delete_object_cache");
-
-
- acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND);
+ (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
return_VOID;
}
-#endif
-
/*******************************************************************************
*
@@ -436,16 +373,13 @@ acpi_ut_delete_object_cache (
******************************************************************************/
static acpi_status
-acpi_ut_get_simple_object_size (
- union acpi_operand_object *internal_object,
- acpi_size *obj_length)
+acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
+ acpi_size * obj_length)
{
- acpi_size length;
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object);
+ acpi_size length;
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE_PTR("ut_get_simple_object_size", internal_object);
/*
* Handle a null object (Could be a uninitialized package
@@ -453,18 +387,18 @@ acpi_ut_get_simple_object_size (
*/
if (!internal_object) {
*obj_length = 0;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
/* Start with the length of the Acpi object */
- length = sizeof (union acpi_object);
+ length = sizeof(union acpi_object);
- if (ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
/* Object is a named object (reference), just return the length */
- *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length);
- return_ACPI_STATUS (status);
+ *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
+ return_ACPI_STATUS(status);
}
/*
@@ -473,19 +407,17 @@ acpi_ut_get_simple_object_size (
* must be accessed bytewise or there may be alignment problems on
* certain processors
*/
- switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
+ switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
case ACPI_TYPE_STRING:
length += (acpi_size) internal_object->string.length + 1;
break;
-
case ACPI_TYPE_BUFFER:
length += (acpi_size) internal_object->buffer.length;
break;
-
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
@@ -495,7 +427,6 @@ acpi_ut_get_simple_object_size (
*/
break;
-
case ACPI_TYPE_LOCAL_REFERENCE:
switch (internal_object->reference.opcode) {
@@ -505,8 +436,10 @@ acpi_ut_get_simple_object_size (
* Get the actual length of the full pathname to this object.
* The reference will be converted to the pathname to the object
*/
- length += ACPI_ROUND_UP_TO_NATIVE_WORD (
- acpi_ns_get_pathname_length (internal_object->reference.node));
+ length +=
+ ACPI_ROUND_UP_TO_NATIVE_WORD
+ (acpi_ns_get_pathname_length
+ (internal_object->reference.node));
break;
default:
@@ -516,19 +449,21 @@ acpi_ut_get_simple_object_size (
* Notably, Locals and Args are not supported, but this may be
* required eventually.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unsupported Reference opcode=%X in object %p\n",
- internal_object->reference.opcode, internal_object));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unsupported Reference opcode=%X in object %p\n",
+ internal_object->reference.opcode,
+ internal_object));
status = AE_TYPE;
break;
}
break;
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n",
- ACPI_GET_OBJECT_TYPE (internal_object), internal_object));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unsupported type=%X in object %p\n",
+ ACPI_GET_OBJECT_TYPE(internal_object),
+ internal_object));
status = AE_TYPE;
break;
}
@@ -539,11 +474,10 @@ acpi_ut_get_simple_object_size (
* on a machine word boundary. (preventing alignment faults on some
* machines.)
*/
- *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length);
- return_ACPI_STATUS (status);
+ *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_element_length
@@ -557,16 +491,13 @@ acpi_ut_get_simple_object_size (
******************************************************************************/
static acpi_status
-acpi_ut_get_element_length (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context)
+acpi_ut_get_element_length(u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state, void *context)
{
- acpi_status status = AE_OK;
- struct acpi_pkg_info *info = (struct acpi_pkg_info *) context;
- acpi_size object_space;
-
+ acpi_status status = AE_OK;
+ struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
+ acpi_size object_space;
switch (object_type) {
case ACPI_COPY_TYPE_SIMPLE:
@@ -575,15 +506,16 @@ acpi_ut_get_element_length (
* Simple object - just get the size (Null object/entry is handled
* here also) and sum it into the running package length
*/
- status = acpi_ut_get_simple_object_size (source_object, &object_space);
- if (ACPI_FAILURE (status)) {
+ status =
+ acpi_ut_get_simple_object_size(source_object,
+ &object_space);
+ if (ACPI_FAILURE(status)) {
return (status);
}
info->length += object_space;
break;
-
case ACPI_COPY_TYPE_PACKAGE:
/* Package object - nothing much to do here, let the walk handle it */
@@ -592,7 +524,6 @@ acpi_ut_get_element_length (
state->pkg.this_target_obj = NULL;
break;
-
default:
/* No other types allowed */
@@ -603,7 +534,6 @@ acpi_ut_get_element_length (
return (status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_package_object_size
@@ -622,25 +552,22 @@ acpi_ut_get_element_length (
******************************************************************************/
static acpi_status
-acpi_ut_get_package_object_size (
- union acpi_operand_object *internal_object,
- acpi_size *obj_length)
+acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
+ acpi_size * obj_length)
{
- acpi_status status;
- struct acpi_pkg_info info;
+ acpi_status status;
+ struct acpi_pkg_info info;
+ ACPI_FUNCTION_TRACE_PTR("ut_get_package_object_size", internal_object);
- ACPI_FUNCTION_TRACE_PTR ("ut_get_package_object_size", internal_object);
-
-
- info.length = 0;
+ info.length = 0;
info.object_space = 0;
info.num_packages = 1;
- status = acpi_ut_walk_package_tree (internal_object, NULL,
- acpi_ut_get_element_length, &info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_walk_package_tree(internal_object, NULL,
+ acpi_ut_get_element_length, &info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
@@ -648,16 +575,15 @@ acpi_ut_get_package_object_size (
* just add the length of the package objects themselves.
* Round up to the next machine word.
*/
- info.length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)) *
- (acpi_size) info.num_packages;
+ info.length += ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
+ (acpi_size) info.num_packages;
/* Return the total package length */
*obj_length = info.length;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_object_size
@@ -673,25 +599,23 @@ acpi_ut_get_package_object_size (
******************************************************************************/
acpi_status
-acpi_ut_get_object_size (
- union acpi_operand_object *internal_object,
- acpi_size *obj_length)
+acpi_ut_get_object_size(union acpi_operand_object *internal_object,
+ acpi_size * obj_length)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- if ((ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_OPERAND) &&
- (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE)) {
- status = acpi_ut_get_package_object_size (internal_object, obj_length);
- }
- else {
- status = acpi_ut_get_simple_object_size (internal_object, obj_length);
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
+ ACPI_DESC_TYPE_OPERAND)
+ && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+ status =
+ acpi_ut_get_package_object_size(internal_object,
+ obj_length);
+ } else {
+ status =
+ acpi_ut_get_simple_object_size(internal_object, obj_length);
}
return (status);
}
-
-
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
new file mode 100644
index 000000000000..c1cb27583be8
--- /dev/null
+++ b/drivers/acpi/utilities/utstate.c
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ *
+ * Module Name: utstate - state object support procedures
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utstate")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_pkg_state_and_push
+ *
+ * PARAMETERS: Object - Object to be added to the new state
+ * Action - Increment/Decrement
+ * state_list - List the state will be added to
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+acpi_status
+acpi_ut_create_pkg_state_and_push(void *internal_object,
+ void *external_object,
+ u16 index,
+ union acpi_generic_state ** state_list)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_ENTRY();
+
+ state =
+ acpi_ut_create_pkg_state(internal_object, external_object, index);
+ if (!state) {
+ return (AE_NO_MEMORY);
+ }
+
+ acpi_ut_push_generic_state(state_list, state);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_push_generic_state
+ *
+ * PARAMETERS: list_head - Head of the state stack
+ * State - State object to push
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push a state object onto a state stack
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_push_generic_state(union acpi_generic_state **list_head,
+ union acpi_generic_state *state)
+{
+ ACPI_FUNCTION_TRACE("ut_push_generic_state");
+
+ /* Push the state object onto the front of the list (stack) */
+
+ state->common.next = *list_head;
+ *list_head = state;
+
+ return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_pop_generic_state
+ *
+ * PARAMETERS: list_head - Head of the state stack
+ *
+ * RETURN: The popped state object
+ *
+ * DESCRIPTION: Pop a state object from a state stack
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
+ **list_head)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_TRACE("ut_pop_generic_state");
+
+ /* Remove the state object at the head of the list (stack) */
+
+ state = *list_head;
+ if (state) {
+ /* Update the list head */
+
+ *list_head = state->common.next;
+ }
+
+ return_PTR(state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_generic_state
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: The new state object. NULL on failure.
+ *
+ * DESCRIPTION: Create a generic state object. Attempt to obtain one from
+ * the global state cache; If none available, create a new one.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *acpi_ut_create_generic_state(void)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_ENTRY();
+
+ state = acpi_os_acquire_object(acpi_gbl_state_cache);
+ if (state) {
+ /* Initialize */
+ memset(state, 0, sizeof(union acpi_generic_state));
+ state->common.data_type = ACPI_DESC_TYPE_STATE;
+ }
+
+ return (state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_thread_state
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: New Thread State. NULL on failure
+ *
+ * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
+ * to track per-thread info during method execution
+ *
+ ******************************************************************************/
+
+struct acpi_thread_state *acpi_ut_create_thread_state(void)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_TRACE("ut_create_thread_state");
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state();
+ if (!state) {
+ return_PTR(NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD;
+ state->thread.thread_id = acpi_os_get_thread_id();
+
+ return_PTR((struct acpi_thread_state *)state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_update_state
+ *
+ * PARAMETERS: Object - Initial Object to be installed in the state
+ * Action - Update action to be performed
+ *
+ * RETURN: New state object, null on failure
+ *
+ * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
+ * to update reference counts and delete complex objects such
+ * as packages.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
+ *object, u16 action)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_TRACE_PTR("ut_create_update_state", object);
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state();
+ if (!state) {
+ return_PTR(NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE;
+ state->update.object = object;
+ state->update.value = action;
+
+ return_PTR(state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_pkg_state
+ *
+ * PARAMETERS: Object - Initial Object to be installed in the state
+ * Action - Update action to be performed
+ *
+ * RETURN: New state object, null on failure
+ *
+ * DESCRIPTION: Create a "Package State"
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
+ void *external_object,
+ u16 index)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_TRACE_PTR("ut_create_pkg_state", internal_object);
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state();
+ if (!state) {
+ return_PTR(NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE;
+ state->pkg.source_object = (union acpi_operand_object *)internal_object;
+ state->pkg.dest_object = external_object;
+ state->pkg.index = index;
+ state->pkg.num_packages = 1;
+
+ return_PTR(state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_control_state
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: New state object, null on failure
+ *
+ * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
+ * to support nested IF/WHILE constructs in the AML.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *acpi_ut_create_control_state(void)
+{
+ union acpi_generic_state *state;
+
+ ACPI_FUNCTION_TRACE("ut_create_control_state");
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state();
+ if (!state) {
+ return_PTR(NULL);
+ }
+
+ /* Init fields specific to the control struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL;
+ state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
+
+ return_PTR(state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_generic_state
+ *
+ * PARAMETERS: State - The state object to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Put a state object back into the global state cache. The object
+ * is not actually freed at this time.
+ *
+ ******************************************************************************/
+
+void acpi_ut_delete_generic_state(union acpi_generic_state *state)
+{
+ ACPI_FUNCTION_TRACE("ut_delete_generic_state");
+
+ (void)acpi_os_release_object(acpi_gbl_state_cache, state);
+ return_VOID;
+}
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index e8803d810656..f06bd5e5e9d1 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -46,13 +46,10 @@
#include <acpi/acpi.h>
#include <acpi/acevents.h>
#include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
-#include <acpi/acdispat.h>
#include <acpi/acdebug.h>
#define _COMPONENT ACPI_UTILITIES
- ACPI_MODULE_NAME ("utxface")
-
+ACPI_MODULE_NAME("utxface")
/*******************************************************************************
*
@@ -66,61 +63,54 @@
* called, so any early initialization belongs here.
*
******************************************************************************/
-
-acpi_status
-acpi_initialize_subsystem (
- void)
+acpi_status acpi_initialize_subsystem(void)
{
- acpi_status status;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_initialize_subsystem");
- ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem");
+ ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
+ /* Initialize the OS-Dependent layer */
- ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ());
-
+ status = acpi_os_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("OSD failed to initialize, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
+ }
/* Initialize all globals used by the subsystem */
- acpi_ut_init_globals ();
-
- /* Initialize the OS-Dependent layer */
-
- status = acpi_os_initialize ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("OSD failed to initialize, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
- }
+ acpi_ut_init_globals();
/* Create the default mutex objects */
- status = acpi_ut_mutex_initialize ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Global mutex creation failure, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ut_mutex_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Global mutex creation failure, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
/*
* Initialize the namespace manager and
* the root of the namespace tree
*/
- status = acpi_ns_root_initialize ();
- if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n",
- acpi_format_exception (status)));
- return_ACPI_STATUS (status);
+ status = acpi_ns_root_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_REPORT_ERROR(("Namespace initialization failure, %s\n",
+ acpi_format_exception(status)));
+ return_ACPI_STATUS(status);
}
/* If configured, initialize the AML debugger */
- ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ());
+ ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_enable_subsystem
@@ -134,41 +124,39 @@ acpi_initialize_subsystem (
*
******************************************************************************/
-acpi_status
-acpi_enable_subsystem (
- u32 flags)
+acpi_status acpi_enable_subsystem(u32 flags)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("acpi_enable_subsystem");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("acpi_enable_subsystem");
/*
* We must initialize the hardware before we can enable ACPI.
* The values from the FADT are validated here.
*/
if (!(flags & ACPI_NO_HARDWARE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Initializing ACPI hardware\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI hardware\n"));
- status = acpi_hw_initialize ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_hw_initialize();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Enable ACPI mode */
if (!(flags & ACPI_NO_ACPI_ENABLE)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Going into ACPI mode\n"));
acpi_gbl_original_mode = acpi_hw_get_mode();
- status = acpi_enable ();
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_enable failed.\n"));
- return_ACPI_STATUS (status);
+ status = acpi_enable();
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "acpi_enable failed.\n"));
+ return_ACPI_STATUS(status);
}
}
@@ -178,12 +166,12 @@ acpi_enable_subsystem (
* install_address_space_handler interface.
*/
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Installing default address space handlers\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Installing default address space handlers\n"));
- status = acpi_ev_install_region_handlers ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ev_install_region_handlers();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -196,28 +184,28 @@ acpi_enable_subsystem (
* execution!
*/
if (!(flags & ACPI_NO_EVENT_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Initializing ACPI events\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI events\n"));
- status = acpi_ev_initialize_events ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ev_initialize_events();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
/* Install the SCI handler and Global Lock handler */
if (!(flags & ACPI_NO_HANDLER_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Installing SCI/GL handlers\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Installing SCI/GL handlers\n"));
- status = acpi_ev_install_xrupt_handlers ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ev_install_xrupt_handlers();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -233,15 +221,11 @@ acpi_enable_subsystem (
*
******************************************************************************/
-acpi_status
-acpi_initialize_objects (
- u32 flags)
+acpi_status acpi_initialize_objects(u32 flags)
{
- acpi_status status = AE_OK;
-
-
- ACPI_FUNCTION_TRACE ("acpi_initialize_objects");
+ acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE("acpi_initialize_objects");
/*
* Run all _REG methods
@@ -251,12 +235,12 @@ acpi_initialize_objects (
* contain executable AML (see call to acpi_ns_initialize_objects below).
*/
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Executing _REG op_region methods\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Executing _REG op_region methods\n"));
- status = acpi_ev_initialize_op_regions ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ev_initialize_op_regions();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -266,12 +250,12 @@ acpi_initialize_objects (
* objects: operation_regions, buffer_fields, Buffers, and Packages.
*/
if (!(flags & ACPI_NO_OBJECT_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Completing Initialization of ACPI Objects\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Completing Initialization of ACPI Objects\n"));
- status = acpi_ns_initialize_objects ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_initialize_objects();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -280,12 +264,12 @@ acpi_initialize_objects (
* This runs the _STA and _INI methods.
*/
if (!(flags & ACPI_NO_DEVICE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "[Init] Initializing ACPI Devices\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI Devices\n"));
- status = acpi_ns_initialize_devices ();
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ns_initialize_devices();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
}
@@ -294,13 +278,12 @@ acpi_initialize_objects (
* the table load filled them up more than they will be at runtime --
* thus wasting non-paged memory.
*/
- status = acpi_purge_cached_objects ();
+ status = acpi_purge_cached_objects();
acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
- return_ACPI_STATUS (status);
+ return_ACPI_STATUS(status);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_terminate
@@ -313,15 +296,11 @@ acpi_initialize_objects (
*
******************************************************************************/
-acpi_status
-acpi_terminate (
- void)
+acpi_status acpi_terminate(void)
{
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE ("acpi_terminate");
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("acpi_terminate");
/* Terminate the AML Debugger if present */
@@ -329,28 +308,25 @@ acpi_terminate (
/* Shutdown and free all resources */
- acpi_ut_subsystem_shutdown ();
-
+ acpi_ut_subsystem_shutdown();
/* Free the mutex objects */
- acpi_ut_mutex_terminate ();
-
+ acpi_ut_mutex_terminate();
#ifdef ACPI_DEBUGGER
/* Shut down the debugger */
- acpi_db_terminate ();
+ acpi_db_terminate();
#endif
/* Now we can shutdown the OS-dependent layer */
- status = acpi_os_terminate ();
- return_ACPI_STATUS (status);
+ status = acpi_os_terminate();
+ return_ACPI_STATUS(status);
}
-
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -366,20 +342,16 @@ acpi_terminate (
*
******************************************************************************/
-acpi_status
-acpi_subsystem_status (
- void)
+acpi_status acpi_subsystem_status(void)
{
if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
return (AE_OK);
- }
- else {
+ } else {
return (AE_ERROR);
}
}
-
/*******************************************************************************
*
* FUNCTION: acpi_get_system_info
@@ -398,64 +370,60 @@ acpi_subsystem_status (
*
******************************************************************************/
-acpi_status
-acpi_get_system_info (
- struct acpi_buffer *out_buffer)
+acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
{
- struct acpi_system_info *info_ptr;
- acpi_status status;
- u32 i;
-
-
- ACPI_FUNCTION_TRACE ("acpi_get_system_info");
+ struct acpi_system_info *info_ptr;
+ acpi_status status;
+ u32 i;
+ ACPI_FUNCTION_TRACE("acpi_get_system_info");
/* Parameter validation */
- status = acpi_ut_validate_buffer (out_buffer);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status = acpi_ut_validate_buffer(out_buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (out_buffer, sizeof (struct acpi_system_info));
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ status =
+ acpi_ut_initialize_buffer(out_buffer,
+ sizeof(struct acpi_system_info));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/*
* Populate the return buffer
*/
- info_ptr = (struct acpi_system_info *) out_buffer->pointer;
+ info_ptr = (struct acpi_system_info *)out_buffer->pointer;
- info_ptr->acpi_ca_version = ACPI_CA_VERSION;
+ info_ptr->acpi_ca_version = ACPI_CA_VERSION;
/* System flags (ACPI capabilities) */
- info_ptr->flags = ACPI_SYS_MODE_ACPI;
+ info_ptr->flags = ACPI_SYS_MODE_ACPI;
/* Timer resolution - 24 or 32 bits */
if (!acpi_gbl_FADT) {
info_ptr->timer_resolution = 0;
- }
- else if (acpi_gbl_FADT->tmr_val_ext == 0) {
+ } else if (acpi_gbl_FADT->tmr_val_ext == 0) {
info_ptr->timer_resolution = 24;
- }
- else {
+ } else {
info_ptr->timer_resolution = 32;
}
/* Clear the reserved fields */
- info_ptr->reserved1 = 0;
- info_ptr->reserved2 = 0;
+ info_ptr->reserved1 = 0;
+ info_ptr->reserved2 = 0;
/* Current debug levels */
- info_ptr->debug_layer = acpi_dbg_layer;
- info_ptr->debug_level = acpi_dbg_level;
+ info_ptr->debug_layer = acpi_dbg_layer;
+ info_ptr->debug_level = acpi_dbg_level;
/* Current status of the ACPI tables, per table type */
@@ -464,10 +432,10 @@ acpi_get_system_info (
info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
}
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_get_system_info);
+EXPORT_SYMBOL(acpi_get_system_info);
/*****************************************************************************
*
@@ -485,9 +453,7 @@ EXPORT_SYMBOL(acpi_get_system_info);
****************************************************************************/
acpi_status
-acpi_install_initialization_handler (
- acpi_init_handler handler,
- u32 function)
+acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
{
if (!handler) {
@@ -502,7 +468,7 @@ acpi_install_initialization_handler (
return AE_OK;
}
-#endif /* ACPI_FUTURE_USAGE */
+#endif /* ACPI_FUTURE_USAGE */
/*****************************************************************************
*
@@ -516,19 +482,13 @@ acpi_install_initialization_handler (
*
****************************************************************************/
-acpi_status
-acpi_purge_cached_objects (
- void)
+acpi_status acpi_purge_cached_objects(void)
{
- ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects");
-
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
- acpi_ut_delete_generic_state_cache ();
- acpi_ut_delete_object_cache ();
- acpi_ds_delete_walk_state_cache ();
- acpi_ps_delete_parse_cache ();
-#endif
+ ACPI_FUNCTION_TRACE("acpi_purge_cached_objects");
- return_ACPI_STATUS (AE_OK);
+ (void)acpi_os_purge_cache(acpi_gbl_state_cache);
+ (void)acpi_os_purge_cache(acpi_gbl_operand_cache);
+ (void)acpi_os_purge_cache(acpi_gbl_ps_node_cache);
+ (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache);
+ return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 1ce2047c3804..6458c47f7ac2 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -30,15 +30,12 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-
#define _COMPONENT ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME ("acpi_utils")
-
+ACPI_MODULE_NAME("acpi_utils")
/* --------------------------------------------------------------------------
Object Evaluation Helpers
-------------------------------------------------------------------------- */
-
#ifdef ACPI_DEBUG_OUTPUT
#define acpi_util_eval_error(h,p,s) {\
char prefix[80] = {'\0'};\
@@ -49,26 +46,24 @@ ACPI_MODULE_NAME ("acpi_utils")
#else
#define acpi_util_eval_error(h,p,s)
#endif
-
-
acpi_status
-acpi_extract_package (
- union acpi_object *package,
- struct acpi_buffer *format,
- struct acpi_buffer *buffer)
+acpi_extract_package(union acpi_object *package,
+ struct acpi_buffer *format, struct acpi_buffer *buffer)
{
- u32 size_required = 0;
- u32 tail_offset = 0;
- char *format_string = NULL;
- u32 format_count = 0;
- u32 i = 0;
- u8 *head = NULL;
- u8 *tail = NULL;
+ u32 size_required = 0;
+ u32 tail_offset = 0;
+ char *format_string = NULL;
+ u32 format_count = 0;
+ u32 i = 0;
+ u8 *head = NULL;
+ u8 *tail = NULL;
ACPI_FUNCTION_TRACE("acpi_extract_package");
- if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argument\n"));
+ if (!package || (package->type != ACPI_TYPE_PACKAGE)
+ || (package->package.count < 1)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid 'package' argument\n"));
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
@@ -82,18 +77,20 @@ acpi_extract_package (
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- format_count = (format->length/sizeof(char)) - 1;
+ format_count = (format->length / sizeof(char)) - 1;
if (format_count > package->package.count) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Format specifies more objects [%d] than exist in package [%d].",
+ format_count, package->package.count));
return_ACPI_STATUS(AE_BAD_DATA);
}
- format_string = (char*)format->pointer;
+ format_string = (char *)format->pointer;
/*
* Calculate size_required.
*/
- for (i=0; i<format_count; i++) {
+ for (i = 0; i < format_count; i++) {
union acpi_object *element = &(package->package.elements[i]);
@@ -110,11 +107,15 @@ acpi_extract_package (
tail_offset += sizeof(acpi_integer);
break;
case 'S':
- size_required += sizeof(char*) + sizeof(acpi_integer) + sizeof(char);
- tail_offset += sizeof(char*);
+ size_required +=
+ sizeof(char *) + sizeof(acpi_integer) +
+ sizeof(char);
+ tail_offset += sizeof(char *);
break;
default:
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].\n", i, format_string[i]));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid package element [%d]: got number, expecing [%c].\n",
+ i, format_string[i]));
return_ACPI_STATUS(AE_BAD_DATA);
break;
}
@@ -124,15 +125,22 @@ acpi_extract_package (
case ACPI_TYPE_BUFFER:
switch (format_string[i]) {
case 'S':
- size_required += sizeof(char*) + (element->string.length * sizeof(char)) + sizeof(char);
- tail_offset += sizeof(char*);
+ size_required +=
+ sizeof(char *) +
+ (element->string.length * sizeof(char)) +
+ sizeof(char);
+ tail_offset += sizeof(char *);
break;
case 'B':
- size_required += sizeof(u8*) + (element->buffer.length * sizeof(u8));
- tail_offset += sizeof(u8*);
+ size_required +=
+ sizeof(u8 *) +
+ (element->buffer.length * sizeof(u8));
+ tail_offset += sizeof(u8 *);
break;
default:
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format_string[i]));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Invalid package element [%d] got string/buffer, expecing [%c].\n",
+ i, format_string[i]));
return_ACPI_STATUS(AE_BAD_DATA);
break;
}
@@ -140,7 +148,9 @@ acpi_extract_package (
case ACPI_TYPE_PACKAGE:
default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d\n", i));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found unsupported element at index=%d\n",
+ i));
/* TBD: handle nested packages... */
return_ACPI_STATUS(AE_SUPPORT);
break;
@@ -153,8 +163,7 @@ acpi_extract_package (
if (buffer->length < size_required) {
buffer->length = size_required;
return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
- }
- else if (buffer->length != size_required || !buffer->pointer) {
+ } else if (buffer->length != size_required || !buffer->pointer) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
@@ -164,7 +173,7 @@ acpi_extract_package (
/*
* Extract package data.
*/
- for (i=0; i<format_count; i++) {
+ for (i = 0; i < format_count; i++) {
u8 **pointer = NULL;
union acpi_object *element = &(package->package.elements[i]);
@@ -178,14 +187,16 @@ acpi_extract_package (
case ACPI_TYPE_INTEGER:
switch (format_string[i]) {
case 'N':
- *((acpi_integer*)head) = element->integer.value;
+ *((acpi_integer *) head) =
+ element->integer.value;
head += sizeof(acpi_integer);
break;
case 'S':
- pointer = (u8**)head;
+ pointer = (u8 **) head;
*pointer = tail;
- *((acpi_integer*)tail) = element->integer.value;
- head += sizeof(acpi_integer*);
+ *((acpi_integer *) tail) =
+ element->integer.value;
+ head += sizeof(acpi_integer *);
tail += sizeof(acpi_integer);
/* NULL terminate string */
*tail = (char)0;
@@ -201,20 +212,22 @@ acpi_extract_package (
case ACPI_TYPE_BUFFER:
switch (format_string[i]) {
case 'S':
- pointer = (u8**)head;
+ pointer = (u8 **) head;
*pointer = tail;
- memcpy(tail, element->string.pointer, element->string.length);
- head += sizeof(char*);
+ memcpy(tail, element->string.pointer,
+ element->string.length);
+ head += sizeof(char *);
tail += element->string.length * sizeof(char);
/* NULL terminate string */
*tail = (char)0;
tail += sizeof(char);
break;
case 'B':
- pointer = (u8**)head;
+ pointer = (u8 **) head;
*pointer = tail;
- memcpy(tail, element->buffer.pointer, element->buffer.length);
- head += sizeof(u8*);
+ memcpy(tail, element->buffer.pointer,
+ element->buffer.length);
+ head += sizeof(u8 *);
tail += element->buffer.length * sizeof(u8);
break;
default:
@@ -233,19 +246,17 @@ acpi_extract_package (
return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_extract_package);
+EXPORT_SYMBOL(acpi_extract_package);
acpi_status
-acpi_evaluate_integer (
- acpi_handle handle,
- acpi_string pathname,
- struct acpi_object_list *arguments,
- unsigned long *data)
+acpi_evaluate_integer(acpi_handle handle,
+ acpi_string pathname,
+ struct acpi_object_list *arguments, unsigned long *data)
{
- acpi_status status = AE_OK;
- union acpi_object *element;
- struct acpi_buffer buffer = {0,NULL};
+ acpi_status status = AE_OK;
+ union acpi_object *element;
+ struct acpi_buffer buffer = { 0, NULL };
ACPI_FUNCTION_TRACE("acpi_evaluate_integer");
@@ -253,7 +264,7 @@ acpi_evaluate_integer (
return_ACPI_STATUS(AE_BAD_PARAMETER);
element = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
- if(!element)
+ if (!element)
return_ACPI_STATUS(AE_NO_MEMORY);
memset(element, 0, sizeof(union acpi_object));
@@ -277,20 +288,18 @@ acpi_evaluate_integer (
return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_evaluate_integer);
+EXPORT_SYMBOL(acpi_evaluate_integer);
#if 0
acpi_status
-acpi_evaluate_string (
- acpi_handle handle,
- acpi_string pathname,
- acpi_object_list *arguments,
- acpi_string *data)
+acpi_evaluate_string(acpi_handle handle,
+ acpi_string pathname,
+ acpi_object_list * arguments, acpi_string * data)
{
- acpi_status status = AE_OK;
- acpi_object *element = NULL;
- acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ acpi_status status = AE_OK;
+ acpi_object *element = NULL;
+ acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
ACPI_FUNCTION_TRACE("acpi_evaluate_string");
@@ -305,9 +314,9 @@ acpi_evaluate_string (
element = (acpi_object *) buffer.pointer;
- if ((element->type != ACPI_TYPE_STRING)
- || (element->type != ACPI_TYPE_BUFFER)
- || !element->string.length) {
+ if ((element->type != ACPI_TYPE_STRING)
+ || (element->type != ACPI_TYPE_BUFFER)
+ || !element->string.length) {
acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
return_ACPI_STATUS(AE_BAD_DATA);
}
@@ -329,19 +338,17 @@ acpi_evaluate_string (
}
#endif
-
acpi_status
-acpi_evaluate_reference (
- acpi_handle handle,
- acpi_string pathname,
- struct acpi_object_list *arguments,
- struct acpi_handle_list *list)
+acpi_evaluate_reference(acpi_handle handle,
+ acpi_string pathname,
+ struct acpi_object_list *arguments,
+ struct acpi_handle_list *list)
{
- acpi_status status = AE_OK;
- union acpi_object *package = NULL;
- union acpi_object *element = NULL;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- u32 i = 0;
+ acpi_status status = AE_OK;
+ union acpi_object *package = NULL;
+ union acpi_object *element = NULL;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ u32 i = 0;
ACPI_FUNCTION_TRACE("acpi_evaluate_reference");
@@ -355,28 +362,28 @@ acpi_evaluate_reference (
if (ACPI_FAILURE(status))
goto end;
- package = (union acpi_object *) buffer.pointer;
+ package = (union acpi_object *)buffer.pointer;
if ((buffer.length == 0) || !package) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "No return object (len %X ptr %p)\n",
- (unsigned)buffer.length, package));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "No return object (len %X ptr %p)\n",
+ (unsigned)buffer.length, package));
status = AE_BAD_DATA;
acpi_util_eval_error(handle, pathname, status);
goto end;
}
if (package->type != ACPI_TYPE_PACKAGE) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Expecting a [Package], found type %X\n",
- package->type));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Expecting a [Package], found type %X\n",
+ package->type));
status = AE_BAD_DATA;
acpi_util_eval_error(handle, pathname, status);
goto end;
}
if (!package->package.count) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "[Package] has zero elements (%p)\n",
- package));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "[Package] has zero elements (%p)\n",
+ package));
status = AE_BAD_DATA;
acpi_util_eval_error(handle, pathname, status);
goto end;
@@ -395,9 +402,9 @@ acpi_evaluate_reference (
if (element->type != ACPI_TYPE_ANY) {
status = AE_BAD_DATA;
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Expecting a [Reference] package element, found type %X\n",
- element->type));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Expecting a [Reference] package element, found type %X\n",
+ element->type));
acpi_util_eval_error(handle, pathname, status);
break;
}
@@ -406,10 +413,10 @@ acpi_evaluate_reference (
list->handles[i] = element->reference.handle;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n",
- list->handles[i]));
+ list->handles[i]));
}
-end:
+ end:
if (ACPI_FAILURE(status)) {
list->count = 0;
//kfree(list->handles);
@@ -419,5 +426,5 @@ end:
return_ACPI_STATUS(status);
}
-EXPORT_SYMBOL(acpi_evaluate_reference);
+EXPORT_SYMBOL(acpi_evaluate_reference);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 2cf264fd52e0..e383d6109ae1 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -53,21 +53,20 @@
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86
-
#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
#define ACPI_VIDEO_HEAD_END (~0u)
-
#define _COMPONENT ACPI_VIDEO_COMPONENT
-ACPI_MODULE_NAME ("acpi_video")
+ACPI_MODULE_NAME("acpi_video")
-MODULE_AUTHOR("Bruno Ducrot");
+ MODULE_AUTHOR("Bruno Ducrot");
MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME);
MODULE_LICENSE("GPL");
-static int acpi_video_bus_add (struct acpi_device *device);
-static int acpi_video_bus_remove (struct acpi_device *device, int type);
-static int acpi_video_bus_match (struct acpi_device *device, struct acpi_driver *driver);
+static int acpi_video_bus_add(struct acpi_device *device);
+static int acpi_video_bus_remove(struct acpi_device *device, int type);
+static int acpi_video_bus_match(struct acpi_device *device,
+ struct acpi_driver *driver);
static struct acpi_driver acpi_video_bus = {
.name = ACPI_VIDEO_DRIVER_NAME,
@@ -76,187 +75,192 @@ static struct acpi_driver acpi_video_bus = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
.match = acpi_video_bus_match,
- },
+ },
};
struct acpi_video_bus_flags {
- u8 multihead:1; /* can switch video heads */
- u8 rom:1; /* can retrieve a video rom */
- u8 post:1; /* can configure the head to */
- u8 reserved:5;
+ u8 multihead:1; /* can switch video heads */
+ u8 rom:1; /* can retrieve a video rom */
+ u8 post:1; /* can configure the head to */
+ u8 reserved:5;
};
struct acpi_video_bus_cap {
- u8 _DOS:1; /*Enable/Disable output switching*/
- u8 _DOD:1; /*Enumerate all devices attached to display adapter*/
- u8 _ROM:1; /*Get ROM Data*/
- u8 _GPD:1; /*Get POST Device*/
- u8 _SPD:1; /*Set POST Device*/
- u8 _VPO:1; /*Video POST Options*/
- u8 reserved:2;
+ u8 _DOS:1; /*Enable/Disable output switching */
+ u8 _DOD:1; /*Enumerate all devices attached to display adapter */
+ u8 _ROM:1; /*Get ROM Data */
+ u8 _GPD:1; /*Get POST Device */
+ u8 _SPD:1; /*Set POST Device */
+ u8 _VPO:1; /*Video POST Options */
+ u8 reserved:2;
};
-struct acpi_video_device_attrib{
- u32 display_index:4; /* A zero-based instance of the Display*/
- u32 display_port_attachment:4; /*This field differenates displays type*/
- u32 display_type:4; /*Describe the specific type in use*/
- u32 vendor_specific:4; /*Chipset Vendor Specifi*/
- u32 bios_can_detect:1; /*BIOS can detect the device*/
- u32 depend_on_vga:1; /*Non-VGA output device whose power is related to
- the VGA device.*/
- u32 pipe_id:3; /*For VGA multiple-head devices.*/
- u32 reserved:10; /*Must be 0*/
- u32 device_id_scheme:1; /*Device ID Scheme*/
+struct acpi_video_device_attrib {
+ u32 display_index:4; /* A zero-based instance of the Display */
+ u32 display_port_attachment:4; /*This field differenates displays type */
+ u32 display_type:4; /*Describe the specific type in use */
+ u32 vendor_specific:4; /*Chipset Vendor Specifi */
+ u32 bios_can_detect:1; /*BIOS can detect the device */
+ u32 depend_on_vga:1; /*Non-VGA output device whose power is related to
+ the VGA device. */
+ u32 pipe_id:3; /*For VGA multiple-head devices. */
+ u32 reserved:10; /*Must be 0 */
+ u32 device_id_scheme:1; /*Device ID Scheme */
};
struct acpi_video_enumerated_device {
union {
u32 int_val;
- struct acpi_video_device_attrib attrib;
+ struct acpi_video_device_attrib attrib;
} value;
struct acpi_video_device *bind_info;
};
struct acpi_video_bus {
- acpi_handle handle;
- u8 dos_setting;
+ acpi_handle handle;
+ u8 dos_setting;
struct acpi_video_enumerated_device *attached_array;
- u8 attached_count;
- struct acpi_video_bus_cap cap;
+ u8 attached_count;
+ struct acpi_video_bus_cap cap;
struct acpi_video_bus_flags flags;
- struct semaphore sem;
- struct list_head video_device_list;
- struct proc_dir_entry *dir;
+ struct semaphore sem;
+ struct list_head video_device_list;
+ struct proc_dir_entry *dir;
};
struct acpi_video_device_flags {
- u8 crt:1;
- u8 lcd:1;
- u8 tvout:1;
- u8 bios:1;
- u8 unknown:1;
- u8 reserved:3;
+ u8 crt:1;
+ u8 lcd:1;
+ u8 tvout:1;
+ u8 bios:1;
+ u8 unknown:1;
+ u8 reserved:3;
};
struct acpi_video_device_cap {
- u8 _ADR:1; /*Return the unique ID */
- u8 _BCL:1; /*Query list of brightness control levels supported*/
- u8 _BCM:1; /*Set the brightness level*/
- u8 _DDC:1; /*Return the EDID for this device*/
- u8 _DCS:1; /*Return status of output device*/
- u8 _DGS:1; /*Query graphics state*/
- u8 _DSS:1; /*Device state set*/
- u8 _reserved:1;
+ u8 _ADR:1; /*Return the unique ID */
+ u8 _BCL:1; /*Query list of brightness control levels supported */
+ u8 _BCM:1; /*Set the brightness level */
+ u8 _DDC:1; /*Return the EDID for this device */
+ u8 _DCS:1; /*Return status of output device */
+ u8 _DGS:1; /*Query graphics state */
+ u8 _DSS:1; /*Device state set */
+ u8 _reserved:1;
};
struct acpi_video_device_brightness {
- int curr;
- int count;
- int *levels;
+ int curr;
+ int count;
+ int *levels;
};
struct acpi_video_device {
- acpi_handle handle;
- unsigned long device_id;
- struct acpi_video_device_flags flags;
- struct acpi_video_device_cap cap;
- struct list_head entry;
- struct acpi_video_bus *video;
- struct acpi_device *dev;
+ acpi_handle handle;
+ unsigned long device_id;
+ struct acpi_video_device_flags flags;
+ struct acpi_video_device_cap cap;
+ struct list_head entry;
+ struct acpi_video_bus *video;
+ struct acpi_device *dev;
struct acpi_video_device_brightness *brightness;
};
-
/* bus */
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_video_bus_info_fops = {
- .open = acpi_video_bus_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_bus_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_video_bus_ROM_fops = {
- .open = acpi_video_bus_ROM_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_bus_ROM_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static int acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file);
+static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
+ struct file *file);
static struct file_operations acpi_video_bus_POST_info_fops = {
- .open = acpi_video_bus_POST_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_bus_POST_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_video_bus_POST_fops = {
- .open = acpi_video_bus_POST_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_bus_POST_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-
static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_video_bus_DOS_fops = {
- .open = acpi_video_bus_DOS_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_bus_DOS_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
/* device */
-static int acpi_video_device_info_open_fs(struct inode *inode, struct file *file);
+static int acpi_video_device_info_open_fs(struct inode *inode,
+ struct file *file);
static struct file_operations acpi_video_device_info_fops = {
- .open = acpi_video_device_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_device_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static int acpi_video_device_state_open_fs(struct inode *inode, struct file *file);
+static int acpi_video_device_state_open_fs(struct inode *inode,
+ struct file *file);
static struct file_operations acpi_video_device_state_fops = {
- .open = acpi_video_device_state_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_device_state_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static int acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file);
+static int acpi_video_device_brightness_open_fs(struct inode *inode,
+ struct file *file);
static struct file_operations acpi_video_device_brightness_fops = {
- .open = acpi_video_device_brightness_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_device_brightness_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static int acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file);
+static int acpi_video_device_EDID_open_fs(struct inode *inode,
+ struct file *file);
static struct file_operations acpi_video_device_EDID_fops = {
- .open = acpi_video_device_EDID_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = acpi_video_device_EDID_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static char device_decode[][30] = {
+static char device_decode[][30] = {
"motherboard VGA device",
"PCI VGA device",
"AGP VGA device",
"UNKNOWN",
};
-static void acpi_video_device_notify ( acpi_handle handle, u32 event, void *data);
-static void acpi_video_device_rebind( struct acpi_video_bus *video);
-static void acpi_video_device_bind( struct acpi_video_bus *video, struct acpi_video_device *device);
+static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_video_device_rebind(struct acpi_video_bus *video);
+static void acpi_video_device_bind(struct acpi_video_bus *video,
+ struct acpi_video_device *device);
static int acpi_video_device_enumerate(struct acpi_video_bus *video);
-static int acpi_video_switch_output( struct acpi_video_bus *video, int event);
-static int acpi_video_get_next_level( struct acpi_video_device *device, u32 level_current,u32 event);
-static void acpi_video_switch_brightness ( struct acpi_video_device *device, int event);
-
+static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
+static int acpi_video_get_next_level(struct acpi_video_device *device,
+ u32 level_current, u32 event);
+static void acpi_video_switch_brightness(struct acpi_video_device *device,
+ int event);
/* --------------------------------------------------------------------------
Video Management
@@ -265,11 +269,9 @@ static void acpi_video_switch_brightness ( struct acpi_video_device *device, int
/* device */
static int
-acpi_video_device_query (
- struct acpi_video_device *device,
- unsigned long *state)
+acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
{
- int status;
+ int status;
ACPI_FUNCTION_TRACE("acpi_video_device_query");
status = acpi_evaluate_integer(device->handle, "_DGS", NULL, state);
@@ -277,11 +279,10 @@ acpi_video_device_query (
}
static int
-acpi_video_device_get_state (
- struct acpi_video_device *device,
- unsigned long *state)
+acpi_video_device_get_state(struct acpi_video_device *device,
+ unsigned long *state)
{
- int status;
+ int status;
ACPI_FUNCTION_TRACE("acpi_video_device_get_state");
@@ -291,31 +292,28 @@ acpi_video_device_get_state (
}
static int
-acpi_video_device_set_state (
- struct acpi_video_device *device,
- int state)
+acpi_video_device_set_state(struct acpi_video_device *device, int state)
{
- int status;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list args = {1, &arg0};
+ int status;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list args = { 1, &arg0 };
+ unsigned long ret;
ACPI_FUNCTION_TRACE("acpi_video_device_set_state");
arg0.integer.value = state;
- status = acpi_evaluate_integer(device->handle, "_DSS", &args, NULL);
+ status = acpi_evaluate_integer(device->handle, "_DSS", &args, &ret);
return_VALUE(status);
}
static int
-acpi_video_device_lcd_query_levels (
- struct acpi_video_device *device,
- union acpi_object **levels)
+acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
+ union acpi_object **levels)
{
- int status;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *obj;
-
+ int status;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
ACPI_FUNCTION_TRACE("acpi_video_device_lcd_query_levels");
@@ -324,7 +322,7 @@ acpi_video_device_lcd_query_levels (
status = acpi_evaluate_object(device->handle, "_BCL", NULL, &buffer);
if (!ACPI_SUCCESS(status))
return_VALUE(status);
- obj = (union acpi_object *) buffer.pointer;
+ obj = (union acpi_object *)buffer.pointer;
if (!obj && (obj->type != ACPI_TYPE_PACKAGE)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _BCL data\n"));
status = -EFAULT;
@@ -335,7 +333,7 @@ acpi_video_device_lcd_query_levels (
return_VALUE(0);
-err:
+ err:
if (buffer.pointer)
kfree(buffer.pointer);
@@ -343,13 +341,11 @@ err:
}
static int
-acpi_video_device_lcd_set_level (
- struct acpi_video_device *device,
- int level)
+acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
- int status;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list args = {1, &arg0};
+ int status;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list args = { 1, &arg0 };
ACPI_FUNCTION_TRACE("acpi_video_device_lcd_set_level");
@@ -361,11 +357,10 @@ acpi_video_device_lcd_set_level (
}
static int
-acpi_video_device_lcd_get_level_current (
- struct acpi_video_device *device,
- unsigned long *level)
+acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
+ unsigned long *level)
{
- int status;
+ int status;
ACPI_FUNCTION_TRACE("acpi_video_device_lcd_get_level_current");
status = acpi_evaluate_integer(device->handle, "_BQC", NULL, level);
@@ -374,16 +369,14 @@ acpi_video_device_lcd_get_level_current (
}
static int
-acpi_video_device_EDID (
- struct acpi_video_device *device,
- union acpi_object **edid,
- ssize_t length)
+acpi_video_device_EDID(struct acpi_video_device *device,
+ union acpi_object **edid, ssize_t length)
{
- int status;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *obj;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list args = {1, &arg0};
+ int status;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list args = { 1, &arg0 };
ACPI_FUNCTION_TRACE("acpi_video_device_get_EDID");
@@ -402,7 +395,7 @@ acpi_video_device_EDID (
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
- obj = (union acpi_object *) buffer.pointer;
+ obj = (union acpi_object *)buffer.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER)
*edid = obj;
@@ -415,18 +408,15 @@ acpi_video_device_EDID (
return_VALUE(status);
}
-
/* bus */
static int
-acpi_video_bus_set_POST (
- struct acpi_video_bus *video,
- unsigned long option)
+acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
{
- int status;
- unsigned long tmp;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list args = {1, &arg0};
+ int status;
+ unsigned long tmp;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list args = { 1, &arg0 };
ACPI_FUNCTION_TRACE("acpi_video_bus_set_POST");
@@ -434,15 +424,13 @@ acpi_video_bus_set_POST (
status = acpi_evaluate_integer(video->handle, "_SPD", &args, &tmp);
if (ACPI_SUCCESS(status))
- status = tmp ? (-EINVAL):(AE_OK);
+ status = tmp ? (-EINVAL) : (AE_OK);
return_VALUE(status);
}
static int
-acpi_video_bus_get_POST (
- struct acpi_video_bus *video,
- unsigned long *id)
+acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
{
int status;
@@ -454,11 +442,10 @@ acpi_video_bus_get_POST (
}
static int
-acpi_video_bus_POST_options (
- struct acpi_video_bus *video,
- unsigned long *options)
+acpi_video_bus_POST_options(struct acpi_video_bus *video,
+ unsigned long *options)
{
- int status;
+ int status;
ACPI_FUNCTION_TRACE("acpi_video_bus_POST_options");
status = acpi_evaluate_integer(video->handle, "_VPO", NULL, options);
@@ -489,18 +476,15 @@ acpi_video_bus_POST_options (
*/
static int
-acpi_video_bus_DOS(
- struct acpi_video_bus *video,
- int bios_flag,
- int lcd_flag)
+acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
{
- acpi_integer status = 0;
- union acpi_object arg0 = {ACPI_TYPE_INTEGER};
- struct acpi_object_list args = {1, &arg0};
+ acpi_integer status = 0;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list args = { 1, &arg0 };
ACPI_FUNCTION_TRACE("acpi_video_bus_DOS");
- if (bios_flag < 0 || bios_flag >3 || lcd_flag < 0 || lcd_flag > 1){
+ if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) {
status = -1;
goto Failed;
}
@@ -508,7 +492,7 @@ acpi_video_bus_DOS(
video->dos_setting = arg0.integer.value;
acpi_evaluate_object(video->handle, "_DOS", &args, NULL);
-Failed:
+ Failed:
return_VALUE(status);
}
@@ -523,10 +507,9 @@ Failed:
* device.
*/
-static void
-acpi_video_device_find_cap (struct acpi_video_device *device)
+static void acpi_video_device_find_cap(struct acpi_video_device *device)
{
- acpi_integer status;
+ acpi_integer status;
acpi_handle h_dummy1;
int i;
union acpi_object *obj = NULL;
@@ -534,27 +517,27 @@ acpi_video_device_find_cap (struct acpi_video_device *device)
ACPI_FUNCTION_TRACE("acpi_video_device_find_cap");
- memset( &device->cap, 0, 4);
+ memset(&device->cap, 0, 4);
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_ADR", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ADR", &h_dummy1))) {
device->cap._ADR = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCL", &h_dummy1))) {
- device->cap._BCL= 1;
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCL", &h_dummy1))) {
+ device->cap._BCL = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCM", &h_dummy1))) {
- device->cap._BCM= 1;
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCM", &h_dummy1))) {
+ device->cap._BCM = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DDC", &h_dummy1))) {
- device->cap._DDC= 1;
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DDC", &h_dummy1))) {
+ device->cap._DDC = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DCS", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DCS", &h_dummy1))) {
device->cap._DCS = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DGS", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DGS", &h_dummy1))) {
device->cap._DGS = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DSS", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DSS", &h_dummy1))) {
device->cap._DSS = 1;
}
@@ -563,34 +546,38 @@ acpi_video_device_find_cap (struct acpi_video_device *device)
if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) {
int count = 0;
union acpi_object *o;
-
+
br = kmalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
} else {
memset(br, 0, sizeof(*br));
br->levels = kmalloc(obj->package.count *
- sizeof *(br->levels), GFP_KERNEL);
+ sizeof *(br->levels), GFP_KERNEL);
if (!br->levels)
goto out;
for (i = 0; i < obj->package.count; i++) {
- o = (union acpi_object *) &obj->package.elements[i];
+ o = (union acpi_object *)&obj->package.
+ elements[i];
if (o->type != ACPI_TYPE_INTEGER) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid data\n"));
continue;
}
br->levels[count] = (u32) o->integer.value;
count++;
}
-out:
+ out:
if (count < 2) {
kfree(br->levels);
kfree(br);
} else {
br->count = count;
device->brightness = br;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "found %d brightness levels\n",
+ count));
}
}
}
@@ -610,28 +597,27 @@ out:
* Find out all required AML method defined under the video bus device.
*/
-static void
-acpi_video_bus_find_cap (struct acpi_video_bus *video)
+static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
{
- acpi_handle h_dummy1;
+ acpi_handle h_dummy1;
- memset(&video->cap ,0, 4);
- if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOS", &h_dummy1))) {
+ memset(&video->cap, 0, 4);
+ if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOS", &h_dummy1))) {
video->cap._DOS = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOD", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOD", &h_dummy1))) {
video->cap._DOD = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_ROM", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_ROM", &h_dummy1))) {
video->cap._ROM = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_GPD", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_GPD", &h_dummy1))) {
video->cap._GPD = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_SPD", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_SPD", &h_dummy1))) {
video->cap._SPD = 1;
}
- if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_VPO", &h_dummy1))) {
+ if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_VPO", &h_dummy1))) {
video->cap._VPO = 1;
}
}
@@ -641,12 +627,9 @@ acpi_video_bus_find_cap (struct acpi_video_bus *video)
* support the desired features
*/
-static int
-acpi_video_bus_check (
- struct acpi_video_bus *video)
+static int acpi_video_bus_check(struct acpi_video_bus *video)
{
- acpi_status status = -ENOENT;
-
+ acpi_status status = -ENOENT;
ACPI_FUNCTION_TRACE("acpi_video_bus_check");
@@ -658,19 +641,19 @@ acpi_video_bus_check (
*/
/* Does this device able to support video switching ? */
- if(video->cap._DOS){
+ if (video->cap._DOS) {
video->flags.multihead = 1;
status = 0;
}
/* Does this device able to retrieve a retrieve a video ROM ? */
- if(video->cap._ROM){
+ if (video->cap._ROM) {
video->flags.rom = 1;
status = 0;
}
/* Does this device able to configure which video device to POST ? */
- if(video->cap._GPD && video->cap._SPD && video->cap._VPO){
+ if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
video->flags.post = 1;
status = 0;
}
@@ -682,16 +665,14 @@ acpi_video_bus_check (
FS Interface (/proc)
-------------------------------------------------------------------------- */
-static struct proc_dir_entry *acpi_video_dir;
+static struct proc_dir_entry *acpi_video_dir;
/* video devices */
-static int
-acpi_video_device_info_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_device *dev = (struct acpi_video_device *) seq->private;
+ struct acpi_video_device *dev =
+ (struct acpi_video_device *)seq->private;
ACPI_FUNCTION_TRACE("acpi_video_device_info_seq_show");
@@ -709,30 +690,25 @@ acpi_video_device_info_seq_show (
else
seq_printf(seq, "UNKNOWN\n");
- seq_printf(seq,"known by bios: %s\n",
- dev->flags.bios ? "yes":"no");
+ seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
-end:
+ end:
return_VALUE(0);
}
static int
-acpi_video_device_info_open_fs (
- struct inode *inode,
- struct file *file)
+acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_video_device_info_seq_show,
PDE(inode)->data);
}
-static int
-acpi_video_device_state_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
{
- int status;
- struct acpi_video_device *dev = (struct acpi_video_device *) seq->private;
- unsigned long state;
+ int status;
+ struct acpi_video_device *dev =
+ (struct acpi_video_device *)seq->private;
+ unsigned long state;
ACPI_FUNCTION_TRACE("acpi_video_device_state_seq_show");
@@ -753,31 +729,27 @@ acpi_video_device_state_seq_show (
else
seq_printf(seq, "<not supported>\n");
-end:
+ end:
return_VALUE(0);
}
static int
-acpi_video_device_state_open_fs (
- struct inode *inode,
- struct file *file)
+acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_video_device_state_seq_show,
PDE(inode)->data);
}
static ssize_t
-acpi_video_device_write_state (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+acpi_video_device_write_state(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- int status;
- struct seq_file *m = (struct seq_file *) file->private_data;
- struct acpi_video_device *dev = (struct acpi_video_device *) m->private;
- char str[12] = {0};
- u32 state = 0;
+ int status;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
+ char str[12] = { 0 };
+ u32 state = 0;
ACPI_FUNCTION_TRACE("acpi_video_device_write_state");
@@ -789,7 +761,7 @@ acpi_video_device_write_state (
str[count] = 0;
state = simple_strtoul(str, NULL, 0);
- state &= ((1ul<<31) | (1ul<<30) | (1ul<<0));
+ state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
status = acpi_video_device_set_state(dev, state);
@@ -800,12 +772,11 @@ acpi_video_device_write_state (
}
static int
-acpi_video_device_brightness_seq_show (
- struct seq_file *seq,
- void *offset)
+acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_device *dev = (struct acpi_video_device *) seq->private;
- int i;
+ struct acpi_video_device *dev =
+ (struct acpi_video_device *)seq->private;
+ int i;
ACPI_FUNCTION_TRACE("acpi_video_device_brightness_seq_show");
@@ -823,26 +794,22 @@ acpi_video_device_brightness_seq_show (
}
static int
-acpi_video_device_brightness_open_fs (
- struct inode *inode,
- struct file *file)
+acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_video_device_brightness_seq_show,
PDE(inode)->data);
}
static ssize_t
-acpi_video_device_write_brightness (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+acpi_video_device_write_brightness(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- struct seq_file *m = (struct seq_file *) file->private_data;
- struct acpi_video_device *dev = (struct acpi_video_device *) m->private;
- char str[4] = {0};
- unsigned int level = 0;
- int i;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
+ char str[4] = { 0 };
+ unsigned int level = 0;
+ int i;
ACPI_FUNCTION_TRACE("acpi_video_device_write_brightness");
@@ -854,14 +821,15 @@ acpi_video_device_write_brightness (
str[count] = 0;
level = simple_strtoul(str, NULL, 0);
-
+
if (level > 100)
return_VALUE(-EFAULT);
/* validate though the list of available levels */
for (i = 0; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
- if (ACPI_SUCCESS(acpi_video_device_lcd_set_level(dev, level)))
+ if (ACPI_SUCCESS
+ (acpi_video_device_lcd_set_level(dev, level)))
dev->brightness->curr = level;
break;
}
@@ -869,24 +837,22 @@ acpi_video_device_write_brightness (
return_VALUE(count);
}
-static int
-acpi_video_device_EDID_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_device *dev = (struct acpi_video_device *) seq->private;
- int status;
- int i;
- union acpi_object *edid = NULL;
+ struct acpi_video_device *dev =
+ (struct acpi_video_device *)seq->private;
+ int status;
+ int i;
+ union acpi_object *edid = NULL;
ACPI_FUNCTION_TRACE("acpi_video_device_EDID_seq_show");
if (!dev)
goto out;
- status = acpi_video_device_EDID (dev, &edid, 128);
+ status = acpi_video_device_EDID(dev, &edid, 128);
if (ACPI_FAILURE(status)) {
- status = acpi_video_device_EDID (dev, &edid, 256);
+ status = acpi_video_device_EDID(dev, &edid, 256);
}
if (ACPI_FAILURE(status)) {
@@ -898,7 +864,7 @@ acpi_video_device_EDID_seq_show (
seq_putc(seq, edid->buffer.pointer[i]);
}
-out:
+ out:
if (!edid)
seq_printf(seq, "<not supported>\n");
else
@@ -908,20 +874,15 @@ out:
}
static int
-acpi_video_device_EDID_open_fs (
- struct inode *inode,
- struct file *file)
+acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_video_device_EDID_seq_show,
PDE(inode)->data);
}
-
-static int
-acpi_video_device_add_fs (
- struct acpi_device *device)
+static int acpi_video_device_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry = NULL;
struct acpi_video_device *vid_dev;
ACPI_FUNCTION_TRACE("acpi_video_device_add_fs");
@@ -929,13 +890,13 @@ acpi_video_device_add_fs (
if (!device)
return_VALUE(-ENODEV);
- vid_dev = (struct acpi_video_device *) acpi_driver_data(device);
+ vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
if (!vid_dev)
return_VALUE(-ENODEV);
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- vid_dev->video->dir);
+ vid_dev->video->dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
acpi_device_dir(device)->owner = THIS_MODULE;
@@ -945,7 +906,7 @@ acpi_video_device_add_fs (
entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create 'info' fs entry\n"));
+ "Unable to create 'info' fs entry\n"));
else {
entry->proc_fops = &acpi_video_device_info_fops;
entry->data = acpi_driver_data(device);
@@ -953,10 +914,12 @@ acpi_video_device_add_fs (
}
/* 'state' [R/W] */
- entry = create_proc_entry("state", S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ entry =
+ create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create 'state' fs entry\n"));
+ "Unable to create 'state' fs entry\n"));
else {
entry->proc_fops = &acpi_video_device_state_fops;
entry->proc_fops->write = acpi_video_device_write_state;
@@ -965,10 +928,12 @@ acpi_video_device_add_fs (
}
/* 'brightness' [R/W] */
- entry = create_proc_entry("brightness", S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+ entry =
+ create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create 'brightness' fs entry\n"));
+ "Unable to create 'brightness' fs entry\n"));
else {
entry->proc_fops = &acpi_video_device_brightness_fops;
entry->proc_fops->write = acpi_video_device_write_brightness;
@@ -980,7 +945,7 @@ acpi_video_device_add_fs (
entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create 'brightness' fs entry\n"));
+ "Unable to create 'brightness' fs entry\n"));
else {
entry->proc_fops = &acpi_video_device_EDID_fops;
entry->data = acpi_driver_data(device);
@@ -990,14 +955,12 @@ acpi_video_device_add_fs (
return_VALUE(0);
}
-static int
-acpi_video_device_remove_fs (
- struct acpi_device *device)
+static int acpi_video_device_remove_fs(struct acpi_device *device)
{
struct acpi_video_device *vid_dev;
ACPI_FUNCTION_TRACE("acpi_video_device_remove_fs");
- vid_dev = (struct acpi_video_device *) acpi_driver_data(device);
+ vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
return_VALUE(-ENODEV);
@@ -1006,22 +969,17 @@ acpi_video_device_remove_fs (
remove_proc_entry("state", acpi_device_dir(device));
remove_proc_entry("brightness", acpi_device_dir(device));
remove_proc_entry("EDID", acpi_device_dir(device));
- remove_proc_entry(acpi_device_bid(device),
- vid_dev->video->dir);
+ remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
acpi_device_dir(device) = NULL;
}
return_VALUE(0);
}
-
/* video bus */
-static int
-acpi_video_bus_info_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
ACPI_FUNCTION_TRACE("acpi_video_bus_info_seq_show");
@@ -1029,30 +987,25 @@ acpi_video_bus_info_seq_show (
goto end;
seq_printf(seq, "Switching heads: %s\n",
- video->flags.multihead ? "yes":"no");
+ video->flags.multihead ? "yes" : "no");
seq_printf(seq, "Video ROM: %s\n",
- video->flags.rom ? "yes":"no");
+ video->flags.rom ? "yes" : "no");
seq_printf(seq, "Device to be POSTed on boot: %s\n",
- video->flags.post ? "yes":"no");
+ video->flags.post ? "yes" : "no");
-end:
+ end:
return_VALUE(0);
}
-static int
-acpi_video_bus_info_open_fs (
- struct inode *inode,
- struct file *file)
+static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
{
- return single_open(file, acpi_video_bus_info_seq_show, PDE(inode)->data);
+ return single_open(file, acpi_video_bus_info_seq_show,
+ PDE(inode)->data);
}
-static int
-acpi_video_bus_ROM_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
ACPI_FUNCTION_TRACE("acpi_video_bus_ROM_seq_show");
@@ -1062,26 +1015,20 @@ acpi_video_bus_ROM_seq_show (
printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__);
seq_printf(seq, "<TODO>\n");
-end:
+ end:
return_VALUE(0);
}
-static int
-acpi_video_bus_ROM_open_fs (
- struct inode *inode,
- struct file *file)
+static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
}
-static int
-acpi_video_bus_POST_info_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private;
- unsigned long options;
- int status;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+ unsigned long options;
+ int status;
ACPI_FUNCTION_TRACE("acpi_video_bus_POST_info_seq_show");
@@ -1091,8 +1038,10 @@ acpi_video_bus_POST_info_seq_show (
status = acpi_video_bus_POST_options(video, &options);
if (ACPI_SUCCESS(status)) {
if (!(options & 1)) {
- printk(KERN_WARNING PREFIX "The motherboard VGA device is not listed as a possible POST device.\n");
- printk(KERN_WARNING PREFIX "This indicate a BIOS bug. Please contact the manufacturer.\n");
+ printk(KERN_WARNING PREFIX
+ "The motherboard VGA device is not listed as a possible POST device.\n");
+ printk(KERN_WARNING PREFIX
+ "This indicate a BIOS bug. Please contact the manufacturer.\n");
}
printk("%lx\n", options);
seq_printf(seq, "can POST: <intgrated video>");
@@ -1103,89 +1052,74 @@ acpi_video_bus_POST_info_seq_show (
seq_putc(seq, '\n');
} else
seq_printf(seq, "<not supported>\n");
-end:
+ end:
return_VALUE(0);
}
static int
-acpi_video_bus_POST_info_open_fs (
- struct inode *inode,
- struct file *file)
+acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
{
- return single_open(file, acpi_video_bus_POST_info_seq_show, PDE(inode)->data);
+ return single_open(file, acpi_video_bus_POST_info_seq_show,
+ PDE(inode)->data);
}
-static int
-acpi_video_bus_POST_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private;
- int status;
- unsigned long id;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+ int status;
+ unsigned long id;
ACPI_FUNCTION_TRACE("acpi_video_bus_POST_seq_show");
if (!video)
goto end;
- status = acpi_video_bus_get_POST (video, &id);
+ status = acpi_video_bus_get_POST(video, &id);
if (!ACPI_SUCCESS(status)) {
seq_printf(seq, "<not supported>\n");
goto end;
}
- seq_printf(seq, "device posted is <%s>\n", device_decode[id & 3]);
+ seq_printf(seq, "device posted is <%s>\n", device_decode[id & 3]);
-end:
+ end:
return_VALUE(0);
}
-static int
-acpi_video_bus_DOS_seq_show (
- struct seq_file *seq,
- void *offset)
+static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
ACPI_FUNCTION_TRACE("acpi_video_bus_DOS_seq_show");
- seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting );
+ seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
return_VALUE(0);
}
-static int
-acpi_video_bus_POST_open_fs (
- struct inode *inode,
- struct file *file)
+static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
{
- return single_open(file, acpi_video_bus_POST_seq_show, PDE(inode)->data);
+ return single_open(file, acpi_video_bus_POST_seq_show,
+ PDE(inode)->data);
}
-static int
-acpi_video_bus_DOS_open_fs (
- struct inode *inode,
- struct file *file)
+static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
}
static ssize_t
-acpi_video_bus_write_POST (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+acpi_video_bus_write_POST(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- int status;
- struct seq_file *m = (struct seq_file *) file->private_data;
- struct acpi_video_bus *video = (struct acpi_video_bus *) m->private;
- char str[12] = {0};
- unsigned long opt, options;
+ int status;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
+ char str[12] = { 0 };
+ unsigned long opt, options;
ACPI_FUNCTION_TRACE("acpi_video_bus_write_POST");
-
if (!video || count + 1 > sizeof str)
return_VALUE(-EINVAL);
@@ -1205,32 +1139,28 @@ acpi_video_bus_write_POST (
options |= 1;
if (options & (1ul << opt)) {
- status = acpi_video_bus_set_POST (video, opt);
+ status = acpi_video_bus_set_POST(video, opt);
if (!ACPI_SUCCESS(status))
return_VALUE(-EFAULT);
}
-
return_VALUE(count);
}
static ssize_t
-acpi_video_bus_write_DOS (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data)
+acpi_video_bus_write_DOS(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
{
- int status;
- struct seq_file *m = (struct seq_file *) file->private_data;
- struct acpi_video_bus *video = (struct acpi_video_bus *) m->private;
- char str[12] = {0};
- unsigned long opt;
+ int status;
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
+ char str[12] = { 0 };
+ unsigned long opt;
ACPI_FUNCTION_TRACE("acpi_video_bus_write_DOS");
-
if (!video || count + 1 > sizeof str)
return_VALUE(-EINVAL);
@@ -1242,7 +1172,7 @@ acpi_video_bus_write_DOS (
if (opt > 7)
return_VALUE(-EFAULT);
- status = acpi_video_bus_DOS (video, opt & 0x3, (opt & 0x4)>>2);
+ status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
if (!ACPI_SUCCESS(status))
return_VALUE(-EFAULT);
@@ -1250,20 +1180,18 @@ acpi_video_bus_write_DOS (
return_VALUE(count);
}
-static int
-acpi_video_bus_add_fs (
- struct acpi_device *device)
+static int acpi_video_bus_add_fs(struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
- struct acpi_video_bus *video;
+ struct proc_dir_entry *entry = NULL;
+ struct acpi_video_bus *video;
ACPI_FUNCTION_TRACE("acpi_video_bus_add_fs");
- video = (struct acpi_video_bus *) acpi_driver_data(device);
+ video = (struct acpi_video_bus *)acpi_driver_data(device);
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_video_dir);
+ acpi_video_dir);
if (!acpi_device_dir(device))
return_VALUE(-ENODEV);
video->dir = acpi_device_dir(device);
@@ -1273,7 +1201,8 @@ acpi_video_bus_add_fs (
/* 'info' [R] */
entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'info' fs entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create 'info' fs entry\n"));
else {
entry->proc_fops = &acpi_video_bus_info_fops;
entry->data = acpi_driver_data(device);
@@ -1283,7 +1212,8 @@ acpi_video_bus_add_fs (
/* 'ROM' [R] */
entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device));
if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'ROM' fs entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create 'ROM' fs entry\n"));
else {
entry->proc_fops = &acpi_video_bus_ROM_fops;
entry->data = acpi_driver_data(device);
@@ -1291,9 +1221,11 @@ acpi_video_bus_add_fs (
}
/* 'POST_info' [R] */
- entry = create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));
+ entry =
+ create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));
if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST_info' fs entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create 'POST_info' fs entry\n"));
else {
entry->proc_fops = &acpi_video_bus_POST_info_fops;
entry->data = acpi_driver_data(device);
@@ -1301,9 +1233,12 @@ acpi_video_bus_add_fs (
}
/* 'POST' [R/W] */
- entry = create_proc_entry("POST", S_IFREG|S_IRUGO|S_IRUSR, acpi_device_dir(device));
+ entry =
+ create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR,
+ acpi_device_dir(device));
if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST' fs entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create 'POST' fs entry\n"));
else {
entry->proc_fops = &acpi_video_bus_POST_fops;
entry->proc_fops->write = acpi_video_bus_write_POST;
@@ -1312,9 +1247,12 @@ acpi_video_bus_add_fs (
}
/* 'DOS' [R/W] */
- entry = create_proc_entry("DOS", S_IFREG|S_IRUGO|S_IRUSR, acpi_device_dir(device));
+ entry =
+ create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR,
+ acpi_device_dir(device));
if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'DOS' fs entry\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to create 'DOS' fs entry\n"));
else {
entry->proc_fops = &acpi_video_bus_DOS_fops;
entry->proc_fops->write = acpi_video_bus_write_DOS;
@@ -1325,15 +1263,13 @@ acpi_video_bus_add_fs (
return_VALUE(0);
}
-static int
-acpi_video_bus_remove_fs (
- struct acpi_device *device)
+static int acpi_video_bus_remove_fs(struct acpi_device *device)
{
- struct acpi_video_bus *video;
+ struct acpi_video_bus *video;
ACPI_FUNCTION_TRACE("acpi_video_bus_remove_fs");
- video = (struct acpi_video_bus *) acpi_driver_data(device);
+ video = (struct acpi_video_bus *)acpi_driver_data(device);
if (acpi_device_dir(device)) {
remove_proc_entry("info", acpi_device_dir(device));
@@ -1341,8 +1277,7 @@ acpi_video_bus_remove_fs (
remove_proc_entry("POST_info", acpi_device_dir(device));
remove_proc_entry("POST", acpi_device_dir(device));
remove_proc_entry("DOS", acpi_device_dir(device));
- remove_proc_entry(acpi_device_bid(device),
- acpi_video_dir);
+ remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
acpi_device_dir(device) = NULL;
}
@@ -1356,20 +1291,20 @@ acpi_video_bus_remove_fs (
/* device interface */
static int
-acpi_video_bus_get_one_device (
- struct acpi_device *device,
- struct acpi_video_bus *video)
+acpi_video_bus_get_one_device(struct acpi_device *device,
+ struct acpi_video_bus *video)
{
- unsigned long device_id;
- int status, result;
- struct acpi_video_device *data;
+ unsigned long device_id;
+ int status, result;
+ struct acpi_video_device *data;
ACPI_FUNCTION_TRACE("acpi_video_bus_get_one_device");
if (!device || !video)
return_VALUE(-EINVAL);
- status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
+ status =
+ acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
if (ACPI_SUCCESS(status)) {
data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
@@ -1401,15 +1336,17 @@ acpi_video_bus_get_one_device (
data->flags.unknown = 1;
break;
}
-
+
acpi_video_device_bind(video, data);
acpi_video_device_find_cap(data);
status = acpi_install_notify_handler(data->handle,
- ACPI_DEVICE_NOTIFY, acpi_video_device_notify, data);
+ ACPI_DEVICE_NOTIFY,
+ acpi_video_device_notify,
+ data);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
result = -ENODEV;
goto end;
}
@@ -1423,7 +1360,7 @@ acpi_video_bus_get_one_device (
return_VALUE(0);
}
-end:
+ end:
return_VALUE(-ENOENT);
}
@@ -1437,15 +1374,15 @@ end:
* Enumerate the video device list of the video bus,
* bind the ids with the corresponding video devices
* under the video bus.
- */
+ */
-static void
-acpi_video_device_rebind( struct acpi_video_bus *video)
+static void acpi_video_device_rebind(struct acpi_video_bus *video)
{
- struct list_head * node, * next;
+ struct list_head *node, *next;
list_for_each_safe(node, next, &video->video_device_list) {
- struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry);
- acpi_video_device_bind( video, dev);
+ struct acpi_video_device *dev =
+ container_of(node, struct acpi_video_device, entry);
+ acpi_video_device_bind(video, dev);
}
}
@@ -1460,21 +1397,21 @@ acpi_video_device_rebind( struct acpi_video_bus *video)
*
* Bind the ids with the corresponding video devices
* under the video bus.
- */
+ */
static void
-acpi_video_device_bind( struct acpi_video_bus *video,
- struct acpi_video_device *device)
+acpi_video_device_bind(struct acpi_video_bus *video,
+ struct acpi_video_device *device)
{
- int i;
+ int i;
ACPI_FUNCTION_TRACE("acpi_video_device_bind");
#define IDS_VAL(i) video->attached_array[i].value.int_val
#define IDS_BIND(i) video->attached_array[i].bind_info
-
- for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID &&
- i < video->attached_count; i++) {
- if (device->device_id == (IDS_VAL(i)& 0xffff)) {
+
+ for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID &&
+ i < video->attached_count; i++) {
+ if (device->device_id == (IDS_VAL(i) & 0xffff)) {
IDS_BIND(i) = device;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
}
@@ -1492,17 +1429,17 @@ acpi_video_device_bind( struct acpi_video_bus *video,
*
* Call _DOD to enumerate all devices attached to display adapter
*
- */
+ */
static int acpi_video_device_enumerate(struct acpi_video_bus *video)
{
- int status;
- int count;
- int i;
+ int status;
+ int count;
+ int i;
struct acpi_video_enumerated_device *active_device_list;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *dod = NULL;
- union acpi_object *obj;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *dod = NULL;
+ union acpi_object *obj;
ACPI_FUNCTION_TRACE("acpi_video_device_enumerate");
@@ -1512,7 +1449,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
return_VALUE(status);
}
- dod = (union acpi_object *) buffer.pointer;
+ dod = (union acpi_object *)buffer.pointer;
if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DOD data\n"));
status = -EFAULT;
@@ -1520,11 +1457,13 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
- dod->package.count));
+ dod->package.count));
- active_device_list= kmalloc(
- (1+dod->package.count)*sizeof(struct acpi_video_enumerated_device),
- GFP_KERNEL);
+ active_device_list = kmalloc((1 +
+ dod->package.count) *
+ sizeof(struct
+ acpi_video_enumerated_device),
+ GFP_KERNEL);
if (!active_device_list) {
status = -ENOMEM;
@@ -1533,25 +1472,28 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
count = 0;
for (i = 0; i < dod->package.count; i++) {
- obj = (union acpi_object *) &dod->package.elements[i];
+ obj = (union acpi_object *)&dod->package.elements[i];
if (obj->type != ACPI_TYPE_INTEGER) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DOD data\n"));
- active_device_list[i].value.int_val = ACPI_VIDEO_HEAD_INVALID;
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid _DOD data\n"));
+ active_device_list[i].value.int_val =
+ ACPI_VIDEO_HEAD_INVALID;
}
active_device_list[i].value.int_val = obj->integer.value;
active_device_list[i].bind_info = NULL;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, (int) obj->integer.value));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
+ (int)obj->integer.value));
count++;
}
active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
- if(video->attached_array)
+ if (video->attached_array)
kfree(video->attached_array);
-
+
video->attached_array = active_device_list;
video->attached_count = count;
-out:
+ out:
acpi_os_free(buffer.pointer);
return_VALUE(status);
}
@@ -1567,17 +1509,14 @@ out:
* 1. Find out the current active output device.
* 2. Identify the next output device to switch
* 3. call _DSS to do actual switch.
- */
+ */
-static int
-acpi_video_switch_output(
- struct acpi_video_bus *video,
- int event)
+static int acpi_video_switch_output(struct acpi_video_bus *video, int event)
{
- struct list_head * node, * next;
- struct acpi_video_device *dev=NULL;
- struct acpi_video_device *dev_next=NULL;
- struct acpi_video_device *dev_prev=NULL;
+ struct list_head *node, *next;
+ struct acpi_video_device *dev = NULL;
+ struct acpi_video_device *dev_next = NULL;
+ struct acpi_video_device *dev_prev = NULL;
unsigned long state;
int status = 0;
@@ -1586,15 +1525,19 @@ acpi_video_switch_output(
list_for_each_safe(node, next, &video->video_device_list) {
dev = container_of(node, struct acpi_video_device, entry);
status = acpi_video_device_get_state(dev, &state);
- if (state & 0x2){
- dev_next = container_of(node->next, struct acpi_video_device, entry);
- dev_prev = container_of(node->prev, struct acpi_video_device, entry);
+ if (state & 0x2) {
+ dev_next =
+ container_of(node->next, struct acpi_video_device,
+ entry);
+ dev_prev =
+ container_of(node->prev, struct acpi_video_device,
+ entry);
goto out;
}
}
dev_next = container_of(node->next, struct acpi_video_device, entry);
dev_prev = container_of(node->prev, struct acpi_video_device, entry);
-out:
+ out:
switch (event) {
case ACPI_VIDEO_NOTIFY_CYCLE:
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
@@ -1611,21 +1554,16 @@ out:
return_VALUE(status);
}
-static int
-acpi_video_get_next_level(
- struct acpi_video_device *device,
- u32 level_current,
- u32 event)
+static int
+acpi_video_get_next_level(struct acpi_video_device *device,
+ u32 level_current, u32 event)
{
- /*Fix me*/
+ /*Fix me */
return level_current;
}
-
static void
-acpi_video_switch_brightness (
- struct acpi_video_device *device,
- int event)
+acpi_video_switch_brightness(struct acpi_video_device *device, int event)
{
unsigned long level_current, level_next;
acpi_video_device_lcd_get_level_current(device, &level_current);
@@ -1634,26 +1572,27 @@ acpi_video_switch_brightness (
}
static int
-acpi_video_bus_get_devices (
- struct acpi_video_bus *video,
- struct acpi_device *device)
+acpi_video_bus_get_devices(struct acpi_video_bus *video,
+ struct acpi_device *device)
{
- int status = 0;
- struct list_head *node, *next;
+ int status = 0;
+ struct list_head *node, *next;
ACPI_FUNCTION_TRACE("acpi_video_get_devices");
acpi_video_device_enumerate(video);
list_for_each_safe(node, next, &device->children) {
- struct acpi_device *dev = list_entry(node, struct acpi_device, node);
+ struct acpi_device *dev =
+ list_entry(node, struct acpi_device, node);
if (!dev)
continue;
status = acpi_video_bus_get_one_device(dev, video);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Cant attach device\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Cant attach device\n"));
continue;
}
@@ -1661,10 +1600,9 @@ acpi_video_bus_get_devices (
return_VALUE(status);
}
-static int
-acpi_video_bus_put_one_device(
- struct acpi_video_device *device)
+static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
{
+ acpi_status status;
struct acpi_video_bus *video;
ACPI_FUNCTION_TRACE("acpi_video_bus_put_one_device");
@@ -1679,26 +1617,33 @@ acpi_video_bus_put_one_device(
up(&video->sem);
acpi_video_device_remove_fs(device->dev);
+ status = acpi_remove_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_video_device_notify);
+ if (ACPI_FAILURE(status))
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error removing notify handler\n"));
+
return_VALUE(0);
}
-static int
-acpi_video_bus_put_devices (
- struct acpi_video_bus *video)
+static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
{
- int status;
- struct list_head *node, *next;
+ int status;
+ struct list_head *node, *next;
ACPI_FUNCTION_TRACE("acpi_video_bus_put_devices");
list_for_each_safe(node, next, &video->video_device_list) {
- struct acpi_video_device *data = list_entry(node, struct acpi_video_device, entry);
+ struct acpi_video_device *data =
+ list_entry(node, struct acpi_video_device, entry);
if (!data)
continue;
status = acpi_video_bus_put_one_device(data);
- if(ACPI_FAILURE(status))
- printk(KERN_WARNING PREFIX "hhuuhhuu bug in acpi video driver.\n");
+ if (ACPI_FAILURE(status))
+ printk(KERN_WARNING PREFIX
+ "hhuuhhuu bug in acpi video driver.\n");
if (data->brightness)
kfree(data->brightness);
@@ -1711,28 +1656,20 @@ acpi_video_bus_put_devices (
/* acpi_video interface */
-static int
-acpi_video_bus_start_devices(
- struct acpi_video_bus *video)
+static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
{
return acpi_video_bus_DOS(video, 1, 0);
}
-static int
-acpi_video_bus_stop_devices(
- struct acpi_video_bus *video)
+static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
{
return acpi_video_bus_DOS(video, 0, 1);
}
-static void
-acpi_video_bus_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_video_bus *video = (struct acpi_video_bus *) data;
- struct acpi_device *device = NULL;
+ struct acpi_video_bus *video = (struct acpi_video_bus *)data;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_video_bus_notify");
printk("video bus notify\n");
@@ -1757,30 +1694,27 @@ acpi_video_bus_notify (
acpi_bus_generate_event(device, event, 0);
break;
- case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed.*/
- case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
- case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
+ case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
+ case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
+ case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
acpi_video_switch_output(video, event);
acpi_bus_generate_event(device, event, 0);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-static void
-acpi_video_device_notify (
- acpi_handle handle,
- u32 event,
- void *data)
+static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_video_device *video_device = (struct acpi_video_device *) data;
- struct acpi_device *device = NULL;
+ struct acpi_video_device *video_device =
+ (struct acpi_video_device *)data;
+ struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_video_device_notify");
@@ -1792,36 +1726,34 @@ acpi_video_device_notify (
return_VOID;
switch (event) {
- case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
- case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
+ case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
+ case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
acpi_bus_generate_event(device, event, 0);
break;
- case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
- case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
- case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
- case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
- case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
- acpi_video_switch_brightness (video_device, event);
+ case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
+ case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
+ case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
+ case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
+ case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
+ acpi_video_switch_brightness(video_device, event);
acpi_bus_generate_event(device, event, 0);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ "Unsupported event [0x%x]\n", event));
break;
}
return_VOID;
}
-static int
-acpi_video_bus_add (
- struct acpi_device *device)
+static int acpi_video_bus_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_video_bus *video = NULL;
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_video_bus *video = NULL;
ACPI_FUNCTION_TRACE("acpi_video_bus_add");
-
+
if (!device)
return_VALUE(-EINVAL);
@@ -1851,21 +1783,22 @@ acpi_video_bus_add (
acpi_video_bus_start_devices(video);
status = acpi_install_notify_handler(video->handle,
- ACPI_DEVICE_NOTIFY, acpi_video_bus_notify, video);
+ ACPI_DEVICE_NOTIFY,
+ acpi_video_bus_notify, video);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
+ "Error installing notify handler\n"));
result = -ENODEV;
goto end;
}
printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
- ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
- video->flags.multihead ? "yes":"no",
- video->flags.rom ? "yes":"no",
- video->flags.post ? "yes":"no");
+ ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
+ video->flags.multihead ? "yes" : "no",
+ video->flags.rom ? "yes" : "no",
+ video->flags.post ? "yes" : "no");
-end:
+ end:
if (result) {
acpi_video_bus_remove_fs(device);
kfree(video);
@@ -1874,28 +1807,26 @@ end:
return_VALUE(result);
}
-static int
-acpi_video_bus_remove (
- struct acpi_device *device,
- int type)
+static int acpi_video_bus_remove(struct acpi_device *device, int type)
{
- acpi_status status = 0;
- struct acpi_video_bus *video = NULL;
+ acpi_status status = 0;
+ struct acpi_video_bus *video = NULL;
ACPI_FUNCTION_TRACE("acpi_video_bus_remove");
if (!device || !acpi_driver_data(device))
return_VALUE(-EINVAL);
- video = (struct acpi_video_bus *) acpi_driver_data(device);
+ video = (struct acpi_video_bus *)acpi_driver_data(device);
acpi_video_bus_stop_devices(video);
status = acpi_remove_notify_handler(video->handle,
- ACPI_DEVICE_NOTIFY, acpi_video_bus_notify);
+ ACPI_DEVICE_NOTIFY,
+ acpi_video_bus_notify);
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error removing notify handler\n"));
+ "Error removing notify handler\n"));
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
@@ -1907,15 +1838,12 @@ acpi_video_bus_remove (
return_VALUE(0);
}
-
static int
-acpi_video_bus_match (
- struct acpi_device *device,
- struct acpi_driver *driver)
+acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
{
- acpi_handle h_dummy1;
- acpi_handle h_dummy2;
- acpi_handle h_dummy3;
+ acpi_handle h_dummy1;
+ acpi_handle h_dummy2;
+ acpi_handle h_dummy3;
ACPI_FUNCTION_TRACE("acpi_video_bus_match");
@@ -1941,22 +1869,19 @@ acpi_video_bus_match (
ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
return_VALUE(0);
-
return_VALUE(-ENODEV);
}
-
-static int __init
-acpi_video_init (void)
+static int __init acpi_video_init(void)
{
- int result = 0;
+ int result = 0;
ACPI_FUNCTION_TRACE("acpi_video_init");
/*
- acpi_dbg_level = 0xFFFFFFFF;
- acpi_dbg_layer = 0x08000000;
- */
+ acpi_dbg_level = 0xFFFFFFFF;
+ acpi_dbg_layer = 0x08000000;
+ */
acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
if (!acpi_video_dir)
@@ -1972,8 +1897,7 @@ acpi_video_init (void)
return_VALUE(0);
}
-static void __exit
-acpi_video_exit (void)
+static void __exit acpi_video_exit(void)
{
ACPI_FUNCTION_TRACE("acpi_video_exit");
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index d74a7c5e75dd..4b6bf19c39c0 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -795,7 +795,7 @@ static void drain_rx_pools (amb_dev * dev) {
}
static inline void fill_rx_pool (amb_dev * dev, unsigned char pool,
- unsigned int __nocast priority)
+ gfp_t priority)
{
rx_in rx;
amb_rxq * rxq;
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 58219744f5db..7f7ec288824d 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1374,8 +1374,7 @@ static void reset_chip (struct fs_dev *dev)
}
}
-static void __devinit *aligned_kmalloc (int size, unsigned int __nocast flags,
- int alignment)
+static void __devinit *aligned_kmalloc (int size, gfp_t flags, int alignment)
{
void *t;
@@ -1466,7 +1465,7 @@ static inline int nr_buffers_in_freepool (struct fs_dev *dev, struct freepool *f
working again after that... -- REW */
static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
- unsigned int __nocast gfp_flags)
+ gfp_t gfp_flags)
{
struct FS_BPENTRY *qe, *ne;
struct sk_buff *skb;
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 2bf723a7b6e6..14f6a6201da3 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -178,14 +178,12 @@ fore200e_irq_itoa(int irq)
static void*
-fore200e_kmalloc(int size, int flags)
+fore200e_kmalloc(int size, gfp_t flags)
{
- void* chunk = kmalloc(size, flags);
+ void *chunk = kzalloc(size, flags);
- if (chunk)
- memset(chunk, 0x00, size);
- else
- printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags);
+ if (!chunk)
+ printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags);
return chunk;
}
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
index b8c260ed4b27..0aabfc2a59d9 100644
--- a/drivers/atm/idt77105.c
+++ b/drivers/atm/idt77105.c
@@ -50,10 +50,8 @@ static void idt77105_stats_timer_func(unsigned long);
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 a43575acb2c1..2e2e50e1167a 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/base/attribute_container.c b/drivers/base/attribute_container.c
index 373e7b728fa7..6b2eb6f39b4d 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -152,12 +152,13 @@ attribute_container_add_device(struct device *dev,
if (!cont->match(cont, dev))
continue;
- ic = kmalloc(sizeof(struct internal_container), GFP_KERNEL);
+
+ ic = kzalloc(sizeof(*ic), GFP_KERNEL);
if (!ic) {
dev_printk(KERN_ERR, dev, "failed to allocate class container\n");
continue;
}
- memset(ic, 0, sizeof(struct internal_container));
+
ic->cont = cont;
class_device_initialize(&ic->classdev);
ic->classdev.dev = get_device(dev);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index d164c32a97ad..ce23dc8c18c5 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -189,12 +189,11 @@ struct class *class_create(struct module *owner, char *name)
struct class *cls;
int retval;
- cls = kmalloc(sizeof(struct class), GFP_KERNEL);
+ cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls) {
retval = -ENOMEM;
goto error;
}
- memset(cls, 0x00, sizeof(struct class));
cls->name = name;
cls->owner = owner;
@@ -500,13 +499,13 @@ int class_device_add(struct class_device *class_dev)
/* add the needed attributes to this device */
if (MAJOR(class_dev->devt)) {
struct class_device_attribute *attr;
- attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+ attr = kzalloc(sizeof(*attr), GFP_KERNEL);
if (!attr) {
error = -ENOMEM;
kobject_del(&class_dev->kobj);
goto register_done;
}
- memset(attr, sizeof(*attr), 0x00);
+
attr->attr.name = "dev";
attr->attr.mode = S_IRUGO;
attr->attr.owner = parent->owner;
@@ -577,12 +576,11 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
if (cls == NULL || IS_ERR(cls))
goto error;
- class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+ class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
if (!class_dev) {
retval = -ENOMEM;
goto error;
}
- memset(class_dev, 0x00, sizeof(struct class_device));
class_dev->devt = devt;
class_dev->dev = device;
@@ -671,6 +669,7 @@ void class_device_destroy(struct class *cls, dev_t devt)
int class_device_rename(struct class_device *class_dev, char *new_name)
{
int error = 0;
+ char *old_class_name = NULL, *new_class_name = NULL;
class_dev = class_device_get(class_dev);
if (!class_dev)
@@ -679,12 +678,24 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
new_name);
+ if (class_dev->dev)
+ old_class_name = make_class_name(class_dev);
+
strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
error = kobject_rename(&class_dev->kobj, new_name);
+ if (class_dev->dev) {
+ new_class_name = make_class_name(class_dev);
+ sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
+ new_class_name);
+ sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
+ }
class_device_put(class_dev);
+ kfree(old_class_name);
+ kfree(new_class_name);
+
return error;
}
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index d5bbce38282f..3565e9795301 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -40,6 +40,9 @@
*/
void device_bind_driver(struct device * dev)
{
+ if (klist_node_attached(&dev->knode_driver))
+ return;
+
pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id, dev->driver->name);
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index c4aebf2f522d..e2f64f91ed05 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -156,7 +156,7 @@ dma_pool_create (const char *name, struct device *dev,
static struct dma_page *
-pool_alloc_page (struct dma_pool *pool, unsigned int __nocast mem_flags)
+pool_alloc_page (struct dma_pool *pool, gfp_t mem_flags)
{
struct dma_page *page;
int mapsize;
@@ -262,7 +262,7 @@ dma_pool_destroy (struct dma_pool *pool)
* If such a memory block can't be allocated, null is returned.
*/
void *
-dma_pool_alloc (struct dma_pool *pool, int mem_flags, dma_addr_t *handle)
+dma_pool_alloc (struct dma_pool *pool, gfp_t mem_flags, dma_addr_t *handle)
{
unsigned long flags;
struct dma_page *page;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 5bfa2e9a7c26..4acb2c5733c3 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -301,9 +301,9 @@ fw_register_class_device(struct class_device **class_dev_p,
const char *fw_name, struct device *device)
{
int retval;
- struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
+ struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv),
GFP_KERNEL);
- struct class_device *class_dev = kmalloc(sizeof (struct class_device),
+ struct class_device *class_dev = kzalloc(sizeof(*class_dev),
GFP_KERNEL);
*class_dev_p = NULL;
@@ -313,8 +313,6 @@ fw_register_class_device(struct class_device **class_dev_p,
retval = -ENOMEM;
goto error_kfree;
}
- memset(fw_priv, 0, sizeof (*fw_priv));
- memset(class_dev, 0, sizeof (*class_dev));
init_completion(&fw_priv->completion);
fw_priv->attr_data = firmware_attr_data_tmpl;
@@ -402,14 +400,13 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
if (!firmware_p)
return -EINVAL;
- *firmware_p = firmware = kmalloc(sizeof (struct firmware), GFP_KERNEL);
+ *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
if (!firmware) {
printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
__FUNCTION__);
retval = -ENOMEM;
goto out;
}
- memset(firmware, 0, sizeof (*firmware));
retval = fw_setup_class_device(firmware, &class_dev, name, device,
hotplug);
diff --git a/drivers/base/map.c b/drivers/base/map.c
index 2f455d86793c..b449dae6f0d3 100644
--- a/drivers/base/map.c
+++ b/drivers/base/map.c
@@ -135,7 +135,7 @@ retry:
struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
{
struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
- struct probe *base = kmalloc(sizeof(struct probe), GFP_KERNEL);
+ struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
int i;
if ((p == NULL) || (base == NULL)) {
@@ -144,7 +144,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
return NULL;
}
- memset(base, 0, sizeof(struct probe));
base->dev = 1;
base->range = ~0;
base->get = base_probe;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 3a5f4c991797..361e204209eb 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -225,13 +225,12 @@ struct platform_device *platform_device_register_simple(char *name, unsigned int
struct platform_object *pobj;
int retval;
- pobj = kmalloc(sizeof(struct platform_object) + sizeof(struct resource) * num, GFP_KERNEL);
+ pobj = kzalloc(sizeof(*pobj) + sizeof(struct resource) * num, GFP_KERNEL);
if (!pobj) {
retval = -ENOMEM;
goto error;
}
- memset(pobj, 0, sizeof(*pobj));
pobj->pdev.name = name;
pobj->pdev.id = id;
pobj->pdev.dev.release = platform_device_release_simple;
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index ce933de48084..0e1f34fef0c8 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -371,7 +371,7 @@ static int acsi_revalidate (struct gendisk *disk);
/************************* 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 e3be8c31a74c..a5c1c8e871ec 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -268,7 +268,7 @@ static int slm_get_pagesize( int device, int *w, int *h );
/************************* 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/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 721ba8086043..0e9e586e9ba3 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "10"
+#define VERSION "12"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
@@ -7,12 +7,12 @@
* default is 16, which is 15 partitions plus the whole disk
*/
#ifndef AOE_PARTITIONS
-#define AOE_PARTITIONS 16
+#define AOE_PARTITIONS (16)
#endif
-#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor))
-#define AOEMAJOR(sysminor) ((sysminor) / 10)
-#define AOEMINOR(sysminor) ((sysminor) % 10)
+#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor))
+#define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF)
+#define AOEMINOR(sysminor) ((sysminor) % NPERSHELF)
#define WHITESPACE " \t\v\f\n"
enum {
@@ -83,7 +83,7 @@ enum {
enum {
MAXATADATA = 1024,
- NPERSHELF = 10,
+ NPERSHELF = 16, /* number of slots per shelf address */
FREETAG = -1,
MIN_BUFS = 8,
};
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index 95c0a3690b0f..4081c36c8c19 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -98,7 +98,6 @@ struct as_data {
struct as_rq *next_arq[2]; /* next in sort order */
sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */
- struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */
unsigned long exit_prob; /* probability a task will exit while
@@ -239,6 +238,25 @@ static struct io_context *as_get_io_context(void)
return ioc;
}
+static void as_put_io_context(struct as_rq *arq)
+{
+ struct as_io_context *aic;
+
+ if (unlikely(!arq->io_context))
+ return;
+
+ aic = arq->io_context->aic;
+
+ if (arq->is_sync == REQ_SYNC && aic) {
+ spin_lock(&aic->lock);
+ set_bit(AS_TASK_IORUNNING, &aic->state);
+ aic->last_end_request = jiffies;
+ spin_unlock(&aic->lock);
+ }
+
+ put_io_context(arq->io_context);
+}
+
/*
* the back merge hash support functions
*/
@@ -261,14 +279,6 @@ static inline void as_del_arq_hash(struct as_rq *arq)
__as_del_arq_hash(arq);
}
-static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq)
-{
- as_del_arq_hash(arq);
-
- if (q->last_merge == arq->request)
- q->last_merge = NULL;
-}
-
static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq)
{
struct request *rq = arq->request;
@@ -312,7 +322,7 @@ static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
BUG_ON(!arq->on_hash);
if (!rq_mergeable(__rq)) {
- as_remove_merge_hints(ad->q, arq);
+ as_del_arq_hash(arq);
continue;
}
@@ -950,23 +960,12 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
WARN_ON(!list_empty(&rq->queuelist));
- if (arq->state == AS_RQ_PRESCHED) {
- WARN_ON(arq->io_context);
- goto out;
- }
-
- if (arq->state == AS_RQ_MERGED)
- goto out_ioc;
-
if (arq->state != AS_RQ_REMOVED) {
printk("arq->state %d\n", arq->state);
WARN_ON(1);
goto out;
}
- if (!blk_fs_request(rq))
- goto out;
-
if (ad->changed_batch && ad->nr_dispatched == 1) {
kblockd_schedule_work(&ad->antic_work);
ad->changed_batch = 0;
@@ -1001,21 +1000,7 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
}
}
-out_ioc:
- if (!arq->io_context)
- goto out;
-
- if (arq->is_sync == REQ_SYNC) {
- struct as_io_context *aic = arq->io_context->aic;
- if (aic) {
- spin_lock(&aic->lock);
- set_bit(AS_TASK_IORUNNING, &aic->state);
- aic->last_end_request = jiffies;
- spin_unlock(&aic->lock);
- }
- }
-
- put_io_context(arq->io_context);
+ as_put_io_context(arq);
out:
arq->state = AS_RQ_POSTSCHED;
}
@@ -1047,73 +1032,11 @@ static void as_remove_queued_request(request_queue_t *q, struct request *rq)
ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
list_del_init(&arq->fifo);
- as_remove_merge_hints(q, arq);
+ as_del_arq_hash(arq);
as_del_arq_rb(ad, arq);
}
/*
- * as_remove_dispatched_request is called to remove a request which has gone
- * to the dispatch list.
- */
-static void as_remove_dispatched_request(request_queue_t *q, struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
- struct as_io_context *aic;
-
- if (!arq) {
- WARN_ON(1);
- return;
- }
-
- WARN_ON(arq->state != AS_RQ_DISPATCHED);
- WARN_ON(ON_RB(&arq->rb_node));
- if (arq->io_context && arq->io_context->aic) {
- aic = arq->io_context->aic;
- if (aic) {
- WARN_ON(!atomic_read(&aic->nr_dispatched));
- atomic_dec(&aic->nr_dispatched);
- }
- }
-}
-
-/*
- * as_remove_request is called when a driver has finished with a request.
- * This should be only called for dispatched requests, but for some reason
- * a POWER4 box running hwscan it does not.
- */
-static void as_remove_request(request_queue_t *q, struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
-
- if (unlikely(arq->state == AS_RQ_NEW))
- goto out;
-
- if (ON_RB(&arq->rb_node)) {
- if (arq->state != AS_RQ_QUEUED) {
- printk("arq->state %d\n", arq->state);
- WARN_ON(1);
- goto out;
- }
- /*
- * We'll lose the aliased request(s) here. I don't think this
- * will ever happen, but if it does, hopefully someone will
- * report it.
- */
- WARN_ON(!list_empty(&rq->queuelist));
- as_remove_queued_request(q, rq);
- } else {
- if (arq->state != AS_RQ_DISPATCHED) {
- printk("arq->state %d\n", arq->state);
- WARN_ON(1);
- goto out;
- }
- as_remove_dispatched_request(q, rq);
- }
-out:
- arq->state = AS_RQ_REMOVED;
-}
-
-/*
* as_fifo_expired returns 0 if there are no expired reads on the fifo,
* 1 otherwise. It is ratelimited so that we only perform the check once per
* `fifo_expire' interval. Otherwise a large number of expired requests
@@ -1165,7 +1088,6 @@ static inline int as_batch_expired(struct as_data *ad)
static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
{
struct request *rq = arq->request;
- struct list_head *insert;
const int data_dir = arq->is_sync;
BUG_ON(!ON_RB(&arq->rb_node));
@@ -1198,13 +1120,13 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
/*
* take it off the sort and fifo list, add to dispatch queue
*/
- insert = ad->dispatch->prev;
-
while (!list_empty(&rq->queuelist)) {
struct request *__rq = list_entry_rq(rq->queuelist.next);
struct as_rq *__arq = RQ_DATA(__rq);
- list_move_tail(&__rq->queuelist, ad->dispatch);
+ list_del(&__rq->queuelist);
+
+ elv_dispatch_add_tail(ad->q, __rq);
if (__arq->io_context && __arq->io_context->aic)
atomic_inc(&__arq->io_context->aic->nr_dispatched);
@@ -1218,7 +1140,8 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
as_remove_queued_request(ad->q, rq);
WARN_ON(arq->state != AS_RQ_QUEUED);
- list_add(&rq->queuelist, insert);
+ elv_dispatch_sort(ad->q, rq);
+
arq->state = AS_RQ_DISPATCHED;
if (arq->io_context && arq->io_context->aic)
atomic_inc(&arq->io_context->aic->nr_dispatched);
@@ -1230,12 +1153,42 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
* read/write expire, batch expire, etc, and moves it to the dispatch
* queue. Returns 1 if a request was found, 0 otherwise.
*/
-static int as_dispatch_request(struct as_data *ad)
+static int as_dispatch_request(request_queue_t *q, int force)
{
+ struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq;
const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
+ if (unlikely(force)) {
+ /*
+ * Forced dispatch, accounting is useless. Reset
+ * accounting states and dump fifo_lists. Note that
+ * batch_data_dir is reset to REQ_SYNC to avoid
+ * screwing write batch accounting as write batch
+ * accounting occurs on W->R transition.
+ */
+ int dispatched = 0;
+
+ ad->batch_data_dir = REQ_SYNC;
+ ad->changed_batch = 0;
+ ad->new_batch = 0;
+
+ while (ad->next_arq[REQ_SYNC]) {
+ as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
+ dispatched++;
+ }
+ ad->last_check_fifo[REQ_SYNC] = jiffies;
+
+ while (ad->next_arq[REQ_ASYNC]) {
+ as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
+ dispatched++;
+ }
+ ad->last_check_fifo[REQ_ASYNC] = jiffies;
+
+ return dispatched;
+ }
+
/* Signal that the write batch was uncontended, so we can't time it */
if (ad->batch_data_dir == REQ_ASYNC && !reads) {
if (ad->current_write_count == 0 || !writes)
@@ -1359,20 +1312,6 @@ fifo_expired:
return 1;
}
-static struct request *as_next_request(request_queue_t *q)
-{
- struct as_data *ad = q->elevator->elevator_data;
- struct request *rq = NULL;
-
- /*
- * if there are still requests on the dispatch queue, grab the first
- */
- if (!list_empty(ad->dispatch) || as_dispatch_request(ad))
- rq = list_entry_rq(ad->dispatch->next);
-
- return rq;
-}
-
/*
* Add arq to a list behind alias
*/
@@ -1404,17 +1343,25 @@ as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alia
/*
* Don't want to have to handle merges.
*/
- as_remove_merge_hints(ad->q, arq);
+ as_del_arq_hash(arq);
}
/*
* add arq to rbtree and fifo
*/
-static void as_add_request(struct as_data *ad, struct as_rq *arq)
+static void as_add_request(request_queue_t *q, struct request *rq)
{
+ struct as_data *ad = q->elevator->elevator_data;
+ struct as_rq *arq = RQ_DATA(rq);
struct as_rq *alias;
int data_dir;
+ if (arq->state != AS_RQ_PRESCHED) {
+ printk("arq->state: %d\n", arq->state);
+ WARN_ON(1);
+ }
+ arq->state = AS_RQ_NEW;
+
if (rq_data_dir(arq->request) == READ
|| current->flags&PF_SYNCWRITE)
arq->is_sync = 1;
@@ -1437,12 +1384,8 @@ static void as_add_request(struct as_data *ad, struct as_rq *arq)
arq->expires = jiffies + ad->fifo_expire[data_dir];
list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
- if (rq_mergeable(arq->request)) {
+ if (rq_mergeable(arq->request))
as_add_arq_hash(ad, arq);
-
- if (!ad->q->last_merge)
- ad->q->last_merge = arq->request;
- }
as_update_arq(ad, arq); /* keep state machine up to date */
} else {
@@ -1463,96 +1406,24 @@ static void as_add_request(struct as_data *ad, struct as_rq *arq)
arq->state = AS_RQ_QUEUED;
}
-static void as_deactivate_request(request_queue_t *q, struct request *rq)
+static void as_activate_request(request_queue_t *q, struct request *rq)
{
- struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = RQ_DATA(rq);
- if (arq) {
- if (arq->state == AS_RQ_REMOVED) {
- arq->state = AS_RQ_DISPATCHED;
- if (arq->io_context && arq->io_context->aic)
- atomic_inc(&arq->io_context->aic->nr_dispatched);
- }
- } else
- WARN_ON(blk_fs_request(rq)
- && (!(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) );
-
- /* Stop anticipating - let this request get through */
- as_antic_stop(ad);
-}
-
-/*
- * requeue the request. The request has not been completed, nor is it a
- * new request, so don't touch accounting.
- */
-static void as_requeue_request(request_queue_t *q, struct request *rq)
-{
- as_deactivate_request(q, rq);
- list_add(&rq->queuelist, &q->queue_head);
-}
-
-/*
- * Account a request that is inserted directly onto the dispatch queue.
- * arq->io_context->aic->nr_dispatched should not need to be incremented
- * because only new requests should come through here: requeues go through
- * our explicit requeue handler.
- */
-static void as_account_queued_request(struct as_data *ad, struct request *rq)
-{
- if (blk_fs_request(rq)) {
- struct as_rq *arq = RQ_DATA(rq);
- arq->state = AS_RQ_DISPATCHED;
- ad->nr_dispatched++;
- }
+ WARN_ON(arq->state != AS_RQ_DISPATCHED);
+ arq->state = AS_RQ_REMOVED;
+ if (arq->io_context && arq->io_context->aic)
+ atomic_dec(&arq->io_context->aic->nr_dispatched);
}
-static void
-as_insert_request(request_queue_t *q, struct request *rq, int where)
+static void as_deactivate_request(request_queue_t *q, struct request *rq)
{
- struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = RQ_DATA(rq);
- if (arq) {
- if (arq->state != AS_RQ_PRESCHED) {
- printk("arq->state: %d\n", arq->state);
- WARN_ON(1);
- }
- arq->state = AS_RQ_NEW;
- }
-
- /* barriers must flush the reorder queue */
- if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
- && where == ELEVATOR_INSERT_SORT)) {
- WARN_ON(1);
- where = ELEVATOR_INSERT_BACK;
- }
-
- switch (where) {
- case ELEVATOR_INSERT_BACK:
- while (ad->next_arq[REQ_SYNC])
- as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
-
- while (ad->next_arq[REQ_ASYNC])
- as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
-
- list_add_tail(&rq->queuelist, ad->dispatch);
- as_account_queued_request(ad, rq);
- as_antic_stop(ad);
- break;
- case ELEVATOR_INSERT_FRONT:
- list_add(&rq->queuelist, ad->dispatch);
- as_account_queued_request(ad, rq);
- as_antic_stop(ad);
- break;
- case ELEVATOR_INSERT_SORT:
- BUG_ON(!blk_fs_request(rq));
- as_add_request(ad, arq);
- break;
- default:
- BUG();
- return;
- }
+ WARN_ON(arq->state != AS_RQ_REMOVED);
+ arq->state = AS_RQ_DISPATCHED;
+ if (arq->io_context && arq->io_context->aic)
+ atomic_inc(&arq->io_context->aic->nr_dispatched);
}
/*
@@ -1565,12 +1436,8 @@ static int as_queue_empty(request_queue_t *q)
{
struct as_data *ad = q->elevator->elevator_data;
- if (!list_empty(&ad->fifo_list[REQ_ASYNC])
- || !list_empty(&ad->fifo_list[REQ_SYNC])
- || !list_empty(ad->dispatch))
- return 0;
-
- return 1;
+ return list_empty(&ad->fifo_list[REQ_ASYNC])
+ && list_empty(&ad->fifo_list[REQ_SYNC]);
}
static struct request *
@@ -1608,15 +1475,6 @@ as_merge(request_queue_t *q, struct request **req, struct bio *bio)
int ret;
/*
- * try last_merge to avoid going to hash
- */
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE) {
- __rq = q->last_merge;
- goto out_insert;
- }
-
- /*
* see if the merge hash can satisfy a back merge
*/
__rq = as_find_arq_hash(ad, bio->bi_sector);
@@ -1644,9 +1502,6 @@ as_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- if (rq_mergeable(__rq))
- q->last_merge = __rq;
-out_insert:
if (ret) {
if (rq_mergeable(__rq))
as_hot_arq_hash(ad, RQ_DATA(__rq));
@@ -1693,9 +1548,6 @@ static void as_merged_request(request_queue_t *q, struct request *req)
* behind the disk head. We currently don't bother adjusting.
*/
}
-
- if (arq->on_hash)
- q->last_merge = req;
}
static void
@@ -1763,6 +1615,7 @@ as_merged_requests(request_queue_t *q, struct request *req,
* kill knowledge of next, this one is a goner
*/
as_remove_queued_request(q, next);
+ as_put_io_context(anext);
anext->state = AS_RQ_MERGED;
}
@@ -1782,7 +1635,7 @@ static void as_work_handler(void *data)
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
- if (as_next_request(q))
+ if (!as_queue_empty(q))
q->request_fn(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -1797,7 +1650,9 @@ static void as_put_request(request_queue_t *q, struct request *rq)
return;
}
- if (arq->state != AS_RQ_POSTSCHED && arq->state != AS_RQ_PRESCHED) {
+ if (unlikely(arq->state != AS_RQ_POSTSCHED &&
+ arq->state != AS_RQ_PRESCHED &&
+ arq->state != AS_RQ_MERGED)) {
printk("arq->state %d\n", arq->state);
WARN_ON(1);
}
@@ -1807,7 +1662,7 @@ static void as_put_request(request_queue_t *q, struct request *rq)
}
static int as_set_request(request_queue_t *q, struct request *rq,
- struct bio *bio, int gfp_mask)
+ struct bio *bio, gfp_t gfp_mask)
{
struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
@@ -1907,7 +1762,6 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
ad->sort_list[REQ_SYNC] = RB_ROOT;
ad->sort_list[REQ_ASYNC] = RB_ROOT;
- ad->dispatch = &q->queue_head;
ad->fifo_expire[REQ_SYNC] = default_read_expire;
ad->fifo_expire[REQ_ASYNC] = default_write_expire;
ad->antic_expire = default_antic_expire;
@@ -2072,10 +1926,9 @@ static struct elevator_type iosched_as = {
.elevator_merge_fn = as_merge,
.elevator_merged_fn = as_merged_request,
.elevator_merge_req_fn = as_merged_requests,
- .elevator_next_req_fn = as_next_request,
- .elevator_add_req_fn = as_insert_request,
- .elevator_remove_req_fn = as_remove_request,
- .elevator_requeue_req_fn = as_requeue_request,
+ .elevator_dispatch_fn = as_dispatch_request,
+ .elevator_add_req_fn = as_add_request,
+ .elevator_activate_req_fn = as_activate_request,
.elevator_deactivate_req_fn = as_deactivate_request,
.elevator_queue_empty_fn = as_queue_empty,
.elevator_completed_req_fn = as_completed_request,
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index db05a5a99f35..22bda05fc693 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -371,16 +371,10 @@ static int floppy_release( struct inode * inode, struct file * filp );
/************************* 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/cciss.c b/drivers/block/cciss.c
index 418b1469d75d..486b6e1c7dfb 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -47,14 +47,14 @@
#include <linux/completion.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.6.6)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,6)
+#define DRIVER_NAME "HP CISS Driver (v 2.6.8)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8)
/* Embedded module documentation macros - see modules.h */
MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.6");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8");
MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
- " SA6i P600 P800 E400 E300");
+ " SA6i P600 P800 P400 P400i E200 E200i");
MODULE_LICENSE("GPL");
#include "cciss_cmd.h"
@@ -83,12 +83,22 @@ static const struct pci_device_id cciss_pci_device_id[] = {
0x0E11, 0x4091, 0, 0, 0},
{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA,
0x103C, 0x3225, 0, 0, 0},
- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSB,
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
0x103c, 0x3223, 0, 0, 0},
{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
- 0x103c, 0x3231, 0, 0, 0},
+ 0x103c, 0x3234, 0, 0, 0},
{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
- 0x103c, 0x3233, 0, 0, 0},
+ 0x103c, 0x3235, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103c, 0x3211, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103c, 0x3212, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103c, 0x3213, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103c, 0x3214, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103c, 0x3215, 0, 0, 0},
{0,}
};
MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -111,8 +121,13 @@ static struct board_type products[] = {
{ 0x40910E11, "Smart Array 6i", &SA5_access},
{ 0x3225103C, "Smart Array P600", &SA5_access},
{ 0x3223103C, "Smart Array P800", &SA5_access},
- { 0x3231103C, "Smart Array E400", &SA5_access},
- { 0x3233103C, "Smart Array E300", &SA5_access},
+ { 0x3234103C, "Smart Array P400", &SA5_access},
+ { 0x3235103C, "Smart Array P400i", &SA5_access},
+ { 0x3211103C, "Smart Array E200i", &SA5_access},
+ { 0x3212103C, "Smart Array E200", &SA5_access},
+ { 0x3213103C, "Smart Array E200i", &SA5_access},
+ { 0x3214103C, "Smart Array E200i", &SA5_access},
+ { 0x3215103C, "Smart Array E200i", &SA5_access},
};
/* How long to wait (in millesconds) for board to go into simple mode */
@@ -140,15 +155,26 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
static int revalidate_allvol(ctlr_info_t *host);
static int cciss_revalidate(struct gendisk *disk);
-static int deregister_disk(struct gendisk *disk);
-static int register_new_disk(ctlr_info_t *h);
+static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
+static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all);
+static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
+ int withirq, unsigned int *total_size, unsigned int *block_size);
+static void cciss_geometry_inquiry(int ctlr, int logvol,
+ int withirq, unsigned int total_size,
+ unsigned int block_size, InquiryData_struct *inq_buff,
+ drive_info_struct *drv);
static void cciss_getgeometry(int cntl_num);
static void start_io( ctlr_info_t *h);
static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
unsigned char *scsi3addr, int cmd_type);
+static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
+ unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
+ int cmd_type);
+
+static void fail_all_cmds(unsigned long ctlr);
#ifdef CONFIG_PROC_FS
static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
@@ -265,7 +291,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
for(i=0; i<=h->highest_lun; i++) {
drv = &h->drv[i];
- if (drv->block_size == 0)
+ if (drv->heads == 0)
continue;
vol_sz = drv->nr_blocks;
@@ -363,6 +389,8 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
return NULL;
memset(c, 0, sizeof(CommandList_struct));
+ c->cmdindex = -1;
+
c->err_info = (ErrorInfo_struct *)pci_alloc_consistent(
h->pdev, sizeof(ErrorInfo_struct),
&err_dma_handle);
@@ -393,6 +421,8 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
err_dma_handle = h->errinfo_pool_dhandle
+ i*sizeof(ErrorInfo_struct);
h->nr_allocs++;
+
+ c->cmdindex = i;
}
c->busaddr = (__u32) cmd_dma_handle;
@@ -453,6 +483,8 @@ static int cciss_open(struct inode *inode, struct file *filep)
printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */
+ if (host->busy_initializing || drv->busy_configuring)
+ return -EBUSY;
/*
* Root is allowed to open raw volume zero even if it's not configured
* so array config can still work. Root is also allowed to open any
@@ -796,10 +828,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
return(0);
}
case CCISS_DEREGDISK:
- return deregister_disk(disk);
+ return rebuild_lun_table(host, disk);
case CCISS_REGNEWD:
- return register_new_disk(host);
+ return rebuild_lun_table(host, NULL);
case CCISS_PASSTHRU:
{
@@ -1143,48 +1175,323 @@ static int revalidate_allvol(ctlr_info_t *host)
return 0;
}
-static int deregister_disk(struct gendisk *disk)
+/* This function will check the usage_count of the drive to be updated/added.
+ * If the usage_count is zero then the drive information will be updated and
+ * the disk will be re-registered with the kernel. If not then it will be
+ * left alone for the next reboot. The exception to this is disk 0 which
+ * will always be left registered with the kernel since it is also the
+ * controller node. Any changes to disk 0 will show up on the next
+ * reboot.
+*/
+static void cciss_update_drive_info(int ctlr, int drv_index)
+ {
+ ctlr_info_t *h = hba[ctlr];
+ struct gendisk *disk;
+ ReadCapdata_struct *size_buff = NULL;
+ InquiryData_struct *inq_buff = NULL;
+ unsigned int block_size;
+ unsigned int total_size;
+ unsigned long flags = 0;
+ int ret = 0;
+
+ /* if the disk already exists then deregister it before proceeding*/
+ if (h->drv[drv_index].raid_level != -1){
+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+ h->drv[drv_index].busy_configuring = 1;
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ ret = deregister_disk(h->gendisk[drv_index],
+ &h->drv[drv_index], 0);
+ h->drv[drv_index].busy_configuring = 0;
+ }
+
+ /* If the disk is in use return */
+ if (ret)
+ return;
+
+
+ /* Get information about the disk and modify the driver sturcture */
+ size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
+ if (size_buff == NULL)
+ goto mem_msg;
+ inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+ if (inq_buff == NULL)
+ goto mem_msg;
+
+ cciss_read_capacity(ctlr, drv_index, size_buff, 1,
+ &total_size, &block_size);
+ cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
+ inq_buff, &h->drv[drv_index]);
+
+ ++h->num_luns;
+ disk = h->gendisk[drv_index];
+ set_capacity(disk, h->drv[drv_index].nr_blocks);
+
+
+ /* if it's the controller it's already added */
+ if (drv_index){
+ disk->queue = blk_init_queue(do_cciss_request, &h->lock);
+
+ /* Set up queue information */
+ disk->queue->backing_dev_info.ra_pages = READ_AHEAD;
+ blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask);
+
+ /* This is a hardware imposed limit. */
+ blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES);
+
+ /* This is a limit in the driver and could be eliminated. */
+ blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);
+
+ blk_queue_max_sectors(disk->queue, 512);
+
+ disk->queue->queuedata = hba[ctlr];
+
+ blk_queue_hardsect_size(disk->queue,
+ hba[ctlr]->drv[drv_index].block_size);
+
+ h->drv[drv_index].queue = disk->queue;
+ add_disk(disk);
+ }
+
+freeret:
+ kfree(size_buff);
+ kfree(inq_buff);
+ return;
+mem_msg:
+ printk(KERN_ERR "cciss: out of memory\n");
+ goto freeret;
+}
+
+/* This function will find the first index of the controllers drive array
+ * that has a -1 for the raid_level and will return that index. This is
+ * where new drives will be added. If the index to be returned is greater
+ * than the highest_lun index for the controller then highest_lun is set
+ * to this new index. If there are no available indexes then -1 is returned.
+*/
+static int cciss_find_free_drive_index(int ctlr)
{
+ int i;
+
+ for (i=0; i < CISS_MAX_LUN; i++){
+ if (hba[ctlr]->drv[i].raid_level == -1){
+ if (i > hba[ctlr]->highest_lun)
+ hba[ctlr]->highest_lun = i;
+ return i;
+ }
+ }
+ return -1;
+}
+
+/* This function will add and remove logical drives from the Logical
+ * drive array of the controller and maintain persistancy of ordering
+ * so that mount points are preserved until the next reboot. This allows
+ * for the removal of logical drives in the middle of the drive array
+ * without a re-ordering of those drives.
+ * INPUT
+ * h = The controller to perform the operations on
+ * del_disk = The disk to remove if specified. If the value given
+ * is NULL then no disk is removed.
+*/
+static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
+{
+ int ctlr = h->ctlr;
+ int num_luns;
+ ReportLunData_struct *ld_buff = NULL;
+ drive_info_struct *drv = NULL;
+ int return_code;
+ int listlength = 0;
+ int i;
+ int drv_found;
+ int drv_index = 0;
+ __u32 lunid = 0;
unsigned long flags;
+
+ /* Set busy_configuring flag for this operation */
+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+ if (h->num_luns >= CISS_MAX_LUN){
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return -EINVAL;
+ }
+
+ if (h->busy_configuring){
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return -EBUSY;
+ }
+ h->busy_configuring = 1;
+
+ /* if del_disk is NULL then we are being called to add a new disk
+ * and update the logical drive table. If it is not NULL then
+ * we will check if the disk is in use or not.
+ */
+ if (del_disk != NULL){
+ drv = get_drv(del_disk);
+ drv->busy_configuring = 1;
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return_code = deregister_disk(del_disk, drv, 1);
+ drv->busy_configuring = 0;
+ h->busy_configuring = 0;
+ return return_code;
+ } else {
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
+ ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
+ if (ld_buff == NULL)
+ goto mem_msg;
+
+ return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
+ sizeof(ReportLunData_struct), 0, 0, 0,
+ TYPE_CMD);
+
+ if (return_code == IO_OK){
+ listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
+ listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
+ listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
+ listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
+ } else{ /* reading number of logical volumes failed */
+ printk(KERN_WARNING "cciss: report logical volume"
+ " command failed\n");
+ listlength = 0;
+ goto freeret;
+ }
+
+ num_luns = listlength / 8; /* 8 bytes per entry */
+ if (num_luns > CISS_MAX_LUN){
+ num_luns = CISS_MAX_LUN;
+ printk(KERN_WARNING "cciss: more luns configured"
+ " on controller than can be handled by"
+ " this driver.\n");
+ }
+
+ /* Compare controller drive array to drivers drive array.
+ * Check for updates in the drive information and any new drives
+ * on the controller.
+ */
+ for (i=0; i < num_luns; i++){
+ int j;
+
+ drv_found = 0;
+
+ lunid = (0xff &
+ (unsigned int)(ld_buff->LUN[i][3])) << 24;
+ lunid |= (0xff &
+ (unsigned int)(ld_buff->LUN[i][2])) << 16;
+ lunid |= (0xff &
+ (unsigned int)(ld_buff->LUN[i][1])) << 8;
+ lunid |= 0xff &
+ (unsigned int)(ld_buff->LUN[i][0]);
+
+ /* Find if the LUN is already in the drive array
+ * of the controller. If so then update its info
+ * if not is use. If it does not exist then find
+ * the first free index and add it.
+ */
+ for (j=0; j <= h->highest_lun; j++){
+ if (h->drv[j].LunID == lunid){
+ drv_index = j;
+ drv_found = 1;
+ }
+ }
+
+ /* check if the drive was found already in the array */
+ if (!drv_found){
+ drv_index = cciss_find_free_drive_index(ctlr);
+ if (drv_index == -1)
+ goto freeret;
+
+ }
+ h->drv[drv_index].LunID = lunid;
+ cciss_update_drive_info(ctlr, drv_index);
+ } /* end for */
+ } /* end else */
+
+freeret:
+ kfree(ld_buff);
+ h->busy_configuring = 0;
+ /* We return -1 here to tell the ACU that we have registered/updated
+ * all of the drives that we can and to keep it from calling us
+ * additional times.
+ */
+ return -1;
+mem_msg:
+ printk(KERN_ERR "cciss: out of memory\n");
+ goto freeret;
+}
+
+/* This function will deregister the disk and it's queue from the
+ * kernel. It must be called with the controller lock held and the
+ * drv structures busy_configuring flag set. It's parameters are:
+ *
+ * disk = This is the disk to be deregistered
+ * drv = This is the drive_info_struct associated with the disk to be
+ * deregistered. It contains information about the disk used
+ * by the driver.
+ * clear_all = This flag determines whether or not the disk information
+ * is going to be completely cleared out and the highest_lun
+ * reset. Sometimes we want to clear out information about
+ * the disk in preperation for re-adding it. In this case
+ * the highest_lun should be left unchanged and the LunID
+ * should not be cleared.
+*/
+static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
+ int clear_all)
+{
ctlr_info_t *h = get_host(disk);
- drive_info_struct *drv = get_drv(disk);
- int ctlr = h->ctlr;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
- spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* make sure logical volume is NOT is use */
- if( drv->usage_count > 1) {
- spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+ if(clear_all || (h->gendisk[0] == disk)) {
+ if (drv->usage_count > 1)
return -EBUSY;
}
- drv->usage_count++;
- spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+ else
+ if( drv->usage_count > 0 )
+ return -EBUSY;
- /* invalidate the devices and deregister the disk */
- if (disk->flags & GENHD_FL_UP)
+ /* invalidate the devices and deregister the disk. If it is disk
+ * zero do not deregister it but just zero out it's values. This
+ * allows us to delete disk zero but keep the controller registered.
+ */
+ if (h->gendisk[0] != disk){
+ if (disk->flags & GENHD_FL_UP){
+ blk_cleanup_queue(disk->queue);
del_gendisk(disk);
+ drv->queue = NULL;
+ }
+ }
+
+ --h->num_luns;
+ /* zero out the disk size info */
+ drv->nr_blocks = 0;
+ drv->block_size = 0;
+ drv->heads = 0;
+ drv->sectors = 0;
+ drv->cylinders = 0;
+ drv->raid_level = -1; /* This can be used as a flag variable to
+ * indicate that this element of the drive
+ * array is free.
+ */
+
+ if (clear_all){
/* check to see if it was the last disk */
if (drv == h->drv + h->highest_lun) {
/* if so, find the new hightest lun */
int i, newhighest =-1;
for(i=0; i<h->highest_lun; i++) {
/* if the disk has size > 0, it is available */
- if (h->drv[i].nr_blocks)
+ if (h->drv[i].heads)
newhighest = i;
}
h->highest_lun = newhighest;
-
}
- --h->num_luns;
- /* zero out the disk size info */
- drv->nr_blocks = 0;
- drv->block_size = 0;
- drv->cylinders = 0;
+
drv->LunID = 0;
+ }
return(0);
}
+
static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
size_t size,
unsigned int use_unit_num, /* 0: address the controller,
@@ -1420,8 +1727,10 @@ case CMD_HARDWARE_ERR:
}
}
/* unlock the buffers from DMA */
+ buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
+ buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val,
- size, PCI_DMA_BIDIRECTIONAL);
+ c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
cmd_free(h, c, 0);
return(return_status);
@@ -1495,164 +1804,6 @@ cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
return;
}
-static int register_new_disk(ctlr_info_t *h)
-{
- struct gendisk *disk;
- int ctlr = h->ctlr;
- int i;
- int num_luns;
- int logvol;
- int new_lun_found = 0;
- int new_lun_index = 0;
- int free_index_found = 0;
- int free_index = 0;
- ReportLunData_struct *ld_buff = NULL;
- ReadCapdata_struct *size_buff = NULL;
- InquiryData_struct *inq_buff = NULL;
- int return_code;
- int listlength = 0;
- __u32 lunid = 0;
- unsigned int block_size;
- unsigned int total_size;
-
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
- /* if we have no space in our disk array left to add anything */
- if( h->num_luns >= CISS_MAX_LUN)
- return -EINVAL;
-
- ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
- if (ld_buff == NULL)
- goto mem_msg;
- memset(ld_buff, 0, sizeof(ReportLunData_struct));
- size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
- if (size_buff == NULL)
- goto mem_msg;
- inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
- if (inq_buff == NULL)
- goto mem_msg;
-
- return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
- sizeof(ReportLunData_struct), 0, 0, 0, TYPE_CMD);
-
- if( return_code == IO_OK)
- {
-
- // printk("LUN Data\n--------------------------\n");
-
- listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
- listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
- listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
- listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
- } else /* reading number of logical volumes failed */
- {
- printk(KERN_WARNING "cciss: report logical volume"
- " command failed\n");
- listlength = 0;
- goto free_err;
- }
- num_luns = listlength / 8; // 8 bytes pre entry
- if (num_luns > CISS_MAX_LUN)
- {
- num_luns = CISS_MAX_LUN;
- }
-#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", ld_buff->LUNListLength[0],
- ld_buff->LUNListLength[1], ld_buff->LUNListLength[2],
- ld_buff->LUNListLength[3], num_luns);
-#endif
- for(i=0; i< num_luns; i++)
- {
- int j;
- int lunID_found = 0;
-
- lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24;
- lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16;
- lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8;
- lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
-
- /* check to see if this is a new lun */
- for(j=0; j <= h->highest_lun; j++)
- {
-#ifdef CCISS_DEBUG
- printk("Checking %d %x against %x\n", j,h->drv[j].LunID,
- lunid);
-#endif /* CCISS_DEBUG */
- if (h->drv[j].LunID == lunid)
- {
- lunID_found = 1;
- break;
- }
-
- }
- if( lunID_found == 1)
- continue;
- else
- { /* It is the new lun we have been looking for */
-#ifdef CCISS_DEBUG
- printk("new lun found at %d\n", i);
-#endif /* CCISS_DEBUG */
- new_lun_index = i;
- new_lun_found = 1;
- break;
- }
- }
- if (!new_lun_found)
- {
- printk(KERN_WARNING "cciss: New Logical Volume not found\n");
- goto free_err;
- }
- /* Now find the free index */
- for(i=0; i <CISS_MAX_LUN; i++)
- {
-#ifdef CCISS_DEBUG
- printk("Checking Index %d\n", i);
-#endif /* CCISS_DEBUG */
- if(h->drv[i].LunID == 0)
- {
-#ifdef CCISS_DEBUG
- printk("free index found at %d\n", i);
-#endif /* CCISS_DEBUG */
- free_index_found = 1;
- free_index = i;
- break;
- }
- }
- if (!free_index_found)
- {
- printk(KERN_WARNING "cciss: unable to find free slot for disk\n");
- goto free_err;
- }
-
- logvol = free_index;
- h->drv[logvol].LunID = lunid;
- /* there could be gaps in lun numbers, track hightest */
- if(h->highest_lun < lunid)
- h->highest_lun = logvol;
- cciss_read_capacity(ctlr, logvol, size_buff, 1,
- &total_size, &block_size);
- cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size,
- inq_buff, &h->drv[logvol]);
- h->drv[logvol].usage_count = 0;
- ++h->num_luns;
- /* setup partitions per disk */
- disk = h->gendisk[logvol];
- set_capacity(disk, h->drv[logvol].nr_blocks);
- /* if it's the controller it's already added */
- if(logvol)
- add_disk(disk);
-freeret:
- kfree(ld_buff);
- kfree(size_buff);
- kfree(inq_buff);
- return (logvol);
-mem_msg:
- printk(KERN_ERR "cciss: out of memory\n");
-free_err:
- logvol = -1;
- goto freeret;
-}
-
static int cciss_revalidate(struct gendisk *disk)
{
ctlr_info_t *h = get_host(disk);
@@ -1713,10 +1864,9 @@ static unsigned long pollcomplete(int ctlr)
for (i = 20 * HZ; i > 0; i--) {
done = hba[ctlr]->access.command_completed(hba[ctlr]);
- if (done == FIFO_EMPTY) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- } else
+ if (done == FIFO_EMPTY)
+ schedule_timeout_uninterruptible(1);
+ else
return (done);
}
/* Invalid address to tell caller we ran out of time */
@@ -1860,8 +2010,10 @@ resend_cmd1:
cleanup1:
/* unlock the data buffer from DMA */
+ buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
+ buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
- size, PCI_DMA_BIDIRECTIONAL);
+ c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
cmd_free(info_p, c, 1);
return (status);
}
@@ -2112,7 +2264,11 @@ queue:
/* fill in the request */
drv = creq->rq_disk->private_data;
c->Header.ReplyQueue = 0; // unused in simple mode
- c->Header.Tag.lower = c->busaddr; // use the physical address the cmd block for tag
+ /* got command from pool, so use the command block index instead */
+ /* for direct lookups. */
+ /* The first 2 bits are reserved for controller error reporting. */
+ c->Header.Tag.lower = (c->cmdindex << 3);
+ c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
c->Header.LUN.LogDev.VolId= drv->LunID;
c->Header.LUN.LogDev.Mode = 1;
c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
@@ -2187,7 +2343,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
ctlr_info_t *h = dev_id;
CommandList_struct *c;
unsigned long flags;
- __u32 a, a1;
+ __u32 a, a1, a2;
int j;
int start_queue = h->next_to_run;
@@ -2205,10 +2361,21 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
while((a = h->access.command_completed(h)) != FIFO_EMPTY)
{
a1 = a;
+ if ((a & 0x04)) {
+ a2 = (a >> 3);
+ if (a2 >= NR_CMDS) {
+ printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr);
+ fail_all_cmds(h->ctlr);
+ return IRQ_HANDLED;
+ }
+
+ c = h->cmd_pool + a2;
+ a = c->busaddr;
+
+ } else {
a &= ~3;
- if ((c = h->cmpQ) == NULL)
- {
- printk(KERN_WARNING "cciss: Completion of %08lx ignored\n", (unsigned long)a1);
+ if ((c = h->cmpQ) == NULL) {
+ printk(KERN_WARNING "cciss: Completion of %08x ignored\n", a1);
continue;
}
while(c->busaddr != a) {
@@ -2216,6 +2383,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
if (c == h->cmpQ)
break;
}
+ }
/*
* If we've found the command, take it off the
* completion Q and free it
@@ -2635,12 +2803,16 @@ static void cciss_getgeometry(int cntl_num)
#endif /* CCISS_DEBUG */
hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns-1;
- for(i=0; i< hba[cntl_num]->num_luns; i++)
+// for(i=0; i< hba[cntl_num]->num_luns; i++)
+ for(i=0; i < CISS_MAX_LUN; i++)
{
-
- lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24;
- lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16;
- lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8;
+ if (i < hba[cntl_num]->num_luns){
+ lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
+ << 24;
+ lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2]))
+ << 16;
+ lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1]))
+ << 8;
lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
hba[cntl_num]->drv[i].LunID = lunid;
@@ -2648,13 +2820,18 @@ static void cciss_getgeometry(int cntl_num)
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i,
- ld_buff->LUN[i][0], ld_buff->LUN[i][1],ld_buff->LUN[i][2],
- ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID);
+ ld_buff->LUN[i][0], ld_buff->LUN[i][1],
+ ld_buff->LUN[i][2], ld_buff->LUN[i][3],
+ hba[cntl_num]->drv[i].LunID);
#endif /* CCISS_DEBUG */
cciss_read_capacity(cntl_num, i, size_buff, 0,
&total_size, &block_size);
- cciss_geometry_inquiry(cntl_num, i, 0, total_size, block_size,
- inq_buff, &hba[cntl_num]->drv[i]);
+ cciss_geometry_inquiry(cntl_num, i, 0, total_size,
+ block_size, inq_buff, &hba[cntl_num]->drv[i]);
+ } else {
+ /* initialize raid_level to indicate a free space */
+ hba[cntl_num]->drv[i].raid_level = -1;
+ }
}
kfree(ld_buff);
kfree(size_buff);
@@ -2728,6 +2905,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
i = alloc_cciss_hba();
if(i < 0)
return (-1);
+
+ hba[i]->busy_initializing = 1;
+
if (cciss_pci_init(hba[i], pdev) != 0)
goto clean1;
@@ -2808,6 +2988,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
cciss_procinit(i);
+ hba[i]->busy_initializing = 0;
for(j=0; j < NWD; j++) { /* mfm */
drive_info_struct *drv = &(hba[i]->drv[j]);
@@ -2870,6 +3051,7 @@ clean2:
clean1:
release_io_mem(hba[i]);
free_hba(i);
+ hba[i]->busy_initializing = 0;
return(-1);
}
@@ -2914,9 +3096,10 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
/* remove it from the disk list */
for (j = 0; j < NWD; j++) {
struct gendisk *disk = hba[i]->gendisk[j];
- if (disk->flags & GENHD_FL_UP)
- blk_cleanup_queue(disk->queue);
+ if (disk->flags & GENHD_FL_UP) {
del_gendisk(disk);
+ blk_cleanup_queue(disk->queue);
+ }
}
pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
@@ -2965,5 +3148,43 @@ static void __exit cciss_cleanup(void)
remove_proc_entry("cciss", proc_root_driver);
}
+static void fail_all_cmds(unsigned long ctlr)
+{
+ /* If we get here, the board is apparently dead. */
+ ctlr_info_t *h = hba[ctlr];
+ CommandList_struct *c;
+ unsigned long flags;
+
+ printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr);
+ h->alive = 0; /* the controller apparently died... */
+
+ spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+
+ pci_disable_device(h->pdev); /* Make sure it is really dead. */
+
+ /* move everything off the request queue onto the completed queue */
+ while( (c = h->reqQ) != NULL ) {
+ removeQ(&(h->reqQ), c);
+ h->Qdepth--;
+ addQ (&(h->cmpQ), c);
+ }
+
+ /* Now, fail everything on the completed queue with a HW error */
+ while( (c = h->cmpQ) != NULL ) {
+ removeQ(&h->cmpQ, c);
+ c->err_info->CommandStatus = CMD_HARDWARE_ERR;
+ if (c->cmd_type == CMD_RWREQ) {
+ complete_command(h, c, 0);
+ } else if (c->cmd_type == CMD_IOCTL_PEND)
+ complete(c->waiting);
+#ifdef CONFIG_CISS_SCSI_TAPE
+ else if (c->cmd_type == CMD_SCSI)
+ complete_scsi_command(c, 0, 0);
+#endif
+ }
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+ return;
+}
+
module_init(cciss_init);
module_exit(cciss_cleanup);
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 566587d0a500..ef277baee9fd 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -35,7 +35,13 @@ typedef struct _drive_info_struct
int heads;
int sectors;
int cylinders;
- int raid_level;
+ int raid_level; /* set to -1 to indicate that
+ * the drive is not in use/configured
+ */
+ int busy_configuring; /*This is set when the drive is being removed
+ *to prevent it from being opened or it's queue
+ *from being started.
+ */
} drive_info_struct;
struct ctlr_info
@@ -83,6 +89,7 @@ struct ctlr_info
int nr_allocs;
int nr_frees;
int busy_configuring;
+ int busy_initializing;
/* This element holds the zero based queue number of the last
* queue to be started. It is used for fairness.
@@ -94,6 +101,7 @@ struct ctlr_info
#ifdef CONFIG_CISS_SCSI_TAPE
void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
#endif
+ unsigned char alive;
};
/* Defining the diffent access_menthods */
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index a88a88817623..53fea549ba8b 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -226,6 +226,10 @@ typedef struct _ErrorInfo_struct {
#define CMD_MSG_DONE 0x04
#define CMD_MSG_TIMEOUT 0x05
+/* This structure needs to be divisible by 8 for new
+ * indexing method.
+ */
+#define PADSIZE (sizeof(long) - 4)
typedef struct _CommandList_struct {
CommandListHeader_struct Header;
RequestBlock_struct Request;
@@ -236,14 +240,14 @@ typedef struct _CommandList_struct {
ErrorInfo_struct * err_info; /* pointer to the allocated mem */
int ctlr;
int cmd_type;
+ long cmdindex;
struct _CommandList_struct *prev;
struct _CommandList_struct *next;
struct request * rq;
struct completion *waiting;
int retry_count;
-#ifdef CONFIG_CISS_SCSI_TAPE
void * scsi_cmd;
-#endif
+ char pad[PADSIZE];
} CommandList_struct;
//Configuration Table Structure
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index f16e3caed58a..e183a3ef7839 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -93,6 +93,7 @@ struct cciss_scsi_cmd_stack_elem_t {
CommandList_struct cmd;
ErrorInfo_struct Err;
__u32 busaddr;
+ __u32 pad;
};
#pragma pack()
@@ -877,7 +878,7 @@ cciss_scsi_interpret_error(CommandList_struct *cp)
static int
cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
- InquiryData_struct *buf)
+ unsigned char *buf, unsigned char bufsize)
{
int rc;
CommandList_struct *cp;
@@ -900,11 +901,10 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
cdb[1] = 0;
cdb[2] = 0;
cdb[3] = 0;
- cdb[4] = sizeof(*buf) & 0xff;
+ cdb[4] = bufsize;
cdb[5] = 0;
rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb,
- 6, (unsigned char *) buf,
- sizeof(*buf), XFER_READ);
+ 6, buf, bufsize, XFER_READ);
if (rc != 0) return rc; /* something went wrong */
@@ -1000,9 +1000,10 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
that though.
*/
-
+#define OBDR_TAPE_INQ_SIZE 49
+#define OBDR_TAPE_SIG "$DR-10"
ReportLunData_struct *ld_buff;
- InquiryData_struct *inq_buff;
+ unsigned char *inq_buff;
unsigned char scsi3addr[8];
ctlr_info_t *c;
__u32 num_luns=0;
@@ -1020,7 +1021,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
return;
}
memset(ld_buff, 0, reportlunsize);
- inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+ inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
if (inq_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
kfree(ld_buff);
@@ -1051,19 +1052,36 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
/* for each physical lun, do an inquiry */
if (ld_buff->LUN[i][3] & 0xC0) continue;
- memset(inq_buff, 0, sizeof(InquiryData_struct));
+ memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
- if (cciss_scsi_do_inquiry(hba[cntl_num],
- scsi3addr, inq_buff) != 0)
- {
+ if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff,
+ (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
/* Inquiry failed (msg printed already) */
devtype = 0; /* so we will skip this device. */
} else /* what kind of device is this? */
- devtype = (inq_buff->data_byte[0] & 0x1f);
+ devtype = (inq_buff[0] & 0x1f);
switch (devtype)
{
+ case 0x05: /* CD-ROM */ {
+
+ /* We don't *really* support actual CD-ROM devices,
+ * just this "One Button Disaster Recovery" tape drive
+ * which temporarily pretends to be a CD-ROM drive.
+ * So we check that the device is really an OBDR tape
+ * device by checking for "$DR-10" in bytes 43-48 of
+ * the inquiry data.
+ */
+ char obdr_sig[7];
+
+ strncpy(obdr_sig, &inq_buff[43], 6);
+ obdr_sig[6] = '\0';
+ if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
+ /* Not OBDR device, ignore it. */
+ break;
+ }
+ /* fall through . . . */
case 0x01: /* sequential access, (tape) */
case 0x08: /* medium changer */
if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
@@ -1126,6 +1144,7 @@ cciss_scsi_proc_info(struct Scsi_Host *sh,
int buflen, datalen;
ctlr_info_t *ci;
+ int i;
int cntl_num;
@@ -1136,8 +1155,28 @@ cciss_scsi_proc_info(struct Scsi_Host *sh,
cntl_num = ci->ctlr; /* Get our index into the hba[] array */
if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */
- buflen = sprintf(buffer, "hostnum=%d\n", sh->host_no);
-
+ buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
+ cntl_num, sh->host_no);
+
+ /* this information is needed by apps to know which cciss
+ device corresponds to which scsi host number without
+ having to open a scsi target device node. The device
+ information is not a duplicate of /proc/scsi/scsi because
+ the two may be out of sync due to scsi hotplug, rather
+ this info is for an app to be able to use to know how to
+ get them back in sync. */
+
+ for (i=0;i<ccissscsi[cntl_num].ndevices;i++) {
+ struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i];
+ buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
+ "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ sh->host_no, sd->bus, sd->target, sd->lun,
+ sd->devtype,
+ sd->scsi3addr[0], sd->scsi3addr[1],
+ sd->scsi3addr[2], sd->scsi3addr[3],
+ sd->scsi3addr[4], sd->scsi3addr[5],
+ sd->scsi3addr[6], sd->scsi3addr[7]);
+ }
datalen = buflen - offset;
if (datalen < 0) { /* they're reading past EOF. */
datalen = 0;
@@ -1399,7 +1438,7 @@ cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
CPQ_TAPE_LOCK(ctlr, flags);
size = sprintf(buffer + *len,
- " Sequential access devices: %d\n\n",
+ "Sequential access devices: %d\n\n",
ccissscsi[ctlr].ndevices);
CPQ_TAPE_UNLOCK(ctlr, flags);
*pos += size; *len += size;
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
index 30c0903c7cdd..94690e4d41e0 100644
--- a/drivers/block/cfq-iosched.c
+++ b/drivers/block/cfq-iosched.c
@@ -84,7 +84,6 @@ static int cfq_max_depth = 2;
(node)->rb_left = NULL; \
} while (0)
#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL)
-#define ON_RB(node) ((node)->rb_color != RB_NONE)
#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
#define rq_rb_key(rq) (rq)->sector
@@ -271,10 +270,7 @@ CFQ_CFQQ_FNS(expired);
#undef CFQ_CFQQ_FNS
enum cfq_rq_state_flags {
- CFQ_CRQ_FLAG_in_flight = 0,
- CFQ_CRQ_FLAG_in_driver,
- CFQ_CRQ_FLAG_is_sync,
- CFQ_CRQ_FLAG_requeued,
+ CFQ_CRQ_FLAG_is_sync = 0,
};
#define CFQ_CRQ_FNS(name) \
@@ -291,14 +287,11 @@ static inline int cfq_crq_##name(const struct cfq_rq *crq) \
return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0; \
}
-CFQ_CRQ_FNS(in_flight);
-CFQ_CRQ_FNS(in_driver);
CFQ_CRQ_FNS(is_sync);
-CFQ_CRQ_FNS(requeued);
#undef CFQ_CRQ_FNS
static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short);
-static void cfq_dispatch_sort(request_queue_t *, struct cfq_rq *);
+static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *);
static void cfq_put_cfqd(struct cfq_data *cfqd);
#define process_sync(tsk) ((tsk)->flags & PF_SYNCWRITE)
@@ -311,14 +304,6 @@ static inline void cfq_del_crq_hash(struct cfq_rq *crq)
hlist_del_init(&crq->hash);
}
-static void cfq_remove_merge_hints(request_queue_t *q, struct cfq_rq *crq)
-{
- cfq_del_crq_hash(crq);
-
- if (q->last_merge == crq->request)
- q->last_merge = NULL;
-}
-
static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
{
const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
@@ -347,18 +332,13 @@ static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
return NULL;
}
-static inline int cfq_pending_requests(struct cfq_data *cfqd)
-{
- return !list_empty(&cfqd->queue->queue_head) || cfqd->busy_queues;
-}
-
/*
* scheduler run of queue, if there are requests pending and no one in the
* driver that will restart queueing
*/
static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
{
- if (!cfqd->rq_in_driver && cfq_pending_requests(cfqd))
+ if (!cfqd->rq_in_driver && cfqd->busy_queues)
kblockd_schedule_work(&cfqd->unplug_work);
}
@@ -366,7 +346,7 @@ static int cfq_queue_empty(request_queue_t *q)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
- return !cfq_pending_requests(cfqd);
+ return !cfqd->busy_queues;
}
/*
@@ -386,11 +366,6 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
if (crq2 == NULL)
return crq1;
- if (cfq_crq_requeued(crq1) && !cfq_crq_requeued(crq2))
- return crq1;
- else if (cfq_crq_requeued(crq2) && !cfq_crq_requeued(crq1))
- return crq2;
-
if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2))
return crq1;
else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1))
@@ -461,10 +436,7 @@ cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
struct cfq_rq *crq_next = NULL, *crq_prev = NULL;
struct rb_node *rbnext, *rbprev;
- rbnext = NULL;
- if (ON_RB(&last->rb_node))
- rbnext = rb_next(&last->rb_node);
- if (!rbnext) {
+ if (!(rbnext = rb_next(&last->rb_node))) {
rbnext = rb_first(&cfqq->sort_list);
if (rbnext == &last->rb_node)
rbnext = NULL;
@@ -545,13 +517,13 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
* the pending list according to last request service
*/
static inline void
-cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq, int requeue)
+cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
BUG_ON(cfq_cfqq_on_rr(cfqq));
cfq_mark_cfqq_on_rr(cfqq);
cfqd->busy_queues++;
- cfq_resort_rr_list(cfqq, requeue);
+ cfq_resort_rr_list(cfqq, 0);
}
static inline void
@@ -571,22 +543,19 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
static inline void cfq_del_crq_rb(struct cfq_rq *crq)
{
struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_data *cfqd = cfqq->cfqd;
+ const int sync = cfq_crq_is_sync(crq);
- if (ON_RB(&crq->rb_node)) {
- struct cfq_data *cfqd = cfqq->cfqd;
- const int sync = cfq_crq_is_sync(crq);
+ BUG_ON(!cfqq->queued[sync]);
+ cfqq->queued[sync]--;
- BUG_ON(!cfqq->queued[sync]);
- cfqq->queued[sync]--;
+ cfq_update_next_crq(crq);
- cfq_update_next_crq(crq);
+ rb_erase(&crq->rb_node, &cfqq->sort_list);
+ RB_CLEAR_COLOR(&crq->rb_node);
- rb_erase(&crq->rb_node, &cfqq->sort_list);
- RB_CLEAR_COLOR(&crq->rb_node);
-
- if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
- cfq_del_cfqq_rr(cfqd, cfqq);
- }
+ if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
+ cfq_del_cfqq_rr(cfqd, cfqq);
}
static struct cfq_rq *
@@ -627,12 +596,12 @@ static void cfq_add_crq_rb(struct cfq_rq *crq)
* if that happens, put the alias on the dispatch list
*/
while ((__alias = __cfq_add_crq_rb(crq)) != NULL)
- cfq_dispatch_sort(cfqd->queue, __alias);
+ cfq_dispatch_insert(cfqd->queue, __alias);
rb_insert_color(&crq->rb_node, &cfqq->sort_list);
if (!cfq_cfqq_on_rr(cfqq))
- cfq_add_cfqq_rr(cfqd, cfqq, cfq_crq_requeued(crq));
+ cfq_add_cfqq_rr(cfqd, cfqq);
/*
* check if this request is a better next-serve candidate
@@ -643,10 +612,8 @@ static void cfq_add_crq_rb(struct cfq_rq *crq)
static inline void
cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
{
- if (ON_RB(&crq->rb_node)) {
- rb_erase(&crq->rb_node, &cfqq->sort_list);
- cfqq->queued[cfq_crq_is_sync(crq)]--;
- }
+ rb_erase(&crq->rb_node, &cfqq->sort_list);
+ cfqq->queued[cfq_crq_is_sync(crq)]--;
cfq_add_crq_rb(crq);
}
@@ -676,49 +643,28 @@ out:
return NULL;
}
-static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
+static void cfq_activate_request(request_queue_t *q, struct request *rq)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
- struct cfq_rq *crq = RQ_DATA(rq);
-
- if (crq) {
- struct cfq_queue *cfqq = crq->cfq_queue;
-
- if (cfq_crq_in_driver(crq)) {
- cfq_clear_crq_in_driver(crq);
- WARN_ON(!cfqd->rq_in_driver);
- cfqd->rq_in_driver--;
- }
- if (cfq_crq_in_flight(crq)) {
- const int sync = cfq_crq_is_sync(crq);
- cfq_clear_crq_in_flight(crq);
- WARN_ON(!cfqq->on_dispatch[sync]);
- cfqq->on_dispatch[sync]--;
- }
- cfq_mark_crq_requeued(crq);
- }
+ cfqd->rq_in_driver++;
}
-/*
- * make sure the service time gets corrected on reissue of this request
- */
-static void cfq_requeue_request(request_queue_t *q, struct request *rq)
+static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
{
- cfq_deactivate_request(q, rq);
- list_add(&rq->queuelist, &q->queue_head);
+ struct cfq_data *cfqd = q->elevator->elevator_data;
+
+ WARN_ON(!cfqd->rq_in_driver);
+ cfqd->rq_in_driver--;
}
-static void cfq_remove_request(request_queue_t *q, struct request *rq)
+static void cfq_remove_request(struct request *rq)
{
struct cfq_rq *crq = RQ_DATA(rq);
- if (crq) {
- list_del_init(&rq->queuelist);
- cfq_del_crq_rb(crq);
- cfq_remove_merge_hints(q, crq);
-
- }
+ list_del_init(&rq->queuelist);
+ cfq_del_crq_rb(crq);
+ cfq_del_crq_hash(crq);
}
static int
@@ -728,12 +674,6 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
struct request *__rq;
int ret;
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE) {
- __rq = q->last_merge;
- goto out_insert;
- }
-
__rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
if (__rq && elv_rq_merge_ok(__rq, bio)) {
ret = ELEVATOR_BACK_MERGE;
@@ -748,8 +688,6 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = __rq;
-out_insert:
*req = __rq;
return ret;
}
@@ -762,14 +700,12 @@ static void cfq_merged_request(request_queue_t *q, struct request *req)
cfq_del_crq_hash(crq);
cfq_add_crq_hash(cfqd, crq);
- if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
+ if (rq_rb_key(req) != crq->rb_key) {
struct cfq_queue *cfqq = crq->cfq_queue;
cfq_update_next_crq(crq);
cfq_reposition_crq_rb(cfqq, crq);
}
-
- q->last_merge = req;
}
static void
@@ -785,7 +721,7 @@ cfq_merged_requests(request_queue_t *q, struct request *rq,
time_before(next->start_time, rq->start_time))
list_move(&rq->queuelist, &next->queuelist);
- cfq_remove_request(q, next);
+ cfq_remove_request(next);
}
static inline void
@@ -992,53 +928,15 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
return 1;
}
-/*
- * we dispatch cfqd->cfq_quantum requests in total from the rr_list queues,
- * this function sector sorts the selected request to minimize seeks. we start
- * at cfqd->last_sector, not 0.
- */
-static void cfq_dispatch_sort(request_queue_t *q, struct cfq_rq *crq)
+static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_queue *cfqq = crq->cfq_queue;
- struct list_head *head = &q->queue_head, *entry = head;
- struct request *__rq;
- sector_t last;
-
- list_del(&crq->request->queuelist);
-
- last = cfqd->last_sector;
- list_for_each_entry_reverse(__rq, head, queuelist) {
- struct cfq_rq *__crq = RQ_DATA(__rq);
-
- if (blk_barrier_rq(__rq))
- break;
- if (!blk_fs_request(__rq))
- break;
- if (cfq_crq_requeued(__crq))
- break;
-
- if (__rq->sector <= crq->request->sector)
- break;
- if (__rq->sector > last && crq->request->sector < last) {
- last = crq->request->sector + crq->request->nr_sectors;
- break;
- }
- entry = &__rq->queuelist;
- }
-
- cfqd->last_sector = last;
cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
-
- cfq_del_crq_rb(crq);
- cfq_remove_merge_hints(q, crq);
-
- cfq_mark_crq_in_flight(crq);
- cfq_clear_crq_requeued(crq);
-
+ cfq_remove_request(crq->request);
cfqq->on_dispatch[cfq_crq_is_sync(crq)]++;
- list_add_tail(&crq->request->queuelist, entry);
+ elv_dispatch_sort(q, crq->request);
}
/*
@@ -1159,7 +1057,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
/*
* finally, insert request into driver dispatch list
*/
- cfq_dispatch_sort(cfqd->queue, crq);
+ cfq_dispatch_insert(cfqd->queue, crq);
cfqd->dispatch_slice++;
dispatched++;
@@ -1194,7 +1092,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
}
static int
-cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
+cfq_dispatch_requests(request_queue_t *q, int force)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_queue *cfqq;
@@ -1204,12 +1102,25 @@ cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
cfqq = cfq_select_queue(cfqd, force);
if (cfqq) {
+ int max_dispatch;
+
+ /*
+ * if idle window is disabled, allow queue buildup
+ */
+ if (!cfq_cfqq_idle_window(cfqq) &&
+ cfqd->rq_in_driver >= cfqd->cfq_max_depth)
+ return 0;
+
cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_wait_request(cfqq);
del_timer(&cfqd->idle_slice_timer);
- if (cfq_class_idle(cfqq))
- max_dispatch = 1;
+ if (!force) {
+ max_dispatch = cfqd->cfq_quantum;
+ if (cfq_class_idle(cfqq))
+ max_dispatch = 1;
+ } else
+ max_dispatch = INT_MAX;
return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
}
@@ -1217,93 +1128,6 @@ cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
return 0;
}
-static inline void cfq_account_dispatch(struct cfq_rq *crq)
-{
- struct cfq_queue *cfqq = crq->cfq_queue;
- struct cfq_data *cfqd = cfqq->cfqd;
-
- if (unlikely(!blk_fs_request(crq->request)))
- return;
-
- /*
- * accounted bit is necessary since some drivers will call
- * elv_next_request() many times for the same request (eg ide)
- */
- if (cfq_crq_in_driver(crq))
- return;
-
- cfq_mark_crq_in_driver(crq);
- cfqd->rq_in_driver++;
-}
-
-static inline void
-cfq_account_completion(struct cfq_queue *cfqq, struct cfq_rq *crq)
-{
- struct cfq_data *cfqd = cfqq->cfqd;
- unsigned long now;
-
- if (!cfq_crq_in_driver(crq))
- return;
-
- now = jiffies;
-
- WARN_ON(!cfqd->rq_in_driver);
- cfqd->rq_in_driver--;
-
- if (!cfq_class_idle(cfqq))
- cfqd->last_end_request = now;
-
- if (!cfq_cfqq_dispatched(cfqq)) {
- if (cfq_cfqq_on_rr(cfqq)) {
- cfqq->service_last = now;
- cfq_resort_rr_list(cfqq, 0);
- }
- if (cfq_cfqq_expired(cfqq)) {
- __cfq_slice_expired(cfqd, cfqq, 0);
- cfq_schedule_dispatch(cfqd);
- }
- }
-
- if (cfq_crq_is_sync(crq))
- crq->io_context->last_end_request = now;
-}
-
-static struct request *cfq_next_request(request_queue_t *q)
-{
- struct cfq_data *cfqd = q->elevator->elevator_data;
- struct request *rq;
-
- if (!list_empty(&q->queue_head)) {
- struct cfq_rq *crq;
-dispatch:
- rq = list_entry_rq(q->queue_head.next);
-
- crq = RQ_DATA(rq);
- if (crq) {
- struct cfq_queue *cfqq = crq->cfq_queue;
-
- /*
- * if idle window is disabled, allow queue buildup
- */
- if (!cfq_crq_in_driver(crq) &&
- !cfq_cfqq_idle_window(cfqq) &&
- !blk_barrier_rq(rq) &&
- cfqd->rq_in_driver >= cfqd->cfq_max_depth)
- return NULL;
-
- cfq_remove_merge_hints(q, crq);
- cfq_account_dispatch(crq);
- }
-
- return rq;
- }
-
- if (cfq_dispatch_requests(q, cfqd->cfq_quantum, 0))
- goto dispatch;
-
- return NULL;
-}
-
/*
* task holds one reference to the queue, dropped when task exits. each crq
* in-flight on this queue also holds a reference, dropped when crq is freed.
@@ -1422,7 +1246,7 @@ static void cfq_exit_io_context(struct cfq_io_context *cic)
}
static struct cfq_io_context *
-cfq_alloc_io_context(struct cfq_data *cfqd, int gfp_mask)
+cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
{
struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
@@ -1517,7 +1341,7 @@ static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
static struct cfq_queue *
cfq_get_queue(struct cfq_data *cfqd, unsigned int key, unsigned short ioprio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
const int hashval = hash_long(key, CFQ_QHASH_SHIFT);
struct cfq_queue *cfqq, *new_cfqq = NULL;
@@ -1578,7 +1402,7 @@ out:
* cfqq, so we don't need to worry about it disappearing
*/
static struct cfq_io_context *
-cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, int gfp_mask)
+cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, gfp_t gfp_mask)
{
struct io_context *ioc = NULL;
struct cfq_io_context *cic;
@@ -1816,8 +1640,9 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
}
}
-static void cfq_enqueue(struct cfq_data *cfqd, struct request *rq)
+static void cfq_insert_request(request_queue_t *q, struct request *rq)
{
+ struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_rq *crq = RQ_DATA(rq);
struct cfq_queue *cfqq = crq->cfq_queue;
@@ -1827,66 +1652,43 @@ static void cfq_enqueue(struct cfq_data *cfqd, struct request *rq)
list_add_tail(&rq->queuelist, &cfqq->fifo);
- if (rq_mergeable(rq)) {
+ if (rq_mergeable(rq))
cfq_add_crq_hash(cfqd, crq);
- if (!cfqd->queue->last_merge)
- cfqd->queue->last_merge = rq;
- }
-
cfq_crq_enqueued(cfqd, cfqq, crq);
}
-static void
-cfq_insert_request(request_queue_t *q, struct request *rq, int where)
-{
- struct cfq_data *cfqd = q->elevator->elevator_data;
-
- switch (where) {
- case ELEVATOR_INSERT_BACK:
- while (cfq_dispatch_requests(q, INT_MAX, 1))
- ;
- list_add_tail(&rq->queuelist, &q->queue_head);
- /*
- * If we were idling with pending requests on
- * inactive cfqqs, force dispatching will
- * remove the idle timer and the queue won't
- * be kicked by __make_request() afterward.
- * Kick it here.
- */
- cfq_schedule_dispatch(cfqd);
- break;
- case ELEVATOR_INSERT_FRONT:
- list_add(&rq->queuelist, &q->queue_head);
- break;
- case ELEVATOR_INSERT_SORT:
- BUG_ON(!blk_fs_request(rq));
- cfq_enqueue(cfqd, rq);
- break;
- default:
- printk("%s: bad insert point %d\n", __FUNCTION__,where);
- return;
- }
-}
-
static void cfq_completed_request(request_queue_t *q, struct request *rq)
{
struct cfq_rq *crq = RQ_DATA(rq);
- struct cfq_queue *cfqq;
+ struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_data *cfqd = cfqq->cfqd;
+ const int sync = cfq_crq_is_sync(crq);
+ unsigned long now;
- if (unlikely(!blk_fs_request(rq)))
- return;
+ now = jiffies;
- cfqq = crq->cfq_queue;
+ WARN_ON(!cfqd->rq_in_driver);
+ WARN_ON(!cfqq->on_dispatch[sync]);
+ cfqd->rq_in_driver--;
+ cfqq->on_dispatch[sync]--;
- if (cfq_crq_in_flight(crq)) {
- const int sync = cfq_crq_is_sync(crq);
+ if (!cfq_class_idle(cfqq))
+ cfqd->last_end_request = now;
- WARN_ON(!cfqq->on_dispatch[sync]);
- cfqq->on_dispatch[sync]--;
+ if (!cfq_cfqq_dispatched(cfqq)) {
+ if (cfq_cfqq_on_rr(cfqq)) {
+ cfqq->service_last = now;
+ cfq_resort_rr_list(cfqq, 0);
+ }
+ if (cfq_cfqq_expired(cfqq)) {
+ __cfq_slice_expired(cfqd, cfqq, 0);
+ cfq_schedule_dispatch(cfqd);
+ }
}
- cfq_account_completion(cfqq, crq);
+ if (cfq_crq_is_sync(crq))
+ crq->io_context->last_end_request = now;
}
static struct request *
@@ -2075,7 +1877,7 @@ static void cfq_put_request(request_queue_t *q, struct request *rq)
*/
static int
cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct task_struct *tsk = current;
@@ -2118,9 +1920,6 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
INIT_HLIST_NODE(&crq->hash);
crq->cfq_queue = cfqq;
crq->io_context = cic;
- cfq_clear_crq_in_flight(crq);
- cfq_clear_crq_in_driver(crq);
- cfq_clear_crq_requeued(crq);
if (rw == READ || process_sync(tsk))
cfq_mark_crq_is_sync(crq);
@@ -2201,7 +2000,7 @@ static void cfq_idle_slice_timer(unsigned long data)
* only expire and reinvoke request handler, if there are
* other queues with pending requests
*/
- if (!cfq_pending_requests(cfqd)) {
+ if (!cfqd->busy_queues) {
cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
add_timer(&cfqd->idle_slice_timer);
goto out_cont;
@@ -2260,6 +2059,8 @@ static void cfq_put_cfqd(struct cfq_data *cfqd)
if (!atomic_dec_and_test(&cfqd->ref))
return;
+ blk_put_queue(q);
+
cfq_shutdown_timer_wq(cfqd);
q->elevator->elevator_data = NULL;
@@ -2316,6 +2117,7 @@ static int cfq_init_queue(request_queue_t *q, elevator_t *e)
e->elevator_data = cfqd;
cfqd->queue = q;
+ atomic_inc(&q->refcnt);
cfqd->max_queued = q->nr_requests / 4;
q->nr_batching = cfq_queued;
@@ -2573,10 +2375,9 @@ static struct elevator_type iosched_cfq = {
.elevator_merge_fn = cfq_merge,
.elevator_merged_fn = cfq_merged_request,
.elevator_merge_req_fn = cfq_merged_requests,
- .elevator_next_req_fn = cfq_next_request,
+ .elevator_dispatch_fn = cfq_dispatch_requests,
.elevator_add_req_fn = cfq_insert_request,
- .elevator_remove_req_fn = cfq_remove_request,
- .elevator_requeue_req_fn = cfq_requeue_request,
+ .elevator_activate_req_fn = cfq_activate_request,
.elevator_deactivate_req_fn = cfq_deactivate_request,
.elevator_queue_empty_fn = cfq_queue_empty,
.elevator_completed_req_fn = cfq_completed_request,
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 24594c57c323..7929471d7df7 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -50,7 +50,6 @@ struct deadline_data {
* next in sort order. read, write or both are NULL
*/
struct deadline_rq *next_drq[2];
- struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */
unsigned int batching; /* number of sequential requests made */
sector_t last_sector; /* head position */
@@ -113,15 +112,6 @@ static inline void deadline_del_drq_hash(struct deadline_rq *drq)
__deadline_del_drq_hash(drq);
}
-static void
-deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq)
-{
- deadline_del_drq_hash(drq);
-
- if (q->last_merge == drq->request)
- q->last_merge = NULL;
-}
-
static inline void
deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
{
@@ -239,10 +229,9 @@ deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
dd->next_drq[data_dir] = rb_entry_drq(rbnext);
}
- if (ON_RB(&drq->rb_node)) {
- rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
- RB_CLEAR(&drq->rb_node);
- }
+ BUG_ON(!ON_RB(&drq->rb_node));
+ rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
+ RB_CLEAR(&drq->rb_node);
}
static struct request *
@@ -286,7 +275,7 @@ deadline_find_first_drq(struct deadline_data *dd, int data_dir)
/*
* add drq to rbtree and fifo
*/
-static inline void
+static void
deadline_add_request(struct request_queue *q, struct request *rq)
{
struct deadline_data *dd = q->elevator->elevator_data;
@@ -301,12 +290,8 @@ deadline_add_request(struct request_queue *q, struct request *rq)
drq->expires = jiffies + dd->fifo_expire[data_dir];
list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
- if (rq_mergeable(rq)) {
+ if (rq_mergeable(rq))
deadline_add_drq_hash(dd, drq);
-
- if (!q->last_merge)
- q->last_merge = rq;
- }
}
/*
@@ -315,14 +300,11 @@ deadline_add_request(struct request_queue *q, struct request *rq)
static void deadline_remove_request(request_queue_t *q, struct request *rq)
{
struct deadline_rq *drq = RQ_DATA(rq);
+ struct deadline_data *dd = q->elevator->elevator_data;
- if (drq) {
- struct deadline_data *dd = q->elevator->elevator_data;
-
- list_del_init(&drq->fifo);
- deadline_remove_merge_hints(q, drq);
- deadline_del_drq_rb(dd, drq);
- }
+ list_del_init(&drq->fifo);
+ deadline_del_drq_rb(dd, drq);
+ deadline_del_drq_hash(drq);
}
static int
@@ -333,15 +315,6 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
int ret;
/*
- * try last_merge to avoid going to hash
- */
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE) {
- __rq = q->last_merge;
- goto out_insert;
- }
-
- /*
* see if the merge hash can satisfy a back merge
*/
__rq = deadline_find_drq_hash(dd, bio->bi_sector);
@@ -373,8 +346,6 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = __rq;
-out_insert:
if (ret)
deadline_hot_drq_hash(dd, RQ_DATA(__rq));
*req = __rq;
@@ -399,8 +370,6 @@ static void deadline_merged_request(request_queue_t *q, struct request *req)
deadline_del_drq_rb(dd, drq);
deadline_add_drq_rb(dd, drq);
}
-
- q->last_merge = req;
}
static void
@@ -452,7 +421,7 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
request_queue_t *q = drq->request->q;
deadline_remove_request(q, drq->request);
- list_add_tail(&drq->request->queuelist, dd->dispatch);
+ elv_dispatch_add_tail(q, drq->request);
}
/*
@@ -502,8 +471,9 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
* deadline_dispatch_requests selects the best request according to
* read/write expire, fifo_batch, etc
*/
-static int deadline_dispatch_requests(struct deadline_data *dd)
+static int deadline_dispatch_requests(request_queue_t *q, int force)
{
+ struct deadline_data *dd = q->elevator->elevator_data;
const int reads = !list_empty(&dd->fifo_list[READ]);
const int writes = !list_empty(&dd->fifo_list[WRITE]);
struct deadline_rq *drq;
@@ -512,7 +482,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" */
@@ -594,65 +567,12 @@ dispatch_request:
return 1;
}
-static struct request *deadline_next_request(request_queue_t *q)
-{
- struct deadline_data *dd = q->elevator->elevator_data;
- struct request *rq;
-
- /*
- * if there are still requests on the dispatch queue, grab the first one
- */
- if (!list_empty(dd->dispatch)) {
-dispatch:
- rq = list_entry_rq(dd->dispatch->next);
- return rq;
- }
-
- if (deadline_dispatch_requests(dd))
- goto dispatch;
-
- return NULL;
-}
-
-static void
-deadline_insert_request(request_queue_t *q, struct request *rq, int where)
-{
- struct deadline_data *dd = q->elevator->elevator_data;
-
- /* barriers must flush the reorder queue */
- if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
- && where == ELEVATOR_INSERT_SORT))
- where = ELEVATOR_INSERT_BACK;
-
- switch (where) {
- case ELEVATOR_INSERT_BACK:
- while (deadline_dispatch_requests(dd))
- ;
- list_add_tail(&rq->queuelist, dd->dispatch);
- break;
- case ELEVATOR_INSERT_FRONT:
- list_add(&rq->queuelist, dd->dispatch);
- break;
- case ELEVATOR_INSERT_SORT:
- BUG_ON(!blk_fs_request(rq));
- deadline_add_request(q, rq);
- break;
- default:
- printk("%s: bad insert point %d\n", __FUNCTION__,where);
- return;
- }
-}
-
static int deadline_queue_empty(request_queue_t *q)
{
struct deadline_data *dd = q->elevator->elevator_data;
- if (!list_empty(&dd->fifo_list[WRITE])
- || !list_empty(&dd->fifo_list[READ])
- || !list_empty(dd->dispatch))
- return 0;
-
- return 1;
+ return list_empty(&dd->fifo_list[WRITE])
+ && list_empty(&dd->fifo_list[READ]);
}
static struct request *
@@ -730,7 +650,6 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
dd->sort_list[READ] = RB_ROOT;
dd->sort_list[WRITE] = RB_ROOT;
- dd->dispatch = &q->queue_head;
dd->fifo_expire[READ] = read_expire;
dd->fifo_expire[WRITE] = write_expire;
dd->writes_starved = writes_starved;
@@ -745,15 +664,13 @@ static void deadline_put_request(request_queue_t *q, struct request *rq)
struct deadline_data *dd = q->elevator->elevator_data;
struct deadline_rq *drq = RQ_DATA(rq);
- if (drq) {
- mempool_free(drq, dd->drq_pool);
- rq->elevator_private = NULL;
- }
+ mempool_free(drq, dd->drq_pool);
+ rq->elevator_private = NULL;
}
static int
deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct deadline_data *dd = q->elevator->elevator_data;
struct deadline_rq *drq;
@@ -914,9 +831,8 @@ static struct elevator_type iosched_deadline = {
.elevator_merge_fn = deadline_merge,
.elevator_merged_fn = deadline_merged_request,
.elevator_merge_req_fn = deadline_merged_requests,
- .elevator_next_req_fn = deadline_next_request,
- .elevator_add_req_fn = deadline_insert_request,
- .elevator_remove_req_fn = deadline_remove_request,
+ .elevator_dispatch_fn = deadline_dispatch_requests,
+ .elevator_add_req_fn = deadline_add_request,
.elevator_queue_empty_fn = deadline_queue_empty,
.elevator_former_req_fn = deadline_former_request,
.elevator_latter_req_fn = deadline_latter_request,
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 98f0126a2deb..55621d5c5774 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
@@ -83,21 +84,11 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
}
EXPORT_SYMBOL(elv_try_merge);
-inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
-{
- if (q->last_merge)
- return elv_try_merge(q->last_merge, bio);
-
- return ELEVATOR_NO_MERGE;
-}
-EXPORT_SYMBOL(elv_try_last_merge);
-
static struct elevator_type *elevator_find(const char *name)
{
struct elevator_type *e = NULL;
struct list_head *entry;
- spin_lock_irq(&elv_list_lock);
list_for_each(entry, &elv_list) {
struct elevator_type *__e;
@@ -108,7 +99,6 @@ static struct elevator_type *elevator_find(const char *name)
break;
}
}
- spin_unlock_irq(&elv_list_lock);
return e;
}
@@ -120,12 +110,15 @@ static void elevator_put(struct elevator_type *e)
static struct elevator_type *elevator_get(const char *name)
{
- struct elevator_type *e = elevator_find(name);
+ struct elevator_type *e;
- if (!e)
- return NULL;
- if (!try_module_get(e->elevator_owner))
- return NULL;
+ spin_lock_irq(&elv_list_lock);
+
+ e = elevator_find(name);
+ if (e && !try_module_get(e->elevator_owner))
+ e = NULL;
+
+ spin_unlock_irq(&elv_list_lock);
return e;
}
@@ -139,8 +132,6 @@ static int elevator_attach(request_queue_t *q, struct elevator_type *e,
eq->ops = &e->ops;
eq->elevator_type = e;
- INIT_LIST_HEAD(&q->queue_head);
- q->last_merge = NULL;
q->elevator = eq;
if (eq->ops->elevator_init_fn)
@@ -153,11 +144,15 @@ static char chosen_elevator[16];
static void elevator_setup_default(void)
{
+ struct elevator_type *e;
+
/*
* check if default is set and exists
*/
- if (chosen_elevator[0] && elevator_find(chosen_elevator))
+ if (chosen_elevator[0] && (e = elevator_get(chosen_elevator))) {
+ elevator_put(e);
return;
+ }
#if defined(CONFIG_IOSCHED_AS)
strcpy(chosen_elevator, "anticipatory");
@@ -186,6 +181,11 @@ int elevator_init(request_queue_t *q, char *name)
struct elevator_queue *eq;
int ret = 0;
+ INIT_LIST_HEAD(&q->queue_head);
+ q->last_merge = NULL;
+ q->end_sector = 0;
+ q->boundary_rq = NULL;
+
elevator_setup_default();
if (!name)
@@ -220,9 +220,52 @@ void elevator_exit(elevator_t *e)
kfree(e);
}
+/*
+ * Insert rq into dispatch queue of q. Queue lock must be held on
+ * entry. If sort != 0, rq is sort-inserted; otherwise, rq will be
+ * appended to the dispatch queue. To be used by specific elevators.
+ */
+void elv_dispatch_sort(request_queue_t *q, struct request *rq)
+{
+ sector_t boundary;
+ struct list_head *entry;
+
+ if (q->last_merge == rq)
+ q->last_merge = NULL;
+
+ boundary = q->end_sector;
+
+ list_for_each_prev(entry, &q->queue_head) {
+ struct request *pos = list_entry_rq(entry);
+
+ if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED))
+ break;
+ if (rq->sector >= boundary) {
+ if (pos->sector < boundary)
+ continue;
+ } else {
+ if (pos->sector >= boundary)
+ break;
+ }
+ if (rq->sector >= pos->sector)
+ break;
+ }
+
+ list_add(&rq->queuelist, entry);
+}
+
int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
elevator_t *e = q->elevator;
+ int ret;
+
+ if (q->last_merge) {
+ ret = elv_try_merge(q->last_merge, bio);
+ if (ret != ELEVATOR_NO_MERGE) {
+ *req = q->last_merge;
+ return ret;
+ }
+ }
if (e->ops->elevator_merge_fn)
return e->ops->elevator_merge_fn(q, req, bio);
@@ -236,6 +279,8 @@ void elv_merged_request(request_queue_t *q, struct request *rq)
if (e->ops->elevator_merged_fn)
e->ops->elevator_merged_fn(q, rq);
+
+ q->last_merge = rq;
}
void elv_merge_requests(request_queue_t *q, struct request *rq,
@@ -243,20 +288,13 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
{
elevator_t *e = q->elevator;
- if (q->last_merge == next)
- q->last_merge = NULL;
-
if (e->ops->elevator_merge_req_fn)
e->ops->elevator_merge_req_fn(q, rq, next);
+
+ q->last_merge = rq;
}
-/*
- * For careful internal use by the block layer. Essentially the same as
- * a requeue in that it tells the io scheduler that this request is not
- * active in the driver or hardware anymore, but we don't want the request
- * added back to the scheduler. Function is not exported.
- */
-void elv_deactivate_request(request_queue_t *q, struct request *rq)
+void elv_requeue_request(request_queue_t *q, struct request *rq)
{
elevator_t *e = q->elevator;
@@ -264,19 +302,14 @@ void elv_deactivate_request(request_queue_t *q, struct request *rq)
* it already went through dequeue, we need to decrement the
* in_flight count again
*/
- if (blk_account_rq(rq))
+ if (blk_account_rq(rq)) {
q->in_flight--;
+ if (blk_sorted_rq(rq) && e->ops->elevator_deactivate_req_fn)
+ e->ops->elevator_deactivate_req_fn(q, rq);
+ }
rq->flags &= ~REQ_STARTED;
- if (e->ops->elevator_deactivate_req_fn)
- e->ops->elevator_deactivate_req_fn(q, rq);
-}
-
-void elv_requeue_request(request_queue_t *q, struct request *rq)
-{
- elv_deactivate_request(q, rq);
-
/*
* if this is the flush, requeue the original instead and drop the flush
*/
@@ -285,31 +318,27 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
rq = rq->end_io_data;
}
- /*
- * the request is prepped and may have some resources allocated.
- * allowing unprepped requests to pass this one may cause resource
- * deadlock. turn on softbarrier.
- */
- rq->flags |= REQ_SOFTBARRIER;
-
- /*
- * if iosched has an explicit requeue hook, then use that. otherwise
- * just put the request at the front of the queue
- */
- if (q->elevator->ops->elevator_requeue_req_fn)
- q->elevator->ops->elevator_requeue_req_fn(q, rq);
- else
- __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+ __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
}
void __elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
- /*
- * barriers implicitly indicate back insertion
- */
- if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER) &&
- where == ELEVATOR_INSERT_SORT)
+ if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+ /*
+ * barriers implicitly indicate back insertion
+ */
+ if (where == ELEVATOR_INSERT_SORT)
+ where = ELEVATOR_INSERT_BACK;
+
+ /*
+ * this request is scheduling boundary, update end_sector
+ */
+ if (blk_fs_request(rq)) {
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = rq;
+ }
+ } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
where = ELEVATOR_INSERT_BACK;
if (plug)
@@ -317,23 +346,54 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
rq->q = q;
- if (!test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) {
- q->elevator->ops->elevator_add_req_fn(q, rq, where);
+ switch (where) {
+ case ELEVATOR_INSERT_FRONT:
+ rq->flags |= REQ_SOFTBARRIER;
- if (blk_queue_plugged(q)) {
- int nrq = q->rq.count[READ] + q->rq.count[WRITE]
- - q->in_flight;
+ list_add(&rq->queuelist, &q->queue_head);
+ break;
- if (nrq >= q->unplug_thresh)
- __generic_unplug_device(q);
- }
- } else
+ case ELEVATOR_INSERT_BACK:
+ rq->flags |= REQ_SOFTBARRIER;
+
+ while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+ ;
+ list_add_tail(&rq->queuelist, &q->queue_head);
/*
- * if drain is set, store the request "locally". when the drain
- * is finished, the requests will be handed ordered to the io
- * scheduler
+ * We kick the queue here for the following reasons.
+ * - The elevator might have returned NULL previously
+ * to delay requests and returned them now. As the
+ * queue wasn't empty before this request, ll_rw_blk
+ * won't run the queue on return, resulting in hang.
+ * - Usually, back inserted requests won't be merged
+ * with anything. There's no point in delaying queue
+ * processing.
*/
- list_add_tail(&rq->queuelist, &q->drain_list);
+ blk_remove_plug(q);
+ q->request_fn(q);
+ break;
+
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+ rq->flags |= REQ_SORTED;
+ q->elevator->ops->elevator_add_req_fn(q, rq);
+ if (q->last_merge == NULL && rq_mergeable(rq))
+ q->last_merge = rq;
+ break;
+
+ default:
+ printk(KERN_ERR "%s: bad insertion point %d\n",
+ __FUNCTION__, where);
+ BUG();
+ }
+
+ if (blk_queue_plugged(q)) {
+ int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+ - q->in_flight;
+
+ if (nrq >= q->unplug_thresh)
+ __generic_unplug_device(q);
+ }
}
void elv_add_request(request_queue_t *q, struct request *rq, int where,
@@ -348,13 +408,19 @@ void elv_add_request(request_queue_t *q, struct request *rq, int where,
static inline struct request *__elv_next_request(request_queue_t *q)
{
- struct request *rq = q->elevator->ops->elevator_next_req_fn(q);
+ struct request *rq;
+
+ if (unlikely(list_empty(&q->queue_head) &&
+ !q->elevator->ops->elevator_dispatch_fn(q, 0)))
+ return NULL;
+
+ rq = list_entry_rq(q->queue_head.next);
/*
* if this is a barrier write and the device has to issue a
* flush sequence to support it, check how far we are
*/
- if (rq && blk_fs_request(rq) && blk_barrier_rq(rq)) {
+ if (blk_fs_request(rq) && blk_barrier_rq(rq)) {
BUG_ON(q->ordered == QUEUE_ORDERED_NONE);
if (q->ordered == QUEUE_ORDERED_FLUSH &&
@@ -371,15 +437,30 @@ struct request *elv_next_request(request_queue_t *q)
int ret;
while ((rq = __elv_next_request(q)) != NULL) {
- /*
- * just mark as started even if we don't start it, a request
- * that has been delayed should not be passed by new incoming
- * requests
- */
- rq->flags |= REQ_STARTED;
+ if (!(rq->flags & REQ_STARTED)) {
+ elevator_t *e = q->elevator;
- if (rq == q->last_merge)
- q->last_merge = NULL;
+ /*
+ * This is the first time the device driver
+ * sees this request (possibly after
+ * requeueing). Notify IO scheduler.
+ */
+ if (blk_sorted_rq(rq) &&
+ e->ops->elevator_activate_req_fn)
+ e->ops->elevator_activate_req_fn(q, rq);
+
+ /*
+ * just mark as started even if we don't start
+ * it, a request that has been delayed should
+ * not be passed by new incoming requests
+ */
+ rq->flags |= REQ_STARTED;
+ }
+
+ if (!q->boundary_rq || q->boundary_rq == rq) {
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = NULL;
+ }
if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
break;
@@ -391,9 +472,9 @@ struct request *elv_next_request(request_queue_t *q)
/*
* the request may have been (partially) prepped.
* we need to keep this request in the front to
- * avoid resource deadlock. turn on softbarrier.
+ * avoid resource deadlock. REQ_STARTED will
+ * prevent other fs requests from passing this one.
*/
- rq->flags |= REQ_SOFTBARRIER;
rq = NULL;
break;
} else if (ret == BLKPREP_KILL) {
@@ -416,42 +497,32 @@ struct request *elv_next_request(request_queue_t *q)
return rq;
}
-void elv_remove_request(request_queue_t *q, struct request *rq)
+void elv_dequeue_request(request_queue_t *q, struct request *rq)
{
- elevator_t *e = q->elevator;
+ BUG_ON(list_empty(&rq->queuelist));
+
+ list_del_init(&rq->queuelist);
/*
* the time frame between a request being removed from the lists
* and to it is freed is accounted as io that is in progress at
- * the driver side. note that we only account requests that the
- * driver has seen (REQ_STARTED set), to avoid false accounting
- * for request-request merges
+ * the driver side.
*/
if (blk_account_rq(rq))
q->in_flight++;
-
- /*
- * the main clearing point for q->last_merge is on retrieval of
- * request by driver (it calls elv_next_request()), but it _can_
- * also happen here if a request is added to the queue but later
- * deleted without ever being given to driver (merged with another
- * request).
- */
- if (rq == q->last_merge)
- q->last_merge = NULL;
-
- if (e->ops->elevator_remove_req_fn)
- e->ops->elevator_remove_req_fn(q, rq);
}
int elv_queue_empty(request_queue_t *q)
{
elevator_t *e = q->elevator;
+ if (!list_empty(&q->queue_head))
+ return 0;
+
if (e->ops->elevator_queue_empty_fn)
return e->ops->elevator_queue_empty_fn(q);
- return list_empty(&q->queue_head);
+ return 1;
}
struct request *elv_latter_request(request_queue_t *q, struct request *rq)
@@ -487,7 +558,7 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq)
}
int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
elevator_t *e = q->elevator;
@@ -523,11 +594,11 @@ void elv_completed_request(request_queue_t *q, struct request *rq)
/*
* request is released from the driver, io must be done
*/
- if (blk_account_rq(rq))
+ if (blk_account_rq(rq)) {
q->in_flight--;
-
- if (e->ops->elevator_completed_req_fn)
- e->ops->elevator_completed_req_fn(q, rq);
+ if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
+ e->ops->elevator_completed_req_fn(q, rq);
+ }
}
int elv_register_queue(struct request_queue *q)
@@ -555,10 +626,9 @@ void elv_unregister_queue(struct request_queue *q)
int elv_register(struct elevator_type *e)
{
+ spin_lock_irq(&elv_list_lock);
if (elevator_find(e->elevator_name))
BUG();
-
- spin_lock_irq(&elv_list_lock);
list_add_tail(&e->list, &elv_list);
spin_unlock_irq(&elv_list_lock);
@@ -582,25 +652,36 @@ EXPORT_SYMBOL_GPL(elv_unregister);
* switch to new_e io scheduler. be careful not to introduce deadlocks -
* we don't free the old io scheduler, before we have allocated what we
* need for the new one. this way we have a chance of going back to the old
- * one, if the new one fails init for some reason. we also do an intermediate
- * switch to noop to ensure safety with stack-allocated requests, since they
- * don't originate from the block layer allocator. noop is safe here, because
- * it never needs to touch the elevator itself for completion events. DRAIN
- * flags will make sure we don't touch it for additions either.
+ * one, if the new one fails init for some reason.
*/
static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
{
- elevator_t *e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
- struct elevator_type *noop_elevator = NULL;
- elevator_t *old_elevator;
+ elevator_t *old_elevator, *e;
+ /*
+ * Allocate new elevator
+ */
+ e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
if (!e)
goto error;
/*
- * first step, drain requests from the block freelist
+ * Turn on BYPASS and drain all requests w/ elevator private data
*/
- blk_wait_queue_drained(q, 0);
+ spin_lock_irq(q->queue_lock);
+
+ set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+
+ while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+ ;
+
+ while (q->rq.elvpriv) {
+ spin_unlock_irq(q->queue_lock);
+ msleep(10);
+ spin_lock_irq(q->queue_lock);
+ }
+
+ spin_unlock_irq(q->queue_lock);
/*
* unregister old elevator data
@@ -609,18 +690,6 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
old_elevator = q->elevator;
/*
- * next step, switch to noop since it uses no private rq structures
- * and doesn't allocate any memory for anything. then wait for any
- * non-fs requests in-flight
- */
- noop_elevator = elevator_get("noop");
- spin_lock_irq(q->queue_lock);
- elevator_attach(q, noop_elevator, e);
- spin_unlock_irq(q->queue_lock);
-
- blk_wait_queue_drained(q, 1);
-
- /*
* attach and start new elevator
*/
if (elevator_attach(q, new_e, e))
@@ -630,11 +699,10 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
goto fail_register;
/*
- * finally exit old elevator and start queue again
+ * finally exit old elevator and turn off BYPASS.
*/
elevator_exit(old_elevator);
- blk_finish_queue_drain(q);
- elevator_put(noop_elevator);
+ clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
return;
fail_register:
@@ -643,13 +711,13 @@ fail_register:
* one again (along with re-adding the sysfs dir)
*/
elevator_exit(e);
+ e = NULL;
fail:
q->elevator = old_elevator;
elv_register_queue(q);
- blk_finish_queue_drain(q);
+ clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+ kfree(e);
error:
- if (noop_elevator)
- elevator_put(noop_elevator);
elevator_put(new_e);
printk(KERN_ERR "elevator: switch to %s failed\n",new_e->elevator_name);
}
@@ -701,11 +769,12 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
return len;
}
+EXPORT_SYMBOL(elv_dispatch_sort);
EXPORT_SYMBOL(elv_add_request);
EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(elv_requeue_request);
EXPORT_SYMBOL(elv_next_request);
-EXPORT_SYMBOL(elv_remove_request);
+EXPORT_SYMBOL(elv_dequeue_request);
EXPORT_SYMBOL(elv_queue_empty);
EXPORT_SYMBOL(elv_completed_request);
EXPORT_SYMBOL(elevator_exit);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 888dad5eef34..00895477155e 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -628,7 +628,7 @@ static inline void debugt(const char *message) { }
#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/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 483d71b10cf9..0af73512b9a8 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -263,8 +263,6 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
blk_queue_activity_fn(q, NULL, NULL);
-
- INIT_LIST_HEAD(&q->drain_list);
}
EXPORT_SYMBOL(blk_queue_make_request);
@@ -353,6 +351,8 @@ static void blk_pre_flush_end_io(struct request *flush_rq)
struct request *rq = flush_rq->end_io_data;
request_queue_t *q = rq->q;
+ elv_completed_request(q, flush_rq);
+
rq->flags |= REQ_BAR_PREFLUSH;
if (!flush_rq->errors)
@@ -369,6 +369,8 @@ static void blk_post_flush_end_io(struct request *flush_rq)
struct request *rq = flush_rq->end_io_data;
request_queue_t *q = rq->q;
+ elv_completed_request(q, flush_rq);
+
rq->flags |= REQ_BAR_POSTFLUSH;
q->end_flush_fn(q, flush_rq);
@@ -408,8 +410,6 @@ struct request *blk_start_pre_flush(request_queue_t *q, struct request *rq)
if (!list_empty(&rq->queuelist))
blkdev_dequeue_request(rq);
- elv_deactivate_request(q, rq);
-
flush_rq->end_io_data = rq;
flush_rq->end_io = blk_pre_flush_end_io;
@@ -1040,6 +1040,7 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags);
static char *rq_flags[] = {
"REQ_RW",
"REQ_FAILFAST",
+ "REQ_SORTED",
"REQ_SOFTBARRIER",
"REQ_HARDBARRIER",
"REQ_CMD",
@@ -1047,6 +1048,7 @@ static char *rq_flags[] = {
"REQ_STARTED",
"REQ_DONTPREP",
"REQ_QUEUED",
+ "REQ_ELVPRIV",
"REQ_PC",
"REQ_BLOCK_PC",
"REQ_SENSE",
@@ -1637,9 +1639,9 @@ static int blk_init_free_list(request_queue_t *q)
rl->count[READ] = rl->count[WRITE] = 0;
rl->starved[READ] = rl->starved[WRITE] = 0;
+ rl->elvpriv = 0;
init_waitqueue_head(&rl->wait[READ]);
init_waitqueue_head(&rl->wait[WRITE]);
- init_waitqueue_head(&rl->drain);
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
mempool_free_slab, request_cachep, q->node);
@@ -1652,13 +1654,13 @@ static int blk_init_free_list(request_queue_t *q)
static int __make_request(request_queue_t *, struct bio *);
-request_queue_t *blk_alloc_queue(int gfp_mask)
+request_queue_t *blk_alloc_queue(gfp_t gfp_mask)
{
return blk_alloc_queue_node(gfp_mask, -1);
}
EXPORT_SYMBOL(blk_alloc_queue);
-request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
+request_queue_t *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
{
request_queue_t *q;
@@ -1782,12 +1784,14 @@ EXPORT_SYMBOL(blk_get_queue);
static inline void blk_free_request(request_queue_t *q, struct request *rq)
{
- elv_put_request(q, rq);
+ if (rq->flags & REQ_ELVPRIV)
+ elv_put_request(q, rq);
mempool_free(rq, q->rq.rq_pool);
}
static inline struct request *
-blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
+blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
+ int priv, gfp_t gfp_mask)
{
struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
@@ -1800,11 +1804,15 @@ blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
*/
rq->flags = rw;
- if (!elv_set_request(q, rq, bio, gfp_mask))
- return rq;
+ if (priv) {
+ if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
+ mempool_free(rq, q->rq.rq_pool);
+ return NULL;
+ }
+ rq->flags |= REQ_ELVPRIV;
+ }
- mempool_free(rq, q->rq.rq_pool);
- return NULL;
+ return rq;
}
/*
@@ -1860,22 +1868,18 @@ static void __freed_request(request_queue_t *q, int rw)
* A request has just been released. Account for it, update the full and
* congestion status, wake up any waiters. Called under q->queue_lock.
*/
-static void freed_request(request_queue_t *q, int rw)
+static void freed_request(request_queue_t *q, int rw, int priv)
{
struct request_list *rl = &q->rq;
rl->count[rw]--;
+ if (priv)
+ rl->elvpriv--;
__freed_request(q, rw);
if (unlikely(rl->starved[rw ^ 1]))
__freed_request(q, rw ^ 1);
-
- if (!rl->count[READ] && !rl->count[WRITE]) {
- smp_mb();
- if (unlikely(waitqueue_active(&rl->drain)))
- wake_up(&rl->drain);
- }
}
#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
@@ -1885,14 +1889,12 @@ static void freed_request(request_queue_t *q, int rw)
* Returns !NULL on success, with queue_lock *not held*.
*/
static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct request *rq = NULL;
struct request_list *rl = &q->rq;
struct io_context *ioc = current_io_context(GFP_ATOMIC);
-
- if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
- goto out;
+ int priv;
if (rl->count[rw]+1 >= q->nr_requests) {
/*
@@ -1937,9 +1939,14 @@ get_rq:
rl->starved[rw] = 0;
if (rl->count[rw] >= queue_congestion_on_threshold(q))
set_queue_congested(q, rw);
+
+ priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+ if (priv)
+ rl->elvpriv++;
+
spin_unlock_irq(q->queue_lock);
- rq = blk_alloc_request(q, rw, bio, gfp_mask);
+ rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
if (!rq) {
/*
* Allocation failed presumably due to memory. Undo anything
@@ -1949,7 +1956,7 @@ get_rq:
* wait queue, but this is pretty rare.
*/
spin_lock_irq(q->queue_lock);
- freed_request(q, rw);
+ freed_request(q, rw, priv);
/*
* in the very unlikely event that allocation failed and no
@@ -2019,7 +2026,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
return rq;
}
-struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
+struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask)
{
struct request *rq;
@@ -2251,7 +2258,7 @@ EXPORT_SYMBOL(blk_rq_unmap_user);
* @gfp_mask: memory allocation flags
*/
int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
- unsigned int len, unsigned int gfp_mask)
+ unsigned int len, gfp_t gfp_mask)
{
struct bio *bio;
@@ -2373,44 +2380,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
EXPORT_SYMBOL(blkdev_issue_flush);
-/**
- * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
- * @q: device queue
- * @disk: gendisk
- * @error_sector: error offset
- *
- * Description:
- * Devices understanding the SCSI command set, can use this function as
- * a helper for issuing a cache flush. Note: driver is required to store
- * the error offset (in case of error flushing) in ->sector of struct
- * request.
- */
-int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
- int ret;
-
- rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
- rq->sector = 0;
- memset(rq->cmd, 0, sizeof(rq->cmd));
- rq->cmd[0] = 0x35;
- rq->cmd_len = 12;
- rq->data = NULL;
- rq->data_len = 0;
- rq->timeout = 60 * HZ;
-
- ret = blk_execute_rq(q, disk, rq, 0);
-
- if (ret && error_sector)
- *error_sector = rq->sector;
-
- blk_put_request(rq);
- return ret;
-}
-
-EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
-
static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
{
int rw = rq_data_dir(rq);
@@ -2471,13 +2440,15 @@ void disk_round_stats(struct gendisk *disk)
{
unsigned long now = jiffies;
- __disk_stat_add(disk, time_in_queue,
- disk->in_flight * (now - disk->stamp));
- disk->stamp = now;
+ if (now == disk->stamp)
+ return;
- if (disk->in_flight)
- __disk_stat_add(disk, io_ticks, (now - disk->stamp_idle));
- disk->stamp_idle = now;
+ if (disk->in_flight) {
+ __disk_stat_add(disk, time_in_queue,
+ disk->in_flight * (now - disk->stamp));
+ __disk_stat_add(disk, io_ticks, (now - disk->stamp));
+ }
+ disk->stamp = now;
}
/*
@@ -2492,6 +2463,8 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
if (unlikely(--req->ref_count))
return;
+ elv_completed_request(q, req);
+
req->rq_status = RQ_INACTIVE;
req->rl = NULL;
@@ -2501,26 +2474,25 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
*/
if (rl) {
int rw = rq_data_dir(req);
-
- elv_completed_request(q, req);
+ int priv = req->flags & REQ_ELVPRIV;
BUG_ON(!list_empty(&req->queuelist));
blk_free_request(q, req);
- freed_request(q, rw);
+ freed_request(q, rw, priv);
}
}
void blk_put_request(struct request *req)
{
+ unsigned long flags;
+ request_queue_t *q = req->q;
+
/*
- * if req->rl isn't set, this request didnt originate from the
- * block layer, so it's safe to just disregard it
+ * Gee, IDE calls in w/ NULL q. Fix IDE and remove the
+ * following if (q) test.
*/
- if (req->rl) {
- unsigned long flags;
- request_queue_t *q = req->q;
-
+ if (q) {
spin_lock_irqsave(q->queue_lock, flags);
__blk_put_request(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
@@ -2835,97 +2807,6 @@ static inline void blk_partition_remap(struct bio *bio)
}
}
-void blk_finish_queue_drain(request_queue_t *q)
-{
- struct request_list *rl = &q->rq;
- struct request *rq;
- int requeued = 0;
-
- spin_lock_irq(q->queue_lock);
- clear_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
-
- while (!list_empty(&q->drain_list)) {
- rq = list_entry_rq(q->drain_list.next);
-
- list_del_init(&rq->queuelist);
- elv_requeue_request(q, rq);
- requeued++;
- }
-
- if (requeued)
- q->request_fn(q);
-
- spin_unlock_irq(q->queue_lock);
-
- wake_up(&rl->wait[0]);
- wake_up(&rl->wait[1]);
- wake_up(&rl->drain);
-}
-
-static int wait_drain(request_queue_t *q, struct request_list *rl, int dispatch)
-{
- int wait = rl->count[READ] + rl->count[WRITE];
-
- if (dispatch)
- wait += !list_empty(&q->queue_head);
-
- return wait;
-}
-
-/*
- * We rely on the fact that only requests allocated through blk_alloc_request()
- * have io scheduler private data structures associated with them. Any other
- * type of request (allocated on stack or through kmalloc()) should not go
- * to the io scheduler core, but be attached to the queue head instead.
- */
-void blk_wait_queue_drained(request_queue_t *q, int wait_dispatch)
-{
- struct request_list *rl = &q->rq;
- DEFINE_WAIT(wait);
-
- spin_lock_irq(q->queue_lock);
- set_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
-
- while (wait_drain(q, rl, wait_dispatch)) {
- prepare_to_wait(&rl->drain, &wait, TASK_UNINTERRUPTIBLE);
-
- if (wait_drain(q, rl, wait_dispatch)) {
- __generic_unplug_device(q);
- spin_unlock_irq(q->queue_lock);
- io_schedule();
- spin_lock_irq(q->queue_lock);
- }
-
- finish_wait(&rl->drain, &wait);
- }
-
- spin_unlock_irq(q->queue_lock);
-}
-
-/*
- * block waiting for the io scheduler being started again.
- */
-static inline void block_wait_queue_running(request_queue_t *q)
-{
- DEFINE_WAIT(wait);
-
- while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) {
- struct request_list *rl = &q->rq;
-
- prepare_to_wait_exclusive(&rl->drain, &wait,
- TASK_UNINTERRUPTIBLE);
-
- /*
- * re-check the condition. avoids using prepare_to_wait()
- * in the fast path (queue is running)
- */
- if (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))
- io_schedule();
-
- finish_wait(&rl->drain, &wait);
- }
-}
-
static void handle_bad_sector(struct bio *bio)
{
char b[BDEVNAME_SIZE];
@@ -3021,8 +2902,6 @@ end_io:
if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
goto end_io;
- block_wait_queue_running(q);
-
/*
* If this device has partitions, remap block n
* of partition p to block n+start(p) of the disk.
@@ -3431,7 +3310,7 @@ void exit_io_context(void)
* but since the current task itself holds a reference, the context can be
* used in general code, so long as it stays within `current` context.
*/
-struct io_context *current_io_context(int gfp_flags)
+struct io_context *current_io_context(gfp_t gfp_flags)
{
struct task_struct *tsk = current;
struct io_context *ret;
@@ -3462,7 +3341,7 @@ EXPORT_SYMBOL(current_io_context);
*
* This is always called in the context of the task which submitted the I/O.
*/
-struct io_context *get_io_context(int gfp_flags)
+struct io_context *get_io_context(gfp_t gfp_flags)
{
struct io_context *ret;
ret = current_io_context(gfp_flags);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b35e08876dd4..96c664af8d06 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -881,7 +881,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
{
struct file *filp = lo->lo_backing_file;
- int gfp = lo->old_gfp_mask;
+ gfp_t gfp = lo->old_gfp_mask;
if (lo->lo_state != Lo_bound)
return -ENXIO;
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
index b1730b62c37e..f56b8edb06e4 100644
--- a/drivers/block/noop-iosched.c
+++ b/drivers/block/noop-iosched.c
@@ -7,57 +7,19 @@
#include <linux/module.h>
#include <linux/init.h>
-/*
- * See if we can find a request that this buffer can be coalesced with.
- */
-static int elevator_noop_merge(request_queue_t *q, struct request **req,
- struct bio *bio)
-{
- int ret;
-
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE)
- *req = q->last_merge;
-
- return ret;
-}
-
-static void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
- struct request *next)
-{
- list_del_init(&next->queuelist);
-}
-
-static void elevator_noop_add_request(request_queue_t *q, struct request *rq,
- int where)
+static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
{
- if (where == ELEVATOR_INSERT_FRONT)
- list_add(&rq->queuelist, &q->queue_head);
- else
- list_add_tail(&rq->queuelist, &q->queue_head);
-
- /*
- * new merges must not precede this barrier
- */
- if (rq->flags & REQ_HARDBARRIER)
- q->last_merge = NULL;
- else if (!q->last_merge)
- q->last_merge = rq;
+ elv_dispatch_add_tail(q, rq);
}
-static struct request *elevator_noop_next_request(request_queue_t *q)
+static int elevator_noop_dispatch(request_queue_t *q, int force)
{
- if (!list_empty(&q->queue_head))
- return list_entry_rq(q->queue_head.next);
-
- return NULL;
+ return 0;
}
static struct elevator_type elevator_noop = {
.ops = {
- .elevator_merge_fn = elevator_noop_merge,
- .elevator_merge_req_fn = elevator_noop_merge_requests,
- .elevator_next_req_fn = elevator_noop_next_request,
+ .elevator_dispatch_fn = elevator_noop_dispatch,
.elevator_add_req_fn = elevator_noop_add_request,
},
.elevator_name = "noop",
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 7289f67e9568..ac5ba462710b 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -516,8 +516,7 @@ static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
static void pcd_sleep(int cs)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(cs);
+ schedule_timeout_interruptible(cs);
}
static int pcd_reset(struct pcd_unit *cd)
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 060b1f2a91dd..94af920465b5 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -507,8 +507,7 @@ static void pf_eject(struct pf_unit *pf)
static void pf_sleep(int cs)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(cs);
+ schedule_timeout_interruptible(cs);
}
/* the ATAPI standard actually specifies the contents of all 7 registers
@@ -751,6 +750,14 @@ static int pf_ready(void)
static struct request_queue *pf_queue;
+static void pf_end_request(int uptodate)
+{
+ if (pf_req) {
+ end_request(pf_req, uptodate);
+ pf_req = NULL;
+ }
+}
+
static void do_pf_request(request_queue_t * q)
{
if (pf_busy)
@@ -766,7 +773,7 @@ repeat:
pf_count = pf_req->current_nr_sectors;
if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) {
- end_request(pf_req, 0);
+ pf_end_request(0);
goto repeat;
}
@@ -781,7 +788,7 @@ repeat:
pi_do_claimed(pf_current->pi, do_pf_write);
else {
pf_busy = 0;
- end_request(pf_req, 0);
+ pf_end_request(0);
goto repeat;
}
}
@@ -799,9 +806,11 @@ static int pf_next_buf(void)
if (!pf_count)
return 1;
spin_lock_irqsave(&pf_spin_lock, saved_flags);
- end_request(pf_req, 1);
- pf_count = pf_req->current_nr_sectors;
- pf_buf = pf_req->buffer;
+ pf_end_request(1);
+ if (pf_req) {
+ pf_count = pf_req->current_nr_sectors;
+ pf_buf = pf_req->buffer;
+ }
spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return 1;
}
@@ -811,7 +820,7 @@ static inline void next_request(int success)
unsigned long saved_flags;
spin_lock_irqsave(&pf_spin_lock, saved_flags);
- end_request(pf_req, success);
+ pf_end_request(success);
pf_busy = 0;
do_pf_request(pf_queue);
spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 84d8e291ed96..b3982395f22b 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -276,8 +276,7 @@ static inline u8 DRIVE(struct pg *dev)
static void pg_sleep(int cs)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(cs);
+ schedule_timeout_interruptible(cs);
}
static int pg_wait(struct pg *dev, int go, int stop, unsigned long tmo, char *msg)
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 5fe8ee86f095..d8d35233cf49 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -383,8 +383,7 @@ static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char *
static void pt_sleep(int cs)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(cs);
+ schedule_timeout_interruptible(cs);
}
static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 7b838342f0a3..a280e679b1ca 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -5,29 +5,41 @@
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
- * Packet writing layer for ATAPI and SCSI CD-R, CD-RW, DVD-R, and
- * DVD-RW devices (aka an exercise in block layer masturbation)
+ * Packet writing layer for ATAPI and SCSI CD-RW, DVD+RW, DVD-RW and
+ * DVD-RAM devices.
*
+ * Theory of operation:
*
- * TODO: (circa order of when I will fix it)
- * - Only able to write on CD-RW media right now.
- * - check host application code on media and set it in write page
- * - interface for UDF <-> packet to negotiate a new location when a write
- * fails.
- * - handle OPC, especially for -RW media
+ * At the lowest level, there is the standard driver for the CD/DVD device,
+ * typically ide-cd.c or sr.c. This driver can handle read and write requests,
+ * but it doesn't know anything about the special restrictions that apply to
+ * packet writing. One restriction is that write requests must be aligned to
+ * packet boundaries on the physical media, and the size of a write request
+ * must be equal to the packet size. Another restriction is that a
+ * GPCMD_FLUSH_CACHE command has to be issued to the drive before a read
+ * command, if the previous command was a write.
*
- * Theory of operation:
+ * The purpose of the packet writing driver is to hide these restrictions from
+ * higher layers, such as file systems, and present a block device that can be
+ * randomly read and written using 2kB-sized blocks.
+ *
+ * The lowest layer in the packet writing driver is the packet I/O scheduler.
+ * Its data is defined by the struct packet_iosched and includes two bio
+ * queues with pending read and write requests. These queues are processed
+ * by the pkt_iosched_process_queue() function. The write requests in this
+ * queue are already properly aligned and sized. This layer is responsible for
+ * issuing the flush cache commands and scheduling the I/O in a good order.
*
- * We use a custom make_request_fn function that forwards reads directly to
- * the underlying CD device. Write requests are either attached directly to
- * a live packet_data object, or simply stored sequentially in a list for
- * later processing by the kcdrwd kernel thread. This driver doesn't use
- * any elevator functionally as defined by the elevator_s struct, but the
- * underlying CD device uses a standard elevator.
+ * The next layer transforms unaligned write requests to aligned writes. This
+ * transformation requires reading missing pieces of data from the underlying
+ * block device, assembling the pieces to full packets and queuing them to the
+ * packet I/O scheduler.
*
- * This strategy makes it possible to do very late merging of IO requests.
- * A new bio sent to pkt_make_request can be merged with a live packet_data
- * object even if the object is in the data gathering state.
+ * At the top layer there is a custom make_request_fn function that forwards
+ * read requests directly to the iosched queue and puts write requests in the
+ * unaligned write queue. A kernel thread performs the necessary read
+ * gathering to convert the unaligned writes to aligned writes and then feeds
+ * them to the packet I/O scheduler.
*
*************************************************************************/
@@ -100,10 +112,9 @@ static struct bio *pkt_bio_alloc(int nr_iovecs)
goto no_bio;
bio_init(bio);
- bvl = kmalloc(nr_iovecs * sizeof(struct bio_vec), GFP_KERNEL);
+ bvl = kcalloc(nr_iovecs, sizeof(struct bio_vec), GFP_KERNEL);
if (!bvl)
goto no_bvl;
- memset(bvl, 0, nr_iovecs * sizeof(struct bio_vec));
bio->bi_max_vecs = nr_iovecs;
bio->bi_io_vec = bvl;
@@ -125,10 +136,9 @@ static struct packet_data *pkt_alloc_packet_data(void)
int i;
struct packet_data *pkt;
- pkt = kmalloc(sizeof(struct packet_data), GFP_KERNEL);
+ pkt = kzalloc(sizeof(struct packet_data), GFP_KERNEL);
if (!pkt)
goto no_pkt;
- memset(pkt, 0, sizeof(struct packet_data));
pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE);
if (!pkt->w_bio)
@@ -219,7 +229,7 @@ static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
return 1;
}
-static void *pkt_rb_alloc(unsigned int __nocast gfp_mask, void *data)
+static void *pkt_rb_alloc(gfp_t gfp_mask, void *data)
{
return kmalloc(sizeof(struct pkt_rb_node), gfp_mask);
}
@@ -659,7 +669,6 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in
}
offs += CD_FRAMESIZE;
if (offs >= PAGE_SIZE) {
- BUG_ON(offs > PAGE_SIZE);
offs = 0;
p++;
}
@@ -724,12 +733,6 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
atomic_set(&pkt->io_wait, 0);
atomic_set(&pkt->io_errors, 0);
- if (pkt->cache_valid) {
- VPRINTK("pkt_gather_data: zone %llx cached\n",
- (unsigned long long)pkt->sector);
- goto out_account;
- }
-
/*
* Figure out which frames we need to read before we can write.
*/
@@ -738,6 +741,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
for (bio = pkt->orig_bios; bio; bio = bio->bi_next) {
int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
int num_frames = bio->bi_size / CD_FRAMESIZE;
+ pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9);
BUG_ON(first_frame < 0);
BUG_ON(first_frame + num_frames > pkt->frames);
for (f = first_frame; f < first_frame + num_frames; f++)
@@ -745,6 +749,12 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
}
spin_unlock(&pkt->lock);
+ if (pkt->cache_valid) {
+ VPRINTK("pkt_gather_data: zone %llx cached\n",
+ (unsigned long long)pkt->sector);
+ goto out_account;
+ }
+
/*
* Schedule reads for missing parts of the packet.
*/
@@ -778,7 +788,6 @@ out_account:
frames_read, (unsigned long long)pkt->sector);
pd->stats.pkt_started++;
pd->stats.secs_rg += frames_read * (CD_FRAMESIZE >> 9);
- pd->stats.secs_w += pd->settings.size;
}
/*
@@ -794,10 +803,11 @@ static struct packet_data *pkt_get_packet_data(struct pktcdvd_device *pd, int zo
list_del_init(&pkt->list);
if (pkt->sector != zone)
pkt->cache_valid = 0;
- break;
+ return pkt;
}
}
- return pkt;
+ BUG();
+ return NULL;
}
static void pkt_put_packet_data(struct pktcdvd_device *pd, struct packet_data *pkt)
@@ -941,12 +951,10 @@ try_next_bio:
}
pkt = pkt_get_packet_data(pd, zone);
- BUG_ON(!pkt);
pd->current_sector = zone + pd->settings.size;
pkt->sector = zone;
pkt->frames = pd->settings.size >> 2;
- BUG_ON(pkt->frames > PACKET_MAX_SIZE);
pkt->write_size = 0;
/*
@@ -1636,6 +1644,10 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
printk("pktcdvd: detected zero packet size!\n");
pd->settings.size = 128;
}
+ if (pd->settings.size > PACKET_MAX_SECTORS) {
+ printk("pktcdvd: packet size is too big\n");
+ return -ENXIO;
+ }
pd->settings.fp = ti.fp;
pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1);
@@ -2070,7 +2082,7 @@ static int pkt_close(struct inode *inode, struct file *file)
}
-static void *psd_pool_alloc(unsigned int __nocast gfp_mask, void *data)
+static void *psd_pool_alloc(gfp_t gfp_mask, void *data)
{
return kmalloc(sizeof(struct packet_stacked_data), gfp_mask);
}
@@ -2198,7 +2210,6 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
* No matching packet found. Store the bio in the work queue.
*/
node = mempool_alloc(pd->rb_pool, GFP_NOIO);
- BUG_ON(!node);
node->bio = bio;
spin_lock(&pd->lock);
BUG_ON(pd->bio_queue_size < 0);
@@ -2406,7 +2417,6 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode));
- BUG_ON(!pd);
switch (cmd) {
/*
@@ -2477,10 +2487,9 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
return -EBUSY;
}
- pd = kmalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
+ pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
if (!pd)
return ret;
- memset(pd, 0, sizeof(struct pktcdvd_device));
pd->rb_pool = mempool_create(PKT_RB_POOL_SIZE, pkt_rb_alloc, pkt_rb_free, NULL);
if (!pd->rb_pool)
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 29548784cb7b..29d1518be72a 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -99,8 +99,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
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/rd.c b/drivers/block/rd.c
index 145c1fbffe01..68c60a5bcdab 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -348,7 +348,7 @@ static int rd_open(struct inode *inode, struct file *filp)
struct block_device *bdev = inode->i_bdev;
struct address_space *mapping;
unsigned bsize;
- int gfp_mask;
+ gfp_t gfp_mask;
inode = igrab(bdev->bd_inode);
rd_bdev[unit] = bdev;
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
index abb2df249fd3..382dea7b224c 100644
--- a/drivers/block/scsi_ioctl.c
+++ b/drivers/block/scsi_ioctl.c
@@ -123,6 +123,7 @@ static int verify_command(struct file *file, unsigned char *cmd)
safe_for_read(READ_12),
safe_for_read(READ_16),
safe_for_read(READ_BUFFER),
+ safe_for_read(READ_DEFECT_DATA),
safe_for_read(READ_LONG),
safe_for_read(INQUIRY),
safe_for_read(MODE_SENSE),
@@ -167,6 +168,7 @@ static int verify_command(struct file *file, unsigned char *cmd)
safe_for_write(WRITE_VERIFY_12),
safe_for_write(WRITE_16),
safe_for_write(WRITE_LONG),
+ safe_for_write(WRITE_LONG_2),
safe_for_write(ERASE),
safe_for_write(GPCMD_MODE_SELECT_10),
safe_for_write(MODE_SELECT),
@@ -199,15 +201,15 @@ static int verify_command(struct file *file, unsigned char *cmd)
return 0;
}
+ /* And root can do any command.. */
+ if (capable(CAP_SYS_RAWIO))
+ return 0;
+
if (!type) {
cmd_type[cmd[0]] = CMD_WARNED;
printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]);
}
- /* And root can do any command.. */
- if (capable(CAP_SYS_RAWIO))
- return 0;
-
/* Otherwise fail it with an "Operation not permitted" */
return -EPERM;
}
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index e5f7494c00ee..e425ad3eebba 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -834,8 +834,7 @@ static int fd_eject(struct floppy_state *fs)
break;
}
swim3_select(fs, RELAX);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (swim3_readbit(fs, DISK_IN) == 0)
break;
}
@@ -906,8 +905,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
break;
}
swim3_select(fs, RELAX);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
|| swim3_readbit(fs, DISK_IN) == 0))
@@ -992,8 +990,7 @@ static int floppy_revalidate(struct gendisk *disk)
if (signal_pending(current))
break;
swim3_select(fs, RELAX);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
ret = swim3_readbit(fs, SEEK_COMPLETE) == 0
|| swim3_readbit(fs, DISK_IN) == 0;
diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
index a1283f6dc018..89e3c2f8b776 100644
--- a/drivers/block/swim_iop.c
+++ b/drivers/block/swim_iop.c
@@ -338,8 +338,7 @@ static int swimiop_eject(struct floppy_state *fs)
err = -EINTR;
break;
}
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
release_drive(fs);
return cmd->error;
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index d57007b92f77..1ded3b433459 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1,7 +1,7 @@
/*
* sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
*
- * Copyright 2004 Red Hat, Inc.
+ * Copyright 2004-2005 Red Hat, Inc.
*
* Author/maintainer: Jeff Garzik <jgarzik@pobox.com>
*
@@ -31,10 +31,6 @@
#include <asm/semaphore.h>
#include <asm/uaccess.h>
-MODULE_AUTHOR("Jeff Garzik");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Promise SATA SX8 block driver");
-
#if 0
#define CARM_DEBUG
#define CARM_VERBOSE_DEBUG
@@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 block driver");
#undef CARM_NDEBUG
#define DRV_NAME "sx8"
-#define DRV_VERSION "0.8"
+#define DRV_VERSION "1.0"
#define PFX DRV_NAME ": "
+MODULE_AUTHOR("Jeff Garzik");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Promise SATA SX8 block driver");
+MODULE_VERSION(DRV_VERSION);
+
+/*
+ * SX8 hardware has a single message queue for all ATA ports.
+ * When this driver was written, the hardware (firmware?) would
+ * corrupt data eventually, if more than one request was outstanding.
+ * As one can imagine, having 8 ports bottlenecking on a single
+ * command hurts performance.
+ *
+ * Based on user reports, later versions of the hardware (firmware?)
+ * seem to be able to survive with more than one command queued.
+ *
+ * Therefore, we default to the safe option -- 1 command -- but
+ * allow the user to increase this.
+ *
+ * SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ),
+ * but problems seem to occur when you exceed ~30, even on newer hardware.
+ */
+static int max_queue = 1;
+module_param(max_queue, int, 0444);
+MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30, safe==1)");
+
+
#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN)
/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
@@ -90,12 +112,10 @@ enum {
/* command message queue limits */
CARM_MAX_REQ = 64, /* max command msgs per host */
- CARM_MAX_Q = 1, /* one command at a time */
CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */
/* S/G limits, host-wide and per-request */
CARM_MAX_REQ_SG = 32, /* max s/g entries per request */
- CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */
CARM_MAX_HOST_SG = 600, /* max s/g entries per host */
CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */
@@ -181,6 +201,10 @@ enum {
FL_DYN_MAJOR = (1 << 17),
};
+enum {
+ CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */
+};
+
enum scatter_gather_types {
SGT_32BIT = 0,
SGT_64BIT = 1,
@@ -218,7 +242,6 @@ static const char *state_name[] = {
struct carm_port {
unsigned int port_no;
- unsigned int n_queued;
struct gendisk *disk;
struct carm_host *host;
@@ -448,7 +471,7 @@ static inline int carm_lookup_bucket(u32 msg_size)
for (i = 0; i < ARRAY_SIZE(msg_sizes); i++)
if (msg_size <= msg_sizes[i])
return i;
-
+
return -ENOENT;
}
@@ -509,7 +532,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG))
return NULL;
- for (i = 0; i < CARM_MAX_Q; i++)
+ for (i = 0; i < max_queue; i++)
if ((host->msg_alloc & (1ULL << i)) == 0) {
struct carm_request *crq = &host->req[i];
crq->port = NULL;
@@ -521,14 +544,14 @@ static struct carm_request *carm_get_request(struct carm_host *host)
assert(host->n_msgs <= CARM_MAX_REQ);
return crq;
}
-
+
DPRINTK("no request available, returning NULL\n");
return NULL;
}
static int carm_put_request(struct carm_host *host, struct carm_request *crq)
{
- assert(crq->tag < CARM_MAX_Q);
+ assert(crq->tag < max_queue);
if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0))
return -EINVAL; /* tried to clear a tag that was not active */
@@ -791,7 +814,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
int is_ok)
{
carm_end_request_queued(host, crq, is_ok);
- if (CARM_MAX_Q == 1)
+ if (max_queue == 1)
carm_round_robin(host);
else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
(host->hw_sg_used <= CARM_SG_LOW_WATER)) {
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index a026567f5d18..ed4d5006fe62 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 9 /* cdrecord requires 32KB and maybe a header */
#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[6];
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,14 @@ 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 .. %d\n",
+ sc->sg_stat[0],
+ sc->sg_stat[1],
+ sc->sg_stat[2],
+ sc->sg_stat[3],
+ sc->sg_stat[4],
+ sc->sg_stat[5]);
list_for_each (p, &sc->luns) {
lun = list_entry(p, struct ub_lun, link);
@@ -744,20 +753,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 +783,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 +799,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 +812,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 < 5 ? n_elem : 5]++;
/*
* build the command
@@ -876,30 +857,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 +874,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;
+ }
+ if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
+ printk(KERN_WARNING "%s: request with %d segments\n",
+ sc->name, n_elem);
+ return -1;
}
- cmd->data = rq->data;
+ cmd->nsg = n_elem;
+ sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
+
+ memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
+ cmd->cdb_len = rq->cmd_len;
+
cmd->len = rq->data_len;
return 0;
@@ -919,24 +906,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 +1011,6 @@ 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;
/* Fill what we shouldn't be filling, because usb-storage did so. */
sc->work_urb.actual_length = 0;
@@ -1023,7 +1019,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
/* XXX Clear stalls */
- printk("ub: cmd #%d start failed (%d)\n", cmd->tag, rc); /* P3 */
ub_complete(&sc->work_done);
return rc;
}
@@ -1103,7 +1098,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)) {
@@ -1195,47 +1189,20 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
if (urb->status != 0) {
- printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */
goto Bad_End;
}
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
- printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */
/* XXX Must do reset here to unconfuse the device */
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 +1224,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 +1374,44 @@ 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.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 */
+ 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 +1437,6 @@ 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.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
@@ -1484,6 +1494,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 +1503,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 +1557,6 @@ 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.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
@@ -1560,7 +1575,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 +1867,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 +1888,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;
@@ -1973,17 +1993,16 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,
(unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);
- 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_KERNEL)) != 0) {
if (rc == -EPIPE) {
- printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
+ printk("%s: Stall submitting GetMaxLUN, using 1 LUN\n",
sc->name); /* P3 */
} else {
- printk(KERN_WARNING
+ printk(KERN_NOTICE
"%s: Unable to submit GetMaxLUN (%d)\n",
sc->name, rc);
}
@@ -2001,6 +2020,18 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
del_timer_sync(&timer);
usb_kill_urb(&sc->work_urb);
+ if ((rc = sc->work_urb.status) < 0) {
+ if (rc == -EPIPE) {
+ printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
+ sc->name); /* P3 */
+ } else {
+ printk(KERN_NOTICE
+ "%s: Error at GetMaxLUN (%d)\n",
+ sc->name, rc);
+ }
+ goto err_io;
+ }
+
if (sc->work_urb.actual_length != 1) {
printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
sc->work_urb.actual_length); /* P3 */
@@ -2021,6 +2052,7 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
kfree(p);
return nluns;
+err_io:
err_submit:
kfree(p);
err_alloc:
@@ -2053,7 +2085,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
(unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
- sc->work_urb.transfer_flags = 0;
sc->work_urb.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
@@ -2186,8 +2217,10 @@ static int ub_probe(struct usb_interface *intf,
* This is needed to clear toggles. It is a problem only if we do
* `rmmod ub && modprobe ub` without disconnects, but we like that.
*/
+#if 0 /* iPod Mini fails if we do this (big white iPod works) */
ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
ub_probe_clear_stall(sc, sc->send_bulk_pipe);
+#endif
/*
* The way this is used by the startup code is a little specific.
@@ -2214,10 +2247,10 @@ static int ub_probe(struct usb_interface *intf,
for (i = 0; i < 3; i++) {
if ((rc = ub_sync_getmaxlun(sc)) < 0) {
/*
- * Some devices (i.e. Iomega Zip100) need this --
- * apparently the bulk pipes get STALLed when the
- * GetMaxLUN request is processed.
- * XXX I have a ZIP-100, verify it does this.
+ * This segment is taken from usb-storage. They say
+ * that ZIP-100 needs this, but my own ZIP-100 works
+ * fine without this.
+ * Still, it does not seem to hurt anything.
*/
if (rc == -EPIPE) {
ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
@@ -2286,10 +2319,10 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
disk->fops = &ub_bd_fops;
disk->private_data = lun;
- disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */
+ disk->driverfs_dev = &sc->intf->dev;
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;
@@ -2439,9 +2472,6 @@ static int __init ub_init(void)
{
int rc;
- /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n",
- sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun));
-
if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
goto err_regblkdev;
devfs_mk_dir(DEVFS_NAME);
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 0c4c121d2e79..0f48301342da 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -34,6 +34,7 @@
* - set initialised bit then.
*/
+//#define DEBUG /* uncomment if you want debugging info (pr_debug) */
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/fs.h>
@@ -58,10 +59,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#define PRINTK(x...) do {} while (0)
-#define dprintk(x...) do {} while (0)
-/*#define dprintk(x...) printk(x) */
-
#define MM_MAXCARDS 4
#define MM_RAHEAD 2 /* two sectors */
#define MM_BLKSIZE 1024 /* 1k blocks */
@@ -299,7 +296,7 @@ static void mm_start_io(struct cardinfo *card)
/* make the last descriptor end the chain */
page = &card->mm_pages[card->Active];
- PRINTK("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1);
+ pr_debug("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1);
desc = &page->desc[page->cnt-1];
desc->control_bits |= cpu_to_le32(DMASCR_CHAIN_COMP_EN);
@@ -532,7 +529,7 @@ static void process_page(unsigned long data)
activate(card);
} else {
/* haven't finished with this one yet */
- PRINTK("do some more\n");
+ pr_debug("do some more\n");
mm_start_io(card);
}
out_unlock:
@@ -555,7 +552,7 @@ static void process_page(unsigned long data)
static int mm_make_request(request_queue_t *q, struct bio *bio)
{
struct cardinfo *card = q->queuedata;
- PRINTK("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size);
+ pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size);
bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/
spin_lock_irq(&card->lock);
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 1676033da6c6..68b6d7b154cf 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -47,6 +47,7 @@
#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
+#include <linux/delay.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -62,7 +63,7 @@ static int xd[5] = { -1,-1,-1,-1, };
#define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
"nodma" module option */
-#define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */
+#define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
/* Above may need to be increased if a problem with the 2nd drive detection
(ST11M controller) or resetting a controller (WD) appears */
@@ -529,10 +530,8 @@ static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long t
int success;
xdc_busy = 1;
- while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry))
+ schedule_timeout_uninterruptible(1);
xdc_busy = 0;
return (success);
}
@@ -633,14 +632,12 @@ static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
for (i = 0; i < XD_MAXDRIVES; i++) {
xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep_interruptible(XD_INIT_DISK_DELAY);
init_drive(count);
count++;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep_interruptible(XD_INIT_DISK_DELAY);
}
}
return (count);
@@ -761,8 +758,7 @@ static void __init xd_wd_init_controller (unsigned int address)
outb(0,XD_RESET); /* reset the controller */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep(XD_INIT_DISK_DELAY);
}
static void __init xd_wd_init_drive (u_char drive)
@@ -936,8 +932,7 @@ If you need non-standard settings use the xd=... command */
xd_maxsectors = 0x01;
outb(0,XD_RESET); /* reset the controller */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep(XD_INIT_DISK_DELAY);
}
static void __init xd_xebec_init_drive (u_char drive)
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 007f6a662439..bb5e8d665a2a 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -296,7 +296,7 @@ z2_open( struct inode *inode, struct file *filp )
return 0;
err_out_kfree:
- kfree( z2ram_map );
+ kfree(z2ram_map);
err_out:
return rc;
}
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index a1bf8f066c88..4fa85234d8b5 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -308,7 +308,7 @@ unlock:
}
static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe,
- size_t size, unsigned int __nocast flags, void *data)
+ size_t size, gfp_t flags, void *data)
{
struct urb *urb;
struct usb_ctrlrequest *cr;
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 67d96b5cbb96..6756cb20b753 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,13 +65,15 @@
#endif
static int ignore = 0;
+static int ignore_csr = 0;
+static int ignore_sniffer = 0;
static int reset = 0;
#ifdef CONFIG_BT_HCIUSB_SCO
static int isoc = 2;
#endif
-#define VERSION "2.8"
+#define VERSION "2.9"
static struct usb_driver hci_usb_driver;
@@ -98,6 +100,9 @@ static struct usb_device_id bluetooth_ids[] = {
MODULE_DEVICE_TABLE (usb, bluetooth_ids);
static struct usb_device_id blacklist_ids[] = {
+ /* CSR BlueCore devices */
+ { USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },
+
/* Broadcom BCM2033 without firmware */
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
@@ -127,7 +132,7 @@ static struct usb_device_id blacklist_ids[] = {
{ } /* Terminating entry */
};
-static struct _urb *_urb_alloc(int isoc, unsigned int __nocast gfp)
+static struct _urb *_urb_alloc(int isoc, gfp_t gfp)
{
struct _urb *_urb = kmalloc(sizeof(struct _urb) +
sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
@@ -836,6 +841,12 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
if (ignore || id->driver_info & HCI_IGNORE)
return -ENODEV;
+ if (ignore_csr && id->driver_info & HCI_CSR)
+ return -ENODEV;
+
+ if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
+ return -ENODEV;
+
if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
return -ENODEV;
@@ -1061,6 +1072,12 @@ module_exit(hci_usb_exit);
module_param(ignore, bool, 0644);
MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+module_param(ignore_csr, bool, 0644);
+MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
+
+module_param(ignore_sniffer, bool, 0644);
+MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
+
module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
index 29936b43d4f8..37100a6ea1a8 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -31,9 +31,10 @@
#define HCI_IGNORE 0x01
#define HCI_RESET 0x02
#define HCI_DIGIANSWER 0x04
-#define HCI_SNIFFER 0x08
-#define HCI_BROKEN_ISOC 0x10
+#define HCI_CSR 0x08
+#define HCI_SNIFFER 0x10
#define HCI_BCM92035 0x20
+#define HCI_BROKEN_ISOC 0x40
#define HCI_MAX_IFACE_NUM 3
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
index 43bf1e5dc38a..ce4a1ce59d6a 100644
--- a/drivers/cdrom/aztcd.c
+++ b/drivers/cdrom/aztcd.c
@@ -297,7 +297,7 @@ static char azt_auto_eject = AZT_AUTO_EJECT;
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 7eac10e63b23..ad5464ab99bc 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 351a01dd503a..0b0eab4f40fa 100644
--- a/drivers/cdrom/optcd.c
+++ b/drivers/cdrom/optcd.c
@@ -264,7 +264,7 @@ static inline int flag_low(int flag, unsigned long timeout)
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 452d34675159..466e9c2974bd 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
/*==========================================================================*/
/*
@@ -830,8 +827,7 @@ static void mark_timeout_audio(u_long i)
static void sbp_sleep(u_int time)
{
sti();
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(time);
+ schedule_timeout_interruptible(time);
sti();
}
/*==========================================================================*/
@@ -4219,7 +4215,8 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
- if (current_drive->sbp_audsiz>0) vfree(current_drive->aud_buf);
+ if (current_drive->sbp_audsiz>0)
+ vfree(current_drive->aud_buf);
current_drive->aud_buf=NULL;
current_drive->sbp_audsiz=arg;
@@ -5913,7 +5910,8 @@ static void sbpcd_exit(void)
put_disk(D_S[j].disk);
devfs_remove("sbp/c0t%d", j);
vfree(D_S[j].sbp_buf);
- if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
+ if (D_S[j].sbp_audsiz>0)
+ vfree(D_S[j].aud_buf);
if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
{
msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
index 4e7a342ec36f..74b1cadbf161 100644
--- a/drivers/cdrom/sjcd.c
+++ b/drivers/cdrom/sjcd.c
@@ -151,7 +151,7 @@ static struct sjcd_stat statistic;
/*
* 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/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
index 9f22e8f1f6c0..e65659926432 100644
--- a/drivers/cdrom/sonycd535.c
+++ b/drivers/cdrom/sonycd535.c
@@ -1478,8 +1478,7 @@ static int __init sony535_init(void)
/* look for the CD-ROM, follows the procedure in the DOS driver */
inb(select_unit_reg);
/* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout((HZ+17)*40/18);
+ schedule_timeout_interruptible((HZ+17)*40/18);
inb(result_reg);
outb(0, read_status_reg); /* does a reset? */
diff --git a/drivers/char/.gitignore b/drivers/char/.gitignore
new file mode 100644
index 000000000000..2b6b1d772ed7
--- /dev/null
+++ b/drivers/char/.gitignore
@@ -0,0 +1,3 @@
+consolemap_deftbl.c
+defkeymap.c
+
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 2bc9d64db106..c29365d5b524 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
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 59f589d733f9..0a7624a9b1c1 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -429,7 +429,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
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/backend.c b/drivers/char/agp/backend.c
index 4d4e602fdc7e..82b43c541c8d 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -206,10 +206,9 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
bridge->driver->cleanup();
if (bridge->driver->free_gatt_table)
bridge->driver->free_gatt_table(bridge);
- if (bridge->key_list) {
- vfree(bridge->key_list);
- bridge->key_list = NULL;
- }
+
+ vfree(bridge->key_list);
+ bridge->key_list = NULL;
if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page)
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index f0079e991bdc..ac9da0ca36b7 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -319,7 +319,6 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)
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/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 99762b6c19ae..de5d6d212674 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -252,7 +252,7 @@ hp_zx1_configure (void)
readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
readl(hp->ioc_regs+HP_ZX1_TCNFG);
- writel(~(HP_ZX1_IOVA_SIZE-1), hp->ioc_regs+HP_ZX1_IMASK);
+ writel((unsigned int)(~(HP_ZX1_IOVA_SIZE-1)), hp->ioc_regs+HP_ZX1_IMASK);
readl(hp->ioc_regs+HP_ZX1_IMASK);
writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
readl(hp->ioc_regs+HP_ZX1_IBASE);
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 2a36561eec68..a124f8c5d062 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -2053,10 +2053,6 @@ static int __init rs_init(void)
state->icount.rx = state->icount.tx = 0;
state->icount.frame = state->icount.parity = 0;
state->icount.overrun = state->icount.brk = 0;
- /*
- if(state->port && check_region(state->port,REGION_LENGTH(state)))
- continue;
- */
printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n",
state->line);
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 11f9ee581124..927a5bbe112c 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -172,7 +172,7 @@ static int ac_register_board(unsigned long physloc, void __iomem *loc,
void cleanup_module(void)
{
- int i;
+ unsigned int i;
misc_deregister(&ac_miscdev);
@@ -195,7 +195,7 @@ int __init applicom_init(void)
int i, numisa = 0;
struct pci_dev *dev = NULL;
void __iomem *RamIO;
- int boardno;
+ int boardno, ret;
printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n");
@@ -294,7 +294,8 @@ int __init applicom_init(void)
}
if (!numisa)
- printk(KERN_WARNING"ac.o: No valid ISA Applicom boards found at mem 0x%lx\n",mem);
+ printk(KERN_WARNING "ac.o: No valid ISA Applicom boards found "
+ "at mem 0x%lx\n", mem);
fin:
init_waitqueue_head(&FlagSleepRec);
@@ -304,7 +305,11 @@ int __init applicom_init(void)
DeviceErrorCount = 0;
if (numboards) {
- misc_register(&ac_miscdev);
+ ret = misc_register(&ac_miscdev);
+ if (ret) {
+ printk(KERN_WARNING "ac.o: Unable to register misc device\n");
+ goto out;
+ }
for (i = 0; i < MAX_BOARD; i++) {
int serial;
char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1];
@@ -337,6 +342,17 @@ int __init applicom_init(void)
else
return -ENXIO;
+
+out:
+ for (i = 0; i < MAX_BOARD; i++) {
+ if (!apbs[i].RamIO)
+ continue;
+ if (apbs[i].irq)
+ free_irq(apbs[i].irq, &dummy);
+ iounmap(apbs[i].RamIO);
+ }
+ pci_disable_device(dev);
+ return ret;
}
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a5337bf0936..cf4c3648463d 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -865,7 +865,7 @@ static void cyz_poll(unsigned long);
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 6f98701dfe15..121cc85f347e 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -1071,5 +1071,9 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
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/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 6ba48f346fcf..041bb47b5c39 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -376,7 +376,7 @@ static int __init drm_core_init(void)
goto err_p2;
}
- drm_proc_root = create_proc_entry("dri", S_IFDIR, NULL);
+ drm_proc_root = proc_mkdir("dri", NULL);
if (!drm_proc_root) {
DRM_ERROR("Cannot create /proc/dri\n");
ret = -1;
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 32d2bb99462c..977961002488 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -95,7 +95,7 @@ int drm_proc_init(drm_device_t *dev, int minor,
char name[64];
sprintf(name, "%d", minor);
- *dev_root = create_proc_entry(name, S_IFDIR, root);
+ *dev_root = proc_mkdir(name, root);
if (!*dev_root) {
DRM_ERROR("Cannot create /proc/dri/%s\n", name);
return -1;
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 95a976c96eb8..70458cb061c6 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -47,7 +47,7 @@ MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
MODULE_PARM_DESC(debug, "Enable debug output");
module_param_named(cards_limit, drm_cards_limit, int, 0444);
-module_param_named(debug, drm_debug, int, 0666);
+module_param_named(debug, drm_debug, int, 0600);
drm_head_t **drm_heads;
struct drm_sysfs_class *drm_class;
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index ced4215e2275..39ea96e42c5b 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -148,7 +148,8 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
- page = vmalloc_to_page((void *)i);
+ page = (map->type == _DRM_CONSISTENT) ?
+ virt_to_page((void *)i) : vmalloc_to_page((void *)i);
if (!page)
return NOPAGE_OOM;
get_page(page);
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index fc7d4a594bca..c8e1b6c83636 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -437,7 +437,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
- const unsigned int warp_size = mga_warp_microcode_size(dev_priv);
+ unsigned int warp_size = mga_warp_microcode_size(dev_priv);
int err;
unsigned offset;
const unsigned secondary_size = dma_bs->secondary_bin_count
@@ -499,6 +499,12 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
return err;
}
+ /* Make drm_addbufs happy by not trying to create a mapping for less
+ * than a page.
+ */
+ if (warp_size < PAGE_SIZE)
+ warp_size = PAGE_SIZE;
+
offset = 0;
err = drm_addmap( dev, offset, warp_size,
_DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp );
@@ -587,7 +593,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
- const unsigned int warp_size = mga_warp_microcode_size(dev_priv);
+ unsigned int warp_size = mga_warp_microcode_size(dev_priv);
unsigned int primary_size;
unsigned int bin_count;
int err;
@@ -599,6 +605,12 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
return DRM_ERR(EFAULT);
}
+ /* Make drm_addbufs happy by not trying to create a mapping for less
+ * than a page.
+ */
+ if (warp_size < PAGE_SIZE)
+ warp_size = PAGE_SIZE;
+
/* The proper alignment is 0x100 for this mapping */
err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
_DRM_READ_ONLY, &dev_priv->warp);
@@ -812,6 +824,10 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
}
if (! dev_priv->used_new_dma_init) {
+
+ dev_priv->dma_access = MGA_PAGPXFER;
+ dev_priv->wagp_enable = MGA_WAGP_ENABLE;
+
dev_priv->status = drm_core_findmap(dev, init->status_offset);
if (!dev_priv->status) {
DRM_ERROR("failed to find status page!\n");
@@ -928,7 +944,7 @@ static int mga_do_cleanup_dma( drm_device_t *dev )
drm_mga_private_t *dev_priv = dev->dev_private;
if ((dev_priv->warp != NULL)
- && (dev_priv->mmio->type != _DRM_CONSISTENT))
+ && (dev_priv->warp->type != _DRM_CONSISTENT))
drm_core_ioremapfree(dev_priv->warp, dev);
if ((dev_priv->primary != NULL)
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index b22fdbd4f830..6059c5a5b105 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -227,7 +227,7 @@ static inline u32 _MGA_READ(u32 *addr)
#define MGA_EMIT_STATE( dev_priv, dirty ) \
do { \
if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \
- if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { \
+ if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) { \
mga_g400_emit_state( dev_priv ); \
} else { \
mga_g200_emit_state( dev_priv ); \
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
index 05bbb4719376..6ac5e006226f 100644
--- a/drivers/char/drm/mga_state.c
+++ b/drivers/char/drm/mga_state.c
@@ -53,7 +53,7 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
/* Force reset of DWGCTL on G400 (eliminates clip disable bit).
*/
- if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
+ if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl,
MGA_LEN + MGA_EXEC, 0x80000000,
MGA_DWGCTL, ctx->dwgctl,
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 6d9080a3ca7e..12ef13ff04ca 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1133,10 +1133,10 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
ring_start = (dev_priv->cp_ring->offset
- dev->agp->base
+ dev_priv->gart_vm_start);
- } else
+ } else
#endif
ring_start = (dev_priv->cp_ring->offset
- - dev->sg->handle
+ - (unsigned long)dev->sg->virtual
+ dev_priv->gart_vm_start);
RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
@@ -1164,7 +1164,8 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
drm_sg_mem_t *entry = dev->sg;
unsigned long tmp_ofs, page_ofs;
- tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
+ tmp_ofs = dev_priv->ring_rptr->offset -
+ (unsigned long)dev->sg->virtual;
page_ofs = tmp_ofs >> PAGE_SHIFT;
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
@@ -1491,8 +1492,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
else
#endif
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- - dev->sg->handle
- + dev_priv->gart_vm_start);
+ - (unsigned long)dev->sg->virtual
+ + dev_priv->gart_vm_start);
DRM_DEBUG( "dev_priv->gart_size %d\n",
dev_priv->gart_size );
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 58d3738a2b7f..407708a001e4 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -534,7 +534,7 @@ static void shutdown(struct channel *ch)
unsigned long flags;
struct tty_struct *tty;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
if (!(ch->asyncflags & ASYNC_INITIALIZED))
return;
@@ -618,7 +618,7 @@ static int pc_write(struct tty_struct * tty,
struct channel *ch;
unsigned long flags;
int remain;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
/* ----------------------------------------------------------------
pc_write is primarily called directly by the kernel routine
@@ -685,7 +685,7 @@ static int pc_write(struct tty_struct * tty,
------------------------------------------------------------------- */
dataLen = min(bytesAvailable, dataLen);
- memcpy(ch->txptr + head, buf, dataLen);
+ memcpy_toio(ch->txptr + head, buf, dataLen);
buf += dataLen;
head += dataLen;
amountCopied += dataLen;
@@ -726,7 +726,7 @@ static int pc_write_room(struct tty_struct *tty)
struct channel *ch;
unsigned long flags;
unsigned int head, tail;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
remain = 0;
@@ -773,7 +773,7 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
int remain;
unsigned long flags;
struct channel *ch;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
/* ---------------------------------------------------------
verifyChannel returns the channel from the tty struct
@@ -830,7 +830,7 @@ static void pc_flush_buffer(struct tty_struct *tty)
unsigned int tail;
unsigned long flags;
struct channel *ch;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
/* ---------------------------------------------------------
verifyChannel returns the channel from the tty struct
if it is valid. This serves as a sanity check.
@@ -976,7 +976,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
struct channel *ch;
unsigned long flags;
int line, retval, boardnum;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
unsigned int head;
line = tty->index;
@@ -1041,7 +1041,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
ch->statusflags = 0;
/* Save boards current modem status */
- ch->imodem = bc->mstat;
+ ch->imodem = readb(&bc->mstat);
/* ----------------------------------------------------------------
Set receive head and tail ptrs to each other. This indicates
@@ -1399,10 +1399,10 @@ static void post_fep_init(unsigned int crd)
{ /* Begin post_fep_init */
int i;
- unsigned char *memaddr;
- struct global_data *gd;
+ void __iomem *memaddr;
+ struct global_data __iomem *gd;
struct board_info *bd;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
struct channel *ch;
int shrinkmem = 0, lowwater ;
@@ -1461,7 +1461,7 @@ static void post_fep_init(unsigned int crd)
8 and 64 of these structures.
-------------------------------------------------------------------- */
- bc = (struct board_chan *)(memaddr + CHANSTRUCT);
+ bc = memaddr + CHANSTRUCT;
/* -------------------------------------------------------------------
The below assignment will set gd to point at the BEGINING of
@@ -1470,7 +1470,7 @@ static void post_fep_init(unsigned int crd)
pointer begins at 0xd10.
---------------------------------------------------------------------- */
- gd = (struct global_data *)(memaddr + GLOBAL);
+ gd = memaddr + GLOBAL;
/* --------------------------------------------------------------------
XEPORTS (address 0xc22) points at the number of channels the
@@ -1493,6 +1493,7 @@ static void post_fep_init(unsigned int crd)
for (i = 0; i < bd->numports; i++, ch++, bc++) { /* Begin for each port */
unsigned long flags;
+ u16 tseg, rseg;
ch->brdchan = bc;
ch->mailbox = gd;
@@ -1553,50 +1554,53 @@ static void post_fep_init(unsigned int crd)
shrinkmem = 0;
}
+ tseg = readw(&bc->tseg);
+ rseg = readw(&bc->rseg);
+
switch (bd->type) {
case PCIXEM:
case PCIXRJ:
case PCIXR:
/* Cover all the 2MEG cards */
- ch->txptr = memaddr + (((bc->tseg) << 4) & 0x1fffff);
- ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x1fffff);
- ch->txwin = FEPWIN | ((bc->tseg) >> 11);
- ch->rxwin = FEPWIN | ((bc->rseg) >> 11);
+ ch->txptr = memaddr + ((tseg << 4) & 0x1fffff);
+ ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff);
+ ch->txwin = FEPWIN | (tseg >> 11);
+ ch->rxwin = FEPWIN | (rseg >> 11);
break;
case PCXEM:
case EISAXEM:
/* Cover all the 32K windowed cards */
/* Mask equal to window size - 1 */
- ch->txptr = memaddr + (((bc->tseg) << 4) & 0x7fff);
- ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x7fff);
- ch->txwin = FEPWIN | ((bc->tseg) >> 11);
- ch->rxwin = FEPWIN | ((bc->rseg) >> 11);
+ ch->txptr = memaddr + ((tseg << 4) & 0x7fff);
+ ch->rxptr = memaddr + ((rseg << 4) & 0x7fff);
+ ch->txwin = FEPWIN | (tseg >> 11);
+ ch->rxwin = FEPWIN | (rseg >> 11);
break;
case PCXEVE:
case PCXE:
- ch->txptr = memaddr + (((bc->tseg - bd->memory_seg) << 4) & 0x1fff);
- ch->txwin = FEPWIN | ((bc->tseg - bd->memory_seg) >> 9);
- ch->rxptr = memaddr + (((bc->rseg - bd->memory_seg) << 4) & 0x1fff);
- ch->rxwin = FEPWIN | ((bc->rseg - bd->memory_seg) >>9 );
+ ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff);
+ ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
+ ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff);
+ ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 );
break;
case PCXI:
case PC64XE:
- ch->txptr = memaddr + ((bc->tseg - bd->memory_seg) << 4);
- ch->rxptr = memaddr + ((bc->rseg - bd->memory_seg) << 4);
+ ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4);
+ ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4);
ch->txwin = ch->rxwin = 0;
break;
} /* End switch bd->type */
ch->txbufhead = 0;
- ch->txbufsize = bc->tmax + 1;
+ ch->txbufsize = readw(&bc->tmax) + 1;
ch->rxbufhead = 0;
- ch->rxbufsize = bc->rmax + 1;
+ ch->rxbufsize = readw(&bc->rmax) + 1;
lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);
@@ -1718,11 +1722,11 @@ static void epcapoll(unsigned long ignored)
static void doevent(int crd)
{ /* Begin doevent */
- void *eventbuf;
+ void __iomem *eventbuf;
struct channel *ch, *chan0;
static struct tty_struct *tty;
struct board_info *bd;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
unsigned int tail, head;
int event, channel;
int mstat, lstat;
@@ -1817,7 +1821,7 @@ static void doevent(int crd)
static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
int byte2, int ncmds, int bytecmd)
{ /* Begin fepcmd */
- unchar *memaddr;
+ unchar __iomem *memaddr;
unsigned int head, cmdTail, cmdStart, cmdMax;
long count;
int n;
@@ -2000,7 +2004,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
unsigned int cmdHead;
struct termios *ts;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
unsigned mval, hflow, cflag, iflag;
bc = ch->brdchan;
@@ -2010,7 +2014,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
ts = tty->termios;
if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */
cmdHead = readw(&bc->rin);
- bc->rout = cmdHead;
+ writew(cmdHead, &bc->rout);
cmdHead = readw(&bc->tin);
/* Changing baud in mid-stream transmission can be wonderful */
/* ---------------------------------------------------------------
@@ -2116,7 +2120,7 @@ static void receive_data(struct channel *ch)
unchar *rptr;
struct termios *ts = NULL;
struct tty_struct *tty;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
int dataToRead, wrapgap, bytesAvailable;
unsigned int tail, head;
unsigned int wrapmask;
@@ -2154,7 +2158,7 @@ static void receive_data(struct channel *ch)
--------------------------------------------------------------------- */
if (!tty || !ts || !(ts->c_cflag & CREAD)) {
- bc->rout = head;
+ writew(head, &bc->rout);
return;
}
@@ -2270,7 +2274,7 @@ static int info_ioctl(struct tty_struct *tty, struct file * file,
static int pc_tiocmget(struct tty_struct *tty, struct file *file)
{
struct channel *ch = (struct channel *) tty->driver_data;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
unsigned int mstat, mflag = 0;
unsigned long flags;
@@ -2351,7 +2355,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
unsigned long flags;
unsigned int mflag, mstat;
unsigned char startc, stopc;
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
struct channel *ch = (struct channel *) tty->driver_data;
void __user *argp = (void __user *)arg;
@@ -2633,7 +2637,7 @@ static void pc_start(struct tty_struct *tty)
spin_lock_irqsave(&epca_lock, flags);
/* Just in case output was resumed because of a change in Digi-flow */
if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */
- struct board_chan *bc;
+ struct board_chan __iomem *bc;
globalwinon(ch);
bc = ch->brdchan;
if (ch->statusflags & LOWWAIT)
@@ -2727,7 +2731,7 @@ void digi_send_break(struct channel *ch, int msec)
static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
{ /* Begin setup_empty_event */
- struct board_chan *bc = ch->brdchan;
+ struct board_chan __iomem *bc = ch->brdchan;
globalwinon(ch);
ch->statusflags |= EMPTYWAIT;
diff --git a/drivers/char/epca.h b/drivers/char/epca.h
index 20eeb5a70e1a..456d6c8f94a8 100644
--- a/drivers/char/epca.h
+++ b/drivers/char/epca.h
@@ -128,17 +128,17 @@ struct channel
unsigned long c_cflag;
unsigned long c_lflag;
unsigned long c_oflag;
- unsigned char *txptr;
- unsigned char *rxptr;
+ unsigned char __iomem *txptr;
+ unsigned char __iomem *rxptr;
unsigned char *tmp_buf;
struct board_info *board;
- struct board_chan *brdchan;
+ struct board_chan __iomem *brdchan;
struct digi_struct digiext;
struct tty_struct *tty;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
struct work_struct tqueue;
- struct global_data *mailbox;
+ struct global_data __iomem *mailbox;
};
struct board_info
@@ -149,8 +149,8 @@ struct board_info
unsigned short numports;
unsigned long port;
unsigned long membase;
- unsigned char __iomem *re_map_port;
- unsigned char *re_map_membase;
+ void __iomem *re_map_port;
+ void __iomem *re_map_membase;
unsigned long memory_seg;
void ( * memwinon ) (struct board_info *, unsigned int) ;
void ( * memwinoff ) (struct board_info *, unsigned int) ;
diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
index 1704a2a57048..b2e0928e8428 100644
--- a/drivers/char/ftape/lowlevel/fdc-io.c
+++ b/drivers/char/ftape/lowlevel/fdc-io.c
@@ -387,10 +387,8 @@ int fdc_interrupt_wait(unsigned int time)
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&ftape_wait_intr, &wait);
- while (!ft_interrupt_seen && timeout) {
- set_current_state(TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- }
+ while (!ft_interrupt_seen && timeout)
+ timeout = schedule_timeout_interruptible(timeout);
spin_lock_irq(&current->sighand->siglock);
current->blocked = old_sigmask;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 81d811edf3c5..a54bc93353af 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -149,8 +149,7 @@ static unsigned long long hangcheck_tsc, hangcheck_tsc_margin;
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/hpet.c b/drivers/char/hpet.c
index a695f25e4497..c055bb630ffc 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -100,14 +100,14 @@ static struct hpets *hpets;
#endif
#ifndef readq
-static unsigned long long __inline readq(void __iomem *addr)
+static inline unsigned long long readq(void __iomem *addr)
{
return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL);
}
#endif
#ifndef writeq
-static void __inline writeq(unsigned long long v, void __iomem *addr)
+static inline void writeq(unsigned long long v, void __iomem *addr)
{
writel(v & 0xffffffff, addr);
writel(v >> 32, addr + 4);
@@ -273,7 +273,6 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_flags |= VM_IO;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- addr = __pa(addr);
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
@@ -906,11 +905,15 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
if (irqp->number_of_interrupts > 0) {
hdp->hd_nirqs = irqp->number_of_interrupts;
- for (i = 0; i < hdp->hd_nirqs; i++)
- hdp->hd_irq[i] =
+ for (i = 0; i < hdp->hd_nirqs; i++) {
+ int rc =
acpi_register_gsi(irqp->interrupts[i],
irqp->edge_level,
irqp->active_high_low);
+ if (rc < 0)
+ return AE_ERROR;
+ hdp->hd_irq[i] = rc;
+ }
}
}
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index cddb789902db..f92177634677 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -839,9 +839,6 @@ int __init hvc_init(void)
hvc_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(hvc_driver, &hvc_ops);
- if (tty_register_driver(hvc_driver))
- panic("Couldn't register hvc console driver\n");
-
/* Always start the kthread because there can be hotplug vty adapters
* added later. */
hvc_task = kthread_run(khvcd, NULL, "khvcd");
@@ -851,6 +848,9 @@ int __init hvc_init(void)
return -EIO;
}
+ if (tty_register_driver(hvc_driver))
+ panic("Couldn't register hvc console driver\n");
+
return 0;
}
module_init(hvc_init);
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 3480535a09c5..6f673d2de0b1 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -513,10 +513,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
return ret ? : -EAGAIN;
if(need_resched())
- {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
+ schedule_timeout_interruptible(1);
else
udelay(200); /* FIXME: We could poll for 250uS ?? */
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 82c5f30375ac..ba85eb1b6ec7 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -655,8 +655,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
timeout--; // So negative values == forever
if (!in_interrupt()) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1); // short nap
+ schedule_timeout_interruptible(1); // short nap
} else {
// we cannot sched/sleep in interrrupt silly
return 0;
@@ -1132,8 +1131,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
ip2trace (CHANN, ITRC_OUTPUT, 61, 0 );
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(2);
+ schedule_timeout_interruptible(2);
if (signal_pending(current)) {
break;
}
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index cf0cd58d6305..9e4e26aef94e 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -120,7 +120,6 @@
#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 883ac4352be4..a09ff1080687 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -735,7 +735,8 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
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/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 463351d4f942..32fa82c78c73 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2620,7 +2620,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
if (!list_empty(&(intf->waiting_msgs))) {
list_add_tail(&(msg->link), &(intf->waiting_msgs));
- spin_unlock(&(intf->waiting_msgs_lock));
+ spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
goto out_unlock;
}
spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
@@ -2629,9 +2629,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
if (rv > 0) {
/* Could not handle the message now, just add it to a
list to handle later. */
- spin_lock(&(intf->waiting_msgs_lock));
+ spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
list_add_tail(&(msg->link), &(intf->waiting_msgs));
- spin_unlock(&(intf->waiting_msgs_lock));
+ spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
} else if (rv == 0) {
ipmi_free_smi_msg(msg);
}
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index e82a96ba396b..f66947722e12 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -55,7 +55,7 @@ extern void (*pm_power_off)(void);
static int poweroff_powercycle;
/* parameter definition to allow user to flag power cycle */
-module_param(poweroff_powercycle, int, 0);
+module_param(poweroff_powercycle, int, 0644);
MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
/* Stuff from the get device id command. */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 1abec687865c..b6e5cbfb09f8 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1019,7 +1019,7 @@ MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
#define IPMI_MEM_ADDR_SPACE 1
#define IPMI_IO_ADDR_SPACE 2
-#if defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
+#if defined(CONFIG_ACPI) || defined(CONFIG_X86) || defined(CONFIG_PCI)
static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
{
int i;
@@ -1395,7 +1395,7 @@ static int try_init_mem(int intf_num, struct smi_info **new_info)
}
-#ifdef CONFIG_ACPI_INTERPRETER
+#ifdef CONFIG_ACPI
#include <linux/acpi.h>
@@ -1517,6 +1517,9 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info)
char *io_type;
u8 addr_space;
+ if (acpi_disabled)
+ return -ENODEV;
+
if (acpi_failure)
return -ENODEV;
@@ -1917,8 +1920,7 @@ static int try_get_dev_id(struct smi_info *smi_info)
for (;;)
{
if (smi_result == SI_SM_CALL_WITH_DELAY) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
smi_result = smi_info->handlers->event(
smi_info->si_sm, 100);
}
@@ -2092,7 +2094,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
rv = try_init_mem(intf_num, &new_smi);
if (rv)
rv = try_init_port(intf_num, &new_smi);
-#ifdef CONFIG_ACPI_INTERPRETER
+#ifdef CONFIG_ACPI
if (rv && si_trydefaults)
rv = try_init_acpi(intf_num, &new_smi);
#endif
@@ -2253,10 +2255,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
/* Wait for the timer to stop. This avoids problems with race
conditions removing the timer here. */
- while (! new_smi->timer_stopped) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while (!new_smi->timer_stopped)
+ schedule_timeout_uninterruptible(1);
out_err:
if (new_smi->intf)
@@ -2376,17 +2376,14 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
/* Wait for the timer to stop. This avoids problems with race
conditions removing the timer here. */
- while (! to_clean->timer_stopped) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while (!to_clean->timer_stopped)
+ schedule_timeout_uninterruptible(1);
/* Interrupts and timeouts are stopped, now make sure the
interface is in a clean state. */
while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
poll(to_clean);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
rv = ipmi_unregister_smi(to_clean->intf);
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index e71aaae855ad..2da64bf7469c 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -1037,10 +1037,8 @@ static __exit void ipmi_unregister_watchdog(void)
/* Wait to make sure the message makes it out. The lower layer has
pointers to our buffers, we want to make sure they are done before
we release our memory. */
- while (atomic_read(&set_timeout_tofree)) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while (atomic_read(&set_timeout_tofree))
+ schedule_timeout_uninterruptible(1);
/* Disconnect from IPMI. */
rv = ipmi_destroy_user(watchdog_user);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 52a073eee201..9c19e5435a11 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -780,7 +780,7 @@ static struct file_operations stli_fsiomem = {
* 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 523fd3c8bbaa..449d029ad4f4 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -14,7 +14,7 @@
* `Sticky' modifier keys, 951006.
*
* 11-11-96: SAK should now work in the raw mode (Martin Mares)
- *
+ *
* Modified to provide 'generic' keyboard support by Hamish Macdonald
* Merge with the m68k keyboard driver and split-off of the PC low-level
* parts by Geert Uytterhoeven, May 1997
@@ -52,7 +52,7 @@ extern void ctrl_alt_del(void);
/*
* Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
* This seems a good reason to start with NumLock off. On HIL keyboards
- * of PARISC machines however there is no NumLock key and everyone expects the keypad
+ * of PARISC machines however there is no NumLock key and everyone expects the keypad
* to be used for numbers.
*/
@@ -76,17 +76,17 @@ void compute_shiftstate(void);
k_meta, k_ascii, k_lock, k_lowercase,\
k_slock, k_dead2, k_ignore, k_ignore
-typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
+typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
char up_flag, struct pt_regs *regs);
static k_handler_fn K_HANDLERS;
static k_handler_fn *k_handler[16] = { K_HANDLERS };
#define FN_HANDLERS\
- fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
- fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
- fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
- fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
- fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
+ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
+ fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
+ fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
+ fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
+ fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
static fn_handler_fn FN_HANDLERS;
@@ -159,13 +159,13 @@ static int sysrq_alt;
*/
int getkeycode(unsigned int scancode)
{
- struct list_head * node;
+ struct list_head *node;
struct input_dev *dev = NULL;
- list_for_each(node,&kbd_handler.h_list) {
- struct input_handle * handle = to_handle_h(node);
- if (handle->dev->keycodesize) {
- dev = handle->dev;
+ list_for_each(node, &kbd_handler.h_list) {
+ struct input_handle *handle = to_handle_h(node);
+ if (handle->dev->keycodesize) {
+ dev = handle->dev;
break;
}
}
@@ -181,15 +181,15 @@ int getkeycode(unsigned int scancode)
int setkeycode(unsigned int scancode, unsigned int keycode)
{
- struct list_head * node;
+ struct list_head *node;
struct input_dev *dev = NULL;
unsigned int i, oldkey;
- list_for_each(node,&kbd_handler.h_list) {
+ list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
- if (handle->dev->keycodesize) {
- dev = handle->dev;
- break;
+ if (handle->dev->keycodesize) {
+ dev = handle->dev;
+ break;
}
}
@@ -200,7 +200,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
return -EINVAL;
if (keycode < 0 || keycode > KEY_MAX)
return -EINVAL;
- if (keycode >> (dev->keycodesize * 8))
+ if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
return -EINVAL;
oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
@@ -216,11 +216,11 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
}
/*
- * Making beeps and bells.
+ * Making beeps and bells.
*/
static void kd_nosound(unsigned long ignored)
{
- struct list_head * node;
+ struct list_head *node;
list_for_each(node,&kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
@@ -233,17 +233,16 @@ 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)
{
- struct list_head * node;
+ struct list_head *node;
del_timer(&kd_mksound_timer);
if (hz) {
- list_for_each_prev(node,&kbd_handler.h_list) {
+ list_for_each_prev(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit)) {
@@ -338,19 +337,19 @@ static void to_utf8(struct vc_data *vc, ushort c)
if (c < 0x80)
/* 0******* */
put_queue(vc, c);
- else if (c < 0x800) {
+ else if (c < 0x800) {
/* 110***** 10****** */
- put_queue(vc, 0xc0 | (c >> 6));
+ put_queue(vc, 0xc0 | (c >> 6));
put_queue(vc, 0x80 | (c & 0x3f));
- } else {
+ } else {
/* 1110**** 10****** 10****** */
put_queue(vc, 0xe0 | (c >> 12));
put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
put_queue(vc, 0x80 | (c & 0x3f));
- }
+ }
}
-/*
+/*
* Called after returning from RAW mode or when changing consoles - recompute
* shift_down[] and shift_state from key_down[] maybe called when keymap is
* undefined, so that shiftkey release is seen
@@ -361,7 +360,7 @@ void compute_shiftstate(void)
shift_state = 0;
memset(shift_down, 0, sizeof(shift_down));
-
+
for (i = 0; i < ARRAY_SIZE(key_down); i++) {
if (!key_down[i])
@@ -500,9 +499,9 @@ static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
if (want_console != -1)
cur = want_console;
- for (i = cur-1; i != cur; i--) {
+ for (i = cur - 1; i != cur; i--) {
if (i == -1)
- i = MAX_NR_CONSOLES-1;
+ i = MAX_NR_CONSOLES - 1;
if (vc_cons_allocated(i))
break;
}
@@ -568,9 +567,9 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
{
- if (spawnpid)
- if(kill_proc(spawnpid, spawnsig, 1))
- spawnpid = 0;
+ if (spawnpid)
+ if (kill_proc(spawnpid, spawnsig, 1))
+ spawnpid = 0;
}
static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
@@ -604,8 +603,8 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct
return;
if (value >= ARRAY_SIZE(fn_handler))
return;
- if ((kbd->kbdmode == VC_RAW ||
- kbd->kbdmode == VC_MEDIUMRAW) &&
+ if ((kbd->kbdmode == VC_RAW ||
+ kbd->kbdmode == VC_MEDIUMRAW) &&
value != KVAL(K_SAK))
return; /* SAK is allowed even in raw mode */
fn_handler[value](vc, regs);
@@ -895,11 +894,11 @@ static inline unsigned char getleds(void)
static void kbd_bh(unsigned long dummy)
{
- struct list_head * node;
+ struct list_head *node;
unsigned char leds = getleds();
if (leds != ledstate) {
- list_for_each(node,&kbd_handler.h_list) {
+ list_for_each(node, &kbd_handler.h_list) {
struct input_handle * handle = to_handle_h(node);
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
@@ -964,11 +963,11 @@ static int sparc_l1_a_state = 0;
extern void sun_do_break(void);
#endif
-static int emulate_raw(struct vc_data *vc, unsigned int keycode,
+static int emulate_raw(struct vc_data *vc, unsigned int keycode,
unsigned char up_flag)
{
if (keycode > 255 || !x86_keycodes[keycode])
- return -1;
+ return -1;
switch (keycode) {
case KEY_PAUSE:
@@ -982,7 +981,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
case KEY_HANJA:
if (!up_flag) put_queue(vc, 0xf2);
return 0;
- }
+ }
if (keycode == KEY_SYSRQ && sysrq_alt) {
put_queue(vc, 0x54 | up_flag);
@@ -1105,11 +1104,12 @@ static void kbd_keycode(unsigned int keycode, int down,
else
clear_bit(keycode, key_down);
- if (rep && (!vc_kbd_mode(kbd, VC_REPEAT) || (tty &&
- (!L_ECHO(tty) && tty->driver->chars_in_buffer(tty))))) {
+ if (rep &&
+ (!vc_kbd_mode(kbd, VC_REPEAT) ||
+ (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) {
/*
* Don't repeat a key if the input buffers are not empty and the
- * characters get aren't echoed locally. This makes key repeat
+ * characters get aren't echoed locally. This makes key repeat
* usable with slow applications and under heavy loads.
*/
return;
@@ -1131,7 +1131,8 @@ static void kbd_keycode(unsigned int keycode, int down,
type = KTYP(keysym);
if (type < 0xf0) {
- if (down && !raw_mode) to_utf8(vc, keysym);
+ if (down && !raw_mode)
+ to_utf8(vc, keysym);
return;
}
@@ -1155,7 +1156,7 @@ static void kbd_keycode(unsigned int keycode, int down,
kbd->slockstate = 0;
}
-static void kbd_event(struct input_handle *handle, unsigned int event_type,
+static void kbd_event(struct input_handle *handle, unsigned int event_type,
unsigned int event_code, int value)
{
if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
@@ -1167,15 +1168,13 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
schedule_console_callback();
}
-static char kbd_name[] = "kbd";
-
/*
* When a keyboard (or other input device) is found, the kbd_connect
* function is called. The function then looks at the device, and if it
* likes it, it can open it and get events from it. In this (kbd_connect)
* function, we should decide which VT to bind that keyboard to initially.
*/
-static struct input_handle *kbd_connect(struct input_handler *handler,
+static struct input_handle *kbd_connect(struct input_handler *handler,
struct input_dev *dev,
struct input_device_id *id)
{
@@ -1183,18 +1182,19 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
int i;
for (i = KEY_RESERVED; i < BTN_MISC; i++)
- if (test_bit(i, dev->keybit)) break;
+ if (test_bit(i, dev->keybit))
+ break;
- if ((i == BTN_MISC) && !test_bit(EV_SND, dev->evbit))
+ if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
return NULL;
- if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
+ if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
return NULL;
memset(handle, 0, sizeof(struct input_handle));
handle->dev = dev;
handle->handler = handler;
- handle->name = kbd_name;
+ handle->name = "kbd";
input_open_device(handle);
kbd_refresh_leds(handle);
@@ -1213,11 +1213,11 @@ static struct input_device_id kbd_ids[] = {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_KEY) },
},
-
+
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_SND) },
- },
+ },
{ }, /* Terminating entry */
};
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index cf01a720eb2e..b77161146144 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -613,10 +613,15 @@ static struct miscdevice lcd_dev = {
static int lcd_init(void)
{
+ int ret;
unsigned long data;
pr_info("%s\n", LCD_DRIVER);
- misc_register(&lcd_dev);
+ ret = misc_register(&lcd_dev);
+ if (ret) {
+ printk(KERN_WARNING LCD "Unable to register misc device.\n");
+ return ret;
+ }
/* Check region? Naaah! Just snarf it up. */
/* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 59eebe5a035f..2afb9038dbc5 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -128,6 +128,7 @@
#include <linux/console.h>
#include <linux/device.h>
#include <linux/wait.h>
+#include <linux/jiffies.h>
#include <linux/parport.h>
#undef LP_STATS
@@ -307,7 +308,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
(LP_F(minor) & LP_ABORT));
#ifdef LP_STATS
- if (jiffies-lp_table[minor].lastcall > LP_TIME(minor))
+ if (time_after(jiffies, lp_table[minor].lastcall + LP_TIME(minor)))
lp_table[minor].runchars = 0;
lp_table[minor].lastcall = jiffies;
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 3fa64c631108..c268ee04b2aa 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -830,6 +830,9 @@ static int __init mbcs_init(void)
{
int rv;
+ if (!ia64_platform_is("sn2"))
+ return -ENODEV;
+
// Put driver into chrdevs[]. Get major number.
rv = register_chrdev(mbcs_major, DEVICE_NAME, &mbcs_ops);
if (rv < 0) {
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index d0ef1ae41298..45d012d85e8c 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1058,8 +1058,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
*/
timeout = jiffies + HZ;
while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(5);
+ schedule_timeout_interruptible(5);
if (time_after(jiffies, timeout))
break;
}
@@ -1080,10 +1079,8 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
info->event = 0;
info->tty = NULL;
if (info->blocked_open) {
- if (info->close_delay) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(info->close_delay);
- }
+ if (info->close_delay)
+ schedule_timeout_interruptible(info->close_delay);
wake_up_interruptible(&info->open_wait);
}
@@ -1801,8 +1798,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
#endif
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(char_time);
+ schedule_timeout_interruptible(char_time);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, orig_jiffies + timeout))
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 2291a87e8ada..853c98cee64f 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -229,8 +229,8 @@ static int __init r3964_init(void)
TRACE_L("line discipline %d registered", N_R3964);
TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
tty_ldisc_N_R3964.num);
- TRACE_L("open=%x", (int)tty_ldisc_N_R3964.open);
- TRACE_L("tty_ldisc_N_R3964 = %x", (int)&tty_ldisc_N_R3964);
+ TRACE_L("open=%p", tty_ldisc_N_R3964.open);
+ TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
}
else
{
@@ -267,8 +267,8 @@ static void add_tx_queue(struct r3964_info *pInfo, struct r3964_block_header *pH
spin_unlock_irqrestore(&pInfo->lock, flags);
- TRACE_Q("add_tx_queue %x, length %d, tx_first = %x",
- (int)pHeader, pHeader->length, (int)pInfo->tx_first );
+ TRACE_Q("add_tx_queue %p, length %d, tx_first = %p",
+ pHeader, pHeader->length, pInfo->tx_first );
}
static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
@@ -285,10 +285,10 @@ static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
return;
#ifdef DEBUG_QUEUE
- printk("r3964: remove_from_tx_queue: %x, length %d - ",
- (int)pHeader, (int)pHeader->length );
+ printk("r3964: remove_from_tx_queue: %p, length %u - ",
+ pHeader, pHeader->length );
for(pDump=pHeader;pDump;pDump=pDump->next)
- printk("%x ", (int)pDump);
+ printk("%p ", pDump);
printk("\n");
#endif
@@ -319,10 +319,10 @@ static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
spin_unlock_irqrestore(&pInfo->lock, flags);
kfree(pHeader);
- TRACE_M("remove_from_tx_queue - kfree %x",(int)pHeader);
+ TRACE_M("remove_from_tx_queue - kfree %p",pHeader);
- TRACE_Q("remove_from_tx_queue: tx_first = %x, tx_last = %x",
- (int)pInfo->tx_first, (int)pInfo->tx_last );
+ TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
+ pInfo->tx_first, pInfo->tx_last );
}
static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader)
@@ -346,9 +346,9 @@ static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pH
spin_unlock_irqrestore(&pInfo->lock, flags);
- TRACE_Q("add_rx_queue: %x, length = %d, rx_first = %x, count = %d",
- (int)pHeader, pHeader->length,
- (int)pInfo->rx_first, pInfo->blocks_in_rx_queue);
+ TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
+ pHeader, pHeader->length,
+ pInfo->rx_first, pInfo->blocks_in_rx_queue);
}
static void remove_from_rx_queue(struct r3964_info *pInfo,
@@ -360,10 +360,10 @@ static void remove_from_rx_queue(struct r3964_info *pInfo,
if(pHeader==NULL)
return;
- TRACE_Q("remove_from_rx_queue: rx_first = %x, rx_last = %x, count = %d",
- (int)pInfo->rx_first, (int)pInfo->rx_last, pInfo->blocks_in_rx_queue );
- TRACE_Q("remove_from_rx_queue: %x, length %d",
- (int)pHeader, (int)pHeader->length );
+ TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+ pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
+ TRACE_Q("remove_from_rx_queue: %p, length %u",
+ pHeader, pHeader->length );
spin_lock_irqsave(&pInfo->lock, flags);
@@ -401,10 +401,10 @@ static void remove_from_rx_queue(struct r3964_info *pInfo,
spin_unlock_irqrestore(&pInfo->lock, flags);
kfree(pHeader);
- TRACE_M("remove_from_rx_queue - kfree %x",(int)pHeader);
+ TRACE_M("remove_from_rx_queue - kfree %p",pHeader);
- TRACE_Q("remove_from_rx_queue: rx_first = %x, rx_last = %x, count = %d",
- (int)pInfo->rx_first, (int)pInfo->rx_last, pInfo->blocks_in_rx_queue );
+ TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+ pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
}
static void put_char(struct r3964_info *pInfo, unsigned char ch)
@@ -506,8 +506,8 @@ static void transmit_block(struct r3964_info *pInfo)
if(tty->driver->write_room)
room=tty->driver->write_room(tty);
- TRACE_PS("transmit_block %x, room %d, length %d",
- (int)pBlock, room, pBlock->length);
+ TRACE_PS("transmit_block %p, room %d, length %d",
+ pBlock, room, pBlock->length);
while(pInfo->tx_position < pBlock->length)
{
@@ -588,7 +588,7 @@ static void on_receive_block(struct r3964_info *pInfo)
/* prepare struct r3964_block_header: */
pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL);
- TRACE_M("on_receive_block - kmalloc %x",(int)pBlock);
+ TRACE_M("on_receive_block - kmalloc %p",pBlock);
if(pBlock==NULL)
return;
@@ -695,7 +695,7 @@ static void receive_char(struct r3964_info *pInfo, const unsigned char c)
{
TRACE_PE("IDLE - got STX but no space in rx_queue!");
pInfo->state=R3964_WAIT_FOR_RX_BUF;
- mod_timer(&pInfo->tmr, R3964_TO_NO_BUF);
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_NO_BUF);
break;
}
start_receiving:
@@ -705,7 +705,7 @@ start_receiving:
pInfo->last_rx = 0;
pInfo->flags &= ~R3964_ERROR;
pInfo->state=R3964_RECEIVING;
- mod_timer(&pInfo->tmr, R3964_TO_ZVZ);
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
pInfo->nRetry = 0;
put_char(pInfo, DLE);
flush(pInfo);
@@ -732,7 +732,7 @@ start_receiving:
if(pInfo->flags & R3964_BCC)
{
pInfo->state = R3964_WAIT_FOR_BCC;
- mod_timer(&pInfo->tmr, R3964_TO_ZVZ);
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
}
else
{
@@ -744,7 +744,7 @@ start_receiving:
pInfo->last_rx = c;
char_to_buf:
pInfo->rx_buf[pInfo->rx_position++] = c;
- mod_timer(&pInfo->tmr, R3964_TO_ZVZ);
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
}
}
/* else: overflow-msg? BUF_SIZE>MTU; should not happen? */
@@ -868,11 +868,11 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
if(pMsg)
{
kfree(pMsg);
- TRACE_M("enable_signals - msg kfree %x",(int)pMsg);
+ TRACE_M("enable_signals - msg kfree %p",pMsg);
}
}
kfree(pClient);
- TRACE_M("enable_signals - kfree %x",(int)pClient);
+ TRACE_M("enable_signals - kfree %p",pClient);
return 0;
}
}
@@ -890,7 +890,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
{
/* add client to client list */
pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL);
- TRACE_M("enable_signals - kmalloc %x",(int)pClient);
+ TRACE_M("enable_signals - kmalloc %p",pClient);
if(pClient==NULL)
return -ENOMEM;
@@ -954,7 +954,7 @@ static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
queue_the_message:
pMsg = kmalloc(sizeof(struct r3964_message), GFP_KERNEL);
- TRACE_M("add_msg - kmalloc %x",(int)pMsg);
+ TRACE_M("add_msg - kmalloc %p",pMsg);
if(pMsg==NULL) {
return;
}
@@ -1067,11 +1067,11 @@ static int r3964_open(struct tty_struct *tty)
struct r3964_info *pInfo;
TRACE_L("open");
- TRACE_L("tty=%x, PID=%d, disc_data=%x",
- (int)tty, current->pid, (int)tty->disc_data);
+ TRACE_L("tty=%p, PID=%d, disc_data=%p",
+ tty, current->pid, tty->disc_data);
pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
- TRACE_M("r3964_open - info kmalloc %x",(int)pInfo);
+ TRACE_M("r3964_open - info kmalloc %p",pInfo);
if(!pInfo)
{
@@ -1080,26 +1080,26 @@ static int r3964_open(struct tty_struct *tty)
}
pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
- TRACE_M("r3964_open - rx_buf kmalloc %x",(int)pInfo->rx_buf);
+ TRACE_M("r3964_open - rx_buf kmalloc %p",pInfo->rx_buf);
if(!pInfo->rx_buf)
{
printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
kfree(pInfo);
- TRACE_M("r3964_open - info kfree %x",(int)pInfo);
+ TRACE_M("r3964_open - info kfree %p",pInfo);
return -ENOMEM;
}
pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
- TRACE_M("r3964_open - tx_buf kmalloc %x",(int)pInfo->tx_buf);
+ TRACE_M("r3964_open - tx_buf kmalloc %p",pInfo->tx_buf);
if(!pInfo->tx_buf)
{
printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
kfree(pInfo->rx_buf);
- TRACE_M("r3964_open - rx_buf kfree %x",(int)pInfo->rx_buf);
+ TRACE_M("r3964_open - rx_buf kfree %p",pInfo->rx_buf);
kfree(pInfo);
- TRACE_M("r3964_open - info kfree %x",(int)pInfo);
+ TRACE_M("r3964_open - info kfree %p",pInfo);
return -ENOMEM;
}
@@ -1154,11 +1154,11 @@ static void r3964_close(struct tty_struct *tty)
if(pMsg)
{
kfree(pMsg);
- TRACE_M("r3964_close - msg kfree %x",(int)pMsg);
+ TRACE_M("r3964_close - msg kfree %p",pMsg);
}
}
kfree(pClient);
- TRACE_M("r3964_close - client kfree %x",(int)pClient);
+ TRACE_M("r3964_close - client kfree %p",pClient);
pClient=pNext;
}
/* Remove jobs from tx_queue: */
@@ -1177,11 +1177,11 @@ static void r3964_close(struct tty_struct *tty)
/* Free buffers: */
wake_up_interruptible(&pInfo->read_wait);
kfree(pInfo->rx_buf);
- TRACE_M("r3964_close - rx_buf kfree %x",(int)pInfo->rx_buf);
+ TRACE_M("r3964_close - rx_buf kfree %p",pInfo->rx_buf);
kfree(pInfo->tx_buf);
- TRACE_M("r3964_close - tx_buf kfree %x",(int)pInfo->tx_buf);
+ TRACE_M("r3964_close - tx_buf kfree %p",pInfo->tx_buf);
kfree(pInfo);
- TRACE_M("r3964_close - info kfree %x",(int)pInfo);
+ TRACE_M("r3964_close - info kfree %p",pInfo);
}
static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
@@ -1234,7 +1234,7 @@ repeat:
count = sizeof(struct r3964_client_message);
kfree(pMsg);
- TRACE_M("r3964_read - msg kfree %x",(int)pMsg);
+ TRACE_M("r3964_read - msg kfree %p",pMsg);
if (copy_to_user(buf,&theMsg, count))
return -EFAULT;
@@ -1279,7 +1279,7 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
* Allocate a buffer for the data and copy it from the buffer with header prepended
*/
new_data = kmalloc (count+sizeof(struct r3964_block_header), GFP_KERNEL);
- TRACE_M("r3964_write - kmalloc %x",(int)new_data);
+ TRACE_M("r3964_write - kmalloc %p",new_data);
if (new_data == NULL) {
if (pInfo->flags & R3964_DEBUG)
{
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 09103b3d8f05..c556f4d3ccd7 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -62,7 +62,7 @@
static inline unsigned char *alloc_buf(void)
{
- int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ gfp_t prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
if (PAGE_SIZE != N_TTY_BUF_SIZE)
return kmalloc(N_TTY_BUF_SIZE, prio);
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 1af733d07321..9e24bbd4090c 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -32,9 +32,11 @@
* added changelog
* 1.2 Erik Gilling: Cobalt Networks support
* Tim Hockin: general cleanup, Cobalt support
+ * 1.3 Jon Ringle: Comdial MP1000 support
+ *
*/
-#define NVRAM_VERSION "1.2"
+#define NVRAM_VERSION "1.3"
#include <linux/module.h>
#include <linux/config.h>
@@ -45,6 +47,7 @@
#define PC 1
#define ATARI 2
#define COBALT 3
+#define MP1000 4
/* select machine configuration */
#if defined(CONFIG_ATARI)
@@ -54,6 +57,9 @@
# if defined(CONFIG_COBALT)
# include <linux/cobalt-nvram.h>
# define MACH COBALT
+# elif defined(CONFIG_MACH_MP1000)
+# undef MACH
+# define MACH MP1000
# else
# define MACH PC
# endif
@@ -112,6 +118,23 @@
#endif
+#if MACH == MP1000
+
+/* RTC in a MP1000 */
+#define CHECK_DRIVER_INIT() 1
+
+#define MP1000_CKS_RANGE_START 0
+#define MP1000_CKS_RANGE_END 111
+#define MP1000_CKS_LOC 112
+
+#define NVRAM_BYTES (128-NVRAM_FIRST_BYTE)
+
+#define mach_check_checksum mp1000_check_checksum
+#define mach_set_checksum mp1000_set_checksum
+#define mach_proc_infos mp1000_proc_infos
+
+#endif
+
/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
* rtc_lock held. Due to the index-port/data-port design of the RTC, we
* don't want two different things trying to get to it at once. (e.g. the
@@ -915,6 +938,91 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len,
#endif /* MACH == ATARI */
+#if MACH == MP1000
+
+static int
+mp1000_check_checksum(void)
+{
+ int i;
+ unsigned short sum = 0;
+ unsigned short expect;
+
+ for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i)
+ sum += __nvram_read_byte(i);
+
+ expect = __nvram_read_byte(MP1000_CKS_LOC+1)<<8 |
+ __nvram_read_byte(MP1000_CKS_LOC);
+ return ((sum & 0xffff) == expect);
+}
+
+static void
+mp1000_set_checksum(void)
+{
+ int i;
+ unsigned short sum = 0;
+
+ for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i)
+ sum += __nvram_read_byte(i);
+ __nvram_write_byte(sum >> 8, MP1000_CKS_LOC + 1);
+ __nvram_write_byte(sum & 0xff, MP1000_CKS_LOC);
+}
+
+#ifdef CONFIG_PROC_FS
+
+#define SERVER_N_LEN 32
+#define PATH_N_LEN 32
+#define FILE_N_LEN 32
+#define NVRAM_MAGIC_SIG 0xdead
+
+typedef struct NvRamImage
+{
+ unsigned short int magic;
+ unsigned short int mode;
+ char fname[FILE_N_LEN];
+ char path[PATH_N_LEN];
+ char server[SERVER_N_LEN];
+ char pad[12];
+} NvRam;
+
+static int
+mp1000_proc_infos(unsigned char *nvram, char *buffer, int *len,
+ off_t *begin, off_t offset, int size)
+{
+ int checksum;
+ NvRam* nv = (NvRam*)nvram;
+
+ spin_lock_irq(&rtc_lock);
+ checksum = __nvram_check_checksum();
+ spin_unlock_irq(&rtc_lock);
+
+ PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");
+
+ switch( nv->mode )
+ {
+ case 0 :
+ PRINT_PROC( "\tMode 0, tftp prompt\n" );
+ break;
+ case 1 :
+ PRINT_PROC( "\tMode 1, booting from disk\n" );
+ break;
+ case 2 :
+ PRINT_PROC( "\tMode 2, Alternate boot from disk /boot/%s\n", nv->fname );
+ break;
+ case 3 :
+ PRINT_PROC( "\tMode 3, Booting from net:\n" );
+ PRINT_PROC( "\t\t%s:%s%s\n",nv->server, nv->path, nv->fname );
+ break;
+ default:
+ PRINT_PROC( "\tInconsistant nvram?\n" );
+ break;
+ }
+
+ return 1;
+}
+#endif
+
+#endif /* MACH == MP1000 */
+
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(__nvram_read_byte);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 7a0c74648124..02d7f046c10a 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/pcmcia/synclink_cs.c
*
- * $Id: synclink_cs.c,v 4.26 2004/08/11 19:30:02 paulkf Exp $
+ * $Id: synclink_cs.c,v 4.34 2005/09/08 13:20:54 paulkf Exp $
*
* Device driver for Microgate SyncLink PC Card
* multiprotocol serial adapter.
@@ -472,7 +472,7 @@ module_param_array(dosyncppp, int, NULL, 0);
MODULE_LICENSE("GPL");
static char *driver_name = "SyncLink PC Card driver";
-static char *driver_version = "$Revision: 4.26 $";
+static char *driver_version = "$Revision: 4.34 $";
static struct tty_driver *serial_driver;
@@ -1457,6 +1457,8 @@ static int startup(MGSLPC_INFO * 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 = tx_timeout;
@@ -1946,9 +1948,13 @@ static int get_stats(MGSLPC_INFO * info, struct mgsl_icount __user *user_icount)
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("get_params(%s)\n", info->device_name);
- COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount));
- if (err)
- 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;
}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index da32889d22c0..49f3997fd251 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -149,15 +149,14 @@ static int pty_write_room(struct tty_struct *tty)
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/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index ed867db550a9..e1a90d9a8756 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -564,6 +564,7 @@ static int s3c2410_rtc_resume(struct device *dev, u32 level)
static struct device_driver s3c2410_rtcdrv = {
.name = "s3c2410-rtc",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2410_rtc_probe,
.remove = s3c2410_rtc_remove,
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 37c8bea8e2b0..ea2d54be4843 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* 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 ec949e4c070f..6fb165cf8a61 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/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 79e9832ef1f3..b58adfe3ed19 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -17,7 +17,7 @@ config TCG_TPM
obtained at: <http://sourceforge.net/projects/trousers>. To
compile this driver as a module, choose M here; the module
will be called tpm. If unsure, say N.
- Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI_BUS
+ Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
and CONFIG_PNPACPI.
config TCG_NSC
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9d657127f313..e5953f3433f3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -469,21 +469,19 @@ static void tty_ldisc_enable(struct tty_struct *tty)
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 b8d0c290b0db..e91268e86833 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,45 @@ 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 + (old_row_size * new_rows);
+ }
+ } else
+ /*
+ * Cursor near the top, copy contents from the top of buffer
+ */
+ end = (old_rows > new_rows) ? old_origin +
+ (old_row_size * new_rows) :
+ 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/Kconfig b/drivers/char/watchdog/Kconfig
index c3898afce3ae..344001b45af9 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -84,6 +84,17 @@ config 977_WATCHDOG
Not sure? It's safe to say N.
+config IXP2000_WATCHDOG
+ tristate "IXP2000 Watchdog"
+ depends on WATCHDOG && ARCH_IXP2000
+ help
+ Say Y here if to include support for the watchdog timer
+ in the Intel IXP2000(2400, 2800, 2850) network processors.
+ This driver can be built as a module by choosing M. The module
+ will be called ixp2000_wdt.
+
+ Say N if you are unsure.
+
config IXP4XX_WATCHDOG
tristate "IXP4xx Watchdog"
depends on WATCHDOG && ARCH_IXP4XX
@@ -100,17 +111,6 @@ config IXP4XX_WATCHDOG
Say N if you are unsure.
-config IXP2000_WATCHDOG
- tristate "IXP2000 Watchdog"
- depends on WATCHDOG && ARCH_IXP2000
- help
- Say Y here if to include support for the watchdog timer
- in the Intel IXP2000(2400, 2800, 2850) network processors.
- This driver can be built as a module by choosing M. The module
- will be called ixp2000_wdt.
-
- Say N if you are unsure.
-
config S3C2410_WATCHDOG
tristate "S3C2410 Watchdog"
depends on WATCHDOG && ARCH_S3C2410
@@ -139,6 +139,15 @@ config SA1100_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called sa1100_wdt.
+config MPCORE_WATCHDOG
+ tristate "MPcore watchdog"
+ depends on WATCHDOG && ARM_MPCORE_PLATFORM && LOCAL_TIMERS
+ help
+ Watchdog timer embedded into the MPcore system.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mpcore_wdt.
+
# X86 (i386 + ia64 + x86_64) Architecture
config ACQUIRE_WDT
@@ -224,6 +233,16 @@ config IB700_WDT
Most people will say N.
+config IBMASR
+ tristate "IBM Automatic Server Restart"
+ depends on WATCHDOG && X86
+ help
+ This is the driver for the IBM Automatic Server Restart watchdog
+ timer builtin into some eServer xSeries machines.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ibmasr.
+
config WAFER_WDT
tristate "ICP Wafer 5823 Single Board Computer Watchdog"
depends on WATCHDOG && X86
@@ -234,6 +253,16 @@ config WAFER_WDT
To compile this driver as a module, choose M here: the
module will be called wafer5823wdt.
+config I6300ESB_WDT
+ tristate "Intel 6300ESB Timer/Watchdog"
+ depends on WATCHDOG && X86 && PCI
+ ---help---
+ Hardware driver for the watchdog timer built into the Intel
+ 6300ESB controller hub.
+
+ To compile this driver as a module, choose M here: the
+ module will be called i6300esb.
+
config I8XX_TCO
tristate "Intel i8xx TCO Timer/Watchdog"
depends on WATCHDOG && (X86 || IA64) && PCI
@@ -289,6 +318,19 @@ config 60XX_WDT
You can compile this driver directly into the kernel, or use
it as a module. The module will be called sbc60xxwdt.
+config SBC8360_WDT
+ tristate "SBC8360 Watchdog Timer"
+ depends on WATCHDOG && X86
+ ---help---
+
+ This is the driver for the hardware watchdog on the SBC8360 Single
+ Board Computer produced by Axiomtek Co., Ltd. (www.axiomtek.com).
+
+ To compile this driver as a module, choose M here: the
+ module will be called sbc8360.ko.
+
+ Most people will say N.
+
config CPU5_WDT
tristate "SMA CPU5 Watchdog"
depends on WATCHDOG && X86
@@ -327,6 +369,19 @@ config W83877F_WDT
Most people will say N.
+config W83977F_WDT
+ tristate "W83977F (PCM-5335) Watchdog Timer"
+ depends on WATCHDOG && X86
+ ---help---
+ This is the driver for the hardware watchdog on the W83977F I/O chip
+ as used in AAEON's PCM-5335 SBC (and likely others). This
+ watchdog simply watches your kernel to make sure it doesn't freeze,
+ and if it does, it reboots your computer after a certain amount of
+ time.
+
+ To compile this driver as a module, choose M here: the
+ module will be called w83977f_wdt.
+
config MACHZ_WDT
tristate "ZF MachZ Watchdog"
depends on WATCHDOG && X86
@@ -346,6 +401,10 @@ config 8xx_WDT
tristate "MPC8xx Watchdog Timer"
depends on WATCHDOG && 8xx
+config MV64X60_WDT
+ tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
+ depends on WATCHDOG && MV64X60
+
config BOOKE_WDT
tristate "PowerPC Book-E Watchdog Timer"
depends on WATCHDOG && (BOOKE || 4xx)
@@ -353,6 +412,17 @@ config BOOKE_WDT
Please see Documentation/watchdog/watchdog-api.txt for
more information.
+# PPC64 Architecture
+
+config WATCHDOG_RTAS
+ tristate "RTAS watchdog"
+ depends on WATCHDOG && PPC_RTAS
+ help
+ This driver adds watchdog support for the RTAS watchdog.
+
+ To compile this driver as a module, choose M here. The module
+ will be called wdrtas.
+
# MIPS Architecture
config INDYDOG
@@ -421,16 +491,6 @@ config WATCHDOG_RIO
machines. The watchdog timeout period is normally one minute but
can be changed with a boot-time parameter.
-# ppc64 RTAS watchdog
-config WATCHDOG_RTAS
- tristate "RTAS watchdog"
- depends on WATCHDOG && PPC_RTAS
- help
- This driver adds watchdog support for the RTAS watchdog.
-
- To compile this driver as a module, choose M here. The module
- will be called wdrtas.
-
#
# ISA-based Watchdog Cards
#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index cfeac6f10137..cfd0a3987710 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
+obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
# X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
@@ -38,22 +39,27 @@ obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o
+obj-$(CONFIG_IBMASR) += ibmasr.o
obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
+obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
+obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
+obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
# PowerPC Architecture
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
+obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# PPC64 Architecture
obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
-obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# MIPS Architecture
obj-$(CONFIG_INDYDOG) += indydog.o
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
new file mode 100644
index 000000000000..93785f13242e
--- /dev/null
+++ b/drivers/char/watchdog/i6300esb.c
@@ -0,0 +1,527 @@
+/*
+ * i6300esb: Watchdog timer driver for Intel 6300ESB chipset
+ *
+ * (c) Copyright 2004 Google Inc.
+ * (c) Copyright 2005 David Härdeman <david@2gen.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.
+ *
+ * based on i810-tco.c which is in turn based on softdog.c
+ *
+ * The timer is implemented in the following I/O controller hubs:
+ * (See the intel documentation on http://developer.intel.com.)
+ * 6300ESB chip : document number 300641-003
+ *
+ * 2004YYZZ Ross Biro
+ * Initial version 0.01
+ * 2004YYZZ Ross Biro
+ * Version 0.02
+ * 20050210 David Härdeman <david@2gen.com>
+ * Ported driver to kernel 2.6
+ */
+
+/*
+ * Includes, defines, variables, module parameters, ...
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* Module and version information */
+#define ESB_VERSION "0.03"
+#define ESB_MODULE_NAME "i6300ESB timer"
+#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
+#define PFX ESB_MODULE_NAME ": "
+
+/* PCI configuration registers */
+#define ESB_CONFIG_REG 0x60 /* Config register */
+#define ESB_LOCK_REG 0x68 /* WDT lock register */
+
+/* Memory mapped registers */
+#define ESB_TIMER1_REG BASEADDR + 0x00 /* Timer1 value after each reset */
+#define ESB_TIMER2_REG BASEADDR + 0x04 /* Timer2 value after each reset */
+#define ESB_GINTSR_REG BASEADDR + 0x08 /* General Interrupt Status Register */
+#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */
+
+/* Lock register bits */
+#define ESB_WDT_FUNC ( 0x01 << 2 ) /* Watchdog functionality */
+#define ESB_WDT_ENABLE ( 0x01 << 1 ) /* Enable WDT */
+#define ESB_WDT_LOCK ( 0x01 << 0 ) /* Lock (nowayout) */
+
+/* Config register bits */
+#define ESB_WDT_REBOOT ( 0x01 << 5 ) /* Enable reboot on timeout */
+#define ESB_WDT_FREQ ( 0x01 << 2 ) /* Decrement frequency */
+#define ESB_WDT_INTTYPE ( 0x11 << 0 ) /* Interrupt type on timer1 timeout */
+
+/* Reload register bits */
+#define ESB_WDT_RELOAD ( 0x01 << 8 ) /* prevent timeout */
+
+/* Magic constants */
+#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
+#define ESB_UNLOCK2 0x86 /* Step 2 to unlock reset registers */
+
+/* internal variables */
+static void __iomem *BASEADDR;
+static spinlock_t esb_lock; /* Guards the hardware */
+static unsigned long timer_alive;
+static struct pci_dev *esb_pci;
+static unsigned short triggered; /* The status of the watchdog upon boot */
+static char esb_expect_close;
+
+/* module parameters */
+#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */
+static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Some i6300ESB specific functions
+ */
+
+/*
+ * Prepare for reloading the timer by unlocking the proper registers.
+ * This is performed by first writing 0x80 followed by 0x86 to the
+ * reload register. After this the appropriate registers can be written
+ * to once before they need to be unlocked again.
+ */
+static inline void esb_unlock_registers(void) {
+ writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
+ writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
+}
+
+static void esb_timer_start(void)
+{
+ u8 val;
+
+ /* Enable or Enable + Lock? */
+ val = 0x02 | (nowayout ? 0x01 : 0x00);
+
+ pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
+}
+
+static int esb_timer_stop(void)
+{
+ u8 val;
+
+ spin_lock(&esb_lock);
+ /* First, reset timers as suggested by the docs */
+ esb_unlock_registers();
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+ /* Then disable the WDT */
+ pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
+ pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
+ spin_unlock(&esb_lock);
+
+ /* Returns 0 if the timer was disabled, non-zero otherwise */
+ return (val & 0x01);
+}
+
+static void esb_timer_keepalive(void)
+{
+ spin_lock(&esb_lock);
+ esb_unlock_registers();
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+ /* FIXME: Do we need to flush anything here? */
+ spin_unlock(&esb_lock);
+}
+
+static int esb_timer_set_heartbeat(int time)
+{
+ u32 val;
+
+ if (time < 0x1 || time > (2 * 0x03ff))
+ return -EINVAL;
+
+ spin_lock(&esb_lock);
+
+ /* We shift by 9, so if we are passed a value of 1 sec,
+ * val will be 1 << 9 = 512, then write that to two
+ * timers => 2 * 512 = 1024 (which is decremented at 1KHz)
+ */
+ val = time << 9;
+
+ /* Write timer 1 */
+ esb_unlock_registers();
+ writel(val, ESB_TIMER1_REG);
+
+ /* Write timer 2 */
+ esb_unlock_registers();
+ writel(val, ESB_TIMER2_REG);
+
+ /* Reload */
+ esb_unlock_registers();
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+
+ /* FIXME: Do we need to flush everything out? */
+
+ /* Done */
+ heartbeat = time;
+ spin_unlock(&esb_lock);
+ return 0;
+}
+
+static int esb_timer_read (void)
+{
+ u32 count;
+
+ /* This isn't documented, and doesn't take into
+ * acount which stage is running, but it looks
+ * like a 20 bit count down, so we might as well report it.
+ */
+ pci_read_config_dword(esb_pci, 0x64, &count);
+ return (int)count;
+}
+
+/*
+ * /dev/watchdog handling
+ */
+
+static int esb_open (struct inode *inode, struct file *file)
+{
+ /* /dev/watchdog can only be opened once */
+ if (test_and_set_bit(0, &timer_alive))
+ return -EBUSY;
+
+ /* Reload and activate timer */
+ esb_timer_keepalive ();
+ esb_timer_start ();
+
+ return nonseekable_open(inode, file);
+}
+
+static int esb_release (struct inode *inode, struct file *file)
+{
+ /* Shut off the timer. */
+ if (esb_expect_close == 42) {
+ esb_timer_stop ();
+ } else {
+ printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+ esb_timer_keepalive ();
+ }
+ clear_bit(0, &timer_alive);
+ esb_expect_close = 0;
+ return 0;
+}
+
+static ssize_t esb_write (struct file *file, const char __user *data,
+ size_t len, loff_t * ppos)
+{
+ /* See if we got the magic character 'V' and reload the timer */
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ /* note: just in case someone wrote the magic character
+ * five months ago... */
+ esb_expect_close = 0;
+
+ /* scan to see whether or not we got the magic character */
+ for (i = 0; i != len; i++) {
+ char c;
+ if(get_user(c, data+i))
+ return -EFAULT;
+ if (c == 'V')
+ esb_expect_close = 42;
+ }
+ }
+
+ /* someone wrote to us, we should reload the timer */
+ esb_timer_keepalive ();
+ }
+ return len;
+}
+
+static int esb_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int new_options, retval = -EINVAL;
+ int new_heartbeat;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ static struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .firmware_version = 0,
+ .identity = ESB_MODULE_NAME,
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ident,
+ sizeof (ident)) ? -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ return put_user (esb_timer_read(), p);
+
+ case WDIOC_GETBOOTSTATUS:
+ return put_user (triggered, p);
+
+ case WDIOC_KEEPALIVE:
+ esb_timer_keepalive ();
+ return 0;
+
+ case WDIOC_SETOPTIONS:
+ {
+ if (get_user (new_options, p))
+ return -EFAULT;
+
+ if (new_options & WDIOS_DISABLECARD) {
+ esb_timer_stop ();
+ retval = 0;
+ }
+
+ if (new_options & WDIOS_ENABLECARD) {
+ esb_timer_keepalive ();
+ esb_timer_start ();
+ retval = 0;
+ }
+
+ return retval;
+ }
+
+ case WDIOC_SETTIMEOUT:
+ {
+ if (get_user(new_heartbeat, p))
+ return -EFAULT;
+
+ if (esb_timer_set_heartbeat(new_heartbeat))
+ return -EINVAL;
+
+ esb_timer_keepalive ();
+ /* Fall */
+ }
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(heartbeat, p);
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+/*
+ * Notify system
+ */
+
+static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
+{
+ if (code==SYS_DOWN || code==SYS_HALT) {
+ /* Turn the WDT off */
+ esb_timer_stop ();
+ }
+
+ return NOTIFY_DONE;
+}
+
+/*
+ * Kernel Interfaces
+ */
+
+static struct file_operations esb_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = esb_write,
+ .ioctl = esb_ioctl,
+ .open = esb_open,
+ .release = esb_release,
+};
+
+static struct miscdevice esb_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &esb_fops,
+};
+
+static struct notifier_block esb_notifier = {
+ .notifier_call = esb_notify_sys,
+};
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE. We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static struct pci_device_id esb_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
+ { 0, }, /* End of list */
+};
+MODULE_DEVICE_TABLE (pci, esb_pci_tbl);
+
+/*
+ * Init & exit routines
+ */
+
+static unsigned char __init esb_getdevice (void)
+{
+ u8 val1;
+ unsigned short val2;
+
+ struct pci_dev *dev = NULL;
+ /*
+ * Find the PCI device
+ */
+
+ for_each_pci_dev(dev) {
+ if (pci_match_id(esb_pci_tbl, dev)) {
+ esb_pci = dev;
+ break;
+ }
+ }
+
+ if (esb_pci) {
+ if (pci_enable_device(esb_pci)) {
+ printk (KERN_ERR PFX "failed to enable device\n");
+ goto err_devput;
+ }
+
+ if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
+ printk (KERN_ERR PFX "failed to request region\n");
+ goto err_disable;
+ }
+
+ BASEADDR = ioremap(pci_resource_start(esb_pci, 0),
+ pci_resource_len(esb_pci, 0));
+ if (BASEADDR == NULL) {
+ /* Something's wrong here, BASEADDR has to be set */
+ printk (KERN_ERR PFX "failed to get BASEADDR\n");
+ goto err_release;
+ }
+
+ /*
+ * The watchdog has two timers, it can be setup so that the
+ * expiry of timer1 results in an interrupt and the expiry of
+ * timer2 results in a reboot. We set it to not generate
+ * any interrupts as there is not much we can do with it
+ * right now.
+ *
+ * We also enable reboots and set the timer frequency to
+ * the PCI clock divided by 2^15 (approx 1KHz).
+ */
+ pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
+
+ /* Check that the WDT isn't already locked */
+ pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
+ if (val1 & ESB_WDT_LOCK)
+ printk (KERN_WARNING PFX "nowayout already set\n");
+
+ /* Set the timer to watchdog mode and disable it for now */
+ pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
+
+ /* Check if the watchdog was previously triggered */
+ esb_unlock_registers();
+ val2 = readw(ESB_RELOAD_REG);
+ triggered = (val2 & (0x01 << 9) >> 9);
+
+ /* Reset trigger flag and timers */
+ esb_unlock_registers();
+ writew((0x11 << 8), ESB_RELOAD_REG);
+
+ /* Done */
+ return 1;
+
+err_release:
+ pci_release_region(esb_pci, 0);
+err_disable:
+ pci_disable_device(esb_pci);
+err_devput:
+ pci_dev_put(esb_pci);
+ }
+ return 0;
+}
+
+static int __init watchdog_init (void)
+{
+ int ret;
+
+ spin_lock_init(&esb_lock);
+
+ /* Check whether or not the hardware watchdog is there */
+ if (!esb_getdevice () || esb_pci == NULL)
+ return -ENODEV;
+
+ /* Check that the heartbeat value is within it's range ; if not reset to the default */
+ if (esb_timer_set_heartbeat (heartbeat)) {
+ esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT);
+ printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n",
+ heartbeat);
+ }
+
+ ret = register_reboot_notifier(&esb_notifier);
+ if (ret != 0) {
+ printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+ ret);
+ goto err_unmap;
+ }
+
+ ret = misc_register(&esb_miscdev);
+ if (ret != 0) {
+ printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ WATCHDOG_MINOR, ret);
+ goto err_notifier;
+ }
+
+ esb_timer_stop ();
+
+ printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
+ BASEADDR, heartbeat, nowayout);
+
+ return 0;
+
+err_notifier:
+ unregister_reboot_notifier(&esb_notifier);
+err_unmap:
+ iounmap(BASEADDR);
+/* err_release: */
+ pci_release_region(esb_pci, 0);
+/* err_disable: */
+ pci_disable_device(esb_pci);
+/* err_devput: */
+ pci_dev_put(esb_pci);
+ return ret;
+}
+
+static void __exit watchdog_cleanup (void)
+{
+ /* Stop the timer before we leave */
+ if (!nowayout)
+ esb_timer_stop ();
+
+ /* Deregister */
+ misc_deregister(&esb_miscdev);
+ unregister_reboot_notifier(&esb_notifier);
+ iounmap(BASEADDR);
+ pci_release_region(esb_pci, 0);
+ pci_disable_device(esb_pci);
+ pci_dev_put(esb_pci);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_cleanup);
+
+MODULE_AUTHOR("Ross Biro and David Härdeman");
+MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
new file mode 100644
index 000000000000..294c474ae485
--- /dev/null
+++ b/drivers/char/watchdog/ibmasr.c
@@ -0,0 +1,405 @@
+/*
+ * IBM Automatic Server Restart driver.
+ *
+ * Copyright (c) 2005 Andrey Panin <pazke@donpac.ru>
+ *
+ * Based on driver written by Pete Reynolds.
+ * Copyright (c) IBM Corporation, 1998-2004.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/dmi.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+
+enum {
+ ASMTYPE_UNKNOWN,
+ ASMTYPE_TOPAZ,
+ ASMTYPE_JASPER,
+ ASMTYPE_PEARL,
+ ASMTYPE_JUNIPER,
+ ASMTYPE_SPRUCE,
+};
+
+#define PFX "ibmasr: "
+
+#define TOPAZ_ASR_REG_OFFSET 4
+#define TOPAZ_ASR_TOGGLE 0x40
+#define TOPAZ_ASR_DISABLE 0x80
+
+/* PEARL ASR S/W REGISTER SUPERIO PORT ADDRESSES */
+#define PEARL_BASE 0xe04
+#define PEARL_WRITE 0xe06
+#define PEARL_READ 0xe07
+
+#define PEARL_ASR_DISABLE_MASK 0x80 /* bit 7: disable = 1, enable = 0 */
+#define PEARL_ASR_TOGGLE_MASK 0x40 /* bit 6: 0, then 1, then 0 */
+
+/* JASPER OFFSET FROM SIO BASE ADDR TO ASR S/W REGISTERS. */
+#define JASPER_ASR_REG_OFFSET 0x38
+
+#define JASPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1, enable = 0 */
+#define JASPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */
+
+#define JUNIPER_BASE_ADDRESS 0x54b /* Base address of Juniper ASR */
+#define JUNIPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1 enable = 0 */
+#define JUNIPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */
+
+#define SPRUCE_BASE_ADDRESS 0x118e /* Base address of Spruce ASR */
+#define SPRUCE_ASR_DISABLE_MASK 0x01 /* bit 1: disable = 1 enable = 0 */
+#define SPRUCE_ASR_TOGGLE_MASK 0x02 /* bit 0: 0, then 1, then 0 */
+
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+static unsigned long asr_is_open;
+static char asr_expect_close;
+
+static unsigned int asr_type, asr_base, asr_length;
+static unsigned int asr_read_addr, asr_write_addr;
+static unsigned char asr_toggle_mask, asr_disable_mask;
+
+static void asr_toggle(void)
+{
+ unsigned char reg = inb(asr_read_addr);
+
+ outb(reg & ~asr_toggle_mask, asr_write_addr);
+ reg = inb(asr_read_addr);
+
+ outb(reg | asr_toggle_mask, asr_write_addr);
+ reg = inb(asr_read_addr);
+
+ outb(reg & ~asr_toggle_mask, asr_write_addr);
+ reg = inb(asr_read_addr);
+}
+
+static void asr_enable(void)
+{
+ unsigned char reg;
+
+ if (asr_type == ASMTYPE_TOPAZ) {
+ /* asr_write_addr == asr_read_addr */
+ reg = inb(asr_read_addr);
+ outb(reg & ~(TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE),
+ asr_read_addr);
+ } else {
+ /*
+ * First make sure the hardware timer is reset by toggling
+ * ASR hardware timer line.
+ */
+ asr_toggle();
+
+ reg = inb(asr_read_addr);
+ outb(reg & ~asr_disable_mask, asr_write_addr);
+ }
+ reg = inb(asr_read_addr);
+}
+
+static void asr_disable(void)
+{
+ unsigned char reg = inb(asr_read_addr);
+
+ if (asr_type == ASMTYPE_TOPAZ)
+ /* asr_write_addr == asr_read_addr */
+ outb(reg | TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE,
+ asr_read_addr);
+ else {
+ outb(reg | asr_toggle_mask, asr_write_addr);
+ reg = inb(asr_read_addr);
+
+ outb(reg | asr_disable_mask, asr_write_addr);
+ }
+ reg = inb(asr_read_addr);
+}
+
+static int __init asr_get_base_address(void)
+{
+ unsigned char low, high;
+ const char *type = "";
+
+ asr_length = 1;
+
+ switch (asr_type) {
+ case ASMTYPE_TOPAZ:
+ /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
+ outb(0x07, 0x2e);
+ outb(0x07, 0x2f);
+
+ /* SELECT AND READ THE HIGH-NIBBLE OF THE GPIO BASE ADDRESS */
+ outb(0x60, 0x2e);
+ high = inb(0x2f);
+
+ /* SELECT AND READ THE LOW-NIBBLE OF THE GPIO BASE ADDRESS */
+ outb(0x61, 0x2e);
+ low = inb(0x2f);
+
+ asr_base = (high << 16) | low;
+ asr_read_addr = asr_write_addr =
+ asr_base + TOPAZ_ASR_REG_OFFSET;
+ asr_length = 5;
+
+ break;
+
+ case ASMTYPE_JASPER:
+ type = "Jaspers ";
+
+ /* FIXME: need to use pci_config_lock here, but it's not exported */
+
+/* spin_lock_irqsave(&pci_config_lock, flags);*/
+
+ /* Select the SuperIO chip in the PCI I/O port register */
+ outl(0x8000f858, 0xcf8);
+
+ /*
+ * Read the base address for the SuperIO chip.
+ * Only the lower 16 bits are valid, but the address is word
+ * aligned so the last bit must be masked off.
+ */
+ asr_base = inl(0xcfc) & 0xfffe;
+
+/* spin_unlock_irqrestore(&pci_config_lock, flags);*/
+
+ asr_read_addr = asr_write_addr =
+ asr_base + JASPER_ASR_REG_OFFSET;
+ asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
+ asr_disable_mask = JASPER_ASR_DISABLE_MASK;
+ asr_length = JASPER_ASR_REG_OFFSET + 1;
+
+ break;
+
+ case ASMTYPE_PEARL:
+ type = "Pearls ";
+ asr_base = PEARL_BASE;
+ asr_read_addr = PEARL_READ;
+ asr_write_addr = PEARL_WRITE;
+ asr_toggle_mask = PEARL_ASR_TOGGLE_MASK;
+ asr_disable_mask = PEARL_ASR_DISABLE_MASK;
+ asr_length = 4;
+ break;
+
+ case ASMTYPE_JUNIPER:
+ type = "Junipers ";
+ asr_base = JUNIPER_BASE_ADDRESS;
+ asr_read_addr = asr_write_addr = asr_base;
+ asr_toggle_mask = JUNIPER_ASR_TOGGLE_MASK;
+ asr_disable_mask = JUNIPER_ASR_DISABLE_MASK;
+ break;
+
+ case ASMTYPE_SPRUCE:
+ type = "Spruce's ";
+ asr_base = SPRUCE_BASE_ADDRESS;
+ asr_read_addr = asr_write_addr = asr_base;
+ asr_toggle_mask = SPRUCE_ASR_TOGGLE_MASK;
+ asr_disable_mask = SPRUCE_ASR_DISABLE_MASK;
+ break;
+ }
+
+ if (!request_region(asr_base, asr_length, "ibmasr")) {
+ printk(KERN_ERR PFX "address %#x already in use\n",
+ asr_base);
+ return -EBUSY;
+ }
+
+ printk(KERN_INFO PFX "found %sASR @ addr %#x\n", type, asr_base);
+
+ return 0;
+}
+
+
+static ssize_t asr_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (count) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ asr_expect_close = 0;
+
+ for (i = 0; i != count; i++) {
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ if (c == 'V')
+ asr_expect_close = 42;
+ }
+ }
+ asr_toggle();
+ }
+ return count;
+}
+
+static int asr_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ static const struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .identity = "IBM ASR"
+ };
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int heartbeat;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ident, sizeof(ident)) ?
+ -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, p);
+
+ case WDIOC_KEEPALIVE:
+ asr_toggle();
+ return 0;
+
+ /*
+ * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
+ * and WDIOC_GETTIMEOUT always returns 256.
+ */
+ case WDIOC_GETTIMEOUT:
+ heartbeat = 256;
+ return put_user(heartbeat, p);
+
+ case WDIOC_SETOPTIONS: {
+ int new_options, retval = -EINVAL;
+
+ if (get_user(new_options, p))
+ return -EFAULT;
+
+ if (new_options & WDIOS_DISABLECARD) {
+ asr_disable();
+ retval = 0;
+ }
+
+ if (new_options & WDIOS_ENABLECARD) {
+ asr_enable();
+ asr_toggle();
+ retval = 0;
+ }
+
+ return retval;
+ }
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static int asr_open(struct inode *inode, struct file *file)
+{
+ if(test_and_set_bit(0, &asr_is_open))
+ return -EBUSY;
+
+ asr_toggle();
+ asr_enable();
+
+ return nonseekable_open(inode, file);
+}
+
+static int asr_release(struct inode *inode, struct file *file)
+{
+ if (asr_expect_close == 42)
+ asr_disable();
+ else {
+ printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
+ asr_toggle();
+ }
+ clear_bit(0, &asr_is_open);
+ asr_expect_close = 0;
+ return 0;
+}
+
+static struct file_operations asr_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = asr_write,
+ .ioctl = asr_ioctl,
+ .open = asr_open,
+ .release = asr_release,
+};
+
+static struct miscdevice asr_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &asr_fops,
+};
+
+
+struct ibmasr_id {
+ const char *desc;
+ int type;
+};
+
+static struct ibmasr_id __initdata ibmasr_id_table[] = {
+ { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ },
+ { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL },
+ { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER },
+ { "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER },
+ { "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE },
+ { NULL }
+};
+
+static int __init ibmasr_init(void)
+{
+ struct ibmasr_id *id;
+ int rc;
+
+ for (id = ibmasr_id_table; id->desc; id++) {
+ if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) {
+ asr_type = id->type;
+ break;
+ }
+ }
+
+ if (!asr_type)
+ return -ENODEV;
+
+ rc = misc_register(&asr_miscdev);
+ if (rc < 0) {
+ printk(KERN_ERR PFX "failed to register misc device\n");
+ return rc;
+ }
+
+ rc = asr_get_base_address();
+ if (rc) {
+ misc_deregister(&asr_miscdev);
+ return rc;
+ }
+
+ return 0;
+}
+
+static void __exit ibmasr_exit(void)
+{
+ if (!nowayout)
+ asr_disable();
+
+ misc_deregister(&asr_miscdev);
+
+ release_region(asr_base, asr_length);
+}
+
+module_init(ibmasr_init);
+module_exit(ibmasr_exit);
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
+MODULE_AUTHOR("Andrey Panin");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index c9b301dccec3..7fc2188386d9 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -59,7 +59,7 @@ static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
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/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
new file mode 100644
index 000000000000..75ca84ed4adf
--- /dev/null
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -0,0 +1,436 @@
+/*
+ * Watchdog driver for the mpcore watchdog timer
+ *
+ * (c) Copyright 2004 ARM Limited
+ *
+ * Based on the SoftDog driver:
+ * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ * http://www.redhat.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.
+ *
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ *
+ * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/hardware/arm_twd.h>
+#include <asm/uaccess.h>
+
+struct mpcore_wdt {
+ unsigned long timer_alive;
+ struct device *dev;
+ void __iomem *base;
+ int irq;
+ unsigned int perturb;
+ char expect_close;
+};
+
+static struct platform_device *mpcore_wdt_dev;
+
+extern unsigned int mpcore_timer_rate;
+
+#define TIMER_MARGIN 60
+static int mpcore_margin = TIMER_MARGIN;
+module_param(mpcore_margin, int, 0);
+MODULE_PARM_DESC(mpcore_margin, "MPcore timer margin in seconds. (0<mpcore_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define ONLY_TESTING 0
+static int mpcore_noboot = ONLY_TESTING;
+module_param(mpcore_noboot, int, 0);
+MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, set to 1 to ignore reboots, 0 to reboot (default=" __MODULE_STRING(ONLY_TESTING) ")");
+
+/*
+ * This is the interrupt handler. Note that we only use this
+ * in testing mode, so don't actually do a reboot here.
+ */
+static irqreturn_t mpcore_wdt_fire(int irq, void *arg, struct pt_regs *regs)
+{
+ struct mpcore_wdt *wdt = arg;
+
+ /* Check it really was our interrupt */
+ if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
+ dev_printk(KERN_CRIT, wdt->dev, "Triggered - Reboot ignored.\n");
+
+ /* Clear the interrupt on the watchdog */
+ writel(1, wdt->base + TWD_WDOG_INTSTAT);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+/*
+ * mpcore_wdt_keepalive - reload the timer
+ *
+ * Note that the spec says a DIFFERENT value must be written to the reload
+ * register each time. The "perturb" variable deals with this by adding 1
+ * to the count every other time the function is called.
+ */
+static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
+{
+ unsigned int count;
+
+ /* Assume prescale is set to 256 */
+ count = (mpcore_timer_rate / 256) * mpcore_margin;
+
+ /* Reload the counter */
+ writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
+
+ wdt->perturb = wdt->perturb ? 0 : 1;
+}
+
+static void mpcore_wdt_stop(struct mpcore_wdt *wdt)
+{
+ writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
+ writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
+ writel(0x0, wdt->base + TWD_WDOG_CONTROL);
+}
+
+static void mpcore_wdt_start(struct mpcore_wdt *wdt)
+{
+ dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
+
+ /* This loads the count register but does NOT start the count yet */
+ mpcore_wdt_keepalive(wdt);
+
+ if (mpcore_noboot) {
+ /* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
+ writel(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
+ } else {
+ /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
+ writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
+ }
+}
+
+static int mpcore_wdt_set_heartbeat(int t)
+{
+ if (t < 0x0001 || t > 0xFFFF)
+ return -EINVAL;
+
+ mpcore_margin = t;
+ return 0;
+}
+
+/*
+ * /dev/watchdog handling
+ */
+static int mpcore_wdt_open(struct inode *inode, struct file *file)
+{
+ struct mpcore_wdt *wdt = dev_get_drvdata(&mpcore_wdt_dev->dev);
+
+ if (test_and_set_bit(0, &wdt->timer_alive))
+ return -EBUSY;
+
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ file->private_data = wdt;
+
+ /*
+ * Activate timer
+ */
+ mpcore_wdt_start(wdt);
+
+ return nonseekable_open(inode, file);
+}
+
+static int mpcore_wdt_release(struct inode *inode, struct file *file)
+{
+ struct mpcore_wdt *wdt = file->private_data;
+
+ /*
+ * Shut off the timer.
+ * Lock it in if it's a module and we set nowayout
+ */
+ if (wdt->expect_close == 42) {
+ mpcore_wdt_stop(wdt);
+ } else {
+ dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n");
+ mpcore_wdt_keepalive(wdt);
+ }
+ clear_bit(0, &wdt->timer_alive);
+ wdt->expect_close = 0;
+ return 0;
+}
+
+static ssize_t mpcore_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+ struct mpcore_wdt *wdt = file->private_data;
+
+ /* Can't seek (pwrite) on this device */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+
+ /*
+ * Refresh the timer.
+ */
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ wdt->expect_close = 0;
+
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ wdt->expect_close = 42;
+ }
+ }
+ mpcore_wdt_keepalive(wdt);
+ }
+ return len;
+}
+
+static struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .identity = "MPcore Watchdog",
+};
+
+static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct mpcore_wdt *wdt = file->private_data;
+ int ret;
+ union {
+ struct watchdog_info ident;
+ int i;
+ } uarg;
+
+ if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
+ return -ENOIOCTLCMD;
+
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
+ if (ret)
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ uarg.ident = ident;
+ ret = 0;
+ break;
+
+ case WDIOC_SETOPTIONS:
+ ret = -EINVAL;
+ if (uarg.i & WDIOS_DISABLECARD) {
+ mpcore_wdt_stop(wdt);
+ ret = 0;
+ }
+ if (uarg.i & WDIOS_ENABLECARD) {
+ mpcore_wdt_start(wdt);
+ ret = 0;
+ }
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ uarg.i = 0;
+ ret = 0;
+ break;
+
+ case WDIOC_KEEPALIVE:
+ mpcore_wdt_keepalive(wdt);
+ ret = 0;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ ret = mpcore_wdt_set_heartbeat(uarg.i);
+ if (ret)
+ break;
+
+ mpcore_wdt_keepalive(wdt);
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ uarg.i = mpcore_margin;
+ ret = 0;
+ break;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
+ ret = copy_to_user((void __user *)arg, &uarg, _IOC_SIZE(cmd));
+ if (ret)
+ ret = -EFAULT;
+ }
+ return ret;
+}
+
+/*
+ * System shutdown handler. Turn off the watchdog if we're
+ * restarting or halting the system.
+ */
+static void mpcore_wdt_shutdown(struct device *_dev)
+{
+ struct mpcore_wdt *wdt = dev_get_drvdata(_dev);
+
+ if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
+ mpcore_wdt_stop(wdt);
+}
+
+/*
+ * Kernel Interfaces
+ */
+static struct file_operations mpcore_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = mpcore_wdt_write,
+ .ioctl = mpcore_wdt_ioctl,
+ .open = mpcore_wdt_open,
+ .release = mpcore_wdt_release,
+};
+
+static struct miscdevice mpcore_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &mpcore_wdt_fops,
+};
+
+static int __devinit mpcore_wdt_probe(struct device *_dev)
+{
+ struct platform_device *dev = to_platform_device(_dev);
+ struct mpcore_wdt *wdt;
+ struct resource *res;
+ int ret;
+
+ /* We only accept one device, and it must have an id of -1 */
+ if (dev->id != -1)
+ return -ENODEV;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENODEV;
+ goto err_out;
+ }
+
+ wdt = kmalloc(sizeof(struct mpcore_wdt), GFP_KERNEL);
+ if (!wdt) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+ memset(wdt, 0, sizeof(struct mpcore_wdt));
+
+ wdt->dev = &dev->dev;
+ wdt->irq = platform_get_irq(dev, 0);
+ wdt->base = ioremap(res->start, res->end - res->start + 1);
+ if (!wdt->base) {
+ ret = -ENOMEM;
+ goto err_free;
+ }
+
+ mpcore_wdt_miscdev.dev = &dev->dev;
+ ret = misc_register(&mpcore_wdt_miscdev);
+ if (ret) {
+ dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n",
+ WATCHDOG_MINOR, ret);
+ goto err_misc;
+ }
+
+ ret = request_irq(wdt->irq, mpcore_wdt_fire, SA_INTERRUPT, "mpcore_wdt", wdt);
+ if (ret) {
+ dev_printk(KERN_ERR, _dev, "cannot register IRQ%d for watchdog\n", wdt->irq);
+ goto err_irq;
+ }
+
+ mpcore_wdt_stop(wdt);
+ dev_set_drvdata(&dev->dev, wdt);
+ mpcore_wdt_dev = dev;
+
+ return 0;
+
+ err_irq:
+ misc_deregister(&mpcore_wdt_miscdev);
+ err_misc:
+ iounmap(wdt->base);
+ err_free:
+ kfree(wdt);
+ err_out:
+ return ret;
+}
+
+static int __devexit mpcore_wdt_remove(struct device *dev)
+{
+ struct mpcore_wdt *wdt = dev_get_drvdata(dev);
+
+ dev_set_drvdata(dev, NULL);
+
+ misc_deregister(&mpcore_wdt_miscdev);
+
+ mpcore_wdt_dev = NULL;
+
+ free_irq(wdt->irq, wdt);
+ iounmap(wdt->base);
+ kfree(wdt);
+ return 0;
+}
+
+static struct device_driver mpcore_wdt_driver = {
+ .name = "mpcore_wdt",
+ .bus = &platform_bus_type,
+ .probe = mpcore_wdt_probe,
+ .remove = __devexit_p(mpcore_wdt_remove),
+ .shutdown = mpcore_wdt_shutdown,
+};
+
+static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
+
+static int __init mpcore_wdt_init(void)
+{
+ /*
+ * Check that the margin value is within it's range;
+ * if not reset to the default
+ */
+ if (mpcore_wdt_set_heartbeat(mpcore_margin)) {
+ mpcore_wdt_set_heartbeat(TIMER_MARGIN);
+ printk(KERN_INFO "mpcore_margin value must be 0<mpcore_margin<65536, using %d\n",
+ TIMER_MARGIN);
+ }
+
+ printk(banner, mpcore_noboot, mpcore_margin, nowayout);
+
+ return driver_register(&mpcore_wdt_driver);
+}
+
+static void __exit mpcore_wdt_exit(void)
+{
+ driver_unregister(&mpcore_wdt_driver);
+}
+
+module_init(mpcore_wdt_init);
+module_exit(mpcore_wdt_exit);
+
+MODULE_AUTHOR("ARM Limited");
+MODULE_DESCRIPTION("MPcore Watchdog Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
new file mode 100644
index 000000000000..6d3ff0836c44
--- /dev/null
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -0,0 +1,252 @@
+/*
+ * mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
+ *
+ * Author: James Chapman <jchapman@katalix.com>
+ *
+ * Platform-specific setup code should configure the dog to generate
+ * interrupt or reset as required. This code only enables/disables
+ * and services the watchdog.
+ *
+ * Derived from mpc8xx_wdt.c, with the following copyright.
+ *
+ * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/watchdog.h>
+#include <asm/mv64x60.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* MV64x60 WDC (config) register access definitions */
+#define MV64x60_WDC_CTL1_MASK (3 << 24)
+#define MV64x60_WDC_CTL1(val) ((val & 3) << 24)
+#define MV64x60_WDC_CTL2_MASK (3 << 26)
+#define MV64x60_WDC_CTL2(val) ((val & 3) << 26)
+
+/* Flags bits */
+#define MV64x60_WDOG_FLAG_OPENED 0
+#define MV64x60_WDOG_FLAG_ENABLED 1
+
+static unsigned long wdt_flags;
+static int wdt_status;
+static void __iomem *mv64x60_regs;
+static int mv64x60_wdt_timeout;
+
+static void mv64x60_wdt_reg_write(u32 val)
+{
+ /* Allow write only to CTL1 / CTL2 fields, retaining values in
+ * other fields.
+ */
+ u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC);
+ data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK);
+ data |= val;
+ writel(data, mv64x60_regs + MV64x60_WDT_WDC);
+}
+
+static void mv64x60_wdt_service(void)
+{
+ /* Write 01 followed by 10 to CTL2 */
+ mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01));
+ mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02));
+}
+
+static void mv64x60_wdt_handler_disable(void)
+{
+ if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
+ /* Write 01 followed by 10 to CTL1 */
+ mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
+ mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
+ printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
+ }
+}
+
+static void mv64x60_wdt_handler_enable(void)
+{
+ if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
+ /* Write 01 followed by 10 to CTL1 */
+ mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
+ mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
+ printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
+ }
+}
+
+static int mv64x60_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
+ return -EBUSY;
+
+ mv64x60_wdt_service();
+ mv64x60_wdt_handler_enable();
+
+ nonseekable_open(inode, file);
+
+ return 0;
+}
+
+static int mv64x60_wdt_release(struct inode *inode, struct file *file)
+{
+ mv64x60_wdt_service();
+
+#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
+ mv64x60_wdt_handler_disable();
+#endif
+
+ clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
+
+ return 0;
+}
+
+static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
+ size_t len, loff_t * ppos)
+{
+ if (len)
+ mv64x60_wdt_service();
+
+ return len;
+}
+
+static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int timeout;
+ void __user *argp = (void __user *)arg;
+ static struct watchdog_info info = {
+ .options = WDIOF_KEEPALIVEPING,
+ .firmware_version = 0,
+ .identity = "MV64x60 watchdog",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ if (put_user(wdt_status, (int __user *)argp))
+ return -EFAULT;
+ wdt_status &= ~WDIOF_KEEPALIVEPING;
+ break;
+
+ case WDIOC_GETTEMP:
+ return -EOPNOTSUPP;
+
+ case WDIOC_SETOPTIONS:
+ return -EOPNOTSUPP;
+
+ case WDIOC_KEEPALIVE:
+ mv64x60_wdt_service();
+ wdt_status |= WDIOF_KEEPALIVEPING;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ return -EOPNOTSUPP;
+
+ case WDIOC_GETTIMEOUT:
+ timeout = mv64x60_wdt_timeout * HZ;
+ if (put_user(timeout, (int __user *)argp))
+ return -EFAULT;
+ break;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ return 0;
+}
+
+static struct file_operations mv64x60_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = mv64x60_wdt_write,
+ .ioctl = mv64x60_wdt_ioctl,
+ .open = mv64x60_wdt_open,
+ .release = mv64x60_wdt_release,
+};
+
+static struct miscdevice mv64x60_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &mv64x60_wdt_fops,
+};
+
+static int __devinit mv64x60_wdt_probe(struct device *dev)
+{
+ struct platform_device *pd = to_platform_device(dev);
+ struct mv64x60_wdt_pdata *pdata = pd->dev.platform_data;
+ int bus_clk = 133;
+
+ mv64x60_wdt_timeout = 10;
+ if (pdata) {
+ mv64x60_wdt_timeout = pdata->timeout;
+ bus_clk = pdata->bus_clk;
+ }
+
+ mv64x60_regs = mv64x60_get_bridge_vbase();
+
+ writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8,
+ mv64x60_regs + MV64x60_WDT_WDC);
+
+ return misc_register(&mv64x60_wdt_miscdev);
+}
+
+static int __devexit mv64x60_wdt_remove(struct device *dev)
+{
+ misc_deregister(&mv64x60_wdt_miscdev);
+
+ mv64x60_wdt_service();
+ mv64x60_wdt_handler_disable();
+
+ return 0;
+}
+
+static struct device_driver mv64x60_wdt_driver = {
+ .name = MV64x60_WDT_NAME,
+ .bus = &platform_bus_type,
+ .probe = mv64x60_wdt_probe,
+ .remove = __devexit_p(mv64x60_wdt_remove),
+};
+
+static struct platform_device *mv64x60_wdt_dev;
+
+static int __init mv64x60_wdt_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO "MV64x60 watchdog driver\n");
+
+ mv64x60_wdt_dev = platform_device_register_simple(MV64x60_WDT_NAME,
+ -1, NULL, 0);
+ if (IS_ERR(mv64x60_wdt_dev)) {
+ ret = PTR_ERR(mv64x60_wdt_dev);
+ goto out;
+ }
+
+ ret = driver_register(&mv64x60_wdt_driver);
+ out:
+ return ret;
+}
+
+static void __exit mv64x60_wdt_exit(void)
+{
+ driver_unregister(&mv64x60_wdt_driver);
+ platform_device_unregister(mv64x60_wdt_dev);
+}
+
+module_init(mv64x60_wdt_init);
+module_exit(mv64x60_wdt_exit);
+
+MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
+MODULE_DESCRIPTION("MV64x60 watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 2b13afb09c5d..0b8e493be045 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -29,27 +29,29 @@
* Includes, defines, variables, module parameters, ...
*/
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */
+#include <linux/module.h> /* For module specific items */
+#include <linux/moduleparam.h> /* For new moduleparam's */
+#include <linux/types.h> /* For standard types (like size_t) */
+#include <linux/errno.h> /* For the -ENODEV/... values */
+#include <linux/kernel.h> /* For printk/panic/... */
+#include <linux/delay.h> /* For mdelay function */
+#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
+#include <linux/watchdog.h> /* For the watchdog specific items */
+#include <linux/notifier.h> /* For notifier support */
+#include <linux/reboot.h> /* For reboot_notifier stuff */
+#include <linux/init.h> /* For __init/__exit/... */
+#include <linux/fs.h> /* For file operations */
+#include <linux/pci.h> /* For pci functions */
+#include <linux/ioport.h> /* For io-port access */
+#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
+
+#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
+#include <asm/io.h> /* For inb/outb/... */
/* Module and version information */
-#define WATCHDOG_VERSION "1.01"
-#define WATCHDOG_DATE "15 Mar 2005"
+#define WATCHDOG_VERSION "1.02"
+#define WATCHDOG_DATE "03 Sep 2005"
#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
#define WATCHDOG_NAME "pcwd_pci"
#define PFX WATCHDOG_NAME ": "
@@ -68,19 +70,30 @@
* These are the defines that describe the control status bits for the
* PCI-PC Watchdog card.
*/
-#define WD_PCI_WTRP 0x01 /* Watchdog Trip status */
-#define WD_PCI_HRBT 0x02 /* Watchdog Heartbeat */
-#define WD_PCI_TTRP 0x04 /* Temperature Trip status */
+/* Port 1 : Control Status #1 */
+#define WD_PCI_WTRP 0x01 /* Watchdog Trip status */
+#define WD_PCI_HRBT 0x02 /* Watchdog Heartbeat */
+#define WD_PCI_TTRP 0x04 /* Temperature Trip status */
+#define WD_PCI_RL2A 0x08 /* Relay 2 Active */
+#define WD_PCI_RL1A 0x10 /* Relay 1 Active */
+#define WD_PCI_R2DS 0x40 /* Relay 2 Disable Temperature-trip/reset */
+#define WD_PCI_RLY2 0x80 /* Activate Relay 2 on the board */
+/* Port 2 : Control Status #2 */
+#define WD_PCI_WDIS 0x10 /* Watchdog Disable */
+#define WD_PCI_ENTP 0x20 /* Enable Temperature Trip Reset */
+#define WD_PCI_WRSP 0x40 /* Watchdog wrote response */
+#define WD_PCI_PCMD 0x80 /* PC has sent command */
/* according to documentation max. time to process a command for the pci
* watchdog card is 100 ms, so we give it 150 ms to do it's job */
#define PCI_COMMAND_TIMEOUT 150
/* Watchdog's internal commands */
-#define CMD_GET_STATUS 0x04
-#define CMD_GET_FIRMWARE_VERSION 0x08
-#define CMD_READ_WATCHDOG_TIMEOUT 0x18
-#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19
+#define CMD_GET_STATUS 0x04
+#define CMD_GET_FIRMWARE_VERSION 0x08
+#define CMD_READ_WATCHDOG_TIMEOUT 0x18
+#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19
+#define CMD_GET_CLEAR_RESET_COUNT 0x84
/* We can only use 1 card due to the /dev/watchdog restriction */
static int cards_found;
@@ -89,15 +102,22 @@ static int cards_found;
static int temp_panic;
static unsigned long is_active;
static char expect_release;
-static struct {
- int supports_temp; /* Wether or not the card has a temperature device */
- int boot_status; /* The card's boot status */
- unsigned long io_addr; /* The cards I/O address */
- spinlock_t io_lock;
- struct pci_dev *pdev;
+static struct { /* this is private data for each PCI-PC watchdog card */
+ int supports_temp; /* Wether or not the card has a temperature device */
+ int boot_status; /* The card's boot status */
+ unsigned long io_addr; /* The cards I/O address */
+ spinlock_t io_lock; /* the lock for io operations */
+ struct pci_dev *pdev; /* the PCI-device */
} pcipcwd_private;
/* module parameters */
+#define QUIET 0 /* Default */
+#define VERBOSE 1 /* Verbose */
+#define DEBUG 2 /* print fancy stuff too */
+static int debug = QUIET;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
+
#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */
static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0);
@@ -115,6 +135,10 @@ static int send_command(int cmd, int *msb, int *lsb)
{
int got_response, count;
+ if (debug >= DEBUG)
+ printk(KERN_DEBUG PFX "sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x\n",
+ cmd, *msb, *lsb);
+
spin_lock(&pcipcwd_private.io_lock);
/* If a command requires data it should be written first.
* Data for commands with 8 bits of data should be written to port 4.
@@ -129,10 +153,19 @@ static int send_command(int cmd, int *msb, int *lsb)
/* wait till the pci card processed the command, signaled by
* the WRSP bit in port 2 and give it a max. timeout of
* PCI_COMMAND_TIMEOUT to process */
- got_response = inb_p(pcipcwd_private.io_addr + 2) & 0x40;
+ got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response); count++) {
mdelay(1);
- got_response = inb_p(pcipcwd_private.io_addr + 2) & 0x40;
+ got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
+ }
+
+ if (debug >= DEBUG) {
+ if (got_response) {
+ printk(KERN_DEBUG PFX "time to process command was: %d ms\n",
+ count);
+ } else {
+ printk(KERN_DEBUG PFX "card did not respond on command!\n");
+ }
}
if (got_response) {
@@ -142,12 +175,66 @@ static int send_command(int cmd, int *msb, int *lsb)
/* clear WRSP bit */
inb_p(pcipcwd_private.io_addr + 6);
+
+ if (debug >= DEBUG)
+ printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
+ cmd, *msb, *lsb);
}
+
spin_unlock(&pcipcwd_private.io_lock);
return got_response;
}
+static inline void pcipcwd_check_temperature_support(void)
+{
+ if (inb_p(pcipcwd_private.io_addr) != 0xF0)
+ pcipcwd_private.supports_temp = 1;
+}
+
+static int pcipcwd_get_option_switches(void)
+{
+ int option_switches;
+
+ option_switches = inb_p(pcipcwd_private.io_addr + 3);
+ return option_switches;
+}
+
+static void pcipcwd_show_card_info(void)
+{
+ int got_fw_rev, fw_rev_major, fw_rev_minor;
+ char fw_ver_str[20]; /* The cards firmware version */
+ int option_switches;
+
+ got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
+ if (got_fw_rev) {
+ sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
+ } else {
+ sprintf(fw_ver_str, "<card no answer>");
+ }
+
+ /* Get switch settings */
+ option_switches = pcipcwd_get_option_switches();
+
+ printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",
+ (int) pcipcwd_private.io_addr, fw_ver_str,
+ (pcipcwd_private.supports_temp ? "with" : "without"));
+
+ printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
+ option_switches,
+ ((option_switches & 0x10) ? "ON" : "OFF"),
+ ((option_switches & 0x08) ? "ON" : "OFF"));
+
+ if (pcipcwd_private.boot_status & WDIOF_CARDRESET)
+ printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");
+
+ if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)
+ printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");
+
+ if (pcipcwd_private.boot_status == 0)
+ printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
+}
+
static int pcipcwd_start(void)
{
int stat_reg;
@@ -159,11 +246,14 @@ static int pcipcwd_start(void)
stat_reg = inb_p(pcipcwd_private.io_addr + 2);
spin_unlock(&pcipcwd_private.io_lock);
- if (stat_reg & 0x10) {
+ if (stat_reg & WD_PCI_WDIS) {
printk(KERN_ERR PFX "Card timer not enabled\n");
return -1;
}
+ if (debug >= VERBOSE)
+ printk(KERN_DEBUG PFX "Watchdog started\n");
+
return 0;
}
@@ -181,18 +271,25 @@ static int pcipcwd_stop(void)
stat_reg = inb_p(pcipcwd_private.io_addr + 2);
spin_unlock(&pcipcwd_private.io_lock);
- if (!(stat_reg & 0x10)) {
+ if (!(stat_reg & WD_PCI_WDIS)) {
printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n");
return -1;
}
+ if (debug >= VERBOSE)
+ printk(KERN_DEBUG PFX "Watchdog stopped\n");
+
return 0;
}
static int pcipcwd_keepalive(void)
{
/* Re-trigger watchdog by writing to port 0 */
- outb_p(0x42, pcipcwd_private.io_addr);
+ outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */
+
+ if (debug >= DEBUG)
+ printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
+
return 0;
}
@@ -208,29 +305,64 @@ static int pcipcwd_set_heartbeat(int t)
send_command(CMD_WRITE_WATCHDOG_TIMEOUT, &t_msb, &t_lsb);
heartbeat = t;
+ if (debug >= VERBOSE)
+ printk(KERN_DEBUG PFX "New heartbeat: %d\n",
+ heartbeat);
+
return 0;
}
static int pcipcwd_get_status(int *status)
{
- int new_status;
+ int control_status;
*status=0;
- new_status = inb_p(pcipcwd_private.io_addr + 1);
- if (new_status & WD_PCI_WTRP)
+ control_status = inb_p(pcipcwd_private.io_addr + 1);
+ if (control_status & WD_PCI_WTRP)
*status |= WDIOF_CARDRESET;
- if (new_status & WD_PCI_TTRP) {
+ if (control_status & WD_PCI_TTRP) {
*status |= WDIOF_OVERHEAT;
if (temp_panic)
panic(PFX "Temperature overheat trip!\n");
}
+ if (debug >= DEBUG)
+ printk(KERN_DEBUG PFX "Control Status #1: 0x%02x\n",
+ control_status);
+
return 0;
}
static int pcipcwd_clear_status(void)
{
- outb_p(0x01, pcipcwd_private.io_addr + 1);
+ int control_status;
+ int msb;
+ int reset_counter;
+
+ if (debug >= VERBOSE)
+ printk(KERN_INFO PFX "clearing watchdog trip status & LED\n");
+
+ control_status = inb_p(pcipcwd_private.io_addr + 1);
+
+ if (debug >= DEBUG) {
+ printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status);
+ printk(KERN_DEBUG PFX "sending: 0x%02x\n",
+ (control_status & WD_PCI_R2DS) | WD_PCI_WTRP);
+ }
+
+ /* clear trip status & LED and keep mode of relay 2 */
+ outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1);
+
+ /* clear reset counter */
+ msb=0;
+ reset_counter=0xff;
+ send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter);
+
+ if (debug >= DEBUG) {
+ printk(KERN_DEBUG PFX "reset count was: 0x%02x\n",
+ reset_counter);
+ }
+
return 0;
}
@@ -240,11 +372,18 @@ static int pcipcwd_get_temperature(int *temperature)
if (!pcipcwd_private.supports_temp)
return -ENODEV;
+ *temperature = inb_p(pcipcwd_private.io_addr);
+
/*
* Convert celsius to fahrenheit, since this was
* the decided 'standard' for this return value.
*/
- *temperature = ((inb_p(pcipcwd_private.io_addr)) * 9 / 5) + 32;
+ *temperature = (*temperature * 9 / 5) + 32;
+
+ if (debug >= DEBUG) {
+ printk(KERN_DEBUG PFX "temperature is: %d F\n",
+ *temperature);
+ }
return 0;
}
@@ -254,7 +393,7 @@ static int pcipcwd_get_temperature(int *temperature)
*/
static ssize_t pcipcwd_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+ size_t len, loff_t *ppos)
{
/* See if we got the magic character 'V' and reload the timer */
if (len) {
@@ -335,12 +474,14 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
if (new_options & WDIOS_DISABLECARD) {
- pcipcwd_stop();
+ if (pcipcwd_stop())
+ return -EIO;
retval = 0;
}
if (new_options & WDIOS_ENABLECARD) {
- pcipcwd_start();
+ if (pcipcwd_start())
+ return -EIO;
retval = 0;
}
@@ -377,8 +518,11 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
static int pcipcwd_open(struct inode *inode, struct file *file)
{
/* /dev/watchdog can only be opened once */
- if (test_and_set_bit(0, &is_active))
+ if (test_and_set_bit(0, &is_active)) {
+ if (debug >= VERBOSE)
+ printk(KERN_ERR PFX "Attempt to open already opened device.\n");
return -EBUSY;
+ }
/* Activate */
pcipcwd_start();
@@ -488,19 +632,10 @@ static struct notifier_block pcipcwd_notifier = {
* Init & exit routines
*/
-static inline void check_temperature_support(void)
-{
- if (inb_p(pcipcwd_private.io_addr) != 0xF0)
- pcipcwd_private.supports_temp = 1;
-}
-
static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int ret = -EIO;
- int got_fw_rev, fw_rev_major, fw_rev_minor;
- char fw_ver_str[20];
- char option_switches;
cards_found++;
if (cards_found == 1)
@@ -542,36 +677,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
pcipcwd_stop();
/* Check whether or not the card supports the temperature device */
- check_temperature_support();
-
- /* Get the Firmware Version */
- got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
- if (got_fw_rev) {
- sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
- } else {
- sprintf(fw_ver_str, "<card no answer>");
- }
+ pcipcwd_check_temperature_support();
- /* Get switch settings */
- option_switches = inb_p(pcipcwd_private.io_addr + 3);
-
- printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",
- (int) pcipcwd_private.io_addr, fw_ver_str,
- (pcipcwd_private.supports_temp ? "with" : "without"));
-
- printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
- option_switches,
- ((option_switches & 0x10) ? "ON" : "OFF"),
- ((option_switches & 0x08) ? "ON" : "OFF"));
-
- if (pcipcwd_private.boot_status & WDIOF_CARDRESET)
- printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");
-
- if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)
- printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");
-
- if (pcipcwd_private.boot_status == 0)
- printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
+ /* Show info about the card itself */
+ pcipcwd_show_card_info();
/* Check that the heartbeat value is within it's range ; if not reset to the default */
if (pcipcwd_set_heartbeat(heartbeat)) {
@@ -652,7 +761,7 @@ static struct pci_driver pcipcwd_driver = {
static int __init pcipcwd_init_module(void)
{
- spin_lock_init (&pcipcwd_private.io_lock);
+ spin_lock_init(&pcipcwd_private.io_lock);
return pci_register_driver(&pcipcwd_driver);
}
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 8b292bf343c4..3625b2601b42 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -464,7 +464,7 @@ static void s3c2410wdt_shutdown(struct device *dev)
static unsigned long wtcon_save;
static unsigned long wtdat_save;
-static int s3c2410wdt_suspend(struct device *dev, u32 state, u32 level)
+static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
{
if (level == SUSPEND_POWER_DOWN) {
/* Save watchdog state, and turn it off. */
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
new file mode 100644
index 000000000000..c6cbf808d8c2
--- /dev/null
+++ b/drivers/char/watchdog/sbc8360.c
@@ -0,0 +1,414 @@
+/*
+ * SBC8360 Watchdog driver
+ *
+ * (c) Copyright 2005 Webcon, Inc.
+ *
+ * Based on ib700wdt.c, which is based on advantechwdt.c which is based
+ * on acquirewdt.c which is based on wdt.c.
+ *
+ * (c) Copyright 2001 Charles Howes <chowes@vsol.net>
+ *
+ * Based on advantechwdt.c which is based on acquirewdt.c which
+ * is based on wdt.c.
+ *
+ * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
+ *
+ * Based on acquirewdt.c which is based on wdt.c.
+ * Original copyright messages:
+ *
+ * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ * http://www.redhat.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.
+ *
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ *
+ * (c) Copyright 1995 Alan Cox <alan@redhat.com>
+ *
+ * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ * Added timeout module option to override default
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/fs.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+static unsigned long sbc8360_is_open;
+static spinlock_t sbc8360_lock;
+static char expect_close;
+
+#define PFX "sbc8360: "
+
+/*
+ *
+ * Watchdog Timer Configuration
+ *
+ * The function of the watchdog timer is to reset the system automatically
+ * and is defined at I/O port 0120H and 0121H. To enable the watchdog timer
+ * and allow the system to reset, write appropriate values from the table
+ * below to I/O port 0120H and 0121H. To disable the timer, write a zero
+ * value to I/O port 0121H for the system to stop the watchdog function.
+ *
+ * The following describes how the timer should be programmed (according to
+ * the vendor documentation)
+ *
+ * Enabling Watchdog:
+ * MOV AX,000AH (enable, phase I)
+ * MOV DX,0120H
+ * OUT DX,AX
+ * MOV AX,000BH (enable, phase II)
+ * MOV DX,0120H
+ * OUT DX,AX
+ * MOV AX,000nH (set multiplier n, from 1-4)
+ * MOV DX,0120H
+ * OUT DX,AX
+ * MOV AX,000mH (set base timer m, from 0-F)
+ * MOV DX,0121H
+ * OUT DX,AX
+ *
+ * Reset timer:
+ * MOV AX,000mH (same as set base timer, above)
+ * MOV DX,0121H
+ * OUT DX,AX
+ *
+ * Disabling Watchdog:
+ * MOV AX,0000H (a zero value)
+ * MOV DX,0120H
+ * OUT DX,AX
+ *
+ * Watchdog timeout configuration values:
+ * N
+ * M | 1 2 3 4
+ * --|----------------------------------
+ * 0 | 0.5s 5s 50s 100s
+ * 1 | 1s 10s 100s 200s
+ * 2 | 1.5s 15s 150s 300s
+ * 3 | 2s 20s 200s 400s
+ * 4 | 2.5s 25s 250s 500s
+ * 5 | 3s 30s 300s 600s
+ * 6 | 3.5s 35s 350s 700s
+ * 7 | 4s 40s 400s 800s
+ * 8 | 4.5s 45s 450s 900s
+ * 9 | 5s 50s 500s 1000s
+ * A | 5.5s 55s 550s 1100s
+ * B | 6s 60s 600s 1200s
+ * C | 6.5s 65s 650s 1300s
+ * D | 7s 70s 700s 1400s
+ * E | 7.5s 75s 750s 1500s
+ * F | 8s 80s 800s 1600s
+ *
+ * Another way to say the same things is:
+ * For N=1, Timeout = (M+1) * 0.5s
+ * For N=2, Timeout = (M+1) * 5s
+ * For N=3, Timeout = (M+1) * 50s
+ * For N=4, Timeout = (M+1) * 100s
+ *
+ */
+
+static int wd_times[64][2] = {
+ {0, 1}, /* 0 = 0.5s */
+ {1, 1}, /* 1 = 1s */
+ {2, 1}, /* 2 = 1.5s */
+ {3, 1}, /* 3 = 2s */
+ {4, 1}, /* 4 = 2.5s */
+ {5, 1}, /* 5 = 3s */
+ {6, 1}, /* 6 = 3.5s */
+ {7, 1}, /* 7 = 4s */
+ {8, 1}, /* 8 = 4.5s */
+ {9, 1}, /* 9 = 5s */
+ {0xA, 1}, /* 10 = 5.5s */
+ {0xB, 1}, /* 11 = 6s */
+ {0xC, 1}, /* 12 = 6.5s */
+ {0xD, 1}, /* 13 = 7s */
+ {0xE, 1}, /* 14 = 7.5s */
+ {0xF, 1}, /* 15 = 8s */
+ {0, 2}, /* 16 = 5s */
+ {1, 2}, /* 17 = 10s */
+ {2, 2}, /* 18 = 15s */
+ {3, 2}, /* 19 = 20s */
+ {4, 2}, /* 20 = 25s */
+ {5, 2}, /* 21 = 30s */
+ {6, 2}, /* 22 = 35s */
+ {7, 2}, /* 23 = 40s */
+ {8, 2}, /* 24 = 45s */
+ {9, 2}, /* 25 = 50s */
+ {0xA, 2}, /* 26 = 55s */
+ {0xB, 2}, /* 27 = 60s */
+ {0xC, 2}, /* 28 = 65s */
+ {0xD, 2}, /* 29 = 70s */
+ {0xE, 2}, /* 30 = 75s */
+ {0xF, 2}, /* 31 = 80s */
+ {0, 3}, /* 32 = 50s */
+ {1, 3}, /* 33 = 100s */
+ {2, 3}, /* 34 = 150s */
+ {3, 3}, /* 35 = 200s */
+ {4, 3}, /* 36 = 250s */
+ {5, 3}, /* 37 = 300s */
+ {6, 3}, /* 38 = 350s */
+ {7, 3}, /* 39 = 400s */
+ {8, 3}, /* 40 = 450s */
+ {9, 3}, /* 41 = 500s */
+ {0xA, 3}, /* 42 = 550s */
+ {0xB, 3}, /* 43 = 600s */
+ {0xC, 3}, /* 44 = 650s */
+ {0xD, 3}, /* 45 = 700s */
+ {0xE, 3}, /* 46 = 750s */
+ {0xF, 3}, /* 47 = 800s */
+ {0, 4}, /* 48 = 100s */
+ {1, 4}, /* 49 = 200s */
+ {2, 4}, /* 50 = 300s */
+ {3, 4}, /* 51 = 400s */
+ {4, 4}, /* 52 = 500s */
+ {5, 4}, /* 53 = 600s */
+ {6, 4}, /* 54 = 700s */
+ {7, 4}, /* 55 = 800s */
+ {8, 4}, /* 56 = 900s */
+ {9, 4}, /* 57 = 1000s */
+ {0xA, 4}, /* 58 = 1100s */
+ {0xB, 4}, /* 59 = 1200s */
+ {0xC, 4}, /* 60 = 1300s */
+ {0xD, 4}, /* 61 = 1400s */
+ {0xE, 4}, /* 62 = 1500s */
+ {0xF, 4} /* 63 = 1600s */
+};
+
+#define SBC8360_ENABLE 0x120
+#define SBC8360_BASETIME 0x121
+
+static int timeout = 27;
+static int wd_margin = 0xB;
+static int wd_multiplier = 2;
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(timeout, int, 27);
+MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Kernel methods.
+ */
+
+/* Activate and pre-configure watchdog */
+static void sbc8360_activate(void)
+{
+ /* Enable the watchdog */
+ outb(0x0A, SBC8360_ENABLE);
+ msleep_interruptible(100);
+ outb(0x0B, SBC8360_ENABLE);
+ msleep_interruptible(100);
+ /* Set timeout multiplier */
+ outb(wd_multiplier, SBC8360_ENABLE);
+ msleep_interruptible(100);
+ /* Nothing happens until first sbc8360_ping() */
+}
+
+/* Kernel pings watchdog */
+static void sbc8360_ping(void)
+{
+ /* Write the base timer register */
+ outb(wd_margin, SBC8360_BASETIME);
+}
+
+/* Userspace pings kernel driver, or requests clean close */
+static ssize_t sbc8360_write(struct file *file, const char __user * buf,
+ size_t count, loff_t * ppos)
+{
+ if (count) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ expect_close = 0;
+
+ for (i = 0; i != count; i++) {
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+ sbc8360_ping();
+ }
+ return count;
+}
+
+static int sbc8360_open(struct inode *inode, struct file *file)
+{
+ spin_lock(&sbc8360_lock);
+ if (test_and_set_bit(0, &sbc8360_is_open)) {
+ spin_unlock(&sbc8360_lock);
+ return -EBUSY;
+ }
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ /* Activate and ping once to start the countdown */
+ spin_unlock(&sbc8360_lock);
+ sbc8360_activate();
+ sbc8360_ping();
+ return nonseekable_open(inode, file);
+}
+
+static int sbc8360_close(struct inode *inode, struct file *file)
+{
+ spin_lock(&sbc8360_lock);
+ if (expect_close == 42)
+ outb(0, SBC8360_ENABLE);
+ else
+ printk(KERN_CRIT PFX
+ "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n");
+
+ clear_bit(0, &sbc8360_is_open);
+ expect_close = 0;
+ spin_unlock(&sbc8360_lock);
+ return 0;
+}
+
+/*
+ * Notifier for system down
+ */
+
+static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT) {
+ /* Disable the SBC8360 Watchdog */
+ outb(0, SBC8360_ENABLE);
+ }
+ return NOTIFY_DONE;
+}
+
+/*
+ * Kernel Interfaces
+ */
+
+static struct file_operations sbc8360_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = sbc8360_write,
+ .open = sbc8360_open,
+ .release = sbc8360_close,
+};
+
+static struct miscdevice sbc8360_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &sbc8360_fops,
+};
+
+/*
+ * The SBC8360 needs to learn about soft shutdowns in order to
+ * turn the timebomb registers off.
+ */
+
+static struct notifier_block sbc8360_notifier = {
+ .notifier_call = sbc8360_notify_sys,
+};
+
+static int __init sbc8360_init(void)
+{
+ int res;
+ unsigned long int mseconds = 60000;
+
+ spin_lock_init(&sbc8360_lock);
+ res = misc_register(&sbc8360_miscdev);
+ if (res) {
+ printk(KERN_ERR PFX "failed to register misc device\n");
+ goto out_nomisc;
+ }
+
+ if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) {
+ printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n",
+ SBC8360_ENABLE);
+ res = -EIO;
+ goto out_noenablereg;
+ }
+ if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) {
+ printk(KERN_ERR PFX
+ "BASETIME method I/O %X is not available.\n",
+ SBC8360_BASETIME);
+ res = -EIO;
+ goto out_nobasetimereg;
+ }
+
+ res = register_reboot_notifier(&sbc8360_notifier);
+ if (res) {
+ printk(KERN_ERR PFX "Failed to register reboot notifier.\n");
+ goto out_noreboot;
+ }
+
+ if (timeout < 0 || timeout > 63) {
+ printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n");
+ res = -EINVAL;
+ goto out_noreboot;
+ }
+
+ wd_margin = wd_times[timeout][0];
+ wd_multiplier = wd_times[timeout][1];
+
+ if (wd_multiplier == 1)
+ mseconds = (wd_margin + 1) * 500;
+ else if (wd_multiplier == 2)
+ mseconds = (wd_margin + 1) * 5000;
+ else if (wd_multiplier == 3)
+ mseconds = (wd_margin + 1) * 50000;
+ else if (wd_multiplier == 4)
+ mseconds = (wd_margin + 1) * 100000;
+
+ /* My kingdom for the ability to print "0.5 seconds" in the kernel! */
+ printk(KERN_INFO PFX "Timeout set at %ld ms.\n", mseconds);
+
+ return 0;
+
+ out_noreboot:
+ release_region(SBC8360_ENABLE, 1);
+ release_region(SBC8360_BASETIME, 1);
+ out_noenablereg:
+ out_nobasetimereg:
+ misc_deregister(&sbc8360_miscdev);
+ out_nomisc:
+ return res;
+}
+
+static void __exit sbc8360_exit(void)
+{
+ misc_deregister(&sbc8360_miscdev);
+ unregister_reboot_notifier(&sbc8360_notifier);
+ release_region(SBC8360_ENABLE, 1);
+ release_region(SBC8360_BASETIME, 1);
+}
+
+module_init(sbc8360_init);
+module_exit(sbc8360_exit);
+
+MODULE_AUTHOR("Ian E. Morgan <imorgan@webcon.ca>");
+MODULE_DESCRIPTION("SBC8360 watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+/* end of sbc8360.c */
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
new file mode 100644
index 000000000000..a7ff64c8921f
--- /dev/null
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -0,0 +1,543 @@
+/*
+ * W83977F Watchdog Timer Driver for Winbond W83977F I/O Chip
+ *
+ * (c) Copyright 2005 Jose Goncalves <jose.goncalves@inov.pt>
+ *
+ * Based on w83877f_wdt.c by Scott Jennings,
+ * and wdt977.c by Woody Suwalski
+ *
+ * -----------------------
+ *
+ * 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/moduleparam.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#define WATCHDOG_VERSION "1.00"
+#define WATCHDOG_NAME "W83977F WDT"
+#define PFX WATCHDOG_NAME ": "
+#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
+
+#define IO_INDEX_PORT 0x3F0
+#define IO_DATA_PORT (IO_INDEX_PORT+1)
+
+#define UNLOCK_DATA 0x87
+#define LOCK_DATA 0xAA
+#define DEVICE_REGISTER 0x07
+
+#define DEFAULT_TIMEOUT 45 /* default timeout in seconds */
+
+static int timeout = DEFAULT_TIMEOUT;
+static int timeoutW; /* timeout in watchdog counter units */
+static unsigned long timer_alive;
+static int testmode;
+static char expect_close;
+static spinlock_t spinlock;
+
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")");
+module_param(testmode, int, 0);
+MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Start the watchdog
+ */
+
+static int wdt_start(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&spinlock, flags);
+
+ /* Unlock the SuperIO chip */
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+ /*
+ * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
+ * F2 has the timeout in watchdog counter units.
+ * F3 is set to enable watchdog LED blink at timeout.
+ * F4 is used to just clear the TIMEOUT'ed state (bit 0).
+ */
+ outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+ outb_p(0x08,IO_DATA_PORT);
+ outb_p(0xF2,IO_INDEX_PORT);
+ outb_p(timeoutW,IO_DATA_PORT);
+ outb_p(0xF3,IO_INDEX_PORT);
+ outb_p(0x08,IO_DATA_PORT);
+ outb_p(0xF4,IO_INDEX_PORT);
+ outb_p(0x00,IO_DATA_PORT);
+
+ /* Set device Aux2 active */
+ outb_p(0x30,IO_INDEX_PORT);
+ outb_p(0x01,IO_DATA_PORT);
+
+ /*
+ * Select device Aux1 (dev=7) to set GP16 as the watchdog output
+ * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
+ * Map GP16 at pin 119.
+ * In test mode watch the bit 0 on F4 to indicate "triggered" or
+ * check watchdog LED on SBC.
+ */
+ outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+ outb_p(0x07,IO_DATA_PORT);
+ if (!testmode)
+ {
+ unsigned pin_map;
+
+ outb_p(0xE6,IO_INDEX_PORT);
+ outb_p(0x0A,IO_DATA_PORT);
+ outb_p(0x2C,IO_INDEX_PORT);
+ pin_map = inb_p(IO_DATA_PORT);
+ pin_map |= 0x10;
+ pin_map &= ~(0x20);
+ outb_p(0x2C,IO_INDEX_PORT);
+ outb_p(pin_map,IO_DATA_PORT);
+ }
+ outb_p(0xE3,IO_INDEX_PORT);
+ outb_p(0x08,IO_DATA_PORT);
+
+ /* Set device Aux1 active */
+ outb_p(0x30,IO_INDEX_PORT);
+ outb_p(0x01,IO_DATA_PORT);
+
+ /* Lock the SuperIO chip */
+ outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+ spin_unlock_irqrestore(&spinlock, flags);
+
+ printk(KERN_INFO PFX "activated.\n");
+
+ return 0;
+}
+
+/*
+ * Stop the watchdog
+ */
+
+static int wdt_stop(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&spinlock, flags);
+
+ /* Unlock the SuperIO chip */
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+ /*
+ * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
+ * F2 is reset to its default value (watchdog timer disabled).
+ * F3 is reset to its default state.
+ * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
+ */
+ outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+ outb_p(0x08,IO_DATA_PORT);
+ outb_p(0xF2,IO_INDEX_PORT);
+ outb_p(0xFF,IO_DATA_PORT);
+ outb_p(0xF3,IO_INDEX_PORT);
+ outb_p(0x00,IO_DATA_PORT);
+ outb_p(0xF4,IO_INDEX_PORT);
+ outb_p(0x00,IO_DATA_PORT);
+ outb_p(0xF2,IO_INDEX_PORT);
+ outb_p(0x00,IO_DATA_PORT);
+
+ /*
+ * Select device Aux1 (dev=7) to set GP16 (in reg E6) and
+ * Gp13 (in reg E3) as inputs.
+ */
+ outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+ outb_p(0x07,IO_DATA_PORT);
+ if (!testmode)
+ {
+ outb_p(0xE6,IO_INDEX_PORT);
+ outb_p(0x01,IO_DATA_PORT);
+ }
+ outb_p(0xE3,IO_INDEX_PORT);
+ outb_p(0x01,IO_DATA_PORT);
+
+ /* Lock the SuperIO chip */
+ outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+ spin_unlock_irqrestore(&spinlock, flags);
+
+ printk(KERN_INFO PFX "shutdown.\n");
+
+ return 0;
+}
+
+/*
+ * Send a keepalive ping to the watchdog
+ * This is done by simply re-writing the timeout to reg. 0xF2
+ */
+
+static int wdt_keepalive(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&spinlock, flags);
+
+ /* Unlock the SuperIO chip */
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+ /* Select device Aux2 (device=8) to kick watchdog reg F2 */
+ outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+ outb_p(0x08,IO_DATA_PORT);
+ outb_p(0xF2,IO_INDEX_PORT);
+ outb_p(timeoutW,IO_DATA_PORT);
+
+ /* Lock the SuperIO chip */
+ outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+ spin_unlock_irqrestore(&spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * Set the watchdog timeout value
+ */
+
+static int wdt_set_timeout(int t)
+{
+ int tmrval;
+
+ /*
+ * Convert seconds to watchdog counter time units, rounding up.
+ * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup
+ * value. This information is supplied in the PCM-5335 manual and was
+ * checked by me on a real board. This is a bit strange because W83977f
+ * datasheet says counter unit is in minutes!
+ */
+ if (t < 15)
+ return -EINVAL;
+
+ tmrval = ((t + 15) + 29) / 30;
+
+ if (tmrval > 255)
+ return -EINVAL;
+
+ /*
+ * timeout is the timeout in seconds,
+ * timeoutW is the timeout in watchdog counter units.
+ */
+ timeoutW = tmrval;
+ timeout = (timeoutW * 30) - 15;
+ return 0;
+}
+
+/*
+ * Get the watchdog status
+ */
+
+static int wdt_get_status(int *status)
+{
+ int new_status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&spinlock, flags);
+
+ /* Unlock the SuperIO chip */
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+ outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+ /* Select device Aux2 (device=8) to read watchdog reg F4 */
+ outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+ outb_p(0x08,IO_DATA_PORT);
+ outb_p(0xF4,IO_INDEX_PORT);
+ new_status = inb_p(IO_DATA_PORT);
+
+ /* Lock the SuperIO chip */
+ outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+ spin_unlock_irqrestore(&spinlock, flags);
+
+ *status = 0;
+ if (new_status & 1)
+ *status |= WDIOF_CARDRESET;
+
+ return 0;
+}
+
+
+/*
+ * /dev/watchdog handling
+ */
+
+static int wdt_open(struct inode *inode, struct file *file)
+{
+ /* If the watchdog is alive we don't need to start it again */
+ if( test_and_set_bit(0, &timer_alive) )
+ return -EBUSY;
+
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ wdt_start();
+ return nonseekable_open(inode, file);
+}
+
+static int wdt_release(struct inode *inode, struct file *file)
+{
+ /*
+ * Shut off the timer.
+ * Lock it in if it's a module and we set nowayout
+ */
+ if (expect_close == 42)
+ {
+ wdt_stop();
+ clear_bit(0, &timer_alive);
+ } else {
+ wdt_keepalive();
+ printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
+ }
+ expect_close = 0;
+ return 0;
+}
+
+/*
+ * wdt_write:
+ * @file: file handle to the watchdog
+ * @buf: buffer to write (unused as data does not matter here
+ * @count: count of bytes
+ * @ppos: pointer to the position to write. No seeks allowed
+ *
+ * A write to a watchdog device is defined as a keepalive signal. Any
+ * write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t wdt_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ /* See if we got the magic character 'V' and reload the timer */
+ if(count)
+ {
+ if (!nowayout)
+ {
+ size_t ofs;
+
+ /* note: just in case someone wrote the magic character long ago */
+ expect_close = 0;
+
+ /* scan to see whether or not we got the magic character */
+ for(ofs = 0; ofs != count; ofs++)
+ {
+ char c;
+ if (get_user(c, buf + ofs))
+ return -EFAULT;
+ if (c == 'V') {
+ expect_close = 42;
+ }
+ }
+ }
+
+ /* someone wrote to us, we should restart timer */
+ wdt_keepalive();
+ }
+ return count;
+}
+
+/*
+ * wdt_ioctl:
+ * @inode: inode of the device
+ * @file: file handle to the device
+ * @cmd: watchdog command
+ * @arg: argument pointer
+ *
+ * The watchdog API defines a common set of functions for all watchdogs
+ * according to their available features.
+ */
+
+static struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+ .firmware_version = 1,
+ .identity = WATCHDOG_NAME,
+};
+
+static int wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int status;
+ int new_options, retval = -EINVAL;
+ int new_timeout;
+ union {
+ struct watchdog_info __user *ident;
+ int __user *i;
+ } uarg;
+
+ uarg.i = (int __user *)arg;
+
+ switch(cmd)
+ {
+ default:
+ return -ENOIOCTLCMD;
+
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ wdt_get_status(&status);
+ return put_user(status, uarg.i);
+
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, uarg.i);
+
+ case WDIOC_KEEPALIVE:
+ wdt_keepalive();
+ return 0;
+
+ case WDIOC_SETOPTIONS:
+ if (get_user (new_options, uarg.i))
+ return -EFAULT;
+
+ if (new_options & WDIOS_DISABLECARD) {
+ wdt_stop();
+ retval = 0;
+ }
+
+ if (new_options & WDIOS_ENABLECARD) {
+ wdt_start();
+ retval = 0;
+ }
+
+ return retval;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_timeout, uarg.i))
+ return -EFAULT;
+
+ if (wdt_set_timeout(new_timeout))
+ return -EINVAL;
+
+ wdt_keepalive();
+ /* Fall */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(timeout, uarg.i);
+
+ }
+}
+
+static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ if (code==SYS_DOWN || code==SYS_HALT)
+ wdt_stop();
+ return NOTIFY_DONE;
+}
+
+static struct file_operations wdt_fops=
+{
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = wdt_write,
+ .ioctl = wdt_ioctl,
+ .open = wdt_open,
+ .release = wdt_release,
+};
+
+static struct miscdevice wdt_miscdev=
+{
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &wdt_fops,
+};
+
+static struct notifier_block wdt_notifier = {
+ .notifier_call = wdt_notify_sys,
+};
+
+static int __init w83977f_wdt_init(void)
+{
+ int rc;
+
+ printk(KERN_INFO PFX DRIVER_VERSION);
+
+ spin_lock_init(&spinlock);
+
+ /*
+ * Check that the timeout value is within it's range ;
+ * if not reset to the default
+ */
+ if (wdt_set_timeout(timeout)) {
+ wdt_set_timeout(DEFAULT_TIMEOUT);
+ printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n",
+ DEFAULT_TIMEOUT);
+ }
+
+ if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME))
+ {
+ printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
+ IO_INDEX_PORT);
+ rc = -EIO;
+ goto err_out;
+ }
+
+ rc = misc_register(&wdt_miscdev);
+ if (rc)
+ {
+ printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ wdt_miscdev.minor, rc);
+ goto err_out_region;
+ }
+
+ rc = register_reboot_notifier(&wdt_notifier);
+ if (rc)
+ {
+ printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+ rc);
+ goto err_out_miscdev;
+ }
+
+ printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
+ timeout, nowayout, testmode);
+
+ return 0;
+
+err_out_miscdev:
+ misc_deregister(&wdt_miscdev);
+err_out_region:
+ release_region(IO_INDEX_PORT,2);
+err_out:
+ return rc;
+}
+
+static void __exit w83977f_wdt_exit(void)
+{
+ wdt_stop();
+ misc_deregister(&wdt_miscdev);
+ unregister_reboot_notifier(&wdt_notifier);
+ release_region(IO_INDEX_PORT,2);
+}
+
+module_init(w83977f_wdt_init);
+module_exit(w83977f_wdt_exit);
+
+MODULE_AUTHOR("Jose Goncalves <jose.goncalves@inov.pt>");
+MODULE_DESCRIPTION("Driver for watchdog timer in W83977F I/O chip");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/connector/Kconfig b/drivers/connector/Kconfig
new file mode 100644
index 000000000000..0bc2059c1e08
--- /dev/null
+++ b/drivers/connector/Kconfig
@@ -0,0 +1,13 @@
+menu "Connector - unified userspace <-> kernelspace linker"
+
+config CONNECTOR
+ tristate "Connector - unified userspace <-> kernelspace linker"
+ depends on NET
+ ---help---
+ This is unified userspace <-> kernelspace connector working on top
+ of the netlink socket protocol.
+
+ Connector support can also be built as a module. If so, the module
+ will be called cn.ko.
+
+endmenu
diff --git a/drivers/connector/Makefile b/drivers/connector/Makefile
new file mode 100644
index 000000000000..12ca79e8234d
--- /dev/null
+++ b/drivers/connector/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_CONNECTOR) += cn.o
+
+cn-y += cn_queue.o connector.o
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
new file mode 100644
index 000000000000..9f2f00d82917
--- /dev/null
+++ b/drivers/connector/cn_queue.c
@@ -0,0 +1,179 @@
+/*
+ * cn_queue.c
+ *
+ * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ * 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. 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/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/suspend.h>
+#include <linux/connector.h>
+#include <linux/delay.h>
+
+void cn_queue_wrapper(void *data)
+{
+ struct cn_callback_data *d = data;
+
+ d->callback(d->callback_priv);
+
+ d->destruct_data(d->ddata);
+ d->ddata = NULL;
+
+ kfree(d->free);
+}
+
+static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struct cb_id *id, void (*callback)(void *))
+{
+ struct cn_callback_entry *cbq;
+
+ cbq = kzalloc(sizeof(*cbq), GFP_KERNEL);
+ if (!cbq) {
+ printk(KERN_ERR "Failed to create new callback queue.\n");
+ return NULL;
+ }
+
+ snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
+ memcpy(&cbq->id.id, id, sizeof(struct cb_id));
+ cbq->data.callback = callback;
+
+ INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data);
+ return cbq;
+}
+
+static void cn_queue_free_callback(struct cn_callback_entry *cbq)
+{
+ cancel_delayed_work(&cbq->work);
+ flush_workqueue(cbq->pdev->cn_queue);
+
+ kfree(cbq);
+}
+
+int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
+{
+ return ((i1->idx == i2->idx) && (i1->val == i2->val));
+}
+
+int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *))
+{
+ struct cn_callback_entry *cbq, *__cbq;
+ int found = 0;
+
+ cbq = cn_queue_alloc_callback_entry(name, id, callback);
+ if (!cbq)
+ return -ENOMEM;
+
+ atomic_inc(&dev->refcnt);
+ cbq->pdev = dev;
+
+ spin_lock_bh(&dev->queue_lock);
+ list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
+ if (cn_cb_equal(&__cbq->id.id, id)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ list_add_tail(&cbq->callback_entry, &dev->queue_list);
+ spin_unlock_bh(&dev->queue_lock);
+
+ if (found) {
+ atomic_dec(&dev->refcnt);
+ cn_queue_free_callback(cbq);
+ return -EINVAL;
+ }
+
+ cbq->nls = dev->nls;
+ cbq->seq = 0;
+ cbq->group = cbq->id.id.idx;
+
+ return 0;
+}
+
+void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
+{
+ struct cn_callback_entry *cbq, *n;
+ int found = 0;
+
+ spin_lock_bh(&dev->queue_lock);
+ list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) {
+ if (cn_cb_equal(&cbq->id.id, id)) {
+ list_del(&cbq->callback_entry);
+ found = 1;
+ break;
+ }
+ }
+ spin_unlock_bh(&dev->queue_lock);
+
+ if (found) {
+ cn_queue_free_callback(cbq);
+ atomic_dec_and_test(&dev->refcnt);
+ }
+}
+
+struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
+{
+ struct cn_queue_dev *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ snprintf(dev->name, sizeof(dev->name), "%s", name);
+ atomic_set(&dev->refcnt, 0);
+ INIT_LIST_HEAD(&dev->queue_list);
+ spin_lock_init(&dev->queue_lock);
+
+ dev->nls = nls;
+ dev->netlink_groups = 0;
+
+ dev->cn_queue = create_workqueue(dev->name);
+ if (!dev->cn_queue) {
+ kfree(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+
+void cn_queue_free_dev(struct cn_queue_dev *dev)
+{
+ struct cn_callback_entry *cbq, *n;
+
+ flush_workqueue(dev->cn_queue);
+ destroy_workqueue(dev->cn_queue);
+
+ spin_lock_bh(&dev->queue_lock);
+ list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
+ list_del(&cbq->callback_entry);
+ spin_unlock_bh(&dev->queue_lock);
+
+ while (atomic_read(&dev->refcnt)) {
+ printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
+ dev->name, atomic_read(&dev->refcnt));
+ msleep(1000);
+ }
+
+ kfree(dev);
+ dev = NULL;
+}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
new file mode 100644
index 000000000000..505677fb3157
--- /dev/null
+++ b/drivers/connector/connector.c
@@ -0,0 +1,488 @@
+/*
+ * connector.c
+ *
+ * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ * 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. 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/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/moduleparam.h>
+#include <linux/connector.h>
+
+#include <net/sock.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
+MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+
+static u32 cn_idx = CN_IDX_CONNECTOR;
+static u32 cn_val = CN_VAL_CONNECTOR;
+
+module_param(cn_idx, uint, 0);
+module_param(cn_val, uint, 0);
+MODULE_PARM_DESC(cn_idx, "Connector's main device idx.");
+MODULE_PARM_DESC(cn_val, "Connector's main device val.");
+
+static DECLARE_MUTEX(notify_lock);
+static LIST_HEAD(notify_list);
+
+static struct cn_dev cdev;
+
+int cn_already_initialized = 0;
+
+/*
+ * msg->seq and msg->ack are used to determine message genealogy.
+ * When someone sends message it puts there locally unique sequence
+ * and random acknowledge numbers. Sequence number may be copied into
+ * nlmsghdr->nlmsg_seq too.
+ *
+ * Sequence number is incremented with each message to be sent.
+ *
+ * If we expect reply to our message then the sequence number in
+ * received message MUST be the same as in original message, and
+ * acknowledge number MUST be the same + 1.
+ *
+ * If we receive a message and its sequence number is not equal to the
+ * one we are expecting then it is a new message.
+ *
+ * If we receive a message and its sequence number is the same as one
+ * we are expecting but it's acknowledgement number is not equal to
+ * the acknowledgement number in the original message + 1, then it is
+ * a new message.
+ *
+ */
+int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
+{
+ struct cn_callback_entry *__cbq;
+ unsigned int size;
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ struct cn_msg *data;
+ struct cn_dev *dev = &cdev;
+ u32 group = 0;
+ int found = 0;
+
+ if (!__group) {
+ spin_lock_bh(&dev->cbdev->queue_lock);
+ list_for_each_entry(__cbq, &dev->cbdev->queue_list,
+ callback_entry) {
+ if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
+ found = 1;
+ group = __cbq->group;
+ }
+ }
+ spin_unlock_bh(&dev->cbdev->queue_lock);
+
+ if (!found)
+ return -ENODEV;
+ } else {
+ group = __group;
+ }
+
+ size = NLMSG_SPACE(sizeof(*msg) + msg->len);
+
+ skb = alloc_skb(size, gfp_mask);
+ if (!skb)
+ return -ENOMEM;
+
+ nlh = NLMSG_PUT(skb, 0, msg->seq, NLMSG_DONE, size - sizeof(*nlh));
+
+ data = NLMSG_DATA(nlh);
+
+ memcpy(data, msg, sizeof(*data) + msg->len);
+
+ NETLINK_CB(skb).dst_group = group;
+
+ netlink_broadcast(dev->nls, skb, 0, group, gfp_mask);
+
+ return 0;
+
+nlmsg_failure:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/*
+ * Callback helper - queues work and setup destructor for given data.
+ */
+static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
+{
+ struct cn_callback_entry *__cbq;
+ struct cn_dev *dev = &cdev;
+ int err = -ENODEV;
+
+ spin_lock_bh(&dev->cbdev->queue_lock);
+ list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
+ if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
+ if (likely(!test_bit(0, &__cbq->work.pending) &&
+ __cbq->data.ddata == NULL)) {
+ __cbq->data.callback_priv = msg;
+
+ __cbq->data.ddata = data;
+ __cbq->data.destruct_data = destruct_data;
+
+ if (queue_work(dev->cbdev->cn_queue,
+ &__cbq->work))
+ err = 0;
+ } else {
+ struct work_struct *w;
+ struct cn_callback_data *d;
+
+ w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC);
+ if (w) {
+ d = (struct cn_callback_data *)(w+1);
+
+ d->callback_priv = msg;
+ d->callback = __cbq->data.callback;
+ d->ddata = data;
+ d->destruct_data = destruct_data;
+ d->free = w;
+
+ INIT_LIST_HEAD(&w->entry);
+ w->pending = 0;
+ w->func = &cn_queue_wrapper;
+ w->data = d;
+ init_timer(&w->timer);
+
+ if (queue_work(dev->cbdev->cn_queue, w))
+ err = 0;
+ else {
+ kfree(w);
+ err = -EINVAL;
+ }
+ } else
+ err = -ENOMEM;
+ }
+ break;
+ }
+ }
+ spin_unlock_bh(&dev->cbdev->queue_lock);
+
+ return err;
+}
+
+/*
+ * Skb receive helper - checks skb and msg size and calls callback
+ * helper.
+ */
+static int __cn_rx_skb(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ u32 pid, uid, seq, group;
+ struct cn_msg *msg;
+
+ pid = NETLINK_CREDS(skb)->pid;
+ uid = NETLINK_CREDS(skb)->uid;
+ seq = nlh->nlmsg_seq;
+ group = NETLINK_CB((skb)).dst_group;
+ msg = NLMSG_DATA(nlh);
+
+ return cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
+}
+
+/*
+ * Main netlink receiving function.
+ *
+ * It checks skb and netlink header sizes and calls the skb receive
+ * helper with a shared skb.
+ */
+static void cn_rx_skb(struct sk_buff *__skb)
+{
+ struct nlmsghdr *nlh;
+ u32 len;
+ int err;
+ struct sk_buff *skb;
+
+ skb = skb_get(__skb);
+
+ if (skb->len >= NLMSG_SPACE(0)) {
+ nlh = (struct nlmsghdr *)skb->data;
+
+ if (nlh->nlmsg_len < sizeof(struct cn_msg) ||
+ skb->len < nlh->nlmsg_len ||
+ nlh->nlmsg_len > CONNECTOR_MAX_MSG_SIZE) {
+ kfree_skb(skb);
+ goto out;
+ }
+
+ len = NLMSG_ALIGN(nlh->nlmsg_len);
+ if (len > skb->len)
+ len = skb->len;
+
+ err = __cn_rx_skb(skb, nlh);
+ if (err < 0)
+ kfree_skb(skb);
+ }
+
+out:
+ kfree_skb(__skb);
+}
+
+/*
+ * Netlink socket input callback - dequeues the skbs and calls the
+ * main netlink receiving function.
+ */
+static void cn_input(struct sock *sk, int len)
+{
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
+ cn_rx_skb(skb);
+}
+
+/*
+ * Notification routing.
+ *
+ * Gets id and checks if there are notification request for it's idx
+ * and val. If there are such requests notify the listeners with the
+ * given notify event.
+ *
+ */
+static void cn_notify(struct cb_id *id, u32 notify_event)
+{
+ struct cn_ctl_entry *ent;
+
+ down(&notify_lock);
+ list_for_each_entry(ent, &notify_list, notify_entry) {
+ int i;
+ struct cn_notify_req *req;
+ struct cn_ctl_msg *ctl = ent->msg;
+ int idx_found, val_found;
+
+ idx_found = val_found = 0;
+
+ req = (struct cn_notify_req *)ctl->data;
+ for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
+ if (id->idx >= req->first &&
+ id->idx < req->first + req->range) {
+ idx_found = 1;
+ break;
+ }
+ }
+
+ for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
+ if (id->val >= req->first &&
+ id->val < req->first + req->range) {
+ val_found = 1;
+ break;
+ }
+ }
+
+ if (idx_found && val_found) {
+ struct cn_msg m = { .ack = notify_event, };
+
+ memcpy(&m.id, id, sizeof(m.id));
+ cn_netlink_send(&m, ctl->group, GFP_KERNEL);
+ }
+ }
+ up(&notify_lock);
+}
+
+/*
+ * Callback add routing - adds callback with given ID and name.
+ * If there is registered callback with the same ID it will not be added.
+ *
+ * May sleep.
+ */
+int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *))
+{
+ int err;
+ struct cn_dev *dev = &cdev;
+
+ err = cn_queue_add_callback(dev->cbdev, name, id, callback);
+ if (err)
+ return err;
+
+ cn_notify(id, 0);
+
+ return 0;
+}
+
+/*
+ * Callback remove routing - removes callback
+ * with given ID.
+ * If there is no registered callback with given
+ * ID nothing happens.
+ *
+ * May sleep while waiting for reference counter to become zero.
+ */
+void cn_del_callback(struct cb_id *id)
+{
+ struct cn_dev *dev = &cdev;
+
+ cn_queue_del_callback(dev->cbdev, id);
+ cn_notify(id, 1);
+}
+
+/*
+ * Checks two connector's control messages to be the same.
+ * Returns 1 if they are the same or if the first one is corrupted.
+ */
+static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
+{
+ int i;
+ struct cn_notify_req *req1, *req2;
+
+ if (m1->idx_notify_num != m2->idx_notify_num)
+ return 0;
+
+ if (m1->val_notify_num != m2->val_notify_num)
+ return 0;
+
+ if (m1->len != m2->len)
+ return 0;
+
+ if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) !=
+ m1->len)
+ return 1;
+
+ req1 = (struct cn_notify_req *)m1->data;
+ req2 = (struct cn_notify_req *)m2->data;
+
+ for (i = 0; i < m1->idx_notify_num; ++i) {
+ if (req1->first != req2->first || req1->range != req2->range)
+ return 0;
+ req1++;
+ req2++;
+ }
+
+ for (i = 0; i < m1->val_notify_num; ++i) {
+ if (req1->first != req2->first || req1->range != req2->range)
+ return 0;
+ req1++;
+ req2++;
+ }
+
+ return 1;
+}
+
+/*
+ * Main connector device's callback.
+ *
+ * Used for notification of a request's processing.
+ */
+static void cn_callback(void *data)
+{
+ struct cn_msg *msg = data;
+ struct cn_ctl_msg *ctl;
+ struct cn_ctl_entry *ent;
+ u32 size;
+
+ if (msg->len < sizeof(*ctl))
+ return;
+
+ ctl = (struct cn_ctl_msg *)msg->data;
+
+ size = (sizeof(*ctl) + ((ctl->idx_notify_num +
+ ctl->val_notify_num) *
+ sizeof(struct cn_notify_req)));
+
+ if (msg->len != size)
+ return;
+
+ if (ctl->len + sizeof(*ctl) != msg->len)
+ return;
+
+ /*
+ * Remove notification.
+ */
+ if (ctl->group == 0) {
+ struct cn_ctl_entry *n;
+
+ down(&notify_lock);
+ list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
+ if (cn_ctl_msg_equals(ent->msg, ctl)) {
+ list_del(&ent->notify_entry);
+ kfree(ent);
+ }
+ }
+ up(&notify_lock);
+
+ return;
+ }
+
+ size += sizeof(*ent);
+
+ ent = kzalloc(size, GFP_KERNEL);
+ if (!ent)
+ return;
+
+ ent->msg = (struct cn_ctl_msg *)(ent + 1);
+
+ memcpy(ent->msg, ctl, size - sizeof(*ent));
+
+ down(&notify_lock);
+ list_add(&ent->notify_entry, &notify_list);
+ up(&notify_lock);
+}
+
+static int __init cn_init(void)
+{
+ struct cn_dev *dev = &cdev;
+ int err;
+
+ dev->input = cn_input;
+ dev->id.idx = cn_idx;
+ dev->id.val = cn_val;
+
+ dev->nls = netlink_kernel_create(NETLINK_CONNECTOR,
+ CN_NETLINK_USERS + 0xf,
+ dev->input, THIS_MODULE);
+ if (!dev->nls)
+ return -EIO;
+
+ dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls);
+ if (!dev->cbdev) {
+ if (dev->nls->sk_socket)
+ sock_release(dev->nls->sk_socket);
+ return -EINVAL;
+ }
+
+ err = cn_add_callback(&dev->id, "connector", &cn_callback);
+ if (err) {
+ cn_queue_free_dev(dev->cbdev);
+ if (dev->nls->sk_socket)
+ sock_release(dev->nls->sk_socket);
+ return -EINVAL;
+ }
+
+ cn_already_initialized = 1;
+
+ return 0;
+}
+
+static void __exit cn_fini(void)
+{
+ struct cn_dev *dev = &cdev;
+
+ cn_already_initialized = 0;
+
+ cn_del_callback(&dev->id);
+ cn_queue_free_dev(dev->cbdev);
+ if (dev->nls->sk_socket)
+ sock_release(dev->nls->sk_socket);
+}
+
+module_init(cn_init);
+module_exit(cn_fini);
+
+EXPORT_SYMBOL_GPL(cn_add_callback);
+EXPORT_SYMBOL_GPL(cn_del_callback);
+EXPORT_SYMBOL_GPL(cn_netlink_send);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 10b014982381..109d62ccf651 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -627,7 +627,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
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/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index e1df376e709e..2ed5c4363b53 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -315,9 +315,9 @@ static void dbs_check_cpu(int cpu)
policy = this_dbs_info->cur_policy;
if ( init_flag == 0 ) {
- for ( /* NULL */; init_flag < NR_CPUS; init_flag++ ) {
- dbs_info = &per_cpu(cpu_dbs_info, init_flag);
- requested_freq[cpu] = dbs_info->cur_policy->cur;
+ for_each_online_cpu(j) {
+ dbs_info = &per_cpu(cpu_dbs_info, j);
+ requested_freq[j] = dbs_info->cur_policy->cur;
}
init_flag = 1;
}
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 3b865f34a095..4f4ba9b6d182 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -50,7 +50,7 @@
MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
MODULE_LICENSE("GPL");
-MODULE_VERSION("1.0");
+MODULE_VERSION("3.0");
#define BIOS_SCAN_LIMIT 0xffffffff
#define MAX_IMAGE_LENGTH 16
@@ -62,14 +62,16 @@ static struct _rbu_data {
int dma_alloc;
spinlock_t lock;
unsigned long packet_read_count;
- unsigned long packet_write_count;
unsigned long num_packets;
unsigned long packetsize;
+ unsigned long imagesize;
+ int entry_created;
} rbu_data;
-static char image_type[MAX_IMAGE_LENGTH] = "mono";
-module_param_string(image_type, image_type, sizeof(image_type), 0);
-MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet");
+static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
+module_param_string(image_type, image_type, sizeof (image_type), 0);
+MODULE_PARM_DESC(image_type,
+ "BIOS image type. choose- mono or packet or init");
struct packet_data {
struct list_head list;
@@ -87,55 +89,13 @@ static dma_addr_t dell_rbu_dmaaddr;
static void init_packet_head(void)
{
INIT_LIST_HEAD(&packet_data_head.list);
- rbu_data.packet_write_count = 0;
rbu_data.packet_read_count = 0;
rbu_data.num_packets = 0;
rbu_data.packetsize = 0;
+ rbu_data.imagesize = 0;
}
-static int fill_last_packet(void *data, size_t length)
-{
- struct list_head *ptemp_list;
- struct packet_data *packet = NULL;
- int packet_count = 0;
-
- pr_debug("fill_last_packet: entry \n");
-
- if (!rbu_data.num_packets) {
- pr_debug("fill_last_packet: num_packets=0\n");
- return -ENOMEM;
- }
-
- packet_count = rbu_data.num_packets;
-
- ptemp_list = (&packet_data_head.list)->prev;
-
- packet = list_entry(ptemp_list, struct packet_data, list);
-
- if ((rbu_data.packet_write_count + length) > rbu_data.packetsize) {
- pr_debug("dell_rbu:%s: packet size data "
- "overrun\n", __FUNCTION__);
- return -EINVAL;
- }
-
- pr_debug("fill_last_packet : buffer = %p\n", packet->data);
-
- memcpy((packet->data + rbu_data.packet_write_count), data, length);
-
- if ((rbu_data.packet_write_count + length) == rbu_data.packetsize) {
- /*
- * this was the last data chunk in the packet
- * so reinitialize the packet data counter to zero
- */
- rbu_data.packet_write_count = 0;
- } else
- rbu_data.packet_write_count += length;
-
- pr_debug("fill_last_packet: exit \n");
- return 0;
-}
-
-static int create_packet(size_t length)
+static int create_packet(void *data, size_t length)
{
struct packet_data *newpacket;
int ordernum = 0;
@@ -146,12 +106,14 @@ static int create_packet(size_t length)
pr_debug("create_packet: packetsize not specified\n");
return -EINVAL;
}
+ spin_unlock(&rbu_data.lock);
+ newpacket = kmalloc(sizeof (struct packet_data), GFP_KERNEL);
+ spin_lock(&rbu_data.lock);
- newpacket = kmalloc(sizeof(struct packet_data), GFP_KERNEL);
if (!newpacket) {
printk(KERN_WARNING
- "dell_rbu:%s: failed to allocate new "
- "packet\n", __FUNCTION__);
+ "dell_rbu:%s: failed to allocate new "
+ "packet\n", __FUNCTION__);
return -ENOMEM;
}
@@ -160,15 +122,17 @@ static int create_packet(size_t length)
* there is no upper limit on memory
* address for packetized mechanism
*/
- newpacket->data = (unsigned char *)__get_free_pages(GFP_KERNEL,
- ordernum);
+ spin_unlock(&rbu_data.lock);
+ newpacket->data = (unsigned char *) __get_free_pages(GFP_KERNEL,
+ ordernum);
+ spin_lock(&rbu_data.lock);
pr_debug("create_packet: newpacket %p\n", newpacket->data);
if (!newpacket->data) {
printk(KERN_WARNING
- "dell_rbu:%s: failed to allocate new "
- "packet\n", __FUNCTION__);
+ "dell_rbu:%s: failed to allocate new "
+ "packet\n", __FUNCTION__);
kfree(newpacket);
return -ENOMEM;
}
@@ -181,9 +145,11 @@ static int create_packet(size_t length)
INIT_LIST_HEAD(&newpacket->list);
list_add_tail(&newpacket->list, &packet_data_head.list);
/*
- * packets have fixed size
+ * packets may not have fixed size
*/
- newpacket->length = rbu_data.packetsize;
+ newpacket->length = length;
+
+ memcpy(newpacket->data, data, length);
pr_debug("create_packet: exit \n");
@@ -193,20 +159,43 @@ static int create_packet(size_t length)
static int packetize_data(void *data, size_t length)
{
int rc = 0;
+ int done = 0;
+ int packet_length;
+ u8 *temp;
+ u8 *end = (u8 *) data + length;
+ pr_debug("packetize_data: data length %d\n", length);
+ if (!rbu_data.packetsize) {
+ printk(KERN_WARNING
+ "dell_rbu: packetsize not specified\n");
+ return -EIO;
+ }
+
+ temp = (u8 *) data;
- if (!rbu_data.packet_write_count) {
- if ((rc = create_packet(length)))
+ /* packetize the hunk */
+ while (!done) {
+ if ((temp + rbu_data.packetsize) < end)
+ packet_length = rbu_data.packetsize;
+ else {
+ /* this is the last packet */
+ packet_length = end - temp;
+ done = 1;
+ }
+
+ if ((rc = create_packet(temp, packet_length)))
return rc;
+
+ pr_debug("%lu:%lu\n", temp, (end - temp));
+ temp += packet_length;
}
- if ((rc = fill_last_packet(data, length)))
- return rc;
+
+ rbu_data.imagesize = length;
return rc;
}
-static int
-do_packet_read(char *data, struct list_head *ptemp_list,
- int length, int bytes_read, int *list_read_count)
+static int do_packet_read(char *data, struct list_head *ptemp_list,
+ int length, int bytes_read, int *list_read_count)
{
void *ptemp_buf;
struct packet_data *newpacket = NULL;
@@ -258,8 +247,7 @@ static int packet_read_list(char *data, size_t * pread_length)
ptemp_list = (&packet_data_head.list)->next;
while (!list_empty(ptemp_list)) {
bytes_copied = do_packet_read(pdest, ptemp_list,
- remaining_bytes, bytes_read,
- &temp_count);
+ remaining_bytes, bytes_read, &temp_count);
remaining_bytes -= bytes_copied;
bytes_read += bytes_copied;
pdest += bytes_copied;
@@ -287,7 +275,7 @@ static void packet_empty_list(void)
ptemp_list = (&packet_data_head.list)->next;
while (!list_empty(ptemp_list)) {
newpacket =
- list_entry(ptemp_list, struct packet_data, list);
+ list_entry(ptemp_list, struct packet_data, list);
pnext_list = ptemp_list->next;
list_del(ptemp_list);
ptemp_list = pnext_list;
@@ -296,14 +284,13 @@ static void packet_empty_list(void)
* to make sure there are no stale RBU packets left in memory
*/
memset(newpacket->data, 0, rbu_data.packetsize);
- free_pages((unsigned long)newpacket->data,
- newpacket->ordernum);
+ free_pages((unsigned long) newpacket->data,
+ newpacket->ordernum);
kfree(newpacket);
}
- rbu_data.packet_write_count = 0;
rbu_data.packet_read_count = 0;
rbu_data.num_packets = 0;
- rbu_data.packetsize = 0;
+ rbu_data.imagesize = 0;
}
/*
@@ -319,14 +306,13 @@ static void img_update_free(void)
* BIOS image copied in memory.
*/
memset(rbu_data.image_update_buffer, 0,
- rbu_data.image_update_buffer_size);
+ rbu_data.image_update_buffer_size);
if (rbu_data.dma_alloc == 1)
dma_free_coherent(NULL, rbu_data.bios_image_size,
- rbu_data.image_update_buffer,
- dell_rbu_dmaaddr);
+ rbu_data.image_update_buffer, dell_rbu_dmaaddr);
else
- free_pages((unsigned long)rbu_data.image_update_buffer,
- rbu_data.image_update_ordernum);
+ free_pages((unsigned long) rbu_data.image_update_buffer,
+ rbu_data.image_update_ordernum);
/*
* Re-initialize the rbu_data variables after a free
@@ -366,7 +352,7 @@ static int img_update_realloc(unsigned long size)
*/
if ((size != 0) && (rbu_data.image_update_buffer == NULL)) {
printk(KERN_ERR "dell_rbu:%s: corruption "
- "check failed\n", __FUNCTION__);
+ "check failed\n", __FUNCTION__);
return -EINVAL;
}
/*
@@ -385,17 +371,16 @@ static int img_update_realloc(unsigned long size)
ordernum = get_order(size);
image_update_buffer =
- (unsigned char *)__get_free_pages(GFP_KERNEL, ordernum);
+ (unsigned char *) __get_free_pages(GFP_KERNEL, ordernum);
img_buf_phys_addr =
- (unsigned long)virt_to_phys(image_update_buffer);
+ (unsigned long) virt_to_phys(image_update_buffer);
if (img_buf_phys_addr > BIOS_SCAN_LIMIT) {
- free_pages((unsigned long)image_update_buffer, ordernum);
+ free_pages((unsigned long) image_update_buffer, ordernum);
ordernum = -1;
image_update_buffer = dma_alloc_coherent(NULL, size,
- &dell_rbu_dmaaddr,
- GFP_KERNEL);
+ &dell_rbu_dmaaddr, GFP_KERNEL);
dma_alloc = 1;
}
@@ -405,13 +390,13 @@ static int img_update_realloc(unsigned long size)
rbu_data.image_update_buffer = image_update_buffer;
rbu_data.image_update_buffer_size = size;
rbu_data.bios_image_size =
- rbu_data.image_update_buffer_size;
+ rbu_data.image_update_buffer_size;
rbu_data.image_update_ordernum = ordernum;
rbu_data.dma_alloc = dma_alloc;
rc = 0;
} else {
pr_debug("Not enough memory for image update:"
- "size = %ld\n", size);
+ "size = %ld\n", size);
rc = -ENOMEM;
}
@@ -424,7 +409,6 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
size_t bytes_left;
size_t data_length;
char *ptempBuf = buffer;
- unsigned long imagesize;
/* check to see if we have something to return */
if (rbu_data.num_packets == 0) {
@@ -433,22 +417,20 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
goto read_rbu_data_exit;
}
- imagesize = rbu_data.num_packets * rbu_data.packetsize;
-
- if (pos > imagesize) {
+ if (pos > rbu_data.imagesize) {
retval = 0;
printk(KERN_WARNING "dell_rbu:read_packet_data: "
- "data underrun\n");
+ "data underrun\n");
goto read_rbu_data_exit;
}
- bytes_left = imagesize - pos;
+ bytes_left = rbu_data.imagesize - pos;
data_length = min(bytes_left, count);
if ((retval = packet_read_list(ptempBuf, &data_length)) < 0)
goto read_rbu_data_exit;
- if ((pos + count) > imagesize) {
+ if ((pos + count) > rbu_data.imagesize) {
rbu_data.packet_read_count = 0;
/* this was the last copy */
retval = bytes_left;
@@ -468,11 +450,11 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
/* check to see if we have something to return */
if ((rbu_data.image_update_buffer == NULL) ||
- (rbu_data.bios_image_size == 0)) {
+ (rbu_data.bios_image_size == 0)) {
pr_debug("read_rbu_data_mono: image_update_buffer %p ,"
- "bios_image_size %lu\n",
- rbu_data.image_update_buffer,
- rbu_data.bios_image_size);
+ "bios_image_size %lu\n",
+ rbu_data.image_update_buffer,
+ rbu_data.bios_image_size);
ret_count = -ENOMEM;
goto read_rbu_data_exit;
}
@@ -497,8 +479,8 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
return ret_count;
}
-static ssize_t
-read_rbu_data(struct kobject *kobj, char *buffer, loff_t pos, size_t count)
+static ssize_t read_rbu_data(struct kobject *kobj, char *buffer,
+ loff_t pos, size_t count)
{
ssize_t ret_count = 0;
@@ -515,9 +497,49 @@ read_rbu_data(struct kobject *kobj, char *buffer, loff_t pos, size_t count)
return ret_count;
}
-static ssize_t
-read_rbu_image_type(struct kobject *kobj, char *buffer, loff_t pos,
- size_t count)
+static void callbackfn_rbu(const struct firmware *fw, void *context)
+{
+ int rc = 0;
+
+ if (!fw || !fw->size) {
+ rbu_data.entry_created = 0;
+ return;
+ }
+
+ spin_lock(&rbu_data.lock);
+ if (!strcmp(image_type, "mono")) {
+ if (!img_update_realloc(fw->size))
+ memcpy(rbu_data.image_update_buffer,
+ fw->data, fw->size);
+ } else if (!strcmp(image_type, "packet")) {
+ /*
+ * we need to free previous packets if a
+ * new hunk of packets needs to be downloaded
+ */
+ packet_empty_list();
+ if (packetize_data(fw->data, fw->size))
+ /* Incase something goes wrong when we are
+ * in middle of packetizing the data, we
+ * need to free up whatever packets might
+ * have been created before we quit.
+ */
+ packet_empty_list();
+ } else
+ pr_debug("invalid image type specified.\n");
+ spin_unlock(&rbu_data.lock);
+
+ rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
+ "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu);
+ if (rc)
+ printk(KERN_ERR
+ "dell_rbu:%s request_firmware_nowait failed"
+ " %d\n", __FUNCTION__, rc);
+ else
+ rbu_data.entry_created = 1;
+}
+
+static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
+ loff_t pos, size_t count)
{
int size = 0;
if (!pos)
@@ -525,27 +547,90 @@ read_rbu_image_type(struct kobject *kobj, char *buffer, loff_t pos,
return size;
}
-static ssize_t
-write_rbu_image_type(struct kobject *kobj, char *buffer, loff_t pos,
- size_t count)
+static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
+ loff_t pos, size_t count)
{
int rc = count;
+ int req_firm_rc = 0;
+ int i;
spin_lock(&rbu_data.lock);
-
- if (strlen(buffer) < MAX_IMAGE_LENGTH)
- sscanf(buffer, "%s", image_type);
- else
- printk(KERN_WARNING "dell_rbu: image_type is invalid"
- "max chars = %d, \n incoming str--%s-- \n",
- MAX_IMAGE_LENGTH, buffer);
+ /*
+ * Find the first newline or space
+ */
+ for (i = 0; i < count; ++i)
+ if (buffer[i] == '\n' || buffer[i] == ' ') {
+ buffer[i] = '\0';
+ break;
+ }
+ if (i == count)
+ buffer[count] = '\0';
+
+ if (strstr(buffer, "mono"))
+ strcpy(image_type, "mono");
+ else if (strstr(buffer, "packet"))
+ strcpy(image_type, "packet");
+ else if (strstr(buffer, "init")) {
+ /*
+ * If due to the user error the driver gets in a bad
+ * state where even though it is loaded , the
+ * /sys/class/firmware/dell_rbu entries are missing.
+ * to cover this situation the user can recreate entries
+ * by writing init to image_type.
+ */
+ if (!rbu_data.entry_created) {
+ spin_unlock(&rbu_data.lock);
+ req_firm_rc = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_NOHOTPLUG, "dell_rbu",
+ &rbu_device->dev, &context,
+ callbackfn_rbu);
+ if (req_firm_rc) {
+ printk(KERN_ERR
+ "dell_rbu:%s request_firmware_nowait"
+ " failed %d\n", __FUNCTION__, rc);
+ rc = -EIO;
+ } else
+ rbu_data.entry_created = 1;
+
+ spin_lock(&rbu_data.lock);
+ }
+ } else {
+ printk(KERN_WARNING "dell_rbu: image_type is invalid\n");
+ spin_unlock(&rbu_data.lock);
+ return -EINVAL;
+ }
/* we must free all previous allocations */
packet_empty_list();
img_update_free();
-
spin_unlock(&rbu_data.lock);
+
return rc;
+}
+static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
+ loff_t pos, size_t count)
+{
+ int size = 0;
+ if (!pos) {
+ spin_lock(&rbu_data.lock);
+ size = sprintf(buffer, "%lu\n", rbu_data.packetsize);
+ spin_unlock(&rbu_data.lock);
+ }
+ return size;
+}
+
+static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
+ loff_t pos, size_t count)
+{
+ unsigned long temp;
+ spin_lock(&rbu_data.lock);
+ packet_empty_list();
+ sscanf(buffer, "%lu", &temp);
+ if (temp < 0xffffffff)
+ rbu_data.packetsize = temp;
+
+ spin_unlock(&rbu_data.lock);
+ return count;
}
static struct bin_attribute rbu_data_attr = {
@@ -559,38 +644,11 @@ static struct bin_attribute rbu_image_type_attr = {
.write = write_rbu_image_type,
};
-static void callbackfn_rbu(const struct firmware *fw, void *context)
-{
- int rc = 0;
-
- if (!fw || !fw->size)
- return;
-
- spin_lock(&rbu_data.lock);
- if (!strcmp(image_type, "mono")) {
- if (!img_update_realloc(fw->size))
- memcpy(rbu_data.image_update_buffer,
- fw->data, fw->size);
- } else if (!strcmp(image_type, "packet")) {
- if (!rbu_data.packetsize)
- rbu_data.packetsize = fw->size;
- else if (rbu_data.packetsize != fw->size) {
- packet_empty_list();
- rbu_data.packetsize = fw->size;
- }
- packetize_data(fw->data, fw->size);
- } else
- pr_debug("invalid image type specified.\n");
- spin_unlock(&rbu_data.lock);
-
- rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
- "dell_rbu", &rbu_device->dev,
- &context, callbackfn_rbu);
- if (rc)
- printk(KERN_ERR
- "dell_rbu:%s request_firmware_nowait failed"
- " %d\n", __FUNCTION__, rc);
-}
+static struct bin_attribute rbu_packet_size_attr = {
+ .attr = {.name = "packet_size",.owner = THIS_MODULE,.mode = 0644},
+ .read = read_rbu_packet_size,
+ .write = write_rbu_packet_size,
+};
static int __init dcdrbu_init(void)
{
@@ -599,23 +657,26 @@ static int __init dcdrbu_init(void)
init_packet_head();
rbu_device =
- platform_device_register_simple("dell_rbu", -1, NULL, 0);
+ platform_device_register_simple("dell_rbu", -1, NULL, 0);
if (!rbu_device) {
printk(KERN_ERR
- "dell_rbu:%s:platform_device_register_simple "
- "failed\n", __FUNCTION__);
+ "dell_rbu:%s:platform_device_register_simple "
+ "failed\n", __FUNCTION__);
return -EIO;
}
sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+ sysfs_create_bin_file(&rbu_device->dev.kobj,
+ &rbu_packet_size_attr);
rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
- "dell_rbu", &rbu_device->dev,
- &context, callbackfn_rbu);
+ "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu);
if (rc)
printk(KERN_ERR "dell_rbu:%s:request_firmware_nowait"
- " failed %d\n", __FUNCTION__, rc);
+ " failed %d\n", __FUNCTION__, rc);
+ else
+ rbu_data.entry_created = 1;
return rc;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 138dc50270e3..db358cfa7cbf 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -411,6 +411,22 @@ config SENSORS_W83627EHF
This driver can also be built as a module. If so, the module
will be called w83627ehf.
+config SENSORS_HDAPS
+ tristate "IBM Hard Drive Active Protection System (hdaps)"
+ depends on HWMON && INPUT && X86
+ default n
+ help
+ This driver provides support for the IBM Hard Drive Active Protection
+ System (hdaps), which provides an accelerometer and other misc. data.
+ ThinkPads starting with the R50, T41, and X40 are supported. The
+ accelerometer data is readable via sysfs.
+
+ This driver also provides an absolute input class device, allowing
+ the laptop to act as a pinball machine-esque joystick.
+
+ Say Y here if you have an applicable laptop and want to experience
+ the awesome power of hdaps.
+
config HWMON_DEBUG_CHIP
bool "Hardware Monitoring Chip debugging messages"
depends on HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 381f1bf04cc5..f7d6a2f61ee7 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
+obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_LM63) += lm63.o
obj-$(CONFIG_SENSORS_LM75) += lm75.o
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
new file mode 100644
index 000000000000..7f0107613827
--- /dev/null
+++ b/drivers/hwmon/hdaps.c
@@ -0,0 +1,616 @@
+/*
+ * drivers/hwmon/hdaps.c - driver for IBM's Hard Drive Active Protection System
+ *
+ * Copyright (C) 2005 Robert Love <rml@novell.com>
+ * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
+ *
+ * The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads
+ * starting with the R40, T41, and X40. It provides a basic two-axis
+ * accelerometer and other data, such as the device's temperature.
+ *
+ * This driver is based on the document by Mark A. Smith available at
+ * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial
+ * and error.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/dmi.h>
+#include <asm/io.h>
+
+#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
+#define HDAPS_NR_PORTS 0x30 /* number of ports: 0x1600 - 0x162f */
+
+#define HDAPS_PORT_STATE 0x1611 /* device state */
+#define HDAPS_PORT_YPOS 0x1612 /* y-axis position */
+#define HDAPS_PORT_XPOS 0x1614 /* x-axis position */
+#define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in celcius */
+#define HDAPS_PORT_YVAR 0x1617 /* y-axis variance (what is this?) */
+#define HDAPS_PORT_XVAR 0x1619 /* x-axis variance (what is this?) */
+#define HDAPS_PORT_TEMP2 0x161b /* device temperature (again?) */
+#define HDAPS_PORT_UNKNOWN 0x161c /* what is this? */
+#define HDAPS_PORT_KMACT 0x161d /* keyboard or mouse activity */
+
+#define STATE_FRESH 0x50 /* accelerometer data is fresh */
+
+#define KEYBD_MASK 0x20 /* set if keyboard activity */
+#define MOUSE_MASK 0x40 /* set if mouse activity */
+#define KEYBD_ISSET(n) (!! (n & KEYBD_MASK)) /* keyboard used? */
+#define MOUSE_ISSET(n) (!! (n & MOUSE_MASK)) /* mouse used? */
+
+#define INIT_TIMEOUT_MSECS 4000 /* wait up to 4s for device init ... */
+#define INIT_WAIT_MSECS 200 /* ... in 200ms increments */
+
+#define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
+#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
+
+static struct timer_list hdaps_timer;
+static struct platform_device *pdev;
+static unsigned int hdaps_invert;
+static u8 km_activity;
+static int rest_x;
+static int rest_y;
+
+static DECLARE_MUTEX(hdaps_sem);
+
+/*
+ * __get_latch - Get the value from a given port. Callers must hold hdaps_sem.
+ */
+static inline u8 __get_latch(u16 port)
+{
+ return inb(port) & 0xff;
+}
+
+/*
+ * __check_latch - Check a port latch for a given value. Returns zero if the
+ * port contains the given value. Callers must hold hdaps_sem.
+ */
+static inline int __check_latch(u16 port, u8 val)
+{
+ if (__get_latch(port) == val)
+ return 0;
+ return -EINVAL;
+}
+
+/*
+ * __wait_latch - Wait up to 100us for a port latch to get a certain value,
+ * returning zero if the value is obtained. Callers must hold hdaps_sem.
+ */
+static int __wait_latch(u16 port, u8 val)
+{
+ unsigned int i;
+
+ for (i = 0; i < 20; i++) {
+ if (!__check_latch(port, val))
+ return 0;
+ udelay(5);
+ }
+
+ return -EIO;
+}
+
+/*
+ * __device_refresh - request a refresh from the accelerometer. Does not wait
+ * for refresh to complete. Callers must hold hdaps_sem.
+ */
+static void __device_refresh(void)
+{
+ udelay(200);
+ if (inb(0x1604) != STATE_FRESH) {
+ outb(0x11, 0x1610);
+ outb(0x01, 0x161f);
+ }
+}
+
+/*
+ * __device_refresh_sync - request a synchronous refresh from the
+ * accelerometer. We wait for the refresh to complete. Returns zero if
+ * successful and nonzero on error. Callers must hold hdaps_sem.
+ */
+static int __device_refresh_sync(void)
+{
+ __device_refresh();
+ return __wait_latch(0x1604, STATE_FRESH);
+}
+
+/*
+ * __device_complete - indicate to the accelerometer that we are done reading
+ * data, and then initiate an async refresh. Callers must hold hdaps_sem.
+ */
+static inline void __device_complete(void)
+{
+ inb(0x161f);
+ inb(0x1604);
+ __device_refresh();
+}
+
+/*
+ * hdaps_readb_one - reads a byte from a single I/O port, placing the value in
+ * the given pointer. Returns zero on success or a negative error on failure.
+ * Can sleep.
+ */
+static int hdaps_readb_one(unsigned int port, u8 *val)
+{
+ int ret;
+
+ down(&hdaps_sem);
+
+ /* do a sync refresh -- we need to be sure that we read fresh data */
+ ret = __device_refresh_sync();
+ if (ret)
+ goto out;
+
+ *val = inb(port);
+ __device_complete();
+
+out:
+ up(&hdaps_sem);
+ return ret;
+}
+
+/* __hdaps_read_pair - internal lockless helper for hdaps_read_pair(). */
+static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
+ int *x, int *y)
+{
+ /* do a sync refresh -- we need to be sure that we read fresh data */
+ if (__device_refresh_sync())
+ return -EIO;
+
+ *y = inw(port2);
+ *x = inw(port1);
+ km_activity = inb(HDAPS_PORT_KMACT);
+ __device_complete();
+
+ /* if hdaps_invert is set, negate the two values */
+ if (hdaps_invert) {
+ *x = -*x;
+ *y = -*y;
+ }
+
+ return 0;
+}
+
+/*
+ * hdaps_read_pair - reads the values from a pair of ports, placing the values
+ * in the given pointers. Returns zero on success. Can sleep.
+ */
+static int hdaps_read_pair(unsigned int port1, unsigned int port2,
+ int *val1, int *val2)
+{
+ int ret;
+
+ down(&hdaps_sem);
+ ret = __hdaps_read_pair(port1, port2, val1, val2);
+ up(&hdaps_sem);
+
+ return ret;
+}
+
+/*
+ * hdaps_device_init - initialize the accelerometer. Returns zero on success
+ * and negative error code on failure. Can sleep.
+ */
+static int hdaps_device_init(void)
+{
+ int total, ret = -ENXIO;
+
+ down(&hdaps_sem);
+
+ outb(0x13, 0x1610);
+ outb(0x01, 0x161f);
+ if (__wait_latch(0x161f, 0x00))
+ goto out;
+
+ /*
+ * Most ThinkPads return 0x01.
+ *
+ * Others--namely the R50p, T41p, and T42p--return 0x03. These laptops
+ * have "inverted" axises.
+ *
+ * The 0x02 value occurs when the chip has been previously initialized.
+ */
+ if (__check_latch(0x1611, 0x03) &&
+ __check_latch(0x1611, 0x02) &&
+ __check_latch(0x1611, 0x01))
+ goto out;
+
+ printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x).\n",
+ __get_latch(0x1611));
+
+ outb(0x17, 0x1610);
+ outb(0x81, 0x1611);
+ outb(0x01, 0x161f);
+ if (__wait_latch(0x161f, 0x00))
+ goto out;
+ if (__wait_latch(0x1611, 0x00))
+ goto out;
+ if (__wait_latch(0x1612, 0x60))
+ goto out;
+ if (__wait_latch(0x1613, 0x00))
+ goto out;
+ outb(0x14, 0x1610);
+ outb(0x01, 0x1611);
+ outb(0x01, 0x161f);
+ if (__wait_latch(0x161f, 0x00))
+ goto out;
+ outb(0x10, 0x1610);
+ outb(0xc8, 0x1611);
+ outb(0x00, 0x1612);
+ outb(0x02, 0x1613);
+ outb(0x01, 0x161f);
+ if (__wait_latch(0x161f, 0x00))
+ goto out;
+ if (__device_refresh_sync())
+ goto out;
+ if (__wait_latch(0x1611, 0x00))
+ goto out;
+
+ /* we have done our dance, now let's wait for the applause */
+ for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
+ int x, y;
+
+ /* a read of the device helps push it into action */
+ __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y);
+ if (!__wait_latch(0x1611, 0x02)) {
+ ret = 0;
+ break;
+ }
+
+ msleep(INIT_WAIT_MSECS);
+ }
+
+out:
+ up(&hdaps_sem);
+ return ret;
+}
+
+
+/* Device model stuff */
+
+static int hdaps_probe(struct device *dev)
+{
+ int ret;
+
+ ret = hdaps_device_init();
+ if (ret)
+ return ret;
+
+ printk(KERN_INFO "hdaps: device successfully initialized.\n");
+ return 0;
+}
+
+static int hdaps_resume(struct device *dev, u32 level)
+{
+ if (level == RESUME_ENABLE)
+ return hdaps_device_init();
+ return 0;
+}
+
+static struct device_driver hdaps_driver = {
+ .name = "hdaps",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ .probe = hdaps_probe,
+ .resume = hdaps_resume
+};
+
+/* Input class stuff */
+
+static struct input_dev hdaps_idev = {
+ .name = "hdaps",
+ .evbit = { BIT(EV_ABS) },
+ .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
+ .absmin = { [ABS_X] = -256, [ABS_Y] = -256 },
+ .absmax = { [ABS_X] = 256, [ABS_Y] = 256 },
+ .absfuzz = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
+ .absflat = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
+};
+
+/*
+ * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
+ */
+static void hdaps_calibrate(void)
+{
+ __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &rest_x, &rest_y);
+}
+
+static void hdaps_mousedev_poll(unsigned long unused)
+{
+ int x, y;
+
+ /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
+ if (down_trylock(&hdaps_sem)) {
+ mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
+ return;
+ }
+
+ if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y))
+ goto out;
+
+ input_report_abs(&hdaps_idev, ABS_X, x - rest_x);
+ input_report_abs(&hdaps_idev, ABS_Y, y - rest_y);
+ input_sync(&hdaps_idev);
+
+ mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
+
+out:
+ up(&hdaps_sem);
+}
+
+
+/* Sysfs Files */
+
+static ssize_t hdaps_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret, x, y;
+
+ ret = hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "(%d,%d)\n", x, y);
+}
+
+static ssize_t hdaps_variance_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret, x, y;
+
+ ret = hdaps_read_pair(HDAPS_PORT_XVAR, HDAPS_PORT_YVAR, &x, &y);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "(%d,%d)\n", x, y);
+}
+
+static ssize_t hdaps_temp1_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 temp;
+ int ret;
+
+ ret = hdaps_readb_one(HDAPS_PORT_TEMP1, &temp);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%u\n", temp);
+}
+
+static ssize_t hdaps_temp2_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 temp;
+ int ret;
+
+ ret = hdaps_readb_one(HDAPS_PORT_TEMP2, &temp);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%u\n", temp);
+}
+
+static ssize_t hdaps_keyboard_activity_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", KEYBD_ISSET(km_activity));
+}
+
+static ssize_t hdaps_mouse_activity_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", MOUSE_ISSET(km_activity));
+}
+
+static ssize_t hdaps_calibrate_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "(%d,%d)\n", rest_x, rest_y);
+}
+
+static ssize_t hdaps_calibrate_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ down(&hdaps_sem);
+ hdaps_calibrate();
+ up(&hdaps_sem);
+
+ return count;
+}
+
+static ssize_t hdaps_invert_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", hdaps_invert);
+}
+
+static ssize_t hdaps_invert_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int invert;
+
+ if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0))
+ return -EINVAL;
+
+ hdaps_invert = invert;
+ hdaps_calibrate();
+
+ return count;
+}
+
+static DEVICE_ATTR(position, 0444, hdaps_position_show, NULL);
+static DEVICE_ATTR(variance, 0444, hdaps_variance_show, NULL);
+static DEVICE_ATTR(temp1, 0444, hdaps_temp1_show, NULL);
+static DEVICE_ATTR(temp2, 0444, hdaps_temp2_show, NULL);
+static DEVICE_ATTR(keyboard_activity, 0444, hdaps_keyboard_activity_show, NULL);
+static DEVICE_ATTR(mouse_activity, 0444, hdaps_mouse_activity_show, NULL);
+static DEVICE_ATTR(calibrate, 0644, hdaps_calibrate_show,hdaps_calibrate_store);
+static DEVICE_ATTR(invert, 0644, hdaps_invert_show, hdaps_invert_store);
+
+static struct attribute *hdaps_attributes[] = {
+ &dev_attr_position.attr,
+ &dev_attr_variance.attr,
+ &dev_attr_temp1.attr,
+ &dev_attr_temp2.attr,
+ &dev_attr_keyboard_activity.attr,
+ &dev_attr_mouse_activity.attr,
+ &dev_attr_calibrate.attr,
+ &dev_attr_invert.attr,
+ NULL,
+};
+
+static struct attribute_group hdaps_attribute_group = {
+ .attrs = hdaps_attributes,
+};
+
+
+/* Module stuff */
+
+/* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */
+static int hdaps_dmi_match(struct dmi_system_id *id)
+{
+ printk(KERN_INFO "hdaps: %s detected.\n", id->ident);
+ return 1;
+}
+
+/* hdaps_dmi_match_invert - found an inverted match. */
+static int hdaps_dmi_match_invert(struct dmi_system_id *id)
+{
+ hdaps_invert = 1;
+ printk(KERN_INFO "hdaps: inverting axis readings.\n");
+ return hdaps_dmi_match(id);
+}
+
+#define HDAPS_DMI_MATCH_NORMAL(model) { \
+ .ident = "IBM " model, \
+ .callback = hdaps_dmi_match, \
+ .matches = { \
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \
+ DMI_MATCH(DMI_PRODUCT_VERSION, model) \
+ } \
+}
+
+#define HDAPS_DMI_MATCH_INVERT(model) { \
+ .ident = "IBM " model, \
+ .callback = hdaps_dmi_match_invert, \
+ .matches = { \
+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \
+ DMI_MATCH(DMI_PRODUCT_VERSION, model) \
+ } \
+}
+
+static int __init hdaps_init(void)
+{
+ int ret;
+
+ /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */
+ struct dmi_system_id hdaps_whitelist[] = {
+ HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"),
+ HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"),
+ HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"),
+ HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
+ { .ident = NULL }
+ };
+
+ if (!dmi_check_system(hdaps_whitelist)) {
+ printk(KERN_WARNING "hdaps: supported laptop not found!\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ if (!request_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS, "hdaps")) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ ret = driver_register(&hdaps_driver);
+ if (ret)
+ goto out_region;
+
+ pdev = platform_device_register_simple("hdaps", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto out_driver;
+ }
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &hdaps_attribute_group);
+ if (ret)
+ goto out_device;
+
+ /* initial calibrate for the input device */
+ hdaps_calibrate();
+
+ /* initialize the input class */
+ hdaps_idev.dev = &pdev->dev;
+ input_register_device(&hdaps_idev);
+
+ /* start up our timer for the input device */
+ init_timer(&hdaps_timer);
+ hdaps_timer.function = hdaps_mousedev_poll;
+ hdaps_timer.expires = jiffies + HDAPS_POLL_PERIOD;
+ add_timer(&hdaps_timer);
+
+ printk(KERN_INFO "hdaps: driver successfully loaded.\n");
+ return 0;
+
+out_device:
+ platform_device_unregister(pdev);
+out_driver:
+ driver_unregister(&hdaps_driver);
+out_region:
+ release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
+out:
+ printk(KERN_WARNING "hdaps: driver init failed (ret=%d)!\n", ret);
+ return ret;
+}
+
+static void __exit hdaps_exit(void)
+{
+ del_timer_sync(&hdaps_timer);
+ input_unregister_device(&hdaps_idev);
+ sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
+ platform_device_unregister(pdev);
+ driver_unregister(&hdaps_driver);
+ release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
+
+ printk(KERN_INFO "hdaps: driver unloaded.\n");
+}
+
+module_init(hdaps_init);
+module_exit(hdaps_exit);
+
+module_param_named(invert, hdaps_invert, bool, 0);
+MODULE_PARM_DESC(invert, "invert data along each axis");
+
+MODULE_AUTHOR("Robert Love");
+MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 8610bce08244..21aa9a41f62c 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -758,11 +758,6 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev,
return -ENODEV;
}
- if (!address) {
- dev_err(&dev->dev,"No SiS 5595 sensors found.\n");
- return -ENODEV;
- }
-
s_bridge = pci_dev_get(dev);
if (i2c_isa_add_driver(&sis5595_driver)) {
pci_dev_put(s_bridge);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 7e699a8ede26..c9cc683eba4a 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -2,8 +2,8 @@
smsc47m1.c - Part of lm_sensors, Linux kernel modules
for hardware monitoring
- Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x and LPC47M14x
- Super-I/O chips.
+ Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
+ LPC47M15x and LPC47M192 Super-I/O chips.
Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index eb84997627c8..05ddc88e7dd2 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -812,11 +812,6 @@ static int __devinit via686a_pci_probe(struct pci_dev *dev,
return -ENODEV;
}
- if (!address) {
- dev_err(&dev->dev, "No Via 686A sensors found.\n");
- return -ENODEV;
- }
-
s_bridge = pci_dev_get(dev);
if (i2c_isa_add_driver(&via686a_driver)) {
pci_dev_put(s_bridge);
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 02bd5c0239a2..3479dc5208e2 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -64,6 +64,10 @@ static unsigned short address;
/* Insmod parameters */
enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf };
+static int reset;
+module_param(reset, bool, 0);
+MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
+
static int init = 1;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
@@ -1279,7 +1283,15 @@ static void w83627hf_init_client(struct i2c_client *client)
int type = data->type;
u8 tmp;
- if(init) {
+ if (reset) {
+ /* Resetting the chip has been the default for a long time,
+ but repeatedly caused problems (fans going to full
+ speed...) so it is now optional. It might even go away if
+ nobody reports it as being useful, as I see very little
+ reason why this would be needed at all. */
+ dev_info(&client->dev, "If reset=1 solved a problem you were "
+ "having, please report!\n");
+
/* save this register */
i = w83627hf_read_value(client, W83781D_REG_BEEP_CONFIG);
/* Reset all except Watchdog values and last conversion values
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6e9da1372225..3badfec75b1c 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
@@ -229,6 +245,18 @@ config I2C_KEYWEST
This support is also available as a module. If so, the module
will be called i2c-keywest.
+config I2C_PMAC_SMU
+ tristate "Powermac SMU I2C interface"
+ depends on I2C && PMAC_SMU
+ help
+ This supports the use of the I2C interface in the SMU
+ chip on recent Apple machines like the iMac G5. It is used
+ among others by the thermal control driver for those machines.
+ Say Y if you have such a machine.
+
+ This support is also available as a module. If so, the module
+ will be called i2c-pmac-smu.
+
config I2C_MPC
tristate "MPC107/824x/85xx/52xx"
depends on I2C && PPC32
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 42d6d814da72..f1df00f66c6c 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_ITE) += i2c-ite.o
obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o
obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o
+obj-$(CONFIG_I2C_PMAC_SMU) += i2c-pmac-smu.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
@@ -28,6 +29,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-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index 37b49c2daf5f..eff5896ce865 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -611,7 +611,6 @@ create_iface(struct device_node *np, struct device *dev)
for (i=0; i<nchan; i++) {
struct keywest_chan* chan = &iface->channels[i];
- u8 addr;
sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
chan->iface = iface;
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index e0b7a913431e..fe9c0f42a2b7 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -98,11 +98,6 @@ struct nforce2_smbus {
#define NVIDIA_SMB_PRTCL_PEC 0x80
-/* Other settings */
-#define MAX_TIMEOUT 256
-
-
-
static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data);
diff --git a/drivers/i2c/busses/i2c-pmac-smu.c b/drivers/i2c/busses/i2c-pmac-smu.c
new file mode 100644
index 000000000000..8a9f5648a23d
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pmac-smu.c
@@ -0,0 +1,316 @@
+/*
+ i2c Support for Apple SMU Controller
+
+ Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
+ <benh@kernel.crashing.org>
+
+ 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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+#include <asm/smu.h>
+
+static int probe;
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("I2C driver for Apple's SMU");
+MODULE_LICENSE("GPL");
+module_param(probe, bool, 0);
+
+
+/* Physical interface */
+struct smu_iface
+{
+ struct i2c_adapter adapter;
+ struct completion complete;
+ u32 busid;
+};
+
+static void smu_i2c_done(struct smu_i2c_cmd *cmd, void *misc)
+{
+ struct smu_iface *iface = misc;
+ complete(&iface->complete);
+}
+
+/*
+ * SMBUS-type transfer entrypoint
+ */
+static s32 smu_smbus_xfer( struct i2c_adapter* adap,
+ u16 addr,
+ unsigned short flags,
+ char read_write,
+ u8 command,
+ int size,
+ union i2c_smbus_data* data)
+{
+ struct smu_iface *iface = i2c_get_adapdata(adap);
+ struct smu_i2c_cmd cmd;
+ int rc = 0;
+ int read = (read_write == I2C_SMBUS_READ);
+
+ cmd.info.bus = iface->busid;
+ cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00);
+
+ /* Prepare datas & select mode */
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+ cmd.info.type = SMU_I2C_TRANSFER_SIMPLE;
+ cmd.info.datalen = 0;
+ break;
+ case I2C_SMBUS_BYTE:
+ cmd.info.type = SMU_I2C_TRANSFER_SIMPLE;
+ cmd.info.datalen = 1;
+ if (!read)
+ cmd.info.data[0] = data->byte;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
+ cmd.info.datalen = 1;
+ cmd.info.sublen = 1;
+ cmd.info.subaddr[0] = command;
+ cmd.info.subaddr[1] = 0;
+ cmd.info.subaddr[2] = 0;
+ if (!read)
+ cmd.info.data[0] = data->byte;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
+ cmd.info.datalen = 2;
+ cmd.info.sublen = 1;
+ cmd.info.subaddr[0] = command;
+ cmd.info.subaddr[1] = 0;
+ cmd.info.subaddr[2] = 0;
+ if (!read) {
+ cmd.info.data[0] = data->byte & 0xff;
+ cmd.info.data[1] = (data->byte >> 8) & 0xff;
+ }
+ break;
+ /* Note that these are broken vs. the expected smbus API where
+ * on reads, the lenght is actually returned from the function,
+ * but I think the current API makes no sense and I don't want
+ * any driver that I haven't verified for correctness to go
+ * anywhere near a pmac i2c bus anyway ...
+ */
+ case I2C_SMBUS_BLOCK_DATA:
+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
+ cmd.info.datalen = data->block[0] + 1;
+ if (cmd.info.datalen > 6)
+ return -EINVAL;
+ if (!read)
+ memcpy(cmd.info.data, data->block, cmd.info.datalen);
+ cmd.info.sublen = 1;
+ cmd.info.subaddr[0] = command;
+ cmd.info.subaddr[1] = 0;
+ cmd.info.subaddr[2] = 0;
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
+ cmd.info.datalen = data->block[0];
+ if (cmd.info.datalen > 7)
+ return -EINVAL;
+ if (!read)
+ memcpy(cmd.info.data, &data->block[1],
+ cmd.info.datalen);
+ cmd.info.sublen = 1;
+ cmd.info.subaddr[0] = command;
+ cmd.info.subaddr[1] = 0;
+ cmd.info.subaddr[2] = 0;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Turn a standardsub read into a combined mode access */
+ if (read_write == I2C_SMBUS_READ &&
+ cmd.info.type == SMU_I2C_TRANSFER_STDSUB)
+ cmd.info.type = SMU_I2C_TRANSFER_COMBINED;
+
+ /* Finish filling command and submit it */
+ cmd.done = smu_i2c_done;
+ cmd.misc = iface;
+ rc = smu_queue_i2c(&cmd);
+ if (rc < 0)
+ return rc;
+ wait_for_completion(&iface->complete);
+ rc = cmd.status;
+
+ if (!read || rc < 0)
+ return rc;
+
+ switch (size) {
+ case I2C_SMBUS_BYTE:
+ case I2C_SMBUS_BYTE_DATA:
+ data->byte = cmd.info.data[0];
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ data->word = ((u16)cmd.info.data[1]) << 8;
+ data->word |= cmd.info.data[0];
+ break;
+ /* Note that these are broken vs. the expected smbus API where
+ * on reads, the lenght is actually returned from the function,
+ * but I think the current API makes no sense and I don't want
+ * any driver that I haven't verified for correctness to go
+ * anywhere near a pmac i2c bus anyway ...
+ */
+ case I2C_SMBUS_BLOCK_DATA:
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ memcpy(&data->block[0], cmd.info.data, cmd.info.datalen);
+ break;
+ }
+
+ return rc;
+}
+
+static u32
+smu_smbus_func(struct i2c_adapter * adapter)
+{
+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+/* For now, we only handle combined mode (smbus) */
+static struct i2c_algorithm smu_algorithm = {
+ .smbus_xfer = smu_smbus_xfer,
+ .functionality = smu_smbus_func,
+};
+
+static int create_iface(struct device_node *np, struct device *dev)
+{
+ struct smu_iface* iface;
+ u32 *reg, busid;
+ int rc;
+
+ reg = (u32 *)get_property(np, "reg", NULL);
+ if (reg == NULL) {
+ printk(KERN_ERR "i2c-pmac-smu: can't find bus number !\n");
+ return -ENXIO;
+ }
+ busid = *reg;
+
+ iface = kmalloc(sizeof(struct smu_iface), GFP_KERNEL);
+ if (iface == NULL) {
+ printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n");
+ return -ENOMEM;
+ }
+ memset(iface, 0, sizeof(struct smu_iface));
+ init_completion(&iface->complete);
+ iface->busid = busid;
+
+ dev_set_drvdata(dev, iface);
+
+ sprintf(iface->adapter.name, "smu-i2c-%02x", busid);
+ iface->adapter.algo = &smu_algorithm;
+ iface->adapter.algo_data = NULL;
+ iface->adapter.client_register = NULL;
+ iface->adapter.client_unregister = NULL;
+ i2c_set_adapdata(&iface->adapter, iface);
+ iface->adapter.dev.parent = dev;
+
+ rc = i2c_add_adapter(&iface->adapter);
+ if (rc) {
+ printk(KERN_ERR "i2c-pamc-smu.c: Adapter %s registration "
+ "failed\n", iface->adapter.name);
+ i2c_set_adapdata(&iface->adapter, NULL);
+ }
+
+ if (probe) {
+ unsigned char addr;
+ printk("Probe: ");
+ for (addr = 0x00; addr <= 0x7f; addr++) {
+ if (i2c_smbus_xfer(&iface->adapter,addr,
+ 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0)
+ printk("%02x ", addr);
+ }
+ printk("\n");
+ }
+
+ printk(KERN_INFO "SMU i2c bus %x registered\n", busid);
+
+ return 0;
+}
+
+static int dispose_iface(struct device *dev)
+{
+ struct smu_iface *iface = dev_get_drvdata(dev);
+ int rc;
+
+ rc = i2c_del_adapter(&iface->adapter);
+ i2c_set_adapdata(&iface->adapter, NULL);
+ /* We aren't that prepared to deal with this... */
+ if (rc)
+ printk("i2c-pmac-smu.c: Failed to remove bus %s !\n",
+ iface->adapter.name);
+ dev_set_drvdata(dev, NULL);
+ kfree(iface);
+
+ return 0;
+}
+
+
+static int create_iface_of_platform(struct of_device* dev,
+ const struct of_device_id *match)
+{
+ return create_iface(dev->node, &dev->dev);
+}
+
+
+static int dispose_iface_of_platform(struct of_device* dev)
+{
+ return dispose_iface(&dev->dev);
+}
+
+
+static struct of_device_id i2c_smu_match[] =
+{
+ {
+ .compatible = "smu-i2c",
+ },
+ {},
+};
+static struct of_platform_driver i2c_smu_of_platform_driver =
+{
+ .name = "i2c-smu",
+ .match_table = i2c_smu_match,
+ .probe = create_iface_of_platform,
+ .remove = dispose_iface_of_platform
+};
+
+
+static int __init i2c_pmac_smu_init(void)
+{
+ of_register_driver(&i2c_smu_of_platform_driver);
+ return 0;
+}
+
+
+static void __exit i2c_pmac_smu_cleanup(void)
+{
+ of_unregister_driver(&i2c_smu_of_platform_driver);
+}
+
+module_init(i2c_pmac_smu_init);
+module_exit(i2c_pmac_smu_cleanup);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
new file mode 100644
index 000000000000..44b595d90a4a
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -0,0 +1,1026 @@
+/*
+ * 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 u32 i2c_pxa_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm i2c_pxa_algorithm = {
+ .master_xfer = i2c_pxa_xfer,
+ .functionality = i2c_pxa_functionality,
+};
+
+static struct pxa_i2c i2c_pxa = {
+ .lock = SPIN_LOCK_UNLOCKED,
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
+ .adap = {
+ .owner = THIS_MODULE,
+ .algo = &i2c_pxa_algorithm,
+ .name = "pxa2xx-i2c",
+ .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/ide-io.c b/drivers/ide/ide-io.c
index f174aee659e5..5275cbb1afe9 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -560,7 +560,7 @@ ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq)
EXPORT_SYMBOL_GPL(__ide_abort);
/**
- * ide_abort - abort pending IDE operatins
+ * ide_abort - abort pending IDE operations
* @drive: drive the error occurred on
* @msg: message to report
*
@@ -623,7 +623,7 @@ static void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect,
* @drive: drive the completion interrupt occurred on
*
* drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- * We do any necessary daya reading and then wait for the drive to
+ * We do any necessary data reading and then wait for the drive to
* go non busy. At that point we may read the error data and complete
* the request
*/
@@ -773,7 +773,7 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
/**
* execute_drive_command - issue special drive command
- * @drive: the drive to issue th command on
+ * @drive: the drive to issue the command on
* @rq: the request structure holding the command
*
* execute_drive_cmd() issues a special drive command, usually
@@ -1101,6 +1101,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
ide_hwif_t *hwif;
struct request *rq;
ide_startstop_t startstop;
+ int loops = 0;
/* for atari only: POSSIBLY BROKEN HERE(?) */
ide_get_lock(ide_intr, hwgroup);
@@ -1153,6 +1154,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
/* no more work for this hwgroup (for now) */
return;
}
+ again:
hwif = HWIF(drive);
if (hwgroup->hwif->sharing_irq &&
hwif != hwgroup->hwif &&
@@ -1192,8 +1194,14 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
* though. I hope that doesn't happen too much, hopefully not
* unless the subdriver triggers such a thing in its own PM
* state machine.
+ *
+ * We count how many times we loop here to make sure we service
+ * all drives in the hwgroup without looping for ever
*/
if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
+ drive = drive->next ? drive->next : hwgroup->drive;
+ if (loops++ < 4 && !blk_queue_plugged(drive->queue))
+ goto again;
/* We clear busy, there should be no pending ATA command at this point. */
hwgroup->busy = 0;
break;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index b443b04a4c5a..0b0aa4f51628 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -601,44 +601,15 @@ EXPORT_SYMBOL(ide_wait_stat);
*/
u8 eighty_ninty_three (ide_drive_t *drive)
{
-#if 0
- if (!HWIF(drive)->udma_four)
+ if(HWIF(drive)->udma_four == 0)
+ return 0;
+ if (!(drive->id->hw_config & 0x6000))
return 0;
-
- if (drive->id->major_rev_num) {
- int hssbd = 0;
- int i;
- /*
- * Determine highest Supported SPEC
- */
- for (i=1; i<=15; i++)
- if (drive->id->major_rev_num & (1<<i))
- hssbd++;
-
- switch (hssbd) {
- case 7:
- case 6:
- case 5:
- /* ATA-4 and older do not support above Ultra 33 */
- default:
- return 0;
- }
- }
-
- return ((u8) (
-#ifndef CONFIG_IDEDMA_IVB
- (drive->id->hw_config & 0x4000) &&
-#endif /* CONFIG_IDEDMA_IVB */
- (drive->id->hw_config & 0x6000)) ? 1 : 0);
-
-#else
-
- return ((u8) ((HWIF(drive)->udma_four) &&
#ifndef CONFIG_IDEDMA_IVB
- (drive->id->hw_config & 0x4000) &&
+ if(!(drive->id->hw_config & 0x4000))
+ return 0;
#endif /* CONFIG_IDEDMA_IVB */
- (drive->id->hw_config & 0x6000)) ? 1 : 0);
-#endif
+ return 1;
}
EXPORT_SYMBOL(eighty_ninty_three);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 5a3dc46008e6..ee38e6b143a4 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2903,8 +2903,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
} else if (!(tape->sense_key == 2 && tape->asc == 4 &&
(tape->ascq == 1 || tape->ascq == 8)))
return -EIO;
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ / 10);
+ msleep(100);
}
return -EIO;
}
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index d04f62ab5de1..ace8edad6e96 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -500,6 +500,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
}
rq.special = args;
+ args->rq = &rq;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h
index c1196ce15b4d..2fcfac6e967a 100644
--- a/drivers/ide/ide-timing.h
+++ b/drivers/ide/ide-timing.h
@@ -27,6 +27,7 @@
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
+#include <linux/kernel.h>
#include <linux/hdreg.h>
#define XFER_PIO_5 0x0d
@@ -96,11 +97,9 @@ static struct ide_timing ide_timing[] = {
#define IDE_TIMING_UDMA 0x80
#define IDE_TIMING_ALL 0xff
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#define FIT(v,min,max) MAX(MIN(v,max),min)
-#define ENOUGH(v,unit) (((v)-1)/(unit)+1)
-#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
+#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin)
+#define ENOUGH(v,unit) (((v)-1)/(unit)+1)
+#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
#define XFER_MODE 0xf0
#define XFER_UDMA_133 0x48
@@ -188,14 +187,14 @@ static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int
static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what)
{
- if (what & IDE_TIMING_SETUP ) m->setup = MAX(a->setup, b->setup);
- if (what & IDE_TIMING_ACT8B ) m->act8b = MAX(a->act8b, b->act8b);
- if (what & IDE_TIMING_REC8B ) m->rec8b = MAX(a->rec8b, b->rec8b);
- if (what & IDE_TIMING_CYC8B ) m->cyc8b = MAX(a->cyc8b, b->cyc8b);
- if (what & IDE_TIMING_ACTIVE ) m->active = MAX(a->active, b->active);
- if (what & IDE_TIMING_RECOVER) m->recover = MAX(a->recover, b->recover);
- if (what & IDE_TIMING_CYCLE ) m->cycle = MAX(a->cycle, b->cycle);
- if (what & IDE_TIMING_UDMA ) m->udma = MAX(a->udma, b->udma);
+ if (what & IDE_TIMING_SETUP ) m->setup = max(a->setup, b->setup);
+ if (what & IDE_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b);
+ if (what & IDE_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b);
+ if (what & IDE_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b);
+ if (what & IDE_TIMING_ACTIVE ) m->active = max(a->active, b->active);
+ if (what & IDE_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
+ if (what & IDE_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle);
+ if (what & IDE_TIMING_UDMA ) m->udma = max(a->udma, b->udma);
}
static struct ide_timing* ide_timing_find_mode(short speed)
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index f1d1ec4e9677..a35a58bef1a4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -43,6 +43,7 @@
#include <linux/ide.h>
#include <linux/hdreg.h>
#include <linux/major.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -340,8 +341,7 @@ static void ide_config(dev_link_t *link)
break;
}
}
- __set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ/10);
+ msleep(100);
}
if (hd < 0) {
@@ -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),
@@ -474,13 +477,14 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
- PCMCIA_DEVICE_PROD_ID12(" ", "NinjaATA-", 0x3b6e20c8, 0xebe0bd79),
+ PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
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/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 3de9ab897e42..3d9c7afc8695 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -608,7 +608,7 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
#ifdef __i386__
if (dev->resource[PCI_ROM_RESOURCE].start) {
- pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
}
#endif
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index bbde46279984..be334da7a754 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -173,7 +173,7 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha
if (cmd & PCI_COMMAND_MEMORY) {
if (pci_resource_start(dev, PCI_ROM_RESOURCE)) {
- pci_write_config_byte(dev, PCI_ROM_ADDRESS,
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS,
dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n",
dev->resource[PCI_ROM_RESOURCE].start);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 7b64db10d1b0..127619a109ed 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1334,9 +1334,13 @@ static int __devinit init_hpt366(struct pci_dev *dev)
static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)
{
int ret = 0;
- /* FIXME: Not portable */
+
+ /*
+ * FIXME: Not portable. Also, why do we enable the ROM in the first place?
+ * We don't seem to be using it.
+ */
if (dev->resource[PCI_ROM_RESOURCE].start)
- pci_write_config_byte(dev, PCI_ROM_ADDRESS,
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS,
dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
diff --git a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
index 84ae027b021a..e8e28569a668 100644
--- a/drivers/ieee1394/amdtp.c
+++ b/drivers/ieee1394/amdtp.c
@@ -1297,4 +1297,3 @@ static void __exit amdtp_exit_module (void)
module_init(amdtp_init_module);
module_exit(amdtp_exit_module);
-MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16);
diff --git a/drivers/ieee1394/csr1212.h b/drivers/ieee1394/csr1212.h
index e6734263a1d3..28c5f4b726e2 100644
--- a/drivers/ieee1394/csr1212.h
+++ b/drivers/ieee1394/csr1212.h
@@ -37,7 +37,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/sched.h>
#include <linux/vmalloc.h>
#include <asm/pgalloc.h>
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 4538b0235ca3..e34730c7a874 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2660,4 +2660,3 @@ static int __init dv1394_init_module(void)
module_init(dv1394_init_module);
module_exit(dv1394_exit_module);
-MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16);
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index cd53c174ced1..c9e92d85c893 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata =
- "$Rev: 1264 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1312 $ Ben Collins <bcollins@debian.org>";
struct fragment_info {
struct list_head list;
@@ -221,9 +221,7 @@ static int ether1394_open (struct net_device *dev)
if (priv->bc_state == ETHER1394_BC_ERROR) {
/* we'll try again */
priv->iso = hpsb_iso_recv_init(priv->host,
- ETHER1394_GASP_BUFFERS * 2 *
- (1 << (priv->host->csr.max_rec +
- 1)),
+ ETHER1394_ISO_BUF_SIZE,
ETHER1394_GASP_BUFFERS,
priv->broadcast_channel,
HPSB_ISO_DMA_PACKET_PER_BUFFER,
@@ -635,8 +633,8 @@ static void ether1394_add_host (struct hpsb_host *host)
* be checked when the eth device is opened. */
priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
- priv->iso = hpsb_iso_recv_init(host, (ETHER1394_GASP_BUFFERS * 2 *
- (1 << (host->csr.max_rec + 1))),
+ priv->iso = hpsb_iso_recv_init(host,
+ ETHER1394_ISO_BUF_SIZE,
ETHER1394_GASP_BUFFERS,
priv->broadcast_channel,
HPSB_ISO_DMA_PACKET_PER_BUFFER,
@@ -1632,7 +1630,7 @@ static void ether1394_complete_cb(void *__ptask)
/* Transmit a packet (called by kernel) */
static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
{
- int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ gfp_t kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
struct eth1394hdr *eth;
struct eth1394_priv *priv = netdev_priv(dev);
int proto;
@@ -1770,7 +1768,7 @@ fail:
static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strcpy (info->driver, driver_name);
- strcpy (info->version, "$Rev: 1264 $");
+ strcpy (info->version, "$Rev: 1312 $");
/* FIXME XXX provide sane businfo */
strcpy (info->bus_info, "ieee1394");
}
diff --git a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h
index ed8f1c4b7fd8..a77213cfc483 100644
--- a/drivers/ieee1394/eth1394.h
+++ b/drivers/ieee1394/eth1394.h
@@ -44,6 +44,12 @@
#define ETHER1394_GASP_BUFFERS 16
+/* rawiso buffer size - due to a limitation in rawiso, we must limit each
+ * GASP buffer to be less than PAGE_SIZE. */
+#define ETHER1394_ISO_BUF_SIZE ETHER1394_GASP_BUFFERS * \
+ min((unsigned int)PAGE_SIZE, \
+ 2 * (1U << (priv->host->csr.max_rec + 1)))
+
/* Node set == 64 */
#define NODE_SET (ALL_NODES + 1)
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index c502c6e9c440..aeeaeb670d03 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/timer.h>
+#include <linux/jiffies.h>
#include "csr1212.h"
#include "ieee1394.h"
@@ -217,7 +218,7 @@ int hpsb_update_config_rom_image(struct hpsb_host *host)
/* IEEE 1394a-2000 prohibits using the same generation number
* twice in a 60 second period. */
- if (jiffies - host->csr.gen_timestamp[next_gen] < 60 * HZ)
+ if (time_before(jiffies, host->csr.gen_timestamp[next_gen] + 60 * HZ))
/* Wait 60 seconds from the last time this generation number was
* used. */
reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index 739e76840d51..38f42112dff0 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -135,17 +135,17 @@ enum isoctl_cmd {
enum reset_types {
/* 166 microsecond reset -- only type of reset available on
- non-1394a capable IEEE 1394 controllers */
+ non-1394a capable controllers */
LONG_RESET,
/* Short (arbitrated) reset -- only available on 1394a capable
- IEEE 1394 capable controllers */
+ controllers */
SHORT_RESET,
- /* Variants, that set force_root before issueing the bus reset */
+ /* Variants that set force_root before issueing the bus reset */
LONG_RESET_FORCE_ROOT, SHORT_RESET_FORCE_ROOT,
- /* Variants, that clear force_root before issueing the bus reset */
+ /* Variants that clear force_root before issueing the bus reset */
LONG_RESET_NO_FORCE_ROOT, SHORT_RESET_NO_FORCE_ROOT
};
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index d633770fac8e..32a1e016c85e 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -70,7 +70,7 @@ const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S32
struct class *hpsb_protocol_class;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-static void dump_packet(const char *text, quadlet_t *data, int size)
+static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
{
int i;
@@ -78,12 +78,15 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
size = (size > 4 ? 4 : size);
printk(KERN_DEBUG "ieee1394: %s", text);
+ if (speed > -1 && speed < 6)
+ printk(" at %s", hpsb_speedto_str[speed]);
+ printk(":");
for (i = 0; i < size; i++)
printk(" %08x", data[i]);
printk("\n");
}
#else
-#define dump_packet(x,y,z)
+#define dump_packet(a,b,c,d)
#endif
static void abort_requests(struct hpsb_host *host);
@@ -544,8 +547,7 @@ int hpsb_send_packet(struct hpsb_packet *packet)
if (packet->data_size)
memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size);
- dump_packet("send packet local:", packet->header,
- packet->header_size);
+ dump_packet("send packet local", packet->header, packet->header_size, -1);
hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
hpsb_packet_received(host, data, size, 0);
@@ -561,21 +563,7 @@ int hpsb_send_packet(struct hpsb_packet *packet)
+ NODEID_TO_NODE(packet->node_id)];
}
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
- switch (packet->speed_code) {
- case 2:
- dump_packet("send packet 400:", packet->header,
- packet->header_size);
- break;
- case 1:
- dump_packet("send packet 200:", packet->header,
- packet->header_size);
- break;
- default:
- dump_packet("send packet 100:", packet->header,
- packet->header_size);
- }
-#endif
+ dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
return host->driver->transmit_packet(host, packet);
}
@@ -636,7 +624,7 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
if (packet == NULL) {
HPSB_DEBUG("unsolicited response packet received - no tlabel match");
- dump_packet("contents:", data, 16);
+ dump_packet("contents", data, 16, -1);
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
return;
}
@@ -677,7 +665,7 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
if (!tcode_match) {
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
HPSB_INFO("unsolicited response packet received - tcode mismatch");
- dump_packet("contents:", data, 16);
+ dump_packet("contents", data, 16, -1);
return;
}
@@ -914,7 +902,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
return;
}
- dump_packet("received packet:", data, size);
+ dump_packet("received packet", data, size, -1);
tcode = (data[0] >> 4) & 0xf;
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index b23322523ef5..347ece6b583c 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -64,10 +64,10 @@ static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
struct nodemgr_csr_info *ci = (struct nodemgr_csr_info*)__ci;
int i, ret = 0;
- for (i = 0; i < 3; i++) {
+ for (i = 1; ; i++) {
ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
buffer, length);
- if (!ret)
+ if (!ret || i == 3)
break;
if (msleep_interruptible(334))
@@ -1438,9 +1438,13 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
if (host->busmgr_id == 0xffff && host->node_count > 1)
{
u16 root_node = host->node_count - 1;
- struct node_entry *ne = find_entry_by_nodeid(host, root_node | LOCAL_BUS);
- if (ne && ne->busopt.cmc)
+ /* get cycle master capability flag from root node */
+ if (host->is_cycmst ||
+ (!hpsb_read(host, LOCAL_BUS | root_node, get_hpsb_generation(host),
+ (CSR_REGISTER_BASE + CSR_CONFIG_ROM + 2 * sizeof(quadlet_t)),
+ &bc, sizeof(quadlet_t)) &&
+ be32_to_cpu(bc) & 1 << CSR_CMC_SHIFT))
hpsb_send_phy_config(host, root_node, -1);
else {
HPSB_DEBUG("The root node is not cycle master capable; "
@@ -1557,24 +1561,19 @@ static int nodemgr_host_thread(void *__hi)
}
}
- if (!nodemgr_check_irm_capability(host, reset_cycles)) {
+ if (!nodemgr_check_irm_capability(host, reset_cycles) ||
+ !nodemgr_do_irm_duties(host, reset_cycles)) {
reset_cycles++;
up(&nodemgr_serialize);
continue;
}
+ reset_cycles = 0;
/* Scan our nodes to get the bus options and create node
* entries. This does not do the sysfs stuff, since that
* would trigger hotplug callbacks and such, which is a
* bad idea at this point. */
nodemgr_node_scan(hi, generation);
- if (!nodemgr_do_irm_duties(host, reset_cycles)) {
- reset_cycles++;
- up(&nodemgr_serialize);
- continue;
- }
-
- reset_cycles = 0;
/* This actually does the full probe, with sysfs
* registration. */
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 27018c8efc24..4cf9b8f3e336 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
static char version[] __devinitdata =
- "$Rev: 1299 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1313 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
@@ -1084,7 +1084,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
if (printk_ratelimit())
- PRINT(KERN_ERR, "IR legacy activated");
+ DBGMSG("IR legacy activated");
}
spin_lock_irqsave(&ohci->IR_channel_lock, flags);
@@ -2283,8 +2283,9 @@ static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci,
{
struct ohci1394_iso_tasklet *t;
unsigned long mask;
+ unsigned long flags;
- spin_lock(&ohci->iso_tasklet_list_lock);
+ spin_lock_irqsave(&ohci->iso_tasklet_list_lock, flags);
list_for_each_entry(t, &ohci->iso_tasklet_list, link) {
mask = 1 << t->context;
@@ -2295,8 +2296,7 @@ static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci,
tasklet_schedule(&t->tasklet);
}
- spin_unlock(&ohci->iso_tasklet_list_lock);
-
+ spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags);
}
static irqreturn_t ohci_irq_handler(int irq, void *dev_id,
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index b4fa14793fe5..0470f77a9cd1 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -98,7 +98,7 @@ static struct hpsb_address_ops arm_ops = {
static void queue_complete_cb(struct pending_request *req);
-static struct pending_request *__alloc_pending_request(unsigned int __nocast flags)
+static struct pending_request *__alloc_pending_request(gfp_t flags)
{
struct pending_request *req;
@@ -412,6 +412,7 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
static ssize_t raw1394_read(struct file *file, char __user * buffer,
size_t count, loff_t * offset_is_ignored)
{
+ unsigned long flags;
struct file_info *fi = (struct file_info *)file->private_data;
struct list_head *lh;
struct pending_request *req;
@@ -435,10 +436,10 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
}
}
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
lh = fi->req_complete.next;
list_del(lh);
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
req = list_entry(lh, struct pending_request, list);
@@ -486,6 +487,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req)
static int state_initialized(struct file_info *fi, struct pending_request *req)
{
+ unsigned long flags;
struct host_info *hi;
struct raw1394_khost_list *khl;
@@ -499,7 +501,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
switch (req->req.type) {
case RAW1394_REQ_LIST_CARDS:
- spin_lock_irq(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, flags);
khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count,
SLAB_ATOMIC);
@@ -513,7 +515,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
khl++;
}
}
- spin_unlock_irq(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, flags);
if (khl != NULL) {
req->req.error = RAW1394_ERROR_NONE;
@@ -528,7 +530,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
break;
case RAW1394_REQ_SET_CARD:
- spin_lock_irq(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, flags);
if (req->req.misc < host_count) {
list_for_each_entry(hi, &host_info_list, list) {
if (!req->req.misc--)
@@ -550,7 +552,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
} else {
req->req.error = RAW1394_ERROR_INVALID_ARG;
}
- spin_unlock_irq(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, flags);
req->req.length = 0;
break;
@@ -569,7 +571,6 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
{
int channel = req->req.misc;
- spin_lock_irq(&host_info_lock);
if ((channel > 63) || (channel < -64)) {
req->req.error = RAW1394_ERROR_INVALID_ARG;
} else if (channel >= 0) {
@@ -601,7 +602,6 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
req->req.length = 0;
queue_complete_req(req);
- spin_unlock_irq(&host_info_lock);
}
static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
@@ -627,6 +627,7 @@ static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
static int handle_async_request(struct file_info *fi,
struct pending_request *req, int node)
{
+ unsigned long flags;
struct hpsb_packet *packet = NULL;
u64 addr = req->req.address & 0xffffffffffffULL;
@@ -761,9 +762,9 @@ static int handle_async_request(struct file_info *fi,
hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_cb, req);
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
list_add_tail(&req->list, &fi->req_pending);
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
packet->generation = req->req.generation;
@@ -779,6 +780,7 @@ static int handle_async_request(struct file_info *fi,
static int handle_iso_send(struct file_info *fi, struct pending_request *req,
int channel)
{
+ unsigned long flags;
struct hpsb_packet *packet;
packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,
@@ -804,9 +806,9 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
(void (*)(void *))queue_complete_req,
req);
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
list_add_tail(&req->list, &fi->req_pending);
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
/* Update the generation of the packet just before sending. */
packet->generation = req->req.generation;
@@ -821,6 +823,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
static int handle_async_send(struct file_info *fi, struct pending_request *req)
{
+ unsigned long flags;
struct hpsb_packet *packet;
int header_length = req->req.misc & 0xffff;
int expect_response = req->req.misc >> 16;
@@ -867,9 +870,9 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_cb, req);
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
list_add_tail(&req->list, &fi->req_pending);
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
/* Update the generation of the packet just before sending. */
packet->generation = req->req.generation;
@@ -885,6 +888,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
u64 addr, size_t length, u16 flags)
{
+ unsigned long irqflags;
struct pending_request *req;
struct host_info *hi;
struct file_info *fi = NULL;
@@ -899,7 +903,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
"addr: %4.4x %8.8x length: %Zu", nodeid,
(u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
length);
- spin_lock(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, irqflags);
hi = find_host_info(host); /* search address-entry */
if (hi != NULL) {
list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -924,7 +928,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
if (!found) {
printk(KERN_ERR "raw1394: arm_read FAILED addr_entry not found"
" -> rcode_address_error\n");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_ADDRESS_ERROR);
} else {
DBGMSG("arm_read addr_entry FOUND");
@@ -954,7 +958,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) {
DBGMSG("arm_read -> rcode_conflict_error");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
}
@@ -974,7 +978,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
if (!(req->data)) {
free_pending_request(req);
DBGMSG("arm_read -> rcode_conflict_error");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
}
@@ -1031,13 +1035,14 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
sizeof(struct arm_request));
queue_complete_req(req);
}
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (rcode);
}
static int arm_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t * data, u64 addr, size_t length, u16 flags)
{
+ unsigned long irqflags;
struct pending_request *req;
struct host_info *hi;
struct file_info *fi = NULL;
@@ -1052,7 +1057,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
"addr: %4.4x %8.8x length: %Zu", nodeid,
(u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
length);
- spin_lock(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, irqflags);
hi = find_host_info(host); /* search address-entry */
if (hi != NULL) {
list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -1077,7 +1082,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
if (!found) {
printk(KERN_ERR "raw1394: arm_write FAILED addr_entry not found"
" -> rcode_address_error\n");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_ADDRESS_ERROR);
} else {
DBGMSG("arm_write addr_entry FOUND");
@@ -1106,7 +1111,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) {
DBGMSG("arm_write -> rcode_conflict_error");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request my be retried */
}
@@ -1118,7 +1123,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
if (!(req->data)) {
free_pending_request(req);
DBGMSG("arm_write -> rcode_conflict_error");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
}
@@ -1165,7 +1170,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
sizeof(struct arm_request));
queue_complete_req(req);
}
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (rcode);
}
@@ -1173,6 +1178,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
u16 flags)
{
+ unsigned long irqflags;
struct pending_request *req;
struct host_info *hi;
struct file_info *fi = NULL;
@@ -1198,7 +1204,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
(u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF,
be32_to_cpu(data), be32_to_cpu(arg));
}
- spin_lock(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, irqflags);
hi = find_host_info(host); /* search address-entry */
if (hi != NULL) {
list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -1224,7 +1230,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
if (!found) {
printk(KERN_ERR "raw1394: arm_lock FAILED addr_entry not found"
" -> rcode_address_error\n");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_ADDRESS_ERROR);
} else {
DBGMSG("arm_lock addr_entry FOUND");
@@ -1307,7 +1313,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) {
DBGMSG("arm_lock -> rcode_conflict_error");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
}
@@ -1316,7 +1322,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
if (!(req->data)) {
free_pending_request(req);
DBGMSG("arm_lock -> rcode_conflict_error");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
}
@@ -1382,7 +1388,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
sizeof(struct arm_response) + 2 * sizeof(*store));
queue_complete_req(req);
}
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (rcode);
}
@@ -1390,6 +1396,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
u16 flags)
{
+ unsigned long irqflags;
struct pending_request *req;
struct host_info *hi;
struct file_info *fi = NULL;
@@ -1422,7 +1429,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
(u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF),
(u32) (be64_to_cpu(arg) & 0xFFFFFFFF));
}
- spin_lock(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, irqflags);
hi = find_host_info(host); /* search addressentry in file_info's for host */
if (hi != NULL) {
list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -1449,7 +1456,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
printk(KERN_ERR
"raw1394: arm_lock64 FAILED addr_entry not found"
" -> rcode_address_error\n");
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (RCODE_ADDRESS_ERROR);
} else {
DBGMSG("arm_lock64 addr_entry FOUND");
@@ -1533,7 +1540,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
DBGMSG("arm_lock64 -> entering notification-section");
req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) {
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
DBGMSG("arm_lock64 -> rcode_conflict_error");
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
@@ -1542,7 +1549,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
req->data = kmalloc(size, SLAB_ATOMIC);
if (!(req->data)) {
free_pending_request(req);
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
DBGMSG("arm_lock64 -> rcode_conflict_error");
return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */
@@ -1609,7 +1616,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
sizeof(struct arm_response) + 2 * sizeof(*store));
queue_complete_req(req);
}
- spin_unlock(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, irqflags);
return (rcode);
}
@@ -1980,6 +1987,7 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
struct hpsb_packet *packet = NULL;
int retval = 0;
quadlet_t data;
+ unsigned long flags;
data = be32_to_cpu((u32) req->req.sendb);
DBGMSG("write_phypacket called - quadlet 0x%8.8x ", data);
@@ -1990,9 +1998,9 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
req->packet = packet;
hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_cb, req);
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
list_add_tail(&req->list, &fi->req_pending);
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
packet->generation = req->req.generation;
retval = hpsb_send_packet(packet);
DBGMSG("write_phypacket send_packet called => retval: %d ", retval);
@@ -2659,14 +2667,15 @@ static unsigned int raw1394_poll(struct file *file, poll_table * pt)
{
struct file_info *fi = file->private_data;
unsigned int mask = POLLOUT | POLLWRNORM;
+ unsigned long flags;
poll_wait(file, &fi->poll_wait_complete, pt);
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
if (!list_empty(&fi->req_complete)) {
mask |= POLLIN | POLLRDNORM;
}
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
return mask;
}
@@ -2710,6 +2719,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
struct arm_addr *arm_addr = NULL;
int another_host;
int csr_mod = 0;
+ unsigned long flags;
if (fi->iso_state != RAW1394_ISO_INACTIVE)
raw1394_iso_shutdown(fi);
@@ -2720,13 +2730,11 @@ static int raw1394_release(struct inode *inode, struct file *file)
}
}
- spin_lock_irq(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, flags);
fi->listen_channels = 0;
- spin_unlock_irq(&host_info_lock);
fail = 0;
/* set address-entries invalid */
- spin_lock_irq(&host_info_lock);
while (!list_empty(&fi->addr_list)) {
another_host = 0;
@@ -2777,14 +2785,14 @@ static int raw1394_release(struct inode *inode, struct file *file)
vfree(addr->addr_space_buffer);
kfree(addr);
} /* while */
- spin_unlock_irq(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, flags);
if (fail > 0) {
printk(KERN_ERR "raw1394: during addr_list-release "
"error(s) occurred \n");
}
while (!done) {
- spin_lock_irq(&fi->reqlists_lock);
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
while (!list_empty(&fi->req_complete)) {
lh = fi->req_complete.next;
@@ -2798,7 +2806,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
if (list_empty(&fi->req_pending))
done = 1;
- spin_unlock_irq(&fi->reqlists_lock);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
if (!done)
down_interruptible(&fi->complete_sem);
@@ -2828,9 +2836,9 @@ static int raw1394_release(struct inode *inode, struct file *file)
fi->host->id);
if (fi->state == connected) {
- spin_lock_irq(&host_info_lock);
+ spin_lock_irqsave(&host_info_lock, flags);
list_del(&fi->list);
- spin_unlock_irq(&host_info_lock);
+ spin_unlock_irqrestore(&host_info_lock, flags);
put_device(&fi->host->device);
}
@@ -2958,4 +2966,3 @@ static void __exit cleanup_raw1394(void)
module_init(init_raw1394);
module_exit(cleanup_raw1394);
MODULE_LICENSE("GPL");
-MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16);
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 627af507643a..12cec7c4a342 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -97,16 +97,18 @@ static char version[] __devinitdata =
*/
static int max_speed = IEEE1394_SPEED_MAX;
module_param(max_speed, int, 0644);
-MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 = 200mb, 0 = 100mb)");
+MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb, 1 = 200mb, 0 = 100mb)");
/*
* Set serialize_io to 1 if you'd like only one scsi command sent
* down to us at a time (debugging). This might be necessary for very
* badly behaved sbp2 devices.
+ *
+ * TODO: Make this configurable per device.
*/
-static int serialize_io;
+static int serialize_io = 1;
module_param(serialize_io, int, 0444);
-MODULE_PARM_DESC(serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)");
+MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers (default = 1, faster = 0)");
/*
* Bump up max_sectors if you'd like to support very large sized
@@ -596,6 +598,14 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
}
+/*
+ * Is scsi_id valid? Is the 1394 node still present?
+ */
+static inline int sbp2util_node_is_available(struct scsi_id_instance_data *scsi_id)
+{
+ return scsi_id && scsi_id->ne && !scsi_id->ne->in_limbo;
+}
+
/*********************************************
@@ -631,11 +641,23 @@ static int sbp2_remove(struct device *dev)
{
struct unit_directory *ud;
struct scsi_id_instance_data *scsi_id;
+ struct scsi_device *sdev;
SBP2_DEBUG("sbp2_remove");
ud = container_of(dev, struct unit_directory, device);
scsi_id = ud->device.driver_data;
+ if (!scsi_id)
+ return 0;
+
+ /* Trigger shutdown functions in scsi's highlevel. */
+ if (scsi_id->scsi_host)
+ scsi_unblock_requests(scsi_id->scsi_host);
+ sdev = scsi_id->sdev;
+ if (sdev) {
+ scsi_id->sdev = NULL;
+ scsi_remove_device(sdev);
+ }
sbp2_logout_device(scsi_id);
sbp2_remove_device(scsi_id);
@@ -790,7 +812,7 @@ static void sbp2_host_reset(struct hpsb_host *host)
static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
{
struct sbp2scsi_host_info *hi = scsi_id->hi;
- struct scsi_device *sdev;
+ int error;
SBP2_DEBUG("sbp2_start_device");
@@ -939,10 +961,10 @@ alloc_fail:
sbp2_max_speed_and_size(scsi_id);
/* Add this device to the scsi layer now */
- sdev = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
- if (IS_ERR(sdev)) {
+ error = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
+ if (error) {
SBP2_ERR("scsi_add_device failed");
- return PTR_ERR(sdev);
+ return error;
}
return 0;
@@ -2473,37 +2495,26 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
struct sbp2scsi_host_info *hi;
+ int result = DID_NO_CONNECT << 16;
SBP2_DEBUG("sbp2scsi_queuecommand");
- /*
- * If scsi_id is null, it means there is no device in this slot,
- * so we should return selection timeout.
- */
- if (!scsi_id) {
- SCpnt->result = DID_NO_CONNECT << 16;
- done (SCpnt);
- return 0;
- }
+ if (!sbp2util_node_is_available(scsi_id))
+ goto done;
hi = scsi_id->hi;
if (!hi) {
SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
- SCpnt->result = DID_NO_CONNECT << 16;
- done (SCpnt);
- return(0);
+ goto done;
}
/*
* Until we handle multiple luns, just return selection time-out
* to any IO directed at non-zero LUNs
*/
- if (SCpnt->device->lun) {
- SCpnt->result = DID_NO_CONNECT << 16;
- done (SCpnt);
- return(0);
- }
+ if (SCpnt->device->lun)
+ goto done;
/*
* Check for request sense command, and handle it here
@@ -2514,7 +2525,7 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
memcpy(SCpnt->request_buffer, SCpnt->sense_buffer, SCpnt->request_bufflen);
memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
sbp2scsi_complete_command(scsi_id, SBP2_SCSI_STATUS_GOOD, SCpnt, done);
- return(0);
+ return 0;
}
/*
@@ -2522,9 +2533,8 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
*/
if (!hpsb_node_entry_valid(scsi_id->ne)) {
SBP2_ERR("Bus reset in progress - rejecting command");
- SCpnt->result = DID_BUS_BUSY << 16;
- done (SCpnt);
- return(0);
+ result = DID_BUS_BUSY << 16;
+ goto done;
}
/*
@@ -2535,8 +2545,12 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
sbp2scsi_complete_command(scsi_id, SBP2_SCSI_STATUS_SELECTION_TIMEOUT,
SCpnt, done);
}
+ return 0;
- return(0);
+done:
+ SCpnt->result = result;
+ done(SCpnt);
+ return 0;
}
/*
@@ -2683,14 +2697,27 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
}
-static int sbp2scsi_slave_configure (struct scsi_device *sdev)
+static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
{
- blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
+ ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = sdev;
+ return 0;
+}
+
+static int sbp2scsi_slave_configure(struct scsi_device *sdev)
+{
+ blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
return 0;
}
+static void sbp2scsi_slave_destroy(struct scsi_device *sdev)
+{
+ ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = NULL;
+ return;
+}
+
+
/*
* Called by scsi stack when something has really gone wrong. Usually
* called when a command has timed-out for some reason.
@@ -2705,7 +2732,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
SBP2_ERR("aborting sbp2 command");
scsi_print_command(SCpnt);
- if (scsi_id) {
+ if (sbp2util_node_is_available(scsi_id)) {
/*
* Right now, just return any matching command structures
@@ -2742,31 +2769,24 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
/*
* Called by scsi stack when something has really gone wrong.
*/
-static int __sbp2scsi_reset(struct scsi_cmnd *SCpnt)
+static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{
struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
+ unsigned long flags;
SBP2_ERR("reset requested");
- if (scsi_id) {
+ spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
+
+ if (sbp2util_node_is_available(scsi_id)) {
SBP2_ERR("Generating sbp2 fetch agent reset");
sbp2_agent_reset(scsi_id, 0);
}
- return(SUCCESS);
-}
-
-static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
-{
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
- rc = __sbp2scsi_reset(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
- return rc;
+ return SUCCESS;
}
static const char *sbp2scsi_info (struct Scsi_Host *host)
@@ -2817,7 +2837,9 @@ static struct scsi_host_template scsi_driver_template = {
.eh_device_reset_handler = sbp2scsi_reset,
.eh_bus_reset_handler = sbp2scsi_reset,
.eh_host_reset_handler = sbp2scsi_reset,
+ .slave_alloc = sbp2scsi_slave_alloc,
.slave_configure = sbp2scsi_slave_configure,
+ .slave_destroy = sbp2scsi_slave_destroy,
.this_id = -1,
.sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
@@ -2837,7 +2859,8 @@ static int sbp2_module_init(void)
/* Module load debug option to force one command at a time (serializing I/O) */
if (serialize_io) {
- SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
+ SBP2_INFO("Driver forced to serialize I/O (serialize_io=1)");
+ SBP2_INFO("Try serialize_io=0 for better performance");
scsi_driver_template.can_queue = 1;
scsi_driver_template.cmd_per_lun = 1;
}
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 06759b36afea..11be9c9c82a8 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;
}
@@ -1571,4 +1571,3 @@ static int __init video1394_init_module (void)
module_init(video1394_init_module);
module_exit(video1394_exit_module);
-MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16);
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 32cdfb30e9b4..325d502e25cd 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -8,15 +8,26 @@ config INFINIBAND
any protocols you wish to use as well as drivers for your
InfiniBand hardware.
-config INFINIBAND_USER_VERBS
- tristate "InfiniBand userspace verbs support"
+config INFINIBAND_USER_MAD
+ tristate "InfiniBand userspace MAD support"
depends on INFINIBAND
---help---
- Userspace InfiniBand verbs support. This is the kernel side
- of userspace verbs, which allows userspace processes to
- directly access InfiniBand hardware for fast-path
- operations. You will also need libibverbs and a hardware
- driver library from <http://www.openib.org>.
+ Userspace InfiniBand Management Datagram (MAD) support. This
+ is the kernel side of the userspace MAD support, which allows
+ userspace processes to send and receive MADs. You will also
+ need libibumad from <http://www.openib.org>.
+
+config INFINIBAND_USER_ACCESS
+ tristate "InfiniBand userspace access (verbs and CM)"
+ depends on INFINIBAND
+ ---help---
+ Userspace InfiniBand access support. This enables the
+ kernel side of userspace verbs and the userspace
+ communication manager (CM). This allows userspace processes
+ to set up connections and directly access InfiniBand
+ hardware for fast-path operations. You will also need
+ libibverbs, libibcm and a hardware driver library from
+ <http://www.openib.org>.
source "drivers/infiniband/hw/mthca/Kconfig"
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index 678a7e097f32..ec3353f24b27 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
- ib_cm.o ib_umad.o ib_ucm.o
-obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o
+ ib_cm.o
+obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
+obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o
ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
device.o fmr_pool.o cache.o
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 4de93ba274a6..54db6d4831f1 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -173,7 +173,8 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
if (IS_ERR(ah))
return PTR_ERR(ah);
- m = ib_create_send_mad(mad_agent, 1, cm_id_priv->av.pkey_index,
+ m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
+ cm_id_priv->av.pkey_index,
ah, 0, sizeof(struct ib_mad_hdr),
sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
GFP_ATOMIC);
@@ -536,6 +537,7 @@ struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
cm_id_priv->id.state = IB_CM_IDLE;
cm_id_priv->id.cm_handler = cm_handler;
cm_id_priv->id.context = context;
+ cm_id_priv->id.remote_cm_qpn = 1;
ret = cm_alloc_id(cm_id_priv);
if (ret)
goto error;
@@ -1313,6 +1315,7 @@ error3: atomic_dec(&cm_id_priv->refcount);
cm_deref_id(listen_cm_id_priv);
cm_cleanup_timewait(cm_id_priv->timewait_info);
error2: kfree(cm_id_priv->timewait_info);
+ cm_id_priv->timewait_info = NULL;
error1: ib_destroy_cm_id(&cm_id_priv->id);
return ret;
}
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index a4a4d9c1eef3..a14ca87fda18 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -783,7 +783,7 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
u32 remote_qpn, u16 pkey_index,
struct ib_ah *ah, int rmpp_active,
int hdr_len, int data_len,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
struct ib_mad_agent_private *mad_agent_priv;
struct ib_mad_send_buf *send_buf;
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 43fd805e0265..e23836d0e21b 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -412,8 +412,8 @@ static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv)
hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class);
data_size = sizeof(struct ib_rmpp_mad) - hdr_size;
- pad = data_size - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
- if (pad > data_size || pad < 0)
+ pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
+ if (pad > IB_MGMT_RMPP_DATA || pad < 0)
pad = 0;
return hdr_size + rmpp_recv->seg_num * data_size - pad;
@@ -583,6 +583,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
{
struct ib_rmpp_mad *rmpp_mad;
int timeout;
+ u32 paylen;
rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
@@ -590,10 +591,9 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
if (mad_send_wr->seg_num == 1) {
rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST;
- rmpp_mad->rmpp_hdr.paylen_newwin =
- cpu_to_be32(mad_send_wr->total_seg *
- (sizeof(struct ib_rmpp_mad) -
- offsetof(struct ib_rmpp_mad, data)));
+ paylen = mad_send_wr->total_seg * IB_MGMT_RMPP_DATA -
+ mad_send_wr->pad;
+ rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad);
} else {
mad_send_wr->send_wr.num_sge = 2;
@@ -602,14 +602,13 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
mad_send_wr->sg_list[1].length = sizeof(struct ib_rmpp_mad) -
mad_send_wr->data_offset;
mad_send_wr->sg_list[1].lkey = mad_send_wr->sg_list[0].lkey;
+ rmpp_mad->rmpp_hdr.paylen_newwin = 0;
}
if (mad_send_wr->seg_num == mad_send_wr->total_seg) {
rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST;
- rmpp_mad->rmpp_hdr.paylen_newwin =
- cpu_to_be32(sizeof(struct ib_rmpp_mad) -
- offsetof(struct ib_rmpp_mad, data) -
- mad_send_wr->pad);
+ paylen = IB_MGMT_RMPP_DATA - mad_send_wr->pad;
+ rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
}
/* 2 seconds for an ACK until we can find the packet lifetime */
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 126ac80db7b8..262618210c1c 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -113,32 +113,6 @@ static DEFINE_IDR(query_idr);
static spinlock_t tid_lock;
static u32 tid;
-enum {
- IB_SA_ATTR_CLASS_PORTINFO = 0x01,
- IB_SA_ATTR_NOTICE = 0x02,
- IB_SA_ATTR_INFORM_INFO = 0x03,
- IB_SA_ATTR_NODE_REC = 0x11,
- IB_SA_ATTR_PORT_INFO_REC = 0x12,
- IB_SA_ATTR_SL2VL_REC = 0x13,
- IB_SA_ATTR_SWITCH_REC = 0x14,
- IB_SA_ATTR_LINEAR_FDB_REC = 0x15,
- IB_SA_ATTR_RANDOM_FDB_REC = 0x16,
- IB_SA_ATTR_MCAST_FDB_REC = 0x17,
- IB_SA_ATTR_SM_INFO_REC = 0x18,
- IB_SA_ATTR_LINK_REC = 0x20,
- IB_SA_ATTR_GUID_INFO_REC = 0x30,
- IB_SA_ATTR_SERVICE_REC = 0x31,
- IB_SA_ATTR_PARTITION_REC = 0x33,
- IB_SA_ATTR_RANGE_REC = 0x34,
- IB_SA_ATTR_PATH_REC = 0x35,
- IB_SA_ATTR_VL_ARB_REC = 0x36,
- IB_SA_ATTR_MC_GROUP_REC = 0x37,
- IB_SA_ATTR_MC_MEMBER_REC = 0x38,
- IB_SA_ATTR_TRACE_REC = 0x39,
- IB_SA_ATTR_MULTI_PATH_REC = 0x3a,
- IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b
-};
-
#define PATH_REC_FIELD(field) \
.struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \
.struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \
@@ -431,8 +405,8 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event
event->event == IB_EVENT_LID_CHANGE ||
event->event == IB_EVENT_PKEY_CHANGE ||
event->event == IB_EVENT_SM_CHANGE) {
- struct ib_sa_device *sa_dev =
- ib_get_client_data(event->device, &sa_client);
+ struct ib_sa_device *sa_dev;
+ sa_dev = container_of(handler, typeof(*sa_dev), event_handler);
schedule_work(&sa_dev->port[event->element.port_num -
sa_dev->start_port].update_task);
@@ -600,7 +574,7 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
struct ib_sa_path_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_path_rec *resp,
void *context),
@@ -702,7 +676,7 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
struct ib_sa_service_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_service_rec *resp,
void *context),
@@ -785,7 +759,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
u8 method,
struct ib_sa_mcmember_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_mcmember_rec *resp,
void *context),
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 79595826ccc7..d0f0b0a2edd3 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -72,7 +72,6 @@ enum {
static struct semaphore ctx_id_mutex;
static struct idr ctx_id_table;
-static int ctx_id_rover = 0;
static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
{
@@ -97,33 +96,16 @@ static void ib_ucm_ctx_put(struct ib_ucm_context *ctx)
wake_up(&ctx->wait);
}
-static ssize_t ib_ucm_destroy_ctx(struct ib_ucm_file *file, int id)
+static inline int ib_ucm_new_cm_id(int event)
{
- struct ib_ucm_context *ctx;
- struct ib_ucm_event *uevent;
-
- down(&ctx_id_mutex);
- ctx = idr_find(&ctx_id_table, id);
- if (!ctx)
- ctx = ERR_PTR(-ENOENT);
- else if (ctx->file != file)
- ctx = ERR_PTR(-EINVAL);
- else
- idr_remove(&ctx_id_table, ctx->id);
- up(&ctx_id_mutex);
-
- if (IS_ERR(ctx))
- return PTR_ERR(ctx);
-
- atomic_dec(&ctx->ref);
- wait_event(ctx->wait, !atomic_read(&ctx->ref));
+ return event == IB_CM_REQ_RECEIVED || event == IB_CM_SIDR_REQ_RECEIVED;
+}
- /* No new events will be generated after destroying the cm_id. */
- if (!IS_ERR(ctx->cm_id))
- ib_destroy_cm_id(ctx->cm_id);
+static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx)
+{
+ struct ib_ucm_event *uevent;
- /* Cleanup events not yet reported to the user. */
- down(&file->mutex);
+ down(&ctx->file->mutex);
list_del(&ctx->file_list);
while (!list_empty(&ctx->events)) {
@@ -133,15 +115,12 @@ static ssize_t ib_ucm_destroy_ctx(struct ib_ucm_file *file, int id)
list_del(&uevent->ctx_list);
/* clear incoming connections. */
- if (uevent->cm_id)
+ if (ib_ucm_new_cm_id(uevent->resp.event))
ib_destroy_cm_id(uevent->cm_id);
kfree(uevent);
}
- up(&file->mutex);
-
- kfree(ctx);
- return 0;
+ up(&ctx->file->mutex);
}
static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
@@ -153,36 +132,31 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
if (!ctx)
return NULL;
+ memset(ctx, 0, sizeof *ctx);
atomic_set(&ctx->ref, 1);
init_waitqueue_head(&ctx->wait);
ctx->file = file;
-
INIT_LIST_HEAD(&ctx->events);
- list_add_tail(&ctx->file_list, &file->ctxs);
-
- ctx_id_rover = (ctx_id_rover + 1) & INT_MAX;
-retry:
- result = idr_pre_get(&ctx_id_table, GFP_KERNEL);
- if (!result)
- goto error;
+ do {
+ result = idr_pre_get(&ctx_id_table, GFP_KERNEL);
+ if (!result)
+ goto error;
- down(&ctx_id_mutex);
- result = idr_get_new_above(&ctx_id_table, ctx, ctx_id_rover, &ctx->id);
- up(&ctx_id_mutex);
+ down(&ctx_id_mutex);
+ result = idr_get_new(&ctx_id_table, ctx, &ctx->id);
+ up(&ctx_id_mutex);
+ } while (result == -EAGAIN);
- if (result == -EAGAIN)
- goto retry;
if (result)
goto error;
+ list_add_tail(&ctx->file_list, &file->ctxs);
ucm_dbg("Allocated CM ID <%d>\n", ctx->id);
-
return ctx;
+
error:
- list_del(&ctx->file_list);
kfree(ctx);
-
return NULL;
}
/*
@@ -219,12 +193,9 @@ static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath,
kpath->packet_life_time_selector;
}
-static void ib_ucm_event_req_get(struct ib_ucm_context *ctx,
- struct ib_ucm_req_event_resp *ureq,
+static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq,
struct ib_cm_req_event_param *kreq)
{
- ureq->listen_id = ctx->id;
-
ureq->remote_ca_guid = kreq->remote_ca_guid;
ureq->remote_qkey = kreq->remote_qkey;
ureq->remote_qpn = kreq->remote_qpn;
@@ -259,14 +230,6 @@ static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep,
urep->srq = krep->srq;
}
-static void ib_ucm_event_sidr_req_get(struct ib_ucm_context *ctx,
- struct ib_ucm_sidr_req_event_resp *ureq,
- struct ib_cm_sidr_req_event_param *kreq)
-{
- ureq->listen_id = ctx->id;
- ureq->pkey = kreq->pkey;
-}
-
static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep,
struct ib_cm_sidr_rep_event_param *krep)
{
@@ -275,15 +238,14 @@ static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep,
urep->qpn = krep->qpn;
};
-static int ib_ucm_event_process(struct ib_ucm_context *ctx,
- struct ib_cm_event *evt,
+static int ib_ucm_event_process(struct ib_cm_event *evt,
struct ib_ucm_event *uvt)
{
void *info = NULL;
switch (evt->event) {
case IB_CM_REQ_RECEIVED:
- ib_ucm_event_req_get(ctx, &uvt->resp.u.req_resp,
+ ib_ucm_event_req_get(&uvt->resp.u.req_resp,
&evt->param.req_rcvd);
uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE;
uvt->resp.present = IB_UCM_PRES_PRIMARY;
@@ -331,8 +293,8 @@ static int ib_ucm_event_process(struct ib_ucm_context *ctx,
info = evt->param.apr_rcvd.apr_info;
break;
case IB_CM_SIDR_REQ_RECEIVED:
- ib_ucm_event_sidr_req_get(ctx, &uvt->resp.u.sidr_req_resp,
- &evt->param.sidr_req_rcvd);
+ uvt->resp.u.sidr_req_resp.pkey =
+ evt->param.sidr_req_rcvd.pkey;
uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;
break;
case IB_CM_SIDR_REP_RECEIVED:
@@ -378,31 +340,24 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id,
struct ib_ucm_event *uevent;
struct ib_ucm_context *ctx;
int result = 0;
- int id;
ctx = cm_id->context;
- if (event->event == IB_CM_REQ_RECEIVED ||
- event->event == IB_CM_SIDR_REQ_RECEIVED)
- id = IB_UCM_CM_ID_INVALID;
- else
- id = ctx->id;
-
uevent = kmalloc(sizeof(*uevent), GFP_KERNEL);
if (!uevent)
goto err1;
memset(uevent, 0, sizeof(*uevent));
- uevent->resp.id = id;
+ uevent->ctx = ctx;
+ uevent->cm_id = cm_id;
+ uevent->resp.uid = ctx->uid;
+ uevent->resp.id = ctx->id;
uevent->resp.event = event->event;
- result = ib_ucm_event_process(ctx, event, uevent);
+ result = ib_ucm_event_process(event, uevent);
if (result)
goto err2;
- uevent->ctx = ctx;
- uevent->cm_id = (id == IB_UCM_CM_ID_INVALID) ? cm_id : NULL;
-
down(&ctx->file->mutex);
list_add_tail(&uevent->file_list, &ctx->file->events);
list_add_tail(&uevent->ctx_list, &ctx->events);
@@ -414,7 +369,7 @@ err2:
kfree(uevent);
err1:
/* Destroy new cm_id's */
- return (id == IB_UCM_CM_ID_INVALID);
+ return ib_ucm_new_cm_id(event->event);
}
static ssize_t ib_ucm_event(struct ib_ucm_file *file,
@@ -423,7 +378,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,
{
struct ib_ucm_context *ctx;
struct ib_ucm_event_get cmd;
- struct ib_ucm_event *uevent = NULL;
+ struct ib_ucm_event *uevent;
int result = 0;
DEFINE_WAIT(wait);
@@ -436,7 +391,6 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,
* wait
*/
down(&file->mutex);
-
while (list_empty(&file->events)) {
if (file->filp->f_flags & O_NONBLOCK) {
@@ -463,21 +417,18 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,
uevent = list_entry(file->events.next, struct ib_ucm_event, file_list);
- if (!uevent->cm_id)
- goto user;
+ if (ib_ucm_new_cm_id(uevent->resp.event)) {
+ ctx = ib_ucm_ctx_alloc(file);
+ if (!ctx) {
+ result = -ENOMEM;
+ goto done;
+ }
- ctx = ib_ucm_ctx_alloc(file);
- if (!ctx) {
- result = -ENOMEM;
- goto done;
+ ctx->cm_id = uevent->cm_id;
+ ctx->cm_id->context = ctx;
+ uevent->resp.id = ctx->id;
}
- ctx->cm_id = uevent->cm_id;
- ctx->cm_id->context = ctx;
-
- uevent->resp.id = ctx->id;
-
-user:
if (copy_to_user((void __user *)(unsigned long)cmd.response,
&uevent->resp, sizeof(uevent->resp))) {
result = -EFAULT;
@@ -485,12 +436,10 @@ user:
}
if (uevent->data) {
-
if (cmd.data_len < uevent->data_len) {
result = -ENOMEM;
goto done;
}
-
if (copy_to_user((void __user *)(unsigned long)cmd.data,
uevent->data, uevent->data_len)) {
result = -EFAULT;
@@ -499,12 +448,10 @@ user:
}
if (uevent->info) {
-
if (cmd.info_len < uevent->info_len) {
result = -ENOMEM;
goto done;
}
-
if (copy_to_user((void __user *)(unsigned long)cmd.info,
uevent->info, uevent->info_len)) {
result = -EFAULT;
@@ -514,6 +461,7 @@ user:
list_del(&uevent->file_list);
list_del(&uevent->ctx_list);
+ uevent->ctx->events_reported++;
kfree(uevent->data);
kfree(uevent->info);
@@ -545,6 +493,7 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
if (!ctx)
return -ENOMEM;
+ ctx->uid = cmd.uid;
ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx);
if (IS_ERR(ctx->cm_id)) {
result = PTR_ERR(ctx->cm_id);
@@ -561,7 +510,14 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
return 0;
err:
- ib_ucm_destroy_ctx(file, ctx->id);
+ down(&ctx_id_mutex);
+ idr_remove(&ctx_id_table, ctx->id);
+ up(&ctx_id_mutex);
+
+ if (!IS_ERR(ctx->cm_id))
+ ib_destroy_cm_id(ctx->cm_id);
+
+ kfree(ctx);
return result;
}
@@ -570,11 +526,44 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,
int in_len, int out_len)
{
struct ib_ucm_destroy_id cmd;
+ struct ib_ucm_destroy_id_resp resp;
+ struct ib_ucm_context *ctx;
+ int result = 0;
+
+ if (out_len < sizeof(resp))
+ return -ENOSPC;
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;
- return ib_ucm_destroy_ctx(file, cmd.id);
+ down(&ctx_id_mutex);
+ ctx = idr_find(&ctx_id_table, cmd.id);
+ if (!ctx)
+ ctx = ERR_PTR(-ENOENT);
+ else if (ctx->file != file)
+ ctx = ERR_PTR(-EINVAL);
+ else
+ idr_remove(&ctx_id_table, ctx->id);
+ up(&ctx_id_mutex);
+
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ atomic_dec(&ctx->ref);
+ wait_event(ctx->wait, !atomic_read(&ctx->ref));
+
+ /* No new events will be generated after destroying the cm_id. */
+ ib_destroy_cm_id(ctx->cm_id);
+ /* Cleanup events not yet reported to the user. */
+ ib_ucm_cleanup_events(ctx);
+
+ resp.events_reported = ctx->events_reported;
+ if (copy_to_user((void __user *)(unsigned long)cmd.response,
+ &resp, sizeof(resp)))
+ result = -EFAULT;
+
+ kfree(ctx);
+ return result;
}
static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,
@@ -609,6 +598,98 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,
return result;
}
+static void ib_ucm_copy_ah_attr(struct ib_ucm_ah_attr *dest_attr,
+ struct ib_ah_attr *src_attr)
+{
+ memcpy(dest_attr->grh_dgid, src_attr->grh.dgid.raw,
+ sizeof src_attr->grh.dgid);
+ dest_attr->grh_flow_label = src_attr->grh.flow_label;
+ dest_attr->grh_sgid_index = src_attr->grh.sgid_index;
+ dest_attr->grh_hop_limit = src_attr->grh.hop_limit;
+ dest_attr->grh_traffic_class = src_attr->grh.traffic_class;
+
+ dest_attr->dlid = src_attr->dlid;
+ dest_attr->sl = src_attr->sl;
+ dest_attr->src_path_bits = src_attr->src_path_bits;
+ dest_attr->static_rate = src_attr->static_rate;
+ dest_attr->is_global = (src_attr->ah_flags & IB_AH_GRH);
+ dest_attr->port_num = src_attr->port_num;
+}
+
+static void ib_ucm_copy_qp_attr(struct ib_ucm_init_qp_attr_resp *dest_attr,
+ struct ib_qp_attr *src_attr)
+{
+ dest_attr->cur_qp_state = src_attr->cur_qp_state;
+ dest_attr->path_mtu = src_attr->path_mtu;
+ dest_attr->path_mig_state = src_attr->path_mig_state;
+ dest_attr->qkey = src_attr->qkey;
+ dest_attr->rq_psn = src_attr->rq_psn;
+ dest_attr->sq_psn = src_attr->sq_psn;
+ dest_attr->dest_qp_num = src_attr->dest_qp_num;
+ dest_attr->qp_access_flags = src_attr->qp_access_flags;
+
+ dest_attr->max_send_wr = src_attr->cap.max_send_wr;
+ dest_attr->max_recv_wr = src_attr->cap.max_recv_wr;
+ dest_attr->max_send_sge = src_attr->cap.max_send_sge;
+ dest_attr->max_recv_sge = src_attr->cap.max_recv_sge;
+ dest_attr->max_inline_data = src_attr->cap.max_inline_data;
+
+ ib_ucm_copy_ah_attr(&dest_attr->ah_attr, &src_attr->ah_attr);
+ ib_ucm_copy_ah_attr(&dest_attr->alt_ah_attr, &src_attr->alt_ah_attr);
+
+ dest_attr->pkey_index = src_attr->pkey_index;
+ dest_attr->alt_pkey_index = src_attr->alt_pkey_index;
+ dest_attr->en_sqd_async_notify = src_attr->en_sqd_async_notify;
+ dest_attr->sq_draining = src_attr->sq_draining;
+ dest_attr->max_rd_atomic = src_attr->max_rd_atomic;
+ dest_attr->max_dest_rd_atomic = src_attr->max_dest_rd_atomic;
+ dest_attr->min_rnr_timer = src_attr->min_rnr_timer;
+ dest_attr->port_num = src_attr->port_num;
+ dest_attr->timeout = src_attr->timeout;
+ dest_attr->retry_cnt = src_attr->retry_cnt;
+ dest_attr->rnr_retry = src_attr->rnr_retry;
+ dest_attr->alt_port_num = src_attr->alt_port_num;
+ dest_attr->alt_timeout = src_attr->alt_timeout;
+}
+
+static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct ib_ucm_init_qp_attr_resp resp;
+ struct ib_ucm_init_qp_attr cmd;
+ struct ib_ucm_context *ctx;
+ struct ib_qp_attr qp_attr;
+ int result = 0;
+
+ if (out_len < sizeof(resp))
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ ctx = ib_ucm_ctx_get(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ resp.qp_attr_mask = 0;
+ memset(&qp_attr, 0, sizeof qp_attr);
+ qp_attr.qp_state = cmd.qp_state;
+ result = ib_cm_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask);
+ if (result)
+ goto out;
+
+ ib_ucm_copy_qp_attr(&resp, &qp_attr);
+
+ if (copy_to_user((void __user *)(unsigned long)cmd.response,
+ &resp, sizeof(resp)))
+ result = -EFAULT;
+
+out:
+ ib_ucm_ctx_put(ctx);
+ return result;
+}
+
static ssize_t ib_ucm_listen(struct ib_ucm_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -808,6 +889,7 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file,
ctx = ib_ucm_ctx_get(file, cmd.id);
if (!IS_ERR(ctx)) {
+ ctx->uid = cmd.uid;
result = ib_send_cm_rep(ctx->cm_id, &param);
ib_ucm_ctx_put(ctx);
} else
@@ -1086,6 +1168,7 @@ static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file,
[IB_USER_CM_CMD_SEND_SIDR_REQ] = ib_ucm_send_sidr_req,
[IB_USER_CM_CMD_SEND_SIDR_REP] = ib_ucm_send_sidr_rep,
[IB_USER_CM_CMD_EVENT] = ib_ucm_event,
+ [IB_USER_CM_CMD_INIT_QP_ATTR] = ib_ucm_init_qp_attr,
};
static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,
@@ -1161,12 +1244,18 @@ static int ib_ucm_close(struct inode *inode, struct file *filp)
down(&file->mutex);
while (!list_empty(&file->ctxs)) {
-
ctx = list_entry(file->ctxs.next,
struct ib_ucm_context, file_list);
-
up(&file->mutex);
- ib_ucm_destroy_ctx(file, ctx->id);
+
+ down(&ctx_id_mutex);
+ idr_remove(&ctx_id_table, ctx->id);
+ up(&ctx_id_mutex);
+
+ ib_destroy_cm_id(ctx->cm_id);
+ ib_ucm_cleanup_events(ctx);
+ kfree(ctx);
+
down(&file->mutex);
}
up(&file->mutex);
diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h
index c8819b928a1b..f46f37bc1201 100644
--- a/drivers/infiniband/core/ucm.h
+++ b/drivers/infiniband/core/ucm.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -43,8 +44,6 @@
#include <rdma/ib_cm.h>
#include <rdma/ib_user_cm.h>
-#define IB_UCM_CM_ID_INVALID 0xffffffff
-
struct ib_ucm_file {
struct semaphore mutex;
struct file *filp;
@@ -58,9 +57,11 @@ struct ib_ucm_context {
int id;
wait_queue_head_t wait;
atomic_t ref;
+ int events_reported;
struct ib_ucm_file *file;
struct ib_cm_id *cm_id;
+ __u64 uid;
struct list_head events; /* list of pending events. */
struct list_head file_list; /* member in file ctx list */
@@ -71,16 +72,12 @@ struct ib_ucm_event {
struct list_head file_list; /* member in file event list */
struct list_head ctx_list; /* member in ctx event list */
+ struct ib_cm_id *cm_id;
struct ib_ucm_event_resp resp;
void *data;
void *info;
int data_len;
int info_len;
- /*
- * new connection identifiers needs to be saved until
- * userspace can get a handle on them.
- */
- struct ib_cm_id *cm_id;
};
#endif /* UCM_H */
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 7c2f03057ddb..a64d6b4dcc16 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -334,10 +334,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
ret = -EINVAL;
goto err_ah;
}
- /* Validate that management class can support RMPP */
+
+ /* Validate that the management class can support RMPP */
if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
hdr_len = offsetof(struct ib_sa_mad, data);
- data_len = length;
+ data_len = length - hdr_len;
} else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
(rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {
hdr_len = offsetof(struct ib_vendor_mad, data);
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 180b3d4765e4..cc124344dd2c 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -69,6 +69,7 @@ struct ib_uverbs_event_file {
struct ib_uverbs_file {
struct kref ref;
+ struct semaphore mutex;
struct ib_uverbs_device *device;
struct ib_ucontext *ucontext;
struct ib_event_handler event_handler;
@@ -76,20 +77,28 @@ struct ib_uverbs_file {
struct ib_uverbs_event_file comp_file[1];
};
-struct ib_uverbs_async_event {
- struct ib_uverbs_async_event_desc desc;
+struct ib_uverbs_event {
+ union {
+ struct ib_uverbs_async_event_desc async;
+ struct ib_uverbs_comp_event_desc comp;
+ } desc;
struct list_head list;
+ struct list_head obj_list;
+ u32 *counter;
};
-struct ib_uverbs_comp_event {
- struct ib_uverbs_comp_event_desc desc;
- struct list_head list;
+struct ib_uevent_object {
+ struct ib_uobject uobject;
+ struct list_head event_list;
+ u32 events_reported;
};
-struct ib_uobject_mr {
- struct ib_uobject uobj;
- struct page *page_list;
- struct scatterlist *sg_list;
+struct ib_ucq_object {
+ struct ib_uobject uobject;
+ struct list_head comp_list;
+ struct list_head async_list;
+ u32 comp_events_reported;
+ u32 async_events_reported;
};
extern struct semaphore ib_uverbs_idr_mutex;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index ebccf9f38af9..562445165d2b 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -76,8 +76,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
struct ib_uverbs_get_context_resp resp;
struct ib_udata udata;
struct ib_device *ibdev = file->device->ib_dev;
+ struct ib_ucontext *ucontext;
int i;
- int ret = in_len;
+ int ret;
if (out_len < sizeof resp)
return -ENOSPC;
@@ -85,45 +86,56 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ down(&file->mutex);
+
+ if (file->ucontext) {
+ ret = -EINVAL;
+ goto err;
+ }
+
INIT_UDATA(&udata, buf + sizeof cmd,
(unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp);
- file->ucontext = ibdev->alloc_ucontext(ibdev, &udata);
- if (IS_ERR(file->ucontext)) {
- ret = PTR_ERR(file->ucontext);
- file->ucontext = NULL;
- return ret;
- }
+ ucontext = ibdev->alloc_ucontext(ibdev, &udata);
+ if (IS_ERR(ucontext))
+ return PTR_ERR(file->ucontext);
- file->ucontext->device = ibdev;
- INIT_LIST_HEAD(&file->ucontext->pd_list);
- INIT_LIST_HEAD(&file->ucontext->mr_list);
- INIT_LIST_HEAD(&file->ucontext->mw_list);
- INIT_LIST_HEAD(&file->ucontext->cq_list);
- INIT_LIST_HEAD(&file->ucontext->qp_list);
- INIT_LIST_HEAD(&file->ucontext->srq_list);
- INIT_LIST_HEAD(&file->ucontext->ah_list);
- spin_lock_init(&file->ucontext->lock);
+ ucontext->device = ibdev;
+ INIT_LIST_HEAD(&ucontext->pd_list);
+ INIT_LIST_HEAD(&ucontext->mr_list);
+ INIT_LIST_HEAD(&ucontext->mw_list);
+ INIT_LIST_HEAD(&ucontext->cq_list);
+ INIT_LIST_HEAD(&ucontext->qp_list);
+ INIT_LIST_HEAD(&ucontext->srq_list);
+ INIT_LIST_HEAD(&ucontext->ah_list);
resp.async_fd = file->async_file.fd;
for (i = 0; i < file->device->num_comp; ++i)
if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
i * sizeof (__u32),
- &file->comp_file[i].fd, sizeof (__u32)))
- goto err;
+ &file->comp_file[i].fd, sizeof (__u32))) {
+ ret = -EFAULT;
+ goto err_free;
+ }
if (copy_to_user((void __user *) (unsigned long) cmd.response,
- &resp, sizeof resp))
- goto err;
+ &resp, sizeof resp)) {
+ ret = -EFAULT;
+ goto err_free;
+ }
+
+ file->ucontext = ucontext;
+ up(&file->mutex);
return in_len;
-err:
- ibdev->dealloc_ucontext(file->ucontext);
- file->ucontext = NULL;
+err_free:
+ ibdev->dealloc_ucontext(ucontext);
- return -EFAULT;
+err:
+ up(&file->mutex);
+ return ret;
}
ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
@@ -352,9 +364,9 @@ retry:
if (ret)
goto err_pd;
- spin_lock_irq(&file->ucontext->lock);
+ down(&file->mutex);
list_add_tail(&uobj->list, &file->ucontext->pd_list);
- spin_unlock_irq(&file->ucontext->lock);
+ up(&file->mutex);
memset(&resp, 0, sizeof resp);
resp.pd_handle = uobj->id;
@@ -368,9 +380,9 @@ retry:
return in_len;
err_list:
- spin_lock_irq(&file->ucontext->lock);
+ down(&file->mutex);
list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ up(&file->mutex);
down(&ib_uverbs_idr_mutex);
idr_remove(&ib_uverbs_pd_idr, uobj->id);
@@ -410,9 +422,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
- spin_lock_irq(&file->ucontext->lock);
+ down(&file->mutex);
list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ up(&file->mutex);
kfree(uobj);
@@ -512,9 +524,9 @@ retry:
resp.mr_handle = obj->uobject.id;
- spin_lock_irq(&file->ucontext->lock);
+ down(&file->mutex);
list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
- spin_unlock_irq(&file->ucontext->lock);
+ up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
@@ -527,9 +539,9 @@ retry:
return in_len;
err_list:
- spin_lock_irq(&file->ucontext->lock);
+ down(&file->mutex);
list_del(&obj->uobject.list);
- spin_unlock_irq(&file->ucontext->lock);
+ up(&file->mutex);
err_unreg:
ib_dereg_mr(mr);
@@ -570,9 +582,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
- spin_lock_irq(&file->ucontext->lock);
+ down(&file->mutex);
list_del(&memobj->uobject.list);
- spin_unlock_irq(&file->ucontext->lock);
+ up(&file->mutex);
ib_umem_release(file->device->ib_dev, &memobj->umem);
kfree(memobj);
@@ -590,7 +602,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
struct ib_uverbs_create_cq cmd;
struct ib_uverbs_create_cq_resp resp;
struct ib_udata udata;
- struct ib_uobject *uobj;
+ struct ib_ucq_object *uobj;
struct ib_cq *cq;
int ret;
@@ -611,8 +623,12 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
if (!uobj)
return -ENOMEM;
- uobj->user_handle = cmd.user_handle;
- uobj->context = file->ucontext;
+ uobj->uobject.user_handle = cmd.user_handle;
+ uobj->uobject.context = file->ucontext;
+ uobj->comp_events_reported = 0;
+ uobj->async_events_reported = 0;
+ INIT_LIST_HEAD(&uobj->comp_list);
+ INIT_LIST_HEAD(&uobj->async_list);
cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
file->ucontext, &udata);
@@ -622,7 +638,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
}
cq->device = file->device->ib_dev;
- cq->uobject = uobj;
+ cq->uobject = &uobj->uobject;
cq->comp_handler = ib_uverbs_comp_handler;
cq->event_handler = ib_uverbs_cq_event_handler;
cq->cq_context = file;
@@ -635,7 +651,7 @@ retry:
}
down(&ib_uverbs_idr_mutex);
- ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->id);
+ ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id);
up(&ib_uverbs_idr_mutex);
if (ret == -EAGAIN)
@@ -643,12 +659,12 @@ retry:
if (ret)
goto err_cq;
- spin_lock_irq(&file->ucontext->lock);
- list_add_tail(&uobj->list, &file->ucontext->cq_list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
+ up(&file->mutex);
memset(&resp, 0, sizeof resp);
- resp.cq_handle = uobj->id;
+ resp.cq_handle = uobj->uobject.id;
resp.cqe = cq->cqe;
if (copy_to_user((void __user *) (unsigned long) cmd.response,
@@ -660,12 +676,12 @@ retry:
return in_len;
err_list:
- spin_lock_irq(&file->ucontext->lock);
- list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_del(&uobj->uobject.list);
+ up(&file->mutex);
down(&ib_uverbs_idr_mutex);
- idr_remove(&ib_uverbs_cq_idr, uobj->id);
+ idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
up(&ib_uverbs_idr_mutex);
err_cq:
@@ -680,21 +696,27 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
- struct ib_uverbs_destroy_cq cmd;
- struct ib_cq *cq;
- struct ib_uobject *uobj;
- int ret = -EINVAL;
+ struct ib_uverbs_destroy_cq cmd;
+ struct ib_uverbs_destroy_cq_resp resp;
+ struct ib_cq *cq;
+ struct ib_ucq_object *uobj;
+ struct ib_uverbs_event *evt, *tmp;
+ u64 user_handle;
+ int ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ memset(&resp, 0, sizeof resp);
+
down(&ib_uverbs_idr_mutex);
cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
if (!cq || cq->uobject->context != file->ucontext)
goto out;
- uobj = cq->uobject;
+ user_handle = cq->uobject->user_handle;
+ uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
ret = ib_destroy_cq(cq);
if (ret)
@@ -702,12 +724,33 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
- spin_lock_irq(&file->ucontext->lock);
- list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_del(&uobj->uobject.list);
+ up(&file->mutex);
+
+ spin_lock_irq(&file->comp_file[0].lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&file->comp_file[0].lock);
+
+ spin_lock_irq(&file->async_file.lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&file->async_file.lock);
+
+ resp.comp_events_reported = uobj->comp_events_reported;
+ resp.async_events_reported = uobj->async_events_reported;
kfree(uobj);
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
+
out:
up(&ib_uverbs_idr_mutex);
@@ -721,7 +764,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
struct ib_uverbs_create_qp cmd;
struct ib_uverbs_create_qp_resp resp;
struct ib_udata udata;
- struct ib_uobject *uobj;
+ struct ib_uevent_object *uobj;
struct ib_pd *pd;
struct ib_cq *scq, *rcq;
struct ib_srq *srq;
@@ -772,8 +815,10 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
attr.cap.max_recv_sge = cmd.max_recv_sge;
attr.cap.max_inline_data = cmd.max_inline_data;
- uobj->user_handle = cmd.user_handle;
- uobj->context = file->ucontext;
+ uobj->uobject.user_handle = cmd.user_handle;
+ uobj->uobject.context = file->ucontext;
+ uobj->events_reported = 0;
+ INIT_LIST_HEAD(&uobj->event_list);
qp = pd->device->create_qp(pd, &attr, &udata);
if (IS_ERR(qp)) {
@@ -786,7 +831,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
qp->send_cq = attr.send_cq;
qp->recv_cq = attr.recv_cq;
qp->srq = attr.srq;
- qp->uobject = uobj;
+ qp->uobject = &uobj->uobject;
qp->event_handler = attr.event_handler;
qp->qp_context = attr.qp_context;
qp->qp_type = attr.qp_type;
@@ -805,18 +850,18 @@ retry:
goto err_destroy;
}
- ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->id);
+ ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->uobject.id);
if (ret == -EAGAIN)
goto retry;
if (ret)
goto err_destroy;
- resp.qp_handle = uobj->id;
+ resp.qp_handle = uobj->uobject.id;
- spin_lock_irq(&file->ucontext->lock);
- list_add_tail(&uobj->list, &file->ucontext->qp_list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
+ up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
@@ -829,9 +874,9 @@ retry:
return in_len;
err_list:
- spin_lock_irq(&file->ucontext->lock);
- list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_del(&uobj->uobject.list);
+ up(&file->mutex);
err_destroy:
ib_destroy_qp(qp);
@@ -930,21 +975,25 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
- struct ib_uverbs_destroy_qp cmd;
- struct ib_qp *qp;
- struct ib_uobject *uobj;
- int ret = -EINVAL;
+ struct ib_uverbs_destroy_qp cmd;
+ struct ib_uverbs_destroy_qp_resp resp;
+ struct ib_qp *qp;
+ struct ib_uevent_object *uobj;
+ struct ib_uverbs_event *evt, *tmp;
+ int ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ memset(&resp, 0, sizeof resp);
+
down(&ib_uverbs_idr_mutex);
qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
if (!qp || qp->uobject->context != file->ucontext)
goto out;
- uobj = qp->uobject;
+ uobj = container_of(qp->uobject, struct ib_uevent_object, uobject);
ret = ib_destroy_qp(qp);
if (ret)
@@ -952,12 +1001,25 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
- spin_lock_irq(&file->ucontext->lock);
- list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_del(&uobj->uobject.list);
+ up(&file->mutex);
+
+ spin_lock_irq(&file->async_file.lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&file->async_file.lock);
+
+ resp.events_reported = uobj->events_reported;
kfree(uobj);
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
+
out:
up(&ib_uverbs_idr_mutex);
@@ -1015,7 +1077,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
struct ib_uverbs_create_srq cmd;
struct ib_uverbs_create_srq_resp resp;
struct ib_udata udata;
- struct ib_uobject *uobj;
+ struct ib_uevent_object *uobj;
struct ib_pd *pd;
struct ib_srq *srq;
struct ib_srq_init_attr attr;
@@ -1050,8 +1112,10 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
attr.attr.max_sge = cmd.max_sge;
attr.attr.srq_limit = cmd.srq_limit;
- uobj->user_handle = cmd.user_handle;
- uobj->context = file->ucontext;
+ uobj->uobject.user_handle = cmd.user_handle;
+ uobj->uobject.context = file->ucontext;
+ uobj->events_reported = 0;
+ INIT_LIST_HEAD(&uobj->event_list);
srq = pd->device->create_srq(pd, &attr, &udata);
if (IS_ERR(srq)) {
@@ -1061,7 +1125,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
srq->device = pd->device;
srq->pd = pd;
- srq->uobject = uobj;
+ srq->uobject = &uobj->uobject;
srq->event_handler = attr.event_handler;
srq->srq_context = attr.srq_context;
atomic_inc(&pd->usecnt);
@@ -1075,18 +1139,18 @@ retry:
goto err_destroy;
}
- ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->id);
+ ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->uobject.id);
if (ret == -EAGAIN)
goto retry;
if (ret)
goto err_destroy;
- resp.srq_handle = uobj->id;
+ resp.srq_handle = uobj->uobject.id;
- spin_lock_irq(&file->ucontext->lock);
- list_add_tail(&uobj->list, &file->ucontext->srq_list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
+ up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
@@ -1099,9 +1163,9 @@ retry:
return in_len;
err_list:
- spin_lock_irq(&file->ucontext->lock);
- list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_del(&uobj->uobject.list);
+ up(&file->mutex);
err_destroy:
ib_destroy_srq(srq);
@@ -1149,21 +1213,25 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
- struct ib_uverbs_destroy_srq cmd;
- struct ib_srq *srq;
- struct ib_uobject *uobj;
- int ret = -EINVAL;
+ struct ib_uverbs_destroy_srq cmd;
+ struct ib_uverbs_destroy_srq_resp resp;
+ struct ib_srq *srq;
+ struct ib_uevent_object *uobj;
+ struct ib_uverbs_event *evt, *tmp;
+ int ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
down(&ib_uverbs_idr_mutex);
+ memset(&resp, 0, sizeof resp);
+
srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
if (!srq || srq->uobject->context != file->ucontext)
goto out;
- uobj = srq->uobject;
+ uobj = container_of(srq->uobject, struct ib_uevent_object, uobject);
ret = ib_destroy_srq(srq);
if (ret)
@@ -1171,12 +1239,25 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
- spin_lock_irq(&file->ucontext->lock);
- list_del(&uobj->list);
- spin_unlock_irq(&file->ucontext->lock);
+ down(&file->mutex);
+ list_del(&uobj->uobject.list);
+ up(&file->mutex);
+
+ spin_lock_irq(&file->async_file.lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&file->async_file.lock);
+
+ resp.events_reported = uobj->events_reported;
kfree(uobj);
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
+
out:
up(&ib_uverbs_idr_mutex);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 09caf5b1ef36..12511808de21 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -120,7 +120,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
idr_remove(&ib_uverbs_qp_idr, uobj->id);
ib_destroy_qp(qp);
list_del(&uobj->list);
- kfree(uobj);
+ kfree(container_of(uobj, struct ib_uevent_object, uobject));
}
list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
@@ -128,7 +128,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
idr_remove(&ib_uverbs_cq_idr, uobj->id);
ib_destroy_cq(cq);
list_del(&uobj->list);
- kfree(uobj);
+ kfree(container_of(uobj, struct ib_ucq_object, uobject));
}
list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
@@ -136,7 +136,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
idr_remove(&ib_uverbs_srq_idr, uobj->id);
ib_destroy_srq(srq);
list_del(&uobj->list);
- kfree(uobj);
+ kfree(container_of(uobj, struct ib_uevent_object, uobject));
}
/* XXX Free MWs */
@@ -182,7 +182,7 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
size_t count, loff_t *pos)
{
struct ib_uverbs_event_file *file = filp->private_data;
- void *event;
+ struct ib_uverbs_event *event;
int eventsz;
int ret = 0;
@@ -207,21 +207,23 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
return -ENODEV;
}
- if (file->is_async) {
- event = list_entry(file->event_list.next,
- struct ib_uverbs_async_event, list);
+ event = list_entry(file->event_list.next, struct ib_uverbs_event, list);
+
+ if (file->is_async)
eventsz = sizeof (struct ib_uverbs_async_event_desc);
- } else {
- event = list_entry(file->event_list.next,
- struct ib_uverbs_comp_event, list);
+ else
eventsz = sizeof (struct ib_uverbs_comp_event_desc);
- }
if (eventsz > count) {
ret = -EINVAL;
event = NULL;
- } else
+ } else {
list_del(file->event_list.next);
+ if (event->counter) {
+ ++(*event->counter);
+ list_del(&event->obj_list);
+ }
+ }
spin_unlock_irq(&file->lock);
@@ -257,16 +259,13 @@ static unsigned int ib_uverbs_event_poll(struct file *filp,
static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
{
- struct list_head *entry, *tmp;
+ struct ib_uverbs_event *entry, *tmp;
spin_lock_irq(&file->lock);
if (file->fd != -1) {
file->fd = -1;
- list_for_each_safe(entry, tmp, &file->event_list)
- if (file->is_async)
- kfree(list_entry(entry, struct ib_uverbs_async_event, list));
- else
- kfree(list_entry(entry, struct ib_uverbs_comp_event, list));
+ list_for_each_entry_safe(entry, tmp, &file->event_list, list)
+ kfree(entry);
}
spin_unlock_irq(&file->lock);
}
@@ -304,18 +303,23 @@ static struct file_operations uverbs_event_fops = {
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
{
- struct ib_uverbs_file *file = cq_context;
- struct ib_uverbs_comp_event *entry;
- unsigned long flags;
+ struct ib_uverbs_file *file = cq_context;
+ struct ib_ucq_object *uobj;
+ struct ib_uverbs_event *entry;
+ unsigned long flags;
entry = kmalloc(sizeof *entry, GFP_ATOMIC);
if (!entry)
return;
- entry->desc.cq_handle = cq->uobject->user_handle;
+ uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
+
+ entry->desc.comp.cq_handle = cq->uobject->user_handle;
+ entry->counter = &uobj->comp_events_reported;
spin_lock_irqsave(&file->comp_file[0].lock, flags);
list_add_tail(&entry->list, &file->comp_file[0].event_list);
+ list_add_tail(&entry->obj_list, &uobj->comp_list);
spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
wake_up_interruptible(&file->comp_file[0].poll_wait);
@@ -323,20 +327,25 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
}
static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
- __u64 element, __u64 event)
+ __u64 element, __u64 event,
+ struct list_head *obj_list,
+ u32 *counter)
{
- struct ib_uverbs_async_event *entry;
+ struct ib_uverbs_event *entry;
unsigned long flags;
entry = kmalloc(sizeof *entry, GFP_ATOMIC);
if (!entry)
return;
- entry->desc.element = element;
- entry->desc.event_type = event;
+ entry->desc.async.element = element;
+ entry->desc.async.event_type = event;
+ entry->counter = counter;
spin_lock_irqsave(&file->async_file.lock, flags);
list_add_tail(&entry->list, &file->async_file.event_list);
+ if (obj_list)
+ list_add_tail(&entry->obj_list, obj_list);
spin_unlock_irqrestore(&file->async_file.lock, flags);
wake_up_interruptible(&file->async_file.poll_wait);
@@ -345,23 +354,39 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
{
- ib_uverbs_async_handler(context_ptr,
- event->element.cq->uobject->user_handle,
- event->event);
+ struct ib_ucq_object *uobj;
+
+ uobj = container_of(event->element.cq->uobject,
+ struct ib_ucq_object, uobject);
+
+ ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
+ event->event, &uobj->async_list,
+ &uobj->async_events_reported);
+
}
void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
{
- ib_uverbs_async_handler(context_ptr,
- event->element.qp->uobject->user_handle,
- event->event);
+ struct ib_uevent_object *uobj;
+
+ uobj = container_of(event->element.qp->uobject,
+ struct ib_uevent_object, uobject);
+
+ ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
+ event->event, &uobj->event_list,
+ &uobj->events_reported);
}
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
{
- ib_uverbs_async_handler(context_ptr,
- event->element.srq->uobject->user_handle,
- event->event);
+ struct ib_uevent_object *uobj;
+
+ uobj = container_of(event->element.srq->uobject,
+ struct ib_uevent_object, uobject);
+
+ ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
+ event->event, &uobj->event_list,
+ &uobj->events_reported);
}
static void ib_uverbs_event_handler(struct ib_event_handler *handler,
@@ -370,7 +395,8 @@ static void ib_uverbs_event_handler(struct ib_event_handler *handler,
struct ib_uverbs_file *file =
container_of(handler, struct ib_uverbs_file, event_handler);
- ib_uverbs_async_handler(file, event->element.port_num, event->event);
+ ib_uverbs_async_handler(file, event->element.port_num, event->event,
+ NULL, NULL);
}
static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
@@ -422,7 +448,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
if (hdr.in_words * 4 != count)
return -EINVAL;
- if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table))
+ if (hdr.command < 0 ||
+ hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||
+ !uverbs_cmd_table[hdr.command])
return -EINVAL;
if (!file->ucontext &&
@@ -458,27 +486,29 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
file = kmalloc(sizeof *file +
(dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
GFP_KERNEL);
- if (!file)
- return -ENOMEM;
+ if (!file) {
+ ret = -ENOMEM;
+ goto err;
+ }
file->device = dev;
kref_init(&file->ref);
+ init_MUTEX(&file->mutex);
file->ucontext = NULL;
+ kref_get(&file->ref);
ret = ib_uverbs_event_init(&file->async_file, file);
if (ret)
- goto err;
+ goto err_kref;
file->async_file.is_async = 1;
- kref_get(&file->ref);
-
for (i = 0; i < dev->num_comp; ++i) {
+ kref_get(&file->ref);
ret = ib_uverbs_event_init(&file->comp_file[i], file);
if (ret)
goto err_async;
- kref_get(&file->ref);
file->comp_file[i].is_async = 0;
}
@@ -498,9 +528,16 @@ err_async:
ib_uverbs_event_release(&file->async_file);
-err:
+err_kref:
+ /*
+ * One extra kref_put() because we took a reference before the
+ * event file creation that failed and got us here.
+ */
+ kref_put(&file->ref, ib_uverbs_release_file);
kref_put(&file->ref, ib_uverbs_release_file);
+err:
+ module_put(dev->ib_dev->owner);
return ret;
}
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index cc758a2d2bc6..378646b5a1b8 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -524,7 +524,7 @@ void mthca_cmd_use_polling(struct mthca_dev *dev)
}
struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
struct mthca_mailbox *mailbox;
@@ -605,7 +605,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
err = -EINVAL;
goto out;
}
- for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) {
+ for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) {
if (virt != -1) {
pages[nent * 2] = cpu_to_be64(virt);
virt += 1 << lg;
@@ -616,7 +616,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
ts += 1 << (lg - 10);
++tc;
- if (nent == MTHCA_MAILBOX_SIZE / 16) {
+ if (++nent == MTHCA_MAILBOX_SIZE / 16) {
err = mthca_cmd(dev, mailbox->dma, nent, 0, op,
CMD_TIME_CLASS_B, status);
if (err || *status)
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
index 65f976a13e02..18175bec84c2 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -248,7 +248,7 @@ void mthca_cmd_event(struct mthca_dev *dev, u16 token,
u8 status, u64 out_param);
struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
- unsigned int gfp_mask);
+ gfp_t gfp_mask);
void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox);
int mthca_SYS_EN(struct mthca_dev *dev, u8 *status);
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 18f0981eb0c1..8dfafda5ed24 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -396,20 +396,21 @@ static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr, struct pt_regs
writel(dev->eq_table.clr_mask, dev->eq_table.clr_int);
ecr = readl(dev->eq_regs.tavor.ecr_base + 4);
- if (ecr) {
- writel(ecr, dev->eq_regs.tavor.ecr_base +
- MTHCA_ECR_CLR_BASE - MTHCA_ECR_BASE + 4);
+ if (!ecr)
+ return IRQ_NONE;
- for (i = 0; i < MTHCA_NUM_EQ; ++i)
- if (ecr & dev->eq_table.eq[i].eqn_mask &&
- mthca_eq_int(dev, &dev->eq_table.eq[i])) {
+ writel(ecr, dev->eq_regs.tavor.ecr_base +
+ MTHCA_ECR_CLR_BASE - MTHCA_ECR_BASE + 4);
+
+ for (i = 0; i < MTHCA_NUM_EQ; ++i)
+ if (ecr & dev->eq_table.eq[i].eqn_mask) {
+ if (mthca_eq_int(dev, &dev->eq_table.eq[i]))
tavor_set_eq_ci(dev, &dev->eq_table.eq[i],
dev->eq_table.eq[i].cons_index);
- tavor_eq_req_not(dev, dev->eq_table.eq[i].eqn);
- }
- }
+ tavor_eq_req_not(dev, dev->eq_table.eq[i].eqn);
+ }
- return IRQ_RETVAL(ecr);
+ return IRQ_HANDLED;
}
static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr,
@@ -476,12 +477,8 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
int i;
u8 status;
- /* Make sure EQ size is aligned to a power of 2 size. */
- for (i = 1; i < nent; i <<= 1)
- ; /* nothing */
- nent = i;
-
- eq->dev = dev;
+ eq->dev = dev;
+ eq->nent = roundup_pow_of_two(max(nent, 2));
eq->page_list = kmalloc(npages * sizeof *eq->page_list,
GFP_KERNEL);
@@ -512,7 +509,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
memset(eq->page_list[i].buf, 0, PAGE_SIZE);
}
- for (i = 0; i < nent; ++i)
+ for (i = 0; i < eq->nent; ++i)
set_eqe_hw(get_eqe(eq, i));
eq->eqn = mthca_alloc(&dev->eq_table.alloc);
@@ -528,8 +525,6 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
if (err)
goto err_out_free_eq;
- eq->nent = nent;
-
memset(eq_context, 0, sizeof *eq_context);
eq_context->flags = cpu_to_be32(MTHCA_EQ_STATUS_OK |
MTHCA_EQ_OWNER_HW |
@@ -538,7 +533,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
if (mthca_is_memfree(dev))
eq_context->flags |= cpu_to_be32(MTHCA_EQ_STATE_ARBEL);
- eq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
+ eq_context->logsize_usrpage = cpu_to_be32((ffs(eq->nent) - 1) << 24);
if (mthca_is_memfree(dev)) {
eq_context->arbel_pd = cpu_to_be32(dev->driver_pd.pd_num);
} else {
@@ -569,7 +564,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
dev->eq_table.arm_mask |= eq->eqn_mask;
mthca_dbg(dev, "Allocated EQ %d with %d entries\n",
- eq->eqn, nent);
+ eq->eqn, eq->nent);
return err;
@@ -842,7 +837,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev)
dev->eq_table.clr_mask =
swab32(1 << (dev->eq_table.inta_pin & 31));
dev->eq_table.clr_int = dev->clr_base +
- (dev->eq_table.inta_pin < 31 ? 4 : 0);
+ (dev->eq_table.inta_pin < 32 ? 4 : 0);
}
dev->eq_table.arm_mask = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 3241d6c9dc11..23a3f56c7899 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -503,6 +503,25 @@ err_free_aux:
return err;
}
+static void mthca_free_icms(struct mthca_dev *mdev)
+{
+ u8 status;
+
+ mthca_free_icm_table(mdev, mdev->mcg_table.table);
+ if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
+ mthca_free_icm_table(mdev, mdev->srq_table.table);
+ mthca_free_icm_table(mdev, mdev->cq_table.table);
+ mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
+ mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
+ mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
+ mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
+ mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
+ mthca_unmap_eq_icm(mdev);
+
+ mthca_UNMAP_ICM_AUX(mdev, &status);
+ mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
+}
+
static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
{
struct mthca_dev_lim dev_lim;
@@ -580,18 +599,7 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
return 0;
err_free_icm:
- if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
- mthca_free_icm_table(mdev, mdev->srq_table.table);
- mthca_free_icm_table(mdev, mdev->cq_table.table);
- mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
- mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
- mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
- mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
- mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
- mthca_unmap_eq_icm(mdev);
-
- mthca_UNMAP_ICM_AUX(mdev, &status);
- mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
+ mthca_free_icms(mdev);
err_stop_fw:
mthca_UNMAP_FA(mdev, &status);
@@ -611,18 +619,7 @@ static void mthca_close_hca(struct mthca_dev *mdev)
mthca_CLOSE_HCA(mdev, 0, &status);
if (mthca_is_memfree(mdev)) {
- if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
- mthca_free_icm_table(mdev, mdev->srq_table.table);
- mthca_free_icm_table(mdev, mdev->cq_table.table);
- mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
- mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
- mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
- mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
- mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
- mthca_unmap_eq_icm(mdev);
-
- mthca_UNMAP_ICM_AUX(mdev, &status);
- mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
+ mthca_free_icms(mdev);
mthca_UNMAP_FA(mdev, &status);
mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
@@ -937,12 +934,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_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 1827400f189b..9ad8b3b6cfef 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -82,7 +82,7 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
}
struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
struct mthca_icm *icm;
struct mthca_icm_chunk *chunk = NULL;
@@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
int i;
u8 status;
- num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE;
+ num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE;
table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
if (!table)
@@ -529,12 +529,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
goto found;
}
+ for (i = start; i != end; i += dir)
+ if (!dev->db_tab->page[i].db_rec) {
+ page = dev->db_tab->page + i;
+ goto alloc;
+ }
+
if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) {
ret = -ENOMEM;
goto out;
}
+ if (group == 0)
+ ++dev->db_tab->max_group1;
+ else
+ --dev->db_tab->min_group2;
+
page = dev->db_tab->page + end;
+
+alloc:
page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096,
&page->mapping, GFP_KERNEL);
if (!page->db_rec) {
@@ -554,10 +567,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
}
bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE);
- if (group == 0)
- ++dev->db_tab->max_group1;
- else
- --dev->db_tab->min_group2;
found:
j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE);
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index bafa51544aa3..29433f295253 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -77,7 +77,7 @@ struct mthca_icm_iter {
struct mthca_dev;
struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
- unsigned int gfp_mask);
+ gfp_t gfp_mask);
void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm);
struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 1c1c2e230871..3f5319a46577 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -84,7 +84,7 @@ static int mthca_query_device(struct ib_device *ibdev,
props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
0xffffff;
props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30));
- props->hw_ver = be16_to_cpup((__be16 *) (out_mad->data + 32));
+ props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32));
memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
memcpy(&props->node_guid, out_mad->data + 12, 8);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 0164b84d4ec6..5fa00669f9b8 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -220,6 +220,15 @@ static void *get_send_wqe(struct mthca_qp *qp, int n)
(PAGE_SIZE - 1));
}
+static void mthca_wq_init(struct mthca_wq *wq)
+{
+ spin_lock_init(&wq->lock);
+ wq->next_ind = 0;
+ wq->last_comp = wq->max - 1;
+ wq->head = 0;
+ wq->tail = 0;
+}
+
void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
enum ib_event_type event_type)
{
@@ -677,7 +686,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
}
if (attr_mask & IB_QP_TIMEOUT) {
- qp_context->pri_path.ackto = attr->timeout;
+ qp_context->pri_path.ackto = attr->timeout << 3;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);
}
@@ -833,8 +842,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
store_attrs(to_msqp(qp), attr, attr_mask);
/*
- * If we are moving QP0 to RTR, bring the IB link up; if we
- * are moving QP0 to RESET or ERROR, bring the link back down.
+ * If we moved QP0 to RTR, bring the IB link up; if we moved
+ * QP0 to RESET or ERROR, bring the link back down.
*/
if (is_qp0(dev, qp)) {
if (cur_state != IB_QPS_RTR &&
@@ -848,6 +857,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
}
+ /*
+ * If we moved a kernel QP to RESET, clean up all old CQ
+ * entries and reinitialize the QP.
+ */
+ if (!err && new_state == IB_QPS_RESET && !qp->ibqp.uobject) {
+ mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn,
+ qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
+ if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
+ mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn,
+ qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
+
+ mthca_wq_init(&qp->sq);
+ mthca_wq_init(&qp->rq);
+
+ if (mthca_is_memfree(dev)) {
+ *qp->sq.db = 0;
+ *qp->rq.db = 0;
+ }
+ }
+
return err;
}
@@ -1003,16 +1032,6 @@ static void mthca_free_memfree(struct mthca_dev *dev,
}
}
-static void mthca_wq_init(struct mthca_wq* wq)
-{
- spin_lock_init(&wq->lock);
- wq->next_ind = 0;
- wq->last_comp = wq->max - 1;
- wq->head = 0;
- wq->tail = 0;
- wq->last = NULL;
-}
-
static int mthca_alloc_qp_common(struct mthca_dev *dev,
struct mthca_pd *pd,
struct mthca_cq *send_cq,
@@ -1024,6 +1043,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
int i;
atomic_set(&qp->refcount, 1);
+ init_waitqueue_head(&qp->wait);
qp->state = IB_QPS_RESET;
qp->atomic_rd_en = 0;
qp->resp_depth = 0;
@@ -1082,6 +1102,9 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
}
}
+ qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
+ qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1);
+
return 0;
}
@@ -1562,15 +1585,13 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
goto out;
}
- if (prev_wqe) {
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32(((ind << qp->sq.wqe_shift) +
- qp->send_wqe_offset) |
- mthca_opcode[wr->opcode]);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
- }
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32(((ind << qp->sq.wqe_shift) +
+ qp->send_wqe_offset) |
+ mthca_opcode[wr->opcode]);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
if (!size0) {
size0 = size;
@@ -1667,13 +1688,11 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
qp->wrid[ind] = wr->wr_id;
- if (likely(prev_wqe)) {
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32((ind << qp->rq.wqe_shift) | 1);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32(MTHCA_NEXT_DBD | size);
- }
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32((ind << qp->rq.wqe_shift) | 1);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32(MTHCA_NEXT_DBD | size);
if (!size0)
size0 = size;
@@ -1884,15 +1903,13 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
goto out;
}
- if (likely(prev_wqe)) {
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32(((ind << qp->sq.wqe_shift) +
- qp->send_wqe_offset) |
- mthca_opcode[wr->opcode]);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32(MTHCA_NEXT_DBD | size);
- }
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32(((ind << qp->sq.wqe_shift) +
+ qp->send_wqe_offset) |
+ mthca_opcode[wr->opcode]);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32(MTHCA_NEXT_DBD | size);
if (!size0) {
size0 = size;
@@ -2106,5 +2123,6 @@ void __devexit mthca_cleanup_qp_table(struct mthca_dev *dev)
for (i = 0; i < 2; ++i)
mthca_CONF_SPECIAL_QP(dev, i, 0, &status);
+ mthca_array_cleanup(&dev->qp_table.qp, dev->limits.num_qps);
mthca_alloc_cleanup(&dev->qp_table.alloc);
}
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 8ea801271a41..4f995391dd1d 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -71,8 +71,8 @@ int mthca_reset(struct mthca_dev *mdev)
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/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 75cd2d84ef12..18998d48c53e 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -172,6 +172,8 @@ static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd,
scatter->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
}
+ srq->last = get_wqe(srq, srq->max - 1);
+
return 0;
}
@@ -189,7 +191,6 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
srq->max = attr->max_wr;
srq->max_gs = attr->max_sge;
- srq->last = NULL;
srq->counter = 0;
if (mthca_is_memfree(dev))
@@ -409,7 +410,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
mthca_err(dev, "SRQ %06x full\n", srq->srqn);
err = -ENOMEM;
*bad_wr = wr;
- return nreq;
+ break;
}
wqe = get_wqe(srq, ind);
@@ -427,7 +428,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
err = -EINVAL;
*bad_wr = wr;
srq->last = prev_wqe;
- return nreq;
+ break;
}
for (i = 0; i < wr->num_sge; ++i) {
@@ -446,20 +447,16 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
((struct mthca_data_seg *) wqe)->addr = 0;
}
- if (likely(prev_wqe)) {
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32((ind << srq->wqe_shift) | 1);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32(MTHCA_NEXT_DBD);
- }
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32((ind << srq->wqe_shift) | 1);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32(MTHCA_NEXT_DBD);
srq->wrid[ind] = wr->wr_id;
srq->first_free = next_ind;
}
- return nreq;
-
if (likely(nreq)) {
__be32 doorbell[2];
@@ -503,7 +500,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
mthca_err(dev, "SRQ %06x full\n", srq->srqn);
err = -ENOMEM;
*bad_wr = wr;
- return nreq;
+ break;
}
wqe = get_wqe(srq, ind);
@@ -519,7 +516,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
if (unlikely(wr->num_sge > srq->max_gs)) {
err = -EINVAL;
*bad_wr = wr;
- return nreq;
+ break;
}
for (i = 0; i < wr->num_sge; ++i) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index bea960b8191f..4ea1c1ca85bc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -257,7 +257,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
void ipoib_mcast_restart_task(void *dev_ptr);
int ipoib_mcast_start_thread(struct net_device *dev);
-int ipoib_mcast_stop_thread(struct net_device *dev);
+int ipoib_mcast_stop_thread(struct net_device *dev, int flush);
void ipoib_mcast_dev_down(struct net_device *dev);
void ipoib_mcast_dev_flush(struct net_device *dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index ef0e3894863c..f7440096b5ed 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -432,7 +432,7 @@ int ipoib_ib_dev_down(struct net_device *dev)
flush_workqueue(ipoib_workqueue);
}
- ipoib_mcast_stop_thread(dev);
+ ipoib_mcast_stop_thread(dev, 1);
/*
* Flush the multicast groups first so we stop any multicast joins. The
@@ -599,7 +599,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
ipoib_dbg(priv, "cleaning up ib_dev\n");
- ipoib_mcast_stop_thread(dev);
+ ipoib_mcast_stop_thread(dev, 1);
/* Delete the broadcast address and the local address */
ipoib_mcast_dev_down(dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 0e8ac138e355..6c5bf07489f4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -474,7 +474,7 @@ err:
spin_unlock(&priv->lock);
}
-static void path_lookup(struct sk_buff *skb, struct net_device *dev)
+static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
@@ -569,7 +569,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->dst && skb->dst->neighbour) {
if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
- path_lookup(skb, dev);
+ ipoib_path_lookup(skb, dev);
goto out;
}
@@ -1005,6 +1005,7 @@ debug_failed:
register_failed:
ib_unregister_event_handler(&priv->event_handler);
+ flush_scheduled_work();
event_failed:
ipoib_dev_cleanup(priv->dev);
@@ -1057,11 +1058,14 @@ static void ipoib_remove_one(struct ib_device *device)
list_for_each_entry_safe(priv, tmp, dev_list, list) {
ib_unregister_event_handler(&priv->event_handler);
+ flush_scheduled_work();
unregister_netdev(priv->dev);
ipoib_dev_cleanup(priv->dev);
free_netdev(priv->dev);
}
+
+ kfree(dev_list);
}
static int __init ipoib_init_module(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index aca7aea18a69..36ce29836bf2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -145,7 +145,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev,
mcast->dev = dev;
mcast->created = jiffies;
- mcast->backoff = HZ;
+ mcast->backoff = 1;
mcast->logcount = 0;
INIT_LIST_HEAD(&mcast->list);
@@ -396,7 +396,7 @@ static void ipoib_mcast_join_complete(int status,
IPOIB_GID_ARG(mcast->mcmember.mgid), status);
if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) {
- mcast->backoff = HZ;
+ mcast->backoff = 1;
down(&mcast_mutex);
if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
queue_work(ipoib_workqueue, &priv->mcast_task);
@@ -496,7 +496,7 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
queue_delayed_work(ipoib_workqueue,
&priv->mcast_task,
- mcast->backoff);
+ mcast->backoff * HZ);
up(&mcast_mutex);
} else
mcast->query_id = ret;
@@ -598,7 +598,7 @@ int ipoib_mcast_start_thread(struct net_device *dev)
return 0;
}
-int ipoib_mcast_stop_thread(struct net_device *dev)
+int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_mcast *mcast;
@@ -610,7 +610,8 @@ int ipoib_mcast_stop_thread(struct net_device *dev)
cancel_delayed_work(&priv->mcast_task);
up(&mcast_mutex);
- flush_workqueue(ipoib_workqueue);
+ if (flush)
+ flush_workqueue(ipoib_workqueue);
if (priv->broadcast && priv->broadcast->query) {
ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
@@ -832,7 +833,7 @@ void ipoib_mcast_restart_task(void *dev_ptr)
ipoib_dbg_mcast(priv, "restarting multicast task\n");
- ipoib_mcast_stop_thread(dev);
+ ipoib_mcast_stop_thread(dev, 0);
spin_lock_irqsave(&priv->lock, flags);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 19c14c4beb44..3738d173f9a6 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -322,7 +322,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
if (get_user(v, ip + 1)) return -EFAULT;
if (v < 0 || v > KEY_MAX) return -EINVAL;
- if (v >> (dev->keycodesize * 8)) return -EINVAL;
+ if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) return -EINVAL;
u = SET_INPUT_KEYCODE(dev, t, v);
clear_bit(u, dev->keybit);
set_bit(v, dev->keybit);
@@ -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/input/input.c b/drivers/input/input.c
index 88636a204525..14ae5583e198 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -308,6 +308,7 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
MATCH_BIT(ledbit, LED_MAX);
MATCH_BIT(sndbit, SND_MAX);
MATCH_BIT(ffbit, FF_MAX);
+ MATCH_BIT(swbit, SW_MAX);
return id;
}
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 58728ebaaf80..e5a31e55d3e2 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -249,9 +249,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
int iforce_get_id_packet(struct iforce *iforce, char *packet)
{
- DECLARE_WAITQUEUE(wait, current);
- int timeout = HZ; /* 1 second */
-
switch (iforce->bus) {
case IFORCE_USB:
@@ -260,22 +257,13 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
iforce->cr.bRequest = packet[0];
iforce->ctrl->dev = iforce->usbdev;
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&iforce->wait, &wait);
-
- if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&iforce->wait, &wait);
+ if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC))
return -1;
- }
- while (timeout && iforce->ctrl->status == -EINPROGRESS)
- timeout = schedule_timeout(timeout);
+ wait_event_interruptible_timeout(iforce->wait,
+ iforce->ctrl->status != -EINPROGRESS, HZ);
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&iforce->wait, &wait);
-
- if (!timeout) {
+ if (iforce->ctrl->status != -EINPROGRESS) {
usb_unlink_urb(iforce->ctrl);
return -1;
}
@@ -290,16 +278,10 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
iforce->expect_packet = FF_CMD_QUERY;
iforce_send_packet(iforce, FF_CMD_QUERY, packet);
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&iforce->wait, &wait);
-
- while (timeout && iforce->expect_packet)
- timeout = schedule_timeout(timeout);
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&iforce->wait, &wait);
+ wait_event_interruptible_timeout(iforce->wait,
+ !iforce->expect_packet, HZ);
- if (!timeout) {
+ if (iforce->expect_packet) {
iforce->expect_packet = 0;
return -1;
}
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 6369a24684fe..58600f91eff5 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -95,6 +95,7 @@ static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs)
goto exit;
}
+ wake_up(&iforce->wait);
iforce_process_packet(iforce,
(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index e55dee390775..571a68691a4a 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -93,7 +93,7 @@ config KEYBOARD_LKKBD
config KEYBOARD_LOCOMO
tristate "LoCoMo Keyboard Support"
- depends on SHARP_LOCOMO
+ depends on SHARP_LOCOMO && INPUT_KEYBOARD
help
Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
@@ -132,6 +132,17 @@ config KEYBOARD_CORGI
To compile this driver as a module, choose M here: the
module will be called corgikbd.
+config KEYBOARD_SPITZ
+ tristate "Spitz keyboard"
+ depends on PXA_SHARPSL
+ default y
+ help
+ Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
+ SL-C3000 and Sl-C3100 series of PDAs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called spitzkbd.
+
config KEYBOARD_MAPLE
tristate "Maple bus keyboard"
depends on SH_DREAMCAST && MAPLE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b02eeceea3c3..9ce0b87f2fac 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
obj-$(CONFIG_KEYBOARD_98KBD) += 98kbd.o
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
+obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 4d4985b59abf..1ad8c2ee7dbf 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -208,6 +208,7 @@ struct atkbd {
unsigned char resend;
unsigned char release;
unsigned char bat_xl;
+ unsigned char err_xl;
unsigned int last;
unsigned long time;
};
@@ -296,15 +297,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (atkbd->emul ||
!(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA ||
- code == ATKBD_RET_ERR ||
+ (code == ATKBD_RET_ERR && !atkbd->err_xl) ||
(code == ATKBD_RET_BAT && !atkbd->bat_xl))) {
atkbd->release = code >> 7;
code &= 0x7f;
}
- if (!atkbd->emul &&
- (code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
+ if (!atkbd->emul) {
+ if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
atkbd->bat_xl = !atkbd->release;
+ if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f))
+ atkbd->err_xl = !atkbd->release;
+ }
}
switch (code) {
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
new file mode 100644
index 000000000000..344f46005401
--- /dev/null
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -0,0 +1,478 @@
+/*
+ * Keyboard driver for Sharp Spitz, Borzoi and Akita (SL-Cxx00 series)
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on corgikbd.c
+ *
+ * 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.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+
+#include <asm/arch/spitz.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#define KB_ROWS 7
+#define KB_COLS 11
+#define KB_ROWMASK(r) (1 << (r))
+#define SCANCODE(r,c) (((r)<<4) + (c) + 1)
+#define NR_SCANCODES ((KB_ROWS<<4) + 1)
+
+#define HINGE_SCAN_INTERVAL (150) /* ms */
+
+#define SPITZ_KEY_CALENDER KEY_F1
+#define SPITZ_KEY_ADDRESS KEY_F2
+#define SPITZ_KEY_FN KEY_F3
+#define SPITZ_KEY_CANCEL KEY_F4
+#define SPITZ_KEY_EXOK KEY_F5
+#define SPITZ_KEY_EXCANCEL KEY_F6
+#define SPITZ_KEY_EXJOGDOWN KEY_F7
+#define SPITZ_KEY_EXJOGUP KEY_F8
+#define SPITZ_KEY_JAP1 KEY_LEFTALT
+#define SPITZ_KEY_JAP2 KEY_RIGHTCTRL
+#define SPITZ_KEY_SYNC KEY_F9
+#define SPITZ_KEY_MAIL KEY_F10
+#define SPITZ_KEY_OK KEY_F11
+#define SPITZ_KEY_MENU KEY_F12
+
+static unsigned char spitzkbd_keycode[NR_SCANCODES] = {
+ 0, /* 0 */
+ KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */
+ 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */
+ KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */
+ SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */
+ SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */
+ SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */
+ KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */
+};
+
+static int spitz_strobes[] = {
+ SPITZ_GPIO_KEY_STROBE0,
+ SPITZ_GPIO_KEY_STROBE1,
+ SPITZ_GPIO_KEY_STROBE2,
+ SPITZ_GPIO_KEY_STROBE3,
+ SPITZ_GPIO_KEY_STROBE4,
+ SPITZ_GPIO_KEY_STROBE5,
+ SPITZ_GPIO_KEY_STROBE6,
+ SPITZ_GPIO_KEY_STROBE7,
+ SPITZ_GPIO_KEY_STROBE8,
+ SPITZ_GPIO_KEY_STROBE9,
+ SPITZ_GPIO_KEY_STROBE10,
+};
+
+static int spitz_senses[] = {
+ SPITZ_GPIO_KEY_SENSE0,
+ SPITZ_GPIO_KEY_SENSE1,
+ SPITZ_GPIO_KEY_SENSE2,
+ SPITZ_GPIO_KEY_SENSE3,
+ SPITZ_GPIO_KEY_SENSE4,
+ SPITZ_GPIO_KEY_SENSE5,
+ SPITZ_GPIO_KEY_SENSE6,
+};
+
+struct spitzkbd {
+ unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
+ struct input_dev input;
+ char phys[32];
+
+ spinlock_t lock;
+ struct timer_list timer;
+ struct timer_list htimer;
+
+ unsigned int suspended;
+ unsigned long suspend_jiffies;
+};
+
+#define KB_DISCHARGE_DELAY 10
+#define KB_ACTIVATE_DELAY 10
+
+/* Helper functions for reading the keyboard matrix
+ * Note: We should really be using pxa_gpio_mode to alter GPDR but it
+ * requires a function call per GPIO bit which is excessive
+ * when we need to access 11 bits at once, multiple times.
+ * These functions must be called within local_irq_save()/local_irq_restore()
+ * or similar.
+ */
+static inline void spitzkbd_discharge_all(void)
+{
+ /* STROBE All HiZ */
+ GPCR0 = SPITZ_GPIO_G0_STROBE_BIT;
+ GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+ GPCR1 = SPITZ_GPIO_G1_STROBE_BIT;
+ GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+ GPCR2 = SPITZ_GPIO_G2_STROBE_BIT;
+ GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+ GPCR3 = SPITZ_GPIO_G3_STROBE_BIT;
+ GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+}
+
+static inline void spitzkbd_activate_all(void)
+{
+ /* STROBE ALL -> High */
+ GPSR0 = SPITZ_GPIO_G0_STROBE_BIT;
+ GPDR0 |= SPITZ_GPIO_G0_STROBE_BIT;
+ GPSR1 = SPITZ_GPIO_G1_STROBE_BIT;
+ GPDR1 |= SPITZ_GPIO_G1_STROBE_BIT;
+ GPSR2 = SPITZ_GPIO_G2_STROBE_BIT;
+ GPDR2 |= SPITZ_GPIO_G2_STROBE_BIT;
+ GPSR3 = SPITZ_GPIO_G3_STROBE_BIT;
+ GPDR3 |= SPITZ_GPIO_G3_STROBE_BIT;
+
+ udelay(KB_DISCHARGE_DELAY);
+
+ /* Clear any interrupts we may have triggered when altering the GPIO lines */
+ GEDR0 = SPITZ_GPIO_G0_SENSE_BIT;
+ GEDR1 = SPITZ_GPIO_G1_SENSE_BIT;
+ GEDR2 = SPITZ_GPIO_G2_SENSE_BIT;
+ GEDR3 = SPITZ_GPIO_G3_SENSE_BIT;
+}
+
+static inline void spitzkbd_activate_col(int col)
+{
+ int gpio = spitz_strobes[col];
+ GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+ GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+ GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+ GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+ GPSR(gpio) = GPIO_bit(gpio);
+ GPDR(gpio) |= GPIO_bit(gpio);
+}
+
+static inline void spitzkbd_reset_col(int col)
+{
+ int gpio = spitz_strobes[col];
+ GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+ GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+ GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+ GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+ GPCR(gpio) = GPIO_bit(gpio);
+ GPDR(gpio) |= GPIO_bit(gpio);
+}
+
+static inline int spitzkbd_get_row_status(int col)
+{
+ return ((GPLR0 >> 12) & 0x01) | ((GPLR0 >> 16) & 0x02)
+ | ((GPLR2 >> 25) & 0x04) | ((GPLR1 << 1) & 0x08)
+ | ((GPLR1 >> 0) & 0x10) | ((GPLR1 >> 1) & 0x60);
+}
+
+/*
+ * The spitz keyboard only generates interrupts when a key is pressed.
+ * When a key is pressed, we enable a timer which then scans the
+ * keyboard to detect when the key is released.
+ */
+
+/* Scan the hardware keyboard and push any changes up through the input layer */
+static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs *regs)
+{
+ unsigned int row, col, rowd;
+ unsigned long flags;
+ unsigned int num_pressed, pwrkey = ((GPLR(SPITZ_GPIO_ON_KEY) & GPIO_bit(SPITZ_GPIO_ON_KEY)) != 0);
+
+ if (spitzkbd_data->suspended)
+ return;
+
+ spin_lock_irqsave(&spitzkbd_data->lock, flags);
+
+ if (regs)
+ input_regs(&spitzkbd_data->input, regs);
+
+ num_pressed = 0;
+ for (col = 0; col < KB_COLS; col++) {
+ /*
+ * Discharge the output driver capacitatance
+ * in the keyboard matrix. (Yes it is significant..)
+ */
+
+ spitzkbd_discharge_all();
+ udelay(KB_DISCHARGE_DELAY);
+
+ spitzkbd_activate_col(col);
+ udelay(KB_ACTIVATE_DELAY);
+
+ rowd = spitzkbd_get_row_status(col);
+ for (row = 0; row < KB_ROWS; row++) {
+ unsigned int scancode, pressed;
+
+ scancode = SCANCODE(row, col);
+ pressed = rowd & KB_ROWMASK(row);
+
+ input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
+
+ if (pressed)
+ num_pressed++;
+ }
+ spitzkbd_reset_col(col);
+ }
+
+ spitzkbd_activate_all();
+
+ input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
+ input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey);
+
+ if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
+ input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
+ spitzkbd_data->suspend_jiffies = jiffies;
+ }
+
+ input_sync(&spitzkbd_data->input);
+
+ /* if any keys are pressed, enable the timer */
+ if (num_pressed)
+ mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(100));
+
+ spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
+}
+
+/*
+ * spitz keyboard interrupt handler.
+ */
+static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct spitzkbd *spitzkbd_data = dev_id;
+
+ if (!timer_pending(&spitzkbd_data->timer)) {
+ /** wait chattering delay **/
+ udelay(20);
+ spitzkbd_scankeyboard(spitzkbd_data, regs);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * spitz timer checking for released keys
+ */
+static void spitzkbd_timer_callback(unsigned long data)
+{
+ struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+ spitzkbd_scankeyboard(spitzkbd_data, NULL);
+}
+
+/*
+ * The hinge switches generate an interrupt.
+ * We debounce the switches and pass them to the input system.
+ */
+
+static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct spitzkbd *spitzkbd_data = dev_id;
+
+ if (!timer_pending(&spitzkbd_data->htimer))
+ mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+
+ return IRQ_HANDLED;
+}
+
+#define HINGE_STABLE_COUNT 2
+static int sharpsl_hinge_state;
+static int hinge_count;
+
+static void spitzkbd_hinge_timer(unsigned long data)
+{
+ struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+ unsigned long state;
+ unsigned long flags;
+
+ state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB));
+ if (state != sharpsl_hinge_state) {
+ hinge_count = 0;
+ sharpsl_hinge_state = state;
+ } else if (hinge_count < HINGE_STABLE_COUNT) {
+ hinge_count++;
+ }
+
+ if (hinge_count >= HINGE_STABLE_COUNT) {
+ spin_lock_irqsave(&spitzkbd_data->lock, flags);
+
+ input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
+ input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
+ input_sync(&spitzkbd_data->input);
+
+ spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
+ } else {
+ mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+ }
+}
+
+#ifdef CONFIG_PM
+static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
+{
+ if (level == SUSPEND_POWER_DOWN) {
+ int i;
+ struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+ spitzkbd->suspended = 1;
+
+ /* Set Strobe lines as inputs - *except* strobe line 0 leave this
+ enabled so we can detect a power button press for resume */
+ for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
+ pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
+ }
+ return 0;
+}
+
+static int spitzkbd_resume(struct device *dev, uint32_t level)
+{
+ if (level == RESUME_POWER_ON) {
+ int i;
+ struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+
+ for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+ pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+
+ /* Upon resume, ignore the suspend key for a short while */
+ spitzkbd->suspend_jiffies = jiffies;
+ spitzkbd->suspended = 0;
+ }
+ return 0;
+}
+#else
+#define spitzkbd_suspend NULL
+#define spitzkbd_resume NULL
+#endif
+
+static int __init spitzkbd_probe(struct device *dev)
+{
+ int i;
+ struct spitzkbd *spitzkbd;
+
+ spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
+ if (!spitzkbd)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev,spitzkbd);
+ strcpy(spitzkbd->phys, "spitzkbd/input0");
+
+ spin_lock_init(&spitzkbd->lock);
+
+ /* Init Keyboard rescan timer */
+ init_timer(&spitzkbd->timer);
+ spitzkbd->timer.function = spitzkbd_timer_callback;
+ spitzkbd->timer.data = (unsigned long) spitzkbd;
+
+ /* Init Hinge Timer */
+ init_timer(&spitzkbd->htimer);
+ spitzkbd->htimer.function = spitzkbd_hinge_timer;
+ spitzkbd->htimer.data = (unsigned long) spitzkbd;
+
+ spitzkbd->suspend_jiffies=jiffies;
+
+ init_input_dev(&spitzkbd->input);
+ spitzkbd->input.private = spitzkbd;
+ spitzkbd->input.name = "Spitz Keyboard";
+ spitzkbd->input.dev = dev;
+ spitzkbd->input.phys = spitzkbd->phys;
+ spitzkbd->input.id.bustype = BUS_HOST;
+ spitzkbd->input.id.vendor = 0x0001;
+ spitzkbd->input.id.product = 0x0001;
+ spitzkbd->input.id.version = 0x0100;
+ spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+ spitzkbd->input.keycode = spitzkbd->keycode;
+ spitzkbd->input.keycodesize = sizeof(unsigned char);
+ spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode);
+
+ memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
+ for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
+ set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit);
+ clear_bit(0, spitzkbd->input.keybit);
+ set_bit(SW_0, spitzkbd->input.swbit);
+ set_bit(SW_1, spitzkbd->input.swbit);
+
+ input_register_device(&spitzkbd->input);
+ mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+
+ /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
+ for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) {
+ pxa_gpio_mode(spitz_senses[i] | GPIO_IN);
+ if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt,
+ SA_INTERRUPT, "Spitzkbd Sense", spitzkbd))
+ printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i);
+ else
+ set_irq_type(IRQ_GPIO(spitz_senses[i]),IRQT_RISING);
+ }
+
+ /* Set Strobe lines as outputs - set high */
+ for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+ pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+
+ pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
+ pxa_gpio_mode(SPITZ_GPIO_ON_KEY | GPIO_IN);
+ pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN);
+ pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN);
+
+ request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd Sync", spitzkbd);
+ request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd PwrOn", spitzkbd);
+ request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWA", spitzkbd);
+ request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWB", spitzkbd);
+
+ set_irq_type(SPITZ_IRQ_GPIO_SYNC, IRQT_BOTHEDGE);
+ set_irq_type(SPITZ_IRQ_GPIO_ON_KEY, IRQT_BOTHEDGE);
+ set_irq_type(SPITZ_IRQ_GPIO_SWA, IRQT_BOTHEDGE);
+ set_irq_type(SPITZ_IRQ_GPIO_SWB, IRQT_BOTHEDGE);
+
+ printk(KERN_INFO "input: Spitz Keyboard Registered\n");
+
+ return 0;
+}
+
+static int spitzkbd_remove(struct device *dev)
+{
+ int i;
+ struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+
+ for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++)
+ free_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd);
+
+ free_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd);
+ free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd);
+ free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd);
+ free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd);
+
+ del_timer_sync(&spitzkbd->htimer);
+ del_timer_sync(&spitzkbd->timer);
+
+ input_unregister_device(&spitzkbd->input);
+
+ kfree(spitzkbd);
+
+ return 0;
+}
+
+static struct device_driver spitzkbd_driver = {
+ .name = "spitz-keyboard",
+ .bus = &platform_bus_type,
+ .probe = spitzkbd_probe,
+ .remove = spitzkbd_remove,
+ .suspend = spitzkbd_suspend,
+ .resume = spitzkbd_resume,
+};
+
+static int __devinit spitzkbd_init(void)
+{
+ return driver_register(&spitzkbd_driver);
+}
+
+static void __exit spitzkbd_exit(void)
+{
+ driver_unregister(&spitzkbd_driver);
+}
+
+module_init(spitzkbd_init);
+module_exit(spitzkbd_exit);
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
+MODULE_DESCRIPTION("Spitz Keyboard Driver");
+MODULE_LICENSE("GPLv2");
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 596964ceb96d..4bae5d89348d 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -44,7 +44,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static unsigned char sunkbd_keycode[128] = {
- 0,128,114,129,115, 59, 60, 68, 61, 87, 62, 88, 63,100, 64, 0,
+ 0,128,114,129,115, 59, 60, 68, 61, 87, 62, 88, 63,100, 64,112,
65, 66, 67, 56,103,119, 99, 70,105,130,131,108,106, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 41, 14,110,113, 98, 55,
116,132, 83,133,102, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index d5c5b32045af..4015a91f4b6e 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -90,11 +90,11 @@ static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct
static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request)
{
- complete(&request->done);
-
/* Mark slot as available */
udev->requests[request->id] = NULL;
wake_up_interruptible(&udev->requests_waitq);
+
+ complete(&request->done);
}
static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index c4909b49337d..82b330bbf068 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -15,4 +15,4 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
-psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o
+psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o trackpoint.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 0d68e5e0182a..b20783f9748a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -170,7 +170,7 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
input_report_key(dev, BTN_TOOL_FINGER, z > 0);
if (priv->i->flags & ALPS_WHEEL)
- input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08));
+ input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
input_report_key(dev, BTN_FORWARD, forward);
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 48d2b20d2642..7df96525222e 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -150,12 +150,12 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
}
-static ssize_t psmouse_attr_show_smartscroll(struct psmouse *psmouse, char *buf)
+static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf)
{
return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0);
}
-static ssize_t psmouse_attr_set_smartscroll(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
@@ -169,7 +169,8 @@ static ssize_t psmouse_attr_set_smartscroll(struct psmouse *psmouse, const char
return count;
}
-PSMOUSE_DEFINE_ATTR(smartscroll);
+PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
+ ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
/*
* Support 800 dpi resolution _only_ if the user wants it (there are good
@@ -194,7 +195,7 @@ static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolutio
static void ps2pp_disconnect(struct psmouse *psmouse)
{
- device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll);
+ device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
}
static struct ps2pp_info *get_model_info(unsigned char model)
@@ -222,6 +223,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
{ 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
{ 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 86, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 96, 0, 0 },
{ 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL },
@@ -379,7 +381,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
psmouse->set_resolution = ps2pp_set_resolution;
psmouse->disconnect = ps2pp_disconnect;
- device_create_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll);
+ device_create_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_smartscroll.dattr);
}
}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 12bdd3eff923..af24313ff5bb 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -25,6 +25,7 @@
#include "logips2pp.h"
#include "alps.h"
#include "lifebook.h"
+#include "trackpoint.h"
#define DRIVER_DESC "PS/2 mouse driver"
@@ -57,10 +58,30 @@ static unsigned int psmouse_resetafter;
module_param_named(resetafter, psmouse_resetafter, uint, 0644);
MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
-PSMOUSE_DEFINE_ATTR(protocol);
-PSMOUSE_DEFINE_ATTR(rate);
-PSMOUSE_DEFINE_ATTR(resolution);
-PSMOUSE_DEFINE_ATTR(resetafter);
+PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
+ NULL,
+ psmouse_attr_show_protocol, psmouse_attr_set_protocol);
+PSMOUSE_DEFINE_ATTR(rate, S_IWUSR | S_IRUGO,
+ (void *) offsetof(struct psmouse, rate),
+ psmouse_show_int_attr, psmouse_attr_set_rate);
+PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
+ (void *) offsetof(struct psmouse, resolution),
+ psmouse_show_int_attr, psmouse_attr_set_resolution);
+PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
+ (void *) offsetof(struct psmouse, resetafter),
+ psmouse_show_int_attr, psmouse_set_int_attr);
+
+static struct attribute *psmouse_attributes[] = {
+ &psmouse_attr_protocol.dattr.attr,
+ &psmouse_attr_rate.dattr.attr,
+ &psmouse_attr_resolution.dattr.attr,
+ &psmouse_attr_resetafter.dattr.attr,
+ NULL
+};
+
+static struct attribute_group psmouse_attribute_group = {
+ .attrs = psmouse_attributes,
+};
__obsolete_setup("psmouse_noext");
__obsolete_setup("psmouse_resolution=");
@@ -520,6 +541,12 @@ static int psmouse_extensions(struct psmouse *psmouse,
return PSMOUSE_IMPS;
/*
+ * Try to initialize the IBM TrackPoint
+ */
+ if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0)
+ return PSMOUSE_TRACKPOINT;
+
+/*
* Okay, all failed, we have a standard mouse here. The number of the buttons
* is still a question, though. We assume 3.
*/
@@ -600,6 +627,12 @@ static struct psmouse_protocol psmouse_protocols[] = {
.init = lifebook_init,
},
{
+ .type = PSMOUSE_TRACKPOINT,
+ .name = "TPPS/2",
+ .alias = "trackpoint",
+ .detect = trackpoint_detect,
+ },
+ {
.type = PSMOUSE_AUTO,
.name = "auto",
.alias = "any",
@@ -787,10 +820,7 @@ static void psmouse_disconnect(struct serio *serio)
psmouse = serio_get_drvdata(serio);
- device_remove_file(&serio->dev, &psmouse_attr_protocol);
- device_remove_file(&serio->dev, &psmouse_attr_rate);
- device_remove_file(&serio->dev, &psmouse_attr_resolution);
- device_remove_file(&serio->dev, &psmouse_attr_resetafter);
+ sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group);
down(&psmouse_sem);
@@ -927,10 +957,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
if (parent && parent->pt_activate)
parent->pt_activate(parent);
- device_create_file(&serio->dev, &psmouse_attr_protocol);
- device_create_file(&serio->dev, &psmouse_attr_rate);
- device_create_file(&serio->dev, &psmouse_attr_resolution);
- device_create_file(&serio->dev, &psmouse_attr_resetafter);
+ sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
psmouse_activate(psmouse);
@@ -1027,10 +1054,12 @@ static struct serio_driver psmouse_drv = {
.cleanup = psmouse_cleanup,
};
-ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct psmouse *, char *))
+ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *devattr,
+ char *buf)
{
struct serio *serio = to_serio_port(dev);
+ struct psmouse_attribute *attr = to_psmouse_attr(devattr);
+ struct psmouse *psmouse;
int retval;
retval = serio_pin_driver(serio);
@@ -1042,19 +1071,21 @@ ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
goto out;
}
- retval = handler(serio_get_drvdata(serio), buf);
+ psmouse = serio_get_drvdata(serio);
+
+ retval = attr->show(psmouse, attr->data, buf);
out:
serio_unpin_driver(serio);
return retval;
}
-ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct psmouse *, const char *, size_t))
+ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
{
struct serio *serio = to_serio_port(dev);
- struct psmouse *psmouse = serio_get_drvdata(serio);
- struct psmouse *parent = NULL;
+ struct psmouse_attribute *attr = to_psmouse_attr(devattr);
+ struct psmouse *psmouse, *parent = NULL;
int retval;
retval = serio_pin_driver(serio);
@@ -1070,6 +1101,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
if (retval)
goto out_unpin;
+ psmouse = serio_get_drvdata(serio);
+
if (psmouse->state == PSMOUSE_IGNORE) {
retval = -ENODEV;
goto out_up;
@@ -1082,7 +1115,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
psmouse_deactivate(psmouse);
- retval = handler(psmouse, buf, count);
+ retval = attr->set(psmouse, attr->data, buf, count);
if (retval != -ENODEV)
psmouse_activate(psmouse);
@@ -1097,12 +1130,34 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
return retval;
}
-static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf)
+static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf)
+{
+ unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
+
+ return sprintf(buf, "%lu\n", *field);
+}
+
+static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count)
+{
+ unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
+ unsigned long value;
+ char *rest;
+
+ value = simple_strtoul(buf, &rest, 10);
+ if (*rest)
+ return -EINVAL;
+
+ *field = value;
+
+ return count;
+}
+
+static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, void *data, char *buf)
{
return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name);
}
-static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
struct serio *serio = psmouse->ps2dev.serio;
struct psmouse *parent = NULL;
@@ -1166,12 +1221,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *bu
return count;
}
-static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf)
-{
- return sprintf(buf, "%d\n", psmouse->rate);
-}
-
-static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
@@ -1184,12 +1234,7 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, s
return count;
}
-static ssize_t psmouse_attr_show_resolution(struct psmouse *psmouse, char *buf)
-{
- return sprintf(buf, "%d\n", psmouse->resolution);
-}
-
-static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
@@ -1202,23 +1247,6 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *
return count;
}
-static ssize_t psmouse_attr_show_resetafter(struct psmouse *psmouse, char *buf)
-{
- return sprintf(buf, "%d\n", psmouse->resetafter);
-}
-
-static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char *buf, size_t count)
-{
- unsigned long value;
- char *rest;
-
- value = simple_strtoul(buf, &rest, 10);
- if (*rest)
- return -EINVAL;
-
- psmouse->resetafter = value;
- return count;
-}
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
{
@@ -1234,7 +1262,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
*((unsigned int *)kp->arg) = proto->type;
- return 0; \
+ return 0;
}
static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 86691cf43433..45d2bd774f00 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -78,6 +78,7 @@ enum psmouse_type {
PSMOUSE_SYNAPTICS,
PSMOUSE_ALPS,
PSMOUSE_LIFEBOOK,
+ PSMOUSE_TRACKPOINT,
PSMOUSE_AUTO /* This one should always be last */
};
@@ -85,24 +86,37 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
int psmouse_reset(struct psmouse *psmouse);
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
-ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct psmouse *, char *));
-ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct psmouse *, const char *, size_t));
-
-#define PSMOUSE_DEFINE_ATTR(_name) \
-static ssize_t psmouse_attr_show_##_name(struct psmouse *, char *); \
-static ssize_t psmouse_attr_set_##_name(struct psmouse *, const char *, size_t);\
-static ssize_t psmouse_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \
-{ \
- return psmouse_attr_show_helper(d, b, psmouse_attr_show_##_name); \
-} \
-static ssize_t psmouse_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s)\
-{ \
- return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name); \
-} \
-static struct device_attribute psmouse_attr_##_name = \
- __ATTR(_name, S_IWUSR | S_IRUGO, \
- psmouse_do_show_##_name, psmouse_do_set_##_name);
+
+struct psmouse_attribute {
+ struct device_attribute dattr;
+ void *data;
+ ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
+ ssize_t (*set)(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count);
+};
+#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
+
+ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+
+#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
+static ssize_t _show(struct psmouse *, void *data, char *); \
+static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
+static struct psmouse_attribute psmouse_attr_##_name = { \
+ .dattr = { \
+ .attr = { \
+ .name = __stringify(_name), \
+ .mode = _mode, \
+ .owner = THIS_MODULE, \
+ }, \
+ .show = psmouse_attr_show_helper, \
+ .store = psmouse_attr_set_helper, \
+ }, \
+ .data = _data, \
+ .show = _show, \
+ .set = _set, \
+}
#endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
new file mode 100644
index 000000000000..b4898d8a68e2
--- /dev/null
+++ b/drivers/input/mouse/trackpoint.c
@@ -0,0 +1,304 @@
+/*
+ * Stephen Evanchik <evanchsa@gmail.com>
+ *
+ * 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.
+ *
+ * Trademarks are the property of their respective owners.
+ */
+
+#include <linux/delay.h>
+#include <linux/serio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/libps2.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include "psmouse.h"
+#include "trackpoint.h"
+
+/*
+ * Device IO: read, write and toggle bit
+ */
+static int trackpoint_read(struct ps2dev *ps2dev, unsigned char loc, unsigned char *results)
+{
+ if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
+ ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int trackpoint_write(struct ps2dev *ps2dev, unsigned char loc, unsigned char val)
+{
+ if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
+ ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) ||
+ ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc)) ||
+ ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, val))) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int trackpoint_toggle_bit(struct ps2dev *ps2dev, unsigned char loc, unsigned char mask)
+{
+ /* Bad things will happen if the loc param isn't in this range */
+ if (loc < 0x20 || loc >= 0x2F)
+ return -1;
+
+ if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
+ ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_TOGGLE)) ||
+ ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc)) ||
+ ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, mask))) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Trackpoint-specific attributes
+ */
+struct trackpoint_attr_data {
+ size_t field_offset;
+ unsigned char command;
+ unsigned char mask;
+};
+
+static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf)
+{
+ struct trackpoint_data *tp = psmouse->private;
+ struct trackpoint_attr_data *attr = data;
+ unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
+
+ return sprintf(buf, "%u\n", *field);
+}
+
+static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ struct trackpoint_data *tp = psmouse->private;
+ struct trackpoint_attr_data *attr = data;
+ unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
+ unsigned long value;
+ char *rest;
+
+ value = simple_strtoul(buf, &rest, 10);
+ if (*rest || value > 255)
+ return -EINVAL;
+
+ *field = value;
+ trackpoint_write(&psmouse->ps2dev, attr->command, value);
+
+ return count;
+}
+
+#define TRACKPOINT_INT_ATTR(_name, _command) \
+ static struct trackpoint_attr_data trackpoint_attr_##_name = { \
+ .field_offset = offsetof(struct trackpoint_data, _name), \
+ .command = _command, \
+ }; \
+ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \
+ &trackpoint_attr_##_name, \
+ trackpoint_show_int_attr, trackpoint_set_int_attr)
+
+static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ struct trackpoint_data *tp = psmouse->private;
+ struct trackpoint_attr_data *attr = data;
+ unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
+ unsigned long value;
+ char *rest;
+
+ value = simple_strtoul(buf, &rest, 10);
+ if (*rest || value > 1)
+ return -EINVAL;
+
+ if (*field != value) {
+ *field = value;
+ trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask);
+ }
+
+ return count;
+}
+
+
+#define TRACKPOINT_BIT_ATTR(_name, _command, _mask) \
+ static struct trackpoint_attr_data trackpoint_attr_##_name = { \
+ .field_offset = offsetof(struct trackpoint_data, _name), \
+ .command = _command, \
+ .mask = _mask, \
+ }; \
+ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \
+ &trackpoint_attr_##_name, \
+ trackpoint_show_int_attr, trackpoint_set_bit_attr)
+
+TRACKPOINT_INT_ATTR(sensitivity, TP_SENS);
+TRACKPOINT_INT_ATTR(speed, TP_SPEED);
+TRACKPOINT_INT_ATTR(inertia, TP_INERTIA);
+TRACKPOINT_INT_ATTR(reach, TP_REACH);
+TRACKPOINT_INT_ATTR(draghys, TP_DRAGHYS);
+TRACKPOINT_INT_ATTR(mindrag, TP_MINDRAG);
+TRACKPOINT_INT_ATTR(thresh, TP_THRESH);
+TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH);
+TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME);
+TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV);
+
+TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON);
+TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK);
+TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+
+static struct attribute *trackpoint_attrs[] = {
+ &psmouse_attr_sensitivity.dattr.attr,
+ &psmouse_attr_speed.dattr.attr,
+ &psmouse_attr_inertia.dattr.attr,
+ &psmouse_attr_reach.dattr.attr,
+ &psmouse_attr_draghys.dattr.attr,
+ &psmouse_attr_mindrag.dattr.attr,
+ &psmouse_attr_thresh.dattr.attr,
+ &psmouse_attr_upthresh.dattr.attr,
+ &psmouse_attr_ztime.dattr.attr,
+ &psmouse_attr_jenks.dattr.attr,
+ &psmouse_attr_press_to_select.dattr.attr,
+ &psmouse_attr_skipback.dattr.attr,
+ &psmouse_attr_ext_dev.dattr.attr,
+ NULL
+};
+
+static struct attribute_group trackpoint_attr_group = {
+ .attrs = trackpoint_attrs,
+};
+
+static void trackpoint_disconnect(struct psmouse *psmouse)
+{
+ sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
+
+ kfree(psmouse->private);
+ psmouse->private = NULL;
+}
+
+static int trackpoint_sync(struct psmouse *psmouse)
+{
+ unsigned char toggle;
+ struct trackpoint_data *tp = psmouse->private;
+
+ if (!tp)
+ return -1;
+
+ /* Disable features that may make device unusable with this driver */
+ trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle);
+ if (toggle & TP_MASK_TWOHAND)
+ trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, TP_MASK_TWOHAND);
+
+ trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_SOURCE_TAG, &toggle);
+ if (toggle & TP_MASK_SOURCE_TAG)
+ trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_SOURCE_TAG, TP_MASK_SOURCE_TAG);
+
+ trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_MB, &toggle);
+ if (toggle & TP_MASK_MB)
+ trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_MB, TP_MASK_MB);
+
+ /* Push the config to the device */
+ trackpoint_write(&psmouse->ps2dev, TP_SENS, tp->sensitivity);
+ trackpoint_write(&psmouse->ps2dev, TP_INERTIA, tp->inertia);
+ trackpoint_write(&psmouse->ps2dev, TP_SPEED, tp->speed);
+
+ trackpoint_write(&psmouse->ps2dev, TP_REACH, tp->reach);
+ trackpoint_write(&psmouse->ps2dev, TP_DRAGHYS, tp->draghys);
+ trackpoint_write(&psmouse->ps2dev, TP_MINDRAG, tp->mindrag);
+
+ trackpoint_write(&psmouse->ps2dev, TP_THRESH, tp->thresh);
+ trackpoint_write(&psmouse->ps2dev, TP_UP_THRESH, tp->upthresh);
+
+ trackpoint_write(&psmouse->ps2dev, TP_Z_TIME, tp->ztime);
+ trackpoint_write(&psmouse->ps2dev, TP_JENKS_CURV, tp->jenks);
+
+ trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_PTSON, &toggle);
+ if (((toggle & TP_MASK_PTSON) == TP_MASK_PTSON) != tp->press_to_select)
+ trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_PTSON, TP_MASK_PTSON);
+
+ trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_SKIPBACK, &toggle);
+ if (((toggle & TP_MASK_SKIPBACK) == TP_MASK_SKIPBACK) != tp->skipback)
+ trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK);
+
+ trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_EXT_DEV, &toggle);
+ if (((toggle & TP_MASK_EXT_DEV) == TP_MASK_EXT_DEV) != tp->ext_dev)
+ trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+
+ return 0;
+}
+
+static void trackpoint_defaults(struct trackpoint_data *tp)
+{
+ tp->press_to_select = TP_DEF_PTSON;
+ tp->sensitivity = TP_DEF_SENS;
+ tp->speed = TP_DEF_SPEED;
+ tp->reach = TP_DEF_REACH;
+
+ tp->draghys = TP_DEF_DRAGHYS;
+ tp->mindrag = TP_DEF_MINDRAG;
+
+ tp->thresh = TP_DEF_THRESH;
+ tp->upthresh = TP_DEF_UP_THRESH;
+
+ tp->ztime = TP_DEF_Z_TIME;
+ tp->jenks = TP_DEF_JENKS_CURV;
+
+ tp->inertia = TP_DEF_INERTIA;
+ tp->skipback = TP_DEF_SKIPBACK;
+ tp->ext_dev = TP_DEF_EXT_DEV;
+}
+
+int trackpoint_detect(struct psmouse *psmouse, int set_properties)
+{
+ struct trackpoint_data *priv;
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char firmware_id;
+ unsigned char button_info;
+ unsigned char param[2];
+
+ param[0] = param[1] = 0;
+
+ if (ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
+ return -1;
+
+ if (param[0] != TP_MAGIC_IDENT)
+ return -1;
+
+ if (!set_properties)
+ return 0;
+
+ firmware_id = param[1];
+
+ if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
+ printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n");
+ button_info = 0;
+ }
+
+ psmouse->private = priv = kcalloc(1, sizeof(struct trackpoint_data), GFP_KERNEL);
+ if (!priv)
+ return -1;
+
+ psmouse->vendor = "IBM";
+ psmouse->name = "TrackPoint";
+
+ psmouse->reconnect = trackpoint_sync;
+ psmouse->disconnect = trackpoint_disconnect;
+
+ trackpoint_defaults(priv);
+ trackpoint_sync(psmouse);
+
+ sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
+
+ printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
+ firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f);
+
+ return 0;
+}
+
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
new file mode 100644
index 000000000000..9857d8b6ad66
--- /dev/null
+++ b/drivers/input/mouse/trackpoint.h
@@ -0,0 +1,147 @@
+/*
+ * IBM TrackPoint PS/2 mouse driver
+ *
+ * Stephen Evanchik <evanchsa@gmail.com>
+ *
+ * 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 _TRACKPOINT_H
+#define _TRACKPOINT_H
+
+/*
+ * These constants are from the TrackPoint System
+ * Engineering documentation Version 4 from IBM Watson
+ * research:
+ * http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
+ */
+
+#define TP_COMMAND 0xE2 /* Commands start with this */
+
+#define TP_READ_ID 0xE1 /* Sent for device identification */
+#define TP_MAGIC_IDENT 0x01 /* Sent after a TP_READ_ID followed */
+ /* by the firmware ID */
+
+
+/*
+ * Commands
+ */
+#define TP_RECALIB 0x51 /* Recalibrate */
+#define TP_POWER_DOWN 0x44 /* Can only be undone through HW reset */
+#define TP_EXT_DEV 0x21 /* Determines if external device is connected (RO) */
+#define TP_EXT_BTN 0x4B /* Read extended button status */
+#define TP_POR 0x7F /* Execute Power on Reset */
+#define TP_POR_RESULTS 0x25 /* Read Power on Self test results */
+#define TP_DISABLE_EXT 0x40 /* Disable external pointing device */
+#define TP_ENABLE_EXT 0x41 /* Enable external pointing device */
+
+/*
+ * Mode manipulation
+ */
+#define TP_SET_SOFT_TRANS 0x4E /* Set mode */
+#define TP_CANCEL_SOFT_TRANS 0xB9 /* Cancel mode */
+#define TP_SET_HARD_TRANS 0x45 /* Mode can only be set */
+
+
+/*
+ * Register oriented commands/properties
+ */
+#define TP_WRITE_MEM 0x81
+#define TP_READ_MEM 0x80 /* Not used in this implementation */
+
+/*
+* RAM Locations for properties
+ */
+#define TP_SENS 0x4A /* Sensitivity */
+#define TP_MB 0x4C /* Read Middle Button Status (RO) */
+#define TP_INERTIA 0x4D /* Negative Inertia */
+#define TP_SPEED 0x60 /* Speed of TP Cursor */
+#define TP_REACH 0x57 /* Backup for Z-axis press */
+#define TP_DRAGHYS 0x58 /* Drag Hysteresis */
+ /* (how hard it is to drag */
+ /* with Z-axis pressed) */
+
+#define TP_MINDRAG 0x59 /* Minimum amount of force needed */
+ /* to trigger dragging */
+
+#define TP_THRESH 0x5C /* Minimum value for a Z-axis press */
+#define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */
+#define TP_Z_TIME 0x5E /* How sharp of a press */
+#define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */
+
+/*
+ * Toggling Flag bits
+ */
+#define TP_TOGGLE 0x47 /* Toggle command */
+
+#define TP_TOGGLE_MB 0x23 /* Disable/Enable Middle Button */
+#define TP_MASK_MB 0x01
+#define TP_TOGGLE_EXT_DEV 0x23 /* Toggle external device */
+#define TP_MASK_EXT_DEV 0x02
+#define TP_TOGGLE_DRIFT 0x23 /* Drift Correction */
+#define TP_MASK_DRIFT 0x80
+#define TP_TOGGLE_BURST 0x28 /* Burst Mode */
+#define TP_MASK_BURST 0x80
+#define TP_TOGGLE_PTSON 0x2C /* Press to Select */
+#define TP_MASK_PTSON 0x01
+#define TP_TOGGLE_HARD_TRANS 0x2C /* Alternate method to set Hard Transparency */
+#define TP_MASK_HARD_TRANS 0x80
+#define TP_TOGGLE_TWOHAND 0x2D /* Two handed */
+#define TP_MASK_TWOHAND 0x01
+#define TP_TOGGLE_STICKY_TWO 0x2D /* Sticky two handed */
+#define TP_MASK_STICKY_TWO 0x04
+#define TP_TOGGLE_SKIPBACK 0x2D /* Suppress movement after drag release */
+#define TP_MASK_SKIPBACK 0x08
+#define TP_TOGGLE_SOURCE_TAG 0x20 /* Bit 3 of the first packet will be set to
+ to the origin of the packet (external or TP) */
+#define TP_MASK_SOURCE_TAG 0x80
+#define TP_TOGGLE_EXT_TAG 0x22 /* Bit 3 of the first packet coming from the
+ external device will be forced to 1 */
+#define TP_MASK_EXT_TAG 0x04
+
+
+/* Power on Self Test Results */
+#define TP_POR_SUCCESS 0x3B
+
+/*
+ * Default power on values
+ */
+#define TP_DEF_SENS 0x80
+#define TP_DEF_INERTIA 0x06
+#define TP_DEF_SPEED 0x61
+#define TP_DEF_REACH 0x0A
+
+#define TP_DEF_DRAGHYS 0xFF
+#define TP_DEF_MINDRAG 0x14
+
+#define TP_DEF_THRESH 0x08
+#define TP_DEF_UP_THRESH 0xFF
+#define TP_DEF_Z_TIME 0x26
+#define TP_DEF_JENKS_CURV 0x87
+
+/* Toggles */
+#define TP_DEF_MB 0x00
+#define TP_DEF_PTSON 0x00
+#define TP_DEF_SKIPBACK 0x00
+#define TP_DEF_EXT_DEV 0x01
+
+#define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd))
+
+struct trackpoint_data
+{
+ unsigned char sensitivity, speed, inertia, reach;
+ unsigned char draghys, mindrag;
+ unsigned char thresh, upthresh;
+ unsigned char ztime, jenks;
+
+ unsigned char press_to_select;
+ unsigned char skipback;
+
+ unsigned char ext_dev;
+};
+
+extern int trackpoint_detect(struct psmouse *psmouse, int set_properties);
+
+#endif /* _TRACKPOINT_H */
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index c9e633d21d90..9a9221644250 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -69,16 +69,16 @@ static inline int i8042_platform_init(void)
*/
#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64)
if (!request_region(I8042_DATA_REG, 16, "i8042"))
- return -1;
+ return -EBUSY;
#endif
i8042_reset = 1;
#if defined(CONFIG_PPC64)
if (check_legacy_ioport(I8042_DATA_REG))
- return -1;
+ return -EBUSY;
if (!request_region(I8042_DATA_REG, 16, "i8042"))
- return -1;
+ return -EBUSY;
#endif
return 0;
}
diff --git a/drivers/input/serio/i8042-ip22io.h b/drivers/input/serio/i8042-ip22io.h
index 863b9c95fbb8..ee1ad27d6ed0 100644
--- a/drivers/input/serio/i8042-ip22io.h
+++ b/drivers/input/serio/i8042-ip22io.h
@@ -58,7 +58,7 @@ static inline int i8042_platform_init(void)
#if 0
/* XXX sgi_kh is a virtual address */
if (!request_mem_region(sgi_kh, sizeof(struct hpc_keyb), "i8042"))
- return 1;
+ return -EBUSY;
#endif
i8042_reset = 1;
diff --git a/drivers/input/serio/i8042-jazzio.h b/drivers/input/serio/i8042-jazzio.h
index 5c20ab131488..13fd7108eb28 100644
--- a/drivers/input/serio/i8042-jazzio.h
+++ b/drivers/input/serio/i8042-jazzio.h
@@ -53,7 +53,7 @@ static inline int i8042_platform_init(void)
#if 0
/* XXX JAZZ_KEYBOARD_ADDRESS is a virtual address */
if (!request_mem_region(JAZZ_KEYBOARD_ADDRESS, 2, "i8042"))
- return 1;
+ return -EBUSY;
#endif
return 0;
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index da2a19812485..ed9446f6d7e3 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -48,10 +48,10 @@ static inline void i8042_write_command(int val)
#define OBP_PS2MS_NAME1 "kdmouse"
#define OBP_PS2MS_NAME2 "mouse"
-static int i8042_platform_init(void)
+static int __init i8042_platform_init(void)
{
#ifndef CONFIG_PCI
- return -1;
+ return -ENODEV;
#else
char prop[128];
int len;
@@ -59,14 +59,14 @@ static int i8042_platform_init(void)
len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop));
if (len < 0) {
printk("i8042: Cannot get name property of root OBP node.\n");
- return -1;
+ return -ENODEV;
}
if (strncmp(prop, "SUNW,JavaStation-1", len) == 0) {
/* Hardcoded values for MrCoffee. */
i8042_kbd_irq = i8042_aux_irq = 13 | 0x20;
kbd_iobase = ioremap(0x71300060, 8);
if (!kbd_iobase)
- return -1;
+ return -ENODEV;
} else {
struct linux_ebus *ebus;
struct linux_ebus_device *edev;
@@ -78,7 +78,7 @@ static int i8042_platform_init(void)
goto edev_found;
}
}
- return -1;
+ return -ENODEV;
edev_found:
for_each_edevchild(edev, child) {
@@ -96,7 +96,7 @@ static int i8042_platform_init(void)
i8042_aux_irq == -1) {
printk("i8042: Error, 8042 device lacks both kbd and "
"mouse nodes.\n");
- return -1;
+ return -ENODEV;
}
}
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 03877c84e6ff..273bb3b08cfa 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -138,6 +138,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
},
},
{
+ .ident = "Fujitsu-Siemens Lifebook E4010",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
+ },
+ },
+ {
.ident = "Toshiba P10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
@@ -256,9 +263,10 @@ static void i8042_pnp_exit(void)
}
}
-static int i8042_pnp_init(void)
+static int __init i8042_pnp_init(void)
{
- int result_kbd, result_aux;
+ int result_kbd = 0, result_aux = 0;
+ char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
if (i8042_nopnp) {
printk(KERN_INFO "i8042: PNP detection disabled\n");
@@ -267,6 +275,7 @@ static int i8042_pnp_init(void)
if ((result_kbd = pnp_register_driver(&i8042_pnp_kbd_driver)) >= 0)
i8042_pnp_kbd_registered = 1;
+
if ((result_aux = pnp_register_driver(&i8042_pnp_aux_driver)) >= 0)
i8042_pnp_aux_registered = 1;
@@ -280,6 +289,27 @@ static int i8042_pnp_init(void)
#endif
}
+ if (result_kbd > 0)
+ snprintf(kbd_irq_str, sizeof(kbd_irq_str),
+ "%d", i8042_pnp_kbd_irq);
+ if (result_aux > 0)
+ snprintf(aux_irq_str, sizeof(aux_irq_str),
+ "%d", i8042_pnp_aux_irq);
+
+ printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
+ i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "",
+ i8042_pnp_aux_name,
+ i8042_pnp_data_reg, i8042_pnp_command_reg,
+ kbd_irq_str, (result_kbd > 0 && result_aux > 0) ? "," : "",
+ aux_irq_str);
+
+#if defined(__ia64__)
+ if (result_kbd <= 0)
+ i8042_nokbd = 1;
+ if (result_aux <= 0)
+ i8042_noaux = 1;
+#endif
+
if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) {
printk(KERN_WARNING "PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
@@ -294,53 +324,47 @@ static int i8042_pnp_init(void)
i8042_pnp_command_reg = i8042_command_reg;
}
- if (!i8042_pnp_kbd_irq) {
- printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %#x\n", i8042_kbd_irq);
+ if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
+ printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %d\n", i8042_kbd_irq);
i8042_pnp_kbd_irq = i8042_kbd_irq;
}
- if (!i8042_pnp_aux_irq) {
- printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq);
+ if (!i8042_noaux && !i8042_pnp_aux_irq) {
+ printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %d\n", i8042_aux_irq);
i8042_pnp_aux_irq = i8042_aux_irq;
}
-#if defined(__ia64__)
- if (result_aux <= 0)
- i8042_noaux = 1;
-#endif
-
i8042_data_reg = i8042_pnp_data_reg;
i8042_command_reg = i8042_pnp_command_reg;
i8042_kbd_irq = i8042_pnp_kbd_irq;
i8042_aux_irq = i8042_pnp_aux_irq;
- printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %d%s%d\n",
- i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "", i8042_pnp_aux_name,
- i8042_data_reg, i8042_command_reg, i8042_kbd_irq,
- (result_aux > 0) ? "," : "", i8042_aux_irq);
-
return 0;
}
+#else
+static inline int i8042_pnp_init(void) { return 0; }
+static inline void i8042_pnp_exit(void) { }
#endif
-static inline int i8042_platform_init(void)
+static int __init i8042_platform_init(void)
{
+ int retval;
+
/*
* On ix86 platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on ix86 boxes.
*
* if (!request_region(I8042_DATA_REG, 16, "i8042"))
- * return -1;
+ * return -EBUSY;
*/
i8042_kbd_irq = I8042_MAP_IRQ(1);
i8042_aux_irq = I8042_MAP_IRQ(12);
-#ifdef CONFIG_PNP
- if (i8042_pnp_init())
- return -1;
-#endif
+ retval = i8042_pnp_init();
+ if (retval)
+ return retval;
#if defined(__ia64__)
i8042_reset = 1;
@@ -354,14 +378,12 @@ static inline int i8042_platform_init(void)
i8042_nomux = 1;
#endif
- return 0;
+ return retval;
}
static inline void i8042_platform_exit(void)
{
-#ifdef CONFIG_PNP
i8042_pnp_exit();
-#endif
}
#endif /* _I8042_X86IA64IO_H */
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 708a1d3beab9..40d451ce07ff 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -27,6 +27,10 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver");
MODULE_LICENSE("GPL");
+static unsigned int i8042_nokbd;
+module_param_named(nokbd, i8042_nokbd, bool, 0);
+MODULE_PARM_DESC(nokbd, "Do not probe or use KBD port.");
+
static unsigned int i8042_noaux;
module_param_named(noaux, i8042_noaux, bool, 0);
MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
@@ -338,10 +342,10 @@ static int i8042_open(struct serio *serio)
return 0;
-activate_fail:
+ activate_fail:
free_irq(port->irq, i8042_request_irq_cookie);
-irq_fail:
+ irq_fail:
serio_unregister_port_delayed(serio);
return -1;
@@ -485,7 +489,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
serio_interrupt(port->serio, data, dfl, regs);
ret = 1;
-out:
+ out:
return IRQ_RETVAL(ret);
}
@@ -552,7 +556,7 @@ static int i8042_enable_mux_ports(void)
* Enable all muxed ports.
*/
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
i8042_command(&param, I8042_CMD_MUX_PFX + i);
i8042_command(&param, I8042_CMD_AUX_ENABLE);
}
@@ -682,7 +686,7 @@ static int __init i8042_port_register(struct i8042_port *port)
kfree(port->serio);
port->serio = NULL;
i8042_ctr |= port->disable;
- return -1;
+ return -EIO;
}
printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
@@ -977,85 +981,88 @@ static struct device_driver i8042_driver = {
.shutdown = i8042_shutdown,
};
-static void __init i8042_create_kbd_port(void)
+static int __init i8042_create_kbd_port(void)
{
struct serio *serio;
struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
- serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
- if (serio) {
- memset(serio, 0, sizeof(struct serio));
- serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
- serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
- serio->open = i8042_open;
- serio->close = i8042_close;
- serio->start = i8042_start;
- serio->stop = i8042_stop;
- serio->port_data = port;
- serio->dev.parent = &i8042_platform_device->dev;
- strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
- strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
-
- port->serio = serio;
- i8042_port_register(port);
- }
+ serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!serio)
+ return -ENOMEM;
+
+ serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
+ serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
+ serio->open = i8042_open;
+ serio->close = i8042_close;
+ serio->start = i8042_start;
+ serio->stop = i8042_stop;
+ serio->port_data = port;
+ serio->dev.parent = &i8042_platform_device->dev;
+ strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
+ strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
+
+ port->serio = serio;
+
+ return i8042_port_register(port);
}
-static void __init i8042_create_aux_port(void)
+static int __init i8042_create_aux_port(void)
{
struct serio *serio;
struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
- serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
- if (serio) {
- memset(serio, 0, sizeof(struct serio));
- serio->id.type = SERIO_8042;
- serio->write = i8042_aux_write;
- serio->open = i8042_open;
- serio->close = i8042_close;
- serio->start = i8042_start;
- serio->stop = i8042_stop;
- serio->port_data = port;
- serio->dev.parent = &i8042_platform_device->dev;
- strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
- strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
-
- port->serio = serio;
- i8042_port_register(port);
- }
+ serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!serio)
+ return -ENOMEM;
+
+ serio->id.type = SERIO_8042;
+ serio->write = i8042_aux_write;
+ serio->open = i8042_open;
+ serio->close = i8042_close;
+ serio->start = i8042_start;
+ serio->stop = i8042_stop;
+ serio->port_data = port;
+ serio->dev.parent = &i8042_platform_device->dev;
+ strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
+ strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+
+ port->serio = serio;
+
+ return i8042_port_register(port);
}
-static void __init i8042_create_mux_port(int index)
+static int __init i8042_create_mux_port(int index)
{
struct serio *serio;
struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
- serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
- if (serio) {
- memset(serio, 0, sizeof(struct serio));
- serio->id.type = SERIO_8042;
- serio->write = i8042_aux_write;
- serio->open = i8042_open;
- serio->close = i8042_close;
- serio->start = i8042_start;
- serio->stop = i8042_stop;
- serio->port_data = port;
- serio->dev.parent = &i8042_platform_device->dev;
- snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
- snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
-
- *port = i8042_ports[I8042_AUX_PORT_NO];
- port->exists = 0;
- snprintf(port->name, sizeof(port->name), "AUX%d", index);
- port->mux = index;
- port->serio = serio;
- i8042_port_register(port);
- }
+ serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!serio)
+ return -ENOMEM;
+
+ serio->id.type = SERIO_8042;
+ serio->write = i8042_aux_write;
+ serio->open = i8042_open;
+ serio->close = i8042_close;
+ serio->start = i8042_start;
+ serio->stop = i8042_stop;
+ serio->port_data = port;
+ serio->dev.parent = &i8042_platform_device->dev;
+ snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
+ snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
+
+ *port = i8042_ports[I8042_AUX_PORT_NO];
+ port->exists = 0;
+ snprintf(port->name, sizeof(port->name), "AUX%d", index);
+ port->mux = index;
+ port->serio = serio;
+
+ return i8042_port_register(port);
}
static int __init i8042_init(void)
{
- int i;
+ int i, have_ports = 0;
int err;
dbg_init();
@@ -1063,43 +1070,73 @@ static int __init i8042_init(void)
init_timer(&i8042_timer);
i8042_timer.function = i8042_timer_func;
- if (i8042_platform_init())
- return -EBUSY;
+ err = i8042_platform_init();
+ if (err)
+ return err;
i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
if (i8042_controller_init()) {
- i8042_platform_exit();
- return -ENODEV;
+ err = -ENODEV;
+ goto err_platform_exit;
}
err = driver_register(&i8042_driver);
- if (err) {
- i8042_platform_exit();
- return err;
- }
+ if (err)
+ goto err_controller_cleanup;
i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
if (IS_ERR(i8042_platform_device)) {
- driver_unregister(&i8042_driver);
- i8042_platform_exit();
- return PTR_ERR(i8042_platform_device);
+ err = PTR_ERR(i8042_platform_device);
+ goto err_unregister_driver;
}
if (!i8042_noaux && !i8042_check_aux()) {
- if (!i8042_nomux && !i8042_check_mux())
- for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
- i8042_create_mux_port(i);
- else
- i8042_create_aux_port();
+ if (!i8042_nomux && !i8042_check_mux()) {
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+ err = i8042_create_mux_port(i);
+ if (err)
+ goto err_unregister_ports;
+ }
+ } else {
+ err = i8042_create_aux_port();
+ if (err)
+ goto err_unregister_ports;
+ }
+ have_ports = 1;
}
- i8042_create_kbd_port();
+ if (!i8042_nokbd) {
+ err = i8042_create_kbd_port();
+ if (err)
+ goto err_unregister_ports;
+ have_ports = 1;
+ }
+
+ if (!have_ports) {
+ err = -ENODEV;
+ goto err_unregister_device;
+ }
mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
return 0;
+
+ err_unregister_ports:
+ for (i = 0; i < I8042_NUM_PORTS; i++)
+ if (i8042_ports[i].serio)
+ serio_unregister_port(i8042_ports[i].serio);
+ err_unregister_device:
+ platform_device_unregister(i8042_platform_device);
+ err_unregister_driver:
+ driver_unregister(&i8042_driver);
+ err_controller_cleanup:
+ i8042_controller_cleanup();
+ err_platform_exit:
+ i8042_platform_exit();
+
+ return err;
}
static void __exit i8042_exit(void)
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 0489af5a80c9..21d55ed4b88a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -24,17 +24,17 @@ config TOUCHSCREEN_BITSY
module will be called h3600_ts_input.
config TOUCHSCREEN_CORGI
- tristate "Corgi touchscreen (for Sharp SL-C7xx)"
+ tristate "SharpSL (Corgi and Spitz series) touchscreen driver"
depends on PXA_SHARPSL
default y
help
Say Y here to enable the driver for the touchscreen on the
- Sharp SL-C7xx series of PDAs.
+ Sharp SL-C7xx and SL-Cxx00 series of PDAs.
If unsure, say N.
To compile this driver as a module, choose M here: the
- module will be called ads7846_ts.
+ module will be called corgi_ts.
config TOUCHSCREEN_GUNZE
tristate "Gunze AHL-51S touchscreen"
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 5d19261b884f..4c7fbe550365 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -1,5 +1,5 @@
/*
- * Touchscreen driver for Sharp Corgi models (SL-C7xx)
+ * Touchscreen driver for Sharp SL-C7xx and SL-Cxx00 models
*
* Copyright (c) 2004-2005 Richard Purdie
*
@@ -19,7 +19,7 @@
#include <linux/slab.h>
#include <asm/irq.h>
-#include <asm/arch/corgi.h>
+#include <asm/arch/sharpsl.h>
#include <asm/arch/hardware.h>
#include <asm/arch/pxa-regs.h>
@@ -47,15 +47,20 @@ struct corgi_ts {
struct ts_event tc;
int pendown;
int power_mode;
+ int irq_gpio;
+ struct corgits_machinfo *machinfo;
};
-#define STATUS_HSYNC (GPLR(CORGI_GPIO_HSYNC) & GPIO_bit(CORGI_GPIO_HSYNC))
-
-#define SyncHS() while((STATUS_HSYNC) == 0); while((STATUS_HSYNC) != 0);
+#ifdef CONFIG_PXA25x
#define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C0, 0" : "=r"(a))
#define PMNC_GET(x) asm volatile ("mrc p14, 0, %0, C0, C0, 0" : "=r"(x))
#define PMNC_SET(x) asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(x))
-
+#endif
+#ifdef CONFIG_PXA27x
+#define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
+#define PMNC_GET(x) asm volatile ("mrc p14, 0, %0, C0, C1, 0" : "=r"(x))
+#define PMNC_SET(x) asm volatile ("mcr p14, 0, %0, C0, C1, 0" : : "r"(x))
+#endif
/* ADS7846 Touch Screen Controller bit definitions */
#define ADSCTRL_PD0 (1u << 0) /* PD0 */
@@ -66,12 +71,11 @@ struct corgi_ts {
#define ADSCTRL_STS (1u << 7) /* Start Bit */
/* External Functions */
-extern unsigned long w100fb_get_hsynclen(struct device *dev);
extern unsigned int get_clk_frequency_khz(int info);
-static unsigned long calc_waittime(void)
+static unsigned long calc_waittime(struct corgi_ts *corgi_ts)
{
- unsigned long hsync_len = w100fb_get_hsynclen(&corgifb_device.dev);
+ unsigned long hsync_len = corgi_ts->machinfo->get_hsync_len();
if (hsync_len)
return get_clk_frequency_khz(0)*1000/hsync_len;
@@ -79,7 +83,8 @@ static unsigned long calc_waittime(void)
return 0;
}
-static int sync_receive_data_send_cmd(int doRecive, int doSend, unsigned int address, unsigned long wait_time)
+static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, int doSend,
+ unsigned int address, unsigned long wait_time)
{
unsigned long timer1 = 0, timer2, pmnc = 0;
int pos = 0;
@@ -90,7 +95,7 @@ static int sync_receive_data_send_cmd(int doRecive, int doSend, unsigned int add
PMNC_SET(0x01);
/* polling HSync */
- SyncHS();
+ corgi_ts->machinfo->wait_hsync();
/* get CCNT */
CCNT(timer1);
}
@@ -109,7 +114,7 @@ static int sync_receive_data_send_cmd(int doRecive, int doSend, unsigned int add
CCNT(timer2);
if (timer2-timer1 > wait_time) {
/* too slow - timeout, try again */
- SyncHS();
+ corgi_ts->machinfo->wait_hsync();
/* get OSCR */
CCNT(timer1);
/* Wait after HSync */
@@ -133,23 +138,23 @@ static int read_xydata(struct corgi_ts *corgi_ts)
/* critical section */
local_irq_save(flags);
corgi_ssp_ads7846_lock();
- wait_time=calc_waittime();
+ wait_time = calc_waittime(corgi_ts);
/* Y-axis */
- sync_receive_data_send_cmd(0, 1, 1u, wait_time);
+ sync_receive_data_send_cmd(corgi_ts, 0, 1, 1u, wait_time);
/* Y-axis */
- sync_receive_data_send_cmd(1, 1, 1u, wait_time);
+ sync_receive_data_send_cmd(corgi_ts, 1, 1, 1u, wait_time);
/* X-axis */
- y = sync_receive_data_send_cmd(1, 1, 5u, wait_time);
+ y = sync_receive_data_send_cmd(corgi_ts, 1, 1, 5u, wait_time);
/* Z1 */
- x = sync_receive_data_send_cmd(1, 1, 3u, wait_time);
+ x = sync_receive_data_send_cmd(corgi_ts, 1, 1, 3u, wait_time);
/* Z2 */
- z1 = sync_receive_data_send_cmd(1, 1, 4u, wait_time);
- z2 = sync_receive_data_send_cmd(1, 0, 4u, wait_time);
+ z1 = sync_receive_data_send_cmd(corgi_ts, 1, 1, 4u, wait_time);
+ z2 = sync_receive_data_send_cmd(corgi_ts, 1, 0, 4u, wait_time);
/* Power-Down Enable */
corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
@@ -189,9 +194,9 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs)
static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs)
{
- if ((GPLR(CORGI_GPIO_TP_INT) & GPIO_bit(CORGI_GPIO_TP_INT)) == 0) {
+ if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) {
/* Disable Interrupt */
- set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_NOEDGE);
+ set_irq_type(corgi_ts->irq_gpio, IRQT_NOEDGE);
if (read_xydata(corgi_ts)) {
corgi_ts->pendown = 1;
new_data(corgi_ts, regs);
@@ -210,7 +215,7 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_
}
/* Enable Falling Edge */
- set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_FALLING);
+ set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
corgi_ts->pendown = 0;
}
}
@@ -254,7 +259,7 @@ static int corgits_resume(struct device *dev, uint32_t level)
corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
/* Enable Falling Edge */
- set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_FALLING);
+ set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
corgi_ts->power_mode = PWR_MODE_ACTIVE;
}
return 0;
@@ -267,6 +272,7 @@ static int corgits_resume(struct device *dev, uint32_t level)
static int __init corgits_probe(struct device *dev)
{
struct corgi_ts *corgi_ts;
+ struct platform_device *pdev = to_platform_device(dev);
if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL)))
return -ENOMEM;
@@ -275,6 +281,14 @@ static int __init corgits_probe(struct device *dev)
memset(corgi_ts, 0, sizeof(struct corgi_ts));
+ corgi_ts->machinfo = dev->platform_data;
+ corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
+
+ if (corgi_ts->irq_gpio < 0) {
+ kfree(corgi_ts);
+ return -ENODEV;
+ }
+
init_input_dev(&corgi_ts->input);
corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
@@ -293,8 +307,7 @@ static int __init corgits_probe(struct device *dev)
corgi_ts->input.id.product = 0x0002;
corgi_ts->input.id.version = 0x0100;
- pxa_gpio_mode(CORGI_GPIO_TP_INT | GPIO_IN);
- pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
+ pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
/* Initiaize ADS7846 Difference Reference mode */
corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
@@ -313,14 +326,14 @@ static int __init corgits_probe(struct device *dev)
input_register_device(&corgi_ts->input);
corgi_ts->power_mode = PWR_MODE_ACTIVE;
- if (request_irq(CORGI_IRQ_GPIO_TP_INT, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
+ if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
input_unregister_device(&corgi_ts->input);
kfree(corgi_ts);
return -EBUSY;
}
/* Enable Falling Edge */
- set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_FALLING);
+ set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
printk(KERN_INFO "input: Corgi Touchscreen Registered\n");
@@ -331,8 +344,9 @@ static int corgits_remove(struct device *dev)
{
struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
- free_irq(CORGI_IRQ_GPIO_TP_INT, NULL);
+ free_irq(corgi_ts->irq_gpio, NULL);
del_timer_sync(&corgi_ts->timer);
+ corgi_ts->machinfo->put_hsync();
input_unregister_device(&corgi_ts->input);
kfree(corgi_ts);
return 0;
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index e1f0d87de0eb..0b0ea26023e5 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -287,12 +287,12 @@ divert_dev_init(void)
init_waitqueue_head(&rd_queue);
#ifdef CONFIG_PROC_FS
- isdn_proc_entry = create_proc_entry("isdn", S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+ isdn_proc_entry = proc_mkdir("net/isdn", NULL);
if (!isdn_proc_entry)
return (-1);
isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry);
if (!isdn_divert_entry) {
- remove_proc_entry("isdn", proc_net);
+ remove_proc_entry("net/isdn", NULL);
return (-1);
}
isdn_divert_entry->proc_fops = &isdn_fops;
@@ -312,7 +312,7 @@ divert_dev_deinit(void)
#ifdef CONFIG_PROC_FS
remove_proc_entry("divert", isdn_proc_entry);
- remove_proc_entry("isdn", proc_net);
+ remove_proc_entry("net/isdn", NULL);
#endif /* CONFIG_PROC_FS */
return (0);
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
index 7fdf8ae5be52..27204f4b111a 100644
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ b/drivers/isdn/hardware/eicon/diva_didd.c
@@ -30,8 +30,6 @@ static char *DRIVERNAME =
static char *DRIVERLNAME = "divadidd";
char *DRIVERRELEASE_DIDD = "2.0";
-static char *main_proc_dir = "eicon";
-
MODULE_DESCRIPTION("DIDD table driver for diva drivers");
MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
MODULE_SUPPORTED_DEVICE("Eicon diva drivers");
@@ -89,7 +87,7 @@ proc_read(char *page, char **start, off_t off, int count, int *eof,
static int DIVA_INIT_FUNCTION create_proc(void)
{
- proc_net_eicon = create_proc_entry(main_proc_dir, S_IFDIR, proc_net);
+ proc_net_eicon = proc_mkdir("net/eicon", NULL);
if (proc_net_eicon) {
if ((proc_didd =
@@ -105,7 +103,7 @@ static int DIVA_INIT_FUNCTION create_proc(void)
static void DIVA_EXIT_FUNCTION remove_proc(void)
{
remove_proc_entry(DRIVERLNAME, proc_net_eicon);
- remove_proc_entry(main_proc_dir, proc_net);
+ remove_proc_entry("net/eicon", NULL);
}
static int DIVA_INIT_FUNCTION divadidd_init(void)
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
index b6435589d459..c12efa6f8429 100644
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ b/drivers/isdn/hardware/eicon/divasproc.c
@@ -381,7 +381,7 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a)
char tmp[16];
sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
- if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_eicon)))
+ if (!(de = proc_mkdir(tmp, proc_net_eicon)))
return (0);
a->proc_adapter_dir = (void *) de;
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 8337b0f26cc4..4866fc32d8d9 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -61,6 +61,7 @@ static const PCI_ENTRY id_list[] =
{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
+ {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2, "Sitecom Europe", "DC-105 ISDN PCI"},
{0, 0, NULL, NULL},
};
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index c6b5bf7d2aca..dc334aab433e 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -611,7 +611,7 @@ static int sedlbauer_event(event_t event, int priority,
} /* sedlbauer_event */
static struct pcmcia_device_id sedlbauer_ids[] = {
- PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", "speed star II", "V 3.1", "(c) 93 - 98 cb ", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a, 0x50d4149c),
+ PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90),
PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce),
PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe),
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
index 0fda5c89429b..9ffaae7c657a 100644
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -466,10 +466,10 @@ void st5481_stop(struct st5481_adapter *adapter);
#define __debug_variable st5481_debug
#include "hisax_debug.h"
-#ifdef CONFIG_HISAX_DEBUG
-
extern int st5481_debug;
+#ifdef CONFIG_HISAX_DEBUG
+
#define DBG_ISO_PACKET(level,urb) \
if (level & __debug_variable) dump_iso_packet(__FUNCTION__,urb)
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 2fcd093921d8..657817a591fe 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -172,14 +172,18 @@ static void usb_b_out_complete(struct urb *urb, struct pt_regs *regs)
test_and_clear_bit(buf_nr, &b_out->busy);
if (unlikely(urb->status < 0)) {
- if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
- WARN("urb status %d",urb->status);
- if (b_out->busy == 0) {
- st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
- }
- } else {
- DBG(1,"urb killed");
- return; // Give up
+ switch (urb->status) {
+ case -ENOENT:
+ case -ESHUTDOWN:
+ case -ECONNRESET:
+ DBG(4,"urb killed status %d", urb->status);
+ return; // Give up
+ default:
+ WARN("urb status %d",urb->status);
+ if (b_out->busy == 0) {
+ st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
+ }
+ break;
}
}
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 071b1d31999f..941f7022ada1 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -382,16 +382,20 @@ static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs)
test_and_clear_bit(buf_nr, &d_out->busy);
if (unlikely(urb->status < 0)) {
- if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
- WARN("urb status %d",urb->status);
- if (d_out->busy == 0) {
- st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
- }
- return;
- } else {
- DBG(1,"urb killed");
- return; // Give up
+ switch (urb->status) {
+ case -ENOENT:
+ case -ESHUTDOWN:
+ case -ECONNRESET:
+ DBG(1,"urb killed status %d", urb->status);
+ break;
+ default:
+ WARN("urb status %d",urb->status);
+ if (d_out->busy == 0) {
+ st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
+ }
+ break;
}
+ return; // Give up
}
FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr);
@@ -709,14 +713,14 @@ int st5481_setup_d(struct st5481_adapter *adapter)
adapter->l1m.fsm = &l1fsm;
adapter->l1m.state = ST_L1_F3;
- adapter->l1m.debug = 1;
+ adapter->l1m.debug = st5481_debug & 0x100;
adapter->l1m.userdata = adapter;
adapter->l1m.printdebug = l1m_debug;
FsmInitTimer(&adapter->l1m, &adapter->timer);
adapter->d_out.fsm.fsm = &dout_fsm;
adapter->d_out.fsm.state = ST_DOUT_NONE;
- adapter->d_out.fsm.debug = 1;
+ adapter->d_out.fsm.debug = st5481_debug & 0x100;
adapter->d_out.fsm.userdata = adapter;
adapter->d_out.fsm.printdebug = dout_debug;
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 7aa810d5d333..2cf5d1a6df6c 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -43,10 +43,10 @@ static int number_of_leds = 2; /* 2 LEDs on the adpater default */
module_param(number_of_leds, int, 0);
#ifdef CONFIG_HISAX_DEBUG
-static int debug = 0x1;
+static int debug = 0;
module_param(debug, int, 0);
-int st5481_debug;
#endif
+int st5481_debug;
static LIST_HEAD(adapter_list);
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index ab62223297a5..89fbeb58485d 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -132,11 +132,15 @@ static void usb_ctrl_complete(struct urb *urb, struct pt_regs *regs)
struct ctrl_msg *ctrl_msg;
if (unlikely(urb->status < 0)) {
- if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
- WARN("urb status %d",urb->status);
- } else {
- DBG(1,"urb killed");
- return; // Give up
+ switch (urb->status) {
+ case -ENOENT:
+ case -ESHUTDOWN:
+ case -ECONNRESET:
+ DBG(1,"urb killed status %d", urb->status);
+ return; // Give up
+ default:
+ WARN("urb status %d",urb->status);
+ break;
}
}
@@ -184,22 +188,22 @@ static void usb_int_complete(struct urb *urb, struct pt_regs *regs)
int status;
switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- DBG(1, "urb shutting down with status: %d", urb->status);
- return;
- default:
- WARN("nonzero urb status received: %d", urb->status);
- goto exit;
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ DBG(2, "urb shutting down with status: %d", urb->status);
+ return;
+ default:
+ WARN("nonzero urb status received: %d", urb->status);
+ goto exit;
}
- DBG_PACKET(1, data, INT_PKT_SIZE);
+ DBG_PACKET(2, data, INT_PKT_SIZE);
if (urb->actual_length == 0) {
goto exit;
@@ -250,7 +254,7 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
struct urb *urb;
u8 *buf;
- DBG(1,"");
+ DBG(2,"");
if ((status = usb_reset_configuration (dev)) < 0) {
WARN("reset_configuration failed,status=%d",status);
@@ -330,15 +334,17 @@ void st5481_release_usb(struct st5481_adapter *adapter)
DBG(1,"");
// Stop and free Control and Interrupt URBs
- usb_unlink_urb(ctrl->urb);
+ usb_kill_urb(ctrl->urb);
if (ctrl->urb->transfer_buffer)
kfree(ctrl->urb->transfer_buffer);
usb_free_urb(ctrl->urb);
+ ctrl->urb = NULL;
- usb_unlink_urb(intr->urb);
+ usb_kill_urb(intr->urb);
if (intr->urb->transfer_buffer)
kfree(intr->urb->transfer_buffer);
usb_free_urb(intr->urb);
+ ctrl->urb = NULL;
}
/*
@@ -406,6 +412,7 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev,
spin_lock_init(&urb->lock);
urb->dev=dev;
urb->pipe=pipe;
+ urb->interval = 1;
urb->transfer_buffer=buf;
urb->number_of_packets = num_packets;
urb->transfer_buffer_length=num_packets*packet_size;
@@ -452,7 +459,9 @@ st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
if (urb[j]) {
if (urb[j]->transfer_buffer)
kfree(urb[j]->transfer_buffer);
+ urb[j]->transfer_buffer = NULL;
usb_free_urb(urb[j]);
+ urb[j] = NULL;
}
}
return retval;
@@ -463,10 +472,11 @@ void st5481_release_isocpipes(struct urb* urb[2])
int j;
for (j = 0; j < 2; j++) {
- usb_unlink_urb(urb[j]);
+ usb_kill_urb(urb[j]);
if (urb[j]->transfer_buffer)
kfree(urb[j]->transfer_buffer);
usb_free_urb(urb[j]);
+ urb[j] = NULL;
}
}
@@ -485,11 +495,15 @@ static void usb_in_complete(struct urb *urb, struct pt_regs *regs)
int len, count, status;
if (unlikely(urb->status < 0)) {
- if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
- WARN("urb status %d",urb->status);
- } else {
- DBG(1,"urb killed");
- return; // Give up
+ switch (urb->status) {
+ case -ENOENT:
+ case -ESHUTDOWN:
+ case -ECONNRESET:
+ DBG(1,"urb killed status %d", urb->status);
+ return; // Give up
+ default:
+ WARN("urb status %d",urb->status);
+ break;
}
}
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 5da507e532fc..639582f61f41 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -394,7 +394,7 @@ hysdn_procconf_init(void)
hysdn_card *card;
uchar conf_name[20];
- hysdn_proc_entry = create_proc_entry(PROC_SUBDIR_NAME, S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+ hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, proc_net);
if (!hysdn_proc_entry) {
printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n");
return (-1);
diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c
index baf4bcad9bf9..0afe442db3b0 100644
--- a/drivers/isdn/i4l/isdn_bsdcomp.c
+++ b/drivers/isdn/i4l/isdn_bsdcomp.c
@@ -283,23 +283,19 @@ static void bsd_free (void *state)
/*
* Release the dictionary
*/
- if (db->dict) {
- vfree (db->dict);
- db->dict = NULL;
- }
+ vfree(db->dict);
+ db->dict = NULL;
/*
* Release the string buffer
*/
- if (db->lens) {
- vfree (db->lens);
- db->lens = NULL;
- }
+ vfree(db->lens);
+ db->lens = NULL;
/*
* Finally release the structure itself.
*/
- kfree (db);
+ kfree(db);
}
}
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index eebcb0b97f0e..8a7d54a5c97d 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1953,7 +1953,8 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
kfree(d->rcvcount);
if (!(d->rcvcount = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n");
- if (!adding) kfree(d->rcverr);
+ if (!adding)
+ kfree(d->rcverr);
return -1;
}
memset((char *) d->rcvcount, 0, sizeof(int) * m);
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 40b0df04ed9f..1ebed041672d 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -87,7 +87,7 @@ static int __init sc_init(void)
*/
for (i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
if(!request_region(io[b] + i * 0x400, 1, "sc test")) {
- pr_debug("check_region for 0x%x failed\n", io[b] + i * 0x400);
+ pr_debug("request_region for 0x%x failed\n", io[b] + i * 0x400);
io[b] = 0;
break;
} else
@@ -181,7 +181,7 @@ static int __init sc_init(void)
for (i = SRAM_MIN ; i < SRAM_MAX ; i += SRAM_PAGESIZE) {
pr_debug("Checking RAM address 0x%x...\n", i);
if(request_region(i, SRAM_PAGESIZE, "sc test")) {
- pr_debug(" check_region succeeded\n");
+ pr_debug(" request_region succeeded\n");
model = identify_board(i, io[b]);
release_region(i, SRAM_PAGESIZE);
if (model >= 0) {
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index fb535737d17d..9b38674fbf75 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -8,21 +8,15 @@
*/
/*
- * For now, this driver includes:
- * - RTC get & set
- * - reboot & shutdown commands
- * all synchronous with IRQ disabled (ugh)
- *
* TODO:
- * rework in a way the PMU driver works, that is asynchronous
- * with a queue of commands. I'll do that as soon as I have an
- * SMU based machine at hand. Some more cleanup is needed too,
- * like maybe fitting it into a platform device, etc...
- * Also check what's up with cache coherency, and if we really
- * can't do better than flushing the cache, maybe build a table
- * of command len/reply len like the PMU driver to only flush
- * what is actually necessary.
- * --BenH.
+ * - maybe add timeout to commands ?
+ * - blocking version of time functions
+ * - polling version of i2c commands (including timer that works with
+ * interrutps off)
+ * - maybe avoid some data copies with i2c by directly using the smu cmd
+ * buffer and a lower level internal interface
+ * - understand SMU -> CPU events and implement reception of them via
+ * the userland interface
*/
#include <linux/config.h>
@@ -36,6 +30,11 @@
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
+#include <linux/completion.h>
+#include <linux/miscdevice.h>
+#include <linux/delay.h>
+#include <linux/sysdev.h>
+#include <linux/poll.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -45,8 +44,13 @@
#include <asm/smu.h>
#include <asm/sections.h>
#include <asm/abs_addr.h>
+#include <asm/uaccess.h>
+#include <asm/of_device.h>
+
+#define VERSION "0.6"
+#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
-#define DEBUG_SMU 1
+#undef DEBUG_SMU
#ifdef DEBUG_SMU
#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0)
@@ -57,20 +61,30 @@
/*
* This is the command buffer passed to the SMU hardware
*/
+#define SMU_MAX_DATA 254
+
struct smu_cmd_buf {
u8 cmd;
u8 length;
- u8 data[0x0FFE];
+ u8 data[SMU_MAX_DATA];
};
struct smu_device {
spinlock_t lock;
struct device_node *of_node;
- int db_ack; /* doorbell ack GPIO */
- int db_req; /* doorbell req GPIO */
+ struct of_device *of_dev;
+ int doorbell; /* doorbell gpio */
u32 __iomem *db_buf; /* doorbell buffer */
+ int db_irq;
+ int msg;
+ int msg_irq;
struct smu_cmd_buf *cmd_buf; /* command buffer virtual */
u32 cmd_buf_abs; /* command buffer absolute */
+ struct list_head cmd_list;
+ struct smu_cmd *cmd_cur; /* pending command */
+ struct list_head cmd_i2c_list;
+ struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */
+ struct timer_list i2c_timer;
};
/*
@@ -79,113 +93,245 @@ struct smu_device {
*/
static struct smu_device *smu;
+
/*
- * SMU low level communication stuff
+ * SMU driver low level stuff
*/
-static inline int smu_cmd_stat(struct smu_cmd_buf *cmd_buf, u8 cmd_ack)
-{
- rmb();
- return cmd_buf->cmd == cmd_ack && cmd_buf->length != 0;
-}
-static inline u8 smu_save_ack_cmd(struct smu_cmd_buf *cmd_buf)
+static void smu_start_cmd(void)
{
- return (~cmd_buf->cmd) & 0xff;
-}
+ unsigned long faddr, fend;
+ struct smu_cmd *cmd;
-static void smu_send_cmd(struct smu_device *dev)
-{
- /* SMU command buf is currently cacheable, we need a physical
- * address. This isn't exactly a DMA mapping here, I suspect
+ if (list_empty(&smu->cmd_list))
+ return;
+
+ /* Fetch first command in queue */
+ cmd = list_entry(smu->cmd_list.next, struct smu_cmd, link);
+ smu->cmd_cur = cmd;
+ list_del(&cmd->link);
+
+ DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd,
+ cmd->data_len);
+ DPRINTK("SMU: data buffer: %02x %02x %02x %02x ...\n",
+ ((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1],
+ ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3]);
+
+ /* Fill the SMU command buffer */
+ smu->cmd_buf->cmd = cmd->cmd;
+ smu->cmd_buf->length = cmd->data_len;
+ memcpy(smu->cmd_buf->data, cmd->data_buf, cmd->data_len);
+
+ /* Flush command and data to RAM */
+ faddr = (unsigned long)smu->cmd_buf;
+ fend = faddr + smu->cmd_buf->length + 2;
+ flush_inval_dcache_range(faddr, fend);
+
+ /* This isn't exactly a DMA mapping here, I suspect
* the SMU is actually communicating with us via i2c to the
* northbridge or the CPU to access RAM.
*/
- writel(dev->cmd_buf_abs, dev->db_buf);
+ writel(smu->cmd_buf_abs, smu->db_buf);
/* Ring the SMU doorbell */
- pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, dev->db_req, 4);
- pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, dev->db_req, 4);
+ pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, smu->doorbell, 4);
}
-static int smu_cmd_done(struct smu_device *dev)
+
+static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs)
{
- unsigned long wait = 0;
- int gpio;
+ unsigned long flags;
+ struct smu_cmd *cmd;
+ void (*done)(struct smu_cmd *cmd, void *misc) = NULL;
+ void *misc = NULL;
+ u8 gpio;
+ int rc = 0;
- /* Check the SMU doorbell */
- do {
- gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO,
- NULL, dev->db_ack);
- if ((gpio & 7) == 7)
- return 0;
- udelay(100);
- } while(++wait < 10000);
+ /* SMU completed the command, well, we hope, let's make sure
+ * of it
+ */
+ spin_lock_irqsave(&smu->lock, flags);
- printk(KERN_ERR "SMU timeout !\n");
- return -ENXIO;
+ gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell);
+ if ((gpio & 7) != 7) {
+ spin_unlock_irqrestore(&smu->lock, flags);
+ return IRQ_HANDLED;
+ }
+
+ cmd = smu->cmd_cur;
+ smu->cmd_cur = NULL;
+ if (cmd == NULL)
+ goto bail;
+
+ if (rc == 0) {
+ unsigned long faddr;
+ int reply_len;
+ u8 ack;
+
+ /* CPU might have brought back the cache line, so we need
+ * to flush again before peeking at the SMU response. We
+ * flush the entire buffer for now as we haven't read the
+ * reply lenght (it's only 2 cache lines anyway)
+ */
+ faddr = (unsigned long)smu->cmd_buf;
+ flush_inval_dcache_range(faddr, faddr + 256);
+
+ /* Now check ack */
+ ack = (~cmd->cmd) & 0xff;
+ if (ack != smu->cmd_buf->cmd) {
+ DPRINTK("SMU: incorrect ack, want %x got %x\n",
+ ack, smu->cmd_buf->cmd);
+ rc = -EIO;
+ }
+ reply_len = rc == 0 ? smu->cmd_buf->length : 0;
+ DPRINTK("SMU: reply len: %d\n", reply_len);
+ if (reply_len > cmd->reply_len) {
+ printk(KERN_WARNING "SMU: reply buffer too small,"
+ "got %d bytes for a %d bytes buffer\n",
+ reply_len, cmd->reply_len);
+ reply_len = cmd->reply_len;
+ }
+ cmd->reply_len = reply_len;
+ if (cmd->reply_buf && reply_len)
+ memcpy(cmd->reply_buf, smu->cmd_buf->data, reply_len);
+ }
+
+ /* Now complete the command. Write status last in order as we lost
+ * ownership of the command structure as soon as it's no longer -1
+ */
+ done = cmd->done;
+ misc = cmd->misc;
+ mb();
+ cmd->status = rc;
+ bail:
+ /* Start next command if any */
+ smu_start_cmd();
+ spin_unlock_irqrestore(&smu->lock, flags);
+
+ /* Call command completion handler if any */
+ if (done)
+ done(cmd, misc);
+
+ /* It's an edge interrupt, nothing to do */
+ return IRQ_HANDLED;
}
-static int smu_do_cmd(struct smu_device *dev)
+
+static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs)
{
- int rc;
- u8 cmd_ack;
+ /* I don't quite know what to do with this one, we seem to never
+ * receive it, so I suspect we have to arm it someway in the SMU
+ * to start getting events that way.
+ */
- DPRINTK("SMU do_cmd %02x len=%d %02x\n",
- dev->cmd_buf->cmd, dev->cmd_buf->length,
- dev->cmd_buf->data[0]);
+ printk(KERN_INFO "SMU: message interrupt !\n");
- cmd_ack = smu_save_ack_cmd(dev->cmd_buf);
+ /* It's an edge interrupt, nothing to do */
+ return IRQ_HANDLED;
+}
- /* Clear cmd_buf cache lines */
- flush_inval_dcache_range((unsigned long)dev->cmd_buf,
- ((unsigned long)dev->cmd_buf) +
- sizeof(struct smu_cmd_buf));
- smu_send_cmd(dev);
- rc = smu_cmd_done(dev);
- if (rc == 0)
- rc = smu_cmd_stat(dev->cmd_buf, cmd_ack) ? 0 : -1;
- DPRINTK("SMU do_cmd %02x len=%d %02x => %d (%02x)\n",
- dev->cmd_buf->cmd, dev->cmd_buf->length,
- dev->cmd_buf->data[0], rc, cmd_ack);
+/*
+ * Queued command management.
+ *
+ */
+
+int smu_queue_cmd(struct smu_cmd *cmd)
+{
+ unsigned long flags;
- return rc;
+ if (smu == NULL)
+ return -ENODEV;
+ if (cmd->data_len > SMU_MAX_DATA ||
+ cmd->reply_len > SMU_MAX_DATA)
+ return -EINVAL;
+
+ cmd->status = 1;
+ spin_lock_irqsave(&smu->lock, flags);
+ list_add_tail(&cmd->link, &smu->cmd_list);
+ if (smu->cmd_cur == NULL)
+ smu_start_cmd();
+ spin_unlock_irqrestore(&smu->lock, flags);
+
+ return 0;
}
+EXPORT_SYMBOL(smu_queue_cmd);
-/* RTC low level commands */
-static inline int bcd2hex (int n)
+
+int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command,
+ unsigned int data_len,
+ void (*done)(struct smu_cmd *cmd, void *misc),
+ void *misc, ...)
{
- return (((n & 0xf0) >> 4) * 10) + (n & 0xf);
+ struct smu_cmd *cmd = &scmd->cmd;
+ va_list list;
+ int i;
+
+ if (data_len > sizeof(scmd->buffer))
+ return -EINVAL;
+
+ memset(scmd, 0, sizeof(*scmd));
+ cmd->cmd = command;
+ cmd->data_len = data_len;
+ cmd->data_buf = scmd->buffer;
+ cmd->reply_len = sizeof(scmd->buffer);
+ cmd->reply_buf = scmd->buffer;
+ cmd->done = done;
+ cmd->misc = misc;
+
+ va_start(list, misc);
+ for (i = 0; i < data_len; ++i)
+ scmd->buffer[i] = (u8)va_arg(list, int);
+ va_end(list);
+
+ return smu_queue_cmd(cmd);
}
+EXPORT_SYMBOL(smu_queue_simple);
-static inline int hex2bcd (int n)
+
+void smu_poll(void)
{
- return ((n / 10) << 4) + (n % 10);
+ u8 gpio;
+
+ if (smu == NULL)
+ return;
+
+ gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell);
+ if ((gpio & 7) == 7)
+ smu_db_intr(smu->db_irq, smu, NULL);
}
+EXPORT_SYMBOL(smu_poll);
-#if 0
-static inline void smu_fill_set_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf)
+
+void smu_done_complete(struct smu_cmd *cmd, void *misc)
{
- cmd_buf->cmd = 0x8e;
- cmd_buf->length = 8;
- cmd_buf->data[0] = 0x00;
- memset(cmd_buf->data + 1, 0, 7);
+ struct completion *comp = misc;
+
+ complete(comp);
}
+EXPORT_SYMBOL(smu_done_complete);
+
-static inline void smu_fill_get_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf)
+void smu_spinwait_cmd(struct smu_cmd *cmd)
{
- cmd_buf->cmd = 0x8e;
- cmd_buf->length = 1;
- cmd_buf->data[0] = 0x01;
+ while(cmd->status == 1)
+ smu_poll();
}
+EXPORT_SYMBOL(smu_spinwait_cmd);
+
-static inline void smu_fill_dis_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf)
+/* RTC low level commands */
+static inline int bcd2hex (int n)
{
- cmd_buf->cmd = 0x8e;
- cmd_buf->length = 1;
- cmd_buf->data[0] = 0x02;
+ return (((n & 0xf0) >> 4) * 10) + (n & 0xf);
}
-#endif
+
+
+static inline int hex2bcd (int n)
+{
+ return ((n / 10) << 4) + (n % 10);
+}
+
static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf,
struct rtc_time *time)
@@ -202,100 +348,96 @@ static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf,
cmd_buf->data[7] = hex2bcd(time->tm_year - 100);
}
-static inline void smu_fill_get_rtc_cmd(struct smu_cmd_buf *cmd_buf)
-{
- cmd_buf->cmd = 0x8e;
- cmd_buf->length = 1;
- cmd_buf->data[0] = 0x81;
-}
-static void smu_parse_get_rtc_reply(struct smu_cmd_buf *cmd_buf,
- struct rtc_time *time)
+int smu_get_rtc_time(struct rtc_time *time, int spinwait)
{
- time->tm_sec = bcd2hex(cmd_buf->data[0]);
- time->tm_min = bcd2hex(cmd_buf->data[1]);
- time->tm_hour = bcd2hex(cmd_buf->data[2]);
- time->tm_wday = bcd2hex(cmd_buf->data[3]);
- time->tm_mday = bcd2hex(cmd_buf->data[4]);
- time->tm_mon = bcd2hex(cmd_buf->data[5]) - 1;
- time->tm_year = bcd2hex(cmd_buf->data[6]) + 100;
-}
-
-int smu_get_rtc_time(struct rtc_time *time)
-{
- unsigned long flags;
+ struct smu_simple_cmd cmd;
int rc;
if (smu == NULL)
return -ENODEV;
memset(time, 0, sizeof(struct rtc_time));
- spin_lock_irqsave(&smu->lock, flags);
- smu_fill_get_rtc_cmd(smu->cmd_buf);
- rc = smu_do_cmd(smu);
- if (rc == 0)
- smu_parse_get_rtc_reply(smu->cmd_buf, time);
- spin_unlock_irqrestore(&smu->lock, flags);
+ rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 1, NULL, NULL,
+ SMU_CMD_RTC_GET_DATETIME);
+ if (rc)
+ return rc;
+ smu_spinwait_simple(&cmd);
- return rc;
+ time->tm_sec = bcd2hex(cmd.buffer[0]);
+ time->tm_min = bcd2hex(cmd.buffer[1]);
+ time->tm_hour = bcd2hex(cmd.buffer[2]);
+ time->tm_wday = bcd2hex(cmd.buffer[3]);
+ time->tm_mday = bcd2hex(cmd.buffer[4]);
+ time->tm_mon = bcd2hex(cmd.buffer[5]) - 1;
+ time->tm_year = bcd2hex(cmd.buffer[6]) + 100;
+
+ return 0;
}
-int smu_set_rtc_time(struct rtc_time *time)
+
+int smu_set_rtc_time(struct rtc_time *time, int spinwait)
{
- unsigned long flags;
+ struct smu_simple_cmd cmd;
int rc;
if (smu == NULL)
return -ENODEV;
- spin_lock_irqsave(&smu->lock, flags);
- smu_fill_set_rtc_cmd(smu->cmd_buf, time);
- rc = smu_do_cmd(smu);
- spin_unlock_irqrestore(&smu->lock, flags);
+ rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 8, NULL, NULL,
+ SMU_CMD_RTC_SET_DATETIME,
+ hex2bcd(time->tm_sec),
+ hex2bcd(time->tm_min),
+ hex2bcd(time->tm_hour),
+ time->tm_wday,
+ hex2bcd(time->tm_mday),
+ hex2bcd(time->tm_mon) + 1,
+ hex2bcd(time->tm_year - 100));
+ if (rc)
+ return rc;
+ smu_spinwait_simple(&cmd);
- return rc;
+ return 0;
}
+
void smu_shutdown(void)
{
- const unsigned char *command = "SHUTDOWN";
- unsigned long flags;
+ struct smu_simple_cmd cmd;
if (smu == NULL)
return;
- spin_lock_irqsave(&smu->lock, flags);
- smu->cmd_buf->cmd = 0xaa;
- smu->cmd_buf->length = strlen(command);
- strcpy(smu->cmd_buf->data, command);
- smu_do_cmd(smu);
+ if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 9, NULL, NULL,
+ 'S', 'H', 'U', 'T', 'D', 'O', 'W', 'N', 0))
+ return;
+ smu_spinwait_simple(&cmd);
for (;;)
;
- spin_unlock_irqrestore(&smu->lock, flags);
}
+
void smu_restart(void)
{
- const unsigned char *command = "RESTART";
- unsigned long flags;
+ struct smu_simple_cmd cmd;
if (smu == NULL)
return;
- spin_lock_irqsave(&smu->lock, flags);
- smu->cmd_buf->cmd = 0xaa;
- smu->cmd_buf->length = strlen(command);
- strcpy(smu->cmd_buf->data, command);
- smu_do_cmd(smu);
+ if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, NULL, NULL,
+ 'R', 'E', 'S', 'T', 'A', 'R', 'T', 0))
+ return;
+ smu_spinwait_simple(&cmd);
for (;;)
;
- spin_unlock_irqrestore(&smu->lock, flags);
}
+
int smu_present(void)
{
return smu != NULL;
}
+EXPORT_SYMBOL(smu_present);
int smu_init (void)
@@ -307,6 +449,8 @@ int smu_init (void)
if (np == NULL)
return -ENODEV;
+ printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR);
+
if (smu_cmdbuf_abs == 0) {
printk(KERN_ERR "SMU: Command buffer not allocated !\n");
return -EINVAL;
@@ -318,7 +462,13 @@ int smu_init (void)
memset(smu, 0, sizeof(*smu));
spin_lock_init(&smu->lock);
+ INIT_LIST_HEAD(&smu->cmd_list);
+ INIT_LIST_HEAD(&smu->cmd_i2c_list);
smu->of_node = np;
+ smu->db_irq = NO_IRQ;
+ smu->msg_irq = NO_IRQ;
+ init_timer(&smu->i2c_timer);
+
/* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a
* 32 bits value safely
*/
@@ -331,8 +481,8 @@ int smu_init (void)
goto fail;
}
data = (u32 *)get_property(np, "reg", NULL);
- of_node_put(np);
if (data == NULL) {
+ of_node_put(np);
printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n");
goto fail;
}
@@ -341,8 +491,31 @@ int smu_init (void)
* and ack. GPIOs are at 0x50, best would be to find that out
* in the device-tree though.
*/
- smu->db_req = 0x50 + *data;
- smu->db_ack = 0x50 + *data;
+ smu->doorbell = *data;
+ if (smu->doorbell < 0x50)
+ smu->doorbell += 0x50;
+ if (np->n_intrs > 0)
+ smu->db_irq = np->intrs[0].line;
+
+ of_node_put(np);
+
+ /* Now look for the smu-interrupt GPIO */
+ do {
+ np = of_find_node_by_name(NULL, "smu-interrupt");
+ if (np == NULL)
+ break;
+ data = (u32 *)get_property(np, "reg", NULL);
+ if (data == NULL) {
+ of_node_put(np);
+ break;
+ }
+ smu->msg = *data;
+ if (smu->msg < 0x50)
+ smu->msg += 0x50;
+ if (np->n_intrs > 0)
+ smu->msg_irq = np->intrs[0].line;
+ of_node_put(np);
+ } while(0);
/* Doorbell buffer is currently hard-coded, I didn't find a proper
* device-tree entry giving the address. Best would probably to use
@@ -362,3 +535,584 @@ int smu_init (void)
return -ENXIO;
}
+
+
+static int smu_late_init(void)
+{
+ if (!smu)
+ return 0;
+
+ /*
+ * Try to request the interrupts
+ */
+
+ if (smu->db_irq != NO_IRQ) {
+ if (request_irq(smu->db_irq, smu_db_intr,
+ SA_SHIRQ, "SMU doorbell", smu) < 0) {
+ printk(KERN_WARNING "SMU: can't "
+ "request interrupt %d\n",
+ smu->db_irq);
+ smu->db_irq = NO_IRQ;
+ }
+ }
+
+ if (smu->msg_irq != NO_IRQ) {
+ if (request_irq(smu->msg_irq, smu_msg_intr,
+ SA_SHIRQ, "SMU message", smu) < 0) {
+ printk(KERN_WARNING "SMU: can't "
+ "request interrupt %d\n",
+ smu->msg_irq);
+ smu->msg_irq = NO_IRQ;
+ }
+ }
+
+ return 0;
+}
+arch_initcall(smu_late_init);
+
+/*
+ * sysfs visibility
+ */
+
+static void smu_expose_childs(void *unused)
+{
+ struct device_node *np;
+
+ for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) {
+ if (device_is_compatible(np, "smu-i2c")) {
+ char name[32];
+ u32 *reg = (u32 *)get_property(np, "reg", NULL);
+
+ if (reg == NULL)
+ continue;
+ sprintf(name, "smu-i2c-%02x", *reg);
+ of_platform_device_create(np, name, &smu->of_dev->dev);
+ }
+ }
+
+}
+
+static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL);
+
+static int smu_platform_probe(struct of_device* dev,
+ const struct of_device_id *match)
+{
+ if (!smu)
+ return -ENODEV;
+ smu->of_dev = dev;
+
+ /*
+ * Ok, we are matched, now expose all i2c busses. We have to defer
+ * that unfortunately or it would deadlock inside the device model
+ */
+ schedule_work(&smu_expose_childs_work);
+
+ return 0;
+}
+
+static struct of_device_id smu_platform_match[] =
+{
+ {
+ .type = "smu",
+ },
+ {},
+};
+
+static struct of_platform_driver smu_of_platform_driver =
+{
+ .name = "smu",
+ .match_table = smu_platform_match,
+ .probe = smu_platform_probe,
+};
+
+static int __init smu_init_sysfs(void)
+{
+ int rc;
+
+ /*
+ * Due to sysfs bogosity, a sysdev is not a real device, so
+ * we should in fact create both if we want sysdev semantics
+ * for power management.
+ * For now, we don't power manage machines with an SMU chip,
+ * I'm a bit too far from figuring out how that works with those
+ * new chipsets, but that will come back and bite us
+ */
+ rc = of_register_driver(&smu_of_platform_driver);
+ return 0;
+}
+
+device_initcall(smu_init_sysfs);
+
+struct of_device *smu_get_ofdev(void)
+{
+ if (!smu)
+ return NULL;
+ return smu->of_dev;
+}
+
+EXPORT_SYMBOL_GPL(smu_get_ofdev);
+
+/*
+ * i2c interface
+ */
+
+static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail)
+{
+ void (*done)(struct smu_i2c_cmd *cmd, void *misc) = cmd->done;
+ void *misc = cmd->misc;
+ unsigned long flags;
+
+ /* Check for read case */
+ if (!fail && cmd->read) {
+ if (cmd->pdata[0] < 1)
+ fail = 1;
+ else
+ memcpy(cmd->info.data, &cmd->pdata[1],
+ cmd->info.datalen);
+ }
+
+ DPRINTK("SMU: completing, success: %d\n", !fail);
+
+ /* Update status and mark no pending i2c command with lock
+ * held so nobody comes in while we dequeue an eventual
+ * pending next i2c command
+ */
+ spin_lock_irqsave(&smu->lock, flags);
+ smu->cmd_i2c_cur = NULL;
+ wmb();
+ cmd->status = fail ? -EIO : 0;
+
+ /* Is there another i2c command waiting ? */
+ if (!list_empty(&smu->cmd_i2c_list)) {
+ struct smu_i2c_cmd *newcmd;
+
+ /* Fetch it, new current, remove from list */
+ newcmd = list_entry(smu->cmd_i2c_list.next,
+ struct smu_i2c_cmd, link);
+ smu->cmd_i2c_cur = newcmd;
+ list_del(&cmd->link);
+
+ /* Queue with low level smu */
+ list_add_tail(&cmd->scmd.link, &smu->cmd_list);
+ if (smu->cmd_cur == NULL)
+ smu_start_cmd();
+ }
+ spin_unlock_irqrestore(&smu->lock, flags);
+
+ /* Call command completion handler if any */
+ if (done)
+ done(cmd, misc);
+
+}
+
+
+static void smu_i2c_retry(unsigned long data)
+{
+ struct smu_i2c_cmd *cmd = (struct smu_i2c_cmd *)data;
+
+ DPRINTK("SMU: i2c failure, requeuing...\n");
+
+ /* requeue command simply by resetting reply_len */
+ cmd->pdata[0] = 0xff;
+ cmd->scmd.reply_len = 0x10;
+ smu_queue_cmd(&cmd->scmd);
+}
+
+
+static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
+{
+ struct smu_i2c_cmd *cmd = misc;
+ int fail = 0;
+
+ DPRINTK("SMU: i2c compl. stage=%d status=%x pdata[0]=%x rlen: %x\n",
+ cmd->stage, scmd->status, cmd->pdata[0], scmd->reply_len);
+
+ /* Check for possible status */
+ if (scmd->status < 0)
+ fail = 1;
+ else if (cmd->read) {
+ if (cmd->stage == 0)
+ fail = cmd->pdata[0] != 0;
+ else
+ fail = cmd->pdata[0] >= 0x80;
+ } else {
+ fail = cmd->pdata[0] != 0;
+ }
+
+ /* Handle failures by requeuing command, after 5ms interval
+ */
+ if (fail && --cmd->retries > 0) {
+ DPRINTK("SMU: i2c failure, starting timer...\n");
+ smu->i2c_timer.function = smu_i2c_retry;
+ smu->i2c_timer.data = (unsigned long)cmd;
+ smu->i2c_timer.expires = jiffies + msecs_to_jiffies(5);
+ add_timer(&smu->i2c_timer);
+ return;
+ }
+
+ /* If failure or stage 1, command is complete */
+ if (fail || cmd->stage != 0) {
+ smu_i2c_complete_command(cmd, fail);
+ return;
+ }
+
+ DPRINTK("SMU: going to stage 1\n");
+
+ /* Ok, initial command complete, now poll status */
+ scmd->reply_buf = cmd->pdata;
+ scmd->reply_len = 0x10;
+ scmd->data_buf = cmd->pdata;
+ scmd->data_len = 1;
+ cmd->pdata[0] = 0;
+ cmd->stage = 1;
+ cmd->retries = 20;
+ smu_queue_cmd(scmd);
+}
+
+
+int smu_queue_i2c(struct smu_i2c_cmd *cmd)
+{
+ unsigned long flags;
+
+ if (smu == NULL)
+ return -ENODEV;
+
+ /* Fill most fields of scmd */
+ cmd->scmd.cmd = SMU_CMD_I2C_COMMAND;
+ cmd->scmd.done = smu_i2c_low_completion;
+ cmd->scmd.misc = cmd;
+ cmd->scmd.reply_buf = cmd->pdata;
+ cmd->scmd.reply_len = 0x10;
+ cmd->scmd.data_buf = (u8 *)(char *)&cmd->info;
+ cmd->scmd.status = 1;
+ cmd->stage = 0;
+ cmd->pdata[0] = 0xff;
+ cmd->retries = 20;
+ cmd->status = 1;
+
+ /* Check transfer type, sanitize some "info" fields
+ * based on transfer type and do more checking
+ */
+ cmd->info.caddr = cmd->info.devaddr;
+ cmd->read = cmd->info.devaddr & 0x01;
+ switch(cmd->info.type) {
+ case SMU_I2C_TRANSFER_SIMPLE:
+ memset(&cmd->info.sublen, 0, 4);
+ break;
+ case SMU_I2C_TRANSFER_COMBINED:
+ cmd->info.devaddr &= 0xfe;
+ case SMU_I2C_TRANSFER_STDSUB:
+ if (cmd->info.sublen > 3)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Finish setting up command based on transfer direction
+ */
+ if (cmd->read) {
+ if (cmd->info.datalen > SMU_I2C_READ_MAX)
+ return -EINVAL;
+ memset(cmd->info.data, 0xff, cmd->info.datalen);
+ cmd->scmd.data_len = 9;
+ } else {
+ if (cmd->info.datalen > SMU_I2C_WRITE_MAX)
+ return -EINVAL;
+ cmd->scmd.data_len = 9 + cmd->info.datalen;
+ }
+
+ DPRINTK("SMU: i2c enqueuing command\n");
+ DPRINTK("SMU: %s, len=%d bus=%x addr=%x sub0=%x type=%x\n",
+ cmd->read ? "read" : "write", cmd->info.datalen,
+ cmd->info.bus, cmd->info.caddr,
+ cmd->info.subaddr[0], cmd->info.type);
+
+
+ /* Enqueue command in i2c list, and if empty, enqueue also in
+ * main command list
+ */
+ spin_lock_irqsave(&smu->lock, flags);
+ if (smu->cmd_i2c_cur == NULL) {
+ smu->cmd_i2c_cur = cmd;
+ list_add_tail(&cmd->scmd.link, &smu->cmd_list);
+ if (smu->cmd_cur == NULL)
+ smu_start_cmd();
+ } else
+ list_add_tail(&cmd->link, &smu->cmd_i2c_list);
+ spin_unlock_irqrestore(&smu->lock, flags);
+
+ return 0;
+}
+
+
+
+/*
+ * Userland driver interface
+ */
+
+
+static LIST_HEAD(smu_clist);
+static DEFINE_SPINLOCK(smu_clist_lock);
+
+enum smu_file_mode {
+ smu_file_commands,
+ smu_file_events,
+ smu_file_closing
+};
+
+struct smu_private
+{
+ struct list_head list;
+ enum smu_file_mode mode;
+ int busy;
+ struct smu_cmd cmd;
+ spinlock_t lock;
+ wait_queue_head_t wait;
+ u8 buffer[SMU_MAX_DATA];
+};
+
+
+static int smu_open(struct inode *inode, struct file *file)
+{
+ struct smu_private *pp;
+ unsigned long flags;
+
+ pp = kmalloc(sizeof(struct smu_private), GFP_KERNEL);
+ if (pp == 0)
+ return -ENOMEM;
+ memset(pp, 0, sizeof(struct smu_private));
+ spin_lock_init(&pp->lock);
+ pp->mode = smu_file_commands;
+ init_waitqueue_head(&pp->wait);
+
+ spin_lock_irqsave(&smu_clist_lock, flags);
+ list_add(&pp->list, &smu_clist);
+ spin_unlock_irqrestore(&smu_clist_lock, flags);
+ file->private_data = pp;
+
+ return 0;
+}
+
+
+static void smu_user_cmd_done(struct smu_cmd *cmd, void *misc)
+{
+ struct smu_private *pp = misc;
+
+ wake_up_all(&pp->wait);
+}
+
+
+static ssize_t smu_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct smu_private *pp = file->private_data;
+ unsigned long flags;
+ struct smu_user_cmd_hdr hdr;
+ int rc = 0;
+
+ if (pp->busy)
+ return -EBUSY;
+ else if (copy_from_user(&hdr, buf, sizeof(hdr)))
+ return -EFAULT;
+ else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) {
+ pp->mode = smu_file_events;
+ return 0;
+ } else if (hdr.cmdtype != SMU_CMDTYPE_SMU)
+ return -EINVAL;
+ else if (pp->mode != smu_file_commands)
+ return -EBADFD;
+ else if (hdr.data_len > SMU_MAX_DATA)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pp->lock, flags);
+ if (pp->busy) {
+ spin_unlock_irqrestore(&pp->lock, flags);
+ return -EBUSY;
+ }
+ pp->busy = 1;
+ pp->cmd.status = 1;
+ spin_unlock_irqrestore(&pp->lock, flags);
+
+ if (copy_from_user(pp->buffer, buf + sizeof(hdr), hdr.data_len)) {
+ pp->busy = 0;
+ return -EFAULT;
+ }
+
+ pp->cmd.cmd = hdr.cmd;
+ pp->cmd.data_len = hdr.data_len;
+ pp->cmd.reply_len = SMU_MAX_DATA;
+ pp->cmd.data_buf = pp->buffer;
+ pp->cmd.reply_buf = pp->buffer;
+ pp->cmd.done = smu_user_cmd_done;
+ pp->cmd.misc = pp;
+ rc = smu_queue_cmd(&pp->cmd);
+ if (rc < 0)
+ return rc;
+ return count;
+}
+
+
+static ssize_t smu_read_command(struct file *file, struct smu_private *pp,
+ char __user *buf, size_t count)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ struct smu_user_reply_hdr hdr;
+ unsigned long flags;
+ int size, rc = 0;
+
+ if (!pp->busy)
+ return 0;
+ if (count < sizeof(struct smu_user_reply_hdr))
+ return -EOVERFLOW;
+ spin_lock_irqsave(&pp->lock, flags);
+ if (pp->cmd.status == 1) {
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ add_wait_queue(&pp->wait, &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ rc = 0;
+ if (pp->cmd.status != 1)
+ break;
+ rc = -ERESTARTSYS;
+ if (signal_pending(current))
+ break;
+ spin_unlock_irqrestore(&pp->lock, flags);
+ schedule();
+ spin_lock_irqsave(&pp->lock, flags);
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&pp->wait, &wait);
+ }
+ spin_unlock_irqrestore(&pp->lock, flags);
+ if (rc)
+ return rc;
+ if (pp->cmd.status != 0)
+ pp->cmd.reply_len = 0;
+ size = sizeof(hdr) + pp->cmd.reply_len;
+ if (count < size)
+ size = count;
+ rc = size;
+ hdr.status = pp->cmd.status;
+ hdr.reply_len = pp->cmd.reply_len;
+ if (copy_to_user(buf, &hdr, sizeof(hdr)))
+ return -EFAULT;
+ size -= sizeof(hdr);
+ if (size && copy_to_user(buf + sizeof(hdr), pp->buffer, size))
+ return -EFAULT;
+ pp->busy = 0;
+
+ return rc;
+}
+
+
+static ssize_t smu_read_events(struct file *file, struct smu_private *pp,
+ char __user *buf, size_t count)
+{
+ /* Not implemented */
+ msleep_interruptible(1000);
+ return 0;
+}
+
+
+static ssize_t smu_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct smu_private *pp = file->private_data;
+
+ if (pp->mode == smu_file_commands)
+ return smu_read_command(file, pp, buf, count);
+ if (pp->mode == smu_file_events)
+ return smu_read_events(file, pp, buf, count);
+
+ return -EBADFD;
+}
+
+static unsigned int smu_fpoll(struct file *file, poll_table *wait)
+{
+ struct smu_private *pp = file->private_data;
+ unsigned int mask = 0;
+ unsigned long flags;
+
+ if (pp == 0)
+ return 0;
+
+ if (pp->mode == smu_file_commands) {
+ poll_wait(file, &pp->wait, wait);
+
+ spin_lock_irqsave(&pp->lock, flags);
+ if (pp->busy && pp->cmd.status != 1)
+ mask |= POLLIN;
+ spin_unlock_irqrestore(&pp->lock, flags);
+ } if (pp->mode == smu_file_events) {
+ /* Not yet implemented */
+ }
+ return mask;
+}
+
+static int smu_release(struct inode *inode, struct file *file)
+{
+ struct smu_private *pp = file->private_data;
+ unsigned long flags;
+ unsigned int busy;
+
+ if (pp == 0)
+ return 0;
+
+ file->private_data = NULL;
+
+ /* Mark file as closing to avoid races with new request */
+ spin_lock_irqsave(&pp->lock, flags);
+ pp->mode = smu_file_closing;
+ busy = pp->busy;
+
+ /* Wait for any pending request to complete */
+ if (busy && pp->cmd.status == 1) {
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&pp->wait, &wait);
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (pp->cmd.status != 1)
+ break;
+ spin_lock_irqsave(&pp->lock, flags);
+ schedule();
+ spin_unlock_irqrestore(&pp->lock, flags);
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&pp->wait, &wait);
+ }
+ spin_unlock_irqrestore(&pp->lock, flags);
+
+ spin_lock_irqsave(&smu_clist_lock, flags);
+ list_del(&pp->list);
+ spin_unlock_irqrestore(&smu_clist_lock, flags);
+ kfree(pp);
+
+ return 0;
+}
+
+
+static struct file_operations smu_device_fops __pmacdata = {
+ .llseek = no_llseek,
+ .read = smu_read,
+ .write = smu_write,
+ .poll = smu_fpoll,
+ .open = smu_open,
+ .release = smu_release,
+};
+
+static struct miscdevice pmu_device __pmacdata = {
+ MISC_DYNAMIC_MINOR, "smu", &smu_device_fops
+};
+
+static int smu_device_init(void)
+{
+ if (!smu)
+ return -ENODEV;
+ if (misc_register(&pmu_device) < 0)
+ printk(KERN_ERR "via-pmu: cannot register misc device.\n");
+ return 0;
+}
+device_initcall(smu_device_init);
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index c9ca1118e449..f38696622eb4 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -599,7 +599,7 @@ thermostat_init(void)
sensor_location[2] = "?";
}
- of_dev = of_platform_device_create(np, "temperatures");
+ of_dev = of_platform_device_create(np, "temperatures", NULL);
if (of_dev == NULL) {
printk(KERN_ERR "Can't register temperatures device !\n");
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 703e31973314..cc507ceef153 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -2051,7 +2051,7 @@ static int __init therm_pm72_init(void)
return -ENODEV;
}
}
- of_dev = of_platform_device_create(np, "temperature");
+ of_dev = of_platform_device_create(np, "temperature", NULL);
if (of_dev == NULL) {
printk(KERN_ERR "Can't register FCU platform device !\n");
return -ENODEV;
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index cbb72eb0426d..6aaa1df1a64e 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -504,7 +504,7 @@ g4fan_init( void )
}
if( !(np=of_find_node_by_name(NULL, "fan")) )
return -ENODEV;
- x.of_dev = of_platform_device_create( np, "temperature" );
+ x.of_dev = of_platform_device_create(np, "temperature", NULL);
of_node_put( np );
if( !x.of_dev ) {
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 41df4cda66e2..01654fcabc52 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -91,7 +91,7 @@ int bitmap_active(struct bitmap *bitmap)
#define WRITE_POOL_SIZE 256
/* mempool for queueing pending writes on the bitmap file */
-static void *write_pool_alloc(unsigned int gfp_flags, void *data)
+static void *write_pool_alloc(gfp_t gfp_flags, void *data)
{
return kmalloc(sizeof(struct page_list), gfp_flags);
}
@@ -270,19 +270,20 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
if (!page)
return ERR_PTR(-ENOMEM);
- do {
- ITERATE_RDEV(mddev, rdev, tmp)
- if (rdev->in_sync && !rdev->faulty)
- goto found;
- return ERR_PTR(-EIO);
- found:
+ ITERATE_RDEV(mddev, rdev, tmp) {
+ if (! rdev->in_sync || rdev->faulty)
+ continue;
+
target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
- } while (!sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ));
+ if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) {
+ page->index = index;
+ return page;
+ }
+ }
+ return ERR_PTR(-EIO);
- page->index = index;
- return page;
}
static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
@@ -437,6 +438,7 @@ void bitmap_print_sb(struct bitmap *bitmap)
printk(KERN_DEBUG " daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
printk(KERN_DEBUG " sync size: %llu KB\n",
(unsigned long long)le64_to_cpu(sb->sync_size)/2);
+ printk(KERN_DEBUG "max write behind: %d\n", le32_to_cpu(sb->write_behind));
kunmap(bitmap->sb_page);
}
@@ -445,7 +447,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
{
char *reason = NULL;
bitmap_super_t *sb;
- unsigned long chunksize, daemon_sleep;
+ unsigned long chunksize, daemon_sleep, write_behind;
unsigned long bytes_read;
unsigned long long events;
int err = -EINVAL;
@@ -474,6 +476,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
chunksize = le32_to_cpu(sb->chunksize);
daemon_sleep = le32_to_cpu(sb->daemon_sleep);
+ write_behind = le32_to_cpu(sb->write_behind);
/* verify that the bitmap-specific fields are valid */
if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
@@ -485,7 +488,9 @@ static int bitmap_read_sb(struct bitmap *bitmap)
else if ((1 << ffz(~chunksize)) != chunksize)
reason = "bitmap chunksize not a power of 2";
else if (daemon_sleep < 1 || daemon_sleep > 15)
- reason = "daemon sleep period out of range";
+ reason = "daemon sleep period out of range (1-15s)";
+ else if (write_behind > COUNTER_MAX)
+ reason = "write-behind limit out of range (0 - 16383)";
if (reason) {
printk(KERN_INFO "%s: invalid bitmap file superblock: %s\n",
bmname(bitmap), reason);
@@ -518,8 +523,12 @@ success:
/* assign fields using values from superblock */
bitmap->chunksize = chunksize;
bitmap->daemon_sleep = daemon_sleep;
+ bitmap->daemon_lastrun = jiffies;
+ bitmap->max_write_behind = write_behind;
bitmap->flags |= sb->state;
bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
+ if (sb->state & BITMAP_STALE)
+ bitmap->events_cleared = bitmap->mddev->events;
err = 0;
out:
kunmap(bitmap->sb_page);
@@ -617,7 +626,7 @@ static void bitmap_file_unmap(struct bitmap *bitmap)
page_cache_release(sb_page);
}
-static void bitmap_stop_daemons(struct bitmap *bitmap);
+static void bitmap_stop_daemon(struct bitmap *bitmap);
/* dequeue the next item in a page list -- don't call from irq context */
static struct page_list *dequeue_page(struct bitmap *bitmap)
@@ -659,7 +668,7 @@ static void bitmap_file_put(struct bitmap *bitmap)
bitmap->file = NULL;
spin_unlock_irqrestore(&bitmap->lock, flags);
- bitmap_stop_daemons(bitmap);
+ bitmap_stop_daemon(bitmap);
drain_write_queues(bitmap);
@@ -818,7 +827,7 @@ int bitmap_unplug(struct bitmap *bitmap)
return 0;
}
-static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset);
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
* the in-memory bitmap from the on-disk bitmap -- also, sets up the
* memory mapping of the bitmap file
@@ -826,8 +835,11 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset);
* if there's no bitmap file, or if the bitmap file had been
* previously kicked from the array, we mark all the bits as
* 1's in order to cause a full resync.
+ *
+ * We ignore all bits for sectors that end earlier than 'start'.
+ * This is used when reading an out-of-date bitmap...
*/
-static int bitmap_init_from_disk(struct bitmap *bitmap)
+static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
{
unsigned long i, chunks, index, oldindex, bit;
struct page *page = NULL, *oldpage = NULL;
@@ -914,7 +926,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap)
* whole page and write it out
*/
memset(page_address(page) + offset, 0xff,
- PAGE_SIZE - offset);
+ PAGE_SIZE - offset);
ret = write_page(bitmap, page, 1);
if (ret) {
kunmap(page);
@@ -928,8 +940,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap)
}
if (test_bit(bit, page_address(page))) {
/* if the disk bit is set, set the memory bit */
- bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap));
+ bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
+ ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
+ );
bit_cnt++;
+ set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
}
}
@@ -1141,6 +1156,9 @@ static void bitmap_writeback_daemon(mddev_t *mddev)
err = -EINTR;
goto out;
}
+ if (bitmap == NULL)
+ /* about to be stopped. */
+ return;
PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap));
/* wait on bitmap page writebacks */
@@ -1170,21 +1188,12 @@ static void bitmap_writeback_daemon(mddev_t *mddev)
}
}
-static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr,
+static mdk_thread_t *bitmap_start_daemon(struct bitmap *bitmap,
void (*func)(mddev_t *), char *name)
{
mdk_thread_t *daemon;
- unsigned long flags;
char namebuf[32];
- spin_lock_irqsave(&bitmap->lock, flags);
- *ptr = NULL;
-
- if (!bitmap->file) /* no need for daemon if there's no backing file */
- goto out_unlock;
-
- spin_unlock_irqrestore(&bitmap->lock, flags);
-
#ifdef INJECT_FATAL_FAULT_2
daemon = NULL;
#else
@@ -1194,47 +1203,32 @@ static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr,
if (!daemon) {
printk(KERN_ERR "%s: failed to start bitmap daemon\n",
bmname(bitmap));
- return -ECHILD;
+ return ERR_PTR(-ECHILD);
}
- spin_lock_irqsave(&bitmap->lock, flags);
- *ptr = daemon;
-
md_wakeup_thread(daemon); /* start it running */
PRINTK("%s: %s daemon (pid %d) started...\n",
bmname(bitmap), name, daemon->tsk->pid);
-out_unlock:
- spin_unlock_irqrestore(&bitmap->lock, flags);
- return 0;
-}
-static int bitmap_start_daemons(struct bitmap *bitmap)
-{
- int err = bitmap_start_daemon(bitmap, &bitmap->writeback_daemon,
- bitmap_writeback_daemon, "bitmap_wb");
- return err;
+ return daemon;
}
-static void bitmap_stop_daemon(struct bitmap *bitmap, mdk_thread_t **ptr)
+static void bitmap_stop_daemon(struct bitmap *bitmap)
{
- mdk_thread_t *daemon;
- unsigned long flags;
-
- spin_lock_irqsave(&bitmap->lock, flags);
- daemon = *ptr;
- *ptr = NULL;
- spin_unlock_irqrestore(&bitmap->lock, flags);
- if (daemon)
- md_unregister_thread(daemon); /* destroy the thread */
-}
+ /* the daemon can't stop itself... it'll just exit instead... */
+ if (bitmap->writeback_daemon && ! IS_ERR(bitmap->writeback_daemon) &&
+ current->pid != bitmap->writeback_daemon->tsk->pid) {
+ mdk_thread_t *daemon;
+ unsigned long flags;
-static void bitmap_stop_daemons(struct bitmap *bitmap)
-{
- /* the daemons can't stop themselves... they'll just exit instead... */
- if (bitmap->writeback_daemon &&
- current->pid != bitmap->writeback_daemon->tsk->pid)
- bitmap_stop_daemon(bitmap, &bitmap->writeback_daemon);
+ spin_lock_irqsave(&bitmap->lock, flags);
+ daemon = bitmap->writeback_daemon;
+ bitmap->writeback_daemon = NULL;
+ spin_unlock_irqrestore(&bitmap->lock, flags);
+ if (daemon && ! IS_ERR(daemon))
+ md_unregister_thread(daemon); /* destroy the thread */
+ }
}
static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
@@ -1274,9 +1268,16 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
}
}
-int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors)
+int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
{
if (!bitmap) return 0;
+
+ if (behind) {
+ atomic_inc(&bitmap->behind_writes);
+ PRINTK(KERN_DEBUG "inc write-behind count %d/%d\n",
+ atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
+ }
+
while (sectors) {
int blocks;
bitmap_counter_t *bmc;
@@ -1311,9 +1312,15 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
}
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
- int success)
+ int success, int behind)
{
if (!bitmap) return;
+ if (behind) {
+ atomic_dec(&bitmap->behind_writes);
+ PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
+ atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
+ }
+
while (sectors) {
int blocks;
unsigned long flags;
@@ -1424,7 +1431,7 @@ void bitmap_close_sync(struct bitmap *bitmap)
}
}
-static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
{
/* For each chunk covered by any of these sectors, set the
* counter to 1 and set resync_needed. They should all
@@ -1441,7 +1448,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
}
if (! *bmc) {
struct page *page;
- *bmc = 1 | NEEDED_MASK;
+ *bmc = 1 | (needed?NEEDED_MASK:0);
bitmap_count_page(bitmap, offset, 1);
page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
@@ -1476,17 +1483,14 @@ void bitmap_flush(mddev_t *mddev)
/*
* free memory that was allocated
*/
-void bitmap_destroy(mddev_t *mddev)
+static void bitmap_free(struct bitmap *bitmap)
{
unsigned long k, pages;
struct bitmap_page *bp;
- struct bitmap *bitmap = mddev->bitmap;
if (!bitmap) /* there was no bitmap */
return;
- mddev->bitmap = NULL; /* disconnect from the md device */
-
/* release the bitmap file and kill the daemon */
bitmap_file_put(bitmap);
@@ -1504,6 +1508,17 @@ void bitmap_destroy(mddev_t *mddev)
kfree(bp);
kfree(bitmap);
}
+void bitmap_destroy(mddev_t *mddev)
+{
+ struct bitmap *bitmap = mddev->bitmap;
+
+ if (!bitmap) /* there was no bitmap */
+ return;
+
+ mddev->bitmap = NULL; /* disconnect from the md device */
+
+ bitmap_free(bitmap);
+}
/*
* initialize the bitmap structure
@@ -1517,6 +1532,7 @@ int bitmap_create(mddev_t *mddev)
unsigned long pages;
struct file *file = mddev->bitmap_file;
int err;
+ sector_t start;
BUG_ON(sizeof(bitmap_super_t) != 256);
@@ -1533,15 +1549,15 @@ int bitmap_create(mddev_t *mddev)
spin_lock_init(&bitmap->lock);
bitmap->mddev = mddev;
- mddev->bitmap = bitmap;
spin_lock_init(&bitmap->write_lock);
INIT_LIST_HEAD(&bitmap->complete_pages);
init_waitqueue_head(&bitmap->write_wait);
bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc,
write_pool_free, NULL);
+ err = -ENOMEM;
if (!bitmap->write_pool)
- return -ENOMEM;
+ goto error;
bitmap->file = file;
bitmap->offset = mddev->bitmap_offset;
@@ -1549,7 +1565,7 @@ int bitmap_create(mddev_t *mddev)
/* read superblock from bitmap file (this sets bitmap->chunksize) */
err = bitmap_read_sb(bitmap);
if (err)
- return err;
+ goto error;
bitmap->chunkshift = find_first_bit(&bitmap->chunksize,
sizeof(bitmap->chunksize));
@@ -1573,27 +1589,44 @@ int bitmap_create(mddev_t *mddev)
#else
bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
#endif
+ err = -ENOMEM;
if (!bitmap->bp)
- return -ENOMEM;
+ goto error;
memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp));
bitmap->flags |= BITMAP_ACTIVE;
/* now that we have some pages available, initialize the in-memory
* bitmap from the on-disk bitmap */
- err = bitmap_init_from_disk(bitmap);
+ start = 0;
+ if (mddev->degraded == 0
+ || bitmap->events_cleared == mddev->events)
+ /* no need to keep dirty bits to optimise a re-add of a missing device */
+ start = mddev->recovery_cp;
+ err = bitmap_init_from_disk(bitmap, start);
if (err)
- return err;
+ goto error;
printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
pages, bmname(bitmap));
- /* kick off the bitmap daemons */
- err = bitmap_start_daemons(bitmap);
- if (err)
- return err;
+ mddev->bitmap = bitmap;
+
+ if (file)
+ /* kick off the bitmap writeback daemon */
+ bitmap->writeback_daemon =
+ bitmap_start_daemon(bitmap,
+ bitmap_writeback_daemon,
+ "bitmap_wb");
+
+ if (IS_ERR(bitmap->writeback_daemon))
+ return PTR_ERR(bitmap->writeback_daemon);
return bitmap_update_sb(bitmap);
+
+ error:
+ bitmap_free(bitmap);
+ return err;
}
/* the bitmap API -- for raid personalities */
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index b82bc3150476..28c1a628621f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -96,7 +96,7 @@ static kmem_cache_t *_crypt_io_pool;
/*
* Mempool alloc and free functions for the page
*/
-static void *mempool_alloc_page(unsigned int __nocast gfp_mask, void *data)
+static void *mempool_alloc_page(gfp_t gfp_mask, void *data)
{
return alloc_page(gfp_mask);
}
@@ -331,7 +331,7 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
{
struct bio *bio;
unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
+ gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
unsigned int i;
/*
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index 17212b4201a1..cc07bbebbb16 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -568,12 +568,9 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
bad:
dm_io_put(sectors_to_pages(chunk_size));
- if (ps) {
- if (ps->area)
- free_area(ps);
-
- kfree(ps);
- }
+ if (ps && ps->area)
+ free_area(ps);
+ kfree(ps);
return r;
}
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 9de000131a8a..4809b209fbb1 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -32,7 +32,7 @@ struct io {
static unsigned _num_ios;
static mempool_t *_io_pool;
-static void *alloc_io(unsigned int __nocast gfp_mask, void *pool_data)
+static void *alloc_io(gfp_t gfp_mask, void *pool_data)
{
return kmalloc(sizeof(struct io), gfp_mask);
}
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 200a0688f717..54ec737195e0 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -230,11 +230,20 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi
static void __hash_remove(struct hash_cell *hc)
{
+ struct dm_table *table;
+
/* remove from the dev hash */
list_del(&hc->uuid_list);
list_del(&hc->name_list);
unregister_with_devfs(hc);
dm_set_mdptr(hc->md, NULL);
+
+ table = dm_get_table(hc->md);
+ if (table) {
+ dm_table_event(table);
+ dm_table_put(table);
+ }
+
dm_put(hc->md);
if (hc->new_map)
dm_table_put(hc->new_map);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 785806bdb248..f9b7b32d5d5c 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -329,13 +329,17 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
/*
* If we run out of usable paths, should we queue I/O or error it?
*/
-static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
+static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path,
+ unsigned save_old_value)
{
unsigned long flags;
spin_lock_irqsave(&m->lock, flags);
- m->saved_queue_if_no_path = m->queue_if_no_path;
+ if (save_old_value)
+ m->saved_queue_if_no_path = m->queue_if_no_path;
+ else
+ m->saved_queue_if_no_path = queue_if_no_path;
m->queue_if_no_path = queue_if_no_path;
if (!m->queue_if_no_path && m->queue_size)
queue_work(kmultipathd, &m->process_queued_ios);
@@ -677,7 +681,7 @@ static int parse_features(struct arg_set *as, struct multipath *m,
return 0;
if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
- return queue_if_no_path(m, 1);
+ return queue_if_no_path(m, 1, 0);
else {
ti->error = "Unrecognised multipath feature request";
return -EINVAL;
@@ -1077,7 +1081,7 @@ static void multipath_presuspend(struct dm_target *ti)
{
struct multipath *m = (struct multipath *) ti->private;
- queue_if_no_path(m, 0);
+ queue_if_no_path(m, 0, 1);
}
/*
@@ -1222,9 +1226,9 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
if (argc == 1) {
if (!strnicmp(argv[0], MESG_STR("queue_if_no_path")))
- return queue_if_no_path(m, 1);
+ return queue_if_no_path(m, 1, 0);
else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path")))
- return queue_if_no_path(m, 0);
+ return queue_if_no_path(m, 0, 0);
}
if (argc != 2)
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index b08df8b9b2ca..2375709a392c 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -122,7 +122,7 @@ static inline sector_t region_to_sector(struct region_hash *rh, region_t region)
/* FIXME move this */
static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw);
-static void *region_alloc(unsigned int __nocast gfp_mask, void *pool_data)
+static void *region_alloc(gfp_t gfp_mask, void *pool_data)
{
return kmalloc(sizeof(struct region), gfp_mask);
}
@@ -375,16 +375,18 @@ static void rh_inc(struct region_hash *rh, region_t region)
read_lock(&rh->hash_lock);
reg = __rh_find(rh, region);
+
+ atomic_inc(&reg->pending);
+
+ spin_lock_irq(&rh->region_lock);
if (reg->state == RH_CLEAN) {
rh->log->type->mark_region(rh->log, reg->key);
- spin_lock_irq(&rh->region_lock);
reg->state = RH_DIRTY;
list_del_init(&reg->list); /* take off the clean list */
- spin_unlock_irq(&rh->region_lock);
}
+ spin_unlock_irq(&rh->region_lock);
- atomic_inc(&reg->pending);
read_unlock(&rh->hash_lock);
}
@@ -408,6 +410,10 @@ static void rh_dec(struct region_hash *rh, region_t region)
if (atomic_dec_and_test(&reg->pending)) {
spin_lock_irqsave(&rh->region_lock, flags);
+ if (atomic_read(&reg->pending)) { /* check race */
+ spin_unlock_irqrestore(&rh->region_lock, flags);
+ return;
+ }
if (reg->state == RH_RECOVERING) {
list_add_tail(&reg->list, &rh->quiesced_regions);
} else {
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 8d740013d74d..bb279fad2fd2 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -38,7 +38,8 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
/*
* sector_div(a,b) returns the remainer and sets a to a/b
*/
- (void)sector_div(block, conf->smallest->size);
+ block >>= conf->preshift;
+ (void)sector_div(block, conf->hash_spacing);
hash = conf->hash_table[block];
while ((sector>>1) >= (hash->size + hash->offset))
@@ -47,7 +48,7 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
}
/**
- * linear_mergeable_bvec -- tell bio layer if a two requests can be merged
+ * linear_mergeable_bvec -- tell bio layer if two requests can be merged
* @q: request queue
* @bio: the buffer head that's been built up so far
* @biovec: the request that could be merged to it.
@@ -116,7 +117,7 @@ static int linear_run (mddev_t *mddev)
dev_info_t **table;
mdk_rdev_t *rdev;
int i, nb_zone, cnt;
- sector_t start;
+ sector_t min_spacing;
sector_t curr_offset;
struct list_head *tmp;
@@ -127,11 +128,6 @@ static int linear_run (mddev_t *mddev)
memset(conf, 0, sizeof(*conf) + mddev->raid_disks*sizeof(dev_info_t));
mddev->private = conf;
- /*
- * Find the smallest device.
- */
-
- conf->smallest = NULL;
cnt = 0;
mddev->array_size = 0;
@@ -159,8 +155,6 @@ static int linear_run (mddev_t *mddev)
disk->size = rdev->size;
mddev->array_size += rdev->size;
- if (!conf->smallest || (disk->size < conf->smallest->size))
- conf->smallest = disk;
cnt++;
}
if (cnt != mddev->raid_disks) {
@@ -168,6 +162,36 @@ static int linear_run (mddev_t *mddev)
goto out;
}
+ min_spacing = mddev->array_size;
+ sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
+
+ /* min_spacing is the minimum spacing that will fit the hash
+ * table in one PAGE. This may be much smaller than needed.
+ * We find the smallest non-terminal set of consecutive devices
+ * that is larger than min_spacing as use the size of that as
+ * the actual spacing
+ */
+ conf->hash_spacing = mddev->array_size;
+ for (i=0; i < cnt-1 ; i++) {
+ sector_t sz = 0;
+ int j;
+ for (j=i; i<cnt-1 && sz < min_spacing ; j++)
+ sz += conf->disks[j].size;
+ if (sz >= min_spacing && sz < conf->hash_spacing)
+ conf->hash_spacing = sz;
+ }
+
+ /* hash_spacing may be too large for sector_div to work with,
+ * so we might need to pre-shift
+ */
+ conf->preshift = 0;
+ if (sizeof(sector_t) > sizeof(u32)) {
+ sector_t space = conf->hash_spacing;
+ while (space > (sector_t)(~(u32)0)) {
+ space >>= 1;
+ conf->preshift++;
+ }
+ }
/*
* This code was restructured to work around a gcc-2.95.3 internal
* compiler error. Alter it with care.
@@ -177,39 +201,52 @@ static int linear_run (mddev_t *mddev)
unsigned round;
unsigned long base;
- sz = mddev->array_size;
- base = conf->smallest->size;
+ sz = mddev->array_size >> conf->preshift;
+ sz += 1; /* force round-up */
+ base = conf->hash_spacing >> conf->preshift;
round = sector_div(sz, base);
- nb_zone = conf->nr_zones = sz + (round ? 1 : 0);
+ nb_zone = sz + (round ? 1 : 0);
}
-
- conf->hash_table = kmalloc (sizeof (dev_info_t*) * nb_zone,
+ BUG_ON(nb_zone > PAGE_SIZE / sizeof(struct dev_info *));
+
+ conf->hash_table = kmalloc (sizeof (struct dev_info *) * nb_zone,
GFP_KERNEL);
if (!conf->hash_table)
goto out;
/*
* Here we generate the linear hash table
+ * First calculate the device offsets.
*/
+ conf->disks[0].offset = 0;
+ for (i=1; i<mddev->raid_disks; i++)
+ conf->disks[i].offset =
+ conf->disks[i-1].offset +
+ conf->disks[i-1].size;
+
table = conf->hash_table;
- start = 0;
curr_offset = 0;
- for (i = 0; i < cnt; i++) {
- dev_info_t *disk = conf->disks + i;
+ i = 0;
+ for (curr_offset = 0;
+ curr_offset < mddev->array_size;
+ curr_offset += conf->hash_spacing) {
- disk->offset = curr_offset;
- curr_offset += disk->size;
+ while (i < mddev->raid_disks-1 &&
+ curr_offset >= conf->disks[i+1].offset)
+ i++;
- /* 'curr_offset' is the end of this disk
- * 'start' is the start of table
+ *table ++ = conf->disks + i;
+ }
+
+ if (conf->preshift) {
+ conf->hash_spacing >>= conf->preshift;
+ /* round hash_spacing up so that when we divide by it,
+ * we err on the side of "too-low", which is safest.
*/
- while (start < curr_offset) {
- *table++ = disk;
- start += conf->smallest->size;
- }
+ conf->hash_spacing++;
}
- if (table-conf->hash_table != nb_zone)
- BUG();
+
+ BUG_ON(table - conf->hash_table > nb_zone);
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
@@ -238,6 +275,11 @@ static int linear_make_request (request_queue_t *q, struct bio *bio)
dev_info_t *tmp_dev;
sector_t block;
+ if (unlikely(bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
if (bio_data_dir(bio)==WRITE) {
disk_stat_inc(mddev->gendisk, writes);
disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
@@ -294,7 +336,7 @@ static void linear_status (struct seq_file *seq, mddev_t *mddev)
sector_t s = 0;
seq_printf(seq, " ");
- for (j = 0; j < conf->nr_zones; j++)
+ for (j = 0; j < mddev->raid_disks; j++)
{
char b[BDEVNAME_SIZE];
s += conf->smallest_size;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 20ca80b7dc20..2a8a5696bf8a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/config.h>
+#include <linux/kthread.h>
#include <linux/linkage.h>
#include <linux/raid/md.h>
#include <linux/raid/bitmap.h>
@@ -73,7 +74,7 @@ static DEFINE_SPINLOCK(pers_lock);
* Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
* is 1000 KB/sec, so the extra system load does not show up that much.
* Increase it if you want to have more _guaranteed_ speed. Note that
- * the RAID driver will use the maximum available bandwith if the IO
+ * the RAID driver will use the maximum available bandwidth if the IO
* subsystem is idle. There is also an 'absolute maximum' reconstruction
* speed limit - in case reconstruction slows down your system despite
* idle IO detection.
@@ -393,7 +394,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size,
return ret;
}
-static int read_disk_sb(mdk_rdev_t * rdev)
+static int read_disk_sb(mdk_rdev_t * rdev, int size)
{
char b[BDEVNAME_SIZE];
if (!rdev->sb_page) {
@@ -404,7 +405,7 @@ static int read_disk_sb(mdk_rdev_t * rdev)
return 0;
- if (!sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, READ))
+ if (!sync_page_io(rdev->bdev, rdev->sb_offset<<1, size, rdev->sb_page, READ))
goto fail;
rdev->sb_loaded = 1;
return 0;
@@ -531,7 +532,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
sb_offset = calc_dev_sboffset(rdev->bdev);
rdev->sb_offset = sb_offset;
- ret = read_disk_sb(rdev);
+ ret = read_disk_sb(rdev, MD_SB_BYTES);
if (ret) return ret;
ret = -EINVAL;
@@ -564,6 +565,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
rdev->preferred_minor = sb->md_minor;
rdev->data_offset = 0;
+ rdev->sb_size = MD_SB_BYTES;
if (sb->level == LEVEL_MULTIPATH)
rdev->desc_nr = -1;
@@ -623,6 +625,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->size = sb->size;
mddev->events = md_event(sb);
mddev->bitmap_offset = 0;
+ mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
if (sb->state & (1<<MD_SB_CLEAN))
mddev->recovery_cp = MaxSector;
@@ -643,12 +646,12 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
mddev->bitmap_file == NULL) {
- if (mddev->level != 1) {
+ if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6) {
/* FIXME use a better test */
printk(KERN_WARNING "md: bitmaps only support for raid1\n");
return -EINVAL;
}
- mddev->bitmap_offset = (MD_SB_BYTES >> 9);
+ mddev->bitmap_offset = mddev->default_bitmap_offset;
}
} else if (mddev->pers == NULL) {
@@ -669,6 +672,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
if (mddev->level != LEVEL_MULTIPATH) {
rdev->faulty = 0;
+ rdev->flags = 0;
desc = sb->disks + rdev->desc_nr;
if (desc->state & (1<<MD_DISK_FAULTY))
@@ -678,6 +682,8 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
rdev->in_sync = 1;
rdev->raid_disk = desc->raid_disk;
}
+ if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
+ set_bit(WriteMostly, &rdev->flags);
} else /* MULTIPATH are always insync */
rdev->in_sync = 1;
return 0;
@@ -706,6 +712,8 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
int i;
int active=0, working=0,failed=0,spare=0,nr_disks=0;
+ rdev->sb_size = MD_SB_BYTES;
+
sb = (mdp_super_t*)page_address(rdev->sb_page);
memset(sb, 0, sizeof(*sb));
@@ -776,6 +784,8 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
spare++;
working++;
}
+ if (test_bit(WriteMostly, &rdev2->flags))
+ d->state |= (1<<MD_DISK_WRITEMOSTLY);
}
/* now set the "removed" and "faulty" bits on any missing devices */
@@ -831,6 +841,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
int ret;
sector_t sb_offset;
char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+ int bmask;
/*
* Calculate the position of the superblock.
@@ -859,7 +870,10 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
}
rdev->sb_offset = sb_offset;
- ret = read_disk_sb(rdev);
+ /* superblock is rarely larger than 1K, but it can be larger,
+ * and it is safe to read 4k, so we do that
+ */
+ ret = read_disk_sb(rdev, 4096);
if (ret) return ret;
@@ -869,7 +883,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
sb->major_version != cpu_to_le32(1) ||
le32_to_cpu(sb->max_dev) > (4096-256)/2 ||
le64_to_cpu(sb->super_offset) != (rdev->sb_offset<<1) ||
- sb->feature_map != 0)
+ (le32_to_cpu(sb->feature_map) & ~MD_FEATURE_ALL) != 0)
return -EINVAL;
if (calc_sb_1_csum(sb) != sb->sb_csum) {
@@ -885,6 +899,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
rdev->preferred_minor = 0xffff;
rdev->data_offset = le64_to_cpu(sb->data_offset);
+ rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
+ bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
+ if (rdev->sb_size & bmask)
+ rdev-> sb_size = (rdev->sb_size | bmask)+1;
+
if (refdev == 0)
return 1;
else {
@@ -939,13 +958,15 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->size = le64_to_cpu(sb->size)/2;
mddev->events = le64_to_cpu(sb->events);
mddev->bitmap_offset = 0;
+ mddev->default_bitmap_offset = 0;
+ mddev->default_bitmap_offset = 1024;
mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
memcpy(mddev->uuid, sb->set_uuid, 16);
mddev->max_disks = (4096-256)/2;
- if ((le32_to_cpu(sb->feature_map) & 1) &&
+ if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) &&
mddev->bitmap_file == NULL ) {
if (mddev->level != 1) {
printk(KERN_WARNING "md: bitmaps only supported for raid1\n");
@@ -986,6 +1007,9 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
rdev->raid_disk = role;
break;
}
+ rdev->flags = 0;
+ if (sb->devflags & WriteMostly1)
+ set_bit(WriteMostly, &rdev->flags);
} else /* MULTIPATH are always insync */
rdev->in_sync = 1;
@@ -1017,7 +1041,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
if (mddev->bitmap && mddev->bitmap_file == NULL) {
sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
- sb->feature_map = cpu_to_le32(1);
+ sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
}
max_dev = 0;
@@ -1363,7 +1387,7 @@ repeat:
dprintk("%s ", bdevname(rdev->bdev,b));
if (!rdev->faulty) {
md_super_write(mddev,rdev,
- rdev->sb_offset<<1, MD_SB_BYTES,
+ rdev->sb_offset<<1, rdev->sb_size,
rdev->sb_page);
dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
bdevname(rdev->bdev,b),
@@ -2073,6 +2097,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
info.state = 0;
if (mddev->in_sync)
info.state = (1<<MD_SB_CLEAN);
+ if (mddev->bitmap && mddev->bitmap_offset)
+ info.state = (1<<MD_SB_BITMAP_PRESENT);
info.active_disks = active;
info.working_disks = working;
info.failed_disks = failed;
@@ -2087,7 +2113,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;
@@ -2146,6 +2172,8 @@ static int get_disk_info(mddev_t * mddev, void __user * arg)
info.state |= (1<<MD_DISK_ACTIVE);
info.state |= (1<<MD_DISK_SYNC);
}
+ if (test_bit(WriteMostly, &rdev->flags))
+ info.state |= (1<<MD_DISK_WRITEMOSTLY);
} else {
info.major = info.minor = 0;
info.raid_disk = -1;
@@ -2210,8 +2238,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
mdname(mddev));
return -EINVAL;
}
- rdev = md_import_device(dev, mddev->major_version,
- mddev->minor_version);
+ if (mddev->persistent)
+ rdev = md_import_device(dev, mddev->major_version,
+ mddev->minor_version);
+ else
+ rdev = md_import_device(dev, -1, -1);
if (IS_ERR(rdev)) {
printk(KERN_WARNING
"md: md_import_device returned %ld\n",
@@ -2231,6 +2262,9 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
rdev->saved_raid_disk = rdev->raid_disk;
rdev->in_sync = 0; /* just to be sure */
+ if (info->state & (1<<MD_DISK_WRITEMOSTLY))
+ set_bit(WriteMostly, &rdev->flags);
+
rdev->raid_disk = -1;
err = bind_rdev_to_array(rdev, mddev);
if (err)
@@ -2271,6 +2305,9 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
else
rdev->in_sync = 0;
+ if (info->state & (1<<MD_DISK_WRITEMOSTLY))
+ set_bit(WriteMostly, &rdev->flags);
+
err = bind_rdev_to_array(rdev, mddev);
if (err) {
export_rdev(rdev);
@@ -2430,25 +2467,51 @@ static int set_bitmap_file(mddev_t *mddev, int fd)
{
int err;
- if (mddev->pers)
- return -EBUSY;
+ if (mddev->pers) {
+ if (!mddev->pers->quiesce)
+ return -EBUSY;
+ if (mddev->recovery || mddev->sync_thread)
+ return -EBUSY;
+ /* we should be able to change the bitmap.. */
+ }
- mddev->bitmap_file = fget(fd);
- if (mddev->bitmap_file == NULL) {
- printk(KERN_ERR "%s: error: failed to get bitmap file\n",
- mdname(mddev));
- return -EBADF;
- }
+ if (fd >= 0) {
+ if (mddev->bitmap)
+ return -EEXIST; /* cannot add when bitmap is present */
+ mddev->bitmap_file = fget(fd);
- err = deny_bitmap_write_access(mddev->bitmap_file);
- if (err) {
- printk(KERN_ERR "%s: error: bitmap file is already in use\n",
- mdname(mddev));
- fput(mddev->bitmap_file);
- mddev->bitmap_file = NULL;
- } else
+ if (mddev->bitmap_file == NULL) {
+ printk(KERN_ERR "%s: error: failed to get bitmap file\n",
+ mdname(mddev));
+ return -EBADF;
+ }
+
+ err = deny_bitmap_write_access(mddev->bitmap_file);
+ if (err) {
+ printk(KERN_ERR "%s: error: bitmap file is already in use\n",
+ mdname(mddev));
+ fput(mddev->bitmap_file);
+ mddev->bitmap_file = NULL;
+ return err;
+ }
mddev->bitmap_offset = 0; /* file overrides offset */
+ } else if (mddev->bitmap == NULL)
+ return -ENOENT; /* cannot remove what isn't there */
+ err = 0;
+ if (mddev->pers) {
+ mddev->pers->quiesce(mddev, 1);
+ if (fd >= 0)
+ err = bitmap_create(mddev);
+ if (fd < 0 || err)
+ bitmap_destroy(mddev);
+ mddev->pers->quiesce(mddev, 0);
+ } else if (fd < 0) {
+ if (mddev->bitmap_file)
+ fput(mddev->bitmap_file);
+ mddev->bitmap_file = NULL;
+ }
+
return err;
}
@@ -2528,6 +2591,11 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
{
int rv = 0;
int cnt = 0;
+ int state = 0;
+
+ /* calculate expected state,ignoring low bits */
+ if (mddev->bitmap && mddev->bitmap_offset)
+ state |= (1 << MD_SB_BITMAP_PRESENT);
if (mddev->major_version != info->major_version ||
mddev->minor_version != info->minor_version ||
@@ -2536,12 +2604,16 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
mddev->level != info->level ||
/* mddev->layout != info->layout || */
!mddev->persistent != info->not_persistent||
- mddev->chunk_size != info->chunk_size )
+ mddev->chunk_size != info->chunk_size ||
+ /* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */
+ ((state^info->state) & 0xfffffe00)
+ )
return -EINVAL;
/* Check there is only one change */
if (mddev->size != info->size) cnt++;
if (mddev->raid_disks != info->raid_disks) cnt++;
if (mddev->layout != info->layout) cnt++;
+ if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
if (cnt == 0) return 0;
if (cnt > 1) return -EINVAL;
@@ -2620,6 +2692,35 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
}
}
}
+ if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) {
+ if (mddev->pers->quiesce == NULL)
+ return -EINVAL;
+ if (mddev->recovery || mddev->sync_thread)
+ return -EBUSY;
+ if (info->state & (1<<MD_SB_BITMAP_PRESENT)) {
+ /* add the bitmap */
+ if (mddev->bitmap)
+ return -EEXIST;
+ if (mddev->default_bitmap_offset == 0)
+ return -EINVAL;
+ mddev->bitmap_offset = mddev->default_bitmap_offset;
+ mddev->pers->quiesce(mddev, 1);
+ rv = bitmap_create(mddev);
+ if (rv)
+ bitmap_destroy(mddev);
+ mddev->pers->quiesce(mddev, 0);
+ } else {
+ /* remove the bitmap */
+ if (!mddev->bitmap)
+ return -ENOENT;
+ if (mddev->bitmap->file)
+ return -EINVAL;
+ mddev->pers->quiesce(mddev, 1);
+ bitmap_destroy(mddev);
+ mddev->pers->quiesce(mddev, 0);
+ mddev->bitmap_offset = 0;
+ }
+ }
md_update_sb(mddev);
return rv;
}
@@ -2781,7 +2882,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:
@@ -2950,18 +3051,6 @@ static int md_thread(void * arg)
{
mdk_thread_t *thread = arg;
- lock_kernel();
-
- /*
- * Detach thread
- */
-
- daemonize(thread->name, mdname(thread->mddev));
-
- current->exit_signal = SIGCHLD;
- allow_signal(SIGKILL);
- thread->tsk = current;
-
/*
* md_thread is a 'system-thread', it's priority should be very
* high. We avoid resource deadlocks individually in each
@@ -2973,14 +3062,15 @@ static int md_thread(void * arg)
* bdflush, otherwise bdflush will deadlock if there are too
* many dirty RAID5 blocks.
*/
- unlock_kernel();
+ allow_signal(SIGKILL);
complete(thread->event);
- while (thread->run) {
+ while (!kthread_should_stop()) {
void (*run)(mddev_t *);
wait_event_interruptible_timeout(thread->wqueue,
- test_bit(THREAD_WAKEUP, &thread->flags),
+ test_bit(THREAD_WAKEUP, &thread->flags)
+ || kthread_should_stop(),
thread->timeout);
try_to_freeze();
@@ -2989,11 +3079,8 @@ static int md_thread(void * arg)
run = thread->run;
if (run)
run(thread->mddev);
-
- if (signal_pending(current))
- flush_signals(current);
}
- complete(thread->event);
+
return 0;
}
@@ -3010,11 +3097,9 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
const char *name)
{
mdk_thread_t *thread;
- int ret;
struct completion event;
- thread = (mdk_thread_t *) kmalloc
- (sizeof(mdk_thread_t), GFP_KERNEL);
+ thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
if (!thread)
return NULL;
@@ -3027,8 +3112,8 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
thread->mddev = mddev;
thread->name = name;
thread->timeout = MAX_SCHEDULE_TIMEOUT;
- ret = kernel_thread(md_thread, thread, 0);
- if (ret < 0) {
+ thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev));
+ if (IS_ERR(thread->tsk)) {
kfree(thread);
return NULL;
}
@@ -3038,21 +3123,9 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
void md_unregister_thread(mdk_thread_t *thread)
{
- struct completion event;
-
- init_completion(&event);
-
- thread->event = &event;
-
- /* As soon as ->run is set to NULL, the task could disappear,
- * so we need to hold tasklist_lock until we have sent the signal
- */
dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
- read_lock(&tasklist_lock);
- thread->run = NULL;
- send_sig(SIGKILL, thread->tsk, 1);
- read_unlock(&tasklist_lock);
- wait_for_completion(&event);
+
+ kthread_stop(thread->tsk);
kfree(thread);
}
@@ -3259,10 +3332,13 @@ static int md_seq_show(struct seq_file *seq, void *v)
char b[BDEVNAME_SIZE];
seq_printf(seq, " %s[%d]",
bdevname(rdev->bdev,b), rdev->desc_nr);
+ if (test_bit(WriteMostly, &rdev->flags))
+ seq_printf(seq, "(W)");
if (rdev->faulty) {
seq_printf(seq, "(F)");
continue;
- }
+ } else if (rdev->raid_disk < 0)
+ seq_printf(seq, "(S)"); /* spare */
size += rdev->size;
}
@@ -3274,6 +3350,15 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "\n %llu blocks",
(unsigned long long)size);
}
+ if (mddev->persistent) {
+ if (mddev->major_version != 0 ||
+ mddev->minor_version != 90) {
+ seq_printf(seq," super %d.%d",
+ mddev->major_version,
+ mddev->minor_version);
+ }
+ } else
+ seq_printf(seq, " super non-persistent");
if (mddev->pers) {
mddev->pers->status (seq, mddev);
@@ -3416,7 +3501,6 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok)
*/
void md_write_start(mddev_t *mddev, struct bio *bi)
{
- DEFINE_WAIT(w);
if (bio_data_dir(bi) != WRITE)
return;
@@ -3484,8 +3568,10 @@ static void md_do_sync(mddev_t *mddev)
mddev->curr_resync = 2;
try_again:
- if (signal_pending(current)) {
+ if (signal_pending(current) ||
+ kthread_should_stop()) {
flush_signals(current);
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
goto skip;
}
ITERATE_MDDEV(mddev2,tmp) {
@@ -3505,8 +3591,9 @@ static void md_do_sync(mddev_t *mddev)
*/
continue;
prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE);
- if (!signal_pending(current)
- && mddev2->curr_resync >= mddev->curr_resync) {
+ if (!signal_pending(current) &&
+ !kthread_should_stop() &&
+ mddev2->curr_resync >= mddev->curr_resync) {
printk(KERN_INFO "md: delaying resync of %s"
" until %s has finished resync (they"
" share one or more physical units)\n",
@@ -3533,7 +3620,7 @@ static void md_do_sync(mddev_t *mddev)
printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev));
printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:"
" %d KB/sec/disc.\n", sysctl_speed_limit_min);
- printk(KERN_INFO "md: using maximum available idle IO bandwith "
+ printk(KERN_INFO "md: using maximum available idle IO bandwidth "
"(but not more than %d KB/sec) for reconstruction.\n",
sysctl_speed_limit_max);
@@ -3612,7 +3699,7 @@ static void md_do_sync(mddev_t *mddev)
}
- if (signal_pending(current)) {
+ if (signal_pending(current) || kthread_should_stop()) {
/*
* got a signal, exit.
*/
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 2d2ca7fa0265..1151c3ed3006 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -38,7 +38,7 @@
static mdk_personality_t multipath_personality;
-static void *mp_pool_alloc(unsigned int __nocast gfp_flags, void *data)
+static void *mp_pool_alloc(gfp_t gfp_flags, void *data)
{
struct multipath_bh *mpb;
mpb = kmalloc(sizeof(*mpb), gfp_flags);
@@ -169,6 +169,11 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
struct multipath_bh * mp_bh;
struct multipath_info *multipath;
+ if (unlikely(bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
mp_bh = mempool_alloc(conf->pool, GFP_NOIO);
mp_bh->master_bio = bio;
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 2120710172c5..f6757259ce7f 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -404,6 +404,11 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
unsigned long chunk;
sector_t block, rsect;
+ if (unlikely(bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
if (bio_data_dir(bio)==WRITE) {
disk_stat_inc(mddev->gendisk, writes);
disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 51d9645ed09c..0e1f148dd41d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -52,7 +52,7 @@ static mdk_personality_t raid1_personality;
static void unplug_slaves(mddev_t *mddev);
-static void * r1bio_pool_alloc(unsigned int __nocast gfp_flags, void *data)
+static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
{
struct pool_info *pi = data;
r1bio_t *r1_bio;
@@ -79,7 +79,7 @@ static void r1bio_pool_free(void *r1_bio, void *data)
#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
#define RESYNC_WINDOW (2048*1024)
-static void * r1buf_pool_alloc(unsigned int __nocast gfp_flags, void *data)
+static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
{
struct pool_info *pi = data;
struct page *page;
@@ -222,8 +222,17 @@ static void raid_end_bio_io(r1bio_t *r1_bio)
{
struct bio *bio = r1_bio->master_bio;
- bio_endio(bio, bio->bi_size,
- test_bit(R1BIO_Uptodate, &r1_bio->state) ? 0 : -EIO);
+ /* if nobody has done the final endio yet, do it now */
+ if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
+ PRINTK(KERN_DEBUG "raid1: sync end %s on sectors %llu-%llu\n",
+ (bio_data_dir(bio) == WRITE) ? "write" : "read",
+ (unsigned long long) bio->bi_sector,
+ (unsigned long long) bio->bi_sector +
+ (bio->bi_size >> 9) - 1);
+
+ bio_endio(bio, bio->bi_size,
+ test_bit(R1BIO_Uptodate, &r1_bio->state) ? 0 : -EIO);
+ }
free_r1bio(r1_bio);
}
@@ -292,7 +301,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
- int mirror;
+ int mirror, behind;
conf_t *conf = mddev_to_conf(r1_bio->mddev);
if (bio->bi_size)
@@ -323,16 +332,46 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
update_head_pos(mirror, r1_bio);
+ behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
+ if (behind) {
+ if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
+ atomic_dec(&r1_bio->behind_remaining);
+
+ /* In behind mode, we ACK the master bio once the I/O has safely
+ * reached all non-writemostly disks. Setting the Returned bit
+ * ensures that this gets done only once -- we don't ever want to
+ * return -EIO here, instead we'll wait */
+
+ if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
+ test_bit(R1BIO_Uptodate, &r1_bio->state)) {
+ /* Maybe we can return now */
+ if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
+ struct bio *mbio = r1_bio->master_bio;
+ PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
+ (unsigned long long) mbio->bi_sector,
+ (unsigned long long) mbio->bi_sector +
+ (mbio->bi_size >> 9) - 1);
+ bio_endio(mbio, mbio->bi_size, 0);
+ }
+ }
+ }
/*
*
* Let's see if all mirrored write operations have finished
* already.
*/
if (atomic_dec_and_test(&r1_bio->remaining)) {
+ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
+ /* free extra copy of the data pages */
+ int i = bio->bi_vcnt;
+ while (i--)
+ __free_page(bio->bi_io_vec[i].bv_page);
+ }
/* clear the bitmap if all writes complete successfully */
bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
r1_bio->sectors,
- !test_bit(R1BIO_Degraded, &r1_bio->state));
+ !test_bit(R1BIO_Degraded, &r1_bio->state),
+ behind);
md_write_end(r1_bio->mddev);
raid_end_bio_io(r1_bio);
}
@@ -360,13 +399,14 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
{
const unsigned long this_sector = r1_bio->sector;
int new_disk = conf->last_used, disk = new_disk;
+ int wonly_disk = -1;
const int sectors = r1_bio->sectors;
sector_t new_distance, current_distance;
- mdk_rdev_t *new_rdev, *rdev;
+ mdk_rdev_t *rdev;
rcu_read_lock();
/*
- * Check if it if we can balance. We can balance on the whole
+ * Check if we can balance. We can balance on the whole
* device if no resync is going on, or below the resync window.
* We take the first readable disk when above the resync window.
*/
@@ -376,11 +416,16 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
/* Choose the first operation device, for consistancy */
new_disk = 0;
- while ((new_rdev=conf->mirrors[new_disk].rdev) == NULL ||
- !new_rdev->in_sync) {
- new_disk++;
- if (new_disk == conf->raid_disks) {
- new_disk = -1;
+ for (rdev = conf->mirrors[new_disk].rdev;
+ !rdev || !rdev->in_sync
+ || test_bit(WriteMostly, &rdev->flags);
+ rdev = conf->mirrors[++new_disk].rdev) {
+
+ if (rdev && rdev->in_sync)
+ wonly_disk = new_disk;
+
+ if (new_disk == conf->raid_disks - 1) {
+ new_disk = wonly_disk;
break;
}
}
@@ -389,16 +434,26 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
/* make sure the disk is operational */
- while ((new_rdev=conf->mirrors[new_disk].rdev) == NULL ||
- !new_rdev->in_sync) {
+ for (rdev = conf->mirrors[new_disk].rdev;
+ !rdev || !rdev->in_sync ||
+ test_bit(WriteMostly, &rdev->flags);
+ rdev = conf->mirrors[new_disk].rdev) {
+
+ if (rdev && rdev->in_sync)
+ wonly_disk = new_disk;
+
if (new_disk <= 0)
new_disk = conf->raid_disks;
new_disk--;
if (new_disk == disk) {
- new_disk = -1;
- goto rb_out;
+ new_disk = wonly_disk;
+ break;
}
}
+
+ if (new_disk < 0)
+ goto rb_out;
+
disk = new_disk;
/* now disk == new_disk == starting point for search */
@@ -419,37 +474,41 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
disk = conf->raid_disks;
disk--;
- if ((rdev=conf->mirrors[disk].rdev) == NULL ||
- !rdev->in_sync)
+ rdev = conf->mirrors[disk].rdev;
+
+ if (!rdev ||
+ !rdev->in_sync ||
+ test_bit(WriteMostly, &rdev->flags))
continue;
if (!atomic_read(&rdev->nr_pending)) {
new_disk = disk;
- new_rdev = rdev;
break;
}
new_distance = abs(this_sector - conf->mirrors[disk].head_position);
if (new_distance < current_distance) {
current_distance = new_distance;
new_disk = disk;
- new_rdev = rdev;
}
} while (disk != conf->last_used);
-rb_out:
+ rb_out:
if (new_disk >= 0) {
- conf->next_seq_sect = this_sector + sectors;
- conf->last_used = new_disk;
- atomic_inc(&new_rdev->nr_pending);
- if (!new_rdev->in_sync) {
+ rdev = conf->mirrors[new_disk].rdev;
+ if (!rdev)
+ goto retry;
+ atomic_inc(&rdev->nr_pending);
+ if (!rdev->in_sync) {
/* cannot risk returning a device that failed
* before we inc'ed nr_pending
*/
- atomic_dec(&new_rdev->nr_pending);
+ atomic_dec(&rdev->nr_pending);
goto retry;
}
+ conf->next_seq_sect = this_sector + sectors;
+ conf->last_used = new_disk;
}
rcu_read_unlock();
@@ -542,6 +601,39 @@ static void device_barrier(conf_t *conf, sector_t sect)
spin_unlock_irq(&conf->resync_lock);
}
+/* duplicate the data pages for behind I/O */
+static struct page **alloc_behind_pages(struct bio *bio)
+{
+ int i;
+ struct bio_vec *bvec;
+ struct page **pages = kmalloc(bio->bi_vcnt * sizeof(struct page *),
+ GFP_NOIO);
+ if (unlikely(!pages))
+ goto do_sync_io;
+
+ memset(pages, 0, bio->bi_vcnt * sizeof(struct page *));
+
+ bio_for_each_segment(bvec, bio, i) {
+ pages[i] = alloc_page(GFP_NOIO);
+ if (unlikely(!pages[i]))
+ goto do_sync_io;
+ memcpy(kmap(pages[i]) + bvec->bv_offset,
+ kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len);
+ kunmap(pages[i]);
+ kunmap(bvec->bv_page);
+ }
+
+ return pages;
+
+do_sync_io:
+ if (pages)
+ for (i = 0; i < bio->bi_vcnt && pages[i]; i++)
+ __free_page(pages[i]);
+ kfree(pages);
+ PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
+ return NULL;
+}
+
static int make_request(request_queue_t *q, struct bio * bio)
{
mddev_t *mddev = q->queuedata;
@@ -554,7 +646,12 @@ static int make_request(request_queue_t *q, struct bio * bio)
struct bitmap *bitmap = mddev->bitmap;
unsigned long flags;
struct bio_list bl;
+ struct page **behind_pages = NULL;
+ if (unlikely(bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
/*
* Register the new request and wait if the reconstruction
@@ -589,8 +686,6 @@ static int make_request(request_queue_t *q, struct bio * bio)
r1_bio->mddev = mddev;
r1_bio->sector = bio->bi_sector;
- r1_bio->state = 0;
-
if (bio_data_dir(bio) == READ) {
/*
* read balancing logic:
@@ -651,13 +746,22 @@ static int make_request(request_queue_t *q, struct bio * bio)
}
rcu_read_unlock();
+ BUG_ON(targets == 0); /* we never fail the last device */
+
if (targets < conf->raid_disks) {
/* array is degraded, we will not clear the bitmap
* on I/O completion (see raid1_end_write_request) */
set_bit(R1BIO_Degraded, &r1_bio->state);
}
+ /* do behind I/O ? */
+ if (bitmap &&
+ atomic_read(&bitmap->behind_writes) < bitmap->max_write_behind &&
+ (behind_pages = alloc_behind_pages(bio)) != NULL)
+ set_bit(R1BIO_BehindIO, &r1_bio->state);
+
atomic_set(&r1_bio->remaining, 0);
+ atomic_set(&r1_bio->behind_remaining, 0);
bio_list_init(&bl);
for (i = 0; i < disks; i++) {
@@ -674,12 +778,31 @@ static int make_request(request_queue_t *q, struct bio * bio)
mbio->bi_rw = WRITE;
mbio->bi_private = r1_bio;
+ if (behind_pages) {
+ struct bio_vec *bvec;
+ int j;
+
+ /* Yes, I really want the '__' version so that
+ * we clear any unused pointer in the io_vec, rather
+ * than leave them unchanged. This is important
+ * because when we come to free the pages, we won't
+ * know the originial bi_idx, so we just free
+ * them all
+ */
+ __bio_for_each_segment(bvec, mbio, j, 0)
+ bvec->bv_page = behind_pages[j];
+ if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags))
+ atomic_inc(&r1_bio->behind_remaining);
+ }
+
atomic_inc(&r1_bio->remaining);
bio_list_add(&bl, mbio);
}
+ kfree(behind_pages); /* the behind pages are attached to the bios now */
- bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors);
+ bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
+ test_bit(R1BIO_BehindIO, &r1_bio->state));
spin_lock_irqsave(&conf->device_lock, flags);
bio_list_merge(&conf->pending_bio_list, &bl);
bio_list_init(&bl);
@@ -1105,6 +1228,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
sector_t max_sector, nr_sectors;
int disk;
int i;
+ int wonly;
int write_targets = 0;
int sync_blocks;
int still_degraded = 0;
@@ -1160,14 +1284,21 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
*/
disk = conf->last_used;
/* make sure disk is operational */
-
+ wonly = disk;
while (conf->mirrors[disk].rdev == NULL ||
- !conf->mirrors[disk].rdev->in_sync) {
+ !conf->mirrors[disk].rdev->in_sync ||
+ test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
+ ) {
+ if (conf->mirrors[disk].rdev &&
+ conf->mirrors[disk].rdev->in_sync)
+ wonly = disk;
if (disk <= 0)
disk = conf->raid_disks;
disk--;
- if (disk == conf->last_used)
+ if (disk == conf->last_used) {
+ disk = wonly;
break;
+ }
}
conf->last_used = disk;
atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
@@ -1439,6 +1570,17 @@ out:
static int stop(mddev_t *mddev)
{
conf_t *conf = mddev_to_conf(mddev);
+ struct bitmap *bitmap = mddev->bitmap;
+ int behind_wait = 0;
+
+ /* wait for behind writes to complete */
+ while (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
+ behind_wait++;
+ printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop (%d)\n", mdname(mddev), behind_wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ); /* wait a second */
+ /* need to kick something here to make sure I/O goes? */
+ }
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
@@ -1561,6 +1703,35 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks)
return 0;
}
+static void raid1_quiesce(mddev_t *mddev, int state)
+{
+ conf_t *conf = mddev_to_conf(mddev);
+
+ switch(state) {
+ case 1:
+ spin_lock_irq(&conf->resync_lock);
+ conf->barrier++;
+ wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
+ conf->resync_lock, raid1_unplug(mddev->queue));
+ spin_unlock_irq(&conf->resync_lock);
+ break;
+ case 0:
+ spin_lock_irq(&conf->resync_lock);
+ conf->barrier--;
+ spin_unlock_irq(&conf->resync_lock);
+ wake_up(&conf->wait_resume);
+ wake_up(&conf->wait_idle);
+ break;
+ }
+ if (mddev->thread) {
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+ else
+ mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+ md_wakeup_thread(mddev->thread);
+ }
+}
+
static mdk_personality_t raid1_personality =
{
@@ -1577,6 +1748,7 @@ static mdk_personality_t raid1_personality =
.sync_request = sync_request,
.resize = raid1_resize,
.reshape = raid1_reshape,
+ .quiesce = raid1_quiesce,
};
static int __init raid_init(void)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 62ebb1bc72be..28dd028415e4 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -47,7 +47,7 @@
static void unplug_slaves(mddev_t *mddev);
-static void * r10bio_pool_alloc(unsigned int __nocast gfp_flags, void *data)
+static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
{
conf_t *conf = data;
r10bio_t *r10_bio;
@@ -81,7 +81,7 @@ static void r10bio_pool_free(void *r10_bio, void *data)
* one for write (we recover only one drive per r10buf)
*
*/
-static void * r10buf_pool_alloc(unsigned int __nocast gfp_flags, void *data)
+static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
{
conf_t *conf = data;
struct page *page;
@@ -538,7 +538,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
}
- current_distance = abs(this_sector - conf->mirrors[disk].head_position);
+ current_distance = abs(r10_bio->devs[slot].addr -
+ conf->mirrors[disk].head_position);
/* Find the disk whose head is closest */
@@ -668,6 +669,11 @@ static int make_request(request_queue_t *q, struct bio * bio)
int i;
int chunk_sects = conf->chunk_mask + 1;
+ if (unlikely(bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
/* If this request crosses a chunk boundary, we need to
* split it. This will only happen for 1 PAGE (or less) requests.
*/
@@ -900,6 +906,27 @@ static void close_sync(conf_t *conf)
conf->r10buf_pool = NULL;
}
+/* check if there are enough drives for
+ * every block to appear on atleast one
+ */
+static int enough(conf_t *conf)
+{
+ int first = 0;
+
+ do {
+ int n = conf->copies;
+ int cnt = 0;
+ while (n--) {
+ if (conf->mirrors[first].rdev)
+ cnt++;
+ first = (first+1) % conf->raid_disks;
+ }
+ if (cnt == 0)
+ return 0;
+ } while (first != 0);
+ return 1;
+}
+
static int raid10_spare_active(mddev_t *mddev)
{
int i;
@@ -938,6 +965,8 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
* very different from resync
*/
return 0;
+ if (!enough(conf))
+ return 0;
for (mirror=0; mirror < mddev->raid_disks; mirror++)
if ( !(p=conf->mirrors+mirror)->rdev) {
@@ -1445,7 +1474,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
}
}
if (j == conf->copies) {
- BUG();
+ /* Cannot recover, so abort the recovery */
+ put_buf(r10_bio);
+ r10_bio = rb2;
+ if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery))
+ printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n",
+ mdname(mddev));
+ break;
}
}
if (biolist == NULL) {
@@ -1678,9 +1713,10 @@ static int run(mddev_t *mddev)
init_waitqueue_head(&conf->wait_idle);
init_waitqueue_head(&conf->wait_resume);
- if (!conf->working_disks) {
- printk(KERN_ERR "raid10: no operational mirrors for %s\n",
- mdname(mddev));
+ /* need to check that every block has at least one working mirror */
+ if (!enough(conf)) {
+ printk(KERN_ERR "raid10: not enough operational mirrors for %s\n",
+ mdname(mddev));
goto out_free_conf;
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 43f231a467d5..4683ca24c046 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -24,6 +24,8 @@
#include <linux/bitops.h>
#include <asm/atomic.h>
+#include <linux/raid/bitmap.h>
+
/*
* Stripe cache
*/
@@ -79,8 +81,13 @@ static inline void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
if (test_bit(STRIPE_HANDLE, &sh->state)) {
if (test_bit(STRIPE_DELAYED, &sh->state))
list_add_tail(&sh->lru, &conf->delayed_list);
- else
+ else if (test_bit(STRIPE_BIT_DELAY, &sh->state) &&
+ conf->seq_write == sh->bm_seq)
+ list_add_tail(&sh->lru, &conf->bitmap_list);
+ else {
+ clear_bit(STRIPE_BIT_DELAY, &sh->state);
list_add_tail(&sh->lru, &conf->handle_list);
+ }
md_wakeup_thread(conf->mddev->thread);
} else {
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
@@ -244,6 +251,9 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
spin_lock_irq(&conf->device_lock);
do {
+ wait_event_lock_irq(conf->wait_for_stripe,
+ conf->quiesce == 0,
+ conf->device_lock, /* nothing */);
sh = __find_stripe(conf, sector);
if (!sh) {
if (!conf->inactive_blocked)
@@ -803,6 +813,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
{
struct bio **bip;
raid5_conf_t *conf = sh->raid_conf;
+ int firstwrite=0;
PRINTK("adding bh b#%llu to stripe s#%llu\n",
(unsigned long long)bi->bi_sector,
@@ -811,9 +822,11 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
spin_lock(&sh->lock);
spin_lock_irq(&conf->device_lock);
- if (forwrite)
+ if (forwrite) {
bip = &sh->dev[dd_idx].towrite;
- else
+ if (*bip == NULL && sh->dev[dd_idx].written == NULL)
+ firstwrite = 1;
+ } else
bip = &sh->dev[dd_idx].toread;
while (*bip && (*bip)->bi_sector < bi->bi_sector) {
if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
@@ -836,6 +849,13 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
(unsigned long long)bi->bi_sector,
(unsigned long long)sh->sector, dd_idx);
+ if (conf->mddev->bitmap && firstwrite) {
+ sh->bm_seq = conf->seq_write;
+ bitmap_startwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0);
+ set_bit(STRIPE_BIT_DELAY, &sh->state);
+ }
+
if (forwrite) {
/* check if page is covered */
sector_t sector = sh->dev[dd_idx].sector;
@@ -958,12 +978,13 @@ static void handle_stripe(struct stripe_head *sh)
* need to be failed
*/
if (failed > 1 && to_read+to_write+written) {
- spin_lock_irq(&conf->device_lock);
for (i=disks; i--; ) {
+ int bitmap_end = 0;
+ spin_lock_irq(&conf->device_lock);
/* fail all writes first */
bi = sh->dev[i].towrite;
sh->dev[i].towrite = NULL;
- if (bi) to_write--;
+ if (bi) { to_write--; bitmap_end = 1; }
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
@@ -981,6 +1002,7 @@ static void handle_stripe(struct stripe_head *sh)
/* and fail all 'written' */
bi = sh->dev[i].written;
sh->dev[i].written = NULL;
+ if (bi) bitmap_end = 1;
while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1009,8 +1031,11 @@ static void handle_stripe(struct stripe_head *sh)
bi = nextbi;
}
}
+ spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0, 0);
}
- spin_unlock_irq(&conf->device_lock);
}
if (failed > 1 && syncing) {
md_done_sync(conf->mddev, STRIPE_SECTORS,0);
@@ -1038,6 +1063,7 @@ static void handle_stripe(struct stripe_head *sh)
test_bit(R5_UPTODATE, &dev->flags) ) {
/* We can return any write requests */
struct bio *wbi, *wbi2;
+ int bitmap_end = 0;
PRINTK("Return write for disc %d\n", i);
spin_lock_irq(&conf->device_lock);
wbi = dev->written;
@@ -1051,7 +1077,13 @@ static void handle_stripe(struct stripe_head *sh)
}
wbi = wbi2;
}
+ if (dev->towrite == NULL)
+ bitmap_end = 1;
spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS,
+ !test_bit(STRIPE_DEGRADED, &sh->state), 0);
}
}
}
@@ -1175,7 +1207,8 @@ static void handle_stripe(struct stripe_head *sh)
}
}
/* now if nothing is locked, and if we have enough data, we can start a write request */
- if (locked == 0 && (rcw == 0 ||rmw == 0)) {
+ if (locked == 0 && (rcw == 0 ||rmw == 0) &&
+ !test_bit(STRIPE_BIT_DELAY, &sh->state)) {
PRINTK("Computing parity...\n");
compute_parity(sh, rcw==0 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);
/* now every locked buffer is ready to be written */
@@ -1231,6 +1264,7 @@ static void handle_stripe(struct stripe_head *sh)
dev = &sh->dev[failed_num];
set_bit(R5_LOCKED, &dev->flags);
set_bit(R5_Wantwrite, &dev->flags);
+ clear_bit(STRIPE_DEGRADED, &sh->state);
locked++;
set_bit(STRIPE_INSYNC, &sh->state);
set_bit(R5_Syncio, &dev->flags);
@@ -1298,6 +1332,8 @@ static void handle_stripe(struct stripe_head *sh)
bi->bi_next = NULL;
generic_make_request(bi);
} else {
+ if (rw == 1)
+ set_bit(STRIPE_DEGRADED, &sh->state);
PRINTK("skip op %ld on disc %d for sector %llu\n",
bi->bi_rw, i, (unsigned long long)sh->sector);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -1322,6 +1358,20 @@ static inline void raid5_activate_delayed(raid5_conf_t *conf)
}
}
+static inline void activate_bit_delay(raid5_conf_t *conf)
+{
+ /* device_lock is held */
+ struct list_head head;
+ list_add(&head, &conf->bitmap_list);
+ list_del_init(&conf->bitmap_list);
+ while (!list_empty(&head)) {
+ struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ atomic_inc(&sh->count);
+ __release_stripe(conf, sh);
+ }
+}
+
static void unplug_slaves(mddev_t *mddev)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -1354,8 +1404,10 @@ static void raid5_unplug_device(request_queue_t *q)
spin_lock_irqsave(&conf->device_lock, flags);
- if (blk_remove_plug(q))
+ if (blk_remove_plug(q)) {
+ conf->seq_flush++;
raid5_activate_delayed(conf);
+ }
md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags);
@@ -1411,6 +1463,11 @@ static int make_request (request_queue_t *q, struct bio * bi)
sector_t logical_sector, last_sector;
struct stripe_head *sh;
+ if (unlikely(bio_barrier(bi))) {
+ bio_endio(bi, bi->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
md_write_start(mddev, bi);
if (bio_data_dir(bi)==WRITE) {
@@ -1488,10 +1545,20 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
sector_t first_sector;
int raid_disks = conf->raid_disks;
int data_disks = raid_disks-1;
+ sector_t max_sector = mddev->size << 1;
+ int sync_blocks;
- if (sector_nr >= mddev->size <<1) {
+ if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
+ if (mddev->curr_resync < max_sector) /* aborted */
+ bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
+ &sync_blocks, 1);
+ else /* compelted sync */
+ conf->fullsync = 0;
+ bitmap_close_sync(mddev->bitmap);
+
return 0;
}
/* if there is 1 or more failed drives and we are trying
@@ -1503,6 +1570,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
*skipped = 1;
return rv;
}
+ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+ !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
+ /* we can skip this block, and probably more */
+ sync_blocks /= STRIPE_SECTORS;
+ *skipped = 1;
+ return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
+ }
x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk);
@@ -1520,6 +1594,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
}
+ bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
spin_lock(&sh->lock);
set_bit(STRIPE_SYNCING, &sh->state);
clear_bit(STRIPE_INSYNC, &sh->state);
@@ -1553,6 +1628,13 @@ static void raid5d (mddev_t *mddev)
while (1) {
struct list_head *first;
+ if (conf->seq_flush - conf->seq_write > 0) {
+ int seq = conf->seq_flush;
+ bitmap_unplug(mddev->bitmap);
+ conf->seq_write = seq;
+ activate_bit_delay(conf);
+ }
+
if (list_empty(&conf->handle_list) &&
atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
!blk_queue_plugged(mddev->queue) &&
@@ -1586,7 +1668,7 @@ static void raid5d (mddev_t *mddev)
PRINTK("--- raid5d inactive\n");
}
-static int run (mddev_t *mddev)
+static int run(mddev_t *mddev)
{
raid5_conf_t *conf;
int raid_disk, memory;
@@ -1616,6 +1698,7 @@ static int run (mddev_t *mddev)
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
INIT_LIST_HEAD(&conf->delayed_list);
+ INIT_LIST_HEAD(&conf->bitmap_list);
INIT_LIST_HEAD(&conf->inactive_list);
atomic_set(&conf->active_stripes, 0);
atomic_set(&conf->preread_active_stripes, 0);
@@ -1727,6 +1810,9 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
/* Ok, everything is just fine now */
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->issue_flush_fn = raid5_issue_flush;
@@ -1907,6 +1993,8 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
rdev->in_sync = 0;
rdev->raid_disk = disk;
found = 1;
+ if (rdev->saved_raid_disk != disk)
+ conf->fullsync = 1;
p->rdev = rdev;
break;
}
@@ -1936,6 +2024,35 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
return 0;
}
+static void raid5_quiesce(mddev_t *mddev, int state)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ switch(state) {
+ case 1: /* stop all writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 1;
+ wait_event_lock_irq(conf->wait_for_stripe,
+ atomic_read(&conf->active_stripes) == 0,
+ conf->device_lock, /* nothing */);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+
+ case 0: /* re-enable writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 0;
+ wake_up(&conf->wait_for_stripe);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+ }
+ if (mddev->thread) {
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+ else
+ mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+ md_wakeup_thread(mddev->thread);
+ }
+}
static mdk_personality_t raid5_personality=
{
.name = "raid5",
@@ -1950,6 +2067,7 @@ static mdk_personality_t raid5_personality=
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
+ .quiesce = raid5_quiesce,
};
static int __init raid5_init (void)
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h
index f80ee6350edf..31cbee71365f 100644
--- a/drivers/md/raid6.h
+++ b/drivers/md/raid6.h
@@ -69,9 +69,13 @@ extern const char raid6_empty_zero_page[PAGE_SIZE];
#define __init
#define __exit
#define __attribute_const__ __attribute__((const))
+#define noinline __attribute__((noinline))
#define preempt_enable()
#define preempt_disable()
+#define cpu_has_feature(x) 1
+#define enable_kernel_altivec()
+#define disable_kernel_altivec()
#endif /* __KERNEL__ */
diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
index acf386fc4b4f..51c63c0cf1c9 100644
--- a/drivers/md/raid6algos.c
+++ b/drivers/md/raid6algos.c
@@ -19,6 +19,7 @@
#include "raid6.h"
#ifndef __KERNEL__
#include <sys/mman.h>
+#include <stdio.h>
#endif
struct raid6_calls raid6_call;
diff --git a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
index 1de8f030eee0..b9afd35b8812 100644
--- a/drivers/md/raid6altivec.uc
+++ b/drivers/md/raid6altivec.uc
@@ -27,16 +27,20 @@
#ifdef CONFIG_ALTIVEC
#include <altivec.h>
-#include <asm/system.h>
-#include <asm/cputable.h>
+#ifdef __KERNEL__
+# include <asm/system.h>
+# include <asm/cputable.h>
+#endif
/*
- * This is the C data type to use
+ * This is the C data type to use. We use a vector of
+ * signed char so vec_cmpgt() will generate the right
+ * instruction.
*/
-typedef vector unsigned char unative_t;
+typedef vector signed char unative_t;
-#define NBYTES(x) ((vector unsigned char) {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x})
+#define NBYTES(x) ((vector signed char) {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x})
#define NSIZE sizeof(unative_t)
/*
@@ -108,7 +112,11 @@ int raid6_have_altivec(void);
int raid6_have_altivec(void)
{
/* This assumes either all CPUs have Altivec or none does */
+# ifdef __KERNEL__
return cpu_has_feature(CPU_FTR_ALTIVEC);
+# else
+ return 1;
+# endif
}
#endif
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 495dee1d1e83..267eb1430c83 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -29,6 +29,8 @@
#include <asm/atomic.h>
#include "raid6.h"
+#include <linux/raid/bitmap.h>
+
/*
* Stripe cache
*/
@@ -98,8 +100,13 @@ static inline void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh)
if (test_bit(STRIPE_HANDLE, &sh->state)) {
if (test_bit(STRIPE_DELAYED, &sh->state))
list_add_tail(&sh->lru, &conf->delayed_list);
- else
+ else if (test_bit(STRIPE_BIT_DELAY, &sh->state) &&
+ conf->seq_write == sh->bm_seq)
+ list_add_tail(&sh->lru, &conf->bitmap_list);
+ else {
+ clear_bit(STRIPE_BIT_DELAY, &sh->state);
list_add_tail(&sh->lru, &conf->handle_list);
+ }
md_wakeup_thread(conf->mddev->thread);
} else {
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
@@ -262,6 +269,9 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector
spin_lock_irq(&conf->device_lock);
do {
+ wait_event_lock_irq(conf->wait_for_stripe,
+ conf->quiesce == 0,
+ conf->device_lock, /* nothing */);
sh = __find_stripe(conf, sector);
if (!sh) {
if (!conf->inactive_blocked)
@@ -906,6 +916,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
{
struct bio **bip;
raid6_conf_t *conf = sh->raid_conf;
+ int firstwrite=0;
PRINTK("adding bh b#%llu to stripe s#%llu\n",
(unsigned long long)bi->bi_sector,
@@ -914,9 +925,11 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
spin_lock(&sh->lock);
spin_lock_irq(&conf->device_lock);
- if (forwrite)
+ if (forwrite) {
bip = &sh->dev[dd_idx].towrite;
- else
+ if (*bip == NULL && sh->dev[dd_idx].written == NULL)
+ firstwrite = 1;
+ } else
bip = &sh->dev[dd_idx].toread;
while (*bip && (*bip)->bi_sector < bi->bi_sector) {
if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
@@ -939,6 +952,13 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
(unsigned long long)bi->bi_sector,
(unsigned long long)sh->sector, dd_idx);
+ if (conf->mddev->bitmap && firstwrite) {
+ sh->bm_seq = conf->seq_write;
+ bitmap_startwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0);
+ set_bit(STRIPE_BIT_DELAY, &sh->state);
+ }
+
if (forwrite) {
/* check if page is covered */
sector_t sector = sh->dev[dd_idx].sector;
@@ -1066,12 +1086,13 @@ static void handle_stripe(struct stripe_head *sh)
* need to be failed
*/
if (failed > 2 && to_read+to_write+written) {
- spin_lock_irq(&conf->device_lock);
for (i=disks; i--; ) {
+ int bitmap_end = 0;
+ spin_lock_irq(&conf->device_lock);
/* fail all writes first */
bi = sh->dev[i].towrite;
sh->dev[i].towrite = NULL;
- if (bi) to_write--;
+ if (bi) { to_write--; bitmap_end = 1; }
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
@@ -1089,6 +1110,7 @@ static void handle_stripe(struct stripe_head *sh)
/* and fail all 'written' */
bi = sh->dev[i].written;
sh->dev[i].written = NULL;
+ if (bi) bitmap_end = 1;
while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1117,8 +1139,11 @@ static void handle_stripe(struct stripe_head *sh)
bi = nextbi;
}
}
+ spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0, 0);
}
- spin_unlock_irq(&conf->device_lock);
}
if (failed > 2 && syncing) {
md_done_sync(conf->mddev, STRIPE_SECTORS,0);
@@ -1155,6 +1180,7 @@ static void handle_stripe(struct stripe_head *sh)
if (!test_bit(R5_LOCKED, &dev->flags) &&
test_bit(R5_UPTODATE, &dev->flags) ) {
/* We can return any write requests */
+ int bitmap_end = 0;
struct bio *wbi, *wbi2;
PRINTK("Return write for stripe %llu disc %d\n",
(unsigned long long)sh->sector, i);
@@ -1170,7 +1196,13 @@ static void handle_stripe(struct stripe_head *sh)
}
wbi = wbi2;
}
+ if (dev->towrite == NULL)
+ bitmap_end = 1;
spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS,
+ !test_bit(STRIPE_DEGRADED, &sh->state), 0);
}
}
}
@@ -1285,7 +1317,8 @@ static void handle_stripe(struct stripe_head *sh)
}
}
/* now if nothing is locked, and if we have enough data, we can start a write request */
- if (locked == 0 && rcw == 0) {
+ if (locked == 0 && rcw == 0 &&
+ !test_bit(STRIPE_BIT_DELAY, &sh->state)) {
if ( must_compute > 0 ) {
/* We have failed blocks and need to compute them */
switch ( failed ) {
@@ -1388,6 +1421,7 @@ static void handle_stripe(struct stripe_head *sh)
bdev = &sh->dev[failed_num[1]];
locked += !test_bit(R5_LOCKED, &bdev->flags);
set_bit(R5_LOCKED, &bdev->flags);
+ clear_bit(STRIPE_DEGRADED, &sh->state);
set_bit(R5_Wantwrite, &bdev->flags);
set_bit(STRIPE_INSYNC, &sh->state);
@@ -1457,6 +1491,8 @@ static void handle_stripe(struct stripe_head *sh)
bi->bi_next = NULL;
generic_make_request(bi);
} else {
+ if (rw == 1)
+ set_bit(STRIPE_DEGRADED, &sh->state);
PRINTK("skip op %ld on disc %d for sector %llu\n",
bi->bi_rw, i, (unsigned long long)sh->sector);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -1481,6 +1517,20 @@ static inline void raid6_activate_delayed(raid6_conf_t *conf)
}
}
+static inline void activate_bit_delay(raid6_conf_t *conf)
+{
+ /* device_lock is held */
+ struct list_head head;
+ list_add(&head, &conf->bitmap_list);
+ list_del_init(&conf->bitmap_list);
+ while (!list_empty(&head)) {
+ struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ atomic_inc(&sh->count);
+ __release_stripe(conf, sh);
+ }
+}
+
static void unplug_slaves(mddev_t *mddev)
{
raid6_conf_t *conf = mddev_to_conf(mddev);
@@ -1513,8 +1563,10 @@ static void raid6_unplug_device(request_queue_t *q)
spin_lock_irqsave(&conf->device_lock, flags);
- if (blk_remove_plug(q))
+ if (blk_remove_plug(q)) {
+ conf->seq_flush++;
raid6_activate_delayed(conf);
+ }
md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags);
@@ -1570,6 +1622,11 @@ static int make_request (request_queue_t *q, struct bio * bi)
sector_t logical_sector, last_sector;
struct stripe_head *sh;
+ if (unlikely(bio_barrier(bi))) {
+ bio_endio(bi, bi->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
md_write_start(mddev, bi);
if (bio_data_dir(bi)==WRITE) {
@@ -1647,10 +1704,20 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
sector_t first_sector;
int raid_disks = conf->raid_disks;
int data_disks = raid_disks - 2;
+ sector_t max_sector = mddev->size << 1;
+ int sync_blocks;
- if (sector_nr >= mddev->size <<1) {
+ if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
+ if (mddev->curr_resync < max_sector) /* aborted */
+ bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
+ &sync_blocks, 1);
+ else /* compelted sync */
+ conf->fullsync = 0;
+ bitmap_close_sync(mddev->bitmap);
+
return 0;
}
/* if there are 2 or more failed drives and we are trying
@@ -1662,6 +1729,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
*skipped = 1;
return rv;
}
+ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+ !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
+ /* we can skip this block, and probably more */
+ sync_blocks /= STRIPE_SECTORS;
+ *skipped = 1;
+ return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
+ }
x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk);
@@ -1679,6 +1753,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
}
+ bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
spin_lock(&sh->lock);
set_bit(STRIPE_SYNCING, &sh->state);
clear_bit(STRIPE_INSYNC, &sh->state);
@@ -1712,6 +1787,13 @@ static void raid6d (mddev_t *mddev)
while (1) {
struct list_head *first;
+ if (conf->seq_flush - conf->seq_write > 0) {
+ int seq = conf->seq_flush;
+ bitmap_unplug(mddev->bitmap);
+ conf->seq_write = seq;
+ activate_bit_delay(conf);
+ }
+
if (list_empty(&conf->handle_list) &&
atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
!blk_queue_plugged(mddev->queue) &&
@@ -1745,7 +1827,7 @@ static void raid6d (mddev_t *mddev)
PRINTK("--- raid6d inactive\n");
}
-static int run (mddev_t *mddev)
+static int run(mddev_t *mddev)
{
raid6_conf_t *conf;
int raid_disk, memory;
@@ -1775,6 +1857,7 @@ static int run (mddev_t *mddev)
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
INIT_LIST_HEAD(&conf->delayed_list);
+ INIT_LIST_HEAD(&conf->bitmap_list);
INIT_LIST_HEAD(&conf->inactive_list);
atomic_set(&conf->active_stripes, 0);
atomic_set(&conf->preread_active_stripes, 0);
@@ -1894,6 +1977,9 @@ static int run (mddev_t *mddev)
/* Ok, everything is just fine now */
mddev->array_size = mddev->size * (mddev->raid_disks - 2);
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+
mddev->queue->unplug_fn = raid6_unplug_device;
mddev->queue->issue_flush_fn = raid6_issue_flush;
return 0;
@@ -2071,6 +2157,8 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
rdev->in_sync = 0;
rdev->raid_disk = disk;
found = 1;
+ if (rdev->saved_raid_disk != disk)
+ conf->fullsync = 1;
p->rdev = rdev;
break;
}
@@ -2100,6 +2188,35 @@ static int raid6_resize(mddev_t *mddev, sector_t sectors)
return 0;
}
+static void raid6_quiesce(mddev_t *mddev, int state)
+{
+ raid6_conf_t *conf = mddev_to_conf(mddev);
+
+ switch(state) {
+ case 1: /* stop all writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 1;
+ wait_event_lock_irq(conf->wait_for_stripe,
+ atomic_read(&conf->active_stripes) == 0,
+ conf->device_lock, /* nothing */);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+
+ case 0: /* re-enable writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 0;
+ wake_up(&conf->wait_for_stripe);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+ }
+ if (mddev->thread) {
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+ else
+ mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+ md_wakeup_thread(mddev->thread);
+ }
+}
static mdk_personality_t raid6_personality=
{
.name = "raid6",
@@ -2114,6 +2231,7 @@ static mdk_personality_t raid6_personality=
.spare_active = raid6_spare_active,
.sync_request = sync_request,
.resize = raid6_resize,
+ .quiesce = raid6_quiesce,
};
static int __init raid6_init (void)
diff --git a/drivers/md/raid6test/Makefile b/drivers/md/raid6test/Makefile
index 557806728609..78e0396adf2a 100644
--- a/drivers/md/raid6test/Makefile
+++ b/drivers/md/raid6test/Makefile
@@ -8,6 +8,8 @@ OPTFLAGS = -O2 # Adjust as desired
CFLAGS = -I.. -g $(OPTFLAGS)
LD = ld
PERL = perl
+AR = ar
+RANLIB = ranlib
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<
@@ -18,18 +20,33 @@ PERL = perl
%.uc: ../%.uc
cp -f $< $@
-all: raid6.o raid6test
+all: raid6.a raid6test
-raid6.o: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \
+raid6.a: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \
raid6int32.o \
raid6mmx.o raid6sse1.o raid6sse2.o \
+ raid6altivec1.o raid6altivec2.o raid6altivec4.o raid6altivec8.o \
raid6recov.o raid6algos.o \
raid6tables.o
- $(LD) -r -o $@ $^
+ rm -f $@
+ $(AR) cq $@ $^
+ $(RANLIB) $@
-raid6test: raid6.o test.c
+raid6test: test.c raid6.a
$(CC) $(CFLAGS) -o raid6test $^
+raid6altivec1.c: raid6altivec.uc ../unroll.pl
+ $(PERL) ../unroll.pl 1 < raid6altivec.uc > $@
+
+raid6altivec2.c: raid6altivec.uc ../unroll.pl
+ $(PERL) ../unroll.pl 2 < raid6altivec.uc > $@
+
+raid6altivec4.c: raid6altivec.uc ../unroll.pl
+ $(PERL) ../unroll.pl 4 < raid6altivec.uc > $@
+
+raid6altivec8.c: raid6altivec.uc ../unroll.pl
+ $(PERL) ../unroll.pl 8 < raid6altivec.uc > $@
+
raid6int1.c: raid6int.uc ../unroll.pl
$(PERL) ../unroll.pl 1 < raid6int.uc > $@
@@ -52,7 +69,7 @@ raid6tables.c: mktables
./mktables > raid6tables.c
clean:
- rm -f *.o mktables mktables.c raid6int.uc raid6*.c raid6test
+ rm -f *.o *.a mktables mktables.c raid6int.uc raid6*.c raid6test
spotless: clean
rm -f *~
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 772d6112fb3b..c578a529e7a8 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,4 +2,7 @@
# 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 ab7a1fba4427..a0e700d7a4a4 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_core.c b/drivers/media/common/saa7146_core.c
index cd5828b5e9e3..206cc2f61f26 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -168,10 +168,8 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
return;
pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
pt->cpu = NULL;
- if (NULL != pt->slist) {
- kfree(pt->slist);
- pt->slist = NULL;
- }
+ kfree(pt->slist);
+ pt->slist = NULL;
}
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index c04fd11526e0..37888989ea2e 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -1,5 +1,4 @@
#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 6284894505c6..fec6beab8c28 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 0410cc96a48e..47e28b0ee951 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -164,12 +164,11 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate,
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 3c5a8e273c4a..f29571450038 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 837623f7fcdf..a73baf00ca39 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 07a0b0a968a6..34a837a1abf4 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 bfaacd5fc20f..6776a592045f 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 ef532a6aceaa..3281a6ca3685 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 6f857c6091f3..c5c7672cd538 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 2923b3b0dd3c..9ec8e5bd6c1f 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 226714085f58..7cf4c4a888ec 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
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 9ea5747b1211..6db0929ef53d 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 fb55eaa5c8e7..9719a3b30f78 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 68050cd527cb..8028c3a5e287 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -571,7 +571,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
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 0eb9aa711fb0..88757e2634e5 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -47,7 +47,7 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
#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 ac9889d22288..dc476dda2b71 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -38,82 +38,52 @@
*/
// #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 c09beb391622..0cc888339d52 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -20,7 +20,6 @@
*
*/
-
#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 6a968c346a36..87935490bfb2 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -62,7 +62,6 @@
#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 612e5b087b1c..54e2b29076b1 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -93,13 +93,30 @@ config DVB_USB_DIGITV
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 746d87ed6f32..2dc9aad9681e 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -4,6 +4,9 @@ obj-$(CONFIG_DVB_USB) += dvb-usb.o
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 f2fcc2f1f846..e55322ef76b3 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -90,7 +90,7 @@ static struct dvb_usb_properties a800_properties;
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 9e96a188f1e9..3fe383f4bb4c 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -48,35 +48,26 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
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 1d79016e3195..135c2a81f581 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 828b5182e16c..0058505634a0 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -86,9 +86,9 @@ static struct dvb_usb_properties dibusb2_0b_properties;
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 e9dac430f37d..6a0912eab396 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -20,7 +20,7 @@ static struct dvb_usb_properties dibusb_mc_properties;
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 f70e0be0920a..74545f82eff1 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -111,31 +111,28 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
}
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 b032523b07bc..0a94ec22aeb8 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -18,6 +18,7 @@ struct dtt200u_fe_state {
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 47dba6e45968..5aa12ebab34f 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -98,20 +98,19 @@ static struct dvb_usb_properties wt220u_properties;
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 794d513a8480..0818996bf150 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -24,8 +24,10 @@
#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 65f0c095abc9..a902059812a2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -128,7 +128,9 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device
/*
* 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 a80567caf508..0e4f1035b0dd 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -127,7 +127,7 @@ struct dvb_usb_device;
* 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 258a92bfbcc7..1841a66427bf 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -144,7 +144,7 @@ static struct dvb_usb_properties nova_t_properties;
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 2112ac3cf5e2..6fd67657c269 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -77,7 +77,7 @@ static struct dvb_usb_properties umt_properties;
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 000000000000..f20d8dbd0be8
--- /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 000000000000..de13c04e8e64
--- /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 000000000000..4a3e8c7eca2b
--- /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 9ac95f54f9fc..0f57abeb6d6b 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -164,7 +164,6 @@ static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int off
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 8222b88cb486..d4b97989e3ed 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 6b663f4744e0..b63ecf26421a 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 cd434b7cf9db..21433e1831e7 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 cd33705a4320..441de665fec3 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 d32dc4de9e7f..cc1bc0edd65e 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -462,9 +462,11 @@ static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
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 966de9853d18..88a57b791112 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -482,6 +482,7 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
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 cc0a77c790f1..b6d0eecc59eb 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -370,22 +370,19 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
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 4f396ac8de77..c7fe27fd530c 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 b687fc77ceb3..872028ddf2a2 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 928aca052afe..8d09afd7545d 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 3be535989302..9e53f019db71 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 cfa3928bb487..2d62931f20b5 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 79457a80a11f..d0c4484861e1 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/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 87d5f4d8790f..eaf130e666d8 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -100,8 +100,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2)
- printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
- state->frontend.dvb->num, __FUNCTION__, ret);
+ printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
+ __FUNCTION__, ret);
return b1[0];
}
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index ab0c032472cc..74cea9f8d721 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -1046,8 +1046,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
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 70fb44b391a7..c6d276618e86 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -194,19 +194,18 @@ static int ves1820_init(struct dvb_frontend* fe)
{
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 e4c6e87f6c5d..22b203f8ff27 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -168,7 +168,9 @@ static void init_av7110_av(struct av7110 *av7110)
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 508b7739c609..cce00ef293e9 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 1220826696c5..7442f56a72ec 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 665cdb8a3f71..357a3728ec68 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 e65fc36e2ce8..6af74f78b3e5 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -70,7 +70,7 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
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 9746d2bb916f..7692cd23f839 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
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 a1267054bc01..2980db3ef22f 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 8142e26b47f5..b1f21ef0e3b3 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -353,9 +353,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
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 9961917e8a7f..43d6c8268642 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -332,9 +332,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
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 7daf7b1598a0..d200ab0ad9e7 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -18,6 +18,7 @@
#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 45c9a9a08e4d..3d08fc83a754 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -28,7 +28,6 @@
#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/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 8b4ad70dd1b2..877c770558e9 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -29,7 +29,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 013c835ed910..5319a9c9a979 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -26,7 +26,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 53d399b6652b..9b0406318f2d 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -29,7 +29,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
@@ -543,7 +543,7 @@ static int cadet_probe(void)
for(i=0;i<8;i++) {
io=iovals[i];
- if(request_region(io,2, "cadet-probe")>=0) {
+ if (request_region(io, 2, "cadet-probe")) {
cadet_setfreq(1410);
if(cadet_getfreq()==1410) {
release_region(io, 2);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 202bfe6819b8..6418f03b9ce4 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -17,7 +17,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index c00245d4d249..b2256d675b44 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -10,7 +10,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 3a464a09221f..6f03ce4dd7b0 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -18,7 +18,7 @@
#include <linux/kernel.h> /* __setup */
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <linux/videodev.h> /* kernel radio structs */
#include <linux/isapnp.h>
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 0732efda6a98..71971e9bb342 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -14,7 +14,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 248d67fde037..b03573c6840e 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -25,7 +25,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index d7da901ebe90..f304f3c14763 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -31,7 +31,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/proc_fs.h> /* radio card status report */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 342f92df4aba..4c6d6fb49034 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -28,7 +28,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay, msleep */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 16c85c081e6e..bbb989df4cf0 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
@@ -253,7 +262,6 @@ config VIDEO_SAA7134_DVB
depends on VIDEO_SAA7134 && DVB_CORE
select VIDEO_BUF_DVB
select DVB_MT352
- select DVB_CX22702
select DVB_TDA1004X
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3e6f5347da21..046b82de9285 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,6 +5,7 @@
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 7f2d515d2873..a48de3c0e3f0 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 41f60395a520..503e6c6d7b69 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 a97b9b958ed6..0881a17d5226 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 = 3,
+ .audio_inputs = 1,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1 },
+ .gpiomask = 0x00e00007,
+ .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 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 087efb4dea09..c062a017491e 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];
@@ -761,21 +763,21 @@ static void set_pll(struct bttv *btv)
/* no PLL needed */
if (btv->pll.pll_current == 0)
return;
- vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
- btv->c.nr,btv->pll.pll_ifreq);
+ bttv_printk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
+ btv->c.nr,btv->pll.pll_ifreq);
btwrite(0x00,BT848_TGCTRL);
btwrite(0x00,BT848_PLL_XCI);
btv->pll.pll_current = 0;
return;
}
- vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
- btv->pll.pll_ifreq, btv->pll.pll_ofreq);
+ bttv_printk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
+ btv->pll.pll_ifreq, btv->pll.pll_ofreq);
set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
for (i=0; i<10; i++) {
/* Let other people run while the PLL stabilizes */
- vprintk(".");
+ bttv_printk(".");
msleep(10);
if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
@@ -783,12 +785,12 @@ static void set_pll(struct bttv *btv)
} else {
btwrite(0x08,BT848_TGCTRL);
btv->pll.pll_current = btv->pll.pll_ofreq;
- vprintk(" ok\n");
+ bttv_printk(" ok\n");
return;
}
}
btv->pll.pll_current = -1;
- vprintk("failed\n");
+ bttv_printk("failed\n");
return;
}
@@ -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 77320cdf205f..6b280c03e398 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 706dc48df962..e684df37eb0e 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 f7b5543a96a1..e8aada772b89 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 9ed21fd190c6..a5ed99b89445 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 06f3e62b3e8d..f4f58c60f152 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 f2af9e1454f0..d254e90e3bb9 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 aab094bc243d..7a312f79340a 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
@@ -222,7 +221,7 @@ extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
extern int init_bttv_i2c(struct bttv *btv);
extern int fini_bttv_i2c(struct bttv *btv);
-#define vprintk if (bttv_verbose) printk
+#define bttv_printk if (bttv_verbose) printk
#define dprintk if (bttv_debug >= 1) printk
#define d2printk if (bttv_debug >= 2) printk
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 8c08b7f1ad23..b7ec9bf45085 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -1397,7 +1397,7 @@ static void destroy_proc_cpia_cam(struct cam_data *cam)
static void proc_cpia_create(void)
{
- cpia_proc_root = create_proc_entry("cpia", S_IFDIR, NULL);
+ cpia_proc_root = proc_mkdir("cpia", NULL);
if (cpia_proc_root)
cpia_proc_root->owner = THIS_MODULE;
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
index cdda423386c5..9774e94d1e7d 100644
--- a/drivers/media/video/cpia_usb.c
+++ b/drivers/media/video/cpia_usb.c
@@ -445,10 +445,8 @@ static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
ucpia->sbuf[1].urb = NULL;
}
- if (ucpia->sbuf[1].data) {
- kfree(ucpia->sbuf[1].data);
- ucpia->sbuf[1].data = NULL;
- }
+ kfree(ucpia->sbuf[1].data);
+ ucpia->sbuf[1].data = NULL;
if (ucpia->sbuf[0].urb) {
usb_kill_urb(ucpia->sbuf[0].urb);
@@ -456,10 +454,8 @@ static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
ucpia->sbuf[0].urb = NULL;
}
- if (ucpia->sbuf[0].data) {
- kfree(ucpia->sbuf[0].data);
- ucpia->sbuf[0].data = NULL;
- }
+ kfree(ucpia->sbuf[0].data);
+ ucpia->sbuf[0].data = NULL;
}
static int cpia_usb_close(void *privdata)
@@ -623,20 +619,14 @@ static void cpia_disconnect(struct usb_interface *intf)
ucpia->curbuff = ucpia->workbuff = NULL;
- if (ucpia->buffers[2]) {
- vfree(ucpia->buffers[2]);
- ucpia->buffers[2] = NULL;
- }
+ vfree(ucpia->buffers[2]);
+ ucpia->buffers[2] = NULL;
- if (ucpia->buffers[1]) {
- vfree(ucpia->buffers[1]);
- ucpia->buffers[1] = NULL;
- }
+ vfree(ucpia->buffers[1]);
+ ucpia->buffers[1] = NULL;
- if (ucpia->buffers[0]) {
- vfree(ucpia->buffers[0]);
- ucpia->buffers[0] = NULL;
- }
+ vfree(ucpia->buffers[0]);
+ ucpia->buffers[0] = NULL;
cam->lowlevel_data = NULL;
kfree(ucpia);
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 4f39688f780a..0c0c59e94774 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,4 @@
/*
- * $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 ebf02a7f81e8..4da91d535a5b 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 5e868f5cd0c0..dc5c5c1f3461 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 78d223257a68..4334744652de 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,24 @@ 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 */
+ 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 +235,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 +275,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 +368,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,10 +400,8 @@ 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));
+ /* Put the analog decoder in standby to keep it quiet */
+ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
/* 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 7f598039e025..761cebd40dbd 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 214887798192..d81b21d6e05d 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 fe2767c0ff94..ee2300e1ae0b 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 37f82662d265..0a3a62fc9bbb 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 91207f10bae7..2765acee0285 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 320d57888bbd..9bc6c8995581 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 5f58c103198a..3dbc074fb515 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 da65dc92787c..f48dd4353568 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 a565823330aa..cf292da8fdd5 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 1e273ff3f956..67105b9804a2 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 ca02f6f14b00..f0d43fc2632f 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 023f33056a4f..2d9ff40f0b09 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 2fb7c2d1787a..972aa5e0aeef 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 000000000000..0d30eb744e61
--- /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 __user *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 000000000000..72b70eb5da1d
--- /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 *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 __user *buf_ptr = a->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 88b71a20b602..acc7a4335e23 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 1dbe61755e9f..e5e36f3c6250 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 8be6a90358c8..639ae51a052d 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 c85348d0239f..77b627eb6483 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 eae6b529713f..711aa8e85fac 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 213740122fe6..1f456c4d76f2 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 b5bede95dbf5..c20630c82f1c 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 87734f22af7d..ae0c7a165390 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 4dd9f1b23928..463885601ab4 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 eeafa5a71d2b..badf2f9e3072 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 29e51cad2aaf..f4aee0af80e1 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 a4c2f751d097..35e5e85f669a 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 2af0cb2a731b..3ea09142ec9c 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/stradis.c b/drivers/media/video/stradis.c
index b57743571087..d4497dbae05c 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -2184,30 +2184,18 @@ static void release_saa(void)
vfree(saa->vidbuf);
vfree(saa->audbuf);
vfree(saa->osdbuf);
- if (saa->dmavid2)
- kfree((void *) saa->dmavid2);
+ kfree(saa->dmavid2);
saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
saa->dmavid2 = NULL;
- if (saa->dmadebi)
- kfree((void *) saa->dmadebi);
- if (saa->dmavid1)
- kfree((void *) saa->dmavid1);
- if (saa->dmavid2)
- kfree((void *) saa->dmavid2);
- if (saa->dmavid3)
- kfree((void *) saa->dmavid3);
- if (saa->dmaa1in)
- kfree((void *) saa->dmaa1in);
- if (saa->dmaa1out)
- kfree((void *) saa->dmaa1out);
- if (saa->dmaa2in)
- kfree((void *) saa->dmaa2in);
- if (saa->dmaa2out)
- kfree((void *) saa->dmaa2out);
- if (saa->dmaRPS1)
- kfree((void *) saa->dmaRPS1);
- if (saa->dmaRPS2)
- kfree((void *) saa->dmaRPS2);
+ kfree(saa->dmadebi);
+ kfree(saa->dmavid1);
+ kfree(saa->dmavid3);
+ kfree(saa->dmaa1in);
+ kfree(saa->dmaa1out);
+ kfree(saa->dmaa2in);
+ kfree(saa->dmaa2out);
+ kfree(saa->dmaRPS1);
+ kfree(saa->dmaRPS2);
free_irq(saa->irq, saa);
if (saa->saa7146_mem)
iounmap(saa->saa7146_mem);
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index a8b6a8df5109..c65f0c7680a2 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,4 @@
/*
- * $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 d60fc562aecd..0456dda2624d 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 cebcc1fa68d1..38bf50943798 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 3b1893c2ae3b..05572020af4d 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 de0c93aeb75d..8edd73abe1d8 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 258724b2d6d2..1c31ef52f863 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -46,7 +46,17 @@ MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
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 3c3356a01cc6..5344d5592199 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 a43301a154af..d86e08ebddfc 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 70ecbdb80277..59bb71381a1b 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 b5e0cf3448f4..597b8db35a13 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 15f5bb486963..55f129e964eb 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 5afdc7852610..574b8e36f3c6 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.
@@ -268,10 +267,10 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
kfree(dma->pages);
dma->pages = NULL;
}
- if (dma->vmalloc) {
- vfree(dma->vmalloc);
- dma->vmalloc = NULL;
- }
+
+ vfree(dma->vmalloc);
+ dma->vmalloc = NULL;
+
if (dma->bus_addr) {
dma->bus_addr = 0;
}
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 4437bdebe24f..137b58f2c666 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -203,7 +203,7 @@ static const unsigned short init_ntsc[] = {
0x8c, 640, /* Horizontal length */
0x8d, 640, /* Number of pixels */
0x8f, 0xc00, /* Disable window 2 */
- 0xf0, 0x173, /* 13.5 MHz transport, Forced
+ 0xf0, 0x73, /* 13.5 MHz transport, Forced
* mode, latch windows */
0xf2, 0x13, /* NTSC M, composite input */
0xe7, 0x1e1, /* Enable vertical standard
@@ -212,38 +212,36 @@ static const unsigned short init_ntsc[] = {
static const unsigned short init_pal[] = {
0x88, 23, /* Window 1 vertical begin */
- 0x89, 288 + 16, /* Vertical lines in (16 lines
+ 0x89, 288, /* Vertical lines in (16 lines
* skipped by the VFE) */
- 0x8a, 288 + 16, /* Vertical lines out (16 lines
+ 0x8a, 288, /* Vertical lines out (16 lines
* skipped by the VFE) */
0x8b, 16, /* Horizontal begin */
0x8c, 768, /* Horizontal length */
0x8d, 784, /* Number of pixels
* Must be >= Horizontal begin + Horizontal length */
0x8f, 0xc00, /* Disable window 2 */
- 0xf0, 0x177, /* 13.5 MHz transport, Forced
+ 0xf0, 0x77, /* 13.5 MHz transport, Forced
* mode, latch windows */
0xf2, 0x3d1, /* PAL B,G,H,I, composite input */
- 0xe7, 0x261, /* PAL/SECAM set to 288 + 16 lines
- * change to 0x241 for 288 lines */
+ 0xe7, 0x241, /* PAL/SECAM set to 288 lines */
};
static const unsigned short init_secam[] = {
- 0x88, 23 - 16, /* Window 1 vertical begin */
- 0x89, 288 + 16, /* Vertical lines in (16 lines
+ 0x88, 23, /* Window 1 vertical begin */
+ 0x89, 288, /* Vertical lines in (16 lines
* skipped by the VFE) */
- 0x8a, 288 + 16, /* Vertical lines out (16 lines
+ 0x8a, 288, /* Vertical lines out (16 lines
* skipped by the VFE) */
0x8b, 16, /* Horizontal begin */
0x8c, 768, /* Horizontal length */
0x8d, 784, /* Number of pixels
* Must be >= Horizontal begin + Horizontal length */
0x8f, 0xc00, /* Disable window 2 */
- 0xf0, 0x177, /* 13.5 MHz transport, Forced
+ 0xf0, 0x77, /* 13.5 MHz transport, Forced
* mode, latch windows */
0xf2, 0x3d5, /* SECAM, composite input */
- 0xe7, 0x261, /* PAL/SECAM set to 288 + 16 lines
- * change to 0x241 for 288 lines */
+ 0xe7, 0x241, /* PAL/SECAM set to 288 lines */
};
static const unsigned char init_common[] = {
@@ -410,6 +408,12 @@ vpx3220_command (struct i2c_client *client,
case DECODER_SET_NORM:
{
int *iarg = arg, data;
+ int temp_input;
+
+ /* Here we back up the input selection because it gets
+ overwritten when we fill the registers with the
+ choosen video norm */
+ temp_input = vpx3220_fp_read(client, 0xf2);
dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
I2C_NAME(client), *iarg);
@@ -449,6 +453,10 @@ vpx3220_command (struct i2c_client *client,
}
decoder->norm = *iarg;
+
+ /* And here we set the backed up video input again */
+ vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
+ udelay(10);
}
break;
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index ba838a42ec80..53adeb70f2ca 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -650,7 +650,7 @@ jpg_fbuffer_free (struct file *file)
off += PAGE_SIZE)
ClearPageReserved(MAP_NR
(mem + off));
- kfree((void *) mem);
+ kfree(mem);
fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
}
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
index c33533155cc7..07286816d7df 100644
--- a/drivers/media/video/zr36120.c
+++ b/drivers/media/video/zr36120.c
@@ -820,11 +820,9 @@ void zoran_close(struct video_device* dev)
msleep(100); /* Wait 1/10th of a second */
/* free the allocated framebuffer */
- if (ztv->fbuffer)
- bfree( ztv->fbuffer, ZORAN_MAX_FBUFSIZE );
+ bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
ztv->fbuffer = 0;
- if (ztv->overinfo.overlay)
- kfree( ztv->overinfo.overlay );
+ kfree(ztv->overinfo.overlay);
ztv->overinfo.overlay = 0;
}
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index 33f209a39cb6..1883d22cffeb 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -35,6 +35,23 @@ config FUSION_FC
LSIFC929X
LSIFC929XL
+config FUSION_SAS
+ tristate "Fusion MPT ScsiHost drivers for SAS"
+ depends on PCI && SCSI
+ select FUSION
+ select SCSI_SAS_ATTRS
+ ---help---
+ SCSI HOST support for a SAS host adapters.
+
+ List of supported controllers:
+
+ LSISAS1064
+ LSISAS1066
+ LSISAS1068
+ LSISAS1064E
+ LSISAS1066E
+ LSISAS1068E
+
config FUSION_MAX_SGE
int "Maximum number of scatter gather entries (16 - 128)"
depends on FUSION
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 1d2f9db813c1..8a2e2657f4c2 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -34,5 +34,6 @@
obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
obj-$(CONFIG_FUSION_FC) += mptbase.o mptscsih.o mptfc.o
+obj-$(CONFIG_FUSION_SAS) += mptbase.o mptscsih.o mptsas.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index f517d0692d5f..790a2932ded9 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -135,13 +135,12 @@ static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
-//static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
-static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
+static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
@@ -152,6 +151,7 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int GetLanConfigPages(MPT_ADAPTER *ioc);
static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
static int GetIoUnitPage2(MPT_ADAPTER *ioc);
+int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
@@ -159,6 +159,8 @@ static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
static void mpt_timer_expired(unsigned long data);
static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
+static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
+static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
#ifdef CONFIG_PROC_FS
static int procmpt_summary_read(char *buf, char **start, off_t offset,
@@ -175,6 +177,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *
static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
+static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
/* module entry point */
static int __init fusion_init (void);
@@ -206,6 +209,144 @@ pci_enable_io_access(struct pci_dev *pdev)
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
}
+/*
+ * Process turbo (context) reply...
+ */
+static void
+mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
+{
+ MPT_FRAME_HDR *mf = NULL;
+ MPT_FRAME_HDR *mr = NULL;
+ int req_idx = 0;
+ int cb_idx;
+
+ dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
+ ioc->name, pa));
+
+ switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
+ case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
+ req_idx = pa & 0x0000FFFF;
+ cb_idx = (pa & 0x00FF0000) >> 16;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+ break;
+ case MPI_CONTEXT_REPLY_TYPE_LAN:
+ cb_idx = mpt_lan_index;
+ /*
+ * Blind set of mf to NULL here was fatal
+ * after lan_reply says "freeme"
+ * Fix sort of combined with an optimization here;
+ * added explicit check for case where lan_reply
+ * was just returning 1 and doing nothing else.
+ * For this case skip the callback, but set up
+ * proper mf value first here:-)
+ */
+ if ((pa & 0x58000000) == 0x58000000) {
+ req_idx = pa & 0x0000FFFF;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+ mpt_free_msg_frame(ioc, mf);
+ mb();
+ return;
+ break;
+ }
+ mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
+ break;
+ case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
+ cb_idx = mpt_stm_index;
+ mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
+ break;
+ default:
+ cb_idx = 0;
+ BUG();
+ }
+
+ /* Check for (valid) IO callback! */
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
+ MptCallbacks[cb_idx] == NULL) {
+ printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
+ __FUNCTION__, ioc->name, cb_idx);
+ goto out;
+ }
+
+ if (MptCallbacks[cb_idx](ioc, mf, mr))
+ mpt_free_msg_frame(ioc, mf);
+ out:
+ mb();
+}
+
+static void
+mpt_reply(MPT_ADAPTER *ioc, u32 pa)
+{
+ MPT_FRAME_HDR *mf;
+ MPT_FRAME_HDR *mr;
+ int req_idx;
+ int cb_idx;
+ int freeme;
+
+ u32 reply_dma_low;
+ u16 ioc_stat;
+
+ /* non-TURBO reply! Hmmm, something may be up...
+ * Newest turbo reply mechanism; get address
+ * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
+ */
+
+ /* Map DMA address of reply header to cpu address.
+ * pa is 32 bits - but the dma address may be 32 or 64 bits
+ * get offset based only only the low addresses
+ */
+
+ reply_dma_low = (pa <<= 1);
+ mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
+ (reply_dma_low - ioc->reply_frames_low_dma));
+
+ req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
+ cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+
+ dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
+ ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
+ DBG_DUMP_REPLY_FRAME(mr)
+
+ /* Check/log IOC log info
+ */
+ ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
+ if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+ u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+ if (ioc->bus_type == FC)
+ mpt_fc_log_info(ioc, log_info);
+ else if (ioc->bus_type == SCSI)
+ mpt_sp_log_info(ioc, log_info);
+ else if (ioc->bus_type == SAS)
+ mpt_sas_log_info(ioc, log_info);
+ }
+ if (ioc_stat & MPI_IOCSTATUS_MASK) {
+ if (ioc->bus_type == SCSI &&
+ cb_idx != mpt_stm_index &&
+ cb_idx != mpt_lan_index)
+ mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
+ }
+
+
+ /* Check for (valid) IO callback! */
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
+ MptCallbacks[cb_idx] == NULL) {
+ printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
+ __FUNCTION__, ioc->name, cb_idx);
+ freeme = 0;
+ goto out;
+ }
+
+ freeme = MptCallbacks[cb_idx](ioc, mf, mr);
+
+ out:
+ /* Flush (non-TURBO) reply with a WRITE! */
+ CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
+
+ if (freeme)
+ mpt_free_msg_frame(ioc, mf);
+ mb();
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
@@ -227,164 +368,21 @@ pci_enable_io_access(struct pci_dev *pdev)
static irqreturn_t
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
{
- MPT_ADAPTER *ioc;
- MPT_FRAME_HDR *mf;
- MPT_FRAME_HDR *mr;
- u32 pa;
- int req_idx;
- int cb_idx;
- int type;
- int freeme;
-
- ioc = (MPT_ADAPTER *)bus_id;
+ MPT_ADAPTER *ioc = bus_id;
+ u32 pa;
/*
* Drain the reply FIFO!
- *
- * NOTES: I've seen up to 10 replies processed in this loop, so far...
- * Update: I've seen up to 9182 replies processed in this loop! ??
- * Update: Limit ourselves to processing max of N replies
- * (bottom of loop).
*/
while (1) {
-
- if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
+ pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
+ if (pa == 0xFFFFFFFF)
return IRQ_HANDLED;
-
- cb_idx = 0;
- freeme = 0;
-
- /*
- * Check for non-TURBO reply!
- */
- if (pa & MPI_ADDRESS_REPLY_A_BIT) {
- u32 reply_dma_low;
- u16 ioc_stat;
-
- /* non-TURBO reply! Hmmm, something may be up...
- * Newest turbo reply mechanism; get address
- * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
- */
-
- /* Map DMA address of reply header to cpu address.
- * pa is 32 bits - but the dma address may be 32 or 64 bits
- * get offset based only only the low addresses
- */
- reply_dma_low = (pa = (pa << 1));
- mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
- (reply_dma_low - ioc->reply_frames_low_dma));
-
- req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
- cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
-
- dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
- ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
- DBG_DUMP_REPLY_FRAME(mr)
-
- /* Check/log IOC log info
- */
- ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
- if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
- u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
- if (ioc->bus_type == FC)
- mpt_fc_log_info(ioc, log_info);
- else if (ioc->bus_type == SCSI)
- mpt_sp_log_info(ioc, log_info);
- }
- if (ioc_stat & MPI_IOCSTATUS_MASK) {
- if (ioc->bus_type == SCSI)
- mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
- }
- } else {
- /*
- * Process turbo (context) reply...
- */
- dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
- type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
- if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
- cb_idx = mpt_stm_index;
- mf = NULL;
- mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
- } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
- cb_idx = mpt_lan_index;
- /* Blind set of mf to NULL here was fatal
- * after lan_reply says "freeme"
- * Fix sort of combined with an optimization here;
- * added explicit check for case where lan_reply
- * was just returning 1 and doing nothing else.
- * For this case skip the callback, but set up
- * proper mf value first here:-)
- */
- if ((pa & 0x58000000) == 0x58000000) {
- req_idx = pa & 0x0000FFFF;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
- freeme = 1;
- /*
- * IMPORTANT! Invalidate the callback!
- */
- cb_idx = 0;
- } else {
- mf = NULL;
- }
- mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
- } else {
- req_idx = pa & 0x0000FFFF;
- cb_idx = (pa & 0x00FF0000) >> 16;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
- mr = NULL;
- }
- pa = 0; /* No reply flush! */
- }
-
-#ifdef MPT_DEBUG_IRQ
- if (ioc->bus_type == SCSI) {
- /* Verify mf, mr are reasonable.
- */
- if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
- || (mf < ioc->req_frames)) ) {
- printk(MYIOC_s_WARN_FMT
- "mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf);
- cb_idx = 0;
- pa = 0;
- freeme = 0;
- }
- if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
- || (mr < ioc->reply_frames)) ) {
- printk(MYIOC_s_WARN_FMT
- "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
- cb_idx = 0;
- pa = 0;
- freeme = 0;
- }
- if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
- printk(MYIOC_s_WARN_FMT
- "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
- cb_idx = 0;
- pa = 0;
- freeme = 0;
- }
- }
-#endif
-
- /* Check for (valid) IO callback! */
- if (cb_idx) {
- /* Do the callback! */
- freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
- }
-
- if (pa) {
- /* Flush (non-TURBO) reply with a WRITE! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
- }
-
- if (freeme) {
- /* Put Request back on FreeQ! */
- mpt_free_msg_frame(ioc, mf);
- }
-
- mb();
- } /* drain reply FIFO */
+ else if (pa & MPI_ADDRESS_REPLY_A_BIT)
+ mpt_reply(ioc, pa);
+ else
+ mpt_turbo_reply(ioc, pa);
+ }
return IRQ_HANDLED;
}
@@ -509,6 +507,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
pCfg->wait_done = 1;
wake_up(&mpt_waitq);
}
+ } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
+ /* we should be always getting a reply frame */
+ memcpy(ioc->persist_reply_frame, reply,
+ min(MPT_DEFAULT_FRAME_SIZE,
+ 4*reply->u.reply.MsgLength));
+ del_timer(&ioc->persist_timer);
+ ioc->persist_wait_done = 1;
+ wake_up(&mpt_waitq);
} else {
printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
ioc->name, func);
@@ -750,6 +756,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
u.frame.linkage.list);
list_del(&mf->u.frame.linkage.list);
+ mf->u.frame.linkage.arg1 = 0;
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
/* u16! */
@@ -845,6 +852,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
/* Put Request back on FreeQ! */
spin_lock_irqsave(&ioc->FreeQlock, flags);
+ mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
#ifdef MFCNT
ioc->mfcnt--;
@@ -971,12 +979,123 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
+
return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
+ * mpt_host_page_access_control - provides mechanism for the host
+ * driver to control the IOC's Host Page Buffer access.
+ * @ioc: Pointer to MPT adapter structure
+ * @access_control_value: define bits below
+ *
+ * Access Control Value - bits[15:12]
+ * 0h Reserved
+ * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
+ * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
+ * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+
+static int
+mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
+{
+ int r = 0;
+
+ /* return if in use */
+ if (CHIPREG_READ32(&ioc->chip->Doorbell)
+ & MPI_DOORBELL_ACTIVE)
+ return -1;
+
+ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+
+ CHIPREG_WRITE32(&ioc->chip->Doorbell,
+ ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
+ <<MPI_DOORBELL_FUNCTION_SHIFT) |
+ (access_control_value<<12)));
+
+ /* Wait for IOC to clear Doorbell Status bit */
+ if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
+ return -2;
+ }else
+ return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ * mpt_host_page_alloc - allocate system memory for the fw
+ * If we already allocated memory in past, then resend the same pointer.
+ * ioc@: Pointer to pointer to IOC adapter
+ * ioc_init@: Pointer to ioc init config page
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+static int
+mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
+{
+ char *psge;
+ int flags_length;
+ u32 host_page_buffer_sz=0;
+
+ if(!ioc->HostPageBuffer) {
+
+ host_page_buffer_sz =
+ le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
+
+ if(!host_page_buffer_sz)
+ return 0; /* fw doesn't need any host buffers */
+
+ /* spin till we get enough memory */
+ while(host_page_buffer_sz > 0) {
+
+ if((ioc->HostPageBuffer = pci_alloc_consistent(
+ ioc->pcidev,
+ host_page_buffer_sz,
+ &ioc->HostPageBuffer_dma)) != NULL) {
+
+ dinitprintk((MYIOC_s_INFO_FMT
+ "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
+ ioc->name,
+ ioc->HostPageBuffer,
+ ioc->HostPageBuffer_dma,
+ host_page_buffer_sz));
+ ioc->alloc_total += host_page_buffer_sz;
+ ioc->HostPageBuffer_sz = host_page_buffer_sz;
+ break;
+ }
+
+ host_page_buffer_sz -= (4*1024);
+ }
+ }
+
+ if(!ioc->HostPageBuffer) {
+ printk(MYIOC_s_ERR_FMT
+ "Failed to alloc memory for host_page_buffer!\n",
+ ioc->name);
+ return -999;
+ }
+
+ psge = (char *)&ioc_init->HostPageBufferSGE;
+ flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+ MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+ MPI_SGE_FLAGS_32_BIT_ADDRESSING |
+ MPI_SGE_FLAGS_HOST_TO_IOC |
+ MPI_SGE_FLAGS_END_OF_BUFFER;
+ if (sizeof(dma_addr_t) == sizeof(u64)) {
+ flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
+ }
+ flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
+ flags_length |= ioc->HostPageBuffer_sz;
+ mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
+ ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
+
+return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
* mpt_verify_adapter - Given a unique IOC identifier, set pointer to
* the associated MPT adapter structure.
* @iocid: IOC unique identifier (integer)
@@ -1084,7 +1203,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initilize SCSI Config Data structure
*/
- memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
+ memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
/* Initialize the running configQ head.
*/
@@ -1213,6 +1332,33 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->prod_name = "LSI53C1035";
ioc->bus_type = SCSI;
}
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
+ ioc->prod_name = "LSISAS1064";
+ ioc->bus_type = SAS;
+ ioc->errata_flag_1064 = 1;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
+ ioc->prod_name = "LSISAS1066";
+ ioc->bus_type = SAS;
+ ioc->errata_flag_1064 = 1;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
+ ioc->prod_name = "LSISAS1068";
+ ioc->bus_type = SAS;
+ ioc->errata_flag_1064 = 1;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
+ ioc->prod_name = "LSISAS1064E";
+ ioc->bus_type = SAS;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
+ ioc->prod_name = "LSISAS1066E";
+ ioc->bus_type = SAS;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
+ ioc->prod_name = "LSISAS1068E";
+ ioc->bus_type = SAS;
+ }
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -1604,8 +1750,23 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
*/
if (ret == 0) {
rc = mpt_do_upload(ioc, sleepFlag);
- if (rc != 0)
+ if (rc == 0) {
+ if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
+ /*
+ * Maintain only one pointer to FW memory
+ * so there will not be two attempt to
+ * downloadboot onboard dual function
+ * chips (mpt_adapter_disable,
+ * mpt_diag_reset)
+ */
+ ioc->cached_fw = NULL;
+ ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
+ ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
+ }
+ } else {
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
+ ret = -5;
+ }
}
}
}
@@ -1640,7 +1801,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* and we try GetLanConfigPages again...
*/
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
- if (ioc->bus_type == FC) {
+ if (ioc->bus_type == SAS) {
+
+ /* clear persistency table */
+ if(ioc->facts.IOCExceptions &
+ MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
+ ret = mptbase_sas_persist_operation(ioc,
+ MPI_SAS_OP_CLEAR_NOT_PRESENT);
+ if(ret != 0)
+ return -1;
+ }
+
+ /* Find IM volumes
+ */
+ mpt_findImVolumes(ioc);
+
+ } else if (ioc->bus_type == FC) {
/*
* Pre-fetch FC port WWN and stuff...
* (FCPortPage0_t stuff)
@@ -1783,7 +1959,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
if (ioc->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
- if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
+ if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", ret);
}
@@ -1831,9 +2007,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
}
kfree(ioc->spi_data.nvram);
- kfree(ioc->spi_data.pIocPg3);
+ kfree(ioc->raid_data.pIocPg3);
ioc->spi_data.nvram = NULL;
- ioc->spi_data.pIocPg3 = NULL;
+ ioc->raid_data.pIocPg3 = NULL;
if (ioc->spi_data.pIocPg4 != NULL) {
sz = ioc->spi_data.IocPg4Sz;
@@ -1852,6 +2028,23 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
kfree(ioc->ChainToChain);
ioc->ChainToChain = NULL;
+
+ if (ioc->HostPageBuffer != NULL) {
+ if((ret = mpt_host_page_access_control(ioc,
+ MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
+ printk(KERN_ERR MYNAM
+ ": %s: host page buffers free failed (%d)!\n",
+ __FUNCTION__, ret);
+ }
+ dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
+ ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
+ pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
+ ioc->HostPageBuffer,
+ ioc->HostPageBuffer_dma);
+ ioc->HostPageBuffer = NULL;
+ ioc->HostPageBuffer_sz = 0;
+ ioc->alloc_total -= ioc->HostPageBuffer_sz;
+ }
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2034,7 +2227,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Loop here waiting for IOC to come READY.
*/
ii = 0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
+ cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
@@ -2212,6 +2405,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
le32_to_cpu(facts->CurrentSenseBufferHighAddr);
facts->CurReplyFrameSize =
le16_to_cpu(facts->CurReplyFrameSize);
+ facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
/*
* Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
@@ -2383,13 +2577,25 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
ioc->name, ioc->upload_fw, ioc->facts.Flags));
- if (ioc->bus_type == FC)
+ if(ioc->bus_type == SAS)
+ ioc_init.MaxDevices = ioc->facts.MaxDevices;
+ else if(ioc->bus_type == FC)
ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
else
ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
-
ioc_init.MaxBuses = MPT_MAX_BUS;
-
+ dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
+ ioc->name, ioc->facts.MsgVersion));
+ if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
+ // set MsgVersion and HeaderVersion host driver was built with
+ ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
+ ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
+
+ if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
+ ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
+ } else if(mpt_host_page_alloc(ioc, &ioc_init))
+ return -99;
+ }
ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
if (sizeof(dma_addr_t) == sizeof(u64)) {
@@ -2403,17 +2609,21 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ioc_init.HostMfaHighAddr = cpu_to_le32(0);
ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
}
-
+
ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
+ ioc->facts.MaxDevices = ioc_init.MaxDevices;
+ ioc->facts.MaxBuses = ioc_init.MaxBuses;
dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
ioc->name, &ioc_init));
r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
- if (r != 0)
+ if (r != 0) {
+ printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
return r;
+ }
/* No need to byte swap the multibyte fields in the reply
* since we don't even look at it's contents.
@@ -2472,7 +2682,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
{
PortEnable_t port_enable;
MPIDefaultReply_t reply_buf;
- int ii;
+ int rc;
int req_sz;
int reply_sz;
@@ -2494,22 +2704,15 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
/* RAID FW may take a long time to enable
*/
- if (ioc->bus_type == FC) {
- ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
- reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
- } else {
- ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+ if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
+ > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
+ rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
+ } else {
+ rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+ reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
}
-
- if (ii != 0)
- return ii;
-
- /* We do not even look at the reply, so we need not
- * swap the multi-byte fields.
- */
-
- return 0;
+ return rc;
}
/*
@@ -2666,9 +2869,8 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
* <0 for fw upload failure.
*/
static int
-mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
+mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
{
- MpiFwHeader_t *pFwHeader;
MpiExtImageHeader_t *pExtImage;
u32 fwSize;
u32 diag0val;
@@ -2679,18 +2881,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
u32 load_addr;
u32 ioc_state=0;
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
- ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
-
- if ( ioc->facts.FWImageSize == 0 )
- return -1;
-
- if (ioc->cached_fw == NULL)
- return -2;
-
- /* prevent a second downloadboot and memory free with alt_ioc */
- if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
- ioc->alt_ioc->cached_fw = NULL;
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
+ ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
@@ -2718,16 +2910,17 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
ioc->name, count));
break;
}
- /* wait 1 sec */
+ /* wait .1 sec */
if (sleepFlag == CAN_SLEEP) {
- msleep_interruptible (1000);
+ msleep_interruptible (100);
} else {
- mdelay (1000);
+ mdelay (100);
}
}
if ( count == 30 ) {
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
+ "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
ioc->name, diag0val));
return -3;
}
@@ -2742,7 +2935,6 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Set the DiagRwEn and Disable ARM bits */
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
- pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
fwSize = (pFwHeader->ImageSize + 3)/4;
ptrFw = (u32 *) pFwHeader;
@@ -2792,19 +2984,38 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Clear the internal flash bad bit - autoincrementing register,
* so must do two writes.
*/
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
- diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
- diagRwData |= 0x4000000;
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
+ if (ioc->bus_type == SCSI) {
+ /*
+ * 1030 and 1035 H/W errata, workaround to access
+ * the ClearFlashBadSignatureBit
+ */
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+ diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
+ diagRwData |= 0x40000000;
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
+
+ } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
+ MPI_DIAG_CLEAR_FLASH_BAD_SIG);
+
+ /* wait 1 msec */
+ if (sleepFlag == CAN_SLEEP) {
+ msleep_interruptible (1);
+ } else {
+ mdelay (1);
+ }
+ }
if (ioc->errata_flag_1064)
pci_disable_io_access(ioc->pcidev);
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
+ "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
ioc->name, diag0val));
- diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
+ diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
@@ -2812,10 +3023,23 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Write 0xFF to reset the sequencer */
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
+ if (ioc->bus_type == SAS) {
+ ioc_state = mpt_GetIocState(ioc, 0);
+ if ( (GetIocFacts(ioc, sleepFlag,
+ MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
+ ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
+ ioc->name, ioc_state));
+ return -EFAULT;
+ }
+ }
+
for (count=0; count<HZ*20; count++) {
if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
ioc->name, count, ioc_state));
+ if (ioc->bus_type == SAS) {
+ return 0;
+ }
if ((SendIocInit(ioc, sleepFlag)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
ioc->name));
@@ -3049,12 +3273,13 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
- ssleep(1);
+ msleep_interruptible (1000);
} else {
mdelay (1000);
}
}
- if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
+ if ((count = mpt_downloadboot(ioc,
+ (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count);
}
@@ -3637,7 +3862,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0;
u32 intstat=0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
+ cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
@@ -3687,7 +3912,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0;
u32 intstat=0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
+ cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
@@ -4001,6 +4226,85 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
+ * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @sas_address: 64bit SAS Address for operation.
+ * @target_id: specified target for operation
+ * @bus: specified bus for operation
+ * @persist_opcode: see below
+ *
+ * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
+ * devices not currently present.
+ * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
+ *
+ * NOTE: Don't use not this function during interrupt time.
+ *
+ * Returns: 0 for success, non-zero error
+ */
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+int
+mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
+{
+ SasIoUnitControlRequest_t *sasIoUnitCntrReq;
+ SasIoUnitControlReply_t *sasIoUnitCntrReply;
+ MPT_FRAME_HDR *mf = NULL;
+ MPIHeader_t *mpi_hdr;
+
+
+ /* insure garbage is not sent to fw */
+ switch(persist_opcode) {
+
+ case MPI_SAS_OP_CLEAR_NOT_PRESENT:
+ case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
+
+ /* Get a MF for this command.
+ */
+ if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
+ printk("%s: no msg frames!\n",__FUNCTION__);
+ return -1;
+ }
+
+ mpi_hdr = (MPIHeader_t *) mf;
+ sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
+ memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
+ sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
+ sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
+ sasIoUnitCntrReq->Operation = persist_opcode;
+
+ init_timer(&ioc->persist_timer);
+ ioc->persist_timer.data = (unsigned long) ioc;
+ ioc->persist_timer.function = mpt_timer_expired;
+ ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
+ ioc->persist_wait_done=0;
+ add_timer(&ioc->persist_timer);
+ mpt_put_msg_frame(mpt_base_index, ioc, mf);
+ wait_event(mpt_waitq, ioc->persist_wait_done);
+
+ sasIoUnitCntrReply =
+ (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
+ if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
+ printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
+ __FUNCTION__,
+ sasIoUnitCntrReply->IOCStatus,
+ sasIoUnitCntrReply->IOCLogInfo);
+ return -1;
+ }
+
+ printk("%s: success\n",__FUNCTION__);
+ return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
* GetIoUnitPage2 - Retrieve BIOS version and boot order information.
* @ioc: Pointer to MPT_ADAPTER structure
*
@@ -4340,10 +4644,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
if (mpt_config(ioc, &cfg) != 0)
goto done_and_free;
- if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
+ if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
mem = kmalloc(iocpage2sz, GFP_ATOMIC);
if (mem) {
- ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
+ ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
} else {
goto done_and_free;
}
@@ -4360,7 +4664,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* At least 1 RAID Volume
*/
pIocRv = pIoc2->RaidVolume;
- ioc->spi_data.isRaid = 0;
+ ioc->raid_data.isRaid = 0;
for (jj = 0; jj < nVols; jj++, pIocRv++) {
vid = pIocRv->VolumeID;
vbus = pIocRv->VolumeBus;
@@ -4369,7 +4673,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* find the match
*/
if (vbus == 0) {
- ioc->spi_data.isRaid |= (1 << vid);
+ ioc->raid_data.isRaid |= (1 << vid);
} else {
/* Error! Always bus 0
*/
@@ -4404,8 +4708,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
/* Free the old page
*/
- kfree(ioc->spi_data.pIocPg3);
- ioc->spi_data.pIocPg3 = NULL;
+ kfree(ioc->raid_data.pIocPg3);
+ ioc->raid_data.pIocPg3 = NULL;
/* There is at least one physical disk.
* Read and save IOC Page 3
@@ -4442,7 +4746,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
mem = kmalloc(iocpage3sz, GFP_ATOMIC);
if (mem) {
memcpy(mem, (u8 *)pIoc3, iocpage3sz);
- ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
+ ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
}
}
@@ -5366,8 +5670,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static char *
-EventDescriptionStr(u8 event, u32 evData0)
+static void
+EventDescriptionStr(u8 event, u32 evData0, char *evStr)
{
char *ds;
@@ -5420,8 +5724,95 @@ EventDescriptionStr(u8 event, u32 evData0)
ds = "Events(OFF) Change";
break;
case MPI_EVENT_INTEGRATED_RAID:
- ds = "Integrated Raid";
+ {
+ u8 ReasonCode = (u8)(evData0 >> 16);
+ switch (ReasonCode) {
+ case MPI_EVENT_RAID_RC_VOLUME_CREATED :
+ ds = "Integrated Raid: Volume Created";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_DELETED :
+ ds = "Integrated Raid: Volume Deleted";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
+ ds = "Integrated Raid: Volume Settings Changed";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
+ ds = "Integrated Raid: Volume Status Changed";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
+ ds = "Integrated Raid: Volume Physdisk Changed";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
+ ds = "Integrated Raid: Physdisk Created";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
+ ds = "Integrated Raid: Physdisk Deleted";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
+ ds = "Integrated Raid: Physdisk Settings Changed";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
+ ds = "Integrated Raid: Physdisk Status Changed";
+ break;
+ case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
+ ds = "Integrated Raid: Domain Validation Needed";
+ break;
+ case MPI_EVENT_RAID_RC_SMART_DATA :
+ ds = "Integrated Raid; Smart Data";
+ break;
+ case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
+ ds = "Integrated Raid: Replace Action Started";
+ break;
+ default:
+ ds = "Integrated Raid";
+ break;
+ }
+ break;
+ }
+ case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
+ ds = "SCSI Device Status Change";
+ break;
+ case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
+ {
+ u8 ReasonCode = (u8)(evData0 >> 16);
+ switch (ReasonCode) {
+ case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
+ ds = "SAS Device Status Change: Added";
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
+ ds = "SAS Device Status Change: Deleted";
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
+ ds = "SAS Device Status Change: SMART Data";
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
+ ds = "SAS Device Status Change: No Persistancy Added";
+ break;
+ default:
+ ds = "SAS Device Status Change: Unknown";
+ break;
+ }
+ break;
+ }
+ case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
+ ds = "Bus Timer Expired";
+ break;
+ case MPI_EVENT_QUEUE_FULL:
+ ds = "Queue Full";
+ break;
+ case MPI_EVENT_SAS_SES:
+ ds = "SAS SES Event";
+ break;
+ case MPI_EVENT_PERSISTENT_TABLE_FULL:
+ ds = "Persistent Table Full";
+ break;
+ case MPI_EVENT_SAS_PHY_LINK_STATUS:
+ ds = "SAS PHY Link Status";
+ break;
+ case MPI_EVENT_SAS_DISCOVERY_ERROR:
+ ds = "SAS Discovery Error";
break;
+
/*
* MPT base "custom" events may be added here...
*/
@@ -5429,7 +5820,7 @@ EventDescriptionStr(u8 event, u32 evData0)
ds = "Unknown";
break;
}
- return ds;
+ strcpy(evStr,ds);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5451,7 +5842,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
int ii;
int r = 0;
int handlers = 0;
- char *evStr;
+ char evStr[100];
u8 event;
/*
@@ -5464,7 +5855,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
evData0 = le32_to_cpu(pEventReply->Data[0]);
}
- evStr = EventDescriptionStr(event, evData0);
+ EventDescriptionStr(event, evData0, evStr);
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
ioc->name,
evStr,
@@ -5481,20 +5872,6 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* Do general / base driver event processing
*/
switch(event) {
- case MPI_EVENT_NONE: /* 00 */
- case MPI_EVENT_LOG_DATA: /* 01 */
- case MPI_EVENT_STATE_CHANGE: /* 02 */
- case MPI_EVENT_UNIT_ATTENTION: /* 03 */
- case MPI_EVENT_IOC_BUS_RESET: /* 04 */
- case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- case MPI_EVENT_RESCAN: /* 06 */
- case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
- case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
- case MPI_EVENT_LOGOUT: /* 09 */
- case MPI_EVENT_INTEGRATED_RAID: /* 0B */
- case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
- default:
- break;
case MPI_EVENT_EVENT_CHANGE: /* 0A */
if (evDataLen) {
u8 evState = evData0 & 0xFF;
@@ -5507,6 +5884,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
}
}
break;
+ default:
+ break;
}
/*
@@ -5653,6 +6032,111 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
}
+/* strings for sas loginfo */
+ static char *originator_str[] = {
+ "IOP", /* 00h */
+ "PL", /* 01h */
+ "IR" /* 02h */
+ };
+ static char *iop_code_str[] = {
+ NULL, /* 00h */
+ "Invalid SAS Address", /* 01h */
+ NULL, /* 02h */
+ "Invalid Page", /* 03h */
+ NULL, /* 04h */
+ "Task Terminated" /* 05h */
+ };
+ static char *pl_code_str[] = {
+ NULL, /* 00h */
+ "Open Failure", /* 01h */
+ "Invalid Scatter Gather List", /* 02h */
+ "Wrong Relative Offset or Frame Length", /* 03h */
+ "Frame Transfer Error", /* 04h */
+ "Transmit Frame Connected Low", /* 05h */
+ "SATA Non-NCQ RW Error Bit Set", /* 06h */
+ "SATA Read Log Receive Data Error", /* 07h */
+ "SATA NCQ Fail All Commands After Error", /* 08h */
+ "SATA Error in Receive Set Device Bit FIS", /* 09h */
+ "Receive Frame Invalid Message", /* 0Ah */
+ "Receive Context Message Valid Error", /* 0Bh */
+ "Receive Frame Current Frame Error", /* 0Ch */
+ "SATA Link Down", /* 0Dh */
+ "Discovery SATA Init W IOS", /* 0Eh */
+ "Config Invalid Page", /* 0Fh */
+ "Discovery SATA Init Timeout", /* 10h */
+ "Reset", /* 11h */
+ "Abort", /* 12h */
+ "IO Not Yet Executed", /* 13h */
+ "IO Executed", /* 14h */
+ NULL, /* 15h */
+ NULL, /* 16h */
+ NULL, /* 17h */
+ NULL, /* 18h */
+ NULL, /* 19h */
+ NULL, /* 1Ah */
+ NULL, /* 1Bh */
+ NULL, /* 1Ch */
+ NULL, /* 1Dh */
+ NULL, /* 1Eh */
+ NULL, /* 1Fh */
+ "Enclosure Management" /* 20h */
+ };
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * mpt_sas_log_info - Log information returned from SAS IOC.
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @log_info: U32 LogInfo reply word from the IOC
+ *
+ * Refer to lsi/mpi_log_sas.h.
+ */
+static void
+mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
+{
+union loginfo_type {
+ u32 loginfo;
+ struct {
+ u32 subcode:16;
+ u32 code:8;
+ u32 originator:4;
+ u32 bus_type:4;
+ }dw;
+};
+ union loginfo_type sas_loginfo;
+ char *code_desc = NULL;
+
+ sas_loginfo.loginfo = log_info;
+ if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
+ (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
+ return;
+ if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
+ (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
+ code_desc = iop_code_str[sas_loginfo.dw.code];
+ }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
+ (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
+ code_desc = pl_code_str[sas_loginfo.dw.code];
+ }
+
+ if (code_desc != NULL)
+ printk(MYIOC_s_INFO_FMT
+ "LogInfo(0x%08x): Originator={%s}, Code={%s},"
+ " SubCode(0x%04x)\n",
+ ioc->name,
+ log_info,
+ originator_str[sas_loginfo.dw.originator],
+ code_desc,
+ sas_loginfo.dw.subcode);
+ else
+ printk(MYIOC_s_INFO_FMT
+ "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
+ " SubCode(0x%04x)\n",
+ ioc->name,
+ log_info,
+ originator_str[sas_loginfo.dw.originator],
+ sas_loginfo.dw.code,
+ sas_loginfo.dw.subcode);
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
@@ -5814,6 +6298,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
+EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index f4827d923731..75105277e22f 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -65,6 +65,7 @@
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
#include "lsi/mpi_tool.h" /* Tools support */
+#include "lsi/mpi_sas.h" /* SAS support */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -76,8 +77,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.03.02"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.02"
+#define MPT_LINUX_VERSION_COMMON "3.03.03"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -423,7 +424,7 @@ typedef struct _MPT_IOCTL {
/*
* Event Structure and define
*/
-#define MPTCTL_EVENT_LOG_SIZE (0x0000000A)
+#define MPTCTL_EVENT_LOG_SIZE (0x000000032)
typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */
@@ -451,16 +452,13 @@ typedef struct _mpt_ioctl_events {
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
-typedef struct _ScsiCfgData {
+typedef struct _SpiCfgData {
u32 PortFlags;
int *nvram; /* table of device NVRAM values */
- IOCPage2_t *pIocPg2; /* table of Raid Volumes */
- IOCPage3_t *pIocPg3; /* table of physical disks */
IOCPage4_t *pIocPg4; /* SEP devices addressing */
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
int IocPg4Sz; /* IOCPage4 size */
u8 dvStatus[MPT_MAX_SCSI_DEVICES];
- int isRaid; /* bit field, 1 if RAID */
u8 minSyncFactor; /* 0xFF if async */
u8 maxSyncOffset; /* 0 if async */
u8 maxBusWidth; /* 0 if narrow, 1 if wide */
@@ -472,10 +470,28 @@ typedef struct _ScsiCfgData {
u8 dvScheduled; /* 1 if scheduled */
u8 forceDv; /* 1 to force DV scheduling */
u8 noQas; /* Disable QAS for this adapter */
- u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
+ u8 Saf_Te; /* 1 to force all Processors as
+ * SAF-TE if Inquiry data length
+ * is too short to check for SAF-TE
+ */
u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
+ u8 bus_reset; /* 1 to allow bus reset */
u8 rsvd[1];
-} ScsiCfgData;
+}SpiCfgData;
+
+typedef struct _SasCfgData {
+ u8 ptClear; /* 1 to automatically clear the
+ * persistent table.
+ * 0 to disable
+ * automatic clearing.
+ */
+}SasCfgData;
+
+typedef struct _RaidCfgData {
+ IOCPage2_t *pIocPg2; /* table of Raid Volumes */
+ IOCPage3_t *pIocPg3; /* table of physical disks */
+ int isRaid; /* bit field, 1 if RAID */
+}RaidCfgData;
/*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
@@ -530,11 +546,16 @@ typedef struct _MPT_ADAPTER
u8 *sense_buf_pool;
dma_addr_t sense_buf_pool_dma;
u32 sense_buf_low_dma;
+ u8 *HostPageBuffer; /* SAS - host page buffer support */
+ u32 HostPageBuffer_sz;
+ dma_addr_t HostPageBuffer_dma;
int mtrr_reg;
struct pci_dev *pcidev; /* struct pci_dev pointer */
u8 __iomem *memmap; /* mmap address */
struct Scsi_Host *sh; /* Scsi Host pointer */
- ScsiCfgData spi_data; /* Scsi config. data */
+ SpiCfgData spi_data; /* Scsi config. data */
+ RaidCfgData raid_data; /* Raid config. data */
+ SasCfgData sas_data; /* Sas config. data */
MPT_IOCTL *ioctl; /* ioctl data pointer */
struct proc_dir_entry *ioc_dentry;
struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
@@ -554,31 +575,35 @@ typedef struct _MPT_ADAPTER
#else
u32 mfcnt;
#endif
- u32 NB_for_64_byte_frame;
+ u32 NB_for_64_byte_frame;
u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
IOCFactsReply_t facts;
PortFactsReply_t pfacts[2];
FCPortPage0_t fc_port_page0[2];
+ struct timer_list persist_timer; /* persist table timer */
+ int persist_wait_done; /* persist completion flag */
+ u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
LANPage0_t lan_cnfg_page0;
LANPage1_t lan_cnfg_page1;
- /*
+ /*
* Description: errata_flag_1064
* If a PCIX read occurs within 1 or 2 cycles after the chip receives
* a split completion for a read data, an internal address pointer incorrectly
* increments by 32 bytes
*/
- int errata_flag_1064;
+ int errata_flag_1064;
u8 FirstWhoInit;
u8 upload_fw; /* If set, do a fw upload */
u8 reload_fw; /* Force a FW Reload on next reset */
- u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
+ u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
u8 pad1[4];
int DoneCtx;
int TaskCtx;
int InternalCtx;
- struct list_head list;
+ struct list_head list;
struct net_device *netdev;
+ struct list_head sas_topology;
} MPT_ADAPTER;
/*
@@ -964,6 +989,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
+extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
/*
* Public data decl's...
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 7577c2417e2e..cb2d59d5f5af 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -1326,7 +1326,7 @@ mptctl_gettargetinfo (unsigned long arg)
*/
if (hd && hd->Targets) {
mpt_findImVolumes(ioc);
- pIoc2 = ioc->spi_data.pIocPg2;
+ pIoc2 = ioc->raid_data.pIocPg2;
for ( id = 0; id <= max_id; ) {
if ( pIoc2 && pIoc2->NumActiveVolumes ) {
if ( id == pIoc2->RaidVolume[0].VolumeID ) {
@@ -1348,7 +1348,7 @@ mptctl_gettargetinfo (unsigned long arg)
--maxWordsLeft;
goto next_id;
} else {
- pIoc3 = ioc->spi_data.pIocPg3;
+ pIoc3 = ioc->raid_data.pIocPg3;
for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
goto next_id;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 13771abea13f..a628be9bbbad 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -189,7 +189,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return -ENODEV;
+ return 0;
}
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 52794be5a95c..ed3c891e388f 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -312,7 +312,12 @@ static int
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
struct net_device *dev = ioc->netdev;
- struct mpt_lan_priv *priv = netdev_priv(dev);
+ struct mpt_lan_priv *priv;
+
+ if (dev == NULL)
+ return(1);
+ else
+ priv = netdev_priv(dev);
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
new file mode 100644
index 000000000000..7de19a84dc74
--- /dev/null
+++ b/drivers/message/fusion/mptsas.c
@@ -0,0 +1,1239 @@
+/*
+ * linux/drivers/message/fusion/mptsas.c
+ * For use with LSI Logic PCI chip/adapter(s)
+ * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
+ *
+ * Copyright (c) 1999-2005 LSI Logic Corporation
+ * (mailto:mpt_linux_developer@lsil.com)
+ * Copyright (c) 2005 Dell
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ 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 of the License.
+
+ 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.
+
+ NO WARRANTY
+ THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ solely responsible for determining the appropriateness of using and
+ distributing the Program and assumes all risks associated with its
+ exercise of rights under this Agreement, including but not limited to
+ the risks and costs of program errors, damage to or loss of data,
+ programs or equipment, and unavailability or interruption of operations.
+
+ DISCLAIMER OF LIABILITY
+ NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_sas.h>
+
+#include "mptbase.h"
+#include "mptscsih.h"
+
+
+#define my_NAME "Fusion MPT SAS Host driver"
+#define my_VERSION MPT_LINUX_VERSION_COMMON
+#define MYNAM "mptsas"
+
+MODULE_AUTHOR(MODULEAUTHOR);
+MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
+static int mpt_pq_filter;
+module_param(mpt_pq_filter, int, 0);
+MODULE_PARM_DESC(mpt_pq_filter,
+ "Enable peripheral qualifier filter: enable=1 "
+ "(default=0)");
+
+static int mpt_pt_clear;
+module_param(mpt_pt_clear, int, 0);
+MODULE_PARM_DESC(mpt_pt_clear,
+ "Clear persistency table: enable=1 "
+ "(default=MPTSCSIH_PT_CLEAR=0)");
+
+static int mptsasDoneCtx = -1;
+static int mptsasTaskCtx = -1;
+static int mptsasInternalCtx = -1; /* Used only for internal commands */
+
+
+/*
+ * SAS topology structures
+ *
+ * The MPT Fusion firmware interface spreads information about the
+ * SAS topology over many manufacture pages, thus we need some data
+ * structure to collect it and process it for the SAS transport class.
+ */
+
+struct mptsas_devinfo {
+ u16 handle; /* unique id to address this device */
+ u8 phy_id; /* phy number of parent device */
+ u8 port_id; /* sas physical port this device
+ is assoc'd with */
+ u8 target; /* logical target id of this device */
+ u8 bus; /* logical bus number of this device */
+ u64 sas_address; /* WWN of this device,
+ SATA is assigned by HBA,expander */
+ u32 device_info; /* bitfield detailed info about this device */
+};
+
+struct mptsas_phyinfo {
+ u8 phy_id; /* phy index */
+ u8 port_id; /* port number this phy is part of */
+ u8 negotiated_link_rate; /* nego'd link rate for this phy */
+ u8 hw_link_rate; /* hardware max/min phys link rate */
+ u8 programmed_link_rate; /* programmed max/min phy link rate */
+ struct mptsas_devinfo identify; /* point to phy device info */
+ struct mptsas_devinfo attached; /* point to attached device info */
+ struct sas_rphy *rphy;
+};
+
+struct mptsas_portinfo {
+ struct list_head list;
+ u16 handle; /* unique id to address this */
+ u8 num_phys; /* number of phys */
+ struct mptsas_phyinfo *phy_info;
+};
+
+/*
+ * This is pretty ugly. We will be able to seriously clean it up
+ * once the DV code in mptscsih goes away and we can properly
+ * implement ->target_alloc.
+ */
+static int
+mptsas_slave_alloc(struct scsi_device *device)
+{
+ struct Scsi_Host *host = device->host;
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
+ struct sas_rphy *rphy;
+ struct mptsas_portinfo *p;
+ VirtDevice *vdev;
+ uint target = device->id;
+ int i;
+
+ if ((vdev = hd->Targets[target]) != NULL)
+ goto out;
+
+ vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
+ if (!vdev) {
+ printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
+ hd->ioc->name, sizeof(VirtDevice));
+ return -ENOMEM;
+ }
+
+ memset(vdev, 0, sizeof(VirtDevice));
+ vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
+ vdev->ioc_id = hd->ioc->id;
+
+ rphy = dev_to_rphy(device->sdev_target->dev.parent);
+ list_for_each_entry(p, &hd->ioc->sas_topology, list) {
+ for (i = 0; i < p->num_phys; i++) {
+ if (p->phy_info[i].attached.sas_address ==
+ rphy->identify.sas_address) {
+ vdev->target_id =
+ p->phy_info[i].attached.target;
+ vdev->bus_id = p->phy_info[i].attached.bus;
+ hd->Targets[device->id] = vdev;
+ goto out;
+ }
+ }
+ }
+
+ printk("No matching SAS device found!!\n");
+ kfree(vdev);
+ return -ENODEV;
+
+ out:
+ vdev->num_luns++;
+ device->hostdata = vdev;
+ return 0;
+}
+
+static struct scsi_host_template mptsas_driver_template = {
+ .proc_name = "mptsas",
+ .proc_info = mptscsih_proc_info,
+ .name = "MPT SPI Host",
+ .info = mptscsih_info,
+ .queuecommand = mptscsih_qcmd,
+ .slave_alloc = mptsas_slave_alloc,
+ .slave_configure = mptscsih_slave_configure,
+ .slave_destroy = mptscsih_slave_destroy,
+ .change_queue_depth = mptscsih_change_queue_depth,
+ .eh_abort_handler = mptscsih_abort,
+ .eh_device_reset_handler = mptscsih_dev_reset,
+ .eh_bus_reset_handler = mptscsih_bus_reset,
+ .eh_host_reset_handler = mptscsih_host_reset,
+ .bios_param = mptscsih_bios_param,
+ .can_queue = MPT_FC_CAN_QUEUE,
+ .this_id = -1,
+ .sg_tablesize = MPT_SCSI_SG_DEPTH,
+ .max_sectors = 8192,
+ .cmd_per_lun = 7,
+ .use_clustering = ENABLE_CLUSTERING,
+};
+
+static struct sas_function_template mptsas_transport_functions = {
+};
+
+static struct scsi_transport_template *mptsas_transport_template;
+
+#ifdef SASDEBUG
+static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
+{
+ printk("---- IO UNIT PAGE 0 ------------\n");
+ printk("Handle=0x%X\n",
+ le16_to_cpu(phy_data->AttachedDeviceHandle));
+ printk("Controller Handle=0x%X\n",
+ le16_to_cpu(phy_data->ControllerDevHandle));
+ printk("Port=0x%X\n", phy_data->Port);
+ printk("Port Flags=0x%X\n", phy_data->PortFlags);
+ printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
+ printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
+ printk("Controller PHY Device Info=0x%X\n",
+ le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
+ printk("DiscoveryStatus=0x%X\n",
+ le32_to_cpu(phy_data->DiscoveryStatus));
+ printk("\n");
+}
+
+static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
+{
+ __le64 sas_address;
+
+ memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+
+ printk("---- SAS PHY PAGE 0 ------------\n");
+ printk("Attached Device Handle=0x%X\n",
+ le16_to_cpu(pg0->AttachedDevHandle));
+ printk("SAS Address=0x%llX\n",
+ (unsigned long long)le64_to_cpu(sas_address));
+ printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
+ printk("Attached Device Info=0x%X\n",
+ le32_to_cpu(pg0->AttachedDeviceInfo));
+ printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
+ printk("Change Count=0x%X\n", pg0->ChangeCount);
+ printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
+ printk("\n");
+}
+
+static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
+{
+ __le64 sas_address;
+
+ memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+
+ printk("---- SAS DEVICE PAGE 0 ---------\n");
+ printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
+ printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
+ printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
+ printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
+ printk("Target ID=0x%X\n", pg0->TargetID);
+ printk("Bus=0x%X\n", pg0->Bus);
+ printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
+ printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
+ printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
+ printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
+ printk("Physical Port=0x%X\n", pg0->PhysicalPort);
+ printk("\n");
+}
+
+static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
+{
+ printk("---- SAS EXPANDER PAGE 1 ------------\n");
+
+ printk("Physical Port=0x%X\n", pg1->PhysicalPort);
+ printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
+ printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
+ printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
+ printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
+ printk("Owner Device Handle=0x%X\n",
+ le16_to_cpu(pg1->OwnerDevHandle));
+ printk("Attached Device Handle=0x%X\n",
+ le16_to_cpu(pg1->AttachedDevHandle));
+}
+#else
+#define mptsas_print_phy_data(phy_data) do { } while (0)
+#define mptsas_print_phy_pg0(pg0) do { } while (0)
+#define mptsas_print_device_pg0(pg0) do { } while (0)
+#define mptsas_print_expander_pg1(pg1) do { } while (0)
+#endif
+
+static int
+mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasIOUnitPage0_t *buffer;
+ dma_addr_t dma_handle;
+ int error, i;
+
+ hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = 0;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ port_info->num_phys = buffer->NumPhys;
+ port_info->phy_info = kcalloc(port_info->num_phys,
+ sizeof(struct mptsas_phyinfo),GFP_KERNEL);
+ if (!port_info->phy_info) {
+ error = -ENOMEM;
+ goto out_free_consistent;
+ }
+
+ for (i = 0; i < port_info->num_phys; i++) {
+ mptsas_print_phy_data(&buffer->PhyData[i]);
+ port_info->phy_info[i].phy_id = i;
+ port_info->phy_info[i].port_id =
+ buffer->PhyData[i].Port;
+ port_info->phy_info[i].negotiated_link_rate =
+ buffer->PhyData[i].NegotiatedLinkRate;
+ }
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasPhyPage0_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
+
+ hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ /* Get Phy Pg 0 for each Phy. */
+ cfg.physAddr = -1;
+ cfg.pageAddr = form + form_specific;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ mptsas_print_phy_pg0(buffer);
+
+ phy_info->hw_link_rate = buffer->HwLinkRate;
+ phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
+ phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
+ phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasDevicePage0_t *buffer;
+ dma_addr_t dma_handle;
+ __le64 sas_address;
+ int error;
+
+ hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.pageAddr = form + form_specific;
+ cfg.physAddr = -1;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ mptsas_print_device_pg0(buffer);
+
+ device_info->handle = le16_to_cpu(buffer->DevHandle);
+ device_info->phy_id = buffer->PhyNum;
+ device_info->port_id = buffer->PhysicalPort;
+ device_info->target = buffer->TargetID;
+ device_info->bus = buffer->Bus;
+ memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
+ device_info->sas_address = le64_to_cpu(sas_address);
+ device_info->device_info =
+ le32_to_cpu(buffer->DeviceInfo);
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasExpanderPage0_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
+
+ hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = form + form_specific;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ /* save config data */
+ port_info->num_phys = buffer->NumPhys;
+ port_info->handle = le16_to_cpu(buffer->DevHandle);
+ port_info->phy_info = kcalloc(port_info->num_phys,
+ sizeof(struct mptsas_phyinfo),GFP_KERNEL);
+ if (!port_info->phy_info) {
+ error = -ENOMEM;
+ goto out_free_consistent;
+ }
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasExpanderPage1_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
+
+ hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 1;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = form + form_specific;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+
+ mptsas_print_expander_pg1(buffer);
+
+ /* save config data */
+ phy_info->phy_id = buffer->PhyIdentifier;
+ phy_info->port_id = buffer->PhysicalPort;
+ phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
+ phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
+ phy_info->hw_link_rate = buffer->HwLinkRate;
+ phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
+ phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
+
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static void
+mptsas_parse_device_info(struct sas_identify *identify,
+ struct mptsas_devinfo *device_info)
+{
+ u16 protocols;
+
+ identify->sas_address = device_info->sas_address;
+ identify->phy_identifier = device_info->phy_id;
+
+ /*
+ * Fill in Phy Initiator Port Protocol.
+ * Bits 6:3, more than one bit can be set, fall through cases.
+ */
+ protocols = device_info->device_info & 0x78;
+ identify->initiator_port_protocols = 0;
+ if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
+ if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
+
+ /*
+ * Fill in Phy Target Port Protocol.
+ * Bits 10:7, more than one bit can be set, fall through cases.
+ */
+ protocols = device_info->device_info & 0x780;
+ identify->target_port_protocols = 0;
+ if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
+ identify->target_port_protocols |= SAS_PROTOCOL_SSP;
+ if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
+ identify->target_port_protocols |= SAS_PROTOCOL_STP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
+ identify->target_port_protocols |= SAS_PROTOCOL_SMP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
+ identify->target_port_protocols |= SAS_PROTOCOL_SATA;
+
+ /*
+ * Fill in Attached device type.
+ */
+ switch (device_info->device_info &
+ MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
+ case MPI_SAS_DEVICE_INFO_NO_DEVICE:
+ identify->device_type = SAS_PHY_UNUSED;
+ break;
+ case MPI_SAS_DEVICE_INFO_END_DEVICE:
+ identify->device_type = SAS_END_DEVICE;
+ break;
+ case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
+ identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
+ break;
+ case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
+ identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
+ break;
+ }
+}
+
+static int mptsas_probe_one_phy(struct device *dev,
+ struct mptsas_phyinfo *phy_info, int index)
+{
+ struct sas_phy *port;
+ int error;
+
+ port = sas_phy_alloc(dev, index);
+ if (!port)
+ return -ENOMEM;
+
+ port->port_identifier = phy_info->port_id;
+ mptsas_parse_device_info(&port->identify, &phy_info->identify);
+
+ /*
+ * Set Negotiated link rate.
+ */
+ switch (phy_info->negotiated_link_rate) {
+ case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
+ port->negotiated_linkrate = SAS_PHY_DISABLED;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
+ port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_1_5:
+ port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_3_0:
+ port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
+ case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
+ default:
+ port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
+ break;
+ }
+
+ /*
+ * Set Max hardware link rate.
+ */
+ switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
+ case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
+ port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
+ port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Set Max programmed link rate.
+ */
+ switch (phy_info->programmed_link_rate &
+ MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
+ case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
+ port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
+ port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Set Min hardware link rate.
+ */
+ switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
+ case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
+ port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
+ port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Set Min programmed link rate.
+ */
+ switch (phy_info->programmed_link_rate &
+ MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
+ case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
+ port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
+ port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ error = sas_phy_add(port);
+ if (error) {
+ sas_phy_free(port);
+ return error;
+ }
+
+ if (phy_info->attached.handle) {
+ struct sas_rphy *rphy;
+
+ rphy = sas_rphy_alloc(port);
+ if (!rphy)
+ return 0; /* non-fatal: an rphy can be added later */
+
+ mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
+ error = sas_rphy_add(rphy);
+ if (error) {
+ sas_rphy_free(rphy);
+ return error;
+ }
+
+ phy_info->rphy = rphy;
+ }
+
+ return 0;
+}
+
+static int
+mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
+{
+ struct mptsas_portinfo *port_info;
+ u32 handle = 0xFFFF;
+ int error = -ENOMEM, i;
+
+ port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
+ if (!port_info)
+ goto out;
+ memset(port_info, 0, sizeof(*port_info));
+
+ error = mptsas_sas_io_unit_pg0(ioc, port_info);
+ if (error)
+ goto out_free_port_info;
+
+ list_add_tail(&port_info->list, &ioc->sas_topology);
+
+ for (i = 0; i < port_info->num_phys; i++) {
+ mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
+ (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
+ MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
+
+ mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
+ (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
+ port_info->phy_info[i].identify.phy_id =
+ port_info->phy_info[i].phy_id;
+ handle = port_info->phy_info[i].identify.handle;
+
+ if (port_info->phy_info[i].attached.handle) {
+ mptsas_sas_device_pg0(ioc,
+ &port_info->phy_info[i].attached,
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].attached.handle);
+ }
+
+ mptsas_probe_one_phy(&ioc->sh->shost_gendev,
+ &port_info->phy_info[i], *index);
+ (*index)++;
+ }
+
+ return 0;
+
+ out_free_port_info:
+ kfree(port_info);
+ out:
+ return error;
+}
+
+static int
+mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
+{
+ struct mptsas_portinfo *port_info, *p;
+ int error = -ENOMEM, i, j;
+
+ port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
+ if (!port_info)
+ goto out;
+ memset(port_info, 0, sizeof(*port_info));
+
+ error = mptsas_sas_expander_pg0(ioc, port_info,
+ (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
+ MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
+ if (error)
+ goto out_free_port_info;
+
+ *handle = port_info->handle;
+
+ list_add_tail(&port_info->list, &ioc->sas_topology);
+ for (i = 0; i < port_info->num_phys; i++) {
+ struct device *parent;
+
+ mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
+ (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
+ MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
+
+ if (port_info->phy_info[i].identify.handle) {
+ mptsas_sas_device_pg0(ioc,
+ &port_info->phy_info[i].identify,
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].identify.handle);
+ port_info->phy_info[i].identify.phy_id =
+ port_info->phy_info[i].phy_id;
+ }
+
+ if (port_info->phy_info[i].attached.handle) {
+ mptsas_sas_device_pg0(ioc,
+ &port_info->phy_info[i].attached,
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].attached.handle);
+ }
+
+ /*
+ * If we find a parent port handle this expander is
+ * attached to another expander, else it hangs of the
+ * HBA phys.
+ */
+ parent = &ioc->sh->shost_gendev;
+ list_for_each_entry(p, &ioc->sas_topology, list) {
+ for (j = 0; j < p->num_phys; j++) {
+ if (port_info->phy_info[i].identify.handle ==
+ p->phy_info[j].attached.handle)
+ parent = &p->phy_info[j].rphy->dev;
+ }
+ }
+
+ mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
+ (*index)++;
+ }
+
+ return 0;
+
+ out_free_port_info:
+ kfree(port_info);
+ out:
+ return error;
+}
+
+static void
+mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
+{
+ u32 handle = 0xFFFF;
+ int index = 0;
+
+ mptsas_probe_hba_phys(ioc, &index);
+ while (!mptsas_probe_expander_phys(ioc, &handle, &index))
+ ;
+}
+
+static int
+mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct Scsi_Host *sh;
+ MPT_SCSI_HOST *hd;
+ MPT_ADAPTER *ioc;
+ unsigned long flags;
+ int sz, ii;
+ int numSGE = 0;
+ int scale;
+ int ioc_cap;
+ u8 *mem;
+ int error=0;
+ int r;
+
+ r = mpt_attach(pdev,id);
+ if (r)
+ return r;
+
+ ioc = pci_get_drvdata(pdev);
+ ioc->DoneCtx = mptsasDoneCtx;
+ ioc->TaskCtx = mptsasTaskCtx;
+ ioc->InternalCtx = mptsasInternalCtx;
+
+ /* Added sanity check on readiness of the MPT adapter.
+ */
+ if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
+ printk(MYIOC_s_WARN_FMT
+ "Skipping because it's not operational!\n",
+ ioc->name);
+ return -ENODEV;
+ }
+
+ if (!ioc->active) {
+ printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
+ ioc->name);
+ return -ENODEV;
+ }
+
+ /* Sanity check - ensure at least 1 port is INITIATOR capable
+ */
+ ioc_cap = 0;
+ for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
+ if (ioc->pfacts[ii].ProtocolFlags &
+ MPI_PORTFACTS_PROTOCOL_INITIATOR)
+ ioc_cap++;
+ }
+
+ if (!ioc_cap) {
+ printk(MYIOC_s_WARN_FMT
+ "Skipping ioc=%p because SCSI Initiator mode "
+ "is NOT enabled!\n", ioc->name, ioc);
+ return 0;
+ }
+
+ sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
+ if (!sh) {
+ printk(MYIOC_s_WARN_FMT
+ "Unable to register controller with SCSI subsystem\n",
+ ioc->name);
+ return -1;
+ }
+
+ spin_lock_irqsave(&ioc->FreeQlock, flags);
+
+ /* Attach the SCSI Host to the IOC structure
+ */
+ ioc->sh = sh;
+
+ sh->io_port = 0;
+ sh->n_io_port = 0;
+ sh->irq = 0;
+
+ /* set 16 byte cdb's */
+ sh->max_cmd_len = 16;
+
+ sh->max_id = ioc->pfacts->MaxDevices + 1;
+
+ sh->transportt = mptsas_transport_template;
+
+ sh->max_lun = MPT_LAST_LUN + 1;
+ sh->max_channel = 0;
+ sh->this_id = ioc->pfacts[0].PortSCSIID;
+
+ /* Required entry.
+ */
+ sh->unique_id = ioc->id;
+
+ INIT_LIST_HEAD(&ioc->sas_topology);
+
+ /* Verify that we won't exceed the maximum
+ * number of chain buffers
+ * We can optimize: ZZ = req_sz/sizeof(SGE)
+ * For 32bit SGE's:
+ * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
+ * + (req_sz - 64)/sizeof(SGE)
+ * A slightly different algorithm is required for
+ * 64bit SGEs.
+ */
+ scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
+ if (sizeof(dma_addr_t) == sizeof(u64)) {
+ numSGE = (scale - 1) *
+ (ioc->facts.MaxChainDepth-1) + scale +
+ (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
+ sizeof(u32));
+ } else {
+ numSGE = 1 + (scale - 1) *
+ (ioc->facts.MaxChainDepth-1) + scale +
+ (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
+ sizeof(u32));
+ }
+
+ if (numSGE < sh->sg_tablesize) {
+ /* Reset this value */
+ dprintk((MYIOC_s_INFO_FMT
+ "Resetting sg_tablesize to %d from %d\n",
+ ioc->name, numSGE, sh->sg_tablesize));
+ sh->sg_tablesize = numSGE;
+ }
+
+ spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+ hd = (MPT_SCSI_HOST *) sh->hostdata;
+ hd->ioc = ioc;
+
+ /* SCSI needs scsi_cmnd lookup table!
+ * (with size equal to req_depth*PtrSz!)
+ */
+ sz = ioc->req_depth * sizeof(void *);
+ mem = kmalloc(sz, GFP_ATOMIC);
+ if (mem == NULL) {
+ error = -ENOMEM;
+ goto mptsas_probe_failed;
+ }
+
+ memset(mem, 0, sz);
+ hd->ScsiLookup = (struct scsi_cmnd **) mem;
+
+ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
+ ioc->name, hd->ScsiLookup, sz));
+
+ /* Allocate memory for the device structures.
+ * A non-Null pointer at an offset
+ * indicates a device exists.
+ * max_id = 1 + maximum id (hosts.h)
+ */
+ sz = sh->max_id * sizeof(void *);
+ mem = kmalloc(sz, GFP_ATOMIC);
+ if (mem == NULL) {
+ error = -ENOMEM;
+ goto mptsas_probe_failed;
+ }
+
+ memset(mem, 0, sz);
+ hd->Targets = (VirtDevice **) mem;
+
+ dprintk((KERN_INFO
+ " Targets @ %p, sz=%d\n", hd->Targets, sz));
+
+ /* Clear the TM flags
+ */
+ hd->tmPending = 0;
+ hd->tmState = TM_STATE_NONE;
+ hd->resetPending = 0;
+ hd->abortSCpnt = NULL;
+
+ /* Clear the pointer used to store
+ * single-threaded commands, i.e., those
+ * issued during a bus scan, dv and
+ * configuration pages.
+ */
+ hd->cmdPtr = NULL;
+
+ /* Initialize this SCSI Hosts' timers
+ * To use, set the timer expires field
+ * and add_timer
+ */
+ init_timer(&hd->timer);
+ hd->timer.data = (unsigned long) hd;
+ hd->timer.function = mptscsih_timer_expired;
+
+ hd->mpt_pq_filter = mpt_pq_filter;
+ ioc->sas_data.ptClear = mpt_pt_clear;
+
+ if (ioc->sas_data.ptClear==1) {
+ mptbase_sas_persist_operation(
+ ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
+ }
+
+ ddvprintk((MYIOC_s_INFO_FMT
+ "mpt_pq_filter %x mpt_pq_filter %x\n",
+ ioc->name,
+ mpt_pq_filter,
+ mpt_pq_filter));
+
+ init_waitqueue_head(&hd->scandv_waitq);
+ hd->scandv_wait_done = 0;
+ hd->last_queue_full = 0;
+
+ error = scsi_add_host(sh, &ioc->pcidev->dev);
+ if (error) {
+ dprintk((KERN_ERR MYNAM
+ "scsi_add_host failed\n"));
+ goto mptsas_probe_failed;
+ }
+
+ mptsas_scan_sas_topology(ioc);
+
+ return 0;
+
+mptsas_probe_failed:
+
+ mptscsih_remove(pdev);
+ return error;
+}
+
+static void __devexit mptsas_remove(struct pci_dev *pdev)
+{
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+ struct mptsas_portinfo *p, *n;
+
+ sas_remove_host(ioc->sh);
+
+ list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
+ list_del(&p->list);
+ kfree(p);
+ }
+
+ mptscsih_remove(pdev);
+}
+
+static struct pci_device_id mptsas_pci_table[] = {
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
+ PCI_ANY_ID, PCI_ANY_ID },
+ {0} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
+
+
+static struct pci_driver mptsas_driver = {
+ .name = "mptsas",
+ .id_table = mptsas_pci_table,
+ .probe = mptsas_probe,
+ .remove = __devexit_p(mptsas_remove),
+ .shutdown = mptscsih_shutdown,
+#ifdef CONFIG_PM
+ .suspend = mptscsih_suspend,
+ .resume = mptscsih_resume,
+#endif
+};
+
+static int __init
+mptsas_init(void)
+{
+ show_mptmod_ver(my_NAME, my_VERSION);
+
+ mptsas_transport_template =
+ sas_attach_transport(&mptsas_transport_functions);
+ if (!mptsas_transport_template)
+ return -ENODEV;
+
+ mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
+ mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
+ mptsasInternalCtx =
+ mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
+
+ if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
+ devtprintk((KERN_INFO MYNAM
+ ": Registered for IOC event notifications\n"));
+ }
+
+ if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
+ dprintk((KERN_INFO MYNAM
+ ": Registered for IOC reset notifications\n"));
+ }
+
+ return pci_register_driver(&mptsas_driver);
+}
+
+static void __exit
+mptsas_exit(void)
+{
+ pci_unregister_driver(&mptsas_driver);
+ sas_release_transport(mptsas_transport_template);
+
+ mpt_reset_deregister(mptsasDoneCtx);
+ mpt_event_deregister(mptsasDoneCtx);
+
+ mpt_deregister(mptsasInternalCtx);
+ mpt_deregister(mptsasTaskCtx);
+ mpt_deregister(mptsasDoneCtx);
+}
+
+module_init(mptsas_init);
+module_exit(mptsas_exit);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 4a003dc5fde8..5cb07eb224d7 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -62,6 +62,7 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
#include "mptbase.h"
#include "mptscsih.h"
@@ -93,8 +94,9 @@ typedef struct _BIG_SENSE_BUF {
#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
-#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
-#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
+#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
+#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
+#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
@@ -159,6 +161,8 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
+static struct work_struct mptscsih_persistTask;
+
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
@@ -167,6 +171,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
+static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
#endif
void mptscsih_remove(struct pci_dev *);
@@ -606,11 +611,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
sc->resid = sc->request_bufflen - xfer_cnt;
+ /*
+ * if we get a data underrun indication, yet no data was
+ * transferred and the SCSI status indicates that the
+ * command was never started, change the data underrun
+ * to success
+ */
+ if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
+ (scsi_status == MPI_SCSI_STATUS_BUSY ||
+ scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
+ scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
+ status = MPI_IOCSTATUS_SUCCESS;
+ }
+
dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
"resid=%d bufflen=%d xfer_cnt=%d\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
- status, scsi_state, scsi_status, sc->resid,
+ status, scsi_state, scsi_status, sc->resid,
sc->request_bufflen, xfer_cnt));
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
@@ -619,8 +637,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/*
* Look for + dump FCP ResponseInfo[]!
*/
- if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
- printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
+ if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
+ pScsiReply->ResponseInfo) {
+ printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
+ "FCP_ResponseInfo=%08xh\n",
+ ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
le32_to_cpu(pScsiReply->ResponseInfo));
}
@@ -661,23 +682,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
- if ( xfer_cnt >= sc->underflow ) {
- /* Sufficient data transfer occurred */
+ sc->resid = sc->request_bufflen - xfer_cnt;
+ if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
+ sc->result=DID_SOFT_ERROR << 16;
+ else /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
- } else if ( xfer_cnt == 0 ) {
- /* A CRC Error causes this condition; retry */
- sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
- (CHECK_CONDITION << 1);
- sc->sense_buffer[0] = 0x70;
- sc->sense_buffer[2] = NO_SENSE;
- sc->sense_buffer[12] = 0;
- sc->sense_buffer[13] = 0;
- } else {
- sc->result = DID_SOFT_ERROR << 16;
- }
- dreplyprintk((KERN_NOTICE
- "RESIDUAL_MISMATCH: result=%x on id=%d\n",
- sc->result, sc->device->id));
+ dreplyprintk((KERN_NOTICE
+ "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -692,7 +703,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
;
} else {
if (xfer_cnt < sc->underflow) {
- sc->result = DID_SOFT_ERROR << 16;
+ if (scsi_status == SAM_STAT_BUSY)
+ sc->result = SAM_STAT_BUSY;
+ else
+ sc->result = DID_SOFT_ERROR << 16;
}
if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
/* What to do?
@@ -717,8 +731,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
- scsi_status = pScsiReply->SCSIStatus;
- sc->result = (DID_OK << 16) | scsi_status;
+ if (scsi_status == MPI_SCSI_STATUS_BUSY)
+ sc->result = (DID_BUS_BUSY << 16) | scsi_status;
+ else
+ sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state == 0) {
;
} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -890,12 +906,13 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
SCSIIORequest_t *mf = NULL;
int ii;
int max = hd->ioc->req_depth;
+ struct scsi_cmnd *sc;
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
target, lun, max));
for (ii=0; ii < max; ii++) {
- if (hd->ScsiLookup[ii] != NULL) {
+ if ((sc = hd->ScsiLookup[ii]) != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
@@ -910,9 +927,22 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+ if (sc->use_sg) {
+ pci_unmap_sg(hd->ioc->pcidev,
+ (struct scatterlist *) sc->request_buffer,
+ sc->use_sg,
+ sc->sc_data_direction);
+ } else if (sc->request_bufflen) {
+ pci_unmap_single(hd->ioc->pcidev,
+ sc->SCp.dma_handle,
+ sc->request_bufflen,
+ sc->sc_data_direction);
+ }
+ sc->host_scribble = NULL;
+ sc->result = DID_NO_CONNECT << 16;
+ sc->scsi_done(sc);
}
}
-
return;
}
@@ -967,8 +997,10 @@ mptscsih_remove(struct pci_dev *pdev)
unsigned long flags;
int sz1;
- if(!host)
+ if(!host) {
+ mpt_detach(pdev);
return;
+ }
scsi_remove_host(host);
@@ -1256,8 +1288,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq;
- VirtDevice *pTarget;
- int target;
+ VirtDevice *pTarget = SCpnt->device->hostdata;
int lun;
u32 datalen;
u32 scsictl;
@@ -1267,12 +1298,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
int ii;
hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
- target = SCpnt->device->id;
lun = SCpnt->device->lun;
SCpnt->scsi_done = done;
- pTarget = hd->Targets[target];
-
dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
@@ -1315,7 +1343,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged.
*/
- if ( pTarget
+ if (pTarget
&& (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
@@ -1325,8 +1353,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame
*/
- pScsiReq->TargetID = (u8) target;
- pScsiReq->Bus = (u8) SCpnt->device->channel;
+ pScsiReq->TargetID = (u8) pTarget->target_id;
+ pScsiReq->Bus = pTarget->bus_id;
pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1378,7 +1406,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if (hd->ioc->bus_type == SCSI) {
- int dvStatus = hd->ioc->spi_data.dvStatus[target];
+ int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
int issueCmd = 1;
if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1426,6 +1454,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return 0;
fail:
+ hd->ScsiLookup[my_idx] = NULL;
mptscsih_freeChainBuffers(hd->ioc, my_idx);
mpt_free_msg_frame(hd->ioc, mf);
return SCSI_MLQUEUE_HOST_BUSY;
@@ -1713,24 +1742,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
MPT_FRAME_HDR *mf;
u32 ctx2abort;
int scpnt_idx;
+ int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt);
- dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
+ dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
}
ioc = hd->ioc;
- if (hd->resetPending)
+ if (hd->resetPending) {
return FAILED;
-
- printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ }
if (hd->timeouts < -1)
hd->timeouts++;
@@ -1738,16 +1766,20 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
/* Find this command
*/
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
- /* Cmd not found in ScsiLookup.
+ /* Cmd not found in ScsiLookup.
* Do OS callback.
*/
SCpnt->result = DID_RESET << 16;
- dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
+ dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
"Command not in the active list! (sc=%p)\n",
hd->ioc->name, SCpnt));
return SUCCESS;
}
+ printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
+ hd->ioc->name, SCpnt);
+ scsi_print_command(SCpnt);
+
/* Most important! Set TaskMsgContext to SCpnt's MsgContext!
* (the IO to be ABORT'd)
*
@@ -1760,38 +1792,22 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
hd->abortSCpnt = SCpnt;
- if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
+ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
- ctx2abort, 2 /* 2 second timeout */)
- < 0) {
+ ctx2abort, 2 /* 2 second timeout */);
- /* The TM request failed and the subsequent FW-reload failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
+ hd->ioc->name,
+ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
- /* We must clear our pending flag before clearing our state.
- */
+ if (retval == 0)
+ return SUCCESS;
+
+ if(retval != FAILED ) {
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
-
- /* Unmap the DMA buffers, if any. */
- if (SCpnt->use_sg) {
- pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
- SCpnt->use_sg, SCpnt->sc_data_direction);
- } else if (SCpnt->request_bufflen) {
- pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
- SCpnt->request_bufflen, SCpnt->sc_data_direction);
- }
- hd->ScsiLookup[scpnt_idx] = NULL;
- SCpnt->result = DID_RESET << 16;
- SCpnt->scsi_done(SCpnt); /* Issue the command callback */
- mptscsih_freeChainBuffers(ioc, scpnt_idx);
- mpt_free_msg_frame(ioc, mf);
- return FAILED;
}
- return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1807,11 +1823,12 @@ int
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
+ int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
+ dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
@@ -1820,24 +1837,26 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
if (hd->resetPending)
return FAILED;
- printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
+ scsi_print_command(SCpnt);
- if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->channel, SCpnt->device->id,
- 0, 0, 5 /* 5 second timeout */)
- < 0){
- /* The TM request failed and the subsequent FW-reload failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ 0, 0, 5 /* 5 second timeout */);
+
+ printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
+ hd->ioc->name,
+ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+ if (retval == 0)
+ return SUCCESS;
+
+ if(retval != FAILED ) {
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
- return FAILED;
}
-
- return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1853,41 +1872,39 @@ int
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
- spinlock_t *host_lock = SCpnt->device->host->host_lock;
+ int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
+ dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt ) );
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
+ scsi_print_command(SCpnt);
if (hd->timeouts < -1)
hd->timeouts++;
- /* We are now ready to execute the task management request. */
- if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
- SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
- < 0){
+ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+ SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
- /* The TM request failed and the subsequent FW-reload failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT
- "Error processing TaskMgmt request (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
+ hd->ioc->name,
+ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+ if (retval == 0)
+ return SUCCESS;
+
+ if(retval != FAILED ) {
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
- spin_lock_irq(host_lock);
- return FAILED;
}
-
- return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2169,7 +2186,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
vdev->raidVolume = 0;
hd->Targets[device->id] = vdev;
if (hd->ioc->bus_type == SCSI) {
- if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
+ if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO
"RAID Volume @ id %d\n", device->id));
@@ -2180,22 +2197,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
out:
vdev->num_luns++;
- return 0;
-}
-
-static int
-mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
-{
- int i;
-
- if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
- return 0;
-
- for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
- if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
- return 1;
- }
-
+ device->hostdata = vdev;
return 0;
}
@@ -2226,7 +2228,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
hd->Targets[target] = NULL;
if (hd->ioc->bus_type == SCSI) {
- if (mptscsih_is_raid_volume(hd, target)) {
+ if (mptscsih_is_phys_disk(hd->ioc, target)) {
hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
} else {
hd->ioc->spi_data.dvStatus[target] =
@@ -2439,6 +2441,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
MPT_SCSI_HOST *hd;
unsigned long flags;
+ int ii;
dtmprintk((KERN_WARNING MYNAM
": IOC %s_reset routed to SCSI host driver!\n",
@@ -2496,11 +2499,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* ScsiLookup initialization
*/
- {
- int ii;
- for (ii=0; ii < hd->ioc->req_depth; ii++)
- hd->ScsiLookup[ii] = NULL;
- }
+ for (ii=0; ii < hd->ioc->req_depth; ii++)
+ hd->ScsiLookup[ii] = NULL;
/* 2. Chain Buffer initialization
*/
@@ -2549,6 +2549,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* work queue thread to clear the persitency table */
+static void
+mptscsih_sas_persist_clear_table(void * arg)
+{
+ MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+
+ mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int
mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
{
@@ -2558,18 +2568,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event));
+ if (ioc->sh == NULL ||
+ ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
+ return 1;
+
switch (event) {
case MPI_EVENT_UNIT_ATTENTION: /* 03 */
/* FIXME! */
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- hd = NULL;
- if (ioc->sh) {
- hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
- if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
- hd->soft_resets++;
- }
+ if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
+ hd->soft_resets++;
break;
case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */
@@ -2588,69 +2598,24 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
break;
case MPI_EVENT_INTEGRATED_RAID: /* 0B */
+ {
+ pMpiEventDataRaid_t pRaidEventData =
+ (pMpiEventDataRaid_t) pEvReply->Data;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
- /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
- * if DV disabled. Need to check for target mode.
- */
- hd = NULL;
- if (ioc->sh)
- hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
-
- if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
- ScsiCfgData *pSpi;
- Ioc3PhysDisk_t *pPDisk;
- int numPDisk;
- u8 reason;
- u8 physDiskNum;
-
- reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
- if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
- /* New or replaced disk.
- * Set DV flag and schedule DV.
- */
- pSpi = &ioc->spi_data;
- physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
- ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
- if (pSpi->pIocPg3) {
- pPDisk = pSpi->pIocPg3->PhysDisk;
- numPDisk =pSpi->pIocPg3->NumPhysDisks;
-
- while (numPDisk) {
- if (physDiskNum == pPDisk->PhysDiskNum) {
- pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
- pSpi->forceDv = MPT_SCSICFG_NEED_DV;
- ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
- break;
- }
- pPDisk++;
- numPDisk--;
- }
-
- if (numPDisk == 0) {
- /* The physical disk that needs DV was not found
- * in the stored IOC Page 3. The driver must reload
- * this page. DV routine will set the NEED_DV flag for
- * all phys disks that have DV_NOT_DONE set.
- */
- pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
- ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
- }
- }
- }
- }
+ /* Domain Validation Needed */
+ if (ioc->bus_type == SCSI &&
+ pRaidEventData->ReasonCode ==
+ MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
+ mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
#endif
+ break;
+ }
-#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
- printk("Raid Event RF: ");
- {
- u32 *m = (u32 *)pEvReply;
- int ii;
- int n = (int)pEvReply->MsgLength;
- for (ii=6; ii < n; ii++)
- printk(" %08x", le32_to_cpu(m[ii]));
- printk("\n");
- }
-#endif
+ /* Persistent table is full. */
+ case MPI_EVENT_PERSISTENT_TABLE_FULL:
+ INIT_WORK(&mptscsih_persistTask,
+ mptscsih_sas_persist_clear_table,(void *)ioc);
+ schedule_work(&mptscsih_persistTask);
break;
case MPI_EVENT_NONE: /* 00 */
@@ -2687,7 +2652,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
{
int indexed_lun, lun_index;
VirtDevice *vdev;
- ScsiCfgData *pSpi;
+ SpiCfgData *pSpi;
char data_56;
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
@@ -2794,7 +2759,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
static void
mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
{
- ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+ SpiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
VirtDevice *vdev;
@@ -2973,11 +2938,13 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
static void
mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
{
+ MPT_ADAPTER *ioc = hd->ioc;
u8 cmd;
- ScsiCfgData *pSpi;
+ SpiCfgData *pSpi;
- ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
- pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
+ ddvtprintk((MYIOC_s_NOTE_FMT
+ " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+ hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
return;
@@ -2985,12 +2952,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
cmd = pReq->CDB[0];
if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
- pSpi = &hd->ioc->spi_data;
- if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
+ pSpi = &ioc->spi_data;
+ if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
/* Set NEED_DV for all hidden disks
*/
- Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
- int numPDisk = pSpi->pIocPg3->NumPhysDisks;
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
@@ -3004,6 +2971,50 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
}
}
+/* mptscsih_raid_set_dv_flags()
+ *
+ * New or replaced disk. Set DV flag and schedule DV.
+ */
+static void
+mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
+{
+ MPT_ADAPTER *ioc = hd->ioc;
+ SpiCfgData *pSpi = &ioc->spi_data;
+ Ioc3PhysDisk_t *pPDisk;
+ int numPDisk;
+
+ if (hd->negoNvram != 0)
+ return;
+
+ ddvtprintk(("DV requested for phys disk id %d\n", id));
+ if (ioc->raid_data.pIocPg3) {
+ pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+ while (numPDisk) {
+ if (id == pPDisk->PhysDiskNum) {
+ pSpi->dvStatus[pPDisk->PhysDiskID] =
+ (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+ ddvtprintk(("NEED_DV set for phys disk id %d\n",
+ pPDisk->PhysDiskID));
+ break;
+ }
+ pPDisk++;
+ numPDisk--;
+ }
+
+ if (numPDisk == 0) {
+ /* The physical disk that needs DV was not found
+ * in the stored IOC Page 3. The driver must reload
+ * this page. DV routine will set the NEED_DV flag for
+ * all phys disks that have DV_NOT_DONE set.
+ */
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+ ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
+ }
+ }
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* If no Target, bus reset on 1st I/O. Set the flag to
@@ -3091,7 +3102,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq;
SCSIDevicePage1_t *pData;
- VirtDevice *pTarget;
+ VirtDevice *pTarget=NULL;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
u16 req_idx;
@@ -3190,7 +3201,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
#endif
if (flags & MPT_SCSICFG_BLK_NEGO)
- negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
+ negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
mptscsih_setDevicePage1Flags(width, factor, offset,
&requested, &configuration, negoFlags);
@@ -4011,7 +4022,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
/* If target Ptr NULL or if this target is NOT a disk, skip.
*/
- if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
+ if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
for (lun=0; lun <= MPT_LAST_LUN; lun++) {
/* If LUN present, issue the command
*/
@@ -4106,9 +4117,9 @@ mptscsih_domainValidation(void *arg)
if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
mpt_read_ioc_pg_3(ioc);
- if (ioc->spi_data.pIocPg3) {
- Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+ if (ioc->raid_data.pIocPg3) {
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
@@ -4147,7 +4158,7 @@ mptscsih_domainValidation(void *arg)
isPhysDisk = mptscsih_is_phys_disk(ioc, id);
if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
- if (hd->ioc->spi_data.isRaid & (1 << ii)) {
+ if (hd->ioc->raid_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
}
}
@@ -4166,7 +4177,7 @@ mptscsih_domainValidation(void *arg)
if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
- if (hd->ioc->spi_data.isRaid & (1 << ii)) {
+ if (hd->ioc->raid_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
}
}
@@ -4188,21 +4199,21 @@ mptscsih_domainValidation(void *arg)
/* Search IOC page 3 to determine if this is hidden physical disk
*/
-static int
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+static int
mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
{
- if (ioc->spi_data.pIocPg3) {
- Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+ int i;
- while (numPDisk) {
- if (pPDisk->PhysDiskID == id) {
- return 1;
- }
- pPDisk++;
- numPDisk--;
- }
+ if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
+ return 0;
+
+ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+ if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+ return 1;
}
+
return 0;
}
@@ -4408,7 +4419,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Skip this ID? Set cfg.cfghdr.hdr to force config page write
*/
{
- ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+ SpiCfgData *pspi_data = &hd->ioc->spi_data;
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
/* Set the factor from nvram */
nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
@@ -4438,11 +4449,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
/* Finish iocmd inititialization - hidden or visible disk? */
- if (ioc->spi_data.pIocPg3) {
+ if (ioc->raid_data.pIocPg3) {
/* Search IOC page 3 for matching id
*/
- Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (pPDisk->PhysDiskID == id) {
@@ -4466,7 +4477,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* RAID Volume ID's may double for a physical device. If RAID but
* not a physical ID as well, skip DV.
*/
- if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
+ if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
goto target_done;
@@ -4815,6 +4826,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
notDone = 0;
if (iocmd.flags & MPT_ICFLAG_ECHO) {
bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
+ if (pbuf1[0] & 0x01)
+ iocmd.flags |= MPT_ICFLAG_EBOS;
} else {
bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
}
@@ -4911,6 +4924,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
+ if (iocmd.flags & MPT_ICFLAG_EBOS)
+ goto skip_Reserve;
+
repeat = 5;
while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
iocmd.cmd = RESERVE;
@@ -4954,6 +4970,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
}
+skip_Reserve:
mptscsih_fillbuf(pbuf1, sz, patt, 1);
iocmd.cmd = WRITE_BUFFER;
iocmd.data_dma = buf1_dma;
@@ -5198,11 +5215,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* If not an LVD bus, the adapter minSyncFactor has been
* already throttled back.
*/
+ negoFlags = hd->ioc->spi_data.noQas;
if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
width = pTarget->maxWidth;
offset = pTarget->maxOffset;
factor = pTarget->minSyncFactor;
- negoFlags = pTarget->negoFlags;
+ negoFlags |= pTarget->negoFlags;
} else {
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id];
@@ -5223,7 +5241,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
}
/* Set the negotiation flags */
- negoFlags = hd->ioc->spi_data.noQas;
if (!width)
negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 51c0255ac16e..971fda4b8b57 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/message/fusion/mptscsi.h
+ * linux/drivers/message/fusion/mptscsih.h
* High performance SCSI / Fibre Channel SCSI Host device driver.
* For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel
@@ -53,8 +53,8 @@
* SCSI Public stuff...
*/
-#define MPT_SCSI_CMD_PER_DEV_HIGH 31
-#define MPT_SCSI_CMD_PER_DEV_LOW 7
+#define MPT_SCSI_CMD_PER_DEV_HIGH 64
+#define MPT_SCSI_CMD_PER_DEV_LOW 32
#define MPT_SCSI_CMD_PER_LUN 7
@@ -77,6 +77,7 @@
#define MPTSCSIH_MAX_WIDTH 1
#define MPTSCSIH_MIN_SYNC 0x08
#define MPTSCSIH_SAF_TE 0
+#define MPTSCSIH_PT_CLEAR 0
#endif
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 587d1274fd74..5c0e307d1d5d 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -199,7 +199,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return -ENODEV;
+ return 0;
}
sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
index af32ab4e90cd..10432f665201 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/message/i2o/config-osm.c
@@ -56,8 +56,11 @@ static int __init i2o_config_init(void)
return -EBUSY;
}
#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
- if (i2o_config_old_init())
+ if (i2o_config_old_init()) {
+ osm_err("old config handler initialization failed\n");
i2o_driver_unregister(&i2o_config_driver);
+ return -EBUSY;
+ }
#endif
return 0;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 1588a59e3767..550f29744812 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -13,4 +13,13 @@ config MCP_SA11X0
depends on ARCH_SA1100
select MCP
+# Chip drivers
+config MCP_UCB1200
+ tristate "Support for UCB1200 / UCB1300"
+ depends on MCP
+
+config MCP_UCB1200_TS
+ tristate "Touchscreen interface support"
+ depends on MCP_UCB1200 && INPUT
+
endmenu
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 98bdd6a42188..adb29b5368a8 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -4,3 +4,9 @@
obj-$(CONFIG_MCP) += mcp-core.o
obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
+
+ifeq ($(CONFIG_SA1100_ASSABET),y)
+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+endif
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
new file mode 100644
index 000000000000..e325fa71f38b
--- /dev/null
+++ b/drivers/mfd/ucb1x00-assabet.c
@@ -0,0 +1,73 @@
+/*
+ * linux/drivers/mfd/ucb1x00-assabet.c
+ *
+ * Copyright (C) 2001-2003 Russell King, 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.
+ *
+ * We handle the machine-specific bits of the UCB1x00 driver here.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/device.h>
+
+#include <asm/dma.h>
+
+#include "ucb1x00.h"
+
+#define UCB1X00_ATTR(name,input)\
+static ssize_t name##_show(struct class_device *dev, char *buf) \
+{ \
+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
+ int val; \
+ ucb1x00_adc_enable(ucb); \
+ val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
+ ucb1x00_adc_disable(ucb); \
+ return sprintf(buf, "%d\n", val); \
+} \
+static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL)
+
+UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1);
+UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0);
+UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
+
+static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
+{
+ class_device_create_file(&dev->ucb->cdev, &class_device_attr_vbatt);
+ class_device_create_file(&dev->ucb->cdev, &class_device_attr_vcharger);
+ class_device_create_file(&dev->ucb->cdev, &class_device_attr_batt_temp);
+ return 0;
+}
+
+static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
+{
+ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_batt_temp);
+ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vcharger);
+ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vbatt);
+}
+
+static struct ucb1x00_driver ucb1x00_assabet_driver = {
+ .add = ucb1x00_assabet_add,
+ .remove = ucb1x00_assabet_remove,
+};
+
+static int __init ucb1x00_assabet_init(void)
+{
+ return ucb1x00_register_driver(&ucb1x00_assabet_driver);
+}
+
+static void __exit ucb1x00_assabet_exit(void)
+{
+ ucb1x00_unregister_driver(&ucb1x00_assabet_driver);
+}
+
+module_init(ucb1x00_assabet_init);
+module_exit(ucb1x00_assabet_exit);
+
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
new file mode 100644
index 000000000000..e335d54c4659
--- /dev/null
+++ b/drivers/mfd/ucb1x00-core.c
@@ -0,0 +1,663 @@
+/*
+ * linux/drivers/mfd/ucb1x00-core.c
+ *
+ * Copyright (C) 2001 Russell King, 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.
+ *
+ * The UCB1x00 core driver provides basic services for handling IO,
+ * the ADC, interrupts, and accessing registers. It is designed
+ * such that everything goes through this layer, thereby providing
+ * a consistent locking methodology, as well as allowing the drivers
+ * to be used on other non-MCP-enabled hardware platforms.
+ *
+ * Note that all locks are private to this file. Nothing else may
+ * touch them.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/dma.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include "ucb1x00.h"
+
+static DECLARE_MUTEX(ucb1x00_sem);
+static LIST_HEAD(ucb1x00_drivers);
+static LIST_HEAD(ucb1x00_devices);
+
+/**
+ * ucb1x00_io_set_dir - set IO direction
+ * @ucb: UCB1x00 structure describing chip
+ * @in: bitfield of IO pins to be set as inputs
+ * @out: bitfield of IO pins to be set as outputs
+ *
+ * Set the IO direction of the ten general purpose IO pins on
+ * the UCB1x00 chip. The @in bitfield has priority over the
+ * @out bitfield, in that if you specify a pin as both input
+ * and output, it will end up as an input.
+ *
+ * ucb1x00_enable must have been called to enable the comms
+ * before using this function.
+ *
+ * This function takes a spinlock, disabling interrupts.
+ */
+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ ucb->io_dir |= out;
+ ucb->io_dir &= ~in;
+
+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+ spin_unlock_irqrestore(&ucb->io_lock, flags);
+}
+
+/**
+ * ucb1x00_io_write - set or clear IO outputs
+ * @ucb: UCB1x00 structure describing chip
+ * @set: bitfield of IO pins to set to logic '1'
+ * @clear: bitfield of IO pins to set to logic '0'
+ *
+ * Set the IO output state of the specified IO pins. The value
+ * is retained if the pins are subsequently configured as inputs.
+ * The @clear bitfield has priority over the @set bitfield -
+ * outputs will be cleared.
+ *
+ * ucb1x00_enable must have been called to enable the comms
+ * before using this function.
+ *
+ * This function takes a spinlock, disabling interrupts.
+ */
+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ ucb->io_out |= set;
+ ucb->io_out &= ~clear;
+
+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+ spin_unlock_irqrestore(&ucb->io_lock, flags);
+}
+
+/**
+ * ucb1x00_io_read - read the current state of the IO pins
+ * @ucb: UCB1x00 structure describing chip
+ *
+ * Return a bitfield describing the logic state of the ten
+ * general purpose IO pins.
+ *
+ * ucb1x00_enable must have been called to enable the comms
+ * before using this function.
+ *
+ * This function does not take any semaphores or spinlocks.
+ */
+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
+{
+ return ucb1x00_reg_read(ucb, UCB_IO_DATA);
+}
+
+/*
+ * UCB1300 data sheet says we must:
+ * 1. enable ADC => 5us (including reference startup time)
+ * 2. select input => 51*tsibclk => 4.3us
+ * 3. start conversion => 102*tsibclk => 8.5us
+ * (tsibclk = 1/11981000)
+ * Period between SIB 128-bit frames = 10.7us
+ */
+
+/**
+ * ucb1x00_adc_enable - enable the ADC converter
+ * @ucb: UCB1x00 structure describing chip
+ *
+ * Enable the ucb1x00 and ADC converter on the UCB1x00 for use.
+ * Any code wishing to use the ADC converter must call this
+ * function prior to using it.
+ *
+ * This function takes the ADC semaphore to prevent two or more
+ * concurrent uses, and therefore may sleep. As a result, it
+ * can only be called from process context, not interrupt
+ * context.
+ *
+ * You should release the ADC as soon as possible using
+ * ucb1x00_adc_disable.
+ */
+void ucb1x00_adc_enable(struct ucb1x00 *ucb)
+{
+ down(&ucb->adc_sem);
+
+ ucb->adc_cr |= UCB_ADC_ENA;
+
+ ucb1x00_enable(ucb);
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
+}
+
+/**
+ * ucb1x00_adc_read - read the specified ADC channel
+ * @ucb: UCB1x00 structure describing chip
+ * @adc_channel: ADC channel mask
+ * @sync: wait for syncronisation pulse.
+ *
+ * Start an ADC conversion and wait for the result. Note that
+ * synchronised ADC conversions (via the ADCSYNC pin) must wait
+ * until the trigger is asserted and the conversion is finished.
+ *
+ * This function currently spins waiting for the conversion to
+ * complete (2 frames max without sync).
+ *
+ * If called for a synchronised ADC conversion, it may sleep
+ * with the ADC semaphore held.
+ */
+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
+{
+ unsigned int val;
+
+ if (sync)
+ adc_channel |= UCB_ADC_SYNC_ENA;
+
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel);
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START);
+
+ for (;;) {
+ val = ucb1x00_reg_read(ucb, UCB_ADC_DATA);
+ if (val & UCB_ADC_DAT_VAL)
+ break;
+ /* yield to other processes */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
+ return UCB_ADC_DAT(val);
+}
+
+/**
+ * ucb1x00_adc_disable - disable the ADC converter
+ * @ucb: UCB1x00 structure describing chip
+ *
+ * Disable the ADC converter and release the ADC semaphore.
+ */
+void ucb1x00_adc_disable(struct ucb1x00 *ucb)
+{
+ ucb->adc_cr &= ~UCB_ADC_ENA;
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
+ ucb1x00_disable(ucb);
+
+ up(&ucb->adc_sem);
+}
+
+/*
+ * UCB1x00 Interrupt handling.
+ *
+ * The UCB1x00 can generate interrupts when the SIBCLK is stopped.
+ * Since we need to read an internal register, we must re-enable
+ * SIBCLK to talk to the chip. We leave the clock running until
+ * we have finished processing all interrupts from the chip.
+ */
+static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
+{
+ struct ucb1x00 *ucb = devid;
+ struct ucb1x00_irq *irq;
+ unsigned int isr, i;
+
+ ucb1x00_enable(ucb);
+ isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
+
+ for (i = 0, irq = ucb->irq_handler; i < 16 && isr; i++, isr >>= 1, irq++)
+ if (isr & 1 && irq->fn)
+ irq->fn(i, irq->devid);
+ ucb1x00_disable(ucb);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * ucb1x00_hook_irq - hook a UCB1x00 interrupt
+ * @ucb: UCB1x00 structure describing chip
+ * @idx: interrupt index
+ * @fn: function to call when interrupt is triggered
+ * @devid: device id to pass to interrupt handler
+ *
+ * Hook the specified interrupt. You can only register one handler
+ * for each interrupt source. The interrupt source is not enabled
+ * by this function; use ucb1x00_enable_irq instead.
+ *
+ * Interrupt handlers will be called with other interrupts enabled.
+ *
+ * Returns zero on success, or one of the following errors:
+ * -EINVAL if the interrupt index is invalid
+ * -EBUSY if the interrupt has already been hooked
+ */
+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
+{
+ struct ucb1x00_irq *irq;
+ int ret = -EINVAL;
+
+ if (idx < 16) {
+ irq = ucb->irq_handler + idx;
+ ret = -EBUSY;
+
+ spin_lock_irq(&ucb->lock);
+ if (irq->fn == NULL) {
+ irq->devid = devid;
+ irq->fn = fn;
+ ret = 0;
+ }
+ spin_unlock_irq(&ucb->lock);
+ }
+ return ret;
+}
+
+/**
+ * ucb1x00_enable_irq - enable an UCB1x00 interrupt source
+ * @ucb: UCB1x00 structure describing chip
+ * @idx: interrupt index
+ * @edges: interrupt edges to enable
+ *
+ * Enable the specified interrupt to trigger on %UCB_RISING,
+ * %UCB_FALLING or both edges. The interrupt should have been
+ * hooked by ucb1x00_hook_irq.
+ */
+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
+{
+ unsigned long flags;
+
+ if (idx < 16) {
+ spin_lock_irqsave(&ucb->lock, flags);
+
+ ucb1x00_enable(ucb);
+ if (edges & UCB_RISING) {
+ ucb->irq_ris_enbl |= 1 << idx;
+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+ }
+ if (edges & UCB_FALLING) {
+ ucb->irq_fal_enbl |= 1 << idx;
+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+ }
+ ucb1x00_disable(ucb);
+ spin_unlock_irqrestore(&ucb->lock, flags);
+ }
+}
+
+/**
+ * ucb1x00_disable_irq - disable an UCB1x00 interrupt source
+ * @ucb: UCB1x00 structure describing chip
+ * @edges: interrupt edges to disable
+ *
+ * Disable the specified interrupt triggering on the specified
+ * (%UCB_RISING, %UCB_FALLING or both) edges.
+ */
+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
+{
+ unsigned long flags;
+
+ if (idx < 16) {
+ spin_lock_irqsave(&ucb->lock, flags);
+
+ ucb1x00_enable(ucb);
+ if (edges & UCB_RISING) {
+ ucb->irq_ris_enbl &= ~(1 << idx);
+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+ }
+ if (edges & UCB_FALLING) {
+ ucb->irq_fal_enbl &= ~(1 << idx);
+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+ }
+ ucb1x00_disable(ucb);
+ spin_unlock_irqrestore(&ucb->lock, flags);
+ }
+}
+
+/**
+ * ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
+ * @ucb: UCB1x00 structure describing chip
+ * @idx: interrupt index
+ * @devid: device id.
+ *
+ * Disable the interrupt source and remove the handler. devid must
+ * match the devid passed when hooking the interrupt.
+ *
+ * Returns zero on success, or one of the following errors:
+ * -EINVAL if the interrupt index is invalid
+ * -ENOENT if devid does not match
+ */
+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
+{
+ struct ucb1x00_irq *irq;
+ int ret;
+
+ if (idx >= 16)
+ goto bad;
+
+ irq = ucb->irq_handler + idx;
+ ret = -ENOENT;
+
+ spin_lock_irq(&ucb->lock);
+ if (irq->devid == devid) {
+ ucb->irq_ris_enbl &= ~(1 << idx);
+ ucb->irq_fal_enbl &= ~(1 << idx);
+
+ ucb1x00_enable(ucb);
+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+ ucb1x00_disable(ucb);
+
+ irq->fn = NULL;
+ irq->devid = NULL;
+ ret = 0;
+ }
+ spin_unlock_irq(&ucb->lock);
+ return ret;
+
+bad:
+ printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx);
+ return -EINVAL;
+}
+
+static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
+{
+ struct ucb1x00_dev *dev;
+ int ret = -ENOMEM;
+
+ dev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL);
+ if (dev) {
+ dev->ucb = ucb;
+ dev->drv = drv;
+
+ ret = drv->add(dev);
+
+ if (ret == 0) {
+ list_add(&dev->dev_node, &ucb->devs);
+ list_add(&dev->drv_node, &drv->devs);
+ } else {
+ kfree(dev);
+ }
+ }
+ return ret;
+}
+
+static void ucb1x00_remove_dev(struct ucb1x00_dev *dev)
+{
+ dev->drv->remove(dev);
+ list_del(&dev->dev_node);
+ list_del(&dev->drv_node);
+ kfree(dev);
+}
+
+/*
+ * Try to probe our interrupt, rather than relying on lots of
+ * hard-coded machine dependencies. For reference, the expected
+ * IRQ mappings are:
+ *
+ * Machine Default IRQ
+ * adsbitsy IRQ_GPCIN4
+ * cerf IRQ_GPIO_UCB1200_IRQ
+ * flexanet IRQ_GPIO_GUI
+ * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ
+ * graphicsclient ADS_EXT_IRQ(8)
+ * graphicsmaster ADS_EXT_IRQ(8)
+ * lart LART_IRQ_UCB1200
+ * omnimeter IRQ_GPIO23
+ * pfs168 IRQ_GPIO_UCB1300_IRQ
+ * simpad IRQ_GPIO_UCB1300_IRQ
+ * shannon SHANNON_IRQ_GPIO_IRQ_CODEC
+ * yopy IRQ_GPIO_UCB1200_IRQ
+ */
+static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
+{
+ unsigned long mask;
+
+ mask = probe_irq_on();
+ if (!mask)
+ return NO_IRQ;
+
+ /*
+ * Enable the ADC interrupt.
+ */
+ ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
+ ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
+
+ /*
+ * Cause an ADC interrupt.
+ */
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
+
+ /*
+ * Wait for the conversion to complete.
+ */
+ while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0);
+ ucb1x00_reg_write(ucb, UCB_ADC_CR, 0);
+
+ /*
+ * Disable and clear interrupt.
+ */
+ ucb1x00_reg_write(ucb, UCB_IE_RIS, 0);
+ ucb1x00_reg_write(ucb, UCB_IE_FAL, 0);
+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
+
+ /*
+ * Read triggered interrupt.
+ */
+ return probe_irq_off(mask);
+}
+
+static void ucb1x00_release(struct class_device *dev)
+{
+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
+ kfree(ucb);
+}
+
+static struct class ucb1x00_class = {
+ .name = "ucb1x00",
+ .release = ucb1x00_release,
+};
+
+static int ucb1x00_probe(struct mcp *mcp)
+{
+ struct ucb1x00 *ucb;
+ struct ucb1x00_driver *drv;
+ unsigned int id;
+ int ret = -ENODEV;
+
+ mcp_enable(mcp);
+ id = mcp_reg_read(mcp, UCB_ID);
+
+ if (id != UCB_ID_1200 && id != UCB_ID_1300) {
+ printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
+ goto err_disable;
+ }
+
+ ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
+ ret = -ENOMEM;
+ if (!ucb)
+ goto err_disable;
+
+ memset(ucb, 0, sizeof(struct ucb1x00));
+
+ ucb->cdev.class = &ucb1x00_class;
+ ucb->cdev.dev = &mcp->attached_device;
+ strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id));
+
+ spin_lock_init(&ucb->lock);
+ spin_lock_init(&ucb->io_lock);
+ sema_init(&ucb->adc_sem, 1);
+
+ ucb->id = id;
+ ucb->mcp = mcp;
+ ucb->irq = ucb1x00_detect_irq(ucb);
+ if (ucb->irq == NO_IRQ) {
+ printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
+ ret = -ENODEV;
+ goto err_free;
+ }
+
+ ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb);
+ if (ret) {
+ printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
+ ucb->irq, ret);
+ goto err_free;
+ }
+
+ set_irq_type(ucb->irq, IRQT_RISING);
+ mcp_set_drvdata(mcp, ucb);
+
+ ret = class_device_register(&ucb->cdev);
+ if (ret)
+ goto err_irq;
+
+ INIT_LIST_HEAD(&ucb->devs);
+ down(&ucb1x00_sem);
+ list_add(&ucb->node, &ucb1x00_devices);
+ list_for_each_entry(drv, &ucb1x00_drivers, node) {
+ ucb1x00_add_dev(ucb, drv);
+ }
+ up(&ucb1x00_sem);
+ goto out;
+
+ err_irq:
+ free_irq(ucb->irq, ucb);
+ err_free:
+ kfree(ucb);
+ err_disable:
+ mcp_disable(mcp);
+ out:
+ return ret;
+}
+
+static void ucb1x00_remove(struct mcp *mcp)
+{
+ struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
+ struct list_head *l, *n;
+
+ down(&ucb1x00_sem);
+ list_del(&ucb->node);
+ list_for_each_safe(l, n, &ucb->devs) {
+ struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node);
+ ucb1x00_remove_dev(dev);
+ }
+ up(&ucb1x00_sem);
+
+ free_irq(ucb->irq, ucb);
+ class_device_unregister(&ucb->cdev);
+}
+
+int ucb1x00_register_driver(struct ucb1x00_driver *drv)
+{
+ struct ucb1x00 *ucb;
+
+ INIT_LIST_HEAD(&drv->devs);
+ down(&ucb1x00_sem);
+ list_add(&drv->node, &ucb1x00_drivers);
+ list_for_each_entry(ucb, &ucb1x00_devices, node) {
+ ucb1x00_add_dev(ucb, drv);
+ }
+ up(&ucb1x00_sem);
+ return 0;
+}
+
+void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
+{
+ struct list_head *n, *l;
+
+ down(&ucb1x00_sem);
+ list_del(&drv->node);
+ list_for_each_safe(l, n, &drv->devs) {
+ struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node);
+ ucb1x00_remove_dev(dev);
+ }
+ up(&ucb1x00_sem);
+}
+
+static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
+{
+ struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
+ struct ucb1x00_dev *dev;
+
+ down(&ucb1x00_sem);
+ list_for_each_entry(dev, &ucb->devs, dev_node) {
+ if (dev->drv->suspend)
+ dev->drv->suspend(dev, state);
+ }
+ up(&ucb1x00_sem);
+ return 0;
+}
+
+static int ucb1x00_resume(struct mcp *mcp)
+{
+ struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
+ struct ucb1x00_dev *dev;
+
+ down(&ucb1x00_sem);
+ list_for_each_entry(dev, &ucb->devs, dev_node) {
+ if (dev->drv->resume)
+ dev->drv->resume(dev);
+ }
+ up(&ucb1x00_sem);
+ return 0;
+}
+
+static struct mcp_driver ucb1x00_driver = {
+ .drv = {
+ .name = "ucb1x00",
+ },
+ .probe = ucb1x00_probe,
+ .remove = ucb1x00_remove,
+ .suspend = ucb1x00_suspend,
+ .resume = ucb1x00_resume,
+};
+
+static int __init ucb1x00_init(void)
+{
+ int ret = class_register(&ucb1x00_class);
+ if (ret == 0) {
+ ret = mcp_driver_register(&ucb1x00_driver);
+ if (ret)
+ class_unregister(&ucb1x00_class);
+ }
+ return ret;
+}
+
+static void __exit ucb1x00_exit(void)
+{
+ mcp_driver_unregister(&ucb1x00_driver);
+ class_unregister(&ucb1x00_class);
+}
+
+module_init(ucb1x00_init);
+module_exit(ucb1x00_exit);
+
+EXPORT_SYMBOL(ucb1x00_io_set_dir);
+EXPORT_SYMBOL(ucb1x00_io_write);
+EXPORT_SYMBOL(ucb1x00_io_read);
+
+EXPORT_SYMBOL(ucb1x00_adc_enable);
+EXPORT_SYMBOL(ucb1x00_adc_read);
+EXPORT_SYMBOL(ucb1x00_adc_disable);
+
+EXPORT_SYMBOL(ucb1x00_hook_irq);
+EXPORT_SYMBOL(ucb1x00_free_irq);
+EXPORT_SYMBOL(ucb1x00_enable_irq);
+EXPORT_SYMBOL(ucb1x00_disable_irq);
+
+EXPORT_SYMBOL(ucb1x00_register_driver);
+EXPORT_SYMBOL(ucb1x00_unregister_driver);
+
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("UCB1x00 core driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
new file mode 100644
index 000000000000..a260f83bcb02
--- /dev/null
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -0,0 +1,399 @@
+/*
+ * Touchscreen driver for UCB1x00-based touchscreens
+ *
+ * Copyright (C) 2001 Russell King, All Rights Reserved.
+ * Copyright (C) 2005 Pavel Machek
+ *
+ * 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.
+ *
+ * 21-Jan-2002 <jco@ict.es> :
+ *
+ * Added support for synchronous A/D mode. This mode is useful to
+ * avoid noise induced in the touchpanel by the LCD, provided that
+ * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
+ * It is important to note that the signal connected to the ADCSYNC
+ * pin should provide pulses even when the LCD is blanked, otherwise
+ * a pen touch needed to unblank the LCD will never be read.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+
+#include <asm/dma.h>
+#include <asm/semaphore.h>
+
+#include "ucb1x00.h"
+
+
+struct ucb1x00_ts {
+ struct input_dev idev;
+ struct ucb1x00 *ucb;
+
+ wait_queue_head_t irq_wait;
+ struct task_struct *rtask;
+ u16 x_res;
+ u16 y_res;
+
+ unsigned int restart:1;
+ unsigned int adcsync:1;
+};
+
+static int adcsync;
+
+static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
+{
+ input_report_abs(&ts->idev, ABS_X, x);
+ input_report_abs(&ts->idev, ABS_Y, y);
+ input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
+ input_sync(&ts->idev);
+}
+
+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
+{
+ input_report_abs(&ts->idev, ABS_PRESSURE, 0);
+ input_sync(&ts->idev);
+}
+
+/*
+ * Switch to interrupt mode.
+ */
+static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
+{
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_INT);
+}
+
+/*
+ * Switch to pressure mode, and read pressure. We don't need to wait
+ * here, since both plates are being driven.
+ */
+static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
+{
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+}
+
+/*
+ * Switch to X position mode and measure Y plate. We switch the plate
+ * configuration in pressure mode, then switch to position mode. This
+ * gives a faster response time. Even so, we need to wait about 55us
+ * for things to stabilise.
+ */
+static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
+{
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+ udelay(55);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+}
+
+/*
+ * Switch to Y position mode and measure X plate. We switch the plate
+ * configuration in pressure mode, then switch to position mode. This
+ * gives a faster response time. Even so, we need to wait about 55us
+ * for things to stabilise.
+ */
+static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
+{
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+ udelay(55);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
+}
+
+/*
+ * Switch to X plate resistance mode. Set MX to ground, PX to
+ * supply. Measure current.
+ */
+static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
+{
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
+}
+
+/*
+ * Switch to Y plate resistance mode. Set MY to ground, PY to
+ * supply. Measure current.
+ */
+static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
+{
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
+}
+
+/*
+ * This is a RT kernel thread that handles the ADC accesses
+ * (mainly so we can use semaphores in the UCB1200 core code
+ * to serialise accesses to the ADC).
+ */
+static int ucb1x00_thread(void *_ts)
+{
+ struct ucb1x00_ts *ts = _ts;
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+ int valid;
+
+ /*
+ * We could run as a real-time thread. However, thus far
+ * this doesn't seem to be necessary.
+ */
+// tsk->policy = SCHED_FIFO;
+// tsk->rt_priority = 1;
+
+ valid = 0;
+
+ add_wait_queue(&ts->irq_wait, &wait);
+ while (!kthread_should_stop()) {
+ unsigned int x, y, p, val;
+ signed long timeout;
+
+ ts->restart = 0;
+
+ ucb1x00_adc_enable(ts->ucb);
+
+ x = ucb1x00_ts_read_xpos(ts);
+ y = ucb1x00_ts_read_ypos(ts);
+ p = ucb1x00_ts_read_pressure(ts);
+
+ /*
+ * Switch back to interrupt mode.
+ */
+ ucb1x00_ts_mode_int(ts);
+ ucb1x00_adc_disable(ts->ucb);
+
+ msleep(10);
+
+ ucb1x00_enable(ts->ucb);
+ val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
+
+ if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+
+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+ ucb1x00_disable(ts->ucb);
+
+ /*
+ * If we spat out a valid sample set last time,
+ * spit out a "pen off" sample here.
+ */
+ if (valid) {
+ ucb1x00_ts_event_release(ts);
+ valid = 0;
+ }
+
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ } else {
+ ucb1x00_disable(ts->ucb);
+
+ /*
+ * Filtering is policy. Policy belongs in user
+ * space. We therefore leave it to user space
+ * to do any filtering they please.
+ */
+ if (!ts->restart) {
+ ucb1x00_ts_evt_add(ts, p, x, y);
+ valid = 1;
+ }
+
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+ timeout = HZ / 100;
+ }
+
+ try_to_freeze();
+
+ schedule_timeout(timeout);
+ }
+
+ remove_wait_queue(&ts->irq_wait, &wait);
+
+ ts->rtask = NULL;
+ return 0;
+}
+
+/*
+ * We only detect touch screen _touches_ with this interrupt
+ * handler, and even then we just schedule our task.
+ */
+static void ucb1x00_ts_irq(int idx, void *id)
+{
+ struct ucb1x00_ts *ts = id;
+ ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+ wake_up(&ts->irq_wait);
+}
+
+static int ucb1x00_ts_open(struct input_dev *idev)
+{
+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
+ int ret = 0;
+
+ BUG_ON(ts->rtask);
+
+ init_waitqueue_head(&ts->irq_wait);
+ ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
+ if (ret < 0)
+ goto out;
+
+ /*
+ * If we do this at all, we should allow the user to
+ * measure and read the X and Y resistance at any time.
+ */
+ ucb1x00_adc_enable(ts->ucb);
+ ts->x_res = ucb1x00_ts_read_xres(ts);
+ ts->y_res = ucb1x00_ts_read_yres(ts);
+ ucb1x00_adc_disable(ts->ucb);
+
+ ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd");
+ if (!IS_ERR(ts->rtask)) {
+ ret = 0;
+ } else {
+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
+ ts->rtask = NULL;
+ ret = -EFAULT;
+ }
+
+ out:
+ return ret;
+}
+
+/*
+ * Release touchscreen resources. Disable IRQs.
+ */
+static void ucb1x00_ts_close(struct input_dev *idev)
+{
+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
+
+ if (ts->rtask)
+ kthread_stop(ts->rtask);
+
+ ucb1x00_enable(ts->ucb);
+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
+ ucb1x00_disable(ts->ucb);
+}
+
+#ifdef CONFIG_PM
+static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
+{
+ struct ucb1x00_ts *ts = dev->priv;
+
+ if (ts->rtask != NULL) {
+ /*
+ * Restart the TS thread to ensure the
+ * TS interrupt mode is set up again
+ * after sleep.
+ */
+ ts->restart = 1;
+ wake_up(&ts->irq_wait);
+ }
+ return 0;
+}
+#else
+#define ucb1x00_ts_resume NULL
+#endif
+
+
+/*
+ * Initialisation.
+ */
+static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
+{
+ struct ucb1x00_ts *ts;
+
+ ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ memset(ts, 0, sizeof(struct ucb1x00_ts));
+
+ ts->ucb = dev->ucb;
+ ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
+
+ ts->idev.name = "Touchscreen panel";
+ ts->idev.id.product = ts->ucb->id;
+ ts->idev.open = ucb1x00_ts_open;
+ ts->idev.close = ucb1x00_ts_close;
+
+ __set_bit(EV_ABS, ts->idev.evbit);
+ __set_bit(ABS_X, ts->idev.absbit);
+ __set_bit(ABS_Y, ts->idev.absbit);
+ __set_bit(ABS_PRESSURE, ts->idev.absbit);
+
+ input_register_device(&ts->idev);
+
+ dev->priv = ts;
+
+ return 0;
+}
+
+static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
+{
+ struct ucb1x00_ts *ts = dev->priv;
+ input_unregister_device(&ts->idev);
+ kfree(ts);
+}
+
+static struct ucb1x00_driver ucb1x00_ts_driver = {
+ .add = ucb1x00_ts_add,
+ .remove = ucb1x00_ts_remove,
+ .resume = ucb1x00_ts_resume,
+};
+
+static int __init ucb1x00_ts_init(void)
+{
+ return ucb1x00_register_driver(&ucb1x00_ts_driver);
+}
+
+static void __exit ucb1x00_ts_exit(void)
+{
+ ucb1x00_unregister_driver(&ucb1x00_ts_driver);
+}
+
+module_param(adcsync, int, 0444);
+module_init(ucb1x00_ts_init);
+module_exit(ucb1x00_ts_exit);
+
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h
new file mode 100644
index 000000000000..9c9a647d8b7b
--- /dev/null
+++ b/drivers/mfd/ucb1x00.h
@@ -0,0 +1,254 @@
+/*
+ * linux/drivers/mfd/ucb1x00.h
+ *
+ * Copyright (C) 2001 Russell King, 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.
+ */
+#ifndef UCB1200_H
+#define UCB1200_H
+
+#define UCB_IO_DATA 0x00
+#define UCB_IO_DIR 0x01
+
+#define UCB_IO_0 (1 << 0)
+#define UCB_IO_1 (1 << 1)
+#define UCB_IO_2 (1 << 2)
+#define UCB_IO_3 (1 << 3)
+#define UCB_IO_4 (1 << 4)
+#define UCB_IO_5 (1 << 5)
+#define UCB_IO_6 (1 << 6)
+#define UCB_IO_7 (1 << 7)
+#define UCB_IO_8 (1 << 8)
+#define UCB_IO_9 (1 << 9)
+
+#define UCB_IE_RIS 0x02
+#define UCB_IE_FAL 0x03
+#define UCB_IE_STATUS 0x04
+#define UCB_IE_CLEAR 0x04
+#define UCB_IE_ADC (1 << 11)
+#define UCB_IE_TSPX (1 << 12)
+#define UCB_IE_TSMX (1 << 13)
+#define UCB_IE_TCLIP (1 << 14)
+#define UCB_IE_ACLIP (1 << 15)
+
+#define UCB_IRQ_TSPX 12
+
+#define UCB_TC_A 0x05
+#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
+#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
+
+#define UCB_TC_B 0x06
+#define UCB_TC_B_VOICE_ENA (1 << 3)
+#define UCB_TC_B_CLIP (1 << 4)
+#define UCB_TC_B_ATT (1 << 6)
+#define UCB_TC_B_SIDE_ENA (1 << 11)
+#define UCB_TC_B_MUTE (1 << 13)
+#define UCB_TC_B_IN_ENA (1 << 14)
+#define UCB_TC_B_OUT_ENA (1 << 15)
+
+#define UCB_AC_A 0x07
+#define UCB_AC_B 0x08
+#define UCB_AC_B_LOOP (1 << 8)
+#define UCB_AC_B_MUTE (1 << 13)
+#define UCB_AC_B_IN_ENA (1 << 14)
+#define UCB_AC_B_OUT_ENA (1 << 15)
+
+#define UCB_TS_CR 0x09
+#define UCB_TS_CR_TSMX_POW (1 << 0)
+#define UCB_TS_CR_TSPX_POW (1 << 1)
+#define UCB_TS_CR_TSMY_POW (1 << 2)
+#define UCB_TS_CR_TSPY_POW (1 << 3)
+#define UCB_TS_CR_TSMX_GND (1 << 4)
+#define UCB_TS_CR_TSPX_GND (1 << 5)
+#define UCB_TS_CR_TSMY_GND (1 << 6)
+#define UCB_TS_CR_TSPY_GND (1 << 7)
+#define UCB_TS_CR_MODE_INT (0 << 8)
+#define UCB_TS_CR_MODE_PRES (1 << 8)
+#define UCB_TS_CR_MODE_POS (2 << 8)
+#define UCB_TS_CR_BIAS_ENA (1 << 11)
+#define UCB_TS_CR_TSPX_LOW (1 << 12)
+#define UCB_TS_CR_TSMX_LOW (1 << 13)
+
+#define UCB_ADC_CR 0x0a
+#define UCB_ADC_SYNC_ENA (1 << 0)
+#define UCB_ADC_VREFBYP_CON (1 << 1)
+#define UCB_ADC_INP_TSPX (0 << 2)
+#define UCB_ADC_INP_TSMX (1 << 2)
+#define UCB_ADC_INP_TSPY (2 << 2)
+#define UCB_ADC_INP_TSMY (3 << 2)
+#define UCB_ADC_INP_AD0 (4 << 2)
+#define UCB_ADC_INP_AD1 (5 << 2)
+#define UCB_ADC_INP_AD2 (6 << 2)
+#define UCB_ADC_INP_AD3 (7 << 2)
+#define UCB_ADC_EXT_REF (1 << 5)
+#define UCB_ADC_START (1 << 7)
+#define UCB_ADC_ENA (1 << 15)
+
+#define UCB_ADC_DATA 0x0b
+#define UCB_ADC_DAT_VAL (1 << 15)
+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
+
+#define UCB_ID 0x0c
+#define UCB_ID_1200 0x1004
+#define UCB_ID_1300 0x1005
+
+#define UCB_MODE 0x0d
+#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
+#define UCB_MODE_AUD_OFF_CAN (1 << 13)
+
+#include "mcp.h"
+
+struct ucb1x00_irq {
+ void *devid;
+ void (*fn)(int, void *);
+};
+
+struct ucb1x00 {
+ spinlock_t lock;
+ struct mcp *mcp;
+ unsigned int irq;
+ struct semaphore adc_sem;
+ spinlock_t io_lock;
+ u16 id;
+ u16 io_dir;
+ u16 io_out;
+ u16 adc_cr;
+ u16 irq_fal_enbl;
+ u16 irq_ris_enbl;
+ struct ucb1x00_irq irq_handler[16];
+ struct class_device cdev;
+ struct list_head node;
+ struct list_head devs;
+};
+
+struct ucb1x00_driver;
+
+struct ucb1x00_dev {
+ struct list_head dev_node;
+ struct list_head drv_node;
+ struct ucb1x00 *ucb;
+ struct ucb1x00_driver *drv;
+ void *priv;
+};
+
+struct ucb1x00_driver {
+ struct list_head node;
+ struct list_head devs;
+ int (*add)(struct ucb1x00_dev *dev);
+ void (*remove)(struct ucb1x00_dev *dev);
+ int (*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
+ int (*resume)(struct ucb1x00_dev *dev);
+};
+
+#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev)
+
+int ucb1x00_register_driver(struct ucb1x00_driver *);
+void ucb1x00_unregister_driver(struct ucb1x00_driver *);
+
+/**
+ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
+ * @ucb: UCB1x00 structure describing chip
+ *
+ * Return the SIB clock rate in Hz.
+ */
+static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
+{
+ return mcp_get_sclk_rate(ucb->mcp);
+}
+
+/**
+ * ucb1x00_enable - enable the UCB1x00 SIB clock
+ * @ucb: UCB1x00 structure describing chip
+ *
+ * Enable the SIB clock. This can be called multiple times.
+ */
+static inline void ucb1x00_enable(struct ucb1x00 *ucb)
+{
+ mcp_enable(ucb->mcp);
+}
+
+/**
+ * ucb1x00_disable - disable the UCB1x00 SIB clock
+ * @ucb: UCB1x00 structure describing chip
+ *
+ * Disable the SIB clock. The SIB clock will only be disabled
+ * when the number of ucb1x00_enable calls match the number of
+ * ucb1x00_disable calls.
+ */
+static inline void ucb1x00_disable(struct ucb1x00 *ucb)
+{
+ mcp_disable(ucb->mcp);
+}
+
+/**
+ * ucb1x00_reg_write - write a UCB1x00 register
+ * @ucb: UCB1x00 structure describing chip
+ * @reg: UCB1x00 4-bit register index to write
+ * @val: UCB1x00 16-bit value to write
+ *
+ * Write the UCB1x00 register @reg with value @val. The SIB
+ * clock must be running for this function to return.
+ */
+static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
+{
+ mcp_reg_write(ucb->mcp, reg, val);
+}
+
+/**
+ * ucb1x00_reg_read - read a UCB1x00 register
+ * @ucb: UCB1x00 structure describing chip
+ * @reg: UCB1x00 4-bit register index to write
+ *
+ * Read the UCB1x00 register @reg and return its value. The SIB
+ * clock must be running for this function to return.
+ */
+static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
+{
+ return mcp_reg_read(ucb->mcp, reg);
+}
+/**
+ * ucb1x00_set_audio_divisor -
+ * @ucb: UCB1x00 structure describing chip
+ * @div: SIB clock divisor
+ */
+static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
+{
+ mcp_set_audio_divisor(ucb->mcp, div);
+}
+
+/**
+ * ucb1x00_set_telecom_divisor -
+ * @ucb: UCB1x00 structure describing chip
+ * @div: SIB clock divisor
+ */
+static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
+{
+ mcp_set_telecom_divisor(ucb->mcp, div);
+}
+
+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
+
+#define UCB_NOSYNC (0)
+#define UCB_SYNC (1)
+
+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
+void ucb1x00_adc_enable(struct ucb1x00 *ucb);
+void ucb1x00_adc_disable(struct ucb1x00 *ucb);
+
+/*
+ * Which edges of the IRQ do you want to control today?
+ */
+#define UCB_RISING (1 << 0)
+#define UCB_FALLING (1 << 1)
+
+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
+
+#endif
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 7501fab349e4..46de5c940555 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -192,22 +192,37 @@ static int hdpu_cpustate_probe(struct device *ddev)
{
struct platform_device *pdev = to_platform_device(ddev);
struct resource *res;
+ struct proc_dir_entry *proc_de;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cpustate.set_addr = (unsigned long *)res->start;
cpustate.clr_addr = (unsigned long *)res->end - 1;
- misc_register(&cpustate_dev);
- create_proc_read_entry("sky_cpustate", 0, 0, cpustate_read_proc, NULL);
+ ret = misc_register(&cpustate_dev);
+ if (ret) {
+ printk(KERN_WARNING "sky_cpustate: Unable to register misc "
+ "device.\n");
+ cpustate.set_addr = NULL;
+ cpustate.clr_addr = NULL;
+ return ret;
+ }
+
+ proc_de = create_proc_read_entry("sky_cpustate", 0, 0,
+ cpustate_read_proc, NULL);
+ if (proc_de == NULL)
+ printk(KERN_WARNING "sky_cpustate: Unable to create proc "
+ "dir entry\n");
printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n");
return 0;
}
+
static int hdpu_cpustate_remove(struct device *ddev)
{
- cpustate.set_addr = 0;
- cpustate.clr_addr = 0;
+ cpustate.set_addr = NULL;
+ cpustate.clr_addr = NULL;
remove_proc_entry("sky_cpustate", NULL);
misc_deregister(&cpustate_dev);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0a117c61cd18..ceae379a4d4c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1079,13 +1079,17 @@ static void mmc_setup(struct mmc_host *host)
/**
* 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 716c4ef4faf6..1e6bdba26756 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/scatterlist.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
#include <asm/mach/mmc.h>
@@ -442,7 +443,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 e99a53b09e32..b53af57074e3 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -423,7 +423,9 @@ static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
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 dec01d38c782..3cbca7cbea80 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -93,7 +93,7 @@ static int dma = 2;
static inline void wbsd_unlock_config(struct wbsd_host* host)
{
BUG_ON(host->config == 0);
-
+
outb(host->unlock_code, host->config);
outb(host->unlock_code, host->config);
}
@@ -101,14 +101,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host)
static inline void wbsd_lock_config(struct wbsd_host* host)
{
BUG_ON(host->config == 0);
-
+
outb(LOCK_CODE, host->config);
}
static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
{
BUG_ON(host->config == 0);
-
+
outb(reg, host->config);
outb(value, host->config + 1);
}
@@ -116,7 +116,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
{
BUG_ON(host->config == 0);
-
+
outb(reg, host->config);
return inb(host->config + 1);
}
@@ -140,21 +140,21 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
static void wbsd_init_device(struct wbsd_host* host)
{
u8 setup, ier;
-
+
/*
* Reset chip (SD/MMC part) and fifo.
*/
setup = wbsd_read_index(host, WBSD_IDX_SETUP);
setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET;
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
-
+
/*
* Set DAT3 to input
*/
setup &= ~WBSD_DAT3_H;
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
host->flags &= ~WBSD_FIGNORE_DETECT;
-
+
/*
* Read back default clock.
*/
@@ -164,12 +164,12 @@ static void wbsd_init_device(struct wbsd_host* host)
* Power down port.
*/
outb(WBSD_POWER_N, host->base + WBSD_CSR);
-
+
/*
* Set maximum timeout.
*/
wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F);
-
+
/*
* Test for card presence
*/
@@ -177,7 +177,7 @@ static void wbsd_init_device(struct wbsd_host* host)
host->flags |= WBSD_FCARD_PRESENT;
else
host->flags &= ~WBSD_FCARD_PRESENT;
-
+
/*
* Enable interesting interrupts.
*/
@@ -200,9 +200,9 @@ static void wbsd_init_device(struct wbsd_host* host)
static void wbsd_reset(struct wbsd_host* host)
{
u8 setup;
-
+
printk(KERN_ERR DRIVER_NAME ": Resetting chip\n");
-
+
/*
* Soft reset of chip (SD/MMC part).
*/
@@ -214,9 +214,9 @@ static void wbsd_reset(struct wbsd_host* host)
static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
{
unsigned long dmaflags;
-
+
DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode);
-
+
if (host->dma >= 0)
{
/*
@@ -232,7 +232,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
*/
wbsd_write_index(host, WBSD_IDX_DMA, 0);
}
-
+
host->mrq = NULL;
/*
@@ -275,7 +275,7 @@ static inline int wbsd_next_sg(struct wbsd_host* host)
host->offset = 0;
host->remain = host->cur_sg->length;
}
-
+
return host->num_sg;
}
@@ -297,12 +297,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
struct scatterlist* sg;
char* dmabuf = host->dma_buffer;
char* sgbuf;
-
+
size = host->size;
-
+
sg = data->sg;
len = data->sg_len;
-
+
/*
* Just loop through all entries. Size might not
* be the entire list though so make sure that
@@ -317,23 +317,23 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
memcpy(dmabuf, sgbuf, sg[i].length);
kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
dmabuf += sg[i].length;
-
+
if (size < sg[i].length)
size = 0;
else
size -= sg[i].length;
-
+
if (size == 0)
break;
}
-
+
/*
* Check that we didn't get a request to transfer
* more data than can fit into the SG list.
*/
-
+
BUG_ON(size != 0);
-
+
host->size -= size;
}
@@ -343,12 +343,12 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
struct scatterlist* sg;
char* dmabuf = host->dma_buffer;
char* sgbuf;
-
+
size = host->size;
-
+
sg = data->sg;
len = data->sg_len;
-
+
/*
* Just loop through all entries. Size might not
* be the entire list though so make sure that
@@ -363,30 +363,30 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
memcpy(sgbuf, dmabuf, sg[i].length);
kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
dmabuf += sg[i].length;
-
+
if (size < sg[i].length)
size = 0;
else
size -= sg[i].length;
-
+
if (size == 0)
break;
}
-
+
/*
* Check that we didn't get a request to transfer
* more data than can fit into the SG list.
*/
-
+
BUG_ON(size != 0);
-
+
host->size -= size;
}
/*
* Command handling
*/
-
+
static inline void wbsd_get_short_reply(struct wbsd_host* host,
struct mmc_command* cmd)
{
@@ -398,7 +398,7 @@ static inline void wbsd_get_short_reply(struct wbsd_host* host,
cmd->error = MMC_ERR_INVALID;
return;
}
-
+
cmd->resp[0] =
wbsd_read_index(host, WBSD_IDX_RESP12) << 24;
cmd->resp[0] |=
@@ -415,7 +415,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
struct mmc_command* cmd)
{
int i;
-
+
/*
* Correct response type?
*/
@@ -424,7 +424,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
cmd->error = MMC_ERR_INVALID;
return;
}
-
+
for (i = 0;i < 4;i++)
{
cmd->resp[i] =
@@ -442,7 +442,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
{
int i;
u8 status, isr;
-
+
DBGF("Sending cmd (%x)\n", cmd->opcode);
/*
@@ -451,16 +451,16 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
* transfer.
*/
host->isr = 0;
-
+
/*
* Send the command (CRC calculated by host).
*/
outb(cmd->opcode, host->base + WBSD_CMDR);
for (i = 3;i >= 0;i--)
outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);
-
+
cmd->error = MMC_ERR_NONE;
-
+
/*
* Wait for the request to complete.
*/
@@ -477,7 +477,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
* Read back status.
*/
isr = host->isr;
-
+
/* Card removed? */
if (isr & WBSD_INT_CARD)
cmd->error = MMC_ERR_TIMEOUT;
@@ -509,13 +509,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
struct mmc_data* data = host->mrq->cmd->data;
char* buffer;
int i, fsr, fifo;
-
+
/*
* Handle excessive data.
*/
if (data->bytes_xfered == host->size)
return;
-
+
buffer = wbsd_kmap_sg(host) + host->offset;
/*
@@ -527,14 +527,14 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
/*
* The size field in the FSR is broken so we have to
* do some guessing.
- */
+ */
if (fsr & WBSD_FIFO_FULL)
fifo = 16;
else if (fsr & WBSD_FIFO_FUTHRE)
fifo = 8;
else
fifo = 1;
-
+
for (i = 0;i < fifo;i++)
{
*buffer = inb(host->base + WBSD_DFR);
@@ -543,23 +543,23 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
host->remain--;
data->bytes_xfered++;
-
+
/*
* Transfer done?
*/
if (data->bytes_xfered == host->size)
{
- wbsd_kunmap_sg(host);
+ wbsd_kunmap_sg(host);
return;
}
-
+
/*
* End of scatter list entry?
*/
if (host->remain == 0)
{
wbsd_kunmap_sg(host);
-
+
/*
* Get next entry. Check if last.
*/
@@ -572,17 +572,17 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
* into the scatter list.
*/
BUG_ON(1);
-
+
host->size = data->bytes_xfered;
-
+
return;
}
-
+
buffer = wbsd_kmap_sg(host);
}
}
}
-
+
wbsd_kunmap_sg(host);
/*
@@ -599,7 +599,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
struct mmc_data* data = host->mrq->cmd->data;
char* buffer;
int i, fsr, fifo;
-
+
/*
* Check that we aren't being called after the
* entire buffer has been transfered.
@@ -618,7 +618,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
/*
* The size field in the FSR is broken so we have to
* do some guessing.
- */
+ */
if (fsr & WBSD_FIFO_EMPTY)
fifo = 0;
else if (fsr & WBSD_FIFO_EMTHRE)
@@ -632,9 +632,9 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
buffer++;
host->offset++;
host->remain--;
-
+
data->bytes_xfered++;
-
+
/*
* Transfer done?
*/
@@ -650,7 +650,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
if (host->remain == 0)
{
wbsd_kunmap_sg(host);
-
+
/*
* Get next entry. Check if last.
*/
@@ -663,19 +663,19 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
* into the scatter list.
*/
BUG_ON(1);
-
+
host->size = data->bytes_xfered;
-
+
return;
}
-
+
buffer = wbsd_kmap_sg(host);
}
}
}
-
+
wbsd_kunmap_sg(host);
-
+
/*
* The controller stops sending interrupts for
* 'FIFO empty' under certain conditions. So we
@@ -694,7 +694,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
1 << data->blksz_bits, data->blocks, data->flags);
DBGF("tsac %d ms nsac %d clk\n",
data->timeout_ns / 1000000, data->timeout_clks);
-
+
/*
* Calculate size.
*/
@@ -708,12 +708,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
wbsd_write_index(host, WBSD_IDX_TAAC, 127);
else
wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000);
-
+
if (data->timeout_clks > 255)
wbsd_write_index(host, WBSD_IDX_NSAC, 255);
else
wbsd_write_index(host, WBSD_IDX_NSAC, data->timeout_clks);
-
+
/*
* Inform the chip of how large blocks will be
* sent. It needs this to determine when to
@@ -732,7 +732,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
else if (host->bus_width == MMC_BUS_WIDTH_4)
{
blksize = (1 << data->blksz_bits) + 2 * 4;
-
+
wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0)
| WBSD_DATA_WIDTH);
wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
@@ -751,12 +751,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
setup = wbsd_read_index(host, WBSD_IDX_SETUP);
setup |= WBSD_FIFO_RESET;
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
-
+
/*
* DMA transfer?
*/
if (host->dma >= 0)
- {
+ {
/*
* The buffer for DMA is only 64 kB.
*/
@@ -766,17 +766,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
data->error = MMC_ERR_INVALID;
return;
}
-
+
/*
* Transfer data from the SG list to
* the DMA buffer.
*/
if (data->flags & MMC_DATA_WRITE)
wbsd_sg_to_dma(host, data);
-
+
/*
* Initialise the ISA DMA controller.
- */
+ */
dmaflags = claim_dma_lock();
disable_dma(host->dma);
clear_dma_ff(host->dma);
@@ -802,17 +802,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
* output to a minimum.
*/
host->firsterr = 1;
-
+
/*
* Initialise the SG list.
*/
wbsd_init_sg(host, data);
-
+
/*
* Turn off DMA.
*/
wbsd_write_index(host, WBSD_IDX_DMA, 0);
-
+
/*
* Set up FIFO threshold levels (and fill
* buffer if doing a write).
@@ -828,8 +828,8 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
WBSD_FIFOEN_EMPTY | 8);
wbsd_fill_fifo(host);
}
- }
-
+ }
+
data->error = MMC_ERR_NONE;
}
@@ -838,7 +838,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
unsigned long dmaflags;
int count;
u8 status;
-
+
WARN_ON(host->mrq == NULL);
/*
@@ -855,7 +855,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
{
status = wbsd_read_index(host, WBSD_IDX_STATUS);
} while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE));
-
+
/*
* DMA transfer?
*/
@@ -865,7 +865,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
* Disable DMA on the host.
*/
wbsd_write_index(host, WBSD_IDX_DMA, 0);
-
+
/*
* Turn of ISA DMA controller.
*/
@@ -874,7 +874,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
clear_dma_ff(host->dma);
count = get_dma_residue(host->dma);
release_dma_lock(dmaflags);
-
+
/*
* Any leftover data?
*/
@@ -882,7 +882,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
{
printk(KERN_ERR DRIVER_NAME ": Incomplete DMA "
"transfer. %d bytes left.\n", count);
-
+
data->error = MMC_ERR_FAILED;
}
else
@@ -893,13 +893,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
*/
if (data->flags & MMC_DATA_READ)
wbsd_dma_to_sg(host, data);
-
+
data->bytes_xfered = host->size;
}
}
-
+
DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered);
-
+
wbsd_request_end(host, host->mrq);
}
@@ -924,7 +924,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
cmd = mrq->cmd;
host->mrq = mrq;
-
+
/*
* If there is no card in the slot then
* timeout immediatly.
@@ -941,18 +941,18 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
if (cmd->data)
{
wbsd_prepare_data(host, cmd->data);
-
+
if (cmd->data->error != MMC_ERR_NONE)
goto done;
}
-
+
wbsd_send_command(host, cmd);
/*
* If this is a data transfer the request
* will be finished after the data has
* transfered.
- */
+ */
if (cmd->data && (cmd->error == MMC_ERR_NONE))
{
/*
@@ -965,7 +965,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
return;
}
-
+
done:
wbsd_request_end(host, mrq);
@@ -976,7 +976,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
{
struct wbsd_host* host = mmc_priv(mmc);
u8 clk, setup, pwr;
-
+
DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
ios->vdd, ios->bus_width);
@@ -989,7 +989,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
*/
if (ios->power_mode == MMC_POWER_OFF)
wbsd_init_device(host);
-
+
if (ios->clock >= 24000000)
clk = WBSD_CLK_24M;
else if (ios->clock >= 16000000)
@@ -1042,7 +1042,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
mod_timer(&host->ignore_timer, jiffies + HZ/100);
}
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
-
+
/*
* Store bus width for later. Will be used when
* setting up the data transfer.
@@ -1112,20 +1112,6 @@ static void wbsd_reset_ignore(unsigned long data)
}
/*
- * Helper function for card detection
- */
-static void wbsd_detect_card(unsigned long data)
-{
- struct wbsd_host *host = (struct wbsd_host*)data;
-
- BUG_ON(host == NULL);
-
- DBG("Executing card detection\n");
-
- mmc_detect_change(host->mmc);
-}
-
-/*
* Tasklets
*/
@@ -1142,7 +1128,7 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
WARN_ON(!host->mrq->cmd->data);
if (!host->mrq->cmd->data)
return NULL;
-
+
return host->mrq->cmd->data;
}
@@ -1150,70 +1136,67 @@ static void wbsd_tasklet_card(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
u8 csr;
-
+ int delay = -1;
+
spin_lock(&host->lock);
-
+
if (host->flags & WBSD_FIGNORE_DETECT)
{
spin_unlock(&host->lock);
return;
}
-
+
csr = inb(host->base + WBSD_CSR);
WARN_ON(csr == 0xff);
-
+
if (csr & WBSD_CARDPRESENT)
{
if (!(host->flags & WBSD_FCARD_PRESENT))
{
DBG("Card inserted\n");
host->flags |= WBSD_FCARD_PRESENT;
-
- /*
- * Delay card detection to allow electrical connections
- * to stabilise.
- */
- mod_timer(&host->detect_timer, jiffies + HZ/2);
+
+ delay = 500;
}
-
- spin_unlock(&host->lock);
}
else if (host->flags & WBSD_FCARD_PRESENT)
{
DBG("Card removed\n");
host->flags &= ~WBSD_FCARD_PRESENT;
-
+
if (host->mrq)
{
printk(KERN_ERR DRIVER_NAME
": Card removed during transfer!\n");
wbsd_reset(host);
-
+
host->mrq->cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet);
}
-
- /*
- * Unlock first since we might get a call back.
- */
- spin_unlock(&host->lock);
- mmc_detect_change(host->mmc);
+ delay = 0;
}
- else
- spin_unlock(&host->lock);
+
+ /*
+ * Unlock first since we might get a call back.
+ */
+
+ spin_unlock(&host->lock);
+
+ if (delay != -1)
+ mmc_detect_change(host->mmc, msecs_to_jiffies(delay));
}
static void wbsd_tasklet_fifo(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
struct mmc_data* data;
-
+
spin_lock(&host->lock);
-
+
if (!host->mrq)
goto end;
-
+
data = wbsd_get_data(host);
if (!data)
goto end;
@@ -1232,7 +1215,7 @@ static void wbsd_tasklet_fifo(unsigned long param)
tasklet_schedule(&host->finish_tasklet);
}
-end:
+end:
spin_unlock(&host->lock);
}
@@ -1240,23 +1223,23 @@ static void wbsd_tasklet_crc(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
struct mmc_data* data;
-
+
spin_lock(&host->lock);
-
+
if (!host->mrq)
goto end;
-
+
data = wbsd_get_data(host);
if (!data)
goto end;
-
+
DBGF("CRC error\n");
data->error = MMC_ERR_BADCRC;
-
+
tasklet_schedule(&host->finish_tasklet);
-end:
+end:
spin_unlock(&host->lock);
}
@@ -1264,23 +1247,23 @@ static void wbsd_tasklet_timeout(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
struct mmc_data* data;
-
+
spin_lock(&host->lock);
-
+
if (!host->mrq)
goto end;
-
+
data = wbsd_get_data(host);
if (!data)
goto end;
-
+
DBGF("Timeout\n");
data->error = MMC_ERR_TIMEOUT;
-
+
tasklet_schedule(&host->finish_tasklet);
-end:
+end:
spin_unlock(&host->lock);
}
@@ -1288,20 +1271,20 @@ static void wbsd_tasklet_finish(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
struct mmc_data* data;
-
+
spin_lock(&host->lock);
-
+
WARN_ON(!host->mrq);
if (!host->mrq)
goto end;
-
+
data = wbsd_get_data(host);
if (!data)
goto end;
wbsd_finish_data(host, data);
-
-end:
+
+end:
spin_unlock(&host->lock);
}
@@ -1309,7 +1292,7 @@ static void wbsd_tasklet_block(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
struct mmc_data* data;
-
+
spin_lock(&host->lock);
if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) !=
@@ -1318,15 +1301,15 @@ static void wbsd_tasklet_block(unsigned long param)
data = wbsd_get_data(host);
if (!data)
goto end;
-
+
DBGF("CRC error\n");
data->error = MMC_ERR_BADCRC;
-
+
tasklet_schedule(&host->finish_tasklet);
}
-end:
+end:
spin_unlock(&host->lock);
}
@@ -1338,7 +1321,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
{
struct wbsd_host* host = dev_id;
int isr;
-
+
isr = inb(host->base + WBSD_ISR);
/*
@@ -1346,7 +1329,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
*/
if (isr == 0xff || isr == 0x00)
return IRQ_NONE;
-
+
host->isr |= isr;
/*
@@ -1364,7 +1347,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
tasklet_hi_schedule(&host->block_tasklet);
if (isr & WBSD_INT_TC)
tasklet_schedule(&host->finish_tasklet);
-
+
return IRQ_HANDLED;
}
@@ -1382,14 +1365,14 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
{
struct mmc_host* mmc;
struct wbsd_host* host;
-
+
/*
* Allocate MMC structure.
*/
mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev);
if (!mmc)
return -ENOMEM;
-
+
host = mmc_priv(mmc);
host->mmc = mmc;
@@ -1403,41 +1386,37 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
mmc->f_max = 24000000;
mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
mmc->caps = MMC_CAP_4_BIT_DATA;
-
+
spin_lock_init(&host->lock);
-
+
/*
* Set up timers
*/
- init_timer(&host->detect_timer);
- host->detect_timer.data = (unsigned long)host;
- host->detect_timer.function = wbsd_detect_card;
-
init_timer(&host->ignore_timer);
host->ignore_timer.data = (unsigned long)host;
host->ignore_timer.function = wbsd_reset_ignore;
-
+
/*
* Maximum number of segments. Worst case is one sector per segment
* so this will be 64kB/512.
*/
mmc->max_hw_segs = 128;
mmc->max_phys_segs = 128;
-
+
/*
* Maximum number of sectors in one transfer. Also limited by 64kB
* buffer.
*/
mmc->max_sectors = 128;
-
+
/*
* Maximum segment size. Could be one segment with the maximum number
* of segments.
*/
mmc->max_seg_size = mmc->max_sectors * 512;
-
+
dev_set_drvdata(dev, mmc);
-
+
return 0;
}
@@ -1445,19 +1424,18 @@ static void __devexit wbsd_free_mmc(struct device* dev)
{
struct mmc_host* mmc;
struct wbsd_host* host;
-
+
mmc = dev_get_drvdata(dev);
if (!mmc)
return;
-
+
host = mmc_priv(mmc);
BUG_ON(host == NULL);
-
+
del_timer_sync(&host->ignore_timer);
- del_timer_sync(&host->detect_timer);
-
+
mmc_free_host(mmc);
-
+
dev_set_drvdata(dev, NULL);
}
@@ -1469,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
{
int i, j, k;
int id;
-
+
/*
* Iterate through all ports, all codes to
* find hardware that is in our known list.
@@ -1478,32 +1456,32 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
{
if (!request_region(config_ports[i], 2, DRIVER_NAME))
continue;
-
+
for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++)
{
id = 0xFFFF;
-
+
outb(unlock_codes[j], config_ports[i]);
outb(unlock_codes[j], config_ports[i]);
-
+
outb(WBSD_CONF_ID_HI, config_ports[i]);
id = inb(config_ports[i] + 1) << 8;
outb(WBSD_CONF_ID_LO, config_ports[i]);
id |= inb(config_ports[i] + 1);
-
+
for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
{
if (id == valid_ids[k])
- {
+ {
host->chip_id = id;
host->config = config_ports[i];
host->unlock_code = unlock_codes[i];
-
+
return 0;
}
}
-
+
if (id != 0xFFFF)
{
DBG("Unknown hardware (id %x) found at %x\n",
@@ -1512,10 +1490,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
outb(LOCK_CODE, config_ports[i]);
}
-
+
release_region(config_ports[i], 2);
}
-
+
return -ENODEV;
}
@@ -1527,12 +1505,12 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
{
if (io & 0x7)
return -EINVAL;
-
+
if (!request_region(base, 8, DRIVER_NAME))
return -EIO;
-
+
host->base = io;
-
+
return 0;
}
@@ -1540,12 +1518,12 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host)
{
if (host->base)
release_region(host->base, 8);
-
+
host->base = 0;
if (host->config)
release_region(host->config, 2);
-
+
host->config = 0;
}
@@ -1557,10 +1535,10 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
{
if (dma < 0)
return;
-
+
if (request_dma(dma, DRIVER_NAME))
goto err;
-
+
/*
* We need to allocate a special buffer in
* order for ISA to be able to DMA to it.
@@ -1575,7 +1553,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
*/
host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer,
WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
-
+
/*
* ISA DMA must be aligned on a 64k basis.
*/
@@ -1588,19 +1566,19 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
goto kfree;
host->dma = dma;
-
+
return;
-
+
kfree:
/*
* If we've gotten here then there is some kind of alignment bug
*/
BUG_ON(1);
-
+
dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
DMA_BIDIRECTIONAL);
host->dma_addr = (dma_addr_t)NULL;
-
+
kfree(host->dma_buffer);
host->dma_buffer = NULL;
@@ -1621,7 +1599,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
kfree(host->dma_buffer);
if (host->dma >= 0)
free_dma(host->dma);
-
+
host->dma = -1;
host->dma_buffer = NULL;
host->dma_addr = (dma_addr_t)NULL;
@@ -1634,7 +1612,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
{
int ret;
-
+
/*
* Allocate interrupt.
*/
@@ -1642,7 +1620,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host);
if (ret)
return ret;
-
+
host->irq = irq;
/*
@@ -1654,7 +1632,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host);
tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host);
tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host);
-
+
return 0;
}
@@ -1664,9 +1642,9 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host)
return;
free_irq(host->irq, host);
-
+
host->irq = 0;
-
+
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->fifo_tasklet);
tasklet_kill(&host->crc_tasklet);
@@ -1683,7 +1661,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
int base, int irq, int dma)
{
int ret;
-
+
/*
* Allocate I/O ports.
*/
@@ -1702,7 +1680,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
* Allocate DMA.
*/
wbsd_request_dma(host, dma);
-
+
return 0;
}
@@ -1725,7 +1703,7 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
{
/*
* Reset the chip.
- */
+ */
wbsd_write_config(host, WBSD_CONF_SWRST, 1);
wbsd_write_config(host, WBSD_CONF_SWRST, 0);
@@ -1733,23 +1711,23 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
* Select SD/MMC function.
*/
wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
-
+
/*
* Set up card detection.
*/
wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11);
-
+
/*
* Configure chip
*/
wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8);
wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff);
-
+
wbsd_write_config(host, WBSD_CONF_IRQ, host->irq);
-
+
if (host->dma >= 0)
wbsd_write_config(host, WBSD_CONF_DRQ, host->dma);
-
+
/*
* Enable and power up chip.
*/
@@ -1760,26 +1738,26 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
/*
* Check that configured resources are correct.
*/
-
+
static int __devinit wbsd_chip_validate(struct wbsd_host* host)
{
int base, irq, dma;
-
+
/*
* Select SD/MMC function.
*/
wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
-
+
/*
* Read configuration.
*/
base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8;
base |= wbsd_read_config(host, WBSD_CONF_PORT_LO);
-
+
irq = wbsd_read_config(host, WBSD_CONF_IRQ);
-
+
dma = wbsd_read_config(host, WBSD_CONF_DRQ);
-
+
/*
* Validate against given configuration.
*/
@@ -1789,7 +1767,7 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
return 0;
if ((dma != host->dma) && (host->dma != -1))
return 0;
-
+
return 1;
}
@@ -1805,14 +1783,14 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
struct wbsd_host* host = NULL;
struct mmc_host* mmc = NULL;
int ret;
-
+
ret = wbsd_alloc_mmc(dev);
if (ret)
return ret;
-
+
mmc = dev_get_drvdata(dev);
host = mmc_priv(mmc);
-
+
/*
* Scan for hardware.
*/
@@ -1831,7 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
return ret;
}
}
-
+
/*
* Request resources.
*/
@@ -1842,7 +1820,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
wbsd_free_mmc(dev);
return ret;
}
-
+
/*
* See if chip needs to be configured.
*/
@@ -1859,7 +1837,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
}
else
wbsd_chip_config(host);
-
+
/*
* Power Management stuff. No idea how this works.
* Not tested.
@@ -1877,7 +1855,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
* Reset the chip into a known state.
*/
wbsd_init_device(host);
-
+
mmc_add_host(mmc);
printk(KERN_INFO "%s: W83L51xD", mmc_hostname(mmc));
@@ -1899,12 +1877,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
{
struct mmc_host* mmc = dev_get_drvdata(dev);
struct wbsd_host* host;
-
+
if (!mmc)
return;
host = mmc_priv(mmc);
-
+
mmc_remove_host(mmc);
if (!pnp)
@@ -1917,9 +1895,9 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
wbsd_lock_config(host);
}
-
+
wbsd_release_resources(host);
-
+
wbsd_free_mmc(dev);
}
@@ -1949,7 +1927,7 @@ static int __devinit
wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
{
int io, irq, dma;
-
+
/*
* Get resources from PnP layer.
*/
@@ -1959,9 +1937,9 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
dma = pnp_dma(pnpdev, 0);
else
dma = -1;
-
+
DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma);
-
+
return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
}
@@ -2002,7 +1980,7 @@ static struct device_driver wbsd_driver = {
.bus = &platform_bus_type,
.probe = wbsd_probe,
.remove = wbsd_remove,
-
+
.suspend = wbsd_suspend,
.resume = wbsd_resume,
};
@@ -2025,7 +2003,7 @@ static struct pnp_driver wbsd_pnp_driver = {
static int __init wbsd_drv_init(void)
{
int result;
-
+
printk(KERN_INFO DRIVER_NAME
": Winbond W83L51xD SD/MMC card interface driver, "
DRIVER_VERSION "\n");
@@ -2040,8 +2018,8 @@ static int __init wbsd_drv_init(void)
return result;
}
-#endif /* CONFIG_PNP */
-
+#endif /* CONFIG_PNP */
+
if (nopnp)
{
result = driver_register(&wbsd_driver);
@@ -2063,13 +2041,13 @@ static void __exit wbsd_drv_exit(void)
if (!nopnp)
pnp_unregister_driver(&wbsd_pnp_driver);
-
-#endif /* CONFIG_PNP */
+
+#endif /* CONFIG_PNP */
if (nopnp)
{
platform_device_unregister(wbsd_device);
-
+
driver_unregister(&wbsd_driver);
}
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
index 9005b5241b3c..249baa701cb0 100644
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -139,51 +139,50 @@
struct wbsd_host
{
struct mmc_host* mmc; /* MMC structure */
-
+
spinlock_t lock; /* Mutex */
int flags; /* Driver states */
#define WBSD_FCARD_PRESENT (1<<0) /* Card is present */
#define WBSD_FIGNORE_DETECT (1<<1) /* Ignore card detection */
-
+
struct mmc_request* mrq; /* Current request */
-
+
u8 isr; /* Accumulated ISR */
-
+
struct scatterlist* cur_sg; /* Current SG entry */
unsigned int num_sg; /* Number of entries left */
void* mapped_sg; /* vaddr of mapped sg */
-
+
unsigned int offset; /* Offset into current entry */
unsigned int remain; /* Data left in curren entry */
int size; /* Total size of transfer */
-
+
char* dma_buffer; /* ISA DMA buffer */
dma_addr_t dma_addr; /* Physical address for same */
int firsterr; /* See fifo functions */
-
+
u8 clk; /* Current clock speed */
unsigned char bus_width; /* Current bus width */
-
+
int config; /* Config port */
u8 unlock_code; /* Code to unlock config */
int chip_id; /* ID of controller */
-
+
int base; /* I/O port base */
int irq; /* Interrupt */
int dma; /* DMA channel */
-
+
struct tasklet_struct card_tasklet; /* Tasklet structures */
struct tasklet_struct fifo_tasklet;
struct tasklet_struct crc_tasklet;
struct tasklet_struct timeout_tasklet;
struct tasklet_struct finish_tasklet;
struct tasklet_struct block_tasklet;
-
- struct timer_list detect_timer; /* Card detection timer */
+
struct timer_list ignore_timer; /* Ignore detection timer */
};
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 9a087c1fb0b7..24f670b5a4f3 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -40,7 +40,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/doc2000.h>
-#define DEBUG 0
+#define DEBUG_ECC 0
/* need to undef it (from asm/termbits.h) */
#undef B0
@@ -249,7 +249,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
lambda[j] ^= Alpha_to[modnn(u + tmp)];
}
}
-#if DEBUG >= 1
+#if DEBUG_ECC >= 1
/* Test code that verifies the erasure locator polynomial just constructed
Needed only for decoder debugging. */
@@ -276,7 +276,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
count = -1;
goto finish;
}
-#if DEBUG >= 2
+#if DEBUG_ECC >= 2
printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
for (i = 0; i < count; i++)
printf("%d ", loc[i]);
@@ -409,7 +409,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
}
if (den == 0) {
-#if DEBUG >= 1
+#if DEBUG_ECC >= 1
printf("\n ERROR: denominator = 0\n");
#endif
/* Convert to dual- basis */
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index bb713fed2f37..1443117fd8f4 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -91,8 +91,7 @@ static void __exit cleanup_mtdram(void)
{
if (mtd_info) {
del_mtd_device(mtd_info);
- if (mtd_info->priv)
- vfree(mtd_info->priv);
+ vfree(mtd_info->priv);
kfree(mtd_info);
}
}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index d9ab60b36fd4..d32c1b3a8ce3 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1017,27 +1017,16 @@ static int ftl_writesect(struct mtd_blktrans_dev *dev,
void ftl_freepart(partition_t *part)
{
- if (part->VirtualBlockMap) {
vfree(part->VirtualBlockMap);
part->VirtualBlockMap = NULL;
- }
- if (part->VirtualPageMap) {
kfree(part->VirtualPageMap);
part->VirtualPageMap = NULL;
- }
- if (part->EUNInfo) {
kfree(part->EUNInfo);
part->EUNInfo = NULL;
- }
- if (part->XferInfo) {
kfree(part->XferInfo);
part->XferInfo = NULL;
- }
- if (part->bam_cache) {
kfree(part->bam_cache);
part->bam_cache = NULL;
- }
-
} /* ftl_freepart */
static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 0c45464e3f7b..0ba0ff7d43b9 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -39,7 +39,6 @@
#include <linux/mtd/partitions.h>
#include <asm/io.h>
-#include <asm/mach-types.h>
#include <asm/mach/flash.h>
#include <asm/arch/map.h>
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 3e94b616743d..a9f86c7fbd52 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -30,7 +30,6 @@
#include <asm/io.h>
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/mach/flash.h>
#include <linux/reboot.h>
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 5afe660aa2c4..3fcc32884074 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -26,7 +26,6 @@
#include <linux/ioport.h>
#include <linux/device.h>
#include <asm/io.h>
-#include <asm/mach-types.h>
#include <asm/mach/flash.h>
#include <linux/reboot.h>
@@ -254,6 +253,6 @@ module_init(ixp4xx_flash_init);
module_exit(ixp4xx_flash_exit);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems")
+MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
MODULE_AUTHOR("Deepak Saxena");
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 8cc71409a328..b17bca657daf 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -42,7 +42,6 @@
#include <asm/io.h>
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/mach/flash.h>
#include <asm/arch/tc.h>
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 52385705da09..9133351ba483 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -21,7 +21,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
-#include <asm/mach-types.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/sizes.h>
#include <asm/mach/flash.h>
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index d15da6fd84c1..b7f093fbf9b0 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -82,7 +82,7 @@ int __init init_sharpsl(void)
} else if (machine_is_tosa()) {
sharpsl_partitions[0].size=0x006a0000;
sharpsl_partitions[0].offset=0x00160000;
- } else if (machine_is_spitz()) {
+ } else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) {
sharpsl_partitions[0].size=0x006b0000;
sharpsl_partitions[0].offset=0x00140000;
} else {
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index 811d92e5f5b1..cc372136e852 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -25,9 +25,6 @@
/****************************************************************************/
-
-/****************************************************************************/
-
struct map_info uclinux_ram_map = {
.name = "RAM",
};
@@ -60,14 +57,15 @@ int __init uclinux_mtd_init(void)
struct mtd_info *mtd;
struct map_info *mapp;
extern char _ebss;
+ unsigned long addr = (unsigned long) &_ebss;
mapp = &uclinux_ram_map;
- mapp->phys = (unsigned long) &_ebss;
- mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8)));
+ mapp->phys = addr;
+ mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(addr + 8))));
mapp->bankwidth = 4;
printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
- (int) mapp->map_priv_2, (int) mapp->size);
+ (int) mapp->phys, (int) mapp->size);
mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
@@ -95,7 +93,6 @@ int __init uclinux_mtd_init(void)
printk("uclinux[mtd]: set %s to be root filesystem\n",
uclinux_romfs[0].name);
ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
- put_mtd_device(mtd);
return(0);
}
@@ -109,7 +106,7 @@ void __exit uclinux_mtd_cleanup(void)
map_destroy(uclinux_ram_mtdinfo);
uclinux_ram_mtdinfo = NULL;
}
- if (uclinux_ram_map.map_priv_1) {
+ if (uclinux_ram_map.virt) {
iounmap((void *) uclinux_ram_map.virt);
uclinux_ram_map.virt = 0;
}
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 891e3a1b9110..b47ebcb31e0f 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -58,7 +58,6 @@
#include <linux/mtd/partitions.h>
#include <asm/io.h>
-#include <asm/mach-types.h>
#include <asm/hardware/clock.h>
#include <asm/arch/regs-nand.h>
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 9853b87bb756..88b5b5b40b43 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -221,10 +221,16 @@ sharpsl_nand_init(void)
sharpsl_partition_info[1].size=25 * 1024 * 1024;
} else if (machine_is_husky()) {
sharpsl_partition_info[1].size=53 * 1024 * 1024;
- }
+ } else if (machine_is_spitz()) {
+ sharpsl_partition_info[1].size=5 * 1024 * 1024;
+ } else if (machine_is_akita()) {
+ sharpsl_partition_info[1].size=58 * 1024 * 1024;
+ } else if (machine_is_borzoi()) {
+ sharpsl_partition_info[1].size=32 * 1024 * 1024;
+ }
}
- if (machine_is_husky()) {
+ if (machine_is_husky() || machine_is_borzoi()) {
/* Need to use small eraseblock size for backward compatibility */
sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
}
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 34b80de34fae..f822cd3025ff 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -353,8 +353,6 @@ struct cp_private {
struct net_device_stats net_stats;
struct cp_extra_stats cp_stats;
- struct cp_dma_stats *nic_stats;
- dma_addr_t nic_stats_dma;
unsigned rx_tail ____cacheline_aligned;
struct cp_desc *rx_ring;
@@ -1029,8 +1027,7 @@ static void cp_reset_hw (struct cp_private *cp)
if (!(cpr8(Cmd) & CmdReset))
return;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
}
printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
@@ -1143,10 +1140,6 @@ static int cp_alloc_rings (struct cp_private *cp)
cp->rx_ring = mem;
cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
- mem += (CP_RING_BYTES - CP_STATS_SIZE);
- cp->nic_stats = mem;
- cp->nic_stats_dma = cp->ring_dma + (CP_RING_BYTES - CP_STATS_SIZE);
-
return cp_init_rings(cp);
}
@@ -1187,7 +1180,6 @@ static void cp_free_rings (struct cp_private *cp)
pci_free_consistent(cp->pdev, CP_RING_BYTES, cp->rx_ring, cp->ring_dma);
cp->rx_ring = NULL;
cp->tx_ring = NULL;
- cp->nic_stats = NULL;
}
static int cp_open (struct net_device *dev)
@@ -1516,13 +1508,17 @@ static void cp_get_ethtool_stats (struct net_device *dev,
struct ethtool_stats *estats, u64 *tmp_stats)
{
struct cp_private *cp = netdev_priv(dev);
+ struct cp_dma_stats *nic_stats;
+ dma_addr_t dma;
int i;
- memset(cp->nic_stats, 0, sizeof(struct cp_dma_stats));
+ nic_stats = pci_alloc_consistent(cp->pdev, sizeof(*nic_stats), &dma);
+ if (!nic_stats)
+ return;
/* begin NIC statistics dump */
- cpw32(StatsAddr + 4, (cp->nic_stats_dma >> 16) >> 16);
- cpw32(StatsAddr, (cp->nic_stats_dma & 0xffffffff) | DumpStats);
+ cpw32(StatsAddr + 4, (u64)dma >> 32);
+ cpw32(StatsAddr, ((u64)dma & DMA_32BIT_MASK) | DumpStats);
cpr32(StatsAddr);
for (i = 0; i < 1000; i++) {
@@ -1532,24 +1528,27 @@ static void cp_get_ethtool_stats (struct net_device *dev,
}
cpw32(StatsAddr, 0);
cpw32(StatsAddr + 4, 0);
+ cpr32(StatsAddr);
i = 0;
- tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok);
- tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok);
- tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_err);
- tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_err);
- tmp_stats[i++] = le16_to_cpu(cp->nic_stats->rx_fifo);
- tmp_stats[i++] = le16_to_cpu(cp->nic_stats->frame_align);
- tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_1col);
- tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_mcol);
- tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_phys);
- tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_bcast);
- tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_ok_mcast);
- tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_abort);
- tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_underrun);
+ tmp_stats[i++] = le64_to_cpu(nic_stats->tx_ok);
+ tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok);
+ tmp_stats[i++] = le64_to_cpu(nic_stats->tx_err);
+ tmp_stats[i++] = le32_to_cpu(nic_stats->rx_err);
+ tmp_stats[i++] = le16_to_cpu(nic_stats->rx_fifo);
+ tmp_stats[i++] = le16_to_cpu(nic_stats->frame_align);
+ tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_1col);
+ tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_mcol);
+ tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_phys);
+ tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_bcast);
+ tmp_stats[i++] = le32_to_cpu(nic_stats->rx_ok_mcast);
+ tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort);
+ tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun);
tmp_stats[i++] = cp->cp_stats.rx_frags;
if (i != CP_NUM_STATS)
BUG();
+
+ pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma);
}
static struct ethtool_ops cp_ethtool_ops = {
@@ -1575,6 +1574,7 @@ static struct ethtool_ops cp_ethtool_ops = {
.set_wol = cp_set_wol,
.get_strings = cp_get_strings,
.get_ethtool_stats = cp_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1773,6 +1773,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < 3; i++)
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = cp_open;
dev->stop = cp_close;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 4c2cf7bbd252..30bee11c48bd 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -552,7 +552,8 @@ const static struct {
{ "RTL-8100B/8139D",
HW_REVID(1, 1, 1, 0, 1, 0, 1),
- HasLWake,
+ HasHltClk /* XXX undocumented? */
+ | HasLWake,
},
{ "RTL-8101",
@@ -970,6 +971,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
for (i = 0; i < 3; i++)
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* The Rtl8139-specific entries in the device structure. */
dev->open = rtl8139_open;
@@ -2465,6 +2467,7 @@ static struct ethtool_ops rtl8139_ethtool_ops = {
.get_strings = rtl8139_get_strings,
.get_stats_count = rtl8139_get_stats_count,
.get_ethtool_stats = rtl8139_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index 6d76f3a99b17..f87027420081 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -1094,7 +1094,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);
- if (inb_p(e8390_base) & E8390_TRANS)
+ if (inb_p(e8390_base + E8390_CMD) & E8390_TRANS)
{
printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n",
dev->name);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 6bb9232514b4..fee8c5cf1f3a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -475,6 +475,14 @@ config SGI_IOC3_ETH_HW_TX_CSUM
the moment only acceleration of IPv4 is supported. This option
enables offloading for checksums on transmit. If unsure, say Y.
+config MIPS_SIM_NET
+ tristate "MIPS simulator Network device (EXPERIMENTAL)"
+ depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL
+ help
+ The MIPSNET device is a simple Ethernet network device which is
+ emulated by the MIPS Simulator.
+ If you are not using a MIPSsim or are unsure, say N.
+
config SGI_O2MACE_ETH
tristate "SGI O2 MACE Fast Ethernet support"
depends on NET_ETHERNET && SGI_IP32=y
@@ -548,6 +556,14 @@ config SUNGEM
Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also
<http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
+config CASSINI
+ tristate "Sun Cassini support"
+ depends on NET_ETHERNET && PCI
+ select CRC32
+ help
+ Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
+ <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
+
config NET_VENDOR_3COM
bool "3COM cards"
depends on NET_ETHERNET && (ISA || EISA || MCA || PCI)
@@ -1322,7 +1338,7 @@ config FORCEDETH
config CS89x0
tristate "CS89x0 support"
- depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105
+ depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 || MACH_MP1000
---help---
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the
@@ -1647,7 +1663,7 @@ config LAN_SAA9730
config NET_POCKET
bool "Pocket and portable adapters"
- depends on NET_ETHERNET && ISA
+ depends on NET_ETHERNET && PARPORT
---help---
Cute little network (Ethernet) devices which attach to the parallel
port ("pocket adapters"), commonly used with laptops. If you have
@@ -1671,7 +1687,7 @@ config NET_POCKET
config ATP
tristate "AT-LAN-TEC/RealTek pocket adapter support"
- depends on NET_POCKET && ISA && X86
+ depends on NET_POCKET && PARPORT && X86
select CRC32
---help---
This is a network (Ethernet) device which attaches to your parallel
@@ -1686,7 +1702,7 @@ config ATP
config DE600
tristate "D-Link DE600 pocket adapter support"
- depends on NET_POCKET && ISA
+ depends on NET_POCKET && PARPORT
---help---
This is a network (Ethernet) device which attaches to your parallel
port. Read <file:Documentation/networking/DLINK.txt> as well as the
@@ -1701,7 +1717,7 @@ config DE600
config DE620
tristate "D-Link DE620 pocket adapter support"
- depends on NET_POCKET && ISA
+ depends on NET_POCKET && PARPORT
---help---
This is a network (Ethernet) device which attaches to your parallel
port. Read <file:Documentation/networking/DLINK.txt> as well as the
@@ -1738,11 +1754,18 @@ config 68360_ENET
the Motorola 68360 processor.
config FEC
- bool "FEC ethernet controller (of ColdFire 5272)"
- depends on M5272 || M5282
+ bool "FEC ethernet controller (of ColdFire CPUs)"
+ depends on M523x || M527x || M5272 || M528x
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
- controller on the Motorola ColdFire 5272 processor.
+ controller on some Motorola ColdFire processors.
+
+config FEC2
+ bool "Second FEC ethernet controller (on some ColdFire CPUs)"
+ depends on FEC
+ help
+ Say Y here if you want to use the second built-in 10/100 Fast
+ ethernet controller on some Motorola ColdFire processors.
config NE_H8300
tristate "NE2000 compatible support for H8/300"
@@ -1944,7 +1967,7 @@ config SKGE
---help---
This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
and related Gigabit Ethernet adapters. It is a new smaller driver
- driver with better performance and more complete ethtool support.
+ with better performance and more complete ethtool support.
It does not support the link failover and network management
features that "portable" vendor supplied sk98lin driver does.
@@ -2068,6 +2091,7 @@ config SPIDER_NET
config GIANFAR
tristate "Gianfar Ethernet"
depends on 85xx || 83xx
+ select PHYLIB
help
This driver supports the Gigabit TSEC on the MPC85xx
family of chips, and the FEC on the 8540
@@ -2228,6 +2252,20 @@ config ISERIES_VETH
tristate "iSeries Virtual Ethernet driver support"
depends on PPC_ISERIES
+config RIONET
+ tristate "RapidIO Ethernet over messaging driver support"
+ depends on NETDEVICES && RAPIDIO
+
+config RIONET_TX_SIZE
+ int "Number of outbound queue entries"
+ depends on RIONET
+ default "128"
+
+config RIONET_RX_SIZE
+ int "Number of inbound queue entries"
+ depends on RIONET
+ default "128"
+
config FDDI
bool "FDDI driver support"
depends on (PCI || EISA)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 8645c843cf4d..1a84e0435f64 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o
+gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
#
# link order important here
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUNQE) += sunqe.o
obj-$(CONFIG_SUNBMAC) += sunbmac.o
obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o
+obj-$(CONFIG_CASSINI) += cassini.o
obj-$(CONFIG_MACE) += mace.o
obj-$(CONFIG_BMAC) += bmac.o
@@ -63,6 +64,7 @@ obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
+obj-$(CONFIG_RIONET) += rionet.o
#
# end link order section
@@ -165,6 +167,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
+obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
obj-$(CONFIG_DECLANCE) += declance.o
obj-$(CONFIG_ATARILANCE) += atarilance.o
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 52c77cbe8c62..1f0302735416 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -160,7 +160,7 @@ static int __init com90io_probe(struct net_device *dev)
return -ENODEV;
}
if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) {
- BUGMSG(D_INIT_REASONS, "IO check_region %x-%x failed.\n",
+ BUGMSG(D_INIT_REASONS, "IO request_region %x-%x failed.\n",
ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
return -ENXIO;
}
@@ -242,7 +242,7 @@ static int __init com90io_found(struct net_device *dev)
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}
- /* Reserve the I/O region - guaranteed to work by check_region */
+ /* Reserve the I/O region */
if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)")) {
free_irq(dev->irq, dev);
return -EBUSY;
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 9b659e3c8d67..3d50e953faaa 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -15,16 +15,13 @@
*/
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/in.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/crc32.h>
@@ -32,8 +29,8 @@
#include <asm/system.h>
#include <asm/irq.h>
+#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/dma.h>
#define TX_BUFFERS 15
#define RX_BUFFERS 25
@@ -85,7 +82,7 @@ static inline unsigned short read_ireg(u_long base_addr, u_int reg)
u_short v;
__asm__(
"str%?h %1, [%2] @ NAT_RAP\n\t"
- "str%?h %0, [%2, #8] @ NET_IDP\n\t"
+ "ldr%?h %0, [%2, #8] @ NET_IDP\n\t"
: "=r" (v)
: "r" (reg), "r" (ISAIO_BASE + 0x0464));
return v;
@@ -288,7 +285,7 @@ static void am79c961_timer(unsigned long data)
else if (!lnkstat && carrier)
netif_carrier_off(dev);
- mod_timer(&priv->timer, jiffies + 5*HZ);
+ mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500));
}
/*
@@ -709,13 +706,9 @@ static int __init am79c961_init(void)
goto release;
am79c961_banner();
- printk(KERN_INFO "%s: ether address ", dev->name);
- /* Retrive and print the ethernet address. */
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
- printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
- }
spin_lock_init(&priv->chip_lock);
init_timer(&priv->timer);
@@ -736,8 +729,14 @@ static int __init am79c961_init(void)
#endif
ret = register_netdev(dev);
- if (ret == 0)
+ if (ret == 0) {
+ printk(KERN_INFO "%s: ether address ", dev->name);
+
+ for (i = 0; i < 6; i++)
+ printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
+
return 0;
+ }
release:
release_region(dev->base_addr, 0x18);
diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c
index 1798ce7262c9..0095384ff454 100644
--- a/drivers/net/atari_bionet.c
+++ b/drivers/net/atari_bionet.c
@@ -155,7 +155,7 @@ static int bionet_close(struct net_device *dev);
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 81c362c8cb97..8b997809f9de 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -165,7 +165,7 @@ static void pamsnet_tick(unsigned long);
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/au1000_eth.c b/drivers/net/au1000_eth.c
index c82b9cd1c924..78506911d656 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -151,13 +151,6 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
SUPPORTED_Autoneg
-static char *phy_link[] =
-{ "unknown",
- "10Base2", "10BaseT",
- "AUI",
- "100BaseT", "100BaseTX", "100BaseFX"
-};
-
int bcm_5201_init(struct net_device *dev, int phy_addr)
{
s16 data;
@@ -785,6 +778,7 @@ static struct mii_chip_info {
{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
+ {"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0},
{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
@@ -1045,7 +1039,7 @@ found:
#endif
if (aup->mii->chip_info == NULL) {
- printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
+ printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n",
dev->name);
return -1;
}
@@ -1546,6 +1540,9 @@ au1000_probe(u32 ioaddr, int irq, int port_num)
printk(KERN_ERR "%s: out of memory\n", dev->name);
goto err_out;
}
+ aup->mii->next = NULL;
+ aup->mii->chip_info = NULL;
+ aup->mii->status = 0;
aup->mii->mii_control_reg = 0;
aup->mii->mii_data_reg = 0;
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 94939f570f78..282ebd15f011 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -106,6 +106,29 @@ static int b44_poll(struct net_device *dev, int *budget);
static void b44_poll_controller(struct net_device *dev);
#endif
+static int dma_desc_align_mask;
+static int dma_desc_sync_size;
+
+static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
+ dma_addr_t dma_base,
+ unsigned long offset,
+ enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_device(&pdev->dev, dma_base,
+ offset & dma_desc_align_mask,
+ dma_desc_sync_size, dir);
+}
+
+static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
+ dma_addr_t dma_base,
+ unsigned long offset,
+ enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
+ offset & dma_desc_align_mask,
+ dma_desc_sync_size, dir);
+}
+
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
{
return readl(bp->regs + reg);
@@ -668,6 +691,11 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dp->ctrl = cpu_to_le32(ctrl);
dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+ dest_idx * sizeof(dp),
+ DMA_BIDIRECTIONAL);
+
return RX_PKT_BUF_SZ;
}
@@ -692,6 +720,11 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
pci_unmap_addr_set(dest_map, mapping,
pci_unmap_addr(src_map, mapping));
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
+ src_idx * sizeof(src_desc),
+ DMA_BIDIRECTIONAL);
+
ctrl = src_desc->ctrl;
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= cpu_to_le32(DESC_CTRL_EOT);
@@ -700,8 +733,14 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dest_desc->ctrl = ctrl;
dest_desc->addr = src_desc->addr;
+
src_map->skb = NULL;
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+ dest_idx * sizeof(dest_desc),
+ DMA_BIDIRECTIONAL);
+
pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
@@ -959,6 +998,11 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
+ if (bp->flags & B44_FLAG_TX_RING_HACK)
+ b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
+ entry * sizeof(bp->tx_ring[0]),
+ DMA_TO_DEVICE);
+
entry = NEXT_TX(entry);
bp->tx_prod = entry;
@@ -1064,6 +1108,16 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES,
+ PCI_DMA_BIDIRECTIONAL);
+
+ if (bp->flags & B44_FLAG_TX_RING_HACK)
+ dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES,
+ PCI_DMA_TODEVICE);
+
for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
break;
@@ -1085,14 +1139,28 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL;
}
if (bp->rx_ring) {
- pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
- bp->rx_ring, bp->rx_ring_dma);
+ if (bp->flags & B44_FLAG_RX_RING_HACK) {
+ dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
+ kfree(bp->rx_ring);
+ } else
+ pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+ bp->rx_ring, bp->rx_ring_dma);
bp->rx_ring = NULL;
+ bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
- pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
- bp->tx_ring, bp->tx_ring_dma);
+ if (bp->flags & B44_FLAG_TX_RING_HACK) {
+ dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
+ kfree(bp->tx_ring);
+ } else
+ pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+ bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
+ bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
}
@@ -1118,12 +1186,56 @@ static int b44_alloc_consistent(struct b44 *bp)
size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
- if (!bp->rx_ring)
- goto out_err;
+ if (!bp->rx_ring) {
+ /* Allocation may have failed due to pci_alloc_consistent
+ insisting on use of GFP_DMA, which is more restrictive
+ than necessary... */
+ struct dma_desc *rx_ring;
+ dma_addr_t rx_ring_dma;
+
+ if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
+ goto out_err;
+
+ memset(rx_ring, 0, size);
+ rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
+
+ if (rx_ring_dma + size > B44_DMA_MASK) {
+ kfree(rx_ring);
+ goto out_err;
+ }
+
+ bp->rx_ring = rx_ring;
+ bp->rx_ring_dma = rx_ring_dma;
+ bp->flags |= B44_FLAG_RX_RING_HACK;
+ }
bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
- if (!bp->tx_ring)
- goto out_err;
+ if (!bp->tx_ring) {
+ /* Allocation may have failed due to pci_alloc_consistent
+ insisting on use of GFP_DMA, which is more restrictive
+ than necessary... */
+ struct dma_desc *tx_ring;
+ dma_addr_t tx_ring_dma;
+
+ if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
+ goto out_err;
+
+ memset(tx_ring, 0, size);
+ tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
+
+ if (tx_ring_dma + size > B44_DMA_MASK) {
+ kfree(tx_ring);
+ goto out_err;
+ }
+
+ bp->tx_ring = tx_ring;
+ bp->tx_ring_dma = tx_ring_dma;
+ bp->flags |= B44_FLAG_TX_RING_HACK;
+ }
return 0;
@@ -1676,6 +1788,7 @@ static struct ethtool_ops b44_ethtool_ops = {
.set_pauseparam = b44_set_pauseparam,
.get_msglevel = b44_get_msglevel,
.set_msglevel = b44_set_msglevel,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1718,6 +1831,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->dev->dev_addr[3] = eeprom[80];
bp->dev->dev_addr[4] = eeprom[83];
bp->dev->dev_addr[5] = eeprom[82];
+ memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
bp->phy_addr = eeprom[90] & 0x1f;
@@ -1971,6 +2085,12 @@ static struct pci_driver b44_driver = {
static int __init b44_init(void)
{
+ unsigned int dma_desc_align_size = dma_get_cache_alignment();
+
+ /* Setup paramaters for syncing RX/TX DMA descriptors */
+ dma_desc_align_mask = ~(dma_desc_align_size - 1);
+ dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
+
return pci_module_init(&b44_driver);
}
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 11c40a2e71c7..593cb0ad4100 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -400,6 +400,8 @@ struct b44 {
#define B44_FLAG_ADV_100HALF 0x04000000
#define B44_FLAG_ADV_100FULL 0x08000000
#define B44_FLAG_INTERNAL_PHY 0x10000000
+#define B44_FLAG_RX_RING_HACK 0x20000000
+#define B44_FLAG_TX_RING_HACK 0x40000000
u32 rx_offset;
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 8dc657fc8afb..60dba4a1ca5c 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -218,7 +218,7 @@ void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data )
static inline
-volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset )
+unsigned short bmread(struct net_device *dev, unsigned long reg_offset )
{
return in_le16((void __iomem *)dev->base_addr + reg_offset);
}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 55a72c7ad001..3a2ace01e444 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;
@@ -5014,6 +5015,7 @@ static struct ethtool_ops bnx2_ethtool_ops = {
.phys_id = bnx2_phys_id,
.get_stats_count = bnx2_get_stats_count,
.get_ethtool_stats = bnx2_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
/* Called with rtnl_lock */
@@ -5441,6 +5443,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
memcpy(dev->dev_addr, bp->mac_addr, 6);
+ memcpy(dev->perm_addr, bp->mac_addr, 6);
bp->name = board_info[ent->driver_data].name,
printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz found at mem %lx, "
"IRQ %d, ",
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 9ad3f5740cd8..62857b6a6ee4 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -50,6 +50,7 @@
#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/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 94c9f68dd16b..8032126fd589 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -487,6 +487,8 @@
* * Added xmit_hash_policy_layer34()
* - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
* Set version to 2.6.3.
+ * 2005/09/26 - Jay Vosburgh <fubar@us.ibm.com>
+ * - Removed backwards compatibility for old ifenslaves. Version 2.6.4.
*/
//#define BONDING_DEBUG 1
@@ -595,14 +597,7 @@ static int arp_ip_count = 0;
static int bond_mode = BOND_MODE_ROUNDROBIN;
static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
static int lacp_fast = 0;
-static int app_abi_ver = 0;
-static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
- * we receive from the application. Once set,
- * it won't be changed, and the module will
- * refuse to enslave/release interfaces if the
- * command comes from an application using
- * another ABI version.
- */
+
struct bond_parm_tbl {
char *modename;
int mode;
@@ -1294,12 +1289,13 @@ static void bond_mc_list_destroy(struct bonding *bond)
/*
* Copy all the Multicast addresses from src to the bonding device dst
*/
-static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond, int gpf_flag)
+static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
+ gfp_t gfp_flag)
{
struct dev_mc_list *dmi, *new_dmi;
for (dmi = mc_list; dmi; dmi = dmi->next) {
- new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
+ new_dmi = kmalloc(sizeof(struct dev_mc_list), gfp_flag);
if (!new_dmi) {
/* FIXME: Potential memory leak !!! */
@@ -1653,7 +1649,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
int old_features = bond_dev->features;
int res = 0;
- if (slave_dev->do_ioctl == NULL) {
+ if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
+ slave_dev->do_ioctl == NULL) {
printk(KERN_WARNING DRV_NAME
": Warning : no link monitoring support for %s\n",
slave_dev->name);
@@ -1701,51 +1698,29 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
}
}
- if (app_abi_ver >= 1) {
- /* The application is using an ABI, which requires the
- * slave interface to be closed.
- */
- if ((slave_dev->flags & IFF_UP)) {
- printk(KERN_ERR DRV_NAME
- ": Error: %s is up\n",
- slave_dev->name);
- res = -EPERM;
- goto err_undo_flags;
- }
-
- if (slave_dev->set_mac_address == NULL) {
- printk(KERN_ERR DRV_NAME
- ": Error: The slave device you specified does "
- "not support setting the MAC address.\n");
- printk(KERN_ERR
- "Your kernel likely does not support slave "
- "devices.\n");
+ /*
+ * Old ifenslave binaries are no longer supported. These can
+ * be identified with moderate accurary by the state of the slave:
+ * the current ifenslave will set the interface down prior to
+ * enslaving it; the old ifenslave will not.
+ */
+ if ((slave_dev->flags & IFF_UP)) {
+ printk(KERN_ERR DRV_NAME ": %s is up. "
+ "This may be due to an out of date ifenslave.\n",
+ slave_dev->name);
+ res = -EPERM;
+ goto err_undo_flags;
+ }
- res = -EOPNOTSUPP;
- goto err_undo_flags;
- }
- } else {
- /* The application is not using an ABI, which requires the
- * slave interface to be open.
- */
- if (!(slave_dev->flags & IFF_UP)) {
- printk(KERN_ERR DRV_NAME
- ": Error: %s is not running\n",
- slave_dev->name);
- res = -EINVAL;
- goto err_undo_flags;
- }
+ if (slave_dev->set_mac_address == NULL) {
+ printk(KERN_ERR DRV_NAME
+ ": Error: The slave device you specified does "
+ "not support setting the MAC address.\n");
+ printk(KERN_ERR
+ "Your kernel likely does not support slave devices.\n");
- if ((bond->params.mode == BOND_MODE_8023AD) ||
- (bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
- printk(KERN_ERR DRV_NAME
- ": Error: to use %s mode, you must upgrade "
- "ifenslave.\n",
- bond_mode_name(bond->params.mode));
- res = -EOPNOTSUPP;
- goto err_undo_flags;
- }
+ res = -EOPNOTSUPP;
+ goto err_undo_flags;
}
new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL);
@@ -1761,41 +1736,36 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
*/
new_slave->original_flags = slave_dev->flags;
- if (app_abi_ver >= 1) {
- /* save slave's original ("permanent") mac address for
- * modes that needs it, and for restoring it upon release,
- * and then set it to the master's address
- */
- memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
+ /*
+ * Save slave's original ("permanent") mac address for modes
+ * that need it, and for restoring it upon release, and then
+ * set it to the master's address
+ */
+ memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
- /* set slave to master's mac address
- * The application already set the master's
- * mac address to that of the first slave
- */
- memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
- addr.sa_family = slave_dev->type;
- res = dev_set_mac_address(slave_dev, &addr);
- if (res) {
- dprintk("Error %d calling set_mac_address\n", res);
- goto err_free;
- }
+ /*
+ * Set slave to master's mac address. The application already
+ * set the master's mac address to that of the first slave
+ */
+ memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
+ addr.sa_family = slave_dev->type;
+ res = dev_set_mac_address(slave_dev, &addr);
+ if (res) {
+ dprintk("Error %d calling set_mac_address\n", res);
+ goto err_free;
+ }
- /* open the slave since the application closed it */
- res = dev_open(slave_dev);
- if (res) {
- dprintk("Openning slave %s failed\n", slave_dev->name);
- goto err_restore_mac;
- }
+ /* open the slave since the application closed it */
+ res = dev_open(slave_dev);
+ if (res) {
+ dprintk("Openning slave %s failed\n", slave_dev->name);
+ goto err_restore_mac;
}
res = netdev_set_master(slave_dev, bond_dev);
if (res) {
dprintk("Error %d calling netdev_set_master\n", res);
- if (app_abi_ver < 1) {
- goto err_free;
- } else {
- goto err_close;
- }
+ goto err_close;
}
new_slave->dev = slave_dev;
@@ -1996,39 +1966,6 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
write_unlock_bh(&bond->lock);
- if (app_abi_ver < 1) {
- /*
- * !!! This is to support old versions of ifenslave.
- * We can remove this in 2.5 because our ifenslave takes
- * care of this for us.
- * We check to see if the master has a mac address yet.
- * If not, we'll give it the mac address of our slave device.
- */
- int ndx = 0;
-
- for (ndx = 0; ndx < bond_dev->addr_len; ndx++) {
- dprintk("Checking ndx=%d of bond_dev->dev_addr\n",
- ndx);
- if (bond_dev->dev_addr[ndx] != 0) {
- dprintk("Found non-zero byte at ndx=%d\n",
- ndx);
- break;
- }
- }
-
- if (ndx == bond_dev->addr_len) {
- /*
- * We got all the way through the address and it was
- * all 0's.
- */
- dprintk("%s doesn't have a MAC address yet. \n",
- bond_dev->name);
- dprintk("Going to give assign it from %s.\n",
- slave_dev->name);
- bond_sethwaddr(bond_dev, slave_dev);
- }
- }
-
printk(KERN_INFO DRV_NAME
": %s: enslaving %s as a%s interface with a%s link.\n",
bond_dev->name, slave_dev->name,
@@ -2226,12 +2163,10 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
/* close slave before restoring its mac address */
dev_close(slave_dev);
- if (app_abi_ver >= 1) {
- /* restore original ("permanent") mac address */
- memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
- addr.sa_family = slave_dev->type;
- dev_set_mac_address(slave_dev, &addr);
- }
+ /* restore original ("permanent") mac address */
+ memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+ addr.sa_family = slave_dev->type;
+ dev_set_mac_address(slave_dev, &addr);
/* restore the original state of the
* IFF_NOARP flag that might have been
@@ -2319,12 +2254,10 @@ static int bond_release_all(struct net_device *bond_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
- if (app_abi_ver >= 1) {
- /* restore original ("permanent") mac address*/
- memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
- addr.sa_family = slave_dev->type;
- dev_set_mac_address(slave_dev, &addr);
- }
+ /* restore original ("permanent") mac address*/
+ memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+ addr.sa_family = slave_dev->type;
+ dev_set_mac_address(slave_dev, &addr);
/* restore the original state of the IFF_NOARP flag that might have
* been set by bond_set_slave_inactive_flags()
@@ -2422,57 +2355,6 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
return res;
}
-static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr)
-{
- struct ethtool_drvinfo info;
- void __user *addr = ifr->ifr_data;
- uint32_t cmd;
-
- if (get_user(cmd, (uint32_t __user *)addr)) {
- return -EFAULT;
- }
-
- switch (cmd) {
- case ETHTOOL_GDRVINFO:
- if (copy_from_user(&info, addr, sizeof(info))) {
- return -EFAULT;
- }
-
- if (strcmp(info.driver, "ifenslave") == 0) {
- int new_abi_ver;
- char *endptr;
-
- new_abi_ver = simple_strtoul(info.fw_version,
- &endptr, 0);
- if (*endptr) {
- printk(KERN_ERR DRV_NAME
- ": Error: got invalid ABI "
- "version from application\n");
-
- return -EINVAL;
- }
-
- if (orig_app_abi_ver == -1) {
- orig_app_abi_ver = new_abi_ver;
- }
-
- app_abi_ver = new_abi_ver;
- }
-
- strncpy(info.driver, DRV_NAME, 32);
- strncpy(info.version, DRV_VERSION, 32);
- snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
-
- if (copy_to_user(addr, &info, sizeof(info))) {
- return -EFAULT;
- }
-
- return 0;
- default:
- return -EOPNOTSUPP;
- }
-}
-
static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
{
struct bonding *bond = bond_dev->priv;
@@ -2775,7 +2657,7 @@ static u32 bond_glean_dev_ip(struct net_device *dev)
return 0;
rcu_read_lock();
- idev = __in_dev_get(dev);
+ idev = __in_dev_get_rcu(dev);
if (!idev)
goto out;
@@ -2879,6 +2761,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
* This target is not on a VLAN
*/
if (rt->u.dst.dev == bond->dev) {
+ ip_rt_put(rt);
dprintk("basa: rtdev == bond->dev: arp_send\n");
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
bond->master_ip, 0);
@@ -2898,6 +2781,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
}
if (vlan_id) {
+ ip_rt_put(rt);
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
vlan->vlan_ip, vlan_id);
continue;
@@ -2909,6 +2793,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
bond->dev->name, NIPQUAD(fl.fl4_dst),
rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
}
+ ip_rt_put(rt);
}
}
@@ -3438,16 +3323,11 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
seq_printf(seq, "Link Failure Count: %d\n",
slave->link_failure_count);
- if (app_abi_ver >= 1) {
- seq_printf(seq,
- "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
- slave->perm_hwaddr[0],
- slave->perm_hwaddr[1],
- slave->perm_hwaddr[2],
- slave->perm_hwaddr[3],
- slave->perm_hwaddr[4],
- slave->perm_hwaddr[5]);
- }
+ seq_printf(seq,
+ "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ slave->perm_hwaddr[0], slave->perm_hwaddr[1],
+ slave->perm_hwaddr[2], slave->perm_hwaddr[3],
+ slave->perm_hwaddr[4], slave->perm_hwaddr[5]);
if (bond->params.mode == BOND_MODE_8023AD) {
const struct aggregator *agg
@@ -4006,15 +3886,12 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
struct ifslave k_sinfo;
struct ifslave __user *u_sinfo = NULL;
struct mii_ioctl_data *mii = NULL;
- int prev_abi_ver = orig_app_abi_ver;
int res = 0;
dprintk("bond_ioctl: master=%s, cmd=%d\n",
bond_dev->name, cmd);
switch (cmd) {
- case SIOCETHTOOL:
- return bond_ethtool_ioctl(bond_dev, ifr);
case SIOCGMIIPHY:
mii = if_mii(ifr);
if (!mii) {
@@ -4086,21 +3963,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
return -EPERM;
}
- if (orig_app_abi_ver == -1) {
- /* no orig_app_abi_ver was provided yet, so we'll use the
- * current one from now on, even if it's 0
- */
- orig_app_abi_ver = app_abi_ver;
-
- } else if (orig_app_abi_ver != app_abi_ver) {
- printk(KERN_ERR DRV_NAME
- ": Error: already using ifenslave ABI version %d; to "
- "upgrade ifenslave to version %d, you must first "
- "reload bonding.\n",
- orig_app_abi_ver, app_abi_ver);
- return -EINVAL;
- }
-
slave_dev = dev_get_by_name(ifr->ifr_slave);
dprintk("slave_dev=%p: \n", slave_dev);
@@ -4133,14 +3995,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
dev_put(slave_dev);
}
- if (res < 0) {
- /* The ioctl failed, so there's no point in changing the
- * orig_app_abi_ver. We'll restore it's value just in case
- * we've changed it earlier in this function.
- */
- orig_app_abi_ver = prev_abi_ver;
- }
-
return res;
}
@@ -4387,6 +4241,43 @@ out:
return 0;
}
+static void bond_activebackup_xmit_copy(struct sk_buff *skb,
+ struct bonding *bond,
+ struct slave *slave)
+{
+ struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
+ struct ethhdr *eth_data;
+ u8 *hwaddr;
+ int res;
+
+ if (!skb2) {
+ printk(KERN_ERR DRV_NAME ": Error: "
+ "bond_activebackup_xmit_copy(): skb_copy() failed\n");
+ return;
+ }
+
+ skb2->mac.raw = (unsigned char *)skb2->data;
+ eth_data = eth_hdr(skb2);
+
+ /* Pick an appropriate source MAC address
+ * -- use slave's perm MAC addr, unless used by bond
+ * -- otherwise, borrow active slave's perm MAC addr
+ * since that will not be used
+ */
+ hwaddr = slave->perm_hwaddr;
+ if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
+ hwaddr = bond->curr_active_slave->perm_hwaddr;
+
+ /* Set source MAC address appropriately */
+ memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
+
+ res = bond_dev_queue_xmit(bond, skb2, slave->dev);
+ if (res)
+ dev_kfree_skb(skb2);
+
+ return;
+}
+
/*
* in active-backup mode, we know that bond->curr_active_slave is always valid if
* the bond has a usable interface.
@@ -4403,10 +4294,26 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
goto out;
}
- if (bond->curr_active_slave) { /* one usable interface */
- res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+ if (!bond->curr_active_slave)
+ goto out;
+
+ /* Xmit IGMP frames on all slaves to ensure rapid fail-over
+ for multicast traffic on snooping switches */
+ if (skb->protocol == __constant_htons(ETH_P_IP) &&
+ skb->nh.iph->protocol == IPPROTO_IGMP) {
+ struct slave *slave, *active_slave;
+ int i;
+
+ active_slave = bond->curr_active_slave;
+ bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
+ active_slave->prev)
+ if (IS_UP(slave->dev) &&
+ (slave->link == BOND_LINK_UP))
+ bond_activebackup_xmit_copy(skb, bond, slave);
}
+ res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+
out:
if (res) {
/* no suitable interface, frame not sent */
@@ -4574,9 +4481,18 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode)
}
}
+static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strncpy(drvinfo->driver, DRV_NAME, 32);
+ strncpy(drvinfo->version, DRV_VERSION, 32);
+ snprintf(drvinfo->fw_version, 32, "%d", BOND_ABI_VERSION);
+}
+
static struct ethtool_ops bond_ethtool_ops = {
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
+ .get_drvinfo = bond_ethtool_get_drvinfo,
};
/*
@@ -5036,6 +4952,14 @@ static int __init bonding_init(void)
return 0;
out_err:
+ /*
+ * rtnl_unlock() will run netdev_run_todo(), putting the
+ * thus-far-registered bonding devices into a state which
+ * unregigister_netdevice() will accept
+ */
+ rtnl_unlock();
+ rtnl_lock();
+
/* free and unregister all bonds that were successfully added */
bond_free_all();
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 388196980862..bbf9da8af624 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "2.6.3"
-#define DRV_RELDATE "June 8, 2005"
+#define DRV_VERSION "2.6.4"
+#define DRV_RELDATE "September 26, 2005"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c
index 3d88ad622bdb..fb4098ed469e 100644
--- a/drivers/net/bsd_comp.c
+++ b/drivers/net/bsd_comp.c
@@ -323,33 +323,27 @@ static void bsd_reset (void *state)
*/
static void bsd_free (void *state)
- {
- struct bsd_db *db = (struct bsd_db *) state;
+{
+ struct bsd_db *db = state;
- if (db)
- {
+ if (!db)
+ return;
+
/*
* Release the dictionary
*/
- if (db->dict)
- {
- vfree (db->dict);
- db->dict = NULL;
- }
+ vfree(db->dict);
+ db->dict = NULL;
/*
* Release the string buffer
*/
- if (db->lens)
- {
- vfree (db->lens);
- db->lens = NULL;
- }
+ vfree(db->lens);
+ db->lens = NULL;
/*
* Finally release the structure itself.
*/
- kfree (db);
- }
- }
+ kfree(db);
+}
/*
* Allocate space for a (de) compressor.
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
new file mode 100644
index 000000000000..50f43dbf31ae
--- /dev/null
+++ b/drivers/net/cassini.c
@@ -0,0 +1,5237 @@
+/* cassini.c: Sun Microsystems Cassini(+) ethernet driver.
+ *
+ * Copyright (C) 2004 Sun Microsystems Inc.
+ * Copyright (C) 2003 Adrian Sun (asun@darksunrising.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.
+ *
+ * This driver uses the sungem driver (c) David Miller
+ * (davem@redhat.com) as its basis.
+ *
+ * The cassini chip has a number of features that distinguish it from
+ * the gem chip:
+ * 4 transmit descriptor rings that are used for either QoS (VLAN) or
+ * load balancing (non-VLAN mode)
+ * batching of multiple packets
+ * multiple CPU dispatching
+ * page-based RX descriptor engine with separate completion rings
+ * Gigabit support (GMII and PCS interface)
+ * MIF link up/down detection works
+ *
+ * RX is handled by page sized buffers that are attached as fragments to
+ * the skb. here's what's done:
+ * -- driver allocates pages at a time and keeps reference counts
+ * on them.
+ * -- the upper protocol layers assume that the header is in the skb
+ * itself. as a result, cassini will copy a small amount (64 bytes)
+ * to make them happy.
+ * -- driver appends the rest of the data pages as frags to skbuffs
+ * and increments the reference count
+ * -- on page reclamation, the driver swaps the page with a spare page.
+ * if that page is still in use, it frees its reference to that page,
+ * and allocates a new page for use. otherwise, it just recycles the
+ * the page.
+ *
+ * NOTE: cassini can parse the header. however, it's not worth it
+ * as long as the network stack requires a header copy.
+ *
+ * TX has 4 queues. currently these queues are used in a round-robin
+ * fashion for load balancing. They can also be used for QoS. for that
+ * to work, however, QoS information needs to be exposed down to the driver
+ * level so that subqueues get targetted to particular transmit rings.
+ * alternatively, the queues can be configured via use of the all-purpose
+ * ioctl.
+ *
+ * RX DATA: the rx completion ring has all the info, but the rx desc
+ * ring has all of the data. RX can conceivably come in under multiple
+ * interrupts, but the INT# assignment needs to be set up properly by
+ * the BIOS and conveyed to the driver. PCI BIOSes don't know how to do
+ * that. also, the two descriptor rings are designed to distinguish between
+ * encrypted and non-encrypted packets, but we use them for buffering
+ * instead.
+ *
+ * by default, the selective clear mask is set up to process rx packets.
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/list.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/random.h>
+#include <linux/mii.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+
+#include <net/checksum.h>
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#define cas_page_map(x) kmap_atomic((x), KM_SKB_DATA_SOFTIRQ)
+#define cas_page_unmap(x) kunmap_atomic((x), KM_SKB_DATA_SOFTIRQ)
+#define CAS_NCPUS num_online_cpus()
+
+#if defined(CONFIG_CASSINI_NAPI) && defined(HAVE_NETDEV_POLL)
+#define USE_NAPI
+#define cas_skb_release(x) netif_receive_skb(x)
+#else
+#define cas_skb_release(x) netif_rx(x)
+#endif
+
+/* select which firmware to use */
+#define USE_HP_WORKAROUND
+#define HP_WORKAROUND_DEFAULT /* select which firmware to use as default */
+#define CAS_HP_ALT_FIRMWARE cas_prog_null /* alternate firmware */
+
+#include "cassini.h"
+
+#define USE_TX_COMPWB /* use completion writeback registers */
+#define USE_CSMA_CD_PROTO /* standard CSMA/CD */
+#define USE_RX_BLANK /* hw interrupt mitigation */
+#undef USE_ENTROPY_DEV /* don't test for entropy device */
+
+/* NOTE: these aren't useable unless PCI interrupts can be assigned.
+ * also, we need to make cp->lock finer-grained.
+ */
+#undef USE_PCI_INTB
+#undef USE_PCI_INTC
+#undef USE_PCI_INTD
+#undef USE_QOS
+
+#undef USE_VPD_DEBUG /* debug vpd information if defined */
+
+/* rx processing options */
+#define USE_PAGE_ORDER /* specify to allocate large rx pages */
+#define RX_DONT_BATCH 0 /* if 1, don't batch flows */
+#define RX_COPY_ALWAYS 0 /* if 0, use frags */
+#define RX_COPY_MIN 64 /* copy a little to make upper layers happy */
+#undef RX_COUNT_BUFFERS /* define to calculate RX buffer stats */
+
+#define DRV_MODULE_NAME "cassini"
+#define PFX DRV_MODULE_NAME ": "
+#define DRV_MODULE_VERSION "1.4"
+#define DRV_MODULE_RELDATE "1 July 2004"
+
+#define CAS_DEF_MSG_ENABLE \
+ (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_TIMER | \
+ NETIF_MSG_IFDOWN | \
+ NETIF_MSG_IFUP | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
+/* length of time before we decide the hardware is borked,
+ * and dev->tx_timeout() should be called to fix the problem
+ */
+#define CAS_TX_TIMEOUT (HZ)
+#define CAS_LINK_TIMEOUT (22*HZ/10)
+#define CAS_LINK_FAST_TIMEOUT (1)
+
+/* timeout values for state changing. these specify the number
+ * of 10us delays to be used before giving up.
+ */
+#define STOP_TRIES_PHY 1000
+#define STOP_TRIES 5000
+
+/* specify a minimum frame size to deal with some fifo issues
+ * max mtu == 2 * page size - ethernet header - 64 - swivel =
+ * 2 * page_size - 0x50
+ */
+#define CAS_MIN_FRAME 97
+#define CAS_1000MB_MIN_FRAME 255
+#define CAS_MIN_MTU 60
+#define CAS_MAX_MTU min(((cp->page_size << 1) - 0x50), 9000)
+
+#if 1
+/*
+ * Eliminate these and use separate atomic counters for each, to
+ * avoid a race condition.
+ */
+#else
+#define CAS_RESET_MTU 1
+#define CAS_RESET_ALL 2
+#define CAS_RESET_SPARE 3
+#endif
+
+static char version[] __devinitdata =
+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("Adrian Sun (asun@darksunrising.com)");
+MODULE_DESCRIPTION("Sun Cassini(+) ethernet driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(cassini_debug, "i");
+MODULE_PARM_DESC(cassini_debug, "Cassini bitmapped debugging message enable value");
+MODULE_PARM(link_mode, "i");
+MODULE_PARM_DESC(link_mode, "default link mode");
+
+/*
+ * Work around for a PCS bug in which the link goes down due to the chip
+ * being confused and never showing a link status of "up."
+ */
+#define DEFAULT_LINKDOWN_TIMEOUT 5
+/*
+ * Value in seconds, for user input.
+ */
+static int linkdown_timeout = DEFAULT_LINKDOWN_TIMEOUT;
+MODULE_PARM(linkdown_timeout, "i");
+MODULE_PARM_DESC(linkdown_timeout,
+"min reset interval in sec. for PCS linkdown issue; disabled if not positive");
+
+/*
+ * value in 'ticks' (units used by jiffies). Set when we init the
+ * module because 'HZ' in actually a function call on some flavors of
+ * Linux. This will default to DEFAULT_LINKDOWN_TIMEOUT * HZ.
+ */
+static int link_transition_timeout;
+
+
+static int cassini_debug = -1; /* -1 == use CAS_DEF_MSG_ENABLE as value */
+static int link_mode;
+
+static u16 link_modes[] __devinitdata = {
+ BMCR_ANENABLE, /* 0 : autoneg */
+ 0, /* 1 : 10bt half duplex */
+ BMCR_SPEED100, /* 2 : 100bt half duplex */
+ BMCR_FULLDPLX, /* 3 : 10bt full duplex */
+ BMCR_SPEED100|BMCR_FULLDPLX, /* 4 : 100bt full duplex */
+ CAS_BMCR_SPEED1000|BMCR_FULLDPLX /* 5 : 1000bt full duplex */
+};
+
+static struct pci_device_id cas_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_CASSINI,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SATURN,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, cas_pci_tbl);
+
+static void cas_set_link_modes(struct cas *cp);
+
+static inline void cas_lock_tx(struct cas *cp)
+{
+ int i;
+
+ for (i = 0; i < N_TX_RINGS; i++)
+ spin_lock(&cp->tx_lock[i]);
+}
+
+static inline void cas_lock_all(struct cas *cp)
+{
+ spin_lock_irq(&cp->lock);
+ cas_lock_tx(cp);
+}
+
+/* WTZ: QA was finding deadlock problems with the previous
+ * versions after long test runs with multiple cards per machine.
+ * See if replacing cas_lock_all with safer versions helps. The
+ * symptoms QA is reporting match those we'd expect if interrupts
+ * aren't being properly restored, and we fixed a previous deadlock
+ * with similar symptoms by using save/restore versions in other
+ * places.
+ */
+#define cas_lock_all_save(cp, flags) \
+do { \
+ struct cas *xxxcp = (cp); \
+ spin_lock_irqsave(&xxxcp->lock, flags); \
+ cas_lock_tx(xxxcp); \
+} while (0)
+
+static inline void cas_unlock_tx(struct cas *cp)
+{
+ int i;
+
+ for (i = N_TX_RINGS; i > 0; i--)
+ spin_unlock(&cp->tx_lock[i - 1]);
+}
+
+static inline void cas_unlock_all(struct cas *cp)
+{
+ cas_unlock_tx(cp);
+ spin_unlock_irq(&cp->lock);
+}
+
+#define cas_unlock_all_restore(cp, flags) \
+do { \
+ struct cas *xxxcp = (cp); \
+ cas_unlock_tx(xxxcp); \
+ spin_unlock_irqrestore(&xxxcp->lock, flags); \
+} while (0)
+
+static void cas_disable_irq(struct cas *cp, const int ring)
+{
+ /* Make sure we won't get any more interrupts */
+ if (ring == 0) {
+ writel(0xFFFFFFFF, cp->regs + REG_INTR_MASK);
+ return;
+ }
+
+ /* disable completion interrupts and selectively mask */
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ switch (ring) {
+#if defined (USE_PCI_INTB) || defined(USE_PCI_INTC) || defined(USE_PCI_INTD)
+#ifdef USE_PCI_INTB
+ case 1:
+#endif
+#ifdef USE_PCI_INTC
+ case 2:
+#endif
+#ifdef USE_PCI_INTD
+ case 3:
+#endif
+ writel(INTRN_MASK_CLEAR_ALL | INTRN_MASK_RX_EN,
+ cp->regs + REG_PLUS_INTRN_MASK(ring));
+ break;
+#endif
+ default:
+ writel(INTRN_MASK_CLEAR_ALL, cp->regs +
+ REG_PLUS_INTRN_MASK(ring));
+ break;
+ }
+ }
+}
+
+static inline void cas_mask_intr(struct cas *cp)
+{
+ int i;
+
+ for (i = 0; i < N_RX_COMP_RINGS; i++)
+ cas_disable_irq(cp, i);
+}
+
+static void cas_enable_irq(struct cas *cp, const int ring)
+{
+ if (ring == 0) { /* all but TX_DONE */
+ writel(INTR_TX_DONE, cp->regs + REG_INTR_MASK);
+ return;
+ }
+
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ switch (ring) {
+#if defined (USE_PCI_INTB) || defined(USE_PCI_INTC) || defined(USE_PCI_INTD)
+#ifdef USE_PCI_INTB
+ case 1:
+#endif
+#ifdef USE_PCI_INTC
+ case 2:
+#endif
+#ifdef USE_PCI_INTD
+ case 3:
+#endif
+ writel(INTRN_MASK_RX_EN, cp->regs +
+ REG_PLUS_INTRN_MASK(ring));
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+}
+
+static inline void cas_unmask_intr(struct cas *cp)
+{
+ int i;
+
+ for (i = 0; i < N_RX_COMP_RINGS; i++)
+ cas_enable_irq(cp, i);
+}
+
+static inline void cas_entropy_gather(struct cas *cp)
+{
+#ifdef USE_ENTROPY_DEV
+ if ((cp->cas_flags & CAS_FLAG_ENTROPY_DEV) == 0)
+ return;
+
+ batch_entropy_store(readl(cp->regs + REG_ENTROPY_IV),
+ readl(cp->regs + REG_ENTROPY_IV),
+ sizeof(uint64_t)*8);
+#endif
+}
+
+static inline void cas_entropy_reset(struct cas *cp)
+{
+#ifdef USE_ENTROPY_DEV
+ if ((cp->cas_flags & CAS_FLAG_ENTROPY_DEV) == 0)
+ return;
+
+ writel(BIM_LOCAL_DEV_PAD | BIM_LOCAL_DEV_PROM | BIM_LOCAL_DEV_EXT,
+ cp->regs + REG_BIM_LOCAL_DEV_EN);
+ writeb(ENTROPY_RESET_STC_MODE, cp->regs + REG_ENTROPY_RESET);
+ writeb(0x55, cp->regs + REG_ENTROPY_RAND_REG);
+
+ /* if we read back 0x0, we don't have an entropy device */
+ if (readb(cp->regs + REG_ENTROPY_RAND_REG) == 0)
+ cp->cas_flags &= ~CAS_FLAG_ENTROPY_DEV;
+#endif
+}
+
+/* access to the phy. the following assumes that we've initialized the MIF to
+ * be in frame rather than bit-bang mode
+ */
+static u16 cas_phy_read(struct cas *cp, int reg)
+{
+ u32 cmd;
+ int limit = STOP_TRIES_PHY;
+
+ cmd = MIF_FRAME_ST | MIF_FRAME_OP_READ;
+ cmd |= CAS_BASE(MIF_FRAME_PHY_ADDR, cp->phy_addr);
+ cmd |= CAS_BASE(MIF_FRAME_REG_ADDR, reg);
+ cmd |= MIF_FRAME_TURN_AROUND_MSB;
+ writel(cmd, cp->regs + REG_MIF_FRAME);
+
+ /* poll for completion */
+ while (limit-- > 0) {
+ udelay(10);
+ cmd = readl(cp->regs + REG_MIF_FRAME);
+ if (cmd & MIF_FRAME_TURN_AROUND_LSB)
+ return (cmd & MIF_FRAME_DATA_MASK);
+ }
+ return 0xFFFF; /* -1 */
+}
+
+static int cas_phy_write(struct cas *cp, int reg, u16 val)
+{
+ int limit = STOP_TRIES_PHY;
+ u32 cmd;
+
+ cmd = MIF_FRAME_ST | MIF_FRAME_OP_WRITE;
+ cmd |= CAS_BASE(MIF_FRAME_PHY_ADDR, cp->phy_addr);
+ cmd |= CAS_BASE(MIF_FRAME_REG_ADDR, reg);
+ cmd |= MIF_FRAME_TURN_AROUND_MSB;
+ cmd |= val & MIF_FRAME_DATA_MASK;
+ writel(cmd, cp->regs + REG_MIF_FRAME);
+
+ /* poll for completion */
+ while (limit-- > 0) {
+ udelay(10);
+ cmd = readl(cp->regs + REG_MIF_FRAME);
+ if (cmd & MIF_FRAME_TURN_AROUND_LSB)
+ return 0;
+ }
+ return -1;
+}
+
+static void cas_phy_powerup(struct cas *cp)
+{
+ u16 ctl = cas_phy_read(cp, MII_BMCR);
+
+ if ((ctl & BMCR_PDOWN) == 0)
+ return;
+ ctl &= ~BMCR_PDOWN;
+ cas_phy_write(cp, MII_BMCR, ctl);
+}
+
+static void cas_phy_powerdown(struct cas *cp)
+{
+ u16 ctl = cas_phy_read(cp, MII_BMCR);
+
+ if (ctl & BMCR_PDOWN)
+ return;
+ ctl |= BMCR_PDOWN;
+ cas_phy_write(cp, MII_BMCR, ctl);
+}
+
+/* cp->lock held. note: the last put_page will free the buffer */
+static int cas_page_free(struct cas *cp, cas_page_t *page)
+{
+ pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size,
+ PCI_DMA_FROMDEVICE);
+ __free_pages(page->buffer, cp->page_order);
+ kfree(page);
+ return 0;
+}
+
+#ifdef RX_COUNT_BUFFERS
+#define RX_USED_ADD(x, y) ((x)->used += (y))
+#define RX_USED_SET(x, y) ((x)->used = (y))
+#else
+#define RX_USED_ADD(x, y)
+#define RX_USED_SET(x, y)
+#endif
+
+/* local page allocation routines for the receive buffers. jumbo pages
+ * require at least 8K contiguous and 8K aligned buffers.
+ */
+static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags)
+{
+ cas_page_t *page;
+
+ page = kmalloc(sizeof(cas_page_t), flags);
+ if (!page)
+ return NULL;
+
+ INIT_LIST_HEAD(&page->list);
+ RX_USED_SET(page, 0);
+ page->buffer = alloc_pages(flags, cp->page_order);
+ if (!page->buffer)
+ goto page_err;
+ page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0,
+ cp->page_size, PCI_DMA_FROMDEVICE);
+ return page;
+
+page_err:
+ kfree(page);
+ return NULL;
+}
+
+/* initialize spare pool of rx buffers, but allocate during the open */
+static void cas_spare_init(struct cas *cp)
+{
+ spin_lock(&cp->rx_inuse_lock);
+ INIT_LIST_HEAD(&cp->rx_inuse_list);
+ spin_unlock(&cp->rx_inuse_lock);
+
+ spin_lock(&cp->rx_spare_lock);
+ INIT_LIST_HEAD(&cp->rx_spare_list);
+ cp->rx_spares_needed = RX_SPARE_COUNT;
+ spin_unlock(&cp->rx_spare_lock);
+}
+
+/* used on close. free all the spare buffers. */
+static void cas_spare_free(struct cas *cp)
+{
+ struct list_head list, *elem, *tmp;
+
+ /* free spare buffers */
+ INIT_LIST_HEAD(&list);
+ spin_lock(&cp->rx_spare_lock);
+ list_splice(&cp->rx_spare_list, &list);
+ INIT_LIST_HEAD(&cp->rx_spare_list);
+ spin_unlock(&cp->rx_spare_lock);
+ list_for_each_safe(elem, tmp, &list) {
+ cas_page_free(cp, list_entry(elem, cas_page_t, list));
+ }
+
+ INIT_LIST_HEAD(&list);
+#if 1
+ /*
+ * Looks like Adrian had protected this with a different
+ * lock than used everywhere else to manipulate this list.
+ */
+ spin_lock(&cp->rx_inuse_lock);
+ list_splice(&cp->rx_inuse_list, &list);
+ INIT_LIST_HEAD(&cp->rx_inuse_list);
+ spin_unlock(&cp->rx_inuse_lock);
+#else
+ spin_lock(&cp->rx_spare_lock);
+ list_splice(&cp->rx_inuse_list, &list);
+ INIT_LIST_HEAD(&cp->rx_inuse_list);
+ spin_unlock(&cp->rx_spare_lock);
+#endif
+ list_for_each_safe(elem, tmp, &list) {
+ cas_page_free(cp, list_entry(elem, cas_page_t, list));
+ }
+}
+
+/* replenish spares if needed */
+static void cas_spare_recover(struct cas *cp, const gfp_t flags)
+{
+ struct list_head list, *elem, *tmp;
+ int needed, i;
+
+ /* check inuse list. if we don't need any more free buffers,
+ * just free it
+ */
+
+ /* make a local copy of the list */
+ INIT_LIST_HEAD(&list);
+ spin_lock(&cp->rx_inuse_lock);
+ list_splice(&cp->rx_inuse_list, &list);
+ INIT_LIST_HEAD(&cp->rx_inuse_list);
+ spin_unlock(&cp->rx_inuse_lock);
+
+ list_for_each_safe(elem, tmp, &list) {
+ cas_page_t *page = list_entry(elem, cas_page_t, list);
+
+ if (page_count(page->buffer) > 1)
+ continue;
+
+ list_del(elem);
+ spin_lock(&cp->rx_spare_lock);
+ if (cp->rx_spares_needed > 0) {
+ list_add(elem, &cp->rx_spare_list);
+ cp->rx_spares_needed--;
+ spin_unlock(&cp->rx_spare_lock);
+ } else {
+ spin_unlock(&cp->rx_spare_lock);
+ cas_page_free(cp, page);
+ }
+ }
+
+ /* put any inuse buffers back on the list */
+ if (!list_empty(&list)) {
+ spin_lock(&cp->rx_inuse_lock);
+ list_splice(&list, &cp->rx_inuse_list);
+ spin_unlock(&cp->rx_inuse_lock);
+ }
+
+ spin_lock(&cp->rx_spare_lock);
+ needed = cp->rx_spares_needed;
+ spin_unlock(&cp->rx_spare_lock);
+ if (!needed)
+ return;
+
+ /* we still need spares, so try to allocate some */
+ INIT_LIST_HEAD(&list);
+ i = 0;
+ while (i < needed) {
+ cas_page_t *spare = cas_page_alloc(cp, flags);
+ if (!spare)
+ break;
+ list_add(&spare->list, &list);
+ i++;
+ }
+
+ spin_lock(&cp->rx_spare_lock);
+ list_splice(&list, &cp->rx_spare_list);
+ cp->rx_spares_needed -= i;
+ spin_unlock(&cp->rx_spare_lock);
+}
+
+/* pull a page from the list. */
+static cas_page_t *cas_page_dequeue(struct cas *cp)
+{
+ struct list_head *entry;
+ int recover;
+
+ spin_lock(&cp->rx_spare_lock);
+ if (list_empty(&cp->rx_spare_list)) {
+ /* try to do a quick recovery */
+ spin_unlock(&cp->rx_spare_lock);
+ cas_spare_recover(cp, GFP_ATOMIC);
+ spin_lock(&cp->rx_spare_lock);
+ if (list_empty(&cp->rx_spare_list)) {
+ if (netif_msg_rx_err(cp))
+ printk(KERN_ERR "%s: no spare buffers "
+ "available.\n", cp->dev->name);
+ spin_unlock(&cp->rx_spare_lock);
+ return NULL;
+ }
+ }
+
+ entry = cp->rx_spare_list.next;
+ list_del(entry);
+ recover = ++cp->rx_spares_needed;
+ spin_unlock(&cp->rx_spare_lock);
+
+ /* trigger the timer to do the recovery */
+ if ((recover & (RX_SPARE_RECOVER_VAL - 1)) == 0) {
+#if 1
+ atomic_inc(&cp->reset_task_pending);
+ atomic_inc(&cp->reset_task_pending_spare);
+ schedule_work(&cp->reset_task);
+#else
+ atomic_set(&cp->reset_task_pending, CAS_RESET_SPARE);
+ schedule_work(&cp->reset_task);
+#endif
+ }
+ return list_entry(entry, cas_page_t, list);
+}
+
+
+static void cas_mif_poll(struct cas *cp, const int enable)
+{
+ u32 cfg;
+
+ cfg = readl(cp->regs + REG_MIF_CFG);
+ cfg &= (MIF_CFG_MDIO_0 | MIF_CFG_MDIO_1);
+
+ if (cp->phy_type & CAS_PHY_MII_MDIO1)
+ cfg |= MIF_CFG_PHY_SELECT;
+
+ /* poll and interrupt on link status change. */
+ if (enable) {
+ cfg |= MIF_CFG_POLL_EN;
+ cfg |= CAS_BASE(MIF_CFG_POLL_REG, MII_BMSR);
+ cfg |= CAS_BASE(MIF_CFG_POLL_PHY, cp->phy_addr);
+ }
+ writel((enable) ? ~(BMSR_LSTATUS | BMSR_ANEGCOMPLETE) : 0xFFFF,
+ cp->regs + REG_MIF_MASK);
+ writel(cfg, cp->regs + REG_MIF_CFG);
+}
+
+/* Must be invoked under cp->lock */
+static void cas_begin_auto_negotiation(struct cas *cp, struct ethtool_cmd *ep)
+{
+ u16 ctl;
+#if 1
+ int lcntl;
+ int changed = 0;
+ int oldstate = cp->lstate;
+ int link_was_not_down = !(oldstate == link_down);
+#endif
+ /* Setup link parameters */
+ if (!ep)
+ goto start_aneg;
+ lcntl = cp->link_cntl;
+ if (ep->autoneg == AUTONEG_ENABLE)
+ cp->link_cntl = BMCR_ANENABLE;
+ else {
+ cp->link_cntl = 0;
+ if (ep->speed == SPEED_100)
+ cp->link_cntl |= BMCR_SPEED100;
+ else if (ep->speed == SPEED_1000)
+ cp->link_cntl |= CAS_BMCR_SPEED1000;
+ if (ep->duplex == DUPLEX_FULL)
+ cp->link_cntl |= BMCR_FULLDPLX;
+ }
+#if 1
+ changed = (lcntl != cp->link_cntl);
+#endif
+start_aneg:
+ if (cp->lstate == link_up) {
+ printk(KERN_INFO "%s: PCS link down.\n",
+ cp->dev->name);
+ } else {
+ if (changed) {
+ printk(KERN_INFO "%s: link configuration changed\n",
+ cp->dev->name);
+ }
+ }
+ cp->lstate = link_down;
+ cp->link_transition = LINK_TRANSITION_LINK_DOWN;
+ if (!cp->hw_running)
+ return;
+#if 1
+ /*
+ * WTZ: If the old state was link_up, we turn off the carrier
+ * to replicate everything we do elsewhere on a link-down
+ * event when we were already in a link-up state..
+ */
+ if (oldstate == link_up)
+ netif_carrier_off(cp->dev);
+ if (changed && link_was_not_down) {
+ /*
+ * WTZ: This branch will simply schedule a full reset after
+ * we explicitly changed link modes in an ioctl. See if this
+ * fixes the link-problems we were having for forced mode.
+ */
+ atomic_inc(&cp->reset_task_pending);
+ atomic_inc(&cp->reset_task_pending_all);
+ schedule_work(&cp->reset_task);
+ cp->timer_ticks = 0;
+ mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT);
+ return;
+ }
+#endif
+ if (cp->phy_type & CAS_PHY_SERDES) {
+ u32 val = readl(cp->regs + REG_PCS_MII_CTRL);
+
+ if (cp->link_cntl & BMCR_ANENABLE) {
+ val |= (PCS_MII_RESTART_AUTONEG | PCS_MII_AUTONEG_EN);
+ cp->lstate = link_aneg;
+ } else {
+ if (cp->link_cntl & BMCR_FULLDPLX)
+ val |= PCS_MII_CTRL_DUPLEX;
+ val &= ~PCS_MII_AUTONEG_EN;
+ cp->lstate = link_force_ok;
+ }
+ cp->link_transition = LINK_TRANSITION_LINK_CONFIG;
+ writel(val, cp->regs + REG_PCS_MII_CTRL);
+
+ } else {
+ cas_mif_poll(cp, 0);
+ ctl = cas_phy_read(cp, MII_BMCR);
+ ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 |
+ CAS_BMCR_SPEED1000 | BMCR_ANENABLE);
+ ctl |= cp->link_cntl;
+ if (ctl & BMCR_ANENABLE) {
+ ctl |= BMCR_ANRESTART;
+ cp->lstate = link_aneg;
+ } else {
+ cp->lstate = link_force_ok;
+ }
+ cp->link_transition = LINK_TRANSITION_LINK_CONFIG;
+ cas_phy_write(cp, MII_BMCR, ctl);
+ cas_mif_poll(cp, 1);
+ }
+
+ cp->timer_ticks = 0;
+ mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT);
+}
+
+/* Must be invoked under cp->lock. */
+static int cas_reset_mii_phy(struct cas *cp)
+{
+ int limit = STOP_TRIES_PHY;
+ u16 val;
+
+ cas_phy_write(cp, MII_BMCR, BMCR_RESET);
+ udelay(100);
+ while (limit--) {
+ val = cas_phy_read(cp, MII_BMCR);
+ if ((val & BMCR_RESET) == 0)
+ break;
+ udelay(10);
+ }
+ return (limit <= 0);
+}
+
+static void cas_saturn_firmware_load(struct cas *cp)
+{
+ cas_saturn_patch_t *patch = cas_saturn_patch;
+
+ cas_phy_powerdown(cp);
+
+ /* expanded memory access mode */
+ cas_phy_write(cp, DP83065_MII_MEM, 0x0);
+
+ /* pointer configuration for new firmware */
+ cas_phy_write(cp, DP83065_MII_REGE, 0x8ff9);
+ cas_phy_write(cp, DP83065_MII_REGD, 0xbd);
+ cas_phy_write(cp, DP83065_MII_REGE, 0x8ffa);
+ cas_phy_write(cp, DP83065_MII_REGD, 0x82);
+ cas_phy_write(cp, DP83065_MII_REGE, 0x8ffb);
+ cas_phy_write(cp, DP83065_MII_REGD, 0x0);
+ cas_phy_write(cp, DP83065_MII_REGE, 0x8ffc);
+ cas_phy_write(cp, DP83065_MII_REGD, 0x39);
+
+ /* download new firmware */
+ cas_phy_write(cp, DP83065_MII_MEM, 0x1);
+ cas_phy_write(cp, DP83065_MII_REGE, patch->addr);
+ while (patch->addr) {
+ cas_phy_write(cp, DP83065_MII_REGD, patch->val);
+ patch++;
+ }
+
+ /* enable firmware */
+ cas_phy_write(cp, DP83065_MII_REGE, 0x8ff8);
+ cas_phy_write(cp, DP83065_MII_REGD, 0x1);
+}
+
+
+/* phy initialization */
+static void cas_phy_init(struct cas *cp)
+{
+ u16 val;
+
+ /* if we're in MII/GMII mode, set up phy */
+ if (CAS_PHY_MII(cp->phy_type)) {
+ writel(PCS_DATAPATH_MODE_MII,
+ cp->regs + REG_PCS_DATAPATH_MODE);
+
+ cas_mif_poll(cp, 0);
+ cas_reset_mii_phy(cp); /* take out of isolate mode */
+
+ if (PHY_LUCENT_B0 == cp->phy_id) {
+ /* workaround link up/down issue with lucent */
+ cas_phy_write(cp, LUCENT_MII_REG, 0x8000);
+ cas_phy_write(cp, MII_BMCR, 0x00f1);
+ cas_phy_write(cp, LUCENT_MII_REG, 0x0);
+
+ } else if (PHY_BROADCOM_B0 == (cp->phy_id & 0xFFFFFFFC)) {
+ /* workarounds for broadcom phy */
+ cas_phy_write(cp, BROADCOM_MII_REG8, 0x0C20);
+ cas_phy_write(cp, BROADCOM_MII_REG7, 0x0012);
+ cas_phy_write(cp, BROADCOM_MII_REG5, 0x1804);
+ cas_phy_write(cp, BROADCOM_MII_REG7, 0x0013);
+ cas_phy_write(cp, BROADCOM_MII_REG5, 0x1204);
+ cas_phy_write(cp, BROADCOM_MII_REG7, 0x8006);
+ cas_phy_write(cp, BROADCOM_MII_REG5, 0x0132);
+ cas_phy_write(cp, BROADCOM_MII_REG7, 0x8006);
+ cas_phy_write(cp, BROADCOM_MII_REG5, 0x0232);
+ cas_phy_write(cp, BROADCOM_MII_REG7, 0x201F);
+ cas_phy_write(cp, BROADCOM_MII_REG5, 0x0A20);
+
+ } else if (PHY_BROADCOM_5411 == cp->phy_id) {
+ val = cas_phy_read(cp, BROADCOM_MII_REG4);
+ val = cas_phy_read(cp, BROADCOM_MII_REG4);
+ if (val & 0x0080) {
+ /* link workaround */
+ cas_phy_write(cp, BROADCOM_MII_REG4,
+ val & ~0x0080);
+ }
+
+ } else if (cp->cas_flags & CAS_FLAG_SATURN) {
+ writel((cp->phy_type & CAS_PHY_MII_MDIO0) ?
+ SATURN_PCFG_FSI : 0x0,
+ cp->regs + REG_SATURN_PCFG);
+
+ /* load firmware to address 10Mbps auto-negotiation
+ * issue. NOTE: this will need to be changed if the
+ * default firmware gets fixed.
+ */
+ if (PHY_NS_DP83065 == cp->phy_id) {
+ cas_saturn_firmware_load(cp);
+ }
+ cas_phy_powerup(cp);
+ }
+
+ /* advertise capabilities */
+ val = cas_phy_read(cp, MII_BMCR);
+ val &= ~BMCR_ANENABLE;
+ cas_phy_write(cp, MII_BMCR, val);
+ udelay(10);
+
+ cas_phy_write(cp, MII_ADVERTISE,
+ cas_phy_read(cp, MII_ADVERTISE) |
+ (ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL |
+ CAS_ADVERTISE_PAUSE |
+ CAS_ADVERTISE_ASYM_PAUSE));
+
+ if (cp->cas_flags & CAS_FLAG_1000MB_CAP) {
+ /* make sure that we don't advertise half
+ * duplex to avoid a chip issue
+ */
+ val = cas_phy_read(cp, CAS_MII_1000_CTRL);
+ val &= ~CAS_ADVERTISE_1000HALF;
+ val |= CAS_ADVERTISE_1000FULL;
+ cas_phy_write(cp, CAS_MII_1000_CTRL, val);
+ }
+
+ } else {
+ /* reset pcs for serdes */
+ u32 val;
+ int limit;
+
+ writel(PCS_DATAPATH_MODE_SERDES,
+ cp->regs + REG_PCS_DATAPATH_MODE);
+
+ /* enable serdes pins on saturn */
+ if (cp->cas_flags & CAS_FLAG_SATURN)
+ writel(0, cp->regs + REG_SATURN_PCFG);
+
+ /* Reset PCS unit. */
+ val = readl(cp->regs + REG_PCS_MII_CTRL);
+ val |= PCS_MII_RESET;
+ writel(val, cp->regs + REG_PCS_MII_CTRL);
+
+ limit = STOP_TRIES;
+ while (limit-- > 0) {
+ udelay(10);
+ if ((readl(cp->regs + REG_PCS_MII_CTRL) &
+ PCS_MII_RESET) == 0)
+ break;
+ }
+ if (limit <= 0)
+ printk(KERN_WARNING "%s: PCS reset bit would not "
+ "clear [%08x].\n", cp->dev->name,
+ readl(cp->regs + REG_PCS_STATE_MACHINE));
+
+ /* Make sure PCS is disabled while changing advertisement
+ * configuration.
+ */
+ writel(0x0, cp->regs + REG_PCS_CFG);
+
+ /* Advertise all capabilities except half-duplex. */
+ val = readl(cp->regs + REG_PCS_MII_ADVERT);
+ val &= ~PCS_MII_ADVERT_HD;
+ val |= (PCS_MII_ADVERT_FD | PCS_MII_ADVERT_SYM_PAUSE |
+ PCS_MII_ADVERT_ASYM_PAUSE);
+ writel(val, cp->regs + REG_PCS_MII_ADVERT);
+
+ /* enable PCS */
+ writel(PCS_CFG_EN, cp->regs + REG_PCS_CFG);
+
+ /* pcs workaround: enable sync detect */
+ writel(PCS_SERDES_CTRL_SYNCD_EN,
+ cp->regs + REG_PCS_SERDES_CTRL);
+ }
+}
+
+
+static int cas_pcs_link_check(struct cas *cp)
+{
+ u32 stat, state_machine;
+ int retval = 0;
+
+ /* The link status bit latches on zero, so you must
+ * read it twice in such a case to see a transition
+ * to the link being up.
+ */
+ stat = readl(cp->regs + REG_PCS_MII_STATUS);
+ if ((stat & PCS_MII_STATUS_LINK_STATUS) == 0)
+ stat = readl(cp->regs + REG_PCS_MII_STATUS);
+
+ /* The remote-fault indication is only valid
+ * when autoneg has completed.
+ */
+ if ((stat & (PCS_MII_STATUS_AUTONEG_COMP |
+ PCS_MII_STATUS_REMOTE_FAULT)) ==
+ (PCS_MII_STATUS_AUTONEG_COMP | PCS_MII_STATUS_REMOTE_FAULT)) {
+ if (netif_msg_link(cp))
+ printk(KERN_INFO "%s: PCS RemoteFault\n",
+ cp->dev->name);
+ }
+
+ /* work around link detection issue by querying the PCS state
+ * machine directly.
+ */
+ state_machine = readl(cp->regs + REG_PCS_STATE_MACHINE);
+ if ((state_machine & PCS_SM_LINK_STATE_MASK) != SM_LINK_STATE_UP) {
+ stat &= ~PCS_MII_STATUS_LINK_STATUS;
+ } else if (state_machine & PCS_SM_WORD_SYNC_STATE_MASK) {
+ stat |= PCS_MII_STATUS_LINK_STATUS;
+ }
+
+ if (stat & PCS_MII_STATUS_LINK_STATUS) {
+ if (cp->lstate != link_up) {
+ if (cp->opened) {
+ cp->lstate = link_up;
+ cp->link_transition = LINK_TRANSITION_LINK_UP;
+
+ cas_set_link_modes(cp);
+ netif_carrier_on(cp->dev);
+ }
+ }
+ } else if (cp->lstate == link_up) {
+ cp->lstate = link_down;
+ if (link_transition_timeout != 0 &&
+ cp->link_transition != LINK_TRANSITION_REQUESTED_RESET &&
+ !cp->link_transition_jiffies_valid) {
+ /*
+ * force a reset, as a workaround for the
+ * link-failure problem. May want to move this to a
+ * point a bit earlier in the sequence. If we had
+ * generated a reset a short time ago, we'll wait for
+ * the link timer to check the status until a
+ * timer expires (link_transistion_jiffies_valid is
+ * true when the timer is running.) Instead of using
+ * a system timer, we just do a check whenever the
+ * link timer is running - this clears the flag after
+ * a suitable delay.
+ */
+ retval = 1;
+ cp->link_transition = LINK_TRANSITION_REQUESTED_RESET;
+ cp->link_transition_jiffies = jiffies;
+ cp->link_transition_jiffies_valid = 1;
+ } else {
+ cp->link_transition = LINK_TRANSITION_ON_FAILURE;
+ }
+ netif_carrier_off(cp->dev);
+ if (cp->opened && netif_msg_link(cp)) {
+ printk(KERN_INFO "%s: PCS link down.\n",
+ cp->dev->name);
+ }
+
+ /* Cassini only: if you force a mode, there can be
+ * sync problems on link down. to fix that, the following
+ * things need to be checked:
+ * 1) read serialink state register
+ * 2) read pcs status register to verify link down.
+ * 3) if link down and serial link == 0x03, then you need
+ * to global reset the chip.
+ */
+ if ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0) {
+ /* should check to see if we're in a forced mode */
+ stat = readl(cp->regs + REG_PCS_SERDES_STATE);
+ if (stat == 0x03)
+ return 1;
+ }
+ } else if (cp->lstate == link_down) {
+ if (link_transition_timeout != 0 &&
+ cp->link_transition != LINK_TRANSITION_REQUESTED_RESET &&
+ !cp->link_transition_jiffies_valid) {
+ /* force a reset, as a workaround for the
+ * link-failure problem. May want to move
+ * this to a point a bit earlier in the
+ * sequence.
+ */
+ retval = 1;
+ cp->link_transition = LINK_TRANSITION_REQUESTED_RESET;
+ cp->link_transition_jiffies = jiffies;
+ cp->link_transition_jiffies_valid = 1;
+ } else {
+ cp->link_transition = LINK_TRANSITION_STILL_FAILED;
+ }
+ }
+
+ return retval;
+}
+
+static int cas_pcs_interrupt(struct net_device *dev,
+ struct cas *cp, u32 status)
+{
+ u32 stat = readl(cp->regs + REG_PCS_INTR_STATUS);
+
+ if ((stat & PCS_INTR_STATUS_LINK_CHANGE) == 0)
+ return 0;
+ return cas_pcs_link_check(cp);
+}
+
+static int cas_txmac_interrupt(struct net_device *dev,
+ struct cas *cp, u32 status)
+{
+ u32 txmac_stat = readl(cp->regs + REG_MAC_TX_STATUS);
+
+ if (!txmac_stat)
+ return 0;
+
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: txmac interrupt, txmac_stat: 0x%x\n",
+ cp->dev->name, txmac_stat);
+
+ /* Defer timer expiration is quite normal,
+ * don't even log the event.
+ */
+ if ((txmac_stat & MAC_TX_DEFER_TIMER) &&
+ !(txmac_stat & ~MAC_TX_DEFER_TIMER))
+ return 0;
+
+ spin_lock(&cp->stat_lock[0]);
+ if (txmac_stat & MAC_TX_UNDERRUN) {
+ printk(KERN_ERR "%s: TX MAC xmit underrun.\n",
+ dev->name);
+ cp->net_stats[0].tx_fifo_errors++;
+ }
+
+ if (txmac_stat & MAC_TX_MAX_PACKET_ERR) {
+ printk(KERN_ERR "%s: TX MAC max packet size error.\n",
+ dev->name);
+ cp->net_stats[0].tx_errors++;
+ }
+
+ /* The rest are all cases of one of the 16-bit TX
+ * counters expiring.
+ */
+ if (txmac_stat & MAC_TX_COLL_NORMAL)
+ cp->net_stats[0].collisions += 0x10000;
+
+ if (txmac_stat & MAC_TX_COLL_EXCESS) {
+ cp->net_stats[0].tx_aborted_errors += 0x10000;
+ cp->net_stats[0].collisions += 0x10000;
+ }
+
+ if (txmac_stat & MAC_TX_COLL_LATE) {
+ cp->net_stats[0].tx_aborted_errors += 0x10000;
+ cp->net_stats[0].collisions += 0x10000;
+ }
+ spin_unlock(&cp->stat_lock[0]);
+
+ /* We do not keep track of MAC_TX_COLL_FIRST and
+ * MAC_TX_PEAK_ATTEMPTS events.
+ */
+ return 0;
+}
+
+static void cas_load_firmware(struct cas *cp, cas_hp_inst_t *firmware)
+{
+ cas_hp_inst_t *inst;
+ u32 val;
+ int i;
+
+ i = 0;
+ while ((inst = firmware) && inst->note) {
+ writel(i, cp->regs + REG_HP_INSTR_RAM_ADDR);
+
+ val = CAS_BASE(HP_INSTR_RAM_HI_VAL, inst->val);
+ val |= CAS_BASE(HP_INSTR_RAM_HI_MASK, inst->mask);
+ writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_HI);
+
+ val = CAS_BASE(HP_INSTR_RAM_MID_OUTARG, inst->outarg >> 10);
+ val |= CAS_BASE(HP_INSTR_RAM_MID_OUTOP, inst->outop);
+ val |= CAS_BASE(HP_INSTR_RAM_MID_FNEXT, inst->fnext);
+ val |= CAS_BASE(HP_INSTR_RAM_MID_FOFF, inst->foff);
+ val |= CAS_BASE(HP_INSTR_RAM_MID_SNEXT, inst->snext);
+ val |= CAS_BASE(HP_INSTR_RAM_MID_SOFF, inst->soff);
+ val |= CAS_BASE(HP_INSTR_RAM_MID_OP, inst->op);
+ writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_MID);
+
+ val = CAS_BASE(HP_INSTR_RAM_LOW_OUTMASK, inst->outmask);
+ val |= CAS_BASE(HP_INSTR_RAM_LOW_OUTSHIFT, inst->outshift);
+ val |= CAS_BASE(HP_INSTR_RAM_LOW_OUTEN, inst->outenab);
+ val |= CAS_BASE(HP_INSTR_RAM_LOW_OUTARG, inst->outarg);
+ writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_LOW);
+ ++firmware;
+ ++i;
+ }
+}
+
+static void cas_init_rx_dma(struct cas *cp)
+{
+ u64 desc_dma = cp->block_dvma;
+ u32 val;
+ int i, size;
+
+ /* rx free descriptors */
+ val = CAS_BASE(RX_CFG_SWIVEL, RX_SWIVEL_OFF_VAL);
+ val |= CAS_BASE(RX_CFG_DESC_RING, RX_DESC_RINGN_INDEX(0));
+ val |= CAS_BASE(RX_CFG_COMP_RING, RX_COMP_RINGN_INDEX(0));
+ if ((N_RX_DESC_RINGS > 1) &&
+ (cp->cas_flags & CAS_FLAG_REG_PLUS)) /* do desc 2 */
+ val |= CAS_BASE(RX_CFG_DESC_RING1, RX_DESC_RINGN_INDEX(1));
+ writel(val, cp->regs + REG_RX_CFG);
+
+ val = (unsigned long) cp->init_rxds[0] -
+ (unsigned long) cp->init_block;
+ writel((desc_dma + val) >> 32, cp->regs + REG_RX_DB_HI);
+ writel((desc_dma + val) & 0xffffffff, cp->regs + REG_RX_DB_LOW);
+ writel(RX_DESC_RINGN_SIZE(0) - 4, cp->regs + REG_RX_KICK);
+
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ /* rx desc 2 is for IPSEC packets. however,
+ * we don't it that for that purpose.
+ */
+ val = (unsigned long) cp->init_rxds[1] -
+ (unsigned long) cp->init_block;
+ writel((desc_dma + val) >> 32, cp->regs + REG_PLUS_RX_DB1_HI);
+ writel((desc_dma + val) & 0xffffffff, cp->regs +
+ REG_PLUS_RX_DB1_LOW);
+ writel(RX_DESC_RINGN_SIZE(1) - 4, cp->regs +
+ REG_PLUS_RX_KICK1);
+ }
+
+ /* rx completion registers */
+ val = (unsigned long) cp->init_rxcs[0] -
+ (unsigned long) cp->init_block;
+ writel((desc_dma + val) >> 32, cp->regs + REG_RX_CB_HI);
+ writel((desc_dma + val) & 0xffffffff, cp->regs + REG_RX_CB_LOW);
+
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ /* rx comp 2-4 */
+ for (i = 1; i < MAX_RX_COMP_RINGS; i++) {
+ val = (unsigned long) cp->init_rxcs[i] -
+ (unsigned long) cp->init_block;
+ writel((desc_dma + val) >> 32, cp->regs +
+ REG_PLUS_RX_CBN_HI(i));
+ writel((desc_dma + val) & 0xffffffff, cp->regs +
+ REG_PLUS_RX_CBN_LOW(i));
+ }
+ }
+
+ /* read selective clear regs to prevent spurious interrupts
+ * on reset because complete == kick.
+ * selective clear set up to prevent interrupts on resets
+ */
+ readl(cp->regs + REG_INTR_STATUS_ALIAS);
+ writel(INTR_RX_DONE | INTR_RX_BUF_UNAVAIL, cp->regs + REG_ALIAS_CLEAR);
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ for (i = 1; i < N_RX_COMP_RINGS; i++)
+ readl(cp->regs + REG_PLUS_INTRN_STATUS_ALIAS(i));
+
+ /* 2 is different from 3 and 4 */
+ if (N_RX_COMP_RINGS > 1)
+ writel(INTR_RX_DONE_ALT | INTR_RX_BUF_UNAVAIL_1,
+ cp->regs + REG_PLUS_ALIASN_CLEAR(1));
+
+ for (i = 2; i < N_RX_COMP_RINGS; i++)
+ writel(INTR_RX_DONE_ALT,
+ cp->regs + REG_PLUS_ALIASN_CLEAR(i));
+ }
+
+ /* set up pause thresholds */
+ val = CAS_BASE(RX_PAUSE_THRESH_OFF,
+ cp->rx_pause_off / RX_PAUSE_THRESH_QUANTUM);
+ val |= CAS_BASE(RX_PAUSE_THRESH_ON,
+ cp->rx_pause_on / RX_PAUSE_THRESH_QUANTUM);
+ writel(val, cp->regs + REG_RX_PAUSE_THRESH);
+
+ /* zero out dma reassembly buffers */
+ for (i = 0; i < 64; i++) {
+ writel(i, cp->regs + REG_RX_TABLE_ADDR);
+ writel(0x0, cp->regs + REG_RX_TABLE_DATA_LOW);
+ writel(0x0, cp->regs + REG_RX_TABLE_DATA_MID);
+ writel(0x0, cp->regs + REG_RX_TABLE_DATA_HI);
+ }
+
+ /* make sure address register is 0 for normal operation */
+ writel(0x0, cp->regs + REG_RX_CTRL_FIFO_ADDR);
+ writel(0x0, cp->regs + REG_RX_IPP_FIFO_ADDR);
+
+ /* interrupt mitigation */
+#ifdef USE_RX_BLANK
+ val = CAS_BASE(RX_BLANK_INTR_TIME, RX_BLANK_INTR_TIME_VAL);
+ val |= CAS_BASE(RX_BLANK_INTR_PKT, RX_BLANK_INTR_PKT_VAL);
+ writel(val, cp->regs + REG_RX_BLANK);
+#else
+ writel(0x0, cp->regs + REG_RX_BLANK);
+#endif
+
+ /* interrupt generation as a function of low water marks for
+ * free desc and completion entries. these are used to trigger
+ * housekeeping for rx descs. we don't use the free interrupt
+ * as it's not very useful
+ */
+ /* val = CAS_BASE(RX_AE_THRESH_FREE, RX_AE_FREEN_VAL(0)); */
+ val = CAS_BASE(RX_AE_THRESH_COMP, RX_AE_COMP_VAL);
+ writel(val, cp->regs + REG_RX_AE_THRESH);
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ val = CAS_BASE(RX_AE1_THRESH_FREE, RX_AE_FREEN_VAL(1));
+ writel(val, cp->regs + REG_PLUS_RX_AE1_THRESH);
+ }
+
+ /* Random early detect registers. useful for congestion avoidance.
+ * this should be tunable.
+ */
+ writel(0x0, cp->regs + REG_RX_RED);
+
+ /* receive page sizes. default == 2K (0x800) */
+ val = 0;
+ if (cp->page_size == 0x1000)
+ val = 0x1;
+ else if (cp->page_size == 0x2000)
+ val = 0x2;
+ else if (cp->page_size == 0x4000)
+ val = 0x3;
+
+ /* round mtu + offset. constrain to page size. */
+ size = cp->dev->mtu + 64;
+ if (size > cp->page_size)
+ size = cp->page_size;
+
+ if (size <= 0x400)
+ i = 0x0;
+ else if (size <= 0x800)
+ i = 0x1;
+ else if (size <= 0x1000)
+ i = 0x2;
+ else
+ i = 0x3;
+
+ cp->mtu_stride = 1 << (i + 10);
+ val = CAS_BASE(RX_PAGE_SIZE, val);
+ val |= CAS_BASE(RX_PAGE_SIZE_MTU_STRIDE, i);
+ val |= CAS_BASE(RX_PAGE_SIZE_MTU_COUNT, cp->page_size >> (i + 10));
+ val |= CAS_BASE(RX_PAGE_SIZE_MTU_OFF, 0x1);
+ writel(val, cp->regs + REG_RX_PAGE_SIZE);
+
+ /* enable the header parser if desired */
+ if (CAS_HP_FIRMWARE == cas_prog_null)
+ return;
+
+ val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS);
+ val |= HP_CFG_PARSE_EN | HP_CFG_SYN_INC_MASK;
+ val |= CAS_BASE(HP_CFG_TCP_THRESH, HP_TCP_THRESH_VAL);
+ writel(val, cp->regs + REG_HP_CFG);
+}
+
+static inline void cas_rxc_init(struct cas_rx_comp *rxc)
+{
+ memset(rxc, 0, sizeof(*rxc));
+ rxc->word4 = cpu_to_le64(RX_COMP4_ZERO);
+}
+
+/* NOTE: we use the ENC RX DESC ring for spares. the rx_page[0,1]
+ * flipping is protected by the fact that the chip will not
+ * hand back the same page index while it's being processed.
+ */
+static inline cas_page_t *cas_page_spare(struct cas *cp, const int index)
+{
+ cas_page_t *page = cp->rx_pages[1][index];
+ cas_page_t *new;
+
+ if (page_count(page->buffer) == 1)
+ return page;
+
+ new = cas_page_dequeue(cp);
+ if (new) {
+ spin_lock(&cp->rx_inuse_lock);
+ list_add(&page->list, &cp->rx_inuse_list);
+ spin_unlock(&cp->rx_inuse_lock);
+ }
+ return new;
+}
+
+/* this needs to be changed if we actually use the ENC RX DESC ring */
+static cas_page_t *cas_page_swap(struct cas *cp, const int ring,
+ const int index)
+{
+ cas_page_t **page0 = cp->rx_pages[0];
+ cas_page_t **page1 = cp->rx_pages[1];
+
+ /* swap if buffer is in use */
+ if (page_count(page0[index]->buffer) > 1) {
+ cas_page_t *new = cas_page_spare(cp, index);
+ if (new) {
+ page1[index] = page0[index];
+ page0[index] = new;
+ }
+ }
+ RX_USED_SET(page0[index], 0);
+ return page0[index];
+}
+
+static void cas_clean_rxds(struct cas *cp)
+{
+ /* only clean ring 0 as ring 1 is used for spare buffers */
+ struct cas_rx_desc *rxd = cp->init_rxds[0];
+ int i, size;
+
+ /* release all rx flows */
+ for (i = 0; i < N_RX_FLOWS; i++) {
+ struct sk_buff *skb;
+ while ((skb = __skb_dequeue(&cp->rx_flows[i]))) {
+ cas_skb_release(skb);
+ }
+ }
+
+ /* initialize descriptors */
+ size = RX_DESC_RINGN_SIZE(0);
+ for (i = 0; i < size; i++) {
+ cas_page_t *page = cas_page_swap(cp, 0, i);
+ rxd[i].buffer = cpu_to_le64(page->dma_addr);
+ rxd[i].index = cpu_to_le64(CAS_BASE(RX_INDEX_NUM, i) |
+ CAS_BASE(RX_INDEX_RING, 0));
+ }
+
+ cp->rx_old[0] = RX_DESC_RINGN_SIZE(0) - 4;
+ cp->rx_last[0] = 0;
+ cp->cas_flags &= ~CAS_FLAG_RXD_POST(0);
+}
+
+static void cas_clean_rxcs(struct cas *cp)
+{
+ int i, j;
+
+ /* take ownership of rx comp descriptors */
+ memset(cp->rx_cur, 0, sizeof(*cp->rx_cur)*N_RX_COMP_RINGS);
+ memset(cp->rx_new, 0, sizeof(*cp->rx_new)*N_RX_COMP_RINGS);
+ for (i = 0; i < N_RX_COMP_RINGS; i++) {
+ struct cas_rx_comp *rxc = cp->init_rxcs[i];
+ for (j = 0; j < RX_COMP_RINGN_SIZE(i); j++) {
+ cas_rxc_init(rxc + j);
+ }
+ }
+}
+
+#if 0
+/* When we get a RX fifo overflow, the RX unit is probably hung
+ * so we do the following.
+ *
+ * If any part of the reset goes wrong, we return 1 and that causes the
+ * whole chip to be reset.
+ */
+static int cas_rxmac_reset(struct cas *cp)
+{
+ struct net_device *dev = cp->dev;
+ int limit;
+ u32 val;
+
+ /* First, reset MAC RX. */
+ writel(cp->mac_rx_cfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG);
+ for (limit = 0; limit < STOP_TRIES; limit++) {
+ if (!(readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_EN))
+ break;
+ udelay(10);
+ }
+ if (limit == STOP_TRIES) {
+ printk(KERN_ERR "%s: RX MAC will not disable, resetting whole "
+ "chip.\n", dev->name);
+ return 1;
+ }
+
+ /* Second, disable RX DMA. */
+ writel(0, cp->regs + REG_RX_CFG);
+ for (limit = 0; limit < STOP_TRIES; limit++) {
+ if (!(readl(cp->regs + REG_RX_CFG) & RX_CFG_DMA_EN))
+ break;
+ udelay(10);
+ }
+ if (limit == STOP_TRIES) {
+ printk(KERN_ERR "%s: RX DMA will not disable, resetting whole "
+ "chip.\n", dev->name);
+ return 1;
+ }
+
+ mdelay(5);
+
+ /* Execute RX reset command. */
+ writel(SW_RESET_RX, cp->regs + REG_SW_RESET);
+ for (limit = 0; limit < STOP_TRIES; limit++) {
+ if (!(readl(cp->regs + REG_SW_RESET) & SW_RESET_RX))
+ break;
+ udelay(10);
+ }
+ if (limit == STOP_TRIES) {
+ printk(KERN_ERR "%s: RX reset command will not execute, "
+ "resetting whole chip.\n", dev->name);
+ return 1;
+ }
+
+ /* reset driver rx state */
+ cas_clean_rxds(cp);
+ cas_clean_rxcs(cp);
+
+ /* Now, reprogram the rest of RX unit. */
+ cas_init_rx_dma(cp);
+
+ /* re-enable */
+ val = readl(cp->regs + REG_RX_CFG);
+ writel(val | RX_CFG_DMA_EN, cp->regs + REG_RX_CFG);
+ writel(MAC_RX_FRAME_RECV, cp->regs + REG_MAC_RX_MASK);
+ val = readl(cp->regs + REG_MAC_RX_CFG);
+ writel(val | MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG);
+ return 0;
+}
+#endif
+
+static int cas_rxmac_interrupt(struct net_device *dev, struct cas *cp,
+ u32 status)
+{
+ u32 stat = readl(cp->regs + REG_MAC_RX_STATUS);
+
+ if (!stat)
+ return 0;
+
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: rxmac interrupt, stat: 0x%x\n",
+ cp->dev->name, stat);
+
+ /* these are all rollovers */
+ spin_lock(&cp->stat_lock[0]);
+ if (stat & MAC_RX_ALIGN_ERR)
+ cp->net_stats[0].rx_frame_errors += 0x10000;
+
+ if (stat & MAC_RX_CRC_ERR)
+ cp->net_stats[0].rx_crc_errors += 0x10000;
+
+ if (stat & MAC_RX_LEN_ERR)
+ cp->net_stats[0].rx_length_errors += 0x10000;
+
+ if (stat & MAC_RX_OVERFLOW) {
+ cp->net_stats[0].rx_over_errors++;
+ cp->net_stats[0].rx_fifo_errors++;
+ }
+
+ /* We do not track MAC_RX_FRAME_COUNT and MAC_RX_VIOL_ERR
+ * events.
+ */
+ spin_unlock(&cp->stat_lock[0]);
+ return 0;
+}
+
+static int cas_mac_interrupt(struct net_device *dev, struct cas *cp,
+ u32 status)
+{
+ u32 stat = readl(cp->regs + REG_MAC_CTRL_STATUS);
+
+ if (!stat)
+ return 0;
+
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: mac interrupt, stat: 0x%x\n",
+ cp->dev->name, stat);
+
+ /* This interrupt is just for pause frame and pause
+ * tracking. It is useful for diagnostics and debug
+ * but probably by default we will mask these events.
+ */
+ if (stat & MAC_CTRL_PAUSE_STATE)
+ cp->pause_entered++;
+
+ if (stat & MAC_CTRL_PAUSE_RECEIVED)
+ cp->pause_last_time_recvd = (stat >> 16);
+
+ return 0;
+}
+
+
+/* Must be invoked under cp->lock. */
+static inline int cas_mdio_link_not_up(struct cas *cp)
+{
+ u16 val;
+
+ switch (cp->lstate) {
+ case link_force_ret:
+ if (netif_msg_link(cp))
+ printk(KERN_INFO "%s: Autoneg failed again, keeping"
+ " forced mode\n", cp->dev->name);
+ cas_phy_write(cp, MII_BMCR, cp->link_fcntl);
+ cp->timer_ticks = 5;
+ cp->lstate = link_force_ok;
+ cp->link_transition = LINK_TRANSITION_LINK_CONFIG;
+ break;
+
+ case link_aneg:
+ val = cas_phy_read(cp, MII_BMCR);
+
+ /* Try forced modes. we try things in the following order:
+ * 1000 full -> 100 full/half -> 10 half
+ */
+ val &= ~(BMCR_ANRESTART | BMCR_ANENABLE);
+ val |= BMCR_FULLDPLX;
+ val |= (cp->cas_flags & CAS_FLAG_1000MB_CAP) ?
+ CAS_BMCR_SPEED1000 : BMCR_SPEED100;
+ cas_phy_write(cp, MII_BMCR, val);
+ cp->timer_ticks = 5;
+ cp->lstate = link_force_try;
+ cp->link_transition = LINK_TRANSITION_LINK_CONFIG;
+ break;
+
+ case link_force_try:
+ /* Downgrade from 1000 to 100 to 10 Mbps if necessary. */
+ val = cas_phy_read(cp, MII_BMCR);
+ cp->timer_ticks = 5;
+ if (val & CAS_BMCR_SPEED1000) { /* gigabit */
+ val &= ~CAS_BMCR_SPEED1000;
+ val |= (BMCR_SPEED100 | BMCR_FULLDPLX);
+ cas_phy_write(cp, MII_BMCR, val);
+ break;
+ }
+
+ if (val & BMCR_SPEED100) {
+ if (val & BMCR_FULLDPLX) /* fd failed */
+ val &= ~BMCR_FULLDPLX;
+ else { /* 100Mbps failed */
+ val &= ~BMCR_SPEED100;
+ }
+ cas_phy_write(cp, MII_BMCR, val);
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+/* must be invoked with cp->lock held */
+static int cas_mii_link_check(struct cas *cp, const u16 bmsr)
+{
+ int restart;
+
+ if (bmsr & BMSR_LSTATUS) {
+ /* Ok, here we got a link. If we had it due to a forced
+ * fallback, and we were configured for autoneg, we
+ * retry a short autoneg pass. If you know your hub is
+ * broken, use ethtool ;)
+ */
+ if ((cp->lstate == link_force_try) &&
+ (cp->link_cntl & BMCR_ANENABLE)) {
+ cp->lstate = link_force_ret;
+ cp->link_transition = LINK_TRANSITION_LINK_CONFIG;
+ cas_mif_poll(cp, 0);
+ cp->link_fcntl = cas_phy_read(cp, MII_BMCR);
+ cp->timer_ticks = 5;
+ if (cp->opened && netif_msg_link(cp))
+ printk(KERN_INFO "%s: Got link after fallback, retrying"
+ " autoneg once...\n", cp->dev->name);
+ cas_phy_write(cp, MII_BMCR,
+ cp->link_fcntl | BMCR_ANENABLE |
+ BMCR_ANRESTART);
+ cas_mif_poll(cp, 1);
+
+ } else if (cp->lstate != link_up) {
+ cp->lstate = link_up;
+ cp->link_transition = LINK_TRANSITION_LINK_UP;
+
+ if (cp->opened) {
+ cas_set_link_modes(cp);
+ netif_carrier_on(cp->dev);
+ }
+ }
+ return 0;
+ }
+
+ /* link not up. if the link was previously up, we restart the
+ * whole process
+ */
+ restart = 0;
+ if (cp->lstate == link_up) {
+ cp->lstate = link_down;
+ cp->link_transition = LINK_TRANSITION_LINK_DOWN;
+
+ netif_carrier_off(cp->dev);
+ if (cp->opened && netif_msg_link(cp))
+ printk(KERN_INFO "%s: Link down\n",
+ cp->dev->name);
+ restart = 1;
+
+ } else if (++cp->timer_ticks > 10)
+ cas_mdio_link_not_up(cp);
+
+ return restart;
+}
+
+static int cas_mif_interrupt(struct net_device *dev, struct cas *cp,
+ u32 status)
+{
+ u32 stat = readl(cp->regs + REG_MIF_STATUS);
+ u16 bmsr;
+
+ /* check for a link change */
+ if (CAS_VAL(MIF_STATUS_POLL_STATUS, stat) == 0)
+ return 0;
+
+ bmsr = CAS_VAL(MIF_STATUS_POLL_DATA, stat);
+ return cas_mii_link_check(cp, bmsr);
+}
+
+static int cas_pci_interrupt(struct net_device *dev, struct cas *cp,
+ u32 status)
+{
+ u32 stat = readl(cp->regs + REG_PCI_ERR_STATUS);
+
+ if (!stat)
+ return 0;
+
+ printk(KERN_ERR "%s: PCI error [%04x:%04x] ", dev->name, stat,
+ readl(cp->regs + REG_BIM_DIAG));
+
+ /* cassini+ has this reserved */
+ if ((stat & PCI_ERR_BADACK) &&
+ ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0))
+ printk("<No ACK64# during ABS64 cycle> ");
+
+ if (stat & PCI_ERR_DTRTO)
+ printk("<Delayed transaction timeout> ");
+ if (stat & PCI_ERR_OTHER)
+ printk("<other> ");
+ if (stat & PCI_ERR_BIM_DMA_WRITE)
+ printk("<BIM DMA 0 write req> ");
+ if (stat & PCI_ERR_BIM_DMA_READ)
+ printk("<BIM DMA 0 read req> ");
+ printk("\n");
+
+ if (stat & PCI_ERR_OTHER) {
+ u16 cfg;
+
+ /* Interrogate PCI config space for the
+ * true cause.
+ */
+ pci_read_config_word(cp->pdev, PCI_STATUS, &cfg);
+ printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n",
+ dev->name, cfg);
+ if (cfg & PCI_STATUS_PARITY)
+ printk(KERN_ERR "%s: PCI parity error detected.\n",
+ dev->name);
+ if (cfg & PCI_STATUS_SIG_TARGET_ABORT)
+ printk(KERN_ERR "%s: PCI target abort.\n",
+ dev->name);
+ if (cfg & PCI_STATUS_REC_TARGET_ABORT)
+ printk(KERN_ERR "%s: PCI master acks target abort.\n",
+ dev->name);
+ if (cfg & PCI_STATUS_REC_MASTER_ABORT)
+ printk(KERN_ERR "%s: PCI master abort.\n", dev->name);
+ if (cfg & PCI_STATUS_SIG_SYSTEM_ERROR)
+ printk(KERN_ERR "%s: PCI system error SERR#.\n",
+ dev->name);
+ if (cfg & PCI_STATUS_DETECTED_PARITY)
+ printk(KERN_ERR "%s: PCI parity error.\n",
+ dev->name);
+
+ /* Write the error bits back to clear them. */
+ cfg &= (PCI_STATUS_PARITY |
+ PCI_STATUS_SIG_TARGET_ABORT |
+ PCI_STATUS_REC_TARGET_ABORT |
+ PCI_STATUS_REC_MASTER_ABORT |
+ PCI_STATUS_SIG_SYSTEM_ERROR |
+ PCI_STATUS_DETECTED_PARITY);
+ pci_write_config_word(cp->pdev, PCI_STATUS, cfg);
+ }
+
+ /* For all PCI errors, we should reset the chip. */
+ return 1;
+}
+
+/* All non-normal interrupt conditions get serviced here.
+ * Returns non-zero if we should just exit the interrupt
+ * handler right now (ie. if we reset the card which invalidates
+ * all of the other original irq status bits).
+ */
+static int cas_abnormal_irq(struct net_device *dev, struct cas *cp,
+ u32 status)
+{
+ if (status & INTR_RX_TAG_ERROR) {
+ /* corrupt RX tag framing */
+ if (netif_msg_rx_err(cp))
+ printk(KERN_DEBUG "%s: corrupt rx tag framing\n",
+ cp->dev->name);
+ spin_lock(&cp->stat_lock[0]);
+ cp->net_stats[0].rx_errors++;
+ spin_unlock(&cp->stat_lock[0]);
+ goto do_reset;
+ }
+
+ if (status & INTR_RX_LEN_MISMATCH) {
+ /* length mismatch. */
+ if (netif_msg_rx_err(cp))
+ printk(KERN_DEBUG "%s: length mismatch for rx frame\n",
+ cp->dev->name);
+ spin_lock(&cp->stat_lock[0]);
+ cp->net_stats[0].rx_errors++;
+ spin_unlock(&cp->stat_lock[0]);
+ goto do_reset;
+ }
+
+ if (status & INTR_PCS_STATUS) {
+ if (cas_pcs_interrupt(dev, cp, status))
+ goto do_reset;
+ }
+
+ if (status & INTR_TX_MAC_STATUS) {
+ if (cas_txmac_interrupt(dev, cp, status))
+ goto do_reset;
+ }
+
+ if (status & INTR_RX_MAC_STATUS) {
+ if (cas_rxmac_interrupt(dev, cp, status))
+ goto do_reset;
+ }
+
+ if (status & INTR_MAC_CTRL_STATUS) {
+ if (cas_mac_interrupt(dev, cp, status))
+ goto do_reset;
+ }
+
+ if (status & INTR_MIF_STATUS) {
+ if (cas_mif_interrupt(dev, cp, status))
+ goto do_reset;
+ }
+
+ if (status & INTR_PCI_ERROR_STATUS) {
+ if (cas_pci_interrupt(dev, cp, status))
+ goto do_reset;
+ }
+ return 0;
+
+do_reset:
+#if 1
+ atomic_inc(&cp->reset_task_pending);
+ atomic_inc(&cp->reset_task_pending_all);
+ printk(KERN_ERR "%s:reset called in cas_abnormal_irq [0x%x]\n",
+ dev->name, status);
+ schedule_work(&cp->reset_task);
+#else
+ atomic_set(&cp->reset_task_pending, CAS_RESET_ALL);
+ printk(KERN_ERR "reset called in cas_abnormal_irq\n");
+ schedule_work(&cp->reset_task);
+#endif
+ return 1;
+}
+
+/* NOTE: CAS_TABORT returns 1 or 2 so that it can be used when
+ * determining whether to do a netif_stop/wakeup
+ */
+#define CAS_TABORT(x) (((x)->cas_flags & CAS_FLAG_TARGET_ABORT) ? 2 : 1)
+#define CAS_ROUND_PAGE(x) (((x) + PAGE_SIZE - 1) & PAGE_MASK)
+static inline int cas_calc_tabort(struct cas *cp, const unsigned long addr,
+ const int len)
+{
+ unsigned long off = addr + len;
+
+ if (CAS_TABORT(cp) == 1)
+ return 0;
+ if ((CAS_ROUND_PAGE(off) - off) > TX_TARGET_ABORT_LEN)
+ return 0;
+ return TX_TARGET_ABORT_LEN;
+}
+
+static inline void cas_tx_ringN(struct cas *cp, int ring, int limit)
+{
+ struct cas_tx_desc *txds;
+ struct sk_buff **skbs;
+ struct net_device *dev = cp->dev;
+ int entry, count;
+
+ spin_lock(&cp->tx_lock[ring]);
+ txds = cp->init_txds[ring];
+ skbs = cp->tx_skbs[ring];
+ entry = cp->tx_old[ring];
+
+ count = TX_BUFF_COUNT(ring, entry, limit);
+ while (entry != limit) {
+ struct sk_buff *skb = skbs[entry];
+ dma_addr_t daddr;
+ u32 dlen;
+ int frag;
+
+ if (!skb) {
+ /* this should never occur */
+ entry = TX_DESC_NEXT(ring, entry);
+ continue;
+ }
+
+ /* however, we might get only a partial skb release. */
+ count -= skb_shinfo(skb)->nr_frags +
+ + cp->tx_tiny_use[ring][entry].nbufs + 1;
+ if (count < 0)
+ break;
+
+ if (netif_msg_tx_done(cp))
+ printk(KERN_DEBUG "%s: tx[%d] done, slot %d\n",
+ cp->dev->name, ring, entry);
+
+ skbs[entry] = NULL;
+ cp->tx_tiny_use[ring][entry].nbufs = 0;
+
+ for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
+ struct cas_tx_desc *txd = txds + entry;
+
+ daddr = le64_to_cpu(txd->buffer);
+ dlen = CAS_VAL(TX_DESC_BUFLEN,
+ le64_to_cpu(txd->control));
+ pci_unmap_page(cp->pdev, daddr, dlen,
+ PCI_DMA_TODEVICE);
+ entry = TX_DESC_NEXT(ring, entry);
+
+ /* tiny buffer may follow */
+ if (cp->tx_tiny_use[ring][entry].used) {
+ cp->tx_tiny_use[ring][entry].used = 0;
+ entry = TX_DESC_NEXT(ring, entry);
+ }
+ }
+
+ spin_lock(&cp->stat_lock[ring]);
+ cp->net_stats[ring].tx_packets++;
+ cp->net_stats[ring].tx_bytes += skb->len;
+ spin_unlock(&cp->stat_lock[ring]);
+ dev_kfree_skb_irq(skb);
+ }
+ cp->tx_old[ring] = entry;
+
+ /* this is wrong for multiple tx rings. the net device needs
+ * multiple queues for this to do the right thing. we wait
+ * for 2*packets to be available when using tiny buffers
+ */
+ if (netif_queue_stopped(dev) &&
+ (TX_BUFFS_AVAIL(cp, ring) > CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1)))
+ netif_wake_queue(dev);
+ spin_unlock(&cp->tx_lock[ring]);
+}
+
+static void cas_tx(struct net_device *dev, struct cas *cp,
+ u32 status)
+{
+ int limit, ring;
+#ifdef USE_TX_COMPWB
+ u64 compwb = le64_to_cpu(cp->init_block->tx_compwb);
+#endif
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %lx\n",
+ cp->dev->name, status, compwb);
+ /* process all the rings */
+ for (ring = 0; ring < N_TX_RINGS; ring++) {
+#ifdef USE_TX_COMPWB
+ /* use the completion writeback registers */
+ limit = (CAS_VAL(TX_COMPWB_MSB, compwb) << 8) |
+ CAS_VAL(TX_COMPWB_LSB, compwb);
+ compwb = TX_COMPWB_NEXT(compwb);
+#else
+ limit = readl(cp->regs + REG_TX_COMPN(ring));
+#endif
+ if (cp->tx_old[ring] != limit)
+ cas_tx_ringN(cp, ring, limit);
+ }
+}
+
+
+static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
+ int entry, const u64 *words,
+ struct sk_buff **skbref)
+{
+ int dlen, hlen, len, i, alloclen;
+ int off, swivel = RX_SWIVEL_OFF_VAL;
+ struct cas_page *page;
+ struct sk_buff *skb;
+ void *addr, *crcaddr;
+ char *p;
+
+ hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]);
+ dlen = CAS_VAL(RX_COMP1_DATA_SIZE, words[0]);
+ len = hlen + dlen;
+
+ if (RX_COPY_ALWAYS || (words[2] & RX_COMP3_SMALL_PKT))
+ alloclen = len;
+ else
+ alloclen = max(hlen, RX_COPY_MIN);
+
+ skb = dev_alloc_skb(alloclen + swivel + cp->crc_size);
+ if (skb == NULL)
+ return -1;
+
+ *skbref = skb;
+ skb->dev = cp->dev;
+ skb_reserve(skb, swivel);
+
+ p = skb->data;
+ addr = crcaddr = NULL;
+ if (hlen) { /* always copy header pages */
+ i = CAS_VAL(RX_COMP2_HDR_INDEX, words[1]);
+ page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
+ off = CAS_VAL(RX_COMP2_HDR_OFF, words[1]) * 0x100 +
+ swivel;
+
+ i = hlen;
+ if (!dlen) /* attach FCS */
+ i += cp->crc_size;
+ pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i,
+ PCI_DMA_FROMDEVICE);
+ addr = cas_page_map(page->buffer);
+ memcpy(p, addr + off, i);
+ pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
+ PCI_DMA_FROMDEVICE);
+ cas_page_unmap(addr);
+ RX_USED_ADD(page, 0x100);
+ p += hlen;
+ swivel = 0;
+ }
+
+
+ if (alloclen < (hlen + dlen)) {
+ skb_frag_t *frag = skb_shinfo(skb)->frags;
+
+ /* normal or jumbo packets. we use frags */
+ i = CAS_VAL(RX_COMP1_DATA_INDEX, words[0]);
+ page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
+ off = CAS_VAL(RX_COMP1_DATA_OFF, words[0]) + swivel;
+
+ hlen = min(cp->page_size - off, dlen);
+ if (hlen < 0) {
+ if (netif_msg_rx_err(cp)) {
+ printk(KERN_DEBUG "%s: rx page overflow: "
+ "%d\n", cp->dev->name, hlen);
+ }
+ dev_kfree_skb_irq(skb);
+ return -1;
+ }
+ i = hlen;
+ if (i == dlen) /* attach FCS */
+ i += cp->crc_size;
+ pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i,
+ PCI_DMA_FROMDEVICE);
+
+ /* make sure we always copy a header */
+ swivel = 0;
+ if (p == (char *) skb->data) { /* not split */
+ addr = cas_page_map(page->buffer);
+ memcpy(p, addr + off, RX_COPY_MIN);
+ pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
+ PCI_DMA_FROMDEVICE);
+ cas_page_unmap(addr);
+ off += RX_COPY_MIN;
+ swivel = RX_COPY_MIN;
+ RX_USED_ADD(page, cp->mtu_stride);
+ } else {
+ RX_USED_ADD(page, hlen);
+ }
+ skb_put(skb, alloclen);
+
+ skb_shinfo(skb)->nr_frags++;
+ skb->data_len += hlen - swivel;
+ skb->len += hlen - swivel;
+
+ get_page(page->buffer);
+ frag->page = page->buffer;
+ frag->page_offset = off;
+ frag->size = hlen - swivel;
+
+ /* any more data? */
+ if ((words[0] & RX_COMP1_SPLIT_PKT) && ((dlen -= hlen) > 0)) {
+ hlen = dlen;
+ off = 0;
+
+ i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]);
+ page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
+ pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr,
+ hlen + cp->crc_size,
+ PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single_for_device(cp->pdev, page->dma_addr,
+ hlen + cp->crc_size,
+ PCI_DMA_FROMDEVICE);
+
+ skb_shinfo(skb)->nr_frags++;
+ skb->data_len += hlen;
+ skb->len += hlen;
+ frag++;
+
+ get_page(page->buffer);
+ frag->page = page->buffer;
+ frag->page_offset = 0;
+ frag->size = hlen;
+ RX_USED_ADD(page, hlen + cp->crc_size);
+ }
+
+ if (cp->crc_size) {
+ addr = cas_page_map(page->buffer);
+ crcaddr = addr + off + hlen;
+ }
+
+ } else {
+ /* copying packet */
+ if (!dlen)
+ goto end_copy_pkt;
+
+ i = CAS_VAL(RX_COMP1_DATA_INDEX, words[0]);
+ page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
+ off = CAS_VAL(RX_COMP1_DATA_OFF, words[0]) + swivel;
+ hlen = min(cp->page_size - off, dlen);
+ if (hlen < 0) {
+ if (netif_msg_rx_err(cp)) {
+ printk(KERN_DEBUG "%s: rx page overflow: "
+ "%d\n", cp->dev->name, hlen);
+ }
+ dev_kfree_skb_irq(skb);
+ return -1;
+ }
+ i = hlen;
+ if (i == dlen) /* attach FCS */
+ i += cp->crc_size;
+ pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i,
+ PCI_DMA_FROMDEVICE);
+ addr = cas_page_map(page->buffer);
+ memcpy(p, addr + off, i);
+ pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
+ PCI_DMA_FROMDEVICE);
+ cas_page_unmap(addr);
+ if (p == (char *) skb->data) /* not split */
+ RX_USED_ADD(page, cp->mtu_stride);
+ else
+ RX_USED_ADD(page, i);
+
+ /* any more data? */
+ if ((words[0] & RX_COMP1_SPLIT_PKT) && ((dlen -= hlen) > 0)) {
+ p += hlen;
+ i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]);
+ page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
+ pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr,
+ dlen + cp->crc_size,
+ PCI_DMA_FROMDEVICE);
+ addr = cas_page_map(page->buffer);
+ memcpy(p, addr, dlen + cp->crc_size);
+ pci_dma_sync_single_for_device(cp->pdev, page->dma_addr,
+ dlen + cp->crc_size,
+ PCI_DMA_FROMDEVICE);
+ cas_page_unmap(addr);
+ RX_USED_ADD(page, dlen + cp->crc_size);
+ }
+end_copy_pkt:
+ if (cp->crc_size) {
+ addr = NULL;
+ crcaddr = skb->data + alloclen;
+ }
+ skb_put(skb, alloclen);
+ }
+
+ i = CAS_VAL(RX_COMP4_TCP_CSUM, words[3]);
+ if (cp->crc_size) {
+ /* checksum includes FCS. strip it out. */
+ i = csum_fold(csum_partial(crcaddr, cp->crc_size, i));
+ if (addr)
+ cas_page_unmap(addr);
+ }
+ skb->csum = ntohs(i ^ 0xffff);
+ skb->ip_summed = CHECKSUM_HW;
+ skb->protocol = eth_type_trans(skb, cp->dev);
+ return len;
+}
+
+
+/* we can handle up to 64 rx flows at a time. we do the same thing
+ * as nonreassm except that we batch up the buffers.
+ * NOTE: we currently just treat each flow as a bunch of packets that
+ * we pass up. a better way would be to coalesce the packets
+ * into a jumbo packet. to do that, we need to do the following:
+ * 1) the first packet will have a clean split between header and
+ * data. save both.
+ * 2) each time the next flow packet comes in, extend the
+ * data length and merge the checksums.
+ * 3) on flow release, fix up the header.
+ * 4) make sure the higher layer doesn't care.
+ * because packets get coalesced, we shouldn't run into fragment count
+ * issues.
+ */
+static inline void cas_rx_flow_pkt(struct cas *cp, const u64 *words,
+ struct sk_buff *skb)
+{
+ int flowid = CAS_VAL(RX_COMP3_FLOWID, words[2]) & (N_RX_FLOWS - 1);
+ struct sk_buff_head *flow = &cp->rx_flows[flowid];
+
+ /* this is protected at a higher layer, so no need to
+ * do any additional locking here. stick the buffer
+ * at the end.
+ */
+ __skb_insert(skb, flow->prev, (struct sk_buff *) flow, flow);
+ if (words[0] & RX_COMP1_RELEASE_FLOW) {
+ while ((skb = __skb_dequeue(flow))) {
+ cas_skb_release(skb);
+ }
+ }
+}
+
+/* put rx descriptor back on ring. if a buffer is in use by a higher
+ * layer, this will need to put in a replacement.
+ */
+static void cas_post_page(struct cas *cp, const int ring, const int index)
+{
+ cas_page_t *new;
+ int entry;
+
+ entry = cp->rx_old[ring];
+
+ new = cas_page_swap(cp, ring, index);
+ cp->init_rxds[ring][entry].buffer = cpu_to_le64(new->dma_addr);
+ cp->init_rxds[ring][entry].index =
+ cpu_to_le64(CAS_BASE(RX_INDEX_NUM, index) |
+ CAS_BASE(RX_INDEX_RING, ring));
+
+ entry = RX_DESC_ENTRY(ring, entry + 1);
+ cp->rx_old[ring] = entry;
+
+ if (entry % 4)
+ return;
+
+ if (ring == 0)
+ writel(entry, cp->regs + REG_RX_KICK);
+ else if ((N_RX_DESC_RINGS > 1) &&
+ (cp->cas_flags & CAS_FLAG_REG_PLUS))
+ writel(entry, cp->regs + REG_PLUS_RX_KICK1);
+}
+
+
+/* only when things are bad */
+static int cas_post_rxds_ringN(struct cas *cp, int ring, int num)
+{
+ unsigned int entry, last, count, released;
+ int cluster;
+ cas_page_t **page = cp->rx_pages[ring];
+
+ entry = cp->rx_old[ring];
+
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: rxd[%d] interrupt, done: %d\n",
+ cp->dev->name, ring, entry);
+
+ cluster = -1;
+ count = entry & 0x3;
+ last = RX_DESC_ENTRY(ring, num ? entry + num - 4: entry - 4);
+ released = 0;
+ while (entry != last) {
+ /* make a new buffer if it's still in use */
+ if (page_count(page[entry]->buffer) > 1) {
+ cas_page_t *new = cas_page_dequeue(cp);
+ if (!new) {
+ /* let the timer know that we need to
+ * do this again
+ */
+ cp->cas_flags |= CAS_FLAG_RXD_POST(ring);
+ if (!timer_pending(&cp->link_timer))
+ mod_timer(&cp->link_timer, jiffies +
+ CAS_LINK_FAST_TIMEOUT);
+ cp->rx_old[ring] = entry;
+ cp->rx_last[ring] = num ? num - released : 0;
+ return -ENOMEM;
+ }
+ spin_lock(&cp->rx_inuse_lock);
+ list_add(&page[entry]->list, &cp->rx_inuse_list);
+ spin_unlock(&cp->rx_inuse_lock);
+ cp->init_rxds[ring][entry].buffer =
+ cpu_to_le64(new->dma_addr);
+ page[entry] = new;
+
+ }
+
+ if (++count == 4) {
+ cluster = entry;
+ count = 0;
+ }
+ released++;
+ entry = RX_DESC_ENTRY(ring, entry + 1);
+ }
+ cp->rx_old[ring] = entry;
+
+ if (cluster < 0)
+ return 0;
+
+ if (ring == 0)
+ writel(cluster, cp->regs + REG_RX_KICK);
+ else if ((N_RX_DESC_RINGS > 1) &&
+ (cp->cas_flags & CAS_FLAG_REG_PLUS))
+ writel(cluster, cp->regs + REG_PLUS_RX_KICK1);
+ return 0;
+}
+
+
+/* process a completion ring. packets are set up in three basic ways:
+ * small packets: should be copied header + data in single buffer.
+ * large packets: header and data in a single buffer.
+ * split packets: header in a separate buffer from data.
+ * data may be in multiple pages. data may be > 256
+ * bytes but in a single page.
+ *
+ * NOTE: RX page posting is done in this routine as well. while there's
+ * the capability of using multiple RX completion rings, it isn't
+ * really worthwhile due to the fact that the page posting will
+ * force serialization on the single descriptor ring.
+ */
+static int cas_rx_ringN(struct cas *cp, int ring, int budget)
+{
+ struct cas_rx_comp *rxcs = cp->init_rxcs[ring];
+ int entry, drops;
+ int npackets = 0;
+
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: rx[%d] interrupt, done: %d/%d\n",
+ cp->dev->name, ring,
+ readl(cp->regs + REG_RX_COMP_HEAD),
+ cp->rx_new[ring]);
+
+ entry = cp->rx_new[ring];
+ drops = 0;
+ while (1) {
+ struct cas_rx_comp *rxc = rxcs + entry;
+ struct sk_buff *skb;
+ int type, len;
+ u64 words[4];
+ int i, dring;
+
+ words[0] = le64_to_cpu(rxc->word1);
+ words[1] = le64_to_cpu(rxc->word2);
+ words[2] = le64_to_cpu(rxc->word3);
+ words[3] = le64_to_cpu(rxc->word4);
+
+ /* don't touch if still owned by hw */
+ type = CAS_VAL(RX_COMP1_TYPE, words[0]);
+ if (type == 0)
+ break;
+
+ /* hw hasn't cleared the zero bit yet */
+ if (words[3] & RX_COMP4_ZERO) {
+ break;
+ }
+
+ /* get info on the packet */
+ if (words[3] & (RX_COMP4_LEN_MISMATCH | RX_COMP4_BAD)) {
+ spin_lock(&cp->stat_lock[ring]);
+ cp->net_stats[ring].rx_errors++;
+ if (words[3] & RX_COMP4_LEN_MISMATCH)
+ cp->net_stats[ring].rx_length_errors++;
+ if (words[3] & RX_COMP4_BAD)
+ cp->net_stats[ring].rx_crc_errors++;
+ spin_unlock(&cp->stat_lock[ring]);
+
+ /* We'll just return it to Cassini. */
+ drop_it:
+ spin_lock(&cp->stat_lock[ring]);
+ ++cp->net_stats[ring].rx_dropped;
+ spin_unlock(&cp->stat_lock[ring]);
+ goto next;
+ }
+
+ len = cas_rx_process_pkt(cp, rxc, entry, words, &skb);
+ if (len < 0) {
+ ++drops;
+ goto drop_it;
+ }
+
+ /* see if it's a flow re-assembly or not. the driver
+ * itself handles release back up.
+ */
+ if (RX_DONT_BATCH || (type == 0x2)) {
+ /* non-reassm: these always get released */
+ cas_skb_release(skb);
+ } else {
+ cas_rx_flow_pkt(cp, words, skb);
+ }
+
+ spin_lock(&cp->stat_lock[ring]);
+ cp->net_stats[ring].rx_packets++;
+ cp->net_stats[ring].rx_bytes += len;
+ spin_unlock(&cp->stat_lock[ring]);
+ cp->dev->last_rx = jiffies;
+
+ next:
+ npackets++;
+
+ /* should it be released? */
+ if (words[0] & RX_COMP1_RELEASE_HDR) {
+ i = CAS_VAL(RX_COMP2_HDR_INDEX, words[1]);
+ dring = CAS_VAL(RX_INDEX_RING, i);
+ i = CAS_VAL(RX_INDEX_NUM, i);
+ cas_post_page(cp, dring, i);
+ }
+
+ if (words[0] & RX_COMP1_RELEASE_DATA) {
+ i = CAS_VAL(RX_COMP1_DATA_INDEX, words[0]);
+ dring = CAS_VAL(RX_INDEX_RING, i);
+ i = CAS_VAL(RX_INDEX_NUM, i);
+ cas_post_page(cp, dring, i);
+ }
+
+ if (words[0] & RX_COMP1_RELEASE_NEXT) {
+ i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]);
+ dring = CAS_VAL(RX_INDEX_RING, i);
+ i = CAS_VAL(RX_INDEX_NUM, i);
+ cas_post_page(cp, dring, i);
+ }
+
+ /* skip to the next entry */
+ entry = RX_COMP_ENTRY(ring, entry + 1 +
+ CAS_VAL(RX_COMP1_SKIP, words[0]));
+#ifdef USE_NAPI
+ if (budget && (npackets >= budget))
+ break;
+#endif
+ }
+ cp->rx_new[ring] = entry;
+
+ if (drops)
+ printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
+ cp->dev->name);
+ return npackets;
+}
+
+
+/* put completion entries back on the ring */
+static void cas_post_rxcs_ringN(struct net_device *dev,
+ struct cas *cp, int ring)
+{
+ struct cas_rx_comp *rxc = cp->init_rxcs[ring];
+ int last, entry;
+
+ last = cp->rx_cur[ring];
+ entry = cp->rx_new[ring];
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: rxc[%d] interrupt, done: %d/%d\n",
+ dev->name, ring, readl(cp->regs + REG_RX_COMP_HEAD),
+ entry);
+
+ /* zero and re-mark descriptors */
+ while (last != entry) {
+ cas_rxc_init(rxc + last);
+ last = RX_COMP_ENTRY(ring, last + 1);
+ }
+ cp->rx_cur[ring] = last;
+
+ if (ring == 0)
+ writel(last, cp->regs + REG_RX_COMP_TAIL);
+ else if (cp->cas_flags & CAS_FLAG_REG_PLUS)
+ writel(last, cp->regs + REG_PLUS_RX_COMPN_TAIL(ring));
+}
+
+
+
+/* cassini can use all four PCI interrupts for the completion ring.
+ * rings 3 and 4 are identical
+ */
+#if defined(USE_PCI_INTC) || defined(USE_PCI_INTD)
+static inline void cas_handle_irqN(struct net_device *dev,
+ struct cas *cp, const u32 status,
+ const int ring)
+{
+ if (status & (INTR_RX_COMP_FULL_ALT | INTR_RX_COMP_AF_ALT))
+ cas_post_rxcs_ringN(dev, cp, ring);
+}
+
+static irqreturn_t cas_interruptN(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct cas *cp = netdev_priv(dev);
+ unsigned long flags;
+ int ring;
+ u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring));
+
+ /* check for shared irq */
+ if (status == 0)
+ return IRQ_NONE;
+
+ ring = (irq == cp->pci_irq_INTC) ? 2 : 3;
+ spin_lock_irqsave(&cp->lock, flags);
+ if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
+#ifdef USE_NAPI
+ cas_mask_intr(cp);
+ netif_rx_schedule(dev);
+#else
+ cas_rx_ringN(cp, ring, 0);
+#endif
+ status &= ~INTR_RX_DONE_ALT;
+ }
+
+ if (status)
+ cas_handle_irqN(dev, cp, status, ring);
+ spin_unlock_irqrestore(&cp->lock, flags);
+ return IRQ_HANDLED;
+}
+#endif
+
+#ifdef USE_PCI_INTB
+/* everything but rx packets */
+static inline void cas_handle_irq1(struct cas *cp, const u32 status)
+{
+ if (status & INTR_RX_BUF_UNAVAIL_1) {
+ /* Frame arrived, no free RX buffers available.
+ * NOTE: we can get this on a link transition. */
+ cas_post_rxds_ringN(cp, 1, 0);
+ spin_lock(&cp->stat_lock[1]);
+ cp->net_stats[1].rx_dropped++;
+ spin_unlock(&cp->stat_lock[1]);
+ }
+
+ if (status & INTR_RX_BUF_AE_1)
+ cas_post_rxds_ringN(cp, 1, RX_DESC_RINGN_SIZE(1) -
+ RX_AE_FREEN_VAL(1));
+
+ if (status & (INTR_RX_COMP_AF | INTR_RX_COMP_FULL))
+ cas_post_rxcs_ringN(cp, 1);
+}
+
+/* ring 2 handles a few more events than 3 and 4 */
+static irqreturn_t cas_interrupt1(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct cas *cp = netdev_priv(dev);
+ unsigned long flags;
+ u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(1));
+
+ /* check for shared interrupt */
+ if (status == 0)
+ return IRQ_NONE;
+
+ spin_lock_irqsave(&cp->lock, flags);
+ if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
+#ifdef USE_NAPI
+ cas_mask_intr(cp);
+ netif_rx_schedule(dev);
+#else
+ cas_rx_ringN(cp, 1, 0);
+#endif
+ status &= ~INTR_RX_DONE_ALT;
+ }
+ if (status)
+ cas_handle_irq1(cp, status);
+ spin_unlock_irqrestore(&cp->lock, flags);
+ return IRQ_HANDLED;
+}
+#endif
+
+static inline void cas_handle_irq(struct net_device *dev,
+ struct cas *cp, const u32 status)
+{
+ /* housekeeping interrupts */
+ if (status & INTR_ERROR_MASK)
+ cas_abnormal_irq(dev, cp, status);
+
+ if (status & INTR_RX_BUF_UNAVAIL) {
+ /* Frame arrived, no free RX buffers available.
+ * NOTE: we can get this on a link transition.
+ */
+ cas_post_rxds_ringN(cp, 0, 0);
+ spin_lock(&cp->stat_lock[0]);
+ cp->net_stats[0].rx_dropped++;
+ spin_unlock(&cp->stat_lock[0]);
+ } else if (status & INTR_RX_BUF_AE) {
+ cas_post_rxds_ringN(cp, 0, RX_DESC_RINGN_SIZE(0) -
+ RX_AE_FREEN_VAL(0));
+ }
+
+ if (status & (INTR_RX_COMP_AF | INTR_RX_COMP_FULL))
+ cas_post_rxcs_ringN(dev, cp, 0);
+}
+
+static irqreturn_t cas_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct cas *cp = netdev_priv(dev);
+ unsigned long flags;
+ u32 status = readl(cp->regs + REG_INTR_STATUS);
+
+ if (status == 0)
+ return IRQ_NONE;
+
+ spin_lock_irqsave(&cp->lock, flags);
+ if (status & (INTR_TX_ALL | INTR_TX_INTME)) {
+ cas_tx(dev, cp, status);
+ status &= ~(INTR_TX_ALL | INTR_TX_INTME);
+ }
+
+ if (status & INTR_RX_DONE) {
+#ifdef USE_NAPI
+ cas_mask_intr(cp);
+ netif_rx_schedule(dev);
+#else
+ cas_rx_ringN(cp, 0, 0);
+#endif
+ status &= ~INTR_RX_DONE;
+ }
+
+ if (status)
+ cas_handle_irq(dev, cp, status);
+ spin_unlock_irqrestore(&cp->lock, flags);
+ return IRQ_HANDLED;
+}
+
+
+#ifdef USE_NAPI
+static int cas_poll(struct net_device *dev, int *budget)
+{
+ struct cas *cp = netdev_priv(dev);
+ int i, enable_intr, todo, credits;
+ u32 status = readl(cp->regs + REG_INTR_STATUS);
+ unsigned long flags;
+
+ spin_lock_irqsave(&cp->lock, flags);
+ cas_tx(dev, cp, status);
+ spin_unlock_irqrestore(&cp->lock, flags);
+
+ /* NAPI rx packets. we spread the credits across all of the
+ * rxc rings
+ */
+ todo = min(*budget, dev->quota);
+
+ /* to make sure we're fair with the work we loop through each
+ * ring N_RX_COMP_RING times with a request of
+ * todo / N_RX_COMP_RINGS
+ */
+ enable_intr = 1;
+ credits = 0;
+ for (i = 0; i < N_RX_COMP_RINGS; i++) {
+ int j;
+ for (j = 0; j < N_RX_COMP_RINGS; j++) {
+ credits += cas_rx_ringN(cp, j, todo / N_RX_COMP_RINGS);
+ if (credits >= todo) {
+ enable_intr = 0;
+ goto rx_comp;
+ }
+ }
+ }
+
+rx_comp:
+ *budget -= credits;
+ dev->quota -= credits;
+
+ /* final rx completion */
+ spin_lock_irqsave(&cp->lock, flags);
+ if (status)
+ cas_handle_irq(dev, cp, status);
+
+#ifdef USE_PCI_INTB
+ if (N_RX_COMP_RINGS > 1) {
+ status = readl(cp->regs + REG_PLUS_INTRN_STATUS(1));
+ if (status)
+ cas_handle_irq1(dev, cp, status);
+ }
+#endif
+
+#ifdef USE_PCI_INTC
+ if (N_RX_COMP_RINGS > 2) {
+ status = readl(cp->regs + REG_PLUS_INTRN_STATUS(2));
+ if (status)
+ cas_handle_irqN(dev, cp, status, 2);
+ }
+#endif
+
+#ifdef USE_PCI_INTD
+ if (N_RX_COMP_RINGS > 3) {
+ status = readl(cp->regs + REG_PLUS_INTRN_STATUS(3));
+ if (status)
+ cas_handle_irqN(dev, cp, status, 3);
+ }
+#endif
+ spin_unlock_irqrestore(&cp->lock, flags);
+ if (enable_intr) {
+ netif_rx_complete(dev);
+ cas_unmask_intr(cp);
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void cas_netpoll(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+
+ cas_disable_irq(cp, 0);
+ cas_interrupt(cp->pdev->irq, dev, NULL);
+ cas_enable_irq(cp, 0);
+
+#ifdef USE_PCI_INTB
+ if (N_RX_COMP_RINGS > 1) {
+ /* cas_interrupt1(); */
+ }
+#endif
+#ifdef USE_PCI_INTC
+ if (N_RX_COMP_RINGS > 2) {
+ /* cas_interruptN(); */
+ }
+#endif
+#ifdef USE_PCI_INTD
+ if (N_RX_COMP_RINGS > 3) {
+ /* cas_interruptN(); */
+ }
+#endif
+}
+#endif
+
+static void cas_tx_timeout(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+
+ printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+ if (!cp->hw_running) {
+ printk("%s: hrm.. hw not running!\n", dev->name);
+ return;
+ }
+
+ printk(KERN_ERR "%s: MIF_STATE[%08x]\n",
+ dev->name, readl(cp->regs + REG_MIF_STATE_MACHINE));
+
+ printk(KERN_ERR "%s: MAC_STATE[%08x]\n",
+ dev->name, readl(cp->regs + REG_MAC_STATE_MACHINE));
+
+ printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x] "
+ "FIFO[%08x:%08x:%08x] SM1[%08x] SM2[%08x]\n",
+ dev->name,
+ readl(cp->regs + REG_TX_CFG),
+ readl(cp->regs + REG_MAC_TX_STATUS),
+ readl(cp->regs + REG_MAC_TX_CFG),
+ readl(cp->regs + REG_TX_FIFO_PKT_CNT),
+ readl(cp->regs + REG_TX_FIFO_WRITE_PTR),
+ readl(cp->regs + REG_TX_FIFO_READ_PTR),
+ readl(cp->regs + REG_TX_SM_1),
+ readl(cp->regs + REG_TX_SM_2));
+
+ printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n",
+ dev->name,
+ readl(cp->regs + REG_RX_CFG),
+ readl(cp->regs + REG_MAC_RX_STATUS),
+ readl(cp->regs + REG_MAC_RX_CFG));
+
+ printk(KERN_ERR "%s: HP_STATE[%08x:%08x:%08x:%08x]\n",
+ dev->name,
+ readl(cp->regs + REG_HP_STATE_MACHINE),
+ readl(cp->regs + REG_HP_STATUS0),
+ readl(cp->regs + REG_HP_STATUS1),
+ readl(cp->regs + REG_HP_STATUS2));
+
+#if 1
+ atomic_inc(&cp->reset_task_pending);
+ atomic_inc(&cp->reset_task_pending_all);
+ schedule_work(&cp->reset_task);
+#else
+ atomic_set(&cp->reset_task_pending, CAS_RESET_ALL);
+ schedule_work(&cp->reset_task);
+#endif
+}
+
+static inline int cas_intme(int ring, int entry)
+{
+ /* Algorithm: IRQ every 1/2 of descriptors. */
+ if (!(entry & ((TX_DESC_RINGN_SIZE(ring) >> 1) - 1)))
+ return 1;
+ return 0;
+}
+
+
+static void cas_write_txd(struct cas *cp, int ring, int entry,
+ dma_addr_t mapping, int len, u64 ctrl, int last)
+{
+ struct cas_tx_desc *txd = cp->init_txds[ring] + entry;
+
+ ctrl |= CAS_BASE(TX_DESC_BUFLEN, len);
+ if (cas_intme(ring, entry))
+ ctrl |= TX_DESC_INTME;
+ if (last)
+ ctrl |= TX_DESC_EOF;
+ txd->control = cpu_to_le64(ctrl);
+ txd->buffer = cpu_to_le64(mapping);
+}
+
+static inline void *tx_tiny_buf(struct cas *cp, const int ring,
+ const int entry)
+{
+ return cp->tx_tiny_bufs[ring] + TX_TINY_BUF_LEN*entry;
+}
+
+static inline dma_addr_t tx_tiny_map(struct cas *cp, const int ring,
+ const int entry, const int tentry)
+{
+ cp->tx_tiny_use[ring][tentry].nbufs++;
+ cp->tx_tiny_use[ring][entry].used = 1;
+ return cp->tx_tiny_dvma[ring] + TX_TINY_BUF_LEN*entry;
+}
+
+static inline int cas_xmit_tx_ringN(struct cas *cp, int ring,
+ struct sk_buff *skb)
+{
+ struct net_device *dev = cp->dev;
+ int entry, nr_frags, frag, tabort, tentry;
+ dma_addr_t mapping;
+ unsigned long flags;
+ u64 ctrl;
+ u32 len;
+
+ spin_lock_irqsave(&cp->tx_lock[ring], flags);
+
+ /* This is a hard error, log it. */
+ if (TX_BUFFS_AVAIL(cp, ring) <=
+ CAS_TABORT(cp)*(skb_shinfo(skb)->nr_frags + 1)) {
+ netif_stop_queue(dev);
+ spin_unlock_irqrestore(&cp->tx_lock[ring], flags);
+ printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
+ "queue awake!\n", dev->name);
+ return 1;
+ }
+
+ ctrl = 0;
+ if (skb->ip_summed == CHECKSUM_HW) {
+ u64 csum_start_off, csum_stuff_off;
+
+ csum_start_off = (u64) (skb->h.raw - skb->data);
+ csum_stuff_off = (u64) ((skb->h.raw + skb->csum) - skb->data);
+
+ ctrl = TX_DESC_CSUM_EN |
+ CAS_BASE(TX_DESC_CSUM_START, csum_start_off) |
+ CAS_BASE(TX_DESC_CSUM_STUFF, csum_stuff_off);
+ }
+
+ entry = cp->tx_new[ring];
+ cp->tx_skbs[ring][entry] = skb;
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ len = skb_headlen(skb);
+ mapping = pci_map_page(cp->pdev, virt_to_page(skb->data),
+ offset_in_page(skb->data), len,
+ PCI_DMA_TODEVICE);
+
+ tentry = entry;
+ tabort = cas_calc_tabort(cp, (unsigned long) skb->data, len);
+ if (unlikely(tabort)) {
+ /* NOTE: len is always > tabort */
+ cas_write_txd(cp, ring, entry, mapping, len - tabort,
+ ctrl | TX_DESC_SOF, 0);
+ entry = TX_DESC_NEXT(ring, entry);
+
+ memcpy(tx_tiny_buf(cp, ring, entry), skb->data +
+ len - tabort, tabort);
+ mapping = tx_tiny_map(cp, ring, entry, tentry);
+ cas_write_txd(cp, ring, entry, mapping, tabort, ctrl,
+ (nr_frags == 0));
+ } else {
+ cas_write_txd(cp, ring, entry, mapping, len, ctrl |
+ TX_DESC_SOF, (nr_frags == 0));
+ }
+ entry = TX_DESC_NEXT(ring, entry);
+
+ for (frag = 0; frag < nr_frags; frag++) {
+ skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag];
+
+ len = fragp->size;
+ mapping = pci_map_page(cp->pdev, fragp->page,
+ fragp->page_offset, len,
+ PCI_DMA_TODEVICE);
+
+ tabort = cas_calc_tabort(cp, fragp->page_offset, len);
+ if (unlikely(tabort)) {
+ void *addr;
+
+ /* NOTE: len is always > tabort */
+ cas_write_txd(cp, ring, entry, mapping, len - tabort,
+ ctrl, 0);
+ entry = TX_DESC_NEXT(ring, entry);
+
+ addr = cas_page_map(fragp->page);
+ memcpy(tx_tiny_buf(cp, ring, entry),
+ addr + fragp->page_offset + len - tabort,
+ tabort);
+ cas_page_unmap(addr);
+ mapping = tx_tiny_map(cp, ring, entry, tentry);
+ len = tabort;
+ }
+
+ cas_write_txd(cp, ring, entry, mapping, len, ctrl,
+ (frag + 1 == nr_frags));
+ entry = TX_DESC_NEXT(ring, entry);
+ }
+
+ cp->tx_new[ring] = entry;
+ if (TX_BUFFS_AVAIL(cp, ring) <= CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1))
+ netif_stop_queue(dev);
+
+ if (netif_msg_tx_queued(cp))
+ printk(KERN_DEBUG "%s: tx[%d] queued, slot %d, skblen %d, "
+ "avail %d\n",
+ dev->name, ring, entry, skb->len,
+ TX_BUFFS_AVAIL(cp, ring));
+ writel(entry, cp->regs + REG_TX_KICKN(ring));
+ spin_unlock_irqrestore(&cp->tx_lock[ring], flags);
+ return 0;
+}
+
+static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+
+ /* this is only used as a load-balancing hint, so it doesn't
+ * need to be SMP safe
+ */
+ static int ring;
+
+ skb = skb_padto(skb, cp->min_frame_size);
+ if (!skb)
+ return 0;
+
+ /* XXX: we need some higher-level QoS hooks to steer packets to
+ * individual queues.
+ */
+ if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb))
+ return 1;
+ dev->trans_start = jiffies;
+ return 0;
+}
+
+static void cas_init_tx_dma(struct cas *cp)
+{
+ u64 desc_dma = cp->block_dvma;
+ unsigned long off;
+ u32 val;
+ int i;
+
+ /* set up tx completion writeback registers. must be 8-byte aligned */
+#ifdef USE_TX_COMPWB
+ off = offsetof(struct cas_init_block, tx_compwb);
+ writel((desc_dma + off) >> 32, cp->regs + REG_TX_COMPWB_DB_HI);
+ writel((desc_dma + off) & 0xffffffff, cp->regs + REG_TX_COMPWB_DB_LOW);
+#endif
+
+ /* enable completion writebacks, enable paced mode,
+ * disable read pipe, and disable pre-interrupt compwbs
+ */
+ val = TX_CFG_COMPWB_Q1 | TX_CFG_COMPWB_Q2 |
+ TX_CFG_COMPWB_Q3 | TX_CFG_COMPWB_Q4 |
+ TX_CFG_DMA_RDPIPE_DIS | TX_CFG_PACED_MODE |
+ TX_CFG_INTR_COMPWB_DIS;
+
+ /* write out tx ring info and tx desc bases */
+ for (i = 0; i < MAX_TX_RINGS; i++) {
+ off = (unsigned long) cp->init_txds[i] -
+ (unsigned long) cp->init_block;
+
+ val |= CAS_TX_RINGN_BASE(i);
+ writel((desc_dma + off) >> 32, cp->regs + REG_TX_DBN_HI(i));
+ writel((desc_dma + off) & 0xffffffff, cp->regs +
+ REG_TX_DBN_LOW(i));
+ /* don't zero out the kick register here as the system
+ * will wedge
+ */
+ }
+ writel(val, cp->regs + REG_TX_CFG);
+
+ /* program max burst sizes. these numbers should be different
+ * if doing QoS.
+ */
+#ifdef USE_QOS
+ writel(0x800, cp->regs + REG_TX_MAXBURST_0);
+ writel(0x1600, cp->regs + REG_TX_MAXBURST_1);
+ writel(0x2400, cp->regs + REG_TX_MAXBURST_2);
+ writel(0x4800, cp->regs + REG_TX_MAXBURST_3);
+#else
+ writel(0x800, cp->regs + REG_TX_MAXBURST_0);
+ writel(0x800, cp->regs + REG_TX_MAXBURST_1);
+ writel(0x800, cp->regs + REG_TX_MAXBURST_2);
+ writel(0x800, cp->regs + REG_TX_MAXBURST_3);
+#endif
+}
+
+/* Must be invoked under cp->lock. */
+static inline void cas_init_dma(struct cas *cp)
+{
+ cas_init_tx_dma(cp);
+ cas_init_rx_dma(cp);
+}
+
+/* Must be invoked under cp->lock. */
+static u32 cas_setup_multicast(struct cas *cp)
+{
+ u32 rxcfg = 0;
+ int i;
+
+ if (cp->dev->flags & IFF_PROMISC) {
+ rxcfg |= MAC_RX_CFG_PROMISC_EN;
+
+ } else if (cp->dev->flags & IFF_ALLMULTI) {
+ for (i=0; i < 16; i++)
+ writel(0xFFFF, cp->regs + REG_MAC_HASH_TABLEN(i));
+ rxcfg |= MAC_RX_CFG_HASH_FILTER_EN;
+
+ } else {
+ u16 hash_table[16];
+ u32 crc;
+ struct dev_mc_list *dmi = cp->dev->mc_list;
+ int i;
+
+ /* use the alternate mac address registers for the
+ * first 15 multicast addresses
+ */
+ for (i = 1; i <= CAS_MC_EXACT_MATCH_SIZE; i++) {
+ if (!dmi) {
+ writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 0));
+ writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 1));
+ writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 2));
+ continue;
+ }
+ writel((dmi->dmi_addr[4] << 8) | dmi->dmi_addr[5],
+ cp->regs + REG_MAC_ADDRN(i*3 + 0));
+ writel((dmi->dmi_addr[2] << 8) | dmi->dmi_addr[3],
+ cp->regs + REG_MAC_ADDRN(i*3 + 1));
+ writel((dmi->dmi_addr[0] << 8) | dmi->dmi_addr[1],
+ cp->regs + REG_MAC_ADDRN(i*3 + 2));
+ dmi = dmi->next;
+ }
+
+ /* use hw hash table for the next series of
+ * multicast addresses
+ */
+ memset(hash_table, 0, sizeof(hash_table));
+ while (dmi) {
+ crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
+ crc >>= 24;
+ hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
+ dmi = dmi->next;
+ }
+ for (i=0; i < 16; i++)
+ writel(hash_table[i], cp->regs +
+ REG_MAC_HASH_TABLEN(i));
+ rxcfg |= MAC_RX_CFG_HASH_FILTER_EN;
+ }
+
+ return rxcfg;
+}
+
+/* must be invoked under cp->stat_lock[N_TX_RINGS] */
+static void cas_clear_mac_err(struct cas *cp)
+{
+ writel(0, cp->regs + REG_MAC_COLL_NORMAL);
+ writel(0, cp->regs + REG_MAC_COLL_FIRST);
+ writel(0, cp->regs + REG_MAC_COLL_EXCESS);
+ writel(0, cp->regs + REG_MAC_COLL_LATE);
+ writel(0, cp->regs + REG_MAC_TIMER_DEFER);
+ writel(0, cp->regs + REG_MAC_ATTEMPTS_PEAK);
+ writel(0, cp->regs + REG_MAC_RECV_FRAME);
+ writel(0, cp->regs + REG_MAC_LEN_ERR);
+ writel(0, cp->regs + REG_MAC_ALIGN_ERR);
+ writel(0, cp->regs + REG_MAC_FCS_ERR);
+ writel(0, cp->regs + REG_MAC_RX_CODE_ERR);
+}
+
+
+static void cas_mac_reset(struct cas *cp)
+{
+ int i;
+
+ /* do both TX and RX reset */
+ writel(0x1, cp->regs + REG_MAC_TX_RESET);
+ writel(0x1, cp->regs + REG_MAC_RX_RESET);
+
+ /* wait for TX */
+ i = STOP_TRIES;
+ while (i-- > 0) {
+ if (readl(cp->regs + REG_MAC_TX_RESET) == 0)
+ break;
+ udelay(10);
+ }
+
+ /* wait for RX */
+ i = STOP_TRIES;
+ while (i-- > 0) {
+ if (readl(cp->regs + REG_MAC_RX_RESET) == 0)
+ break;
+ udelay(10);
+ }
+
+ if (readl(cp->regs + REG_MAC_TX_RESET) |
+ readl(cp->regs + REG_MAC_RX_RESET))
+ printk(KERN_ERR "%s: mac tx[%d]/rx[%d] reset failed [%08x]\n",
+ cp->dev->name, readl(cp->regs + REG_MAC_TX_RESET),
+ readl(cp->regs + REG_MAC_RX_RESET),
+ readl(cp->regs + REG_MAC_STATE_MACHINE));
+}
+
+
+/* Must be invoked under cp->lock. */
+static void cas_init_mac(struct cas *cp)
+{
+ unsigned char *e = &cp->dev->dev_addr[0];
+ int i;
+#ifdef CONFIG_CASSINI_MULTICAST_REG_WRITE
+ u32 rxcfg;
+#endif
+ cas_mac_reset(cp);
+
+ /* setup core arbitration weight register */
+ writel(CAWR_RR_DIS, cp->regs + REG_CAWR);
+
+ /* XXX Use pci_dma_burst_advice() */
+#if !defined(CONFIG_SPARC64) && !defined(CONFIG_ALPHA)
+ /* set the infinite burst register for chips that don't have
+ * pci issues.
+ */
+ if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) == 0)
+ writel(INF_BURST_EN, cp->regs + REG_INF_BURST);
+#endif
+
+ writel(0x1BF0, cp->regs + REG_MAC_SEND_PAUSE);
+
+ writel(0x00, cp->regs + REG_MAC_IPG0);
+ writel(0x08, cp->regs + REG_MAC_IPG1);
+ writel(0x04, cp->regs + REG_MAC_IPG2);
+
+ /* change later for 802.3z */
+ writel(0x40, cp->regs + REG_MAC_SLOT_TIME);
+
+ /* min frame + FCS */
+ writel(ETH_ZLEN + 4, cp->regs + REG_MAC_FRAMESIZE_MIN);
+
+ /* Ethernet payload + header + FCS + optional VLAN tag. NOTE: we
+ * specify the maximum frame size to prevent RX tag errors on
+ * oversized frames.
+ */
+ writel(CAS_BASE(MAC_FRAMESIZE_MAX_BURST, 0x2000) |
+ CAS_BASE(MAC_FRAMESIZE_MAX_FRAME,
+ (CAS_MAX_MTU + ETH_HLEN + 4 + 4)),
+ cp->regs + REG_MAC_FRAMESIZE_MAX);
+
+ /* NOTE: crc_size is used as a surrogate for half-duplex.
+ * workaround saturn half-duplex issue by increasing preamble
+ * size to 65 bytes.
+ */
+ if ((cp->cas_flags & CAS_FLAG_SATURN) && cp->crc_size)
+ writel(0x41, cp->regs + REG_MAC_PA_SIZE);
+ else
+ writel(0x07, cp->regs + REG_MAC_PA_SIZE);
+ writel(0x04, cp->regs + REG_MAC_JAM_SIZE);
+ writel(0x10, cp->regs + REG_MAC_ATTEMPT_LIMIT);
+ writel(0x8808, cp->regs + REG_MAC_CTRL_TYPE);
+
+ writel((e[5] | (e[4] << 8)) & 0x3ff, cp->regs + REG_MAC_RANDOM_SEED);
+
+ writel(0, cp->regs + REG_MAC_ADDR_FILTER0);
+ writel(0, cp->regs + REG_MAC_ADDR_FILTER1);
+ writel(0, cp->regs + REG_MAC_ADDR_FILTER2);
+ writel(0, cp->regs + REG_MAC_ADDR_FILTER2_1_MASK);
+ writel(0, cp->regs + REG_MAC_ADDR_FILTER0_MASK);
+
+ /* setup mac address in perfect filter array */
+ for (i = 0; i < 45; i++)
+ writel(0x0, cp->regs + REG_MAC_ADDRN(i));
+
+ writel((e[4] << 8) | e[5], cp->regs + REG_MAC_ADDRN(0));
+ writel((e[2] << 8) | e[3], cp->regs + REG_MAC_ADDRN(1));
+ writel((e[0] << 8) | e[1], cp->regs + REG_MAC_ADDRN(2));
+
+ writel(0x0001, cp->regs + REG_MAC_ADDRN(42));
+ writel(0xc200, cp->regs + REG_MAC_ADDRN(43));
+ writel(0x0180, cp->regs + REG_MAC_ADDRN(44));
+
+#ifndef CONFIG_CASSINI_MULTICAST_REG_WRITE
+ cp->mac_rx_cfg = cas_setup_multicast(cp);
+#else
+ /* WTZ: Do what Adrian did in cas_set_multicast. Doing
+ * a writel does not seem to be necessary because Cassini
+ * seems to preserve the configuration when we do the reset.
+ * If the chip is in trouble, though, it is not clear if we
+ * can really count on this behavior. cas_set_multicast uses
+ * spin_lock_irqsave, but we are called only in cas_init_hw and
+ * cas_init_hw is protected by cas_lock_all, which calls
+ * spin_lock_irq (so it doesn't need to save the flags, and
+ * we should be OK for the writel, as that is the only
+ * difference).
+ */
+ cp->mac_rx_cfg = rxcfg = cas_setup_multicast(cp);
+ writel(rxcfg, cp->regs + REG_MAC_RX_CFG);
+#endif
+ spin_lock(&cp->stat_lock[N_TX_RINGS]);
+ cas_clear_mac_err(cp);
+ spin_unlock(&cp->stat_lock[N_TX_RINGS]);
+
+ /* Setup MAC interrupts. We want to get all of the interesting
+ * counter expiration events, but we do not want to hear about
+ * normal rx/tx as the DMA engine tells us that.
+ */
+ writel(MAC_TX_FRAME_XMIT, cp->regs + REG_MAC_TX_MASK);
+ writel(MAC_RX_FRAME_RECV, cp->regs + REG_MAC_RX_MASK);
+
+ /* Don't enable even the PAUSE interrupts for now, we
+ * make no use of those events other than to record them.
+ */
+ writel(0xffffffff, cp->regs + REG_MAC_CTRL_MASK);
+}
+
+/* Must be invoked under cp->lock. */
+static void cas_init_pause_thresholds(struct cas *cp)
+{
+ /* Calculate pause thresholds. Setting the OFF threshold to the
+ * full RX fifo size effectively disables PAUSE generation
+ */
+ if (cp->rx_fifo_size <= (2 * 1024)) {
+ cp->rx_pause_off = cp->rx_pause_on = cp->rx_fifo_size;
+ } else {
+ int max_frame = (cp->dev->mtu + ETH_HLEN + 4 + 4 + 64) & ~63;
+ if (max_frame * 3 > cp->rx_fifo_size) {
+ cp->rx_pause_off = 7104;
+ cp->rx_pause_on = 960;
+ } else {
+ int off = (cp->rx_fifo_size - (max_frame * 2));
+ int on = off - max_frame;
+ cp->rx_pause_off = off;
+ cp->rx_pause_on = on;
+ }
+ }
+}
+
+static int cas_vpd_match(const void __iomem *p, const char *str)
+{
+ int len = strlen(str) + 1;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (readb(p + i) != str[i])
+ return 0;
+ }
+ return 1;
+}
+
+
+/* get the mac address by reading the vpd information in the rom.
+ * also get the phy type and determine if there's an entropy generator.
+ * NOTE: this is a bit convoluted for the following reasons:
+ * 1) vpd info has order-dependent mac addresses for multinic cards
+ * 2) the only way to determine the nic order is to use the slot
+ * number.
+ * 3) fiber cards don't have bridges, so their slot numbers don't
+ * mean anything.
+ * 4) we don't actually know we have a fiber card until after
+ * the mac addresses are parsed.
+ */
+static int cas_get_vpd_info(struct cas *cp, unsigned char *dev_addr,
+ const int offset)
+{
+ void __iomem *p = cp->regs + REG_EXPANSION_ROM_RUN_START;
+ void __iomem *base, *kstart;
+ int i, len;
+ int found = 0;
+#define VPD_FOUND_MAC 0x01
+#define VPD_FOUND_PHY 0x02
+
+ int phy_type = CAS_PHY_MII_MDIO0; /* default phy type */
+ int mac_off = 0;
+
+ /* give us access to the PROM */
+ writel(BIM_LOCAL_DEV_PROM | BIM_LOCAL_DEV_PAD,
+ cp->regs + REG_BIM_LOCAL_DEV_EN);
+
+ /* check for an expansion rom */
+ if (readb(p) != 0x55 || readb(p + 1) != 0xaa)
+ goto use_random_mac_addr;
+
+ /* search for beginning of vpd */
+ base = NULL;
+ for (i = 2; i < EXPANSION_ROM_SIZE; i++) {
+ /* check for PCIR */
+ if ((readb(p + i + 0) == 0x50) &&
+ (readb(p + i + 1) == 0x43) &&
+ (readb(p + i + 2) == 0x49) &&
+ (readb(p + i + 3) == 0x52)) {
+ base = p + (readb(p + i + 8) |
+ (readb(p + i + 9) << 8));
+ break;
+ }
+ }
+
+ if (!base || (readb(base) != 0x82))
+ goto use_random_mac_addr;
+
+ i = (readb(base + 1) | (readb(base + 2) << 8)) + 3;
+ while (i < EXPANSION_ROM_SIZE) {
+ if (readb(base + i) != 0x90) /* no vpd found */
+ goto use_random_mac_addr;
+
+ /* found a vpd field */
+ len = readb(base + i + 1) | (readb(base + i + 2) << 8);
+
+ /* extract keywords */
+ kstart = base + i + 3;
+ p = kstart;
+ while ((p - kstart) < len) {
+ int klen = readb(p + 2);
+ int j;
+ char type;
+
+ p += 3;
+
+ /* look for the following things:
+ * -- correct length == 29
+ * 3 (type) + 2 (size) +
+ * 18 (strlen("local-mac-address") + 1) +
+ * 6 (mac addr)
+ * -- VPD Instance 'I'
+ * -- VPD Type Bytes 'B'
+ * -- VPD data length == 6
+ * -- property string == local-mac-address
+ *
+ * -- correct length == 24
+ * 3 (type) + 2 (size) +
+ * 12 (strlen("entropy-dev") + 1) +
+ * 7 (strlen("vms110") + 1)
+ * -- VPD Instance 'I'
+ * -- VPD Type String 'B'
+ * -- VPD data length == 7
+ * -- property string == entropy-dev
+ *
+ * -- correct length == 18
+ * 3 (type) + 2 (size) +
+ * 9 (strlen("phy-type") + 1) +
+ * 4 (strlen("pcs") + 1)
+ * -- VPD Instance 'I'
+ * -- VPD Type String 'S'
+ * -- VPD data length == 4
+ * -- property string == phy-type
+ *
+ * -- correct length == 23
+ * 3 (type) + 2 (size) +
+ * 14 (strlen("phy-interface") + 1) +
+ * 4 (strlen("pcs") + 1)
+ * -- VPD Instance 'I'
+ * -- VPD Type String 'S'
+ * -- VPD data length == 4
+ * -- property string == phy-interface
+ */
+ if (readb(p) != 'I')
+ goto next;
+
+ /* finally, check string and length */
+ type = readb(p + 3);
+ if (type == 'B') {
+ if ((klen == 29) && readb(p + 4) == 6 &&
+ cas_vpd_match(p + 5,
+ "local-mac-address")) {
+ if (mac_off++ > offset)
+ goto next;
+
+ /* set mac address */
+ for (j = 0; j < 6; j++)
+ dev_addr[j] =
+ readb(p + 23 + j);
+ goto found_mac;
+ }
+ }
+
+ if (type != 'S')
+ goto next;
+
+#ifdef USE_ENTROPY_DEV
+ if ((klen == 24) &&
+ cas_vpd_match(p + 5, "entropy-dev") &&
+ cas_vpd_match(p + 17, "vms110")) {
+ cp->cas_flags |= CAS_FLAG_ENTROPY_DEV;
+ goto next;
+ }
+#endif
+
+ if (found & VPD_FOUND_PHY)
+ goto next;
+
+ if ((klen == 18) && readb(p + 4) == 4 &&
+ cas_vpd_match(p + 5, "phy-type")) {
+ if (cas_vpd_match(p + 14, "pcs")) {
+ phy_type = CAS_PHY_SERDES;
+ goto found_phy;
+ }
+ }
+
+ if ((klen == 23) && readb(p + 4) == 4 &&
+ cas_vpd_match(p + 5, "phy-interface")) {
+ if (cas_vpd_match(p + 19, "pcs")) {
+ phy_type = CAS_PHY_SERDES;
+ goto found_phy;
+ }
+ }
+found_mac:
+ found |= VPD_FOUND_MAC;
+ goto next;
+
+found_phy:
+ found |= VPD_FOUND_PHY;
+
+next:
+ p += klen;
+ }
+ i += len + 3;
+ }
+
+use_random_mac_addr:
+ if (found & VPD_FOUND_MAC)
+ goto done;
+
+ /* Sun MAC prefix then 3 random bytes. */
+ printk(PFX "MAC address not found in ROM VPD\n");
+ dev_addr[0] = 0x08;
+ dev_addr[1] = 0x00;
+ dev_addr[2] = 0x20;
+ get_random_bytes(dev_addr + 3, 3);
+
+done:
+ writel(0, cp->regs + REG_BIM_LOCAL_DEV_EN);
+ return phy_type;
+}
+
+/* check pci invariants */
+static void cas_check_pci_invariants(struct cas *cp)
+{
+ struct pci_dev *pdev = cp->pdev;
+ u8 rev;
+
+ cp->cas_flags = 0;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+ if ((pdev->vendor == PCI_VENDOR_ID_SUN) &&
+ (pdev->device == PCI_DEVICE_ID_SUN_CASSINI)) {
+ if (rev >= CAS_ID_REVPLUS)
+ cp->cas_flags |= CAS_FLAG_REG_PLUS;
+ if (rev < CAS_ID_REVPLUS02u)
+ cp->cas_flags |= CAS_FLAG_TARGET_ABORT;
+
+ /* Original Cassini supports HW CSUM, but it's not
+ * enabled by default as it can trigger TX hangs.
+ */
+ if (rev < CAS_ID_REV2)
+ cp->cas_flags |= CAS_FLAG_NO_HW_CSUM;
+ } else {
+ /* Only sun has original cassini chips. */
+ cp->cas_flags |= CAS_FLAG_REG_PLUS;
+
+ /* We use a flag because the same phy might be externally
+ * connected.
+ */
+ if ((pdev->vendor == PCI_VENDOR_ID_NS) &&
+ (pdev->device == PCI_DEVICE_ID_NS_SATURN))
+ cp->cas_flags |= CAS_FLAG_SATURN;
+ }
+}
+
+
+static int cas_check_invariants(struct cas *cp)
+{
+ struct pci_dev *pdev = cp->pdev;
+ u32 cfg;
+ int i;
+
+ /* get page size for rx buffers. */
+ cp->page_order = 0;
+#ifdef USE_PAGE_ORDER
+ if (PAGE_SHIFT < CAS_JUMBO_PAGE_SHIFT) {
+ /* see if we can allocate larger pages */
+ struct page *page = alloc_pages(GFP_ATOMIC,
+ CAS_JUMBO_PAGE_SHIFT -
+ PAGE_SHIFT);
+ if (page) {
+ __free_pages(page, CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT);
+ cp->page_order = CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT;
+ } else {
+ printk(PFX "MTU limited to %d bytes\n", CAS_MAX_MTU);
+ }
+ }
+#endif
+ cp->page_size = (PAGE_SIZE << cp->page_order);
+
+ /* Fetch the FIFO configurations. */
+ cp->tx_fifo_size = readl(cp->regs + REG_TX_FIFO_SIZE) * 64;
+ cp->rx_fifo_size = RX_FIFO_SIZE;
+
+ /* finish phy determination. MDIO1 takes precedence over MDIO0 if
+ * they're both connected.
+ */
+ cp->phy_type = cas_get_vpd_info(cp, cp->dev->dev_addr,
+ PCI_SLOT(pdev->devfn));
+ if (cp->phy_type & CAS_PHY_SERDES) {
+ cp->cas_flags |= CAS_FLAG_1000MB_CAP;
+ return 0; /* no more checking needed */
+ }
+
+ /* MII */
+ cfg = readl(cp->regs + REG_MIF_CFG);
+ if (cfg & MIF_CFG_MDIO_1) {
+ cp->phy_type = CAS_PHY_MII_MDIO1;
+ } else if (cfg & MIF_CFG_MDIO_0) {
+ cp->phy_type = CAS_PHY_MII_MDIO0;
+ }
+
+ cas_mif_poll(cp, 0);
+ writel(PCS_DATAPATH_MODE_MII, cp->regs + REG_PCS_DATAPATH_MODE);
+
+ for (i = 0; i < 32; i++) {
+ u32 phy_id;
+ int j;
+
+ for (j = 0; j < 3; j++) {
+ cp->phy_addr = i;
+ phy_id = cas_phy_read(cp, MII_PHYSID1) << 16;
+ phy_id |= cas_phy_read(cp, MII_PHYSID2);
+ if (phy_id && (phy_id != 0xFFFFFFFF)) {
+ cp->phy_id = phy_id;
+ goto done;
+ }
+ }
+ }
+ printk(KERN_ERR PFX "MII phy did not respond [%08x]\n",
+ readl(cp->regs + REG_MIF_STATE_MACHINE));
+ return -1;
+
+done:
+ /* see if we can do gigabit */
+ cfg = cas_phy_read(cp, MII_BMSR);
+ if ((cfg & CAS_BMSR_1000_EXTEND) &&
+ cas_phy_read(cp, CAS_MII_1000_EXTEND))
+ cp->cas_flags |= CAS_FLAG_1000MB_CAP;
+ return 0;
+}
+
+/* Must be invoked under cp->lock. */
+static inline void cas_start_dma(struct cas *cp)
+{
+ int i;
+ u32 val;
+ int txfailed = 0;
+
+ /* enable dma */
+ val = readl(cp->regs + REG_TX_CFG) | TX_CFG_DMA_EN;
+ writel(val, cp->regs + REG_TX_CFG);
+ val = readl(cp->regs + REG_RX_CFG) | RX_CFG_DMA_EN;
+ writel(val, cp->regs + REG_RX_CFG);
+
+ /* enable the mac */
+ val = readl(cp->regs + REG_MAC_TX_CFG) | MAC_TX_CFG_EN;
+ writel(val, cp->regs + REG_MAC_TX_CFG);
+ val = readl(cp->regs + REG_MAC_RX_CFG) | MAC_RX_CFG_EN;
+ writel(val, cp->regs + REG_MAC_RX_CFG);
+
+ i = STOP_TRIES;
+ while (i-- > 0) {
+ val = readl(cp->regs + REG_MAC_TX_CFG);
+ if ((val & MAC_TX_CFG_EN))
+ break;
+ udelay(10);
+ }
+ if (i < 0) txfailed = 1;
+ i = STOP_TRIES;
+ while (i-- > 0) {
+ val = readl(cp->regs + REG_MAC_RX_CFG);
+ if ((val & MAC_RX_CFG_EN)) {
+ if (txfailed) {
+ printk(KERN_ERR
+ "%s: enabling mac failed [tx:%08x:%08x].\n",
+ cp->dev->name,
+ readl(cp->regs + REG_MIF_STATE_MACHINE),
+ readl(cp->regs + REG_MAC_STATE_MACHINE));
+ }
+ goto enable_rx_done;
+ }
+ udelay(10);
+ }
+ printk(KERN_ERR "%s: enabling mac failed [%s:%08x:%08x].\n",
+ cp->dev->name,
+ (txfailed? "tx,rx":"rx"),
+ readl(cp->regs + REG_MIF_STATE_MACHINE),
+ readl(cp->regs + REG_MAC_STATE_MACHINE));
+
+enable_rx_done:
+ cas_unmask_intr(cp); /* enable interrupts */
+ writel(RX_DESC_RINGN_SIZE(0) - 4, cp->regs + REG_RX_KICK);
+ writel(0, cp->regs + REG_RX_COMP_TAIL);
+
+ if (cp->cas_flags & CAS_FLAG_REG_PLUS) {
+ if (N_RX_DESC_RINGS > 1)
+ writel(RX_DESC_RINGN_SIZE(1) - 4,
+ cp->regs + REG_PLUS_RX_KICK1);
+
+ for (i = 1; i < N_RX_COMP_RINGS; i++)
+ writel(0, cp->regs + REG_PLUS_RX_COMPN_TAIL(i));
+ }
+}
+
+/* Must be invoked under cp->lock. */
+static void cas_read_pcs_link_mode(struct cas *cp, int *fd, int *spd,
+ int *pause)
+{
+ u32 val = readl(cp->regs + REG_PCS_MII_LPA);
+ *fd = (val & PCS_MII_LPA_FD) ? 1 : 0;
+ *pause = (val & PCS_MII_LPA_SYM_PAUSE) ? 0x01 : 0x00;
+ if (val & PCS_MII_LPA_ASYM_PAUSE)
+ *pause |= 0x10;
+ *spd = 1000;
+}
+
+/* Must be invoked under cp->lock. */
+static void cas_read_mii_link_mode(struct cas *cp, int *fd, int *spd,
+ int *pause)
+{
+ u32 val;
+
+ *fd = 0;
+ *spd = 10;
+ *pause = 0;
+
+ /* use GMII registers */
+ val = cas_phy_read(cp, MII_LPA);
+ if (val & CAS_LPA_PAUSE)
+ *pause = 0x01;
+
+ if (val & CAS_LPA_ASYM_PAUSE)
+ *pause |= 0x10;
+
+ if (val & LPA_DUPLEX)
+ *fd = 1;
+ if (val & LPA_100)
+ *spd = 100;
+
+ if (cp->cas_flags & CAS_FLAG_1000MB_CAP) {
+ val = cas_phy_read(cp, CAS_MII_1000_STATUS);
+ if (val & (CAS_LPA_1000FULL | CAS_LPA_1000HALF))
+ *spd = 1000;
+ if (val & CAS_LPA_1000FULL)
+ *fd = 1;
+ }
+}
+
+/* A link-up condition has occurred, initialize and enable the
+ * rest of the chip.
+ *
+ * Must be invoked under cp->lock.
+ */
+static void cas_set_link_modes(struct cas *cp)
+{
+ u32 val;
+ int full_duplex, speed, pause;
+
+ full_duplex = 0;
+ speed = 10;
+ pause = 0;
+
+ if (CAS_PHY_MII(cp->phy_type)) {
+ cas_mif_poll(cp, 0);
+ val = cas_phy_read(cp, MII_BMCR);
+ if (val & BMCR_ANENABLE) {
+ cas_read_mii_link_mode(cp, &full_duplex, &speed,
+ &pause);
+ } else {
+ if (val & BMCR_FULLDPLX)
+ full_duplex = 1;
+
+ if (val & BMCR_SPEED100)
+ speed = 100;
+ else if (val & CAS_BMCR_SPEED1000)
+ speed = (cp->cas_flags & CAS_FLAG_1000MB_CAP) ?
+ 1000 : 100;
+ }
+ cas_mif_poll(cp, 1);
+
+ } else {
+ val = readl(cp->regs + REG_PCS_MII_CTRL);
+ cas_read_pcs_link_mode(cp, &full_duplex, &speed, &pause);
+ if ((val & PCS_MII_AUTONEG_EN) == 0) {
+ if (val & PCS_MII_CTRL_DUPLEX)
+ full_duplex = 1;
+ }
+ }
+
+ if (netif_msg_link(cp))
+ printk(KERN_INFO "%s: Link up at %d Mbps, %s-duplex.\n",
+ cp->dev->name, speed, (full_duplex ? "full" : "half"));
+
+ val = MAC_XIF_TX_MII_OUTPUT_EN | MAC_XIF_LINK_LED;
+ if (CAS_PHY_MII(cp->phy_type)) {
+ val |= MAC_XIF_MII_BUFFER_OUTPUT_EN;
+ if (!full_duplex)
+ val |= MAC_XIF_DISABLE_ECHO;
+ }
+ if (full_duplex)
+ val |= MAC_XIF_FDPLX_LED;
+ if (speed == 1000)
+ val |= MAC_XIF_GMII_MODE;
+ writel(val, cp->regs + REG_MAC_XIF_CFG);
+
+ /* deal with carrier and collision detect. */
+ val = MAC_TX_CFG_IPG_EN;
+ if (full_duplex) {
+ val |= MAC_TX_CFG_IGNORE_CARRIER;
+ val |= MAC_TX_CFG_IGNORE_COLL;
+ } else {
+#ifndef USE_CSMA_CD_PROTO
+ val |= MAC_TX_CFG_NEVER_GIVE_UP_EN;
+ val |= MAC_TX_CFG_NEVER_GIVE_UP_LIM;
+#endif
+ }
+ /* val now set up for REG_MAC_TX_CFG */
+
+ /* If gigabit and half-duplex, enable carrier extension
+ * mode. increase slot time to 512 bytes as well.
+ * else, disable it and make sure slot time is 64 bytes.
+ * also activate checksum bug workaround
+ */
+ if ((speed == 1000) && !full_duplex) {
+ writel(val | MAC_TX_CFG_CARRIER_EXTEND,
+ cp->regs + REG_MAC_TX_CFG);
+
+ val = readl(cp->regs + REG_MAC_RX_CFG);
+ val &= ~MAC_RX_CFG_STRIP_FCS; /* checksum workaround */
+ writel(val | MAC_RX_CFG_CARRIER_EXTEND,
+ cp->regs + REG_MAC_RX_CFG);
+
+ writel(0x200, cp->regs + REG_MAC_SLOT_TIME);
+
+ cp->crc_size = 4;
+ /* minimum size gigabit frame at half duplex */
+ cp->min_frame_size = CAS_1000MB_MIN_FRAME;
+
+ } else {
+ writel(val, cp->regs + REG_MAC_TX_CFG);
+
+ /* checksum bug workaround. don't strip FCS when in
+ * half-duplex mode
+ */
+ val = readl(cp->regs + REG_MAC_RX_CFG);
+ if (full_duplex) {
+ val |= MAC_RX_CFG_STRIP_FCS;
+ cp->crc_size = 0;
+ cp->min_frame_size = CAS_MIN_MTU;
+ } else {
+ val &= ~MAC_RX_CFG_STRIP_FCS;
+ cp->crc_size = 4;
+ cp->min_frame_size = CAS_MIN_FRAME;
+ }
+ writel(val & ~MAC_RX_CFG_CARRIER_EXTEND,
+ cp->regs + REG_MAC_RX_CFG);
+ writel(0x40, cp->regs + REG_MAC_SLOT_TIME);
+ }
+
+ if (netif_msg_link(cp)) {
+ if (pause & 0x01) {
+ printk(KERN_INFO "%s: Pause is enabled "
+ "(rxfifo: %d off: %d on: %d)\n",
+ cp->dev->name,
+ cp->rx_fifo_size,
+ cp->rx_pause_off,
+ cp->rx_pause_on);
+ } else if (pause & 0x10) {
+ printk(KERN_INFO "%s: TX pause enabled\n",
+ cp->dev->name);
+ } else {
+ printk(KERN_INFO "%s: Pause is disabled\n",
+ cp->dev->name);
+ }
+ }
+
+ val = readl(cp->regs + REG_MAC_CTRL_CFG);
+ val &= ~(MAC_CTRL_CFG_SEND_PAUSE_EN | MAC_CTRL_CFG_RECV_PAUSE_EN);
+ if (pause) { /* symmetric or asymmetric pause */
+ val |= MAC_CTRL_CFG_SEND_PAUSE_EN;
+ if (pause & 0x01) { /* symmetric pause */
+ val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
+ }
+ }
+ writel(val, cp->regs + REG_MAC_CTRL_CFG);
+ cas_start_dma(cp);
+}
+
+/* Must be invoked under cp->lock. */
+static void cas_init_hw(struct cas *cp, int restart_link)
+{
+ if (restart_link)
+ cas_phy_init(cp);
+
+ cas_init_pause_thresholds(cp);
+ cas_init_mac(cp);
+ cas_init_dma(cp);
+
+ if (restart_link) {
+ /* Default aneg parameters */
+ cp->timer_ticks = 0;
+ cas_begin_auto_negotiation(cp, NULL);
+ } else if (cp->lstate == link_up) {
+ cas_set_link_modes(cp);
+ netif_carrier_on(cp->dev);
+ }
+}
+
+/* Must be invoked under cp->lock. on earlier cassini boards,
+ * SOFT_0 is tied to PCI reset. we use this to force a pci reset,
+ * let it settle out, and then restore pci state.
+ */
+static void cas_hard_reset(struct cas *cp)
+{
+ writel(BIM_LOCAL_DEV_SOFT_0, cp->regs + REG_BIM_LOCAL_DEV_EN);
+ udelay(20);
+ pci_restore_state(cp->pdev);
+}
+
+
+static void cas_global_reset(struct cas *cp, int blkflag)
+{
+ int limit;
+
+ /* issue a global reset. don't use RSTOUT. */
+ if (blkflag && !CAS_PHY_MII(cp->phy_type)) {
+ /* For PCS, when the blkflag is set, we should set the
+ * SW_REST_BLOCK_PCS_SLINK bit to prevent the results of
+ * the last autonegotiation from being cleared. We'll
+ * need some special handling if the chip is set into a
+ * loopback mode.
+ */
+ writel((SW_RESET_TX | SW_RESET_RX | SW_RESET_BLOCK_PCS_SLINK),
+ cp->regs + REG_SW_RESET);
+ } else {
+ writel(SW_RESET_TX | SW_RESET_RX, cp->regs + REG_SW_RESET);
+ }
+
+ /* need to wait at least 3ms before polling register */
+ mdelay(3);
+
+ limit = STOP_TRIES;
+ while (limit-- > 0) {
+ u32 val = readl(cp->regs + REG_SW_RESET);
+ if ((val & (SW_RESET_TX | SW_RESET_RX)) == 0)
+ goto done;
+ udelay(10);
+ }
+ printk(KERN_ERR "%s: sw reset failed.\n", cp->dev->name);
+
+done:
+ /* enable various BIM interrupts */
+ writel(BIM_CFG_DPAR_INTR_ENABLE | BIM_CFG_RMA_INTR_ENABLE |
+ BIM_CFG_RTA_INTR_ENABLE, cp->regs + REG_BIM_CFG);
+
+ /* clear out pci error status mask for handled errors.
+ * we don't deal with DMA counter overflows as they happen
+ * all the time.
+ */
+ writel(0xFFFFFFFFU & ~(PCI_ERR_BADACK | PCI_ERR_DTRTO |
+ PCI_ERR_OTHER | PCI_ERR_BIM_DMA_WRITE |
+ PCI_ERR_BIM_DMA_READ), cp->regs +
+ REG_PCI_ERR_STATUS_MASK);
+
+ /* set up for MII by default to address mac rx reset timeout
+ * issue
+ */
+ writel(PCS_DATAPATH_MODE_MII, cp->regs + REG_PCS_DATAPATH_MODE);
+}
+
+static void cas_reset(struct cas *cp, int blkflag)
+{
+ u32 val;
+
+ cas_mask_intr(cp);
+ cas_global_reset(cp, blkflag);
+ cas_mac_reset(cp);
+ cas_entropy_reset(cp);
+
+ /* disable dma engines. */
+ val = readl(cp->regs + REG_TX_CFG);
+ val &= ~TX_CFG_DMA_EN;
+ writel(val, cp->regs + REG_TX_CFG);
+
+ val = readl(cp->regs + REG_RX_CFG);
+ val &= ~RX_CFG_DMA_EN;
+ writel(val, cp->regs + REG_RX_CFG);
+
+ /* program header parser */
+ if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) ||
+ (CAS_HP_ALT_FIRMWARE == cas_prog_null)) {
+ cas_load_firmware(cp, CAS_HP_FIRMWARE);
+ } else {
+ cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE);
+ }
+
+ /* clear out error registers */
+ spin_lock(&cp->stat_lock[N_TX_RINGS]);
+ cas_clear_mac_err(cp);
+ spin_unlock(&cp->stat_lock[N_TX_RINGS]);
+}
+
+/* Shut down the chip, must be called with pm_sem held. */
+static void cas_shutdown(struct cas *cp)
+{
+ unsigned long flags;
+
+ /* Make us not-running to avoid timers respawning */
+ cp->hw_running = 0;
+
+ del_timer_sync(&cp->link_timer);
+
+ /* Stop the reset task */
+#if 0
+ while (atomic_read(&cp->reset_task_pending_mtu) ||
+ atomic_read(&cp->reset_task_pending_spare) ||
+ atomic_read(&cp->reset_task_pending_all))
+ schedule();
+
+#else
+ while (atomic_read(&cp->reset_task_pending))
+ schedule();
+#endif
+ /* Actually stop the chip */
+ cas_lock_all_save(cp, flags);
+ cas_reset(cp, 0);
+ if (cp->cas_flags & CAS_FLAG_SATURN)
+ cas_phy_powerdown(cp);
+ cas_unlock_all_restore(cp, flags);
+}
+
+static int cas_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct cas *cp = netdev_priv(dev);
+
+ if (new_mtu < CAS_MIN_MTU || new_mtu > CAS_MAX_MTU)
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+ if (!netif_running(dev) || !netif_device_present(dev))
+ return 0;
+
+ /* let the reset task handle it */
+#if 1
+ atomic_inc(&cp->reset_task_pending);
+ if ((cp->phy_type & CAS_PHY_SERDES)) {
+ atomic_inc(&cp->reset_task_pending_all);
+ } else {
+ atomic_inc(&cp->reset_task_pending_mtu);
+ }
+ schedule_work(&cp->reset_task);
+#else
+ atomic_set(&cp->reset_task_pending, (cp->phy_type & CAS_PHY_SERDES) ?
+ CAS_RESET_ALL : CAS_RESET_MTU);
+ printk(KERN_ERR "reset called in cas_change_mtu\n");
+ schedule_work(&cp->reset_task);
+#endif
+
+ flush_scheduled_work();
+ return 0;
+}
+
+static void cas_clean_txd(struct cas *cp, int ring)
+{
+ struct cas_tx_desc *txd = cp->init_txds[ring];
+ struct sk_buff *skb, **skbs = cp->tx_skbs[ring];
+ u64 daddr, dlen;
+ int i, size;
+
+ size = TX_DESC_RINGN_SIZE(ring);
+ for (i = 0; i < size; i++) {
+ int frag;
+
+ if (skbs[i] == NULL)
+ continue;
+
+ skb = skbs[i];
+ skbs[i] = NULL;
+
+ for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
+ int ent = i & (size - 1);
+
+ /* first buffer is never a tiny buffer and so
+ * needs to be unmapped.
+ */
+ daddr = le64_to_cpu(txd[ent].buffer);
+ dlen = CAS_VAL(TX_DESC_BUFLEN,
+ le64_to_cpu(txd[ent].control));
+ pci_unmap_page(cp->pdev, daddr, dlen,
+ PCI_DMA_TODEVICE);
+
+ if (frag != skb_shinfo(skb)->nr_frags) {
+ i++;
+
+ /* next buffer might by a tiny buffer.
+ * skip past it.
+ */
+ ent = i & (size - 1);
+ if (cp->tx_tiny_use[ring][ent].used)
+ i++;
+ }
+ }
+ dev_kfree_skb_any(skb);
+ }
+
+ /* zero out tiny buf usage */
+ memset(cp->tx_tiny_use[ring], 0, size*sizeof(*cp->tx_tiny_use[ring]));
+}
+
+/* freed on close */
+static inline void cas_free_rx_desc(struct cas *cp, int ring)
+{
+ cas_page_t **page = cp->rx_pages[ring];
+ int i, size;
+
+ size = RX_DESC_RINGN_SIZE(ring);
+ for (i = 0; i < size; i++) {
+ if (page[i]) {
+ cas_page_free(cp, page[i]);
+ page[i] = NULL;
+ }
+ }
+}
+
+static void cas_free_rxds(struct cas *cp)
+{
+ int i;
+
+ for (i = 0; i < N_RX_DESC_RINGS; i++)
+ cas_free_rx_desc(cp, i);
+}
+
+/* Must be invoked under cp->lock. */
+static void cas_clean_rings(struct cas *cp)
+{
+ int i;
+
+ /* need to clean all tx rings */
+ memset(cp->tx_old, 0, sizeof(*cp->tx_old)*N_TX_RINGS);
+ memset(cp->tx_new, 0, sizeof(*cp->tx_new)*N_TX_RINGS);
+ for (i = 0; i < N_TX_RINGS; i++)
+ cas_clean_txd(cp, i);
+
+ /* zero out init block */
+ memset(cp->init_block, 0, sizeof(struct cas_init_block));
+ cas_clean_rxds(cp);
+ cas_clean_rxcs(cp);
+}
+
+/* allocated on open */
+static inline int cas_alloc_rx_desc(struct cas *cp, int ring)
+{
+ cas_page_t **page = cp->rx_pages[ring];
+ int size, i = 0;
+
+ size = RX_DESC_RINGN_SIZE(ring);
+ for (i = 0; i < size; i++) {
+ if ((page[i] = cas_page_alloc(cp, GFP_KERNEL)) == NULL)
+ return -1;
+ }
+ return 0;
+}
+
+static int cas_alloc_rxds(struct cas *cp)
+{
+ int i;
+
+ for (i = 0; i < N_RX_DESC_RINGS; i++) {
+ if (cas_alloc_rx_desc(cp, i) < 0) {
+ cas_free_rxds(cp);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void cas_reset_task(void *data)
+{
+ struct cas *cp = (struct cas *) data;
+#if 0
+ int pending = atomic_read(&cp->reset_task_pending);
+#else
+ int pending_all = atomic_read(&cp->reset_task_pending_all);
+ int pending_spare = atomic_read(&cp->reset_task_pending_spare);
+ int pending_mtu = atomic_read(&cp->reset_task_pending_mtu);
+
+ if (pending_all == 0 && pending_spare == 0 && pending_mtu == 0) {
+ /* We can have more tasks scheduled than actually
+ * needed.
+ */
+ atomic_dec(&cp->reset_task_pending);
+ return;
+ }
+#endif
+ /* The link went down, we reset the ring, but keep
+ * DMA stopped. Use this function for reset
+ * on error as well.
+ */
+ if (cp->hw_running) {
+ unsigned long flags;
+
+ /* Make sure we don't get interrupts or tx packets */
+ netif_device_detach(cp->dev);
+ cas_lock_all_save(cp, flags);
+
+ if (cp->opened) {
+ /* We call cas_spare_recover when we call cas_open.
+ * but we do not initialize the lists cas_spare_recover
+ * uses until cas_open is called.
+ */
+ cas_spare_recover(cp, GFP_ATOMIC);
+ }
+#if 1
+ /* test => only pending_spare set */
+ if (!pending_all && !pending_mtu)
+ goto done;
+#else
+ if (pending == CAS_RESET_SPARE)
+ goto done;
+#endif
+ /* when pending == CAS_RESET_ALL, the following
+ * call to cas_init_hw will restart auto negotiation.
+ * Setting the second argument of cas_reset to
+ * !(pending == CAS_RESET_ALL) will set this argument
+ * to 1 (avoiding reinitializing the PHY for the normal
+ * PCS case) when auto negotiation is not restarted.
+ */
+#if 1
+ cas_reset(cp, !(pending_all > 0));
+ if (cp->opened)
+ cas_clean_rings(cp);
+ cas_init_hw(cp, (pending_all > 0));
+#else
+ cas_reset(cp, !(pending == CAS_RESET_ALL));
+ if (cp->opened)
+ cas_clean_rings(cp);
+ cas_init_hw(cp, pending == CAS_RESET_ALL);
+#endif
+
+done:
+ cas_unlock_all_restore(cp, flags);
+ netif_device_attach(cp->dev);
+ }
+#if 1
+ atomic_sub(pending_all, &cp->reset_task_pending_all);
+ atomic_sub(pending_spare, &cp->reset_task_pending_spare);
+ atomic_sub(pending_mtu, &cp->reset_task_pending_mtu);
+ atomic_dec(&cp->reset_task_pending);
+#else
+ atomic_set(&cp->reset_task_pending, 0);
+#endif
+}
+
+static void cas_link_timer(unsigned long data)
+{
+ struct cas *cp = (struct cas *) data;
+ int mask, pending = 0, reset = 0;
+ unsigned long flags;
+
+ if (link_transition_timeout != 0 &&
+ cp->link_transition_jiffies_valid &&
+ ((jiffies - cp->link_transition_jiffies) >
+ (link_transition_timeout))) {
+ /* One-second counter so link-down workaround doesn't
+ * cause resets to occur so fast as to fool the switch
+ * into thinking the link is down.
+ */
+ cp->link_transition_jiffies_valid = 0;
+ }
+
+ if (!cp->hw_running)
+ return;
+
+ spin_lock_irqsave(&cp->lock, flags);
+ cas_lock_tx(cp);
+ cas_entropy_gather(cp);
+
+ /* If the link task is still pending, we just
+ * reschedule the link timer
+ */
+#if 1
+ if (atomic_read(&cp->reset_task_pending_all) ||
+ atomic_read(&cp->reset_task_pending_spare) ||
+ atomic_read(&cp->reset_task_pending_mtu))
+ goto done;
+#else
+ if (atomic_read(&cp->reset_task_pending))
+ goto done;
+#endif
+
+ /* check for rx cleaning */
+ if ((mask = (cp->cas_flags & CAS_FLAG_RXD_POST_MASK))) {
+ int i, rmask;
+
+ for (i = 0; i < MAX_RX_DESC_RINGS; i++) {
+ rmask = CAS_FLAG_RXD_POST(i);
+ if ((mask & rmask) == 0)
+ continue;
+
+ /* post_rxds will do a mod_timer */
+ if (cas_post_rxds_ringN(cp, i, cp->rx_last[i]) < 0) {
+ pending = 1;
+ continue;
+ }
+ cp->cas_flags &= ~rmask;
+ }
+ }
+
+ if (CAS_PHY_MII(cp->phy_type)) {
+ u16 bmsr;
+ cas_mif_poll(cp, 0);
+ bmsr = cas_phy_read(cp, MII_BMSR);
+ /* WTZ: Solaris driver reads this twice, but that
+ * may be due to the PCS case and the use of a
+ * common implementation. Read it twice here to be
+ * safe.
+ */
+ bmsr = cas_phy_read(cp, MII_BMSR);
+ cas_mif_poll(cp, 1);
+ readl(cp->regs + REG_MIF_STATUS); /* avoid dups */
+ reset = cas_mii_link_check(cp, bmsr);
+ } else {
+ reset = cas_pcs_link_check(cp);
+ }
+
+ if (reset)
+ goto done;
+
+ /* check for tx state machine confusion */
+ if ((readl(cp->regs + REG_MAC_TX_STATUS) & MAC_TX_FRAME_XMIT) == 0) {
+ u32 val = readl(cp->regs + REG_MAC_STATE_MACHINE);
+ u32 wptr, rptr;
+ int tlm = CAS_VAL(MAC_SM_TLM, val);
+
+ if (((tlm == 0x5) || (tlm == 0x3)) &&
+ (CAS_VAL(MAC_SM_ENCAP_SM, val) == 0)) {
+ if (netif_msg_tx_err(cp))
+ printk(KERN_DEBUG "%s: tx err: "
+ "MAC_STATE[%08x]\n",
+ cp->dev->name, val);
+ reset = 1;
+ goto done;
+ }
+
+ val = readl(cp->regs + REG_TX_FIFO_PKT_CNT);
+ wptr = readl(cp->regs + REG_TX_FIFO_WRITE_PTR);
+ rptr = readl(cp->regs + REG_TX_FIFO_READ_PTR);
+ if ((val == 0) && (wptr != rptr)) {
+ if (netif_msg_tx_err(cp))
+ printk(KERN_DEBUG "%s: tx err: "
+ "TX_FIFO[%08x:%08x:%08x]\n",
+ cp->dev->name, val, wptr, rptr);
+ reset = 1;
+ }
+
+ if (reset)
+ cas_hard_reset(cp);
+ }
+
+done:
+ if (reset) {
+#if 1
+ atomic_inc(&cp->reset_task_pending);
+ atomic_inc(&cp->reset_task_pending_all);
+ schedule_work(&cp->reset_task);
+#else
+ atomic_set(&cp->reset_task_pending, CAS_RESET_ALL);
+ printk(KERN_ERR "reset called in cas_link_timer\n");
+ schedule_work(&cp->reset_task);
+#endif
+ }
+
+ if (!pending)
+ mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT);
+ cas_unlock_tx(cp);
+ spin_unlock_irqrestore(&cp->lock, flags);
+}
+
+/* tiny buffers are used to avoid target abort issues with
+ * older cassini's
+ */
+static void cas_tx_tiny_free(struct cas *cp)
+{
+ struct pci_dev *pdev = cp->pdev;
+ int i;
+
+ for (i = 0; i < N_TX_RINGS; i++) {
+ if (!cp->tx_tiny_bufs[i])
+ continue;
+
+ pci_free_consistent(pdev, TX_TINY_BUF_BLOCK,
+ cp->tx_tiny_bufs[i],
+ cp->tx_tiny_dvma[i]);
+ cp->tx_tiny_bufs[i] = NULL;
+ }
+}
+
+static int cas_tx_tiny_alloc(struct cas *cp)
+{
+ struct pci_dev *pdev = cp->pdev;
+ int i;
+
+ for (i = 0; i < N_TX_RINGS; i++) {
+ cp->tx_tiny_bufs[i] =
+ pci_alloc_consistent(pdev, TX_TINY_BUF_BLOCK,
+ &cp->tx_tiny_dvma[i]);
+ if (!cp->tx_tiny_bufs[i]) {
+ cas_tx_tiny_free(cp);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+static int cas_open(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ int hw_was_up, err;
+ unsigned long flags;
+
+ down(&cp->pm_sem);
+
+ hw_was_up = cp->hw_running;
+
+ /* The power-management semaphore protects the hw_running
+ * etc. state so it is safe to do this bit without cp->lock
+ */
+ if (!cp->hw_running) {
+ /* Reset the chip */
+ cas_lock_all_save(cp, flags);
+ /* We set the second arg to cas_reset to zero
+ * because cas_init_hw below will have its second
+ * argument set to non-zero, which will force
+ * autonegotiation to start.
+ */
+ cas_reset(cp, 0);
+ cp->hw_running = 1;
+ cas_unlock_all_restore(cp, flags);
+ }
+
+ if (cas_tx_tiny_alloc(cp) < 0)
+ return -ENOMEM;
+
+ /* alloc rx descriptors */
+ err = -ENOMEM;
+ if (cas_alloc_rxds(cp) < 0)
+ goto err_tx_tiny;
+
+ /* allocate spares */
+ cas_spare_init(cp);
+ cas_spare_recover(cp, GFP_KERNEL);
+
+ /* We can now request the interrupt as we know it's masked
+ * on the controller. cassini+ has up to 4 interrupts
+ * that can be used, but you need to do explicit pci interrupt
+ * mapping to expose them
+ */
+ if (request_irq(cp->pdev->irq, cas_interrupt,
+ SA_SHIRQ, dev->name, (void *) dev)) {
+ printk(KERN_ERR "%s: failed to request irq !\n",
+ cp->dev->name);
+ err = -EAGAIN;
+ goto err_spare;
+ }
+
+ /* init hw */
+ cas_lock_all_save(cp, flags);
+ cas_clean_rings(cp);
+ cas_init_hw(cp, !hw_was_up);
+ cp->opened = 1;
+ cas_unlock_all_restore(cp, flags);
+
+ netif_start_queue(dev);
+ up(&cp->pm_sem);
+ return 0;
+
+err_spare:
+ cas_spare_free(cp);
+ cas_free_rxds(cp);
+err_tx_tiny:
+ cas_tx_tiny_free(cp);
+ up(&cp->pm_sem);
+ return err;
+}
+
+static int cas_close(struct net_device *dev)
+{
+ unsigned long flags;
+ struct cas *cp = netdev_priv(dev);
+
+ /* Make sure we don't get distracted by suspend/resume */
+ down(&cp->pm_sem);
+
+ netif_stop_queue(dev);
+
+ /* Stop traffic, mark us closed */
+ cas_lock_all_save(cp, flags);
+ cp->opened = 0;
+ cas_reset(cp, 0);
+ cas_phy_init(cp);
+ cas_begin_auto_negotiation(cp, NULL);
+ cas_clean_rings(cp);
+ cas_unlock_all_restore(cp, flags);
+
+ free_irq(cp->pdev->irq, (void *) dev);
+ cas_spare_free(cp);
+ cas_free_rxds(cp);
+ cas_tx_tiny_free(cp);
+ up(&cp->pm_sem);
+ return 0;
+}
+
+static struct {
+ const char name[ETH_GSTRING_LEN];
+} ethtool_cassini_statnames[] = {
+ {"collisions"},
+ {"rx_bytes"},
+ {"rx_crc_errors"},
+ {"rx_dropped"},
+ {"rx_errors"},
+ {"rx_fifo_errors"},
+ {"rx_frame_errors"},
+ {"rx_length_errors"},
+ {"rx_over_errors"},
+ {"rx_packets"},
+ {"tx_aborted_errors"},
+ {"tx_bytes"},
+ {"tx_dropped"},
+ {"tx_errors"},
+ {"tx_fifo_errors"},
+ {"tx_packets"}
+};
+#define CAS_NUM_STAT_KEYS (sizeof(ethtool_cassini_statnames)/ETH_GSTRING_LEN)
+
+static struct {
+ const int offsets; /* neg. values for 2nd arg to cas_read_phy */
+} ethtool_register_table[] = {
+ {-MII_BMSR},
+ {-MII_BMCR},
+ {REG_CAWR},
+ {REG_INF_BURST},
+ {REG_BIM_CFG},
+ {REG_RX_CFG},
+ {REG_HP_CFG},
+ {REG_MAC_TX_CFG},
+ {REG_MAC_RX_CFG},
+ {REG_MAC_CTRL_CFG},
+ {REG_MAC_XIF_CFG},
+ {REG_MIF_CFG},
+ {REG_PCS_CFG},
+ {REG_SATURN_PCFG},
+ {REG_PCS_MII_STATUS},
+ {REG_PCS_STATE_MACHINE},
+ {REG_MAC_COLL_EXCESS},
+ {REG_MAC_COLL_LATE}
+};
+#define CAS_REG_LEN (sizeof(ethtool_register_table)/sizeof(int))
+#define CAS_MAX_REGS (sizeof (u32)*CAS_REG_LEN)
+
+static void cas_read_regs(struct cas *cp, u8 *ptr, int len)
+{
+ u8 *p;
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cp->lock, flags);
+ for (i = 0, p = ptr; i < len ; i ++, p += sizeof(u32)) {
+ u16 hval;
+ u32 val;
+ if (ethtool_register_table[i].offsets < 0) {
+ hval = cas_phy_read(cp,
+ -ethtool_register_table[i].offsets);
+ val = hval;
+ } else {
+ val= readl(cp->regs+ethtool_register_table[i].offsets);
+ }
+ memcpy(p, (u8 *)&val, sizeof(u32));
+ }
+ spin_unlock_irqrestore(&cp->lock, flags);
+}
+
+static struct net_device_stats *cas_get_stats(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ struct net_device_stats *stats = cp->net_stats;
+ unsigned long flags;
+ int i;
+ unsigned long tmp;
+
+ /* we collate all of the stats into net_stats[N_TX_RING] */
+ if (!cp->hw_running)
+ return stats + N_TX_RINGS;
+
+ /* collect outstanding stats */
+ /* WTZ: the Cassini spec gives these as 16 bit counters but
+ * stored in 32-bit words. Added a mask of 0xffff to be safe,
+ * in case the chip somehow puts any garbage in the other bits.
+ * Also, counter usage didn't seem to mach what Adrian did
+ * in the parts of the code that set these quantities. Made
+ * that consistent.
+ */
+ spin_lock_irqsave(&cp->stat_lock[N_TX_RINGS], flags);
+ stats[N_TX_RINGS].rx_crc_errors +=
+ readl(cp->regs + REG_MAC_FCS_ERR) & 0xffff;
+ stats[N_TX_RINGS].rx_frame_errors +=
+ readl(cp->regs + REG_MAC_ALIGN_ERR) &0xffff;
+ stats[N_TX_RINGS].rx_length_errors +=
+ readl(cp->regs + REG_MAC_LEN_ERR) & 0xffff;
+#if 1
+ tmp = (readl(cp->regs + REG_MAC_COLL_EXCESS) & 0xffff) +
+ (readl(cp->regs + REG_MAC_COLL_LATE) & 0xffff);
+ stats[N_TX_RINGS].tx_aborted_errors += tmp;
+ stats[N_TX_RINGS].collisions +=
+ tmp + (readl(cp->regs + REG_MAC_COLL_NORMAL) & 0xffff);
+#else
+ stats[N_TX_RINGS].tx_aborted_errors +=
+ readl(cp->regs + REG_MAC_COLL_EXCESS);
+ stats[N_TX_RINGS].collisions += readl(cp->regs + REG_MAC_COLL_EXCESS) +
+ readl(cp->regs + REG_MAC_COLL_LATE);
+#endif
+ cas_clear_mac_err(cp);
+
+ /* saved bits that are unique to ring 0 */
+ spin_lock(&cp->stat_lock[0]);
+ stats[N_TX_RINGS].collisions += stats[0].collisions;
+ stats[N_TX_RINGS].rx_over_errors += stats[0].rx_over_errors;
+ stats[N_TX_RINGS].rx_frame_errors += stats[0].rx_frame_errors;
+ stats[N_TX_RINGS].rx_fifo_errors += stats[0].rx_fifo_errors;
+ stats[N_TX_RINGS].tx_aborted_errors += stats[0].tx_aborted_errors;
+ stats[N_TX_RINGS].tx_fifo_errors += stats[0].tx_fifo_errors;
+ spin_unlock(&cp->stat_lock[0]);
+
+ for (i = 0; i < N_TX_RINGS; i++) {
+ spin_lock(&cp->stat_lock[i]);
+ stats[N_TX_RINGS].rx_length_errors +=
+ stats[i].rx_length_errors;
+ stats[N_TX_RINGS].rx_crc_errors += stats[i].rx_crc_errors;
+ stats[N_TX_RINGS].rx_packets += stats[i].rx_packets;
+ stats[N_TX_RINGS].tx_packets += stats[i].tx_packets;
+ stats[N_TX_RINGS].rx_bytes += stats[i].rx_bytes;
+ stats[N_TX_RINGS].tx_bytes += stats[i].tx_bytes;
+ stats[N_TX_RINGS].rx_errors += stats[i].rx_errors;
+ stats[N_TX_RINGS].tx_errors += stats[i].tx_errors;
+ stats[N_TX_RINGS].rx_dropped += stats[i].rx_dropped;
+ stats[N_TX_RINGS].tx_dropped += stats[i].tx_dropped;
+ memset(stats + i, 0, sizeof(struct net_device_stats));
+ spin_unlock(&cp->stat_lock[i]);
+ }
+ spin_unlock_irqrestore(&cp->stat_lock[N_TX_RINGS], flags);
+ return stats + N_TX_RINGS;
+}
+
+
+static void cas_set_multicast(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ u32 rxcfg, rxcfg_new;
+ unsigned long flags;
+ int limit = STOP_TRIES;
+
+ if (!cp->hw_running)
+ return;
+
+ spin_lock_irqsave(&cp->lock, flags);
+ rxcfg = readl(cp->regs + REG_MAC_RX_CFG);
+
+ /* disable RX MAC and wait for completion */
+ writel(rxcfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG);
+ while (readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_EN) {
+ if (!limit--)
+ break;
+ udelay(10);
+ }
+
+ /* disable hash filter and wait for completion */
+ limit = STOP_TRIES;
+ rxcfg &= ~(MAC_RX_CFG_PROMISC_EN | MAC_RX_CFG_HASH_FILTER_EN);
+ writel(rxcfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG);
+ while (readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_HASH_FILTER_EN) {
+ if (!limit--)
+ break;
+ udelay(10);
+ }
+
+ /* program hash filters */
+ cp->mac_rx_cfg = rxcfg_new = cas_setup_multicast(cp);
+ rxcfg |= rxcfg_new;
+ writel(rxcfg, cp->regs + REG_MAC_RX_CFG);
+ spin_unlock_irqrestore(&cp->lock, flags);
+}
+
+static void cas_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ struct cas *cp = netdev_priv(dev);
+ strncpy(info->driver, DRV_MODULE_NAME, ETHTOOL_BUSINFO_LEN);
+ strncpy(info->version, DRV_MODULE_VERSION, ETHTOOL_BUSINFO_LEN);
+ info->fw_version[0] = '\0';
+ strncpy(info->bus_info, pci_name(cp->pdev), ETHTOOL_BUSINFO_LEN);
+ info->regdump_len = cp->casreg_len < CAS_MAX_REGS ?
+ cp->casreg_len : CAS_MAX_REGS;
+ info->n_stats = CAS_NUM_STAT_KEYS;
+}
+
+static int cas_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct cas *cp = netdev_priv(dev);
+ u16 bmcr;
+ int full_duplex, speed, pause;
+ unsigned long flags;
+ enum link_state linkstate = link_up;
+
+ cmd->advertising = 0;
+ cmd->supported = SUPPORTED_Autoneg;
+ if (cp->cas_flags & CAS_FLAG_1000MB_CAP) {
+ cmd->supported |= SUPPORTED_1000baseT_Full;
+ cmd->advertising |= ADVERTISED_1000baseT_Full;
+ }
+
+ /* Record PHY settings if HW is on. */
+ spin_lock_irqsave(&cp->lock, flags);
+ bmcr = 0;
+ linkstate = cp->lstate;
+ if (CAS_PHY_MII(cp->phy_type)) {
+ cmd->port = PORT_MII;
+ cmd->transceiver = (cp->cas_flags & CAS_FLAG_SATURN) ?
+ XCVR_INTERNAL : XCVR_EXTERNAL;
+ cmd->phy_address = cp->phy_addr;
+ cmd->advertising |= ADVERTISED_TP | ADVERTISED_MII |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full;
+
+ cmd->supported |=
+ (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_TP | SUPPORTED_MII);
+
+ if (cp->hw_running) {
+ cas_mif_poll(cp, 0);
+ bmcr = cas_phy_read(cp, MII_BMCR);
+ cas_read_mii_link_mode(cp, &full_duplex,
+ &speed, &pause);
+ cas_mif_poll(cp, 1);
+ }
+
+ } else {
+ cmd->port = PORT_FIBRE;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->phy_address = 0;
+ cmd->supported |= SUPPORTED_FIBRE;
+ cmd->advertising |= ADVERTISED_FIBRE;
+
+ if (cp->hw_running) {
+ /* pcs uses the same bits as mii */
+ bmcr = readl(cp->regs + REG_PCS_MII_CTRL);
+ cas_read_pcs_link_mode(cp, &full_duplex,
+ &speed, &pause);
+ }
+ }
+ spin_unlock_irqrestore(&cp->lock, flags);
+
+ if (bmcr & BMCR_ANENABLE) {
+ cmd->advertising |= ADVERTISED_Autoneg;
+ cmd->autoneg = AUTONEG_ENABLE;
+ cmd->speed = ((speed == 10) ?
+ SPEED_10 :
+ ((speed == 1000) ?
+ SPEED_1000 : SPEED_100));
+ cmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+ } else {
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->speed =
+ (bmcr & CAS_BMCR_SPEED1000) ?
+ SPEED_1000 :
+ ((bmcr & BMCR_SPEED100) ? SPEED_100:
+ SPEED_10);
+ cmd->duplex =
+ (bmcr & BMCR_FULLDPLX) ?
+ DUPLEX_FULL : DUPLEX_HALF;
+ }
+ if (linkstate != link_up) {
+ /* Force these to "unknown" if the link is not up and
+ * autonogotiation in enabled. We can set the link
+ * speed to 0, but not cmd->duplex,
+ * because its legal values are 0 and 1. Ethtool will
+ * print the value reported in parentheses after the
+ * word "Unknown" for unrecognized values.
+ *
+ * If in forced mode, we report the speed and duplex
+ * settings that we configured.
+ */
+ if (cp->link_cntl & BMCR_ANENABLE) {
+ cmd->speed = 0;
+ cmd->duplex = 0xff;
+ } else {
+ cmd->speed = SPEED_10;
+ if (cp->link_cntl & BMCR_SPEED100) {
+ cmd->speed = SPEED_100;
+ } else if (cp->link_cntl & CAS_BMCR_SPEED1000) {
+ cmd->speed = SPEED_1000;
+ }
+ cmd->duplex = (cp->link_cntl & BMCR_FULLDPLX)?
+ DUPLEX_FULL : DUPLEX_HALF;
+ }
+ }
+ return 0;
+}
+
+static int cas_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct cas *cp = netdev_priv(dev);
+ unsigned long flags;
+
+ /* Verify the settings we care about. */
+ if (cmd->autoneg != AUTONEG_ENABLE &&
+ cmd->autoneg != AUTONEG_DISABLE)
+ return -EINVAL;
+
+ if (cmd->autoneg == AUTONEG_DISABLE &&
+ ((cmd->speed != SPEED_1000 &&
+ cmd->speed != SPEED_100 &&
+ cmd->speed != SPEED_10) ||
+ (cmd->duplex != DUPLEX_HALF &&
+ cmd->duplex != DUPLEX_FULL)))
+ return -EINVAL;
+
+ /* Apply settings and restart link process. */
+ spin_lock_irqsave(&cp->lock, flags);
+ cas_begin_auto_negotiation(cp, cmd);
+ spin_unlock_irqrestore(&cp->lock, flags);
+ return 0;
+}
+
+static int cas_nway_reset(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ unsigned long flags;
+
+ if ((cp->link_cntl & BMCR_ANENABLE) == 0)
+ return -EINVAL;
+
+ /* Restart link process. */
+ spin_lock_irqsave(&cp->lock, flags);
+ cas_begin_auto_negotiation(cp, NULL);
+ spin_unlock_irqrestore(&cp->lock, flags);
+
+ return 0;
+}
+
+static u32 cas_get_link(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ return cp->lstate == link_up;
+}
+
+static u32 cas_get_msglevel(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ return cp->msg_enable;
+}
+
+static void cas_set_msglevel(struct net_device *dev, u32 value)
+{
+ struct cas *cp = netdev_priv(dev);
+ cp->msg_enable = value;
+}
+
+static int cas_get_regs_len(struct net_device *dev)
+{
+ struct cas *cp = netdev_priv(dev);
+ return cp->casreg_len < CAS_MAX_REGS ? cp->casreg_len: CAS_MAX_REGS;
+}
+
+static void cas_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *p)
+{
+ struct cas *cp = netdev_priv(dev);
+ regs->version = 0;
+ /* cas_read_regs handles locks (cp->lock). */
+ cas_read_regs(cp, p, regs->len / sizeof(u32));
+}
+
+static int cas_get_stats_count(struct net_device *dev)
+{
+ return CAS_NUM_STAT_KEYS;
+}
+
+static void cas_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+ memcpy(data, &ethtool_cassini_statnames,
+ CAS_NUM_STAT_KEYS * ETH_GSTRING_LEN);
+}
+
+static void cas_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *estats, u64 *data)
+{
+ struct cas *cp = netdev_priv(dev);
+ struct net_device_stats *stats = cas_get_stats(cp->dev);
+ int i = 0;
+ data[i++] = stats->collisions;
+ data[i++] = stats->rx_bytes;
+ data[i++] = stats->rx_crc_errors;
+ data[i++] = stats->rx_dropped;
+ data[i++] = stats->rx_errors;
+ data[i++] = stats->rx_fifo_errors;
+ data[i++] = stats->rx_frame_errors;
+ data[i++] = stats->rx_length_errors;
+ data[i++] = stats->rx_over_errors;
+ data[i++] = stats->rx_packets;
+ data[i++] = stats->tx_aborted_errors;
+ data[i++] = stats->tx_bytes;
+ data[i++] = stats->tx_dropped;
+ data[i++] = stats->tx_errors;
+ data[i++] = stats->tx_fifo_errors;
+ data[i++] = stats->tx_packets;
+ BUG_ON(i != CAS_NUM_STAT_KEYS);
+}
+
+static struct ethtool_ops cas_ethtool_ops = {
+ .get_drvinfo = cas_get_drvinfo,
+ .get_settings = cas_get_settings,
+ .set_settings = cas_set_settings,
+ .nway_reset = cas_nway_reset,
+ .get_link = cas_get_link,
+ .get_msglevel = cas_get_msglevel,
+ .set_msglevel = cas_set_msglevel,
+ .get_regs_len = cas_get_regs_len,
+ .get_regs = cas_get_regs,
+ .get_stats_count = cas_get_stats_count,
+ .get_strings = cas_get_strings,
+ .get_ethtool_stats = cas_get_ethtool_stats,
+};
+
+static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct cas *cp = netdev_priv(dev);
+ struct mii_ioctl_data *data = if_mii(ifr);
+ unsigned long flags;
+ int rc = -EOPNOTSUPP;
+
+ /* Hold the PM semaphore while doing ioctl's or we may collide
+ * with open/close and power management and oops.
+ */
+ down(&cp->pm_sem);
+ switch (cmd) {
+ case SIOCGMIIPHY: /* Get address of MII PHY in use. */
+ data->phy_id = cp->phy_addr;
+ /* Fallthrough... */
+
+ case SIOCGMIIREG: /* Read MII PHY register. */
+ spin_lock_irqsave(&cp->lock, flags);
+ cas_mif_poll(cp, 0);
+ data->val_out = cas_phy_read(cp, data->reg_num & 0x1f);
+ cas_mif_poll(cp, 1);
+ spin_unlock_irqrestore(&cp->lock, flags);
+ rc = 0;
+ break;
+
+ case SIOCSMIIREG: /* Write MII PHY register. */
+ if (!capable(CAP_NET_ADMIN)) {
+ rc = -EPERM;
+ break;
+ }
+ spin_lock_irqsave(&cp->lock, flags);
+ cas_mif_poll(cp, 0);
+ rc = cas_phy_write(cp, data->reg_num & 0x1f, data->val_in);
+ cas_mif_poll(cp, 1);
+ spin_unlock_irqrestore(&cp->lock, flags);
+ break;
+ default:
+ break;
+ };
+
+ up(&cp->pm_sem);
+ return rc;
+}
+
+static int __devinit cas_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ static int cas_version_printed = 0;
+ unsigned long casreg_base, casreg_len;
+ struct net_device *dev;
+ struct cas *cp;
+ int i, err, pci_using_dac;
+ u16 pci_cmd;
+ u8 orig_cacheline_size = 0, cas_cacheline_size = 0;
+
+ if (cas_version_printed++ == 0)
+ printk(KERN_INFO "%s", version);
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR PFX "Cannot enable PCI device, "
+ "aborting.\n");
+ return err;
+ }
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+ printk(KERN_ERR PFX "Cannot find proper PCI device "
+ "base address, aborting.\n");
+ err = -ENODEV;
+ goto err_out_disable_pdev;
+ }
+
+ dev = alloc_etherdev(sizeof(*cp));
+ if (!dev) {
+ printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+ err = -ENOMEM;
+ goto err_out_disable_pdev;
+ }
+ SET_MODULE_OWNER(dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = pci_request_regions(pdev, dev->name);
+ if (err) {
+ printk(KERN_ERR PFX "Cannot obtain PCI resources, "
+ "aborting.\n");
+ goto err_out_free_netdev;
+ }
+ pci_set_master(pdev);
+
+ /* we must always turn on parity response or else parity
+ * doesn't get generated properly. disable SERR/PERR as well.
+ * in addition, we want to turn MWI on.
+ */
+ pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
+ pci_cmd &= ~PCI_COMMAND_SERR;
+ pci_cmd |= PCI_COMMAND_PARITY;
+ pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
+ pci_set_mwi(pdev);
+ /*
+ * On some architectures, the default cache line size set
+ * by pci_set_mwi reduces perforamnce. We have to increase
+ * it for this case. To start, we'll print some configuration
+ * data.
+ */
+#if 1
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ &orig_cacheline_size);
+ if (orig_cacheline_size < CAS_PREF_CACHELINE_SIZE) {
+ cas_cacheline_size =
+ (CAS_PREF_CACHELINE_SIZE < SMP_CACHE_BYTES) ?
+ CAS_PREF_CACHELINE_SIZE : SMP_CACHE_BYTES;
+ if (pci_write_config_byte(pdev,
+ PCI_CACHE_LINE_SIZE,
+ cas_cacheline_size)) {
+ printk(KERN_ERR PFX "Could not set PCI cache "
+ "line size\n");
+ goto err_write_cacheline;
+ }
+ }
+#endif
+
+
+ /* Configure DMA attributes. */
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ pci_using_dac = 1;
+ err = pci_set_consistent_dma_mask(pdev,
+ DMA_64BIT_MASK);
+ if (err < 0) {
+ printk(KERN_ERR PFX "Unable to obtain 64-bit DMA "
+ "for consistent allocations\n");
+ goto err_out_free_res;
+ }
+
+ } else {
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err) {
+ printk(KERN_ERR PFX "No usable DMA configuration, "
+ "aborting.\n");
+ goto err_out_free_res;
+ }
+ pci_using_dac = 0;
+ }
+
+ casreg_base = pci_resource_start(pdev, 0);
+ casreg_len = pci_resource_len(pdev, 0);
+
+ cp = netdev_priv(dev);
+ cp->pdev = pdev;
+#if 1
+ /* A value of 0 indicates we never explicitly set it */
+ cp->orig_cacheline_size = cas_cacheline_size ? orig_cacheline_size: 0;
+#endif
+ cp->dev = dev;
+ cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE :
+ cassini_debug;
+
+ cp->link_transition = LINK_TRANSITION_UNKNOWN;
+ cp->link_transition_jiffies_valid = 0;
+
+ spin_lock_init(&cp->lock);
+ spin_lock_init(&cp->rx_inuse_lock);
+ spin_lock_init(&cp->rx_spare_lock);
+ for (i = 0; i < N_TX_RINGS; i++) {
+ spin_lock_init(&cp->stat_lock[i]);
+ spin_lock_init(&cp->tx_lock[i]);
+ }
+ spin_lock_init(&cp->stat_lock[N_TX_RINGS]);
+ init_MUTEX(&cp->pm_sem);
+
+ init_timer(&cp->link_timer);
+ cp->link_timer.function = cas_link_timer;
+ cp->link_timer.data = (unsigned long) cp;
+
+#if 1
+ /* Just in case the implementation of atomic operations
+ * change so that an explicit initialization is necessary.
+ */
+ atomic_set(&cp->reset_task_pending, 0);
+ atomic_set(&cp->reset_task_pending_all, 0);
+ atomic_set(&cp->reset_task_pending_spare, 0);
+ atomic_set(&cp->reset_task_pending_mtu, 0);
+#endif
+ INIT_WORK(&cp->reset_task, cas_reset_task, cp);
+
+ /* Default link parameters */
+ if (link_mode >= 0 && link_mode <= 6)
+ cp->link_cntl = link_modes[link_mode];
+ else
+ cp->link_cntl = BMCR_ANENABLE;
+ cp->lstate = link_down;
+ cp->link_transition = LINK_TRANSITION_LINK_DOWN;
+ netif_carrier_off(cp->dev);
+ cp->timer_ticks = 0;
+
+ /* give us access to cassini registers */
+ cp->regs = ioremap(casreg_base, casreg_len);
+ if (cp->regs == 0UL) {
+ printk(KERN_ERR PFX "Cannot map device registers, "
+ "aborting.\n");
+ goto err_out_free_res;
+ }
+ cp->casreg_len = casreg_len;
+
+ pci_save_state(pdev);
+ cas_check_pci_invariants(cp);
+ cas_hard_reset(cp);
+ cas_reset(cp, 0);
+ if (cas_check_invariants(cp))
+ goto err_out_iounmap;
+
+ cp->init_block = (struct cas_init_block *)
+ pci_alloc_consistent(pdev, sizeof(struct cas_init_block),
+ &cp->block_dvma);
+ if (!cp->init_block) {
+ printk(KERN_ERR PFX "Cannot allocate init block, "
+ "aborting.\n");
+ goto err_out_iounmap;
+ }
+
+ for (i = 0; i < N_TX_RINGS; i++)
+ cp->init_txds[i] = cp->init_block->txds[i];
+
+ for (i = 0; i < N_RX_DESC_RINGS; i++)
+ cp->init_rxds[i] = cp->init_block->rxds[i];
+
+ for (i = 0; i < N_RX_COMP_RINGS; i++)
+ cp->init_rxcs[i] = cp->init_block->rxcs[i];
+
+ for (i = 0; i < N_RX_FLOWS; i++)
+ skb_queue_head_init(&cp->rx_flows[i]);
+
+ dev->open = cas_open;
+ dev->stop = cas_close;
+ dev->hard_start_xmit = cas_start_xmit;
+ dev->get_stats = cas_get_stats;
+ dev->set_multicast_list = cas_set_multicast;
+ dev->do_ioctl = cas_ioctl;
+ dev->ethtool_ops = &cas_ethtool_ops;
+ dev->tx_timeout = cas_tx_timeout;
+ dev->watchdog_timeo = CAS_TX_TIMEOUT;
+ dev->change_mtu = cas_change_mtu;
+#ifdef USE_NAPI
+ dev->poll = cas_poll;
+ dev->weight = 64;
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = cas_netpoll;
+#endif
+ dev->irq = pdev->irq;
+ dev->dma = 0;
+
+ /* Cassini features. */
+ if ((cp->cas_flags & CAS_FLAG_NO_HW_CSUM) == 0)
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+
+ if (pci_using_dac)
+ dev->features |= NETIF_F_HIGHDMA;
+
+ if (register_netdev(dev)) {
+ printk(KERN_ERR PFX "Cannot register net device, "
+ "aborting.\n");
+ goto err_out_free_consistent;
+ }
+
+ i = readl(cp->regs + REG_BIM_CFG);
+ printk(KERN_INFO "%s: Sun Cassini%s (%sbit/%sMHz PCI/%s) "
+ "Ethernet[%d] ", dev->name,
+ (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "",
+ (i & BIM_CFG_32BIT) ? "32" : "64",
+ (i & BIM_CFG_66MHZ) ? "66" : "33",
+ (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq);
+
+ for (i = 0; i < 6; i++)
+ printk("%2.2x%c", dev->dev_addr[i],
+ i == 5 ? ' ' : ':');
+ printk("\n");
+
+ pci_set_drvdata(pdev, dev);
+ cp->hw_running = 1;
+ cas_entropy_reset(cp);
+ cas_phy_init(cp);
+ cas_begin_auto_negotiation(cp, NULL);
+ return 0;
+
+err_out_free_consistent:
+ pci_free_consistent(pdev, sizeof(struct cas_init_block),
+ cp->init_block, cp->block_dvma);
+
+err_out_iounmap:
+ down(&cp->pm_sem);
+ if (cp->hw_running)
+ cas_shutdown(cp);
+ up(&cp->pm_sem);
+
+ iounmap(cp->regs);
+
+
+err_out_free_res:
+ pci_release_regions(pdev);
+
+err_write_cacheline:
+ /* Try to restore it in case the error occured after we
+ * set it.
+ */
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, orig_cacheline_size);
+
+err_out_free_netdev:
+ free_netdev(dev);
+
+err_out_disable_pdev:
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ return -ENODEV;
+}
+
+static void __devexit cas_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct cas *cp;
+ if (!dev)
+ return;
+
+ cp = netdev_priv(dev);
+ unregister_netdev(dev);
+
+ down(&cp->pm_sem);
+ flush_scheduled_work();
+ if (cp->hw_running)
+ cas_shutdown(cp);
+ up(&cp->pm_sem);
+
+#if 1
+ if (cp->orig_cacheline_size) {
+ /* Restore the cache line size if we had modified
+ * it.
+ */
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ cp->orig_cacheline_size);
+ }
+#endif
+ pci_free_consistent(pdev, sizeof(struct cas_init_block),
+ cp->init_block, cp->block_dvma);
+ iounmap(cp->regs);
+ free_netdev(dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int cas_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct cas *cp = netdev_priv(dev);
+ unsigned long flags;
+
+ /* We hold the PM semaphore during entire driver
+ * sleep time
+ */
+ down(&cp->pm_sem);
+
+ /* If the driver is opened, we stop the DMA */
+ if (cp->opened) {
+ netif_device_detach(dev);
+
+ cas_lock_all_save(cp, flags);
+
+ /* We can set the second arg of cas_reset to 0
+ * because on resume, we'll call cas_init_hw with
+ * its second arg set so that autonegotiation is
+ * restarted.
+ */
+ cas_reset(cp, 0);
+ cas_clean_rings(cp);
+ cas_unlock_all_restore(cp, flags);
+ }
+
+ if (cp->hw_running)
+ cas_shutdown(cp);
+
+ return 0;
+}
+
+static int cas_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct cas *cp = netdev_priv(dev);
+
+ printk(KERN_INFO "%s: resuming\n", dev->name);
+
+ cas_hard_reset(cp);
+ if (cp->opened) {
+ unsigned long flags;
+ cas_lock_all_save(cp, flags);
+ cas_reset(cp, 0);
+ cp->hw_running = 1;
+ cas_clean_rings(cp);
+ cas_init_hw(cp, 1);
+ cas_unlock_all_restore(cp, flags);
+
+ netif_device_attach(dev);
+ }
+ up(&cp->pm_sem);
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static struct pci_driver cas_driver = {
+ .name = DRV_MODULE_NAME,
+ .id_table = cas_pci_tbl,
+ .probe = cas_init_one,
+ .remove = __devexit_p(cas_remove_one),
+#ifdef CONFIG_PM
+ .suspend = cas_suspend,
+ .resume = cas_resume
+#endif
+};
+
+static int __init cas_init(void)
+{
+ if (linkdown_timeout > 0)
+ link_transition_timeout = linkdown_timeout * HZ;
+ else
+ link_transition_timeout = 0;
+
+ return pci_module_init(&cas_driver);
+}
+
+static void __exit cas_cleanup(void)
+{
+ pci_unregister_driver(&cas_driver);
+}
+
+module_init(cas_init);
+module_exit(cas_cleanup);
diff --git a/drivers/net/cassini.h b/drivers/net/cassini.h
new file mode 100644
index 000000000000..88063ef16cf6
--- /dev/null
+++ b/drivers/net/cassini.h
@@ -0,0 +1,4425 @@
+/* $Id: cassini.h,v 1.16 2004/08/17 21:15:16 zaumen Exp $
+ * cassini.h: Definitions for Sun Microsystems Cassini(+) ethernet driver.
+ *
+ * Copyright (C) 2004 Sun Microsystems Inc.
+ * Copyright (c) 2003 Adrian Sun (asun@darksunrising.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.
+ *
+ * vendor id: 0x108E (Sun Microsystems, Inc.)
+ * device id: 0xabba (Cassini)
+ * revision ids: 0x01 = Cassini
+ * 0x02 = Cassini rev 2
+ * 0x10 = Cassini+
+ * 0x11 = Cassini+ 0.2u
+ *
+ * vendor id: 0x100b (National Semiconductor)
+ * device id: 0x0035 (DP83065/Saturn)
+ * revision ids: 0x30 = Saturn B2
+ *
+ * rings are all offset from 0.
+ *
+ * there are two clock domains:
+ * PCI: 33/66MHz clock
+ * chip: 125MHz clock
+ */
+
+#ifndef _CASSINI_H
+#define _CASSINI_H
+
+/* cassini register map: 2M memory mapped in 32-bit memory space accessible as
+ * 32-bit words. there is no i/o port access. REG_ addresses are
+ * shared between cassini and cassini+. REG_PLUS_ addresses only
+ * appear in cassini+. REG_MINUS_ addresses only appear in cassini.
+ */
+#define CAS_ID_REV2 0x02
+#define CAS_ID_REVPLUS 0x10
+#define CAS_ID_REVPLUS02u 0x11
+#define CAS_ID_REVSATURNB2 0x30
+
+/** global resources **/
+
+/* this register sets the weights for the weighted round robin arbiter. e.g.,
+ * if rx weight == 1 and tx weight == 0, rx == 2x tx transfer credit
+ * for its next turn to access the pci bus.
+ * map: 0x0 = x1, 0x1 = x2, 0x2 = x4, 0x3 = x8
+ * DEFAULT: 0x0, SIZE: 5 bits
+ */
+#define REG_CAWR 0x0004 /* core arbitration weight */
+#define CAWR_RX_DMA_WEIGHT_SHIFT 0
+#define CAWR_RX_DMA_WEIGHT_MASK 0x03 /* [0:1] */
+#define CAWR_TX_DMA_WEIGHT_SHIFT 2
+#define CAWR_TX_DMA_WEIGHT_MASK 0x0C /* [3:2] */
+#define CAWR_RR_DIS 0x10 /* [4] */
+
+/* if enabled, BIM can send bursts across PCI bus > cacheline size. burst
+ * sizes determined by length of packet or descriptor transfer and the
+ * max length allowed by the target.
+ * DEFAULT: 0x0, SIZE: 1 bit
+ */
+#define REG_INF_BURST 0x0008 /* infinite burst enable reg */
+#define INF_BURST_EN 0x1 /* enable */
+
+/* top level interrupts [0-9] are auto-cleared to 0 when the status
+ * register is read. second level interrupts [13 - 18] are cleared at
+ * the source. tx completion register 3 is replicated in [19 - 31]
+ * DEFAULT: 0x00000000, SIZE: 29 bits
+ */
+#define REG_INTR_STATUS 0x000C /* interrupt status register */
+#define INTR_TX_INTME 0x00000001 /* frame w/ INT ME desc bit set
+ xferred from host queue to
+ TX FIFO */
+#define INTR_TX_ALL 0x00000002 /* all xmit frames xferred into
+ TX FIFO. i.e.,
+ TX Kick == TX complete. if
+ PACED_MODE set, then TX FIFO
+ also empty */
+#define INTR_TX_DONE 0x00000004 /* any frame xferred into tx
+ FIFO */
+#define INTR_TX_TAG_ERROR 0x00000008 /* TX FIFO tag framing
+ corrupted. FATAL ERROR */
+#define INTR_RX_DONE 0x00000010 /* at least 1 frame xferred
+ from RX FIFO to host mem.
+ RX completion reg updated.
+ may be delayed by recv
+ intr blanking. */
+#define INTR_RX_BUF_UNAVAIL 0x00000020 /* no more receive buffers.
+ RX Kick == RX complete */
+#define INTR_RX_TAG_ERROR 0x00000040 /* RX FIFO tag framing
+ corrupted. FATAL ERROR */
+#define INTR_RX_COMP_FULL 0x00000080 /* no more room in completion
+ ring to post descriptors.
+ RX complete head incr to
+ almost reach RX complete
+ tail */
+#define INTR_RX_BUF_AE 0x00000100 /* less than the
+ programmable threshold #
+ of free descr avail for
+ hw use */
+#define INTR_RX_COMP_AF 0x00000200 /* less than the
+ programmable threshold #
+ of descr spaces for hw
+ use in completion descr
+ ring */
+#define INTR_RX_LEN_MISMATCH 0x00000400 /* len field from MAC !=
+ len of non-reassembly pkt
+ from fifo during DMA or
+ header parser provides TCP
+ header and payload size >
+ MAC packet size.
+ FATAL ERROR */
+#define INTR_SUMMARY 0x00001000 /* summary interrupt bit. this
+ bit will be set if an interrupt
+ generated on the pci bus. useful
+ when driver is polling for
+ interrupts */
+#define INTR_PCS_STATUS 0x00002000 /* PCS interrupt status register */
+#define INTR_TX_MAC_STATUS 0x00004000 /* TX MAC status register has at
+ least 1 unmasked interrupt set */
+#define INTR_RX_MAC_STATUS 0x00008000 /* RX MAC status register has at
+ least 1 unmasked interrupt set */
+#define INTR_MAC_CTRL_STATUS 0x00010000 /* MAC control status register has
+ at least 1 unmasked interrupt
+ set */
+#define INTR_MIF_STATUS 0x00020000 /* MIF status register has at least
+ 1 unmasked interrupt set */
+#define INTR_PCI_ERROR_STATUS 0x00040000 /* PCI error status register in the
+ BIF has at least 1 unmasked
+ interrupt set */
+#define INTR_TX_COMP_3_MASK 0xFFF80000 /* mask for TX completion
+ 3 reg data */
+#define INTR_TX_COMP_3_SHIFT 19
+#define INTR_ERROR_MASK (INTR_MIF_STATUS | INTR_PCI_ERROR_STATUS | \
+ INTR_PCS_STATUS | INTR_RX_LEN_MISMATCH | \
+ INTR_TX_MAC_STATUS | INTR_RX_MAC_STATUS | \
+ INTR_TX_TAG_ERROR | INTR_RX_TAG_ERROR | \
+ INTR_MAC_CTRL_STATUS)
+
+/* determines which status events will cause an interrupt. layout same
+ * as REG_INTR_STATUS.
+ * DEFAULT: 0xFFFFFFFF, SIZE: 16 bits
+ */
+#define REG_INTR_MASK 0x0010 /* Interrupt mask */
+
+/* top level interrupt bits that are cleared during read of REG_INTR_STATUS_ALIAS.
+ * useful when driver is polling for interrupts. layout same as REG_INTR_MASK.
+ * DEFAULT: 0x00000000, SIZE: 12 bits
+ */
+#define REG_ALIAS_CLEAR 0x0014 /* alias clear mask
+ (used w/ status alias) */
+/* same as REG_INTR_STATUS except that only bits cleared are those selected by
+ * REG_ALIAS_CLEAR
+ * DEFAULT: 0x00000000, SIZE: 29 bits
+ */
+#define REG_INTR_STATUS_ALIAS 0x001C /* interrupt status alias
+ (selective clear) */
+
+/* DEFAULT: 0x0, SIZE: 3 bits */
+#define REG_PCI_ERR_STATUS 0x1000 /* PCI error status */
+#define PCI_ERR_BADACK 0x01 /* reserved in Cassini+.
+ set if no ACK64# during ABS64 cycle
+ in Cassini. */
+#define PCI_ERR_DTRTO 0x02 /* delayed xaction timeout. set if
+ no read retry after 2^15 clocks */
+#define PCI_ERR_OTHER 0x04 /* other PCI errors */
+#define PCI_ERR_BIM_DMA_WRITE 0x08 /* BIM received 0 count DMA write req.
+ unused in Cassini. */
+#define PCI_ERR_BIM_DMA_READ 0x10 /* BIM received 0 count DMA read req.
+ unused in Cassini. */
+#define PCI_ERR_BIM_DMA_TIMEOUT 0x20 /* BIM received 255 retries during
+ DMA. unused in cassini. */
+
+/* mask for PCI status events that will set PCI_ERR_STATUS. if cleared, event
+ * causes an interrupt to be generated.
+ * DEFAULT: 0x7, SIZE: 3 bits
+ */
+#define REG_PCI_ERR_STATUS_MASK 0x1004 /* PCI Error status mask */
+
+/* used to configure PCI related parameters that are not in PCI config space.
+ * DEFAULT: 0bxx000, SIZE: 5 bits
+ */
+#define REG_BIM_CFG 0x1008 /* BIM Configuration */
+#define BIM_CFG_RESERVED0 0x001 /* reserved */
+#define BIM_CFG_RESERVED1 0x002 /* reserved */
+#define BIM_CFG_64BIT_DISABLE 0x004 /* disable 64-bit mode */
+#define BIM_CFG_66MHZ 0x008 /* (ro) 1 = 66MHz, 0 = < 66MHz */
+#define BIM_CFG_32BIT 0x010 /* (ro) 1 = 32-bit slot, 0 = 64-bit */
+#define BIM_CFG_DPAR_INTR_ENABLE 0x020 /* detected parity err enable */
+#define BIM_CFG_RMA_INTR_ENABLE 0x040 /* master abort intr enable */
+#define BIM_CFG_RTA_INTR_ENABLE 0x080 /* target abort intr enable */
+#define BIM_CFG_RESERVED2 0x100 /* reserved */
+#define BIM_CFG_BIM_DISABLE 0x200 /* stop BIM DMA. use before global
+ reset. reserved in Cassini. */
+#define BIM_CFG_BIM_STATUS 0x400 /* (ro) 1 = BIM DMA suspended.
+ reserved in Cassini. */
+#define BIM_CFG_PERROR_BLOCK 0x800 /* block PERR# to pci bus. def: 0.
+ reserved in Cassini. */
+
+/* DEFAULT: 0x00000000, SIZE: 32 bits */
+#define REG_BIM_DIAG 0x100C /* BIM Diagnostic */
+#define BIM_DIAG_MSTR_SM_MASK 0x3FFFFF00 /* PCI master controller state
+ machine bits [21:0] */
+#define BIM_DIAG_BRST_SM_MASK 0x7F /* PCI burst controller state
+ machine bits [6:0] */
+
+/* writing to SW_RESET_TX and SW_RESET_RX will issue a global
+ * reset. poll until TX and RX read back as 0's for completion.
+ */
+#define REG_SW_RESET 0x1010 /* Software reset */
+#define SW_RESET_TX 0x00000001 /* reset TX DMA engine. poll until
+ cleared to 0. */
+#define SW_RESET_RX 0x00000002 /* reset RX DMA engine. poll until
+ cleared to 0. */
+#define SW_RESET_RSTOUT 0x00000004 /* force RSTOUT# pin active (low).
+ resets PHY and anything else
+ connected to RSTOUT#. RSTOUT#
+ is also activated by local PCI
+ reset when hot-swap is being
+ done. */
+#define SW_RESET_BLOCK_PCS_SLINK 0x00000008 /* if a global reset is done with
+ this bit set, PCS and SLINK
+ modules won't be reset.
+ i.e., link won't drop. */
+#define SW_RESET_BREQ_SM_MASK 0x00007F00 /* breq state machine [6:0] */
+#define SW_RESET_PCIARB_SM_MASK 0x00070000 /* pci arbitration state bits:
+ 0b000: ARB_IDLE1
+ 0b001: ARB_IDLE2
+ 0b010: ARB_WB_ACK
+ 0b011: ARB_WB_WAT
+ 0b100: ARB_RB_ACK
+ 0b101: ARB_RB_WAT
+ 0b110: ARB_RB_END
+ 0b111: ARB_WB_END */
+#define SW_RESET_RDPCI_SM_MASK 0x00300000 /* read pci state bits:
+ 0b00: RD_PCI_WAT
+ 0b01: RD_PCI_RDY
+ 0b11: RD_PCI_ACK */
+#define SW_RESET_RDARB_SM_MASK 0x00C00000 /* read arbitration state bits:
+ 0b00: AD_IDL_RX
+ 0b01: AD_ACK_RX
+ 0b10: AD_ACK_TX
+ 0b11: AD_IDL_TX */
+#define SW_RESET_WRPCI_SM_MASK 0x06000000 /* write pci state bits
+ 0b00: WR_PCI_WAT
+ 0b01: WR_PCI_RDY
+ 0b11: WR_PCI_ACK */
+#define SW_RESET_WRARB_SM_MASK 0x38000000 /* write arbitration state bits:
+ 0b000: ARB_IDLE1
+ 0b001: ARB_IDLE2
+ 0b010: ARB_TX_ACK
+ 0b011: ARB_TX_WAT
+ 0b100: ARB_RX_ACK
+ 0b110: ARB_RX_WAT */
+
+/* Cassini only. 64-bit register used to check PCI datapath. when read,
+ * value written has both lower and upper 32-bit halves rotated to the right
+ * one bit position. e.g., FFFFFFFF FFFFFFFF -> 7FFFFFFF 7FFFFFFF
+ */
+#define REG_MINUS_BIM_DATAPATH_TEST 0x1018 /* Cassini: BIM datapath test
+ Cassini+: reserved */
+
+/* output enables are provided for each device's chip select and for the rest
+ * of the outputs from cassini to its local bus devices. two sw programmable
+ * bits are connected to general purpus control/status bits.
+ * DEFAULT: 0x7
+ */
+#define REG_BIM_LOCAL_DEV_EN 0x1020 /* BIM local device
+ output EN. default: 0x7 */
+#define BIM_LOCAL_DEV_PAD 0x01 /* address bus, RW signal, and
+ OE signal output enable on the
+ local bus interface. these
+ are shared between both local
+ bus devices. tristate when 0. */
+#define BIM_LOCAL_DEV_PROM 0x02 /* PROM chip select */
+#define BIM_LOCAL_DEV_EXT 0x04 /* secondary local bus device chip
+ select output enable */
+#define BIM_LOCAL_DEV_SOFT_0 0x08 /* sw programmable ctrl bit 0 */
+#define BIM_LOCAL_DEV_SOFT_1 0x10 /* sw programmable ctrl bit 1 */
+#define BIM_LOCAL_DEV_HW_RESET 0x20 /* internal hw reset. Cassini+ only. */
+
+/* access 24 entry BIM read and write buffers. put address in REG_BIM_BUFFER_ADDR
+ * and read/write from/to it REG_BIM_BUFFER_DATA_LOW and _DATA_HI.
+ * _DATA_HI should be the last access of the sequence.
+ * DEFAULT: undefined
+ */
+#define REG_BIM_BUFFER_ADDR 0x1024 /* BIM buffer address. for
+ purposes. */
+#define BIM_BUFFER_ADDR_MASK 0x3F /* index (0 - 23) of buffer */
+#define BIM_BUFFER_WR_SELECT 0x40 /* write buffer access = 1
+ read buffer access = 0 */
+/* DEFAULT: undefined */
+#define REG_BIM_BUFFER_DATA_LOW 0x1028 /* BIM buffer data low */
+#define REG_BIM_BUFFER_DATA_HI 0x102C /* BIM buffer data high */
+
+/* set BIM_RAM_BIST_START to start built-in self test for BIM read buffer.
+ * bit auto-clears when done with status read from _SUMMARY and _PASS bits.
+ */
+#define REG_BIM_RAM_BIST 0x102C /* BIM RAM (read buffer) BIST
+ control/status */
+#define BIM_RAM_BIST_RD_START 0x01 /* start BIST for BIM read buffer */
+#define BIM_RAM_BIST_WR_START 0x02 /* start BIST for BIM write buffer.
+ Cassini only. reserved in
+ Cassini+. */
+#define BIM_RAM_BIST_RD_PASS 0x04 /* summary BIST pass status for read
+ buffer. */
+#define BIM_RAM_BIST_WR_PASS 0x08 /* summary BIST pass status for write
+ buffer. Cassini only. reserved
+ in Cassini+. */
+#define BIM_RAM_BIST_RD_LOW_PASS 0x10 /* read low bank passes BIST */
+#define BIM_RAM_BIST_RD_HI_PASS 0x20 /* read high bank passes BIST */
+#define BIM_RAM_BIST_WR_LOW_PASS 0x40 /* write low bank passes BIST.
+ Cassini only. reserved in
+ Cassini+. */
+#define BIM_RAM_BIST_WR_HI_PASS 0x80 /* write high bank passes BIST.
+ Cassini only. reserved in
+ Cassini+. */
+
+/* ASUN: i'm not sure what this does as it's not in the spec.
+ * DEFAULT: 0xFC
+ */
+#define REG_BIM_DIAG_MUX 0x1030 /* BIM diagnostic probe mux
+ select register */
+
+/* enable probe monitoring mode and select data appearing on the P_A* bus. bit
+ * values for _SEL_HI_MASK and _SEL_LOW_MASK:
+ * 0x0: internal probe[7:0] (pci arb state, wtc empty w, wtc full w, wtc empty w,
+ * wtc empty r, post pci)
+ * 0x1: internal probe[15:8] (pci wbuf comp, pci wpkt comp, pci rbuf comp,
+ * pci rpkt comp, txdma wr req, txdma wr ack,
+ * txdma wr rdy, txdma wr xfr done)
+ * 0x2: internal probe[23:16] (txdma rd req, txdma rd ack, txdma rd rdy, rxdma rd,
+ * rd arb state, rd pci state)
+ * 0x3: internal probe[31:24] (rxdma req, rxdma ack, rxdma rdy, wrarb state,
+ * wrpci state)
+ * 0x4: pci io probe[7:0] 0x5: pci io probe[15:8]
+ * 0x6: pci io probe[23:16] 0x7: pci io probe[31:24]
+ * 0x8: pci io probe[39:32] 0x9: pci io probe[47:40]
+ * 0xa: pci io probe[55:48] 0xb: pci io probe[63:56]
+ * the following are not available in Cassini:
+ * 0xc: rx probe[7:0] 0xd: tx probe[7:0]
+ * 0xe: hp probe[7:0] 0xf: mac probe[7:0]
+ */
+#define REG_PLUS_PROBE_MUX_SELECT 0x1034 /* Cassini+: PROBE MUX SELECT */
+#define PROBE_MUX_EN 0x80000000 /* allow probe signals to be
+ driven on local bus P_A[15:0]
+ for debugging */
+#define PROBE_MUX_SUB_MUX_MASK 0x0000FF00 /* select sub module probe signals:
+ 0x03 = mac[1:0]
+ 0x0C = rx[1:0]
+ 0x30 = tx[1:0]
+ 0xC0 = hp[1:0] */
+#define PROBE_MUX_SEL_HI_MASK 0x000000F0 /* select which module to appear
+ on P_A[15:8]. see above for
+ values. */
+#define PROBE_MUX_SEL_LOW_MASK 0x0000000F /* select which module to appear
+ on P_A[7:0]. see above for
+ values. */
+
+/* values mean the same thing as REG_INTR_MASK excep that it's for INTB.
+ DEFAULT: 0x1F */
+#define REG_PLUS_INTR_MASK_1 0x1038 /* Cassini+: interrupt mask
+ register 2 for INTB */
+#define REG_PLUS_INTRN_MASK(x) (REG_PLUS_INTR_MASK_1 + ((x) - 1)*16)
+/* bits correspond to both _MASK and _STATUS registers. _ALT corresponds to
+ * all of the alternate (2-4) INTR registers while _1 corresponds to only
+ * _MASK_1 and _STATUS_1 registers.
+ * DEFAULT: 0x7 for MASK registers, 0x0 for ALIAS_CLEAR registers
+ */
+#define INTR_RX_DONE_ALT 0x01
+#define INTR_RX_COMP_FULL_ALT 0x02
+#define INTR_RX_COMP_AF_ALT 0x04
+#define INTR_RX_BUF_UNAVAIL_1 0x08
+#define INTR_RX_BUF_AE_1 0x10 /* almost empty */
+#define INTRN_MASK_RX_EN 0x80
+#define INTRN_MASK_CLEAR_ALL (INTR_RX_DONE_ALT | \
+ INTR_RX_COMP_FULL_ALT | \
+ INTR_RX_COMP_AF_ALT | \
+ INTR_RX_BUF_UNAVAIL_1 | \
+ INTR_RX_BUF_AE_1)
+#define REG_PLUS_INTR_STATUS_1 0x103C /* Cassini+: interrupt status
+ register 2 for INTB. default: 0x1F */
+#define REG_PLUS_INTRN_STATUS(x) (REG_PLUS_INTR_STATUS_1 + ((x) - 1)*16)
+#define INTR_STATUS_ALT_INTX_EN 0x80 /* generate INTX when one of the
+ flags are set. enables desc ring. */
+
+#define REG_PLUS_ALIAS_CLEAR_1 0x1040 /* Cassini+: alias clear mask
+ register 2 for INTB */
+#define REG_PLUS_ALIASN_CLEAR(x) (REG_PLUS_ALIAS_CLEAR_1 + ((x) - 1)*16)
+
+#define REG_PLUS_INTR_STATUS_ALIAS_1 0x1044 /* Cassini+: interrupt status
+ register alias 2 for INTB */
+#define REG_PLUS_INTRN_STATUS_ALIAS(x) (REG_PLUS_INTR_STATUS_ALIAS_1 + ((x) - 1)*16)
+
+#define REG_SATURN_PCFG 0x106c /* pin configuration register for
+ integrated macphy */
+
+#define SATURN_PCFG_TLA 0x00000001 /* 1 = phy actled */
+#define SATURN_PCFG_FLA 0x00000002 /* 1 = phy link10led */
+#define SATURN_PCFG_CLA 0x00000004 /* 1 = phy link100led */
+#define SATURN_PCFG_LLA 0x00000008 /* 1 = phy link1000led */
+#define SATURN_PCFG_RLA 0x00000010 /* 1 = phy duplexled */
+#define SATURN_PCFG_PDS 0x00000020 /* phy debug mode.
+ 0 = normal */
+#define SATURN_PCFG_MTP 0x00000080 /* test point select */
+#define SATURN_PCFG_GMO 0x00000100 /* GMII observe. 1 =
+ GMII on SERDES pins for
+ monitoring. */
+#define SATURN_PCFG_FSI 0x00000200 /* 1 = freeze serdes/gmii. all
+ pins configed as outputs.
+ for power saving when using
+ internal phy. */
+#define SATURN_PCFG_LAD 0x00000800 /* 0 = mac core led ctrl
+ polarity from strapping
+ value.
+ 1 = mac core led ctrl
+ polarity active low. */
+
+
+/** transmit dma registers **/
+#define MAX_TX_RINGS_SHIFT 2
+#define MAX_TX_RINGS (1 << MAX_TX_RINGS_SHIFT)
+#define MAX_TX_RINGS_MASK (MAX_TX_RINGS - 1)
+
+/* TX configuration.
+ * descr ring sizes size = 32 * (1 << n), n < 9. e.g., 0x8 = 8k. default: 0x8
+ * DEFAULT: 0x3F000001
+ */
+#define REG_TX_CFG 0x2004 /* TX config */
+#define TX_CFG_DMA_EN 0x00000001 /* enable TX DMA. if cleared, DMA
+ will stop after xfer of current
+ buffer has been completed. */
+#define TX_CFG_FIFO_PIO_SEL 0x00000002 /* TX DMA FIFO can be
+ accessed w/ FIFO addr
+ and data registers.
+ TX DMA should be
+ disabled. */
+#define TX_CFG_DESC_RING0_MASK 0x0000003C /* # desc entries in
+ ring 1. */
+#define TX_CFG_DESC_RING0_SHIFT 2
+#define TX_CFG_DESC_RINGN_MASK(a) (TX_CFG_DESC_RING0_MASK << (a)*4)
+#define TX_CFG_DESC_RINGN_SHIFT(a) (TX_CFG_DESC_RING0_SHIFT + (a)*4)
+#define TX_CFG_PACED_MODE 0x00100000 /* TX_ALL only set after
+ TX FIFO becomes empty.
+ if 0, TX_ALL set
+ if descr queue empty. */
+#define TX_CFG_DMA_RDPIPE_DIS 0x01000000 /* always set to 1 */
+#define TX_CFG_COMPWB_Q1 0x02000000 /* completion writeback happens at
+ the end of every packet kicked
+ through Q1. */
+#define TX_CFG_COMPWB_Q2 0x04000000 /* completion writeback happens at
+ the end of every packet kicked
+ through Q2. */
+#define TX_CFG_COMPWB_Q3 0x08000000 /* completion writeback happens at
+ the end of every packet kicked
+ through Q3 */
+#define TX_CFG_COMPWB_Q4 0x10000000 /* completion writeback happens at
+ the end of every packet kicked
+ through Q4 */
+#define TX_CFG_INTR_COMPWB_DIS 0x20000000 /* disable pre-interrupt completion
+ writeback */
+#define TX_CFG_CTX_SEL_MASK 0xC0000000 /* selects tx test port
+ connection
+ 0b00: tx mac req,
+ tx mac retry req,
+ tx ack and tx tag.
+ 0b01: txdma rd req,
+ txdma rd ack,
+ txdma rd rdy,
+ txdma rd type0
+ 0b11: txdma wr req,
+ txdma wr ack,
+ txdma wr rdy,
+ txdma wr xfr done. */
+#define TX_CFG_CTX_SEL_SHIFT 30
+
+/* 11-bit counters that point to next location in FIFO to be loaded/retrieved.
+ * used for diagnostics only.
+ */
+#define REG_TX_FIFO_WRITE_PTR 0x2014 /* TX FIFO write pointer */
+#define REG_TX_FIFO_SHADOW_WRITE_PTR 0x2018 /* TX FIFO shadow write
+ pointer. temp hold reg.
+ diagnostics only. */
+#define REG_TX_FIFO_READ_PTR 0x201C /* TX FIFO read pointer */
+#define REG_TX_FIFO_SHADOW_READ_PTR 0x2020 /* TX FIFO shadow read
+ pointer */
+
+/* (ro) 11-bit up/down counter w/ # of frames currently in TX FIFO */
+#define REG_TX_FIFO_PKT_CNT 0x2024 /* TX FIFO packet counter */
+
+/* current state of all state machines in TX */
+#define REG_TX_SM_1 0x2028 /* TX state machine reg #1 */
+#define TX_SM_1_CHAIN_MASK 0x000003FF /* chaining state machine */
+#define TX_SM_1_CSUM_MASK 0x00000C00 /* checksum state machine */
+#define TX_SM_1_FIFO_LOAD_MASK 0x0003F000 /* FIFO load state machine.
+ = 0x01 when TX disabled. */
+#define TX_SM_1_FIFO_UNLOAD_MASK 0x003C0000 /* FIFO unload state machine */
+#define TX_SM_1_CACHE_MASK 0x03C00000 /* desc. prefetch cache controller
+ state machine */
+#define TX_SM_1_CBQ_ARB_MASK 0xF8000000 /* CBQ arbiter state machine */
+
+#define REG_TX_SM_2 0x202C /* TX state machine reg #2 */
+#define TX_SM_2_COMP_WB_MASK 0x07 /* completion writeback sm */
+#define TX_SM_2_SUB_LOAD_MASK 0x38 /* sub load state machine */
+#define TX_SM_2_KICK_MASK 0xC0 /* kick state machine */
+
+/* 64-bit pointer to the transmit data buffer. only the 50 LSB are incremented
+ * while the upper 23 bits are taken from the TX descriptor
+ */
+#define REG_TX_DATA_PTR_LOW 0x2030 /* TX data pointer low */
+#define REG_TX_DATA_PTR_HI 0x2034 /* TX data pointer high */
+
+/* 13 bit registers written by driver w/ descriptor value that follows
+ * last valid xmit descriptor. kick # and complete # values are used by
+ * the xmit dma engine to control tx descr fetching. if > 1 valid
+ * tx descr is available within the cache line being read, cassini will
+ * internally cache up to 4 of them. 0 on reset. _KICK = rw, _COMP = ro.
+ */
+#define REG_TX_KICK0 0x2038 /* TX kick reg #1 */
+#define REG_TX_KICKN(x) (REG_TX_KICK0 + (x)*4)
+#define REG_TX_COMP0 0x2048 /* TX completion reg #1 */
+#define REG_TX_COMPN(x) (REG_TX_COMP0 + (x)*4)
+
+/* values of TX_COMPLETE_1-4 are written. each completion register
+ * is 2bytes in size and contiguous. 8B allocation w/ 8B alignment.
+ * NOTE: completion reg values are only written back prior to TX_INTME and
+ * TX_ALL interrupts. at all other times, the most up-to-date index values
+ * should be obtained from the REG_TX_COMPLETE_# registers.
+ * here's the layout:
+ * offset from base addr completion # byte
+ * 0 TX_COMPLETE_1_MSB
+ * 1 TX_COMPLETE_1_LSB
+ * 2 TX_COMPLETE_2_MSB
+ * 3 TX_COMPLETE_2_LSB
+ * 4 TX_COMPLETE_3_MSB
+ * 5 TX_COMPLETE_3_LSB
+ * 6 TX_COMPLETE_4_MSB
+ * 7 TX_COMPLETE_4_LSB
+ */
+#define TX_COMPWB_SIZE 8
+#define REG_TX_COMPWB_DB_LOW 0x2058 /* TX completion write back
+ base low */
+#define REG_TX_COMPWB_DB_HI 0x205C /* TX completion write back
+ base high */
+#define TX_COMPWB_MSB_MASK 0x00000000000000FFULL
+#define TX_COMPWB_MSB_SHIFT 0
+#define TX_COMPWB_LSB_MASK 0x000000000000FF00ULL
+#define TX_COMPWB_LSB_SHIFT 8
+#define TX_COMPWB_NEXT(x) ((x) >> 16)
+
+/* 53 MSB used as base address. 11 LSB assumed to be 0. TX desc pointer must
+ * be 2KB-aligned. */
+#define REG_TX_DB0_LOW 0x2060 /* TX descriptor base low #1 */
+#define REG_TX_DB0_HI 0x2064 /* TX descriptor base hi #1 */
+#define REG_TX_DBN_LOW(x) (REG_TX_DB0_LOW + (x)*8)
+#define REG_TX_DBN_HI(x) (REG_TX_DB0_HI + (x)*8)
+
+/* 16-bit registers hold weights for the weighted round-robin of the
+ * four CBQ TX descr rings. weights correspond to # bytes xferred from
+ * host to TXFIFO in a round of WRR arbitration. can be set
+ * dynamically with new weights set upon completion of the current
+ * packet transfer from host memory to TXFIFO. a dummy write to any of
+ * these registers causes a queue1 pre-emption with all historical bw
+ * deficit data reset to 0 (useful when congestion requires a
+ * pre-emption/re-allocation of network bandwidth
+ */
+#define REG_TX_MAXBURST_0 0x2080 /* TX MaxBurst #1 */
+#define REG_TX_MAXBURST_1 0x2084 /* TX MaxBurst #2 */
+#define REG_TX_MAXBURST_2 0x2088 /* TX MaxBurst #3 */
+#define REG_TX_MAXBURST_3 0x208C /* TX MaxBurst #4 */
+
+/* diagnostics access to any TX FIFO location. every access is 65
+ * bits. _DATA_LOW = 32 LSB, _DATA_HI_T1/T0 = 32 MSB. _TAG = tag bit.
+ * writing _DATA_HI_T0 sets tag bit low, writing _DATA_HI_T1 sets tag
+ * bit high. TX_FIFO_PIO_SEL must be set for TX FIFO PIO access. if
+ * TX FIFO data integrity is desired, TX DMA should be
+ * disabled. _DATA_HI_Tx should be the last access of the sequence.
+ */
+#define REG_TX_FIFO_ADDR 0x2104 /* TX FIFO address */
+#define REG_TX_FIFO_TAG 0x2108 /* TX FIFO tag */
+#define REG_TX_FIFO_DATA_LOW 0x210C /* TX FIFO data low */
+#define REG_TX_FIFO_DATA_HI_T1 0x2110 /* TX FIFO data high t1 */
+#define REG_TX_FIFO_DATA_HI_T0 0x2114 /* TX FIFO data high t0 */
+#define REG_TX_FIFO_SIZE 0x2118 /* (ro) TX FIFO size = 0x090 = 9KB */
+
+/* 9-bit register controls BIST of TX FIFO. bit set indicates that the BIST
+ * passed for the specified memory
+ */
+#define REG_TX_RAMBIST 0x211C /* TX RAMBIST control/status */
+#define TX_RAMBIST_STATE 0x01C0 /* progress state of RAMBIST
+ controller state machine */
+#define TX_RAMBIST_RAM33A_PASS 0x0020 /* RAM33A passed */
+#define TX_RAMBIST_RAM32A_PASS 0x0010 /* RAM32A passed */
+#define TX_RAMBIST_RAM33B_PASS 0x0008 /* RAM33B passed */
+#define TX_RAMBIST_RAM32B_PASS 0x0004 /* RAM32B passed */
+#define TX_RAMBIST_SUMMARY 0x0002 /* all RAM passed */
+#define TX_RAMBIST_START 0x0001 /* write 1 to start BIST. self
+ clears on completion. */
+
+/** receive dma registers **/
+#define MAX_RX_DESC_RINGS 2
+#define MAX_RX_COMP_RINGS 4
+
+/* receive DMA channel configuration. default: 0x80910
+ * free ring size = (1 << n)*32 -> [32 - 8k]
+ * completion ring size = (1 << n)*128 -> [128 - 32k], n < 9
+ * DEFAULT: 0x80910
+ */
+#define REG_RX_CFG 0x4000 /* RX config */
+#define RX_CFG_DMA_EN 0x00000001 /* enable RX DMA. 0 stops
+ channel as soon as current
+ frame xfer has completed.
+ driver should disable MAC
+ for 200ms before disabling
+ RX */
+#define RX_CFG_DESC_RING_MASK 0x0000001E /* # desc entries in RX
+ free desc ring.
+ def: 0x8 = 8k */
+#define RX_CFG_DESC_RING_SHIFT 1
+#define RX_CFG_COMP_RING_MASK 0x000001E0 /* # desc entries in RX complete
+ ring. def: 0x8 = 32k */
+#define RX_CFG_COMP_RING_SHIFT 5
+#define RX_CFG_BATCH_DIS 0x00000200 /* disable receive desc
+ batching. def: 0x0 =
+ enabled */
+#define RX_CFG_SWIVEL_MASK 0x00001C00 /* byte offset of the 1st
+ data byte of the packet
+ w/in 8 byte boundares.
+ this swivels the data
+ DMA'ed to header
+ buffers, jumbo buffers
+ when header split is not
+ requested and MTU sized
+ buffers. def: 0x2 */
+#define RX_CFG_SWIVEL_SHIFT 10
+
+/* cassini+ only */
+#define RX_CFG_DESC_RING1_MASK 0x000F0000 /* # of desc entries in
+ RX free desc ring 2.
+ def: 0x8 = 8k */
+#define RX_CFG_DESC_RING1_SHIFT 16
+
+
+/* the page size register allows cassini chips to do the following with
+ * received data:
+ * [--------------------------------------------------------------] page
+ * [off][buf1][pad][off][buf2][pad][off][buf3][pad][off][buf4][pad]
+ * |--------------| = PAGE_SIZE_BUFFER_STRIDE
+ * page = PAGE_SIZE
+ * offset = PAGE_SIZE_MTU_OFF
+ * for the above example, MTU_BUFFER_COUNT = 4.
+ * NOTE: as is apparent, you need to ensure that the following holds:
+ * MTU_BUFFER_COUNT <= PAGE_SIZE/PAGE_SIZE_BUFFER_STRIDE
+ * DEFAULT: 0x48002002 (8k pages)
+ */
+#define REG_RX_PAGE_SIZE 0x4004 /* RX page size */
+#define RX_PAGE_SIZE_MASK 0x00000003 /* size of pages pointed to
+ by receive descriptors.
+ if jumbo buffers are
+ supported the page size
+ should not be < 8k.
+ 0b00 = 2k, 0b01 = 4k
+ 0b10 = 8k, 0b11 = 16k
+ DEFAULT: 8k */
+#define RX_PAGE_SIZE_SHIFT 0
+#define RX_PAGE_SIZE_MTU_COUNT_MASK 0x00007800 /* # of MTU buffers the hw
+ packs into a page.
+ DEFAULT: 4 */
+#define RX_PAGE_SIZE_MTU_COUNT_SHIFT 11
+#define RX_PAGE_SIZE_MTU_STRIDE_MASK 0x18000000 /* # of bytes that separate
+ each MTU buffer +
+ offset from each
+ other.
+ 0b00 = 1k, 0b01 = 2k
+ 0b10 = 4k, 0b11 = 8k
+ DEFAULT: 0x1 */
+#define RX_PAGE_SIZE_MTU_STRIDE_SHIFT 27
+#define RX_PAGE_SIZE_MTU_OFF_MASK 0xC0000000 /* offset in each page that
+ hw writes the MTU buffer
+ into.
+ 0b00 = 0,
+ 0b01 = 64 bytes
+ 0b10 = 96, 0b11 = 128
+ DEFAULT: 0x1 */
+#define RX_PAGE_SIZE_MTU_OFF_SHIFT 30
+
+/* 11-bit counter points to next location in RX FIFO to be loaded/read.
+ * shadow write pointers enable retries in case of early receive aborts.
+ * DEFAULT: 0x0. generated on 64-bit boundaries.
+ */
+#define REG_RX_FIFO_WRITE_PTR 0x4008 /* RX FIFO write pointer */
+#define REG_RX_FIFO_READ_PTR 0x400C /* RX FIFO read pointer */
+#define REG_RX_IPP_FIFO_SHADOW_WRITE_PTR 0x4010 /* RX IPP FIFO shadow write
+ pointer */
+#define REG_RX_IPP_FIFO_SHADOW_READ_PTR 0x4014 /* RX IPP FIFO shadow read
+ pointer */
+#define REG_RX_IPP_FIFO_READ_PTR 0x400C /* RX IPP FIFO read
+ pointer. (8-bit counter) */
+
+/* current state of RX DMA state engines + other info
+ * DEFAULT: 0x0
+ */
+#define REG_RX_DEBUG 0x401C /* RX debug */
+#define RX_DEBUG_LOAD_STATE_MASK 0x0000000F /* load state machine w/ MAC:
+ 0x0 = idle, 0x1 = load_bop
+ 0x2 = load 1, 0x3 = load 2
+ 0x4 = load 3, 0x5 = load 4
+ 0x6 = last detect
+ 0x7 = wait req
+ 0x8 = wait req statuss 1st
+ 0x9 = load st
+ 0xa = bubble mac
+ 0xb = error */
+#define RX_DEBUG_LM_STATE_MASK 0x00000070 /* load state machine w/ HP and
+ RX FIFO:
+ 0x0 = idle, 0x1 = hp xfr
+ 0x2 = wait hp ready
+ 0x3 = wait flow code
+ 0x4 = fifo xfer
+ 0x5 = make status
+ 0x6 = csum ready
+ 0x7 = error */
+#define RX_DEBUG_FC_STATE_MASK 0x000000180 /* flow control state machine
+ w/ MAC:
+ 0x0 = idle
+ 0x1 = wait xoff ack
+ 0x2 = wait xon
+ 0x3 = wait xon ack */
+#define RX_DEBUG_DATA_STATE_MASK 0x000001E00 /* unload data state machine
+ states:
+ 0x0 = idle data
+ 0x1 = header begin
+ 0x2 = xfer header
+ 0x3 = xfer header ld
+ 0x4 = mtu begin
+ 0x5 = xfer mtu
+ 0x6 = xfer mtu ld
+ 0x7 = jumbo begin
+ 0x8 = xfer jumbo
+ 0x9 = xfer jumbo ld
+ 0xa = reas begin
+ 0xb = xfer reas
+ 0xc = flush tag
+ 0xd = xfer reas ld
+ 0xe = error
+ 0xf = bubble idle */
+#define RX_DEBUG_DESC_STATE_MASK 0x0001E000 /* unload desc state machine
+ states:
+ 0x0 = idle desc
+ 0x1 = wait ack
+ 0x9 = wait ack 2
+ 0x2 = fetch desc 1
+ 0xa = fetch desc 2
+ 0x3 = load ptrs
+ 0x4 = wait dma
+ 0x5 = wait ack batch
+ 0x6 = post batch
+ 0x7 = xfr done */
+#define RX_DEBUG_INTR_READ_PTR_MASK 0x30000000 /* interrupt read ptr of the
+ interrupt queue */
+#define RX_DEBUG_INTR_WRITE_PTR_MASK 0xC0000000 /* interrupt write pointer
+ of the interrupt queue */
+
+/* flow control frames are emmitted using two PAUSE thresholds:
+ * XOFF PAUSE uses pause time value pre-programmed in the Send PAUSE MAC reg
+ * XON PAUSE uses a pause time of 0. granularity of threshold is 64bytes.
+ * PAUSE thresholds defined in terms of FIFO occupancy and may be translated
+ * into FIFO vacancy using RX_FIFO_SIZE. setting ON will trigger XON frames
+ * when FIFO reaches 0. OFF threshold should not be > size of RX FIFO. max
+ * value is is 0x6F.
+ * DEFAULT: 0x00078
+ */
+#define REG_RX_PAUSE_THRESH 0x4020 /* RX pause thresholds */
+#define RX_PAUSE_THRESH_QUANTUM 64
+#define RX_PAUSE_THRESH_OFF_MASK 0x000001FF /* XOFF PAUSE emitted when
+ RX FIFO occupancy >
+ value*64B */
+#define RX_PAUSE_THRESH_OFF_SHIFT 0
+#define RX_PAUSE_THRESH_ON_MASK 0x001FF000 /* XON PAUSE emitted after
+ emitting XOFF PAUSE when RX
+ FIFO occupancy falls below
+ this value*64B. must be
+ < XOFF threshold. if =
+ RX_FIFO_SIZE< XON frames are
+ never emitted. */
+#define RX_PAUSE_THRESH_ON_SHIFT 12
+
+/* 13-bit register used to control RX desc fetching and intr generation. if 4+
+ * valid RX descriptors are available, Cassini will read 4 at a time.
+ * writing N means that all desc up to *but* excluding N are available. N must
+ * be a multiple of 4 (N % 4 = 0). first desc should be cache-line aligned.
+ * DEFAULT: 0 on reset
+ */
+#define REG_RX_KICK 0x4024 /* RX kick reg */
+
+/* 8KB aligned 64-bit pointer to the base of the RX free/completion rings.
+ * lower 13 bits of the low register are hard-wired to 0.
+ */
+#define REG_RX_DB_LOW 0x4028 /* RX descriptor ring
+ base low */
+#define REG_RX_DB_HI 0x402C /* RX descriptor ring
+ base hi */
+#define REG_RX_CB_LOW 0x4030 /* RX completion ring
+ base low */
+#define REG_RX_CB_HI 0x4034 /* RX completion ring
+ base hi */
+/* 13-bit register indicate desc used by cassini for receive frames. used
+ * for diagnostic purposes.
+ * DEFAULT: 0 on reset
+ */
+#define REG_RX_COMP 0x4038 /* (ro) RX completion */
+
+/* HEAD and TAIL are used to control RX desc posting and interrupt
+ * generation. hw moves the head register to pass ownership to sw. sw
+ * moves the tail register to pass ownership back to hw. to give all
+ * entries to hw, set TAIL = HEAD. if HEAD and TAIL indicate that no
+ * more entries are available, DMA will pause and an interrupt will be
+ * generated to indicate no more entries are available. sw can use
+ * this interrupt to reduce the # of times it must update the
+ * completion tail register.
+ * DEFAULT: 0 on reset
+ */
+#define REG_RX_COMP_HEAD 0x403C /* RX completion head */
+#define REG_RX_COMP_TAIL 0x4040 /* RX completion tail */
+
+/* values used for receive interrupt blanking. loaded each time the ISR is read
+ * DEFAULT: 0x00000000
+ */
+#define REG_RX_BLANK 0x4044 /* RX blanking register
+ for ISR read */
+#define RX_BLANK_INTR_PKT_MASK 0x000001FF /* RX_DONE intr asserted if
+ this many sets of completion
+ writebacks (up to 2 packets)
+ occur since the last time
+ the ISR was read. 0 = no
+ packet blanking */
+#define RX_BLANK_INTR_PKT_SHIFT 0
+#define RX_BLANK_INTR_TIME_MASK 0x3FFFF000 /* RX_DONE interrupt asserted
+ if that many clocks were
+ counted since last time the
+ ISR was read.
+ each count is 512 core
+ clocks (125MHz). 0 = no
+ time blanking */
+#define RX_BLANK_INTR_TIME_SHIFT 12
+
+/* values used for interrupt generation based on threshold values of how
+ * many free desc and completion entries are available for hw use.
+ * DEFAULT: 0x00000000
+ */
+#define REG_RX_AE_THRESH 0x4048 /* RX almost empty
+ thresholds */
+#define RX_AE_THRESH_FREE_MASK 0x00001FFF /* RX_BUF_AE will be
+ generated if # desc
+ avail for hw use <=
+ # */
+#define RX_AE_THRESH_FREE_SHIFT 0
+#define RX_AE_THRESH_COMP_MASK 0x0FFFE000 /* RX_COMP_AE will be
+ generated if # of
+ completion entries
+ avail for hw use <=
+ # */
+#define RX_AE_THRESH_COMP_SHIFT 13
+
+/* probabilities for random early drop (RED) thresholds on a FIFO threshold
+ * basis. probability should increase when the FIFO level increases. control
+ * packets are never dropped and not counted in stats. probability programmed
+ * on a 12.5% granularity. e.g., 0x1 = 1/8 packets dropped.
+ * DEFAULT: 0x00000000
+ */
+#define REG_RX_RED 0x404C /* RX random early detect enable */
+#define RX_RED_4K_6K_FIFO_MASK 0x000000FF /* 4KB < FIFO thresh < 6KB */
+#define RX_RED_6K_8K_FIFO_MASK 0x0000FF00 /* 6KB < FIFO thresh < 8KB */
+#define RX_RED_8K_10K_FIFO_MASK 0x00FF0000 /* 8KB < FIFO thresh < 10KB */
+#define RX_RED_10K_12K_FIFO_MASK 0xFF000000 /* 10KB < FIFO thresh < 12KB */
+
+/* FIFO fullness levels for RX FIFO, RX control FIFO, and RX IPP FIFO.
+ * RX control FIFO = # of packets in RX FIFO.
+ * DEFAULT: 0x0
+ */
+#define REG_RX_FIFO_FULLNESS 0x4050 /* (ro) RX FIFO fullness */
+#define RX_FIFO_FULLNESS_RX_FIFO_MASK 0x3FF80000 /* level w/ 8B granularity */
+#define RX_FIFO_FULLNESS_IPP_FIFO_MASK 0x0007FF00 /* level w/ 8B granularity */
+#define RX_FIFO_FULLNESS_RX_PKT_MASK 0x000000FF /* # packets in RX FIFO */
+#define REG_RX_IPP_PACKET_COUNT 0x4054 /* RX IPP packet counter */
+#define REG_RX_WORK_DMA_PTR_LOW 0x4058 /* RX working DMA ptr low */
+#define REG_RX_WORK_DMA_PTR_HI 0x405C /* RX working DMA ptr
+ high */
+
+/* BIST testing ro RX FIFO, RX control FIFO, and RX IPP FIFO. only RX BIST
+ * START/COMPLETE is writeable. START will clear when the BIST has completed
+ * checking all 17 RAMS.
+ * DEFAULT: 0bxxxx xxxxx xxxx xxxx xxxx x000 0000 0000 00x0
+ */
+#define REG_RX_BIST 0x4060 /* (ro) RX BIST */
+#define RX_BIST_32A_PASS 0x80000000 /* RX FIFO 32A passed */
+#define RX_BIST_33A_PASS 0x40000000 /* RX FIFO 33A passed */
+#define RX_BIST_32B_PASS 0x20000000 /* RX FIFO 32B passed */
+#define RX_BIST_33B_PASS 0x10000000 /* RX FIFO 33B passed */
+#define RX_BIST_32C_PASS 0x08000000 /* RX FIFO 32C passed */
+#define RX_BIST_33C_PASS 0x04000000 /* RX FIFO 33C passed */
+#define RX_BIST_IPP_32A_PASS 0x02000000 /* RX IPP FIFO 33B passed */
+#define RX_BIST_IPP_33A_PASS 0x01000000 /* RX IPP FIFO 33A passed */
+#define RX_BIST_IPP_32B_PASS 0x00800000 /* RX IPP FIFO 32B passed */
+#define RX_BIST_IPP_33B_PASS 0x00400000 /* RX IPP FIFO 33B passed */
+#define RX_BIST_IPP_32C_PASS 0x00200000 /* RX IPP FIFO 32C passed */
+#define RX_BIST_IPP_33C_PASS 0x00100000 /* RX IPP FIFO 33C passed */
+#define RX_BIST_CTRL_32_PASS 0x00800000 /* RX CTRL FIFO 32 passed */
+#define RX_BIST_CTRL_33_PASS 0x00400000 /* RX CTRL FIFO 33 passed */
+#define RX_BIST_REAS_26A_PASS 0x00200000 /* RX Reas 26A passed */
+#define RX_BIST_REAS_26B_PASS 0x00100000 /* RX Reas 26B passed */
+#define RX_BIST_REAS_27_PASS 0x00080000 /* RX Reas 27 passed */
+#define RX_BIST_STATE_MASK 0x00078000 /* BIST state machine */
+#define RX_BIST_SUMMARY 0x00000002 /* when BIST complete,
+ summary pass bit
+ contains AND of BIST
+ results of all 16
+ RAMS */
+#define RX_BIST_START 0x00000001 /* write 1 to start
+ BIST. self clears
+ on completion. */
+
+/* next location in RX CTRL FIFO that will be loaded w/ data from RX IPP/read
+ * from to retrieve packet control info.
+ * DEFAULT: 0
+ */
+#define REG_RX_CTRL_FIFO_WRITE_PTR 0x4064 /* (ro) RX control FIFO
+ write ptr */
+#define REG_RX_CTRL_FIFO_READ_PTR 0x4068 /* (ro) RX control FIFO read
+ ptr */
+
+/* receive interrupt blanking. loaded each time interrupt alias register is
+ * read.
+ * DEFAULT: 0x0
+ */
+#define REG_RX_BLANK_ALIAS_READ 0x406C /* RX blanking register for
+ alias read */
+#define RX_BAR_INTR_PACKET_MASK 0x000001FF /* assert RX_DONE if #
+ completion writebacks
+ > # since last ISR
+ read. 0 = no
+ blanking. up to 2
+ packets per
+ completion wb. */
+#define RX_BAR_INTR_TIME_MASK 0x3FFFF000 /* assert RX_DONE if #
+ clocks > # since last
+ ISR read. each count
+ is 512 core clocks
+ (125MHz). 0 = no
+ blanking. */
+
+/* diagnostic access to RX FIFO. 32 LSB accessed via DATA_LOW. 32 MSB accessed
+ * via DATA_HI_T0 or DATA_HI_T1. TAG reads the tag bit. writing HI_T0
+ * will unset the tag bit while writing HI_T1 will set the tag bit. to reset
+ * to normal operation after diagnostics, write to address location 0x0.
+ * RX_DMA_EN bit must be set to 0x0 for RX FIFO PIO access. DATA_HI should
+ * be the last write access of a write sequence.
+ * DEFAULT: undefined
+ */
+#define REG_RX_FIFO_ADDR 0x4080 /* RX FIFO address */
+#define REG_RX_FIFO_TAG 0x4084 /* RX FIFO tag */
+#define REG_RX_FIFO_DATA_LOW 0x4088 /* RX FIFO data low */
+#define REG_RX_FIFO_DATA_HI_T0 0x408C /* RX FIFO data high T0 */
+#define REG_RX_FIFO_DATA_HI_T1 0x4090 /* RX FIFO data high T1 */
+
+/* diagnostic assess to RX CTRL FIFO. 8-bit FIFO_ADDR holds address of
+ * 81 bit control entry and 6 bit flow id. LOW and MID are both 32-bit
+ * accesses. HI is 7-bits with 6-bit flow id and 1 bit control
+ * word. RX_DMA_EN must be 0 for RX CTRL FIFO PIO access. DATA_HI
+ * should be last write access of the write sequence.
+ * DEFAULT: undefined
+ */
+#define REG_RX_CTRL_FIFO_ADDR 0x4094 /* RX Control FIFO and
+ Batching FIFO addr */
+#define REG_RX_CTRL_FIFO_DATA_LOW 0x4098 /* RX Control FIFO data
+ low */
+#define REG_RX_CTRL_FIFO_DATA_MID 0x409C /* RX Control FIFO data
+ mid */
+#define REG_RX_CTRL_FIFO_DATA_HI 0x4100 /* RX Control FIFO data
+ hi and flow id */
+#define RX_CTRL_FIFO_DATA_HI_CTRL 0x0001 /* upper bit of ctrl word */
+#define RX_CTRL_FIFO_DATA_HI_FLOW_MASK 0x007E /* flow id */
+
+/* diagnostic access to RX IPP FIFO. same semantics as RX_FIFO.
+ * DEFAULT: undefined
+ */
+#define REG_RX_IPP_FIFO_ADDR 0x4104 /* RX IPP FIFO address */
+#define REG_RX_IPP_FIFO_TAG 0x4108 /* RX IPP FIFO tag */
+#define REG_RX_IPP_FIFO_DATA_LOW 0x410C /* RX IPP FIFO data low */
+#define REG_RX_IPP_FIFO_DATA_HI_T0 0x4110 /* RX IPP FIFO data high
+ T0 */
+#define REG_RX_IPP_FIFO_DATA_HI_T1 0x4114 /* RX IPP FIFO data high
+ T1 */
+
+/* 64-bit pointer to receive data buffer in host memory used for headers and
+ * small packets. MSB in high register. loaded by DMA state machine and
+ * increments as DMA writes receive data. only 50 LSB are incremented. top
+ * 13 bits taken from RX descriptor.
+ * DEFAULT: undefined
+ */
+#define REG_RX_HEADER_PAGE_PTR_LOW 0x4118 /* (ro) RX header page ptr
+ low */
+#define REG_RX_HEADER_PAGE_PTR_HI 0x411C /* (ro) RX header page ptr
+ high */
+#define REG_RX_MTU_PAGE_PTR_LOW 0x4120 /* (ro) RX MTU page pointer
+ low */
+#define REG_RX_MTU_PAGE_PTR_HI 0x4124 /* (ro) RX MTU page pointer
+ high */
+
+/* PIO diagnostic access to RX reassembly DMA Table RAM. 6-bit register holds
+ * one of 64 79-bit locations in the RX Reassembly DMA table and the addr of
+ * one of the 64 byte locations in the Batching table. LOW holds 32 LSB.
+ * MID holds the next 32 LSB. HIGH holds the 15 MSB. RX_DMA_EN must be set
+ * to 0 for PIO access. DATA_HIGH should be last write of write sequence.
+ * layout:
+ * reassmbl ptr [78:15] | reassmbl index [14:1] | reassmbl entry valid [0]
+ * DEFAULT: undefined
+ */
+#define REG_RX_TABLE_ADDR 0x4128 /* RX reassembly DMA table
+ address */
+#define RX_TABLE_ADDR_MASK 0x0000003F /* address mask */
+
+#define REG_RX_TABLE_DATA_LOW 0x412C /* RX reassembly DMA table
+ data low */
+#define REG_RX_TABLE_DATA_MID 0x4130 /* RX reassembly DMA table
+ data mid */
+#define REG_RX_TABLE_DATA_HI 0x4134 /* RX reassembly DMA table
+ data high */
+
+/* cassini+ only */
+/* 8KB aligned 64-bit pointer to base of RX rings. lower 13 bits hardwired to
+ * 0. same semantics as primary desc/complete rings.
+ */
+#define REG_PLUS_RX_DB1_LOW 0x4200 /* RX descriptor ring
+ 2 base low */
+#define REG_PLUS_RX_DB1_HI 0x4204 /* RX descriptor ring
+ 2 base high */
+#define REG_PLUS_RX_CB1_LOW 0x4208 /* RX completion ring
+ 2 base low. 4 total */
+#define REG_PLUS_RX_CB1_HI 0x420C /* RX completion ring
+ 2 base high. 4 total */
+#define REG_PLUS_RX_CBN_LOW(x) (REG_PLUS_RX_CB1_LOW + 8*((x) - 1))
+#define REG_PLUS_RX_CBN_HI(x) (REG_PLUS_RX_CB1_HI + 8*((x) - 1))
+#define REG_PLUS_RX_KICK1 0x4220 /* RX Kick 2 register */
+#define REG_PLUS_RX_COMP1 0x4224 /* (ro) RX completion 2
+ reg */
+#define REG_PLUS_RX_COMP1_HEAD 0x4228 /* (ro) RX completion 2
+ head reg. 4 total. */
+#define REG_PLUS_RX_COMP1_TAIL 0x422C /* RX completion 2
+ tail reg. 4 total. */
+#define REG_PLUS_RX_COMPN_HEAD(x) (REG_PLUS_RX_COMP1_HEAD + 8*((x) - 1))
+#define REG_PLUS_RX_COMPN_TAIL(x) (REG_PLUS_RX_COMP1_TAIL + 8*((x) - 1))
+#define REG_PLUS_RX_AE1_THRESH 0x4240 /* RX almost empty 2
+ thresholds */
+#define RX_AE1_THRESH_FREE_MASK RX_AE_THRESH_FREE_MASK
+#define RX_AE1_THRESH_FREE_SHIFT RX_AE_THRESH_FREE_SHIFT
+
+/** header parser registers **/
+
+/* RX parser configuration register.
+ * DEFAULT: 0x1651004
+ */
+#define REG_HP_CFG 0x4140 /* header parser
+ configuration reg */
+#define HP_CFG_PARSE_EN 0x00000001 /* enab header parsing */
+#define HP_CFG_NUM_CPU_MASK 0x000000FC /* # processors
+ 0 = 64. 0x3f = 63 */
+#define HP_CFG_NUM_CPU_SHIFT 2
+#define HP_CFG_SYN_INC_MASK 0x00000100 /* SYN bit won't increment
+ TCP seq # by one when
+ stored in FDBM */
+#define HP_CFG_TCP_THRESH_MASK 0x000FFE00 /* # bytes of TCP data
+ needed to be considered
+ for reassembly */
+#define HP_CFG_TCP_THRESH_SHIFT 9
+
+/* access to RX Instruction RAM. 5-bit register/counter holds addr
+ * of 39 bit entry to be read/written. 32 LSB in _DATA_LOW. 7 MSB in _DATA_HI.
+ * RX_DMA_EN must be 0 for RX instr PIO access. DATA_HI should be last access
+ * of sequence.
+ * DEFAULT: undefined
+ */
+#define REG_HP_INSTR_RAM_ADDR 0x4144 /* HP instruction RAM
+ address */
+#define HP_INSTR_RAM_ADDR_MASK 0x01F /* 5-bit mask */
+#define REG_HP_INSTR_RAM_DATA_LOW 0x4148 /* HP instruction RAM
+ data low */
+#define HP_INSTR_RAM_LOW_OUTMASK_MASK 0x0000FFFF
+#define HP_INSTR_RAM_LOW_OUTMASK_SHIFT 0
+#define HP_INSTR_RAM_LOW_OUTSHIFT_MASK 0x000F0000
+#define HP_INSTR_RAM_LOW_OUTSHIFT_SHIFT 16
+#define HP_INSTR_RAM_LOW_OUTEN_MASK 0x00300000
+#define HP_INSTR_RAM_LOW_OUTEN_SHIFT 20
+#define HP_INSTR_RAM_LOW_OUTARG_MASK 0xFFC00000
+#define HP_INSTR_RAM_LOW_OUTARG_SHIFT 22
+#define REG_HP_INSTR_RAM_DATA_MID 0x414C /* HP instruction RAM
+ data mid */
+#define HP_INSTR_RAM_MID_OUTARG_MASK 0x00000003
+#define HP_INSTR_RAM_MID_OUTARG_SHIFT 0
+#define HP_INSTR_RAM_MID_OUTOP_MASK 0x0000003C
+#define HP_INSTR_RAM_MID_OUTOP_SHIFT 2
+#define HP_INSTR_RAM_MID_FNEXT_MASK 0x000007C0
+#define HP_INSTR_RAM_MID_FNEXT_SHIFT 6
+#define HP_INSTR_RAM_MID_FOFF_MASK 0x0003F800
+#define HP_INSTR_RAM_MID_FOFF_SHIFT 11
+#define HP_INSTR_RAM_MID_SNEXT_MASK 0x007C0000
+#define HP_INSTR_RAM_MID_SNEXT_SHIFT 18
+#define HP_INSTR_RAM_MID_SOFF_MASK 0x3F800000
+#define HP_INSTR_RAM_MID_SOFF_SHIFT 23
+#define HP_INSTR_RAM_MID_OP_MASK 0xC0000000
+#define HP_INSTR_RAM_MID_OP_SHIFT 30
+#define REG_HP_INSTR_RAM_DATA_HI 0x4150 /* HP instruction RAM
+ data high */
+#define HP_INSTR_RAM_HI_VAL_MASK 0x0000FFFF
+#define HP_INSTR_RAM_HI_VAL_SHIFT 0
+#define HP_INSTR_RAM_HI_MASK_MASK 0xFFFF0000
+#define HP_INSTR_RAM_HI_MASK_SHIFT 16
+
+/* PIO access into RX Header parser data RAM and flow database.
+ * 11-bit register. Data fills the LSB portion of bus if less than 32 bits.
+ * DATA_RAM: write RAM_FDB_DATA with index to access DATA_RAM.
+ * RAM bytes = 4*(x - 1) + [3:0]. e.g., 0 -> [3:0], 31 -> [123:120]
+ * FLOWDB: write DATA_RAM_FDB register and then read/write FDB1-12 to access
+ * flow database.
+ * RX_DMA_EN must be 0 for RX parser RAM PIO access. RX Parser RAM data reg
+ * should be the last write access of the write sequence.
+ * DEFAULT: undefined
+ */
+#define REG_HP_DATA_RAM_FDB_ADDR 0x4154 /* HP data and FDB
+ RAM address */
+#define HP_DATA_RAM_FDB_DATA_MASK 0x001F /* select 1 of 86 byte
+ locations in header
+ parser data ram to
+ read/write */
+#define HP_DATA_RAM_FDB_FDB_MASK 0x3F00 /* 1 of 64 353-bit locations
+ in the flow database */
+#define REG_HP_DATA_RAM_DATA 0x4158 /* HP data RAM data */
+
+/* HP flow database registers: 1 - 12, 0x415C - 0x4188, 4 8-bit bytes
+ * FLOW_DB(1) = IP_SA[127:96], FLOW_DB(2) = IP_SA[95:64]
+ * FLOW_DB(3) = IP_SA[63:32], FLOW_DB(4) = IP_SA[31:0]
+ * FLOW_DB(5) = IP_DA[127:96], FLOW_DB(6) = IP_DA[95:64]
+ * FLOW_DB(7) = IP_DA[63:32], FLOW_DB(8) = IP_DA[31:0]
+ * FLOW_DB(9) = {TCP_SP[15:0],TCP_DP[15:0]}
+ * FLOW_DB(10) = bit 0 has value for flow valid
+ * FLOW_DB(11) = TCP_SEQ[63:32], FLOW_DB(12) = TCP_SEQ[31:0]
+ */
+#define REG_HP_FLOW_DB0 0x415C /* HP flow database 1 reg */
+#define REG_HP_FLOW_DBN(x) (REG_HP_FLOW_DB0 + (x)*4)
+
+/* diagnostics for RX Header Parser block.
+ * ASUN: the header parser state machine register is used for diagnostics
+ * purposes. however, the spec doesn't have any details on it.
+ */
+#define REG_HP_STATE_MACHINE 0x418C /* (ro) HP state machine */
+#define REG_HP_STATUS0 0x4190 /* (ro) HP status 1 */
+#define HP_STATUS0_SAP_MASK 0xFFFF0000 /* SAP */
+#define HP_STATUS0_L3_OFF_MASK 0x0000FE00 /* L3 offset */
+#define HP_STATUS0_LB_CPUNUM_MASK 0x000001F8 /* load balancing CPU
+ number */
+#define HP_STATUS0_HRP_OPCODE_MASK 0x00000007 /* HRP opcode */
+
+#define REG_HP_STATUS1 0x4194 /* (ro) HP status 2 */
+#define HP_STATUS1_ACCUR2_MASK 0xE0000000 /* accu R2[6:4] */
+#define HP_STATUS1_FLOWID_MASK 0x1F800000 /* flow id */
+#define HP_STATUS1_TCP_OFF_MASK 0x007F0000 /* tcp payload offset */
+#define HP_STATUS1_TCP_SIZE_MASK 0x0000FFFF /* tcp payload size */
+
+#define REG_HP_STATUS2 0x4198 /* (ro) HP status 3 */
+#define HP_STATUS2_ACCUR2_MASK 0xF0000000 /* accu R2[3:0] */
+#define HP_STATUS2_CSUM_OFF_MASK 0x07F00000 /* checksum start
+ start offset */
+#define HP_STATUS2_ACCUR1_MASK 0x000FE000 /* accu R1 */
+#define HP_STATUS2_FORCE_DROP 0x00001000 /* force drop */
+#define HP_STATUS2_BWO_REASSM 0x00000800 /* batching w/o
+ reassembly */
+#define HP_STATUS2_JH_SPLIT_EN 0x00000400 /* jumbo header split
+ enable */
+#define HP_STATUS2_FORCE_TCP_NOCHECK 0x00000200 /* force tcp no payload
+ check */
+#define HP_STATUS2_DATA_MASK_ZERO 0x00000100 /* mask of data length
+ equal to zero */
+#define HP_STATUS2_FORCE_TCP_CHECK 0x00000080 /* force tcp payload
+ chk */
+#define HP_STATUS2_MASK_TCP_THRESH 0x00000040 /* mask of payload
+ threshold */
+#define HP_STATUS2_NO_ASSIST 0x00000020 /* no assist */
+#define HP_STATUS2_CTRL_PACKET_FLAG 0x00000010 /* control packet flag */
+#define HP_STATUS2_TCP_FLAG_CHECK 0x00000008 /* tcp flag check */
+#define HP_STATUS2_SYN_FLAG 0x00000004 /* syn flag */
+#define HP_STATUS2_TCP_CHECK 0x00000002 /* tcp payload chk */
+#define HP_STATUS2_TCP_NOCHECK 0x00000001 /* tcp no payload chk */
+
+/* BIST for header parser(HP) and flow database memories (FDBM). set _START
+ * to start BIST. controller clears _START on completion. _START can also
+ * be cleared to force termination of BIST. a bit set indicates that that
+ * memory passed its BIST.
+ */
+#define REG_HP_RAM_BIST 0x419C /* HP RAM BIST reg */
+#define HP_RAM_BIST_HP_DATA_PASS 0x80000000 /* HP data ram */
+#define HP_RAM_BIST_HP_INSTR0_PASS 0x40000000 /* HP instr ram 0 */
+#define HP_RAM_BIST_HP_INSTR1_PASS 0x20000000 /* HP instr ram 1 */
+#define HP_RAM_BIST_HP_INSTR2_PASS 0x10000000 /* HP instr ram 2 */
+#define HP_RAM_BIST_FDBM_AGE0_PASS 0x08000000 /* FDBM aging RAM0 */
+#define HP_RAM_BIST_FDBM_AGE1_PASS 0x04000000 /* FDBM aging RAM1 */
+#define HP_RAM_BIST_FDBM_FLOWID00_PASS 0x02000000 /* FDBM flowid RAM0
+ bank 0 */
+#define HP_RAM_BIST_FDBM_FLOWID10_PASS 0x01000000 /* FDBM flowid RAM1
+ bank 0 */
+#define HP_RAM_BIST_FDBM_FLOWID20_PASS 0x00800000 /* FDBM flowid RAM2
+ bank 0 */
+#define HP_RAM_BIST_FDBM_FLOWID30_PASS 0x00400000 /* FDBM flowid RAM3
+ bank 0 */
+#define HP_RAM_BIST_FDBM_FLOWID01_PASS 0x00200000 /* FDBM flowid RAM0
+ bank 1 */
+#define HP_RAM_BIST_FDBM_FLOWID11_PASS 0x00100000 /* FDBM flowid RAM1
+ bank 2 */
+#define HP_RAM_BIST_FDBM_FLOWID21_PASS 0x00080000 /* FDBM flowid RAM2
+ bank 1 */
+#define HP_RAM_BIST_FDBM_FLOWID31_PASS 0x00040000 /* FDBM flowid RAM3
+ bank 1 */
+#define HP_RAM_BIST_FDBM_TCPSEQ_PASS 0x00020000 /* FDBM tcp sequence
+ RAM */
+#define HP_RAM_BIST_SUMMARY 0x00000002 /* all BIST tests */
+#define HP_RAM_BIST_START 0x00000001 /* start/stop BIST */
+
+
+/** MAC registers. **/
+/* reset bits are set using a PIO write and self-cleared after the command
+ * execution has completed.
+ */
+#define REG_MAC_TX_RESET 0x6000 /* TX MAC software reset
+ command (default: 0x0) */
+#define REG_MAC_RX_RESET 0x6004 /* RX MAC software reset
+ command (default: 0x0) */
+/* execute a pause flow control frame transmission
+ DEFAULT: 0x0XXXX */
+#define REG_MAC_SEND_PAUSE 0x6008 /* send pause command reg */
+#define MAC_SEND_PAUSE_TIME_MASK 0x0000FFFF /* value of pause time
+ to be sent on network
+ in units of slot
+ times */
+#define MAC_SEND_PAUSE_SEND 0x00010000 /* send pause flow ctrl
+ frame on network */
+
+/* bit set indicates that event occurred. auto-cleared when status register
+ * is read and have corresponding mask bits in mask register. events will
+ * trigger an interrupt if the corresponding mask bit is 0.
+ * status register default: 0x00000000
+ * mask register default = 0xFFFFFFFF on reset
+ */
+#define REG_MAC_TX_STATUS 0x6010 /* TX MAC status reg */
+#define MAC_TX_FRAME_XMIT 0x0001 /* successful frame
+ transmision */
+#define MAC_TX_UNDERRUN 0x0002 /* terminated frame
+ transmission due to
+ data starvation in the
+ xmit data path */
+#define MAC_TX_MAX_PACKET_ERR 0x0004 /* frame exceeds max allowed
+ length passed to TX MAC
+ by the DMA engine */
+#define MAC_TX_COLL_NORMAL 0x0008 /* rollover of the normal
+ collision counter */
+#define MAC_TX_COLL_EXCESS 0x0010 /* rollover of the excessive
+ collision counter */
+#define MAC_TX_COLL_LATE 0x0020 /* rollover of the late
+ collision counter */
+#define MAC_TX_COLL_FIRST 0x0040 /* rollover of the first
+ collision counter */
+#define MAC_TX_DEFER_TIMER 0x0080 /* rollover of the defer
+ timer */
+#define MAC_TX_PEAK_ATTEMPTS 0x0100 /* rollover of the peak
+ attempts counter */
+
+#define REG_MAC_RX_STATUS 0x6014 /* RX MAC status reg */
+#define MAC_RX_FRAME_RECV 0x0001 /* successful receipt of
+ a frame */
+#define MAC_RX_OVERFLOW 0x0002 /* dropped frame due to
+ RX FIFO overflow */
+#define MAC_RX_FRAME_COUNT 0x0004 /* rollover of receive frame
+ counter */
+#define MAC_RX_ALIGN_ERR 0x0008 /* rollover of alignment
+ error counter */
+#define MAC_RX_CRC_ERR 0x0010 /* rollover of crc error
+ counter */
+#define MAC_RX_LEN_ERR 0x0020 /* rollover of length
+ error counter */
+#define MAC_RX_VIOL_ERR 0x0040 /* rollover of code
+ violation error */
+
+/* DEFAULT: 0xXXXX0000 on reset */
+#define REG_MAC_CTRL_STATUS 0x6018 /* MAC control status reg */
+#define MAC_CTRL_PAUSE_RECEIVED 0x00000001 /* successful
+ reception of a
+ pause control
+ frame */
+#define MAC_CTRL_PAUSE_STATE 0x00000002 /* MAC has made a
+ transition from
+ "not paused" to
+ "paused" */
+#define MAC_CTRL_NOPAUSE_STATE 0x00000004 /* MAC has made a
+ transition from
+ "paused" to "not
+ paused" */
+#define MAC_CTRL_PAUSE_TIME_MASK 0xFFFF0000 /* value of pause time
+ operand that was
+ received in the last
+ pause flow control
+ frame */
+
+/* layout identical to TX MAC[8:0] */
+#define REG_MAC_TX_MASK 0x6020 /* TX MAC mask reg */
+/* layout identical to RX MAC[6:0] */
+#define REG_MAC_RX_MASK 0x6024 /* RX MAC mask reg */
+/* layout identical to CTRL MAC[2:0] */
+#define REG_MAC_CTRL_MASK 0x6028 /* MAC control mask reg */
+
+/* to ensure proper operation, CFG_EN must be cleared to 0 and a delay
+ * imposed before writes to other bits in the TX_MAC_CFG register or any of
+ * the MAC parameters is performed. delay dependent upon time required to
+ * transmit a maximum size frame (= MAC_FRAMESIZE_MAX*8/Mbps). e.g.,
+ * the delay for a 1518-byte frame on a 100Mbps network is 125us.
+ * alternatively, just poll TX_CFG_EN until it reads back as 0.
+ * NOTE: on half-duplex 1Gbps, TX_CFG_CARRIER_EXTEND and
+ * RX_CFG_CARRIER_EXTEND should be set and the SLOT_TIME register should
+ * be 0x200 (slot time of 512 bytes)
+ */
+#define REG_MAC_TX_CFG 0x6030 /* TX MAC config reg */
+#define MAC_TX_CFG_EN 0x0001 /* enable TX MAC. 0 will
+ force TXMAC state
+ machine to remain in
+ idle state or to
+ transition to idle state
+ on completion of an
+ ongoing packet. */
+#define MAC_TX_CFG_IGNORE_CARRIER 0x0002 /* disable CSMA/CD deferral
+ process. set to 1 when
+ full duplex and 0 when
+ half duplex */
+#define MAC_TX_CFG_IGNORE_COLL 0x0004 /* disable CSMA/CD backoff
+ algorithm. set to 1 when
+ full duplex and 0 when
+ half duplex */
+#define MAC_TX_CFG_IPG_EN 0x0008 /* enable extension of the
+ Rx-to-TX IPG. after
+ receiving a frame, TX
+ MAC will reset its
+ deferral process to
+ carrier sense for the
+ amount of time = IPG0 +
+ IPG1 and commit to
+ transmission for time
+ specified in IPG2. when
+ 0 or when xmitting frames
+ back-to-pack (Tx-to-Tx
+ IPG), TX MAC ignores
+ IPG0 and will only use
+ IPG1 for deferral time.
+ IPG2 still used. */
+#define MAC_TX_CFG_NEVER_GIVE_UP_EN 0x0010 /* TX MAC will not easily
+ give up on frame
+ xmission. if backoff
+ algorithm reaches the
+ ATTEMPT_LIMIT, it will
+ clear attempts counter
+ and continue trying to
+ send the frame as
+ specified by
+ GIVE_UP_LIM. when 0,
+ TX MAC will execute
+ standard CSMA/CD prot. */
+#define MAC_TX_CFG_NEVER_GIVE_UP_LIM 0x0020 /* when set, TX MAC will
+ continue to try to xmit
+ until successful. when
+ 0, TX MAC will continue
+ to try xmitting until
+ successful or backoff
+ algorithm reaches
+ ATTEMPT_LIMIT*16 */
+#define MAC_TX_CFG_NO_BACKOFF 0x0040 /* modify CSMA/CD to disable
+ backoff algorithm. TX
+ MAC will not back off
+ after a xmission attempt
+ that resulted in a
+ collision. */
+#define MAC_TX_CFG_SLOW_DOWN 0x0080 /* modify CSMA/CD so that
+ deferral process is reset
+ in response to carrier
+ sense during the entire
+ duration of IPG. TX MAC
+ will only commit to frame
+ xmission after frame
+ xmission has actually
+ begun. */
+#define MAC_TX_CFG_NO_FCS 0x0100 /* TX MAC will not generate
+ CRC for all xmitted
+ packets. when clear, CRC
+ generation is dependent
+ upon NO_CRC bit in the
+ xmit control word from
+ TX DMA */
+#define MAC_TX_CFG_CARRIER_EXTEND 0x0200 /* enables xmit part of the
+ carrier extension
+ feature. this allows for
+ longer collision domains
+ by extending the carrier
+ and collision window
+ from the end of FCS until
+ the end of the slot time
+ if necessary. Required
+ for half-duplex at 1Gbps,
+ clear otherwise. */
+
+/* when CRC is not stripped, reassembly packets will not contain the CRC.
+ * these will be stripped by HRP because it reassembles layer 4 data, and the
+ * CRC is layer 2. however, non-reassembly packets will still contain the CRC
+ * when passed to the host. to ensure proper operation, need to wait 3.2ms
+ * after clearing RX_CFG_EN before writing to any other RX MAC registers
+ * or other MAC parameters. alternatively, poll RX_CFG_EN until it clears
+ * to 0. similary, HASH_FILTER_EN and ADDR_FILTER_EN have the same
+ * restrictions as CFG_EN.
+ */
+#define REG_MAC_RX_CFG 0x6034 /* RX MAC config reg */
+#define MAC_RX_CFG_EN 0x0001 /* enable RX MAC */
+#define MAC_RX_CFG_STRIP_PAD 0x0002 /* always program to 0.
+ feature not supported */
+#define MAC_RX_CFG_STRIP_FCS 0x0004 /* RX MAC will strip the
+ last 4 bytes of a
+ received frame. */
+#define MAC_RX_CFG_PROMISC_EN 0x0008 /* promiscuous mode */
+#define MAC_RX_CFG_PROMISC_GROUP_EN 0x0010 /* accept all valid
+ multicast frames (group
+ bit in DA field set) */
+#define MAC_RX_CFG_HASH_FILTER_EN 0x0020 /* use hash table to filter
+ multicast addresses */
+#define MAC_RX_CFG_ADDR_FILTER_EN 0x0040 /* cause RX MAC to use
+ address filtering regs
+ to filter both unicast
+ and multicast
+ addresses */
+#define MAC_RX_CFG_DISABLE_DISCARD 0x0080 /* pass errored frames to
+ RX DMA by setting BAD
+ bit but not Abort bit
+ in the status. CRC,
+ framing, and length errs
+ will not increment
+ error counters. frames
+ which don't match dest
+ addr will be passed up
+ w/ BAD bit set. */
+#define MAC_RX_CFG_CARRIER_EXTEND 0x0100 /* enable reception of
+ packet bursts generated
+ by carrier extension
+ with packet bursting
+ senders. only applies
+ to half-duplex 1Gbps */
+
+/* DEFAULT: 0x0 */
+#define REG_MAC_CTRL_CFG 0x6038 /* MAC control config reg */
+#define MAC_CTRL_CFG_SEND_PAUSE_EN 0x0001 /* respond to requests for
+ sending pause flow ctrl
+ frames */
+#define MAC_CTRL_CFG_RECV_PAUSE_EN 0x0002 /* respond to received
+ pause flow ctrl frames */
+#define MAC_CTRL_CFG_PASS_CTRL 0x0004 /* pass valid MAC ctrl
+ packets to RX DMA */
+
+/* to ensure proper operation, a global initialization sequence should be
+ * performed when a loopback config is entered or exited. if programmed after
+ * a hw or global sw reset, RX/TX MAC software reset and initialization
+ * should be done to ensure stable clocking.
+ * DEFAULT: 0x0
+ */
+#define REG_MAC_XIF_CFG 0x603C /* XIF config reg */
+#define MAC_XIF_TX_MII_OUTPUT_EN 0x0001 /* enable output drivers
+ on MII xmit bus */
+#define MAC_XIF_MII_INT_LOOPBACK 0x0002 /* loopback GMII xmit data
+ path to GMII recv data
+ path. phy mode register
+ clock selection must be
+ set to GMII mode and
+ GMII_MODE should be set
+ to 1. in loopback mode,
+ REFCLK will drive the
+ entire mac core. 0 for
+ normal operation. */
+#define MAC_XIF_DISABLE_ECHO 0x0004 /* disables receive data
+ path during packet
+ xmission. clear to 0
+ in any full duplex mode,
+ in any loopback mode,
+ or in half-duplex SERDES
+ or SLINK modes. set when
+ in half-duplex when
+ using external phy. */
+#define MAC_XIF_GMII_MODE 0x0008 /* MAC operates with GMII
+ clocks and datapath */
+#define MAC_XIF_MII_BUFFER_OUTPUT_EN 0x0010 /* MII_BUF_EN pin. enable
+ external tristate buffer
+ on the MII receive
+ bus. */
+#define MAC_XIF_LINK_LED 0x0020 /* LINKLED# active (low) */
+#define MAC_XIF_FDPLX_LED 0x0040 /* FDPLXLED# active (low) */
+
+#define REG_MAC_IPG0 0x6040 /* inter-packet gap0 reg.
+ recommended: 0x00 */
+#define REG_MAC_IPG1 0x6044 /* inter-packet gap1 reg
+ recommended: 0x08 */
+#define REG_MAC_IPG2 0x6048 /* inter-packet gap2 reg
+ recommended: 0x04 */
+#define REG_MAC_SLOT_TIME 0x604C /* slot time reg
+ recommended: 0x40 */
+#define REG_MAC_FRAMESIZE_MIN 0x6050 /* min frame size reg
+ recommended: 0x40 */
+
+/* FRAMESIZE_MAX holds both the max frame size as well as the max burst size.
+ * recommended value: 0x2000.05EE
+ */
+#define REG_MAC_FRAMESIZE_MAX 0x6054 /* max frame size reg */
+#define MAC_FRAMESIZE_MAX_BURST_MASK 0x3FFF0000 /* max burst size */
+#define MAC_FRAMESIZE_MAX_BURST_SHIFT 16
+#define MAC_FRAMESIZE_MAX_FRAME_MASK 0x00007FFF /* max frame size */
+#define MAC_FRAMESIZE_MAX_FRAME_SHIFT 0
+#define REG_MAC_PA_SIZE 0x6058 /* PA size reg. number of
+ preamble bytes that the
+ TX MAC will xmit at the
+ beginning of each frame
+ value should be 2 or
+ greater. recommended
+ value: 0x07 */
+#define REG_MAC_JAM_SIZE 0x605C /* jam size reg. duration
+ of jam in units of media
+ byte time. recommended
+ value: 0x04 */
+#define REG_MAC_ATTEMPT_LIMIT 0x6060 /* attempt limit reg. #
+ of attempts TX MAC will
+ make to xmit a frame
+ before it resets its
+ attempts counter. after
+ the limit has been
+ reached, TX MAC may or
+ may not drop the frame
+ dependent upon value
+ in TX_MAC_CFG.
+ recommended
+ value: 0x10 */
+#define REG_MAC_CTRL_TYPE 0x6064 /* MAC control type reg.
+ type field of a MAC
+ ctrl frame. recommended
+ value: 0x8808 */
+
+/* mac address registers: 0 - 44, 0x6080 - 0x6130, 4 8-bit bytes.
+ * register contains comparison
+ * 0 16 MSB of primary MAC addr [47:32] of DA field
+ * 1 16 middle bits "" [31:16] of DA field
+ * 2 16 LSB "" [15:0] of DA field
+ * 3*x 16MSB of alt MAC addr 1-15 [47:32] of DA field
+ * 4*x 16 middle bits "" [31:16]
+ * 5*x 16 LSB "" [15:0]
+ * 42 16 MSB of MAC CTRL addr [47:32] of DA.
+ * 43 16 middle bits "" [31:16]
+ * 44 16 LSB "" [15:0]
+ * MAC CTRL addr must be the reserved multicast addr for MAC CTRL frames.
+ * if there is a match, MAC will set the bit for alternative address
+ * filter pass [15]
+
+ * here is the map of registers given MAC address notation: a:b:c:d:e:f
+ * ab cd ef
+ * primary addr reg 2 reg 1 reg 0
+ * alt addr 1 reg 5 reg 4 reg 3
+ * alt addr x reg 5*x reg 4*x reg 3*x
+ * ctrl addr reg 44 reg 43 reg 42
+ */
+#define REG_MAC_ADDR0 0x6080 /* MAC address 0 reg */
+#define REG_MAC_ADDRN(x) (REG_MAC_ADDR0 + (x)*4)
+#define REG_MAC_ADDR_FILTER0 0x614C /* address filter 0 reg
+ [47:32] */
+#define REG_MAC_ADDR_FILTER1 0x6150 /* address filter 1 reg
+ [31:16] */
+#define REG_MAC_ADDR_FILTER2 0x6154 /* address filter 2 reg
+ [15:0] */
+#define REG_MAC_ADDR_FILTER2_1_MASK 0x6158 /* address filter 2 and 1
+ mask reg. 8-bit reg
+ contains nibble mask for
+ reg 2 and 1. */
+#define REG_MAC_ADDR_FILTER0_MASK 0x615C /* address filter 0 mask
+ reg */
+
+/* hash table registers: 0 - 15, 0x6160 - 0x619C, 4 8-bit bytes
+ * 16-bit registers contain bits of the hash table.
+ * reg x -> [16*(15 - x) + 15 : 16*(15 - x)].
+ * e.g., 15 -> [15:0], 0 -> [255:240]
+ */
+#define REG_MAC_HASH_TABLE0 0x6160 /* hash table 0 reg */
+#define REG_MAC_HASH_TABLEN(x) (REG_MAC_HASH_TABLE0 + (x)*4)
+
+/* statistics registers. these registers generate an interrupt on
+ * overflow. recommended initialization: 0x0000. most are 16-bits except
+ * for PEAK_ATTEMPTS register which is 8 bits.
+ */
+#define REG_MAC_COLL_NORMAL 0x61A0 /* normal collision
+ counter. */
+#define REG_MAC_COLL_FIRST 0x61A4 /* first attempt
+ successful collision
+ counter */
+#define REG_MAC_COLL_EXCESS 0x61A8 /* excessive collision
+ counter */
+#define REG_MAC_COLL_LATE 0x61AC /* late collision counter */
+#define REG_MAC_TIMER_DEFER 0x61B0 /* defer timer. time base
+ is the media byte
+ clock/256 */
+#define REG_MAC_ATTEMPTS_PEAK 0x61B4 /* peak attempts reg */
+#define REG_MAC_RECV_FRAME 0x61B8 /* receive frame counter */
+#define REG_MAC_LEN_ERR 0x61BC /* length error counter */
+#define REG_MAC_ALIGN_ERR 0x61C0 /* alignment error counter */
+#define REG_MAC_FCS_ERR 0x61C4 /* FCS error counter */
+#define REG_MAC_RX_CODE_ERR 0x61C8 /* RX code violation
+ error counter */
+
+/* misc registers */
+#define REG_MAC_RANDOM_SEED 0x61CC /* random number seed reg.
+ 10-bit register used as a
+ seed for the random number
+ generator for the CSMA/CD
+ backoff algorithm. only
+ programmed after power-on
+ reset and should be a
+ random value which has a
+ high likelihood of being
+ unique for each MAC
+ attached to a network
+ segment (e.g., 10 LSB of
+ MAC address) */
+
+/* ASUN: there's a PAUSE_TIMER (ro) described, but it's not in the address
+ * map
+ */
+
+/* 27-bit register has the current state for key state machines in the MAC */
+#define REG_MAC_STATE_MACHINE 0x61D0 /* (ro) state machine reg */
+#define MAC_SM_RLM_MASK 0x07800000
+#define MAC_SM_RLM_SHIFT 23
+#define MAC_SM_RX_FC_MASK 0x00700000
+#define MAC_SM_RX_FC_SHIFT 20
+#define MAC_SM_TLM_MASK 0x000F0000
+#define MAC_SM_TLM_SHIFT 16
+#define MAC_SM_ENCAP_SM_MASK 0x0000F000
+#define MAC_SM_ENCAP_SM_SHIFT 12
+#define MAC_SM_TX_REQ_MASK 0x00000C00
+#define MAC_SM_TX_REQ_SHIFT 10
+#define MAC_SM_TX_FC_MASK 0x000003C0
+#define MAC_SM_TX_FC_SHIFT 6
+#define MAC_SM_FIFO_WRITE_SEL_MASK 0x00000038
+#define MAC_SM_FIFO_WRITE_SEL_SHIFT 3
+#define MAC_SM_TX_FIFO_EMPTY_MASK 0x00000007
+#define MAC_SM_TX_FIFO_EMPTY_SHIFT 0
+
+/** MIF registers. the MIF can be programmed in either bit-bang or
+ * frame mode.
+ **/
+#define REG_MIF_BIT_BANG_CLOCK 0x6200 /* MIF bit-bang clock.
+ 1 -> 0 will generate a
+ rising edge. 0 -> 1 will
+ generate a falling edge. */
+#define REG_MIF_BIT_BANG_DATA 0x6204 /* MIF bit-bang data. 1-bit
+ register generates data */
+#define REG_MIF_BIT_BANG_OUTPUT_EN 0x6208 /* MIF bit-bang output
+ enable. enable when
+ xmitting data from MIF to
+ transceiver. */
+
+/* 32-bit register serves as an instruction register when the MIF is
+ * programmed in frame mode. load this register w/ a valid instruction
+ * (as per IEEE 802.3u MII spec). poll this register to check for instruction
+ * execution completion. during a read operation, this register will also
+ * contain the 16-bit data returned by the tranceiver. unless specified
+ * otherwise, fields are considered "don't care" when polling for
+ * completion.
+ */
+#define REG_MIF_FRAME 0x620C /* MIF frame/output reg */
+#define MIF_FRAME_START_MASK 0xC0000000 /* start of frame.
+ load w/ 01 when
+ issuing an instr */
+#define MIF_FRAME_ST 0x40000000 /* STart of frame */
+#define MIF_FRAME_OPCODE_MASK 0x30000000 /* opcode. 01 for a
+ write. 10 for a
+ read */
+#define MIF_FRAME_OP_READ 0x20000000 /* read OPcode */
+#define MIF_FRAME_OP_WRITE 0x10000000 /* write OPcode */
+#define MIF_FRAME_PHY_ADDR_MASK 0x0F800000 /* phy address. when
+ issuing an instr,
+ this field should be
+ loaded w/ the XCVR
+ addr */
+#define MIF_FRAME_PHY_ADDR_SHIFT 23
+#define MIF_FRAME_REG_ADDR_MASK 0x007C0000 /* register address.
+ when issuing an instr,
+ addr of register
+ to be read/written */
+#define MIF_FRAME_REG_ADDR_SHIFT 18
+#define MIF_FRAME_TURN_AROUND_MSB 0x00020000 /* turn around, MSB.
+ when issuing an instr,
+ set this bit to 1 */
+#define MIF_FRAME_TURN_AROUND_LSB 0x00010000 /* turn around, LSB.
+ when issuing an instr,
+ set this bit to 0.
+ when polling for
+ completion, 1 means
+ that instr execution
+ has been completed */
+#define MIF_FRAME_DATA_MASK 0x0000FFFF /* instruction payload
+ load with 16-bit data
+ to be written in
+ transceiver reg for a
+ write. doesn't matter
+ in a read. when
+ polling for
+ completion, field is
+ "don't care" for write
+ and 16-bit data
+ returned by the
+ transceiver for a
+ read (if valid bit
+ is set) */
+#define REG_MIF_CFG 0x6210 /* MIF config reg */
+#define MIF_CFG_PHY_SELECT 0x0001 /* 1 -> select MDIO_1
+ 0 -> select MDIO_0 */
+#define MIF_CFG_POLL_EN 0x0002 /* enable polling
+ mechanism. if set,
+ BB_MODE should be 0 */
+#define MIF_CFG_BB_MODE 0x0004 /* 1 -> bit-bang mode
+ 0 -> frame mode */
+#define MIF_CFG_POLL_REG_MASK 0x00F8 /* register address to be
+ used by polling mode.
+ only meaningful if POLL_EN
+ is set to 1 */
+#define MIF_CFG_POLL_REG_SHIFT 3
+#define MIF_CFG_MDIO_0 0x0100 /* (ro) dual purpose.
+ when MDIO_0 is idle,
+ 1 -> tranceiver is
+ connected to MDIO_0.
+ when MIF is communicating
+ w/ MDIO_0 in bit-bang
+ mode, this bit indicates
+ the incoming bit stream
+ during a read op */
+#define MIF_CFG_MDIO_1 0x0200 /* (ro) dual purpose.
+ when MDIO_1 is idle,
+ 1 -> transceiver is
+ connected to MDIO_1.
+ when MIF is communicating
+ w/ MDIO_1 in bit-bang
+ mode, this bit indicates
+ the incoming bit stream
+ during a read op */
+#define MIF_CFG_POLL_PHY_MASK 0x7C00 /* tranceiver address to
+ be polled */
+#define MIF_CFG_POLL_PHY_SHIFT 10
+
+/* 16-bit register used to determine which bits in the POLL_STATUS portion of
+ * the MIF_STATUS register will cause an interrupt. if a mask bit is 0,
+ * corresponding bit of the POLL_STATUS will generate a MIF interrupt when
+ * set. DEFAULT: 0xFFFF
+ */
+#define REG_MIF_MASK 0x6214 /* MIF mask reg */
+
+/* 32-bit register used when in poll mode. auto-cleared after being read */
+#define REG_MIF_STATUS 0x6218 /* MIF status reg */
+#define MIF_STATUS_POLL_DATA_MASK 0xFFFF0000 /* poll data contains
+ the "latest image"
+ update of the XCVR
+ reg being read */
+#define MIF_STATUS_POLL_DATA_SHIFT 16
+#define MIF_STATUS_POLL_STATUS_MASK 0x0000FFFF /* poll status indicates
+ which bits in the
+ POLL_DATA field have
+ changed since the
+ MIF_STATUS reg was
+ last read */
+#define MIF_STATUS_POLL_STATUS_SHIFT 0
+
+/* 7-bit register has current state for all state machines in the MIF */
+#define REG_MIF_STATE_MACHINE 0x621C /* MIF state machine reg */
+#define MIF_SM_CONTROL_MASK 0x07 /* control state machine
+ state */
+#define MIF_SM_EXECUTION_MASK 0x60 /* execution state machine
+ state */
+
+/** PCS/Serialink. the following registers are equivalent to the standard
+ * MII management registers except that they're directly mapped in
+ * Cassini's register space.
+ **/
+
+/* the auto-negotiation enable bit should be programmed the same at
+ * the link partner as in the local device to enable auto-negotiation to
+ * complete. when that bit is reprogrammed, auto-neg/manual config is
+ * restarted automatically.
+ * DEFAULT: 0x1040
+ */
+#define REG_PCS_MII_CTRL 0x9000 /* PCS MII control reg */
+#define PCS_MII_CTRL_1000_SEL 0x0040 /* reads 1. ignored on
+ writes */
+#define PCS_MII_CTRL_COLLISION_TEST 0x0080 /* COL signal at the PCS
+ to MAC interface is
+ activated regardless
+ of activity */
+#define PCS_MII_CTRL_DUPLEX 0x0100 /* forced 0x0. PCS
+ behaviour same for
+ half and full dplx */
+#define PCS_MII_RESTART_AUTONEG 0x0200 /* self clearing.
+ restart auto-
+ negotiation */
+#define PCS_MII_ISOLATE 0x0400 /* read as 0. ignored
+ on writes */
+#define PCS_MII_POWER_DOWN 0x0800 /* read as 0. ignored
+ on writes */
+#define PCS_MII_AUTONEG_EN 0x1000 /* default 1. PCS goes
+ through automatic
+ link config before it
+ can be used. when 0,
+ link can be used
+ w/out any link config
+ phase */
+#define PCS_MII_10_100_SEL 0x2000 /* read as 0. ignored on
+ writes */
+#define PCS_MII_RESET 0x8000 /* reset PCS. self-clears
+ when done */
+
+/* DEFAULT: 0x0108 */
+#define REG_PCS_MII_STATUS 0x9004 /* PCS MII status reg */
+#define PCS_MII_STATUS_EXTEND_CAP 0x0001 /* reads 0 */
+#define PCS_MII_STATUS_JABBER_DETECT 0x0002 /* reads 0 */
+#define PCS_MII_STATUS_LINK_STATUS 0x0004 /* 1 -> link up.
+ 0 -> link down. 0 is
+ latched so that 0 is
+ kept until read. read
+ 2x to determine if the
+ link has gone up again */
+#define PCS_MII_STATUS_AUTONEG_ABLE 0x0008 /* reads 1 (able to perform
+ auto-neg) */
+#define PCS_MII_STATUS_REMOTE_FAULT 0x0010 /* 1 -> remote fault detected
+ from received link code
+ word. only valid after
+ auto-neg completed */
+#define PCS_MII_STATUS_AUTONEG_COMP 0x0020 /* 1 -> auto-negotiation
+ completed
+ 0 -> auto-negotiation not
+ completed */
+#define PCS_MII_STATUS_EXTEND_STATUS 0x0100 /* reads as 1. used as an
+ indication that this is
+ a 1000 Base-X PHY. writes
+ to it are ignored */
+
+/* used during auto-negotiation.
+ * DEFAULT: 0x00E0
+ */
+#define REG_PCS_MII_ADVERT 0x9008 /* PCS MII advertisement
+ reg */
+#define PCS_MII_ADVERT_FD 0x0020 /* advertise full duplex
+ 1000 Base-X */
+#define PCS_MII_ADVERT_HD 0x0040 /* advertise half-duplex
+ 1000 Base-X */
+#define PCS_MII_ADVERT_SYM_PAUSE 0x0080 /* advertise PAUSE
+ symmetric capability */
+#define PCS_MII_ADVERT_ASYM_PAUSE 0x0100 /* advertises PAUSE
+ asymmetric capability */
+#define PCS_MII_ADVERT_RF_MASK 0x3000 /* remote fault. write bit13
+ to optionally indicate to
+ link partner that chip is
+ going off-line. bit12 will
+ get set when signal
+ detect == FAIL and will
+ remain set until
+ successful negotiation */
+#define PCS_MII_ADVERT_ACK 0x4000 /* (ro) */
+#define PCS_MII_ADVERT_NEXT_PAGE 0x8000 /* (ro) forced 0x0 */
+
+/* contents updated as a result of autonegotiation. layout and definitions
+ * identical to PCS_MII_ADVERT
+ */
+#define REG_PCS_MII_LPA 0x900C /* PCS MII link partner
+ ability reg */
+#define PCS_MII_LPA_FD PCS_MII_ADVERT_FD
+#define PCS_MII_LPA_HD PCS_MII_ADVERT_HD
+#define PCS_MII_LPA_SYM_PAUSE PCS_MII_ADVERT_SYM_PAUSE
+#define PCS_MII_LPA_ASYM_PAUSE PCS_MII_ADVERT_ASYM_PAUSE
+#define PCS_MII_LPA_RF_MASK PCS_MII_ADVERT_RF_MASK
+#define PCS_MII_LPA_ACK PCS_MII_ADVERT_ACK
+#define PCS_MII_LPA_NEXT_PAGE PCS_MII_ADVERT_NEXT_PAGE
+
+/* DEFAULT: 0x0 */
+#define REG_PCS_CFG 0x9010 /* PCS config reg */
+#define PCS_CFG_EN 0x01 /* enable PCS. must be
+ 0 when modifying
+ PCS_MII_ADVERT */
+#define PCS_CFG_SD_OVERRIDE 0x02 /* sets signal detect to
+ OK. bit is
+ non-resettable */
+#define PCS_CFG_SD_ACTIVE_LOW 0x04 /* changes interpretation
+ of optical signal to make
+ signal detect okay when
+ signal is low */
+#define PCS_CFG_JITTER_STUDY_MASK 0x18 /* used to make jitter
+ measurements. a single
+ code group is xmitted
+ regularly.
+ 0x0 = normal operation
+ 0x1 = high freq test
+ pattern, D21.5
+ 0x2 = low freq test
+ pattern, K28.7
+ 0x3 = reserved */
+#define PCS_CFG_10MS_TIMER_OVERRIDE 0x20 /* shortens 10-20ms auto-
+ negotiation timer to
+ a few cycles for test
+ purposes */
+
+/* used for diagnostic purposes. bits 20-22 autoclear on read */
+#define REG_PCS_STATE_MACHINE 0x9014 /* (ro) PCS state machine
+ and diagnostic reg */
+#define PCS_SM_TX_STATE_MASK 0x0000000F /* 0 and 1 indicate
+ xmission of idle.
+ otherwise, xmission of
+ a packet */
+#define PCS_SM_RX_STATE_MASK 0x000000F0 /* 0 indicates reception
+ of idle. otherwise,
+ reception of packet */
+#define PCS_SM_WORD_SYNC_STATE_MASK 0x00000700 /* 0 indicates loss of
+ sync */
+#define PCS_SM_SEQ_DETECT_STATE_MASK 0x00001800 /* cycling through 0-3
+ indicates reception of
+ Config codes. cycling
+ through 0-1 indicates
+ reception of idles */
+#define PCS_SM_LINK_STATE_MASK 0x0001E000
+#define SM_LINK_STATE_UP 0x00016000 /* link state is up */
+
+#define PCS_SM_LOSS_LINK_C 0x00100000 /* loss of link due to
+ recept of Config
+ codes */
+#define PCS_SM_LOSS_LINK_SYNC 0x00200000 /* loss of link due to
+ loss of sync */
+#define PCS_SM_LOSS_SIGNAL_DETECT 0x00400000 /* signal detect goes
+ from OK to FAIL. bit29
+ will also be set if
+ this is set */
+#define PCS_SM_NO_LINK_BREAKLINK 0x01000000 /* link not up due to
+ receipt of breaklink
+ C codes from partner.
+ C codes w/ 0 content
+ received triggering
+ start/restart of
+ autonegotiation.
+ should be sent for
+ no longer than 20ms */
+#define PCS_SM_NO_LINK_SERDES 0x02000000 /* serdes being
+ initialized. see serdes
+ state reg */
+#define PCS_SM_NO_LINK_C 0x04000000 /* C codes not stable or
+ not received */
+#define PCS_SM_NO_LINK_SYNC 0x08000000 /* word sync not
+ achieved */
+#define PCS_SM_NO_LINK_WAIT_C 0x10000000 /* waiting for C codes
+ w/ ack bit set */
+#define PCS_SM_NO_LINK_NO_IDLE 0x20000000 /* link partner continues
+ to send C codes
+ instead of idle
+ symbols or pkt data */
+
+/* this register indicates interrupt changes in specific PCS MII status bits.
+ * PCS_INT may be masked at the ISR level. only a single bit is implemented
+ * for link status change.
+ */
+#define REG_PCS_INTR_STATUS 0x9018 /* PCS interrupt status */
+#define PCS_INTR_STATUS_LINK_CHANGE 0x04 /* link status has changed
+ since last read */
+
+/* control which network interface is used. no more than one bit should
+ * be set.
+ * DEFAULT: none
+ */
+#define REG_PCS_DATAPATH_MODE 0x9050 /* datapath mode reg */
+#define PCS_DATAPATH_MODE_MII 0x00 /* PCS is not used and
+ MII/GMII is selected.
+ selection between MII and
+ GMII is controlled by
+ XIF_CFG */
+#define PCS_DATAPATH_MODE_SERDES 0x02 /* PCS is used via the
+ 10-bit interface */
+
+/* input to serdes chip or serialink block */
+#define REG_PCS_SERDES_CTRL 0x9054 /* serdes control reg */
+#define PCS_SERDES_CTRL_LOOPBACK 0x01 /* enable loopback on
+ serdes interface */
+#define PCS_SERDES_CTRL_SYNCD_EN 0x02 /* enable sync carrier
+ detection. should be
+ 0x0 for normal
+ operation */
+#define PCS_SERDES_CTRL_LOCKREF 0x04 /* frequency-lock RBC[0:1]
+ to REFCLK when set.
+ when clear, receiver
+ clock locks to incoming
+ serial data */
+
+/* multiplex test outputs into the PROM address (PA_3 through PA_0) pins.
+ * should be 0x0 for normal operations.
+ * 0b000 normal operation, PROM address[3:0] selected
+ * 0b001 rxdma req, rxdma ack, rxdma ready, rxdma read
+ * 0b010 rxmac req, rx ack, rx tag, rx clk shared
+ * 0b011 txmac req, tx ack, tx tag, tx retry req
+ * 0b100 tx tp3, tx tp2, tx tp1, tx tp0
+ * 0b101 R period RX, R period TX, R period HP, R period BIM
+ * DEFAULT: 0x0
+ */
+#define REG_PCS_SHARED_OUTPUT_SEL 0x9058 /* shared output select */
+#define PCS_SOS_PROM_ADDR_MASK 0x0007
+
+/* used for diagnostics. this register indicates progress of the SERDES
+ * boot up.
+ * 0b00 undergoing reset
+ * 0b01 waiting 500us while lockrefn is asserted
+ * 0b10 waiting for comma detect
+ * 0b11 receive data is synchronized
+ * DEFAULT: 0x0
+ */
+#define REG_PCS_SERDES_STATE 0x905C /* (ro) serdes state */
+#define PCS_SERDES_STATE_MASK 0x03
+
+/* used for diagnostics. indicates number of packets transmitted or received.
+ * counters rollover w/out generating an interrupt.
+ * DEFAULT: 0x0
+ */
+#define REG_PCS_PACKET_COUNT 0x9060 /* (ro) PCS packet counter */
+#define PCS_PACKET_COUNT_TX 0x000007FF /* pkts xmitted by PCS */
+#define PCS_PACKET_COUNT_RX 0x07FF0000 /* pkts recvd by PCS
+ whether they
+ encountered an error
+ or not */
+
+/** LocalBus Devices. the following provides run-time access to the
+ * Cassini's PROM
+ ***/
+#define REG_EXPANSION_ROM_RUN_START 0x100000 /* expansion rom run time
+ access */
+#define REG_EXPANSION_ROM_RUN_END 0x17FFFF
+
+#define REG_SECOND_LOCALBUS_START 0x180000 /* secondary local bus
+ device */
+#define REG_SECOND_LOCALBUS_END 0x1FFFFF
+
+/* entropy device */
+#define REG_ENTROPY_START REG_SECOND_LOCALBUS_START
+#define REG_ENTROPY_DATA (REG_ENTROPY_START + 0x00)
+#define REG_ENTROPY_STATUS (REG_ENTROPY_START + 0x04)
+#define ENTROPY_STATUS_DRDY 0x01
+#define ENTROPY_STATUS_BUSY 0x02
+#define ENTROPY_STATUS_CIPHER 0x04
+#define ENTROPY_STATUS_BYPASS_MASK 0x18
+#define REG_ENTROPY_MODE (REG_ENTROPY_START + 0x05)
+#define ENTROPY_MODE_KEY_MASK 0x07
+#define ENTROPY_MODE_ENCRYPT 0x40
+#define REG_ENTROPY_RAND_REG (REG_ENTROPY_START + 0x06)
+#define REG_ENTROPY_RESET (REG_ENTROPY_START + 0x07)
+#define ENTROPY_RESET_DES_IO 0x01
+#define ENTROPY_RESET_STC_MODE 0x02
+#define ENTROPY_RESET_KEY_CACHE 0x04
+#define ENTROPY_RESET_IV 0x08
+#define REG_ENTROPY_IV (REG_ENTROPY_START + 0x08)
+#define REG_ENTROPY_KEY0 (REG_ENTROPY_START + 0x10)
+#define REG_ENTROPY_KEYN(x) (REG_ENTROPY_KEY0 + 4*(x))
+
+/* phys of interest w/ their special mii registers */
+#define PHY_LUCENT_B0 0x00437421
+#define LUCENT_MII_REG 0x1F
+
+#define PHY_NS_DP83065 0x20005c78
+#define DP83065_MII_MEM 0x16
+#define DP83065_MII_REGD 0x1D
+#define DP83065_MII_REGE 0x1E
+
+#define PHY_BROADCOM_5411 0x00206071
+#define PHY_BROADCOM_B0 0x00206050
+#define BROADCOM_MII_REG4 0x14
+#define BROADCOM_MII_REG5 0x15
+#define BROADCOM_MII_REG7 0x17
+#define BROADCOM_MII_REG8 0x18
+
+#define CAS_MII_ANNPTR 0x07
+#define CAS_MII_ANNPRR 0x08
+#define CAS_MII_1000_CTRL 0x09
+#define CAS_MII_1000_STATUS 0x0A
+#define CAS_MII_1000_EXTEND 0x0F
+
+#define CAS_BMSR_1000_EXTEND 0x0100 /* supports 1000Base-T extended status */
+/*
+ * if autoneg is disabled, here's the table:
+ * BMCR_SPEED100 = 100Mbps
+ * BMCR_SPEED1000 = 1000Mbps
+ * ~(BMCR_SPEED100 | BMCR_SPEED1000) = 10Mbps
+ */
+#define CAS_BMCR_SPEED1000 0x0040 /* Select 1000Mbps */
+
+#define CAS_ADVERTISE_1000HALF 0x0100
+#define CAS_ADVERTISE_1000FULL 0x0200
+#define CAS_ADVERTISE_PAUSE 0x0400
+#define CAS_ADVERTISE_ASYM_PAUSE 0x0800
+
+/* regular lpa register */
+#define CAS_LPA_PAUSE CAS_ADVERTISE_PAUSE
+#define CAS_LPA_ASYM_PAUSE CAS_ADVERTISE_ASYM_PAUSE
+
+/* 1000_STATUS register */
+#define CAS_LPA_1000HALF 0x0400
+#define CAS_LPA_1000FULL 0x0800
+
+#define CAS_EXTEND_1000XFULL 0x8000
+#define CAS_EXTEND_1000XHALF 0x4000
+#define CAS_EXTEND_1000TFULL 0x2000
+#define CAS_EXTEND_1000THALF 0x1000
+
+/* cassini header parser firmware */
+typedef struct cas_hp_inst {
+ const char *note;
+
+ u16 mask, val;
+
+ u8 op;
+ u8 soff, snext; /* if match succeeds, new offset and match */
+ u8 foff, fnext; /* if match fails, new offset and match */
+ /* output info */
+ u8 outop; /* output opcode */
+
+ u16 outarg; /* output argument */
+ u8 outenab; /* output enable: 0 = not, 1 = if match
+ 2 = if !match, 3 = always */
+ u8 outshift; /* barrel shift right, 4 bits */
+ u16 outmask;
+} cas_hp_inst_t;
+
+/* comparison */
+#define OP_EQ 0 /* packet == value */
+#define OP_LT 1 /* packet < value */
+#define OP_GT 2 /* packet > value */
+#define OP_NP 3 /* new packet */
+
+/* output opcodes */
+#define CL_REG 0
+#define LD_FID 1
+#define LD_SEQ 2
+#define LD_CTL 3
+#define LD_SAP 4
+#define LD_R1 5
+#define LD_L3 6
+#define LD_SUM 7
+#define LD_HDR 8
+#define IM_FID 9
+#define IM_SEQ 10
+#define IM_SAP 11
+#define IM_R1 12
+#define IM_CTL 13
+#define LD_LEN 14
+#define ST_FLG 15
+
+/* match setp #s for IP4TCP4 */
+#define S1_PCKT 0
+#define S1_VLAN 1
+#define S1_CFI 2
+#define S1_8023 3
+#define S1_LLC 4
+#define S1_LLCc 5
+#define S1_IPV4 6
+#define S1_IPV4c 7
+#define S1_IPV4F 8
+#define S1_TCP44 9
+#define S1_IPV6 10
+#define S1_IPV6L 11
+#define S1_IPV6c 12
+#define S1_TCP64 13
+#define S1_TCPSQ 14
+#define S1_TCPFG 15
+#define S1_TCPHL 16
+#define S1_TCPHc 17
+#define S1_CLNP 18
+#define S1_CLNP2 19
+#define S1_DROP 20
+#define S2_HTTP 21
+#define S1_ESP4 22
+#define S1_AH4 23
+#define S1_ESP6 24
+#define S1_AH6 25
+
+#define CAS_PROG_IP46TCP4_PREAMBLE \
+{ "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0, S1_PCKT, \
+ CL_REG, 0x3ff, 1, 0x0, 0x0000}, \
+{ "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023, \
+ IM_CTL, 0x00a, 3, 0x0, 0xffff}, \
+{ "CFI?", 0x1000, 0x1000, OP_EQ, 0, S1_DROP, 1, S1_8023, \
+ CL_REG, 0x000, 0, 0x0, 0x0000}, \
+{ "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4, \
+ CL_REG, 0x000, 0, 0x0, 0x0000}, \
+{ "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S1_CLNP, \
+ CL_REG, 0x000, 0, 0x0, 0x0000}, \
+{ "LLCc?", 0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S1_CLNP, \
+ CL_REG, 0x000, 0, 0x0, 0x0000}, \
+{ "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6, \
+ LD_SAP, 0x100, 3, 0x0, 0xffff}, \
+{ "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S1_CLNP, \
+ LD_SUM, 0x00a, 1, 0x0, 0x0000}, \
+{ "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S1_CLNP, \
+ LD_LEN, 0x03e, 1, 0x0, 0xffff}, \
+{ "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S1_TCPSQ, 0, S1_CLNP, \
+ LD_FID, 0x182, 1, 0x0, 0xffff}, /* FID IP4&TCP src+dst */ \
+{ "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S1_IPV6L, 0, S1_CLNP, \
+ LD_SUM, 0x015, 1, 0x0, 0x0000}, \
+{ "IPV6 len", 0xf000, 0x6000, OP_EQ, 0, S1_IPV6c, 0, S1_CLNP, \
+ IM_R1, 0x128, 1, 0x0, 0xffff}, \
+{ "IPV6 cont?", 0x0000, 0x0000, OP_EQ, 3, S1_TCP64, 0, S1_CLNP, \
+ LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */ \
+{ "TCP64?", 0xff00, 0x0600, OP_EQ, 18, S1_TCPSQ, 0, S1_CLNP, \
+ LD_LEN, 0x03f, 1, 0x0, 0xffff}
+
+#ifdef USE_HP_IP46TCP4
+static cas_hp_inst_t cas_prog_ip46tcp4tab[] = {
+ CAS_PROG_IP46TCP4_PREAMBLE,
+ { "TCP seq", /* DADDR should point to dest port */
+ 0x0000, 0x0000, OP_EQ, 0, S1_TCPFG, 4, S1_TCPFG, LD_SEQ,
+ 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */
+ { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHL, 0,
+ S1_TCPHL, ST_FLG, 0x045, 3, 0x0, 0x002f}, /* Load TCP flags */
+ { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0,
+ S1_TCPHc, LD_R1, 0x205, 3, 0xB, 0xf000},
+ { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0,
+ S1_PCKT, LD_HDR, 0x0ff, 3, 0x0, 0xffff},
+ { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2,
+ IM_CTL, 0x001, 3, 0x0, 0x0001},
+ { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x000, 0, 0x0, 0x0000},
+ { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x080, 3, 0x0, 0xffff},
+ { NULL },
+};
+#ifdef HP_IP46TCP4_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_ip46tcp4tab
+#endif
+#endif
+
+/*
+ * Alternate table load which excludes HTTP server traffic from reassembly.
+ * It is substantially similar to the basic table, with one extra state
+ * and a few extra compares. */
+#ifdef USE_HP_IP46TCP4NOHTTP
+static cas_hp_inst_t cas_prog_ip46tcp4nohttptab[] = {
+ CAS_PROG_IP46TCP4_PREAMBLE,
+ { "TCP seq", /* DADDR should point to dest port */
+ 0xFFFF, 0x0080, OP_EQ, 0, S2_HTTP, 0, S1_TCPFG, LD_SEQ,
+ 0x081, 3, 0x0, 0xffff} , /* Load TCP seq # */
+ { "TCP control flags", 0xFFFF, 0x8080, OP_EQ, 0, S2_HTTP, 0,
+ S1_TCPHL, ST_FLG, 0x145, 2, 0x0, 0x002f, }, /* Load TCP flags */
+ { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, S1_TCPHc,
+ LD_R1, 0x205, 3, 0xB, 0xf000},
+ { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ LD_HDR, 0x0ff, 3, 0x0, 0xffff},
+ { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2,
+ IM_CTL, 0x001, 3, 0x0, 0x0001},
+ { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ CL_REG, 0x002, 3, 0x0, 0x0000},
+ { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x080, 3, 0x0, 0xffff},
+ { "No HTTP", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x044, 3, 0x0, 0xffff},
+ { NULL },
+};
+#ifdef HP_IP46TCP4NOHTTP_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_ip46tcp4nohttptab
+#endif
+#endif
+
+/* match step #s for IP4FRAG */
+#define S3_IPV6c 11
+#define S3_TCP64 12
+#define S3_TCPSQ 13
+#define S3_TCPFG 14
+#define S3_TCPHL 15
+#define S3_TCPHc 16
+#define S3_FRAG 17
+#define S3_FOFF 18
+#define S3_CLNP 19
+
+#ifdef USE_HP_IP4FRAG
+static cas_hp_inst_t cas_prog_ip4fragtab[] = {
+ { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0, S1_PCKT,
+ CL_REG, 0x3ff, 1, 0x0, 0x0000},
+ { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023,
+ IM_CTL, 0x00a, 3, 0x0, 0xffff},
+ { "CFI?", 0x1000, 0x1000, OP_EQ, 0, S3_CLNP, 1, S1_8023,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S3_CLNP,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "LLCc?",0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S3_CLNP,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6,
+ LD_SAP, 0x100, 3, 0x0, 0xffff},
+ { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S3_CLNP,
+ LD_SUM, 0x00a, 1, 0x0, 0x0000},
+ { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S3_FRAG,
+ LD_LEN, 0x03e, 3, 0x0, 0xffff},
+ { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S3_TCPSQ, 0, S3_CLNP,
+ LD_FID, 0x182, 3, 0x0, 0xffff}, /* FID IP4&TCP src+dst */
+ { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S3_IPV6c, 0, S3_CLNP,
+ LD_SUM, 0x015, 1, 0x0, 0x0000},
+ { "IPV6 cont?", 0xf000, 0x6000, OP_EQ, 3, S3_TCP64, 0, S3_CLNP,
+ LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */
+ { "TCP64?", 0xff00, 0x0600, OP_EQ, 18, S3_TCPSQ, 0, S3_CLNP,
+ LD_LEN, 0x03f, 1, 0x0, 0xffff},
+ { "TCP seq", /* DADDR should point to dest port */
+ 0x0000, 0x0000, OP_EQ, 0, S3_TCPFG, 4, S3_TCPFG, LD_SEQ,
+ 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */
+ { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S3_TCPHL, 0,
+ S3_TCPHL, ST_FLG, 0x045, 3, 0x0, 0x002f}, /* Load TCP flags */
+ { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S3_TCPHc, 0, S3_TCPHc,
+ LD_R1, 0x205, 3, 0xB, 0xf000},
+ { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ LD_HDR, 0x0ff, 3, 0x0, 0xffff},
+ { "IP4 Fragment", 0x0000, 0x0000, OP_EQ, 0, S3_FOFF, 0, S3_FOFF,
+ LD_FID, 0x103, 3, 0x0, 0xffff}, /* FID IP4 src+dst */
+ { "IP4 frag offset", 0x0000, 0x0000, OP_EQ, 0, S3_FOFF, 0, S3_FOFF,
+ LD_SEQ, 0x040, 1, 0xD, 0xfff8},
+ { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x001, 3, 0x0, 0x0001},
+ { NULL },
+};
+#ifdef HP_IP4FRAG_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_ip4fragtab
+#endif
+#endif
+
+/*
+ * Alternate table which does batching without reassembly
+ */
+#ifdef USE_HP_IP46TCP4BATCH
+static cas_hp_inst_t cas_prog_ip46tcp4batchtab[] = {
+ CAS_PROG_IP46TCP4_PREAMBLE,
+ { "TCP seq", /* DADDR should point to dest port */
+ 0x0000, 0x0000, OP_EQ, 0, S1_TCPFG, 0, S1_TCPFG, LD_SEQ,
+ 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */
+ { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHL, 0,
+ S1_TCPHL, ST_FLG, 0x000, 3, 0x0, 0x0000}, /* Load TCP flags */
+ { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0,
+ S1_TCPHc, LD_R1, 0x205, 3, 0xB, 0xf000},
+ { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0,
+ S1_PCKT, IM_CTL, 0x040, 3, 0x0, 0xffff}, /* set batch bit */
+ { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x001, 3, 0x0, 0x0001},
+ { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0,
+ S1_PCKT, IM_CTL, 0x080, 3, 0x0, 0xffff},
+ { NULL },
+};
+#ifdef HP_IP46TCP4BATCH_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_ip46tcp4batchtab
+#endif
+#endif
+
+/* Workaround for Cassini rev2 descriptor corruption problem.
+ * Does batching without reassembly, and sets the SAP to a known
+ * data pattern for all packets.
+ */
+#ifdef USE_HP_WORKAROUND
+static cas_hp_inst_t cas_prog_workaroundtab[] = {
+ { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0,
+ S1_PCKT, CL_REG, 0x3ff, 1, 0x0, 0x0000} ,
+ { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023,
+ IM_CTL, 0x04a, 3, 0x0, 0xffff},
+ { "CFI?", 0x1000, 0x1000, OP_EQ, 0, S1_CLNP, 1, S1_8023,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S1_CLNP,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "LLCc?", 0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S1_CLNP,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6,
+ IM_SAP, 0x6AE, 3, 0x0, 0xffff},
+ { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S1_CLNP,
+ LD_SUM, 0x00a, 1, 0x0, 0x0000},
+ { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S1_CLNP,
+ LD_LEN, 0x03e, 1, 0x0, 0xffff},
+ { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S1_TCPSQ, 0, S1_CLNP,
+ LD_FID, 0x182, 3, 0x0, 0xffff}, /* FID IP4&TCP src+dst */
+ { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S1_IPV6L, 0, S1_CLNP,
+ LD_SUM, 0x015, 1, 0x0, 0x0000},
+ { "IPV6 len", 0xf000, 0x6000, OP_EQ, 0, S1_IPV6c, 0, S1_CLNP,
+ IM_R1, 0x128, 1, 0x0, 0xffff},
+ { "IPV6 cont?", 0x0000, 0x0000, OP_EQ, 3, S1_TCP64, 0, S1_CLNP,
+ LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */
+ { "TCP64?", 0xff00, 0x0600, OP_EQ, 18, S1_TCPSQ, 0, S1_CLNP,
+ LD_LEN, 0x03f, 1, 0x0, 0xffff},
+ { "TCP seq", /* DADDR should point to dest port */
+ 0x0000, 0x0000, OP_EQ, 0, S1_TCPFG, 4, S1_TCPFG, LD_SEQ,
+ 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */
+ { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHL, 0,
+ S1_TCPHL, ST_FLG, 0x045, 3, 0x0, 0x002f}, /* Load TCP flags */
+ { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, S1_TCPHc,
+ LD_R1, 0x205, 3, 0xB, 0xf000},
+ { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0,
+ S1_PCKT, LD_HDR, 0x0ff, 3, 0x0, 0xffff},
+ { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2,
+ IM_SAP, 0x6AE, 3, 0x0, 0xffff} ,
+ { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x001, 3, 0x0, 0x0001},
+ { NULL },
+};
+#ifdef HP_WORKAROUND_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_workaroundtab
+#endif
+#endif
+
+#ifdef USE_HP_ENCRYPT
+static cas_hp_inst_t cas_prog_encryptiontab[] = {
+ { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0,
+ S1_PCKT, CL_REG, 0x3ff, 1, 0x0, 0x0000},
+ { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023,
+ IM_CTL, 0x00a, 3, 0x0, 0xffff},
+#if 0
+//"CFI?", /* 02 FIND CFI and If FIND go to S1_DROP */
+//0x1000, 0x1000, OP_EQ, 0, S1_DROP, 1, S1_8023, CL_REG, 0x000, 0, 0x0, 0x00
+ 00,
+#endif
+ { "CFI?", /* FIND CFI and If FIND go to CleanUP1 (ignore and send to host) */
+ 0x1000, 0x1000, OP_EQ, 0, S1_CLNP, 1, S1_8023,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S1_CLNP,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "LLCc?", 0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S1_CLNP,
+ CL_REG, 0x000, 0, 0x0, 0x0000},
+ { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6,
+ LD_SAP, 0x100, 3, 0x0, 0xffff},
+ { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S1_CLNP,
+ LD_SUM, 0x00a, 1, 0x0, 0x0000},
+ { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S1_CLNP,
+ LD_LEN, 0x03e, 1, 0x0, 0xffff},
+ { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S1_TCPSQ, 0, S1_ESP4,
+ LD_FID, 0x182, 1, 0x0, 0xffff}, /* FID IP4&TCP src+dst */
+ { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S1_IPV6L, 0, S1_CLNP,
+ LD_SUM, 0x015, 1, 0x0, 0x0000},
+ { "IPV6 len", 0xf000, 0x6000, OP_EQ, 0, S1_IPV6c, 0, S1_CLNP,
+ IM_R1, 0x128, 1, 0x0, 0xffff},
+ { "IPV6 cont?", 0x0000, 0x0000, OP_EQ, 3, S1_TCP64, 0, S1_CLNP,
+ LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */
+ { "TCP64?",
+#if 0
+//@@@0xff00, 0x0600, OP_EQ, 18, S1_TCPSQ, 0, S1_ESP6, LD_LEN, 0x03f, 1, 0x0, 0xffff,
+#endif
+ 0xff00, 0x0600, OP_EQ, 12, S1_TCPSQ, 0, S1_ESP6, LD_LEN,
+ 0x03f, 1, 0x0, 0xffff},
+ { "TCP seq", /* 14:DADDR should point to dest port */
+ 0xFFFF, 0x0080, OP_EQ, 0, S2_HTTP, 0, S1_TCPFG, LD_SEQ,
+ 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */
+ { "TCP control flags", 0xFFFF, 0x8080, OP_EQ, 0, S2_HTTP, 0,
+ S1_TCPHL, ST_FLG, 0x145, 2, 0x0, 0x002f}, /* Load TCP flags */
+ { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, S1_TCPHc,
+ LD_R1, 0x205, 3, 0xB, 0xf000} ,
+ { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0,
+ S1_PCKT, LD_HDR, 0x0ff, 3, 0x0, 0xffff},
+ { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2,
+ IM_CTL, 0x001, 3, 0x0, 0x0001},
+ { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ CL_REG, 0x002, 3, 0x0, 0x0000},
+ { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x080, 3, 0x0, 0xffff},
+ { "No HTTP", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT,
+ IM_CTL, 0x044, 3, 0x0, 0xffff},
+ { "IPV4 ESP encrypted?", /* S1_ESP4 */
+ 0x00ff, 0x0032, OP_EQ, 0, S1_CLNP2, 0, S1_AH4, IM_CTL,
+ 0x021, 1, 0x0, 0xffff},
+ { "IPV4 AH encrypted?", /* S1_AH4 */
+ 0x00ff, 0x0033, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP, IM_CTL,
+ 0x021, 1, 0x0, 0xffff},
+ { "IPV6 ESP encrypted?", /* S1_ESP6 */
+#if 0
+//@@@0x00ff, 0x0032, OP_EQ, 0, S1_CLNP2, 0, S1_AH6, IM_CTL, 0x021, 1, 0x0, 0xffff,
+#endif
+ 0xff00, 0x3200, OP_EQ, 0, S1_CLNP2, 0, S1_AH6, IM_CTL,
+ 0x021, 1, 0x0, 0xffff},
+ { "IPV6 AH encrypted?", /* S1_AH6 */
+#if 0
+//@@@0x00ff, 0x0033, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP, IM_CTL, 0x021, 1, 0x0, 0xffff,
+#endif
+ 0xff00, 0x3300, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP, IM_CTL,
+ 0x021, 1, 0x0, 0xffff},
+ { NULL },
+};
+#ifdef HP_ENCRYPT_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_encryptiontab
+#endif
+#endif
+
+static cas_hp_inst_t cas_prog_null[] = { {NULL} };
+#ifdef HP_NULL_DEFAULT
+#define CAS_HP_FIRMWARE cas_prog_null
+#endif
+
+/* firmware patch for NS_DP83065 */
+typedef struct cas_saturn_patch {
+ u16 addr;
+ u16 val;
+} cas_saturn_patch_t;
+
+#if 1
+cas_saturn_patch_t cas_saturn_patch[] = {
+{0x8200, 0x007e}, {0x8201, 0x0082}, {0x8202, 0x0009},
+{0x8203, 0x0000}, {0x8204, 0x0000}, {0x8205, 0x0000},
+{0x8206, 0x0000}, {0x8207, 0x0000}, {0x8208, 0x0000},
+{0x8209, 0x008e}, {0x820a, 0x008e}, {0x820b, 0x00ff},
+{0x820c, 0x00ce}, {0x820d, 0x0082}, {0x820e, 0x0025},
+{0x820f, 0x00ff}, {0x8210, 0x0001}, {0x8211, 0x000f},
+{0x8212, 0x00ce}, {0x8213, 0x0084}, {0x8214, 0x0026},
+{0x8215, 0x00ff}, {0x8216, 0x0001}, {0x8217, 0x0011},
+{0x8218, 0x00ce}, {0x8219, 0x0085}, {0x821a, 0x003d},
+{0x821b, 0x00df}, {0x821c, 0x00e5}, {0x821d, 0x0086},
+{0x821e, 0x0039}, {0x821f, 0x00b7}, {0x8220, 0x008f},
+{0x8221, 0x00f8}, {0x8222, 0x007e}, {0x8223, 0x00c3},
+{0x8224, 0x00c2}, {0x8225, 0x0096}, {0x8226, 0x0047},
+{0x8227, 0x0084}, {0x8228, 0x00f3}, {0x8229, 0x008a},
+{0x822a, 0x0000}, {0x822b, 0x0097}, {0x822c, 0x0047},
+{0x822d, 0x00ce}, {0x822e, 0x0082}, {0x822f, 0x0033},
+{0x8230, 0x00ff}, {0x8231, 0x0001}, {0x8232, 0x000f},
+{0x8233, 0x0096}, {0x8234, 0x0046}, {0x8235, 0x0084},
+{0x8236, 0x000c}, {0x8237, 0x0081}, {0x8238, 0x0004},
+{0x8239, 0x0027}, {0x823a, 0x000b}, {0x823b, 0x0096},
+{0x823c, 0x0046}, {0x823d, 0x0084}, {0x823e, 0x000c},
+{0x823f, 0x0081}, {0x8240, 0x0008}, {0x8241, 0x0027},
+{0x8242, 0x0057}, {0x8243, 0x007e}, {0x8244, 0x0084},
+{0x8245, 0x0025}, {0x8246, 0x0096}, {0x8247, 0x0047},
+{0x8248, 0x0084}, {0x8249, 0x00f3}, {0x824a, 0x008a},
+{0x824b, 0x0004}, {0x824c, 0x0097}, {0x824d, 0x0047},
+{0x824e, 0x00ce}, {0x824f, 0x0082}, {0x8250, 0x0054},
+{0x8251, 0x00ff}, {0x8252, 0x0001}, {0x8253, 0x000f},
+{0x8254, 0x0096}, {0x8255, 0x0046}, {0x8256, 0x0084},
+{0x8257, 0x000c}, {0x8258, 0x0081}, {0x8259, 0x0004},
+{0x825a, 0x0026}, {0x825b, 0x0038}, {0x825c, 0x00b6},
+{0x825d, 0x0012}, {0x825e, 0x0020}, {0x825f, 0x0084},
+{0x8260, 0x0020}, {0x8261, 0x0026}, {0x8262, 0x0003},
+{0x8263, 0x007e}, {0x8264, 0x0084}, {0x8265, 0x0025},
+{0x8266, 0x0096}, {0x8267, 0x007b}, {0x8268, 0x00d6},
+{0x8269, 0x007c}, {0x826a, 0x00fe}, {0x826b, 0x008f},
+{0x826c, 0x0056}, {0x826d, 0x00bd}, {0x826e, 0x00f7},
+{0x826f, 0x00b6}, {0x8270, 0x00fe}, {0x8271, 0x008f},
+{0x8272, 0x004e}, {0x8273, 0x00bd}, {0x8274, 0x00ec},
+{0x8275, 0x008e}, {0x8276, 0x00bd}, {0x8277, 0x00fa},
+{0x8278, 0x00f7}, {0x8279, 0x00bd}, {0x827a, 0x00f7},
+{0x827b, 0x0028}, {0x827c, 0x00ce}, {0x827d, 0x0082},
+{0x827e, 0x0082}, {0x827f, 0x00ff}, {0x8280, 0x0001},
+{0x8281, 0x000f}, {0x8282, 0x0096}, {0x8283, 0x0046},
+{0x8284, 0x0084}, {0x8285, 0x000c}, {0x8286, 0x0081},
+{0x8287, 0x0004}, {0x8288, 0x0026}, {0x8289, 0x000a},
+{0x828a, 0x00b6}, {0x828b, 0x0012}, {0x828c, 0x0020},
+{0x828d, 0x0084}, {0x828e, 0x0020}, {0x828f, 0x0027},
+{0x8290, 0x00b5}, {0x8291, 0x007e}, {0x8292, 0x0084},
+{0x8293, 0x0025}, {0x8294, 0x00bd}, {0x8295, 0x00f7},
+{0x8296, 0x001f}, {0x8297, 0x007e}, {0x8298, 0x0084},
+{0x8299, 0x001f}, {0x829a, 0x0096}, {0x829b, 0x0047},
+{0x829c, 0x0084}, {0x829d, 0x00f3}, {0x829e, 0x008a},
+{0x829f, 0x0008}, {0x82a0, 0x0097}, {0x82a1, 0x0047},
+{0x82a2, 0x00de}, {0x82a3, 0x00e1}, {0x82a4, 0x00ad},
+{0x82a5, 0x0000}, {0x82a6, 0x00ce}, {0x82a7, 0x0082},
+{0x82a8, 0x00af}, {0x82a9, 0x00ff}, {0x82aa, 0x0001},
+{0x82ab, 0x000f}, {0x82ac, 0x007e}, {0x82ad, 0x0084},
+{0x82ae, 0x0025}, {0x82af, 0x0096}, {0x82b0, 0x0041},
+{0x82b1, 0x0085}, {0x82b2, 0x0010}, {0x82b3, 0x0026},
+{0x82b4, 0x0006}, {0x82b5, 0x0096}, {0x82b6, 0x0023},
+{0x82b7, 0x0085}, {0x82b8, 0x0040}, {0x82b9, 0x0027},
+{0x82ba, 0x0006}, {0x82bb, 0x00bd}, {0x82bc, 0x00ed},
+{0x82bd, 0x0000}, {0x82be, 0x007e}, {0x82bf, 0x0083},
+{0x82c0, 0x00a2}, {0x82c1, 0x00de}, {0x82c2, 0x0042},
+{0x82c3, 0x00bd}, {0x82c4, 0x00eb}, {0x82c5, 0x008e},
+{0x82c6, 0x0096}, {0x82c7, 0x0024}, {0x82c8, 0x0084},
+{0x82c9, 0x0008}, {0x82ca, 0x0027}, {0x82cb, 0x0003},
+{0x82cc, 0x007e}, {0x82cd, 0x0083}, {0x82ce, 0x00df},
+{0x82cf, 0x0096}, {0x82d0, 0x007b}, {0x82d1, 0x00d6},
+{0x82d2, 0x007c}, {0x82d3, 0x00fe}, {0x82d4, 0x008f},
+{0x82d5, 0x0056}, {0x82d6, 0x00bd}, {0x82d7, 0x00f7},
+{0x82d8, 0x00b6}, {0x82d9, 0x00fe}, {0x82da, 0x008f},
+{0x82db, 0x0050}, {0x82dc, 0x00bd}, {0x82dd, 0x00ec},
+{0x82de, 0x008e}, {0x82df, 0x00bd}, {0x82e0, 0x00fa},
+{0x82e1, 0x00f7}, {0x82e2, 0x0086}, {0x82e3, 0x0011},
+{0x82e4, 0x00c6}, {0x82e5, 0x0049}, {0x82e6, 0x00bd},
+{0x82e7, 0x00e4}, {0x82e8, 0x0012}, {0x82e9, 0x00ce},
+{0x82ea, 0x0082}, {0x82eb, 0x00ef}, {0x82ec, 0x00ff},
+{0x82ed, 0x0001}, {0x82ee, 0x000f}, {0x82ef, 0x0096},
+{0x82f0, 0x0046}, {0x82f1, 0x0084}, {0x82f2, 0x000c},
+{0x82f3, 0x0081}, {0x82f4, 0x0000}, {0x82f5, 0x0027},
+{0x82f6, 0x0017}, {0x82f7, 0x00c6}, {0x82f8, 0x0049},
+{0x82f9, 0x00bd}, {0x82fa, 0x00e4}, {0x82fb, 0x0091},
+{0x82fc, 0x0024}, {0x82fd, 0x000d}, {0x82fe, 0x00b6},
+{0x82ff, 0x0012}, {0x8300, 0x0020}, {0x8301, 0x0085},
+{0x8302, 0x0020}, {0x8303, 0x0026}, {0x8304, 0x000c},
+{0x8305, 0x00ce}, {0x8306, 0x0082}, {0x8307, 0x00c1},
+{0x8308, 0x00ff}, {0x8309, 0x0001}, {0x830a, 0x000f},
+{0x830b, 0x007e}, {0x830c, 0x0084}, {0x830d, 0x0025},
+{0x830e, 0x007e}, {0x830f, 0x0084}, {0x8310, 0x0016},
+{0x8311, 0x00fe}, {0x8312, 0x008f}, {0x8313, 0x0052},
+{0x8314, 0x00bd}, {0x8315, 0x00ec}, {0x8316, 0x008e},
+{0x8317, 0x00bd}, {0x8318, 0x00fa}, {0x8319, 0x00f7},
+{0x831a, 0x0086}, {0x831b, 0x006a}, {0x831c, 0x00c6},
+{0x831d, 0x0049}, {0x831e, 0x00bd}, {0x831f, 0x00e4},
+{0x8320, 0x0012}, {0x8321, 0x00ce}, {0x8322, 0x0083},
+{0x8323, 0x0027}, {0x8324, 0x00ff}, {0x8325, 0x0001},
+{0x8326, 0x000f}, {0x8327, 0x0096}, {0x8328, 0x0046},
+{0x8329, 0x0084}, {0x832a, 0x000c}, {0x832b, 0x0081},
+{0x832c, 0x0000}, {0x832d, 0x0027}, {0x832e, 0x000a},
+{0x832f, 0x00c6}, {0x8330, 0x0049}, {0x8331, 0x00bd},
+{0x8332, 0x00e4}, {0x8333, 0x0091}, {0x8334, 0x0025},
+{0x8335, 0x0006}, {0x8336, 0x007e}, {0x8337, 0x0084},
+{0x8338, 0x0025}, {0x8339, 0x007e}, {0x833a, 0x0084},
+{0x833b, 0x0016}, {0x833c, 0x00b6}, {0x833d, 0x0018},
+{0x833e, 0x0070}, {0x833f, 0x00bb}, {0x8340, 0x0019},
+{0x8341, 0x0070}, {0x8342, 0x002a}, {0x8343, 0x0004},
+{0x8344, 0x0081}, {0x8345, 0x00af}, {0x8346, 0x002e},
+{0x8347, 0x0019}, {0x8348, 0x0096}, {0x8349, 0x007b},
+{0x834a, 0x00f6}, {0x834b, 0x0020}, {0x834c, 0x0007},
+{0x834d, 0x00fa}, {0x834e, 0x0020}, {0x834f, 0x0027},
+{0x8350, 0x00c4}, {0x8351, 0x0038}, {0x8352, 0x0081},
+{0x8353, 0x0038}, {0x8354, 0x0027}, {0x8355, 0x000b},
+{0x8356, 0x00f6}, {0x8357, 0x0020}, {0x8358, 0x0007},
+{0x8359, 0x00fa}, {0x835a, 0x0020}, {0x835b, 0x0027},
+{0x835c, 0x00cb}, {0x835d, 0x0008}, {0x835e, 0x007e},
+{0x835f, 0x0082}, {0x8360, 0x00d3}, {0x8361, 0x00bd},
+{0x8362, 0x00f7}, {0x8363, 0x0066}, {0x8364, 0x0086},
+{0x8365, 0x0074}, {0x8366, 0x00c6}, {0x8367, 0x0049},
+{0x8368, 0x00bd}, {0x8369, 0x00e4}, {0x836a, 0x0012},
+{0x836b, 0x00ce}, {0x836c, 0x0083}, {0x836d, 0x0071},
+{0x836e, 0x00ff}, {0x836f, 0x0001}, {0x8370, 0x000f},
+{0x8371, 0x0096}, {0x8372, 0x0046}, {0x8373, 0x0084},
+{0x8374, 0x000c}, {0x8375, 0x0081}, {0x8376, 0x0008},
+{0x8377, 0x0026}, {0x8378, 0x000a}, {0x8379, 0x00c6},
+{0x837a, 0x0049}, {0x837b, 0x00bd}, {0x837c, 0x00e4},
+{0x837d, 0x0091}, {0x837e, 0x0025}, {0x837f, 0x0006},
+{0x8380, 0x007e}, {0x8381, 0x0084}, {0x8382, 0x0025},
+{0x8383, 0x007e}, {0x8384, 0x0084}, {0x8385, 0x0016},
+{0x8386, 0x00bd}, {0x8387, 0x00f7}, {0x8388, 0x003e},
+{0x8389, 0x0026}, {0x838a, 0x000e}, {0x838b, 0x00bd},
+{0x838c, 0x00e5}, {0x838d, 0x0009}, {0x838e, 0x0026},
+{0x838f, 0x0006}, {0x8390, 0x00ce}, {0x8391, 0x0082},
+{0x8392, 0x00c1}, {0x8393, 0x00ff}, {0x8394, 0x0001},
+{0x8395, 0x000f}, {0x8396, 0x007e}, {0x8397, 0x0084},
+{0x8398, 0x0025}, {0x8399, 0x00fe}, {0x839a, 0x008f},
+{0x839b, 0x0054}, {0x839c, 0x00bd}, {0x839d, 0x00ec},
+{0x839e, 0x008e}, {0x839f, 0x00bd}, {0x83a0, 0x00fa},
+{0x83a1, 0x00f7}, {0x83a2, 0x00bd}, {0x83a3, 0x00f7},
+{0x83a4, 0x0033}, {0x83a5, 0x0086}, {0x83a6, 0x000f},
+{0x83a7, 0x00c6}, {0x83a8, 0x0051}, {0x83a9, 0x00bd},
+{0x83aa, 0x00e4}, {0x83ab, 0x0012}, {0x83ac, 0x00ce},
+{0x83ad, 0x0083}, {0x83ae, 0x00b2}, {0x83af, 0x00ff},
+{0x83b0, 0x0001}, {0x83b1, 0x000f}, {0x83b2, 0x0096},
+{0x83b3, 0x0046}, {0x83b4, 0x0084}, {0x83b5, 0x000c},
+{0x83b6, 0x0081}, {0x83b7, 0x0008}, {0x83b8, 0x0026},
+{0x83b9, 0x005c}, {0x83ba, 0x00b6}, {0x83bb, 0x0012},
+{0x83bc, 0x0020}, {0x83bd, 0x0084}, {0x83be, 0x003f},
+{0x83bf, 0x0081}, {0x83c0, 0x003a}, {0x83c1, 0x0027},
+{0x83c2, 0x001c}, {0x83c3, 0x0096}, {0x83c4, 0x0023},
+{0x83c5, 0x0085}, {0x83c6, 0x0040}, {0x83c7, 0x0027},
+{0x83c8, 0x0003}, {0x83c9, 0x007e}, {0x83ca, 0x0084},
+{0x83cb, 0x0025}, {0x83cc, 0x00c6}, {0x83cd, 0x0051},
+{0x83ce, 0x00bd}, {0x83cf, 0x00e4}, {0x83d0, 0x0091},
+{0x83d1, 0x0025}, {0x83d2, 0x0003}, {0x83d3, 0x007e},
+{0x83d4, 0x0084}, {0x83d5, 0x0025}, {0x83d6, 0x00ce},
+{0x83d7, 0x0082}, {0x83d8, 0x00c1}, {0x83d9, 0x00ff},
+{0x83da, 0x0001}, {0x83db, 0x000f}, {0x83dc, 0x007e},
+{0x83dd, 0x0084}, {0x83de, 0x0025}, {0x83df, 0x00bd},
+{0x83e0, 0x00f8}, {0x83e1, 0x0037}, {0x83e2, 0x007c},
+{0x83e3, 0x0000}, {0x83e4, 0x007a}, {0x83e5, 0x00ce},
+{0x83e6, 0x0083}, {0x83e7, 0x00ee}, {0x83e8, 0x00ff},
+{0x83e9, 0x0001}, {0x83ea, 0x000f}, {0x83eb, 0x007e},
+{0x83ec, 0x0084}, {0x83ed, 0x0025}, {0x83ee, 0x0096},
+{0x83ef, 0x0046}, {0x83f0, 0x0084}, {0x83f1, 0x000c},
+{0x83f2, 0x0081}, {0x83f3, 0x0008}, {0x83f4, 0x0026},
+{0x83f5, 0x0020}, {0x83f6, 0x0096}, {0x83f7, 0x0024},
+{0x83f8, 0x0084}, {0x83f9, 0x0008}, {0x83fa, 0x0026},
+{0x83fb, 0x0029}, {0x83fc, 0x00b6}, {0x83fd, 0x0018},
+{0x83fe, 0x0082}, {0x83ff, 0x00bb}, {0x8400, 0x0019},
+{0x8401, 0x0082}, {0x8402, 0x00b1}, {0x8403, 0x0001},
+{0x8404, 0x003b}, {0x8405, 0x0022}, {0x8406, 0x0009},
+{0x8407, 0x00b6}, {0x8408, 0x0012}, {0x8409, 0x0020},
+{0x840a, 0x0084}, {0x840b, 0x0037}, {0x840c, 0x0081},
+{0x840d, 0x0032}, {0x840e, 0x0027}, {0x840f, 0x0015},
+{0x8410, 0x00bd}, {0x8411, 0x00f8}, {0x8412, 0x0044},
+{0x8413, 0x007e}, {0x8414, 0x0082}, {0x8415, 0x00c1},
+{0x8416, 0x00bd}, {0x8417, 0x00f7}, {0x8418, 0x001f},
+{0x8419, 0x00bd}, {0x841a, 0x00f8}, {0x841b, 0x0044},
+{0x841c, 0x00bd}, {0x841d, 0x00fc}, {0x841e, 0x0029},
+{0x841f, 0x00ce}, {0x8420, 0x0082}, {0x8421, 0x0025},
+{0x8422, 0x00ff}, {0x8423, 0x0001}, {0x8424, 0x000f},
+{0x8425, 0x0039}, {0x8426, 0x0096}, {0x8427, 0x0047},
+{0x8428, 0x0084}, {0x8429, 0x00fc}, {0x842a, 0x008a},
+{0x842b, 0x0000}, {0x842c, 0x0097}, {0x842d, 0x0047},
+{0x842e, 0x00ce}, {0x842f, 0x0084}, {0x8430, 0x0034},
+{0x8431, 0x00ff}, {0x8432, 0x0001}, {0x8433, 0x0011},
+{0x8434, 0x0096}, {0x8435, 0x0046}, {0x8436, 0x0084},
+{0x8437, 0x0003}, {0x8438, 0x0081}, {0x8439, 0x0002},
+{0x843a, 0x0027}, {0x843b, 0x0003}, {0x843c, 0x007e},
+{0x843d, 0x0085}, {0x843e, 0x001e}, {0x843f, 0x0096},
+{0x8440, 0x0047}, {0x8441, 0x0084}, {0x8442, 0x00fc},
+{0x8443, 0x008a}, {0x8444, 0x0002}, {0x8445, 0x0097},
+{0x8446, 0x0047}, {0x8447, 0x00de}, {0x8448, 0x00e1},
+{0x8449, 0x00ad}, {0x844a, 0x0000}, {0x844b, 0x0086},
+{0x844c, 0x0001}, {0x844d, 0x00b7}, {0x844e, 0x0012},
+{0x844f, 0x0051}, {0x8450, 0x00bd}, {0x8451, 0x00f7},
+{0x8452, 0x0014}, {0x8453, 0x00b6}, {0x8454, 0x0010},
+{0x8455, 0x0031}, {0x8456, 0x0084}, {0x8457, 0x00fd},
+{0x8458, 0x00b7}, {0x8459, 0x0010}, {0x845a, 0x0031},
+{0x845b, 0x00bd}, {0x845c, 0x00f8}, {0x845d, 0x001e},
+{0x845e, 0x0096}, {0x845f, 0x0081}, {0x8460, 0x00d6},
+{0x8461, 0x0082}, {0x8462, 0x00fe}, {0x8463, 0x008f},
+{0x8464, 0x005a}, {0x8465, 0x00bd}, {0x8466, 0x00f7},
+{0x8467, 0x00b6}, {0x8468, 0x00fe}, {0x8469, 0x008f},
+{0x846a, 0x005c}, {0x846b, 0x00bd}, {0x846c, 0x00ec},
+{0x846d, 0x008e}, {0x846e, 0x00bd}, {0x846f, 0x00fa},
+{0x8470, 0x00f7}, {0x8471, 0x0086}, {0x8472, 0x0008},
+{0x8473, 0x00d6}, {0x8474, 0x0000}, {0x8475, 0x00c5},
+{0x8476, 0x0010}, {0x8477, 0x0026}, {0x8478, 0x0002},
+{0x8479, 0x008b}, {0x847a, 0x0020}, {0x847b, 0x00c6},
+{0x847c, 0x0051}, {0x847d, 0x00bd}, {0x847e, 0x00e4},
+{0x847f, 0x0012}, {0x8480, 0x00ce}, {0x8481, 0x0084},
+{0x8482, 0x0086}, {0x8483, 0x00ff}, {0x8484, 0x0001},
+{0x8485, 0x0011}, {0x8486, 0x0096}, {0x8487, 0x0046},
+{0x8488, 0x0084}, {0x8489, 0x0003}, {0x848a, 0x0081},
+{0x848b, 0x0002}, {0x848c, 0x0027}, {0x848d, 0x0003},
+{0x848e, 0x007e}, {0x848f, 0x0085}, {0x8490, 0x000f},
+{0x8491, 0x00c6}, {0x8492, 0x0051}, {0x8493, 0x00bd},
+{0x8494, 0x00e4}, {0x8495, 0x0091}, {0x8496, 0x0025},
+{0x8497, 0x0003}, {0x8498, 0x007e}, {0x8499, 0x0085},
+{0x849a, 0x001e}, {0x849b, 0x0096}, {0x849c, 0x0044},
+{0x849d, 0x0085}, {0x849e, 0x0010}, {0x849f, 0x0026},
+{0x84a0, 0x000a}, {0x84a1, 0x00b6}, {0x84a2, 0x0012},
+{0x84a3, 0x0050}, {0x84a4, 0x00ba}, {0x84a5, 0x0001},
+{0x84a6, 0x003c}, {0x84a7, 0x0085}, {0x84a8, 0x0010},
+{0x84a9, 0x0027}, {0x84aa, 0x00a8}, {0x84ab, 0x00bd},
+{0x84ac, 0x00f7}, {0x84ad, 0x0066}, {0x84ae, 0x00ce},
+{0x84af, 0x0084}, {0x84b0, 0x00b7}, {0x84b1, 0x00ff},
+{0x84b2, 0x0001}, {0x84b3, 0x0011}, {0x84b4, 0x007e},
+{0x84b5, 0x0085}, {0x84b6, 0x001e}, {0x84b7, 0x0096},
+{0x84b8, 0x0046}, {0x84b9, 0x0084}, {0x84ba, 0x0003},
+{0x84bb, 0x0081}, {0x84bc, 0x0002}, {0x84bd, 0x0026},
+{0x84be, 0x0050}, {0x84bf, 0x00b6}, {0x84c0, 0x0012},
+{0x84c1, 0x0030}, {0x84c2, 0x0084}, {0x84c3, 0x0003},
+{0x84c4, 0x0081}, {0x84c5, 0x0001}, {0x84c6, 0x0027},
+{0x84c7, 0x0003}, {0x84c8, 0x007e}, {0x84c9, 0x0085},
+{0x84ca, 0x001e}, {0x84cb, 0x0096}, {0x84cc, 0x0044},
+{0x84cd, 0x0085}, {0x84ce, 0x0010}, {0x84cf, 0x0026},
+{0x84d0, 0x0013}, {0x84d1, 0x00b6}, {0x84d2, 0x0012},
+{0x84d3, 0x0050}, {0x84d4, 0x00ba}, {0x84d5, 0x0001},
+{0x84d6, 0x003c}, {0x84d7, 0x0085}, {0x84d8, 0x0010},
+{0x84d9, 0x0026}, {0x84da, 0x0009}, {0x84db, 0x00ce},
+{0x84dc, 0x0084}, {0x84dd, 0x0053}, {0x84de, 0x00ff},
+{0x84df, 0x0001}, {0x84e0, 0x0011}, {0x84e1, 0x007e},
+{0x84e2, 0x0085}, {0x84e3, 0x001e}, {0x84e4, 0x00b6},
+{0x84e5, 0x0010}, {0x84e6, 0x0031}, {0x84e7, 0x008a},
+{0x84e8, 0x0002}, {0x84e9, 0x00b7}, {0x84ea, 0x0010},
+{0x84eb, 0x0031}, {0x84ec, 0x00bd}, {0x84ed, 0x0085},
+{0x84ee, 0x001f}, {0x84ef, 0x00bd}, {0x84f0, 0x00f8},
+{0x84f1, 0x0037}, {0x84f2, 0x007c}, {0x84f3, 0x0000},
+{0x84f4, 0x0080}, {0x84f5, 0x00ce}, {0x84f6, 0x0084},
+{0x84f7, 0x00fe}, {0x84f8, 0x00ff}, {0x84f9, 0x0001},
+{0x84fa, 0x0011}, {0x84fb, 0x007e}, {0x84fc, 0x0085},
+{0x84fd, 0x001e}, {0x84fe, 0x0096}, {0x84ff, 0x0046},
+{0x8500, 0x0084}, {0x8501, 0x0003}, {0x8502, 0x0081},
+{0x8503, 0x0002}, {0x8504, 0x0026}, {0x8505, 0x0009},
+{0x8506, 0x00b6}, {0x8507, 0x0012}, {0x8508, 0x0030},
+{0x8509, 0x0084}, {0x850a, 0x0003}, {0x850b, 0x0081},
+{0x850c, 0x0001}, {0x850d, 0x0027}, {0x850e, 0x000f},
+{0x850f, 0x00bd}, {0x8510, 0x00f8}, {0x8511, 0x0044},
+{0x8512, 0x00bd}, {0x8513, 0x00f7}, {0x8514, 0x000b},
+{0x8515, 0x00bd}, {0x8516, 0x00fc}, {0x8517, 0x0029},
+{0x8518, 0x00ce}, {0x8519, 0x0084}, {0x851a, 0x0026},
+{0x851b, 0x00ff}, {0x851c, 0x0001}, {0x851d, 0x0011},
+{0x851e, 0x0039}, {0x851f, 0x00d6}, {0x8520, 0x0022},
+{0x8521, 0x00c4}, {0x8522, 0x000f}, {0x8523, 0x00b6},
+{0x8524, 0x0012}, {0x8525, 0x0030}, {0x8526, 0x00ba},
+{0x8527, 0x0012}, {0x8528, 0x0032}, {0x8529, 0x0084},
+{0x852a, 0x0004}, {0x852b, 0x0027}, {0x852c, 0x000d},
+{0x852d, 0x0096}, {0x852e, 0x0022}, {0x852f, 0x0085},
+{0x8530, 0x0004}, {0x8531, 0x0027}, {0x8532, 0x0005},
+{0x8533, 0x00ca}, {0x8534, 0x0010}, {0x8535, 0x007e},
+{0x8536, 0x0085}, {0x8537, 0x003a}, {0x8538, 0x00ca},
+{0x8539, 0x0020}, {0x853a, 0x00d7}, {0x853b, 0x0022},
+{0x853c, 0x0039}, {0x853d, 0x0086}, {0x853e, 0x0000},
+{0x853f, 0x0097}, {0x8540, 0x0083}, {0x8541, 0x0018},
+{0x8542, 0x00ce}, {0x8543, 0x001c}, {0x8544, 0x0000},
+{0x8545, 0x00bd}, {0x8546, 0x00eb}, {0x8547, 0x0046},
+{0x8548, 0x0096}, {0x8549, 0x0057}, {0x854a, 0x0085},
+{0x854b, 0x0001}, {0x854c, 0x0027}, {0x854d, 0x0002},
+{0x854e, 0x004f}, {0x854f, 0x0039}, {0x8550, 0x0085},
+{0x8551, 0x0002}, {0x8552, 0x0027}, {0x8553, 0x0001},
+{0x8554, 0x0039}, {0x8555, 0x007f}, {0x8556, 0x008f},
+{0x8557, 0x007d}, {0x8558, 0x0086}, {0x8559, 0x0004},
+{0x855a, 0x00b7}, {0x855b, 0x0012}, {0x855c, 0x0004},
+{0x855d, 0x0086}, {0x855e, 0x0008}, {0x855f, 0x00b7},
+{0x8560, 0x0012}, {0x8561, 0x0007}, {0x8562, 0x0086},
+{0x8563, 0x0010}, {0x8564, 0x00b7}, {0x8565, 0x0012},
+{0x8566, 0x000c}, {0x8567, 0x0086}, {0x8568, 0x0007},
+{0x8569, 0x00b7}, {0x856a, 0x0012}, {0x856b, 0x0006},
+{0x856c, 0x00b6}, {0x856d, 0x008f}, {0x856e, 0x007d},
+{0x856f, 0x00b7}, {0x8570, 0x0012}, {0x8571, 0x0070},
+{0x8572, 0x0086}, {0x8573, 0x0001}, {0x8574, 0x00ba},
+{0x8575, 0x0012}, {0x8576, 0x0004}, {0x8577, 0x00b7},
+{0x8578, 0x0012}, {0x8579, 0x0004}, {0x857a, 0x0001},
+{0x857b, 0x0001}, {0x857c, 0x0001}, {0x857d, 0x0001},
+{0x857e, 0x0001}, {0x857f, 0x0001}, {0x8580, 0x00b6},
+{0x8581, 0x0012}, {0x8582, 0x0004}, {0x8583, 0x0084},
+{0x8584, 0x00fe}, {0x8585, 0x008a}, {0x8586, 0x0002},
+{0x8587, 0x00b7}, {0x8588, 0x0012}, {0x8589, 0x0004},
+{0x858a, 0x0001}, {0x858b, 0x0001}, {0x858c, 0x0001},
+{0x858d, 0x0001}, {0x858e, 0x0001}, {0x858f, 0x0001},
+{0x8590, 0x0086}, {0x8591, 0x00fd}, {0x8592, 0x00b4},
+{0x8593, 0x0012}, {0x8594, 0x0004}, {0x8595, 0x00b7},
+{0x8596, 0x0012}, {0x8597, 0x0004}, {0x8598, 0x00b6},
+{0x8599, 0x0012}, {0x859a, 0x0000}, {0x859b, 0x0084},
+{0x859c, 0x0008}, {0x859d, 0x0081}, {0x859e, 0x0008},
+{0x859f, 0x0027}, {0x85a0, 0x0016}, {0x85a1, 0x00b6},
+{0x85a2, 0x008f}, {0x85a3, 0x007d}, {0x85a4, 0x0081},
+{0x85a5, 0x000c}, {0x85a6, 0x0027}, {0x85a7, 0x0008},
+{0x85a8, 0x008b}, {0x85a9, 0x0004}, {0x85aa, 0x00b7},
+{0x85ab, 0x008f}, {0x85ac, 0x007d}, {0x85ad, 0x007e},
+{0x85ae, 0x0085}, {0x85af, 0x006c}, {0x85b0, 0x0086},
+{0x85b1, 0x0003}, {0x85b2, 0x0097}, {0x85b3, 0x0040},
+{0x85b4, 0x007e}, {0x85b5, 0x0089}, {0x85b6, 0x006e},
+{0x85b7, 0x0086}, {0x85b8, 0x0007}, {0x85b9, 0x00b7},
+{0x85ba, 0x0012}, {0x85bb, 0x0006}, {0x85bc, 0x005f},
+{0x85bd, 0x00f7}, {0x85be, 0x008f}, {0x85bf, 0x0082},
+{0x85c0, 0x005f}, {0x85c1, 0x00f7}, {0x85c2, 0x008f},
+{0x85c3, 0x007f}, {0x85c4, 0x00f7}, {0x85c5, 0x008f},
+{0x85c6, 0x0070}, {0x85c7, 0x00f7}, {0x85c8, 0x008f},
+{0x85c9, 0x0071}, {0x85ca, 0x00f7}, {0x85cb, 0x008f},
+{0x85cc, 0x0072}, {0x85cd, 0x00f7}, {0x85ce, 0x008f},
+{0x85cf, 0x0073}, {0x85d0, 0x00f7}, {0x85d1, 0x008f},
+{0x85d2, 0x0074}, {0x85d3, 0x00f7}, {0x85d4, 0x008f},
+{0x85d5, 0x0075}, {0x85d6, 0x00f7}, {0x85d7, 0x008f},
+{0x85d8, 0x0076}, {0x85d9, 0x00f7}, {0x85da, 0x008f},
+{0x85db, 0x0077}, {0x85dc, 0x00f7}, {0x85dd, 0x008f},
+{0x85de, 0x0078}, {0x85df, 0x00f7}, {0x85e0, 0x008f},
+{0x85e1, 0x0079}, {0x85e2, 0x00f7}, {0x85e3, 0x008f},
+{0x85e4, 0x007a}, {0x85e5, 0x00f7}, {0x85e6, 0x008f},
+{0x85e7, 0x007b}, {0x85e8, 0x00b6}, {0x85e9, 0x0012},
+{0x85ea, 0x0004}, {0x85eb, 0x008a}, {0x85ec, 0x0010},
+{0x85ed, 0x00b7}, {0x85ee, 0x0012}, {0x85ef, 0x0004},
+{0x85f0, 0x0086}, {0x85f1, 0x00e4}, {0x85f2, 0x00b7},
+{0x85f3, 0x0012}, {0x85f4, 0x0070}, {0x85f5, 0x00b7},
+{0x85f6, 0x0012}, {0x85f7, 0x0007}, {0x85f8, 0x00f7},
+{0x85f9, 0x0012}, {0x85fa, 0x0005}, {0x85fb, 0x00f7},
+{0x85fc, 0x0012}, {0x85fd, 0x0009}, {0x85fe, 0x0086},
+{0x85ff, 0x0008}, {0x8600, 0x00ba}, {0x8601, 0x0012},
+{0x8602, 0x0004}, {0x8603, 0x00b7}, {0x8604, 0x0012},
+{0x8605, 0x0004}, {0x8606, 0x0086}, {0x8607, 0x00f7},
+{0x8608, 0x00b4}, {0x8609, 0x0012}, {0x860a, 0x0004},
+{0x860b, 0x00b7}, {0x860c, 0x0012}, {0x860d, 0x0004},
+{0x860e, 0x0001}, {0x860f, 0x0001}, {0x8610, 0x0001},
+{0x8611, 0x0001}, {0x8612, 0x0001}, {0x8613, 0x0001},
+{0x8614, 0x00b6}, {0x8615, 0x0012}, {0x8616, 0x0008},
+{0x8617, 0x0027}, {0x8618, 0x007f}, {0x8619, 0x0081},
+{0x861a, 0x0080}, {0x861b, 0x0026}, {0x861c, 0x000b},
+{0x861d, 0x0086}, {0x861e, 0x0008}, {0x861f, 0x00ce},
+{0x8620, 0x008f}, {0x8621, 0x0079}, {0x8622, 0x00bd},
+{0x8623, 0x0089}, {0x8624, 0x007b}, {0x8625, 0x007e},
+{0x8626, 0x0086}, {0x8627, 0x008e}, {0x8628, 0x0081},
+{0x8629, 0x0040}, {0x862a, 0x0026}, {0x862b, 0x000b},
+{0x862c, 0x0086}, {0x862d, 0x0004}, {0x862e, 0x00ce},
+{0x862f, 0x008f}, {0x8630, 0x0076}, {0x8631, 0x00bd},
+{0x8632, 0x0089}, {0x8633, 0x007b}, {0x8634, 0x007e},
+{0x8635, 0x0086}, {0x8636, 0x008e}, {0x8637, 0x0081},
+{0x8638, 0x0020}, {0x8639, 0x0026}, {0x863a, 0x000b},
+{0x863b, 0x0086}, {0x863c, 0x0002}, {0x863d, 0x00ce},
+{0x863e, 0x008f}, {0x863f, 0x0073}, {0x8640, 0x00bd},
+{0x8641, 0x0089}, {0x8642, 0x007b}, {0x8643, 0x007e},
+{0x8644, 0x0086}, {0x8645, 0x008e}, {0x8646, 0x0081},
+{0x8647, 0x0010}, {0x8648, 0x0026}, {0x8649, 0x000b},
+{0x864a, 0x0086}, {0x864b, 0x0001}, {0x864c, 0x00ce},
+{0x864d, 0x008f}, {0x864e, 0x0070}, {0x864f, 0x00bd},
+{0x8650, 0x0089}, {0x8651, 0x007b}, {0x8652, 0x007e},
+{0x8653, 0x0086}, {0x8654, 0x008e}, {0x8655, 0x0081},
+{0x8656, 0x0008}, {0x8657, 0x0026}, {0x8658, 0x000b},
+{0x8659, 0x0086}, {0x865a, 0x0008}, {0x865b, 0x00ce},
+{0x865c, 0x008f}, {0x865d, 0x0079}, {0x865e, 0x00bd},
+{0x865f, 0x0089}, {0x8660, 0x007f}, {0x8661, 0x007e},
+{0x8662, 0x0086}, {0x8663, 0x008e}, {0x8664, 0x0081},
+{0x8665, 0x0004}, {0x8666, 0x0026}, {0x8667, 0x000b},
+{0x8668, 0x0086}, {0x8669, 0x0004}, {0x866a, 0x00ce},
+{0x866b, 0x008f}, {0x866c, 0x0076}, {0x866d, 0x00bd},
+{0x866e, 0x0089}, {0x866f, 0x007f}, {0x8670, 0x007e},
+{0x8671, 0x0086}, {0x8672, 0x008e}, {0x8673, 0x0081},
+{0x8674, 0x0002}, {0x8675, 0x0026}, {0x8676, 0x000b},
+{0x8677, 0x008a}, {0x8678, 0x0002}, {0x8679, 0x00ce},
+{0x867a, 0x008f}, {0x867b, 0x0073}, {0x867c, 0x00bd},
+{0x867d, 0x0089}, {0x867e, 0x007f}, {0x867f, 0x007e},
+{0x8680, 0x0086}, {0x8681, 0x008e}, {0x8682, 0x0081},
+{0x8683, 0x0001}, {0x8684, 0x0026}, {0x8685, 0x0008},
+{0x8686, 0x0086}, {0x8687, 0x0001}, {0x8688, 0x00ce},
+{0x8689, 0x008f}, {0x868a, 0x0070}, {0x868b, 0x00bd},
+{0x868c, 0x0089}, {0x868d, 0x007f}, {0x868e, 0x00b6},
+{0x868f, 0x008f}, {0x8690, 0x007f}, {0x8691, 0x0081},
+{0x8692, 0x000f}, {0x8693, 0x0026}, {0x8694, 0x0003},
+{0x8695, 0x007e}, {0x8696, 0x0087}, {0x8697, 0x0047},
+{0x8698, 0x00b6}, {0x8699, 0x0012}, {0x869a, 0x0009},
+{0x869b, 0x0084}, {0x869c, 0x0003}, {0x869d, 0x0081},
+{0x869e, 0x0003}, {0x869f, 0x0027}, {0x86a0, 0x0006},
+{0x86a1, 0x007c}, {0x86a2, 0x0012}, {0x86a3, 0x0009},
+{0x86a4, 0x007e}, {0x86a5, 0x0085}, {0x86a6, 0x00fe},
+{0x86a7, 0x00b6}, {0x86a8, 0x0012}, {0x86a9, 0x0006},
+{0x86aa, 0x0084}, {0x86ab, 0x0007}, {0x86ac, 0x0081},
+{0x86ad, 0x0007}, {0x86ae, 0x0027}, {0x86af, 0x0008},
+{0x86b0, 0x008b}, {0x86b1, 0x0001}, {0x86b2, 0x00b7},
+{0x86b3, 0x0012}, {0x86b4, 0x0006}, {0x86b5, 0x007e},
+{0x86b6, 0x0086}, {0x86b7, 0x00d5}, {0x86b8, 0x00b6},
+{0x86b9, 0x008f}, {0x86ba, 0x0082}, {0x86bb, 0x0026},
+{0x86bc, 0x000a}, {0x86bd, 0x007c}, {0x86be, 0x008f},
+{0x86bf, 0x0082}, {0x86c0, 0x004f}, {0x86c1, 0x00b7},
+{0x86c2, 0x0012}, {0x86c3, 0x0006}, {0x86c4, 0x007e},
+{0x86c5, 0x0085}, {0x86c6, 0x00c0}, {0x86c7, 0x00b6},
+{0x86c8, 0x0012}, {0x86c9, 0x0006}, {0x86ca, 0x0084},
+{0x86cb, 0x003f}, {0x86cc, 0x0081}, {0x86cd, 0x003f},
+{0x86ce, 0x0027}, {0x86cf, 0x0010}, {0x86d0, 0x008b},
+{0x86d1, 0x0008}, {0x86d2, 0x00b7}, {0x86d3, 0x0012},
+{0x86d4, 0x0006}, {0x86d5, 0x00b6}, {0x86d6, 0x0012},
+{0x86d7, 0x0009}, {0x86d8, 0x0084}, {0x86d9, 0x00fc},
+{0x86da, 0x00b7}, {0x86db, 0x0012}, {0x86dc, 0x0009},
+{0x86dd, 0x007e}, {0x86de, 0x0085}, {0x86df, 0x00fe},
+{0x86e0, 0x00ce}, {0x86e1, 0x008f}, {0x86e2, 0x0070},
+{0x86e3, 0x0018}, {0x86e4, 0x00ce}, {0x86e5, 0x008f},
+{0x86e6, 0x0084}, {0x86e7, 0x00c6}, {0x86e8, 0x000c},
+{0x86e9, 0x00bd}, {0x86ea, 0x0089}, {0x86eb, 0x006f},
+{0x86ec, 0x00ce}, {0x86ed, 0x008f}, {0x86ee, 0x0084},
+{0x86ef, 0x0018}, {0x86f0, 0x00ce}, {0x86f1, 0x008f},
+{0x86f2, 0x0070}, {0x86f3, 0x00c6}, {0x86f4, 0x000c},
+{0x86f5, 0x00bd}, {0x86f6, 0x0089}, {0x86f7, 0x006f},
+{0x86f8, 0x00d6}, {0x86f9, 0x0083}, {0x86fa, 0x00c1},
+{0x86fb, 0x004f}, {0x86fc, 0x002d}, {0x86fd, 0x0003},
+{0x86fe, 0x007e}, {0x86ff, 0x0087}, {0x8700, 0x0040},
+{0x8701, 0x00b6}, {0x8702, 0x008f}, {0x8703, 0x007f},
+{0x8704, 0x0081}, {0x8705, 0x0007}, {0x8706, 0x0027},
+{0x8707, 0x000f}, {0x8708, 0x0081}, {0x8709, 0x000b},
+{0x870a, 0x0027}, {0x870b, 0x0015}, {0x870c, 0x0081},
+{0x870d, 0x000d}, {0x870e, 0x0027}, {0x870f, 0x001b},
+{0x8710, 0x0081}, {0x8711, 0x000e}, {0x8712, 0x0027},
+{0x8713, 0x0021}, {0x8714, 0x007e}, {0x8715, 0x0087},
+{0x8716, 0x0040}, {0x8717, 0x00f7}, {0x8718, 0x008f},
+{0x8719, 0x007b}, {0x871a, 0x0086}, {0x871b, 0x0002},
+{0x871c, 0x00b7}, {0x871d, 0x008f}, {0x871e, 0x007a},
+{0x871f, 0x0020}, {0x8720, 0x001c}, {0x8721, 0x00f7},
+{0x8722, 0x008f}, {0x8723, 0x0078}, {0x8724, 0x0086},
+{0x8725, 0x0002}, {0x8726, 0x00b7}, {0x8727, 0x008f},
+{0x8728, 0x0077}, {0x8729, 0x0020}, {0x872a, 0x0012},
+{0x872b, 0x00f7}, {0x872c, 0x008f}, {0x872d, 0x0075},
+{0x872e, 0x0086}, {0x872f, 0x0002}, {0x8730, 0x00b7},
+{0x8731, 0x008f}, {0x8732, 0x0074}, {0x8733, 0x0020},
+{0x8734, 0x0008}, {0x8735, 0x00f7}, {0x8736, 0x008f},
+{0x8737, 0x0072}, {0x8738, 0x0086}, {0x8739, 0x0002},
+{0x873a, 0x00b7}, {0x873b, 0x008f}, {0x873c, 0x0071},
+{0x873d, 0x007e}, {0x873e, 0x0087}, {0x873f, 0x0047},
+{0x8740, 0x0086}, {0x8741, 0x0004}, {0x8742, 0x0097},
+{0x8743, 0x0040}, {0x8744, 0x007e}, {0x8745, 0x0089},
+{0x8746, 0x006e}, {0x8747, 0x00ce}, {0x8748, 0x008f},
+{0x8749, 0x0072}, {0x874a, 0x00bd}, {0x874b, 0x0089},
+{0x874c, 0x00f7}, {0x874d, 0x00ce}, {0x874e, 0x008f},
+{0x874f, 0x0075}, {0x8750, 0x00bd}, {0x8751, 0x0089},
+{0x8752, 0x00f7}, {0x8753, 0x00ce}, {0x8754, 0x008f},
+{0x8755, 0x0078}, {0x8756, 0x00bd}, {0x8757, 0x0089},
+{0x8758, 0x00f7}, {0x8759, 0x00ce}, {0x875a, 0x008f},
+{0x875b, 0x007b}, {0x875c, 0x00bd}, {0x875d, 0x0089},
+{0x875e, 0x00f7}, {0x875f, 0x004f}, {0x8760, 0x00b7},
+{0x8761, 0x008f}, {0x8762, 0x007d}, {0x8763, 0x00b7},
+{0x8764, 0x008f}, {0x8765, 0x0081}, {0x8766, 0x00b6},
+{0x8767, 0x008f}, {0x8768, 0x0072}, {0x8769, 0x0027},
+{0x876a, 0x0047}, {0x876b, 0x007c}, {0x876c, 0x008f},
+{0x876d, 0x007d}, {0x876e, 0x00b6}, {0x876f, 0x008f},
+{0x8770, 0x0075}, {0x8771, 0x0027}, {0x8772, 0x003f},
+{0x8773, 0x007c}, {0x8774, 0x008f}, {0x8775, 0x007d},
+{0x8776, 0x00b6}, {0x8777, 0x008f}, {0x8778, 0x0078},
+{0x8779, 0x0027}, {0x877a, 0x0037}, {0x877b, 0x007c},
+{0x877c, 0x008f}, {0x877d, 0x007d}, {0x877e, 0x00b6},
+{0x877f, 0x008f}, {0x8780, 0x007b}, {0x8781, 0x0027},
+{0x8782, 0x002f}, {0x8783, 0x007f}, {0x8784, 0x008f},
+{0x8785, 0x007d}, {0x8786, 0x007c}, {0x8787, 0x008f},
+{0x8788, 0x0081}, {0x8789, 0x007a}, {0x878a, 0x008f},
+{0x878b, 0x0072}, {0x878c, 0x0027}, {0x878d, 0x001b},
+{0x878e, 0x007c}, {0x878f, 0x008f}, {0x8790, 0x007d},
+{0x8791, 0x007a}, {0x8792, 0x008f}, {0x8793, 0x0075},
+{0x8794, 0x0027}, {0x8795, 0x0016}, {0x8796, 0x007c},
+{0x8797, 0x008f}, {0x8798, 0x007d}, {0x8799, 0x007a},
+{0x879a, 0x008f}, {0x879b, 0x0078}, {0x879c, 0x0027},
+{0x879d, 0x0011}, {0x879e, 0x007c}, {0x879f, 0x008f},
+{0x87a0, 0x007d}, {0x87a1, 0x007a}, {0x87a2, 0x008f},
+{0x87a3, 0x007b}, {0x87a4, 0x0027}, {0x87a5, 0x000c},
+{0x87a6, 0x007e}, {0x87a7, 0x0087}, {0x87a8, 0x0083},
+{0x87a9, 0x007a}, {0x87aa, 0x008f}, {0x87ab, 0x0075},
+{0x87ac, 0x007a}, {0x87ad, 0x008f}, {0x87ae, 0x0078},
+{0x87af, 0x007a}, {0x87b0, 0x008f}, {0x87b1, 0x007b},
+{0x87b2, 0x00ce}, {0x87b3, 0x00c1}, {0x87b4, 0x00fc},
+{0x87b5, 0x00f6}, {0x87b6, 0x008f}, {0x87b7, 0x007d},
+{0x87b8, 0x003a}, {0x87b9, 0x00a6}, {0x87ba, 0x0000},
+{0x87bb, 0x00b7}, {0x87bc, 0x0012}, {0x87bd, 0x0070},
+{0x87be, 0x00b6}, {0x87bf, 0x008f}, {0x87c0, 0x0072},
+{0x87c1, 0x0026}, {0x87c2, 0x0003}, {0x87c3, 0x007e},
+{0x87c4, 0x0087}, {0x87c5, 0x00fa}, {0x87c6, 0x00b6},
+{0x87c7, 0x008f}, {0x87c8, 0x0075}, {0x87c9, 0x0026},
+{0x87ca, 0x000a}, {0x87cb, 0x0018}, {0x87cc, 0x00ce},
+{0x87cd, 0x008f}, {0x87ce, 0x0073}, {0x87cf, 0x00bd},
+{0x87d0, 0x0089}, {0x87d1, 0x00d5}, {0x87d2, 0x007e},
+{0x87d3, 0x0087}, {0x87d4, 0x00fa}, {0x87d5, 0x00b6},
+{0x87d6, 0x008f}, {0x87d7, 0x0078}, {0x87d8, 0x0026},
+{0x87d9, 0x000a}, {0x87da, 0x0018}, {0x87db, 0x00ce},
+{0x87dc, 0x008f}, {0x87dd, 0x0076}, {0x87de, 0x00bd},
+{0x87df, 0x0089}, {0x87e0, 0x00d5}, {0x87e1, 0x007e},
+{0x87e2, 0x0087}, {0x87e3, 0x00fa}, {0x87e4, 0x00b6},
+{0x87e5, 0x008f}, {0x87e6, 0x007b}, {0x87e7, 0x0026},
+{0x87e8, 0x000a}, {0x87e9, 0x0018}, {0x87ea, 0x00ce},
+{0x87eb, 0x008f}, {0x87ec, 0x0079}, {0x87ed, 0x00bd},
+{0x87ee, 0x0089}, {0x87ef, 0x00d5}, {0x87f0, 0x007e},
+{0x87f1, 0x0087}, {0x87f2, 0x00fa}, {0x87f3, 0x0086},
+{0x87f4, 0x0005}, {0x87f5, 0x0097}, {0x87f6, 0x0040},
+{0x87f7, 0x007e}, {0x87f8, 0x0089}, {0x87f9, 0x0000},
+{0x87fa, 0x00b6}, {0x87fb, 0x008f}, {0x87fc, 0x0075},
+{0x87fd, 0x0081}, {0x87fe, 0x0007}, {0x87ff, 0x002e},
+{0x8800, 0x00f2}, {0x8801, 0x00f6}, {0x8802, 0x0012},
+{0x8803, 0x0006}, {0x8804, 0x00c4}, {0x8805, 0x00f8},
+{0x8806, 0x001b}, {0x8807, 0x00b7}, {0x8808, 0x0012},
+{0x8809, 0x0006}, {0x880a, 0x00b6}, {0x880b, 0x008f},
+{0x880c, 0x0078}, {0x880d, 0x0081}, {0x880e, 0x0007},
+{0x880f, 0x002e}, {0x8810, 0x00e2}, {0x8811, 0x0048},
+{0x8812, 0x0048}, {0x8813, 0x0048}, {0x8814, 0x00f6},
+{0x8815, 0x0012}, {0x8816, 0x0006}, {0x8817, 0x00c4},
+{0x8818, 0x00c7}, {0x8819, 0x001b}, {0x881a, 0x00b7},
+{0x881b, 0x0012}, {0x881c, 0x0006}, {0x881d, 0x00b6},
+{0x881e, 0x008f}, {0x881f, 0x007b}, {0x8820, 0x0081},
+{0x8821, 0x0007}, {0x8822, 0x002e}, {0x8823, 0x00cf},
+{0x8824, 0x00f6}, {0x8825, 0x0012}, {0x8826, 0x0005},
+{0x8827, 0x00c4}, {0x8828, 0x00f8}, {0x8829, 0x001b},
+{0x882a, 0x00b7}, {0x882b, 0x0012}, {0x882c, 0x0005},
+{0x882d, 0x0086}, {0x882e, 0x0000}, {0x882f, 0x00f6},
+{0x8830, 0x008f}, {0x8831, 0x0071}, {0x8832, 0x00bd},
+{0x8833, 0x0089}, {0x8834, 0x0094}, {0x8835, 0x0086},
+{0x8836, 0x0001}, {0x8837, 0x00f6}, {0x8838, 0x008f},
+{0x8839, 0x0074}, {0x883a, 0x00bd}, {0x883b, 0x0089},
+{0x883c, 0x0094}, {0x883d, 0x0086}, {0x883e, 0x0002},
+{0x883f, 0x00f6}, {0x8840, 0x008f}, {0x8841, 0x0077},
+{0x8842, 0x00bd}, {0x8843, 0x0089}, {0x8844, 0x0094},
+{0x8845, 0x0086}, {0x8846, 0x0003}, {0x8847, 0x00f6},
+{0x8848, 0x008f}, {0x8849, 0x007a}, {0x884a, 0x00bd},
+{0x884b, 0x0089}, {0x884c, 0x0094}, {0x884d, 0x00ce},
+{0x884e, 0x008f}, {0x884f, 0x0070}, {0x8850, 0x00a6},
+{0x8851, 0x0001}, {0x8852, 0x0081}, {0x8853, 0x0001},
+{0x8854, 0x0027}, {0x8855, 0x0007}, {0x8856, 0x0081},
+{0x8857, 0x0003}, {0x8858, 0x0027}, {0x8859, 0x0003},
+{0x885a, 0x007e}, {0x885b, 0x0088}, {0x885c, 0x0066},
+{0x885d, 0x00a6}, {0x885e, 0x0000}, {0x885f, 0x00b8},
+{0x8860, 0x008f}, {0x8861, 0x0081}, {0x8862, 0x0084},
+{0x8863, 0x0001}, {0x8864, 0x0026}, {0x8865, 0x000b},
+{0x8866, 0x008c}, {0x8867, 0x008f}, {0x8868, 0x0079},
+{0x8869, 0x002c}, {0x886a, 0x000e}, {0x886b, 0x0008},
+{0x886c, 0x0008}, {0x886d, 0x0008}, {0x886e, 0x007e},
+{0x886f, 0x0088}, {0x8870, 0x0050}, {0x8871, 0x00b6},
+{0x8872, 0x0012}, {0x8873, 0x0004}, {0x8874, 0x008a},
+{0x8875, 0x0040}, {0x8876, 0x00b7}, {0x8877, 0x0012},
+{0x8878, 0x0004}, {0x8879, 0x00b6}, {0x887a, 0x0012},
+{0x887b, 0x0004}, {0x887c, 0x0084}, {0x887d, 0x00fb},
+{0x887e, 0x0084}, {0x887f, 0x00ef}, {0x8880, 0x00b7},
+{0x8881, 0x0012}, {0x8882, 0x0004}, {0x8883, 0x00b6},
+{0x8884, 0x0012}, {0x8885, 0x0007}, {0x8886, 0x0036},
+{0x8887, 0x00b6}, {0x8888, 0x008f}, {0x8889, 0x007c},
+{0x888a, 0x0048}, {0x888b, 0x0048}, {0x888c, 0x00b7},
+{0x888d, 0x0012}, {0x888e, 0x0007}, {0x888f, 0x0086},
+{0x8890, 0x0001}, {0x8891, 0x00ba}, {0x8892, 0x0012},
+{0x8893, 0x0004}, {0x8894, 0x00b7}, {0x8895, 0x0012},
+{0x8896, 0x0004}, {0x8897, 0x0001}, {0x8898, 0x0001},
+{0x8899, 0x0001}, {0x889a, 0x0001}, {0x889b, 0x0001},
+{0x889c, 0x0001}, {0x889d, 0x0086}, {0x889e, 0x00fe},
+{0x889f, 0x00b4}, {0x88a0, 0x0012}, {0x88a1, 0x0004},
+{0x88a2, 0x00b7}, {0x88a3, 0x0012}, {0x88a4, 0x0004},
+{0x88a5, 0x0086}, {0x88a6, 0x0002}, {0x88a7, 0x00ba},
+{0x88a8, 0x0012}, {0x88a9, 0x0004}, {0x88aa, 0x00b7},
+{0x88ab, 0x0012}, {0x88ac, 0x0004}, {0x88ad, 0x0086},
+{0x88ae, 0x00fd}, {0x88af, 0x00b4}, {0x88b0, 0x0012},
+{0x88b1, 0x0004}, {0x88b2, 0x00b7}, {0x88b3, 0x0012},
+{0x88b4, 0x0004}, {0x88b5, 0x0032}, {0x88b6, 0x00b7},
+{0x88b7, 0x0012}, {0x88b8, 0x0007}, {0x88b9, 0x00b6},
+{0x88ba, 0x0012}, {0x88bb, 0x0000}, {0x88bc, 0x0084},
+{0x88bd, 0x0008}, {0x88be, 0x0081}, {0x88bf, 0x0008},
+{0x88c0, 0x0027}, {0x88c1, 0x000f}, {0x88c2, 0x007c},
+{0x88c3, 0x0082}, {0x88c4, 0x0008}, {0x88c5, 0x0026},
+{0x88c6, 0x0007}, {0x88c7, 0x0086}, {0x88c8, 0x0076},
+{0x88c9, 0x0097}, {0x88ca, 0x0040}, {0x88cb, 0x007e},
+{0x88cc, 0x0089}, {0x88cd, 0x006e}, {0x88ce, 0x007e},
+{0x88cf, 0x0086}, {0x88d0, 0x00ec}, {0x88d1, 0x00b6},
+{0x88d2, 0x008f}, {0x88d3, 0x007f}, {0x88d4, 0x0081},
+{0x88d5, 0x000f}, {0x88d6, 0x0027}, {0x88d7, 0x003c},
+{0x88d8, 0x00bd}, {0x88d9, 0x00e6}, {0x88da, 0x00c7},
+{0x88db, 0x00b7}, {0x88dc, 0x0012}, {0x88dd, 0x000d},
+{0x88de, 0x00bd}, {0x88df, 0x00e6}, {0x88e0, 0x00cb},
+{0x88e1, 0x00b6}, {0x88e2, 0x0012}, {0x88e3, 0x0004},
+{0x88e4, 0x008a}, {0x88e5, 0x0020}, {0x88e6, 0x00b7},
+{0x88e7, 0x0012}, {0x88e8, 0x0004}, {0x88e9, 0x00ce},
+{0x88ea, 0x00ff}, {0x88eb, 0x00ff}, {0x88ec, 0x00b6},
+{0x88ed, 0x0012}, {0x88ee, 0x0000}, {0x88ef, 0x0081},
+{0x88f0, 0x000c}, {0x88f1, 0x0026}, {0x88f2, 0x0005},
+{0x88f3, 0x0009}, {0x88f4, 0x0026}, {0x88f5, 0x00f6},
+{0x88f6, 0x0027}, {0x88f7, 0x001c}, {0x88f8, 0x00b6},
+{0x88f9, 0x0012}, {0x88fa, 0x0004}, {0x88fb, 0x0084},
+{0x88fc, 0x00df}, {0x88fd, 0x00b7}, {0x88fe, 0x0012},
+{0x88ff, 0x0004}, {0x8900, 0x0096}, {0x8901, 0x0083},
+{0x8902, 0x0081}, {0x8903, 0x0007}, {0x8904, 0x002c},
+{0x8905, 0x0005}, {0x8906, 0x007c}, {0x8907, 0x0000},
+{0x8908, 0x0083}, {0x8909, 0x0020}, {0x890a, 0x0006},
+{0x890b, 0x0096}, {0x890c, 0x0083}, {0x890d, 0x008b},
+{0x890e, 0x0008}, {0x890f, 0x0097}, {0x8910, 0x0083},
+{0x8911, 0x007e}, {0x8912, 0x0085}, {0x8913, 0x0041},
+{0x8914, 0x007f}, {0x8915, 0x008f}, {0x8916, 0x007e},
+{0x8917, 0x0086}, {0x8918, 0x0080}, {0x8919, 0x00b7},
+{0x891a, 0x0012}, {0x891b, 0x000c}, {0x891c, 0x0086},
+{0x891d, 0x0001}, {0x891e, 0x00b7}, {0x891f, 0x008f},
+{0x8920, 0x007d}, {0x8921, 0x00b6}, {0x8922, 0x0012},
+{0x8923, 0x000c}, {0x8924, 0x0084}, {0x8925, 0x007f},
+{0x8926, 0x00b7}, {0x8927, 0x0012}, {0x8928, 0x000c},
+{0x8929, 0x008a}, {0x892a, 0x0080}, {0x892b, 0x00b7},
+{0x892c, 0x0012}, {0x892d, 0x000c}, {0x892e, 0x0086},
+{0x892f, 0x000a}, {0x8930, 0x00bd}, {0x8931, 0x008a},
+{0x8932, 0x0006}, {0x8933, 0x00b6}, {0x8934, 0x0012},
+{0x8935, 0x000a}, {0x8936, 0x002a}, {0x8937, 0x0009},
+{0x8938, 0x00b6}, {0x8939, 0x0012}, {0x893a, 0x000c},
+{0x893b, 0x00ba}, {0x893c, 0x008f}, {0x893d, 0x007d},
+{0x893e, 0x00b7}, {0x893f, 0x0012}, {0x8940, 0x000c},
+{0x8941, 0x00b6}, {0x8942, 0x008f}, {0x8943, 0x007e},
+{0x8944, 0x0081}, {0x8945, 0x0060}, {0x8946, 0x0027},
+{0x8947, 0x001a}, {0x8948, 0x008b}, {0x8949, 0x0020},
+{0x894a, 0x00b7}, {0x894b, 0x008f}, {0x894c, 0x007e},
+{0x894d, 0x00b6}, {0x894e, 0x0012}, {0x894f, 0x000c},
+{0x8950, 0x0084}, {0x8951, 0x009f}, {0x8952, 0x00ba},
+{0x8953, 0x008f}, {0x8954, 0x007e}, {0x8955, 0x00b7},
+{0x8956, 0x0012}, {0x8957, 0x000c}, {0x8958, 0x00b6},
+{0x8959, 0x008f}, {0x895a, 0x007d}, {0x895b, 0x0048},
+{0x895c, 0x00b7}, {0x895d, 0x008f}, {0x895e, 0x007d},
+{0x895f, 0x007e}, {0x8960, 0x0089}, {0x8961, 0x0021},
+{0x8962, 0x00b6}, {0x8963, 0x0012}, {0x8964, 0x0004},
+{0x8965, 0x008a}, {0x8966, 0x0020}, {0x8967, 0x00b7},
+{0x8968, 0x0012}, {0x8969, 0x0004}, {0x896a, 0x00bd},
+{0x896b, 0x008a}, {0x896c, 0x000a}, {0x896d, 0x004f},
+{0x896e, 0x0039}, {0x896f, 0x00a6}, {0x8970, 0x0000},
+{0x8971, 0x0018}, {0x8972, 0x00a7}, {0x8973, 0x0000},
+{0x8974, 0x0008}, {0x8975, 0x0018}, {0x8976, 0x0008},
+{0x8977, 0x005a}, {0x8978, 0x0026}, {0x8979, 0x00f5},
+{0x897a, 0x0039}, {0x897b, 0x0036}, {0x897c, 0x006c},
+{0x897d, 0x0000}, {0x897e, 0x0032}, {0x897f, 0x00ba},
+{0x8980, 0x008f}, {0x8981, 0x007f}, {0x8982, 0x00b7},
+{0x8983, 0x008f}, {0x8984, 0x007f}, {0x8985, 0x00b6},
+{0x8986, 0x0012}, {0x8987, 0x0009}, {0x8988, 0x0084},
+{0x8989, 0x0003}, {0x898a, 0x00a7}, {0x898b, 0x0001},
+{0x898c, 0x00b6}, {0x898d, 0x0012}, {0x898e, 0x0006},
+{0x898f, 0x0084}, {0x8990, 0x003f}, {0x8991, 0x00a7},
+{0x8992, 0x0002}, {0x8993, 0x0039}, {0x8994, 0x0036},
+{0x8995, 0x0086}, {0x8996, 0x0003}, {0x8997, 0x00b7},
+{0x8998, 0x008f}, {0x8999, 0x0080}, {0x899a, 0x0032},
+{0x899b, 0x00c1}, {0x899c, 0x0000}, {0x899d, 0x0026},
+{0x899e, 0x0006}, {0x899f, 0x00b7}, {0x89a0, 0x008f},
+{0x89a1, 0x007c}, {0x89a2, 0x007e}, {0x89a3, 0x0089},
+{0x89a4, 0x00c9}, {0x89a5, 0x00c1}, {0x89a6, 0x0001},
+{0x89a7, 0x0027}, {0x89a8, 0x0018}, {0x89a9, 0x00c1},
+{0x89aa, 0x0002}, {0x89ab, 0x0027}, {0x89ac, 0x000c},
+{0x89ad, 0x00c1}, {0x89ae, 0x0003}, {0x89af, 0x0027},
+{0x89b0, 0x0000}, {0x89b1, 0x00f6}, {0x89b2, 0x008f},
+{0x89b3, 0x0080}, {0x89b4, 0x0005}, {0x89b5, 0x0005},
+{0x89b6, 0x00f7}, {0x89b7, 0x008f}, {0x89b8, 0x0080},
+{0x89b9, 0x00f6}, {0x89ba, 0x008f}, {0x89bb, 0x0080},
+{0x89bc, 0x0005}, {0x89bd, 0x0005}, {0x89be, 0x00f7},
+{0x89bf, 0x008f}, {0x89c0, 0x0080}, {0x89c1, 0x00f6},
+{0x89c2, 0x008f}, {0x89c3, 0x0080}, {0x89c4, 0x0005},
+{0x89c5, 0x0005}, {0x89c6, 0x00f7}, {0x89c7, 0x008f},
+{0x89c8, 0x0080}, {0x89c9, 0x00f6}, {0x89ca, 0x008f},
+{0x89cb, 0x0080}, {0x89cc, 0x0053}, {0x89cd, 0x00f4},
+{0x89ce, 0x0012}, {0x89cf, 0x0007}, {0x89d0, 0x001b},
+{0x89d1, 0x00b7}, {0x89d2, 0x0012}, {0x89d3, 0x0007},
+{0x89d4, 0x0039}, {0x89d5, 0x00ce}, {0x89d6, 0x008f},
+{0x89d7, 0x0070}, {0x89d8, 0x00a6}, {0x89d9, 0x0000},
+{0x89da, 0x0018}, {0x89db, 0x00e6}, {0x89dc, 0x0000},
+{0x89dd, 0x0018}, {0x89de, 0x00a7}, {0x89df, 0x0000},
+{0x89e0, 0x00e7}, {0x89e1, 0x0000}, {0x89e2, 0x00a6},
+{0x89e3, 0x0001}, {0x89e4, 0x0018}, {0x89e5, 0x00e6},
+{0x89e6, 0x0001}, {0x89e7, 0x0018}, {0x89e8, 0x00a7},
+{0x89e9, 0x0001}, {0x89ea, 0x00e7}, {0x89eb, 0x0001},
+{0x89ec, 0x00a6}, {0x89ed, 0x0002}, {0x89ee, 0x0018},
+{0x89ef, 0x00e6}, {0x89f0, 0x0002}, {0x89f1, 0x0018},
+{0x89f2, 0x00a7}, {0x89f3, 0x0002}, {0x89f4, 0x00e7},
+{0x89f5, 0x0002}, {0x89f6, 0x0039}, {0x89f7, 0x00a6},
+{0x89f8, 0x0000}, {0x89f9, 0x0084}, {0x89fa, 0x0007},
+{0x89fb, 0x00e6}, {0x89fc, 0x0000}, {0x89fd, 0x00c4},
+{0x89fe, 0x0038}, {0x89ff, 0x0054}, {0x8a00, 0x0054},
+{0x8a01, 0x0054}, {0x8a02, 0x001b}, {0x8a03, 0x00a7},
+{0x8a04, 0x0000}, {0x8a05, 0x0039}, {0x8a06, 0x004a},
+{0x8a07, 0x0026}, {0x8a08, 0x00fd}, {0x8a09, 0x0039},
+{0x8a0a, 0x0096}, {0x8a0b, 0x0022}, {0x8a0c, 0x0084},
+{0x8a0d, 0x000f}, {0x8a0e, 0x0097}, {0x8a0f, 0x0022},
+{0x8a10, 0x0086}, {0x8a11, 0x0001}, {0x8a12, 0x00b7},
+{0x8a13, 0x008f}, {0x8a14, 0x0070}, {0x8a15, 0x00b6},
+{0x8a16, 0x0012}, {0x8a17, 0x0007}, {0x8a18, 0x00b7},
+{0x8a19, 0x008f}, {0x8a1a, 0x0071}, {0x8a1b, 0x00f6},
+{0x8a1c, 0x0012}, {0x8a1d, 0x000c}, {0x8a1e, 0x00c4},
+{0x8a1f, 0x000f}, {0x8a20, 0x00c8}, {0x8a21, 0x000f},
+{0x8a22, 0x00f7}, {0x8a23, 0x008f}, {0x8a24, 0x0072},
+{0x8a25, 0x00f6}, {0x8a26, 0x008f}, {0x8a27, 0x0072},
+{0x8a28, 0x00b6}, {0x8a29, 0x008f}, {0x8a2a, 0x0071},
+{0x8a2b, 0x0084}, {0x8a2c, 0x0003}, {0x8a2d, 0x0027},
+{0x8a2e, 0x0014}, {0x8a2f, 0x0081}, {0x8a30, 0x0001},
+{0x8a31, 0x0027}, {0x8a32, 0x001c}, {0x8a33, 0x0081},
+{0x8a34, 0x0002}, {0x8a35, 0x0027}, {0x8a36, 0x0024},
+{0x8a37, 0x00f4}, {0x8a38, 0x008f}, {0x8a39, 0x0070},
+{0x8a3a, 0x0027}, {0x8a3b, 0x002a}, {0x8a3c, 0x0096},
+{0x8a3d, 0x0022}, {0x8a3e, 0x008a}, {0x8a3f, 0x0080},
+{0x8a40, 0x007e}, {0x8a41, 0x008a}, {0x8a42, 0x0064},
+{0x8a43, 0x00f4}, {0x8a44, 0x008f}, {0x8a45, 0x0070},
+{0x8a46, 0x0027}, {0x8a47, 0x001e}, {0x8a48, 0x0096},
+{0x8a49, 0x0022}, {0x8a4a, 0x008a}, {0x8a4b, 0x0010},
+{0x8a4c, 0x007e}, {0x8a4d, 0x008a}, {0x8a4e, 0x0064},
+{0x8a4f, 0x00f4}, {0x8a50, 0x008f}, {0x8a51, 0x0070},
+{0x8a52, 0x0027}, {0x8a53, 0x0012}, {0x8a54, 0x0096},
+{0x8a55, 0x0022}, {0x8a56, 0x008a}, {0x8a57, 0x0020},
+{0x8a58, 0x007e}, {0x8a59, 0x008a}, {0x8a5a, 0x0064},
+{0x8a5b, 0x00f4}, {0x8a5c, 0x008f}, {0x8a5d, 0x0070},
+{0x8a5e, 0x0027}, {0x8a5f, 0x0006}, {0x8a60, 0x0096},
+{0x8a61, 0x0022}, {0x8a62, 0x008a}, {0x8a63, 0x0040},
+{0x8a64, 0x0097}, {0x8a65, 0x0022}, {0x8a66, 0x0074},
+{0x8a67, 0x008f}, {0x8a68, 0x0071}, {0x8a69, 0x0074},
+{0x8a6a, 0x008f}, {0x8a6b, 0x0071}, {0x8a6c, 0x0078},
+{0x8a6d, 0x008f}, {0x8a6e, 0x0070}, {0x8a6f, 0x00b6},
+{0x8a70, 0x008f}, {0x8a71, 0x0070}, {0x8a72, 0x0085},
+{0x8a73, 0x0010}, {0x8a74, 0x0027}, {0x8a75, 0x00af},
+{0x8a76, 0x00d6}, {0x8a77, 0x0022}, {0x8a78, 0x00c4},
+{0x8a79, 0x0010}, {0x8a7a, 0x0058}, {0x8a7b, 0x00b6},
+{0x8a7c, 0x0012}, {0x8a7d, 0x0070}, {0x8a7e, 0x0081},
+{0x8a7f, 0x00e4}, {0x8a80, 0x0027}, {0x8a81, 0x0036},
+{0x8a82, 0x0081}, {0x8a83, 0x00e1}, {0x8a84, 0x0026},
+{0x8a85, 0x000c}, {0x8a86, 0x0096}, {0x8a87, 0x0022},
+{0x8a88, 0x0084}, {0x8a89, 0x0020}, {0x8a8a, 0x0044},
+{0x8a8b, 0x001b}, {0x8a8c, 0x00d6}, {0x8a8d, 0x0022},
+{0x8a8e, 0x00c4}, {0x8a8f, 0x00cf}, {0x8a90, 0x0020},
+{0x8a91, 0x0023}, {0x8a92, 0x0058}, {0x8a93, 0x0081},
+{0x8a94, 0x00c6}, {0x8a95, 0x0026}, {0x8a96, 0x000d},
+{0x8a97, 0x0096}, {0x8a98, 0x0022}, {0x8a99, 0x0084},
+{0x8a9a, 0x0040}, {0x8a9b, 0x0044}, {0x8a9c, 0x0044},
+{0x8a9d, 0x001b}, {0x8a9e, 0x00d6}, {0x8a9f, 0x0022},
+{0x8aa0, 0x00c4}, {0x8aa1, 0x00af}, {0x8aa2, 0x0020},
+{0x8aa3, 0x0011}, {0x8aa4, 0x0058}, {0x8aa5, 0x0081},
+{0x8aa6, 0x0027}, {0x8aa7, 0x0026}, {0x8aa8, 0x000f},
+{0x8aa9, 0x0096}, {0x8aaa, 0x0022}, {0x8aab, 0x0084},
+{0x8aac, 0x0080}, {0x8aad, 0x0044}, {0x8aae, 0x0044},
+{0x8aaf, 0x0044}, {0x8ab0, 0x001b}, {0x8ab1, 0x00d6},
+{0x8ab2, 0x0022}, {0x8ab3, 0x00c4}, {0x8ab4, 0x006f},
+{0x8ab5, 0x001b}, {0x8ab6, 0x0097}, {0x8ab7, 0x0022},
+{0x8ab8, 0x0039}, {0x8ab9, 0x0027}, {0x8aba, 0x000c},
+{0x8abb, 0x007c}, {0x8abc, 0x0082}, {0x8abd, 0x0006},
+{0x8abe, 0x00bd}, {0x8abf, 0x00d9}, {0x8ac0, 0x00ed},
+{0x8ac1, 0x00b6}, {0x8ac2, 0x0082}, {0x8ac3, 0x0007},
+{0x8ac4, 0x007e}, {0x8ac5, 0x008a}, {0x8ac6, 0x00b9},
+{0x8ac7, 0x007f}, {0x8ac8, 0x0082}, {0x8ac9, 0x0006},
+{0x8aca, 0x0039}, { 0x0, 0x0 }
+};
+#else
+cas_saturn_patch_t cas_saturn_patch[] = {
+{0x8200, 0x007e}, {0x8201, 0x0082}, {0x8202, 0x0009},
+{0x8203, 0x0000}, {0x8204, 0x0000}, {0x8205, 0x0000},
+{0x8206, 0x0000}, {0x8207, 0x0000}, {0x8208, 0x0000},
+{0x8209, 0x008e}, {0x820a, 0x008e}, {0x820b, 0x00ff},
+{0x820c, 0x00ce}, {0x820d, 0x0082}, {0x820e, 0x0025},
+{0x820f, 0x00ff}, {0x8210, 0x0001}, {0x8211, 0x000f},
+{0x8212, 0x00ce}, {0x8213, 0x0084}, {0x8214, 0x0026},
+{0x8215, 0x00ff}, {0x8216, 0x0001}, {0x8217, 0x0011},
+{0x8218, 0x00ce}, {0x8219, 0x0085}, {0x821a, 0x003d},
+{0x821b, 0x00df}, {0x821c, 0x00e5}, {0x821d, 0x0086},
+{0x821e, 0x0039}, {0x821f, 0x00b7}, {0x8220, 0x008f},
+{0x8221, 0x00f8}, {0x8222, 0x007e}, {0x8223, 0x00c3},
+{0x8224, 0x00c2}, {0x8225, 0x0096}, {0x8226, 0x0047},
+{0x8227, 0x0084}, {0x8228, 0x00f3}, {0x8229, 0x008a},
+{0x822a, 0x0000}, {0x822b, 0x0097}, {0x822c, 0x0047},
+{0x822d, 0x00ce}, {0x822e, 0x0082}, {0x822f, 0x0033},
+{0x8230, 0x00ff}, {0x8231, 0x0001}, {0x8232, 0x000f},
+{0x8233, 0x0096}, {0x8234, 0x0046}, {0x8235, 0x0084},
+{0x8236, 0x000c}, {0x8237, 0x0081}, {0x8238, 0x0004},
+{0x8239, 0x0027}, {0x823a, 0x000b}, {0x823b, 0x0096},
+{0x823c, 0x0046}, {0x823d, 0x0084}, {0x823e, 0x000c},
+{0x823f, 0x0081}, {0x8240, 0x0008}, {0x8241, 0x0027},
+{0x8242, 0x0057}, {0x8243, 0x007e}, {0x8244, 0x0084},
+{0x8245, 0x0025}, {0x8246, 0x0096}, {0x8247, 0x0047},
+{0x8248, 0x0084}, {0x8249, 0x00f3}, {0x824a, 0x008a},
+{0x824b, 0x0004}, {0x824c, 0x0097}, {0x824d, 0x0047},
+{0x824e, 0x00ce}, {0x824f, 0x0082}, {0x8250, 0x0054},
+{0x8251, 0x00ff}, {0x8252, 0x0001}, {0x8253, 0x000f},
+{0x8254, 0x0096}, {0x8255, 0x0046}, {0x8256, 0x0084},
+{0x8257, 0x000c}, {0x8258, 0x0081}, {0x8259, 0x0004},
+{0x825a, 0x0026}, {0x825b, 0x0038}, {0x825c, 0x00b6},
+{0x825d, 0x0012}, {0x825e, 0x0020}, {0x825f, 0x0084},
+{0x8260, 0x0020}, {0x8261, 0x0026}, {0x8262, 0x0003},
+{0x8263, 0x007e}, {0x8264, 0x0084}, {0x8265, 0x0025},
+{0x8266, 0x0096}, {0x8267, 0x007b}, {0x8268, 0x00d6},
+{0x8269, 0x007c}, {0x826a, 0x00fe}, {0x826b, 0x008f},
+{0x826c, 0x0056}, {0x826d, 0x00bd}, {0x826e, 0x00f7},
+{0x826f, 0x00b6}, {0x8270, 0x00fe}, {0x8271, 0x008f},
+{0x8272, 0x004e}, {0x8273, 0x00bd}, {0x8274, 0x00ec},
+{0x8275, 0x008e}, {0x8276, 0x00bd}, {0x8277, 0x00fa},
+{0x8278, 0x00f7}, {0x8279, 0x00bd}, {0x827a, 0x00f7},
+{0x827b, 0x0028}, {0x827c, 0x00ce}, {0x827d, 0x0082},
+{0x827e, 0x0082}, {0x827f, 0x00ff}, {0x8280, 0x0001},
+{0x8281, 0x000f}, {0x8282, 0x0096}, {0x8283, 0x0046},
+{0x8284, 0x0084}, {0x8285, 0x000c}, {0x8286, 0x0081},
+{0x8287, 0x0004}, {0x8288, 0x0026}, {0x8289, 0x000a},
+{0x828a, 0x00b6}, {0x828b, 0x0012}, {0x828c, 0x0020},
+{0x828d, 0x0084}, {0x828e, 0x0020}, {0x828f, 0x0027},
+{0x8290, 0x00b5}, {0x8291, 0x007e}, {0x8292, 0x0084},
+{0x8293, 0x0025}, {0x8294, 0x00bd}, {0x8295, 0x00f7},
+{0x8296, 0x001f}, {0x8297, 0x007e}, {0x8298, 0x0084},
+{0x8299, 0x001f}, {0x829a, 0x0096}, {0x829b, 0x0047},
+{0x829c, 0x0084}, {0x829d, 0x00f3}, {0x829e, 0x008a},
+{0x829f, 0x0008}, {0x82a0, 0x0097}, {0x82a1, 0x0047},
+{0x82a2, 0x00de}, {0x82a3, 0x00e1}, {0x82a4, 0x00ad},
+{0x82a5, 0x0000}, {0x82a6, 0x00ce}, {0x82a7, 0x0082},
+{0x82a8, 0x00af}, {0x82a9, 0x00ff}, {0x82aa, 0x0001},
+{0x82ab, 0x000f}, {0x82ac, 0x007e}, {0x82ad, 0x0084},
+{0x82ae, 0x0025}, {0x82af, 0x0096}, {0x82b0, 0x0041},
+{0x82b1, 0x0085}, {0x82b2, 0x0010}, {0x82b3, 0x0026},
+{0x82b4, 0x0006}, {0x82b5, 0x0096}, {0x82b6, 0x0023},
+{0x82b7, 0x0085}, {0x82b8, 0x0040}, {0x82b9, 0x0027},
+{0x82ba, 0x0006}, {0x82bb, 0x00bd}, {0x82bc, 0x00ed},
+{0x82bd, 0x0000}, {0x82be, 0x007e}, {0x82bf, 0x0083},
+{0x82c0, 0x00a2}, {0x82c1, 0x00de}, {0x82c2, 0x0042},
+{0x82c3, 0x00bd}, {0x82c4, 0x00eb}, {0x82c5, 0x008e},
+{0x82c6, 0x0096}, {0x82c7, 0x0024}, {0x82c8, 0x0084},
+{0x82c9, 0x0008}, {0x82ca, 0x0027}, {0x82cb, 0x0003},
+{0x82cc, 0x007e}, {0x82cd, 0x0083}, {0x82ce, 0x00df},
+{0x82cf, 0x0096}, {0x82d0, 0x007b}, {0x82d1, 0x00d6},
+{0x82d2, 0x007c}, {0x82d3, 0x00fe}, {0x82d4, 0x008f},
+{0x82d5, 0x0056}, {0x82d6, 0x00bd}, {0x82d7, 0x00f7},
+{0x82d8, 0x00b6}, {0x82d9, 0x00fe}, {0x82da, 0x008f},
+{0x82db, 0x0050}, {0x82dc, 0x00bd}, {0x82dd, 0x00ec},
+{0x82de, 0x008e}, {0x82df, 0x00bd}, {0x82e0, 0x00fa},
+{0x82e1, 0x00f7}, {0x82e2, 0x0086}, {0x82e3, 0x0011},
+{0x82e4, 0x00c6}, {0x82e5, 0x0049}, {0x82e6, 0x00bd},
+{0x82e7, 0x00e4}, {0x82e8, 0x0012}, {0x82e9, 0x00ce},
+{0x82ea, 0x0082}, {0x82eb, 0x00ef}, {0x82ec, 0x00ff},
+{0x82ed, 0x0001}, {0x82ee, 0x000f}, {0x82ef, 0x0096},
+{0x82f0, 0x0046}, {0x82f1, 0x0084}, {0x82f2, 0x000c},
+{0x82f3, 0x0081}, {0x82f4, 0x0000}, {0x82f5, 0x0027},
+{0x82f6, 0x0017}, {0x82f7, 0x00c6}, {0x82f8, 0x0049},
+{0x82f9, 0x00bd}, {0x82fa, 0x00e4}, {0x82fb, 0x0091},
+{0x82fc, 0x0024}, {0x82fd, 0x000d}, {0x82fe, 0x00b6},
+{0x82ff, 0x0012}, {0x8300, 0x0020}, {0x8301, 0x0085},
+{0x8302, 0x0020}, {0x8303, 0x0026}, {0x8304, 0x000c},
+{0x8305, 0x00ce}, {0x8306, 0x0082}, {0x8307, 0x00c1},
+{0x8308, 0x00ff}, {0x8309, 0x0001}, {0x830a, 0x000f},
+{0x830b, 0x007e}, {0x830c, 0x0084}, {0x830d, 0x0025},
+{0x830e, 0x007e}, {0x830f, 0x0084}, {0x8310, 0x0016},
+{0x8311, 0x00fe}, {0x8312, 0x008f}, {0x8313, 0x0052},
+{0x8314, 0x00bd}, {0x8315, 0x00ec}, {0x8316, 0x008e},
+{0x8317, 0x00bd}, {0x8318, 0x00fa}, {0x8319, 0x00f7},
+{0x831a, 0x0086}, {0x831b, 0x006a}, {0x831c, 0x00c6},
+{0x831d, 0x0049}, {0x831e, 0x00bd}, {0x831f, 0x00e4},
+{0x8320, 0x0012}, {0x8321, 0x00ce}, {0x8322, 0x0083},
+{0x8323, 0x0027}, {0x8324, 0x00ff}, {0x8325, 0x0001},
+{0x8326, 0x000f}, {0x8327, 0x0096}, {0x8328, 0x0046},
+{0x8329, 0x0084}, {0x832a, 0x000c}, {0x832b, 0x0081},
+{0x832c, 0x0000}, {0x832d, 0x0027}, {0x832e, 0x000a},
+{0x832f, 0x00c6}, {0x8330, 0x0049}, {0x8331, 0x00bd},
+{0x8332, 0x00e4}, {0x8333, 0x0091}, {0x8334, 0x0025},
+{0x8335, 0x0006}, {0x8336, 0x007e}, {0x8337, 0x0084},
+{0x8338, 0x0025}, {0x8339, 0x007e}, {0x833a, 0x0084},
+{0x833b, 0x0016}, {0x833c, 0x00b6}, {0x833d, 0x0018},
+{0x833e, 0x0070}, {0x833f, 0x00bb}, {0x8340, 0x0019},
+{0x8341, 0x0070}, {0x8342, 0x002a}, {0x8343, 0x0004},
+{0x8344, 0x0081}, {0x8345, 0x00af}, {0x8346, 0x002e},
+{0x8347, 0x0019}, {0x8348, 0x0096}, {0x8349, 0x007b},
+{0x834a, 0x00f6}, {0x834b, 0x0020}, {0x834c, 0x0007},
+{0x834d, 0x00fa}, {0x834e, 0x0020}, {0x834f, 0x0027},
+{0x8350, 0x00c4}, {0x8351, 0x0038}, {0x8352, 0x0081},
+{0x8353, 0x0038}, {0x8354, 0x0027}, {0x8355, 0x000b},
+{0x8356, 0x00f6}, {0x8357, 0x0020}, {0x8358, 0x0007},
+{0x8359, 0x00fa}, {0x835a, 0x0020}, {0x835b, 0x0027},
+{0x835c, 0x00cb}, {0x835d, 0x0008}, {0x835e, 0x007e},
+{0x835f, 0x0082}, {0x8360, 0x00d3}, {0x8361, 0x00bd},
+{0x8362, 0x00f7}, {0x8363, 0x0066}, {0x8364, 0x0086},
+{0x8365, 0x0074}, {0x8366, 0x00c6}, {0x8367, 0x0049},
+{0x8368, 0x00bd}, {0x8369, 0x00e4}, {0x836a, 0x0012},
+{0x836b, 0x00ce}, {0x836c, 0x0083}, {0x836d, 0x0071},
+{0x836e, 0x00ff}, {0x836f, 0x0001}, {0x8370, 0x000f},
+{0x8371, 0x0096}, {0x8372, 0x0046}, {0x8373, 0x0084},
+{0x8374, 0x000c}, {0x8375, 0x0081}, {0x8376, 0x0008},
+{0x8377, 0x0026}, {0x8378, 0x000a}, {0x8379, 0x00c6},
+{0x837a, 0x0049}, {0x837b, 0x00bd}, {0x837c, 0x00e4},
+{0x837d, 0x0091}, {0x837e, 0x0025}, {0x837f, 0x0006},
+{0x8380, 0x007e}, {0x8381, 0x0084}, {0x8382, 0x0025},
+{0x8383, 0x007e}, {0x8384, 0x0084}, {0x8385, 0x0016},
+{0x8386, 0x00bd}, {0x8387, 0x00f7}, {0x8388, 0x003e},
+{0x8389, 0x0026}, {0x838a, 0x000e}, {0x838b, 0x00bd},
+{0x838c, 0x00e5}, {0x838d, 0x0009}, {0x838e, 0x0026},
+{0x838f, 0x0006}, {0x8390, 0x00ce}, {0x8391, 0x0082},
+{0x8392, 0x00c1}, {0x8393, 0x00ff}, {0x8394, 0x0001},
+{0x8395, 0x000f}, {0x8396, 0x007e}, {0x8397, 0x0084},
+{0x8398, 0x0025}, {0x8399, 0x00fe}, {0x839a, 0x008f},
+{0x839b, 0x0054}, {0x839c, 0x00bd}, {0x839d, 0x00ec},
+{0x839e, 0x008e}, {0x839f, 0x00bd}, {0x83a0, 0x00fa},
+{0x83a1, 0x00f7}, {0x83a2, 0x00bd}, {0x83a3, 0x00f7},
+{0x83a4, 0x0033}, {0x83a5, 0x0086}, {0x83a6, 0x000f},
+{0x83a7, 0x00c6}, {0x83a8, 0x0051}, {0x83a9, 0x00bd},
+{0x83aa, 0x00e4}, {0x83ab, 0x0012}, {0x83ac, 0x00ce},
+{0x83ad, 0x0083}, {0x83ae, 0x00b2}, {0x83af, 0x00ff},
+{0x83b0, 0x0001}, {0x83b1, 0x000f}, {0x83b2, 0x0096},
+{0x83b3, 0x0046}, {0x83b4, 0x0084}, {0x83b5, 0x000c},
+{0x83b6, 0x0081}, {0x83b7, 0x0008}, {0x83b8, 0x0026},
+{0x83b9, 0x005c}, {0x83ba, 0x00b6}, {0x83bb, 0x0012},
+{0x83bc, 0x0020}, {0x83bd, 0x0084}, {0x83be, 0x003f},
+{0x83bf, 0x0081}, {0x83c0, 0x003a}, {0x83c1, 0x0027},
+{0x83c2, 0x001c}, {0x83c3, 0x0096}, {0x83c4, 0x0023},
+{0x83c5, 0x0085}, {0x83c6, 0x0040}, {0x83c7, 0x0027},
+{0x83c8, 0x0003}, {0x83c9, 0x007e}, {0x83ca, 0x0084},
+{0x83cb, 0x0025}, {0x83cc, 0x00c6}, {0x83cd, 0x0051},
+{0x83ce, 0x00bd}, {0x83cf, 0x00e4}, {0x83d0, 0x0091},
+{0x83d1, 0x0025}, {0x83d2, 0x0003}, {0x83d3, 0x007e},
+{0x83d4, 0x0084}, {0x83d5, 0x0025}, {0x83d6, 0x00ce},
+{0x83d7, 0x0082}, {0x83d8, 0x00c1}, {0x83d9, 0x00ff},
+{0x83da, 0x0001}, {0x83db, 0x000f}, {0x83dc, 0x007e},
+{0x83dd, 0x0084}, {0x83de, 0x0025}, {0x83df, 0x00bd},
+{0x83e0, 0x00f8}, {0x83e1, 0x0037}, {0x83e2, 0x007c},
+{0x83e3, 0x0000}, {0x83e4, 0x007a}, {0x83e5, 0x00ce},
+{0x83e6, 0x0083}, {0x83e7, 0x00ee}, {0x83e8, 0x00ff},
+{0x83e9, 0x0001}, {0x83ea, 0x000f}, {0x83eb, 0x007e},
+{0x83ec, 0x0084}, {0x83ed, 0x0025}, {0x83ee, 0x0096},
+{0x83ef, 0x0046}, {0x83f0, 0x0084}, {0x83f1, 0x000c},
+{0x83f2, 0x0081}, {0x83f3, 0x0008}, {0x83f4, 0x0026},
+{0x83f5, 0x0020}, {0x83f6, 0x0096}, {0x83f7, 0x0024},
+{0x83f8, 0x0084}, {0x83f9, 0x0008}, {0x83fa, 0x0026},
+{0x83fb, 0x0029}, {0x83fc, 0x00b6}, {0x83fd, 0x0018},
+{0x83fe, 0x0082}, {0x83ff, 0x00bb}, {0x8400, 0x0019},
+{0x8401, 0x0082}, {0x8402, 0x00b1}, {0x8403, 0x0001},
+{0x8404, 0x003b}, {0x8405, 0x0022}, {0x8406, 0x0009},
+{0x8407, 0x00b6}, {0x8408, 0x0012}, {0x8409, 0x0020},
+{0x840a, 0x0084}, {0x840b, 0x0037}, {0x840c, 0x0081},
+{0x840d, 0x0032}, {0x840e, 0x0027}, {0x840f, 0x0015},
+{0x8410, 0x00bd}, {0x8411, 0x00f8}, {0x8412, 0x0044},
+{0x8413, 0x007e}, {0x8414, 0x0082}, {0x8415, 0x00c1},
+{0x8416, 0x00bd}, {0x8417, 0x00f7}, {0x8418, 0x001f},
+{0x8419, 0x00bd}, {0x841a, 0x00f8}, {0x841b, 0x0044},
+{0x841c, 0x00bd}, {0x841d, 0x00fc}, {0x841e, 0x0029},
+{0x841f, 0x00ce}, {0x8420, 0x0082}, {0x8421, 0x0025},
+{0x8422, 0x00ff}, {0x8423, 0x0001}, {0x8424, 0x000f},
+{0x8425, 0x0039}, {0x8426, 0x0096}, {0x8427, 0x0047},
+{0x8428, 0x0084}, {0x8429, 0x00fc}, {0x842a, 0x008a},
+{0x842b, 0x0000}, {0x842c, 0x0097}, {0x842d, 0x0047},
+{0x842e, 0x00ce}, {0x842f, 0x0084}, {0x8430, 0x0034},
+{0x8431, 0x00ff}, {0x8432, 0x0001}, {0x8433, 0x0011},
+{0x8434, 0x0096}, {0x8435, 0x0046}, {0x8436, 0x0084},
+{0x8437, 0x0003}, {0x8438, 0x0081}, {0x8439, 0x0002},
+{0x843a, 0x0027}, {0x843b, 0x0003}, {0x843c, 0x007e},
+{0x843d, 0x0085}, {0x843e, 0x001e}, {0x843f, 0x0096},
+{0x8440, 0x0047}, {0x8441, 0x0084}, {0x8442, 0x00fc},
+{0x8443, 0x008a}, {0x8444, 0x0002}, {0x8445, 0x0097},
+{0x8446, 0x0047}, {0x8447, 0x00de}, {0x8448, 0x00e1},
+{0x8449, 0x00ad}, {0x844a, 0x0000}, {0x844b, 0x0086},
+{0x844c, 0x0001}, {0x844d, 0x00b7}, {0x844e, 0x0012},
+{0x844f, 0x0051}, {0x8450, 0x00bd}, {0x8451, 0x00f7},
+{0x8452, 0x0014}, {0x8453, 0x00b6}, {0x8454, 0x0010},
+{0x8455, 0x0031}, {0x8456, 0x0084}, {0x8457, 0x00fd},
+{0x8458, 0x00b7}, {0x8459, 0x0010}, {0x845a, 0x0031},
+{0x845b, 0x00bd}, {0x845c, 0x00f8}, {0x845d, 0x001e},
+{0x845e, 0x0096}, {0x845f, 0x0081}, {0x8460, 0x00d6},
+{0x8461, 0x0082}, {0x8462, 0x00fe}, {0x8463, 0x008f},
+{0x8464, 0x005a}, {0x8465, 0x00bd}, {0x8466, 0x00f7},
+{0x8467, 0x00b6}, {0x8468, 0x00fe}, {0x8469, 0x008f},
+{0x846a, 0x005c}, {0x846b, 0x00bd}, {0x846c, 0x00ec},
+{0x846d, 0x008e}, {0x846e, 0x00bd}, {0x846f, 0x00fa},
+{0x8470, 0x00f7}, {0x8471, 0x0086}, {0x8472, 0x0008},
+{0x8473, 0x00d6}, {0x8474, 0x0000}, {0x8475, 0x00c5},
+{0x8476, 0x0010}, {0x8477, 0x0026}, {0x8478, 0x0002},
+{0x8479, 0x008b}, {0x847a, 0x0020}, {0x847b, 0x00c6},
+{0x847c, 0x0051}, {0x847d, 0x00bd}, {0x847e, 0x00e4},
+{0x847f, 0x0012}, {0x8480, 0x00ce}, {0x8481, 0x0084},
+{0x8482, 0x0086}, {0x8483, 0x00ff}, {0x8484, 0x0001},
+{0x8485, 0x0011}, {0x8486, 0x0096}, {0x8487, 0x0046},
+{0x8488, 0x0084}, {0x8489, 0x0003}, {0x848a, 0x0081},
+{0x848b, 0x0002}, {0x848c, 0x0027}, {0x848d, 0x0003},
+{0x848e, 0x007e}, {0x848f, 0x0085}, {0x8490, 0x000f},
+{0x8491, 0x00c6}, {0x8492, 0x0051}, {0x8493, 0x00bd},
+{0x8494, 0x00e4}, {0x8495, 0x0091}, {0x8496, 0x0025},
+{0x8497, 0x0003}, {0x8498, 0x007e}, {0x8499, 0x0085},
+{0x849a, 0x001e}, {0x849b, 0x0096}, {0x849c, 0x0044},
+{0x849d, 0x0085}, {0x849e, 0x0010}, {0x849f, 0x0026},
+{0x84a0, 0x000a}, {0x84a1, 0x00b6}, {0x84a2, 0x0012},
+{0x84a3, 0x0050}, {0x84a4, 0x00ba}, {0x84a5, 0x0001},
+{0x84a6, 0x003c}, {0x84a7, 0x0085}, {0x84a8, 0x0010},
+{0x84a9, 0x0027}, {0x84aa, 0x00a8}, {0x84ab, 0x00bd},
+{0x84ac, 0x00f7}, {0x84ad, 0x0066}, {0x84ae, 0x00ce},
+{0x84af, 0x0084}, {0x84b0, 0x00b7}, {0x84b1, 0x00ff},
+{0x84b2, 0x0001}, {0x84b3, 0x0011}, {0x84b4, 0x007e},
+{0x84b5, 0x0085}, {0x84b6, 0x001e}, {0x84b7, 0x0096},
+{0x84b8, 0x0046}, {0x84b9, 0x0084}, {0x84ba, 0x0003},
+{0x84bb, 0x0081}, {0x84bc, 0x0002}, {0x84bd, 0x0026},
+{0x84be, 0x0050}, {0x84bf, 0x00b6}, {0x84c0, 0x0012},
+{0x84c1, 0x0030}, {0x84c2, 0x0084}, {0x84c3, 0x0003},
+{0x84c4, 0x0081}, {0x84c5, 0x0001}, {0x84c6, 0x0027},
+{0x84c7, 0x0003}, {0x84c8, 0x007e}, {0x84c9, 0x0085},
+{0x84ca, 0x001e}, {0x84cb, 0x0096}, {0x84cc, 0x0044},
+{0x84cd, 0x0085}, {0x84ce, 0x0010}, {0x84cf, 0x0026},
+{0x84d0, 0x0013}, {0x84d1, 0x00b6}, {0x84d2, 0x0012},
+{0x84d3, 0x0050}, {0x84d4, 0x00ba}, {0x84d5, 0x0001},
+{0x84d6, 0x003c}, {0x84d7, 0x0085}, {0x84d8, 0x0010},
+{0x84d9, 0x0026}, {0x84da, 0x0009}, {0x84db, 0x00ce},
+{0x84dc, 0x0084}, {0x84dd, 0x0053}, {0x84de, 0x00ff},
+{0x84df, 0x0001}, {0x84e0, 0x0011}, {0x84e1, 0x007e},
+{0x84e2, 0x0085}, {0x84e3, 0x001e}, {0x84e4, 0x00b6},
+{0x84e5, 0x0010}, {0x84e6, 0x0031}, {0x84e7, 0x008a},
+{0x84e8, 0x0002}, {0x84e9, 0x00b7}, {0x84ea, 0x0010},
+{0x84eb, 0x0031}, {0x84ec, 0x00bd}, {0x84ed, 0x0085},
+{0x84ee, 0x001f}, {0x84ef, 0x00bd}, {0x84f0, 0x00f8},
+{0x84f1, 0x0037}, {0x84f2, 0x007c}, {0x84f3, 0x0000},
+{0x84f4, 0x0080}, {0x84f5, 0x00ce}, {0x84f6, 0x0084},
+{0x84f7, 0x00fe}, {0x84f8, 0x00ff}, {0x84f9, 0x0001},
+{0x84fa, 0x0011}, {0x84fb, 0x007e}, {0x84fc, 0x0085},
+{0x84fd, 0x001e}, {0x84fe, 0x0096}, {0x84ff, 0x0046},
+{0x8500, 0x0084}, {0x8501, 0x0003}, {0x8502, 0x0081},
+{0x8503, 0x0002}, {0x8504, 0x0026}, {0x8505, 0x0009},
+{0x8506, 0x00b6}, {0x8507, 0x0012}, {0x8508, 0x0030},
+{0x8509, 0x0084}, {0x850a, 0x0003}, {0x850b, 0x0081},
+{0x850c, 0x0001}, {0x850d, 0x0027}, {0x850e, 0x000f},
+{0x850f, 0x00bd}, {0x8510, 0x00f8}, {0x8511, 0x0044},
+{0x8512, 0x00bd}, {0x8513, 0x00f7}, {0x8514, 0x000b},
+{0x8515, 0x00bd}, {0x8516, 0x00fc}, {0x8517, 0x0029},
+{0x8518, 0x00ce}, {0x8519, 0x0084}, {0x851a, 0x0026},
+{0x851b, 0x00ff}, {0x851c, 0x0001}, {0x851d, 0x0011},
+{0x851e, 0x0039}, {0x851f, 0x00d6}, {0x8520, 0x0022},
+{0x8521, 0x00c4}, {0x8522, 0x000f}, {0x8523, 0x00b6},
+{0x8524, 0x0012}, {0x8525, 0x0030}, {0x8526, 0x00ba},
+{0x8527, 0x0012}, {0x8528, 0x0032}, {0x8529, 0x0084},
+{0x852a, 0x0004}, {0x852b, 0x0027}, {0x852c, 0x000d},
+{0x852d, 0x0096}, {0x852e, 0x0022}, {0x852f, 0x0085},
+{0x8530, 0x0004}, {0x8531, 0x0027}, {0x8532, 0x0005},
+{0x8533, 0x00ca}, {0x8534, 0x0010}, {0x8535, 0x007e},
+{0x8536, 0x0085}, {0x8537, 0x003a}, {0x8538, 0x00ca},
+{0x8539, 0x0020}, {0x853a, 0x00d7}, {0x853b, 0x0022},
+{0x853c, 0x0039}, {0x853d, 0x0086}, {0x853e, 0x0000},
+{0x853f, 0x0097}, {0x8540, 0x0083}, {0x8541, 0x0018},
+{0x8542, 0x00ce}, {0x8543, 0x001c}, {0x8544, 0x0000},
+{0x8545, 0x00bd}, {0x8546, 0x00eb}, {0x8547, 0x0046},
+{0x8548, 0x0096}, {0x8549, 0x0057}, {0x854a, 0x0085},
+{0x854b, 0x0001}, {0x854c, 0x0027}, {0x854d, 0x0002},
+{0x854e, 0x004f}, {0x854f, 0x0039}, {0x8550, 0x0085},
+{0x8551, 0x0002}, {0x8552, 0x0027}, {0x8553, 0x0001},
+{0x8554, 0x0039}, {0x8555, 0x007f}, {0x8556, 0x008f},
+{0x8557, 0x007d}, {0x8558, 0x0086}, {0x8559, 0x0004},
+{0x855a, 0x00b7}, {0x855b, 0x0012}, {0x855c, 0x0004},
+{0x855d, 0x0086}, {0x855e, 0x0008}, {0x855f, 0x00b7},
+{0x8560, 0x0012}, {0x8561, 0x0007}, {0x8562, 0x0086},
+{0x8563, 0x0010}, {0x8564, 0x00b7}, {0x8565, 0x0012},
+{0x8566, 0x000c}, {0x8567, 0x0086}, {0x8568, 0x0007},
+{0x8569, 0x00b7}, {0x856a, 0x0012}, {0x856b, 0x0006},
+{0x856c, 0x00b6}, {0x856d, 0x008f}, {0x856e, 0x007d},
+{0x856f, 0x00b7}, {0x8570, 0x0012}, {0x8571, 0x0070},
+{0x8572, 0x0086}, {0x8573, 0x0001}, {0x8574, 0x00ba},
+{0x8575, 0x0012}, {0x8576, 0x0004}, {0x8577, 0x00b7},
+{0x8578, 0x0012}, {0x8579, 0x0004}, {0x857a, 0x0001},
+{0x857b, 0x0001}, {0x857c, 0x0001}, {0x857d, 0x0001},
+{0x857e, 0x0001}, {0x857f, 0x0001}, {0x8580, 0x00b6},
+{0x8581, 0x0012}, {0x8582, 0x0004}, {0x8583, 0x0084},
+{0x8584, 0x00fe}, {0x8585, 0x008a}, {0x8586, 0x0002},
+{0x8587, 0x00b7}, {0x8588, 0x0012}, {0x8589, 0x0004},
+{0x858a, 0x0001}, {0x858b, 0x0001}, {0x858c, 0x0001},
+{0x858d, 0x0001}, {0x858e, 0x0001}, {0x858f, 0x0001},
+{0x8590, 0x0086}, {0x8591, 0x00fd}, {0x8592, 0x00b4},
+{0x8593, 0x0012}, {0x8594, 0x0004}, {0x8595, 0x00b7},
+{0x8596, 0x0012}, {0x8597, 0x0004}, {0x8598, 0x00b6},
+{0x8599, 0x0012}, {0x859a, 0x0000}, {0x859b, 0x0084},
+{0x859c, 0x0008}, {0x859d, 0x0081}, {0x859e, 0x0008},
+{0x859f, 0x0027}, {0x85a0, 0x0016}, {0x85a1, 0x00b6},
+{0x85a2, 0x008f}, {0x85a3, 0x007d}, {0x85a4, 0x0081},
+{0x85a5, 0x000c}, {0x85a6, 0x0027}, {0x85a7, 0x0008},
+{0x85a8, 0x008b}, {0x85a9, 0x0004}, {0x85aa, 0x00b7},
+{0x85ab, 0x008f}, {0x85ac, 0x007d}, {0x85ad, 0x007e},
+{0x85ae, 0x0085}, {0x85af, 0x006c}, {0x85b0, 0x0086},
+{0x85b1, 0x0003}, {0x85b2, 0x0097}, {0x85b3, 0x0040},
+{0x85b4, 0x007e}, {0x85b5, 0x0089}, {0x85b6, 0x006e},
+{0x85b7, 0x0086}, {0x85b8, 0x0007}, {0x85b9, 0x00b7},
+{0x85ba, 0x0012}, {0x85bb, 0x0006}, {0x85bc, 0x005f},
+{0x85bd, 0x00f7}, {0x85be, 0x008f}, {0x85bf, 0x0082},
+{0x85c0, 0x005f}, {0x85c1, 0x00f7}, {0x85c2, 0x008f},
+{0x85c3, 0x007f}, {0x85c4, 0x00f7}, {0x85c5, 0x008f},
+{0x85c6, 0x0070}, {0x85c7, 0x00f7}, {0x85c8, 0x008f},
+{0x85c9, 0x0071}, {0x85ca, 0x00f7}, {0x85cb, 0x008f},
+{0x85cc, 0x0072}, {0x85cd, 0x00f7}, {0x85ce, 0x008f},
+{0x85cf, 0x0073}, {0x85d0, 0x00f7}, {0x85d1, 0x008f},
+{0x85d2, 0x0074}, {0x85d3, 0x00f7}, {0x85d4, 0x008f},
+{0x85d5, 0x0075}, {0x85d6, 0x00f7}, {0x85d7, 0x008f},
+{0x85d8, 0x0076}, {0x85d9, 0x00f7}, {0x85da, 0x008f},
+{0x85db, 0x0077}, {0x85dc, 0x00f7}, {0x85dd, 0x008f},
+{0x85de, 0x0078}, {0x85df, 0x00f7}, {0x85e0, 0x008f},
+{0x85e1, 0x0079}, {0x85e2, 0x00f7}, {0x85e3, 0x008f},
+{0x85e4, 0x007a}, {0x85e5, 0x00f7}, {0x85e6, 0x008f},
+{0x85e7, 0x007b}, {0x85e8, 0x00b6}, {0x85e9, 0x0012},
+{0x85ea, 0x0004}, {0x85eb, 0x008a}, {0x85ec, 0x0010},
+{0x85ed, 0x00b7}, {0x85ee, 0x0012}, {0x85ef, 0x0004},
+{0x85f0, 0x0086}, {0x85f1, 0x00e4}, {0x85f2, 0x00b7},
+{0x85f3, 0x0012}, {0x85f4, 0x0070}, {0x85f5, 0x00b7},
+{0x85f6, 0x0012}, {0x85f7, 0x0007}, {0x85f8, 0x00f7},
+{0x85f9, 0x0012}, {0x85fa, 0x0005}, {0x85fb, 0x00f7},
+{0x85fc, 0x0012}, {0x85fd, 0x0009}, {0x85fe, 0x0086},
+{0x85ff, 0x0008}, {0x8600, 0x00ba}, {0x8601, 0x0012},
+{0x8602, 0x0004}, {0x8603, 0x00b7}, {0x8604, 0x0012},
+{0x8605, 0x0004}, {0x8606, 0x0086}, {0x8607, 0x00f7},
+{0x8608, 0x00b4}, {0x8609, 0x0012}, {0x860a, 0x0004},
+{0x860b, 0x00b7}, {0x860c, 0x0012}, {0x860d, 0x0004},
+{0x860e, 0x0001}, {0x860f, 0x0001}, {0x8610, 0x0001},
+{0x8611, 0x0001}, {0x8612, 0x0001}, {0x8613, 0x0001},
+{0x8614, 0x00b6}, {0x8615, 0x0012}, {0x8616, 0x0008},
+{0x8617, 0x0027}, {0x8618, 0x007f}, {0x8619, 0x0081},
+{0x861a, 0x0080}, {0x861b, 0x0026}, {0x861c, 0x000b},
+{0x861d, 0x0086}, {0x861e, 0x0008}, {0x861f, 0x00ce},
+{0x8620, 0x008f}, {0x8621, 0x0079}, {0x8622, 0x00bd},
+{0x8623, 0x0089}, {0x8624, 0x007b}, {0x8625, 0x007e},
+{0x8626, 0x0086}, {0x8627, 0x008e}, {0x8628, 0x0081},
+{0x8629, 0x0040}, {0x862a, 0x0026}, {0x862b, 0x000b},
+{0x862c, 0x0086}, {0x862d, 0x0004}, {0x862e, 0x00ce},
+{0x862f, 0x008f}, {0x8630, 0x0076}, {0x8631, 0x00bd},
+{0x8632, 0x0089}, {0x8633, 0x007b}, {0x8634, 0x007e},
+{0x8635, 0x0086}, {0x8636, 0x008e}, {0x8637, 0x0081},
+{0x8638, 0x0020}, {0x8639, 0x0026}, {0x863a, 0x000b},
+{0x863b, 0x0086}, {0x863c, 0x0002}, {0x863d, 0x00ce},
+{0x863e, 0x008f}, {0x863f, 0x0073}, {0x8640, 0x00bd},
+{0x8641, 0x0089}, {0x8642, 0x007b}, {0x8643, 0x007e},
+{0x8644, 0x0086}, {0x8645, 0x008e}, {0x8646, 0x0081},
+{0x8647, 0x0010}, {0x8648, 0x0026}, {0x8649, 0x000b},
+{0x864a, 0x0086}, {0x864b, 0x0001}, {0x864c, 0x00ce},
+{0x864d, 0x008f}, {0x864e, 0x0070}, {0x864f, 0x00bd},
+{0x8650, 0x0089}, {0x8651, 0x007b}, {0x8652, 0x007e},
+{0x8653, 0x0086}, {0x8654, 0x008e}, {0x8655, 0x0081},
+{0x8656, 0x0008}, {0x8657, 0x0026}, {0x8658, 0x000b},
+{0x8659, 0x0086}, {0x865a, 0x0008}, {0x865b, 0x00ce},
+{0x865c, 0x008f}, {0x865d, 0x0079}, {0x865e, 0x00bd},
+{0x865f, 0x0089}, {0x8660, 0x007f}, {0x8661, 0x007e},
+{0x8662, 0x0086}, {0x8663, 0x008e}, {0x8664, 0x0081},
+{0x8665, 0x0004}, {0x8666, 0x0026}, {0x8667, 0x000b},
+{0x8668, 0x0086}, {0x8669, 0x0004}, {0x866a, 0x00ce},
+{0x866b, 0x008f}, {0x866c, 0x0076}, {0x866d, 0x00bd},
+{0x866e, 0x0089}, {0x866f, 0x007f}, {0x8670, 0x007e},
+{0x8671, 0x0086}, {0x8672, 0x008e}, {0x8673, 0x0081},
+{0x8674, 0x0002}, {0x8675, 0x0026}, {0x8676, 0x000b},
+{0x8677, 0x008a}, {0x8678, 0x0002}, {0x8679, 0x00ce},
+{0x867a, 0x008f}, {0x867b, 0x0073}, {0x867c, 0x00bd},
+{0x867d, 0x0089}, {0x867e, 0x007f}, {0x867f, 0x007e},
+{0x8680, 0x0086}, {0x8681, 0x008e}, {0x8682, 0x0081},
+{0x8683, 0x0001}, {0x8684, 0x0026}, {0x8685, 0x0008},
+{0x8686, 0x0086}, {0x8687, 0x0001}, {0x8688, 0x00ce},
+{0x8689, 0x008f}, {0x868a, 0x0070}, {0x868b, 0x00bd},
+{0x868c, 0x0089}, {0x868d, 0x007f}, {0x868e, 0x00b6},
+{0x868f, 0x008f}, {0x8690, 0x007f}, {0x8691, 0x0081},
+{0x8692, 0x000f}, {0x8693, 0x0026}, {0x8694, 0x0003},
+{0x8695, 0x007e}, {0x8696, 0x0087}, {0x8697, 0x0047},
+{0x8698, 0x00b6}, {0x8699, 0x0012}, {0x869a, 0x0009},
+{0x869b, 0x0084}, {0x869c, 0x0003}, {0x869d, 0x0081},
+{0x869e, 0x0003}, {0x869f, 0x0027}, {0x86a0, 0x0006},
+{0x86a1, 0x007c}, {0x86a2, 0x0012}, {0x86a3, 0x0009},
+{0x86a4, 0x007e}, {0x86a5, 0x0085}, {0x86a6, 0x00fe},
+{0x86a7, 0x00b6}, {0x86a8, 0x0012}, {0x86a9, 0x0006},
+{0x86aa, 0x0084}, {0x86ab, 0x0007}, {0x86ac, 0x0081},
+{0x86ad, 0x0007}, {0x86ae, 0x0027}, {0x86af, 0x0008},
+{0x86b0, 0x008b}, {0x86b1, 0x0001}, {0x86b2, 0x00b7},
+{0x86b3, 0x0012}, {0x86b4, 0x0006}, {0x86b5, 0x007e},
+{0x86b6, 0x0086}, {0x86b7, 0x00d5}, {0x86b8, 0x00b6},
+{0x86b9, 0x008f}, {0x86ba, 0x0082}, {0x86bb, 0x0026},
+{0x86bc, 0x000a}, {0x86bd, 0x007c}, {0x86be, 0x008f},
+{0x86bf, 0x0082}, {0x86c0, 0x004f}, {0x86c1, 0x00b7},
+{0x86c2, 0x0012}, {0x86c3, 0x0006}, {0x86c4, 0x007e},
+{0x86c5, 0x0085}, {0x86c6, 0x00c0}, {0x86c7, 0x00b6},
+{0x86c8, 0x0012}, {0x86c9, 0x0006}, {0x86ca, 0x0084},
+{0x86cb, 0x003f}, {0x86cc, 0x0081}, {0x86cd, 0x003f},
+{0x86ce, 0x0027}, {0x86cf, 0x0010}, {0x86d0, 0x008b},
+{0x86d1, 0x0008}, {0x86d2, 0x00b7}, {0x86d3, 0x0012},
+{0x86d4, 0x0006}, {0x86d5, 0x00b6}, {0x86d6, 0x0012},
+{0x86d7, 0x0009}, {0x86d8, 0x0084}, {0x86d9, 0x00fc},
+{0x86da, 0x00b7}, {0x86db, 0x0012}, {0x86dc, 0x0009},
+{0x86dd, 0x007e}, {0x86de, 0x0085}, {0x86df, 0x00fe},
+{0x86e0, 0x00ce}, {0x86e1, 0x008f}, {0x86e2, 0x0070},
+{0x86e3, 0x0018}, {0x86e4, 0x00ce}, {0x86e5, 0x008f},
+{0x86e6, 0x0084}, {0x86e7, 0x00c6}, {0x86e8, 0x000c},
+{0x86e9, 0x00bd}, {0x86ea, 0x0089}, {0x86eb, 0x006f},
+{0x86ec, 0x00ce}, {0x86ed, 0x008f}, {0x86ee, 0x0084},
+{0x86ef, 0x0018}, {0x86f0, 0x00ce}, {0x86f1, 0x008f},
+{0x86f2, 0x0070}, {0x86f3, 0x00c6}, {0x86f4, 0x000c},
+{0x86f5, 0x00bd}, {0x86f6, 0x0089}, {0x86f7, 0x006f},
+{0x86f8, 0x00d6}, {0x86f9, 0x0083}, {0x86fa, 0x00c1},
+{0x86fb, 0x004f}, {0x86fc, 0x002d}, {0x86fd, 0x0003},
+{0x86fe, 0x007e}, {0x86ff, 0x0087}, {0x8700, 0x0040},
+{0x8701, 0x00b6}, {0x8702, 0x008f}, {0x8703, 0x007f},
+{0x8704, 0x0081}, {0x8705, 0x0007}, {0x8706, 0x0027},
+{0x8707, 0x000f}, {0x8708, 0x0081}, {0x8709, 0x000b},
+{0x870a, 0x0027}, {0x870b, 0x0015}, {0x870c, 0x0081},
+{0x870d, 0x000d}, {0x870e, 0x0027}, {0x870f, 0x001b},
+{0x8710, 0x0081}, {0x8711, 0x000e}, {0x8712, 0x0027},
+{0x8713, 0x0021}, {0x8714, 0x007e}, {0x8715, 0x0087},
+{0x8716, 0x0040}, {0x8717, 0x00f7}, {0x8718, 0x008f},
+{0x8719, 0x007b}, {0x871a, 0x0086}, {0x871b, 0x0002},
+{0x871c, 0x00b7}, {0x871d, 0x008f}, {0x871e, 0x007a},
+{0x871f, 0x0020}, {0x8720, 0x001c}, {0x8721, 0x00f7},
+{0x8722, 0x008f}, {0x8723, 0x0078}, {0x8724, 0x0086},
+{0x8725, 0x0002}, {0x8726, 0x00b7}, {0x8727, 0x008f},
+{0x8728, 0x0077}, {0x8729, 0x0020}, {0x872a, 0x0012},
+{0x872b, 0x00f7}, {0x872c, 0x008f}, {0x872d, 0x0075},
+{0x872e, 0x0086}, {0x872f, 0x0002}, {0x8730, 0x00b7},
+{0x8731, 0x008f}, {0x8732, 0x0074}, {0x8733, 0x0020},
+{0x8734, 0x0008}, {0x8735, 0x00f7}, {0x8736, 0x008f},
+{0x8737, 0x0072}, {0x8738, 0x0086}, {0x8739, 0x0002},
+{0x873a, 0x00b7}, {0x873b, 0x008f}, {0x873c, 0x0071},
+{0x873d, 0x007e}, {0x873e, 0x0087}, {0x873f, 0x0047},
+{0x8740, 0x0086}, {0x8741, 0x0004}, {0x8742, 0x0097},
+{0x8743, 0x0040}, {0x8744, 0x007e}, {0x8745, 0x0089},
+{0x8746, 0x006e}, {0x8747, 0x00ce}, {0x8748, 0x008f},
+{0x8749, 0x0072}, {0x874a, 0x00bd}, {0x874b, 0x0089},
+{0x874c, 0x00f7}, {0x874d, 0x00ce}, {0x874e, 0x008f},
+{0x874f, 0x0075}, {0x8750, 0x00bd}, {0x8751, 0x0089},
+{0x8752, 0x00f7}, {0x8753, 0x00ce}, {0x8754, 0x008f},
+{0x8755, 0x0078}, {0x8756, 0x00bd}, {0x8757, 0x0089},
+{0x8758, 0x00f7}, {0x8759, 0x00ce}, {0x875a, 0x008f},
+{0x875b, 0x007b}, {0x875c, 0x00bd}, {0x875d, 0x0089},
+{0x875e, 0x00f7}, {0x875f, 0x004f}, {0x8760, 0x00b7},
+{0x8761, 0x008f}, {0x8762, 0x007d}, {0x8763, 0x00b7},
+{0x8764, 0x008f}, {0x8765, 0x0081}, {0x8766, 0x00b6},
+{0x8767, 0x008f}, {0x8768, 0x0072}, {0x8769, 0x0027},
+{0x876a, 0x0047}, {0x876b, 0x007c}, {0x876c, 0x008f},
+{0x876d, 0x007d}, {0x876e, 0x00b6}, {0x876f, 0x008f},
+{0x8770, 0x0075}, {0x8771, 0x0027}, {0x8772, 0x003f},
+{0x8773, 0x007c}, {0x8774, 0x008f}, {0x8775, 0x007d},
+{0x8776, 0x00b6}, {0x8777, 0x008f}, {0x8778, 0x0078},
+{0x8779, 0x0027}, {0x877a, 0x0037}, {0x877b, 0x007c},
+{0x877c, 0x008f}, {0x877d, 0x007d}, {0x877e, 0x00b6},
+{0x877f, 0x008f}, {0x8780, 0x007b}, {0x8781, 0x0027},
+{0x8782, 0x002f}, {0x8783, 0x007f}, {0x8784, 0x008f},
+{0x8785, 0x007d}, {0x8786, 0x007c}, {0x8787, 0x008f},
+{0x8788, 0x0081}, {0x8789, 0x007a}, {0x878a, 0x008f},
+{0x878b, 0x0072}, {0x878c, 0x0027}, {0x878d, 0x001b},
+{0x878e, 0x007c}, {0x878f, 0x008f}, {0x8790, 0x007d},
+{0x8791, 0x007a}, {0x8792, 0x008f}, {0x8793, 0x0075},
+{0x8794, 0x0027}, {0x8795, 0x0016}, {0x8796, 0x007c},
+{0x8797, 0x008f}, {0x8798, 0x007d}, {0x8799, 0x007a},
+{0x879a, 0x008f}, {0x879b, 0x0078}, {0x879c, 0x0027},
+{0x879d, 0x0011}, {0x879e, 0x007c}, {0x879f, 0x008f},
+{0x87a0, 0x007d}, {0x87a1, 0x007a}, {0x87a2, 0x008f},
+{0x87a3, 0x007b}, {0x87a4, 0x0027}, {0x87a5, 0x000c},
+{0x87a6, 0x007e}, {0x87a7, 0x0087}, {0x87a8, 0x0083},
+{0x87a9, 0x007a}, {0x87aa, 0x008f}, {0x87ab, 0x0075},
+{0x87ac, 0x007a}, {0x87ad, 0x008f}, {0x87ae, 0x0078},
+{0x87af, 0x007a}, {0x87b0, 0x008f}, {0x87b1, 0x007b},
+{0x87b2, 0x00ce}, {0x87b3, 0x00c1}, {0x87b4, 0x00fc},
+{0x87b5, 0x00f6}, {0x87b6, 0x008f}, {0x87b7, 0x007d},
+{0x87b8, 0x003a}, {0x87b9, 0x00a6}, {0x87ba, 0x0000},
+{0x87bb, 0x00b7}, {0x87bc, 0x0012}, {0x87bd, 0x0070},
+{0x87be, 0x00b6}, {0x87bf, 0x008f}, {0x87c0, 0x0072},
+{0x87c1, 0x0026}, {0x87c2, 0x0003}, {0x87c3, 0x007e},
+{0x87c4, 0x0087}, {0x87c5, 0x00fa}, {0x87c6, 0x00b6},
+{0x87c7, 0x008f}, {0x87c8, 0x0075}, {0x87c9, 0x0026},
+{0x87ca, 0x000a}, {0x87cb, 0x0018}, {0x87cc, 0x00ce},
+{0x87cd, 0x008f}, {0x87ce, 0x0073}, {0x87cf, 0x00bd},
+{0x87d0, 0x0089}, {0x87d1, 0x00d5}, {0x87d2, 0x007e},
+{0x87d3, 0x0087}, {0x87d4, 0x00fa}, {0x87d5, 0x00b6},
+{0x87d6, 0x008f}, {0x87d7, 0x0078}, {0x87d8, 0x0026},
+{0x87d9, 0x000a}, {0x87da, 0x0018}, {0x87db, 0x00ce},
+{0x87dc, 0x008f}, {0x87dd, 0x0076}, {0x87de, 0x00bd},
+{0x87df, 0x0089}, {0x87e0, 0x00d5}, {0x87e1, 0x007e},
+{0x87e2, 0x0087}, {0x87e3, 0x00fa}, {0x87e4, 0x00b6},
+{0x87e5, 0x008f}, {0x87e6, 0x007b}, {0x87e7, 0x0026},
+{0x87e8, 0x000a}, {0x87e9, 0x0018}, {0x87ea, 0x00ce},
+{0x87eb, 0x008f}, {0x87ec, 0x0079}, {0x87ed, 0x00bd},
+{0x87ee, 0x0089}, {0x87ef, 0x00d5}, {0x87f0, 0x007e},
+{0x87f1, 0x0087}, {0x87f2, 0x00fa}, {0x87f3, 0x0086},
+{0x87f4, 0x0005}, {0x87f5, 0x0097}, {0x87f6, 0x0040},
+{0x87f7, 0x007e}, {0x87f8, 0x0089}, {0x87f9, 0x006e},
+{0x87fa, 0x00b6}, {0x87fb, 0x008f}, {0x87fc, 0x0075},
+{0x87fd, 0x0081}, {0x87fe, 0x0007}, {0x87ff, 0x002e},
+{0x8800, 0x00f2}, {0x8801, 0x00f6}, {0x8802, 0x0012},
+{0x8803, 0x0006}, {0x8804, 0x00c4}, {0x8805, 0x00f8},
+{0x8806, 0x001b}, {0x8807, 0x00b7}, {0x8808, 0x0012},
+{0x8809, 0x0006}, {0x880a, 0x00b6}, {0x880b, 0x008f},
+{0x880c, 0x0078}, {0x880d, 0x0081}, {0x880e, 0x0007},
+{0x880f, 0x002e}, {0x8810, 0x00e2}, {0x8811, 0x0048},
+{0x8812, 0x0048}, {0x8813, 0x0048}, {0x8814, 0x00f6},
+{0x8815, 0x0012}, {0x8816, 0x0006}, {0x8817, 0x00c4},
+{0x8818, 0x00c7}, {0x8819, 0x001b}, {0x881a, 0x00b7},
+{0x881b, 0x0012}, {0x881c, 0x0006}, {0x881d, 0x00b6},
+{0x881e, 0x008f}, {0x881f, 0x007b}, {0x8820, 0x0081},
+{0x8821, 0x0007}, {0x8822, 0x002e}, {0x8823, 0x00cf},
+{0x8824, 0x00f6}, {0x8825, 0x0012}, {0x8826, 0x0005},
+{0x8827, 0x00c4}, {0x8828, 0x00f8}, {0x8829, 0x001b},
+{0x882a, 0x00b7}, {0x882b, 0x0012}, {0x882c, 0x0005},
+{0x882d, 0x0086}, {0x882e, 0x0000}, {0x882f, 0x00f6},
+{0x8830, 0x008f}, {0x8831, 0x0071}, {0x8832, 0x00bd},
+{0x8833, 0x0089}, {0x8834, 0x0094}, {0x8835, 0x0086},
+{0x8836, 0x0001}, {0x8837, 0x00f6}, {0x8838, 0x008f},
+{0x8839, 0x0074}, {0x883a, 0x00bd}, {0x883b, 0x0089},
+{0x883c, 0x0094}, {0x883d, 0x0086}, {0x883e, 0x0002},
+{0x883f, 0x00f6}, {0x8840, 0x008f}, {0x8841, 0x0077},
+{0x8842, 0x00bd}, {0x8843, 0x0089}, {0x8844, 0x0094},
+{0x8845, 0x0086}, {0x8846, 0x0003}, {0x8847, 0x00f6},
+{0x8848, 0x008f}, {0x8849, 0x007a}, {0x884a, 0x00bd},
+{0x884b, 0x0089}, {0x884c, 0x0094}, {0x884d, 0x00ce},
+{0x884e, 0x008f}, {0x884f, 0x0070}, {0x8850, 0x00a6},
+{0x8851, 0x0001}, {0x8852, 0x0081}, {0x8853, 0x0001},
+{0x8854, 0x0027}, {0x8855, 0x0007}, {0x8856, 0x0081},
+{0x8857, 0x0003}, {0x8858, 0x0027}, {0x8859, 0x0003},
+{0x885a, 0x007e}, {0x885b, 0x0088}, {0x885c, 0x0066},
+{0x885d, 0x00a6}, {0x885e, 0x0000}, {0x885f, 0x00b8},
+{0x8860, 0x008f}, {0x8861, 0x0081}, {0x8862, 0x0084},
+{0x8863, 0x0001}, {0x8864, 0x0026}, {0x8865, 0x000b},
+{0x8866, 0x008c}, {0x8867, 0x008f}, {0x8868, 0x0079},
+{0x8869, 0x002c}, {0x886a, 0x000e}, {0x886b, 0x0008},
+{0x886c, 0x0008}, {0x886d, 0x0008}, {0x886e, 0x007e},
+{0x886f, 0x0088}, {0x8870, 0x0050}, {0x8871, 0x00b6},
+{0x8872, 0x0012}, {0x8873, 0x0004}, {0x8874, 0x008a},
+{0x8875, 0x0040}, {0x8876, 0x00b7}, {0x8877, 0x0012},
+{0x8878, 0x0004}, {0x8879, 0x00b6}, {0x887a, 0x0012},
+{0x887b, 0x0004}, {0x887c, 0x0084}, {0x887d, 0x00fb},
+{0x887e, 0x0084}, {0x887f, 0x00ef}, {0x8880, 0x00b7},
+{0x8881, 0x0012}, {0x8882, 0x0004}, {0x8883, 0x00b6},
+{0x8884, 0x0012}, {0x8885, 0x0007}, {0x8886, 0x0036},
+{0x8887, 0x00b6}, {0x8888, 0x008f}, {0x8889, 0x007c},
+{0x888a, 0x0048}, {0x888b, 0x0048}, {0x888c, 0x00b7},
+{0x888d, 0x0012}, {0x888e, 0x0007}, {0x888f, 0x0086},
+{0x8890, 0x0001}, {0x8891, 0x00ba}, {0x8892, 0x0012},
+{0x8893, 0x0004}, {0x8894, 0x00b7}, {0x8895, 0x0012},
+{0x8896, 0x0004}, {0x8897, 0x0001}, {0x8898, 0x0001},
+{0x8899, 0x0001}, {0x889a, 0x0001}, {0x889b, 0x0001},
+{0x889c, 0x0001}, {0x889d, 0x0086}, {0x889e, 0x00fe},
+{0x889f, 0x00b4}, {0x88a0, 0x0012}, {0x88a1, 0x0004},
+{0x88a2, 0x00b7}, {0x88a3, 0x0012}, {0x88a4, 0x0004},
+{0x88a5, 0x0086}, {0x88a6, 0x0002}, {0x88a7, 0x00ba},
+{0x88a8, 0x0012}, {0x88a9, 0x0004}, {0x88aa, 0x00b7},
+{0x88ab, 0x0012}, {0x88ac, 0x0004}, {0x88ad, 0x0086},
+{0x88ae, 0x00fd}, {0x88af, 0x00b4}, {0x88b0, 0x0012},
+{0x88b1, 0x0004}, {0x88b2, 0x00b7}, {0x88b3, 0x0012},
+{0x88b4, 0x0004}, {0x88b5, 0x0032}, {0x88b6, 0x00b7},
+{0x88b7, 0x0012}, {0x88b8, 0x0007}, {0x88b9, 0x00b6},
+{0x88ba, 0x0012}, {0x88bb, 0x0000}, {0x88bc, 0x0084},
+{0x88bd, 0x0008}, {0x88be, 0x0081}, {0x88bf, 0x0008},
+{0x88c0, 0x0027}, {0x88c1, 0x000f}, {0x88c2, 0x007c},
+{0x88c3, 0x0082}, {0x88c4, 0x0008}, {0x88c5, 0x0026},
+{0x88c6, 0x0007}, {0x88c7, 0x0086}, {0x88c8, 0x0076},
+{0x88c9, 0x0097}, {0x88ca, 0x0040}, {0x88cb, 0x007e},
+{0x88cc, 0x0089}, {0x88cd, 0x006e}, {0x88ce, 0x007e},
+{0x88cf, 0x0086}, {0x88d0, 0x00ec}, {0x88d1, 0x00b6},
+{0x88d2, 0x008f}, {0x88d3, 0x007f}, {0x88d4, 0x0081},
+{0x88d5, 0x000f}, {0x88d6, 0x0027}, {0x88d7, 0x003c},
+{0x88d8, 0x00bd}, {0x88d9, 0x00e6}, {0x88da, 0x00c7},
+{0x88db, 0x00b7}, {0x88dc, 0x0012}, {0x88dd, 0x000d},
+{0x88de, 0x00bd}, {0x88df, 0x00e6}, {0x88e0, 0x00cb},
+{0x88e1, 0x00b6}, {0x88e2, 0x0012}, {0x88e3, 0x0004},
+{0x88e4, 0x008a}, {0x88e5, 0x0020}, {0x88e6, 0x00b7},
+{0x88e7, 0x0012}, {0x88e8, 0x0004}, {0x88e9, 0x00ce},
+{0x88ea, 0x00ff}, {0x88eb, 0x00ff}, {0x88ec, 0x00b6},
+{0x88ed, 0x0012}, {0x88ee, 0x0000}, {0x88ef, 0x0081},
+{0x88f0, 0x000c}, {0x88f1, 0x0026}, {0x88f2, 0x0005},
+{0x88f3, 0x0009}, {0x88f4, 0x0026}, {0x88f5, 0x00f6},
+{0x88f6, 0x0027}, {0x88f7, 0x001c}, {0x88f8, 0x00b6},
+{0x88f9, 0x0012}, {0x88fa, 0x0004}, {0x88fb, 0x0084},
+{0x88fc, 0x00df}, {0x88fd, 0x00b7}, {0x88fe, 0x0012},
+{0x88ff, 0x0004}, {0x8900, 0x0096}, {0x8901, 0x0083},
+{0x8902, 0x0081}, {0x8903, 0x0007}, {0x8904, 0x002c},
+{0x8905, 0x0005}, {0x8906, 0x007c}, {0x8907, 0x0000},
+{0x8908, 0x0083}, {0x8909, 0x0020}, {0x890a, 0x0006},
+{0x890b, 0x0096}, {0x890c, 0x0083}, {0x890d, 0x008b},
+{0x890e, 0x0008}, {0x890f, 0x0097}, {0x8910, 0x0083},
+{0x8911, 0x007e}, {0x8912, 0x0085}, {0x8913, 0x0041},
+{0x8914, 0x007f}, {0x8915, 0x008f}, {0x8916, 0x007e},
+{0x8917, 0x0086}, {0x8918, 0x0080}, {0x8919, 0x00b7},
+{0x891a, 0x0012}, {0x891b, 0x000c}, {0x891c, 0x0086},
+{0x891d, 0x0001}, {0x891e, 0x00b7}, {0x891f, 0x008f},
+{0x8920, 0x007d}, {0x8921, 0x00b6}, {0x8922, 0x0012},
+{0x8923, 0x000c}, {0x8924, 0x0084}, {0x8925, 0x007f},
+{0x8926, 0x00b7}, {0x8927, 0x0012}, {0x8928, 0x000c},
+{0x8929, 0x008a}, {0x892a, 0x0080}, {0x892b, 0x00b7},
+{0x892c, 0x0012}, {0x892d, 0x000c}, {0x892e, 0x0086},
+{0x892f, 0x000a}, {0x8930, 0x00bd}, {0x8931, 0x008a},
+{0x8932, 0x0006}, {0x8933, 0x00b6}, {0x8934, 0x0012},
+{0x8935, 0x000a}, {0x8936, 0x002a}, {0x8937, 0x0009},
+{0x8938, 0x00b6}, {0x8939, 0x0012}, {0x893a, 0x000c},
+{0x893b, 0x00ba}, {0x893c, 0x008f}, {0x893d, 0x007d},
+{0x893e, 0x00b7}, {0x893f, 0x0012}, {0x8940, 0x000c},
+{0x8941, 0x00b6}, {0x8942, 0x008f}, {0x8943, 0x007e},
+{0x8944, 0x0081}, {0x8945, 0x0060}, {0x8946, 0x0027},
+{0x8947, 0x001a}, {0x8948, 0x008b}, {0x8949, 0x0020},
+{0x894a, 0x00b7}, {0x894b, 0x008f}, {0x894c, 0x007e},
+{0x894d, 0x00b6}, {0x894e, 0x0012}, {0x894f, 0x000c},
+{0x8950, 0x0084}, {0x8951, 0x009f}, {0x8952, 0x00ba},
+{0x8953, 0x008f}, {0x8954, 0x007e}, {0x8955, 0x00b7},
+{0x8956, 0x0012}, {0x8957, 0x000c}, {0x8958, 0x00b6},
+{0x8959, 0x008f}, {0x895a, 0x007d}, {0x895b, 0x0048},
+{0x895c, 0x00b7}, {0x895d, 0x008f}, {0x895e, 0x007d},
+{0x895f, 0x007e}, {0x8960, 0x0089}, {0x8961, 0x0021},
+{0x8962, 0x00b6}, {0x8963, 0x0012}, {0x8964, 0x0004},
+{0x8965, 0x008a}, {0x8966, 0x0020}, {0x8967, 0x00b7},
+{0x8968, 0x0012}, {0x8969, 0x0004}, {0x896a, 0x00bd},
+{0x896b, 0x008a}, {0x896c, 0x000a}, {0x896d, 0x004f},
+{0x896e, 0x0039}, {0x896f, 0x00a6}, {0x8970, 0x0000},
+{0x8971, 0x0018}, {0x8972, 0x00a7}, {0x8973, 0x0000},
+{0x8974, 0x0008}, {0x8975, 0x0018}, {0x8976, 0x0008},
+{0x8977, 0x005a}, {0x8978, 0x0026}, {0x8979, 0x00f5},
+{0x897a, 0x0039}, {0x897b, 0x0036}, {0x897c, 0x006c},
+{0x897d, 0x0000}, {0x897e, 0x0032}, {0x897f, 0x00ba},
+{0x8980, 0x008f}, {0x8981, 0x007f}, {0x8982, 0x00b7},
+{0x8983, 0x008f}, {0x8984, 0x007f}, {0x8985, 0x00b6},
+{0x8986, 0x0012}, {0x8987, 0x0009}, {0x8988, 0x0084},
+{0x8989, 0x0003}, {0x898a, 0x00a7}, {0x898b, 0x0001},
+{0x898c, 0x00b6}, {0x898d, 0x0012}, {0x898e, 0x0006},
+{0x898f, 0x0084}, {0x8990, 0x003f}, {0x8991, 0x00a7},
+{0x8992, 0x0002}, {0x8993, 0x0039}, {0x8994, 0x0036},
+{0x8995, 0x0086}, {0x8996, 0x0003}, {0x8997, 0x00b7},
+{0x8998, 0x008f}, {0x8999, 0x0080}, {0x899a, 0x0032},
+{0x899b, 0x00c1}, {0x899c, 0x0000}, {0x899d, 0x0026},
+{0x899e, 0x0006}, {0x899f, 0x00b7}, {0x89a0, 0x008f},
+{0x89a1, 0x007c}, {0x89a2, 0x007e}, {0x89a3, 0x0089},
+{0x89a4, 0x00c9}, {0x89a5, 0x00c1}, {0x89a6, 0x0001},
+{0x89a7, 0x0027}, {0x89a8, 0x0018}, {0x89a9, 0x00c1},
+{0x89aa, 0x0002}, {0x89ab, 0x0027}, {0x89ac, 0x000c},
+{0x89ad, 0x00c1}, {0x89ae, 0x0003}, {0x89af, 0x0027},
+{0x89b0, 0x0000}, {0x89b1, 0x00f6}, {0x89b2, 0x008f},
+{0x89b3, 0x0080}, {0x89b4, 0x0005}, {0x89b5, 0x0005},
+{0x89b6, 0x00f7}, {0x89b7, 0x008f}, {0x89b8, 0x0080},
+{0x89b9, 0x00f6}, {0x89ba, 0x008f}, {0x89bb, 0x0080},
+{0x89bc, 0x0005}, {0x89bd, 0x0005}, {0x89be, 0x00f7},
+{0x89bf, 0x008f}, {0x89c0, 0x0080}, {0x89c1, 0x00f6},
+{0x89c2, 0x008f}, {0x89c3, 0x0080}, {0x89c4, 0x0005},
+{0x89c5, 0x0005}, {0x89c6, 0x00f7}, {0x89c7, 0x008f},
+{0x89c8, 0x0080}, {0x89c9, 0x00f6}, {0x89ca, 0x008f},
+{0x89cb, 0x0080}, {0x89cc, 0x0053}, {0x89cd, 0x00f4},
+{0x89ce, 0x0012}, {0x89cf, 0x0007}, {0x89d0, 0x001b},
+{0x89d1, 0x00b7}, {0x89d2, 0x0012}, {0x89d3, 0x0007},
+{0x89d4, 0x0039}, {0x89d5, 0x00ce}, {0x89d6, 0x008f},
+{0x89d7, 0x0070}, {0x89d8, 0x00a6}, {0x89d9, 0x0000},
+{0x89da, 0x0018}, {0x89db, 0x00e6}, {0x89dc, 0x0000},
+{0x89dd, 0x0018}, {0x89de, 0x00a7}, {0x89df, 0x0000},
+{0x89e0, 0x00e7}, {0x89e1, 0x0000}, {0x89e2, 0x00a6},
+{0x89e3, 0x0001}, {0x89e4, 0x0018}, {0x89e5, 0x00e6},
+{0x89e6, 0x0001}, {0x89e7, 0x0018}, {0x89e8, 0x00a7},
+{0x89e9, 0x0001}, {0x89ea, 0x00e7}, {0x89eb, 0x0001},
+{0x89ec, 0x00a6}, {0x89ed, 0x0002}, {0x89ee, 0x0018},
+{0x89ef, 0x00e6}, {0x89f0, 0x0002}, {0x89f1, 0x0018},
+{0x89f2, 0x00a7}, {0x89f3, 0x0002}, {0x89f4, 0x00e7},
+{0x89f5, 0x0002}, {0x89f6, 0x0039}, {0x89f7, 0x00a6},
+{0x89f8, 0x0000}, {0x89f9, 0x0084}, {0x89fa, 0x0007},
+{0x89fb, 0x00e6}, {0x89fc, 0x0000}, {0x89fd, 0x00c4},
+{0x89fe, 0x0038}, {0x89ff, 0x0054}, {0x8a00, 0x0054},
+{0x8a01, 0x0054}, {0x8a02, 0x001b}, {0x8a03, 0x00a7},
+{0x8a04, 0x0000}, {0x8a05, 0x0039}, {0x8a06, 0x004a},
+{0x8a07, 0x0026}, {0x8a08, 0x00fd}, {0x8a09, 0x0039},
+{0x8a0a, 0x0096}, {0x8a0b, 0x0022}, {0x8a0c, 0x0084},
+{0x8a0d, 0x000f}, {0x8a0e, 0x0097}, {0x8a0f, 0x0022},
+{0x8a10, 0x0086}, {0x8a11, 0x0001}, {0x8a12, 0x00b7},
+{0x8a13, 0x008f}, {0x8a14, 0x0070}, {0x8a15, 0x00b6},
+{0x8a16, 0x0012}, {0x8a17, 0x0007}, {0x8a18, 0x00b7},
+{0x8a19, 0x008f}, {0x8a1a, 0x0071}, {0x8a1b, 0x00f6},
+{0x8a1c, 0x0012}, {0x8a1d, 0x000c}, {0x8a1e, 0x00c4},
+{0x8a1f, 0x000f}, {0x8a20, 0x00c8}, {0x8a21, 0x000f},
+{0x8a22, 0x00f7}, {0x8a23, 0x008f}, {0x8a24, 0x0072},
+{0x8a25, 0x00f6}, {0x8a26, 0x008f}, {0x8a27, 0x0072},
+{0x8a28, 0x00b6}, {0x8a29, 0x008f}, {0x8a2a, 0x0071},
+{0x8a2b, 0x0084}, {0x8a2c, 0x0003}, {0x8a2d, 0x0027},
+{0x8a2e, 0x0014}, {0x8a2f, 0x0081}, {0x8a30, 0x0001},
+{0x8a31, 0x0027}, {0x8a32, 0x001c}, {0x8a33, 0x0081},
+{0x8a34, 0x0002}, {0x8a35, 0x0027}, {0x8a36, 0x0024},
+{0x8a37, 0x00f4}, {0x8a38, 0x008f}, {0x8a39, 0x0070},
+{0x8a3a, 0x0027}, {0x8a3b, 0x002a}, {0x8a3c, 0x0096},
+{0x8a3d, 0x0022}, {0x8a3e, 0x008a}, {0x8a3f, 0x0080},
+{0x8a40, 0x007e}, {0x8a41, 0x008a}, {0x8a42, 0x0064},
+{0x8a43, 0x00f4}, {0x8a44, 0x008f}, {0x8a45, 0x0070},
+{0x8a46, 0x0027}, {0x8a47, 0x001e}, {0x8a48, 0x0096},
+{0x8a49, 0x0022}, {0x8a4a, 0x008a}, {0x8a4b, 0x0010},
+{0x8a4c, 0x007e}, {0x8a4d, 0x008a}, {0x8a4e, 0x0064},
+{0x8a4f, 0x00f4}, {0x8a50, 0x008f}, {0x8a51, 0x0070},
+{0x8a52, 0x0027}, {0x8a53, 0x0012}, {0x8a54, 0x0096},
+{0x8a55, 0x0022}, {0x8a56, 0x008a}, {0x8a57, 0x0020},
+{0x8a58, 0x007e}, {0x8a59, 0x008a}, {0x8a5a, 0x0064},
+{0x8a5b, 0x00f4}, {0x8a5c, 0x008f}, {0x8a5d, 0x0070},
+{0x8a5e, 0x0027}, {0x8a5f, 0x0006}, {0x8a60, 0x0096},
+{0x8a61, 0x0022}, {0x8a62, 0x008a}, {0x8a63, 0x0040},
+{0x8a64, 0x0097}, {0x8a65, 0x0022}, {0x8a66, 0x0074},
+{0x8a67, 0x008f}, {0x8a68, 0x0071}, {0x8a69, 0x0074},
+{0x8a6a, 0x008f}, {0x8a6b, 0x0071}, {0x8a6c, 0x0078},
+{0x8a6d, 0x008f}, {0x8a6e, 0x0070}, {0x8a6f, 0x00b6},
+{0x8a70, 0x008f}, {0x8a71, 0x0070}, {0x8a72, 0x0085},
+{0x8a73, 0x0010}, {0x8a74, 0x0027}, {0x8a75, 0x00af},
+{0x8a76, 0x00d6}, {0x8a77, 0x0022}, {0x8a78, 0x00c4},
+{0x8a79, 0x0010}, {0x8a7a, 0x0058}, {0x8a7b, 0x00b6},
+{0x8a7c, 0x0012}, {0x8a7d, 0x0070}, {0x8a7e, 0x0081},
+{0x8a7f, 0x00e4}, {0x8a80, 0x0027}, {0x8a81, 0x0036},
+{0x8a82, 0x0081}, {0x8a83, 0x00e1}, {0x8a84, 0x0026},
+{0x8a85, 0x000c}, {0x8a86, 0x0096}, {0x8a87, 0x0022},
+{0x8a88, 0x0084}, {0x8a89, 0x0020}, {0x8a8a, 0x0044},
+{0x8a8b, 0x001b}, {0x8a8c, 0x00d6}, {0x8a8d, 0x0022},
+{0x8a8e, 0x00c4}, {0x8a8f, 0x00cf}, {0x8a90, 0x0020},
+{0x8a91, 0x0023}, {0x8a92, 0x0058}, {0x8a93, 0x0081},
+{0x8a94, 0x00c6}, {0x8a95, 0x0026}, {0x8a96, 0x000d},
+{0x8a97, 0x0096}, {0x8a98, 0x0022}, {0x8a99, 0x0084},
+{0x8a9a, 0x0040}, {0x8a9b, 0x0044}, {0x8a9c, 0x0044},
+{0x8a9d, 0x001b}, {0x8a9e, 0x00d6}, {0x8a9f, 0x0022},
+{0x8aa0, 0x00c4}, {0x8aa1, 0x00af}, {0x8aa2, 0x0020},
+{0x8aa3, 0x0011}, {0x8aa4, 0x0058}, {0x8aa5, 0x0081},
+{0x8aa6, 0x0027}, {0x8aa7, 0x0026}, {0x8aa8, 0x000f},
+{0x8aa9, 0x0096}, {0x8aaa, 0x0022}, {0x8aab, 0x0084},
+{0x8aac, 0x0080}, {0x8aad, 0x0044}, {0x8aae, 0x0044},
+{0x8aaf, 0x0044}, {0x8ab0, 0x001b}, {0x8ab1, 0x00d6},
+{0x8ab2, 0x0022}, {0x8ab3, 0x00c4}, {0x8ab4, 0x006f},
+{0x8ab5, 0x001b}, {0x8ab6, 0x0097}, {0x8ab7, 0x0022},
+{0x8ab8, 0x0039}, {0x8ab9, 0x0027}, {0x8aba, 0x000c},
+{0x8abb, 0x007c}, {0x8abc, 0x0082}, {0x8abd, 0x0006},
+{0x8abe, 0x00bd}, {0x8abf, 0x00d9}, {0x8ac0, 0x00ed},
+{0x8ac1, 0x00b6}, {0x8ac2, 0x0082}, {0x8ac3, 0x0007},
+{0x8ac4, 0x007e}, {0x8ac5, 0x008a}, {0x8ac6, 0x00b9},
+{0x8ac7, 0x007f}, {0x8ac8, 0x0082}, {0x8ac9, 0x0006},
+{0x8aca, 0x0039}, { 0x0, 0x0 }
+};
+#endif
+
+
+/* phy types */
+#define CAS_PHY_UNKNOWN 0x00
+#define CAS_PHY_SERDES 0x01
+#define CAS_PHY_MII_MDIO0 0x02
+#define CAS_PHY_MII_MDIO1 0x04
+#define CAS_PHY_MII(x) ((x) & (CAS_PHY_MII_MDIO0 | CAS_PHY_MII_MDIO1))
+
+/* _RING_INDEX is the index for the ring sizes to be used. _RING_SIZE
+ * is the actual size. the default index for the various rings is
+ * 8. NOTE: there a bunch of alignment constraints for the rings. to
+ * deal with that, i just allocate rings to create the desired
+ * alignment. here are the constraints:
+ * RX DESC and COMP rings must be 8KB aligned
+ * TX DESC must be 2KB aligned.
+ * if you change the numbers, be cognizant of how the alignment will change
+ * in INIT_BLOCK as well.
+ */
+
+#define DESC_RING_I_TO_S(x) (32*(1 << (x)))
+#define COMP_RING_I_TO_S(x) (128*(1 << (x)))
+#define TX_DESC_RING_INDEX 4 /* 512 = 8k */
+#define RX_DESC_RING_INDEX 4 /* 512 = 8k */
+#define RX_COMP_RING_INDEX 4 /* 2048 = 64k: should be 4x rx ring size */
+
+#if (TX_DESC_RING_INDEX > 8) || (TX_DESC_RING_INDEX < 0)
+#error TX_DESC_RING_INDEX must be between 0 and 8
+#endif
+
+#if (RX_DESC_RING_INDEX > 8) || (RX_DESC_RING_INDEX < 0)
+#error RX_DESC_RING_INDEX must be between 0 and 8
+#endif
+
+#if (RX_COMP_RING_INDEX > 8) || (RX_COMP_RING_INDEX < 0)
+#error RX_COMP_RING_INDEX must be between 0 and 8
+#endif
+
+#define N_TX_RINGS MAX_TX_RINGS /* for QoS */
+#define N_TX_RINGS_MASK MAX_TX_RINGS_MASK
+#define N_RX_DESC_RINGS MAX_RX_DESC_RINGS /* 1 for ipsec */
+#define N_RX_COMP_RINGS 0x1 /* for mult. PCI interrupts */
+
+/* number of flows that can go through re-assembly */
+#define N_RX_FLOWS 64
+
+#define TX_DESC_RING_SIZE DESC_RING_I_TO_S(TX_DESC_RING_INDEX)
+#define RX_DESC_RING_SIZE DESC_RING_I_TO_S(RX_DESC_RING_INDEX)
+#define RX_COMP_RING_SIZE COMP_RING_I_TO_S(RX_COMP_RING_INDEX)
+#define TX_DESC_RINGN_INDEX(x) TX_DESC_RING_INDEX
+#define RX_DESC_RINGN_INDEX(x) RX_DESC_RING_INDEX
+#define RX_COMP_RINGN_INDEX(x) RX_COMP_RING_INDEX
+#define TX_DESC_RINGN_SIZE(x) TX_DESC_RING_SIZE
+#define RX_DESC_RINGN_SIZE(x) RX_DESC_RING_SIZE
+#define RX_COMP_RINGN_SIZE(x) RX_COMP_RING_SIZE
+
+/* convert values */
+#define CAS_BASE(x, y) (((y) << (x ## _SHIFT)) & (x ## _MASK))
+#define CAS_VAL(x, y) (((y) & (x ## _MASK)) >> (x ## _SHIFT))
+#define CAS_TX_RINGN_BASE(y) ((TX_DESC_RINGN_INDEX(y) << \
+ TX_CFG_DESC_RINGN_SHIFT(y)) & \
+ TX_CFG_DESC_RINGN_MASK(y))
+
+/* min is 2k, but we can't do jumbo frames unless it's at least 8k */
+#define CAS_MIN_PAGE_SHIFT 11 /* 2048 */
+#define CAS_JUMBO_PAGE_SHIFT 13 /* 8192 */
+#define CAS_MAX_PAGE_SHIFT 14 /* 16384 */
+
+#define TX_DESC_BUFLEN_MASK 0x0000000000003FFFULL /* buffer length in
+ bytes. 0 - 9256 */
+#define TX_DESC_BUFLEN_SHIFT 0
+#define TX_DESC_CSUM_START_MASK 0x00000000001F8000ULL /* checksum start. #
+ of bytes to be
+ skipped before
+ csum calc begins.
+ value must be
+ even */
+#define TX_DESC_CSUM_START_SHIFT 15
+#define TX_DESC_CSUM_STUFF_MASK 0x000000001FE00000ULL /* checksum stuff.
+ byte offset w/in
+ the pkt for the
+ 1st csum byte.
+ must be > 8 */
+#define TX_DESC_CSUM_STUFF_SHIFT 21
+#define TX_DESC_CSUM_EN 0x0000000020000000ULL /* enable checksum */
+#define TX_DESC_EOF 0x0000000040000000ULL /* end of frame */
+#define TX_DESC_SOF 0x0000000080000000ULL /* start of frame */
+#define TX_DESC_INTME 0x0000000100000000ULL /* interrupt me */
+#define TX_DESC_NO_CRC 0x0000000200000000ULL /* debugging only.
+ CRC will not be
+ inserted into
+ outgoing frame. */
+struct cas_tx_desc {
+ u64 control;
+ u64 buffer;
+};
+
+/* descriptor ring for free buffers contains page-sized buffers. the index
+ * value is not used by the hw in any way. it's just stored and returned in
+ * the completion ring.
+ */
+struct cas_rx_desc {
+ u64 index;
+ u64 buffer;
+};
+
+/* received packets are put on the completion ring. */
+/* word 1 */
+#define RX_COMP1_DATA_SIZE_MASK 0x0000000007FFE000ULL
+#define RX_COMP1_DATA_SIZE_SHIFT 13
+#define RX_COMP1_DATA_OFF_MASK 0x000001FFF8000000ULL
+#define RX_COMP1_DATA_OFF_SHIFT 27
+#define RX_COMP1_DATA_INDEX_MASK 0x007FFE0000000000ULL
+#define RX_COMP1_DATA_INDEX_SHIFT 41
+#define RX_COMP1_SKIP_MASK 0x0180000000000000ULL
+#define RX_COMP1_SKIP_SHIFT 55
+#define RX_COMP1_RELEASE_NEXT 0x0200000000000000ULL
+#define RX_COMP1_SPLIT_PKT 0x0400000000000000ULL
+#define RX_COMP1_RELEASE_FLOW 0x0800000000000000ULL
+#define RX_COMP1_RELEASE_DATA 0x1000000000000000ULL
+#define RX_COMP1_RELEASE_HDR 0x2000000000000000ULL
+#define RX_COMP1_TYPE_MASK 0xC000000000000000ULL
+#define RX_COMP1_TYPE_SHIFT 62
+
+/* word 2 */
+#define RX_COMP2_NEXT_INDEX_MASK 0x00000007FFE00000ULL
+#define RX_COMP2_NEXT_INDEX_SHIFT 21
+#define RX_COMP2_HDR_SIZE_MASK 0x00000FF800000000ULL
+#define RX_COMP2_HDR_SIZE_SHIFT 35
+#define RX_COMP2_HDR_OFF_MASK 0x0003F00000000000ULL
+#define RX_COMP2_HDR_OFF_SHIFT 44
+#define RX_COMP2_HDR_INDEX_MASK 0xFFFC000000000000ULL
+#define RX_COMP2_HDR_INDEX_SHIFT 50
+
+/* word 3 */
+#define RX_COMP3_SMALL_PKT 0x0000000000000001ULL
+#define RX_COMP3_JUMBO_PKT 0x0000000000000002ULL
+#define RX_COMP3_JUMBO_HDR_SPLIT_EN 0x0000000000000004ULL
+#define RX_COMP3_CSUM_START_MASK 0x000000000007F000ULL
+#define RX_COMP3_CSUM_START_SHIFT 12
+#define RX_COMP3_FLOWID_MASK 0x0000000001F80000ULL
+#define RX_COMP3_FLOWID_SHIFT 19
+#define RX_COMP3_OPCODE_MASK 0x000000000E000000ULL
+#define RX_COMP3_OPCODE_SHIFT 25
+#define RX_COMP3_FORCE_FLAG 0x0000000010000000ULL
+#define RX_COMP3_NO_ASSIST 0x0000000020000000ULL
+#define RX_COMP3_LOAD_BAL_MASK 0x000001F800000000ULL
+#define RX_COMP3_LOAD_BAL_SHIFT 35
+#define RX_PLUS_COMP3_ENC_PKT 0x0000020000000000ULL /* cas+ */
+#define RX_COMP3_L3_HEAD_OFF_MASK 0x0000FE0000000000ULL /* cas */
+#define RX_COMP3_L3_HEAD_OFF_SHIFT 41
+#define RX_PLUS_COMP_L3_HEAD_OFF_MASK 0x0000FC0000000000ULL /* cas+ */
+#define RX_PLUS_COMP_L3_HEAD_OFF_SHIFT 42
+#define RX_COMP3_SAP_MASK 0xFFFF000000000000ULL
+#define RX_COMP3_SAP_SHIFT 48
+
+/* word 4 */
+#define RX_COMP4_TCP_CSUM_MASK 0x000000000000FFFFULL
+#define RX_COMP4_TCP_CSUM_SHIFT 0
+#define RX_COMP4_PKT_LEN_MASK 0x000000003FFF0000ULL
+#define RX_COMP4_PKT_LEN_SHIFT 16
+#define RX_COMP4_PERFECT_MATCH_MASK 0x00000003C0000000ULL
+#define RX_COMP4_PERFECT_MATCH_SHIFT 30
+#define RX_COMP4_ZERO 0x0000080000000000ULL
+#define RX_COMP4_HASH_VAL_MASK 0x0FFFF00000000000ULL
+#define RX_COMP4_HASH_VAL_SHIFT 44
+#define RX_COMP4_HASH_PASS 0x1000000000000000ULL
+#define RX_COMP4_BAD 0x4000000000000000ULL
+#define RX_COMP4_LEN_MISMATCH 0x8000000000000000ULL
+
+/* we encode the following: ring/index/release. only 14 bits
+ * are usable.
+ * NOTE: the encoding is dependent upon RX_DESC_RING_SIZE and
+ * MAX_RX_DESC_RINGS. */
+#define RX_INDEX_NUM_MASK 0x0000000000000FFFULL
+#define RX_INDEX_NUM_SHIFT 0
+#define RX_INDEX_RING_MASK 0x0000000000001000ULL
+#define RX_INDEX_RING_SHIFT 12
+#define RX_INDEX_RELEASE 0x0000000000002000ULL
+
+struct cas_rx_comp {
+ u64 word1;
+ u64 word2;
+ u64 word3;
+ u64 word4;
+};
+
+enum link_state {
+ link_down = 0, /* No link, will retry */
+ link_aneg, /* Autoneg in progress */
+ link_force_try, /* Try Forced link speed */
+ link_force_ret, /* Forced mode worked, retrying autoneg */
+ link_force_ok, /* Stay in forced mode */
+ link_up /* Link is up */
+};
+
+typedef struct cas_page {
+ struct list_head list;
+ struct page *buffer;
+ dma_addr_t dma_addr;
+ int used;
+} cas_page_t;
+
+
+/* some alignment constraints:
+ * TX DESC, RX DESC, and RX COMP must each be 8K aligned.
+ * TX COMPWB must be 8-byte aligned.
+ * to accomplish this, here's what we do:
+ *
+ * INIT_BLOCK_RX_COMP = 64k (already aligned)
+ * INIT_BLOCK_RX_DESC = 8k
+ * INIT_BLOCK_TX = 8k
+ * INIT_BLOCK_RX1_DESC = 8k
+ * TX COMPWB
+ */
+#define INIT_BLOCK_TX (TX_DESC_RING_SIZE)
+#define INIT_BLOCK_RX_DESC (RX_DESC_RING_SIZE)
+#define INIT_BLOCK_RX_COMP (RX_COMP_RING_SIZE)
+
+struct cas_init_block {
+ struct cas_rx_comp rxcs[N_RX_COMP_RINGS][INIT_BLOCK_RX_COMP];
+ struct cas_rx_desc rxds[N_RX_DESC_RINGS][INIT_BLOCK_RX_DESC];
+ struct cas_tx_desc txds[N_TX_RINGS][INIT_BLOCK_TX];
+ u64 tx_compwb;
+};
+
+/* tiny buffers to deal with target abort issue. we allocate a bit
+ * over so that we don't have target abort issues with these buffers
+ * as well.
+ */
+#define TX_TINY_BUF_LEN 0x100
+#define TX_TINY_BUF_BLOCK ((INIT_BLOCK_TX + 1)*TX_TINY_BUF_LEN)
+
+struct cas_tiny_count {
+ int nbufs;
+ int used;
+};
+
+struct cas {
+ spinlock_t lock; /* for most bits */
+ spinlock_t tx_lock[N_TX_RINGS]; /* tx bits */
+ spinlock_t stat_lock[N_TX_RINGS + 1]; /* for stat gathering */
+ spinlock_t rx_inuse_lock; /* rx inuse list */
+ spinlock_t rx_spare_lock; /* rx spare list */
+
+ void __iomem *regs;
+ int tx_new[N_TX_RINGS], tx_old[N_TX_RINGS];
+ int rx_old[N_RX_DESC_RINGS];
+ int rx_cur[N_RX_COMP_RINGS], rx_new[N_RX_COMP_RINGS];
+ int rx_last[N_RX_DESC_RINGS];
+
+ /* Set when chip is actually in operational state
+ * (ie. not power managed) */
+ int hw_running;
+ int opened;
+ struct semaphore pm_sem; /* open/close/suspend/resume */
+
+ struct cas_init_block *init_block;
+ struct cas_tx_desc *init_txds[MAX_TX_RINGS];
+ struct cas_rx_desc *init_rxds[MAX_RX_DESC_RINGS];
+ struct cas_rx_comp *init_rxcs[MAX_RX_COMP_RINGS];
+
+ /* we use sk_buffs for tx and pages for rx. the rx skbuffs
+ * are there for flow re-assembly. */
+ struct sk_buff *tx_skbs[N_TX_RINGS][TX_DESC_RING_SIZE];
+ struct sk_buff_head rx_flows[N_RX_FLOWS];
+ cas_page_t *rx_pages[N_RX_DESC_RINGS][RX_DESC_RING_SIZE];
+ struct list_head rx_spare_list, rx_inuse_list;
+ int rx_spares_needed;
+
+ /* for small packets when copying would be quicker than
+ mapping */
+ struct cas_tiny_count tx_tiny_use[N_TX_RINGS][TX_DESC_RING_SIZE];
+ u8 *tx_tiny_bufs[N_TX_RINGS];
+
+ u32 msg_enable;
+
+ /* N_TX_RINGS must be >= N_RX_DESC_RINGS */
+ struct net_device_stats net_stats[N_TX_RINGS + 1];
+
+ u32 pci_cfg[64 >> 2];
+ u8 pci_revision;
+
+ int phy_type;
+ int phy_addr;
+ u32 phy_id;
+#define CAS_FLAG_1000MB_CAP 0x00000001
+#define CAS_FLAG_REG_PLUS 0x00000002
+#define CAS_FLAG_TARGET_ABORT 0x00000004
+#define CAS_FLAG_SATURN 0x00000008
+#define CAS_FLAG_RXD_POST_MASK 0x000000F0
+#define CAS_FLAG_RXD_POST_SHIFT 4
+#define CAS_FLAG_RXD_POST(x) ((1 << (CAS_FLAG_RXD_POST_SHIFT + (x))) & \
+ CAS_FLAG_RXD_POST_MASK)
+#define CAS_FLAG_ENTROPY_DEV 0x00000100
+#define CAS_FLAG_NO_HW_CSUM 0x00000200
+ u32 cas_flags;
+ int packet_min; /* minimum packet size */
+ int tx_fifo_size;
+ int rx_fifo_size;
+ int rx_pause_off;
+ int rx_pause_on;
+ int crc_size; /* 4 if half-duplex */
+
+ int pci_irq_INTC;
+ int min_frame_size; /* for tx fifo workaround */
+
+ /* page size allocation */
+ int page_size;
+ int page_order;
+ int mtu_stride;
+
+ u32 mac_rx_cfg;
+
+ /* Autoneg & PHY control */
+ int link_cntl;
+ int link_fcntl;
+ enum link_state lstate;
+ struct timer_list link_timer;
+ int timer_ticks;
+ struct work_struct reset_task;
+#if 0
+ atomic_t reset_task_pending;
+#else
+ atomic_t reset_task_pending;
+ atomic_t reset_task_pending_mtu;
+ atomic_t reset_task_pending_spare;
+ atomic_t reset_task_pending_all;
+#endif
+
+#ifdef CONFIG_CASSINI_QGE_DEBUG
+ atomic_t interrupt_seen; /* 1 if any interrupts are getting through */
+#endif
+
+ /* Link-down problem workaround */
+#define LINK_TRANSITION_UNKNOWN 0
+#define LINK_TRANSITION_ON_FAILURE 1
+#define LINK_TRANSITION_STILL_FAILED 2
+#define LINK_TRANSITION_LINK_UP 3
+#define LINK_TRANSITION_LINK_CONFIG 4
+#define LINK_TRANSITION_LINK_DOWN 5
+#define LINK_TRANSITION_REQUESTED_RESET 6
+ int link_transition;
+ int link_transition_jiffies_valid;
+ unsigned long link_transition_jiffies;
+
+ /* Tuning */
+ u8 orig_cacheline_size; /* value when loaded */
+#define CAS_PREF_CACHELINE_SIZE 0x20 /* Minimum desired */
+
+ /* Diagnostic counters and state. */
+ int casreg_len; /* reg-space size for dumping */
+ u64 pause_entered;
+ u16 pause_last_time_recvd;
+
+ dma_addr_t block_dvma, tx_tiny_dvma[N_TX_RINGS];
+ struct pci_dev *pdev;
+ struct net_device *dev;
+};
+
+#define TX_DESC_NEXT(r, x) (((x) + 1) & (TX_DESC_RINGN_SIZE(r) - 1))
+#define RX_DESC_ENTRY(r, x) ((x) & (RX_DESC_RINGN_SIZE(r) - 1))
+#define RX_COMP_ENTRY(r, x) ((x) & (RX_COMP_RINGN_SIZE(r) - 1))
+
+#define TX_BUFF_COUNT(r, x, y) ((x) <= (y) ? ((y) - (x)) : \
+ (TX_DESC_RINGN_SIZE(r) - (x) + (y)))
+
+#define TX_BUFFS_AVAIL(cp, i) ((cp)->tx_old[(i)] <= (cp)->tx_new[(i)] ? \
+ (cp)->tx_old[(i)] + (TX_DESC_RINGN_SIZE(i) - 1) - (cp)->tx_new[(i)] : \
+ (cp)->tx_old[(i)] - (cp)->tx_new[(i)] - 1)
+
+#define CAS_ALIGN(addr, align) \
+ (((unsigned long) (addr) + ((align) - 1UL)) & ~((align) - 1))
+
+#define RX_FIFO_SIZE 16384
+#define EXPANSION_ROM_SIZE 65536
+
+#define CAS_MC_EXACT_MATCH_SIZE 15
+#define CAS_MC_HASH_SIZE 256
+#define CAS_MC_HASH_MAX (CAS_MC_EXACT_MATCH_SIZE + \
+ CAS_MC_HASH_SIZE)
+
+#define TX_TARGET_ABORT_LEN 0x20
+#define RX_SWIVEL_OFF_VAL 0x2
+#define RX_AE_FREEN_VAL(x) (RX_DESC_RINGN_SIZE(x) >> 1)
+#define RX_AE_COMP_VAL (RX_COMP_RING_SIZE >> 1)
+#define RX_BLANK_INTR_PKT_VAL 0x05
+#define RX_BLANK_INTR_TIME_VAL 0x0F
+#define HP_TCP_THRESH_VAL 1530 /* reduce to enable reassembly */
+
+#define RX_SPARE_COUNT (RX_DESC_RING_SIZE >> 1)
+#define RX_SPARE_RECOVER_VAL (RX_SPARE_COUNT >> 2)
+
+#endif /* _CASSINI_H */
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 442670860fca..b68b9cad76e9 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -384,8 +384,8 @@ static unsigned int mdio_phy_addr; /* Transciever address */
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 b780307093eb..bfdae10036ed 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -140,6 +140,7 @@
#include <asm/system.h>
#include <asm/io.h>
+#include <asm/irq.h>
#if ALLOW_DMA
#include <asm/dma.h>
#endif
@@ -181,6 +182,10 @@ static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
+#elif defined(CONFIG_MACH_MP1000)
+#include <asm/arch/mp1000-seprom.h>
+static unsigned int netcard_portlist[] __initdata = {MP1000_EIO_BASE+0x300, 0};
+static unsigned int cs8900_irq_map[] = {IRQ_EINT3,0,0,0};
#else
static unsigned int netcard_portlist[] __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -247,6 +252,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 +413,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.
@@ -573,6 +594,10 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
cnt -= j;
}
} else
+#elif defined(CONFIG_MACH_MP1000)
+ if (1) {
+ memcpy(dev->dev_addr, get_eeprom_mac_address(), ETH_ALEN);
+ } else
#endif
if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
@@ -632,6 +657,10 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
if (1) {
printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n");
} else
+#elif defined(CONFIG_MACH_MP1000)
+ if (1) {
+ lp->force |= FORCE_RJ45;
+ } else
#endif
if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
@@ -760,6 +789,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)
@@ -1211,7 +1243,7 @@ net_open(struct net_device *dev)
else
#endif
{
-#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105)
+#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) && !defined(CONFIG_MACH_MP1000)
if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h
index decea264f121..f19d1ebe0183 100644
--- a/drivers/net/cs89x0.h
+++ b/drivers/net/cs89x0.h
@@ -16,7 +16,7 @@
#include <linux/config.h>
-#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
+#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) || defined (CONFIG_MACH_MP1000)
/* IXDP2401/IXDP2801 uses dword-aligned register addressing */
#define CS89x0_PORT(reg) ((reg) * 2)
#else
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 521c83137bf6..f130bdab3fd3 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -5,7 +5,7 @@
*
* adopted from sunlance.c by Richard van den Berg
*
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*
* additional sources:
* - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
@@ -57,13 +57,15 @@
#include <linux/string.h>
#include <asm/addrspace.h>
+#include <asm/system.h>
+
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
#include <asm/dec/machtype.h>
+#include <asm/dec/system.h>
#include <asm/dec/tc.h>
-#include <asm/system.h>
static char version[] __devinitdata =
"declance.c: v0.009 by Linux MIPS DECstation task force\n";
@@ -79,10 +81,6 @@ MODULE_LICENSE("GPL");
#define PMAD_LANCE 2
#define PMAX_LANCE 3
-#ifndef CONFIG_TC
-unsigned long system_base;
-unsigned long dmaptr;
-#endif
#define LE_CSR0 0
#define LE_CSR1 1
@@ -237,7 +235,7 @@ struct lance_init_block {
/*
* This works *only* for the ring descriptors
*/
-#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
+#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
struct lance_private {
struct net_device *next;
@@ -697,12 +695,13 @@ out:
spin_unlock(&lp->lock);
}
-static void lance_dma_merr_int(const int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id,
+ struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
printk("%s: DMA error\n", dev->name);
+ return IRQ_HANDLED;
}
static irqreturn_t
@@ -1026,10 +1025,6 @@ static int __init dec_lance_init(const int type, const int slot)
unsigned long esar_base;
unsigned char *esar;
-#ifndef CONFIG_TC
- system_base = KN01_LANCE_BASE;
-#endif
-
if (dec_lance_debug && version_printed++ == 0)
printk(version);
@@ -1062,16 +1057,16 @@ static int __init dec_lance_init(const int type, const int slot)
switch (type) {
#ifdef CONFIG_TC
case ASIC_LANCE:
- dev->base_addr = system_base + IOASIC_LANCE;
+ dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
/* buffer space for the on-board LANCE shared memory */
/*
* FIXME: ugly hack!
*/
- dev->mem_start = KSEG1ADDR(0x00020000);
+ dev->mem_start = CKSEG1ADDR(0x00020000);
dev->mem_end = dev->mem_start + 0x00020000;
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
- esar_base = system_base + IOASIC_ESAR;
+ esar_base = CKSEG1ADDR(dec_kn_slot_base + IOASIC_ESAR);
/* Workaround crash with booting KN04 2.1k from Disk */
memset((void *)dev->mem_start, 0,
@@ -1101,14 +1096,14 @@ static int __init dec_lance_init(const int type, const int slot)
/* Setup I/O ASIC LANCE DMA. */
lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
ioasic_write(IO_REG_LANCE_DMA_P,
- PHYSADDR(dev->mem_start) << 3);
+ CPHYSADDR(dev->mem_start) << 3);
break;
case PMAD_LANCE:
claim_tc_card(slot);
- dev->mem_start = get_tc_base_addr(slot);
+ dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
dev->base_addr = dev->mem_start + 0x100000;
dev->irq = get_tc_irq_nr(slot);
esar_base = dev->mem_start + 0x1c0002;
@@ -1137,9 +1132,9 @@ static int __init dec_lance_init(const int type, const int slot)
case PMAX_LANCE:
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
- dev->base_addr = KN01_LANCE_BASE;
- dev->mem_start = KN01_LANCE_BASE + 0x01000000;
- esar_base = KN01_RTC_BASE + 1;
+ dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
+ dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
+ esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
lp->dma_irq = -1;
/*
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 25cc20e415da..eb169a8e8773 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
static void e100_get_defaults(struct nic *nic)
{
- struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
- struct param_range cbs = { .min = 64, .max = 256, .count = 128 };
+ struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
+ struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1007,213 +1007,25 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
}
-/********************************************************/
-/* Micro code for 8086:1229 Rev 8 */
-/********************************************************/
-
-/* Parameter values for the D101M B-step */
-#define D101M_CPUSAVER_TIMER_DWORD 78
-#define D101M_CPUSAVER_BUNDLE_DWORD 65
-#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
-
-#define D101M_B_RCVBUNDLE_UCODE \
-{\
-0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
-0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
-0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
-0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
-0x00380438, 0x00000000, 0x00140000, 0x00380555, \
-0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
-0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
-0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
-0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
-0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
-0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
-0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
-0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
-0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
-0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
-0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
-0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
-0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
-0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
-0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
-0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
-0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
-0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
-0x00380559, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
-0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
-0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
-}
-
-/********************************************************/
-/* Micro code for 8086:1229 Rev 9 */
-/********************************************************/
-
-/* Parameter values for the D101S */
-#define D101S_CPUSAVER_TIMER_DWORD 78
-#define D101S_CPUSAVER_BUNDLE_DWORD 67
-#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
-
-#define D101S_RCVBUNDLE_UCODE \
-{\
-0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
-0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
-0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
-0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
-0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
-0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
-0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
-0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
-0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
-0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
-0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
-0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
-0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
-0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
-0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
-0x00101313, 0x00380700, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
-0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
-0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
-0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
-0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
-0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
-0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
-0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
-0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
-0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00130831, \
-0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
-0x00041000, 0x00010004, 0x00380700 \
-}
-
-/********************************************************/
-/* Micro code for the 8086:1229 Rev F/10 */
-/********************************************************/
-
-/* Parameter values for the D102 E-step */
-#define D102_E_CPUSAVER_TIMER_DWORD 42
-#define D102_E_CPUSAVER_BUNDLE_DWORD 54
-#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
-
-#define D102_E_RCVBUNDLE_UCODE \
-{\
-0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
-0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
-0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
-0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
-0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
-0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
-0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
-0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
-0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
-}
-
static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
{
-/* *INDENT-OFF* */
- static struct {
- u32 ucode[UCODE_SIZE + 1];
- u8 mac;
- u8 timer_dword;
- u8 bundle_dword;
- u8 min_size_dword;
- } ucode_opts[] = {
- { D101M_B_RCVBUNDLE_UCODE,
- mac_82559_D101M,
- D101M_CPUSAVER_TIMER_DWORD,
- D101M_CPUSAVER_BUNDLE_DWORD,
- D101M_CPUSAVER_MIN_SIZE_DWORD },
- { D101S_RCVBUNDLE_UCODE,
- mac_82559_D101S,
- D101S_CPUSAVER_TIMER_DWORD,
- D101S_CPUSAVER_BUNDLE_DWORD,
- D101S_CPUSAVER_MIN_SIZE_DWORD },
- { D102_E_RCVBUNDLE_UCODE,
- mac_82551_F,
- D102_E_CPUSAVER_TIMER_DWORD,
- D102_E_CPUSAVER_BUNDLE_DWORD,
- D102_E_CPUSAVER_MIN_SIZE_DWORD },
- { D102_E_RCVBUNDLE_UCODE,
- mac_82551_10,
- D102_E_CPUSAVER_TIMER_DWORD,
- D102_E_CPUSAVER_BUNDLE_DWORD,
- D102_E_CPUSAVER_MIN_SIZE_DWORD },
- { {0}, 0, 0, 0, 0}
- }, *opts;
-/* *INDENT-ON* */
-
-#define BUNDLESMALL 1
-#define BUNDLEMAX 50
-#define INTDELAY 15000
-
- opts = ucode_opts;
-
- /* do not load u-code for ICH devices */
- if (nic->flags & ich)
- return;
-
- /* Search for ucode match against h/w rev_id */
- while (opts->mac) {
- if (nic->mac == opts->mac) {
- int i;
- u32 *ucode = opts->ucode;
-
- /* Insert user-tunable settings */
- ucode[opts->timer_dword] &= 0xFFFF0000;
- ucode[opts->timer_dword] |=
- (u16) INTDELAY;
- ucode[opts->bundle_dword] &= 0xFFFF0000;
- ucode[opts->bundle_dword] |= (u16) BUNDLEMAX;
- ucode[opts->min_size_dword] &= 0xFFFF0000;
- ucode[opts->min_size_dword] |=
- (BUNDLESMALL) ? 0xFFFF : 0xFF80;
-
- for(i = 0; i < UCODE_SIZE; i++)
- cb->u.ucode[i] = cpu_to_le32(ucode[i]);
- cb->command = cpu_to_le16(cb_ucode);
- return;
- }
- opts++;
- }
+ int i;
+ static const u32 ucode[UCODE_SIZE] = {
+ /* NFS packets are misinterpreted as TCO packets and
+ * incorrectly routed to the BMC over SMBus. This
+ * microcode patch checks the fragmented IP bit in the
+ * NFS/UDP header to distinguish between NFS and TCO. */
+ 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
+ 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
+ 0x00906EFD, 0x00900EFD, 0x00E00EF8,
+ };
- cb->command = cpu_to_le16(cb_nop);
+ if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
+ for(i = 0; i < UCODE_SIZE; i++)
+ cb->u.ucode[i] = cpu_to_le32(ucode[i]);
+ cb->command = cpu_to_le16(cb_ucode);
+ } else
+ cb->command = cpu_to_le16(cb_nop);
}
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
@@ -1387,13 +1199,13 @@ static void e100_update_stats(struct nic *nic)
ns->collisions += nic->tx_collisions;
ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
le32_to_cpu(s->tx_lost_crs);
- ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
nic->rx_over_length_errors;
ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
+ ns->rx_missed_errors += le32_to_cpu(s->rx_resource_errors);
ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
le32_to_cpu(s->rx_alignment_errors) +
le32_to_cpu(s->rx_short_frame_errors) +
@@ -1727,12 +1539,10 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
if(unlikely(!(rfd_status & cb_ok))) {
/* Don't indicate if hardware indicates errors */
- nic->net_stats.rx_dropped++;
dev_kfree_skb_any(skb);
} else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) {
/* Don't indicate oversized frames */
nic->rx_over_length_errors++;
- nic->net_stats.rx_dropped++;
dev_kfree_skb_any(skb);
} else {
nic->net_stats.rx_packets++;
@@ -2391,6 +2201,7 @@ static struct ethtool_ops e100_ethtool_ops = {
.phys_id = e100_phys_id,
.get_stats_count = e100_get_stats_count,
.get_ethtool_stats = e100_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
@@ -2541,7 +2352,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
e100_phy_init(nic);
memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
- if(!is_valid_ether_addr(netdev->dev_addr)) {
+ memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
+ if(!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC address from "
"EEPROM, aborting.\n");
err = -EAGAIN;
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 092757bc721f..3f653a93e1bc 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -72,6 +72,10 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
+#ifdef CONFIG_E1000_MQ
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#endif
#define BAR_0 0
#define BAR_1 1
@@ -165,10 +169,33 @@ struct e1000_buffer {
uint16_t next_to_watch;
};
-struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
-struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
+struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
+struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
+
+struct e1000_tx_ring {
+ /* pointer to the descriptor ring memory */
+ void *desc;
+ /* physical address of the descriptor ring */
+ dma_addr_t dma;
+ /* length of descriptor ring in bytes */
+ unsigned int size;
+ /* number of descriptors in the ring */
+ unsigned int count;
+ /* next descriptor to associate a buffer with */
+ unsigned int next_to_use;
+ /* next descriptor to check for DD status bit */
+ unsigned int next_to_clean;
+ /* array of buffer information structs */
+ struct e1000_buffer *buffer_info;
+
+ struct e1000_buffer previous_buffer_info;
+ spinlock_t tx_lock;
+ uint16_t tdh;
+ uint16_t tdt;
+ uint64_t pkt;
+};
-struct e1000_desc_ring {
+struct e1000_rx_ring {
/* pointer to the descriptor ring memory */
void *desc;
/* physical address of the descriptor ring */
@@ -186,6 +213,10 @@ struct e1000_desc_ring {
/* arrays of page information for packet split */
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
+
+ uint16_t rdh;
+ uint16_t rdt;
+ uint64_t pkt;
};
#define E1000_DESC_UNUSED(R) \
@@ -227,9 +258,10 @@ struct e1000_adapter {
unsigned long led_status;
/* TX */
- struct e1000_desc_ring tx_ring;
- struct e1000_buffer previous_buffer_info;
- spinlock_t tx_lock;
+ struct e1000_tx_ring *tx_ring; /* One per active queue */
+#ifdef CONFIG_E1000_MQ
+ struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */
+#endif
uint32_t txd_cmd;
uint32_t tx_int_delay;
uint32_t tx_abs_int_delay;
@@ -246,19 +278,33 @@ struct e1000_adapter {
/* RX */
#ifdef CONFIG_E1000_NAPI
- boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
- int work_to_do);
+ boolean_t (*clean_rx) (struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
+ int *work_done, int work_to_do);
#else
- boolean_t (*clean_rx) (struct e1000_adapter *adapter);
+ boolean_t (*clean_rx) (struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
#endif
- void (*alloc_rx_buf) (struct e1000_adapter *adapter);
- struct e1000_desc_ring rx_ring;
+ void (*alloc_rx_buf) (struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
+ struct e1000_rx_ring *rx_ring; /* One per active queue */
+#ifdef CONFIG_E1000_NAPI
+ struct net_device *polling_netdev; /* One per active queue */
+#endif
+#ifdef CONFIG_E1000_MQ
+ struct net_device **cpu_netdev; /* per-cpu */
+ struct call_async_data_struct rx_sched_call_data;
+ int cpu_for_queue[4];
+#endif
+ int num_queues;
+
uint64_t hw_csum_err;
uint64_t hw_csum_good;
+ uint64_t rx_hdr_split;
uint32_t rx_int_delay;
uint32_t rx_abs_int_delay;
boolean_t rx_csum;
- boolean_t rx_ps;
+ unsigned int rx_ps_pages;
uint32_t gorcl;
uint64_t gorcl_old;
uint16_t rx_ps_bsize0;
@@ -278,8 +324,8 @@ struct e1000_adapter {
struct e1000_phy_stats phy_stats;
uint32_t test_icr;
- struct e1000_desc_ring test_tx_ring;
- struct e1000_desc_ring test_rx_ring;
+ struct e1000_tx_ring test_tx_ring;
+ struct e1000_rx_ring test_rx_ring;
int msg_enable;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index f133ff0b0b94..6b9acc7f94a3 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
struct e1000_stats {
@@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
- { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
+ { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
+ { "rx_header_split", E1000_STAT(rx_hdr_split) },
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
@@ -546,8 +547,10 @@ e1000_set_eeprom(struct net_device *netdev,
ret_val = e1000_write_eeprom(hw, first_word,
last_word - first_word + 1, eeprom_buff);
- /* Update the checksum over the first part of the EEPROM if needed */
- if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
+ /* Update the checksum over the first part of the EEPROM if needed
+ * and flush shadow RAM for 82573 conrollers */
+ if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) ||
+ (hw->mac_type == e1000_82573)))
e1000_update_eeprom_checksum(hw);
kfree(eeprom_buff);
@@ -576,8 +579,8 @@ e1000_get_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+ struct e1000_tx_ring *txdr = adapter->tx_ring;
+ struct e1000_rx_ring *rxdr = adapter->rx_ring;
ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
@@ -597,20 +600,40 @@ e1000_set_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
- struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
- int err;
+ struct e1000_tx_ring *txdr, *tx_old, *tx_new;
+ struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+ int i, err, tx_ring_size, rx_ring_size;
+
+ tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+ rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+
+ if (netif_running(adapter->netdev))
+ e1000_down(adapter);
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
+ adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
+ if (!adapter->tx_ring) {
+ err = -ENOMEM;
+ goto err_setup_rx;
+ }
+ memset(adapter->tx_ring, 0, tx_ring_size);
+
+ adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ err = -ENOMEM;
+ goto err_setup_rx;
+ }
+ memset(adapter->rx_ring, 0, rx_ring_size);
+
+ txdr = adapter->tx_ring;
+ rxdr = adapter->rx_ring;
+
if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
- if(netif_running(adapter->netdev))
- e1000_down(adapter);
-
rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
E1000_MAX_RXD : E1000_MAX_82544_RXD));
@@ -621,11 +644,16 @@ e1000_set_ringparam(struct net_device *netdev,
E1000_MAX_TXD : E1000_MAX_82544_TXD));
E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+ for (i = 0; i < adapter->num_queues; i++) {
+ txdr[i].count = txdr->count;
+ rxdr[i].count = rxdr->count;
+ }
+
if(netif_running(adapter->netdev)) {
/* Try to get new resources before deleting old */
- if((err = e1000_setup_rx_resources(adapter)))
+ if ((err = e1000_setup_all_rx_resources(adapter)))
goto err_setup_rx;
- if((err = e1000_setup_tx_resources(adapter)))
+ if ((err = e1000_setup_all_tx_resources(adapter)))
goto err_setup_tx;
/* save the new, restore the old in order to free it,
@@ -635,8 +663,10 @@ e1000_set_ringparam(struct net_device *netdev,
tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
- e1000_free_rx_resources(adapter);
- e1000_free_tx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
+ kfree(tx_old);
+ kfree(rx_old);
adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new;
if((err = e1000_up(adapter)))
@@ -645,7 +675,7 @@ e1000_set_ringparam(struct net_device *netdev,
return 0;
err_setup_tx:
- e1000_free_rx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
@@ -696,6 +726,11 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
* Some bits that get toggled are ignored.
*/
switch (adapter->hw.mac_type) {
+ /* there are several bits on newer hardware that are r/w */
+ case e1000_82571:
+ case e1000_82572:
+ toggle = 0x7FFFF3FF;
+ break;
case e1000_82573:
toggle = 0x7FFFF033;
break;
@@ -898,8 +933,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
static void
e1000_free_desc_rings(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i;
@@ -941,8 +976,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
static int
e1000_setup_desc_rings(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
uint32_t rctl;
int size, i, ret_val;
@@ -1245,6 +1280,8 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
case e1000_82541_rev_2:
case e1000_82547:
case e1000_82547_rev_2:
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
return e1000_integrated_phy_loopback(adapter);
break;
@@ -1340,8 +1377,8 @@ e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
static int
e1000_run_loopback_test(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i, j, k, l, lc, good_cnt, ret_val=0;
unsigned long time;
@@ -1509,6 +1546,7 @@ e1000_diag_test(struct net_device *netdev,
data[2] = 0;
data[3] = 0;
}
+ msleep_interruptible(4 * 1000);
}
static void
@@ -1625,7 +1663,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
- if(adapter->hw.mac_type < e1000_82573) {
+ if(adapter->hw.mac_type < e1000_82571) {
if(!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = e1000_led_blink_callback;
@@ -1739,6 +1777,7 @@ struct ethtool_ops e1000_ethtool_ops = {
.phys_id = e1000_phys_id,
.get_stats_count = e1000_get_stats_count,
.get_ethtool_stats = e1000_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
void e1000_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 045f5426ab9a..8fc876da43b4 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -83,14 +83,14 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
static const
uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
- { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
- 22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
- 32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
- 43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
- 57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
- 73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
- 91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
- 108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
+ { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
+ 0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
+ 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
+ 21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
+ 40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
+ 60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
+ 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
+ 104, 109, 114, 118, 121, 124};
/******************************************************************************
@@ -286,7 +286,6 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82546GB_SERDES:
case E1000_DEV_ID_82546GB_PCIE:
- case E1000_DEV_ID_82546GB_QUAD_COPPER:
hw->mac_type = e1000_82546_rev_3;
break;
case E1000_DEV_ID_82541EI:
@@ -305,8 +304,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82547GI:
hw->mac_type = e1000_82547_rev_2;
break;
+ case E1000_DEV_ID_82571EB_COPPER:
+ case E1000_DEV_ID_82571EB_FIBER:
+ case E1000_DEV_ID_82571EB_SERDES:
+ hw->mac_type = e1000_82571;
+ break;
+ case E1000_DEV_ID_82572EI_COPPER:
+ case E1000_DEV_ID_82572EI_FIBER:
+ case E1000_DEV_ID_82572EI_SERDES:
+ hw->mac_type = e1000_82572;
+ break;
case E1000_DEV_ID_82573E:
case E1000_DEV_ID_82573E_IAMT:
+ case E1000_DEV_ID_82573L:
hw->mac_type = e1000_82573;
break;
default:
@@ -315,6 +325,8 @@ e1000_set_mac_type(struct e1000_hw *hw)
}
switch(hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
hw->eeprom_semaphore_present = TRUE;
/* fall through */
@@ -351,6 +363,8 @@ e1000_set_media_type(struct e1000_hw *hw)
switch (hw->device_id) {
case E1000_DEV_ID_82545GM_SERDES:
case E1000_DEV_ID_82546GB_SERDES:
+ case E1000_DEV_ID_82571EB_SERDES:
+ case E1000_DEV_ID_82572EI_SERDES:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
@@ -523,6 +537,8 @@ e1000_reset_hw(struct e1000_hw *hw)
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
/* fall through */
+ case e1000_82571:
+ case e1000_82572:
ret_val = e1000_get_auto_rd_done(hw);
if(ret_val)
/* We don't want to continue accessing MAC registers. */
@@ -683,6 +699,9 @@ e1000_init_hw(struct e1000_hw *hw)
switch (hw->mac_type) {
default:
break;
+ case e1000_82571:
+ case e1000_82572:
+ ctrl |= (1 << 22);
case e1000_82573:
ctrl |= E1000_TXDCTL_COUNT_DESC;
break;
@@ -694,6 +713,26 @@ e1000_init_hw(struct e1000_hw *hw)
e1000_enable_tx_pkt_filtering(hw);
}
+ switch (hw->mac_type) {
+ default:
+ break;
+ case e1000_82571:
+ case e1000_82572:
+ ctrl = E1000_READ_REG(hw, TXDCTL1);
+ ctrl &= ~E1000_TXDCTL_WTHRESH;
+ ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB;
+ ctrl |= (1 << 22);
+ E1000_WRITE_REG(hw, TXDCTL1, ctrl);
+ break;
+ }
+
+
+
+ if (hw->mac_type == e1000_82573) {
+ uint32_t gcr = E1000_READ_REG(hw, GCR);
+ gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+ E1000_WRITE_REG(hw, GCR, gcr);
+ }
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
@@ -878,6 +917,14 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
DEBUGFUNC("e1000_setup_fiber_serdes_link");
+ /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
+ * until explicitly turned off or a power cycle is performed. A read to
+ * the register does not indicate its status. Therefore, we ensure
+ * loopback mode is disabled during initialization.
+ */
+ if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
+ E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
+
/* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
@@ -2943,6 +2990,8 @@ e1000_phy_reset(struct e1000_hw *hw)
switch (hw->mac_type) {
case e1000_82541_rev_2:
+ case e1000_82571:
+ case e1000_82572:
ret_val = e1000_phy_hw_reset(hw);
if(ret_val)
return ret_val;
@@ -2981,6 +3030,16 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
DEBUGFUNC("e1000_detect_gig_phy");
+ /* The 82571 firmware may still be configuring the PHY. In this
+ * case, we cannot access the PHY until the configuration is done. So
+ * we explicitly set the PHY values. */
+ if(hw->mac_type == e1000_82571 ||
+ hw->mac_type == e1000_82572) {
+ hw->phy_id = IGP01E1000_I_PHY_ID;
+ hw->phy_type = e1000_phy_igp_2;
+ return E1000_SUCCESS;
+ }
+
/* Read the PHY ID Registers to identify which PHY is onboard. */
ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
if(ret_val)
@@ -3334,6 +3393,21 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break;
+ case e1000_82571:
+ case e1000_82572:
+ eeprom->type = e1000_eeprom_spi;
+ eeprom->opcode_bits = 8;
+ eeprom->delay_usec = 1;
+ if (eecd & E1000_EECD_ADDR_BITS) {
+ eeprom->page_size = 32;
+ eeprom->address_bits = 16;
+ } else {
+ eeprom->page_size = 8;
+ eeprom->address_bits = 8;
+ }
+ eeprom->use_eerd = FALSE;
+ eeprom->use_eewr = FALSE;
+ break;
case e1000_82573:
eeprom->type = e1000_eeprom_spi;
eeprom->opcode_bits = 8;
@@ -3543,25 +3617,26 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
eecd = E1000_READ_REG(hw, EECD);
if (hw->mac_type != e1000_82573) {
- /* Request EEPROM Access */
- if(hw->mac_type > e1000_82544) {
- eecd |= E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- eecd = E1000_READ_REG(hw, EECD);
- while((!(eecd & E1000_EECD_GNT)) &&
- (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
- i++;
- udelay(5);
- eecd = E1000_READ_REG(hw, EECD);
- }
- if(!(eecd & E1000_EECD_GNT)) {
- eecd &= ~E1000_EECD_REQ;
+ /* Request EEPROM Access */
+ if(hw->mac_type > e1000_82544) {
+ eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
- DEBUGOUT("Could not acquire EEPROM grant\n");
- return -E1000_ERR_EEPROM;
+ eecd = E1000_READ_REG(hw, EECD);
+ while((!(eecd & E1000_EECD_GNT)) &&
+ (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+ i++;
+ udelay(5);
+ eecd = E1000_READ_REG(hw, EECD);
+ }
+ if(!(eecd & E1000_EECD_GNT)) {
+ eecd &= ~E1000_EECD_REQ;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ DEBUGOUT("Could not acquire EEPROM grant\n");
+ e1000_put_hw_eeprom_semaphore(hw);
+ return -E1000_ERR_EEPROM;
+ }
}
}
- }
/* Setup EEPROM for Read/Write */
@@ -4064,7 +4139,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
return -E1000_ERR_EEPROM;
}
- /* 82573 reads only through eerd */
+ /* 82573 writes only through eewr */
if(eeprom->use_eewr == TRUE)
return e1000_write_eeprom_eewr(hw, offset, words, data);
@@ -4353,9 +4428,16 @@ e1000_read_mac_addr(struct e1000_hw * hw)
hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
}
- if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
- (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
+ switch (hw->mac_type) {
+ default:
+ break;
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ case e1000_82571:
+ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
hw->perm_mac_addr[5] ^= 0x01;
+ break;
+ }
for(i = 0; i < NODE_ADDRESS_SIZE; i++)
hw->mac_addr[i] = hw->perm_mac_addr[i];
@@ -4385,6 +4467,12 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
e1000_rar_set(hw, hw->mac_addr, 0);
rar_num = E1000_RAR_ENTRIES;
+
+ /* Reserve a spot for the Locally Administered Address to work around
+ * an 82571 issue in which a reset on one port will reload the MAC on
+ * the other port. */
+ if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
+ rar_num -= 1;
/* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n");
for(i = 1; i < rar_num; i++) {
@@ -4427,6 +4515,12 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
/* Clear RAR[1-15] */
DEBUGOUT(" Clearing RAR[1-15]\n");
num_rar_entry = E1000_RAR_ENTRIES;
+ /* Reserve a spot for the Locally Administered Address to work around
+ * an 82571 issue in which a reset on one port will reload the MAC on
+ * the other port. */
+ if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
+ num_rar_entry -= 1;
+
for(i = rar_used_count; i < num_rar_entry; i++) {
E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
@@ -4984,7 +5078,6 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw)
temp = E1000_READ_REG(hw, ICTXQEC);
temp = E1000_READ_REG(hw, ICTXQMTC);
temp = E1000_READ_REG(hw, ICRXDMTC);
-
}
/******************************************************************************
@@ -5151,6 +5244,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
break;
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
@@ -5250,6 +5345,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
int32_t ret_val;
uint16_t agc_value = 0;
uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
+ uint16_t max_agc = 0;
uint16_t i, phy_data;
uint16_t cable_length;
@@ -5338,6 +5434,40 @@ e1000_get_cable_length(struct e1000_hw *hw,
IGP01E1000_AGC_RANGE) : 0;
*max_length = e1000_igp_cable_length_table[agc_value] +
IGP01E1000_AGC_RANGE;
+ } else if (hw->phy_type == e1000_phy_igp_2) {
+ uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
+ {IGP02E1000_PHY_AGC_A,
+ IGP02E1000_PHY_AGC_B,
+ IGP02E1000_PHY_AGC_C,
+ IGP02E1000_PHY_AGC_D};
+ /* Read the AGC registers for all channels */
+ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
+ ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
+ if (ret_val)
+ return ret_val;
+
+ /* Getting bits 15:9, which represent the combination of course and
+ * fine gain values. The result is a number that can be put into
+ * the lookup table to obtain the approximate cable length. */
+ cur_agc = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
+ IGP02E1000_AGC_LENGTH_MASK;
+
+ /* Remove min & max AGC values from calculation. */
+ if (e1000_igp_2_cable_length_table[min_agc] > e1000_igp_2_cable_length_table[cur_agc])
+ min_agc = cur_agc;
+ if (e1000_igp_2_cable_length_table[max_agc] < e1000_igp_2_cable_length_table[cur_agc])
+ max_agc = cur_agc;
+
+ agc_value += e1000_igp_2_cable_length_table[cur_agc];
+ }
+
+ agc_value -= (e1000_igp_2_cable_length_table[min_agc] + e1000_igp_2_cable_length_table[max_agc]);
+ agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
+
+ /* Calculate cable length with the error range of +/- 10 meters. */
+ *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
+ (agc_value - IGP02E1000_AGC_RANGE) : 0;
+ *max_length = agc_value + IGP02E1000_AGC_RANGE;
}
return E1000_SUCCESS;
@@ -6465,6 +6595,8 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
default:
msec_delay(5);
break;
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
while(timeout) {
if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
@@ -6494,10 +6626,31 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
int32_t
e1000_get_phy_cfg_done(struct e1000_hw *hw)
{
+ int32_t timeout = PHY_CFG_TIMEOUT;
+ uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
+
DEBUGFUNC("e1000_get_phy_cfg_done");
- /* Simply wait for 10ms */
- msec_delay(10);
+ switch (hw->mac_type) {
+ default:
+ msec_delay(10);
+ break;
+ case e1000_82571:
+ case e1000_82572:
+ while (timeout) {
+ if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
+ break;
+ else
+ msec_delay(1);
+ timeout--;
+ }
+
+ if (!timeout) {
+ DEBUGOUT("MNG configuration cycle has not completed.\n");
+ return -E1000_ERR_RESET;
+ }
+ break;
+ }
return E1000_SUCCESS;
}
@@ -6569,8 +6722,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
return;
swsm = E1000_READ_REG(hw, SWSM);
- /* Release both semaphores. */
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+ swsm &= ~(E1000_SWSM_SWESMBI);
E1000_WRITE_REG(hw, SWSM, swsm);
}
@@ -6606,6 +6758,8 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw)
* if this is the case. We read FWSM to determine the manageability mode.
*/
switch (hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
fwsm = E1000_READ_REG(hw, FWSM);
if((fwsm & E1000_FWSM_MODE_MASK) != 0)
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 51c2b3a18b6f..4f2c196dc314 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -57,6 +57,8 @@ typedef enum {
e1000_82541_rev_2,
e1000_82547,
e1000_82547_rev_2,
+ e1000_82571,
+ e1000_82572,
e1000_82573,
e1000_num_macs
} e1000_mac_type;
@@ -478,10 +480,16 @@ uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82547EI 0x1019
+#define E1000_DEV_ID_82571EB_COPPER 0x105E
+#define E1000_DEV_ID_82571EB_FIBER 0x105F
+#define E1000_DEV_ID_82571EB_SERDES 0x1060
+#define E1000_DEV_ID_82572EI_COPPER 0x107D
+#define E1000_DEV_ID_82572EI_FIBER 0x107E
+#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
+#define E1000_DEV_ID_82573L 0x109A
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
@@ -833,6 +841,8 @@ struct e1000_ffvt_entry {
#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+#define E1000_DISABLE_SERDES_LOOPBACK 0x0400
+
/* Register Set. (82543, 82544)
*
* Registers are defined to be 32 bits and should be accessed as 32 bit values.
@@ -853,6 +863,7 @@ struct e1000_ffvt_entry {
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
+#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
@@ -864,6 +875,12 @@ struct e1000_ffvt_entry {
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
+#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
+#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
+#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
+#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
+#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
+#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
@@ -895,6 +912,12 @@ struct e1000_ffvt_entry {
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
+#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
+#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
+#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
+#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
+#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
+#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
@@ -980,15 +1003,15 @@ struct e1000_ffvt_entry {
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
-#define E1000_IAC 0x4100 /* Interrupt Assertion Count */
-#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */
+#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
+#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
+#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
+#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
+#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
+#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
+#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
+#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
+#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
@@ -1018,6 +1041,14 @@ struct e1000_ffvt_entry {
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
+
+/* RSS registers */
+#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
+#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
+#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
+#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
+#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
+#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
/* Register Set (82542)
*
* Some of the 82542 registers are located at different offsets than they are
@@ -1032,6 +1063,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA E1000_FLA
#define E1000_82542_MDIC E1000_MDIC
+#define E1000_82542_SCTL E1000_SCTL
#define E1000_82542_FCAL E1000_FCAL
#define E1000_82542_FCAH E1000_FCAH
#define E1000_82542_FCT E1000_FCT
@@ -1049,6 +1081,18 @@ struct e1000_ffvt_entry {
#define E1000_82542_RDLEN 0x00118
#define E1000_82542_RDH 0x00120
#define E1000_82542_RDT 0x00128
+#define E1000_82542_RDTR0 E1000_82542_RDTR
+#define E1000_82542_RDBAL0 E1000_82542_RDBAL
+#define E1000_82542_RDBAH0 E1000_82542_RDBAH
+#define E1000_82542_RDLEN0 E1000_82542_RDLEN
+#define E1000_82542_RDH0 E1000_82542_RDH
+#define E1000_82542_RDT0 E1000_82542_RDT
+#define E1000_82542_RDTR1 0x00130
+#define E1000_82542_RDBAL1 0x00138
+#define E1000_82542_RDBAH1 0x0013C
+#define E1000_82542_RDLEN1 0x00140
+#define E1000_82542_RDH1 0x00148
+#define E1000_82542_RDT1 0x00150
#define E1000_82542_FCRTH 0x00160
#define E1000_82542_FCRTL 0x00168
#define E1000_82542_FCTTV E1000_FCTTV
@@ -1197,6 +1241,13 @@ struct e1000_ffvt_entry {
#define E1000_82542_ICRXOC E1000_ICRXOC
#define E1000_82542_HICR E1000_HICR
+#define E1000_82542_CPUVEC E1000_CPUVEC
+#define E1000_82542_MRQC E1000_MRQC
+#define E1000_82542_RETA E1000_RETA
+#define E1000_82542_RSSRK E1000_RSSRK
+#define E1000_82542_RSSIM E1000_RSSIM
+#define E1000_82542_RSSIR E1000_RSSIR
+
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
uint64_t crcerrs;
@@ -1336,6 +1387,7 @@ struct e1000_hw {
boolean_t serdes_link_down;
boolean_t tbi_compatibility_en;
boolean_t tbi_compatibility_on;
+ boolean_t laa_is_present;
boolean_t phy_reset_disable;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
@@ -1374,6 +1426,7 @@ struct e1000_hw {
#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
+#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
@@ -1491,6 +1544,8 @@ struct e1000_hw {
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
+#define E1000_CTRL_EXT_CANC 0x04000000 /* Interrupt delay cancellation */
+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
@@ -1524,6 +1579,7 @@ struct e1000_hw {
#define E1000_LEDCTL_LED2_BLINK 0x00800000
#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000
#define E1000_LEDCTL_LED3_IVRT 0x40000000
#define E1000_LEDCTL_LED3_BLINK 0x80000000
@@ -1784,6 +1840,16 @@ struct e1000_hw {
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
+/* Multiple Receive Queue Control */
+#define E1000_MRQC_ENABLE_MASK 0x00000003
+#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001
+#define E1000_MRQC_ENABLE_RSS_INT 0x00000004
+#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
+#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
+#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
+#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
/* Definitions for power management and wakeup registers */
/* Wake Up Control */
@@ -1928,6 +1994,7 @@ struct e1000_host_command_info {
#define E1000_MDALIGN 4096
#define E1000_GCR_BEM32 0x00400000
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
#define E1000_FACTPS_LAN0_VALID 0x00000004
@@ -1980,6 +2047,7 @@ struct e1000_host_command_info {
/* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004
+#define EEPROM_VERSION 0x0005
#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
#define EEPROM_PHY_CLASS_WORD 0x0007
#define EEPROM_INIT_CONTROL1_REG 0x000A
@@ -1990,6 +2058,8 @@ struct e1000_host_command_info {
#define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F
+#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
+
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
@@ -2108,6 +2178,8 @@ struct e1000_host_command_info {
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
+#define E1000_PBA_32K 0x0020
+#define E1000_PBA_38K 0x0026
#define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
@@ -2592,11 +2664,11 @@ struct e1000_host_command_info {
/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
-#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
+#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
/* The precision error of the cable length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE 10
-#define IGP02E1000_AGC_RANGE 10
+#define IGP02E1000_AGC_RANGE 15
/* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7c8a0a22dcd5..6b72f6acdd54 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -43,7 +43,7 @@ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "6.0.60-k2"DRIVERNAPI
+#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION;
char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
@@ -80,6 +80,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1026),
INTEL_E1000_ETHERNET_DEVICE(0x1027),
INTEL_E1000_ETHERNET_DEVICE(0x1028),
+ INTEL_E1000_ETHERNET_DEVICE(0x105E),
+ INTEL_E1000_ETHERNET_DEVICE(0x105F),
+ INTEL_E1000_ETHERNET_DEVICE(0x1060),
INTEL_E1000_ETHERNET_DEVICE(0x1075),
INTEL_E1000_ETHERNET_DEVICE(0x1076),
INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -88,10 +91,13 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x107A),
INTEL_E1000_ETHERNET_DEVICE(0x107B),
INTEL_E1000_ETHERNET_DEVICE(0x107C),
+ INTEL_E1000_ETHERNET_DEVICE(0x107D),
+ INTEL_E1000_ETHERNET_DEVICE(0x107E),
+ INTEL_E1000_ETHERNET_DEVICE(0x107F),
INTEL_E1000_ETHERNET_DEVICE(0x108A),
INTEL_E1000_ETHERNET_DEVICE(0x108B),
INTEL_E1000_ETHERNET_DEVICE(0x108C),
- INTEL_E1000_ETHERNET_DEVICE(0x1099),
+ INTEL_E1000_ETHERNET_DEVICE(0x109A),
/* required last entry */
{0,}
};
@@ -102,10 +108,18 @@ int e1000_up(struct e1000_adapter *adapter);
void e1000_down(struct e1000_adapter *adapter);
void e1000_reset(struct e1000_adapter *adapter);
int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_rx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *txdr);
+int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rxdr);
+void e1000_free_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring);
+void e1000_free_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
void e1000_update_stats(struct e1000_adapter *adapter);
/* Local Function Prototypes */
@@ -114,14 +128,22 @@ static int e1000_init_module(void);
static void e1000_exit_module(void);
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void __devexit e1000_remove(struct pci_dev *pdev);
+static int e1000_alloc_queues(struct e1000_adapter *adapter);
+#ifdef CONFIG_E1000_MQ
+static void e1000_setup_queue_mapping(struct e1000_adapter *adapter);
+#endif
static int e1000_sw_init(struct e1000_adapter *adapter);
static int e1000_open(struct net_device *netdev);
static int e1000_close(struct net_device *netdev);
static void e1000_configure_tx(struct e1000_adapter *adapter);
static void e1000_configure_rx(struct e1000_adapter *adapter);
static void e1000_setup_rctl(struct e1000_adapter *adapter);
-static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
-static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
+static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
+static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
+static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring);
+static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data);
@@ -132,19 +154,26 @@ static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
static int e1000_set_mac(struct net_device *netdev, void *p);
static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
-static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring);
#ifdef CONFIG_E1000_NAPI
-static int e1000_clean(struct net_device *netdev, int *budget);
+static int e1000_clean(struct net_device *poll_dev, int *budget);
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
#else
-static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
-static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
#endif
-static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter);
+static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd);
@@ -172,6 +201,11 @@ static int e1000_resume(struct pci_dev *pdev);
static void e1000_netpoll (struct net_device *netdev);
#endif
+#ifdef CONFIG_E1000_MQ
+/* for multiple Rx queues */
+void e1000_rx_schedule(void *data);
+#endif
+
/* Exported from other modules */
extern void e1000_check_options(struct e1000_adapter *adapter);
@@ -289,7 +323,7 @@ int
e1000_up(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- int err;
+ int i, err;
/* hardware has been reset, we need to reload some things */
@@ -308,7 +342,8 @@ e1000_up(struct e1000_adapter *adapter)
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
- adapter->alloc_rx_buf(adapter);
+ for (i = 0; i < adapter->num_queues; i++)
+ adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i]);
#ifdef CONFIG_PCI_MSI
if(adapter->hw.mac_type > e1000_82547_rev_2) {
@@ -344,6 +379,9 @@ e1000_down(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev;
e1000_irq_disable(adapter);
+#ifdef CONFIG_E1000_MQ
+ while (atomic_read(&adapter->rx_sched_call_data.count) != 0);
+#endif
free_irq(adapter->pdev->irq, netdev);
#ifdef CONFIG_PCI_MSI
if(adapter->hw.mac_type > e1000_82547_rev_2 &&
@@ -363,11 +401,10 @@ e1000_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
e1000_reset(adapter);
- e1000_clean_tx_ring(adapter);
- e1000_clean_rx_ring(adapter);
+ e1000_clean_all_tx_rings(adapter);
+ e1000_clean_all_rx_rings(adapter);
- /* If WoL is not enabled
- * and management mode is not IAMT
+ /* If WoL is not enabled and management mode is not IAMT
* Power down the PHY so no link is implied when interface is down */
if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
adapter->hw.media_type == e1000_media_type_copper &&
@@ -398,6 +435,10 @@ e1000_reset(struct e1000_adapter *adapter)
case e1000_82547_rev_2:
pba = E1000_PBA_30K;
break;
+ case e1000_82571:
+ case e1000_82572:
+ pba = E1000_PBA_38K;
+ break;
case e1000_82573:
pba = E1000_PBA_12K;
break;
@@ -475,6 +516,7 @@ e1000_probe(struct pci_dev *pdev,
struct net_device *netdev;
struct e1000_adapter *adapter;
unsigned long mmio_start, mmio_len;
+ uint32_t ctrl_ext;
uint32_t swsm;
static int cards_found = 0;
@@ -614,8 +656,9 @@ e1000_probe(struct pci_dev *pdev,
if(e1000_read_mac_addr(&adapter->hw))
DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+ memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->dev_addr)) {
+ if(!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
err = -EIO;
goto err_eeprom;
@@ -687,6 +730,12 @@ e1000_probe(struct pci_dev *pdev,
/* Let firmware know the driver has taken over */
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -731,7 +780,11 @@ e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
+ uint32_t ctrl_ext;
uint32_t manc, swsm;
+#ifdef CONFIG_E1000_NAPI
+ int i;
+#endif
flush_scheduled_work();
@@ -745,6 +798,12 @@ e1000_remove(struct pci_dev *pdev)
}
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -756,13 +815,27 @@ e1000_remove(struct pci_dev *pdev)
}
unregister_netdev(netdev);
+#ifdef CONFIG_E1000_NAPI
+ for (i = 0; i < adapter->num_queues; i++)
+ __dev_put(&adapter->polling_netdev[i]);
+#endif
if(!e1000_check_phy_reset_block(&adapter->hw))
e1000_phy_hw_reset(&adapter->hw);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+#ifdef CONFIG_E1000_NAPI
+ kfree(adapter->polling_netdev);
+#endif
+
iounmap(adapter->hw.hw_addr);
pci_release_regions(pdev);
+#ifdef CONFIG_E1000_MQ
+ free_percpu(adapter->cpu_netdev);
+ free_percpu(adapter->cpu_tx_ring);
+#endif
free_netdev(netdev);
pci_disable_device(pdev);
@@ -783,6 +856,9 @@ e1000_sw_init(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
+#ifdef CONFIG_E1000_NAPI
+ int i;
+#endif
/* PCI config space info */
@@ -840,14 +916,123 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->master_slave = E1000_MASTER_SLAVE;
}
+#ifdef CONFIG_E1000_MQ
+ /* Number of supported queues */
+ switch (hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ adapter->num_queues = 2;
+ break;
+ default:
+ adapter->num_queues = 1;
+ break;
+ }
+ adapter->num_queues = min(adapter->num_queues, num_online_cpus());
+#else
+ adapter->num_queues = 1;
+#endif
+
+ if (e1000_alloc_queues(adapter)) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+
+#ifdef CONFIG_E1000_NAPI
+ for (i = 0; i < adapter->num_queues; i++) {
+ adapter->polling_netdev[i].priv = adapter;
+ adapter->polling_netdev[i].poll = &e1000_clean;
+ adapter->polling_netdev[i].weight = 64;
+ dev_hold(&adapter->polling_netdev[i]);
+ set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
+ }
+#endif
+
+#ifdef CONFIG_E1000_MQ
+ e1000_setup_queue_mapping(adapter);
+#endif
+
atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock);
- spin_lock_init(&adapter->tx_lock);
return 0;
}
/**
+ * e1000_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one ring per queue at run-time since we don't know the
+ * number of queues at compile-time. The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
+ **/
+
+static int __devinit
+e1000_alloc_queues(struct e1000_adapter *adapter)
+{
+ int size;
+
+ size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+ adapter->tx_ring = kmalloc(size, GFP_KERNEL);
+ if (!adapter->tx_ring)
+ return -ENOMEM;
+ memset(adapter->tx_ring, 0, size);
+
+ size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+ adapter->rx_ring = kmalloc(size, GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ return -ENOMEM;
+ }
+ memset(adapter->rx_ring, 0, size);
+
+#ifdef CONFIG_E1000_NAPI
+ size = sizeof(struct net_device) * adapter->num_queues;
+ adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
+ if (!adapter->polling_netdev) {
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+ return -ENOMEM;
+ }
+ memset(adapter->polling_netdev, 0, size);
+#endif
+
+ return E1000_SUCCESS;
+}
+
+#ifdef CONFIG_E1000_MQ
+static void __devinit
+e1000_setup_queue_mapping(struct e1000_adapter *adapter)
+{
+ int i, cpu;
+
+ adapter->rx_sched_call_data.func = e1000_rx_schedule;
+ adapter->rx_sched_call_data.info = adapter->netdev;
+ cpus_clear(adapter->rx_sched_call_data.cpumask);
+
+ adapter->cpu_netdev = alloc_percpu(struct net_device *);
+ adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *);
+
+ lock_cpu_hotplug();
+ i = 0;
+ for_each_online_cpu(cpu) {
+ *per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_queues];
+ /* This is incomplete because we'd like to assign separate
+ * physical cpus to these netdev polling structures and
+ * avoid saturating a subset of cpus.
+ */
+ if (i < adapter->num_queues) {
+ *per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i];
+ adapter->cpu_for_queue[i] = cpu;
+ } else
+ *per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL;
+
+ i++;
+ }
+ unlock_cpu_hotplug();
+}
+#endif
+
+/**
* e1000_open - Called when a network interface is made active
* @netdev: network interface device structure
*
@@ -868,12 +1053,12 @@ e1000_open(struct net_device *netdev)
/* allocate transmit descriptors */
- if((err = e1000_setup_tx_resources(adapter)))
+ if ((err = e1000_setup_all_tx_resources(adapter)))
goto err_setup_tx;
/* allocate receive descriptors */
- if((err = e1000_setup_rx_resources(adapter)))
+ if ((err = e1000_setup_all_rx_resources(adapter)))
goto err_setup_rx;
if((err = e1000_up(adapter)))
@@ -887,9 +1072,9 @@ e1000_open(struct net_device *netdev)
return E1000_SUCCESS;
err_up:
- e1000_free_rx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
err_setup_rx:
- e1000_free_tx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
err_setup_tx:
e1000_reset(adapter);
@@ -915,8 +1100,8 @@ e1000_close(struct net_device *netdev)
e1000_down(adapter);
- e1000_free_tx_resources(adapter);
- e1000_free_rx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
@@ -951,14 +1136,15 @@ e1000_check_64k_bound(struct e1000_adapter *adapter,
/**
* e1000_setup_tx_resources - allocate Tx resources (Descriptors)
* @adapter: board private structure
+ * @txdr: tx descriptor ring (for a specific queue) to setup
*
* Return 0 on success, negative on failure
**/
int
-e1000_setup_tx_resources(struct e1000_adapter *adapter)
+e1000_setup_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *txdr)
{
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct pci_dev *pdev = adapter->pdev;
int size;
@@ -970,6 +1156,7 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter)
return -ENOMEM;
}
memset(txdr->buffer_info, 0, size);
+ memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
/* round up to nearest 4K */
@@ -1018,11 +1205,41 @@ setup_tx_desc_die:
txdr->next_to_use = 0;
txdr->next_to_clean = 0;
+ spin_lock_init(&txdr->tx_lock);
return 0;
}
/**
+ * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
+ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int
+e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_queues; i++) {
+ err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+ "Allocation for Tx Queue %u failed\n", i);
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
* e1000_configure_tx - Configure 8254x Transmit Unit after Reset
* @adapter: board private structure
*
@@ -1032,23 +1249,43 @@ setup_tx_desc_die:
static void
e1000_configure_tx(struct e1000_adapter *adapter)
{
- uint64_t tdba = adapter->tx_ring.dma;
- uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc);
- uint32_t tctl, tipg;
-
- E1000_WRITE_REG(&adapter->hw, TDBAL, (tdba & 0x00000000ffffffffULL));
- E1000_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
-
- E1000_WRITE_REG(&adapter->hw, TDLEN, tdlen);
+ uint64_t tdba;
+ struct e1000_hw *hw = &adapter->hw;
+ uint32_t tdlen, tctl, tipg, tarc;
/* Setup the HW Tx Head and Tail descriptor pointers */
- E1000_WRITE_REG(&adapter->hw, TDH, 0);
- E1000_WRITE_REG(&adapter->hw, TDT, 0);
+ switch (adapter->num_queues) {
+ case 2:
+ tdba = adapter->tx_ring[1].dma;
+ tdlen = adapter->tx_ring[1].count *
+ sizeof(struct e1000_tx_desc);
+ E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, TDBAH1, (tdba >> 32));
+ E1000_WRITE_REG(hw, TDLEN1, tdlen);
+ E1000_WRITE_REG(hw, TDH1, 0);
+ E1000_WRITE_REG(hw, TDT1, 0);
+ adapter->tx_ring[1].tdh = E1000_TDH1;
+ adapter->tx_ring[1].tdt = E1000_TDT1;
+ /* Fall Through */
+ case 1:
+ default:
+ tdba = adapter->tx_ring[0].dma;
+ tdlen = adapter->tx_ring[0].count *
+ sizeof(struct e1000_tx_desc);
+ E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
+ E1000_WRITE_REG(hw, TDLEN, tdlen);
+ E1000_WRITE_REG(hw, TDH, 0);
+ E1000_WRITE_REG(hw, TDT, 0);
+ adapter->tx_ring[0].tdh = E1000_TDH;
+ adapter->tx_ring[0].tdt = E1000_TDT;
+ break;
+ }
/* Set the default values for the Tx Inter Packet Gap timer */
- switch (adapter->hw.mac_type) {
+ switch (hw->mac_type) {
case e1000_82542_rev2_0:
case e1000_82542_rev2_1:
tipg = DEFAULT_82542_TIPG_IPGT;
@@ -1056,67 +1293,81 @@ e1000_configure_tx(struct e1000_adapter *adapter)
tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
break;
default:
- if(adapter->hw.media_type == e1000_media_type_fiber ||
- adapter->hw.media_type == e1000_media_type_internal_serdes)
+ if (hw->media_type == e1000_media_type_fiber ||
+ hw->media_type == e1000_media_type_internal_serdes)
tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
else
tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
}
- E1000_WRITE_REG(&adapter->hw, TIPG, tipg);
+ E1000_WRITE_REG(hw, TIPG, tipg);
/* Set the Tx Interrupt Delay register */
- E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
- if(adapter->hw.mac_type >= e1000_82540)
- E1000_WRITE_REG(&adapter->hw, TADV, adapter->tx_abs_int_delay);
+ E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
+ if (hw->mac_type >= e1000_82540)
+ E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
/* Program the Transmit Control Register */
- tctl = E1000_READ_REG(&adapter->hw, TCTL);
+ tctl = E1000_READ_REG(hw, TCTL);
tctl &= ~E1000_TCTL_CT;
- tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
+ tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC |
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
- E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+ E1000_WRITE_REG(hw, TCTL, tctl);
- e1000_config_collision_dist(&adapter->hw);
+ if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
+ tarc = E1000_READ_REG(hw, TARC0);
+ tarc |= ((1 << 25) | (1 << 21));
+ E1000_WRITE_REG(hw, TARC0, tarc);
+ tarc = E1000_READ_REG(hw, TARC1);
+ tarc |= (1 << 25);
+ if (tctl & E1000_TCTL_MULR)
+ tarc &= ~(1 << 28);
+ else
+ tarc |= (1 << 28);
+ E1000_WRITE_REG(hw, TARC1, tarc);
+ }
+
+ e1000_config_collision_dist(hw);
/* Setup Transmit Descriptor Settings for eop descriptor */
adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
E1000_TXD_CMD_IFCS;
- if(adapter->hw.mac_type < e1000_82543)
+ if (hw->mac_type < e1000_82543)
adapter->txd_cmd |= E1000_TXD_CMD_RPS;
else
adapter->txd_cmd |= E1000_TXD_CMD_RS;
/* Cache if we're 82544 running in PCI-X because we'll
* need this to apply a workaround later in the send path. */
- if(adapter->hw.mac_type == e1000_82544 &&
- adapter->hw.bus_type == e1000_bus_type_pcix)
+ if (hw->mac_type == e1000_82544 &&
+ hw->bus_type == e1000_bus_type_pcix)
adapter->pcix_82544 = 1;
}
/**
* e1000_setup_rx_resources - allocate Rx resources (Descriptors)
* @adapter: board private structure
+ * @rxdr: rx descriptor ring (for a specific queue) to setup
*
* Returns 0 on success, negative on failure
**/
int
-e1000_setup_rx_resources(struct e1000_adapter *adapter)
+e1000_setup_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rxdr)
{
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
int size, desc_len;
size = sizeof(struct e1000_buffer) * rxdr->count;
rxdr->buffer_info = vmalloc(size);
- if(!rxdr->buffer_info) {
+ if (!rxdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
@@ -1156,13 +1407,13 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter)
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
- if(!rxdr->desc) {
+ if (!rxdr->desc) {
+ DPRINTK(PROBE, ERR,
+ "Unable to allocate memory for the receive descriptor ring\n");
setup_rx_desc_die:
vfree(rxdr->buffer_info);
kfree(rxdr->ps_page);
kfree(rxdr->ps_page_dma);
- DPRINTK(PROBE, ERR,
- "Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
}
@@ -1174,9 +1425,12 @@ setup_rx_desc_die:
"at %p\n", rxdr->size, rxdr->desc);
/* Try again, without freeing the previous */
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
- if(!rxdr->desc) {
/* Failed allocation, critical failure */
+ if (!rxdr->desc) {
pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+ DPRINTK(PROBE, ERR,
+ "Unable to allocate memory "
+ "for the receive descriptor ring\n");
goto setup_rx_desc_die;
}
@@ -1188,10 +1442,7 @@ setup_rx_desc_die:
DPRINTK(PROBE, ERR,
"Unable to allocate aligned memory "
"for the receive descriptor ring\n");
- vfree(rxdr->buffer_info);
- kfree(rxdr->ps_page);
- kfree(rxdr->ps_page_dma);
- return -ENOMEM;
+ goto setup_rx_desc_die;
} else {
/* Free old allocation, new allocation was successful */
pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
@@ -1206,15 +1457,48 @@ setup_rx_desc_die:
}
/**
+ * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
+ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int
+e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_queues; i++) {
+ err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+ "Allocation for Rx Queue %u failed\n", i);
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
* e1000_setup_rctl - configure the receive control registers
* @adapter: Board private structure
**/
-
+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
static void
e1000_setup_rctl(struct e1000_adapter *adapter)
{
uint32_t rctl, rfctl;
uint32_t psrctl = 0;
+#ifdef CONFIG_E1000_PACKET_SPLIT
+ uint32_t pages = 0;
+#endif
rctl = E1000_READ_REG(&adapter->hw, RCTL);
@@ -1235,7 +1519,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
rctl |= E1000_RCTL_LPE;
/* Setup buffer sizes */
- if(adapter->hw.mac_type == e1000_82573) {
+ if(adapter->hw.mac_type >= e1000_82571) {
/* We can now specify buffers in 1K increments.
* BSIZE and BSEX are ignored in this case. */
rctl |= adapter->rx_buffer_len << 0x11;
@@ -1268,11 +1552,14 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
* followed by the page buffers. Therefore, skb->data is
* sized to hold the largest protocol header.
*/
- adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2)
- && (adapter->netdev->mtu
- < ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0));
+ pages = PAGE_USE_COUNT(adapter->netdev->mtu);
+ if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
+ PAGE_SIZE <= 16384)
+ adapter->rx_ps_pages = pages;
+ else
+ adapter->rx_ps_pages = 0;
#endif
- if(adapter->rx_ps) {
+ if (adapter->rx_ps_pages) {
/* Configure extra packet-split registers */
rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
rfctl |= E1000_RFCTL_EXTEN;
@@ -1284,12 +1571,19 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
psrctl |= adapter->rx_ps_bsize0 >>
E1000_PSRCTL_BSIZE0_SHIFT;
- psrctl |= PAGE_SIZE >>
- E1000_PSRCTL_BSIZE1_SHIFT;
- psrctl |= PAGE_SIZE <<
- E1000_PSRCTL_BSIZE2_SHIFT;
- psrctl |= PAGE_SIZE <<
- E1000_PSRCTL_BSIZE3_SHIFT;
+
+ switch (adapter->rx_ps_pages) {
+ case 3:
+ psrctl |= PAGE_SIZE <<
+ E1000_PSRCTL_BSIZE3_SHIFT;
+ case 2:
+ psrctl |= PAGE_SIZE <<
+ E1000_PSRCTL_BSIZE2_SHIFT;
+ case 1:
+ psrctl |= PAGE_SIZE >>
+ E1000_PSRCTL_BSIZE1_SHIFT;
+ break;
+ }
E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
}
@@ -1307,91 +1601,181 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
static void
e1000_configure_rx(struct e1000_adapter *adapter)
{
- uint64_t rdba = adapter->rx_ring.dma;
- uint32_t rdlen, rctl, rxcsum;
+ uint64_t rdba;
+ struct e1000_hw *hw = &adapter->hw;
+ uint32_t rdlen, rctl, rxcsum, ctrl_ext;
+#ifdef CONFIG_E1000_MQ
+ uint32_t reta, mrqc;
+ int i;
+#endif
- if(adapter->rx_ps) {
- rdlen = adapter->rx_ring.count *
+ if (adapter->rx_ps_pages) {
+ rdlen = adapter->rx_ring[0].count *
sizeof(union e1000_rx_desc_packet_split);
adapter->clean_rx = e1000_clean_rx_irq_ps;
adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
} else {
- rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
+ rdlen = adapter->rx_ring[0].count *
+ sizeof(struct e1000_rx_desc);
adapter->clean_rx = e1000_clean_rx_irq;
adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
}
/* disable receives while setting up the descriptors */
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
+ rctl = E1000_READ_REG(hw, RCTL);
+ E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
/* set the Receive Delay Timer Register */
- E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay);
+ E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
- if(adapter->hw.mac_type >= e1000_82540) {
- E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay);
+ if (hw->mac_type >= e1000_82540) {
+ E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
if(adapter->itr > 1)
- E1000_WRITE_REG(&adapter->hw, ITR,
+ E1000_WRITE_REG(hw, ITR,
1000000000 / (adapter->itr * 256));
}
- /* Setup the Base and Length of the Rx Descriptor Ring */
- E1000_WRITE_REG(&adapter->hw, RDBAL, (rdba & 0x00000000ffffffffULL));
- E1000_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
+ if (hw->mac_type >= e1000_82571) {
+ /* Reset delay timers after every interrupt */
+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_CANC;
+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ E1000_WRITE_FLUSH(hw);
+ }
+
+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring */
+ switch (adapter->num_queues) {
+#ifdef CONFIG_E1000_MQ
+ case 2:
+ rdba = adapter->rx_ring[1].dma;
+ E1000_WRITE_REG(hw, RDBAL1, (rdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, RDBAH1, (rdba >> 32));
+ E1000_WRITE_REG(hw, RDLEN1, rdlen);
+ E1000_WRITE_REG(hw, RDH1, 0);
+ E1000_WRITE_REG(hw, RDT1, 0);
+ adapter->rx_ring[1].rdh = E1000_RDH1;
+ adapter->rx_ring[1].rdt = E1000_RDT1;
+ /* Fall Through */
+#endif
+ case 1:
+ default:
+ rdba = adapter->rx_ring[0].dma;
+ E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
+ E1000_WRITE_REG(hw, RDLEN, rdlen);
+ E1000_WRITE_REG(hw, RDH, 0);
+ E1000_WRITE_REG(hw, RDT, 0);
+ adapter->rx_ring[0].rdh = E1000_RDH;
+ adapter->rx_ring[0].rdt = E1000_RDT;
+ break;
+ }
+
+#ifdef CONFIG_E1000_MQ
+ if (adapter->num_queues > 1) {
+ uint32_t random[10];
+
+ get_random_bytes(&random[0], 40);
+
+ if (hw->mac_type <= e1000_82572) {
+ E1000_WRITE_REG(hw, RSSIR, 0);
+ E1000_WRITE_REG(hw, RSSIM, 0);
+ }
+
+ switch (adapter->num_queues) {
+ case 2:
+ default:
+ reta = 0x00800080;
+ mrqc = E1000_MRQC_ENABLE_RSS_2Q;
+ break;
+ }
+
+ /* Fill out redirection table */
+ for (i = 0; i < 32; i++)
+ E1000_WRITE_REG_ARRAY(hw, RETA, i, reta);
+ /* Fill out hash function seeds */
+ for (i = 0; i < 10; i++)
+ E1000_WRITE_REG_ARRAY(hw, RSSRK, i, random[i]);
+
+ mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+ E1000_MRQC_RSS_FIELD_IPV4_TCP);
+ E1000_WRITE_REG(hw, MRQC, mrqc);
+ }
- E1000_WRITE_REG(&adapter->hw, RDLEN, rdlen);
+ /* Multiqueue and packet checksumming are mutually exclusive. */
+ if (hw->mac_type >= e1000_82571) {
+ rxcsum = E1000_READ_REG(hw, RXCSUM);
+ rxcsum |= E1000_RXCSUM_PCSD;
+ E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+ }
- /* Setup the HW Rx Head and Tail Descriptor Pointers */
- E1000_WRITE_REG(&adapter->hw, RDH, 0);
- E1000_WRITE_REG(&adapter->hw, RDT, 0);
+#else
/* Enable 82543 Receive Checksum Offload for TCP and UDP */
- if(adapter->hw.mac_type >= e1000_82543) {
- rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
+ if (hw->mac_type >= e1000_82543) {
+ rxcsum = E1000_READ_REG(hw, RXCSUM);
if(adapter->rx_csum == TRUE) {
rxcsum |= E1000_RXCSUM_TUOFL;
- /* Enable 82573 IPv4 payload checksum for UDP fragments
+ /* Enable 82571 IPv4 payload checksum for UDP fragments
* Must be used in conjunction with packet-split. */
- if((adapter->hw.mac_type > e1000_82547_rev_2) &&
- (adapter->rx_ps)) {
+ if ((hw->mac_type >= e1000_82571) &&
+ (adapter->rx_ps_pages)) {
rxcsum |= E1000_RXCSUM_IPPCSE;
}
} else {
rxcsum &= ~E1000_RXCSUM_TUOFL;
/* don't need to clear IPPCSE as it defaults to 0 */
}
- E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
+ E1000_WRITE_REG(hw, RXCSUM, rxcsum);
}
+#endif /* CONFIG_E1000_MQ */
- if (adapter->hw.mac_type == e1000_82573)
- E1000_WRITE_REG(&adapter->hw, ERT, 0x0100);
+ if (hw->mac_type == e1000_82573)
+ E1000_WRITE_REG(hw, ERT, 0x0100);
/* Enable Receives */
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+ E1000_WRITE_REG(hw, RCTL, rctl);
}
/**
- * e1000_free_tx_resources - Free Tx Resources
+ * e1000_free_tx_resources - Free Tx Resources per Queue
* @adapter: board private structure
+ * @tx_ring: Tx descriptor ring for a specific queue
*
* Free all transmit software resources
**/
void
-e1000_free_tx_resources(struct e1000_adapter *adapter)
+e1000_free_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
- e1000_clean_tx_ring(adapter);
+ e1000_clean_tx_ring(adapter, tx_ring);
+
+ vfree(tx_ring->buffer_info);
+ tx_ring->buffer_info = NULL;
- vfree(adapter->tx_ring.buffer_info);
- adapter->tx_ring.buffer_info = NULL;
+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+ tx_ring->desc = NULL;
+}
- pci_free_consistent(pdev, adapter->tx_ring.size,
- adapter->tx_ring.desc, adapter->tx_ring.dma);
+/**
+ * e1000_free_all_tx_resources - Free Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
+
+void
+e1000_free_all_tx_resources(struct e1000_adapter *adapter)
+{
+ int i;
- adapter->tx_ring.desc = NULL;
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
}
static inline void
@@ -1414,21 +1798,22 @@ e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
/**
* e1000_clean_tx_ring - Free Tx Buffers
* @adapter: board private structure
+ * @tx_ring: ring to be cleaned
**/
static void
-e1000_clean_tx_ring(struct e1000_adapter *adapter)
+e1000_clean_tx_ring(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_buffer *buffer_info;
unsigned long size;
unsigned int i;
/* Free all the Tx ring sk_buffs */
- if (likely(adapter->previous_buffer_info.skb != NULL)) {
+ if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
e1000_unmap_and_free_tx_resource(adapter,
- &adapter->previous_buffer_info);
+ &tx_ring->previous_buffer_info);
}
for(i = 0; i < tx_ring->count; i++) {
@@ -1446,24 +1831,39 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter)
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- E1000_WRITE_REG(&adapter->hw, TDH, 0);
- E1000_WRITE_REG(&adapter->hw, TDT, 0);
+ writel(0, adapter->hw.hw_addr + tx_ring->tdh);
+ writel(0, adapter->hw.hw_addr + tx_ring->tdt);
+}
+
+/**
+ * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
}
/**
* e1000_free_rx_resources - Free Rx Resources
* @adapter: board private structure
+ * @rx_ring: ring to clean the resources from
*
* Free all receive software resources
**/
void
-e1000_free_rx_resources(struct e1000_adapter *adapter)
+e1000_free_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
- e1000_clean_rx_ring(adapter);
+ e1000_clean_rx_ring(adapter, rx_ring);
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
@@ -1478,14 +1878,31 @@ e1000_free_rx_resources(struct e1000_adapter *adapter)
}
/**
- * e1000_clean_rx_ring - Free Rx Buffers
+ * e1000_free_all_rx_resources - Free Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+
+void
+e1000_free_all_rx_resources(struct e1000_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
+}
+
+/**
+ * e1000_clean_rx_ring - Free Rx Buffers per Queue
* @adapter: board private structure
+ * @rx_ring: ring to free buffers from
**/
static void
-e1000_clean_rx_ring(struct e1000_adapter *adapter)
+e1000_clean_rx_ring(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct e1000_buffer *buffer_info;
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
@@ -1508,7 +1925,7 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
dev_kfree_skb(buffer_info->skb);
buffer_info->skb = NULL;
- for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+ for(j = 0; j < adapter->rx_ps_pages; j++) {
if(!ps_page->ps_page[j]) break;
pci_unmap_single(pdev,
ps_page_dma->ps_page_dma[j],
@@ -1534,8 +1951,22 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
- E1000_WRITE_REG(&adapter->hw, RDH, 0);
- E1000_WRITE_REG(&adapter->hw, RDT, 0);
+ writel(0, adapter->hw.hw_addr + rx_ring->rdh);
+ writel(0, adapter->hw.hw_addr + rx_ring->rdt);
+}
+
+/**
+ * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
}
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
@@ -1556,7 +1987,7 @@ e1000_enter_82542_rst(struct e1000_adapter *adapter)
mdelay(5);
if(netif_running(netdev))
- e1000_clean_rx_ring(adapter);
+ e1000_clean_all_rx_rings(adapter);
}
static void
@@ -1576,7 +2007,7 @@ e1000_leave_82542_rst(struct e1000_adapter *adapter)
if(netif_running(netdev)) {
e1000_configure_rx(adapter);
- e1000_alloc_rx_buffers(adapter);
+ e1000_alloc_rx_buffers(adapter, &adapter->rx_ring[0]);
}
}
@@ -1607,6 +2038,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+ /* With 82571 controllers, LAA may be overwritten (with the default)
+ * due to controller reset from the other port. */
+ if (adapter->hw.mac_type == e1000_82571) {
+ /* activate the work around */
+ adapter->hw.laa_is_present = 1;
+
+ /* Hold a copy of the LAA in RAR[14] This is done so that
+ * between the time RAR[0] gets clobbered and the time it
+ * gets fixed (in e1000_watchdog), the actual LAA is in one
+ * of the RARs and no incoming packets directed to this port
+ * are dropped. Eventaully the LAA will be in RAR[0] and
+ * RAR[14] */
+ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
+ E1000_RAR_ENTRIES - 1);
+ }
+
if(adapter->hw.mac_type == e1000_82542_rev2_0)
e1000_leave_82542_rst(adapter);
@@ -1629,12 +2076,13 @@ e1000_set_multi(struct net_device *netdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr;
- unsigned long flags;
uint32_t rctl;
uint32_t hash_value;
- int i;
+ int i, rar_entries = E1000_RAR_ENTRIES;
- spin_lock_irqsave(&adapter->tx_lock, flags);
+ /* reserve RAR[14] for LAA over-write work-around */
+ if (adapter->hw.mac_type == e1000_82571)
+ rar_entries--;
/* Check for Promiscuous and All Multicast modes */
@@ -1659,11 +2107,12 @@ e1000_set_multi(struct net_device *netdev)
/* load the first 14 multicast address into the exact filters 1-14
* RAR 0 is used for the station MAC adddress
* if there are not 14 addresses, go ahead and clear the filters
+ * -- with 82571 controllers only 0-13 entries are filled here
*/
mc_ptr = netdev->mc_list;
- for(i = 1; i < E1000_RAR_ENTRIES; i++) {
- if(mc_ptr) {
+ for(i = 1; i < rar_entries; i++) {
+ if (mc_ptr) {
e1000_rar_set(hw, mc_ptr->dmi_addr, i);
mc_ptr = mc_ptr->next;
} else {
@@ -1686,8 +2135,6 @@ e1000_set_multi(struct net_device *netdev)
if(hw->mac_type == e1000_82542_rev2_0)
e1000_leave_82542_rst(adapter);
-
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
}
/* Need to wait a few seconds after link up to get diagnostic information from
@@ -1759,7 +2206,7 @@ static void
e1000_watchdog_task(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
+ struct e1000_tx_ring *txdr = &adapter->tx_ring[0];
uint32_t link;
e1000_check_for_link(&adapter->hw);
@@ -1818,8 +2265,8 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
e1000_update_adaptive(&adapter->hw);
- if(!netif_carrier_ok(netdev)) {
- if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
+ if (adapter->num_queues == 1 && !netif_carrier_ok(netdev)) {
+ if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
@@ -1847,6 +2294,11 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
/* Force detection of hung controller every watchdog period */
adapter->detect_tx_hung = TRUE;
+ /* With 82571 controllers, LAA may be overwritten due to controller
+ * reset from the other port. Set the appropriate LAA in RAR[0] */
+ if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
+ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+
/* Reset the timer */
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}
@@ -1859,7 +2311,8 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
#define E1000_TX_FLAGS_VLAN_SHIFT 16
static inline int
-e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
+e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ struct sk_buff *skb)
{
#ifdef NETIF_F_TSO
struct e1000_context_desc *context_desc;
@@ -1910,8 +2363,8 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
- i = adapter->tx_ring.next_to_use;
- context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
+ i = tx_ring->next_to_use;
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
context_desc->lower_setup.ip_fields.ipcss = ipcss;
context_desc->lower_setup.ip_fields.ipcso = ipcso;
@@ -1923,8 +2376,8 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
context_desc->cmd_and_length = cpu_to_le32(cmd_length);
- if(++i == adapter->tx_ring.count) i = 0;
- adapter->tx_ring.next_to_use = i;
+ if (++i == tx_ring->count) i = 0;
+ tx_ring->next_to_use = i;
return 1;
}
@@ -1934,7 +2387,8 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
}
static inline boolean_t
-e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
+e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ struct sk_buff *skb)
{
struct e1000_context_desc *context_desc;
unsigned int i;
@@ -1943,8 +2397,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
if(likely(skb->ip_summed == CHECKSUM_HW)) {
css = skb->h.raw - skb->data;
- i = adapter->tx_ring.next_to_use;
- context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
+ i = tx_ring->next_to_use;
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
context_desc->upper_setup.tcp_fields.tucss = css;
context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
@@ -1952,8 +2406,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
context_desc->tcp_seg_setup.data = 0;
context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
- if(unlikely(++i == adapter->tx_ring.count)) i = 0;
- adapter->tx_ring.next_to_use = i;
+ if (unlikely(++i == tx_ring->count)) i = 0;
+ tx_ring->next_to_use = i;
return TRUE;
}
@@ -1965,11 +2419,10 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
#define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
static inline int
-e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
- unsigned int first, unsigned int max_per_txd,
- unsigned int nr_frags, unsigned int mss)
+e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
+ unsigned int nr_frags, unsigned int mss)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_buffer *buffer_info;
unsigned int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
@@ -2065,9 +2518,9 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
}
static inline void
-e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
+e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ int tx_flags, int count)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_tx_desc *tx_desc = NULL;
struct e1000_buffer *buffer_info;
uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
@@ -2113,7 +2566,7 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
wmb();
tx_ring->next_to_use = i;
- E1000_WRITE_REG(&adapter->hw, TDT, i);
+ writel(i, adapter->hw.hw_addr + tx_ring->tdt);
}
/**
@@ -2206,6 +2659,7 @@ static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_tx_ring *tx_ring;
unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
@@ -2218,7 +2672,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int f;
len -= skb->data_len;
- if(unlikely(skb->len <= 0)) {
+#ifdef CONFIG_E1000_MQ
+ tx_ring = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id());
+#else
+ tx_ring = adapter->tx_ring;
+#endif
+
+ if (unlikely(skb->len <= 0)) {
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2262,21 +2722,42 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if(adapter->pcix_82544)
count += nr_frags;
- local_irq_save(flags);
- if (!spin_trylock(&adapter->tx_lock)) {
- /* Collision - tell upper layer to requeue */
- local_irq_restore(flags);
- return NETDEV_TX_LOCKED;
- }
+#ifdef NETIF_F_TSO
+ /* TSO Workaround for 82571/2 Controllers -- if skb->data
+ * points to just header, pull a few bytes of payload from
+ * frags into skb->data */
+ if (skb_shinfo(skb)->tso_size) {
+ uint8_t hdr_len;
+ hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+ if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) &&
+ (adapter->hw.mac_type == e1000_82571 ||
+ adapter->hw.mac_type == e1000_82572)) {
+ unsigned int pull_size;
+ pull_size = min((unsigned int)4, skb->data_len);
+ if (!__pskb_pull_tail(skb, pull_size)) {
+ printk(KERN_ERR "__pskb_pull_tail failed.\n");
+ dev_kfree_skb_any(skb);
+ return -EFAULT;
+ }
+ }
+ }
+#endif
+
if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
e1000_transfer_dhcp_info(adapter, skb);
+ local_irq_save(flags);
+ if (!spin_trylock(&tx_ring->tx_lock)) {
+ /* Collision - tell upper layer to requeue */
+ local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+ }
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
- if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2)) {
+ if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -2284,7 +2765,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if(unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
}
@@ -2294,37 +2775,37 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
}
- first = adapter->tx_ring.next_to_use;
+ first = tx_ring->next_to_use;
- tso = e1000_tso(adapter, skb);
+ tso = e1000_tso(adapter, tx_ring, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
if (likely(tso))
tx_flags |= E1000_TX_FLAGS_TSO;
- else if(likely(e1000_tx_csum(adapter, skb)))
+ else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
tx_flags |= E1000_TX_FLAGS_CSUM;
/* Old method was to assume IPv4 packet by default if TSO was enabled.
- * 82573 hardware supports TSO capabilities for IPv6 as well...
+ * 82571 hardware supports TSO capabilities for IPv6 as well...
* no longer assume, we must. */
- if(likely(skb->protocol == ntohs(ETH_P_IP)))
+ if (likely(skb->protocol == ntohs(ETH_P_IP)))
tx_flags |= E1000_TX_FLAGS_IPV4;
- e1000_tx_queue(adapter,
- e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
- tx_flags);
+ e1000_tx_queue(adapter, tx_ring, tx_flags,
+ e1000_tx_map(adapter, tx_ring, skb, first,
+ max_per_txd, nr_frags, mss));
netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
- if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < MAX_SKB_FRAGS + 2))
+ if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -2388,9 +2869,18 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
-#define MAX_STD_JUMBO_FRAME_SIZE 9216
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
/* might want this to be bigger enum check... */
- if (adapter->hw.mac_type == e1000_82573 &&
+ /* 82571 controllers limit jumbo frame size to 10500 bytes */
+ if ((adapter->hw.mac_type == e1000_82571 ||
+ adapter->hw.mac_type == e1000_82572) &&
+ max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+ DPRINTK(PROBE, ERR, "MTU > 9216 bytes not supported "
+ "on 82571 and 82572 controllers.\n");
+ return -EINVAL;
+ }
+
+ if(adapter->hw.mac_type == e1000_82573 &&
max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
"on 82573\n");
@@ -2544,7 +3034,6 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter->stats.crcerrs + adapter->stats.algnerrc +
adapter->stats.rlec + adapter->stats.mpc +
adapter->stats.cexterr;
- adapter->net_stats.rx_dropped = adapter->stats.mpc;
adapter->net_stats.rx_length_errors = adapter->stats.rlec;
adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
@@ -2579,6 +3068,29 @@ e1000_update_stats(struct e1000_adapter *adapter)
spin_unlock_irqrestore(&adapter->stats_lock, flags);
}
+#ifdef CONFIG_E1000_MQ
+void
+e1000_rx_schedule(void *data)
+{
+ struct net_device *poll_dev, *netdev = data;
+ struct e1000_adapter *adapter = netdev->priv;
+ int this_cpu = get_cpu();
+
+ poll_dev = *per_cpu_ptr(adapter->cpu_netdev, this_cpu);
+ if (poll_dev == NULL) {
+ put_cpu();
+ return;
+ }
+
+ if (likely(netif_rx_schedule_prep(poll_dev)))
+ __netif_rx_schedule(poll_dev);
+ else
+ e1000_irq_enable(adapter);
+
+ put_cpu();
+}
+#endif
+
/**
* e1000_intr - Interrupt Handler
* @irq: interrupt number
@@ -2593,8 +3105,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
uint32_t icr = E1000_READ_REG(hw, ICR);
-#ifndef CONFIG_E1000_NAPI
- unsigned int i;
+#if defined(CONFIG_E1000_NAPI) && defined(CONFIG_E1000_MQ) || !defined(CONFIG_E1000_NAPI)
+ int i;
#endif
if(unlikely(!icr))
@@ -2606,17 +3118,31 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
}
#ifdef CONFIG_E1000_NAPI
- if(likely(netif_rx_schedule_prep(netdev))) {
-
- /* Disable interrupts and register for poll. The flush
- of the posted write is intentionally left out.
- */
-
- atomic_inc(&adapter->irq_sem);
- E1000_WRITE_REG(hw, IMC, ~0);
- __netif_rx_schedule(netdev);
+ atomic_inc(&adapter->irq_sem);
+ E1000_WRITE_REG(hw, IMC, ~0);
+ E1000_WRITE_FLUSH(hw);
+#ifdef CONFIG_E1000_MQ
+ if (atomic_read(&adapter->rx_sched_call_data.count) == 0) {
+ cpu_set(adapter->cpu_for_queue[0],
+ adapter->rx_sched_call_data.cpumask);
+ for (i = 1; i < adapter->num_queues; i++) {
+ cpu_set(adapter->cpu_for_queue[i],
+ adapter->rx_sched_call_data.cpumask);
+ atomic_inc(&adapter->irq_sem);
+ }
+ atomic_set(&adapter->rx_sched_call_data.count, i);
+ smp_call_async_mask(&adapter->rx_sched_call_data);
+ } else {
+ printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count));
}
-#else
+#else /* if !CONFIG_E1000_MQ */
+ if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
+ __netif_rx_schedule(&adapter->polling_netdev[0]);
+ else
+ e1000_irq_enable(adapter);
+#endif /* CONFIG_E1000_MQ */
+
+#else /* if !CONFIG_E1000_NAPI */
/* Writing IMC and IMS is needed for 82547.
Due to Hub Link bus being occupied, an interrupt
de-assertion message is not able to be sent.
@@ -2633,13 +3159,14 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
}
for(i = 0; i < E1000_MAX_INTR; i++)
- if(unlikely(!adapter->clean_rx(adapter) &
- !e1000_clean_tx_irq(adapter)))
+ if(unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+ !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
break;
if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
e1000_irq_enable(adapter);
-#endif
+
+#endif /* CONFIG_E1000_NAPI */
return IRQ_HANDLED;
}
@@ -2651,22 +3178,37 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
**/
static int
-e1000_clean(struct net_device *netdev, int *budget)
+e1000_clean(struct net_device *poll_dev, int *budget)
{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- int work_to_do = min(*budget, netdev->quota);
- int tx_cleaned;
- int work_done = 0;
+ struct e1000_adapter *adapter;
+ int work_to_do = min(*budget, poll_dev->quota);
+ int tx_cleaned, i = 0, work_done = 0;
- tx_cleaned = e1000_clean_tx_irq(adapter);
- adapter->clean_rx(adapter, &work_done, work_to_do);
+ /* Must NOT use netdev_priv macro here. */
+ adapter = poll_dev->priv;
+
+ /* Keep link state information with original netdev */
+ if (!netif_carrier_ok(adapter->netdev))
+ goto quit_polling;
+
+ while (poll_dev != &adapter->polling_netdev[i]) {
+ i++;
+ if (unlikely(i == adapter->num_queues))
+ BUG();
+ }
+
+ tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+ adapter->clean_rx(adapter, &adapter->rx_ring[i],
+ &work_done, work_to_do);
*budget -= work_done;
- netdev->quota -= work_done;
+ poll_dev->quota -= work_done;
- if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
/* If no Tx and not enough Rx work done, exit the polling mode */
- netif_rx_complete(netdev);
+ if((!tx_cleaned && (work_done == 0)) ||
+ !netif_running(adapter->netdev)) {
+quit_polling:
+ netif_rx_complete(poll_dev);
e1000_irq_enable(adapter);
return 0;
}
@@ -2681,9 +3223,9 @@ e1000_clean(struct net_device *netdev, int *budget)
**/
static boolean_t
-e1000_clean_tx_irq(struct e1000_adapter *adapter)
+e1000_clean_tx_irq(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct net_device *netdev = adapter->netdev;
struct e1000_tx_desc *tx_desc, *eop_desc;
struct e1000_buffer *buffer_info;
@@ -2694,12 +3236,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
- while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+ while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
/* Premature writeback of Tx descriptors clear (free buffers
* and unmap pci_mapping) previous_buffer_info */
- if (likely(adapter->previous_buffer_info.skb != NULL)) {
+ if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
e1000_unmap_and_free_tx_resource(adapter,
- &adapter->previous_buffer_info);
+ &tx_ring->previous_buffer_info);
}
for(cleaned = FALSE; !cleaned; ) {
@@ -2715,7 +3257,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
#ifdef NETIF_F_TSO
} else {
if (cleaned) {
- memcpy(&adapter->previous_buffer_info,
+ memcpy(&tx_ring->previous_buffer_info,
buffer_info,
sizeof(struct e1000_buffer));
memset(buffer_info, 0,
@@ -2733,6 +3275,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
if(unlikely(++i == tx_ring->count)) i = 0;
}
+
+ tx_ring->pkt++;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -2740,15 +3284,15 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring->next_to_clean = i;
- spin_lock(&adapter->tx_lock);
+ spin_lock(&tx_ring->tx_lock);
if(unlikely(cleaned && netif_queue_stopped(netdev) &&
netif_carrier_ok(netdev)))
netif_wake_queue(netdev);
- spin_unlock(&adapter->tx_lock);
- if(adapter->detect_tx_hung) {
+ spin_unlock(&tx_ring->tx_lock);
+ if (adapter->detect_tx_hung) {
/* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = FALSE;
@@ -2772,8 +3316,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
" next_to_watch <%x>\n"
" jiffies <%lx>\n"
" next_to_watch.status <%x>\n",
- E1000_READ_REG(&adapter->hw, TDH),
- E1000_READ_REG(&adapter->hw, TDT),
+ readl(adapter->hw.hw_addr + tx_ring->tdh),
+ readl(adapter->hw.hw_addr + tx_ring->tdt),
tx_ring->next_to_use,
i,
(unsigned long long)tx_ring->buffer_info[i].dma,
@@ -2785,12 +3329,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
}
}
#ifdef NETIF_F_TSO
-
- if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
- time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ)))
+ if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
e1000_unmap_and_free_tx_resource(
- adapter, &adapter->previous_buffer_info);
-
+ adapter, &tx_ring->previous_buffer_info);
#endif
return cleaned;
}
@@ -2853,13 +3395,14 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
static boolean_t
#ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done,
- int work_to_do)
+e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
#else
-e1000_clean_rx_irq(struct e1000_adapter *adapter)
+e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
#endif
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct e1000_rx_desc *rx_desc;
@@ -2945,6 +3488,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
}
#endif /* CONFIG_E1000_NAPI */
netdev->last_rx = jiffies;
+ rx_ring->pkt++;
next_desc:
rx_desc->status = 0;
@@ -2954,7 +3498,7 @@ next_desc:
rx_desc = E1000_RX_DESC(*rx_ring, i);
}
rx_ring->next_to_clean = i;
- adapter->alloc_rx_buf(adapter);
+ adapter->alloc_rx_buf(adapter, rx_ring);
return cleaned;
}
@@ -2966,13 +3510,14 @@ next_desc:
static boolean_t
#ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done,
- int work_to_do)
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
#else
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
#endif
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
union e1000_rx_desc_packet_split *rx_desc;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
@@ -3028,7 +3573,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
/* Good Receive */
skb_put(skb, length);
- for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+ for(j = 0; j < adapter->rx_ps_pages; j++) {
if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
break;
@@ -3049,11 +3594,13 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
skb->protocol = eth_type_trans(skb, netdev);
-#ifdef HAVE_RX_ZERO_COPY
if(likely(rx_desc->wb.upper.header_status &
- E1000_RXDPS_HDRSTAT_HDRSP))
+ E1000_RXDPS_HDRSTAT_HDRSP)) {
+ adapter->rx_hdr_split++;
+#ifdef HAVE_RX_ZERO_COPY
skb_shinfo(skb)->zero_copy = TRUE;
#endif
+ }
#ifdef CONFIG_E1000_NAPI
if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
@@ -3072,6 +3619,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
}
#endif /* CONFIG_E1000_NAPI */
netdev->last_rx = jiffies;
+ rx_ring->pkt++;
next_desc:
rx_desc->wb.middle.status_error &= ~0xFF;
@@ -3082,7 +3630,7 @@ next_desc:
staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
}
rx_ring->next_to_clean = i;
- adapter->alloc_rx_buf(adapter);
+ adapter->alloc_rx_buf(adapter, rx_ring);
return cleaned;
}
@@ -3093,9 +3641,9 @@ next_desc:
**/
static void
-e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
+e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct e1000_rx_desc *rx_desc;
@@ -3179,7 +3727,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
* applicable for weak-ordered memory model archs,
* such as IA-64). */
wmb();
- E1000_WRITE_REG(&adapter->hw, RDT, i);
+ writel(i, adapter->hw.hw_addr + rx_ring->rdt);
}
if(unlikely(++i == rx_ring->count)) i = 0;
@@ -3195,9 +3743,9 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
**/
static void
-e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
+e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_rx_desc_packet_split *rx_desc;
@@ -3216,22 +3764,26 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
for(j = 0; j < PS_PAGE_BUFFERS; j++) {
- if(unlikely(!ps_page->ps_page[j])) {
- ps_page->ps_page[j] =
- alloc_page(GFP_ATOMIC);
- if(unlikely(!ps_page->ps_page[j]))
- goto no_buffers;
- ps_page_dma->ps_page_dma[j] =
- pci_map_page(pdev,
- ps_page->ps_page[j],
- 0, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- }
- /* Refresh the desc even if buffer_addrs didn't
- * change because each write-back erases this info.
- */
- rx_desc->read.buffer_addr[j+1] =
- cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+ if (j < adapter->rx_ps_pages) {
+ if (likely(!ps_page->ps_page[j])) {
+ ps_page->ps_page[j] =
+ alloc_page(GFP_ATOMIC);
+ if (unlikely(!ps_page->ps_page[j]))
+ goto no_buffers;
+ ps_page_dma->ps_page_dma[j] =
+ pci_map_page(pdev,
+ ps_page->ps_page[j],
+ 0, PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ }
+ /* Refresh the desc even if buffer_addrs didn't
+ * change because each write-back erases
+ * this info.
+ */
+ rx_desc->read.buffer_addr[j+1] =
+ cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+ } else
+ rx_desc->read.buffer_addr[j+1] = ~0;
}
skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
@@ -3265,7 +3817,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
* descriptors are 32 bytes...so we increment tail
* twice as much.
*/
- E1000_WRITE_REG(&adapter->hw, RDT, i<<1);
+ writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
}
if(unlikely(++i == rx_ring->count)) i = 0;
@@ -3716,6 +4268,12 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
}
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -3738,6 +4296,7 @@ e1000_resume(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t manc, ret_val, swsm;
+ uint32_t ctrl_ext;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
@@ -3763,6 +4322,12 @@ e1000_resume(struct pci_dev *pdev)
}
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -3787,7 +4352,7 @@ e1000_netpoll(struct net_device *netdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
disable_irq(adapter->pdev->irq);
e1000_intr(adapter->pdev->irq, netdev, NULL);
- e1000_clean_tx_irq(adapter);
+ e1000_clean_tx_irq(adapter, adapter->tx_ring);
enable_irq(adapter->pdev->irq);
}
#endif
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 676247f9f1cc..38695d5b4637 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -306,7 +306,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = E1000_DEFAULT_TXD,
.arg = { .r = { .min = E1000_MIN_TXD }}
};
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+ int i;
e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ?
E1000_MAX_TXD : E1000_MAX_82544_TXD;
@@ -319,6 +320,8 @@ e1000_check_options(struct e1000_adapter *adapter)
} else {
tx_ring->count = opt.def;
}
+ for (i = 0; i < adapter->num_queues; i++)
+ tx_ring[i].count = tx_ring->count;
}
{ /* Receive Descriptor Count */
struct e1000_option opt = {
@@ -329,7 +332,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = E1000_DEFAULT_RXD,
.arg = { .r = { .min = E1000_MIN_RXD }}
};
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ struct e1000_rx_ring *rx_ring = adapter->rx_ring;
+ int i;
e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
@@ -342,6 +346,8 @@ e1000_check_options(struct e1000_adapter *adapter)
} else {
rx_ring->count = opt.def;
}
+ for (i = 0; i < adapter->num_queues; i++)
+ rx_ring[i].count = rx_ring->count;
}
{ /* Checksum Offload Enable/Disable */
struct e1000_option opt = {
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 87f522738bfc..f119ec4e89ea 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1334,7 +1334,7 @@ static void epic_rx_err(struct net_device *dev, struct epic_private *ep)
static int epic_poll(struct net_device *dev, int *budget)
{
struct epic_private *ep = dev->priv;
- int work_done, orig_budget;
+ int work_done = 0, orig_budget;
long ioaddr = dev->base_addr;
orig_budget = (*budget > dev->quota) ? dev->quota : *budget;
@@ -1343,7 +1343,7 @@ rx_action:
epic_tx(dev, ep);
- work_done = epic_rx(dev, *budget);
+ work_done += epic_rx(dev, *budget);
epic_rx_err(dev, ep);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 2c7008491378..85504fb900da 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -8,7 +8,7 @@
* describes connections using the internal parallel port I/O, which
* is basically all of Port D.
*
- * Right now, I am very watseful with the buffers. I allocate memory
+ * Right now, I am very wasteful with the buffers. I allocate memory
* pages and then divide them into 2K frame buffers. This way I know I
* have buffers large enough to hold one frame within one buffer descriptor.
* Once I get this working, I will use 64 or 128 byte CPM buffers, which
@@ -19,7 +19,10 @@
* Copyright (c) 2000 Ericsson Radio Systems AB.
*
* Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282.
- * Copyrught (c) 2001-2004 Greg Ungerer (gerg@snapgear.com)
+ * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com)
+ *
+ * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
+ * Copyright (c) 2004-2005 Macq Electronique SA.
*/
#include <linux/config.h>
@@ -46,7 +49,8 @@
#include <asm/io.h>
#include <asm/pgtable.h>
-#if defined(CONFIG_M527x) || defined(CONFIG_M5272) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
+ defined(CONFIG_M5272) || defined(CONFIG_M528x)
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include "fec.h"
@@ -71,7 +75,7 @@ static unsigned int fec_hw[] = {
#elif defined(CONFIG_M527x)
(MCF_MBAR + 0x1000),
(MCF_MBAR + 0x1800),
-#elif defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
(MCF_MBAR + 0x1000),
#else
&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
@@ -94,12 +98,14 @@ static unsigned char fec_mac_default[] = {
#define FEC_FLASHMAC 0xffe04000
#elif defined(CONFIG_CANCam)
#define FEC_FLASHMAC 0xf0020000
+#elif defined (CONFIG_M5272C3)
+#define FEC_FLASHMAC (0xffe04000 + 4)
+#elif defined(CONFIG_MOD5272)
+#define FEC_FLASHMAC 0xffc0406b
#else
#define FEC_FLASHMAC 0
#endif
-unsigned char *fec_flashmac = (unsigned char *) FEC_FLASHMAC;
-
/* Forward declarations of some structures to support different PHYs
*/
@@ -158,7 +164,7 @@ typedef struct {
* size bits. Other FEC hardware does not, so we need to take that into
* account when setting it.
*/
-#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -196,7 +202,7 @@ struct fec_enet_private {
uint phy_id_done;
uint phy_status;
uint phy_speed;
- phy_info_t *phy;
+ phy_info_t const *phy;
struct work_struct phy_task;
uint sequence_done;
@@ -209,7 +215,6 @@ struct fec_enet_private {
int link;
int old_link;
int full_duplex;
- unsigned char mac_addr[ETH_ALEN];
};
static int fec_enet_open(struct net_device *dev);
@@ -237,10 +242,10 @@ typedef struct mii_list {
} mii_list_t;
#define NMII 20
-mii_list_t mii_cmds[NMII];
-mii_list_t *mii_free;
-mii_list_t *mii_head;
-mii_list_t *mii_tail;
+static mii_list_t mii_cmds[NMII];
+static mii_list_t *mii_free;
+static mii_list_t *mii_head;
+static mii_list_t *mii_tail;
static int mii_queue(struct net_device *dev, int request,
void (*func)(uint, struct net_device *));
@@ -425,7 +430,7 @@ fec_timeout(struct net_device *dev)
}
}
#endif
- fec_restart(dev, 0);
+ fec_restart(dev, fep->full_duplex);
netif_wake_queue(dev);
}
@@ -757,45 +762,52 @@ static void mii_parse_sr(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
+ status = *s & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
if (mii_reg & 0x0004)
- *s |= PHY_STAT_LINK;
+ status |= PHY_STAT_LINK;
if (mii_reg & 0x0010)
- *s |= PHY_STAT_FAULT;
+ status |= PHY_STAT_FAULT;
if (mii_reg & 0x0020)
- *s |= PHY_STAT_ANC;
+ status |= PHY_STAT_ANC;
+
+ *s = status;
}
static void mii_parse_cr(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP);
+ status = *s & ~(PHY_CONF_ANE | PHY_CONF_LOOP);
if (mii_reg & 0x1000)
- *s |= PHY_CONF_ANE;
+ status |= PHY_CONF_ANE;
if (mii_reg & 0x4000)
- *s |= PHY_CONF_LOOP;
+ status |= PHY_CONF_LOOP;
+ *s = status;
}
static void mii_parse_anar(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_CONF_SPMASK);
+ status = *s & ~(PHY_CONF_SPMASK);
if (mii_reg & 0x0020)
- *s |= PHY_CONF_10HDX;
+ status |= PHY_CONF_10HDX;
if (mii_reg & 0x0040)
- *s |= PHY_CONF_10FDX;
+ status |= PHY_CONF_10FDX;
if (mii_reg & 0x0080)
- *s |= PHY_CONF_100HDX;
+ status |= PHY_CONF_100HDX;
if (mii_reg & 0x00100)
- *s |= PHY_CONF_100FDX;
+ status |= PHY_CONF_100FDX;
+ *s = status;
}
/* ------------------------------------------------------------------------- */
@@ -811,37 +823,34 @@ static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_STAT_SPMASK);
-
+ status = *s & ~(PHY_STAT_SPMASK);
if (mii_reg & 0x0800) {
if (mii_reg & 0x1000)
- *s |= PHY_STAT_100FDX;
+ status |= PHY_STAT_100FDX;
else
- *s |= PHY_STAT_100HDX;
+ status |= PHY_STAT_100HDX;
} else {
if (mii_reg & 0x1000)
- *s |= PHY_STAT_10FDX;
+ status |= PHY_STAT_10FDX;
else
- *s |= PHY_STAT_10HDX;
+ status |= PHY_STAT_10HDX;
}
+ *s = status;
}
-static phy_info_t phy_info_lxt970 = {
- 0x07810000,
- "LXT970",
-
- (const phy_cmd_t []) { /* config */
+static phy_cmd_t const phy_cmd_lxt970_config[] = {
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* startup - enable interrupts */
+ };
+static phy_cmd_t const phy_cmd_lxt970_startup[] = { /* enable interrupts */
{ mk_mii_write(MII_LXT970_IER, 0x0002), NULL },
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* ack_int */
+ };
+static phy_cmd_t const phy_cmd_lxt970_ack_int[] = {
/* read SR and ISR to acknowledge */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_read(MII_LXT970_ISR), NULL },
@@ -849,11 +858,18 @@ static phy_info_t phy_info_lxt970 = {
/* find out the current status */
{ mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* shutdown - disable interrupts */
+ };
+static phy_cmd_t const phy_cmd_lxt970_shutdown[] = { /* disable interrupts */
{ mk_mii_write(MII_LXT970_IER, 0x0000), NULL },
{ mk_mii_end, }
- },
+ };
+static phy_info_t const phy_info_lxt970 = {
+ .id = 0x07810000,
+ .name = "LXT970",
+ .config = phy_cmd_lxt970_config,
+ .startup = phy_cmd_lxt970_startup,
+ .ack_int = phy_cmd_lxt970_ack_int,
+ .shutdown = phy_cmd_lxt970_shutdown
};
/* ------------------------------------------------------------------------- */
@@ -878,45 +894,44 @@ static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+ status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
if (mii_reg & 0x0400) {
fep->link = 1;
- *s |= PHY_STAT_LINK;
+ status |= PHY_STAT_LINK;
} else {
fep->link = 0;
}
if (mii_reg & 0x0080)
- *s |= PHY_STAT_ANC;
+ status |= PHY_STAT_ANC;
if (mii_reg & 0x4000) {
if (mii_reg & 0x0200)
- *s |= PHY_STAT_100FDX;
+ status |= PHY_STAT_100FDX;
else
- *s |= PHY_STAT_100HDX;
+ status |= PHY_STAT_100HDX;
} else {
if (mii_reg & 0x0200)
- *s |= PHY_STAT_10FDX;
+ status |= PHY_STAT_10FDX;
else
- *s |= PHY_STAT_10HDX;
+ status |= PHY_STAT_10HDX;
}
if (mii_reg & 0x0008)
- *s |= PHY_STAT_FAULT;
-}
+ status |= PHY_STAT_FAULT;
-static phy_info_t phy_info_lxt971 = {
- 0x0001378e,
- "LXT971",
+ *s = status;
+}
- (const phy_cmd_t []) { /* config */
- /* limit to 10MBit because my protorype board
+static phy_cmd_t const phy_cmd_lxt971_config[] = {
+ /* limit to 10MBit because my prototype board
* doesn't work with 100. */
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* startup - enable interrupts */
+ };
+static phy_cmd_t const phy_cmd_lxt971_startup[] = { /* enable interrupts */
{ mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
{ mk_mii_write(MII_LXT971_LCR, 0xd422), NULL }, /* LED config */
@@ -925,19 +940,26 @@ static phy_info_t phy_info_lxt971 = {
* read here to get a valid value in ack_int */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* ack_int */
+ };
+static phy_cmd_t const phy_cmd_lxt971_ack_int[] = {
+ /* acknowledge the int before reading status ! */
+ { mk_mii_read(MII_LXT971_ISR), NULL },
/* find out the current status */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
- /* we only need to read ISR to acknowledge */
- { mk_mii_read(MII_LXT971_ISR), NULL },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* shutdown - disable interrupts */
+ };
+static phy_cmd_t const phy_cmd_lxt971_shutdown[] = { /* disable interrupts */
{ mk_mii_write(MII_LXT971_IER, 0x0000), NULL },
{ mk_mii_end, }
- },
+ };
+static phy_info_t const phy_info_lxt971 = {
+ .id = 0x0001378e,
+ .name = "LXT971",
+ .config = phy_cmd_lxt971_config,
+ .startup = phy_cmd_lxt971_startup,
+ .ack_int = phy_cmd_lxt971_ack_int,
+ .shutdown = phy_cmd_lxt971_shutdown
};
/* ------------------------------------------------------------------------- */
@@ -956,22 +978,21 @@ static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_STAT_SPMASK);
+ status = *s & ~(PHY_STAT_SPMASK);
switch((mii_reg >> 2) & 7) {
- case 1: *s |= PHY_STAT_10HDX; break;
- case 2: *s |= PHY_STAT_100HDX; break;
- case 5: *s |= PHY_STAT_10FDX; break;
- case 6: *s |= PHY_STAT_100FDX; break;
- }
+ case 1: status |= PHY_STAT_10HDX; break;
+ case 2: status |= PHY_STAT_100HDX; break;
+ case 5: status |= PHY_STAT_10FDX; break;
+ case 6: status |= PHY_STAT_100FDX; break;
}
-static phy_info_t phy_info_qs6612 = {
- 0x00181440,
- "QS6612",
-
- (const phy_cmd_t []) { /* config */
+ *s = status;
+}
+
+static phy_cmd_t const phy_cmd_qs6612_config[] = {
/* The PHY powers up isolated on the RPX,
* so send a command to allow operation.
*/
@@ -981,13 +1002,13 @@ static phy_info_t phy_info_qs6612 = {
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* startup - enable interrupts */
+ };
+static phy_cmd_t const phy_cmd_qs6612_startup[] = { /* enable interrupts */
{ mk_mii_write(MII_QS6612_IMR, 0x003a), NULL },
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* ack_int */
+ };
+static phy_cmd_t const phy_cmd_qs6612_ack_int[] = {
/* we need to read ISR, SR and ANER to acknowledge */
{ mk_mii_read(MII_QS6612_ISR), NULL },
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
@@ -996,11 +1017,18 @@ static phy_info_t phy_info_qs6612 = {
/* read pcr to get info */
{ mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* shutdown - disable interrupts */
+ };
+static phy_cmd_t const phy_cmd_qs6612_shutdown[] = { /* disable interrupts */
{ mk_mii_write(MII_QS6612_IMR, 0x0000), NULL },
{ mk_mii_end, }
- },
+ };
+static phy_info_t const phy_info_qs6612 = {
+ .id = 0x00181440,
+ .name = "QS6612",
+ .config = phy_cmd_qs6612_config,
+ .startup = phy_cmd_qs6612_startup,
+ .ack_int = phy_cmd_qs6612_ack_int,
+ .shutdown = phy_cmd_qs6612_shutdown
};
/* ------------------------------------------------------------------------- */
@@ -1020,49 +1048,54 @@ static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile uint *s = &(fep->phy_status);
+ uint status;
- *s &= ~(PHY_STAT_SPMASK | PHY_STAT_ANC);
+ status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_ANC);
if (mii_reg & 0x0080)
- *s |= PHY_STAT_ANC;
+ status |= PHY_STAT_ANC;
if (mii_reg & 0x0400)
- *s |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX);
+ status |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX);
else
- *s |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX);
+ status |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX);
+
+ *s = status;
}
-static phy_info_t phy_info_am79c874 = {
- 0x00022561,
- "AM79C874",
-
- (const phy_cmd_t []) { /* config */
- /* limit to 10MBit because my protorype board
- * doesn't work with 100. */
+static phy_cmd_t const phy_cmd_am79c874_config[] = {
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
{ mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* startup - enable interrupts */
+ };
+static phy_cmd_t const phy_cmd_am79c874_startup[] = { /* enable interrupts */
{ mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL },
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* ack_int */
+ };
+static phy_cmd_t const phy_cmd_am79c874_ack_int[] = {
/* find out the current status */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
/* we only need to read ISR to acknowledge */
{ mk_mii_read(MII_AM79C874_ICSR), NULL },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* shutdown - disable interrupts */
+ };
+static phy_cmd_t const phy_cmd_am79c874_shutdown[] = { /* disable interrupts */
{ mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL },
{ mk_mii_end, }
- },
+ };
+static phy_info_t const phy_info_am79c874 = {
+ .id = 0x00022561,
+ .name = "AM79C874",
+ .config = phy_cmd_am79c874_config,
+ .startup = phy_cmd_am79c874_startup,
+ .ack_int = phy_cmd_am79c874_ack_int,
+ .shutdown = phy_cmd_am79c874_shutdown
};
+
/* ------------------------------------------------------------------------- */
/* Kendin KS8721BL phy */
@@ -1072,37 +1105,40 @@ static phy_info_t phy_info_am79c874 = {
#define MII_KS8721BL_ICSR 22
#define MII_KS8721BL_PHYCR 31
-static phy_info_t phy_info_ks8721bl = {
- 0x00022161,
- "KS8721BL",
-
- (const phy_cmd_t []) { /* config */
+static phy_cmd_t const phy_cmd_ks8721bl_config[] = {
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* startup */
+ };
+static phy_cmd_t const phy_cmd_ks8721bl_startup[] = { /* enable interrupts */
{ mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL },
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* ack_int */
+ };
+static phy_cmd_t const phy_cmd_ks8721bl_ack_int[] = {
/* find out the current status */
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
/* we only need to read ISR to acknowledge */
{ mk_mii_read(MII_KS8721BL_ICSR), NULL },
{ mk_mii_end, }
- },
- (const phy_cmd_t []) { /* shutdown */
+ };
+static phy_cmd_t const phy_cmd_ks8721bl_shutdown[] = { /* disable interrupts */
{ mk_mii_write(MII_KS8721BL_ICSR, 0x0000), NULL },
{ mk_mii_end, }
- },
+ };
+static phy_info_t const phy_info_ks8721bl = {
+ .id = 0x00022161,
+ .name = "KS8721BL",
+ .config = phy_cmd_ks8721bl_config,
+ .startup = phy_cmd_ks8721bl_startup,
+ .ack_int = phy_cmd_ks8721bl_ack_int,
+ .shutdown = phy_cmd_ks8721bl_shutdown
};
/* ------------------------------------------------------------------------- */
-static phy_info_t *phy_info[] = {
+static phy_info_t const * const phy_info[] = {
&phy_info_lxt970,
&phy_info_lxt971,
&phy_info_qs6612,
@@ -1129,16 +1165,23 @@ mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs);
static void __inline__ fec_request_intrs(struct net_device *dev)
{
volatile unsigned long *icrp;
+ static const struct idesc {
+ char *name;
+ unsigned short irq;
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
+ } *idp, id[] = {
+ { "fec(RX)", 86, fec_enet_interrupt },
+ { "fec(TX)", 87, fec_enet_interrupt },
+ { "fec(OTHER)", 88, fec_enet_interrupt },
+ { "fec(MII)", 66, mii_link_interrupt },
+ { NULL },
+ };
/* Setup interrupt handlers. */
- if (request_irq(86, fec_enet_interrupt, 0, "fec(RX)", dev) != 0)
- printk("FEC: Could not allocate FEC(RC) IRQ(86)!\n");
- if (request_irq(87, fec_enet_interrupt, 0, "fec(TX)", dev) != 0)
- printk("FEC: Could not allocate FEC(RC) IRQ(87)!\n");
- if (request_irq(88, fec_enet_interrupt, 0, "fec(OTHER)", dev) != 0)
- printk("FEC: Could not allocate FEC(OTHER) IRQ(88)!\n");
- if (request_irq(66, mii_link_interrupt, 0, "fec(MII)", dev) != 0)
- printk("FEC: Could not allocate MII IRQ(66)!\n");
+ for (idp = id; idp->name; idp++) {
+ if (request_irq(idp->irq, idp->handler, 0, idp->name, dev) != 0)
+ printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq);
+ }
/* Unmask interrupt at ColdFire 5272 SIM */
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
@@ -1169,17 +1212,16 @@ static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile fec_t *fecp;
- unsigned char *iap, tmpaddr[6];
- int i;
+ unsigned char *iap, tmpaddr[ETH_ALEN];
fecp = fep->hwp;
- if (fec_flashmac) {
+ if (FEC_FLASHMAC) {
/*
* Get MAC address from FLASH.
* If it is all 1's or 0's, use the default.
*/
- iap = fec_flashmac;
+ iap = (unsigned char *)FEC_FLASHMAC;
if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
(iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
iap = fec_mac_default;
@@ -1192,14 +1234,11 @@ static void __inline__ fec_get_mac(struct net_device *dev)
iap = &tmpaddr[0];
}
- for (i=0; i<ETH_ALEN; i++)
- dev->dev_addr[i] = fep->mac_addr[i] = *iap++;
+ memcpy(dev->dev_addr, iap, ETH_ALEN);
/* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default) {
- dev->dev_addr[ETH_ALEN-1] = fep->mac_addr[ETH_ALEN-1] =
- iap[ETH_ALEN-1] + fep->index;
- }
+ if (iap == fec_mac_default)
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
}
static void __inline__ fec_enable_phy_intr(void)
@@ -1234,48 +1273,44 @@ static void __inline__ fec_uncache(unsigned long addr)
/* ------------------------------------------------------------------------- */
-#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
/*
- * Code specific to Coldfire 5270/5271/5274/5275 and 5280/5282 setups.
+ * Code specific to Coldfire 5230/5231/5232/5234/5235,
+ * the 5270/5271/5274/5275 and 5280/5282 setups.
*/
static void __inline__ fec_request_intrs(struct net_device *dev)
{
struct fec_enet_private *fep;
int b;
+ static const struct idesc {
+ char *name;
+ unsigned short irq;
+ } *idp, id[] = {
+ { "fec(TXF)", 23 },
+ { "fec(TXB)", 24 },
+ { "fec(TXFIFO)", 25 },
+ { "fec(TXCR)", 26 },
+ { "fec(RXF)", 27 },
+ { "fec(RXB)", 28 },
+ { "fec(MII)", 29 },
+ { "fec(LC)", 30 },
+ { "fec(HBERR)", 31 },
+ { "fec(GRA)", 32 },
+ { "fec(EBERR)", 33 },
+ { "fec(BABT)", 34 },
+ { "fec(BABR)", 35 },
+ { NULL },
+ };
fep = netdev_priv(dev);
b = (fep->index) ? 128 : 64;
/* Setup interrupt handlers. */
- if (request_irq(b+23, fec_enet_interrupt, 0, "fec(TXF)", dev) != 0)
- printk("FEC: Could not allocate FEC(TXF) IRQ(%d+23)!\n", b);
- if (request_irq(b+24, fec_enet_interrupt, 0, "fec(TXB)", dev) != 0)
- printk("FEC: Could not allocate FEC(TXB) IRQ(%d+24)!\n", b);
- if (request_irq(b+25, fec_enet_interrupt, 0, "fec(TXFIFO)", dev) != 0)
- printk("FEC: Could not allocate FEC(TXFIFO) IRQ(%d+25)!\n", b);
- if (request_irq(b+26, fec_enet_interrupt, 0, "fec(TXCR)", dev) != 0)
- printk("FEC: Could not allocate FEC(TXCR) IRQ(%d+26)!\n", b);
-
- if (request_irq(b+27, fec_enet_interrupt, 0, "fec(RXF)", dev) != 0)
- printk("FEC: Could not allocate FEC(RXF) IRQ(%d+27)!\n", b);
- if (request_irq(b+28, fec_enet_interrupt, 0, "fec(RXB)", dev) != 0)
- printk("FEC: Could not allocate FEC(RXB) IRQ(%d+28)!\n", b);
-
- if (request_irq(b+29, fec_enet_interrupt, 0, "fec(MII)", dev) != 0)
- printk("FEC: Could not allocate FEC(MII) IRQ(%d+29)!\n", b);
- if (request_irq(b+30, fec_enet_interrupt, 0, "fec(LC)", dev) != 0)
- printk("FEC: Could not allocate FEC(LC) IRQ(%d+30)!\n", b);
- if (request_irq(b+31, fec_enet_interrupt, 0, "fec(HBERR)", dev) != 0)
- printk("FEC: Could not allocate FEC(HBERR) IRQ(%d+31)!\n", b);
- if (request_irq(b+32, fec_enet_interrupt, 0, "fec(GRA)", dev) != 0)
- printk("FEC: Could not allocate FEC(GRA) IRQ(%d+32)!\n", b);
- if (request_irq(b+33, fec_enet_interrupt, 0, "fec(EBERR)", dev) != 0)
- printk("FEC: Could not allocate FEC(EBERR) IRQ(%d+33)!\n", b);
- if (request_irq(b+34, fec_enet_interrupt, 0, "fec(BABT)", dev) != 0)
- printk("FEC: Could not allocate FEC(BABT) IRQ(%d+34)!\n", b);
- if (request_irq(b+35, fec_enet_interrupt, 0, "fec(BABR)", dev) != 0)
- printk("FEC: Could not allocate FEC(BABR) IRQ(%d+35)!\n", b);
+ for (idp = id; idp->name; idp++) {
+ if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0)
+ printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+ }
/* Unmask interrupts at ColdFire 5280/5282 interrupt controller */
{
@@ -1300,11 +1335,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
#if defined(CONFIG_M528x)
/* Set up gpio outputs for MII lines */
{
- volatile unsigned short *gpio_paspar;
+ volatile u16 *gpio_paspar;
+ volatile u8 *gpio_pehlpar;
- gpio_paspar = (volatile unsigned short *) (MCF_IPSBAR +
- 0x100056);
- *gpio_paspar = 0x0f00;
+ gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056);
+ gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058);
+ *gpio_paspar |= 0x0f00;
+ *gpio_pehlpar = 0xc0;
}
#endif
}
@@ -1331,17 +1368,16 @@ static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
volatile fec_t *fecp;
- unsigned char *iap, tmpaddr[6];
- int i;
+ unsigned char *iap, tmpaddr[ETH_ALEN];
fecp = fep->hwp;
- if (fec_flashmac) {
+ if (FEC_FLASHMAC) {
/*
* Get MAC address from FLASH.
* If it is all 1's or 0's, use the default.
*/
- iap = fec_flashmac;
+ iap = FEC_FLASHMAC;
if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
(iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
iap = fec_mac_default;
@@ -1354,14 +1390,11 @@ static void __inline__ fec_get_mac(struct net_device *dev)
iap = &tmpaddr[0];
}
- for (i=0; i<ETH_ALEN; i++)
- dev->dev_addr[i] = fep->mac_addr[i] = *iap++;
+ memcpy(dev->dev_addr, iap, ETH_ALEN);
/* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default) {
- dev->dev_addr[ETH_ALEN-1] = fep->mac_addr[ETH_ALEN-1] =
- iap[ETH_ALEN-1] + fep->index;
- }
+ if (iap == fec_mac_default)
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
}
static void __inline__ fec_enable_phy_intr(void)
@@ -1392,7 +1425,7 @@ static void __inline__ fec_uncache(unsigned long addr)
#else
/*
- * Code sepcific to the MPC860T setup.
+ * Code specific to the MPC860T setup.
*/
static void __inline__ fec_request_intrs(struct net_device *dev)
{
@@ -1424,13 +1457,10 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
static void __inline__ fec_get_mac(struct net_device *dev)
{
- struct fec_enet_private *fep = netdev_priv(dev);
- unsigned char *iap, tmpaddr[6];
bd_t *bd;
- int i;
- iap = bd->bi_enetaddr;
bd = (bd_t *)__res;
+ memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN);
#ifdef CONFIG_RPXCLASSIC
/* The Embedded Planet boards have only one MAC address in
@@ -1439,14 +1469,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
* the address bits above something that would have (up to
* now) been allocated.
*/
- for (i=0; i<6; i++)
- tmpaddr[i] = *iap++;
- tmpaddr[3] |= 0x80;
- iap = tmpaddr;
+ dev->dev_adrd[3] |= 0x80;
#endif
-
- for (i=0; i<6; i++)
- dev->dev_addr[i] = fep->mac_addr[i] = *iap++;
}
static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
@@ -1556,7 +1580,7 @@ static void mii_display_status(struct net_device *dev)
static void mii_display_config(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile uint *s = &(fep->phy_status);
+ uint status = fep->phy_status;
/*
** When we get here, phy_task is already removed from
@@ -1565,23 +1589,23 @@ static void mii_display_config(struct net_device *dev)
fep->mii_phy_task_queued = 0;
printk("%s: config: auto-negotiation ", dev->name);
- if (*s & PHY_CONF_ANE)
+ if (status & PHY_CONF_ANE)
printk("on");
else
printk("off");
- if (*s & PHY_CONF_100FDX)
+ if (status & PHY_CONF_100FDX)
printk(", 100FDX");
- if (*s & PHY_CONF_100HDX)
+ if (status & PHY_CONF_100HDX)
printk(", 100HDX");
- if (*s & PHY_CONF_10FDX)
+ if (status & PHY_CONF_10FDX)
printk(", 10FDX");
- if (*s & PHY_CONF_10HDX)
+ if (status & PHY_CONF_10HDX)
printk(", 10HDX");
- if (!(*s & PHY_CONF_SPMASK))
+ if (!(status & PHY_CONF_SPMASK))
printk(", No speed/duplex selected?");
- if (*s & PHY_CONF_LOOP)
+ if (status & PHY_CONF_LOOP)
printk(", loopback enabled");
printk(".\n");
@@ -1639,7 +1663,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
schedule_work(&fep->phy_task);
}
-/* mii_queue_config is called in user context from fec_enet_open */
+/* mii_queue_config is called in interrupt context from fec_enet_mii */
static void mii_queue_config(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
@@ -1652,14 +1676,14 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev)
schedule_work(&fep->phy_task);
}
-
-
-phy_cmd_t phy_cmd_relink[] = { { mk_mii_read(MII_REG_CR), mii_queue_relink },
- { mk_mii_end, } };
-phy_cmd_t phy_cmd_config[] = { { mk_mii_read(MII_REG_CR), mii_queue_config },
- { mk_mii_end, } };
-
-
+phy_cmd_t const phy_cmd_relink[] = {
+ { mk_mii_read(MII_REG_CR), mii_queue_relink },
+ { mk_mii_end, }
+ };
+phy_cmd_t const phy_cmd_config[] = {
+ { mk_mii_read(MII_REG_CR), mii_queue_config },
+ { mk_mii_end, }
+ };
/* Read remainder of PHY ID.
*/
@@ -1897,17 +1921,15 @@ static void set_multicast_list(struct net_device *dev)
static void
fec_set_mac_address(struct net_device *dev)
{
- struct fec_enet_private *fep;
volatile fec_t *fecp;
- fep = netdev_priv(dev);
- fecp = fep->hwp;
+ fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
/* Set station address. */
- fecp->fec_addr_low = fep->mac_addr[3] | (fep->mac_addr[2] << 8) |
- (fep->mac_addr[1] << 16) | (fep->mac_addr[0] << 24);
- fecp->fec_addr_high = (fep->mac_addr[5] << 16) |
- (fep->mac_addr[4] << 24);
+ fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
+ (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
+ fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
+ (dev->dev_addr[4] << 24);
}
@@ -1943,7 +1965,7 @@ int __init fec_enet_init(struct net_device *dev)
udelay(10);
/* Clear and enable interrupts */
- fecp->fec_ievent = 0xffc0;
+ fecp->fec_ievent = 0xffc00000;
fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
fecp->fec_hash_table_high = 0;
@@ -2063,11 +2085,6 @@ int __init fec_enet_init(struct net_device *dev)
/* setup MII interface */
fec_set_mii(dev, fep);
- printk("%s: FEC ENET Version 0.2, ", dev->name);
- for (i=0; i<5; i++)
- printk("%02x:", dev->dev_addr[i]);
- printk("%02x\n", dev->dev_addr[5]);
-
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
*/
@@ -2106,18 +2123,12 @@ fec_restart(struct net_device *dev, int duplex)
/* Clear any outstanding interrupt.
*/
- fecp->fec_ievent = 0xffc0;
+ fecp->fec_ievent = 0xffc00000;
fec_enable_phy_intr();
/* Set station address.
*/
- fecp->fec_addr_low = fep->mac_addr[3] | (fep->mac_addr[2] << 8) |
- (fep->mac_addr[1] << 16) | (fep->mac_addr[0] << 24);
- fecp->fec_addr_high = (fep->mac_addr[5] << 16) |
- (fep->mac_addr[4] << 24);
-
- for (i=0; i<ETH_ALEN; i++)
- dev->dev_addr[i] = fep->mac_addr[i];
+ fec_set_mac_address(dev);
/* Reset all multicast.
*/
@@ -2215,7 +2226,7 @@ fec_stop(struct net_device *dev)
fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
- while(!(fecp->fec_ievent & 0x10000000));
+ while(!(fecp->fec_ievent & FEC_ENET_GRA));
/* Whack a reset. We should wait for this.
*/
@@ -2234,7 +2245,9 @@ fec_stop(struct net_device *dev)
static int __init fec_enet_module_init(void)
{
struct net_device *dev;
- int i, err;
+ int i, j, err;
+
+ printk("FEC ENET Version 0.2\n");
for (i = 0; (i < FEC_MAX_PORTS); i++) {
dev = alloc_etherdev(sizeof(struct fec_enet_private));
@@ -2250,6 +2263,11 @@ static int __init fec_enet_module_init(void)
free_netdev(dev);
return -EIO;
}
+
+ printk("%s: ethernet ", dev->name);
+ for (j = 0; (j < 5); j++)
+ printk("%02x:", dev->dev_addr[j]);
+ printk("%02x\n", dev->dev_addr[5]);
}
return 0;
}
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index c6e4f979ff5d..045761b8a600 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -1,8 +1,9 @@
/****************************************************************************/
/*
- * fec.h -- Fast Ethernet Controller for Motorola ColdFire 5270,
- 5271, 5272, 5274, 5275, 5280 and 5282.
+ * fec.h -- Fast Ethernet Controller for Motorola ColdFire 5230,
+ * 5231, 5232, 5234, 5235, 5270, 5271, 5272, 5274, 5275,
+ * 5280 and 5282.
*
* (C) Copyright 2000-2003, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2000-2001, Lineo (www.lineo.com)
@@ -13,7 +14,7 @@
#define FEC_H
/****************************************************************************/
-#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d6eefdb71c17..22aec6ed80f5 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -95,6 +95,8 @@
* of nv_remove
* 0.42: 06 Aug 2005: Fix lack of link speed initialization
* in the second (and later) nv_open call
+ * 0.43: 10 Aug 2005: Add support for tx checksum.
+ * 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
@@ -106,7 +108,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.41"
+#define FORCEDETH_VERSION "0.44"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -145,6 +147,7 @@
#define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */
#define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */
#define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM 0x0010 /* device supports tx and rx checksum offloads */
enum {
NvRegIrqStatus = 0x000,
@@ -241,6 +244,9 @@ enum {
#define NVREG_TXRXCTL_IDLE 0x0008
#define NVREG_TXRXCTL_RESET 0x0010
#define NVREG_TXRXCTL_RXCHECK 0x0400
+#define NVREG_TXRXCTL_DESC_1 0
+#define NVREG_TXRXCTL_DESC_2 0x02100
+#define NVREG_TXRXCTL_DESC_3 0x02200
NvRegMIIStatus = 0x180,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
@@ -335,6 +341,10 @@ typedef union _ring_type {
/* error and valid are the same for both */
#define NV_TX2_ERROR (1<<30)
#define NV_TX2_VALID (1<<31)
+#define NV_TX2_TSO (1<<28)
+#define NV_TX2_TSO_SHIFT 14
+#define NV_TX2_CHECKSUM_L3 (1<<27)
+#define NV_TX2_CHECKSUM_L4 (1<<26)
#define NV_RX_DESCRIPTORVALID (1<<16)
#define NV_RX_MISSEDFRAME (1<<17)
@@ -417,14 +427,14 @@ typedef union _ring_type {
/*
* desc_ver values:
- * This field has two purposes:
- * - Newer nics uses a different ring layout. The layout is selected by
- * comparing np->desc_ver with DESC_VER_xy.
- * - It contains bits that are forced on when writing to NvRegTxRxControl.
+ * The nic supports three different descriptor types:
+ * - DESC_VER_1: Original
+ * - DESC_VER_2: support for jumbo frames.
+ * - DESC_VER_3: 64-bit format.
*/
-#define DESC_VER_1 0x0
-#define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK)
-#define DESC_VER_3 (0x02200|NVREG_TXRXCTL_RXCHECK)
+#define DESC_VER_1 1
+#define DESC_VER_2 2
+#define DESC_VER_3 3
/* PHY defines */
#define PHY_OUI_MARVELL 0x5043
@@ -491,6 +501,7 @@ struct fe_priv {
u32 orig_mac[2];
u32 irqmask;
u32 desc_ver;
+ u32 txrxctl_bits;
void __iomem *base;
@@ -534,7 +545,7 @@ static inline struct fe_priv *get_nvpriv(struct net_device *dev)
static inline u8 __iomem *get_hwbase(struct net_device *dev)
{
- return get_nvpriv(dev)->base;
+ return ((struct fe_priv *)netdev_priv(dev))->base;
}
static inline void pci_push(u8 __iomem *base)
@@ -623,7 +634,7 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
static int phy_reset(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u32 miicontrol;
unsigned int tries = 0;
@@ -726,7 +737,7 @@ static int phy_init(struct net_device *dev)
static void nv_start_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
@@ -782,14 +793,14 @@ static void nv_stop_tx(struct net_device *dev)
static void nv_txrx_reset(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
- writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
udelay(NV_TXRX_RESET_DELAY);
- writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
}
@@ -801,7 +812,7 @@ static void nv_txrx_reset(struct net_device *dev)
*/
static struct net_device_stats *nv_get_stats(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
/* It seems that the nic always generates interrupts and doesn't
* accumulate errors internally. Thus the current values in np->stats
@@ -817,7 +828,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
*/
static int nv_alloc_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
unsigned int refill_rx = np->refill_rx;
int nr;
@@ -861,7 +872,7 @@ static int nv_alloc_rx(struct net_device *dev)
static void nv_do_rx_refill(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
disable_irq(dev->irq);
if (nv_alloc_rx(dev)) {
@@ -875,7 +886,7 @@ static void nv_do_rx_refill(unsigned long data)
static void nv_init_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int i;
np->cur_rx = RX_RING;
@@ -889,15 +900,17 @@ static void nv_init_rx(struct net_device *dev)
static void nv_init_tx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int i;
np->next_tx = np->nic_tx = 0;
- for (i = 0; i < TX_RING; i++)
+ for (i = 0; i < TX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
+ np->tx_skbuff[i] = NULL;
+ }
}
static int nv_init_ring(struct net_device *dev)
@@ -907,21 +920,44 @@ static int nv_init_ring(struct net_device *dev)
return nv_alloc_rx(dev);
}
+static void nv_release_txskb(struct net_device *dev, unsigned int skbnr)
+{
+ struct fe_priv *np = netdev_priv(dev);
+ struct sk_buff *skb = np->tx_skbuff[skbnr];
+ unsigned int j, entry, fragments;
+
+ dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n",
+ dev->name, skbnr, np->tx_skbuff[skbnr]);
+
+ entry = skbnr;
+ if ((fragments = skb_shinfo(skb)->nr_frags) != 0) {
+ for (j = fragments; j >= 1; j--) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1];
+ pci_unmap_page(np->pci_dev, np->tx_dma[entry],
+ frag->size,
+ PCI_DMA_TODEVICE);
+ entry = (entry - 1) % TX_RING;
+ }
+ }
+ pci_unmap_single(np->pci_dev, np->tx_dma[entry],
+ skb->len - skb->data_len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb_irq(skb);
+ np->tx_skbuff[skbnr] = NULL;
+}
+
static void nv_drain_tx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
- int i;
+ struct fe_priv *np = netdev_priv(dev);
+ unsigned int i;
+
for (i = 0; i < TX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
if (np->tx_skbuff[i]) {
- pci_unmap_single(np->pci_dev, np->tx_dma[i],
- np->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb(np->tx_skbuff[i]);
- np->tx_skbuff[i] = NULL;
+ nv_release_txskb(dev, i);
np->stats.tx_dropped++;
}
}
@@ -929,7 +965,7 @@ static void nv_drain_tx(struct net_device *dev)
static void nv_drain_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int i;
for (i = 0; i < RX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
@@ -959,28 +995,69 @@ static void drain_ring(struct net_device *dev)
*/
static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
- int nr = np->next_tx % TX_RING;
+ struct fe_priv *np = netdev_priv(dev);
+ u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
+ unsigned int fragments = skb_shinfo(skb)->nr_frags;
+ unsigned int nr = (np->next_tx + fragments) % TX_RING;
+ unsigned int i;
+
+ spin_lock_irq(&np->lock);
+
+ if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) {
+ spin_unlock_irq(&np->lock);
+ netif_stop_queue(dev);
+ return NETDEV_TX_BUSY;
+ }
np->tx_skbuff[nr] = skb;
- np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
- PCI_DMA_TODEVICE);
+
+ if (fragments) {
+ dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments);
+ /* setup descriptors in reverse order */
+ for (i = fragments; i >= 1; i--) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
+ np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size,
+ PCI_DMA_TODEVICE);
- if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+ np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
+ np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+ } else {
+ np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
+ np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
+ np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+ }
+
+ nr = (nr - 1) % TX_RING;
+
+ if (np->desc_ver == DESC_VER_1)
+ tx_flags_extra &= ~NV_TX_LASTPACKET;
+ else
+ tx_flags_extra &= ~NV_TX2_LASTPACKET;
+ }
+ }
+
+#ifdef NETIF_F_TSO
+ if (skb_shinfo(skb)->tso_size)
+ tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
+ else
+#endif
+ tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+
+ np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len,
+ PCI_DMA_TODEVICE);
+
+ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
- else {
+ np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+ } else {
np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
- }
+ np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+ }
- spin_lock_irq(&np->lock);
- wmb();
- if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
- np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
- else
- np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
- dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
- dev->name, np->next_tx);
+ dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n",
+ dev->name, np->next_tx, tx_flags_extra);
{
int j;
for (j=0; j<64; j++) {
@@ -991,15 +1068,13 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
dprintk("\n");
}
- np->next_tx++;
+ np->next_tx += 1 + fragments;
dev->trans_start = jiffies;
- if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
- netif_stop_queue(dev);
spin_unlock_irq(&np->lock);
- writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(get_hwbase(dev));
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -1009,9 +1084,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static void nv_tx_done(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u32 Flags;
- int i;
+ unsigned int i;
+ struct sk_buff *skb;
while (np->nic_tx != np->next_tx) {
i = np->nic_tx % TX_RING;
@@ -1026,35 +1102,38 @@ static void nv_tx_done(struct net_device *dev)
if (Flags & NV_TX_VALID)
break;
if (np->desc_ver == DESC_VER_1) {
- if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
- NV_TX_UNDERFLOW|NV_TX_ERROR)) {
- if (Flags & NV_TX_UNDERFLOW)
- np->stats.tx_fifo_errors++;
- if (Flags & NV_TX_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
- } else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->tx_skbuff[i]->len;
+ if (Flags & NV_TX_LASTPACKET) {
+ skb = np->tx_skbuff[i];
+ if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
+ NV_TX_UNDERFLOW|NV_TX_ERROR)) {
+ if (Flags & NV_TX_UNDERFLOW)
+ np->stats.tx_fifo_errors++;
+ if (Flags & NV_TX_CARRIERLOST)
+ np->stats.tx_carrier_errors++;
+ np->stats.tx_errors++;
+ } else {
+ np->stats.tx_packets++;
+ np->stats.tx_bytes += skb->len;
+ }
+ nv_release_txskb(dev, i);
}
} else {
- if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
- NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
- if (Flags & NV_TX2_UNDERFLOW)
- np->stats.tx_fifo_errors++;
- if (Flags & NV_TX2_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
- } else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->tx_skbuff[i]->len;
+ if (Flags & NV_TX2_LASTPACKET) {
+ skb = np->tx_skbuff[i];
+ if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
+ NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
+ if (Flags & NV_TX2_UNDERFLOW)
+ np->stats.tx_fifo_errors++;
+ if (Flags & NV_TX2_CARRIERLOST)
+ np->stats.tx_carrier_errors++;
+ np->stats.tx_errors++;
+ } else {
+ np->stats.tx_packets++;
+ np->stats.tx_bytes += skb->len;
+ }
+ nv_release_txskb(dev, i);
}
}
- pci_unmap_single(np->pci_dev, np->tx_dma[i],
- np->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(np->tx_skbuff[i]);
- np->tx_skbuff[i] = NULL;
np->nic_tx++;
}
if (np->next_tx - np->nic_tx < TX_LIMIT_START)
@@ -1067,7 +1146,7 @@ static void nv_tx_done(struct net_device *dev)
*/
static void nv_tx_timeout(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name,
@@ -1200,7 +1279,7 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
static void nv_rx_process(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u32 Flags;
for (;;) {
@@ -1355,7 +1434,7 @@ static void set_bufsize(struct net_device *dev)
*/
static int nv_change_mtu(struct net_device *dev, int new_mtu)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int old_mtu;
if (new_mtu < 64 || new_mtu > np->pkt_limit)
@@ -1408,7 +1487,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
- writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(base);
/* restart rx engine */
@@ -1440,7 +1519,7 @@ static void nv_copy_mac_to_hw(struct net_device *dev)
*/
static int nv_set_mac_address(struct net_device *dev, void *addr)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
struct sockaddr *macaddr = (struct sockaddr*)addr;
if(!is_valid_ether_addr(macaddr->sa_data))
@@ -1475,7 +1554,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
*/
static void nv_set_multicast(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 addr[2];
u32 mask[2];
@@ -1535,7 +1614,7 @@ static void nv_set_multicast(struct net_device *dev)
static int nv_update_linkspeed(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int adv, lpa;
int newls = np->linkspeed;
@@ -1705,7 +1784,7 @@ static void nv_link_irq(struct net_device *dev)
static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 events;
int i;
@@ -1777,7 +1856,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
static void nv_do_nic_poll(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
disable_irq(dev->irq);
@@ -1801,7 +1880,7 @@ static void nv_poll_controller(struct net_device *dev)
static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
strcpy(info->driver, "forcedeth");
strcpy(info->version, FORCEDETH_VERSION);
strcpy(info->bus_info, pci_name(np->pci_dev));
@@ -1809,7 +1888,7 @@ static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
wolinfo->supported = WAKE_MAGIC;
spin_lock_irq(&np->lock);
@@ -1820,7 +1899,7 @@ static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
spin_lock_irq(&np->lock);
@@ -2021,7 +2100,7 @@ static int nv_get_regs_len(struct net_device *dev)
static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 *rbuf = buf;
int i;
@@ -2035,7 +2114,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void
static int nv_nway_reset(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int ret;
spin_lock_irq(&np->lock);
@@ -2065,11 +2144,12 @@ static struct ethtool_ops ops = {
.get_regs_len = nv_get_regs_len,
.get_regs = nv_get_regs,
.nway_reset = nv_nway_reset,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int nv_open(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int ret, oom, i;
@@ -2114,9 +2194,9 @@ static int nv_open(struct net_device *dev)
/* 5) continue setup */
writel(np->linkspeed, base + NvRegLinkSpeed);
writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
- writel(np->desc_ver, base + NvRegTxRxControl);
+ writel(np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
- writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
@@ -2205,7 +2285,7 @@ out_drain:
static int nv_close(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base;
spin_lock_irq(&np->lock);
@@ -2261,7 +2341,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (!dev)
goto out;
- np = get_nvpriv(dev);
+ np = netdev_priv(dev);
np->pci_dev = pci_dev;
spin_lock_init(&np->lock);
SET_MODULE_OWNER(dev);
@@ -2313,19 +2393,32 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
pci_name(pci_dev));
+ } else {
+ dev->features |= NETIF_F_HIGHDMA;
}
+ np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
} else if (id->driver_data & DEV_HAS_LARGEDESC) {
/* packet format 2: supports jumbo frames */
np->desc_ver = DESC_VER_2;
+ np->txrxctl_bits = NVREG_TXRXCTL_DESC_2;
} else {
/* original packet format */
np->desc_ver = DESC_VER_1;
+ np->txrxctl_bits = NVREG_TXRXCTL_DESC_1;
}
np->pkt_limit = NV_PKTLIMIT_1;
if (id->driver_data & DEV_HAS_LARGEDESC)
np->pkt_limit = NV_PKTLIMIT_2;
+ if (id->driver_data & DEV_HAS_CHECKSUM) {
+ np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+#ifdef NETIF_F_TSO
+ dev->features |= NETIF_F_TSO;
+#endif
+ }
+
err = -ENOMEM;
np->base = ioremap(addr, NV_PCI_REGSZ);
if (!np->base)
@@ -2377,8 +2470,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- if (!is_valid_ether_addr(dev->dev_addr)) {
+ if (!is_valid_ether_addr(dev->perm_addr)) {
/*
* Bad mac address. At least one bios sets the mac address
* to 01:23:45:67:89:ab
@@ -2403,9 +2497,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->wolenabled = 0;
if (np->desc_ver == DESC_VER_1) {
- np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
+ np->tx_flags = NV_TX_VALID;
} else {
- np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
+ np->tx_flags = NV_TX2_VALID;
}
np->irqmask = NVREG_IRQMASK_WANTED;
if (id->driver_data & DEV_NEED_TIMERIRQ)
@@ -2494,7 +2588,7 @@ out:
static void __devexit nv_remove(struct pci_dev *pci_dev)
{
struct net_device *dev = pci_get_drvdata(pci_dev);
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
unregister_netdev(dev);
@@ -2525,35 +2619,35 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
@@ -2565,11 +2659,11 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{0,},
};
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6518334b9280..ae5a2ed3b264 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -29,12 +29,7 @@
* define the configuration needed by the board are defined in a
* board structure in arch/ppc/platforms (though I do not
* discount the possibility that other architectures could one
- * day be supported. One assumption the driver currently makes
- * is that the PHY is configured in such a way to advertise all
- * capabilities. This is a sensible default, and on certain
- * PHYs, changing this default encounters substantial errata
- * issues. Future versions may remove this requirement, but for
- * now, it is best for the firmware to ensure this is the case.
+ * day be supported.
*
* The Gianfar Ethernet Controller uses a ring of buffer
* descriptors. The beginning is indicated by a register
@@ -47,7 +42,7 @@
* corresponding bit in the IMASK register is also set (if
* interrupt coalescing is active, then the interrupt may not
* happen immediately, but will wait until either a set number
- * of frames or amount of time have passed.). In NAPI, the
+ * of frames or amount of time have passed). In NAPI, the
* interrupt handler will signal there is work to be done, and
* exit. Without NAPI, the packet(s) will be handled
* immediately. Both methods will start at the last known empty
@@ -75,6 +70,7 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -97,9 +93,11 @@
#include <linux/version.h>
#include <linux/dma-mapping.h>
#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
#include "gianfar.h"
-#include "gianfar_phy.h"
+#include "gianfar_mii.h"
#define TX_TIMEOUT (1*HZ)
#define SKB_ALLOC_TIMEOUT 1000000
@@ -113,9 +111,8 @@
#endif
const char gfar_driver_name[] = "Gianfar Ethernet";
-const char gfar_driver_version[] = "1.1";
+const char gfar_driver_version[] = "1.2";
-int startup_gfar(struct net_device *dev);
static int gfar_enet_open(struct net_device *dev);
static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void gfar_timeout(struct net_device *dev);
@@ -126,17 +123,13 @@ static int gfar_set_mac_address(struct net_device *dev);
static int gfar_change_mtu(struct net_device *dev, int new_mtu);
static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void gfar_phy_change(void *data);
-static void gfar_phy_timer(unsigned long data);
static void adjust_link(struct net_device *dev);
static void init_registers(struct net_device *dev);
static int init_phy(struct net_device *dev);
static int gfar_probe(struct device *device);
static int gfar_remove(struct device *device);
-void free_skb_resources(struct gfar_private *priv);
+static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
#ifdef CONFIG_GFAR_NAPI
@@ -144,7 +137,6 @@ static int gfar_poll(struct net_device *dev, int *budget);
#endif
int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
-static void gfar_phy_startup_timer(unsigned long data);
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
@@ -162,6 +154,9 @@ int gfar_uses_fcb(struct gfar_private *priv)
else
return 0;
}
+
+/* Set up the ethernet device structure, private data,
+ * and anything else we need before we start */
static int gfar_probe(struct device *device)
{
u32 tempval;
@@ -175,7 +170,7 @@ static int gfar_probe(struct device *device)
einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
- if (einfo == NULL) {
+ if (NULL == einfo) {
printk(KERN_ERR "gfar %d: Missing additional data!\n",
pdev->id);
@@ -185,7 +180,7 @@ static int gfar_probe(struct device *device)
/* Create an ethernet device instance */
dev = alloc_etherdev(sizeof (*priv));
- if (dev == NULL)
+ if (NULL == dev)
return -ENOMEM;
priv = netdev_priv(dev);
@@ -207,20 +202,11 @@ static int gfar_probe(struct device *device)
priv->regs = (struct gfar *)
ioremap(r->start, sizeof (struct gfar));
- if (priv->regs == NULL) {
+ if (NULL == priv->regs) {
err = -ENOMEM;
goto regs_fail;
}
- /* Set the PHY base address */
- priv->phyregs = (struct gfar *)
- ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
-
- if (priv->phyregs == NULL) {
- err = -ENOMEM;
- goto phy_regs_fail;
- }
-
spin_lock_init(&priv->lock);
dev_set_drvdata(device, dev);
@@ -386,12 +372,10 @@ static int gfar_probe(struct device *device)
return 0;
register_fail:
- iounmap((void *) priv->phyregs);
-phy_regs_fail:
iounmap((void *) priv->regs);
regs_fail:
free_netdev(dev);
- return -ENOMEM;
+ return err;
}
static int gfar_remove(struct device *device)
@@ -402,108 +386,41 @@ static int gfar_remove(struct device *device)
dev_set_drvdata(device, NULL);
iounmap((void *) priv->regs);
- iounmap((void *) priv->phyregs);
free_netdev(dev);
return 0;
}
-/* Configure the PHY for dev.
- * returns 0 if success. -1 if failure
+/* Initializes driver's PHY state, and attaches to the PHY.
+ * Returns 0 on success.
*/
static int init_phy(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct phy_info *curphy;
- unsigned int timeout = PHY_INIT_TIMEOUT;
- struct gfar *phyregs = priv->phyregs;
- struct gfar_mii_info *mii_info;
- int err;
+ uint gigabit_support =
+ priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+ SUPPORTED_1000baseT_Full : 0;
+ struct phy_device *phydev;
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
- mii_info = kmalloc(sizeof(struct gfar_mii_info),
- GFP_KERNEL);
-
- if(NULL == mii_info) {
- if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: Could not allocate mii_info\n",
- dev->name);
- return -ENOMEM;
- }
-
- mii_info->speed = SPEED_1000;
- mii_info->duplex = DUPLEX_FULL;
- mii_info->pause = 0;
- mii_info->link = 1;
-
- mii_info->advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Full);
- mii_info->autoneg = 1;
+ phydev = phy_connect(dev, priv->einfo->bus_id, &adjust_link, 0);
- spin_lock_init(&mii_info->mdio_lock);
-
- mii_info->mii_id = priv->einfo->phyid;
-
- mii_info->dev = dev;
-
- mii_info->mdio_read = &read_phy_reg;
- mii_info->mdio_write = &write_phy_reg;
-
- priv->mii_info = mii_info;
-
- /* Reset the management interface */
- gfar_write(&phyregs->miimcfg, MIIMCFG_RESET);
-
- /* Setup the MII Mgmt clock speed */
- gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
-
- /* Wait until the bus is free */
- while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) &&
- timeout--)
- cpu_relax();
-
- if(timeout <= 0) {
- printk(KERN_ERR "%s: The MII Bus is stuck!\n",
- dev->name);
- err = -1;
- goto bus_fail;
- }
-
- /* get info for this PHY */
- curphy = get_phy_info(priv->mii_info);
-
- if (curphy == NULL) {
- if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: No PHY found\n", dev->name);
- err = -1;
- goto no_phy;
+ if (IS_ERR(phydev)) {
+ printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+ return PTR_ERR(phydev);
}
- mii_info->phyinfo = curphy;
+ /* Remove any features not supported by the controller */
+ phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+ phydev->advertising = phydev->supported;
- /* Run the commands which initialize the PHY */
- if(curphy->init) {
- err = curphy->init(priv->mii_info);
-
- if (err)
- goto phy_init_fail;
- }
+ priv->phydev = phydev;
return 0;
-
-phy_init_fail:
-no_phy:
-bus_fail:
- kfree(mii_info);
-
- return err;
}
static void init_registers(struct net_device *dev)
@@ -603,24 +520,13 @@ void stop_gfar(struct net_device *dev)
struct gfar *regs = priv->regs;
unsigned long flags;
+ phy_stop(priv->phydev);
+
/* Lock it down */
spin_lock_irqsave(&priv->lock, flags);
- /* Tell the kernel the link is down */
- priv->mii_info->link = 0;
- adjust_link(dev);
-
gfar_halt(dev);
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
- /* Clear any pending interrupts */
- mii_clear_phy_interrupt(priv->mii_info);
-
- /* Disable PHY Interrupts */
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_DISABLED);
- }
-
spin_unlock_irqrestore(&priv->lock, flags);
/* Free the IRQs */
@@ -629,13 +535,7 @@ void stop_gfar(struct net_device *dev)
free_irq(priv->interruptTransmit, dev);
free_irq(priv->interruptReceive, dev);
} else {
- free_irq(priv->interruptTransmit, dev);
- }
-
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
- free_irq(priv->einfo->interruptPHY, dev);
- } else {
- del_timer_sync(&priv->phy_info_timer);
+ free_irq(priv->interruptTransmit, dev);
}
free_skb_resources(priv);
@@ -649,7 +549,7 @@ void stop_gfar(struct net_device *dev)
/* If there are any tx skbs or rx skbs still around, free them.
* Then free tx_skbuff and rx_skbuff */
-void free_skb_resources(struct gfar_private *priv)
+static void free_skb_resources(struct gfar_private *priv)
{
struct rxbd8 *rxbdp;
struct txbd8 *txbdp;
@@ -770,7 +670,7 @@ int startup_gfar(struct net_device *dev)
(struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
priv->tx_ring_size, GFP_KERNEL);
- if (priv->tx_skbuff == NULL) {
+ if (NULL == priv->tx_skbuff) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
dev->name);
@@ -785,7 +685,7 @@ int startup_gfar(struct net_device *dev)
(struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
priv->rx_ring_size, GFP_KERNEL);
- if (priv->rx_skbuff == NULL) {
+ if (NULL == priv->rx_skbuff) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
dev->name);
@@ -879,13 +779,7 @@ int startup_gfar(struct net_device *dev)
}
}
- /* Set up the PHY change work queue */
- INIT_WORK(&priv->tq, gfar_phy_change, dev);
-
- init_timer(&priv->phy_info_timer);
- priv->phy_info_timer.function = &gfar_phy_startup_timer;
- priv->phy_info_timer.data = (unsigned long) priv->mii_info;
- mod_timer(&priv->phy_info_timer, jiffies + HZ);
+ phy_start(priv->phydev);
/* Configure the coalescing support */
if (priv->txcoalescing)
@@ -933,11 +827,6 @@ tx_skb_fail:
priv->tx_bd_base,
gfar_read(&regs->tbase0));
- if (priv->mii_info->phyinfo->close)
- priv->mii_info->phyinfo->close(priv->mii_info);
-
- kfree(priv->mii_info);
-
return err;
}
@@ -1035,7 +924,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp->status &= TXBD_WRAP;
/* Set up checksumming */
- if ((dev->features & NETIF_F_IP_CSUM)
+ if ((dev->features & NETIF_F_IP_CSUM)
&& (CHECKSUM_HW == skb->ip_summed)) {
fcb = gfar_add_fcb(skb, txbdp);
gfar_tx_checksum(skb, fcb);
@@ -1103,11 +992,9 @@ static int gfar_close(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
stop_gfar(dev);
- /* Shutdown the PHY */
- if (priv->mii_info->phyinfo->close)
- priv->mii_info->phyinfo->close(priv->mii_info);
-
- kfree(priv->mii_info);
+ /* Disconnect from the PHY */
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
netif_stop_queue(dev);
@@ -1343,7 +1230,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
while ((!skb) && timeout--)
skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT);
- if (skb == NULL)
+ if (NULL == skb)
return NULL;
/* We need the data buffer to be aligned properly. We will reserve
@@ -1490,7 +1377,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
struct gfar_private *priv = netdev_priv(dev);
struct rxfcb *fcb = NULL;
- if (skb == NULL) {
+ if (NULL == skb) {
if (netif_msg_rx_err(priv))
printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name);
priv->stats.rx_dropped++;
@@ -1718,131 +1605,9 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct gfar_private *priv = netdev_priv(dev);
-
- /* Clear the interrupt */
- mii_clear_phy_interrupt(priv->mii_info);
-
- /* Disable PHY interrupts */
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_DISABLED);
-
- /* Schedule the phy change */
- schedule_work(&priv->tq);
-
- return IRQ_HANDLED;
-}
-
-/* Scheduled by the phy_interrupt/timer to handle PHY changes */
-static void gfar_phy_change(void *data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct gfar_private *priv = netdev_priv(dev);
- int result = 0;
-
- /* Delay to give the PHY a chance to change the
- * register state */
- msleep(1);
-
- /* Update the link, speed, duplex */
- result = priv->mii_info->phyinfo->read_status(priv->mii_info);
-
- /* Adjust the known status as long as the link
- * isn't still coming up */
- if((0 == result) || (priv->mii_info->link == 0))
- adjust_link(dev);
-
- /* Reenable interrupts, if needed */
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_ENABLED);
-}
-
-/* Called every so often on systems that don't interrupt
- * the core for PHY changes */
-static void gfar_phy_timer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct gfar_private *priv = netdev_priv(dev);
-
- schedule_work(&priv->tq);
-
- mod_timer(&priv->phy_info_timer, jiffies +
- GFAR_PHY_CHANGE_TIME * HZ);
-}
-
-/* Keep trying aneg for some time
- * If, after GFAR_AN_TIMEOUT seconds, it has not
- * finished, we switch to forced.
- * Either way, once the process has completed, we either
- * request the interrupt, or switch the timer over to
- * using gfar_phy_timer to check status */
-static void gfar_phy_startup_timer(unsigned long data)
-{
- int result;
- static int secondary = GFAR_AN_TIMEOUT;
- struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
- struct gfar_private *priv = netdev_priv(mii_info->dev);
-
- /* Configure the Auto-negotiation */
- result = mii_info->phyinfo->config_aneg(mii_info);
-
- /* If autonegotiation failed to start, and
- * we haven't timed out, reset the timer, and return */
- if (result && secondary--) {
- mod_timer(&priv->phy_info_timer, jiffies + HZ);
- return;
- } else if (result) {
- /* Couldn't start autonegotiation.
- * Try switching to forced */
- mii_info->autoneg = 0;
- result = mii_info->phyinfo->config_aneg(mii_info);
-
- /* Forcing failed! Give up */
- if(result) {
- if (netif_msg_link(priv))
- printk(KERN_ERR "%s: Forcing failed!\n",
- mii_info->dev->name);
- return;
- }
- }
-
- /* Kill the timer so it can be restarted */
- del_timer_sync(&priv->phy_info_timer);
-
- /* Grab the PHY interrupt, if necessary/possible */
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
- if (request_irq(priv->einfo->interruptPHY,
- phy_interrupt,
- SA_SHIRQ,
- "phy_interrupt",
- mii_info->dev) < 0) {
- if (netif_msg_intr(priv))
- printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
- mii_info->dev->name,
- priv->einfo->interruptPHY);
- } else {
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_ENABLED);
- return;
- }
- }
-
- /* Start the timer again, this time in order to
- * handle a change in status */
- init_timer(&priv->phy_info_timer);
- priv->phy_info_timer.function = &gfar_phy_timer;
- priv->phy_info_timer.data = (unsigned long) mii_info->dev;
- mod_timer(&priv->phy_info_timer, jiffies +
- GFAR_PHY_CHANGE_TIME * HZ);
-}
-
/* Called every time the controller might need to be made
* aware of new link state. The PHY code conveys this
- * information through variables in the priv structure, and this
+ * information through variables in the phydev structure, and this
* function converts those variables into the appropriate
* register values, and can bring down the device if needed.
*/
@@ -1850,84 +1615,68 @@ static void adjust_link(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar *regs = priv->regs;
- u32 tempval;
- struct gfar_mii_info *mii_info = priv->mii_info;
+ unsigned long flags;
+ struct phy_device *phydev = priv->phydev;
+ int new_state = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (phydev->link) {
+ u32 tempval = gfar_read(&regs->maccfg2);
- if (mii_info->link) {
/* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */
- if (mii_info->duplex != priv->oldduplex) {
- if (!(mii_info->duplex)) {
- tempval = gfar_read(&regs->maccfg2);
+ if (phydev->duplex != priv->oldduplex) {
+ new_state = 1;
+ if (!(phydev->duplex))
tempval &= ~(MACCFG2_FULL_DUPLEX);
- gfar_write(&regs->maccfg2, tempval);
-
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Half Duplex\n",
- dev->name);
- } else {
- tempval = gfar_read(&regs->maccfg2);
+ else
tempval |= MACCFG2_FULL_DUPLEX;
- gfar_write(&regs->maccfg2, tempval);
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Full Duplex\n",
- dev->name);
- }
-
- priv->oldduplex = mii_info->duplex;
+ priv->oldduplex = phydev->duplex;
}
- if (mii_info->speed != priv->oldspeed) {
- switch (mii_info->speed) {
+ if (phydev->speed != priv->oldspeed) {
+ new_state = 1;
+ switch (phydev->speed) {
case 1000:
- tempval = gfar_read(&regs->maccfg2);
tempval =
((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
- gfar_write(&regs->maccfg2, tempval);
break;
case 100:
case 10:
- tempval = gfar_read(&regs->maccfg2);
tempval =
((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
- gfar_write(&regs->maccfg2, tempval);
break;
default:
if (netif_msg_link(priv))
printk(KERN_WARNING
- "%s: Ack! Speed (%d) is not 10/100/1000!\n",
- dev->name, mii_info->speed);
+ "%s: Ack! Speed (%d) is not 10/100/1000!\n",
+ dev->name, phydev->speed);
break;
}
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
- mii_info->speed);
-
- priv->oldspeed = mii_info->speed;
+ priv->oldspeed = phydev->speed;
}
+ gfar_write(&regs->maccfg2, tempval);
+
if (!priv->oldlink) {
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Link is up\n", dev->name);
+ new_state = 1;
priv->oldlink = 1;
- netif_carrier_on(dev);
netif_schedule(dev);
}
- } else {
- if (priv->oldlink) {
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Link is down\n",
- dev->name);
- priv->oldlink = 0;
- priv->oldspeed = 0;
- priv->oldduplex = -1;
- netif_carrier_off(dev);
- }
+ } else if (priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
}
-}
+ if (new_state && netif_msg_link(priv))
+ phy_print_status(phydev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
/* Update the hash table based on the current list of multicast
* addresses we subscribe to. Also, change the promiscuity of
@@ -2122,12 +1871,23 @@ static struct device_driver gfar_driver = {
static int __init gfar_init(void)
{
- return driver_register(&gfar_driver);
+ int err = gfar_mdio_init();
+
+ if (err)
+ return err;
+
+ err = driver_register(&gfar_driver);
+
+ if (err)
+ gfar_mdio_exit();
+
+ return err;
}
static void __exit gfar_exit(void)
{
driver_unregister(&gfar_driver);
+ gfar_mdio_exit();
}
module_init(gfar_init);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 28af087d9fbb..c77ca6c0d04a 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -17,7 +17,6 @@
*
* Still left to do:
* -Add support for module parameters
- * -Add support for ethtool -s
* -Add patch for ethtool phys id
*/
#ifndef __GIANFAR_H
@@ -37,7 +36,8 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/fsl_devices.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -48,7 +48,8 @@
#include <linux/workqueue.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
-#include "gianfar_phy.h"
+#include <linux/fsl_devices.h>
+#include "gianfar_mii.h"
/* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64
@@ -73,7 +74,7 @@
#define PHY_INIT_TIMEOUT 100000
#define GFAR_PHY_CHANGE_TIME 2
-#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, "
+#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
#define DRV_NAME "gfar-enet"
extern const char gfar_driver_name[];
extern const char gfar_driver_version[];
@@ -578,12 +579,7 @@ struct gfar {
u32 hafdup; /* 0x.50c - Half Duplex Register */
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */
u8 res18[12];
- u32 miimcfg; /* 0x.520 - MII Management Configuration Register */
- u32 miimcom; /* 0x.524 - MII Management Command Register */
- u32 miimadd; /* 0x.528 - MII Management Address Register */
- u32 miimcon; /* 0x.52c - MII Management Control Register */
- u32 miimstat; /* 0x.530 - MII Management Status Register */
- u32 miimind; /* 0x.534 - MII Management Indicator Register */
+ u8 gfar_mii_regs[24]; /* See gianfar_phy.h */
u8 res19[4];
u32 ifstat; /* 0x.53c - Interface Status Register */
u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */
@@ -688,9 +684,6 @@ struct gfar_private {
struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */
u32 *hash_regs[16];
int hash_width;
- struct gfar *phyregs;
- struct work_struct tq;
- struct timer_list phy_info_timer;
struct net_device_stats stats; /* linux network statistics */
struct gfar_extra_stats extra_stats;
spinlock_t lock;
@@ -710,7 +703,8 @@ struct gfar_private {
unsigned int interruptError;
struct gianfar_platform_data *einfo;
- struct gfar_mii_info *mii_info;
+ struct phy_device *phydev;
+ struct mii_bus *mii_bus;
int oldspeed;
int oldduplex;
int oldlink;
@@ -732,4 +726,12 @@ extern inline void gfar_write(volatile unsigned *addr, u32 val)
extern struct ethtool_ops *gfar_op_array[];
+extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+extern int startup_gfar(struct net_device *dev);
+extern void stop_gfar(struct net_device *dev);
+extern void gfar_halt(struct net_device *dev);
+extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
+ int enable, u32 regnum, u32 read);
+void gfar_setup_stashing(struct net_device *dev);
+
#endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index a451de629197..68e3578e7613 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -39,17 +39,18 @@
#include <asm/types.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
#include "gianfar.h"
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
-extern int startup_gfar(struct net_device *dev);
-extern void stop_gfar(struct net_device *dev);
-extern void gfar_halt(struct net_device *dev);
extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+#define GFAR_MAX_COAL_USECS 0xffff
+#define GFAR_MAX_COAL_FRAMES 0xff
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
u64 * buf);
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
@@ -182,38 +183,32 @@ static void gfar_gdrvinfo(struct net_device *dev, struct
drvinfo->eedump_len = 0;
}
+
+static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+
+ if (NULL == phydev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, cmd);
+}
+
+
/* Return the current settings in the ethtool_cmd structure */
static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gfar_private *priv = netdev_priv(dev);
- uint gigabit_support =
- priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
- SUPPORTED_1000baseT_Full : 0;
- uint gigabit_advert =
- priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
- ADVERTISED_1000baseT_Full: 0;
-
- cmd->supported = (SUPPORTED_10baseT_Half
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full
- | gigabit_support | SUPPORTED_Autoneg);
-
- /* For now, we always advertise everything */
- cmd->advertising = (ADVERTISED_10baseT_Half
- | ADVERTISED_100baseT_Half
- | ADVERTISED_100baseT_Full
- | gigabit_advert | ADVERTISED_Autoneg);
-
- cmd->speed = priv->mii_info->speed;
- cmd->duplex = priv->mii_info->duplex;
- cmd->port = PORT_MII;
- cmd->phy_address = priv->mii_info->mii_id;
- cmd->transceiver = XCVR_EXTERNAL;
- cmd->autoneg = AUTONEG_ENABLE;
+ struct phy_device *phydev = priv->phydev;
+
+ if (NULL == phydev)
+ return -ENODEV;
+
cmd->maxtxpkt = priv->txcount;
cmd->maxrxpkt = priv->rxcount;
- return 0;
+ return phy_ethtool_gset(phydev, cmd);
}
/* Return the length of the register structure */
@@ -241,14 +236,14 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use
unsigned int count;
/* The timer is different, depending on the interface speed */
- switch (priv->mii_info->speed) {
- case 1000:
+ switch (priv->phydev->speed) {
+ case SPEED_1000:
count = GFAR_GBIT_TIME;
break;
- case 100:
+ case SPEED_100:
count = GFAR_100_TIME;
break;
- case 10:
+ case SPEED_10:
default:
count = GFAR_10_TIME;
break;
@@ -265,14 +260,14 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
unsigned int count;
/* The timer is different, depending on the interface speed */
- switch (priv->mii_info->speed) {
- case 1000:
+ switch (priv->phydev->speed) {
+ case SPEED_1000:
count = GFAR_GBIT_TIME;
break;
- case 100:
+ case SPEED_100:
count = GFAR_100_TIME;
break;
- case 10:
+ case SPEED_10:
default:
count = GFAR_10_TIME;
break;
@@ -292,6 +287,9 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
return -EOPNOTSUPP;
+ if (NULL == priv->phydev)
+ return -ENODEV;
+
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
cvals->rx_max_coalesced_frames = priv->rxcount;
@@ -348,6 +346,22 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
else
priv->rxcoalescing = 1;
+ if (NULL == priv->phydev)
+ return -ENODEV;
+
+ /* Check the bounds of the values */
+ if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
+ pr_info("Coalescing is limited to %d microseconds\n",
+ GFAR_MAX_COAL_USECS);
+ return -EINVAL;
+ }
+
+ if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
+ pr_info("Coalescing is limited to %d frames\n",
+ GFAR_MAX_COAL_FRAMES);
+ return -EINVAL;
+ }
+
priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
priv->rxcount = cvals->rx_max_coalesced_frames;
@@ -358,6 +372,19 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
else
priv->txcoalescing = 1;
+ /* Check the bounds of the values */
+ if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
+ pr_info("Coalescing is limited to %d microseconds\n",
+ GFAR_MAX_COAL_USECS);
+ return -EINVAL;
+ }
+
+ if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
+ pr_info("Coalescing is limited to %d frames\n",
+ GFAR_MAX_COAL_FRAMES);
+ return -EINVAL;
+ }
+
priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
priv->txcount = cvals->tx_max_coalesced_frames;
@@ -536,6 +563,7 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
+ .set_settings = gfar_ssettings,
.get_drvinfo = gfar_gdrvinfo,
.get_regs_len = gfar_reglen,
.get_regs = gfar_get_regs,
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
new file mode 100644
index 000000000000..1eca1dbca7f1
--- /dev/null
+++ b/drivers/net/gianfar_mii.c
@@ -0,0 +1,219 @@
+/*
+ * drivers/net/gianfar_mii.c
+ *
+ * Gianfar Ethernet Driver -- MIIM bus implementation
+ * Provides Bus interface for MIIM regs
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-2004 Freescale Semiconductor, 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.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <asm/ocp.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "gianfar.h"
+#include "gianfar_mii.h"
+
+/* Write value to the PHY at mii_id at register regnum,
+ * on the bus, waiting until the write is done before returning.
+ * All PHY configuration is done through the TSEC1 MIIM regs */
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+{
+ struct gfar_mii *regs = bus->priv;
+
+ /* Set the PHY address and the register address we want to write */
+ gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+
+ /* Write out the value we want */
+ gfar_write(&regs->miimcon, value);
+
+ /* Wait for the transaction to finish */
+ while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
+ cpu_relax();
+
+ return 0;
+}
+
+/* Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value. Clears miimcom first. All PHY
+ * configuration has to be done through the TSEC1 MIIM regs */
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ struct gfar_mii *regs = bus->priv;
+ u16 value;
+
+ /* Set the PHY address and the register address we want to read */
+ gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+
+ /* Clear miimcom, and then initiate a read */
+ gfar_write(&regs->miimcom, 0);
+ gfar_write(&regs->miimcom, MII_READ_COMMAND);
+
+ /* Wait for the transaction to finish */
+ while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+ cpu_relax();
+
+ /* Grab the value of the register from miimstat */
+ value = gfar_read(&regs->miimstat);
+
+ return value;
+}
+
+
+/* Reset the MIIM registers, and wait for the bus to free */
+int gfar_mdio_reset(struct mii_bus *bus)
+{
+ struct gfar_mii *regs = bus->priv;
+ unsigned int timeout = PHY_INIT_TIMEOUT;
+
+ spin_lock_bh(&bus->mdio_lock);
+
+ /* Reset the management interface */
+ gfar_write(&regs->miimcfg, MIIMCFG_RESET);
+
+ /* Setup the MII Mgmt clock speed */
+ gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+
+ /* Wait until the bus is free */
+ while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
+ timeout--)
+ cpu_relax();
+
+ spin_unlock_bh(&bus->mdio_lock);
+
+ if(timeout <= 0) {
+ printk(KERN_ERR "%s: The MII Bus is stuck!\n",
+ bus->name);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+
+int gfar_mdio_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct gianfar_mdio_data *pdata;
+ struct gfar_mii *regs;
+ struct mii_bus *new_bus;
+ int err = 0;
+
+ if (NULL == dev)
+ return -EINVAL;
+
+ new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
+
+ if (NULL == new_bus)
+ return -ENOMEM;
+
+ new_bus->name = "Gianfar MII Bus",
+ new_bus->read = &gfar_mdio_read,
+ new_bus->write = &gfar_mdio_write,
+ new_bus->reset = &gfar_mdio_reset,
+ new_bus->id = pdev->id;
+
+ pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
+
+ if (NULL == pdata) {
+ printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
+ return -ENODEV;
+ }
+
+ /* Set the PHY base address */
+ regs = (struct gfar_mii *) ioremap(pdata->paddr,
+ sizeof (struct gfar_mii));
+
+ if (NULL == regs) {
+ err = -ENOMEM;
+ goto reg_map_fail;
+ }
+
+ new_bus->priv = regs;
+
+ new_bus->irq = pdata->irq;
+
+ new_bus->dev = dev;
+ dev_set_drvdata(dev, new_bus);
+
+ err = mdiobus_register(new_bus);
+
+ if (0 != err) {
+ printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
+ new_bus->name);
+ goto bus_register_fail;
+ }
+
+ return 0;
+
+bus_register_fail:
+ iounmap((void *) regs);
+reg_map_fail:
+ kfree(new_bus);
+
+ return err;
+}
+
+
+int gfar_mdio_remove(struct device *dev)
+{
+ struct mii_bus *bus = dev_get_drvdata(dev);
+
+ mdiobus_unregister(bus);
+
+ dev_set_drvdata(dev, NULL);
+
+ iounmap((void *) (&bus->priv));
+ bus->priv = NULL;
+ kfree(bus);
+
+ return 0;
+}
+
+static struct device_driver gianfar_mdio_driver = {
+ .name = "fsl-gianfar_mdio",
+ .bus = &platform_bus_type,
+ .probe = gfar_mdio_probe,
+ .remove = gfar_mdio_remove,
+};
+
+int __init gfar_mdio_init(void)
+{
+ return driver_register(&gianfar_mdio_driver);
+}
+
+void __exit gfar_mdio_exit(void)
+{
+ driver_unregister(&gianfar_mdio_driver);
+}
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
new file mode 100644
index 000000000000..56e5665d5c9b
--- /dev/null
+++ b/drivers/net/gianfar_mii.h
@@ -0,0 +1,45 @@
+/*
+ * drivers/net/gianfar_mii.h
+ *
+ * Gianfar Ethernet Driver -- MII Management Bus Implementation
+ * Driver for the MDIO bus controller in the Gianfar register space
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-2004 Freescale Semiconductor, 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.
+ *
+ */
+#ifndef __GIANFAR_MII_H
+#define __GIANFAR_MII_H
+
+#define MIIMIND_BUSY 0x00000001
+#define MIIMIND_NOTVALID 0x00000004
+
+#define MII_READ_COMMAND 0x00000001
+
+#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+ | SUPPORTED_100baseT_Half \
+ | SUPPORTED_100baseT_Full \
+ | SUPPORTED_Autoneg \
+ | SUPPORTED_MII)
+
+struct gfar_mii {
+ u32 miimcfg; /* 0x.520 - MII Management Config Register */
+ u32 miimcom; /* 0x.524 - MII Management Command Register */
+ u32 miimadd; /* 0x.528 - MII Management Address Register */
+ u32 miimcon; /* 0x.52c - MII Management Control Register */
+ u32 miimstat; /* 0x.530 - MII Management Status Register */
+ u32 miimind; /* 0x.534 - MII Management Indicator Register */
+};
+
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
+int __init gfar_mdio_init(void);
+void __exit gfar_mdio_exit(void);
+#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c
deleted file mode 100644
index 7c965f268a82..000000000000
--- a/drivers/net/gianfar_phy.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * drivers/net/gianfar_phy.c
- *
- * Gianfar Ethernet Driver -- PHY handling
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
- * Based on 8260_io/fcc_enet.c
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright (c) 2002-2004 Freescale Semiconductor, 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.
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-
-#include "gianfar.h"
-#include "gianfar_phy.h"
-
-static void config_genmii_advert(struct gfar_mii_info *mii_info);
-static void genmii_setup_forced(struct gfar_mii_info *mii_info);
-static void genmii_restart_aneg(struct gfar_mii_info *mii_info);
-static int gbit_config_aneg(struct gfar_mii_info *mii_info);
-static int genmii_config_aneg(struct gfar_mii_info *mii_info);
-static int genmii_update_link(struct gfar_mii_info *mii_info);
-static int genmii_read_status(struct gfar_mii_info *mii_info);
-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum);
-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val);
-
-/* Write value to the PHY for this device to the register at regnum, */
-/* waiting until the write is done before it returns. All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
-{
- struct gfar_private *priv = netdev_priv(dev);
- struct gfar *regbase = priv->phyregs;
-
- /* Set the PHY address and the register address we want to write */
- gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
-
- /* Write out the value we want */
- gfar_write(&regbase->miimcon, value);
-
- /* Wait for the transaction to finish */
- while (gfar_read(&regbase->miimind) & MIIMIND_BUSY)
- cpu_relax();
-}
-
-/* Reads from register regnum in the PHY for device dev, */
-/* returning the value. Clears miimcom first. All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
-{
- struct gfar_private *priv = netdev_priv(dev);
- struct gfar *regbase = priv->phyregs;
- u16 value;
-
- /* Set the PHY address and the register address we want to read */
- gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
-
- /* Clear miimcom, and then initiate a read */
- gfar_write(&regbase->miimcom, 0);
- gfar_write(&regbase->miimcom, MII_READ_COMMAND);
-
- /* Wait for the transaction to finish */
- while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
- cpu_relax();
-
- /* Grab the value of the register from miimstat */
- value = gfar_read(&regbase->miimstat);
-
- return value;
-}
-
-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info)
-{
- if(mii_info->phyinfo->ack_interrupt)
- mii_info->phyinfo->ack_interrupt(mii_info);
-}
-
-
-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts)
-{
- mii_info->interrupts = interrupts;
- if(mii_info->phyinfo->config_intr)
- mii_info->phyinfo->config_intr(mii_info);
-}
-
-
-/* Writes MII_ADVERTISE with the appropriate values, after
- * sanitizing advertise to make sure only supported features
- * are advertised
- */
-static void config_genmii_advert(struct gfar_mii_info *mii_info)
-{
- u32 advertise;
- u16 adv;
-
- /* Only allow advertising what this PHY supports */
- mii_info->advertising &= mii_info->phyinfo->features;
- advertise = mii_info->advertising;
-
- /* Setup standard advertisement */
- adv = phy_read(mii_info, MII_ADVERTISE);
- adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
- if (advertise & ADVERTISED_10baseT_Half)
- adv |= ADVERTISE_10HALF;
- if (advertise & ADVERTISED_10baseT_Full)
- adv |= ADVERTISE_10FULL;
- if (advertise & ADVERTISED_100baseT_Half)
- adv |= ADVERTISE_100HALF;
- if (advertise & ADVERTISED_100baseT_Full)
- adv |= ADVERTISE_100FULL;
- phy_write(mii_info, MII_ADVERTISE, adv);
-}
-
-static void genmii_setup_forced(struct gfar_mii_info *mii_info)
-{
- u16 ctrl;
- u32 features = mii_info->phyinfo->features;
-
- ctrl = phy_read(mii_info, MII_BMCR);
-
- ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE);
- ctrl |= BMCR_RESET;
-
- switch(mii_info->speed) {
- case SPEED_1000:
- if(features & (SUPPORTED_1000baseT_Half
- | SUPPORTED_1000baseT_Full)) {
- ctrl |= BMCR_SPEED1000;
- break;
- }
- mii_info->speed = SPEED_100;
- case SPEED_100:
- if (features & (SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full)) {
- ctrl |= BMCR_SPEED100;
- break;
- }
- mii_info->speed = SPEED_10;
- case SPEED_10:
- if (features & (SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full))
- break;
- default: /* Unsupported speed! */
- printk(KERN_ERR "%s: Bad speed!\n",
- mii_info->dev->name);
- break;
- }
-
- phy_write(mii_info, MII_BMCR, ctrl);
-}
-
-
-/* Enable and Restart Autonegotiation */
-static void genmii_restart_aneg(struct gfar_mii_info *mii_info)
-{
- u16 ctl;
-
- ctl = phy_read(mii_info, MII_BMCR);
- ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
- phy_write(mii_info, MII_BMCR, ctl);
-}
-
-
-static int gbit_config_aneg(struct gfar_mii_info *mii_info)
-{
- u16 adv;
- u32 advertise;
-
- if(mii_info->autoneg) {
- /* Configure the ADVERTISE register */
- config_genmii_advert(mii_info);
- advertise = mii_info->advertising;
-
- adv = phy_read(mii_info, MII_1000BASETCONTROL);
- adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
- MII_1000BASETCONTROL_HALFDUPLEXCAP);
- if (advertise & SUPPORTED_1000baseT_Half)
- adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
- if (advertise & SUPPORTED_1000baseT_Full)
- adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
- phy_write(mii_info, MII_1000BASETCONTROL, adv);
-
- /* Start/Restart aneg */
- genmii_restart_aneg(mii_info);
- } else
- genmii_setup_forced(mii_info);
-
- return 0;
-}
-
-static int marvell_config_aneg(struct gfar_mii_info *mii_info)
-{
- /* The Marvell PHY has an errata which requires
- * that certain registers get written in order
- * to restart autonegotiation */
- phy_write(mii_info, MII_BMCR, BMCR_RESET);
-
- phy_write(mii_info, 0x1d, 0x1f);
- phy_write(mii_info, 0x1e, 0x200c);
- phy_write(mii_info, 0x1d, 0x5);
- phy_write(mii_info, 0x1e, 0);
- phy_write(mii_info, 0x1e, 0x100);
-
- gbit_config_aneg(mii_info);
-
- return 0;
-}
-static int genmii_config_aneg(struct gfar_mii_info *mii_info)
-{
- if (mii_info->autoneg) {
- config_genmii_advert(mii_info);
- genmii_restart_aneg(mii_info);
- } else
- genmii_setup_forced(mii_info);
-
- return 0;
-}
-
-
-static int genmii_update_link(struct gfar_mii_info *mii_info)
-{
- u16 status;
-
- /* Do a fake read */
- phy_read(mii_info, MII_BMSR);
-
- /* Read link and autonegotiation status */
- status = phy_read(mii_info, MII_BMSR);
- if ((status & BMSR_LSTATUS) == 0)
- mii_info->link = 0;
- else
- mii_info->link = 1;
-
- /* If we are autonegotiating, and not done,
- * return an error */
- if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE))
- return -EAGAIN;
-
- return 0;
-}
-
-static int genmii_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- if (mii_info->autoneg) {
- status = phy_read(mii_info, MII_LPA);
-
- if (status & (LPA_10FULL | LPA_100FULL))
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
- if (status & (LPA_100FULL | LPA_100HALF))
- mii_info->speed = SPEED_100;
- else
- mii_info->speed = SPEED_10;
- mii_info->pause = 0;
- }
- /* On non-aneg, we assume what we put in BMCR is the speed,
- * though magic-aneg shouldn't prevent this case from occurring
- */
-
- return 0;
-}
-static int marvell_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- /* If the link is up, read the speed and duplex */
- /* If we aren't autonegotiating, assume speeds
- * are as set */
- if (mii_info->autoneg && mii_info->link) {
- int speed;
- status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
-
-#if 0
- /* If speed and duplex aren't resolved,
- * return an error. Isn't this handled
- * by checking aneg?
- */
- if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
- return -EAGAIN;
-#endif
-
- /* Get the duplexity */
- if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
-
- /* Get the speed */
- speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
- switch(speed) {
- case MII_M1011_PHY_SPEC_STATUS_1000:
- mii_info->speed = SPEED_1000;
- break;
- case MII_M1011_PHY_SPEC_STATUS_100:
- mii_info->speed = SPEED_100;
- break;
- default:
- mii_info->speed = SPEED_10;
- break;
- }
- mii_info->pause = 0;
- }
-
- return 0;
-}
-
-
-static int cis820x_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- /* If the link is up, read the speed and duplex */
- /* If we aren't autonegotiating, assume speeds
- * are as set */
- if (mii_info->autoneg && mii_info->link) {
- int speed;
-
- status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
- if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
-
- speed = status & MII_CIS8201_AUXCONSTAT_SPEED;
-
- switch (speed) {
- case MII_CIS8201_AUXCONSTAT_GBIT:
- mii_info->speed = SPEED_1000;
- break;
- case MII_CIS8201_AUXCONSTAT_100:
- mii_info->speed = SPEED_100;
- break;
- default:
- mii_info->speed = SPEED_10;
- break;
- }
- }
-
- return 0;
-}
-
-static int marvell_ack_interrupt(struct gfar_mii_info *mii_info)
-{
- /* Clear the interrupts by reading the reg */
- phy_read(mii_info, MII_M1011_IEVENT);
-
- return 0;
-}
-
-static int marvell_config_intr(struct gfar_mii_info *mii_info)
-{
- if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
- else
- phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
-
- return 0;
-}
-
-static int cis820x_init(struct gfar_mii_info *mii_info)
-{
- phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
- MII_CIS8201_AUXCONSTAT_INIT);
- phy_write(mii_info, MII_CIS8201_EXT_CON1,
- MII_CIS8201_EXTCON1_INIT);
-
- return 0;
-}
-
-static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info)
-{
- phy_read(mii_info, MII_CIS8201_ISTAT);
-
- return 0;
-}
-
-static int cis820x_config_intr(struct gfar_mii_info *mii_info)
-{
- if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
- else
- phy_write(mii_info, MII_CIS8201_IMASK, 0);
-
- return 0;
-}
-
-#define DM9161_DELAY 10
-
-static int dm9161_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- /* If the link is up, read the speed and duplex */
- /* If we aren't autonegotiating, assume speeds
- * are as set */
- if (mii_info->autoneg && mii_info->link) {
- status = phy_read(mii_info, MII_DM9161_SCSR);
- if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
- mii_info->speed = SPEED_100;
- else
- mii_info->speed = SPEED_10;
-
- if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
- }
-
- return 0;
-}
-
-
-static int dm9161_config_aneg(struct gfar_mii_info *mii_info)
-{
- struct dm9161_private *priv = mii_info->priv;
-
- if(0 == priv->resetdone)
- return -EAGAIN;
-
- return 0;
-}
-
-static void dm9161_timer(unsigned long data)
-{
- struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
- struct dm9161_private *priv = mii_info->priv;
- u16 status = phy_read(mii_info, MII_BMSR);
-
- if (status & BMSR_ANEGCOMPLETE) {
- priv->resetdone = 1;
- } else
- mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
-}
-
-static int dm9161_init(struct gfar_mii_info *mii_info)
-{
- struct dm9161_private *priv;
-
- /* Allocate the private data structure */
- priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL);
-
- if (NULL == priv)
- return -ENOMEM;
-
- mii_info->priv = priv;
-
- /* Reset is not done yet */
- priv->resetdone = 0;
-
- /* Isolate the PHY */
- phy_write(mii_info, MII_BMCR, BMCR_ISOLATE);
-
- /* Do not bypass the scrambler/descrambler */
- phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
-
- /* Clear 10BTCSR to default */
- phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
-
- /* Reconnect the PHY, and enable Autonegotiation */
- phy_write(mii_info, MII_BMCR, BMCR_ANENABLE);
-
- /* Start a timer for DM9161_DELAY seconds to wait
- * for the PHY to be ready */
- init_timer(&priv->timer);
- priv->timer.function = &dm9161_timer;
- priv->timer.data = (unsigned long) mii_info;
- mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
-
- return 0;
-}
-
-static void dm9161_close(struct gfar_mii_info *mii_info)
-{
- struct dm9161_private *priv = mii_info->priv;
-
- del_timer_sync(&priv->timer);
- kfree(priv);
-}
-
-#if 0
-static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info)
-{
- phy_read(mii_info, MII_DM9161_INTR);
-
- return 0;
-}
-#endif
-
-/* Cicada 820x */
-static struct phy_info phy_info_cis820x = {
- 0x000fc440,
- "Cicada Cis8204",
- 0x000fffc0,
- .features = MII_GBIT_FEATURES,
- .init = &cis820x_init,
- .config_aneg = &gbit_config_aneg,
- .read_status = &cis820x_read_status,
- .ack_interrupt = &cis820x_ack_interrupt,
- .config_intr = &cis820x_config_intr,
-};
-
-static struct phy_info phy_info_dm9161 = {
- .phy_id = 0x0181b880,
- .name = "Davicom DM9161E",
- .phy_id_mask = 0x0ffffff0,
- .init = dm9161_init,
- .config_aneg = dm9161_config_aneg,
- .read_status = dm9161_read_status,
- .close = dm9161_close,
-};
-
-static struct phy_info phy_info_marvell = {
- .phy_id = 0x01410c00,
- .phy_id_mask = 0xffffff00,
- .name = "Marvell 88E1101/88E1111",
- .features = MII_GBIT_FEATURES,
- .config_aneg = &marvell_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
-};
-
-static struct phy_info phy_info_genmii= {
- .phy_id = 0x00000000,
- .phy_id_mask = 0x00000000,
- .name = "Generic MII",
- .features = MII_BASIC_FEATURES,
- .config_aneg = genmii_config_aneg,
- .read_status = genmii_read_status,
-};
-
-static struct phy_info *phy_info[] = {
- &phy_info_cis820x,
- &phy_info_marvell,
- &phy_info_dm9161,
- &phy_info_genmii,
- NULL
-};
-
-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum)
-{
- u16 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&mii_info->mdio_lock, flags);
- retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
- spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-
- return retval;
-}
-
-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mii_info->mdio_lock, flags);
- mii_info->mdio_write(mii_info->dev,
- mii_info->mii_id,
- regnum, val);
- spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-}
-
-/* Use the PHY ID registers to determine what type of PHY is attached
- * to device dev. return a struct phy_info structure describing that PHY
- */
-struct phy_info * get_phy_info(struct gfar_mii_info *mii_info)
-{
- u16 phy_reg;
- u32 phy_ID;
- int i;
- struct phy_info *theInfo = NULL;
- struct net_device *dev = mii_info->dev;
-
- /* Grab the bits from PHYIR1, and put them in the upper half */
- phy_reg = phy_read(mii_info, MII_PHYSID1);
- phy_ID = (phy_reg & 0xffff) << 16;
-
- /* Grab the bits from PHYIR2, and put them in the lower half */
- phy_reg = phy_read(mii_info, MII_PHYSID2);
- phy_ID |= (phy_reg & 0xffff);
-
- /* loop through all the known PHY types, and find one that */
- /* matches the ID we read from the PHY. */
- for (i = 0; phy_info[i]; i++)
- if (phy_info[i]->phy_id ==
- (phy_ID & phy_info[i]->phy_id_mask)) {
- theInfo = phy_info[i];
- break;
- }
-
- /* This shouldn't happen, as we have generic PHY support */
- if (theInfo == NULL) {
- printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
- return NULL;
- } else {
- printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name,
- phy_ID);
- }
-
- return theInfo;
-}
diff --git a/drivers/net/gianfar_phy.h b/drivers/net/gianfar_phy.h
deleted file mode 100644
index 1e9b3abf1e6d..000000000000
--- a/drivers/net/gianfar_phy.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * drivers/net/gianfar_phy.h
- *
- * Gianfar Ethernet Driver -- PHY handling
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
- * Based on 8260_io/fcc_enet.c
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright (c) 2002-2004 Freescale Semiconductor, 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.
- *
- */
-#ifndef __GIANFAR_PHY_H
-#define __GIANFAR_PHY_H
-
-#define MII_end ((u32)-2)
-#define MII_read ((u32)-1)
-
-#define MIIMIND_BUSY 0x00000001
-#define MIIMIND_NOTVALID 0x00000004
-
-#define GFAR_AN_TIMEOUT 2000
-
-/* 1000BT control (Marvell & BCM54xx at least) */
-#define MII_1000BASETCONTROL 0x09
-#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200
-#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100
-
-/* Cicada Extended Control Register 1 */
-#define MII_CIS8201_EXT_CON1 0x17
-#define MII_CIS8201_EXTCON1_INIT 0x0000
-
-/* Cicada Interrupt Mask Register */
-#define MII_CIS8201_IMASK 0x19
-#define MII_CIS8201_IMASK_IEN 0x8000
-#define MII_CIS8201_IMASK_SPEED 0x4000
-#define MII_CIS8201_IMASK_LINK 0x2000
-#define MII_CIS8201_IMASK_DUPLEX 0x1000
-#define MII_CIS8201_IMASK_MASK 0xf000
-
-/* Cicada Interrupt Status Register */
-#define MII_CIS8201_ISTAT 0x1a
-#define MII_CIS8201_ISTAT_STATUS 0x8000
-#define MII_CIS8201_ISTAT_SPEED 0x4000
-#define MII_CIS8201_ISTAT_LINK 0x2000
-#define MII_CIS8201_ISTAT_DUPLEX 0x1000
-
-/* Cicada Auxiliary Control/Status Register */
-#define MII_CIS8201_AUX_CONSTAT 0x1c
-#define MII_CIS8201_AUXCONSTAT_INIT 0x0004
-#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020
-#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018
-#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010
-#define MII_CIS8201_AUXCONSTAT_100 0x0008
-
-/* 88E1011 PHY Status Register */
-#define MII_M1011_PHY_SPEC_STATUS 0x11
-#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000
-#define MII_M1011_PHY_SPEC_STATUS_100 0x4000
-#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000
-#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000
-#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800
-#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400
-
-#define MII_M1011_IEVENT 0x13
-#define MII_M1011_IEVENT_CLEAR 0x0000
-
-#define MII_M1011_IMASK 0x12
-#define MII_M1011_IMASK_INIT 0x6400
-#define MII_M1011_IMASK_CLEAR 0x0000
-
-#define MII_DM9161_SCR 0x10
-#define MII_DM9161_SCR_INIT 0x0610
-
-/* DM9161 Specified Configuration and Status Register */
-#define MII_DM9161_SCSR 0x11
-#define MII_DM9161_SCSR_100F 0x8000
-#define MII_DM9161_SCSR_100H 0x4000
-#define MII_DM9161_SCSR_10F 0x2000
-#define MII_DM9161_SCSR_10H 0x1000
-
-/* DM9161 Interrupt Register */
-#define MII_DM9161_INTR 0x15
-#define MII_DM9161_INTR_PEND 0x8000
-#define MII_DM9161_INTR_DPLX_MASK 0x0800
-#define MII_DM9161_INTR_SPD_MASK 0x0400
-#define MII_DM9161_INTR_LINK_MASK 0x0200
-#define MII_DM9161_INTR_MASK 0x0100
-#define MII_DM9161_INTR_DPLX_CHANGE 0x0010
-#define MII_DM9161_INTR_SPD_CHANGE 0x0008
-#define MII_DM9161_INTR_LINK_CHANGE 0x0004
-#define MII_DM9161_INTR_INIT 0x0000
-#define MII_DM9161_INTR_STOP \
-(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
- | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
-
-/* DM9161 10BT Configuration/Status */
-#define MII_DM9161_10BTCSR 0x12
-#define MII_DM9161_10BTCSR_INIT 0x7800
-
-#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
- SUPPORTED_10baseT_Full | \
- SUPPORTED_100baseT_Half | \
- SUPPORTED_100baseT_Full | \
- SUPPORTED_Autoneg | \
- SUPPORTED_TP | \
- SUPPORTED_MII)
-
-#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
- SUPPORTED_1000baseT_Half | \
- SUPPORTED_1000baseT_Full)
-
-#define MII_READ_COMMAND 0x00000001
-
-#define MII_INTERRUPT_DISABLED 0x0
-#define MII_INTERRUPT_ENABLED 0x1
-/* Taken from mii_if_info and sungem_phy.h */
-struct gfar_mii_info {
- /* Information about the PHY type */
- /* And management functions */
- struct phy_info *phyinfo;
-
- /* forced speed & duplex (no autoneg)
- * partner speed & duplex & pause (autoneg)
- */
- int speed;
- int duplex;
- int pause;
-
- /* The most recently read link state */
- int link;
-
- /* Enabled Interrupts */
- u32 interrupts;
-
- u32 advertising;
- int autoneg;
- int mii_id;
-
- /* private data pointer */
- /* For use by PHYs to maintain extra state */
- void *priv;
-
- /* Provided by host chip */
- struct net_device *dev;
-
- /* A lock to ensure that only one thing can read/write
- * the MDIO bus at a time */
- spinlock_t mdio_lock;
-
- /* Provided by ethernet driver */
- int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
- void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
-};
-
-/* struct phy_info: a structure which defines attributes for a PHY
- *
- * id will contain a number which represents the PHY. During
- * startup, the driver will poll the PHY to find out what its
- * UID--as defined by registers 2 and 3--is. The 32-bit result
- * gotten from the PHY will be ANDed with phy_id_mask to
- * discard any bits which may change based on revision numbers
- * unimportant to functionality
- *
- * There are 6 commands which take a gfar_mii_info structure.
- * Each PHY must declare config_aneg, and read_status.
- */
-struct phy_info {
- u32 phy_id;
- char *name;
- unsigned int phy_id_mask;
- u32 features;
-
- /* Called to initialize the PHY */
- int (*init)(struct gfar_mii_info *mii_info);
-
- /* Called to suspend the PHY for power */
- int (*suspend)(struct gfar_mii_info *mii_info);
-
- /* Reconfigures autonegotiation (or disables it) */
- int (*config_aneg)(struct gfar_mii_info *mii_info);
-
- /* Determines the negotiated speed and duplex */
- int (*read_status)(struct gfar_mii_info *mii_info);
-
- /* Clears any pending interrupts */
- int (*ack_interrupt)(struct gfar_mii_info *mii_info);
-
- /* Enables or disables interrupts */
- int (*config_intr)(struct gfar_mii_info *mii_info);
-
- /* Clears up any memory if needed */
- void (*close)(struct gfar_mii_info *mii_info);
-};
-
-struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
-int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
-
-struct dm9161_private {
- struct timer_list timer;
- int resetdone;
-};
-
-#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 0b230222bfea..90999867a32c 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -293,7 +293,7 @@ static int sp_header(struct sk_buff *skb, struct net_device *dev,
{
#ifdef CONFIG_INET
if (type != htons(ETH_P_AX25))
- return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
+ return ax25_hard_header(skb, dev, type, daddr, saddr, len);
#endif
return 0;
}
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index de087cd609d9..896aa02000d7 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -1,6 +1,7 @@
config MKISS
tristate "Serial port KISS driver"
depends on AX25
+ select CRC16
---help---
KISS is a protocol used for the exchange of data between a computer
and a Terminal Node Controller (a small embedded system commonly
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 5298096afbdb..e4188d082f01 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -40,7 +40,7 @@
/*****************************************************************************/
-#include <linux/config.h>
+#include <linux/crc-ccitt.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -48,18 +48,12 @@
#include <linux/workqueue.h>
#include <linux/fs.h>
#include <linux/parport.h>
-#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
#include <linux/if_arp.h>
-#include <linux/kmod.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
#include <linux/jiffies.h>
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-/* prototypes for ax25_encapsulate and ax25_rebuild_header */
#include <net/ax25.h>
-#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
-#include <linux/crc-ccitt.h>
+#include <asm/uaccess.h>
/* --------------------------------------------------------------------- */
@@ -1177,13 +1171,8 @@ static void baycom_probe(struct net_device *dev)
/* Fill in the fields of the device structure */
bc->skb = NULL;
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
-#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
- dev->hard_header = NULL;
- dev->rebuild_header = NULL;
-#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
dev->set_mac_address = baycom_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 2946e037a9b1..cb43a9d28774 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -144,7 +144,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
{
struct bpqdev *bpq;
- list_for_each_entry(bpq, &bpq_devices, bpq_list) {
+ list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
if (bpq->ethdev == dev)
return bpq->axdev;
}
@@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0)
return SEQ_START_TOKEN;
- list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
+ list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
if (i == *pos)
return bpqdev;
}
@@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
p = ((struct bpqdev *)v)->bpq_list.next;
return (p == &bpq_devices) ? NULL
- : list_entry(p, struct bpqdev, bpq_list);
+ : rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
@@ -488,7 +488,7 @@ static void bpq_setup(struct net_device *dev)
dev->flags = 0;
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
#endif
@@ -561,8 +561,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
if (!dev_is_ethdev(dev))
return NOTIFY_DONE;
- rcu_read_lock();
-
switch (event) {
case NETDEV_UP: /* new ethernet device -> new BPQ interface */
if (bpq_get_ax25_dev(dev) == NULL)
@@ -581,7 +579,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
default:
break;
}
- rcu_read_unlock();
return NOTIFY_DONE;
}
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index f515245a3fd0..3be3f916643a 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -449,12 +449,12 @@ module_exit(dmascc_exit);
static void dev_setup(struct net_device *dev)
{
dev->type = ARPHRD_AX25;
- dev->hard_header_len = 73;
+ dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->mtu = 1500;
- dev->addr_len = 7;
+ dev->addr_len = AX25_ADDR_LEN;
dev->tx_queue_len = 64;
- memcpy(dev->broadcast, ax25_broadcast, 7);
- memcpy(dev->dev_addr, ax25_test, 7);
+ memcpy(dev->broadcast, ax25_broadcast, AX25_ADDR_LEN);
+ memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
}
static int __init setup_adapter(int card_base, int type, int n)
@@ -600,7 +600,7 @@ static int __init setup_adapter(int card_base, int type, int n)
dev->do_ioctl = scc_ioctl;
dev->hard_start_xmit = scc_send_packet;
dev->get_stats = scc_get_stats;
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
dev->set_mac_address = scc_set_mac_address;
}
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index b4c836e4fe86..dacc7687b97f 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -42,7 +42,6 @@
/*****************************************************************************/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/net.h>
@@ -52,20 +51,14 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/bitops.h>
-#include <asm/uaccess.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/hdlcdrv.h>
-/* prototypes for ax25_encapsulate and ax25_rebuild_header */
#include <net/ax25.h>
+#include <asm/uaccess.h>
-/* make genksyms happy */
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
#include <linux/crc-ccitt.h>
/* --------------------------------------------------------------------- */
@@ -708,13 +701,8 @@ static void hdlcdrv_setup(struct net_device *dev)
s->skb = NULL;
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
-#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
- dev->hard_header = NULL;
- dev->rebuild_header = NULL;
-#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
dev->set_mac_address = hdlcdrv_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 63b1a2b86acb..85d6dc005be0 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -14,13 +14,14 @@
*
* Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
* Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
+ * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
*/
-
#include <linux/config.h>
#include <linux/module.h>
#include <asm/system.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
+#include <linux/crc16.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
@@ -39,11 +40,6 @@
#include <net/ax25.h>
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#endif
-
#define AX_MTU 236
/* SLIP/KISS protocol characters. */
@@ -80,9 +76,13 @@ struct mkiss {
int mode;
int crcmode; /* MW: for FlexNet, SMACK etc. */
-#define CRC_MODE_NONE 0
-#define CRC_MODE_FLEX 1
-#define CRC_MODE_SMACK 2
+ int crcauto; /* CRC auto mode */
+
+#define CRC_MODE_NONE 0
+#define CRC_MODE_FLEX 1
+#define CRC_MODE_SMACK 2
+#define CRC_MODE_FLEX_TEST 3
+#define CRC_MODE_SMACK_TEST 4
atomic_t refcnt;
struct semaphore dead_sem;
@@ -151,6 +151,21 @@ static int check_crc_flex(unsigned char *cp, int size)
return 0;
}
+static int check_crc_16(unsigned char *cp, int size)
+{
+ unsigned short crc = 0x0000;
+
+ if (size < 3)
+ return -1;
+
+ crc = crc16(0, cp, size);
+
+ if (crc != 0x0000)
+ return -1;
+
+ return 0;
+}
+
/*
* Standard encapsulation
*/
@@ -237,19 +252,42 @@ static void ax_bump(struct mkiss *ax)
spin_lock_bh(&ax->buflock);
if (ax->rbuff[0] > 0x0f) {
- if (ax->rbuff[0] & 0x20) {
- ax->crcmode = CRC_MODE_FLEX;
+ if (ax->rbuff[0] & 0x80) {
+ if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
+ ax->stats.rx_errors++;
+ spin_unlock_bh(&ax->buflock);
+
+ return;
+ }
+ if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
+ printk(KERN_INFO
+ "mkiss: %s: Switchting to crc-smack\n",
+ ax->dev->name);
+ ax->crcmode = CRC_MODE_SMACK;
+ }
+ ax->rcount -= 2;
+ *ax->rbuff &= ~0x80;
+ } else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
- ax->stats.rx_errors++;
+ ax->stats.rx_errors++;
+ spin_unlock_bh(&ax->buflock);
return;
}
+ if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
+ printk(KERN_INFO
+ "mkiss: %s: Switchting to crc-flexnet\n",
+ ax->dev->name);
+ ax->crcmode = CRC_MODE_FLEX;
+ }
ax->rcount -= 2;
- /* dl9sau bugfix: the trailling two bytes flexnet crc
- * will not be passed to the kernel. thus we have
- * to correct the kissparm signature, because it
- * indicates a crc but there's none
+
+ /*
+ * dl9sau bugfix: the trailling two bytes flexnet crc
+ * will not be passed to the kernel. thus we have to
+ * correct the kissparm signature, because it indicates
+ * a crc but there's none
*/
- *ax->rbuff &= ~0x20;
+ *ax->rbuff &= ~0x20;
}
}
spin_unlock_bh(&ax->buflock);
@@ -417,20 +455,69 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
p = icp;
spin_lock_bh(&ax->buflock);
- switch (ax->crcmode) {
- unsigned short crc;
+ if ((*p & 0x0f) != 0) {
+ /* Configuration Command (kissparms(1).
+ * Protocol spec says: never append CRC.
+ * This fixes a very old bug in the linux
+ * kiss driver. -- dl9sau */
+ switch (*p & 0xff) {
+ case 0x85:
+ /* command from userspace especially for us,
+ * not for delivery to the tnc */
+ if (len > 1) {
+ int cmd = (p[1] & 0xff);
+ switch(cmd) {
+ case 3:
+ ax->crcmode = CRC_MODE_SMACK;
+ break;
+ case 2:
+ ax->crcmode = CRC_MODE_FLEX;
+ break;
+ case 1:
+ ax->crcmode = CRC_MODE_NONE;
+ break;
+ case 0:
+ default:
+ ax->crcmode = CRC_MODE_SMACK_TEST;
+ cmd = 0;
+ }
+ ax->crcauto = (cmd ? 0 : 1);
+ printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
+ }
+ spin_unlock_bh(&ax->buflock);
+ netif_start_queue(dev);
- case CRC_MODE_FLEX:
- *p |= 0x20;
- crc = calc_crc_flex(p, len);
- count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
- break;
+ return;
+ default:
+ count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+ }
+ } else {
+ unsigned short crc;
+ switch (ax->crcmode) {
+ case CRC_MODE_SMACK_TEST:
+ ax->crcmode = CRC_MODE_FLEX_TEST;
+ printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
+ // fall through
+ case CRC_MODE_SMACK:
+ *p |= 0x80;
+ crc = swab16(crc16(0, p, len));
+ count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+ break;
+ case CRC_MODE_FLEX_TEST:
+ ax->crcmode = CRC_MODE_NONE;
+ printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
+ // fall through
+ case CRC_MODE_FLEX:
+ *p |= 0x20;
+ crc = calc_crc_flex(p, len);
+ count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+ break;
+
+ default:
+ count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+ }
+ }
- default:
- count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
- break;
- }
-
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
ax->stats.tx_packets++;
@@ -439,8 +526,6 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
ax->dev->trans_start = jiffies;
ax->xleft = count - actual;
ax->xhead = ax->xbuff + actual;
-
- spin_unlock_bh(&ax->buflock);
}
/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
@@ -500,7 +585,7 @@ static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short
{
#ifdef CONFIG_INET
if (type != htons(ETH_P_AX25))
- return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
+ return ax25_hard_header(skb, dev, type, daddr, saddr, len);
#endif
return 0;
}
@@ -622,7 +707,7 @@ static void ax_setup(struct net_device *dev)
* best way to fix this is to use a rwlock in the tty struct, but for now we
* use a single global rwlock for all ttys in ppp line discipline.
*/
-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(disc_data_lock);
static struct mkiss *mkiss_get(struct tty_struct *tty)
{
@@ -643,6 +728,8 @@ static void mkiss_put(struct mkiss *ax)
up(&ax->dead_sem);
}
+static int crc_force = 0; /* Can be overridden with insmod */
+
static int mkiss_open(struct tty_struct *tty)
{
struct net_device *dev;
@@ -682,6 +769,33 @@ static int mkiss_open(struct tty_struct *tty)
if (register_netdev(dev))
goto out_free_buffers;
+ /* after register_netdev() - because else printk smashes the kernel */
+ switch (crc_force) {
+ case 3:
+ ax->crcmode = CRC_MODE_SMACK;
+ printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
+ ax->dev->name);
+ break;
+ case 2:
+ ax->crcmode = CRC_MODE_FLEX;
+ printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
+ ax->dev->name);
+ break;
+ case 1:
+ ax->crcmode = CRC_MODE_NONE;
+ printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
+ ax->dev->name);
+ break;
+ case 0:
+ /* fall through */
+ default:
+ crc_force = 0;
+ printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
+ ax->dev->name);
+ ax->crcmode = CRC_MODE_SMACK_TEST;
+ }
+ ax->crcauto = (crc_force ? 0 : 1);
+
netif_start_queue(dev);
/* Done. We have linked the TTY line to a channel. */
@@ -765,7 +879,6 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
case SIOCSIFHWADDR: {
char addr[AX25_ADDR_LEN];
-printk(KERN_INFO "In SIOCSIFHWADDR");
if (copy_from_user(&addr,
(void __user *) arg, AX25_ADDR_LEN)) {
@@ -864,6 +977,7 @@ out:
}
static struct tty_ldisc ax_ldisc = {
+ .owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "mkiss",
.open = mkiss_open,
@@ -904,6 +1018,8 @@ static void __exit mkiss_exit_driver(void)
MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
+MODULE_PARM(crc_force, "i");
+MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
MODULE_LICENSE("GPL");
MODULE_ALIAS_LDISC(N_AX25);
diff --git a/drivers/net/hamradio/mkiss.h b/drivers/net/hamradio/mkiss.h
deleted file mode 100644
index 4ab700478598..000000000000
--- a/drivers/net/hamradio/mkiss.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
- * Defines for the Multi-KISS driver.
- ****************************************************************************/
-
-#define AX25_MAXDEV 16 /* MAX number of AX25 channels;
- This can be overridden with
- insmod -oax25_maxdev=nnn */
-#define AX_MTU 236
-
-/* SLIP/KISS protocol characters. */
-#define END 0300 /* indicates end of frame */
-#define ESC 0333 /* indicates byte stuffing */
-#define ESC_END 0334 /* ESC ESC_END means END 'data' */
-#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
-
-struct ax_disp {
- int magic;
-
- /* Various fields. */
- struct tty_struct *tty; /* ptr to TTY structure */
- struct net_device *dev; /* easy for intr handling */
-
- /* These are pointers to the malloc()ed frame buffers. */
- unsigned char *rbuff; /* receiver buffer */
- int rcount; /* received chars counter */
- unsigned char *xbuff; /* transmitter buffer */
- unsigned char *xhead; /* pointer to next byte to XMIT */
- int xleft; /* bytes left in XMIT queue */
-
- /* SLIP interface statistics. */
- unsigned long rx_packets; /* inbound frames counter */
- unsigned long tx_packets; /* outbound frames counter */
- unsigned long rx_bytes; /* inbound bytes counter */
- unsigned long tx_bytes; /* outbound bytes counter */
- unsigned long rx_errors; /* Parity, etc. errors */
- unsigned long tx_errors; /* Planned stuff */
- unsigned long rx_dropped; /* No memory for skb */
- unsigned long tx_dropped; /* When MTU change */
- unsigned long rx_over_errors; /* Frame bigger then SLIP buf. */
-
- /* Detailed SLIP statistics. */
- int mtu; /* Our mtu (to spot changes!) */
- int buffsize; /* Max buffers sizes */
-
-
- unsigned long flags; /* Flag values/ mode etc */
- /* long req'd: used by set_bit --RR */
-#define AXF_INUSE 0 /* Channel in use */
-#define AXF_ESCAPE 1 /* ESC received */
-#define AXF_ERROR 2 /* Parity, etc. error */
-#define AXF_KEEPTEST 3 /* Keepalive test flag */
-#define AXF_OUTWAIT 4 /* is outpacket was flag */
-
- int mode;
- int crcmode; /* MW: for FlexNet, SMACK etc. */
-#define CRC_MODE_NONE 0
-#define CRC_MODE_FLEX 1
-#define CRC_MODE_SMACK 2
- spinlock_t buflock; /* lock for rbuf and xbuf */
-};
-
-#define AX25_MAGIC 0x5316
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index c27e417f32bf..6ace0e914fd1 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1557,7 +1557,7 @@ static void scc_net_setup(struct net_device *dev)
dev->stop = scc_net_close;
dev->hard_start_xmit = scc_net_tx;
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
dev->set_mac_address = scc_net_set_mac_address;
dev->get_stats = scc_net_get_stats;
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 41213ef602dc..fe22479eb202 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -60,15 +60,7 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-/* prototypes for ax25_encapsulate and ax25_rebuild_header */
#include <net/ax25.h>
-#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
-
-/* make genksyms happy */
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
@@ -170,7 +162,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);
/* --------------------------------------------------------------------- */
@@ -1116,23 +1108,17 @@ static void yam_setup(struct net_device *dev)
skb_queue_head_init(&yp->send_queue);
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
-#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
- dev->hard_header = NULL;
- dev->rebuild_header = NULL;
-#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
dev->set_mac_address = yam_set_mac_address;
- dev->type = ARPHRD_AX25; /* AF_AX25 device */
- dev->hard_header_len = 73; /* We do digipeaters now */
- dev->mtu = 256; /* AX25 is the default */
- dev->addr_len = 7; /* sizeof an ax.25 address */
- memcpy(dev->broadcast, ax25_bcast, 7);
- memcpy(dev->dev_addr, ax25_test, 7);
-
+ dev->type = ARPHRD_AX25;
+ dev->hard_header_len = AX25_MAX_HEADER_LEN;
+ dev->mtu = AX25_MTU;
+ dev->addr_len = AX25_ADDR_LEN;
+ memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
+ memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
}
static int __init yam_init_driver(void)
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index cf0ac6fda1a1..b71fab6e34f4 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -2517,10 +2517,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
if (time_after_eq(jiffies, time)) /* no signal->no logout */
@@ -2536,10 +2534,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
#ifdef HP100_DEBUG
@@ -2577,10 +2573,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
hp100_orb(HP100_AUTO_MODE, MAC_CFG_3); /* Autosel back on */
@@ -2591,10 +2585,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
if (time_before_eq(time, jiffies)) {
@@ -2606,10 +2598,8 @@ static int hp100_down_vg_link(struct net_device *dev)
time = jiffies + (2 * HZ); /* This seems to take a while.... */
do {
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
return 0;
@@ -2659,10 +2649,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
do {
if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
/* Start an addressed training and optionally request promiscuous port */
@@ -2697,10 +2685,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
do {
if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_before(jiffies, time));
if (time_after_eq(jiffies, time)) {
@@ -2723,10 +2709,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
#endif
break;
}
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
}
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index 0de3bb906174..14e9b6315f20 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -1875,6 +1875,9 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
rc = -ENODEV;
goto bail;
}
+
+ /* Disable any PHY features not supported by the platform */
+ ep->phy_mii.def->features &= ~emacdata->phy_feat_exc;
/* Setup initial PHY config & startup aneg */
if (ep->phy_mii.def->ops->init)
@@ -1882,6 +1885,34 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
netif_carrier_off(ndev);
if (ep->phy_mii.def->features & SUPPORTED_Autoneg)
ep->want_autoneg = 1;
+ else {
+ ep->want_autoneg = 0;
+
+ /* Select highest supported speed/duplex */
+ if (ep->phy_mii.def->features & SUPPORTED_1000baseT_Full) {
+ ep->phy_mii.speed = SPEED_1000;
+ ep->phy_mii.duplex = DUPLEX_FULL;
+ } else if (ep->phy_mii.def->features &
+ SUPPORTED_1000baseT_Half) {
+ ep->phy_mii.speed = SPEED_1000;
+ ep->phy_mii.duplex = DUPLEX_HALF;
+ } else if (ep->phy_mii.def->features &
+ SUPPORTED_100baseT_Full) {
+ ep->phy_mii.speed = SPEED_100;
+ ep->phy_mii.duplex = DUPLEX_FULL;
+ } else if (ep->phy_mii.def->features &
+ SUPPORTED_100baseT_Half) {
+ ep->phy_mii.speed = SPEED_100;
+ ep->phy_mii.duplex = DUPLEX_HALF;
+ } else if (ep->phy_mii.def->features &
+ SUPPORTED_10baseT_Full) {
+ ep->phy_mii.speed = SPEED_10;
+ ep->phy_mii.duplex = DUPLEX_FULL;
+ } else {
+ ep->phy_mii.speed = SPEED_10;
+ ep->phy_mii.duplex = DUPLEX_HALF;
+ }
+ }
emac_start_link(ep, NULL);
/* read the MAC Address */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 32d5fabd4b10..a2c4dd4fb221 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -99,7 +99,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs
static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
#ifdef CONFIG_PROC_FS
-#define IBMVETH_PROC_DIR "ibmveth"
+#define IBMVETH_PROC_DIR "net/ibmveth"
static struct proc_dir_entry *ibmveth_proc_dir;
#endif
@@ -1010,7 +1010,7 @@ static int __devexit ibmveth_remove(struct vio_dev *dev)
#ifdef CONFIG_PROC_FS
static void ibmveth_proc_register_driver(void)
{
- ibmveth_proc_dir = create_proc_entry(IBMVETH_PROC_DIR, S_IFDIR, proc_net);
+ ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, NULL);
if (ibmveth_proc_dir) {
SET_MODULE_OWNER(ibmveth_proc_dir);
}
@@ -1018,7 +1018,7 @@ static void ibmveth_proc_register_driver(void)
static void ibmveth_proc_unregister_driver(void)
{
- remove_proc_entry(IBMVETH_PROC_DIR, proc_net);
+ remove_proc_entry(IBMVETH_PROC_DIR, NULL);
}
static void *ibmveth_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index ca5914091d3a..d54156f11e61 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -400,5 +400,15 @@ config VIA_FIR
To compile it as a module, choose M here: the module will be called
via-ircc.
+config PXA_FICP
+ tristate "Intel PXA2xx Internal FICP"
+ depends on ARCH_PXA && IRDA
+ help
+ Say Y or M here if you want to build support for the PXA2xx
+ built-in IRDA interface which can support both SIR and FIR.
+ This driver relies on platform specific helper routines so
+ available capabilities may vary from one PXA2xx target to
+ another.
+
endmenu
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
index 29a8bd812b21..e7a8b7f7f5dd 100644
--- a/drivers/net/irda/Makefile
+++ b/drivers/net/irda/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
obj-$(CONFIG_ALI_FIR) += ali-ircc.o
obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
obj-$(CONFIG_VIA_FIR) += via-ircc.o
+obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o
# Old dongle drivers for old SIR drivers
obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o
obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 46e0022d3258..6c766fdc51a6 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -267,7 +267,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
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/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
new file mode 100644
index 000000000000..aef80f5e7c9c
--- /dev/null
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -0,0 +1,871 @@
+/*
+ * linux/drivers/net/irda/pxaficp_ir.c
+ *
+ * Based on sa1100_ir.c by Russell King
+ *
+ * Changes copyright (C) 2003-2005 MontaVista 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.
+ *
+ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/slab.h>
+#include <linux/rtnetlink.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/pxa-regs.h>
+
+#ifdef CONFIG_MACH_MAINSTONE
+#include <asm/arch/mainstone.h>
+#endif
+
+#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
+#define IrSR_RXPL_POS_IS_ZERO 0x0
+#define IrSR_TXPL_NEG_IS_ZERO (1<<3)
+#define IrSR_TXPL_POS_IS_ZERO 0x0
+#define IrSR_XMODE_PULSE_1_6 (1<<2)
+#define IrSR_XMODE_PULSE_3_16 0x0
+#define IrSR_RCVEIR_IR_MODE (1<<1)
+#define IrSR_RCVEIR_UART_MODE 0x0
+#define IrSR_XMITIR_IR_MODE (1<<0)
+#define IrSR_XMITIR_UART_MODE 0x0
+
+#define IrSR_IR_RECEIVE_ON (\
+ IrSR_RXPL_NEG_IS_ZERO | \
+ IrSR_TXPL_POS_IS_ZERO | \
+ IrSR_XMODE_PULSE_3_16 | \
+ IrSR_RCVEIR_IR_MODE | \
+ IrSR_XMITIR_UART_MODE)
+
+#define IrSR_IR_TRANSMIT_ON (\
+ IrSR_RXPL_NEG_IS_ZERO | \
+ IrSR_TXPL_POS_IS_ZERO | \
+ IrSR_XMODE_PULSE_3_16 | \
+ IrSR_RCVEIR_UART_MODE | \
+ IrSR_XMITIR_IR_MODE)
+
+struct pxa_irda {
+ int speed;
+ int newspeed;
+ unsigned long last_oscr;
+
+ unsigned char *dma_rx_buff;
+ unsigned char *dma_tx_buff;
+ dma_addr_t dma_rx_buff_phy;
+ dma_addr_t dma_tx_buff_phy;
+ unsigned int dma_tx_buff_len;
+ int txdma;
+ int rxdma;
+
+ struct net_device_stats stats;
+ struct irlap_cb *irlap;
+ struct qos_info qos;
+
+ iobuff_t tx_buff;
+ iobuff_t rx_buff;
+
+ struct device *dev;
+ struct pxaficp_platform_data *pdata;
+};
+
+
+#define IS_FIR(si) ((si)->speed >= 4000000)
+#define IRDA_FRAME_SIZE_LIMIT 2047
+
+inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
+{
+ DCSR(si->rxdma) = DCSR_NODESC;
+ DSADR(si->rxdma) = __PREG(ICDR);
+ DTADR(si->rxdma) = si->dma_rx_buff_phy;
+ DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
+ DCSR(si->rxdma) |= DCSR_RUN;
+}
+
+inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
+{
+ DCSR(si->txdma) = DCSR_NODESC;
+ DSADR(si->txdma) = si->dma_tx_buff_phy;
+ DTADR(si->txdma) = __PREG(ICDR);
+ DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
+ DCSR(si->txdma) |= DCSR_RUN;
+}
+
+/*
+ * Set the IrDA communications speed.
+ */
+static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
+{
+ unsigned long flags;
+ unsigned int divisor;
+
+ switch (speed) {
+ case 9600: case 19200: case 38400:
+ case 57600: case 115200:
+
+ /* refer to PXA250/210 Developer's Manual 10-7 */
+ /* BaudRate = 14.7456 MHz / (16*Divisor) */
+ divisor = 14745600 / (16 * speed);
+
+ local_irq_save(flags);
+
+ if (IS_FIR(si)) {
+ /* stop RX DMA */
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ /* disable FICP */
+ ICCR0 = 0;
+ pxa_set_cken(CKEN13_FICP, 0);
+
+ /* set board transceiver to SIR mode */
+ si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
+
+ /* configure GPIO46/47 */
+ pxa_gpio_mode(GPIO46_STRXD_MD);
+ pxa_gpio_mode(GPIO47_STTXD_MD);
+
+ /* enable the STUART clock */
+ pxa_set_cken(CKEN5_STUART, 1);
+ }
+
+ /* disable STUART first */
+ STIER = 0;
+
+ /* access DLL & DLH */
+ STLCR |= LCR_DLAB;
+ STDLL = divisor & 0xff;
+ STDLH = divisor >> 8;
+ STLCR &= ~LCR_DLAB;
+
+ si->speed = speed;
+ STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
+ STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
+
+ local_irq_restore(flags);
+ break;
+
+ case 4000000:
+ local_irq_save(flags);
+
+ /* disable STUART */
+ STIER = 0;
+ STISR = 0;
+ pxa_set_cken(CKEN5_STUART, 0);
+
+ /* disable FICP first */
+ ICCR0 = 0;
+
+ /* set board transceiver to FIR mode */
+ si->pdata->transceiver_mode(si->dev, IR_FIRMODE);
+
+ /* configure GPIO46/47 */
+ pxa_gpio_mode(GPIO46_ICPRXD_MD);
+ pxa_gpio_mode(GPIO47_ICPTXD_MD);
+
+ /* enable the FICP clock */
+ pxa_set_cken(CKEN13_FICP, 1);
+
+ si->speed = speed;
+ pxa_irda_fir_dma_rx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+ local_irq_restore(flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* SIR interrupt service routine. */
+static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct pxa_irda *si = netdev_priv(dev);
+ int iir, lsr, data;
+
+ iir = STIIR;
+
+ switch (iir & 0x0F) {
+ case 0x06: /* Receiver Line Status */
+ lsr = STLSR;
+ while (lsr & LSR_FIFOE) {
+ data = STRBR;
+ if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) {
+ printk(KERN_DEBUG "pxa_ir: sir receiving error\n");
+ si->stats.rx_errors++;
+ if (lsr & LSR_FE)
+ si->stats.rx_frame_errors++;
+ if (lsr & LSR_OE)
+ si->stats.rx_fifo_errors++;
+ } else {
+ si->stats.rx_bytes++;
+ async_unwrap_char(dev, &si->stats, &si->rx_buff, data);
+ }
+ lsr = STLSR;
+ }
+ dev->last_rx = jiffies;
+ si->last_oscr = OSCR;
+ break;
+
+ case 0x04: /* Received Data Available */
+ /* forth through */
+
+ case 0x0C: /* Character Timeout Indication */
+ do {
+ si->stats.rx_bytes++;
+ async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR);
+ } while (STLSR & LSR_DR);
+ dev->last_rx = jiffies;
+ si->last_oscr = OSCR;
+ break;
+
+ case 0x02: /* Transmit FIFO Data Request */
+ while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) {
+ STTHR = *si->tx_buff.data++;
+ si->tx_buff.len -= 1;
+ }
+
+ if (si->tx_buff.len == 0) {
+ si->stats.tx_packets++;
+ si->stats.tx_bytes += si->tx_buff.data -
+ si->tx_buff.head;
+
+ /* We need to ensure that the transmitter has finished. */
+ while ((STLSR & LSR_TEMT) == 0)
+ cpu_relax();
+ si->last_oscr = OSCR;
+
+ /*
+ * Ok, we've finished transmitting. Now enable
+ * the receiver. Sometimes we get a receive IRQ
+ * immediately after a transmit...
+ */
+ if (si->newspeed) {
+ pxa_irda_set_speed(si, si->newspeed);
+ si->newspeed = 0;
+ } else {
+ /* enable IR Receiver, disable IR Transmitter */
+ STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
+ /* enable STUART and receive interrupts */
+ STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
+ }
+ /* I'm hungry! */
+ netif_wake_queue(dev);
+ }
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* FIR Receive DMA interrupt handler */
+static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs)
+{
+ int dcsr = DCSR(channel);
+
+ DCSR(channel) = dcsr & ~DCSR_RUN;
+
+ printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
+}
+
+/* FIR Transmit DMA interrupt handler */
+static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs)
+{
+ struct net_device *dev = data;
+ struct pxa_irda *si = netdev_priv(dev);
+ int dcsr;
+
+ dcsr = DCSR(channel);
+ DCSR(channel) = dcsr & ~DCSR_RUN;
+
+ if (dcsr & DCSR_ENDINTR) {
+ si->stats.tx_packets++;
+ si->stats.tx_bytes += si->dma_tx_buff_len;
+ } else {
+ si->stats.tx_errors++;
+ }
+
+ while (ICSR1 & ICSR1_TBY)
+ cpu_relax();
+ si->last_oscr = OSCR;
+
+ /*
+ * HACK: It looks like the TBY bit is dropped too soon.
+ * Without this delay things break.
+ */
+ udelay(120);
+
+ if (si->newspeed) {
+ pxa_irda_set_speed(si, si->newspeed);
+ si->newspeed = 0;
+ } else {
+ ICCR0 = 0;
+ pxa_irda_fir_dma_rx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_RXE;
+ }
+ netif_wake_queue(dev);
+}
+
+/* EIF(Error in FIFO/End in Frame) handler for FIR */
+static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
+{
+ unsigned int len, stat, data;
+
+ /* Get the current data position. */
+ len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
+
+ do {
+ /* Read Status, and then Data. */
+ stat = ICSR1;
+ rmb();
+ data = ICDR;
+
+ if (stat & (ICSR1_CRE | ICSR1_ROR)) {
+ si->stats.rx_errors++;
+ if (stat & ICSR1_CRE) {
+ printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n");
+ si->stats.rx_crc_errors++;
+ }
+ if (stat & ICSR1_ROR) {
+ printk(KERN_DEBUG "pxa_ir: fir receive overrun\n");
+ si->stats.rx_frame_errors++;
+ }
+ } else {
+ si->dma_rx_buff[len++] = data;
+ }
+ /* If we hit the end of frame, there's no point in continuing. */
+ if (stat & ICSR1_EOF)
+ break;
+ } while (ICSR0 & ICSR0_EIF);
+
+ if (stat & ICSR1_EOF) {
+ /* end of frame. */
+ struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC);
+ if (!skb) {
+ printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n");
+ si->stats.rx_dropped++;
+ return;
+ }
+
+ /* Align IP header to 20 bytes */
+ skb_reserve(skb, 1);
+ memcpy(skb->data, si->dma_rx_buff, len);
+ skb_put(skb, len);
+
+ /* Feed it to IrLAP */
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx(skb);
+
+ si->stats.rx_packets++;
+ si->stats.rx_bytes += len;
+
+ dev->last_rx = jiffies;
+ }
+}
+
+/* FIR interrupt handler */
+static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct pxa_irda *si = netdev_priv(dev);
+ int icsr0;
+
+ /* stop RX DMA */
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ si->last_oscr = OSCR;
+ icsr0 = ICSR0;
+
+ if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
+ if (icsr0 & ICSR0_FRE) {
+ printk(KERN_DEBUG "pxa_ir: fir receive frame error\n");
+ si->stats.rx_frame_errors++;
+ } else {
+ printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
+ si->stats.rx_errors++;
+ }
+ ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB);
+ }
+
+ if (icsr0 & ICSR0_EIF) {
+ /* An error in FIFO occured, or there is a end of frame */
+ pxa_irda_fir_irq_eif(si, dev);
+ }
+
+ ICCR0 = 0;
+ pxa_irda_fir_dma_rx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+ return IRQ_HANDLED;
+}
+
+/* hard_xmit interface of irda device */
+static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+ int speed = irda_get_next_speed(skb);
+
+ /*
+ * Does this packet contain a request to change the interface
+ * speed? If so, remember it until we complete the transmission
+ * of this frame.
+ */
+ if (speed != si->speed && speed != -1)
+ si->newspeed = speed;
+
+ /*
+ * If this is an empty frame, we can bypass a lot.
+ */
+ if (skb->len == 0) {
+ if (si->newspeed) {
+ si->newspeed = 0;
+ pxa_irda_set_speed(si, speed);
+ }
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ netif_stop_queue(dev);
+
+ if (!IS_FIR(si)) {
+ si->tx_buff.data = si->tx_buff.head;
+ si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);
+
+ /* Disable STUART interrupts and switch to transmit mode. */
+ STIER = 0;
+ STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6;
+
+ /* enable STUART and transmit interrupts */
+ STIER = IER_UUE | IER_TIE;
+ } else {
+ unsigned long mtt = irda_get_mtt(skb);
+
+ si->dma_tx_buff_len = skb->len;
+ memcpy(si->dma_tx_buff, skb->data, skb->len);
+
+ if (mtt)
+ while ((unsigned)(OSCR - si->last_oscr)/4 < mtt)
+ cpu_relax();
+
+ /* stop RX DMA, disable FICP */
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ ICCR0 = 0;
+
+ pxa_irda_fir_dma_tx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_TXE;
+ }
+
+ dev_kfree_skb(skb);
+ dev->trans_start = jiffies;
+ return 0;
+}
+
+static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+{
+ struct if_irda_req *rq = (struct if_irda_req *)ifreq;
+ struct pxa_irda *si = netdev_priv(dev);
+ int ret;
+
+ switch (cmd) {
+ case SIOCSBANDWIDTH:
+ ret = -EPERM;
+ if (capable(CAP_NET_ADMIN)) {
+ /*
+ * We are unable to set the speed if the
+ * device is not running.
+ */
+ if (netif_running(dev)) {
+ ret = pxa_irda_set_speed(si,
+ rq->ifr_baudrate);
+ } else {
+ printk(KERN_INFO "pxa_ir: SIOCSBANDWIDTH: !netif_running\n");
+ ret = 0;
+ }
+ }
+ break;
+
+ case SIOCSMEDIABUSY:
+ ret = -EPERM;
+ if (capable(CAP_NET_ADMIN)) {
+ irda_device_set_media_busy(dev, TRUE);
+ ret = 0;
+ }
+ break;
+
+ case SIOCGRECEIVING:
+ ret = 0;
+ rq->ifr_receiving = IS_FIR(si) ? 0
+ : si->rx_buff.state != OUTSIDE_FRAME;
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+static struct net_device_stats *pxa_irda_stats(struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+ return &si->stats;
+}
+
+static void pxa_irda_startup(struct pxa_irda *si)
+{
+ /* Disable STUART interrupts */
+ STIER = 0;
+ /* enable STUART interrupt to the processor */
+ STMCR = MCR_OUT2;
+ /* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */
+ STLCR = LCR_WLS0 | LCR_WLS1;
+ /* enable FIFO, we use FIFO to improve performance */
+ STFCR = FCR_TRFIFOE | FCR_ITL_32;
+
+ /* disable FICP */
+ ICCR0 = 0;
+ /* configure FICP ICCR2 */
+ ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
+
+ /* configure DMAC */
+ DRCMR17 = si->rxdma | DRCMR_MAPVLD;
+ DRCMR18 = si->txdma | DRCMR_MAPVLD;
+
+ /* force SIR reinitialization */
+ si->speed = 4000000;
+ pxa_irda_set_speed(si, 9600);
+
+ printk(KERN_DEBUG "pxa_ir: irda startup\n");
+}
+
+static void pxa_irda_shutdown(struct pxa_irda *si)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /* disable STUART and interrupt */
+ STIER = 0;
+ /* disable STUART SIR mode */
+ STISR = 0;
+ /* disable the STUART clock */
+ pxa_set_cken(CKEN5_STUART, 0);
+
+ /* disable DMA */
+ DCSR(si->txdma) &= ~DCSR_RUN;
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ /* disable FICP */
+ ICCR0 = 0;
+ /* disable the FICP clock */
+ pxa_set_cken(CKEN13_FICP, 0);
+
+ DRCMR17 = 0;
+ DRCMR18 = 0;
+
+ local_irq_restore(flags);
+
+ /* power off board transceiver */
+ si->pdata->transceiver_mode(si->dev, IR_OFF);
+
+ printk(KERN_DEBUG "pxa_ir: irda shutdown\n");
+}
+
+static int pxa_irda_start(struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+ int err;
+
+ si->speed = 9600;
+
+ err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev);
+ if (err)
+ goto err_irq1;
+
+ err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev);
+ if (err)
+ goto err_irq2;
+
+ /*
+ * The interrupt must remain disabled for now.
+ */
+ disable_irq(IRQ_STUART);
+ disable_irq(IRQ_ICP);
+
+ err = -EBUSY;
+ si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
+ if (si->rxdma < 0)
+ goto err_rx_dma;
+
+ si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
+ if (si->txdma < 0)
+ goto err_tx_dma;
+
+ err = -ENOMEM;
+ si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
+ &si->dma_rx_buff_phy, GFP_KERNEL );
+ if (!si->dma_rx_buff)
+ goto err_dma_rx_buff;
+
+ si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
+ &si->dma_tx_buff_phy, GFP_KERNEL );
+ if (!si->dma_tx_buff)
+ goto err_dma_tx_buff;
+
+ /* Setup the serial port for the initial speed. */
+ pxa_irda_startup(si);
+
+ /*
+ * Open a new IrLAP layer instance.
+ */
+ si->irlap = irlap_open(dev, &si->qos, "pxa");
+ err = -ENOMEM;
+ if (!si->irlap)
+ goto err_irlap;
+
+ /*
+ * Now enable the interrupt and start the queue
+ */
+ enable_irq(IRQ_STUART);
+ enable_irq(IRQ_ICP);
+ netif_start_queue(dev);
+
+ printk(KERN_DEBUG "pxa_ir: irda driver opened\n");
+
+ return 0;
+
+err_irlap:
+ pxa_irda_shutdown(si);
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
+err_dma_tx_buff:
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
+err_dma_rx_buff:
+ pxa_free_dma(si->txdma);
+err_tx_dma:
+ pxa_free_dma(si->rxdma);
+err_rx_dma:
+ free_irq(IRQ_ICP, dev);
+err_irq2:
+ free_irq(IRQ_STUART, dev);
+err_irq1:
+
+ return err;
+}
+
+static int pxa_irda_stop(struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+
+ pxa_irda_shutdown(si);
+
+ /* Stop IrLAP */
+ if (si->irlap) {
+ irlap_close(si->irlap);
+ si->irlap = NULL;
+ }
+
+ free_irq(IRQ_STUART, dev);
+ free_irq(IRQ_ICP, dev);
+
+ pxa_free_dma(si->rxdma);
+ pxa_free_dma(si->txdma);
+
+ if (si->dma_rx_buff)
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
+ if (si->dma_tx_buff)
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
+
+ printk(KERN_DEBUG "pxa_ir: irda driver closed\n");
+ return 0;
+}
+
+static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
+{
+ struct net_device *dev = dev_get_drvdata(_dev);
+ struct pxa_irda *si;
+
+ if (!dev || level != SUSPEND_DISABLE)
+ return 0;
+
+ if (netif_running(dev)) {
+ si = netdev_priv(dev);
+ netif_device_detach(dev);
+ pxa_irda_shutdown(si);
+ }
+
+ return 0;
+}
+
+static int pxa_irda_resume(struct device *_dev, u32 level)
+{
+ struct net_device *dev = dev_get_drvdata(_dev);
+ struct pxa_irda *si;
+
+ if (!dev || level != RESUME_ENABLE)
+ return 0;
+
+ if (netif_running(dev)) {
+ si = netdev_priv(dev);
+ pxa_irda_startup(si);
+ netif_device_attach(dev);
+ netif_wake_queue(dev);
+ }
+
+ return 0;
+}
+
+
+static int pxa_irda_init_iobuf(iobuff_t *io, int size)
+{
+ io->head = kmalloc(size, GFP_KERNEL | GFP_DMA);
+ if (io->head != NULL) {
+ io->truesize = size;
+ io->in_frame = FALSE;
+ io->state = OUTSIDE_FRAME;
+ io->data = io->head;
+ }
+ return io->head ? 0 : -ENOMEM;
+}
+
+static int pxa_irda_probe(struct device *_dev)
+{
+ struct platform_device *pdev = to_platform_device(_dev);
+ struct net_device *dev;
+ struct pxa_irda *si;
+ unsigned int baudrate_mask;
+ int err;
+
+ if (!pdev->dev.platform_data)
+ return -ENODEV;
+
+ err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY;
+ if (err)
+ goto err_mem_1;
+
+ err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY;
+ if (err)
+ goto err_mem_2;
+
+ dev = alloc_irdadev(sizeof(struct pxa_irda));
+ if (!dev)
+ goto err_mem_3;
+
+ si = netdev_priv(dev);
+ si->dev = &pdev->dev;
+ si->pdata = pdev->dev.platform_data;
+
+ /*
+ * Initialise the SIR buffers
+ */
+ err = pxa_irda_init_iobuf(&si->rx_buff, 14384);
+ if (err)
+ goto err_mem_4;
+ err = pxa_irda_init_iobuf(&si->tx_buff, 4000);
+ if (err)
+ goto err_mem_5;
+
+ dev->hard_start_xmit = pxa_irda_hard_xmit;
+ dev->open = pxa_irda_start;
+ dev->stop = pxa_irda_stop;
+ dev->do_ioctl = pxa_irda_ioctl;
+ dev->get_stats = pxa_irda_stats;
+
+ irda_init_max_qos_capabilies(&si->qos);
+
+ baudrate_mask = 0;
+ if (si->pdata->transceiver_cap & IR_SIRMODE)
+ baudrate_mask |= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ if (si->pdata->transceiver_cap & IR_FIRMODE)
+ baudrate_mask |= IR_4000000 << 8;
+
+ si->qos.baud_rate.bits &= baudrate_mask;
+ si->qos.min_turn_time.bits = 7; /* 1ms or more */
+
+ irda_qos_bits_to_value(&si->qos);
+
+ err = register_netdev(dev);
+
+ if (err == 0)
+ dev_set_drvdata(&pdev->dev, dev);
+
+ if (err) {
+ kfree(si->tx_buff.head);
+err_mem_5:
+ kfree(si->rx_buff.head);
+err_mem_4:
+ free_netdev(dev);
+err_mem_3:
+ release_mem_region(__PREG(FICP), 0x1c);
+err_mem_2:
+ release_mem_region(__PREG(STUART), 0x24);
+ }
+err_mem_1:
+ return err;
+}
+
+static int pxa_irda_remove(struct device *_dev)
+{
+ struct net_device *dev = dev_get_drvdata(_dev);
+
+ if (dev) {
+ struct pxa_irda *si = netdev_priv(dev);
+ unregister_netdev(dev);
+ kfree(si->tx_buff.head);
+ kfree(si->rx_buff.head);
+ free_netdev(dev);
+ }
+
+ release_mem_region(__PREG(STUART), 0x24);
+ release_mem_region(__PREG(FICP), 0x1c);
+
+ return 0;
+}
+
+static struct device_driver pxa_ir_driver = {
+ .name = "pxa2xx-ir",
+ .bus = &platform_bus_type,
+ .probe = pxa_irda_probe,
+ .remove = pxa_irda_remove,
+ .suspend = pxa_irda_suspend,
+ .resume = pxa_irda_resume,
+};
+
+static int __init pxa_irda_init(void)
+{
+ return driver_register(&pxa_ir_driver);
+}
+
+static void __exit pxa_irda_exit(void)
+{
+ driver_unregister(&pxa_ir_driver);
+}
+
+module_init(pxa_irda_init);
+module_exit(pxa_irda_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 15f207323d97..3961a754e920 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -678,10 +678,9 @@ static void turnaround_delay(const struct stir_cb *stir, long us)
return;
ticks = us / (1000000 / HZ);
- if (ticks > 0) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1 + ticks);
- } else
+ if (ticks > 0)
+ schedule_timeout_interruptible(1 + ticks);
+ else
udelay(us);
}
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 6d9de626c967..651c5a6578fd 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1875,11 +1875,11 @@ static int __init vlsi_mod_init(void)
sirpulse = !!sirpulse;
- /* create_proc_entry returns NULL if !CONFIG_PROC_FS.
+ /* proc_mkdir returns NULL if !CONFIG_PROC_FS.
* Failure to create the procfs entry is handled like running
* without procfs - it's not required for the driver to work.
*/
- vlsi_proc_root = create_proc_entry(PROC_DIR, S_IFDIR, NULL);
+ vlsi_proc_root = proc_mkdir(PROC_DIR, NULL);
if (vlsi_proc_root) {
/* protect registered procdir against module removal.
* Because we are in the module init path there's no race
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 414694abf588..741aecc655df 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -69,14 +69,8 @@ typedef void irqreturn_t;
#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/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 9d026ed77ddd..04e47189d830 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -645,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, uint32_t data)
mod_timer(&adapter->blink_timer, jiffies);
- set_current_state(TASK_INTERRUPTIBLE);
- if(data)
- schedule_timeout(data * HZ);
+ if (data)
+ schedule_timeout_interruptible(data * HZ);
else
- schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+ schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
del_timer_sync(&adapter->blink_timer);
ixgb_led_off(&adapter->hw);
@@ -723,6 +722,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
.phys_id = ixgb_phys_id,
.get_stats_count = ixgb_get_stats_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
void ixgb_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 5c555373adbe..176680cb153e 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -460,8 +460,9 @@ ixgb_probe(struct pci_dev *pdev,
}
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
+ memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->dev_addr)) {
+ if(!is_valid_ether_addr(netdev->perm_addr)) {
err = -EIO;
goto err_eeprom;
}
@@ -1616,8 +1617,6 @@ ixgb_update_stats(struct ixgb_adapter *adapter)
adapter->stats.icbc +
adapter->stats.ecbc + adapter->stats.mpc;
- adapter->net_stats.rx_dropped = adapter->stats.mpc;
-
/* see above
* adapter->net_stats.rx_length_errors = adapter->stats.rlec;
*/
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index b4929beb33b2..1d75ca0bb939 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -298,7 +298,7 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, PCNET_
static unsigned char lance_need_isa_bounce_buffers = 1;
static int lance_open(struct net_device *dev);
-static void lance_init_ring(struct net_device *dev, int mode);
+static void lance_init_ring(struct net_device *dev, gfp_t mode);
static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int lance_rx(struct net_device *dev);
static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -846,7 +846,7 @@ lance_purge_ring(struct net_device *dev)
/* Initialize the LANCE Rx and Tx rings. */
static void
-lance_init_ring(struct net_device *dev, int gfp)
+lance_init_ring(struct net_device *dev, gfp_t gfp)
{
struct lance_private *lp = dev->priv;
int i;
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index 27f0d8ac4c40..309d254842cf 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -298,7 +298,7 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
return 0;
unmap:
if (ei_status.reg0)
- iounmap((void *)dev->mem_start);
+ iounmap(ei_status.mem);
cleanup:
free_irq(dev->irq, dev);
return ret;
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index c33cb3dc942b..e42aa797f08b 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -207,6 +207,20 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
return 0;
}
+int mii_check_gmii_support(struct mii_if_info *mii)
+{
+ int reg;
+
+ reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+ if (reg & BMSR_ESTATEN) {
+ reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
+ if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
+ return 1;
+ }
+
+ return 0;
+}
+
int mii_link_ok (struct mii_if_info *mii)
{
/* first, a dummy read, needed to latch some MII phys */
@@ -394,5 +408,6 @@ EXPORT_SYMBOL(mii_ethtool_gset);
EXPORT_SYMBOL(mii_ethtool_sset);
EXPORT_SYMBOL(mii_check_link);
EXPORT_SYMBOL(mii_check_media);
+EXPORT_SYMBOL(mii_check_gmii_support);
EXPORT_SYMBOL(generic_mii_ioctl);
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
new file mode 100644
index 000000000000..f79f7ee72ab8
--- /dev/null
+++ b/drivers/net/mipsnet.c
@@ -0,0 +1,371 @@
+/*
+ * 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.
+ */
+
+#define DEBUG
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include <asm/mips-boards/simint.h>
+
+#include "mipsnet.h" /* actual device IO mapping */
+
+#define MIPSNET_VERSION "2005-06-20"
+
+#define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field))
+
+struct mipsnet_priv {
+ struct net_device_stats stats;
+};
+
+static struct platform_device *mips_plat_dev;
+
+static char mipsnet_string[] = "mipsnet";
+
+/*
+ * Copy data from the MIPSNET rx data port
+ */
+static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
+ int len)
+{
+ uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount));
+ if (available_len < len)
+ return -EFAULT;
+
+ for (; len > 0; len--, kdata++) {
+ *kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
+ }
+
+ return inl(mipsnet_reg_address(dev, rxDataCount));
+}
+
+static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
+ struct sk_buff *skb)
+{
+ int count_to_go = skb->len;
+ char *buf_ptr = skb->data;
+ struct mipsnet_priv *mp = netdev_priv(dev);
+
+ pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
+ dev->name, __FUNCTION__, skb->len);
+
+ outl(skb->len, mipsnet_reg_address(dev, txDataCount));
+
+ pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
+ dev->name, __FUNCTION__, skb->len);
+
+ for (; count_to_go; buf_ptr++, count_to_go--) {
+ outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
+ }
+
+ mp->stats.tx_packets++;
+ mp->stats.tx_bytes += skb->len;
+
+ return skb->len;
+}
+
+static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ pr_debug("%s:%s(): transmitting %d bytes\n",
+ dev->name, __FUNCTION__, skb->len);
+
+ /* Only one packet at a time. Once TXDONE interrupt is serviced, the
+ * queue will be restarted.
+ */
+ netif_stop_queue(dev);
+ mipsnet_put_todevice(dev, skb);
+
+ return 0;
+}
+
+static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
+{
+ struct sk_buff *skb;
+ size_t len = count;
+ struct mipsnet_priv *mp = netdev_priv(dev);
+
+ if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
+ mp->stats.rx_dropped++;
+ return -ENOMEM;
+ }
+
+ skb_reserve(skb, 2);
+ if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
+ return -EFAULT;
+
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ pr_debug("%s:%s(): pushing RXed data to kernel\n",
+ dev->name, __FUNCTION__);
+ netif_rx(skb);
+
+ mp->stats.rx_packets++;
+ mp->stats.rx_bytes += len;
+
+ return count;
+}
+
+static irqreturn_t
+mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+
+ irqreturn_t retval = IRQ_NONE;
+ uint64_t interruptFlags;
+
+ if (irq == dev->irq) {
+ pr_debug("%s:%s(): irq %d for device\n",
+ dev->name, __FUNCTION__, irq);
+
+ retval = IRQ_HANDLED;
+
+ interruptFlags =
+ inl(mipsnet_reg_address(dev, interruptControl));
+ pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
+ __FUNCTION__, interruptFlags);
+
+ if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
+ pr_debug("%s:%s(): got TXDone\n",
+ dev->name, __FUNCTION__);
+ outl(MIPSNET_INTCTL_TXDONE,
+ mipsnet_reg_address(dev, interruptControl));
+ // only one packet at a time, we are done.
+ netif_wake_queue(dev);
+ } else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
+ pr_debug("%s:%s(): got RX data\n",
+ dev->name, __FUNCTION__);
+ mipsnet_get_fromdev(dev,
+ inl(mipsnet_reg_address(dev, rxDataCount)));
+ pr_debug("%s:%s(): clearing RX int\n",
+ dev->name, __FUNCTION__);
+ outl(MIPSNET_INTCTL_RXDONE,
+ mipsnet_reg_address(dev, interruptControl));
+
+ } else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
+ pr_debug("%s:%s(): got test interrupt\n",
+ dev->name, __FUNCTION__);
+ // TESTBIT is cleared on read.
+ // And takes effect after a write with 0
+ outl(0, mipsnet_reg_address(dev, interruptControl));
+ } else {
+ pr_debug("%s:%s(): no valid fags 0x%016llx\n",
+ dev->name, __FUNCTION__, interruptFlags);
+ // Maybe shared IRQ, just ignore, no clearing.
+ retval = IRQ_NONE;
+ }
+
+ } else {
+ printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
+ dev->name, __FUNCTION__, irq);
+ retval = IRQ_NONE;
+ }
+ return retval;
+} //mipsnet_interrupt()
+
+static int mipsnet_open(struct net_device *dev)
+{
+ int err;
+ pr_debug("%s: mipsnet_open\n", dev->name);
+
+ err = request_irq(dev->irq, &mipsnet_interrupt,
+ SA_SHIRQ, dev->name, (void *) dev);
+
+ if (err) {
+ pr_debug("%s: %s(): can't get irq %d\n",
+ dev->name, __FUNCTION__, dev->irq);
+ release_region(dev->base_addr, MIPSNET_IO_EXTENT);
+ return err;
+ }
+
+ pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
+ dev->name, __FUNCTION__, dev->base_addr, dev->irq);
+
+
+ netif_start_queue(dev);
+
+ // test interrupt handler
+ outl(MIPSNET_INTCTL_TESTBIT,
+ mipsnet_reg_address(dev, interruptControl));
+
+
+ return 0;
+}
+
+static int mipsnet_close(struct net_device *dev)
+{
+ pr_debug("%s: %s()\n", dev->name, __FUNCTION__);
+ netif_stop_queue(dev);
+ return 0;
+}
+
+static struct net_device_stats *mipsnet_get_stats(struct net_device *dev)
+{
+ struct mipsnet_priv *mp = netdev_priv(dev);
+
+ return &mp->stats;
+}
+
+static void mipsnet_set_mclist(struct net_device *dev)
+{
+ // we don't do anything
+ return;
+}
+
+static int __init mipsnet_probe(struct device *dev)
+{
+ struct net_device *netdev;
+ int err;
+
+ netdev = alloc_etherdev(sizeof(struct mipsnet_priv));
+ if (!netdev) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ dev_set_drvdata(dev, netdev);
+
+ netdev->open = mipsnet_open;
+ netdev->stop = mipsnet_close;
+ netdev->hard_start_xmit = mipsnet_xmit;
+ netdev->get_stats = mipsnet_get_stats;
+ netdev->set_multicast_list = mipsnet_set_mclist;
+
+ /*
+ * TODO: probe for these or load them from PARAM
+ */
+ netdev->base_addr = 0x4200;
+ netdev->irq = MIPSCPU_INT_BASE + MIPSCPU_INT_MB0 +
+ inl(mipsnet_reg_address(netdev, interruptInfo));
+
+ // Get the io region now, get irq on open()
+ if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
+ pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
+ "for dev is not availble.\n", netdev->name,
+ __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
+ err = -EBUSY;
+ goto out_free_netdev;
+ }
+
+ /*
+ * Lacking any better mechanism to allocate a MAC address we use a
+ * random one ...
+ */
+ random_ether_addr(netdev->dev_addr);
+
+ err = register_netdev(netdev);
+ if (err) {
+ printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
+ goto out_free_region;
+ }
+
+ return 0;
+
+out_free_region:
+ release_region(netdev->base_addr, MIPSNET_IO_EXTENT);
+
+out_free_netdev:
+ free_netdev(netdev);
+
+out:
+ return err;
+}
+
+static int __devexit mipsnet_device_remove(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+
+ unregister_netdev(dev);
+ release_region(dev->base_addr, MIPSNET_IO_EXTENT);
+ free_netdev(dev);
+ dev_set_drvdata(device, NULL);
+
+ return 0;
+}
+
+static struct device_driver mipsnet_driver = {
+ .name = mipsnet_string,
+ .bus = &platform_bus_type,
+ .probe = mipsnet_probe,
+ .remove = __devexit_p(mipsnet_device_remove),
+};
+
+static void mipsnet_platform_release(struct device *device)
+{
+ struct platform_device *pldev;
+
+ /* free device */
+ pldev = to_platform_device(device);
+ kfree(pldev);
+}
+
+static int __init mipsnet_init_module(void)
+{
+ struct platform_device *pldev;
+ int err;
+
+ printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
+ "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
+
+ if (driver_register(&mipsnet_driver)) {
+ printk(KERN_ERR "Driver registration failed\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto out_unregister_driver;
+ }
+
+ memset (pldev, 0, sizeof (*pldev));
+ pldev->name = mipsnet_string;
+ pldev->id = 0;
+ pldev->dev.release = mipsnet_platform_release;
+
+ if (platform_device_register(pldev)) {
+ err = -ENODEV;
+ goto out_free_pldev;
+ }
+
+ if (!pldev->dev.driver) {
+ /*
+ * The driver was not bound to this device, there was
+ * no hardware at this address. Unregister it, as the
+ * release fuction will take care of freeing the
+ * allocated structure
+ */
+ platform_device_unregister (pldev);
+ }
+
+ mips_plat_dev = pldev;
+
+ return 0;
+
+out_free_pldev:
+ kfree(pldev);
+
+out_unregister_driver:
+ driver_unregister(&mipsnet_driver);
+out:
+ return err;
+}
+
+static void __exit mipsnet_exit_module(void)
+{
+ pr_debug("MIPSNet Ethernet driver exiting\n");
+
+ driver_unregister(&mipsnet_driver);
+}
+
+module_init(mipsnet_init_module);
+module_exit(mipsnet_exit_module);
diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
new file mode 100644
index 000000000000..878535953cb1
--- /dev/null
+++ b/drivers/net/mipsnet.h
@@ -0,0 +1,127 @@
+//
+// <COPYRIGHT CLASS="1B" YEAR="2005">
+// Unpublished work (c) MIPS Technologies, Inc. All rights reserved.
+// Unpublished rights reserved under the copyright laws of the U.S.A. and
+// other countries.
+//
+// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC.
+// FOR INTERNAL USE ONLY.
+//
+// Under no circumstances (contract or otherwise) may this information be
+// disclosed to, or copied, modified or used by anyone other than employees
+// or contractors of MIPS Technologies having a need to know.
+// </COPYRIGHT>
+//
+//++
+// File: MIPS_Net.h
+//
+// Description:
+// The definition of the emulated MIPSNET device's interface.
+//
+// Notes: This include file needs to work from a Linux device drivers.
+//
+//--
+//
+
+#ifndef __MIPSNET_H
+#define __MIPSNET_H
+
+/*
+ * Id of this Net device, as seen by the core.
+ */
+#define MIPS_NET_DEV_ID ((uint64_t) \
+ ((uint64_t)'M'<< 0)| \
+ ((uint64_t)'I'<< 8)| \
+ ((uint64_t)'P'<<16)| \
+ ((uint64_t)'S'<<24)| \
+ ((uint64_t)'N'<<32)| \
+ ((uint64_t)'E'<<40)| \
+ ((uint64_t)'T'<<48)| \
+ ((uint64_t)'0'<<56))
+
+/*
+ * Net status/control block as seen by sw in the core.
+ * (Why not use bit fields? can't be bothered with cross-platform struct
+ * packing.)
+ */
+typedef struct _net_control_block {
+ /// dev info for probing
+ /// reads as MIPSNET%d where %d is some form of version
+ uint64_t devId; /*0x00 */
+
+ /*
+ * read only busy flag.
+ * Set and cleared by the Net Device to indicate that an rx or a tx
+ * is in progress.
+ */
+ uint32_t busy; /*0x08 */
+
+ /*
+ * Set by the Net Device.
+ * The device will set it once data has been received.
+ * The value is the number of bytes that should be read from
+ * rxDataBuffer. The value will decrease till 0 until all the data
+ * from rxDataBuffer has been read.
+ */
+ uint32_t rxDataCount; /*0x0c */
+#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
+
+ /*
+ * Settable from the MIPS core, cleared by the Net Device.
+ * The core should set the number of bytes it wants to send,
+ * then it should write those bytes of data to txDataBuffer.
+ * The device will clear txDataCount has been processed (not necessarily sent).
+ */
+ uint32_t txDataCount; /*0x10 */
+
+ /*
+ * Interrupt control
+ *
+ * Used to clear the interrupted generated by this dev.
+ * Write a 1 to clear the interrupt. (except bit31).
+ *
+ * Bit0 is set if it was a tx-done interrupt.
+ * Bit1 is set when new rx-data is available.
+ * Until this bit is cleared there will be no other RXs.
+ *
+ * Bit31 is used for testing, it clears after a read.
+ * Writing 1 to this bit will cause an interrupt to be generated.
+ * To clear the test interrupt, write 0 to this register.
+ */
+ uint32_t interruptControl; /*0x14 */
+#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1<< 0))
+#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1<< 1))
+#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1<<31))
+#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
+
+ /*
+ * Readonly core-specific interrupt info for the device to signal the core.
+ * The meaning of the contents of this field might change.
+ */
+ /*###\todo: the whole memIntf interrupt scheme is messy: the device should have
+ * no control what so ever of what VPE/register set is being used.
+ * The MemIntf should only expose interrupt lines, and something in the
+ * config should be responsible for the line<->core/vpe bindings.
+ */
+ uint32_t interruptInfo; /*0x18 */
+
+ /*
+ * This is where the received data is read out.
+ * There is more data to read until rxDataReady is 0.
+ * Only 1 byte at this regs offset is used.
+ */
+ uint32_t rxDataBuffer; /*0x1c */
+
+ /*
+ * This is where the data to transmit is written.
+ * Data should be written for the amount specified in the txDataCount register.
+ * Only 1 byte at this regs offset is used.
+ */
+ uint32_t txDataBuffer; /*0x20 */
+} MIPS_T_NetControl;
+
+#define MIPSNET_IO_EXTENT 0x40 /* being generous */
+
+#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
+
+#endif /* __MIPSNET_H */
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7c9dbc8c9423..25c9a99c377b 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -94,7 +94,7 @@ static char mv643xx_driver_version[] = "1.0";
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/net/myri_sbus.c b/drivers/net/myri_sbus.c
index f0996ce5c268..6c86dca62e2a 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -277,7 +277,7 @@ static void myri_init_rings(struct myri_eth *mp, int from_irq)
struct recvq __iomem *rq = mp->rq;
struct myri_rxd __iomem *rxd = &rq->myri_rxd[0];
struct net_device *dev = mp->dev;
- int gfp_flags = GFP_KERNEL;
+ gfp_t gfp_flags = GFP_KERNEL;
int i;
if (from_irq || in_interrupt())
diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
index 9391e55a5e92..47722f708a41 100644
--- a/drivers/net/myri_sbus.h
+++ b/drivers/net/myri_sbus.h
@@ -296,7 +296,7 @@ struct myri_eth {
/* We use this to acquire receive skb's that we can DMA directly into. */
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
-static inline struct sk_buff *myri_alloc_skb(unsigned int length, int gfp_flags)
+static inline struct sk_buff *myri_alloc_skb(unsigned int length, gfp_t gfp_flags)
{
struct sk_buff *skb;
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index d209a1556b2e..0de8fdd2aa86 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -54,6 +54,10 @@ static const char version2[] =
#include <asm/system.h>
#include <asm/io.h>
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#include <asm/tx4938/rbtx4938.h>
+#endif
+
#include "8390.h"
#define DRV_NAME "ne"
@@ -111,6 +115,9 @@ bad_clone_list[] __initdata = {
{"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+ {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
+#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{NULL,}
};
@@ -226,6 +233,10 @@ struct net_device * __init ne_probe(int unit)
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
+#ifdef CONFIG_TOSHIBA_RBTX4938
+ dev->base_addr = 0x07f20280;
+ dev->irq = RBTX4938_RTL_8019_IRQ;
+#endif
err = do_ne_probe(dev);
if (err)
goto out;
@@ -506,6 +517,10 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ei_status.name = name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+ wordlength = 1;
+#endif
+
#ifdef CONFIG_PLAT_OAKS32R
ei_status.word16 = 0;
#else
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f1c01ac29102..e531a4eedfee 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -372,6 +372,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
dev->dev_addr[i] = SA_prom[i];
}
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
return 0;
@@ -637,6 +638,7 @@ static struct ethtool_ops ne2k_pci_ethtool_ops = {
.get_drvinfo = ne2k_pci_get_drvinfo,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index e64df4d0800b..a3c3fc9c0d8a 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -584,7 +584,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
return 0;
}
-static inline int rx_refill(struct net_device *ndev, int gfp)
+static inline int rx_refill(struct net_device *ndev, gfp_t gfp)
{
struct ns83820 *dev = PRIV(ndev);
unsigned i;
@@ -1632,8 +1632,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab
timed_out = 1;
break;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (status & fail)
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index d652e1eddb45..c7cca842e5ee 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1832,7 +1832,7 @@ static void fill_multicast_tbl(int count, struct dev_mc_list *addrs,
{
struct dev_mc_list *mc_addr;
- for (mc_addr = addrs; mc_addr && --count > 0; mc_addr = mc_addr->next) {
+ for (mc_addr = addrs; mc_addr && count-- > 0; mc_addr = mc_addr->next) {
u_int position = ether_crc(6, mc_addr->dmi_addr);
#ifndef final_version /* Verify multicast address. */
if ((mc_addr->dmi_addr[0] & 1) == 0)
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 113b68099216..70fe81a89df9 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,8 +22,8 @@
*************************************************************************/
#define DRV_NAME "pcnet32"
-#define DRV_VERSION "1.30j"
-#define DRV_RELDATE "29.04.2005"
+#define DRV_VERSION "1.31a"
+#define DRV_RELDATE "12.Sep.2005"
#define PFX DRV_NAME ": "
static const char *version =
@@ -257,6 +257,9 @@ static int homepna[MAX_UNITS];
* v1.30h 24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
* v1.30i 28 Jun 2004 Don Fry change to use module_param.
* v1.30j 29 Apr 2005 Don Fry fix skb/map leak with loopback test.
+ * v1.31 02 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> added set_ringparam().
+ * v1.31a 12 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> set min ring size to 4
+ * to allow loopback test to work unchanged.
*/
@@ -266,17 +269,17 @@ static int homepna[MAX_UNITS];
* That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
*/
#ifndef PCNET32_LOG_TX_BUFFERS
-#define PCNET32_LOG_TX_BUFFERS 4
-#define PCNET32_LOG_RX_BUFFERS 5
+#define PCNET32_LOG_TX_BUFFERS 4
+#define PCNET32_LOG_RX_BUFFERS 5
+#define PCNET32_LOG_MAX_TX_BUFFERS 9 /* 2^9 == 512 */
+#define PCNET32_LOG_MAX_RX_BUFFERS 9
#endif
#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS ((PCNET32_LOG_TX_BUFFERS) << 12)
+#define TX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_TX_BUFFERS))
#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4)
+#define RX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_RX_BUFFERS))
#define PKT_BUF_SZ 1544
@@ -334,14 +337,14 @@ struct pcnet32_access {
};
/*
- * The first three fields of pcnet32_private are read by the ethernet device
- * so we allocate the structure should be allocated by pci_alloc_consistent().
+ * The first field of pcnet32_private is read by the ethernet device
+ * so the structure should be allocated using pci_alloc_consistent().
*/
struct pcnet32_private {
- /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
- struct pcnet32_rx_head rx_ring[RX_RING_SIZE];
- struct pcnet32_tx_head tx_ring[TX_RING_SIZE];
struct pcnet32_init_block init_block;
+ /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
+ struct pcnet32_rx_head *rx_ring;
+ struct pcnet32_tx_head *tx_ring;
dma_addr_t dma_addr; /* DMA address of beginning of this
object, returned by
pci_alloc_consistent */
@@ -349,13 +352,21 @@ struct pcnet32_private {
structure */
const char *name;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
- struct sk_buff *rx_skbuff[RX_RING_SIZE];
- dma_addr_t tx_dma_addr[TX_RING_SIZE];
- dma_addr_t rx_dma_addr[RX_RING_SIZE];
+ struct sk_buff **tx_skbuff;
+ struct sk_buff **rx_skbuff;
+ dma_addr_t *tx_dma_addr;
+ dma_addr_t *rx_dma_addr;
struct pcnet32_access a;
spinlock_t lock; /* Guard lock */
unsigned int cur_rx, cur_tx; /* The next free ring entry */
+ unsigned int rx_ring_size; /* current rx ring size */
+ unsigned int tx_ring_size; /* current tx ring size */
+ unsigned int rx_mod_mask; /* rx ring modular mask */
+ unsigned int tx_mod_mask; /* tx ring modular mask */
+ unsigned short rx_len_bits;
+ unsigned short tx_len_bits;
+ dma_addr_t rx_ring_dma_addr;
+ dma_addr_t tx_ring_dma_addr;
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
struct net_device_stats stats;
char tx_full;
@@ -397,6 +408,9 @@ static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr);
static void pcnet32_purge_tx_ring(struct net_device *dev);
+static int pcnet32_alloc_ring(struct net_device *dev);
+static void pcnet32_free_ring(struct net_device *dev);
+
enum pci_flags_bit {
PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@@ -613,10 +627,62 @@ static void pcnet32_get_ringparam(struct net_device *dev, struct ethtool_ringpar
{
struct pcnet32_private *lp = dev->priv;
- ering->tx_max_pending = TX_RING_SIZE - 1;
- ering->tx_pending = lp->cur_tx - lp->dirty_tx;
- ering->rx_max_pending = RX_RING_SIZE - 1;
- ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK;
+ ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
+ ering->tx_pending = lp->tx_ring_size - 1;
+ ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
+ ering->rx_pending = lp->rx_ring_size - 1;
+}
+
+static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+ struct pcnet32_private *lp = dev->priv;
+ unsigned long flags;
+ int i;
+
+ if (ering->rx_mini_pending || ering->rx_jumbo_pending)
+ return -EINVAL;
+
+ if (netif_running(dev))
+ pcnet32_close(dev);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ pcnet32_free_ring(dev);
+ lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
+ lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
+
+ /* set the minimum ring size to 4, to allow the loopback test to work
+ * unchanged.
+ */
+ for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
+ if (lp->tx_ring_size <= (1 << i))
+ break;
+ }
+ lp->tx_ring_size = (1 << i);
+ lp->tx_mod_mask = lp->tx_ring_size - 1;
+ lp->tx_len_bits = (i << 12);
+
+ for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
+ if (lp->rx_ring_size <= (1 << i))
+ break;
+ }
+ lp->rx_ring_size = (1 << i);
+ lp->rx_mod_mask = lp->rx_ring_size - 1;
+ lp->rx_len_bits = (i << 4);
+
+ if (pcnet32_alloc_ring(dev)) {
+ pcnet32_free_ring(dev);
+ return -ENOMEM;
+ }
+
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size);
+
+ if (netif_running(dev))
+ pcnet32_open(dev);
+
+ return 0;
}
static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -948,6 +1014,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.nway_reset = pcnet32_nway_reset,
.get_link = pcnet32_get_link,
.get_ringparam = pcnet32_get_ringparam,
+ .set_ringparam = pcnet32_set_ringparam,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_tso = ethtool_op_get_tso,
@@ -957,6 +1024,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.phys_id = pcnet32_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
/* only probes for non-PCI devices, the rest are handled by
@@ -1185,9 +1253,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
memcpy(dev->dev_addr, promaddr, 6);
}
}
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
- if (!is_valid_ether_addr(dev->dev_addr))
+ if (!is_valid_ether_addr(dev->perm_addr))
memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
if (pcnet32_debug & NETIF_MSG_PROBE) {
@@ -1239,6 +1308,12 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
dev->priv = lp;
lp->name = chipname;
lp->shared_irq = shared;
+ lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */
+ lp->rx_ring_size = RX_RING_SIZE; /* default rx ring size */
+ lp->tx_mod_mask = lp->tx_ring_size - 1;
+ lp->rx_mod_mask = lp->rx_ring_size - 1;
+ lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
+ lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
lp->mii_if.full_duplex = fdx;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
@@ -1265,21 +1340,23 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
}
lp->a = *a;
+ if (pcnet32_alloc_ring(dev)) {
+ ret = -ENOMEM;
+ goto err_free_ring;
+ }
/* detect special T1/E1 WAN card by checking for MAC address */
if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
&& dev->dev_addr[2] == 0x75)
lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
- lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+ lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, rx_ring));
- lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, tx_ring));
+ lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+ lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
/* switch pcnet32 to 32bit mode */
a->write_bcr(ioaddr, 20, 2);
@@ -1310,7 +1387,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
if (pcnet32_debug & NETIF_MSG_PROBE)
printk(", failed to detect IRQ line.\n");
ret = -ENODEV;
- goto err_free_consistent;
+ goto err_free_ring;
}
if (pcnet32_debug & NETIF_MSG_PROBE)
printk(", probed IRQ %d.\n", dev->irq);
@@ -1341,7 +1418,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
/* Fill in the generic fields of the device structure. */
if (register_netdev(dev))
- goto err_free_consistent;
+ goto err_free_ring;
if (pdev) {
pci_set_drvdata(pdev, dev);
@@ -1359,6 +1436,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
return 0;
+err_free_ring:
+ pcnet32_free_ring(dev);
err_free_consistent:
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
err_free_netdev:
@@ -1369,6 +1448,86 @@ err_release_region:
}
+static int pcnet32_alloc_ring(struct net_device *dev)
+{
+ struct pcnet32_private *lp = dev->priv;
+
+ if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ &lp->tx_ring_dma_addr)) == NULL) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+ return -ENOMEM;
+ }
+
+ if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ &lp->rx_ring_dma_addr)) == NULL) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+ return -ENOMEM;
+ }
+
+ if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_ERR PFX "Memory allocation failed.\n");
+ return -ENOMEM;
+ }
+ memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
+
+ if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_ERR PFX "Memory allocation failed.\n");
+ return -ENOMEM;
+ }
+ memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
+
+ if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_ERR PFX "Memory allocation failed.\n");
+ return -ENOMEM;
+ }
+ memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
+
+ if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_ERR PFX "Memory allocation failed.\n");
+ return -ENOMEM;
+ }
+ memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
+
+ return 0;
+}
+
+
+static void pcnet32_free_ring(struct net_device *dev)
+{
+ struct pcnet32_private *lp = dev->priv;
+
+ kfree(lp->tx_skbuff);
+ lp->tx_skbuff = NULL;
+
+ kfree(lp->rx_skbuff);
+ lp->rx_skbuff = NULL;
+
+ kfree(lp->tx_dma_addr);
+ lp->tx_dma_addr = NULL;
+
+ kfree(lp->rx_dma_addr);
+ lp->rx_dma_addr = NULL;
+
+ if (lp->tx_ring) {
+ pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ lp->tx_ring, lp->tx_ring_dma_addr);
+ lp->tx_ring = NULL;
+ }
+
+ if (lp->rx_ring) {
+ pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ lp->rx_ring, lp->rx_ring_dma_addr);
+ lp->rx_ring = NULL;
+ }
+}
+
+
static int
pcnet32_open(struct net_device *dev)
{
@@ -1400,8 +1559,8 @@ pcnet32_open(struct net_device *dev)
if (netif_msg_ifup(lp))
printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
dev->name, dev->irq,
- (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)),
- (u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)),
+ (u32) (lp->tx_ring_dma_addr),
+ (u32) (lp->rx_ring_dma_addr),
(u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)));
/* set/reset autoselect bit */
@@ -1521,7 +1680,7 @@ pcnet32_open(struct net_device *dev)
err_free_ring:
/* free any allocated skbuffs */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < lp->rx_ring_size; i++) {
lp->rx_ring[i].status = 0;
if (lp->rx_skbuff[i]) {
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
@@ -1531,6 +1690,9 @@ err_free_ring:
lp->rx_skbuff[i] = NULL;
lp->rx_dma_addr[i] = 0;
}
+
+ pcnet32_free_ring(dev);
+
/*
* Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot
@@ -1562,7 +1724,7 @@ pcnet32_purge_tx_ring(struct net_device *dev)
struct pcnet32_private *lp = dev->priv;
int i;
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
@@ -1587,7 +1749,7 @@ pcnet32_init_ring(struct net_device *dev)
lp->cur_rx = lp->cur_tx = 0;
lp->dirty_rx = lp->dirty_tx = 0;
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < lp->rx_ring_size; i++) {
struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
if (rx_skbuff == NULL) {
if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
@@ -1611,20 +1773,18 @@ pcnet32_init_ring(struct net_device *dev)
}
/* The Tx buffer address is filled in as needed, but we do need to clear
* the upper ownership bit. */
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
lp->tx_ring[i].base = 0;
lp->tx_dma_addr[i] = 0;
}
- lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+ lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
- lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, rx_ring));
- lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, tx_ring));
+ lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+ lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
wmb(); /* Make sure all changes are visible */
return 0;
}
@@ -1682,13 +1842,13 @@ pcnet32_tx_timeout (struct net_device *dev)
printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
lp->cur_rx);
- for (i = 0 ; i < RX_RING_SIZE; i++)
+ for (i = 0 ; i < lp->rx_ring_size; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
le32_to_cpu(lp->rx_ring[i].base),
(-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
le32_to_cpu(lp->rx_ring[i].msg_length),
le16_to_cpu(lp->rx_ring[i].status));
- for (i = 0 ; i < TX_RING_SIZE; i++)
+ for (i = 0 ; i < lp->tx_ring_size; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
le32_to_cpu(lp->tx_ring[i].base),
(-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
@@ -1729,7 +1889,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Fill in a Tx ring entry */
/* Mask to ring buffer boundary. */
- entry = lp->cur_tx & TX_RING_MOD_MASK;
+ entry = lp->cur_tx & lp->tx_mod_mask;
/* Caution: the write order is important here, set the status
* with the "ownership" bits last. */
@@ -1753,7 +1913,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
- if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) {
+ if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) {
lp->tx_full = 1;
netif_stop_queue(dev);
}
@@ -1806,7 +1966,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
int delta;
while (dirty_tx != lp->cur_tx) {
- int entry = dirty_tx & TX_RING_MOD_MASK;
+ int entry = dirty_tx & lp->tx_mod_mask;
int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
if (status < 0)
@@ -1864,18 +2024,18 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
dirty_tx++;
}
- delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
- if (delta > TX_RING_SIZE) {
+ delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
+ if (delta > lp->tx_ring_size) {
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
- dirty_tx += TX_RING_SIZE;
- delta -= TX_RING_SIZE;
+ dirty_tx += lp->tx_ring_size;
+ delta -= lp->tx_ring_size;
}
if (lp->tx_full &&
netif_queue_stopped(dev) &&
- delta < TX_RING_SIZE - 2) {
+ delta < lp->tx_ring_size - 2) {
/* The ring is no longer full, clear tbusy. */
lp->tx_full = 0;
netif_wake_queue (dev);
@@ -1932,8 +2092,8 @@ static int
pcnet32_rx(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
- int entry = lp->cur_rx & RX_RING_MOD_MASK;
- int boguscnt = RX_RING_SIZE / 2;
+ int entry = lp->cur_rx & lp->rx_mod_mask;
+ int boguscnt = lp->rx_ring_size / 2;
/* If we own the next entry, it's a new packet. Send it up. */
while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
@@ -1998,12 +2158,12 @@ pcnet32_rx(struct net_device *dev)
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n",
dev->name);
- for (i = 0; i < RX_RING_SIZE; i++)
+ for (i = 0; i < lp->rx_ring_size; i++)
if ((short)le16_to_cpu(lp->rx_ring[(entry+i)
- & RX_RING_MOD_MASK].status) < 0)
+ & lp->rx_mod_mask].status) < 0)
break;
- if (i > RX_RING_SIZE -2) {
+ if (i > lp->rx_ring_size -2) {
lp->stats.rx_dropped++;
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
wmb(); /* Make sure adapter sees owner change */
@@ -2041,7 +2201,7 @@ pcnet32_rx(struct net_device *dev)
lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
wmb(); /* Make sure owner changes after all others are visible */
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
- entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+ entry = (++lp->cur_rx) & lp->rx_mod_mask;
if (--boguscnt <= 0) break; /* don't stay in loop forever */
}
@@ -2084,7 +2244,7 @@ pcnet32_close(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
/* free all allocated skbuffs */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < lp->rx_ring_size; i++) {
lp->rx_ring[i].status = 0;
wmb(); /* Make sure adapter sees owner change */
if (lp->rx_skbuff[i]) {
@@ -2096,7 +2256,7 @@ pcnet32_close(struct net_device *dev)
lp->rx_dma_addr[i] = 0;
}
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
@@ -2265,6 +2425,7 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
struct pcnet32_private *lp = dev->priv;
unregister_netdev(dev);
+ pcnet32_free_ring(dev);
release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
free_netdev(dev);
@@ -2340,6 +2501,7 @@ static void __exit pcnet32_cleanup_module(void)
struct pcnet32_private *lp = pcnet32_dev->priv;
next_dev = lp->next;
unregister_netdev(pcnet32_dev);
+ pcnet32_free_ring(pcnet32_dev);
release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
free_netdev(pcnet32_dev);
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 14f4de1a8180..c782a6329805 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -12,14 +12,6 @@ config PHYLIB
devices. This option provides infrastructure for
managing PHY devices.
-config PHYCONTROL
- bool " Support for automatically handling PHY state changes"
- depends on PHYLIB
- help
- Adds code to perform all the work for keeping PHY link
- state (speed/duplex/etc) up-to-date. Also handles
- interrupts.
-
comment "MII PHY device drivers"
depends on PHYLIB
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index d9e11f93bf3a..9209da9dde0d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -242,10 +242,6 @@ EXPORT_SYMBOL(phy_sanitize_settings);
* choose the next best ones from the ones selected, so we don't
* care if ethtool tries to give us bad values
*
- * A note about the PHYCONTROL Layer. If you turn off
- * CONFIG_PHYCONTROL, you will need to read the PHY status
- * registers after this function completes, and update your
- * controller manually.
*/
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{
@@ -380,7 +376,6 @@ int phy_start_aneg(struct phy_device *phydev)
err = phydev->drv->config_aneg(phydev);
-#ifdef CONFIG_PHYCONTROL
if (err < 0)
goto out_unlock;
@@ -395,14 +390,12 @@ int phy_start_aneg(struct phy_device *phydev)
}
out_unlock:
-#endif
spin_unlock(&phydev->lock);
return err;
}
EXPORT_SYMBOL(phy_start_aneg);
-#ifdef CONFIG_PHYCONTROL
static void phy_change(void *data);
static void phy_timer(unsigned long data);
@@ -868,4 +861,3 @@ static void phy_timer(unsigned long data)
mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
}
-#endif /* CONFIG_PHYCONTROL */
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 33f7bdb5857c..6da1aa0706a1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -101,7 +101,6 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
return dev;
}
-#ifdef CONFIG_PHYCONTROL
/* phy_prepare_link:
*
* description: Tells the PHY infrastructure to handle the
@@ -160,8 +159,6 @@ void phy_disconnect(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_disconnect);
-#endif /* CONFIG_PHYCONTROL */
-
/* phy_attach:
*
* description: Called by drivers to attach to a particular PHY
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index bb71638a7c44..0df7e92b0bf8 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1232,9 +1232,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
navail = 0; /* total # of usable channels (not deregistered) */
hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
i = 0;
- list = &ppp->channels;
- while ((list = list->next) != &ppp->channels) {
- pch = list_entry(list, struct channel, clist);
+ list_for_each_entry(pch, &ppp->channels, clist) {
navail += pch->avail = (pch->chan != NULL);
if (pch->avail) {
if (skb_queue_empty(&pch->file.xq) ||
@@ -1280,6 +1278,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
/* skip to the channel after the one we last used
and start at that one */
+ list = &ppp->channels;
for (i = 0; i < ppp->nxchan; ++i) {
list = list->next;
if (list == &ppp->channels) {
@@ -1730,7 +1729,7 @@ static void
ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
{
u32 mask, seq;
- struct list_head *l;
+ struct channel *ch;
int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0)
@@ -1784,8 +1783,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
* The list of channels can't change because we have the receive
* side of the ppp unit locked.
*/
- for (l = ppp->channels.next; l != &ppp->channels; l = l->next) {
- struct channel *ch = list_entry(l, struct channel, clist);
+ list_for_each_entry(ch, &ppp->channels, clist) {
if (seq_before(ch->lastseq, seq))
seq = ch->lastseq;
}
@@ -2271,10 +2269,8 @@ static struct compressor_entry *
find_comp_entry(int proto)
{
struct compressor_entry *ce;
- struct list_head *list = &compressor_list;
- while ((list = list->next) != &compressor_list) {
- ce = list_entry(list, struct compressor_entry, list);
+ list_for_each_entry(ce, &compressor_list, list) {
if (ce->comp->compress_proto == proto)
return ce;
}
@@ -2540,20 +2536,15 @@ static struct channel *
ppp_find_channel(int unit)
{
struct channel *pch;
- struct list_head *list;
- list = &new_channels;
- while ((list = list->next) != &new_channels) {
- pch = list_entry(list, struct channel, list);
+ list_for_each_entry(pch, &new_channels, list) {
if (pch->file.index == unit) {
list_del(&pch->list);
list_add(&pch->list, &all_channels);
return pch;
}
}
- list = &all_channels;
- while ((list = list->next) != &all_channels) {
- pch = list_entry(list, struct channel, list);
+ list_for_each_entry(pch, &all_channels, list) {
if (pch->file.index == unit)
return pch;
}
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 82f236cc3b9b..a842ecc60a34 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1070,7 +1070,7 @@ static int __init pppoe_proc_init(void)
{
struct proc_dir_entry *p;
- p = create_proc_entry("pppoe", S_IRUGO, proc_net);
+ p = create_proc_entry("net/pppoe", S_IRUGO, NULL);
if (!p)
return -ENOMEM;
@@ -1142,7 +1142,7 @@ static void __exit pppoe_exit(void)
dev_remove_pack(&pppoes_ptype);
dev_remove_pack(&pppoed_ptype);
unregister_netdevice_notifier(&pppoe_notifier);
- remove_proc_entry("pppoe", proc_net);
+ remove_proc_entry("net/pppoe", NULL);
proto_unregister(&pppoe_sk_proto);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f0471d102e3c..159b56a56ef4 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -92,19 +92,18 @@ VERSION 2.2LK <2005/01/25>
#endif /* RTL8169_DEBUG */
#define R8169_MSG_DEFAULT \
- (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | \
- NETIF_MSG_IFDOWN)
+ (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
#define TX_BUFFS_AVAIL(tp) \
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
#ifdef CONFIG_R8169_NAPI
#define rtl8169_rx_skb netif_receive_skb
-#define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx
+#define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb
#define rtl8169_rx_quota(count, quota) min(count, quota)
#else
#define rtl8169_rx_skb netif_rx
-#define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb
+#define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx
#define rtl8169_rx_quota(count, quota) count
#endif
@@ -1028,6 +1027,7 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
.get_strings = rtl8169_get_strings,
.get_stats_count = rtl8169_get_stats_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1512,6 +1512,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = rtl8169_open;
dev->hard_start_xmit = rtl8169_start_xmit;
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
new file mode 100644
index 000000000000..12cde0604580
--- /dev/null
+++ b/drivers/net/rionet.c
@@ -0,0 +1,574 @@
+/*
+ * rionet - Ethernet driver over RapidIO messaging services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * 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/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
+#include <linux/ethtool.h>
+
+#define DRV_NAME "rionet"
+#define DRV_VERSION "0.2"
+#define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>"
+#define DRV_DESC "Ethernet over RapidIO"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+
+#define RIONET_DEFAULT_MSGLEVEL \
+ (NETIF_MSG_DRV | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
+#define RIONET_DOORBELL_JOIN 0x1000
+#define RIONET_DOORBELL_LEAVE 0x1001
+
+#define RIONET_MAILBOX 0
+
+#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE
+#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE
+
+static LIST_HEAD(rionet_peers);
+
+struct rionet_private {
+ struct rio_mport *mport;
+ struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
+ struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
+ struct net_device_stats stats;
+ int rx_slot;
+ int tx_slot;
+ int tx_cnt;
+ int ack_slot;
+ spinlock_t lock;
+ spinlock_t tx_lock;
+ u32 msg_enable;
+};
+
+struct rionet_peer {
+ struct list_head node;
+ struct rio_dev *rdev;
+ struct resource *res;
+};
+
+static int rionet_check = 0;
+static int rionet_capable = 1;
+
+/*
+ * This is a fast lookup table for for translating TX
+ * Ethernet packets into a destination RIO device. It
+ * could be made into a hash table to save memory depending
+ * on system trade-offs.
+ */
+static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
+
+#define is_rionet_capable(pef, src_ops, dst_ops) \
+ ((pef & RIO_PEF_INB_MBOX) && \
+ (pef & RIO_PEF_INB_DOORBELL) && \
+ (src_ops & RIO_SRC_OPS_DOORBELL) && \
+ (dst_ops & RIO_DST_OPS_DOORBELL))
+#define dev_rionet_capable(dev) \
+ is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
+
+#define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001)
+#define RIONET_GET_DESTID(x) (*(u16 *)(x + 4))
+
+static struct net_device_stats *rionet_stats(struct net_device *ndev)
+{
+ struct rionet_private *rnet = ndev->priv;
+ return &rnet->stats;
+}
+
+static int rionet_rx_clean(struct net_device *ndev)
+{
+ int i;
+ int error = 0;
+ struct rionet_private *rnet = ndev->priv;
+ void *data;
+
+ i = rnet->rx_slot;
+
+ do {
+ if (!rnet->rx_skb[i])
+ continue;
+
+ if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
+ break;
+
+ rnet->rx_skb[i]->data = data;
+ skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
+ rnet->rx_skb[i]->dev = ndev;
+ rnet->rx_skb[i]->protocol =
+ eth_type_trans(rnet->rx_skb[i], ndev);
+ error = netif_rx(rnet->rx_skb[i]);
+
+ if (error == NET_RX_DROP) {
+ rnet->stats.rx_dropped++;
+ } else if (error == NET_RX_BAD) {
+ if (netif_msg_rx_err(rnet))
+ printk(KERN_WARNING "%s: bad rx packet\n",
+ DRV_NAME);
+ rnet->stats.rx_errors++;
+ } else {
+ rnet->stats.rx_packets++;
+ rnet->stats.rx_bytes += RIO_MAX_MSG_SIZE;
+ }
+
+ } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
+
+ return i;
+}
+
+static void rionet_rx_fill(struct net_device *ndev, int end)
+{
+ int i;
+ struct rionet_private *rnet = ndev->priv;
+
+ i = rnet->rx_slot;
+ do {
+ rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
+
+ if (!rnet->rx_skb[i])
+ break;
+
+ rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
+ rnet->rx_skb[i]->data);
+ } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
+
+ rnet->rx_slot = i;
+}
+
+static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
+ struct rio_dev *rdev)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
+ rnet->tx_skb[rnet->tx_slot] = skb;
+
+ rnet->stats.tx_packets++;
+ rnet->stats.tx_bytes += skb->len;
+
+ if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
+ netif_stop_queue(ndev);
+
+ ++rnet->tx_slot;
+ rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
+
+ if (netif_msg_tx_queued(rnet))
+ printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
+ (u32) skb, skb->len);
+
+ return 0;
+}
+
+static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ int i;
+ struct rionet_private *rnet = ndev->priv;
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ u16 destid;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (!spin_trylock(&rnet->tx_lock)) {
+ local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+ }
+
+ if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+ netif_stop_queue(ndev);
+ spin_unlock_irqrestore(&rnet->tx_lock, flags);
+ printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
+ ndev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (eth->h_dest[0] & 0x01) {
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
+ if (rionet_active[i])
+ rionet_queue_tx_msg(skb, ndev,
+ rionet_active[i]);
+ } else if (RIONET_MAC_MATCH(eth->h_dest)) {
+ destid = RIONET_GET_DESTID(eth->h_dest);
+ if (rionet_active[destid])
+ rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
+ }
+
+ spin_unlock_irqrestore(&rnet->tx_lock, flags);
+
+ return 0;
+}
+
+static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
+ u16 info)
+{
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = ndev->priv;
+ struct rionet_peer *peer;
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
+ DRV_NAME, sid, tid, info);
+ if (info == RIONET_DOORBELL_JOIN) {
+ if (!rionet_active[sid]) {
+ list_for_each_entry(peer, &rionet_peers, node) {
+ if (peer->rdev->destid == sid)
+ rionet_active[sid] = peer->rdev;
+ }
+ rio_mport_send_doorbell(mport, sid,
+ RIONET_DOORBELL_JOIN);
+ }
+ } else if (info == RIONET_DOORBELL_LEAVE) {
+ rionet_active[sid] = NULL;
+ } else {
+ if (netif_msg_intr(rnet))
+ printk(KERN_WARNING "%s: unhandled doorbell\n",
+ DRV_NAME);
+ }
+}
+
+static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
+{
+ int n;
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
+ DRV_NAME, mbox, slot);
+
+ spin_lock(&rnet->lock);
+ if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
+ rionet_rx_fill(ndev, n);
+ spin_unlock(&rnet->lock);
+}
+
+static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
+{
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = ndev->priv;
+
+ spin_lock(&rnet->lock);
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO
+ "%s: outbound message event, mbox %d slot %d\n",
+ DRV_NAME, mbox, slot);
+
+ while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
+ /* dma unmap single */
+ dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
+ rnet->tx_skb[rnet->ack_slot] = NULL;
+ ++rnet->ack_slot;
+ rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
+ rnet->tx_cnt--;
+ }
+
+ if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
+ netif_wake_queue(ndev);
+
+ spin_unlock(&rnet->lock);
+}
+
+static int rionet_open(struct net_device *ndev)
+{
+ int i, rc = 0;
+ struct rionet_peer *peer, *tmp;
+ u32 pwdcsr;
+ struct rionet_private *rnet = ndev->priv;
+
+ if (netif_msg_ifup(rnet))
+ printk(KERN_INFO "%s: open\n", DRV_NAME);
+
+ if ((rc = rio_request_inb_dbell(rnet->mport,
+ (void *)ndev,
+ RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE,
+ rionet_dbell_event)) < 0)
+ goto out;
+
+ if ((rc = rio_request_inb_mbox(rnet->mport,
+ (void *)ndev,
+ RIONET_MAILBOX,
+ RIONET_RX_RING_SIZE,
+ rionet_inb_msg_event)) < 0)
+ goto out;
+
+ if ((rc = rio_request_outb_mbox(rnet->mport,
+ (void *)ndev,
+ RIONET_MAILBOX,
+ RIONET_TX_RING_SIZE,
+ rionet_outb_msg_event)) < 0)
+ goto out;
+
+ /* Initialize inbound message ring */
+ for (i = 0; i < RIONET_RX_RING_SIZE; i++)
+ rnet->rx_skb[i] = NULL;
+ rnet->rx_slot = 0;
+ rionet_rx_fill(ndev, 0);
+
+ rnet->tx_slot = 0;
+ rnet->tx_cnt = 0;
+ rnet->ack_slot = 0;
+
+ netif_carrier_on(ndev);
+ netif_start_queue(ndev);
+
+ list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ if (!(peer->res = rio_request_outb_dbell(peer->rdev,
+ RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE)))
+ {
+ printk(KERN_ERR "%s: error requesting doorbells\n",
+ DRV_NAME);
+ continue;
+ }
+
+ /*
+ * If device has initialized inbound doorbells,
+ * send a join message
+ */
+ rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
+ if (pwdcsr & RIO_DOORBELL_AVAIL)
+ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
+ }
+
+ out:
+ return rc;
+}
+
+static int rionet_close(struct net_device *ndev)
+{
+ struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+ struct rionet_peer *peer, *tmp;
+ int i;
+
+ if (netif_msg_ifup(rnet))
+ printk(KERN_INFO "%s: close\n", DRV_NAME);
+
+ netif_stop_queue(ndev);
+ netif_carrier_off(ndev);
+
+ for (i = 0; i < RIONET_RX_RING_SIZE; i++)
+ if (rnet->rx_skb[i])
+ kfree_skb(rnet->rx_skb[i]);
+
+ list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ if (rionet_active[peer->rdev->destid]) {
+ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
+ rionet_active[peer->rdev->destid] = NULL;
+ }
+ rio_release_outb_dbell(peer->rdev, peer->res);
+ }
+
+ rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE);
+ rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
+ rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
+
+ return 0;
+}
+
+static void rionet_remove(struct rio_dev *rdev)
+{
+ struct net_device *ndev = NULL;
+ struct rionet_peer *peer, *tmp;
+
+ unregister_netdev(ndev);
+ kfree(ndev);
+
+ list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ list_del(&peer->node);
+ kfree(peer);
+ }
+}
+
+static void rionet_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ strcpy(info->driver, DRV_NAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->fw_version, "n/a");
+ strcpy(info->bus_info, rnet->mport->name);
+}
+
+static u32 rionet_get_msglevel(struct net_device *ndev)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ return rnet->msg_enable;
+}
+
+static void rionet_set_msglevel(struct net_device *ndev, u32 value)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ rnet->msg_enable = value;
+}
+
+static struct ethtool_ops rionet_ethtool_ops = {
+ .get_drvinfo = rionet_get_drvinfo,
+ .get_msglevel = rionet_get_msglevel,
+ .set_msglevel = rionet_set_msglevel,
+ .get_link = ethtool_op_get_link,
+};
+
+static int rionet_setup_netdev(struct rio_mport *mport)
+{
+ int rc = 0;
+ struct net_device *ndev = NULL;
+ struct rionet_private *rnet;
+ u16 device_id;
+
+ /* Allocate our net_device structure */
+ ndev = alloc_etherdev(sizeof(struct rionet_private));
+ if (ndev == NULL) {
+ printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+ DRV_NAME);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* Set up private area */
+ rnet = (struct rionet_private *)ndev->priv;
+ rnet->mport = mport;
+
+ /* Set the default MAC address */
+ device_id = rio_local_get_device_id(mport);
+ ndev->dev_addr[0] = 0x00;
+ ndev->dev_addr[1] = 0x01;
+ ndev->dev_addr[2] = 0x00;
+ ndev->dev_addr[3] = 0x01;
+ ndev->dev_addr[4] = device_id >> 8;
+ ndev->dev_addr[5] = device_id & 0xff;
+
+ /* Fill in the driver function table */
+ ndev->open = &rionet_open;
+ ndev->hard_start_xmit = &rionet_start_xmit;
+ ndev->stop = &rionet_close;
+ ndev->get_stats = &rionet_stats;
+ ndev->mtu = RIO_MAX_MSG_SIZE - 14;
+ ndev->features = NETIF_F_LLTX;
+ SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
+
+ SET_MODULE_OWNER(ndev);
+
+ spin_lock_init(&rnet->lock);
+ spin_lock_init(&rnet->tx_lock);
+
+ rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
+
+ rc = register_netdev(ndev);
+ if (rc != 0)
+ goto out;
+
+ printk("%s: %s %s Version %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ndev->name,
+ DRV_NAME,
+ DRV_DESC,
+ DRV_VERSION,
+ ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+ ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+
+ out:
+ return rc;
+}
+
+/*
+ * XXX Make multi-net safe
+ */
+static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
+{
+ int rc = -ENODEV;
+ u32 lpef, lsrc_ops, ldst_ops;
+ struct rionet_peer *peer;
+
+ /* If local device is not rionet capable, give up quickly */
+ if (!rionet_capable)
+ goto out;
+
+ /*
+ * First time through, make sure local device is rionet
+ * capable, setup netdev, and set flags so this is skipped
+ * on later probes
+ */
+ if (!rionet_check) {
+ rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
+ rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
+ &lsrc_ops);
+ rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
+ &ldst_ops);
+ if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
+ printk(KERN_ERR
+ "%s: local device is not network capable\n",
+ DRV_NAME);
+ rionet_check = 1;
+ rionet_capable = 0;
+ goto out;
+ }
+
+ rc = rionet_setup_netdev(rdev->net->hport);
+ rionet_check = 1;
+ }
+
+ /*
+ * If the remote device has mailbox/doorbell capabilities,
+ * add it to the peer list.
+ */
+ if (dev_rionet_capable(rdev)) {
+ if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ peer->rdev = rdev;
+ list_add_tail(&peer->node, &rionet_peers);
+ }
+
+ out:
+ return rc;
+}
+
+static struct rio_device_id rionet_id_table[] = {
+ {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
+};
+
+static struct rio_driver rionet_driver = {
+ .name = "rionet",
+ .id_table = rionet_id_table,
+ .probe = rionet_probe,
+ .remove = rionet_remove,
+};
+
+static int __init rionet_init(void)
+{
+ return rio_register_driver(&rionet_driver);
+}
+
+static void __exit rionet_exit(void)
+{
+ rio_unregister_driver(&rionet_driver);
+}
+
+module_init(rionet_init);
+module_exit(rionet_exit);
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 7cefe5507b9e..00179bc3437f 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -814,6 +814,17 @@ typedef struct _XENA_dev_config {
u64 rxgxs_ber_0; /* CHANGED */
u64 rxgxs_ber_1; /* CHANGED */
+ u64 spi_control;
+#define SPI_CONTROL_KEY(key) vBIT(key,0,4)
+#define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3)
+#define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8)
+#define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24)
+#define SPI_CONTROL_SEL1 BIT(4)
+#define SPI_CONTROL_REQ BIT(7)
+#define SPI_CONTROL_NACK BIT(5)
+#define SPI_CONTROL_DONE BIT(6)
+ u64 spi_data;
+#define SPI_DATA_WRITE(data,len) vBIT(data,0,len)
} XENA_dev_config_t;
#define XENA_REG_SPACE sizeof(XENA_dev_config_t)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index c829e6a2e8a6..d303d162974f 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -65,9 +65,11 @@
#include "s2io.h"
#include "s2io-regs.h"
+#define DRV_VERSION "Version 2.0.9.1"
+
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
-static char s2io_driver_version[] = "Version 2.0.8.1";
+static char s2io_driver_version[] = DRV_VERSION;
static inline int RXD_IS_UP2DT(RxD_t *rxdp)
{
@@ -307,6 +309,8 @@ static unsigned int indicate_max_pkts;
#endif
/* Frequency of Rx desc syncs expressed as power of 2 */
static unsigned int rxsync_frequency = 3;
+/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+static unsigned int intr_type = 0;
/*
* S2IO device table.
@@ -428,7 +432,7 @@ static int init_shared_mem(struct s2io_nic *nic)
DBG_PRINT(INIT_DBG,
"%s: Zero DMA address for TxDL. ", dev->name);
DBG_PRINT(INIT_DBG,
- "Virtual address %llx\n", (u64)tmp_v);
+ "Virtual address %p\n", tmp_v);
tmp_v = pci_alloc_consistent(nic->pdev,
PAGE_SIZE, &tmp_p);
if (!tmp_v) {
@@ -657,9 +661,10 @@ static void free_shared_mem(struct s2io_nic *nic)
mac_control->zerodma_virt_addr,
(dma_addr_t)0);
DBG_PRINT(INIT_DBG,
- "%s: Freeing TxDL with zero DMA addr. ", dev->name);
- DBG_PRINT(INIT_DBG, "Virtual address %llx\n",
- (u64)(mac_control->zerodma_virt_addr));
+ "%s: Freeing TxDL with zero DMA addr. ",
+ dev->name);
+ DBG_PRINT(INIT_DBG, "Virtual address %p\n",
+ mac_control->zerodma_virt_addr);
}
kfree(mac_control->fifos[i].list_info);
}
@@ -1395,8 +1400,13 @@ static int init_nic(struct s2io_nic *nic)
writeq(val64, &bar0->rti_data1_mem);
val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
- RTI_DATA2_MEM_RX_UFC_B(0x2) |
- RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80);
+ RTI_DATA2_MEM_RX_UFC_B(0x2) ;
+ if (nic->intr_type == MSI_X)
+ val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
+ RTI_DATA2_MEM_RX_UFC_D(0x40));
+ else
+ val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
+ RTI_DATA2_MEM_RX_UFC_D(0x80));
writeq(val64, &bar0->rti_data2_mem);
for (i = 0; i < config->rx_ring_num; i++) {
@@ -1506,17 +1516,15 @@ static int init_nic(struct s2io_nic *nic)
#define LINK_UP_DOWN_INTERRUPT 1
#define MAC_RMAC_ERR_TIMER 2
-#if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE)
-#define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER
-#else
int s2io_link_fault_indication(nic_t *nic)
{
+ if (nic->intr_type != INTA)
+ return MAC_RMAC_ERR_TIMER;
if (nic->device_type == XFRAME_II_DEVICE)
return LINK_UP_DOWN_INTERRUPT;
else
return MAC_RMAC_ERR_TIMER;
}
-#endif
/**
* en_dis_able_nic_intrs - Enable or Disable the interrupts
@@ -1940,11 +1948,14 @@ static int start_nic(struct s2io_nic *nic)
}
/* Enable select interrupts */
- interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
- interruptible |= TX_PIC_INTR | RX_PIC_INTR;
- interruptible |= TX_MAC_INTR | RX_MAC_INTR;
-
- en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
+ if (nic->intr_type != INTA)
+ en_dis_able_nic_intrs(nic, ENA_ALL_INTRS, DISABLE_INTRS);
+ else {
+ interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
+ interruptible |= TX_PIC_INTR | RX_PIC_INTR;
+ interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+ en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
+ }
/*
* With some switches, link might be already up at this point.
@@ -2632,11 +2643,11 @@ static void tx_intr_handler(fifo_info_t *fifo_data)
err = txdlp->Control_1 & TXD_T_CODE;
if ((err >> 48) == 0xA) {
DBG_PRINT(TX_DBG, "TxD returned due \
- to loss of link\n");
+to loss of link\n");
}
else {
DBG_PRINT(ERR_DBG, "***TxD error \
- %llx\n", err);
+%llx\n", err);
}
}
@@ -2853,6 +2864,9 @@ void s2io_reset(nic_t * sp)
/* Set swapper to enable I/O register access */
s2io_set_swapper(sp);
+ /* Restore the MSIX table entries from local variables */
+ restore_xmsi_data(sp);
+
/* Clear certain PCI/PCI-X fields after reset */
if (sp->device_type == XFRAME_II_DEVICE) {
/* Clear parity err detect bit */
@@ -2982,8 +2996,9 @@ int s2io_set_swapper(nic_t * sp)
SWAPPER_CTRL_RXD_W_FE |
SWAPPER_CTRL_RXF_W_FE |
SWAPPER_CTRL_XMSI_FE |
- SWAPPER_CTRL_XMSI_SE |
SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+ if (sp->intr_type == INTA)
+ val64 |= SWAPPER_CTRL_XMSI_SE;
writeq(val64, &bar0->swapper_ctrl);
#else
/*
@@ -3004,8 +3019,9 @@ int s2io_set_swapper(nic_t * sp)
SWAPPER_CTRL_RXD_W_SE |
SWAPPER_CTRL_RXF_W_FE |
SWAPPER_CTRL_XMSI_FE |
- SWAPPER_CTRL_XMSI_SE |
SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+ if (sp->intr_type == INTA)
+ val64 |= SWAPPER_CTRL_XMSI_SE;
writeq(val64, &bar0->swapper_ctrl);
#endif
val64 = readq(&bar0->swapper_ctrl);
@@ -3027,6 +3043,201 @@ int s2io_set_swapper(nic_t * sp)
return SUCCESS;
}
+int wait_for_msix_trans(nic_t *nic, int i)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 val64;
+ int ret = 0, cnt = 0;
+
+ do {
+ val64 = readq(&bar0->xmsi_access);
+ if (!(val64 & BIT(15)))
+ break;
+ mdelay(1);
+ cnt++;
+ } while(cnt < 5);
+ if (cnt == 5) {
+ DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+void restore_xmsi_data(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 val64;
+ int i;
+
+ for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+ writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
+ writeq(nic->msix_info[i].data, &bar0->xmsi_data);
+ val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+ writeq(val64, &bar0->xmsi_access);
+ if (wait_for_msix_trans(nic, i)) {
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ continue;
+ }
+ }
+}
+
+void store_xmsi_data(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 val64, addr, data;
+ int i;
+
+ /* Store and display */
+ for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+ val64 = (BIT(15) | vBIT(i, 26, 6));
+ writeq(val64, &bar0->xmsi_access);
+ if (wait_for_msix_trans(nic, i)) {
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ continue;
+ }
+ addr = readq(&bar0->xmsi_address);
+ data = readq(&bar0->xmsi_data);
+ if (addr && data) {
+ nic->msix_info[i].addr = addr;
+ nic->msix_info[i].data = data;
+ }
+ }
+}
+
+int s2io_enable_msi(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u16 msi_ctrl, msg_val;
+ struct config_param *config = &nic->config;
+ struct net_device *dev = nic->dev;
+ u64 val64, tx_mat, rx_mat;
+ int i, err;
+
+ val64 = readq(&bar0->pic_control);
+ val64 &= ~BIT(1);
+ writeq(val64, &bar0->pic_control);
+
+ err = pci_enable_msi(nic->pdev);
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
+ nic->dev->name);
+ return err;
+ }
+
+ /*
+ * Enable MSI and use MSI-1 in stead of the standard MSI-0
+ * for interrupt handling.
+ */
+ pci_read_config_word(nic->pdev, 0x4c, &msg_val);
+ msg_val ^= 0x1;
+ pci_write_config_word(nic->pdev, 0x4c, msg_val);
+ pci_read_config_word(nic->pdev, 0x4c, &msg_val);
+
+ pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
+ msi_ctrl |= 0x10;
+ pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
+
+ /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
+ tx_mat = readq(&bar0->tx_mat0_n[0]);
+ for (i=0; i<config->tx_fifo_num; i++) {
+ tx_mat |= TX_MAT_SET(i, 1);
+ }
+ writeq(tx_mat, &bar0->tx_mat0_n[0]);
+
+ rx_mat = readq(&bar0->rx_mat);
+ for (i=0; i<config->rx_ring_num; i++) {
+ rx_mat |= RX_MAT_SET(i, 1);
+ }
+ writeq(rx_mat, &bar0->rx_mat);
+
+ dev->irq = nic->pdev->irq;
+ return 0;
+}
+
+int s2io_enable_msi_x(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 tx_mat, rx_mat;
+ u16 msi_control; /* Temp variable */
+ int ret, i, j, msix_indx = 1;
+
+ nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
+ GFP_KERNEL);
+ if (nic->entries == NULL) {
+ DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+
+ nic->s2io_entries =
+ kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
+ GFP_KERNEL);
+ if (nic->s2io_entries == NULL) {
+ DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+ kfree(nic->entries);
+ return -ENOMEM;
+ }
+ memset(nic->s2io_entries, 0,
+ MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+
+ for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+ nic->entries[i].entry = i;
+ nic->s2io_entries[i].entry = i;
+ nic->s2io_entries[i].arg = NULL;
+ nic->s2io_entries[i].in_use = 0;
+ }
+
+ tx_mat = readq(&bar0->tx_mat0_n[0]);
+ for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) {
+ tx_mat |= TX_MAT_SET(i, msix_indx);
+ nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i];
+ nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE;
+ nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+ }
+ writeq(tx_mat, &bar0->tx_mat0_n[0]);
+
+ if (!nic->config.bimodal) {
+ rx_mat = readq(&bar0->rx_mat);
+ for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
+ rx_mat |= RX_MAT_SET(j, msix_indx);
+ nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+ nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+ nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+ }
+ writeq(rx_mat, &bar0->rx_mat);
+ } else {
+ tx_mat = readq(&bar0->tx_mat0_n[7]);
+ for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
+ tx_mat |= TX_MAT_SET(i, msix_indx);
+ nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+ nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+ nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+ }
+ writeq(tx_mat, &bar0->tx_mat0_n[7]);
+ }
+
+ ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X);
+ if (ret) {
+ DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
+ kfree(nic->entries);
+ kfree(nic->s2io_entries);
+ nic->entries = NULL;
+ nic->s2io_entries = NULL;
+ return -ENOMEM;
+ }
+
+ /*
+ * To enable MSI-X, MSI also needs to be enabled, due to a bug
+ * in the herc NIC. (Temp change, needs to be removed later)
+ */
+ pci_read_config_word(nic->pdev, 0x42, &msi_control);
+ msi_control |= 0x1; /* Enable MSI */
+ pci_write_config_word(nic->pdev, 0x42, msi_control);
+
+ return 0;
+}
+
/* ********************************************************* *
* Functions defined below concern the OS part of the driver *
* ********************************************************* */
@@ -3047,6 +3258,8 @@ int s2io_open(struct net_device *dev)
{
nic_t *sp = dev->priv;
int err = 0;
+ int i;
+ u16 msi_control; /* Temp variable */
/*
* Make sure you have link off by default every time
@@ -3063,13 +3276,55 @@ int s2io_open(struct net_device *dev)
goto hw_init_failed;
}
+ /* Store the values of the MSIX table in the nic_t structure */
+ store_xmsi_data(sp);
+
/* After proper initialization of H/W, register ISR */
- err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
- sp->name, dev);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
- dev->name);
- goto isr_registration_failed;
+ if (sp->intr_type == MSI) {
+ err = request_irq((int) sp->pdev->irq, s2io_msi_handle,
+ SA_SHIRQ, sp->name, dev);
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: MSI registration \
+failed\n", dev->name);
+ goto isr_registration_failed;
+ }
+ }
+ if (sp->intr_type == MSI_X) {
+ for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
+ if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) {
+ sprintf(sp->desc1, "%s:MSI-X-%d-TX",
+ dev->name, i);
+ err = request_irq(sp->entries[i].vector,
+ s2io_msix_fifo_handle, 0, sp->desc1,
+ sp->s2io_entries[i].arg);
+ DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1,
+ sp->msix_info[i].addr);
+ } else {
+ sprintf(sp->desc2, "%s:MSI-X-%d-RX",
+ dev->name, i);
+ err = request_irq(sp->entries[i].vector,
+ s2io_msix_ring_handle, 0, sp->desc2,
+ sp->s2io_entries[i].arg);
+ DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2,
+ sp->msix_info[i].addr);
+ }
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
+failed\n", dev->name, i);
+ DBG_PRINT(ERR_DBG, "Returned: %d\n", err);
+ goto isr_registration_failed;
+ }
+ sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
+ }
+ }
+ if (sp->intr_type == INTA) {
+ err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
+ sp->name, dev);
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
+ dev->name);
+ goto isr_registration_failed;
+ }
}
if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) {
@@ -3082,11 +3337,37 @@ int s2io_open(struct net_device *dev)
return 0;
setting_mac_address_failed:
- free_irq(sp->pdev->irq, dev);
+ if (sp->intr_type != MSI_X)
+ free_irq(sp->pdev->irq, dev);
isr_registration_failed:
del_timer_sync(&sp->alarm_timer);
+ if (sp->intr_type == MSI_X) {
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ for (i=1; (sp->s2io_entries[i].in_use ==
+ MSIX_REGISTERED_SUCCESS); i++) {
+ int vector = sp->entries[i].vector;
+ void *arg = sp->s2io_entries[i].arg;
+
+ free_irq(vector, arg);
+ }
+ pci_disable_msix(sp->pdev);
+
+ /* Temp */
+ pci_read_config_word(sp->pdev, 0x42, &msi_control);
+ msi_control &= 0xFFFE; /* Disable MSI */
+ pci_write_config_word(sp->pdev, 0x42, msi_control);
+ }
+ }
+ else if (sp->intr_type == MSI)
+ pci_disable_msi(sp->pdev);
s2io_reset(sp);
hw_init_failed:
+ if (sp->intr_type == MSI_X) {
+ if (sp->entries)
+ kfree(sp->entries);
+ if (sp->s2io_entries)
+ kfree(sp->s2io_entries);
+ }
return err;
}
@@ -3106,12 +3387,35 @@ hw_init_failed:
int s2io_close(struct net_device *dev)
{
nic_t *sp = dev->priv;
+ int i;
+ u16 msi_control;
+
flush_scheduled_work();
netif_stop_queue(dev);
/* Reset card, kill tasklet and free Tx and Rx buffers. */
s2io_card_down(sp);
- free_irq(sp->pdev->irq, dev);
+ if (sp->intr_type == MSI_X) {
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ for (i=1; (sp->s2io_entries[i].in_use ==
+ MSIX_REGISTERED_SUCCESS); i++) {
+ int vector = sp->entries[i].vector;
+ void *arg = sp->s2io_entries[i].arg;
+
+ free_irq(vector, arg);
+ }
+ pci_read_config_word(sp->pdev, 0x42, &msi_control);
+ msi_control &= 0xFFFE; /* Disable MSI */
+ pci_write_config_word(sp->pdev, 0x42, msi_control);
+
+ pci_disable_msix(sp->pdev);
+ }
+ }
+ else {
+ free_irq(sp->pdev->irq, dev);
+ if (sp->intr_type == MSI)
+ pci_disable_msi(sp->pdev);
+ }
sp->device_close_flag = TRUE; /* Device is shut down. */
return 0;
}
@@ -3277,6 +3581,104 @@ s2io_alarm_handle(unsigned long data)
mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
}
+static irqreturn_t
+s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = (struct net_device *) dev_id;
+ nic_t *sp = dev->priv;
+ int i;
+ int ret;
+ mac_info_t *mac_control;
+ struct config_param *config;
+
+ atomic_inc(&sp->isr_cnt);
+ mac_control = &sp->mac_control;
+ config = &sp->config;
+ DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
+
+ /* If Intr is because of Rx Traffic */
+ for (i = 0; i < config->rx_ring_num; i++)
+ rx_intr_handler(&mac_control->rings[i]);
+
+ /* If Intr is because of Tx Traffic */
+ for (i = 0; i < config->tx_fifo_num; i++)
+ tx_intr_handler(&mac_control->fifos[i]);
+
+ /*
+ * If the Rx buffer count is below the panic threshold then
+ * reallocate the buffers from the interrupt handler itself,
+ * else schedule a tasklet to reallocate the buffers.
+ */
+ for (i = 0; i < config->rx_ring_num; i++) {
+ int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
+ int level = rx_buffer_level(sp, rxb_size, i);
+
+ if ((level == PANIC) && (!TASKLET_IN_USE)) {
+ DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name);
+ DBG_PRINT(INTR_DBG, "PANIC levels\n");
+ if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
+ DBG_PRINT(ERR_DBG, "%s:Out of memory",
+ dev->name);
+ DBG_PRINT(ERR_DBG, " in ISR!!\n");
+ clear_bit(0, (&sp->tasklet_status));
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+ }
+ clear_bit(0, (&sp->tasklet_status));
+ } else if (level == LOW) {
+ tasklet_schedule(&sp->task);
+ }
+ }
+
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+ ring_info_t *ring = (ring_info_t *)dev_id;
+ nic_t *sp = ring->nic;
+ int rxb_size, level, rng_n;
+
+ atomic_inc(&sp->isr_cnt);
+ rx_intr_handler(ring);
+
+ rng_n = ring->ring_no;
+ rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
+ level = rx_buffer_level(sp, rxb_size, rng_n);
+
+ if ((level == PANIC) && (!TASKLET_IN_USE)) {
+ int ret;
+ DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
+ DBG_PRINT(INTR_DBG, "PANIC levels\n");
+ if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
+ DBG_PRINT(ERR_DBG, "Out of memory in %s",
+ __FUNCTION__);
+ clear_bit(0, (&sp->tasklet_status));
+ return IRQ_HANDLED;
+ }
+ clear_bit(0, (&sp->tasklet_status));
+ } else if (level == LOW) {
+ tasklet_schedule(&sp->task);
+ }
+ atomic_dec(&sp->isr_cnt);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+ fifo_info_t *fifo = (fifo_info_t *)dev_id;
+ nic_t *sp = fifo->nic;
+
+ atomic_inc(&sp->isr_cnt);
+ tx_intr_handler(fifo);
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+}
+
static void s2io_txpic_intr_handle(nic_t *sp)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
@@ -3777,11 +4179,10 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev,
{
nic_t *sp = dev->priv;
- strncpy(info->driver, s2io_driver_name, sizeof(s2io_driver_name));
- strncpy(info->version, s2io_driver_version,
- sizeof(s2io_driver_version));
- strncpy(info->fw_version, "", 32);
- strncpy(info->bus_info, pci_name(sp->pdev), 32);
+ strncpy(info->driver, s2io_driver_name, sizeof(info->driver));
+ strncpy(info->version, s2io_driver_version, sizeof(info->version));
+ strncpy(info->fw_version, "", sizeof(info->fw_version));
+ strncpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info));
info->regdump_len = XENA_REG_SPACE;
info->eedump_len = XENA_EEPROM_SPACE;
info->testinfo_len = S2IO_TEST_LEN;
@@ -3977,29 +4378,53 @@ static int s2io_ethtool_setpause_data(struct net_device *dev,
*/
#define S2IO_DEV_ID 5
-static int read_eeprom(nic_t * sp, int off, u32 * data)
+static int read_eeprom(nic_t * sp, int off, u64 * data)
{
int ret = -1;
u32 exit_cnt = 0;
u64 val64;
XENA_dev_config_t __iomem *bar0 = sp->bar0;
- val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
- I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
- I2C_CONTROL_CNTL_START;
- SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+ if (sp->device_type == XFRAME_I_DEVICE) {
+ val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+ I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
+ I2C_CONTROL_CNTL_START;
+ SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
- while (exit_cnt < 5) {
- val64 = readq(&bar0->i2c_control);
- if (I2C_CONTROL_CNTL_END(val64)) {
- *data = I2C_CONTROL_GET_DATA(val64);
- ret = 0;
- break;
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->i2c_control);
+ if (I2C_CONTROL_CNTL_END(val64)) {
+ *data = I2C_CONTROL_GET_DATA(val64);
+ ret = 0;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
}
- msleep(50);
- exit_cnt++;
}
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
+ SPI_CONTROL_BYTECNT(0x3) |
+ SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off);
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ val64 |= SPI_CONTROL_REQ;
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->spi_control);
+ if (val64 & SPI_CONTROL_NACK) {
+ ret = 1;
+ break;
+ } else if (val64 & SPI_CONTROL_DONE) {
+ *data = readq(&bar0->spi_data);
+ *data &= 0xffffff;
+ ret = 0;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
+ }
+ }
return ret;
}
@@ -4018,28 +4443,53 @@ static int read_eeprom(nic_t * sp, int off, u32 * data)
* 0 on success, -1 on failure.
*/
-static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
+static int write_eeprom(nic_t * sp, int off, u64 data, int cnt)
{
int exit_cnt = 0, ret = -1;
u64 val64;
XENA_dev_config_t __iomem *bar0 = sp->bar0;
- val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
- I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
- I2C_CONTROL_CNTL_START;
- SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+ if (sp->device_type == XFRAME_I_DEVICE) {
+ val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+ I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) |
+ I2C_CONTROL_CNTL_START;
+ SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->i2c_control);
+ if (I2C_CONTROL_CNTL_END(val64)) {
+ if (!(val64 & I2C_CONTROL_NACK))
+ ret = 0;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
+ }
+ }
- while (exit_cnt < 5) {
- val64 = readq(&bar0->i2c_control);
- if (I2C_CONTROL_CNTL_END(val64)) {
- if (!(val64 & I2C_CONTROL_NACK))
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ int write_cnt = (cnt == 8) ? 0 : cnt;
+ writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data);
+
+ val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
+ SPI_CONTROL_BYTECNT(write_cnt) |
+ SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off);
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ val64 |= SPI_CONTROL_REQ;
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->spi_control);
+ if (val64 & SPI_CONTROL_NACK) {
+ ret = 1;
+ break;
+ } else if (val64 & SPI_CONTROL_DONE) {
ret = 0;
- break;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
}
- msleep(50);
- exit_cnt++;
}
-
return ret;
}
@@ -4059,7 +4509,8 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
static int s2io_ethtool_geeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 * data_buf)
{
- u32 data, i, valid;
+ u32 i, valid;
+ u64 data;
nic_t *sp = dev->priv;
eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16);
@@ -4097,7 +4548,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
u8 * data_buf)
{
int len = eeprom->len, cnt = 0;
- u32 valid = 0, data;
+ u64 valid = 0, data;
nic_t *sp = dev->priv;
if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
@@ -4145,7 +4596,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
static int s2io_register_test(nic_t * sp, uint64_t * data)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
- u64 val64 = 0;
+ u64 val64 = 0, exp_val;
int fail = 0;
val64 = readq(&bar0->pif_rd_swapper_fb);
@@ -4161,7 +4612,11 @@ static int s2io_register_test(nic_t * sp, uint64_t * data)
}
val64 = readq(&bar0->rx_queue_cfg);
- if (val64 != 0x0808080808080808ULL) {
+ if (sp->device_type == XFRAME_II_DEVICE)
+ exp_val = 0x0404040404040404ULL;
+ else
+ exp_val = 0x0808080808080808ULL;
+ if (val64 != exp_val) {
fail = 1;
DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n");
}
@@ -4189,7 +4644,7 @@ static int s2io_register_test(nic_t * sp, uint64_t * data)
}
*data = fail;
- return 0;
+ return fail;
}
/**
@@ -4208,58 +4663,83 @@ static int s2io_register_test(nic_t * sp, uint64_t * data)
static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
{
int fail = 0;
- u32 ret_data;
+ u64 ret_data, org_4F0, org_7F0;
+ u8 saved_4F0 = 0, saved_7F0 = 0;
+ struct net_device *dev = sp->dev;
/* Test Write Error at offset 0 */
- if (!write_eeprom(sp, 0, 0, 3))
- fail = 1;
+ /* Note that SPI interface allows write access to all areas
+ * of EEPROM. Hence doing all negative testing only for Xframe I.
+ */
+ if (sp->device_type == XFRAME_I_DEVICE)
+ if (!write_eeprom(sp, 0, 0, 3))
+ fail = 1;
+
+ /* Save current values at offsets 0x4F0 and 0x7F0 */
+ if (!read_eeprom(sp, 0x4F0, &org_4F0))
+ saved_4F0 = 1;
+ if (!read_eeprom(sp, 0x7F0, &org_7F0))
+ saved_7F0 = 1;
/* Test Write at offset 4f0 */
- if (write_eeprom(sp, 0x4F0, 0x01234567, 3))
+ if (write_eeprom(sp, 0x4F0, 0x012345, 3))
fail = 1;
if (read_eeprom(sp, 0x4F0, &ret_data))
fail = 1;
- if (ret_data != 0x01234567)
+ if (ret_data != 0x012345) {
+ DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data);
fail = 1;
+ }
/* Reset the EEPROM data go FFFF */
- write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3);
+ write_eeprom(sp, 0x4F0, 0xFFFFFF, 3);
/* Test Write Request Error at offset 0x7c */
- if (!write_eeprom(sp, 0x07C, 0, 3))
- fail = 1;
+ if (sp->device_type == XFRAME_I_DEVICE)
+ if (!write_eeprom(sp, 0x07C, 0, 3))
+ fail = 1;
- /* Test Write Request at offset 0x7fc */
- if (write_eeprom(sp, 0x7FC, 0x01234567, 3))
+ /* Test Write Request at offset 0x7f0 */
+ if (write_eeprom(sp, 0x7F0, 0x012345, 3))
fail = 1;
- if (read_eeprom(sp, 0x7FC, &ret_data))
+ if (read_eeprom(sp, 0x7F0, &ret_data))
fail = 1;
- if (ret_data != 0x01234567)
+ if (ret_data != 0x012345) {
+ DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data);
fail = 1;
+ }
/* Reset the EEPROM data go FFFF */
- write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3);
+ write_eeprom(sp, 0x7F0, 0xFFFFFF, 3);
- /* Test Write Error at offset 0x80 */
- if (!write_eeprom(sp, 0x080, 0, 3))
- fail = 1;
+ if (sp->device_type == XFRAME_I_DEVICE) {
+ /* Test Write Error at offset 0x80 */
+ if (!write_eeprom(sp, 0x080, 0, 3))
+ fail = 1;
- /* Test Write Error at offset 0xfc */
- if (!write_eeprom(sp, 0x0FC, 0, 3))
- fail = 1;
+ /* Test Write Error at offset 0xfc */
+ if (!write_eeprom(sp, 0x0FC, 0, 3))
+ fail = 1;
- /* Test Write Error at offset 0x100 */
- if (!write_eeprom(sp, 0x100, 0, 3))
- fail = 1;
+ /* Test Write Error at offset 0x100 */
+ if (!write_eeprom(sp, 0x100, 0, 3))
+ fail = 1;
- /* Test Write Error at offset 4ec */
- if (!write_eeprom(sp, 0x4EC, 0, 3))
- fail = 1;
+ /* Test Write Error at offset 4ec */
+ if (!write_eeprom(sp, 0x4EC, 0, 3))
+ fail = 1;
+ }
+
+ /* Restore values at offsets 0x4F0 and 0x7F0 */
+ if (saved_4F0)
+ write_eeprom(sp, 0x4F0, org_4F0, 3);
+ if (saved_7F0)
+ write_eeprom(sp, 0x7F0, org_7F0, 3);
*data = fail;
- return 0;
+ return fail;
}
/**
@@ -4341,7 +4821,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
u64 val64;
- int cnt, iteration = 0, test_pass = 0;
+ int cnt, iteration = 0, test_fail = 0;
val64 = readq(&bar0->adapter_control);
val64 &= ~ADAPTER_ECC_EN;
@@ -4349,7 +4829,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
val64 = readq(&bar0->mc_rldram_test_ctrl);
val64 |= MC_RLDRAM_TEST_MODE;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
+ SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
val64 = readq(&bar0->mc_rldram_mrs);
val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
@@ -4377,17 +4857,12 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
}
writeq(val64, &bar0->mc_rldram_test_d2);
- val64 = (u64) (0x0000003fffff0000ULL);
+ val64 = (u64) (0x0000003ffffe0100ULL);
writeq(val64, &bar0->mc_rldram_test_add);
-
- val64 = MC_RLDRAM_TEST_MODE;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
-
- val64 |=
- MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
- MC_RLDRAM_TEST_GO;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
+ val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
+ MC_RLDRAM_TEST_GO;
+ SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
for (cnt = 0; cnt < 5; cnt++) {
val64 = readq(&bar0->mc_rldram_test_ctrl);
@@ -4399,11 +4874,8 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
if (cnt == 5)
break;
- val64 = MC_RLDRAM_TEST_MODE;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
-
- val64 |= MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
+ val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
+ SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
for (cnt = 0; cnt < 5; cnt++) {
val64 = readq(&bar0->mc_rldram_test_ctrl);
@@ -4416,18 +4888,18 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
break;
val64 = readq(&bar0->mc_rldram_test_ctrl);
- if (val64 & MC_RLDRAM_TEST_PASS)
- test_pass = 1;
+ if (!(val64 & MC_RLDRAM_TEST_PASS))
+ test_fail = 1;
iteration++;
}
- if (!test_pass)
- *data = 1;
- else
- *data = 0;
+ *data = test_fail;
- return 0;
+ /* Bring the adapter out of test mode */
+ SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF);
+
+ return test_fail;
}
/**
@@ -4931,7 +5403,7 @@ static void s2io_card_down(nic_t * sp)
static int s2io_card_up(nic_t * sp)
{
- int i, ret;
+ int i, ret = 0;
mac_info_t *mac_control;
struct config_param *config;
struct net_device *dev = (struct net_device *) sp->dev;
@@ -4943,6 +5415,15 @@ static int s2io_card_up(nic_t * sp)
return -ENODEV;
}
+ if (sp->intr_type == MSI)
+ ret = s2io_enable_msi(sp);
+ else if (sp->intr_type == MSI_X)
+ ret = s2io_enable_msi_x(sp);
+ if (ret) {
+ DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
+ sp->intr_type = INTA;
+ }
+
/*
* Initializing the Rx buffers. For now we are considering only 1
* Rx ring and initializing buffers into 30 Rx blocks
@@ -5227,6 +5708,8 @@ static void s2io_init_pci(nic_t * sp)
MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>");
MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
module_param(tx_fifo_num, int, 0);
module_param(rx_ring_num, int, 0);
module_param_array(tx_fifo_len, uint, NULL, 0);
@@ -5244,6 +5727,7 @@ module_param(bimodal, bool, 0);
module_param(indicate_max_pkts, int, 0);
#endif
module_param(rxsync_frequency, int, 0);
+module_param(intr_type, int, 0);
/**
* s2io_init_nic - Initialization of the adapter .
@@ -5273,9 +5757,16 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
mac_info_t *mac_control;
struct config_param *config;
int mode;
+ u8 dev_intr_type = intr_type;
#ifdef CONFIG_S2IO_NAPI
- DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
+ if (dev_intr_type != INTA) {
+ DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \
+is enabled. Defaulting to INTA\n");
+ dev_intr_type = INTA;
+ }
+ else
+ DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
#endif
if ((ret = pci_enable_device(pdev))) {
@@ -5302,10 +5793,35 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
return -ENOMEM;
}
- if (pci_request_regions(pdev, s2io_driver_name)) {
- DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
- pci_disable_device(pdev);
- return -ENODEV;
+ if ((dev_intr_type == MSI_X) &&
+ ((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
+ (pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
+ DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \
+Defaulting to INTA\n");
+ dev_intr_type = INTA;
+ }
+ if (dev_intr_type != MSI_X) {
+ if (pci_request_regions(pdev, s2io_driver_name)) {
+ DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+ }
+ else {
+ if (!(request_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0), s2io_driver_name))) {
+ DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+ if (!(request_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2), s2io_driver_name))) {
+ DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
}
dev = alloc_etherdev(sizeof(nic_t));
@@ -5328,6 +5844,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
sp->pdev = pdev;
sp->high_dma_flag = dma_flag;
sp->device_enabled_once = FALSE;
+ sp->intr_type = dev_intr_type;
if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
(pdev->device == PCI_DEVICE_ID_HERC_UNI))
@@ -5335,6 +5852,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
else
sp->device_type = XFRAME_I_DEVICE;
+
/* Initialize some PCI/PCI-X fields of the NIC. */
s2io_init_pci(sp);
@@ -5570,12 +6088,23 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (sp->device_type & XFRAME_II_DEVICE) {
DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ",
dev->name);
- DBG_PRINT(ERR_DBG, "(rev %d), %s",
+ DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
get_xena_rev_id(sp->pdev),
s2io_driver_version);
#ifdef CONFIG_2BUFF_MODE
DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
#endif
+ switch(sp->intr_type) {
+ case INTA:
+ DBG_PRINT(ERR_DBG, ", Intr type INTA");
+ break;
+ case MSI:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI");
+ break;
+ case MSI_X:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
+ break;
+ }
DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -5594,12 +6123,23 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
} else {
DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ",
dev->name);
- DBG_PRINT(ERR_DBG, "(rev %d), %s",
+ DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
get_xena_rev_id(sp->pdev),
s2io_driver_version);
#ifdef CONFIG_2BUFF_MODE
DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
#endif
+ switch(sp->intr_type) {
+ case INTA:
+ DBG_PRINT(ERR_DBG, ", Intr type INTA");
+ break;
+ case MSI:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI");
+ break;
+ case MSI_X:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
+ break;
+ }
DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
sp->def_mac_addr[0].mac_addr[0],
@@ -5643,7 +6183,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
mem_alloc_failed:
free_shared_mem(sp);
pci_disable_device(pdev);
- pci_release_regions(pdev);
+ if (dev_intr_type != MSI_X)
+ pci_release_regions(pdev);
+ else {
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ release_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ }
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
@@ -5677,7 +6224,14 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
iounmap(sp->bar0);
iounmap(sp->bar1);
pci_disable_device(pdev);
- pci_release_regions(pdev);
+ if (sp->intr_type != MSI_X)
+ pci_release_regions(pdev);
+ else {
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ release_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ }
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
}
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 89151cb52181..1cc24b56760e 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -652,6 +652,30 @@ typedef struct {
#define SMALL_BLK_CNT 30
#define LARGE_BLK_CNT 100
+/*
+ * Structure to keep track of the MSI-X vectors and the corresponding
+ * argument registered against each vector
+ */
+#define MAX_REQUESTED_MSI_X 17
+struct s2io_msix_entry
+{
+ u16 vector;
+ u16 entry;
+ void *arg;
+
+ u8 type;
+#define MSIX_FIFO_TYPE 1
+#define MSIX_RING_TYPE 2
+
+ u8 in_use;
+#define MSIX_REGISTERED_SUCCESS 0xAA
+};
+
+struct msix_info_st {
+ u64 addr;
+ u64 data;
+};
+
/* Structure representing one instance of the NIC */
struct s2io_nic {
#ifdef CONFIG_S2IO_NAPI
@@ -719,13 +743,8 @@ struct s2io_nic {
* a schedule task that will set the correct Link state once the
* NIC's PHY has stabilized after a state change.
*/
-#ifdef INIT_TQUEUE
- struct tq_struct rst_timer_task;
- struct tq_struct set_link_task;
-#else
struct work_struct rst_timer_task;
struct work_struct set_link_task;
-#endif
/* Flag that can be used to turn on or turn off the Rx checksum
* offload feature.
@@ -748,10 +767,23 @@ struct s2io_nic {
atomic_t card_state;
volatile unsigned long link_state;
struct vlan_group *vlgrp;
+#define MSIX_FLG 0xA5
+ struct msix_entry *entries;
+ struct s2io_msix_entry *s2io_entries;
+ char desc1[35];
+ char desc2[35];
+
+ struct msix_info_st msix_info[0x3f];
+
#define XFRAME_I_DEVICE 1
#define XFRAME_II_DEVICE 2
u8 device_type;
+#define INTA 0
+#define MSI 1
+#define MSI_X 2
+ u8 intr_type;
+
spinlock_t rx_lock;
atomic_t isr_cnt;
};
@@ -886,6 +918,13 @@ static int s2io_poll(struct net_device *dev, int *budget);
static void s2io_init_pci(nic_t * sp);
int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
static void s2io_alarm_handle(unsigned long data);
+static int s2io_enable_msi(nic_t *nic);
+static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t
+s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t
+s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs);
+int s2io_enable_msi_x(nic_t *nic);
static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
static struct ethtool_ops netdev_ethtool_ops;
@@ -894,4 +933,5 @@ int s2io_set_swapper(nic_t * sp);
static void s2io_card_down(nic_t *nic);
static int s2io_card_up(nic_t *nic);
int get_xena_rev_id(struct pci_dev *pdev);
+void restore_xmsi_data(nic_t *nic);
#endif /* _S2IO_H */
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 7abd55a4fb21..aa4ca1821759 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -10,7 +10,7 @@
* 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.
@@ -118,8 +118,6 @@ MODULE_PARM_DESC(int_timeout, "Timeout value");
********************************************************************* */
-typedef unsigned long sbmac_port_t;
-
typedef enum { sbmac_speed_auto, sbmac_speed_10,
sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
@@ -129,7 +127,7 @@ typedef enum { sbmac_duplex_auto, sbmac_duplex_half,
typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
-typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
+typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
sbmac_state_broken } sbmac_state_t;
@@ -144,17 +142,13 @@ typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES)
-#define SBMAC_READCSR(t) __raw_readq((unsigned long)t)
-#define SBMAC_WRITECSR(t,v) __raw_writeq(v, (unsigned long)t)
-
-
#define SBMAC_MAX_TXDESCR 32
#define SBMAC_MAX_RXDESCR 32
#define ETHER_ALIGN 2
#define ETHER_ADDR_LEN 6
-#define ENET_PACKET_SIZE 1518
-/*#define ENET_PACKET_SIZE 9216 */
+#define ENET_PACKET_SIZE 1518
+/*#define ENET_PACKET_SIZE 9216 */
/**********************************************************************
* DMA Descriptor structure
@@ -172,12 +166,12 @@ typedef unsigned long paddr_t;
********************************************************************* */
typedef struct sbmacdma_s {
-
- /*
+
+ /*
* This stuff is used to identify the channel and the registers
* associated with it.
*/
-
+
struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */
int sbdma_channel; /* channel number */
int sbdma_txdir; /* direction (1=transmit) */
@@ -187,21 +181,21 @@ typedef struct sbmacdma_s {
int sbdma_int_timeout; /* # usec rx/tx interrupt */
#endif
- sbmac_port_t sbdma_config0; /* DMA config register 0 */
- sbmac_port_t sbdma_config1; /* DMA config register 1 */
- sbmac_port_t sbdma_dscrbase; /* Descriptor base address */
- sbmac_port_t sbdma_dscrcnt; /* Descriptor count register */
- sbmac_port_t sbdma_curdscr; /* current descriptor address */
-
+ volatile void __iomem *sbdma_config0; /* DMA config register 0 */
+ volatile void __iomem *sbdma_config1; /* DMA config register 1 */
+ volatile void __iomem *sbdma_dscrbase; /* Descriptor base address */
+ volatile void __iomem *sbdma_dscrcnt; /* Descriptor count register */
+ volatile void __iomem *sbdma_curdscr; /* current descriptor address */
+
/*
* This stuff is for maintenance of the ring
*/
-
+
sbdmadscr_t *sbdma_dscrtable; /* base of descriptor table */
sbdmadscr_t *sbdma_dscrtable_end; /* end of descriptor table */
-
+
struct sk_buff **sbdma_ctxtable; /* context table, one per descr */
-
+
paddr_t sbdma_dscrtable_phys; /* and also the phys addr */
sbdmadscr_t *sbdma_addptr; /* next dscr for sw to add */
sbdmadscr_t *sbdma_remptr; /* next dscr for sw to remove */
@@ -213,15 +207,15 @@ typedef struct sbmacdma_s {
********************************************************************* */
struct sbmac_softc {
-
+
/*
* Linux-specific things
*/
-
+
struct net_device *sbm_dev; /* pointer to linux device */
spinlock_t sbm_lock; /* spin lock */
struct timer_list sbm_timer; /* for monitoring MII */
- struct net_device_stats sbm_stats;
+ struct net_device_stats sbm_stats;
int sbm_devflags; /* current device flags */
int sbm_phy_oldbmsr;
@@ -229,31 +223,31 @@ struct sbmac_softc {
int sbm_phy_oldk1stsr;
int sbm_phy_oldlinkstat;
int sbm_buffersize;
-
+
unsigned char sbm_phys[2];
-
+
/*
* Controller-specific things
*/
-
- unsigned long sbm_base; /* MAC's base address */
+
+ volatile void __iomem *sbm_base; /* MAC's base address */
sbmac_state_t sbm_state; /* current state */
-
- sbmac_port_t sbm_macenable; /* MAC Enable Register */
- sbmac_port_t sbm_maccfg; /* MAC Configuration Register */
- sbmac_port_t sbm_fifocfg; /* FIFO configuration register */
- sbmac_port_t sbm_framecfg; /* Frame configuration register */
- sbmac_port_t sbm_rxfilter; /* receive filter register */
- sbmac_port_t sbm_isr; /* Interrupt status register */
- sbmac_port_t sbm_imr; /* Interrupt mask register */
- sbmac_port_t sbm_mdio; /* MDIO register */
-
+
+ volatile void __iomem *sbm_macenable; /* MAC Enable Register */
+ volatile void __iomem *sbm_maccfg; /* MAC Configuration Register */
+ volatile void __iomem *sbm_fifocfg; /* FIFO configuration register */
+ volatile void __iomem *sbm_framecfg; /* Frame configuration register */
+ volatile void __iomem *sbm_rxfilter; /* receive filter register */
+ volatile void __iomem *sbm_isr; /* Interrupt status register */
+ volatile void __iomem *sbm_imr; /* Interrupt mask register */
+ volatile void __iomem *sbm_mdio; /* MDIO register */
+
sbmac_speed_t sbm_speed; /* current speed */
sbmac_duplex_t sbm_duplex; /* current duplex */
sbmac_fc_t sbm_fc; /* current flow control setting */
-
+
unsigned char sbm_hwaddr[ETHER_ADDR_LEN];
-
+
sbmacdma_t sbm_txdma; /* for now, only use channel 0 */
sbmacdma_t sbm_rxdma;
int rx_hw_checksum;
@@ -302,6 +296,7 @@ static void sbmac_set_rx_mode(struct net_device *dev);
static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int sbmac_close(struct net_device *dev);
static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
+static int sbmac_mii_probe(struct net_device *dev);
static void sbmac_mii_sync(struct sbmac_softc *s);
static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt);
@@ -439,6 +434,9 @@ static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
#define MII_BMCR 0x00 /* Basic mode control register (rw) */
#define MII_BMSR 0x01 /* Basic mode status register (ro) */
+#define MII_PHYIDR1 0x02
+#define MII_PHYIDR2 0x03
+
#define MII_K1STSR 0x0A /* 1K Status Register (ro) */
#define MII_ANLPAR 0x05 /* Autonegotiation lnk partner abilities (rw) */
@@ -450,13 +448,13 @@ static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
/**********************************************************************
* SBMAC_MII_SYNC(s)
- *
+ *
* Synchronize with the MII - send a pattern of bits to the MII
* that will guarantee that it is ready to accept a command.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -467,25 +465,25 @@ static void sbmac_mii_sync(struct sbmac_softc *s)
uint64_t bits;
int mac_mdio_genc;
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
-
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+
bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
-
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
-
+
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+
for (cnt = 0; cnt < 32; cnt++) {
- SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+ __raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
}
}
/**********************************************************************
* SBMAC_MII_SENDDATA(s,data,bitcnt)
- *
+ *
* Send some bits to the MII. The bits to be sent are right-
* justified in the 'data' parameter.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* data - data to send
* bitcnt - number of bits to send
@@ -498,20 +496,20 @@ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitc
unsigned int curmask;
int mac_mdio_genc;
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
-
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+
bits = M_MAC_MDIO_DIR_OUTPUT;
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
-
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+
curmask = 1 << (bitcnt - 1);
-
+
for (i = 0; i < bitcnt; i++) {
if (data & curmask)
bits |= M_MAC_MDIO_OUT;
else bits &= ~M_MAC_MDIO_OUT;
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
curmask >>= 1;
}
}
@@ -520,14 +518,14 @@ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitc
/**********************************************************************
* SBMAC_MII_READ(s,phyaddr,regidx)
- *
+ *
* Read a PHY register.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* phyaddr - PHY's address
* regidx = index of register to read
- *
+ *
* Return value:
* value read, or 0 if an error occurred.
********************************************************************* */
@@ -543,9 +541,9 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
* Synchronize ourselves so that the PHY knows the next
* thing coming down is a command
*/
-
+
sbmac_mii_sync(s);
-
+
/*
* Send the data to the PHY. The sequence is
* a "start" command (2 bits)
@@ -553,59 +551,55 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
* the PHY addr (5 bits)
* the register index (5 bits)
*/
-
+
sbmac_mii_senddata(s,MII_COMMAND_START, 2);
sbmac_mii_senddata(s,MII_COMMAND_READ, 2);
sbmac_mii_senddata(s,phyaddr, 5);
sbmac_mii_senddata(s,regidx, 5);
-
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
-
- /*
+
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+
+ /*
* Switch the port around without a clock transition.
*/
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
-
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+
/*
* Send out a clock pulse to signal we want the status
*/
-
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
-
- /*
+
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+
+ /*
* If an error occurred, the PHY will signal '1' back
*/
- error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN;
-
- /*
+ error = __raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN;
+
+ /*
* Issue an 'idle' clock pulse, but keep the direction
* the same.
*/
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
-
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+
regval = 0;
-
+
for (idx = 0; idx < 16; idx++) {
regval <<= 1;
-
+
if (error == 0) {
- if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN)
+ if (__raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN)
regval |= 1;
}
-
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
}
-
+
/* Switch back to output */
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
-
+ __raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
+
if (error == 0)
return regval;
return 0;
@@ -614,15 +608,15 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
/**********************************************************************
* SBMAC_MII_WRITE(s,phyaddr,regidx,regval)
- *
+ *
* Write a value to a PHY register.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* phyaddr - PHY to use
* regidx - register within the PHY
* regval - data to write to register
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -633,7 +627,7 @@ static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
int mac_mdio_genc;
sbmac_mii_sync(s);
-
+
sbmac_mii_senddata(s,MII_COMMAND_START,2);
sbmac_mii_senddata(s,MII_COMMAND_WRITE,2);
sbmac_mii_senddata(s,phyaddr, 5);
@@ -641,27 +635,27 @@ static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
sbmac_mii_senddata(s,MII_COMMAND_ACK,2);
sbmac_mii_senddata(s,regval,16);
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
+ __raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
}
/**********************************************************************
* SBDMA_INITCTX(d,s,chan,txrx,maxdescr)
- *
+ *
* Initialize a DMA channel context. Since there are potentially
* eight DMA channels per MAC, it's nice to do this in a standard
- * way.
- *
- * Input parameters:
+ * way.
+ *
+ * Input parameters:
* d - sbmacdma_t structure (DMA channel context)
* s - sbmac_softc structure (pointer to a MAC)
* chan - channel number (0..1 right now)
* txrx - Identifies DMA_TX or DMA_RX for channel direction
* maxdescr - number of descriptors
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -672,101 +666,87 @@ static void sbdma_initctx(sbmacdma_t *d,
int txrx,
int maxdescr)
{
- /*
- * Save away interesting stuff in the structure
+ /*
+ * Save away interesting stuff in the structure
*/
-
+
d->sbdma_eth = s;
d->sbdma_channel = chan;
d->sbdma_txdir = txrx;
-
+
#if 0
/* RMON clearing */
s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING;
#endif
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0);
-
- /*
- * initialize register pointers
- */
-
- d->sbdma_config0 =
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)));
+
+ /*
+ * initialize register pointers
+ */
+
+ d->sbdma_config0 =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0);
- d->sbdma_config1 =
+ d->sbdma_config1 =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1);
- d->sbdma_dscrbase =
+ d->sbdma_dscrbase =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE);
- d->sbdma_dscrcnt =
+ d->sbdma_dscrcnt =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT);
- d->sbdma_curdscr =
+ d->sbdma_curdscr =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR);
-
+
/*
* Allocate memory for the ring
*/
-
+
d->sbdma_maxdescr = maxdescr;
-
- d->sbdma_dscrtable = (sbdmadscr_t *)
- kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL);
-
+
+ d->sbdma_dscrtable = (sbdmadscr_t *)
+ kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
+
+ /*
+ * The descriptor table must be aligned to at least 16 bytes or the
+ * MAC will corrupt it.
+ */
+ d->sbdma_dscrtable = (sbdmadscr_t *)
+ ALIGN((unsigned long)d->sbdma_dscrtable, sizeof(sbdmadscr_t));
+
memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t));
-
+
d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr;
-
+
d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable);
-
+
/*
* And context table
*/
-
- d->sbdma_ctxtable = (struct sk_buff **)
+
+ d->sbdma_ctxtable = (struct sk_buff **)
kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL);
-
+
memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *));
-
+
#ifdef CONFIG_SBMAC_COALESCE
/*
* Setup Rx/Tx DMA coalescing defaults
@@ -777,7 +757,7 @@ static void sbdma_initctx(sbmacdma_t *d,
} else {
d->sbdma_int_pktcnt = 1;
}
-
+
if ( int_timeout ) {
d->sbdma_int_timeout = int_timeout;
} else {
@@ -789,13 +769,13 @@ static void sbdma_initctx(sbmacdma_t *d,
/**********************************************************************
* SBDMA_CHANNEL_START(d)
- *
+ *
* Initialize the hardware registers for a DMA channel.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel to init (context must be previously init'd
* rxtx - DMA_RX or DMA_TX depending on what type of channel
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -805,24 +785,21 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
/*
* Turn on the DMA channel
*/
-
+
#ifdef CONFIG_SBMAC_COALESCE
- SBMAC_WRITECSR(d->sbdma_config1,
- V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
- 0);
- SBMAC_WRITECSR(d->sbdma_config0,
- M_DMA_EOP_INT_EN |
+ __raw_writeq(V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
+ 0, d->sbdma_config1);
+ __raw_writeq(M_DMA_EOP_INT_EN |
V_DMA_RINGSZ(d->sbdma_maxdescr) |
V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) |
- 0);
+ 0, d->sbdma_config0);
#else
- SBMAC_WRITECSR(d->sbdma_config1,0);
- SBMAC_WRITECSR(d->sbdma_config0,
- V_DMA_RINGSZ(d->sbdma_maxdescr) |
- 0);
+ __raw_writeq(0, d->sbdma_config1);
+ __raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) |
+ 0, d->sbdma_config0);
#endif
- SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
+ __raw_writeq(d->sbdma_dscrtable_phys, d->sbdma_dscrbase);
/*
* Initialize ring pointers
@@ -834,12 +811,12 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
/**********************************************************************
* SBDMA_CHANNEL_STOP(d)
- *
+ *
* Initialize the hardware registers for a DMA channel.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel to init (context must be previously init'd
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -849,44 +826,44 @@ static void sbdma_channel_stop(sbmacdma_t *d)
/*
* Turn off the DMA channel
*/
-
- SBMAC_WRITECSR(d->sbdma_config1,0);
-
- SBMAC_WRITECSR(d->sbdma_dscrbase,0);
-
- SBMAC_WRITECSR(d->sbdma_config0,0);
-
+
+ __raw_writeq(0, d->sbdma_config1);
+
+ __raw_writeq(0, d->sbdma_dscrbase);
+
+ __raw_writeq(0, d->sbdma_config0);
+
/*
* Zero ring pointers
*/
-
- d->sbdma_addptr = 0;
- d->sbdma_remptr = 0;
+
+ d->sbdma_addptr = NULL;
+ d->sbdma_remptr = NULL;
}
static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
{
unsigned long addr;
unsigned long newaddr;
-
+
addr = (unsigned long) skb->data;
-
+
newaddr = (addr + power2 - 1) & ~(power2 - 1);
-
+
skb_reserve(skb,newaddr-addr+offset);
}
/**********************************************************************
* SBDMA_ADD_RCVBUFFER(d,sb)
- *
+ *
* Add a buffer to the specified DMA channel. For receive channels,
* this queues a buffer for inbound packets.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel descriptor
* sb - sk_buff to add, or NULL if we should allocate one
- *
+ *
* Return value:
* 0 if buffer could not be added (ring is full)
* 1 if buffer added successfully
@@ -899,24 +876,24 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
sbdmadscr_t *nextdsc;
struct sk_buff *sb_new = NULL;
int pktsize = ENET_PACKET_SIZE;
-
+
/* get pointer to our current place in the ring */
-
+
dsc = d->sbdma_addptr;
nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
-
+
/*
* figure out if the ring is full - if the next descriptor
* is the same as the one that we're going to remove from
* the ring, the ring is full
*/
-
+
if (nextdsc == d->sbdma_remptr) {
return -ENOSPC;
}
- /*
- * Allocate a sk_buff if we don't already have one.
+ /*
+ * Allocate a sk_buff if we don't already have one.
* If we do have an sk_buff, reset it so that it's empty.
*
* Note: sk_buffs don't seem to be guaranteed to have any sort
@@ -925,7 +902,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
*
* 1. the data does not start in the middle of a cache line.
* 2. The data does not end in the middle of a cache line
- * 3. The buffer can be aligned such that the IP addresses are
+ * 3. The buffer can be aligned such that the IP addresses are
* naturally aligned.
*
* Remember, the SOCs MAC writes whole cache lines at a time,
@@ -933,7 +910,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
* data portion starts in the middle of a cache line, the SOC
* DMA will trash the beginning (and ending) portions.
*/
-
+
if (sb == NULL) {
sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN);
if (sb_new == NULL) {
@@ -949,23 +926,22 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
}
else {
sb_new = sb;
- /*
+ /*
* nothing special to reinit buffer, it's already aligned
* and sb->data already points to a good place.
*/
}
-
+
/*
- * fill in the descriptor
+ * fill in the descriptor
*/
-
+
#ifdef CONFIG_SBMAC_COALESCE
/*
* Do not interrupt per DMA transfer.
*/
dsc->dscr_a = virt_to_phys(sb_new->data) |
- V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
- 0;
+ V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0;
#else
dsc->dscr_a = virt_to_phys(sb_new->data) |
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
@@ -974,38 +950,38 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
/* receiving: no options */
dsc->dscr_b = 0;
-
+
/*
- * fill in the context
+ * fill in the context
*/
-
+
d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new;
-
- /*
- * point at next packet
+
+ /*
+ * point at next packet
*/
-
+
d->sbdma_addptr = nextdsc;
-
- /*
+
+ /*
* Give the buffer to the DMA engine.
*/
-
- SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
-
+
+ __raw_writeq(1, d->sbdma_dscrcnt);
+
return 0; /* we did it */
}
/**********************************************************************
* SBDMA_ADD_TXBUFFER(d,sb)
- *
+ *
* Add a transmit buffer to the specified DMA channel, causing a
* transmit to start.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel descriptor
* sb - sk_buff to add
- *
+ *
* Return value:
* 0 transmit queued successfully
* otherwise error code
@@ -1019,70 +995,70 @@ static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
uint64_t phys;
uint64_t ncb;
int length;
-
+
/* get pointer to our current place in the ring */
-
+
dsc = d->sbdma_addptr;
nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
-
+
/*
* figure out if the ring is full - if the next descriptor
* is the same as the one that we're going to remove from
* the ring, the ring is full
*/
-
+
if (nextdsc == d->sbdma_remptr) {
return -ENOSPC;
}
-
+
/*
* Under Linux, it's not necessary to copy/coalesce buffers
* like it is on NetBSD. We think they're all contiguous,
* but that may not be true for GBE.
*/
-
+
length = sb->len;
-
+
/*
* fill in the descriptor. Note that the number of cache
* blocks in the descriptor is the number of blocks
* *spanned*, so we need to add in the offset (if any)
* while doing the calculation.
*/
-
+
phys = virt_to_phys(sb->data);
ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1)));
- dsc->dscr_a = phys |
+ dsc->dscr_a = phys |
V_DMA_DSCRA_A_SIZE(ncb) |
#ifndef CONFIG_SBMAC_COALESCE
M_DMA_DSCRA_INTERRUPT |
#endif
M_DMA_ETHTX_SOP;
-
+
/* transmitting: set outbound options and length */
dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
V_DMA_DSCRB_PKT_SIZE(length);
-
+
/*
- * fill in the context
+ * fill in the context
*/
-
+
d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb;
-
- /*
- * point at next packet
+
+ /*
+ * point at next packet
*/
-
+
d->sbdma_addptr = nextdsc;
-
- /*
+
+ /*
* Give the buffer to the DMA engine.
*/
-
- SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
-
+
+ __raw_writeq(1, d->sbdma_dscrcnt);
+
return 0; /* we did it */
}
@@ -1091,12 +1067,12 @@ static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
/**********************************************************************
* SBDMA_EMPTYRING(d)
- *
+ *
* Free all allocated sk_buffs on the specified DMA channel;
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1105,7 +1081,7 @@ static void sbdma_emptyring(sbmacdma_t *d)
{
int idx;
struct sk_buff *sb;
-
+
for (idx = 0; idx < d->sbdma_maxdescr; idx++) {
sb = d->sbdma_ctxtable[idx];
if (sb) {
@@ -1118,13 +1094,13 @@ static void sbdma_emptyring(sbmacdma_t *d)
/**********************************************************************
* SBDMA_FILLRING(d)
- *
+ *
* Fill the specified DMA channel (must be receive channel)
* with sk_buffs
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1132,7 +1108,7 @@ static void sbdma_emptyring(sbmacdma_t *d)
static void sbdma_fillring(sbmacdma_t *d)
{
int idx;
-
+
for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) {
if (sbdma_add_rcvbuffer(d,NULL) != 0)
break;
@@ -1142,16 +1118,16 @@ static void sbdma_fillring(sbmacdma_t *d)
/**********************************************************************
* SBDMA_RX_PROCESS(sc,d)
- *
- * Process "completed" receive buffers on the specified DMA channel.
+ *
+ * Process "completed" receive buffers on the specified DMA channel.
* Note that this isn't really ideal for priority channels, since
- * it processes all of the packets on a given channel before
- * returning.
+ * it processes all of the packets on a given channel before
+ * returning.
*
- * Input parameters:
+ * Input parameters:
* sc - softc structure
* d - DMA channel context
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1163,56 +1139,56 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
sbdmadscr_t *dsc;
struct sk_buff *sb;
int len;
-
+
for (;;) {
- /*
+ /*
* figure out where we are (as an index) and where
* the hardware is (also as an index)
*
- * This could be done faster if (for example) the
+ * This could be done faster if (for example) the
* descriptor table was page-aligned and contiguous in
* both virtual and physical memory -- you could then
* just compare the low-order bits of the virtual address
* (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
*/
-
+
curidx = d->sbdma_remptr - d->sbdma_dscrtable;
- hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+ hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
-
+
/*
* If they're the same, that means we've processed all
* of the descriptors up to (but not including) the one that
* the hardware is working on right now.
*/
-
+
if (curidx == hwidx)
break;
-
+
/*
* Otherwise, get the packet's sk_buff ptr back
*/
-
+
dsc = &(d->sbdma_dscrtable[curidx]);
sb = d->sbdma_ctxtable[curidx];
d->sbdma_ctxtable[curidx] = NULL;
-
+
len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4;
-
+
/*
* Check packet status. If good, process it.
* If not, silently drop it and put it back on the
* receive ring.
*/
-
+
if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) {
-
+
/*
* Add a new buffer to replace the old one. If we fail
* to allocate a buffer, we're going to drop this
* packet and put it right back on the receive ring.
*/
-
+
if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) {
sc->sbm_stats.rx_dropped++;
sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */
@@ -1221,7 +1197,7 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
* Set length into the packet
*/
skb_put(sb,len);
-
+
/*
* Buffer has been replaced on the
* receive ring. Pass the buffer to
@@ -1240,7 +1216,7 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
sb->ip_summed = CHECKSUM_NONE;
}
}
-
+
netif_rx(sb);
}
} else {
@@ -1251,14 +1227,14 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
sc->sbm_stats.rx_errors++;
sbdma_add_rcvbuffer(d,sb);
}
-
-
- /*
+
+
+ /*
* .. and advance to the next buffer.
*/
-
+
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
-
+
}
}
@@ -1266,17 +1242,17 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
/**********************************************************************
* SBDMA_TX_PROCESS(sc,d)
- *
- * Process "completed" transmit buffers on the specified DMA channel.
+ *
+ * Process "completed" transmit buffers on the specified DMA channel.
* This is normally called within the interrupt service routine.
* Note that this isn't really ideal for priority channels, since
- * it processes all of the packets on a given channel before
- * returning.
+ * it processes all of the packets on a given channel before
+ * returning.
*
- * Input parameters:
+ * Input parameters:
* sc - softc structure
* d - DMA channel context
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1290,21 +1266,21 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
unsigned long flags;
spin_lock_irqsave(&(sc->sbm_lock), flags);
-
+
for (;;) {
- /*
+ /*
* figure out where we are (as an index) and where
* the hardware is (also as an index)
*
- * This could be done faster if (for example) the
+ * This could be done faster if (for example) the
* descriptor table was page-aligned and contiguous in
* both virtual and physical memory -- you could then
* just compare the low-order bits of the virtual address
* (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
*/
-
+
curidx = d->sbdma_remptr - d->sbdma_dscrtable;
- hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+ hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
/*
@@ -1312,75 +1288,75 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
* of the descriptors up to (but not including) the one that
* the hardware is working on right now.
*/
-
+
if (curidx == hwidx)
break;
-
+
/*
* Otherwise, get the packet's sk_buff ptr back
*/
-
+
dsc = &(d->sbdma_dscrtable[curidx]);
sb = d->sbdma_ctxtable[curidx];
d->sbdma_ctxtable[curidx] = NULL;
-
+
/*
* Stats
*/
-
+
sc->sbm_stats.tx_bytes += sb->len;
sc->sbm_stats.tx_packets++;
-
+
/*
* for transmits, we just free buffers.
*/
-
+
dev_kfree_skb_irq(sb);
-
- /*
+
+ /*
* .. and advance to the next buffer.
*/
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
-
+
}
-
+
/*
* Decide if we should wake up the protocol or not.
* Other drivers seem to do this when we reach a low
* watermark on the transmit queue.
*/
-
+
netif_wake_queue(d->sbdma_eth->sbm_dev);
-
+
spin_unlock_irqrestore(&(sc->sbm_lock), flags);
-
+
}
/**********************************************************************
* SBMAC_INITCTX(s)
- *
+ *
* Initialize an Ethernet context structure - this is called
* once per MAC on the 1250. Memory is allocated here, so don't
* call it again from inside the ioctl routines that bring the
* interface up/down
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac context structure
- *
+ *
* Return value:
* 0
********************************************************************* */
static int sbmac_initctx(struct sbmac_softc *s)
{
-
- /*
- * figure out the addresses of some ports
+
+ /*
+ * figure out the addresses of some ports
*/
-
+
s->sbm_macenable = s->sbm_base + R_MAC_ENABLE;
s->sbm_maccfg = s->sbm_base + R_MAC_CFG;
s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG;
@@ -1397,29 +1373,29 @@ static int sbmac_initctx(struct sbmac_softc *s)
s->sbm_phy_oldanlpar = 0;
s->sbm_phy_oldk1stsr = 0;
s->sbm_phy_oldlinkstat = 0;
-
+
/*
* Initialize the DMA channels. Right now, only one per MAC is used
* Note: Only do this _once_, as it allocates memory from the kernel!
*/
-
+
sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR);
sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR);
-
+
/*
* initial state is OFF
*/
-
+
s->sbm_state = sbmac_state_off;
-
+
/*
* Initial speed is (XXX TEMP) 10MBit/s HDX no FC
*/
-
+
s->sbm_speed = sbmac_speed_10;
s->sbm_duplex = sbmac_duplex_half;
s->sbm_fc = sbmac_fc_disabled;
-
+
return 0;
}
@@ -1430,7 +1406,7 @@ static void sbdma_uninitctx(struct sbmacdma_s *d)
kfree(d->sbdma_dscrtable);
d->sbdma_dscrtable = NULL;
}
-
+
if (d->sbdma_ctxtable) {
kfree(d->sbdma_ctxtable);
d->sbdma_ctxtable = NULL;
@@ -1447,12 +1423,12 @@ static void sbmac_uninitctx(struct sbmac_softc *sc)
/**********************************************************************
* SBMAC_CHANNEL_START(s)
- *
+ *
* Start packet processing on this MAC.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1460,49 +1436,49 @@ static void sbmac_uninitctx(struct sbmac_softc *sc)
static void sbmac_channel_start(struct sbmac_softc *s)
{
uint64_t reg;
- sbmac_port_t port;
+ volatile void __iomem *port;
uint64_t cfg,fifo,framecfg;
int idx, th_value;
-
+
/*
* Don't do this if running
*/
if (s->sbm_state == sbmac_state_on)
return;
-
+
/*
* Bring the controller out of reset, but leave it off.
*/
-
- SBMAC_WRITECSR(s->sbm_macenable,0);
-
+
+ __raw_writeq(0, s->sbm_macenable);
+
/*
* Ignore all received packets
*/
-
- SBMAC_WRITECSR(s->sbm_rxfilter,0);
-
- /*
+
+ __raw_writeq(0, s->sbm_rxfilter);
+
+ /*
* Calculate values for various control registers.
*/
-
+
cfg = M_MAC_RETRY_EN |
- M_MAC_TX_HOLD_SOP_EN |
+ M_MAC_TX_HOLD_SOP_EN |
V_MAC_TX_PAUSE_CNT_16K |
M_MAC_AP_STAT_EN |
M_MAC_FAST_SYNC |
M_MAC_SS_EN |
0;
-
- /*
+
+ /*
* Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars
* and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above
* Use a larger RD_THRSH for gigabit
*/
- if (periph_rev >= 2)
+ if (periph_rev >= 2)
th_value = 64;
- else
+ else
th_value = 28;
fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */
@@ -1520,51 +1496,51 @@ static void sbmac_channel_start(struct sbmac_softc *s)
V_MAC_BACKOFF_SEL(1);
/*
- * Clear out the hash address map
+ * Clear out the hash address map
*/
-
+
port = s->sbm_base + R_MAC_HASH_BASE;
for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
-
+
/*
* Clear out the exact-match table
*/
-
+
port = s->sbm_base + R_MAC_ADDR_BASE;
for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
-
+
/*
* Clear out the DMA Channel mapping table registers
*/
-
+
port = s->sbm_base + R_MAC_CHUP0_BASE;
for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
port = s->sbm_base + R_MAC_CHLO0_BASE;
for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
-
+
/*
* Program the hardware address. It goes into the hardware-address
* register as well as the first filter register.
*/
-
+
reg = sbmac_addr2reg(s->sbm_hwaddr);
-
+
port = s->sbm_base + R_MAC_ADDR_BASE;
- SBMAC_WRITECSR(port,reg);
+ __raw_writeq(reg, port);
port = s->sbm_base + R_MAC_ETHERNET_ADDR;
#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
@@ -1573,108 +1549,105 @@ static void sbmac_channel_start(struct sbmac_softc *s)
* destination address in the R_MAC_ETHERNET_ADDR register.
* Set the value to zero.
*/
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
#else
- SBMAC_WRITECSR(port,reg);
+ __raw_writeq(reg, port);
#endif
-
+
/*
* Set the receive filter for no packets, and write values
* to the various config registers
*/
-
- SBMAC_WRITECSR(s->sbm_rxfilter,0);
- SBMAC_WRITECSR(s->sbm_imr,0);
- SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
- SBMAC_WRITECSR(s->sbm_fifocfg,fifo);
- SBMAC_WRITECSR(s->sbm_maccfg,cfg);
-
+
+ __raw_writeq(0, s->sbm_rxfilter);
+ __raw_writeq(0, s->sbm_imr);
+ __raw_writeq(framecfg, s->sbm_framecfg);
+ __raw_writeq(fifo, s->sbm_fifocfg);
+ __raw_writeq(cfg, s->sbm_maccfg);
+
/*
* Initialize DMA channels (rings should be ok now)
*/
-
+
sbdma_channel_start(&(s->sbm_rxdma), DMA_RX);
sbdma_channel_start(&(s->sbm_txdma), DMA_TX);
-
+
/*
* Configure the speed, duplex, and flow control
*/
sbmac_set_speed(s,s->sbm_speed);
sbmac_set_duplex(s,s->sbm_duplex,s->sbm_fc);
-
+
/*
* Fill the receive ring
*/
-
+
sbdma_fillring(&(s->sbm_rxdma));
-
- /*
+
+ /*
* Turn on the rest of the bits in the enable register
- */
-
- SBMAC_WRITECSR(s->sbm_macenable,
- M_MAC_RXDMA_EN0 |
+ */
+
+ __raw_writeq(M_MAC_RXDMA_EN0 |
M_MAC_TXDMA_EN0 |
M_MAC_RX_ENABLE |
- M_MAC_TX_ENABLE);
-
-
+ M_MAC_TX_ENABLE, s->sbm_macenable);
+
+
#ifdef CONFIG_SBMAC_COALESCE
/*
* Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
*/
- SBMAC_WRITECSR(s->sbm_imr,
- ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
- ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0));
+ __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
+ ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr);
#else
/*
* Accept any kind of interrupt on TX and RX DMA channel 0
*/
- SBMAC_WRITECSR(s->sbm_imr,
- (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
- (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
+ __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+ (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
#endif
-
- /*
- * Enable receiving unicasts and broadcasts
+
+ /*
+ * Enable receiving unicasts and broadcasts
*/
-
- SBMAC_WRITECSR(s->sbm_rxfilter,M_MAC_UCAST_EN | M_MAC_BCAST_EN);
-
+
+ __raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter);
+
/*
- * we're running now.
+ * we're running now.
*/
-
+
s->sbm_state = sbmac_state_on;
-
- /*
- * Program multicast addresses
+
+ /*
+ * Program multicast addresses
*/
-
+
sbmac_setmulti(s);
-
- /*
- * If channel was in promiscuous mode before, turn that on
+
+ /*
+ * If channel was in promiscuous mode before, turn that on
*/
-
+
if (s->sbm_devflags & IFF_PROMISC) {
sbmac_promiscuous_mode(s,1);
}
-
+
}
/**********************************************************************
* SBMAC_CHANNEL_STOP(s)
- *
+ *
* Stop packet processing on this MAC.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1682,49 +1655,49 @@ static void sbmac_channel_start(struct sbmac_softc *s)
static void sbmac_channel_stop(struct sbmac_softc *s)
{
/* don't do this if already stopped */
-
+
if (s->sbm_state == sbmac_state_off)
return;
-
+
/* don't accept any packets, disable all interrupts */
-
- SBMAC_WRITECSR(s->sbm_rxfilter,0);
- SBMAC_WRITECSR(s->sbm_imr,0);
-
+
+ __raw_writeq(0, s->sbm_rxfilter);
+ __raw_writeq(0, s->sbm_imr);
+
/* Turn off ticker */
-
+
/* XXX */
-
+
/* turn off receiver and transmitter */
-
- SBMAC_WRITECSR(s->sbm_macenable,0);
-
+
+ __raw_writeq(0, s->sbm_macenable);
+
/* We're stopped now. */
-
+
s->sbm_state = sbmac_state_off;
-
+
/*
* Stop DMA channels (rings should be ok now)
*/
-
+
sbdma_channel_stop(&(s->sbm_rxdma));
sbdma_channel_stop(&(s->sbm_txdma));
-
+
/* Empty the receive and transmit rings */
-
+
sbdma_emptyring(&(s->sbm_rxdma));
sbdma_emptyring(&(s->sbm_txdma));
-
+
}
/**********************************************************************
* SBMAC_SET_CHANNEL_STATE(state)
- *
+ *
* Set the channel's state ON or OFF
- *
- * Input parameters:
+ *
+ * Input parameters:
* state - new state
- *
+ *
* Return value:
* old state
********************************************************************* */
@@ -1732,43 +1705,43 @@ static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
sbmac_state_t state)
{
sbmac_state_t oldstate = sc->sbm_state;
-
+
/*
* If same as previous state, return
*/
-
+
if (state == oldstate) {
return oldstate;
}
-
+
/*
- * If new state is ON, turn channel on
+ * If new state is ON, turn channel on
*/
-
+
if (state == sbmac_state_on) {
sbmac_channel_start(sc);
}
else {
sbmac_channel_stop(sc);
}
-
+
/*
* Return previous state
*/
-
+
return oldstate;
}
/**********************************************************************
* SBMAC_PROMISCUOUS_MODE(sc,onoff)
- *
+ *
* Turn on or off promiscuous mode
- *
- * Input parameters:
+ *
+ * Input parameters:
* sc - softc
* onoff - 1 to turn on, 0 to turn off
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1776,30 +1749,30 @@ static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
{
uint64_t reg;
-
+
if (sc->sbm_state != sbmac_state_on)
return;
-
+
if (onoff) {
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg |= M_MAC_ALLPKT_EN;
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
- }
+ __raw_writeq(reg, sc->sbm_rxfilter);
+ }
else {
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg &= ~M_MAC_ALLPKT_EN;
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+ __raw_writeq(reg, sc->sbm_rxfilter);
}
}
/**********************************************************************
* SBMAC_SETIPHDR_OFFSET(sc,onoff)
- *
+ *
* Set the iphdr offset as 15 assuming ethernet encapsulation
- *
- * Input parameters:
+ *
+ * Input parameters:
* sc - softc
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1807,12 +1780,12 @@ static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
{
uint64_t reg;
-
+
/* Hard code the off set to 15 for now */
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15);
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
-
+ __raw_writeq(reg, sc->sbm_rxfilter);
+
/* read system identification to determine revision */
if (periph_rev >= 2) {
sc->rx_hw_checksum = ENABLE;
@@ -1824,13 +1797,13 @@ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
/**********************************************************************
* SBMAC_ADDR2REG(ptr)
- *
+ *
* Convert six bytes into the 64-bit register value that
* we typically write into the SBMAC's address/mcast registers
- *
- * Input parameters:
+ *
+ * Input parameters:
* ptr - pointer to 6 bytes
- *
+ *
* Return value:
* register value
********************************************************************* */
@@ -1838,35 +1811,35 @@ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
static uint64_t sbmac_addr2reg(unsigned char *ptr)
{
uint64_t reg = 0;
-
+
ptr += 6;
-
- reg |= (uint64_t) *(--ptr);
+
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
-
+ reg |= (uint64_t) *(--ptr);
+
return reg;
}
/**********************************************************************
* SBMAC_SET_SPEED(s,speed)
- *
+ *
* Configure LAN speed for the specified MAC.
* Warning: must be called when MAC is off!
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* speed - speed to set MAC to (see sbmac_speed_t enum)
- *
+ *
* Return value:
* 1 if successful
* 0 indicates invalid parameters
@@ -1880,31 +1853,31 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
/*
* Save new current values
*/
-
+
s->sbm_speed = speed;
-
+
if (s->sbm_state == sbmac_state_on)
return 0; /* save for next restart */
/*
- * Read current register values
+ * Read current register values
*/
-
- cfg = SBMAC_READCSR(s->sbm_maccfg);
- framecfg = SBMAC_READCSR(s->sbm_framecfg);
-
+
+ cfg = __raw_readq(s->sbm_maccfg);
+ framecfg = __raw_readq(s->sbm_framecfg);
+
/*
* Mask out the stuff we want to change
*/
-
+
cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL);
framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |
M_MAC_SLOT_SIZE);
-
+
/*
* Now add in the new bits
*/
-
+
switch (speed) {
case sbmac_speed_10:
framecfg |= V_MAC_IFG_RX_10 |
@@ -1913,7 +1886,7 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
V_MAC_SLOT_SIZE_10;
cfg |= V_MAC_SPEED_SEL_10MBPS;
break;
-
+
case sbmac_speed_100:
framecfg |= V_MAC_IFG_RX_100 |
V_MAC_IFG_TX_100 |
@@ -1921,7 +1894,7 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
V_MAC_SLOT_SIZE_100;
cfg |= V_MAC_SPEED_SEL_100MBPS ;
break;
-
+
case sbmac_speed_1000:
framecfg |= V_MAC_IFG_RX_1000 |
V_MAC_IFG_TX_1000 |
@@ -1929,34 +1902,34 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
V_MAC_SLOT_SIZE_1000;
cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
break;
-
+
case sbmac_speed_auto: /* XXX not implemented */
/* fall through */
default:
return 0;
}
-
+
/*
- * Send the bits back to the hardware
+ * Send the bits back to the hardware
*/
-
- SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
- SBMAC_WRITECSR(s->sbm_maccfg,cfg);
-
+
+ __raw_writeq(framecfg, s->sbm_framecfg);
+ __raw_writeq(cfg, s->sbm_maccfg);
+
return 1;
}
/**********************************************************************
* SBMAC_SET_DUPLEX(s,duplex,fc)
- *
+ *
* Set Ethernet duplex and flow control options for this MAC
* Warning: must be called when MAC is off!
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* duplex - duplex setting (see sbmac_duplex_t)
* fc - flow control setting (see sbmac_fc_t)
- *
+ *
* Return value:
* 1 if ok
* 0 if an invalid parameter combination was specified
@@ -1965,67 +1938,67 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc)
{
uint64_t cfg;
-
+
/*
* Save new current values
*/
-
+
s->sbm_duplex = duplex;
s->sbm_fc = fc;
-
+
if (s->sbm_state == sbmac_state_on)
return 0; /* save for next restart */
-
+
/*
- * Read current register values
+ * Read current register values
*/
-
- cfg = SBMAC_READCSR(s->sbm_maccfg);
-
+
+ cfg = __raw_readq(s->sbm_maccfg);
+
/*
* Mask off the stuff we're about to change
*/
-
+
cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN);
-
-
+
+
switch (duplex) {
case sbmac_duplex_half:
switch (fc) {
case sbmac_fc_disabled:
cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED;
break;
-
+
case sbmac_fc_collision:
cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED;
break;
-
+
case sbmac_fc_carrier:
cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
break;
-
+
case sbmac_fc_auto: /* XXX not implemented */
- /* fall through */
+ /* fall through */
case sbmac_fc_frame: /* not valid in half duplex */
default: /* invalid selection */
return 0;
}
break;
-
+
case sbmac_duplex_full:
switch (fc) {
case sbmac_fc_disabled:
cfg |= V_MAC_FC_CMD_DISABLED;
break;
-
+
case sbmac_fc_frame:
cfg |= V_MAC_FC_CMD_ENABLED;
break;
-
+
case sbmac_fc_collision: /* not valid in full duplex */
case sbmac_fc_carrier: /* not valid in full duplex */
case sbmac_fc_auto: /* XXX not implemented */
- /* fall through */
+ /* fall through */
default:
return 0;
}
@@ -2034,13 +2007,13 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
/* XXX not implemented */
break;
}
-
+
/*
- * Send the bits back to the hardware
+ * Send the bits back to the hardware
*/
-
- SBMAC_WRITECSR(s->sbm_maccfg,cfg);
-
+
+ __raw_writeq(cfg, s->sbm_maccfg);
+
return 1;
}
@@ -2049,12 +2022,12 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
/**********************************************************************
* SBMAC_INTR()
- *
+ *
* Interrupt handler for MAC interrupts
- *
- * Input parameters:
+ *
+ * Input parameters:
* MAC structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -2066,27 +2039,27 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
int handled = 0;
for (;;) {
-
+
/*
* Read the ISR (this clears the bits in the real
* register, except for counter addr)
*/
-
- isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
-
+
+ isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
+
if (isr == 0)
break;
handled = 1;
-
+
/*
* Transmits on channel 0
*/
-
+
if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
sbdma_tx_process(sc,&(sc->sbm_txdma));
}
-
+
/*
* Receives on channel 0
*/
@@ -2106,8 +2079,8 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
* EOP_SEEN here takes care of this case.
* (EOP_SEEN is part of M_MAC_INT_CHANNEL << S_MAC_RX_CH0)
*/
-
-
+
+
if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
sbdma_rx_process(sc,&(sc->sbm_rxdma));
}
@@ -2118,29 +2091,29 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
/**********************************************************************
* SBMAC_START_TX(skb,dev)
- *
- * Start output on the specified interface. Basically, we
+ *
+ * Start output on the specified interface. Basically, we
* queue as many buffers as we can until the ring fills up, or
* we run off the end of the queue, whichever comes first.
- *
- * Input parameters:
- *
- *
+ *
+ * Input parameters:
+ *
+ *
* Return value:
* nothing
********************************************************************* */
static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
-
+
/* lock eth irq */
spin_lock_irq (&sc->sbm_lock);
-
+
/*
- * Put the buffer on the transmit ring. If we
+ * Put the buffer on the transmit ring. If we
* don't have room, stop the queue.
*/
-
+
if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) {
/* XXX save skb that we could not send */
netif_stop_queue(dev);
@@ -2148,24 +2121,24 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
return 1;
}
-
+
dev->trans_start = jiffies;
-
+
spin_unlock_irq (&sc->sbm_lock);
-
+
return 0;
}
/**********************************************************************
* SBMAC_SETMULTI(sc)
- *
+ *
* Reprogram the multicast table into the hardware, given
* the list of multicasts associated with the interface
* structure.
- *
- * Input parameters:
+ *
+ * Input parameters:
* sc - softc
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -2173,75 +2146,75 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
static void sbmac_setmulti(struct sbmac_softc *sc)
{
uint64_t reg;
- sbmac_port_t port;
+ volatile void __iomem *port;
int idx;
struct dev_mc_list *mclist;
struct net_device *dev = sc->sbm_dev;
-
- /*
+
+ /*
* Clear out entire multicast table. We do this by nuking
* the entire hash table and all the direct matches except
- * the first one, which is used for our station address
+ * the first one, which is used for our station address
*/
-
+
for (idx = 1; idx < MAC_ADDR_COUNT; idx++) {
port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t));
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
}
-
+
for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t));
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
}
-
+
/*
* Clear the filter to say we don't want any multicasts.
*/
-
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+
+ reg = __raw_readq(sc->sbm_rxfilter);
reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN);
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
-
+ __raw_writeq(reg, sc->sbm_rxfilter);
+
if (dev->flags & IFF_ALLMULTI) {
- /*
- * Enable ALL multicasts. Do this by inverting the
- * multicast enable bit.
+ /*
+ * Enable ALL multicasts. Do this by inverting the
+ * multicast enable bit.
*/
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN);
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+ __raw_writeq(reg, sc->sbm_rxfilter);
return;
}
-
- /*
+
+ /*
* Progam new multicast entries. For now, only use the
* perfect filter. In the future we'll need to use the
* hash filter if the perfect filter overflows
*/
-
+
/* XXX only using perfect filter for now, need to use hash
* XXX if the table overflows */
-
+
idx = 1; /* skip station address */
mclist = dev->mc_list;
while (mclist && (idx < MAC_ADDR_COUNT)) {
reg = sbmac_addr2reg(mclist->dmi_addr);
port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t));
- SBMAC_WRITECSR(port,reg);
+ __raw_writeq(reg, port);
idx++;
mclist = mclist->next;
}
-
- /*
+
+ /*
* Enable the "accept multicast bits" if we programmed at least one
- * multicast.
+ * multicast.
*/
-
+
if (idx > 1) {
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg |= M_MAC_MCAST_EN;
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+ __raw_writeq(reg, sc->sbm_rxfilter);
}
}
@@ -2250,12 +2223,12 @@ static void sbmac_setmulti(struct sbmac_softc *sc)
#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
/**********************************************************************
* SBMAC_PARSE_XDIGIT(str)
- *
+ *
* Parse a hex digit, returning its value
- *
- * Input parameters:
+ *
+ * Input parameters:
* str - character
- *
+ *
* Return value:
* hex value, or -1 if invalid
********************************************************************* */
@@ -2263,7 +2236,7 @@ static void sbmac_setmulti(struct sbmac_softc *sc)
static int sbmac_parse_xdigit(char str)
{
int digit;
-
+
if ((str >= '0') && (str <= '9'))
digit = str - '0';
else if ((str >= 'a') && (str <= 'f'))
@@ -2272,20 +2245,20 @@ static int sbmac_parse_xdigit(char str)
digit = str - 'A' + 10;
else
return -1;
-
+
return digit;
}
/**********************************************************************
* SBMAC_PARSE_HWADDR(str,hwaddr)
- *
+ *
* Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte
* Ethernet address.
- *
- * Input parameters:
+ *
+ * Input parameters:
* str - string
* hwaddr - pointer to hardware address
- *
+ *
* Return value:
* 0 if ok, else -1
********************************************************************* */
@@ -2294,7 +2267,7 @@ static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr)
{
int digit1,digit2;
int idx = 6;
-
+
while (*str && (idx > 0)) {
digit1 = sbmac_parse_xdigit(*str);
if (digit1 < 0)
@@ -2302,7 +2275,7 @@ static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr)
str++;
if (!*str)
return -1;
-
+
if ((*str == ':') || (*str == '-')) {
digit2 = digit1;
digit1 = 0;
@@ -2313,10 +2286,10 @@ static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr)
return -1;
str++;
}
-
+
*hwaddr++ = (digit1 << 4) | digit2;
idx--;
-
+
if (*str == '-')
str++;
if (*str == ':')
@@ -2337,12 +2310,12 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
/**********************************************************************
* SBMAC_INIT(dev)
- *
+ *
* Attach routine - init hardware and hook ourselves into linux
- *
- * Input parameters:
+ *
+ * Input parameters:
* dev - net_device structure
- *
+ *
* Return value:
* status
********************************************************************* */
@@ -2354,53 +2327,53 @@ static int sbmac_init(struct net_device *dev, int idx)
uint64_t ea_reg;
int i;
int err;
-
+
sc = netdev_priv(dev);
-
+
/* Determine controller base address */
-
+
sc->sbm_base = IOADDR(dev->base_addr);
sc->sbm_dev = dev;
sc->sbe_idx = idx;
-
+
eaddr = sc->sbm_hwaddr;
-
- /*
+
+ /*
* Read the ethernet address. The firwmare left this programmed
* for us in the ethernet address register for each mac.
*/
-
- ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR);
- SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0);
+
+ ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR);
+ __raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR);
for (i = 0; i < 6; i++) {
eaddr[i] = (uint8_t) (ea_reg & 0xFF);
ea_reg >>= 8;
}
-
+
for (i = 0; i < 6; i++) {
dev->dev_addr[i] = eaddr[i];
}
-
-
+
+
/*
- * Init packet size
+ * Init packet size
*/
-
+
sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN;
- /*
+ /*
* Initialize context (get pointers to registers and stuff), then
* allocate the memory for the descriptor tables.
*/
-
+
sbmac_initctx(sc);
-
+
/*
* Set up Linux device callins
*/
-
+
spin_lock_init(&(sc->sbm_lock));
-
+
dev->open = sbmac_open;
dev->hard_start_xmit = sbmac_start_tx;
dev->stop = sbmac_close;
@@ -2419,7 +2392,7 @@ static int sbmac_init(struct net_device *dev, int idx)
if (err)
goto out_uninit;
- if (periph_rev >= 2) {
+ if (sc->rx_hw_checksum == ENABLE) {
printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
sc->sbm_dev->name);
}
@@ -2430,10 +2403,10 @@ static int sbmac_init(struct net_device *dev, int idx)
* was being displayed)
*/
printk(KERN_INFO
- "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n",
dev->name, dev->base_addr,
eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]);
-
+
return 0;
@@ -2447,54 +2420,86 @@ out_uninit:
static int sbmac_open(struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
-
+
if (debug > 1) {
printk(KERN_DEBUG "%s: sbmac_open() irq %d.\n", dev->name, dev->irq);
}
-
- /*
+
+ /*
* map/route interrupt (clear status first, in case something
* weird is pending; we haven't initialized the mac registers
* yet)
*/
- SBMAC_READCSR(sc->sbm_isr);
+ __raw_readq(sc->sbm_isr);
if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev))
return -EBUSY;
/*
- * Configure default speed
+ * Probe phy address
+ */
+
+ if(sbmac_mii_probe(dev) == -1) {
+ printk("%s: failed to probe PHY.\n", dev->name);
+ return -EINVAL;
+ }
+
+ /*
+ * Configure default speed
*/
sbmac_mii_poll(sc,noisy_mii);
-
+
/*
* Turn on the channel
*/
sbmac_set_channel_state(sc,sbmac_state_on);
-
+
/*
* XXX Station address is in dev->dev_addr
*/
-
+
if (dev->if_port == 0)
- dev->if_port = 0;
-
+ dev->if_port = 0;
+
netif_start_queue(dev);
-
+
sbmac_set_rx_mode(dev);
-
+
/* Set the timer to check for link beat. */
init_timer(&sc->sbm_timer);
sc->sbm_timer.expires = jiffies + 2 * HZ/100;
sc->sbm_timer.data = (unsigned long)dev;
sc->sbm_timer.function = &sbmac_timer;
add_timer(&sc->sbm_timer);
-
+
return 0;
}
+static int sbmac_mii_probe(struct net_device *dev)
+{
+ int i;
+ struct sbmac_softc *s = netdev_priv(dev);
+ u16 bmsr, id1, id2;
+ u32 vendor, device;
+
+ for (i=1; i<31; i++) {
+ bmsr = sbmac_mii_read(s, i, MII_BMSR);
+ if (bmsr != 0) {
+ s->sbm_phys[0] = i;
+ id1 = sbmac_mii_read(s, i, MII_PHYIDR1);
+ id2 = sbmac_mii_read(s, i, MII_PHYIDR2);
+ vendor = ((u32)id1 << 6) | ((id2 >> 10) & 0x3f);
+ device = (id2 >> 4) & 0x3f;
+
+ printk(KERN_INFO "%s: found phy %d, vendor %06x part %02x\n",
+ dev->name, i, vendor, device);
+ return i;
+ }
+ }
+ return -1;
+}
static int sbmac_mii_poll(struct sbmac_softc *s,int noisy)
@@ -2609,20 +2614,20 @@ static void sbmac_timer(unsigned long data)
int mii_status;
spin_lock_irq (&sc->sbm_lock);
-
+
/* make IFF_RUNNING follow the MII status bit "Link established" */
mii_status = sbmac_mii_read(sc, sc->sbm_phys[0], MII_BMSR);
-
+
if ( (mii_status & BMSR_LINKSTAT) != (sc->sbm_phy_oldlinkstat) ) {
sc->sbm_phy_oldlinkstat = mii_status & BMSR_LINKSTAT;
if (mii_status & BMSR_LINKSTAT) {
netif_carrier_on(dev);
}
else {
- netif_carrier_off(dev);
+ netif_carrier_off(dev);
}
}
-
+
/*
* Poll the PHY to see what speed we should be running at
*/
@@ -2640,9 +2645,9 @@ static void sbmac_timer(unsigned long data)
sbmac_channel_start(sc);
}
}
-
+
spin_unlock_irq (&sc->sbm_lock);
-
+
sc->sbm_timer.expires = jiffies + next_tick;
add_timer(&sc->sbm_timer);
}
@@ -2651,13 +2656,13 @@ static void sbmac_timer(unsigned long data)
static void sbmac_tx_timeout (struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
-
+
spin_lock_irq (&sc->sbm_lock);
-
-
+
+
dev->trans_start = jiffies;
sc->sbm_stats.tx_errors++;
-
+
spin_unlock_irq (&sc->sbm_lock);
printk (KERN_WARNING "%s: Transmit timed out\n",dev->name);
@@ -2670,13 +2675,13 @@ static struct net_device_stats *sbmac_get_stats(struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
unsigned long flags;
-
+
spin_lock_irqsave(&sc->sbm_lock, flags);
-
+
/* XXX update other stats here */
-
+
spin_unlock_irqrestore(&sc->sbm_lock, flags);
-
+
return &sc->sbm_stats;
}
@@ -2693,8 +2698,8 @@ static void sbmac_set_rx_mode(struct net_device *dev)
/*
* Promiscuous changed.
*/
-
- if (dev->flags & IFF_PROMISC) {
+
+ if (dev->flags & IFF_PROMISC) {
/* Unconditionally log net taps. */
msg_flag = 1;
sbmac_promiscuous_mode(sc,1);
@@ -2705,18 +2710,18 @@ static void sbmac_set_rx_mode(struct net_device *dev)
}
}
spin_unlock_irqrestore(&sc->sbm_lock, flags);
-
+
if (msg_flag) {
printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n",
dev->name,(msg_flag==1)?"en":"dis");
}
-
+
/*
* Program the multicasts. Do this every time.
*/
-
+
sbmac_setmulti(sc);
-
+
}
static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -2725,10 +2730,10 @@ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
u16 *data = (u16 *)&rq->ifr_ifru;
unsigned long flags;
int retval;
-
+
spin_lock_irqsave(&sc->sbm_lock, flags);
retval = 0;
-
+
switch(cmd) {
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
data[0] = sc->sbm_phys[0] & 0x1f;
@@ -2750,7 +2755,7 @@ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
default:
retval = -EOPNOTSUPP;
}
-
+
spin_unlock_irqrestore(&sc->sbm_lock, flags);
return retval;
}
@@ -2781,7 +2786,7 @@ static int sbmac_close(struct net_device *dev)
sbdma_emptyring(&(sc->sbm_txdma));
sbdma_emptyring(&(sc->sbm_rxdma));
-
+
return 0;
}
@@ -2793,13 +2798,13 @@ sbmac_setup_hwaddr(int chan,char *addr)
{
uint8_t eaddr[6];
uint64_t val;
- sbmac_port_t port;
+ unsigned long port;
port = A_MAC_CHANNEL_BASE(chan);
sbmac_parse_hwaddr(addr,eaddr);
val = sbmac_addr2reg(eaddr);
- SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),val);
- val = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
+ __raw_writeq(val, IOADDR(port+R_MAC_ETHERNET_ADDR));
+ val = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
}
#endif
@@ -2810,9 +2815,9 @@ sbmac_init_module(void)
{
int idx;
struct net_device *dev;
- sbmac_port_t port;
+ unsigned long port;
int chip_max_units;
-
+
/*
* For bringup when not using the firmware, we can pre-fill
* the MAC addresses using the environment variables
@@ -2858,13 +2863,13 @@ sbmac_init_module(void)
port = A_MAC_CHANNEL_BASE(idx);
- /*
+ /*
* The R_MAC_ETHERNET_ADDR register will be set to some nonzero
* value for us by the firmware if we're going to use this MAC.
* If we find a zero, skip this MAC.
*/
- sbmac_orig_hwaddr[idx] = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
+ sbmac_orig_hwaddr[idx] = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
if (sbmac_orig_hwaddr[idx] == 0) {
printk(KERN_DEBUG "sbmac: not configuring MAC at "
"%lx\n", port);
@@ -2876,7 +2881,7 @@ sbmac_init_module(void)
*/
dev = alloc_etherdev(sizeof(struct sbmac_softc));
- if (!dev)
+ if (!dev)
return -ENOMEM; /* return ENOMEM */
printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
@@ -2886,8 +2891,7 @@ sbmac_init_module(void)
dev->mem_end = 0;
if (sbmac_init(dev, idx)) {
port = A_MAC_CHANNEL_BASE(idx);
- SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),
- sbmac_orig_hwaddr[idx]);
+ __raw_writeq(sbmac_orig_hwaddr[idx], IOADDR(port+R_MAC_ETHERNET_ADDR));
free_netdev(dev);
continue;
}
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 9bc3b1c0dd6a..a4614df38a90 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -32,8 +32,6 @@
#include "sgiseeq.h"
-static char *version = "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n";
-
static char *sgiseeqstr = "SGI Seeq8003";
/*
@@ -113,9 +111,9 @@ static struct net_device *root_sgiseeq_dev;
static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
{
- hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ;
+ hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
udelay(20);
- hregs->rx_reset = 0;
+ hregs->reset = 0;
}
static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
@@ -252,7 +250,6 @@ void sgiseeq_dump_rings(void)
#define TSTAT_INIT_SEEQ (SEEQ_TCMD_IPT|SEEQ_TCMD_I16|SEEQ_TCMD_IC|SEEQ_TCMD_IUF)
#define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2)
-#define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
struct sgiseeq_regs *sregs)
@@ -274,8 +271,6 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
sregs->tstat = TSTAT_INIT_SEEQ;
}
- hregs->rx_dconfig |= RDMACFG_INIT;
-
hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
@@ -446,7 +441,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs
spin_lock(&sp->tx_lock);
/* Ack the IRQ and set software state. */
- hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
+ hregs->reset = HPC3_ERST_CLRIRQ;
/* Always check for received packets. */
sgiseeq_rx(dev, sp, hregs, sregs);
@@ -493,11 +488,13 @@ static int sgiseeq_close(struct net_device *dev)
{
struct sgiseeq_private *sp = netdev_priv(dev);
struct sgiseeq_regs *sregs = sp->sregs;
+ unsigned int irq = dev->irq;
netif_stop_queue(dev);
/* Shutdown the Seeq. */
reset_hpc3_and_seeq(sp->hregs, sregs);
+ free_irq(irq, dev);
return 0;
}
@@ -644,7 +641,7 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
-static int sgiseeq_init(struct hpc3_regs* regs, int irq)
+static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
{
struct sgiseeq_init_block *sr;
struct sgiseeq_private *sp;
@@ -680,8 +677,8 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
gpriv = sp;
gdev = dev;
#endif
- sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
- sp->hregs = &hpc3c0->ethregs;
+ sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0];
+ sp->hregs = &hpcregs->ethregs;
sp->name = sgiseeqstr;
sp->mode = SEEQ_RCMD_RBCAST;
@@ -698,6 +695,11 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
+ /* Setup PIO and DMA transfer timing */
+ sp->hregs->pconfig = 0x161;
+ sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
+ HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
+
/* Reset the chip. */
hpc3_eth_reset(sp->hregs);
@@ -724,7 +726,7 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
goto err_out_free_page;
}
- printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
+ printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr);
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
@@ -734,7 +736,7 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
return 0;
err_out_free_page:
- free_page((unsigned long) sp);
+ free_page((unsigned long) sp->srings);
err_out_free_dev:
kfree(dev);
@@ -744,8 +746,6 @@ err_out:
static int __init sgiseeq_probe(void)
{
- printk(version);
-
/* On board adapter on 1st HPC is always present */
return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
}
@@ -754,15 +754,12 @@ static void __exit sgiseeq_exit(void)
{
struct net_device *next, *dev;
struct sgiseeq_private *sp;
- int irq;
for (dev = root_sgiseeq_dev; dev; dev = next) {
sp = (struct sgiseeq_private *) netdev_priv(dev);
next = sp->next_module;
- irq = dev->irq;
unregister_netdev(dev);
- free_irq(irq, dev);
- free_page((unsigned long) sp);
+ free_page((unsigned long) sp->srings);
free_netdev(dev);
}
}
@@ -770,4 +767,6 @@ static void __exit sgiseeq_exit(void)
module_init(sgiseeq_probe);
module_exit(sgiseeq_exit);
+MODULE_DESCRIPTION("SGI Seeq 8003 driver");
+MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 6ee4771addf1..b18c92cb629e 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -235,7 +235,7 @@ static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
* Extern Function Prototypes
*
******************************************************************************/
-static const char SKRootName[] = "sk98lin";
+static const char SKRootName[] = "net/sk98lin";
static struct proc_dir_entry *pSkRootDir;
extern struct file_operations sk_proc_fops;
@@ -5216,17 +5216,15 @@ static struct pci_device_id skge_pci_tbl[] = {
{ PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+/* DLink card does not have valid VPD so this driver gags
+ * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ */
{ PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-#if 0 /* don't handle Yukon2 cards at the moment -- mlindner@syskonnect.de */
- { PCI_VENDOR_ID_MARVELL, 0x4360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_MARVELL, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-#endif
{ PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
{ PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0, }
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
@@ -5244,20 +5242,20 @@ static int __init skge_init(void)
{
int error;
- pSkRootDir = proc_mkdir(SKRootName, proc_net);
+ pSkRootDir = proc_mkdir(SKRootName, NULL);
if (pSkRootDir)
pSkRootDir->owner = THIS_MODULE;
error = pci_register_driver(&skge_driver);
if (error)
- proc_net_remove(SKRootName);
+ remove_proc_entry(SKRootName, NULL);
return error;
}
static void __exit skge_exit(void)
{
pci_unregister_driver(&skge_driver);
- proc_net_remove(SKRootName);
+ remove_proc_entry(SKRootName, NULL);
}
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index d7c98515fdfd..572f121b1f4e 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -42,7 +42,7 @@
#include "skge.h"
#define DRV_NAME "skge"
-#define DRV_VERSION "0.9"
+#define DRV_VERSION "1.1"
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
@@ -105,41 +105,28 @@ static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 };
-/* Don't need to look at whole 16K.
- * last interesting register is descriptor poll timer.
- */
-#define SKGE_REGS_LEN (29*128)
-
static int skge_get_regs_len(struct net_device *dev)
{
- return SKGE_REGS_LEN;
+ return 0x4000;
}
/*
- * Returns copy of control register region
- * I/O region is divided into banks and certain regions are unreadable
+ * Returns copy of whole control register region
+ * Note: skip RAM address register because accessing it will
+ * cause bus hangs!
*/
static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *p)
{
const struct skge_port *skge = netdev_priv(dev);
- unsigned long offs;
const void __iomem *io = skge->hw->regs;
- static const unsigned long bankmap
- = (1<<0) | (1<<2) | (1<<8) | (1<<9)
- | (1<<12) | (1<<13) | (1<<14) | (1<<15) | (1<<16)
- | (1<<17) | (1<<20) | (1<<21) | (1<<22) | (1<<23)
- | (1<<24) | (1<<25) | (1<<26) | (1<<27) | (1<<28);
regs->version = 1;
- for (offs = 0; offs < regs->len; offs += 128) {
- u32 len = min_t(u32, 128, regs->len - offs);
+ memset(p, 0, regs->len);
+ memcpy_fromio(p, io, B3_RAM_ADDR);
- if (bankmap & (1<<(offs/128)))
- memcpy_fromio(p + offs, io + offs, len);
- else
- memset(p + offs, 0, len);
- }
+ memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
+ regs->len - B3_RI_WTO_R1);
}
/* Wake on Lan only supported on Yukon chps with rev 1 or above */
@@ -669,7 +656,7 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
PHY_M_LED_BLINK_RT(BLINK_84MS) |
PHY_M_LEDC_TX_CTRL |
PHY_M_LEDC_DP_CTRL);
-
+
gm_phy_write(hw, port, PHY_MARV_LED_OVER,
PHY_M_LED_MO_RX(MO_LED_OFF) |
(skge->speed == SPEED_100 ?
@@ -743,6 +730,7 @@ static struct ethtool_ops skge_ethtool_ops = {
.phys_id = skge_phys_id,
.get_stats_count = skge_get_stats_count,
.get_ethtool_stats = skge_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
/*
@@ -775,17 +763,6 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
return 0;
}
-static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size)
-{
- struct sk_buff *skb = dev_alloc_skb(size);
-
- if (likely(skb)) {
- skb->dev = dev;
- skb_reserve(skb, NET_IP_ALIGN);
- }
- return skb;
-}
-
/* Allocate and setup a new buffer for receiving */
static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
struct sk_buff *skb, unsigned int bufsize)
@@ -858,16 +835,17 @@ static int skge_rx_fill(struct skge_port *skge)
{
struct skge_ring *ring = &skge->rx_ring;
struct skge_element *e;
- unsigned int bufsize = skge->rx_buf_size;
e = ring->start;
do {
- struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize);
+ struct sk_buff *skb;
+ skb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN);
if (!skb)
return -ENOMEM;
- skge_rx_setup(skge, e, skb, bufsize);
+ skb_reserve(skb, NET_IP_ALIGN);
+ skge_rx_setup(skge, e, skb, skge->rx_buf_size);
} while ( (e = e->next) != ring->start);
ring->to_clean = ring->start;
@@ -876,7 +854,7 @@ static int skge_rx_fill(struct skge_port *skge)
static void skge_link_up(struct skge_port *skge)
{
- skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
+ skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
LED_BLK_OFF|LED_SYNC_OFF|LED_ON);
netif_carrier_on(skge->netdev);
@@ -987,6 +965,8 @@ static void genesis_reset(struct skge_hw *hw, int port)
{
const u8 zero[8] = { 0 };
+ skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+
/* reset the statistics module */
xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */
@@ -1021,8 +1001,6 @@ static void bcom_check_link(struct skge_hw *hw, int port)
(void) xm_phy_read(hw, port, PHY_BCOM_STAT);
status = xm_phy_read(hw, port, PHY_BCOM_STAT);
- pr_debug("bcom_check_link status=0x%x\n", status);
-
if ((status & PHY_ST_LSYNC) == 0) {
u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
@@ -1106,8 +1084,6 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
};
- pr_debug("bcom_phy_init\n");
-
/* read Id from external PHY (all have the same address) */
id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
@@ -1340,6 +1316,8 @@ static void genesis_stop(struct skge_port *skge)
int port = skge->port;
u32 reg;
+ genesis_reset(hw, port);
+
/* Clear Tx packet arbiter timeout IRQ */
skge_write16(hw, B3_PA_CTRL,
port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
@@ -1465,7 +1443,6 @@ static void genesis_link_up(struct skge_port *skge)
u16 cmd;
u32 mode, msk;
- pr_debug("genesis_link_up\n");
cmd = xm_read16(hw, port, XM_MMU_CMD);
/*
@@ -1578,7 +1555,6 @@ static void yukon_init(struct skge_hw *hw, int port)
struct skge_port *skge = netdev_priv(hw->dev[port]);
u16 ctrl, ct1000, adv;
- pr_debug("yukon_init\n");
if (skge->autoneg == AUTONEG_ENABLE) {
u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
@@ -1668,6 +1644,22 @@ static void yukon_reset(struct skge_hw *hw, int port)
| GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
}
+/* Apparently, early versions of Yukon-Lite had wrong chip_id? */
+static int is_yukon_lite_a0(struct skge_hw *hw)
+{
+ u32 reg;
+ int ret;
+
+ if (hw->chip_id != CHIP_ID_YUKON)
+ return 0;
+
+ reg = skge_read32(hw, B2_FAR);
+ skge_write8(hw, B2_FAR + 3, 0xff);
+ ret = (skge_read8(hw, B2_FAR + 3) != 0);
+ skge_write32(hw, B2_FAR, reg);
+ return ret;
+}
+
static void yukon_mac_init(struct skge_hw *hw, int port)
{
struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1677,9 +1669,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
/* WA code for COMA mode -- set PHY reset */
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev >= CHIP_REV_YU_LITE_A3)
- skge_write32(hw, B2_GP_IO,
- (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
+ hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+ reg = skge_read32(hw, B2_GP_IO);
+ reg |= GP_DIR_9 | GP_IO_9;
+ skge_write32(hw, B2_GP_IO, reg);
+ }
/* hard reset */
skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1687,10 +1681,12 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
/* WA code for COMA mode -- clear PHY reset */
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev >= CHIP_REV_YU_LITE_A3)
- skge_write32(hw, B2_GP_IO,
- (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
- & ~GP_IO_9);
+ hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+ reg = skge_read32(hw, B2_GP_IO);
+ reg |= GP_DIR_9;
+ reg &= ~GP_IO_9;
+ skge_write32(hw, B2_GP_IO, reg);
+ }
/* Set hardware config mode */
reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
@@ -1729,7 +1725,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
}
gma_write16(hw, port, GM_GP_CTRL, reg);
- skge_read16(hw, GMAC_IRQ_SRC);
+ skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
yukon_init(hw, port);
@@ -1779,9 +1775,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
/* Configure Rx MAC FIFO */
skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
- if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev >= CHIP_REV_YU_LITE_A3)
+
+ /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
+ if (is_yukon_lite_a0(hw))
reg &= ~GMF_RX_F_FL_ON;
+
skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
/*
@@ -1801,20 +1799,26 @@ static void yukon_stop(struct skge_port *skge)
struct skge_hw *hw = skge->hw;
int port = skge->port;
- if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
- skge_write32(hw, B2_GP_IO,
- skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
- }
+ skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+ yukon_reset(hw, port);
gma_write16(hw, port, GM_GP_CTRL,
gma_read16(hw, port, GM_GP_CTRL)
& ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
gma_read16(hw, port, GM_GP_CTRL);
+ if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+ hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+ u32 io = skge_read32(hw, B2_GP_IO);
+
+ io |= GP_DIR_9 | GP_IO_9;
+ skge_write32(hw, B2_GP_IO, io);
+ skge_read32(hw, B2_GP_IO);
+ }
+
/* set GPHY Control reset */
- skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
- skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+ skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+ skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
}
static void yukon_get_stats(struct skge_port *skge, u64 *data)
@@ -1873,10 +1877,8 @@ static void yukon_link_up(struct skge_port *skge)
int port = skge->port;
u16 reg;
- pr_debug("yukon_link_up\n");
-
/* Enable Transmit FIFO Underrun */
- skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
+ skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
reg = gma_read16(hw, port, GM_GP_CTRL);
if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
@@ -1896,7 +1898,6 @@ static void yukon_link_down(struct skge_port *skge)
int port = skge->port;
u16 ctrl;
- pr_debug("yukon_link_down\n");
gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
ctrl = gma_read16(hw, port, GM_GP_CTRL);
@@ -2112,7 +2113,6 @@ static int skge_up(struct net_device *dev)
skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
skge_led(skge, LED_MODE_ON);
- pr_debug("skge_up completed\n");
return 0;
free_rx_ring:
@@ -2135,15 +2135,20 @@ static int skge_down(struct net_device *dev)
netif_stop_queue(dev);
+ skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ genesis_stop(skge);
+ else
+ yukon_stop(skge);
+
+ hw->intr_mask &= ~portirqmask[skge->port];
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+
/* Stop transmitter */
skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
RB_RST_SET|RB_DIS_OP_MD);
- if (hw->chip_id == CHIP_ID_GENESIS)
- genesis_stop(skge);
- else
- yukon_stop(skge);
/* Disable Force Sync bit and Enable Alloc bit */
skge_write8(hw, SK_REG(port, TXA_CTRL),
@@ -2367,8 +2372,6 @@ static void genesis_set_multicast(struct net_device *dev)
u32 mode;
u8 filter[8];
- pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
-
mode = xm_read32(hw, port, XM_MODE);
mode |= XM_MD_ENA_HASH;
if (dev->flags & IFF_PROMISC)
@@ -2435,6 +2438,14 @@ static void yukon_set_multicast(struct net_device *dev)
gma_write16(hw, port, GM_RX_CTRL, reg);
}
+static inline u16 phy_length(const struct skge_hw *hw, u32 status)
+{
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ return status >> XMR_FS_LEN_SHIFT;
+ else
+ return status >> GMR_FS_LEN_SHIFT;
+}
+
static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
{
if (hw->chip_id == CHIP_ID_GENESIS)
@@ -2444,80 +2455,99 @@ static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
(status & GMR_FS_RX_OK) == 0;
}
-static void skge_rx_error(struct skge_port *skge, int slot,
- u32 control, u32 status)
-{
- if (netif_msg_rx_err(skge))
- printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n",
- skge->netdev->name, slot, control, status);
-
- if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF))
- skge->net_stats.rx_length_errors++;
- else if (skge->hw->chip_id == CHIP_ID_GENESIS) {
- if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
- skge->net_stats.rx_length_errors++;
- if (status & XMR_FS_FRA_ERR)
- skge->net_stats.rx_frame_errors++;
- if (status & XMR_FS_FCS_ERR)
- skge->net_stats.rx_crc_errors++;
- } else {
- if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
- skge->net_stats.rx_length_errors++;
- if (status & GMR_FS_FRAGMENT)
- skge->net_stats.rx_frame_errors++;
- if (status & GMR_FS_CRC_ERR)
- skge->net_stats.rx_crc_errors++;
- }
-}
/* Get receive buffer from descriptor.
* Handles copy of small buffers and reallocation failures
*/
static inline struct sk_buff *skge_rx_get(struct skge_port *skge,
struct skge_element *e,
- unsigned int len)
+ u32 control, u32 status, u16 csum)
{
- struct sk_buff *nskb, *skb;
+ struct sk_buff *skb;
+ u16 len = control & BMU_BBC;
+
+ if (unlikely(netif_msg_rx_status(skge)))
+ printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n",
+ skge->netdev->name, e - skge->rx_ring.start,
+ status, len);
+
+ if (len > skge->rx_buf_size)
+ goto error;
+
+ if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF))
+ goto error;
+
+ if (bad_phy_status(skge->hw, status))
+ goto error;
+
+ if (phy_length(skge->hw, status) != len)
+ goto error;
if (len < RX_COPY_THRESHOLD) {
- nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN);
- if (unlikely(!nskb))
- return NULL;
+ skb = dev_alloc_skb(len + 2);
+ if (!skb)
+ goto resubmit;
+ skb_reserve(skb, 2);
pci_dma_sync_single_for_cpu(skge->hw->pdev,
pci_unmap_addr(e, mapaddr),
len, PCI_DMA_FROMDEVICE);
- memcpy(nskb->data, e->skb->data, len);
+ memcpy(skb->data, e->skb->data, len);
pci_dma_sync_single_for_device(skge->hw->pdev,
pci_unmap_addr(e, mapaddr),
len, PCI_DMA_FROMDEVICE);
-
- if (skge->rx_csum) {
- struct skge_rx_desc *rd = e->desc;
- nskb->csum = le16_to_cpu(rd->csum2);
- nskb->ip_summed = CHECKSUM_HW;
- }
skge_rx_reuse(e, skge->rx_buf_size);
- return nskb;
} else {
- nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size);
- if (unlikely(!nskb))
- return NULL;
+ struct sk_buff *nskb;
+ nskb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN);
+ if (!nskb)
+ goto resubmit;
pci_unmap_single(skge->hw->pdev,
pci_unmap_addr(e, mapaddr),
pci_unmap_len(e, maplen),
PCI_DMA_FROMDEVICE);
skb = e->skb;
- if (skge->rx_csum) {
- struct skge_rx_desc *rd = e->desc;
- skb->csum = le16_to_cpu(rd->csum2);
- skb->ip_summed = CHECKSUM_HW;
- }
-
+ prefetch(skb->data);
skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
- return skb;
}
+
+ skb_put(skb, len);
+ skb->dev = skge->netdev;
+ if (skge->rx_csum) {
+ skb->csum = csum;
+ skb->ip_summed = CHECKSUM_HW;
+ }
+
+ skb->protocol = eth_type_trans(skb, skge->netdev);
+
+ return skb;
+error:
+
+ if (netif_msg_rx_err(skge))
+ printk(KERN_DEBUG PFX "%s: rx err, slot %td control 0x%x status 0x%x\n",
+ skge->netdev->name, e - skge->rx_ring.start,
+ control, status);
+
+ if (skge->hw->chip_id == CHIP_ID_GENESIS) {
+ if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
+ skge->net_stats.rx_length_errors++;
+ if (status & XMR_FS_FRA_ERR)
+ skge->net_stats.rx_frame_errors++;
+ if (status & XMR_FS_FCS_ERR)
+ skge->net_stats.rx_crc_errors++;
+ } else {
+ if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
+ skge->net_stats.rx_length_errors++;
+ if (status & GMR_FS_FRAGMENT)
+ skge->net_stats.rx_frame_errors++;
+ if (status & GMR_FS_CRC_ERR)
+ skge->net_stats.rx_crc_errors++;
+ }
+
+resubmit:
+ skge_rx_reuse(e, skge->rx_buf_size);
+ return NULL;
}
@@ -2530,37 +2560,19 @@ static int skge_poll(struct net_device *dev, int *budget)
unsigned int to_do = min(dev->quota, *budget);
unsigned int work_done = 0;
- pr_debug("skge_poll\n");
-
for (e = ring->to_clean; work_done < to_do; e = e->next) {
struct skge_rx_desc *rd = e->desc;
struct sk_buff *skb;
- u32 control, len, status;
+ u32 control;
rmb();
control = rd->control;
if (control & BMU_OWN)
break;
- len = control & BMU_BBC;
- status = rd->status;
-
- if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
- || bad_phy_status(hw, status))) {
- skge_rx_error(skge, e - ring->start, control, status);
- skge_rx_reuse(e, skge->rx_buf_size);
- continue;
- }
-
- if (netif_msg_rx_status(skge))
- printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n",
- dev->name, e - ring->start, rd->status, len);
-
- skb = skge_rx_get(skge, e, len);
+ skb = skge_rx_get(skge, e, control, rd->status,
+ le16_to_cpu(rd->csum2));
if (likely(skb)) {
- skb_put(skb, len);
- skb->protocol = eth_type_trans(skb, dev);
-
dev->last_rx = jiffies;
netif_receive_skb(skb);
@@ -2672,9 +2684,9 @@ static void skge_error_irq(struct skge_hw *hw)
if (hw->chip_id == CHIP_ID_GENESIS) {
/* clear xmac errors */
if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
- skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+ skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT);
if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
- skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
+ skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT);
} else {
/* Timestamp (unused) overflow */
if (hwstatus & IS_IRQ_TIST_OV)
@@ -2826,21 +2838,29 @@ static void skge_netpoll(struct net_device *dev)
static int skge_set_mac_address(struct net_device *dev, void *p)
{
struct skge_port *skge = netdev_priv(dev);
- struct sockaddr *addr = p;
- int err = 0;
+ struct skge_hw *hw = skge->hw;
+ unsigned port = skge->port;
+ const struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- skge_down(dev);
+ spin_lock_bh(&hw->phy_lock);
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
- memcpy_toio(skge->hw->regs + B2_MAC_1 + skge->port*8,
+ memcpy_toio(hw->regs + B2_MAC_1 + port*8,
dev->dev_addr, ETH_ALEN);
- memcpy_toio(skge->hw->regs + B2_MAC_2 + skge->port*8,
+ memcpy_toio(hw->regs + B2_MAC_2 + port*8,
dev->dev_addr, ETH_ALEN);
- if (dev->flags & IFF_UP)
- err = skge_up(dev);
- return err;
+
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ xm_outaddr(hw, port, XM_SA, dev->dev_addr);
+ else {
+ gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
+ gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+ }
+ spin_unlock_bh(&hw->phy_lock);
+
+ return 0;
}
static const struct {
@@ -3000,9 +3020,6 @@ static int skge_reset(struct skge_hw *hw)
skge_write32(hw, B0_IMSK, hw->intr_mask);
- if (hw->chip_id != CHIP_ID_GENESIS)
- skge_write8(hw, GMAC_IRQ_MSK, 0);
-
spin_lock_bh(&hw->phy_lock);
for (i = 0; i < hw->ports; i++) {
if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3080,6 +3097,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* device is off until link detection */
netif_carrier_off(dev);
@@ -3230,6 +3248,11 @@ static void __devexit skge_remove(struct pci_dev *pdev)
dev0 = hw->dev[0];
unregister_netdev(dev0);
+ skge_write32(hw, B0_IMSK, 0);
+ skge_write16(hw, B0_LED, LED_STAT_OFF);
+ skge_pci_clear(hw);
+ skge_write8(hw, B0_CTST, CS_RST_SET);
+
tasklet_kill(&hw->ext_tasklet);
free_irq(pdev->irq, hw);
@@ -3238,7 +3261,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
if (dev1)
free_netdev(dev1);
free_netdev(dev0);
- skge_write16(hw, B0_LED, LED_STAT_OFF);
+
iounmap(hw->regs);
kfree(hw);
pci_set_drvdata(pdev, NULL);
@@ -3257,7 +3280,10 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
struct skge_port *skge = netdev_priv(dev);
if (netif_running(dev)) {
netif_carrier_off(dev);
- skge_down(dev);
+ if (skge->wol)
+ netif_stop_queue(dev);
+ else
+ skge_down(dev);
}
netif_device_detach(dev);
wol |= skge->wol;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index f1680beb8e68..72c175b87a5a 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -953,6 +953,7 @@ enum {
*/
enum {
XMR_FS_LEN = 0x3fff<<18, /* Bit 31..18: Rx Frame Length */
+ XMR_FS_LEN_SHIFT = 18,
XMR_FS_2L_VLAN = 1<<17, /* Bit 17: tagged wh 2Lev VLAN ID*/
XMR_FS_1_VLAN = 1<<16, /* Bit 16: tagged wh 1ev VLAN ID*/
XMR_FS_BC = 1<<15, /* Bit 15: Broadcast Frame */
@@ -1868,6 +1869,7 @@ enum {
/* Receive Frame Status Encoding */
enum {
GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */
+ GMR_FS_LEN_SHIFT = 16,
GMR_FS_VLAN = 1<<13, /* Bit 13: VLAN Packet */
GMR_FS_JABBER = 1<<12, /* Bit 12: Jabber Packet */
GMR_FS_UN_SIZE = 1<<11, /* Bit 11: Undersize Packet */
@@ -2008,7 +2010,7 @@ enum {
GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */
GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */
-#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | GM_IS_TX_FF_UR)
+#define GMAC_DEF_MSK (GM_IS_RX_FF_OR | GM_IS_TX_FF_UR)
/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
/* Bits 15.. 2: reserved */
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 4e19220473d0..c796f41b4a52 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1817,6 +1817,10 @@ spider_net_setup_phy(struct spider_net_card *card)
/* LEDs active in both modes, autosense prio = fiber */
spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x945f);
+ /* switch off fibre autoneg */
+ spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0xfc01);
+ spider_net_write_phy(card->netdev, 1, 0x0b, 0x0004);
+
phy->def->ops->read_link(phy);
pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name,
phy->speed, phy->duplex==1 ? "Full" : "Half");
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 88b89dc95c77..efdb179ecc8c 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -133,14 +133,18 @@
- finally added firmware (GPL'ed by Adaptec)
- removed compatibility code for 2.2.x
+ LK1.4.2.1 (Ion Badulescu)
+ - fixed 32/64 bit issues on i386 + CONFIG_HIGHMEM
+ - added 32-bit padding to outgoing skb's, removed previous workaround
+
TODO: - fix forced speed/duplexing code (broken a long time ago, when
somebody converted the driver to use the generic MII code)
- fix VLAN support
*/
#define DRV_NAME "starfire"
-#define DRV_VERSION "1.03+LK1.4.2"
-#define DRV_RELDATE "January 19, 2005"
+#define DRV_VERSION "1.03+LK1.4.2.1"
+#define DRV_RELDATE "October 3, 2005"
#include <linux/config.h>
#include <linux/version.h>
@@ -165,6 +169,14 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
* of length 1. If and when this is fixed, the #define below can be removed.
*/
#define HAS_BROKEN_FIRMWARE
+
+/*
+ * If using the broken firmware, data must be padded to the next 32-bit boundary.
+ */
+#ifdef HAS_BROKEN_FIRMWARE
+#define PADDING_MASK 3
+#endif
+
/*
* Define this if using the driver with the zero-copy patch
*/
@@ -257,9 +269,10 @@ static int full_duplex[MAX_UNITS] = {0, };
* This SUCKS.
* We need a much better method to determine if dma_addr_t is 64-bit.
*/
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
/* 64-bit dma_addr_t */
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
+#define netdrv_addr_t u64
#define cpu_to_dma(x) cpu_to_le64(x)
#define dma_to_cpu(x) le64_to_cpu(x)
#define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit
@@ -268,6 +281,7 @@ static int full_duplex[MAX_UNITS] = {0, };
#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit
#define RX_DESC_ADDR_SIZE RxDescAddr64bit
#else /* 32-bit dma_addr_t */
+#define netdrv_addr_t u32
#define cpu_to_dma(x) cpu_to_le32(x)
#define dma_to_cpu(x) le32_to_cpu(x)
#define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit
@@ -1333,21 +1347,10 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
}
#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
- {
- int has_bad_length = 0;
-
- if (skb_first_frag_len(skb) == 1)
- has_bad_length = 1;
- else {
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
- if (skb_shinfo(skb)->frags[i].size == 1) {
- has_bad_length = 1;
- break;
- }
- }
-
- if (has_bad_length)
- skb_checksum_help(skb, 0);
+ if (skb->ip_summed == CHECKSUM_HW) {
+ skb = skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK);
+ if (skb == NULL)
+ return NETDEV_TX_OK;
}
#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */
@@ -2127,13 +2130,12 @@ static int __init starfire_init (void)
#endif
#endif
-#ifndef ADDR_64BITS
/* we can do this test only at run-time... sigh */
- if (sizeof(dma_addr_t) == sizeof(u64)) {
- printk("This driver has not been ported to this 64-bit architecture yet\n");
+ if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) {
+ printk("This driver has dma_addr_t issues, please send email to maintainer\n");
return -ENODEV;
}
-#endif /* not ADDR_64BITS */
+
return pci_module_init (&starfire_driver);
}
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index f88f5e32b714..cfaf47c63c58 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -214,7 +214,8 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq)
{
struct bmac_init_block *bb = bp->bmac_block;
struct net_device *dev = bp->dev;
- int i, gfp_flags = GFP_KERNEL;
+ int i;
+ gfp_t gfp_flags = GFP_KERNEL;
if (from_irq || in_interrupt())
gfp_flags = GFP_ATOMIC;
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
index 5674003fc38a..b0dbc5187143 100644
--- a/drivers/net/sunbmac.h
+++ b/drivers/net/sunbmac.h
@@ -339,7 +339,7 @@ struct bigmac {
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
-static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, int gfp_flags)
+static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, gfp_t gfp_flags)
{
struct sk_buff *skb;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index d500a5771dbc..5de0554fd7c6 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -518,6 +518,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
#else
int bar = 1;
#endif
+ int phy, phy_idx = 0;
/* when built into the kernel, we only print version if device is found */
@@ -549,6 +550,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
for (i = 0; i < 3; i++)
((u16 *)dev->dev_addr)[i] =
le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->base_addr = (unsigned long)ioaddr;
dev->irq = irq;
@@ -605,33 +607,31 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
printk("%2.2x:", dev->dev_addr[i]);
printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
- if (1) {
- int phy, phy_idx = 0;
- np->phys[0] = 1; /* Default setting */
- np->mii_preamble_required++;
- for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
- int mii_status = mdio_read(dev, phy, MII_BMSR);
- if (mii_status != 0xffff && mii_status != 0x0000) {
- np->phys[phy_idx++] = phy;
- np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
- if ((mii_status & 0x0040) == 0)
- np->mii_preamble_required++;
- printk(KERN_INFO "%s: MII PHY found at address %d, status "
- "0x%4.4x advertising %4.4x.\n",
- dev->name, phy, mii_status, np->mii_if.advertising);
- }
- }
- np->mii_preamble_required--;
-
- if (phy_idx == 0) {
- printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
- dev->name, ioread32(ioaddr + ASICCtrl));
- goto err_out_unregister;
+ np->phys[0] = 1; /* Default setting */
+ np->mii_preamble_required++;
+ for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
+ int mii_status = mdio_read(dev, phy, MII_BMSR);
+ int phyx = phy & 0x1f;
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ np->phys[phy_idx++] = phyx;
+ np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
+ if ((mii_status & 0x0040) == 0)
+ np->mii_preamble_required++;
+ printk(KERN_INFO "%s: MII PHY found at address %d, status "
+ "0x%4.4x advertising %4.4x.\n",
+ dev->name, phyx, mii_status, np->mii_if.advertising);
}
+ }
+ np->mii_preamble_required--;
- np->mii_if.phy_id = np->phys[0];
+ if (phy_idx == 0) {
+ printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
+ dev->name, ioread32(ioaddr + ASICCtrl));
+ goto err_out_unregister;
}
+ np->mii_if.phy_id = np->phys[0];
+
/* Parse override configuration */
np->an_enable = 1;
if (card_idx < MAX_UNITS) {
@@ -692,7 +692,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
/* Reset the chip to erase previous misconfiguration. */
if (netif_msg_hw(np))
printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
- iowrite16(0x007f, ioaddr + ASICCtrl + 2);
+ iowrite16(0x00ff, ioaddr + ASICCtrl + 2);
if (netif_msg_hw(np))
printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
@@ -1619,6 +1619,7 @@ static struct ethtool_ops ethtool_ops = {
.get_link = get_link,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 3f67a42e8503..de399563a9db 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2817,7 +2817,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
#if (!defined(__sparc__) && !defined(CONFIG_PPC_PMAC))
/* Fetch MAC address from vital product data of PCI ROM. */
-static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char *dev_addr)
+static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char *dev_addr)
{
int this_offset;
@@ -2838,35 +2838,27 @@ static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char
for (i = 0; i < 6; i++)
dev_addr[i] = readb(p + i);
- break;
+ return 1;
}
+ return 0;
}
static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
{
- u32 rom_reg_orig;
- void __iomem *p;
-
- if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
- if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
- goto use_random;
- }
+ size_t size;
+ void __iomem *p = pci_map_rom(pdev, &size);
- pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
- pci_write_config_dword(pdev, pdev->rom_base_reg,
- rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
+ if (p) {
+ int found;
- p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
- if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
- find_eth_addr_in_vpd(p, (64 * 1024), dev_addr);
-
- if (p != NULL)
- iounmap(p);
-
- pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
- return;
+ found = readb(p) == 0x55 &&
+ readb(p + 1) == 0xaa &&
+ find_eth_addr_in_vpd(p, (64 * 1024), dev_addr);
+ pci_unmap_rom(pdev, p);
+ if (found)
+ return;
+ }
-use_random:
/* Sun MAC prefix then 3 random bytes. */
dev_addr[0] = 0x08;
dev_addr[1] = 0x00;
diff --git a/drivers/net/sungem.h b/drivers/net/sungem.h
index ff8ae5f79970..13006d759ad8 100644
--- a/drivers/net/sungem.h
+++ b/drivers/net/sungem.h
@@ -1035,7 +1035,8 @@ struct gem {
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr))
-static __inline__ struct sk_buff *gem_alloc_skb(int size, int gfp_flags)
+static __inline__ struct sk_buff *gem_alloc_skb(int size,
+ gfp_t gfp_flags)
{
struct sk_buff *skb = alloc_skb(size + 64, gfp_flags);
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index f02fe4119b2c..9f046cae2f71 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2954,7 +2954,7 @@ static int is_quattro_p(struct pci_dev *pdev)
}
/* Fetch MAC address from vital product data of PCI ROM. */
-static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
+static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
{
int this_offset;
@@ -2977,42 +2977,33 @@ static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, uns
for (i = 0; i < 6; i++)
dev_addr[i] = readb(p + i);
- break;
+ return 1;
}
index--;
}
+ return 0;
}
static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
{
- u32 rom_reg_orig;
- void __iomem *p;
- int index;
+ size_t size;
+ void __iomem *p = pci_map_rom(pdev, &size);
- index = 0;
- if (is_quattro_p(pdev))
- index = PCI_SLOT(pdev->devfn);
-
- if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
- if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
- goto use_random;
- }
+ if (p) {
+ int index = 0;
+ int found;
- pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
- pci_write_config_dword(pdev, pdev->rom_base_reg,
- rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
+ if (is_quattro_p(pdev))
+ index = PCI_SLOT(pdev->devfn);
- p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
- if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
- find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
-
- if (p != NULL)
- iounmap(p);
-
- pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
- return;
+ found = readb(p) == 0x55 &&
+ readb(p + 1) == 0xaa &&
+ find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+ pci_unmap_rom(pdev, p);
+ if (found)
+ return;
+ }
-use_random:
/* Sun MAC prefix then 3 random bytes. */
dev_addr[0] = 0x08;
dev_addr[1] = 0x00;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index dc57352e5a97..1802c3b48799 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -67,8 +67,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.39"
-#define DRV_MODULE_RELDATE "September 5, 2005"
+#define DRV_MODULE_VERSION "3.42"
+#define DRV_MODULE_RELDATE "Oct 3, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -3389,7 +3389,8 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- if (sblk->status & SD_STATUS_UPDATED) {
+ if ((sblk->status & SD_STATUS_UPDATED) ||
+ !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
return IRQ_RETVAL(1);
@@ -3442,31 +3443,47 @@ static void tg3_tx_timeout(struct net_device *dev)
schedule_work(&tp->reset_task);
}
+/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
+static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
+{
+ u32 base = (u32) mapping & 0xffffffff;
+
+ return ((base > 0xffffdcc0) &&
+ (base + len + 8 < base));
+}
+
static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
- u32 guilty_entry, int guilty_len,
- u32 last_plus_one, u32 *start, u32 mss)
+ u32 last_plus_one, u32 *start,
+ u32 base_flags, u32 mss)
{
struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
- dma_addr_t new_addr;
+ dma_addr_t new_addr = 0;
u32 entry = *start;
- int i;
+ int i, ret = 0;
if (!new_skb) {
- dev_kfree_skb(skb);
- return -1;
+ ret = -1;
+ } else {
+ /* New SKB is guaranteed to be linear. */
+ entry = *start;
+ new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
+ PCI_DMA_TODEVICE);
+ /* Make sure new skb does not cross any 4G boundaries.
+ * Drop the packet if it does.
+ */
+ if (tg3_4g_overflow_test(new_addr, new_skb->len)) {
+ ret = -1;
+ dev_kfree_skb(new_skb);
+ new_skb = NULL;
+ } else {
+ tg3_set_txd(tp, entry, new_addr, new_skb->len,
+ base_flags, 1 | (mss << 1));
+ *start = NEXT_TX(entry);
+ }
}
- /* New SKB is guaranteed to be linear. */
- entry = *start;
- new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
- PCI_DMA_TODEVICE);
- tg3_set_txd(tp, entry, new_addr, new_skb->len,
- (skb->ip_summed == CHECKSUM_HW) ?
- TXD_FLAG_TCPUDP_CSUM : 0, 1 | (mss << 1));
- *start = NEXT_TX(entry);
-
/* Now clean up the sw ring entries. */
i = 0;
while (entry != last_plus_one) {
@@ -3491,7 +3508,7 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
dev_kfree_skb(skb);
- return 0;
+ return ret;
}
static void tg3_set_txd(struct tg3 *tp, int entry,
@@ -3517,19 +3534,10 @@ static void tg3_set_txd(struct tg3 *tp, int entry,
txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
}
-static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
-{
- u32 base = (u32) mapping & 0xffffffff;
-
- return ((base > 0xffffdcc0) &&
- (base + len + 8 < base));
-}
-
static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
dma_addr_t mapping;
- unsigned int i;
u32 len, entry, base_flags, mss;
int would_hit_hwbug;
@@ -3624,7 +3632,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
would_hit_hwbug = 0;
if (tg3_4g_overflow_test(mapping, len))
- would_hit_hwbug = entry + 1;
+ would_hit_hwbug = 1;
tg3_set_txd(tp, entry, mapping, len, base_flags,
(skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
@@ -3648,12 +3656,8 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
tp->tx_buffers[entry].skb = NULL;
pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
- if (tg3_4g_overflow_test(mapping, len)) {
- /* Only one should match. */
- if (would_hit_hwbug)
- BUG();
- would_hit_hwbug = entry + 1;
- }
+ if (tg3_4g_overflow_test(mapping, len))
+ would_hit_hwbug = 1;
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
tg3_set_txd(tp, entry, mapping, len,
@@ -3669,34 +3673,15 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (would_hit_hwbug) {
u32 last_plus_one = entry;
u32 start;
- unsigned int len = 0;
-
- would_hit_hwbug -= 1;
- entry = entry - 1 - skb_shinfo(skb)->nr_frags;
- entry &= (TG3_TX_RING_SIZE - 1);
- start = entry;
- i = 0;
- while (entry != last_plus_one) {
- if (i == 0)
- len = skb_headlen(skb);
- else
- len = skb_shinfo(skb)->frags[i-1].size;
- if (entry == would_hit_hwbug)
- break;
-
- i++;
- entry = NEXT_TX(entry);
-
- }
+ start = entry - 1 - skb_shinfo(skb)->nr_frags;
+ start &= (TG3_TX_RING_SIZE - 1);
/* If the workaround fails due to memory/mapping
* failure, silently drop this packet.
*/
- if (tigon3_4gb_hwbug_workaround(tp, skb,
- entry, len,
- last_plus_one,
- &start, mss))
+ if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one,
+ &start, base_flags, mss))
goto out_unlock;
entry = start;
@@ -5411,6 +5396,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
struct tg3 *tp = netdev_priv(dev);
struct sockaddr *addr = p;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
spin_lock_bh(&tp->lock);
@@ -5822,6 +5810,13 @@ static int tg3_reset_hw(struct tg3 *tp)
}
memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
+ tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+ /* reset to prevent losing 1st rx packet intermittently */
+ tw32_f(MAC_RX_MODE, RX_MODE_RESET);
+ udelay(10);
+ }
+
tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
@@ -5953,7 +5948,7 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(MAC_LED_CTRL, tp->led_ctrl);
tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
- if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
udelay(10);
}
@@ -6893,8 +6888,7 @@ static struct net_device_stats *tg3_get_stats(struct net_device *dev)
get_stat64(&hw_stats->tx_octets);
stats->rx_errors = old_stats->rx_errors +
- get_stat64(&hw_stats->rx_errors) +
- get_stat64(&hw_stats->rx_discards);
+ get_stat64(&hw_stats->rx_errors);
stats->tx_errors = old_stats->tx_errors +
get_stat64(&hw_stats->tx_errors) +
get_stat64(&hw_stats->tx_mac_errors) +
@@ -6922,6 +6916,9 @@ static struct net_device_stats *tg3_get_stats(struct net_device *dev)
stats->rx_crc_errors = old_stats->rx_crc_errors +
calc_crc_errors(tp);
+ stats->rx_missed_errors = old_stats->rx_missed_errors +
+ get_stat64(&hw_stats->rx_discards);
+
return stats;
}
@@ -7374,12 +7371,17 @@ static int tg3_nway_reset(struct net_device *dev)
if (!netif_running(dev))
return -EAGAIN;
+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+ return -EINVAL;
+
spin_lock_bh(&tp->lock);
r = -EINVAL;
tg3_readphy(tp, MII_BMCR, &bmcr);
if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
- (bmcr & BMCR_ANENABLE)) {
- tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
+ ((bmcr & BMCR_ANENABLE) ||
+ (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
+ tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
+ BMCR_ANENABLE);
r = 0;
}
spin_unlock_bh(&tp->lock);
@@ -7941,19 +7943,32 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
struct tg3_rx_buffer_desc *desc;
if (loopback_mode == TG3_MAC_LOOPBACK) {
+ /* HW errata - mac loopback fails in some cases on 5780.
+ * Normal traffic and PHY loopback are not affected by
+ * errata.
+ */
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ return 0;
+
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
MAC_MODE_PORT_MODE_GMII;
tw32(MAC_MODE, mac_mode);
} else if (loopback_mode == TG3_PHY_LOOPBACK) {
+ tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
+ BMCR_SPEED1000);
+ udelay(40);
+ /* reset to prevent losing 1st rx packet intermittently */
+ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
+ tw32_f(MAC_RX_MODE, RX_MODE_RESET);
+ udelay(10);
+ tw32_f(MAC_RX_MODE, tp->rx_mode);
+ }
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
mac_mode &= ~MAC_MODE_LINK_POLARITY;
tw32(MAC_MODE, mac_mode);
-
- tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
- BMCR_SPEED1000);
}
else
return -EINVAL;
@@ -8303,6 +8318,7 @@ static struct ethtool_ops tg3_ethtool_ops = {
.get_ethtool_stats = tg3_get_ethtool_stats,
.get_coalesce = tg3_get_coalesce,
.set_coalesce = tg3_set_coalesce,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
@@ -9268,6 +9284,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
static struct pci_device_id write_reorder_chipsets[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_FE_GATE_700C) },
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8385_0) },
{ },
};
u32 misc_ctrl_reg;
@@ -9282,15 +9300,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
#endif
- /* If we have an AMD 762 chipset, write
- * reordering to the mailbox registers done by the host
- * controller can cause major troubles. We read back from
- * every mailbox register write to force the writes to be
- * posted to the chip in order.
- */
- if (pci_dev_present(write_reorder_chipsets))
- tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
-
/* Force memory write invalidate off. If we leave it on,
* then on 5700_BX chips we have to enable a workaround.
* The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
@@ -9421,6 +9430,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+ /* If we have an AMD 762 or VIA K8T800 chipset, write
+ * reordering to the mailbox registers done by the host
+ * controller can cause major troubles. We read back from
+ * every mailbox register write to force the writes to be
+ * posted to the chip in order.
+ */
+ if (pci_dev_present(write_reorder_chipsets) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+ tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
+
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
tp->pci_lat_timer < 64) {
tp->pci_lat_timer = 64;
@@ -9529,7 +9548,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->write32_rx_mbox = tg3_write_indirect_mbox;
iounmap(tp->regs);
- tp->regs = 0;
+ tp->regs = NULL;
pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
pci_cmd &= ~PCI_COMMAND_MEMORY;
@@ -9781,6 +9800,7 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp)
if (prom_getproplen(node, "local-mac-address") == 6) {
prom_getproperty(node, "local-mac-address",
dev->dev_addr, 6);
+ memcpy(dev->perm_addr, dev->dev_addr, 6);
return 0;
}
}
@@ -9792,6 +9812,7 @@ static int __devinit tg3_get_default_macaddr_sparc(struct tg3 *tp)
struct net_device *dev = tp->dev;
memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
+ memcpy(dev->perm_addr, idprom->id_ethaddr, 6);
return 0;
}
#endif
@@ -9861,6 +9882,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
#endif
return -EINVAL;
}
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
return 0;
}
@@ -10332,6 +10354,44 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
};
}
+static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
+{
+ if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ strcpy(str, "PCI Express");
+ return str;
+ } else if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+ u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL) & 0x1f;
+
+ strcpy(str, "PCIX:");
+
+ if ((clock_ctrl == 7) ||
+ ((tr32(GRC_MISC_CFG) & GRC_MISC_CFG_BOARD_ID_MASK) ==
+ GRC_MISC_CFG_BOARD_ID_5704CIOBE))
+ strcat(str, "133MHz");
+ else if (clock_ctrl == 0)
+ strcat(str, "33MHz");
+ else if (clock_ctrl == 2)
+ strcat(str, "50MHz");
+ else if (clock_ctrl == 4)
+ strcat(str, "66MHz");
+ else if (clock_ctrl == 6)
+ strcat(str, "100MHz");
+ else if (clock_ctrl == 7)
+ strcat(str, "133MHz");
+ } else {
+ strcpy(str, "PCI:");
+ if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED)
+ strcat(str, "66MHz");
+ else
+ strcat(str, "33MHz");
+ }
+ if (tp->tg3_flags & TG3_FLAG_PCI_32BIT)
+ strcat(str, ":32-bit");
+ else
+ strcat(str, ":64-bit");
+ return str;
+}
+
static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
{
struct pci_dev *peer;
@@ -10394,6 +10454,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
struct net_device *dev;
struct tg3 *tp;
int i, err, pci_using_dac, pm_cap;
+ char str[40];
if (tg3_version_printed++ == 0)
printk(KERN_INFO "%s", version);
@@ -10639,16 +10700,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
- printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ",
+ printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ",
dev->name,
tp->board_part_number,
tp->pci_chip_rev_id,
tg3_phy_string(tp),
- ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "X" : ""),
- ((tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) ?
- ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "133MHz" : "66MHz") :
- ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "100MHz" : "33MHz")),
- ((tp->tg3_flags & TG3_FLAG_PCI_32BIT) ? "32-bit" : "64-bit"),
+ tg3_bus_string(tp, str),
(tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000");
for (i = 0; i < 6; i++)
@@ -10674,7 +10731,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
err_out_iounmap:
if (tp->regs) {
iounmap(tp->regs);
- tp->regs = 0;
+ tp->regs = NULL;
}
err_out_free_dev:
@@ -10699,7 +10756,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
if (tp->regs) {
iounmap(tp->regs);
- tp->regs = 0;
+ tp->regs = NULL;
}
free_netdev(dev);
pci_release_regions(pdev);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index c184b773e585..2e733c60bfa4 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2246,6 +2246,7 @@ struct tg3 {
(X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
(X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
+ (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
(X) == PHY_ID_BCM8002)
struct tg3_hw_stats *hw_stats;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index e7b001017b9a..9f491563944e 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -318,7 +318,7 @@ static void ibmtr_cleanup_card(struct net_device *dev)
if (dev->base_addr) {
outb(0,dev->base_addr+ADAPTRESET);
- schedule_timeout(TR_RST_TIME); /* wait 50ms */
+ schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0,dev->base_addr+ADAPTRESETREL);
}
@@ -531,7 +531,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
if (!time_after(jiffies, timeout)) continue;
DPRINTK( "Hardware timeout during initialization.\n");
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
}
ti->sram_phys =
@@ -645,7 +644,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
DPRINTK("Unknown shared ram paging info %01X\n",
ti->shared_ram_paging);
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
break;
} /*end switch shared_ram_paging */
@@ -675,7 +673,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
"driver limit (%05x), adapter not started.\n",
chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
} else { /* seems cool, record what we have figured out */
ti->sram_base = new_base >> 12;
@@ -690,7 +687,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",
irq);
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
}
/*?? Now, allocate some of the PIO PORTs for this driver.. */
@@ -699,7 +695,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
DPRINTK("Could not grab PIO range. Halting driver.\n");
free_irq(dev->irq, dev);
iounmap(t_mmio);
- kfree(ti);
return -EBUSY;
}
@@ -859,8 +854,7 @@ static int tok_init_card(struct net_device *dev)
writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
outb(0, PIOaddr + ADAPTRESET);
- current->state=TASK_UNINTERRUPTIBLE;
- schedule_timeout(TR_RST_TIME); /* wait 50ms */
+ schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0, PIOaddr + ADAPTRESETREL);
#ifdef ENABLE_PAGING
@@ -908,8 +902,8 @@ static int tok_open(struct net_device *dev)
DPRINTK("Adapter is up and running\n");
return 0;
}
- current->state=TASK_INTERRUPTIBLE;
- i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
+ i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
+ /* wait 30 seconds */
if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
}
outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 9e7923192a49..05477d24fd49 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -1101,7 +1101,7 @@ static int olympic_close(struct net_device *dev)
while(olympic_priv->srb_queued) {
- t = schedule_timeout(60*HZ);
+ t = schedule_timeout_interruptible(60*HZ);
if(signal_pending(current)) {
printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 2e39bf1f7462..c1925590a0e1 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -1243,8 +1243,7 @@ void tms380tr_wait(unsigned long time)
tmp = jiffies + time/(1000000/HZ);
do {
- current->state = TASK_INTERRUPTIBLE;
- tmp = schedule_timeout(tmp);
+ tmp = schedule_timeout_interruptible(tmp);
} while(time_after(tmp, jiffies));
#else
udelay(time);
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 5db694c4eb02..683f14b01c06 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -172,7 +172,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
int i;
for (i = 0; i < tp->mtable->leafcount; i++)
if (tp->mtable->mleaf[i].media == dev->if_port) {
- int startup = ! ((tp->chip_id == DC21143 && tp->revision == 65));
+ int startup = ! ((tp->chip_id == DC21143 && (tp->revision == 48 || tp->revision == 65)));
tp->cur_index = i;
tulip_select_media(dev, startup);
setup_done = 1;
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index a22d00198e4d..6b8eee8f7bfd 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1787,10 +1787,15 @@ static void __init de21041_get_srom_info (struct de_private *de)
/* DEC now has a specification but early board makers
just put the address in the first EEPROM locations. */
/* This does memcmp(eedata, eedata+16, 8) */
+
+#ifndef CONFIG_MIPS_COBALT
+
for (i = 0; i < 8; i ++)
if (ee_data[i] != ee_data[16+i])
sa_offset = 20;
+#endif
+
/* store MAC address */
for (i = 0; i < 6; i ++)
de->dev->dev_addr[i] = ee_data[i + sa_offset];
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 93800c126e86..ee48bfd67349 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -2144,9 +2144,9 @@ srom_search(struct net_device *dev, struct pci_dev *pdev)
u_long iobase = 0; /* Clear upper 32 bits in Alphas */
int i, j, cfrv;
struct de4x5_private *lp = netdev_priv(dev);
- struct list_head *walk = &pdev->bus_list;
+ struct list_head *walk;
- for (walk = walk->next; walk != &pdev->bus_list; walk = walk->next) {
+ list_for_each(walk, &pdev->bus_list) {
struct pci_dev *this_dev = pci_dev_b(walk);
/* Skip the pci_bus list entry */
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index 26cc4f6378c7..60d1e05ab732 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -117,7 +117,7 @@ static int xircom_open(struct net_device *dev);
static int xircom_close(struct net_device *dev);
static void xircom_up(struct xircom_private *card);
static struct net_device_stats *xircom_get_stats(struct net_device *dev);
-#if CONFIG_NET_POLL_CONTROLLER
+#ifdef CONFIG_NET_POLL_CONTROLLER
static void xircom_poll_controller(struct net_device *dev);
#endif
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index ecfa6f8805ce..4c76cb794bfb 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -419,10 +419,9 @@ typhoon_reset(void __iomem *ioaddr, int wait_type)
TYPHOON_STATUS_WAITING_FOR_HOST)
goto out;
- if(wait_type == WaitSleep) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- } else
+ if(wait_type == WaitSleep)
+ schedule_timeout_uninterruptible(1);
+ else
udelay(TYPHOON_UDELAY);
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index fc7738ffbfff..241871589283 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -490,6 +490,8 @@ struct rhine_private {
u8 tx_thresh, rx_thresh;
struct mii_if_info mii_if;
+ struct work_struct tx_timeout_task;
+ struct work_struct check_media_task;
void __iomem *base;
};
@@ -497,6 +499,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int rhine_open(struct net_device *dev);
static void rhine_tx_timeout(struct net_device *dev);
+static void rhine_tx_timeout_task(struct net_device *dev);
+static void rhine_check_media_task(struct net_device *dev);
static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static void rhine_tx(struct net_device *dev);
@@ -814,8 +818,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
for (i = 0; i < 6; i++)
dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- if (!is_valid_ether_addr(dev->dev_addr)) {
+ if (!is_valid_ether_addr(dev->perm_addr)) {
rc = -EIO;
printk(KERN_ERR "Invalid MAC address\n");
goto err_out_unmap;
@@ -850,6 +855,12 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+ INIT_WORK(&rp->tx_timeout_task,
+ (void (*)(void *))rhine_tx_timeout_task, dev);
+
+ INIT_WORK(&rp->check_media_task,
+ (void (*)(void *))rhine_check_media_task, dev);
+
/* dev->name not defined before register_netdev()! */
rc = register_netdev(dev);
if (rc)
@@ -1076,6 +1087,11 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
ioaddr + ChipCmd1);
}
+static void rhine_check_media_task(struct net_device *dev)
+{
+ rhine_check_media(dev, 0);
+}
+
static void init_registers(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
@@ -1129,8 +1145,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
if (quirks & rqRhineI) {
iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
- /* Can be called from ISR. Evil. */
- mdelay(1);
+ /* Do not call from ISR! */
+ msleep(1);
/* 0x80 must be set immediately before turning it off */
iowrite8(0x80, ioaddr + MIICmd);
@@ -1220,6 +1236,16 @@ static int rhine_open(struct net_device *dev)
static void rhine_tx_timeout(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
+
+ /*
+ * Move bulk of work outside of interrupt context
+ */
+ schedule_work(&rp->tx_timeout_task);
+}
+
+static void rhine_tx_timeout_task(struct net_device *dev)
+{
+ struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
@@ -1625,7 +1651,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
spin_lock(&rp->lock);
if (intr_status & IntrLinkChange)
- rhine_check_media(dev, 0);
+ schedule_work(&rp->check_media_task);
if (intr_status & IntrStatsMax) {
rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@@ -1829,6 +1855,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
.set_wol = rhine_set_wol,
.get_sg = ethtool_op_get_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1872,6 +1899,9 @@ static int rhine_close(struct net_device *dev)
spin_unlock_irq(&rp->lock);
free_irq(rp->pdev->irq, dev);
+
+ flush_scheduled_work();
+
free_rbufs(dev);
free_tbufs(dev);
free_ring(dev);
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 7ff814fd65d0..ae9e897c255e 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -1617,8 +1617,7 @@ static int get_wait_data(struct cosa_data *cosa)
return r;
}
/* sleep if not ready to read */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
cosa_getstatus(cosa));
@@ -1644,8 +1643,7 @@ static int put_wait_data(struct cosa_data *cosa, int data)
}
#if 0
/* sleep if not ready to read */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
#endif
}
printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index 9e56fc346ba4..e6d005726aad 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -109,7 +109,7 @@ static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
* < 0 error.
* Context: process */
-int __init cycx_drv_init(void)
+static int __init cycx_drv_init(void)
{
printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE,
copyright);
@@ -119,7 +119,7 @@ int __init cycx_drv_init(void)
/* Module 'remove' entry point.
* o release all remaining system resources */
-void cycx_drv_cleanup(void)
+static void cycx_drv_cleanup(void)
{
}
@@ -184,8 +184,7 @@ int cycx_down(struct cycx_hw *hw)
}
/* Enable interrupt generation. */
-EXPORT_SYMBOL(cycx_inten);
-void cycx_inten(struct cycx_hw *hw)
+static void cycx_inten(struct cycx_hw *hw)
{
writeb(0, hw->dpmbase);
}
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index 7b48064364dc..430b1f630fb4 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -103,7 +103,7 @@ static struct cycx_device *cycx_card_array; /* adapter data space */
* < 0 error.
* Context: process
*/
-int __init cycx_init(void)
+static int __init cycx_init(void)
{
int cnt, err = -ENOMEM;
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 02d57c0b4243..a631d1c2fa14 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -78,6 +78,7 @@
#define CYCLOMX_X25_DEBUG 1
+#include <linux/ctype.h> /* isdigit() */
#include <linux/errno.h> /* return codes */
#include <linux/if_arp.h> /* ARPHRD_HWX25 */
#include <linux/kernel.h> /* printk(), and other useful stuff */
@@ -418,7 +419,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
/* Set channel timeouts (default if not specified) */
chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
- } else if (is_digit(conf->addr[0])) { /* PVC */
+ } else if (isdigit(conf->addr[0])) { /* PVC */
s16 lcn = dec_to_uint(conf->addr, 0);
if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
@@ -1531,7 +1532,7 @@ static unsigned dec_to_uint(u8 *str, int len)
if (!len)
len = strlen(str);
- for (; len && is_digit(*str); ++str, --len)
+ for (; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned) '0');
return val;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 520a77a798e2..2f61a47b4716 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -446,8 +446,8 @@ static inline unsigned int dscc4_tx_quiescent(struct dscc4_dev_priv *dpriv,
return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
}
-int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
- const char *msg)
+static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
+ struct net_device *dev, const char *msg)
{
int ret = 0;
@@ -466,8 +466,9 @@ int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
return ret;
}
-void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
- char *msg)
+static void dscc4_tx_print(struct net_device *dev,
+ struct dscc4_dev_priv *dpriv,
+ char *msg)
{
printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
@@ -507,7 +508,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
}
}
-inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
+ struct net_device *dev)
{
unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
struct RxFD *rx_fd = dpriv->rx_fd + dirty;
@@ -542,8 +544,7 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv,
msg, i);
goto done;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
rmb();
} while (++i > 0);
printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
@@ -588,8 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
(dpriv->iqtx[cur] & Xpr))
break;
smp_rmb();
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
} while (++i > 0);
return (i >= 0 ) ? i : -EAGAIN;
@@ -1035,8 +1035,7 @@ static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr)
/* Flush posted writes */
readl(ioaddr + GSTAR);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
for (i = 0; i < 16; i++)
pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
@@ -1894,7 +1893,7 @@ try:
* It failed and locked solid. Thus the introduction of a dummy skb.
* Problem is acknowledged in errata sheet DS5. Joy :o/
*/
-struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
+static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
{
struct sk_buff *skb;
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 2c83cca34b86..7981a2c7906e 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -74,11 +74,11 @@ MODULE_LICENSE("GPL");
/*
* Modules parameters and associated varaibles
*/
-int fst_txq_low = FST_LOW_WATER_MARK;
-int fst_txq_high = FST_HIGH_WATER_MARK;
-int fst_max_reads = 7;
-int fst_excluded_cards = 0;
-int fst_excluded_list[FST_MAX_CARDS];
+static int fst_txq_low = FST_LOW_WATER_MARK;
+static int fst_txq_high = FST_HIGH_WATER_MARK;
+static int fst_max_reads = 7;
+static int fst_excluded_cards = 0;
+static int fst_excluded_list[FST_MAX_CARDS];
module_param(fst_txq_low, int, 0);
module_param(fst_txq_high, int, 0);
@@ -572,13 +572,13 @@ static void do_bottom_half_rx(struct fst_card_info *card);
static void fst_process_tx_work_q(unsigned long work_q);
static void fst_process_int_work_q(unsigned long work_q);
-DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
-DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
+static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
+static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
-struct fst_card_info *fst_card_array[FST_MAX_CARDS];
-spinlock_t fst_work_q_lock;
-u64 fst_work_txq;
-u64 fst_work_intq;
+static struct fst_card_info *fst_card_array[FST_MAX_CARDS];
+static spinlock_t fst_work_q_lock;
+static u64 fst_work_txq;
+static u64 fst_work_intq;
static void
fst_q_work_item(u64 * queue, int card_index)
@@ -980,8 +980,7 @@ fst_issue_cmd(struct fst_port_info *port, unsigned short cmd)
/* Wait for any previous command to complete */
while (mbval > NAK) {
spin_unlock_irqrestore(&card->card_lock, flags);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&card->card_lock, flags);
if (++safety > 2000) {
@@ -1498,7 +1497,7 @@ do_bottom_half_rx(struct fst_card_info *card)
* The interrupt service routine
* Dev_id is our fst_card_info pointer
*/
-irqreturn_t
+static irqreturn_t
fst_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct fst_card_info *card;
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 48c03c11cd9a..a01efa6d5c62 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -72,7 +72,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
}
skb_reserve(skb, 4);
cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0);
- data = (cisco_packet*)skb->data;
+ data = (cisco_packet*)(skb->data + 4);
data->type = htonl(type);
data->par1 = htonl(par1);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index a5d6891c9d4c..e1601d35dced 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -330,7 +330,7 @@ static int pvc_close(struct net_device *dev)
-int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
pvc_device *pvc = dev_to_pvc(dev);
fr_proto_pvc_info info;
diff --git a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
index 9dccd9546a17..3b94352b0d03 100644
--- a/drivers/net/wan/lmc/lmc_debug.c
+++ b/drivers/net/wan/lmc/lmc_debug.c
@@ -8,10 +8,10 @@
/*
* Prints out len, max to 80 octets using printk, 20 per line
*/
-void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
-{
#ifdef DEBUG
#ifdef LMC_PACKET_LOG
+void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
+{
int iNewLine = 1;
char str[80], *pstr;
@@ -43,26 +43,24 @@ void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
}
sprintf(pstr, "\n");
printk(str);
+}
#endif
#endif
-}
#ifdef DEBUG
u_int32_t lmcEventLogIndex = 0;
u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
-#endif
void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
{
-#ifdef DEBUG
lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
lmcEventLogBuf[lmcEventLogIndex++] = arg2;
lmcEventLogBuf[lmcEventLogIndex++] = arg3;
lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
-#endif
}
+#endif /* DEBUG */
void lmc_trace(struct net_device *dev, char *msg){
#ifdef LMC_TRACE
diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
index f55ce76b00ed..af8b55fdd9d9 100644
--- a/drivers/net/wan/lmc/lmc_media.c
+++ b/drivers/net/wan/lmc/lmc_media.c
@@ -48,14 +48,6 @@
*/
/*
- * For lack of a better place, put the SSI cable stuff here.
- */
-char *lmc_t1_cables[] = {
- "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
- "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
-};
-
-/*
* protocol independent method.
*/
static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *);
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
index 73401b0f0151..2024b26b99e6 100644
--- a/drivers/net/wan/pc300.h
+++ b/drivers/net/wan/pc300.h
@@ -472,24 +472,8 @@ enum pc300_loopback_cmds {
#ifdef __KERNEL__
/* Function Prototypes */
-int dma_buf_write(pc300_t *, int, ucchar *, int);
-int dma_buf_read(pc300_t *, int, struct sk_buff *);
void tx_dma_start(pc300_t *, int);
-void rx_dma_start(pc300_t *, int);
-void tx_dma_stop(pc300_t *, int);
-void rx_dma_stop(pc300_t *, int);
-int cpc_queue_xmit(struct sk_buff *, struct net_device *);
-void cpc_net_rx(struct net_device *);
-void cpc_sca_status(pc300_t *, int);
-int cpc_change_mtu(struct net_device *, int);
-int cpc_ioctl(struct net_device *, struct ifreq *, int);
-int ch_config(pc300dev_t *);
-int rx_config(pc300dev_t *);
-int tx_config(pc300dev_t *);
-void cpc_opench(pc300dev_t *);
-void cpc_closech(pc300dev_t *);
int cpc_open(struct net_device *dev);
-int cpc_close(struct net_device *dev);
int cpc_set_media(hdlc_device *, int);
#endif /* __KERNEL__ */
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 3e7753b10717..a3e65d1bc19b 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -291,6 +291,7 @@ static uclong detect_ram(pc300_t *);
static void plx_init(pc300_t *);
static void cpc_trace(struct net_device *, struct sk_buff *, char);
static int cpc_attach(struct net_device *, unsigned short, unsigned short);
+static int cpc_close(struct net_device *dev);
#ifdef CONFIG_PC300_MLPPP
void cpc_tty_init(pc300dev_t * dev);
@@ -437,7 +438,7 @@ static void rx_dma_buf_check(pc300_t * card, int ch)
printk("\n");
}
-int dma_get_rx_frame_size(pc300_t * card, int ch)
+static int dma_get_rx_frame_size(pc300_t * card, int ch)
{
volatile pcsca_bd_t __iomem *ptdescr;
ucshort first_bd = card->chan[ch].rx_first_bd;
@@ -462,7 +463,7 @@ int dma_get_rx_frame_size(pc300_t * card, int ch)
* dma_buf_write: writes a frame to the Tx DMA buffers
* NOTE: this function writes one frame at a time.
*/
-int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
{
int i, nchar;
volatile pcsca_bd_t __iomem *ptdescr;
@@ -503,7 +504,7 @@ int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
* dma_buf_read: reads a frame from the Rx DMA buffers
* NOTE: this function reads one frame at a time.
*/
-int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
+static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
{
int nchar;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -560,7 +561,7 @@ int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
return (rcvd);
}
-void tx_dma_stop(pc300_t * card, int ch)
+static void tx_dma_stop(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
ucchar drr_ena_bit = 1 << (5 + 2 * ch);
@@ -571,7 +572,7 @@ void tx_dma_stop(pc300_t * card, int ch)
cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
}
-void rx_dma_stop(pc300_t * card, int ch)
+static void rx_dma_stop(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
ucchar drr_ena_bit = 1 << (4 + 2 * ch);
@@ -582,7 +583,7 @@ void rx_dma_stop(pc300_t * card, int ch)
cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
}
-void rx_dma_start(pc300_t * card, int ch)
+static void rx_dma_start(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -607,7 +608,7 @@ void rx_dma_start(pc300_t * card, int ch)
/*************************/
/*** FALC Routines ***/
/*************************/
-void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
{
void __iomem *falcbase = card->hw.falcbase;
unsigned long i = 0;
@@ -622,7 +623,7 @@ void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
}
-void falc_intr_enable(pc300_t * card, int ch)
+static void falc_intr_enable(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -672,7 +673,7 @@ void falc_intr_enable(pc300_t * card, int ch)
}
}
-void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
{
void __iomem *falcbase = card->hw.falcbase;
ucchar tshf = card->chan[ch].falc.offset;
@@ -688,7 +689,7 @@ void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
(0x80 >> (timeslot & 0x07)));
}
-void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
{
void __iomem *falcbase = card->hw.falcbase;
ucchar tshf = card->chan[ch].falc.offset;
@@ -704,7 +705,7 @@ void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
~(0x80 >> (timeslot & 0x07)));
}
-void falc_close_all_timeslots(pc300_t * card, int ch)
+static void falc_close_all_timeslots(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -726,7 +727,7 @@ void falc_close_all_timeslots(pc300_t * card, int ch)
}
}
-void falc_open_all_timeslots(pc300_t * card, int ch)
+static void falc_open_all_timeslots(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -758,7 +759,7 @@ void falc_open_all_timeslots(pc300_t * card, int ch)
}
}
-void falc_init_timeslot(pc300_t * card, int ch)
+static void falc_init_timeslot(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -776,7 +777,7 @@ void falc_init_timeslot(pc300_t * card, int ch)
}
}
-void falc_enable_comm(pc300_t * card, int ch)
+static void falc_enable_comm(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -792,7 +793,7 @@ void falc_enable_comm(pc300_t * card, int ch)
~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
}
-void falc_disable_comm(pc300_t * card, int ch)
+static void falc_disable_comm(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -806,7 +807,7 @@ void falc_disable_comm(pc300_t * card, int ch)
((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
}
-void falc_init_t1(pc300_t * card, int ch)
+static void falc_init_t1(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -975,7 +976,7 @@ void falc_init_t1(pc300_t * card, int ch)
falc_close_all_timeslots(card, ch);
}
-void falc_init_e1(pc300_t * card, int ch)
+static void falc_init_e1(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1155,7 +1156,7 @@ void falc_init_e1(pc300_t * card, int ch)
falc_close_all_timeslots(card, ch);
}
-void falc_init_hdlc(pc300_t * card, int ch)
+static void falc_init_hdlc(pc300_t * card, int ch)
{
void __iomem *falcbase = card->hw.falcbase;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -1181,7 +1182,7 @@ void falc_init_hdlc(pc300_t * card, int ch)
falc_intr_enable(card, ch);
}
-void te_config(pc300_t * card, int ch)
+static void te_config(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1241,7 +1242,7 @@ void te_config(pc300_t * card, int ch)
CPC_UNLOCK(card, flags);
}
-void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
+static void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1397,7 +1398,7 @@ void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
}
}
-void falc_update_stats(pc300_t * card, int ch)
+static void falc_update_stats(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1450,7 +1451,7 @@ void falc_update_stats(pc300_t * card, int ch)
* the synchronizer and then sent to the system interface.
*----------------------------------------------------------------------------
*/
-void falc_remote_loop(pc300_t * card, int ch, int loop_on)
+static void falc_remote_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1495,7 +1496,7 @@ void falc_remote_loop(pc300_t * card, int ch, int loop_on)
* coding must be identical.
*----------------------------------------------------------------------------
*/
-void falc_local_loop(pc300_t * card, int ch, int loop_on)
+static void falc_local_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1522,7 +1523,7 @@ void falc_local_loop(pc300_t * card, int ch, int loop_on)
* looped. They are originated by the FALC-LH transmitter.
*----------------------------------------------------------------------------
*/
-void falc_payload_loop(pc300_t * card, int ch, int loop_on)
+static void falc_payload_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1576,7 +1577,7 @@ void falc_payload_loop(pc300_t * card, int ch, int loop_on)
* Description: Turns XLU bit off in the proper register
*----------------------------------------------------------------------------
*/
-void turn_off_xlu(pc300_t * card, int ch)
+static void turn_off_xlu(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1597,7 +1598,7 @@ void turn_off_xlu(pc300_t * card, int ch)
* Description: Turns XLD bit off in the proper register
*----------------------------------------------------------------------------
*/
-void turn_off_xld(pc300_t * card, int ch)
+static void turn_off_xld(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1619,7 +1620,7 @@ void turn_off_xld(pc300_t * card, int ch)
* to generate a LOOP activation code over a T1/E1 line.
*----------------------------------------------------------------------------
*/
-void falc_generate_loop_up_code(pc300_t * card, int ch)
+static void falc_generate_loop_up_code(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1652,7 +1653,7 @@ void falc_generate_loop_up_code(pc300_t * card, int ch)
* to generate a LOOP deactivation code over a T1/E1 line.
*----------------------------------------------------------------------------
*/
-void falc_generate_loop_down_code(pc300_t * card, int ch)
+static void falc_generate_loop_down_code(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1682,7 +1683,7 @@ void falc_generate_loop_down_code(pc300_t * card, int ch)
* it on the reception side.
*----------------------------------------------------------------------------
*/
-void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
+static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1729,7 +1730,7 @@ void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
* Description: This routine returns the bit error counter value
*----------------------------------------------------------------------------
*/
-ucshort falc_pattern_test_error(pc300_t * card, int ch)
+static ucshort falc_pattern_test_error(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1769,7 +1770,7 @@ cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx)
netif_rx(skb);
}
-void cpc_tx_timeout(struct net_device *dev)
+static void cpc_tx_timeout(struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1797,7 +1798,7 @@ void cpc_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1880,7 +1881,7 @@ int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-void cpc_net_rx(struct net_device *dev)
+static void cpc_net_rx(struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -2403,7 +2404,7 @@ static irqreturn_t cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void cpc_sca_status(pc300_t * card, int ch)
+static void cpc_sca_status(pc300_t * card, int ch)
{
ucchar ilar;
void __iomem *scabase = card->hw.scabase;
@@ -2495,7 +2496,7 @@ void cpc_sca_status(pc300_t * card, int ch)
}
}
-void cpc_falc_status(pc300_t * card, int ch)
+static void cpc_falc_status(pc300_t * card, int ch)
{
pc300ch_t *chan = &card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2523,7 +2524,7 @@ void cpc_falc_status(pc300_t * card, int ch)
CPC_UNLOCK(card, flags);
}
-int cpc_change_mtu(struct net_device *dev, int new_mtu)
+static int cpc_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
return -EINVAL;
@@ -2531,7 +2532,7 @@ int cpc_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
pc300dev_t *d = (pc300dev_t *) dev->priv;
@@ -2856,7 +2857,7 @@ static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
}
}
-int ch_config(pc300dev_t * d)
+static int ch_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -3004,7 +3005,7 @@ int ch_config(pc300dev_t * d)
return 0;
}
-int rx_config(pc300dev_t * d)
+static int rx_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3035,7 +3036,7 @@ int rx_config(pc300dev_t * d)
return 0;
}
-int tx_config(pc300dev_t * d)
+static int tx_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3098,7 +3099,7 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding,
return 0;
}
-void cpc_opench(pc300dev_t * d)
+static void cpc_opench(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3116,7 +3117,7 @@ void cpc_opench(pc300dev_t * d)
cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
}
-void cpc_closech(pc300dev_t * d)
+static void cpc_closech(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3173,7 +3174,7 @@ int cpc_open(struct net_device *dev)
return 0;
}
-int cpc_close(struct net_device *dev)
+static int cpc_close(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
pc300dev_t *d = (pc300dev_t *) dev->priv;
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 8454bf6caaa7..52f26b9c69d2 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -112,10 +112,10 @@ typedef struct _st_cpc_tty_area {
static struct tty_driver serial_drv;
/* local variables */
-st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
+static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
-int cpc_tty_cnt=0; /* number of intrfaces configured with MLPPP */
-int cpc_tty_unreg_flag = 0;
+static int cpc_tty_cnt = 0; /* number of intrfaces configured with MLPPP */
+static int cpc_tty_unreg_flag = 0;
/* TTY functions prototype */
static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
@@ -132,9 +132,9 @@ static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
-int pc300_tiocmset(struct tty_struct *, struct file *,
- unsigned int, unsigned int);
-int pc300_tiocmget(struct tty_struct *, struct file *);
+static int pc300_tiocmset(struct tty_struct *, struct file *,
+ unsigned int, unsigned int);
+static int pc300_tiocmget(struct tty_struct *, struct file *);
/* functions called by PC300 driver */
void cpc_tty_init(pc300dev_t *dev);
@@ -538,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
return(0);
}
-int pc300_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
+static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
{
st_cpc_tty_area *cpc_tty;
@@ -565,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tty, struct file *file,
return 0;
}
-int pc300_tiocmget(struct tty_struct *tty, struct file *file)
+static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
{
unsigned int result;
unsigned char status;
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 3ac9a45b20fa..036adc4f8ba7 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -182,7 +182,7 @@ static char sdla_byte(struct net_device *dev, int addr)
return(byte);
}
-void sdla_stop(struct net_device *dev)
+static void sdla_stop(struct net_device *dev)
{
struct frad_local *flp;
@@ -209,7 +209,7 @@ void sdla_stop(struct net_device *dev)
}
}
-void sdla_start(struct net_device *dev)
+static void sdla_start(struct net_device *dev)
{
struct frad_local *flp;
@@ -247,7 +247,7 @@ void sdla_start(struct net_device *dev)
*
***************************************************/
-int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
{
unsigned long start, done, now;
char resp, *temp;
@@ -505,7 +505,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
static int sdla_reconfig(struct net_device *dev);
-int sdla_activate(struct net_device *slave, struct net_device *master)
+static int sdla_activate(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -527,7 +527,7 @@ int sdla_activate(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_deactivate(struct net_device *slave, struct net_device *master)
+static int sdla_deactivate(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -549,7 +549,7 @@ int sdla_deactivate(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_assoc(struct net_device *slave, struct net_device *master)
+static int sdla_assoc(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -585,7 +585,7 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_deassoc(struct net_device *slave, struct net_device *master)
+static int sdla_deassoc(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -613,7 +613,7 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
+static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
{
struct frad_local *flp;
struct dlci_local *dlp;
@@ -1324,7 +1324,7 @@ NOTE: This is rather a useless action right now, as the
return(0);
}
-int sdla_change_mtu(struct net_device *dev, int new_mtu)
+static int sdla_change_mtu(struct net_device *dev, int new_mtu)
{
struct frad_local *flp;
@@ -1337,7 +1337,7 @@ int sdla_change_mtu(struct net_device *dev, int new_mtu)
return(-EOPNOTSUPP);
}
-int sdla_set_config(struct net_device *dev, struct ifmap *map)
+static int sdla_set_config(struct net_device *dev, struct ifmap *map)
{
struct frad_local *flp;
int i;
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
index 0497dbdb8631..7f1ce9d4333e 100644
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -822,7 +822,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
chan->card = card;
/* verify media address */
- if (is_digit(conf->addr[0])) {
+ if (isdigit(conf->addr[0])) {
dlci = dec_to_uint(conf->addr, 0);
@@ -3456,7 +3456,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
if (!len)
len = strlen(str);
- for (val = 0; len && is_digit(*str); ++str, --len)
+ for (val = 0; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned)'0');
return val;
diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
index 8a95d61a2f8f..63f846d6f3a6 100644
--- a/drivers/net/wan/sdla_x25.c
+++ b/drivers/net/wan/sdla_x25.c
@@ -957,7 +957,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
chan->hold_timeout = (conf->hold_timeout) ?
conf->hold_timeout : 10;
- }else if (is_digit(conf->addr[0])){ /* PVC */
+ }else if (isdigit(conf->addr[0])){ /* PVC */
int lcn = dec_to_uint(conf->addr, 0);
if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){
@@ -3875,7 +3875,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
if (!len)
len = strlen(str);
- for (val = 0; len && is_digit(*str); ++str, --len)
+ for (val = 0; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned)'0');
return val;
@@ -3896,9 +3896,9 @@ static unsigned int hex_to_uint (unsigned char* str, int len)
for (val = 0; len; ++str, --len)
{
ch = *str;
- if (is_digit(ch))
+ if (isdigit(ch))
val = (val << 4) + (ch - (unsigned)'0');
- else if (is_hex_digit(ch))
+ else if (isxdigit(ch))
val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
else break;
}
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index c8bc6da57a41..7c2cf2e76300 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -642,9 +642,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
* Enable interrupt generation.
*/
-EXPORT_SYMBOL(sdla_inten);
-
-int sdla_inten (sdlahw_t* hw)
+static int sdla_inten (sdlahw_t* hw)
{
unsigned port = hw->port;
int tmp, i;
@@ -698,8 +696,7 @@ int sdla_inten (sdlahw_t* hw)
* Disable interrupt generation.
*/
-EXPORT_SYMBOL(sdla_intde);
-
+#if 0
int sdla_intde (sdlahw_t* hw)
{
unsigned port = hw->port;
@@ -748,14 +745,13 @@ int sdla_intde (sdlahw_t* hw)
}
return 0;
}
+#endif /* 0 */
/*============================================================================
* Acknowledge SDLA hardware interrupt.
*/
-EXPORT_SYMBOL(sdla_intack);
-
-int sdla_intack (sdlahw_t* hw)
+static int sdla_intack (sdlahw_t* hw)
{
unsigned port = hw->port;
int tmp;
@@ -827,8 +823,7 @@ void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
* Generate an interrupt to adapter's CPU.
*/
-EXPORT_SYMBOL(sdla_intr);
-
+#if 0
int sdla_intr (sdlahw_t* hw)
{
unsigned port = hw->port;
@@ -863,6 +858,7 @@ int sdla_intr (sdlahw_t* hw)
}
return 0;
}
+#endif /* 0 */
/*============================================================================
* Execute Adapter Command.
diff --git a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
index 74e151acef3e..7a8b22a7ea31 100644
--- a/drivers/net/wan/sdlamain.c
+++ b/drivers/net/wan/sdlamain.c
@@ -57,6 +57,7 @@
#include <linux/ioport.h> /* request_region(), release_region() */
#include <linux/wanrouter.h> /* WAN router definitions */
#include <linux/wanpipe.h> /* WANPIPE common user API definitions */
+#include <linux/rcupdate.h>
#include <linux/in.h>
#include <asm/io.h> /* phys_to_virt() */
@@ -1268,37 +1269,41 @@ unsigned long get_ip_address(struct net_device *dev, int option)
struct in_ifaddr *ifaddr;
struct in_device *in_dev;
+ unsigned long addr = 0;
- if ((in_dev = __in_dev_get(dev)) == NULL){
- return 0;
+ rcu_read_lock();
+ if ((in_dev = __in_dev_get_rcu(dev)) == NULL){
+ goto out;
}
if ((ifaddr = in_dev->ifa_list)== NULL ){
- return 0;
+ goto out;
}
switch (option){
case WAN_LOCAL_IP:
- return ifaddr->ifa_local;
+ addr = ifaddr->ifa_local;
break;
case WAN_POINTOPOINT_IP:
- return ifaddr->ifa_address;
+ addr = ifaddr->ifa_address;
break;
case WAN_NETMASK_IP:
- return ifaddr->ifa_mask;
+ addr = ifaddr->ifa_mask;
break;
case WAN_BROADCAST_IP:
- return ifaddr->ifa_broadcast;
+ addr = ifaddr->ifa_broadcast;
break;
default:
- return 0;
+ break;
}
- return 0;
+out:
+ rcu_read_unlock();
+ return addr;
}
void add_gateway(sdla_t *card, struct net_device *dev)
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index b56a7b516d24..2d1bba06a085 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -221,7 +221,7 @@ static void sppp_clear_timeout(struct sppp *p)
* here.
*/
-void sppp_input (struct net_device *dev, struct sk_buff *skb)
+static void sppp_input (struct net_device *dev, struct sk_buff *skb)
{
struct ppp_header *h;
struct sppp *sp = (struct sppp *)sppp_of(dev);
@@ -355,8 +355,6 @@ done:
return;
}
-EXPORT_SYMBOL(sppp_input);
-
/*
* Handle transmit packets.
*/
@@ -769,7 +767,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
#ifdef CONFIG_INET
rcu_read_lock();
- if ((in_dev = __in_dev_get(dev)) != NULL)
+ if ((in_dev = __in_dev_get_rcu(dev)) != NULL)
{
for (ifa=in_dev->ifa_list; ifa != NULL;
ifa=ifa->ifa_next) {
@@ -990,7 +988,7 @@ EXPORT_SYMBOL(sppp_reopen);
* the mtu is out of range.
*/
-int sppp_change_mtu(struct net_device *dev, int new_mtu)
+static int sppp_change_mtu(struct net_device *dev, int new_mtu)
{
if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
return -EINVAL;
@@ -998,8 +996,6 @@ int sppp_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-EXPORT_SYMBOL(sppp_change_mtu);
-
/**
* sppp_do_ioctl - Ioctl handler for ppp/hdlc
* @dev: Device subject to ioctl
@@ -1456,7 +1452,7 @@ static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t
return 0;
}
-struct packet_type sppp_packet_type = {
+static struct packet_type sppp_packet_type = {
.type = __constant_htons(ETH_P_WAN_PPP),
.func = sppp_rcv,
};
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 00a07f32a81e..7187958e40ca 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -243,7 +243,7 @@ config IPW_DEBUG
config AIRO
tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
- depends on NET_RADIO && ISA && (PCI || BROKEN)
+ depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
---help---
This is the standard Linux driver to support Cisco/Aironet ISA and
PCI 802.11 wireless cards.
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 2be65d308fbe..cb429e783749 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1046,7 +1046,6 @@ static WifiCtlHdr wifictlhdr8023 = {
}
};
-#ifdef WIRELESS_EXT
// Frequency list (map channels to frequencies)
static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484 };
@@ -1067,7 +1066,6 @@ typedef struct wep_key_t {
/* List of Wireless Handlers (new API) */
static const struct iw_handler_def airo_handler_def;
-#endif /* WIRELESS_EXT */
static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
@@ -1110,10 +1108,8 @@ static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
static int airo_thread(void *data);
static void timer_func( struct net_device *dev );
static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-#ifdef WIRELESS_EXT
static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
static void airo_read_wireless_stats (struct airo_info *local);
-#endif /* WIRELESS_EXT */
#ifdef CISCO_EXT
static int readrids(struct net_device *dev, aironet_ioctl *comp);
static int writerids(struct net_device *dev, aironet_ioctl *comp);
@@ -1187,12 +1183,10 @@ struct airo_info {
int fid;
} xmit, xmit11;
struct net_device *wifidev;
-#ifdef WIRELESS_EXT
struct iw_statistics wstats; // wireless stats
unsigned long scan_timestamp; /* Time started to scan */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT */
#ifdef MICSUPPORT
/* MIC stuff */
struct crypto_tfm *tfm;
@@ -2527,7 +2521,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
unsigned long mem_start, mem_len, aux_start, aux_len;
int rc = -1;
int i;
- unsigned char *busaddroff,*vpackoff;
+ dma_addr_t busaddroff;
+ unsigned char *vpackoff;
unsigned char __iomem *pciaddroff;
mem_start = pci_resource_start(pci, 1);
@@ -2570,7 +2565,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
/*
* Setup descriptor RX, TX, CONFIG
*/
- busaddroff = (unsigned char *)ai->shared_dma;
+ busaddroff = ai->shared_dma;
pciaddroff = ai->pciaux + AUX_OFFSET;
vpackoff = ai->shared;
@@ -2579,7 +2574,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
ai->rxfids[i].pending = 0;
ai->rxfids[i].card_ram_off = pciaddroff;
ai->rxfids[i].virtual_host_addr = vpackoff;
- ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
+ ai->rxfids[i].rx_desc.host_addr = busaddroff;
ai->rxfids[i].rx_desc.valid = 1;
ai->rxfids[i].rx_desc.len = PKTSIZE;
ai->rxfids[i].rx_desc.rdy = 0;
@@ -2594,7 +2589,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
ai->txfids[i].card_ram_off = pciaddroff;
ai->txfids[i].virtual_host_addr = vpackoff;
ai->txfids[i].tx_desc.valid = 1;
- ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
+ ai->txfids[i].tx_desc.host_addr = busaddroff;
memcpy(ai->txfids[i].virtual_host_addr,
&wifictlhdr8023, sizeof(wifictlhdr8023));
@@ -2607,8 +2602,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
/* Rid descriptor setup */
ai->config_desc.card_ram_off = pciaddroff;
ai->config_desc.virtual_host_addr = vpackoff;
- ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
- ai->ridbus = (dma_addr_t)busaddroff;
+ ai->config_desc.rid_desc.host_addr = busaddroff;
+ ai->ridbus = busaddroff;
ai->config_desc.rid_desc.rid = 0;
ai->config_desc.rid_desc.len = RIDSIZE;
ai->config_desc.rid_desc.valid = 1;
@@ -2647,9 +2642,7 @@ static void wifi_setup(struct net_device *dev)
dev->get_stats = &airo_get_stats;
dev->set_mac_address = &airo_set_mac_address;
dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
dev->wireless_handlers = &airo_handler_def;
-#endif /* WIRELESS_EXT */
dev->change_mtu = &airo_change_mtu;
dev->open = &airo_open;
dev->stop = &airo_close;
@@ -2675,9 +2668,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
dev->priv = ethdev->priv;
dev->irq = ethdev->irq;
dev->base_addr = ethdev->base_addr;
-#ifdef WIRELESS_EXT
dev->wireless_data = ethdev->wireless_data;
-#endif /* WIRELESS_EXT */
memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
err = register_netdev(dev);
if (err<0) {
@@ -2755,11 +2746,9 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
dev->set_multicast_list = &airo_set_multicast_list;
dev->set_mac_address = &airo_set_mac_address;
dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
dev->wireless_handlers = &airo_handler_def;
ai->wireless_data.spy_data = &ai->spy_data;
dev->wireless_data = &ai->wireless_data;
-#endif /* WIRELESS_EXT */
dev->change_mtu = &airo_change_mtu;
dev->open = &airo_open;
dev->stop = &airo_close;
@@ -5515,12 +5504,13 @@ static int airo_pci_resume(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct airo_info *ai = dev->priv;
Resp rsp;
+ pci_power_t prev_state = pdev->current_state;
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, ai->power), 0);
+ pci_enable_wake(pdev, PCI_D0, 0);
- if (ai->power.event > 1) {
+ if (prev_state != PCI_D1) {
reset_card(dev, 0);
mpi_init_descriptors(ai);
setup_card(ai, dev->dev_addr, 0);
@@ -5598,7 +5588,6 @@ static void __exit airo_cleanup_module( void )
remove_proc_entry("aironet", proc_root_driver);
}
-#ifdef WIRELESS_EXT
/*
* Initial Wireless Extension code for Aironet driver by :
* Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
@@ -6852,7 +6841,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Add frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
- iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
+ /* iwe.u.freq.m containt the channel (starting 1), our
+ * frequency_list array start at index 0...
+ */
+ iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
@@ -7104,8 +7096,6 @@ static const struct iw_handler_def airo_handler_def =
.get_wireless_stats = airo_get_wireless_stats,
};
-#endif /* WIRELESS_EXT */
-
/*
* This defines the configuration part of the Wireless Extensions
* Note : irq and spinlock protection will occur in the subroutines
@@ -7184,7 +7174,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return rc;
}
-#ifdef WIRELESS_EXT
/*
* Get the Wireless stats out of the driver
* Note : irq and spinlock protection will occur in the subroutines
@@ -7257,7 +7246,6 @@ static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
return &local->wstats;
}
-#endif /* WIRELESS_EXT */
#ifdef CISCO_EXT
/*
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
index 9d496703c465..7b321f7cf358 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -15,28 +15,11 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/current.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
+#include <linux/delay.h>
#include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
#include "orinoco.h"
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 587869d86eee..d57011028b72 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
static void atmel_command_irq(struct atmel_private *priv);
static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 frame_len, u8 rssi);
static void atmel_management_timer(u_long a);
static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u8 *body, int body_len);
static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
static int start_tx (struct sk_buff *skb, struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
unsigned long flags;
u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
}
static void atmel_transmit_management_frame(struct atmel_private *priv,
- struct ieee80211_hdr *header,
+ struct ieee80211_hdr_4addr *header,
u8 *body, int body_len)
{
u16 buff;
@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
}
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc)
{
/* fast path: unfragmented packet copy directly into skbuf */
@@ -990,7 +990,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
return (crc ^ 0xffffffff) == netcrc;
}
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
{
u8 mac4[6];
@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *heade
static void rx_done_irq(struct atmel_private *priv)
{
int i;
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
for (i = 0;
atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -2650,7 +2650,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
{
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
struct auth_body auth;
header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
@@ -2688,7 +2688,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
{
u8 *ssid_el_p;
int bodysize;
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
struct ass_req_format {
u16 capability;
u16 listen_interval;
@@ -2738,7 +2738,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
}
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
{
if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2788,7 +2788,7 @@ static int retrieve_bss(struct atmel_private *priv)
}
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 capability, u16 beacon_period, u8 channel, u8 rssi,
u8 ssid_len, u8 *ssid, int is_beacon)
{
@@ -3072,7 +3072,7 @@ static void atmel_smooth_qual(struct atmel_private *priv)
}
/* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 frame_len, u8 rssi)
{
u16 subtype;
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 21c3d0d227e6..eba0d9d2b7c5 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -39,17 +39,10 @@
*/
#include <linux/config.h>
-
#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/threads.h>
-#include <linux/smp.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/net.h>
-#include <asm/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
#include "hermes.h"
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index 8c9e874c9118..ad28e3294360 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -30,9 +30,8 @@
* access to the hermes_t structure, and to the hardware
*/
-#include <linux/delay.h>
#include <linux/if_ether.h>
-#include <asm/byteorder.h>
+#include <asm/io.h>
/*
* Limits and constants
@@ -192,13 +191,13 @@
#define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II Management Protocol frame */
struct hermes_tx_descriptor {
- u16 status;
- u16 reserved1;
- u16 reserved2;
- u32 sw_support;
+ __le16 status;
+ __le16 reserved1;
+ __le16 reserved2;
+ __le32 sw_support;
u8 retry_count;
u8 tx_rate;
- u16 tx_control;
+ __le16 tx_control;
} __attribute__ ((packed));
#define HERMES_TXSTAT_RETRYERR (0x0001)
@@ -222,60 +221,60 @@ struct hermes_tx_descriptor {
#define HERMES_INQ_SEC_STAT_AGERE (0xF202)
struct hermes_tallies_frame {
- u16 TxUnicastFrames;
- u16 TxMulticastFrames;
- u16 TxFragments;
- u16 TxUnicastOctets;
- u16 TxMulticastOctets;
- u16 TxDeferredTransmissions;
- u16 TxSingleRetryFrames;
- u16 TxMultipleRetryFrames;
- u16 TxRetryLimitExceeded;
- u16 TxDiscards;
- u16 RxUnicastFrames;
- u16 RxMulticastFrames;
- u16 RxFragments;
- u16 RxUnicastOctets;
- u16 RxMulticastOctets;
- u16 RxFCSErrors;
- u16 RxDiscards_NoBuffer;
- u16 TxDiscardsWrongSA;
- u16 RxWEPUndecryptable;
- u16 RxMsgInMsgFragments;
- u16 RxMsgInBadMsgFragments;
+ __le16 TxUnicastFrames;
+ __le16 TxMulticastFrames;
+ __le16 TxFragments;
+ __le16 TxUnicastOctets;
+ __le16 TxMulticastOctets;
+ __le16 TxDeferredTransmissions;
+ __le16 TxSingleRetryFrames;
+ __le16 TxMultipleRetryFrames;
+ __le16 TxRetryLimitExceeded;
+ __le16 TxDiscards;
+ __le16 RxUnicastFrames;
+ __le16 RxMulticastFrames;
+ __le16 RxFragments;
+ __le16 RxUnicastOctets;
+ __le16 RxMulticastOctets;
+ __le16 RxFCSErrors;
+ __le16 RxDiscards_NoBuffer;
+ __le16 TxDiscardsWrongSA;
+ __le16 RxWEPUndecryptable;
+ __le16 RxMsgInMsgFragments;
+ __le16 RxMsgInBadMsgFragments;
/* Those last are probably not available in very old firmwares */
- u16 RxDiscards_WEPICVError;
- u16 RxDiscards_WEPExcluded;
+ __le16 RxDiscards_WEPICVError;
+ __le16 RxDiscards_WEPExcluded;
} __attribute__ ((packed));
/* Grabbed from wlan-ng - Thanks Mark... - Jean II
* This is the result of a scan inquiry command */
/* Structure describing info about an Access Point */
struct prism2_scan_apinfo {
- u16 channel; /* Channel where the AP sits */
- u16 noise; /* Noise level */
- u16 level; /* Signal level */
+ __le16 channel; /* Channel where the AP sits */
+ __le16 noise; /* Noise level */
+ __le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
- u16 beacon_interv; /* Beacon interval */
- u16 capabilities; /* Capabilities */
- u16 essid_len; /* ESSID length */
+ __le16 beacon_interv; /* Beacon interval */
+ __le16 capabilities; /* Capabilities */
+ __le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
u8 rates[10]; /* Bit rate supported */
- u16 proberesp_rate; /* Data rate of the response frame */
- u16 atim; /* ATIM window time, Kus (hostscan only) */
+ __le16 proberesp_rate; /* Data rate of the response frame */
+ __le16 atim; /* ATIM window time, Kus (hostscan only) */
} __attribute__ ((packed));
/* Same stuff for the Lucent/Agere card.
* Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
struct agere_scan_apinfo {
- u16 channel; /* Channel where the AP sits */
- u16 noise; /* Noise level */
- u16 level; /* Signal level */
+ __le16 channel; /* Channel where the AP sits */
+ __le16 noise; /* Noise level */
+ __le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
- u16 beacon_interv; /* Beacon interval */
- u16 capabilities; /* Capabilities */
+ __le16 beacon_interv; /* Beacon interval */
+ __le16 capabilities; /* Capabilities */
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
- u16 essid_len; /* ESSID length */
+ __le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
} __attribute__ ((packed));
@@ -283,16 +282,16 @@ struct agere_scan_apinfo {
struct symbol_scan_apinfo {
u8 channel; /* Channel where the AP sits */
u8 unknown1; /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
- u16 noise; /* Noise level */
- u16 level; /* Signal level */
+ __le16 noise; /* Noise level */
+ __le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
- u16 beacon_interv; /* Beacon interval */
- u16 capabilities; /* Capabilities */
+ __le16 beacon_interv; /* Beacon interval */
+ __le16 capabilities; /* Capabilities */
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
- u16 essid_len; /* ESSID length */
+ __le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
- u16 rates[5]; /* Bit rate supported */
- u16 basic_rates; /* Basic rates bitmask */
+ __le16 rates[5]; /* Bit rate supported */
+ __le16 basic_rates; /* Basic rates bitmask */
u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */
u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */
} __attribute__ ((packed));
@@ -312,7 +311,7 @@ union hermes_scan_info {
#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
struct hermes_linkstatus {
- u16 linkstatus; /* Link status */
+ __le16 linkstatus; /* Link status */
} __attribute__ ((packed));
struct hermes_response {
@@ -321,8 +320,8 @@ struct hermes_response {
/* "ID" structure - used for ESSID and station nickname */
struct hermes_idstring {
- u16 len;
- u16 val[16];
+ __le16 len;
+ __le16 val[16];
} __attribute__ ((packed));
struct hermes_multicast {
@@ -447,7 +446,7 @@ static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count
static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
{
- u16 rec;
+ __le16 rec;
int err;
err = HERMES_READ_RECORD(hw, bap, rid, &rec);
@@ -457,7 +456,7 @@ static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
{
- u16 rec = cpu_to_le16(word);
+ __le16 rec = cpu_to_le16(word);
return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
}
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index e7f5821b4942..6a96cd9f2685 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -716,9 +716,6 @@ static int prism2_close(struct net_device *dev)
hostap_deauth_all_stas(dev, local->ap, 1);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
- if (local->func->dev_close && local->func->dev_close(local))
- return 0;
-
if (dev == local->dev) {
local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
}
@@ -766,9 +763,6 @@ static int prism2_open(struct net_device *dev)
local->hw_downloading)
return -ENODEV;
- if (local->func->dev_open && local->func->dev_open(local))
- return 1;
-
if (!try_module_get(local->hw_module))
return -ENODEV;
local->num_dev_open++;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index b0501243b175..ffac50899454 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -6,10 +6,10 @@
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
"jiffies=%ld\n",
@@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
int hdrlen, phdrlen, head_need, tail_need;
u16 fc;
int prism_header, ret;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -70,7 +70,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
phdrlen = 0;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
@@ -215,7 +215,7 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq,
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
@@ -229,7 +229,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(local->dev->mtu +
- sizeof(struct ieee80211_hdr) +
+ sizeof(struct ieee80211_hdr_4addr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -267,7 +267,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
/* Called only as a tasklet (software IRQ) */
static int prism2_frag_cache_invalidate(local_info_t *local,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
u16 sc;
unsigned int seq;
@@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
u16 stype)
{
if (local->iw_mode == IW_MODE_MASTER) {
- hostap_update_sta_ps(local, (struct ieee80211_hdr *)
+ hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
skb->data);
}
@@ -520,7 +520,7 @@ static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
static inline int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
u16 fc, struct net_device **wds)
{
/* FIX: is this really supposed to accept WDS frames only in Master
@@ -579,13 +579,13 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
{
struct net_device *dev = local->dev;
u16 fc, ethertype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* check that the frame is unicast frame to us */
@@ -619,13 +619,13 @@ static inline int
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
if (local->tkip_countermeasures &&
@@ -658,13 +658,13 @@ static inline int
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
int keyidx, struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
atomic_inc(&crypt->refcnt);
@@ -689,7 +689,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device *wds = NULL;
@@ -716,7 +716,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
dev = local->ddev;
iface = netdev_priv(dev);
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
stats = hostap_get_stats(dev);
if (skb->len < 10)
@@ -737,7 +737,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
struct iw_quality wstats;
wstats.level = rx_stats->signal;
wstats.noise = rx_stats->noise;
- wstats.updated = 6; /* No qual value */
+ wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
+ | IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
/* Update spy records */
wireless_spy_update(dev, hdr->addr2, &wstats);
}
@@ -889,7 +890,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
(keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
@@ -941,7 +942,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
prism2_frag_cache_invalidate(local, hdr);
}
@@ -952,7 +953,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
if (local->ieee_802_1x &&
hostap_is_eapol_frame(local, skb)) {
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 6358015f6526..9d24f8a38ac5 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -1,9 +1,9 @@
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
name, skb->len, jiffies);
@@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
int need_headroom, need_tailroom = 0;
- struct ieee80211_hdr hdr;
+ struct ieee80211_hdr_4addr hdr;
u16 fc, ethertype = 0;
enum {
WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
struct hostap_skb_tx_data *meta;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
iface = netdev_priv(dev);
@@ -266,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
meta->iface = iface;
if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
@@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
int hdr_len, res;
@@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (local->tkip_countermeasures &&
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to " MACSTR "\n",
@@ -317,15 +317,15 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (skb == NULL)
return NULL;
- if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
- skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
- pskb_expand_head(skb, crypt->ops->extra_prefix_len,
- crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
+ if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
+ skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
+ pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
+ crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
kfree_skb(skb);
return NULL;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
hdr_len = hostap_80211_get_hdrlen(fc);
@@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
ap_tx_ret tx_ret;
struct hostap_skb_tx_data *meta;
int no_encrypt = 0;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -403,7 +403,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ret = hostap_handle_sta_tx(local, &tx);
skb = tx.skb;
meta = (struct hostap_skb_tx_data *) skb->cb;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
switch (tx_ret) {
case AP_TX_CONTINUE:
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 930cef8367f2..9da94ab7f05f 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -591,14 +591,14 @@ static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
u16 fc;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
if (!ap->local->hostapd || !ap->local->apdev) {
dev_kfree_skb(skb);
return;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* Pass the TX callback frame to the hostapd; use 802.11 header version
@@ -623,7 +623,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc, *pos, auth_alg, auth_transaction, status;
struct sta_info *sta = NULL;
char *txt = NULL;
@@ -633,7 +633,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
@@ -692,7 +692,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc, *pos, status;
struct sta_info *sta = NULL;
char *txt = NULL;
@@ -702,7 +702,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
(WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
@@ -757,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct sta_info *sta;
if (skb->len < 24)
goto fail;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (ok) {
spin_lock(&ap->sta_table_lock);
sta = ap_get_sta(ap, hdr->addr1);
@@ -918,7 +918,7 @@ static void prism2_send_mgmt(struct net_device *dev,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
struct sk_buff *skb;
struct hostap_skb_tx_data *meta;
@@ -944,7 +944,7 @@ static void prism2_send_mgmt(struct net_device *dev,
fc = type_subtype;
hdrlen = hostap_80211_get_hdrlen(fc);
- hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
+ hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
if (body)
memcpy(skb_put(skb, body_len), body, body_len);
@@ -1256,14 +1256,14 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
}
skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
- ap->crypt->extra_prefix_len +
- ap->crypt->extra_postfix_len);
+ ap->crypt->extra_mpdu_prefix_len +
+ ap->crypt->extra_mpdu_postfix_len);
if (skb == NULL) {
kfree(tmpbuf);
return NULL;
}
- skb_reserve(skb, ap->crypt->extra_prefix_len);
+ skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
WLAN_AUTH_CHALLENGE_LEN);
if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
@@ -1272,7 +1272,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
return NULL;
}
- memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
+ memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
WLAN_AUTH_CHALLENGE_LEN);
dev_kfree_skb(skb);
@@ -1285,7 +1285,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
size_t hdrlen;
struct ap_data *ap = local->ap;
char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
@@ -1498,7 +1498,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int reassoc)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char body[12], *p, *lpos;
int len, left;
u16 *pos;
@@ -1705,7 +1705,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
int len;
u16 reason_code, *pos;
@@ -1746,7 +1746,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len;
u16 reason_code, *pos;
@@ -1784,7 +1784,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_data_nullfunc(local_info_t *local,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
struct net_device *dev = local->dev;
@@ -1801,7 +1801,7 @@ static void ap_handle_data_nullfunc(local_info_t *local,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_dropped_data(local_info_t *local,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
struct net_device *dev = local->dev;
struct sta_info *sta;
@@ -1860,7 +1860,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
/* Called only as a scheduled task for pending AP frames. */
static void handle_pspoll(local_info_t *local,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
@@ -1979,7 +1979,7 @@ static void handle_wds_oper_queue(void *data)
static void handle_beacon(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len, left;
u16 *pos, beacon_int, capability;
@@ -2137,11 +2137,11 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
struct net_device *dev = local->dev;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
u16 fc, type, stype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
/* FIX: should give skb->len to handler functions and check that the
* buffer is long enough */
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
type = WLAN_FC_GET_TYPE(fc);
stype = WLAN_FC_GET_STYPE(fc);
@@ -2258,7 +2258,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_interface *iface;
local_info_t *local;
u16 fc;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -2268,7 +2268,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
local->stats.rx_packets++;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
@@ -2289,7 +2289,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
{
struct sk_buff *skb;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct hostap_80211_rx_status rx_stats;
if (skb_queue_empty(&sta->tx_buf))
@@ -2302,7 +2302,7 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
return;
}
- hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
+ hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
/* Generate a fake pspoll frame to start packet delivery */
hdr->frame_ctl = __constant_cpu_to_le16(
@@ -2349,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
qual[count].updated = sta->last_rx_updated;
- sta->last_rx_updated = 0;
+ sta->last_rx_updated = IW_QUAL_DBM;
count++;
if (count >= buf_size)
@@ -2467,7 +2467,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
- sta->last_rx_updated = 0;
+ sta->last_rx_updated = IW_QUAL_DBM;
/* To be continued, we should make good use of IWEVCUSTOM */
}
@@ -2685,7 +2685,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
struct sta_info *sta = NULL;
struct sk_buff *skb = tx->skb;
int set_tim, ret;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct hostap_skb_tx_data *meta;
meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2694,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
meta->iface->type == HOSTAP_INTERFACE_STA)
goto out;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (hdr->addr1[0] & 0x01) {
/* broadcast/multicast frame - no AP related processing */
@@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr)
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
{
struct sta_info *sta;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct hostap_skb_tx_data *meta;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
meta = (struct hostap_skb_tx_data *) skb->cb;
spin_lock(&local->ap->sta_table_lock);
@@ -2892,7 +2892,7 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
/* Called only as a tasklet (software IRQ). Called for each RX frame to update
* STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
{
struct sta_info *sta;
u16 fc;
@@ -2925,12 +2925,12 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
int ret;
struct sta_info *sta;
u16 fc, type, stype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
if (local->ap == NULL)
return AP_RX_CONTINUE;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
type = WLAN_FC_GET_TYPE(fc);
@@ -3058,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
/* Called only as a tasklet (software IRQ) */
int hostap_handle_sta_crypto(local_info_t *local,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
struct ieee80211_crypt_data **crypt,
void **sta_ptr)
{
@@ -3160,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
/* Called only as a tasklet (software IRQ) */
int hostap_update_rx_stats(struct ap_data *ap,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct sta_info *sta;
@@ -3174,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_data *ap,
sta->last_rx_silence = rx_stats->noise;
sta->last_rx_signal = rx_stats->signal;
sta->last_rx_rate = rx_stats->rate;
- sta->last_rx_updated = 7;
+ sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
if (rx_stats->rate == 10)
sta->rx_count[0]++;
else if (rx_stats->rate == 20)
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index 816a52bcea8f..6d00df69c2e3 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -233,7 +233,7 @@ struct hostap_tx_data {
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
typedef enum {
AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
@@ -241,13 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats,
int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
struct ieee80211_crypt_data **crypt,
void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index faa83badf0a1..2643976a6677 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -492,42 +492,10 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
}
-static int prism2_pccard_dev_open(local_info_t *local)
-{
- struct hostap_cs_priv *hw_priv = local->hw_priv;
- hw_priv->link->open++;
- return 0;
-}
-
-
-static int prism2_pccard_dev_close(local_info_t *local)
-{
- struct hostap_cs_priv *hw_priv;
-
- if (local == NULL || local->hw_priv == NULL)
- return 1;
- hw_priv = local->hw_priv;
- if (hw_priv->link == NULL)
- return 1;
-
- if (!hw_priv->link->open) {
- printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
- "link not open?!\n", local->dev->name);
- return 1;
- }
-
- hw_priv->link->open--;
-
- return 0;
-}
-
-
static struct prism2_helper_functions prism2_pccard_funcs =
{
.card_present = prism2_pccard_card_present,
.cor_sreset = prism2_pccard_cor_sreset,
- .dev_open = prism2_pccard_dev_open,
- .dev_close = prism2_pccard_dev_close,
.genesis_reset = prism2_pccard_genesis_reset,
.hw_type = HOSTAP_HW_PCCARD,
};
@@ -597,13 +565,14 @@ static void prism2_detach(dev_link_t *link)
*linkp = link->next;
/* release net devices */
if (link->priv) {
+ struct hostap_cs_priv *hw_priv;
struct net_device *dev;
struct hostap_interface *iface;
dev = link->priv;
iface = netdev_priv(dev);
- kfree(iface->local->hw_priv);
- iface->local->hw_priv = NULL;
+ hw_priv = iface->local->hw_priv;
prism2_free_local_data(dev);
+ kfree(hw_priv);
}
kfree(link);
}
@@ -883,6 +852,13 @@ static int prism2_event(event_t event, int priority,
{
dev_link_t *link = args->client_data;
struct net_device *dev = (struct net_device *) link->priv;
+ int dev_open = 0;
+
+ if (link->state & DEV_CONFIG) {
+ struct hostap_interface *iface = netdev_priv(dev);
+ if (iface && iface->local)
+ dev_open = iface->local->num_dev_open > 0;
+ }
switch (event) {
case CS_EVENT_CARD_INSERTION:
@@ -911,7 +887,7 @@ static int prism2_event(event_t event, int priority,
case CS_EVENT_RESET_PHYSICAL:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
if (link->state & DEV_CONFIG) {
- if (link->open) {
+ if (dev_open) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
@@ -931,8 +907,8 @@ static int prism2_event(event_t event, int priority,
pcmcia_request_configuration(link->handle,
&link->conf);
prism2_hw_shutdown(dev, 1);
- prism2_hw_config(dev, link->open ? 0 : 1);
- if (link->open) {
+ prism2_hw_config(dev, dev_open ? 0 : 1);
+ if (dev_open) {
netif_device_attach(dev);
netif_start_queue(dev);
}
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index e533a663deda..59fc15572395 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3322,6 +3322,18 @@ static void prism2_free_local_data(struct net_device *dev)
iface = netdev_priv(dev);
local = iface->local;
+ /* Unregister all netdevs before freeing local data. */
+ list_for_each_safe(ptr, n, &local->hostap_interfaces) {
+ iface = list_entry(ptr, struct hostap_interface, list);
+ if (iface->type == HOSTAP_INTERFACE_MASTER) {
+ /* special handling for this interface below */
+ continue;
+ }
+ hostap_remove_interface(iface->dev, 0, 1);
+ }
+
+ unregister_netdev(local->dev);
+
flush_scheduled_work();
if (timer_pending(&local->crypt_deinit_timer))
@@ -3382,15 +3394,6 @@ static void prism2_free_local_data(struct net_device *dev)
prism2_download_free_data(local->dl_sec);
#endif /* PRISM2_DOWNLOAD_SUPPORT */
- list_for_each_safe(ptr, n, &local->hostap_interfaces) {
- iface = list_entry(ptr, struct hostap_interface, list);
- if (iface->type == HOSTAP_INTERFACE_MASTER) {
- /* special handling for this interface below */
- continue;
- }
- hostap_remove_interface(iface->dev, 0, 1);
- }
-
prism2_clear_set_tim_queue(local);
list_for_each_safe(ptr, n, &local->bss_list) {
@@ -3403,7 +3406,6 @@ static void prism2_free_local_data(struct net_device *dev)
kfree(local->last_scan_results);
kfree(local->generic_elem);
- unregister_netdev(local->dev);
free_netdev(local->dev);
}
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index e720369a3515..53f5246c40aa 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -50,7 +50,8 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
#endif /* in_atomic */
if (update && prism2_update_comms_qual(dev) == 0)
- wstats->qual.updated = 7;
+ wstats->qual.updated = IW_QUAL_ALL_UPDATED |
+ IW_QUAL_DBM;
wstats->qual.qual = local->comms_qual;
wstats->qual.level = local->avg_signal;
@@ -59,7 +60,7 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
wstats->qual.qual = 0;
wstats->qual.level = 0;
wstats->qual.noise = 0;
- wstats->qual.updated = 0;
+ wstats->qual.updated = IW_QUAL_ALL_INVALID;
}
return wstats;
@@ -1827,13 +1828,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
- /* FIX:
- * I do not know how this is possible, but iwe_stream_add_event
- * seems to re-order memcpy execution so that len is set only
- * after copying.. Pre-setting len here "fixes" this, but real
- * problems should be solved (after which these iwe.len
- * settings could be removed from this function). */
- iwe.len = IW_EV_ADDR_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
@@ -1843,7 +1837,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
@@ -1859,7 +1852,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- iwe.len = IW_EV_UINT_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_UINT_LEN);
}
@@ -1877,7 +1869,6 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
iwe.u.freq.e = 1;
- iwe.len = IW_EV_FREQ_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@@ -1894,7 +1885,10 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.qual.noise =
HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
}
- iwe.len = IW_EV_QUAL_LEN;
+ iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED
+ | IW_QUAL_QUAL_INVALID
+ | IW_QUAL_DBM;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_QUAL_LEN);
}
@@ -1906,7 +1900,6 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
@@ -1930,7 +1923,7 @@ static char * __prism2_translate_scan(local_info_t *local,
}
/* TODO: add BeaconInt,resp_rate,atim into BSS table */
- buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
+ buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
if (buf && scan) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 025f8cdb5566..da0c80fb941c 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -59,11 +59,13 @@ static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
@@ -74,12 +76,14 @@ static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
u8 v;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
v = readb(hw_priv->mem_start + a);
@@ -91,11 +95,13 @@ static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
@@ -106,12 +112,14 @@ static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
u16 v;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
v = readw(hw_priv->mem_start + a);
@@ -277,8 +285,6 @@ static struct prism2_helper_functions prism2_pci_funcs =
{
.card_present = NULL,
.cor_sreset = prism2_pci_cor_sreset,
- .dev_open = NULL,
- .dev_close = NULL,
.genesis_reset = prism2_pci_genesis_reset,
.hw_type = HOSTAP_HW_PCI,
};
@@ -352,8 +358,6 @@ static int prism2_pci_probe(struct pci_dev *pdev,
return hostap_hw_ready(dev);
fail:
- kfree(hw_priv);
-
if (irq_registered && dev)
free_irq(dev->irq, dev);
@@ -364,10 +368,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
err_out_disable:
pci_disable_device(pdev);
- kfree(hw_priv);
- if (local)
- local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
return -ENODEV;
}
@@ -392,9 +394,8 @@ static void prism2_pci_remove(struct pci_dev *pdev)
free_irq(dev->irq, dev);
mem_start = hw_priv->mem_start;
- kfree(hw_priv);
- iface->local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
iounmap(mem_start);
@@ -441,7 +442,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
static struct pci_driver prism2_pci_drv_id = {
- .name = "prism2_pci",
+ .name = "hostap_pci",
.id_table = prism2_pci_id_table,
.probe = prism2_pci_probe,
.remove = prism2_pci_remove,
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 474ef83d813e..78d67b408b2f 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -328,8 +328,6 @@ static struct prism2_helper_functions prism2_plx_funcs =
{
.card_present = NULL,
.cor_sreset = prism2_plx_cor_sreset,
- .dev_open = NULL,
- .dev_close = NULL,
.genesis_reset = prism2_plx_genesis_reset,
.hw_type = HOSTAP_HW_PLX,
};
@@ -570,10 +568,8 @@ static int prism2_plx_probe(struct pci_dev *pdev,
return hostap_hw_ready(dev);
fail:
- kfree(hw_priv);
- if (local)
- local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
if (irq_registered && dev)
free_irq(dev->irq, dev);
@@ -606,9 +602,8 @@ static void prism2_plx_remove(struct pci_dev *pdev)
if (dev->irq)
free_irq(dev->irq, dev);
- kfree(iface->local->hw_priv);
- iface->local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
pci_disable_device(pdev);
}
@@ -616,7 +611,7 @@ static void prism2_plx_remove(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
static struct pci_driver prism2_plx_drv_id = {
- .name = "prism2_plx",
+ .name = "hostap_plx",
.id_table = prism2_plx_id_table,
.probe = prism2_plx_probe,
.remove = prism2_plx_remove,
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index cc061e1560d3..cfd801559492 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -552,8 +552,6 @@ struct prism2_helper_functions {
* (hostap_{cs,plx,pci}.c */
int (*card_present)(local_info_t *local);
void (*cor_sreset)(local_info_t *local);
- int (*dev_open)(local_info_t *local);
- int (*dev_close)(local_info_t *local);
void (*genesis_reset)(local_info_t *local, int hcr);
/* the following functions are from hostap_hw.c, but they may have some
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2414e6493aa5..ad7f8cd76db9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -800,8 +800,7 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
* doesn't seem to have as many firmware restart cycles...
*
* As a test, we're sticking in a 1/100s delay here */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ / 100);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(10));
return 0;
@@ -1256,8 +1255,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
i = 5000;
do {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(40 * HZ / 1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(40));
/* Todo... wait for sync command ... */
read_register(priv->net_dev, IPW_REG_INTA, &inta);
@@ -1411,8 +1409,7 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
(val2 & IPW2100_COMMAND_PHY_OFF))
return 0;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
+ schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
}
return -EIO;
@@ -1466,7 +1463,7 @@ fail_up:
static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
{
-#define HW_POWER_DOWN_DELAY (HZ / 10)
+#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
struct host_command cmd = {
.host_command = HOST_PRE_POWER_DOWN,
@@ -1520,10 +1517,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
printk(KERN_WARNING DRV_NAME ": "
"%s: Power down command failed: Error %d\n",
priv->net_dev->name, err);
- else {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HW_POWER_DOWN_DELAY);
- }
+ else
+ schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
}
priv->status &= ~STATUS_ENABLED;
@@ -2953,7 +2948,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
int next = txq->next;
int i = 0;
struct ipw2100_data_header *ipw_hdr;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
while (!list_empty(&priv->tx_pend_list)) {
/* if there isn't enough space in TBD queue, then
@@ -2989,7 +2984,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
packet->index = txq->next;
ipw_hdr = packet->info.d_struct.data;
- hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
+ hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
fragments[0]->data;
if (priv->ieee->iw_mode == IW_MODE_INFRA) {
@@ -3274,7 +3269,8 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
return IRQ_NONE;
}
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
+static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
+ int pri)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct list_head *element;
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 2a3cdbd50168..c9e99ce15d66 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -808,7 +808,7 @@ struct ipw2100_priv {
struct ipw2100_rx {
union {
unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
u32 status;
struct ipw2100_notification notification;
struct ipw2100_cmd_header command;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b7f275c00de3..de4e6c23e4b8 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4904,7 +4904,7 @@ static void ipw_rx(struct ipw_priv *priv)
{
struct ipw_rx_mem_buffer *rxb;
struct ipw_rx_packet *pkt;
- struct ieee80211_hdr *header;
+ struct ieee80211_hdr_4addr *header;
u32 r, w, i;
u8 network_packet;
@@ -4967,8 +4967,9 @@ static void ipw_rx(struct ipw_priv *priv)
#endif
header =
- (struct ieee80211_hdr *)(rxb->skb->data +
- IPW_RX_FRAME_SIZE);
+ (struct ieee80211_hdr_4addr *)(rxb->skb->
+ data +
+ IPW_RX_FRAME_SIZE);
/* TODO: Check Ad-Hoc dest/source and make sure
* that we are actually parsing these packets
* correctly -- we should probably use the
@@ -5317,8 +5318,6 @@ static int ipw_wx_set_freq(struct net_device *dev,
IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
return ipw_set_channel(priv, (u8) fwrq->m);
-
- return 0;
}
static int ipw_wx_get_freq(struct net_device *dev,
@@ -6010,12 +6009,12 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
}
if (priv->adapter == IPW_2915ABG) {
- priv->ieee->abg_ture = 1;
+ priv->ieee->abg_true = 1;
if (mode & IEEE_A) {
band |= IEEE80211_52GHZ_BAND;
modulation |= IEEE80211_OFDM_MODULATION;
} else
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
} else {
if (mode & IEEE_A) {
IPW_WARNING("Attempt to set 2200BG into "
@@ -6023,20 +6022,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
return -EINVAL;
}
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
}
if (mode & IEEE_B) {
band |= IEEE80211_24GHZ_BAND;
modulation |= IEEE80211_CCK_MODULATION;
} else
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
if (mode & IEEE_G) {
band |= IEEE80211_24GHZ_BAND;
modulation |= IEEE80211_OFDM_MODULATION;
} else
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
priv->ieee->mode = mode;
priv->ieee->freq_band = band;
@@ -6325,7 +6324,7 @@ we need to heavily modify the ieee80211_skb_to_txb.
static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
+ struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
txb->fragments[0]->data;
int i = 0;
struct tfd_frame *tfd;
@@ -6448,7 +6447,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
}
static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
- struct net_device *dev)
+ struct net_device *dev, int pri)
{
struct ipw_priv *priv = ieee80211_priv(dev);
unsigned long flags;
@@ -7108,7 +7107,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_INFO DRV_NAME
": Detected Intel PRO/Wireless 2915ABG Network "
"Connection\n");
- priv->ieee->abg_ture = 1;
+ priv->ieee->abg_true = 1;
band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
modulation = IEEE80211_OFDM_MODULATION |
IEEE80211_CCK_MODULATION;
@@ -7124,7 +7123,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
": Detected Intel PRO/Wireless 2200BG Network "
"Connection\n");
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
band = IEEE80211_24GHZ_BAND;
modulation = IEEE80211_OFDM_MODULATION |
IEEE80211_CCK_MODULATION;
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 5b00882133f9..e9cf32bf3e31 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1654,12 +1654,12 @@ static const long ipw_frequencies[] = {
#define IPW_MAX_CONFIG_RETRIES 10
-static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
+static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
{
u32 retval;
u16 fc;
- retval = sizeof(struct ieee80211_hdr);
+ retval = sizeof(struct ieee80211_hdr_3addr);
fc = le16_to_cpu(hdr->frame_ctl);
/*
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index ca6c03c89926..92793b958e32 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -57,9 +57,7 @@
#include <linux/bitops.h>
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h>
-#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
-#endif /* WIRELESS_EXT > 12 */
#endif
#include <pcmcia/cs_types.h>
@@ -225,10 +223,7 @@ static void update_stats(struct net_device *dev);
static struct net_device_stats *netwave_get_stats(struct net_device *dev);
/* Wireless extensions */
-#ifdef WIRELESS_EXT
static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
-#endif
-static int netwave_ioctl(struct net_device *, struct ifreq *, int);
static void set_multicast_list(struct net_device *dev);
@@ -260,26 +255,7 @@ static dev_link_t *dev_list;
because they generally can't be allocated dynamically.
*/
-#if WIRELESS_EXT <= 12
-/* Wireless extensions backward compatibility */
-
-/* Part of iw_handler prototype we need */
-struct iw_request_info
-{
- __u16 cmd; /* Wireless Extension command */
- __u16 flags; /* More to come ;-) */
-};
-
-/* Wireless Extension Backward compatibility - Jean II
- * If the new wireless device private ioctl range is not defined,
- * default to standard device private ioctl range */
-#ifndef SIOCIWFIRSTPRIV
-#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
-#endif /* SIOCIWFIRSTPRIV */
-
-#else /* WIRELESS_EXT <= 12 */
static const struct iw_handler_def netwave_handler_def;
-#endif /* WIRELESS_EXT <= 12 */
#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
@@ -319,9 +295,7 @@ typedef struct netwave_private {
struct timer_list watchdog; /* To avoid blocking state */
struct site_survey nss;
struct net_device_stats stats;
-#ifdef WIRELESS_EXT
struct iw_statistics iw_stats; /* Wireless stats */
-#endif
} netwave_private;
#ifdef NETWAVE_STATS
@@ -353,7 +327,6 @@ static inline void wait_WOC(unsigned int iobase)
while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
}
-#ifdef WIRELESS_EXT
static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
kio_addr_t iobase) {
u_short resultBuffer;
@@ -376,9 +349,7 @@ static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
sizeof(struct site_survey));
}
}
-#endif
-#ifdef WIRELESS_EXT
/*
* Function netwave_get_wireless_stats (dev)
*
@@ -411,7 +382,6 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
return &priv->iw_stats;
}
-#endif
/*
* Function netwave_attach (void)
@@ -471,13 +441,7 @@ static dev_link_t *netwave_attach(void)
dev->get_stats = &netwave_get_stats;
dev->set_multicast_list = &set_multicast_list;
/* wireless extensions */
-#if WIRELESS_EXT <= 16
- dev->get_wireless_stats = &netwave_get_wireless_stats;
-#endif /* WIRELESS_EXT <= 16 */
-#if WIRELESS_EXT > 12
dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
-#endif /* WIRELESS_EXT > 12 */
- dev->do_ioctl = &netwave_ioctl;
dev->tx_timeout = &netwave_watchdog;
dev->watchdog_timeo = TX_TIMEOUT;
@@ -576,13 +540,8 @@ static int netwave_set_nwid(struct net_device *dev,
/* Disable interrupts & save flags */
spin_lock_irqsave(&priv->spinlock, flags);
-#if WIRELESS_EXT > 8
if(!wrqu->nwid.disabled) {
domain = wrqu->nwid.value;
-#else /* WIRELESS_EXT > 8 */
- if(wrqu->nwid.on) {
- domain = wrqu->nwid.nwid;
-#endif /* WIRELESS_EXT > 8 */
printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
(domain >> 8) & 0x01, domain & 0xff);
wait_WOC(iobase);
@@ -606,15 +565,9 @@ static int netwave_get_nwid(struct net_device *dev,
union iwreq_data *wrqu,
char *extra)
{
-#if WIRELESS_EXT > 8
wrqu->nwid.value = domain;
wrqu->nwid.disabled = 0;
wrqu->nwid.fixed = 1;
-#else /* WIRELESS_EXT > 8 */
- wrqu->nwid.nwid = domain;
- wrqu->nwid.on = 1;
-#endif /* WIRELESS_EXT > 8 */
-
return 0;
}
@@ -657,17 +610,11 @@ static int netwave_get_scramble(struct net_device *dev,
{
key[1] = scramble_key & 0xff;
key[0] = (scramble_key>>8) & 0xff;
-#if WIRELESS_EXT > 8
wrqu->encoding.flags = IW_ENCODE_ENABLED;
wrqu->encoding.length = 2;
-#else /* WIRELESS_EXT > 8 */
- wrqu->encoding.method = 1;
-#endif /* WIRELESS_EXT > 8 */
-
return 0;
}
-#if WIRELESS_EXT > 8
/*
* Wireless Handler : get mode
*/
@@ -683,7 +630,6 @@ static int netwave_get_mode(struct net_device *dev,
return 0;
}
-#endif /* WIRELESS_EXT > 8 */
/*
* Wireless Handler : get range info
@@ -702,11 +648,9 @@ static int netwave_get_range(struct net_device *dev,
/* Set all the info we don't care or don't know about to zero */
memset(range, 0, sizeof(struct iw_range));
-#if WIRELESS_EXT > 10
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 9; /* Nothing for us in v10 and v11 */
-#endif /* WIRELESS_EXT > 10 */
/* Set information in the range struct */
range->throughput = 450 * 1000; /* don't argue on this ! */
@@ -720,16 +664,12 @@ static int netwave_get_range(struct net_device *dev,
range->max_qual.level = 255;
range->max_qual.noise = 0;
-#if WIRELESS_EXT > 7
range->num_bitrates = 1;
range->bitrate[0] = 1000000; /* 1 Mb/s */
-#endif /* WIRELESS_EXT > 7 */
-#if WIRELESS_EXT > 8
range->encoding_size[0] = 2; /* 16 bits scrambling */
range->num_encoding_sizes = 1;
range->max_encoding_tokens = 1; /* Only one key possible */
-#endif /* WIRELESS_EXT > 8 */
return ret;
}
@@ -775,8 +715,6 @@ static const struct iw_priv_args netwave_private_args[] = {
"getsitesurvey" },
};
-#if WIRELESS_EXT > 12
-
static const iw_handler netwave_handler[] =
{
NULL, /* SIOCSIWNAME */
@@ -839,131 +777,8 @@ static const struct iw_handler_def netwave_handler_def =
.standard = (iw_handler *) netwave_handler,
.private = (iw_handler *) netwave_private_handler,
.private_args = (struct iw_priv_args *) netwave_private_args,
-#if WIRELESS_EXT > 16
.get_wireless_stats = netwave_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
};
-#endif /* WIRELESS_EXT > 12 */
-
-/*
- * Function netwave_ioctl (dev, rq, cmd)
- *
- * Perform ioctl : config & info stuff
- * This is the stuff that are treated the wireless extensions (iwconfig)
- *
- */
-static int netwave_ioctl(struct net_device *dev, /* ioctl device */
- struct ifreq *rq, /* Data passed */
- int cmd) /* Ioctl number */
-{
- int ret = 0;
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
- struct iwreq *wrq = (struct iwreq *) rq;
-#endif
-#endif
-
- DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
-
- /* Look what is the request */
- switch(cmd) {
- /* --------------- WIRELESS EXTENSIONS --------------- */
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
- case SIOCGIWNAME:
- netwave_get_name(dev, NULL, &(wrq->u), NULL);
- break;
- case SIOCSIWNWID:
- ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
- break;
- case SIOCGIWNWID:
- ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
- break;
-#if WIRELESS_EXT > 8 /* Note : The API did change... */
- case SIOCGIWENCODE:
- /* Get scramble key */
- if(wrq->u.encoding.pointer != (caddr_t) 0)
- {
- char key[2];
- ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
- if(copy_to_user(wrq->u.encoding.pointer, key, 2))
- ret = -EFAULT;
- }
- break;
- case SIOCSIWENCODE:
- /* Set scramble key */
- if(wrq->u.encoding.pointer != (caddr_t) 0)
- {
- char key[2];
- if(copy_from_user(key, wrq->u.encoding.pointer, 2))
- {
- ret = -EFAULT;
- break;
- }
- ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
- }
- break;
- case SIOCGIWMODE:
- /* Mode of operation */
- ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
- break;
-#else /* WIRELESS_EXT > 8 */
- case SIOCGIWENCODE:
- /* Get scramble key */
- ret = netwave_get_scramble(dev, NULL, &(wrq->u),
- (char *) &wrq->u.encoding.code);
- break;
- case SIOCSIWENCODE:
- /* Set scramble key */
- ret = netwave_set_scramble(dev, NULL, &(wrq->u),
- (char *) &wrq->u.encoding.code);
- break;
-#endif /* WIRELESS_EXT > 8 */
- case SIOCGIWRANGE:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0) {
- struct iw_range range;
- ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
- if (copy_to_user(wrq->u.data.pointer, &range,
- sizeof(struct iw_range)))
- ret = -EFAULT;
- }
- break;
- case SIOCGIWPRIV:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0) {
- /* Set the number of ioctl available */
- wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
-
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer,
- (u_char *) netwave_private_args,
- sizeof(netwave_private_args)))
- ret = -EFAULT;
- }
- break;
- case SIOCGIPSNAP:
- if(wrq->u.data.pointer != (caddr_t) 0) {
- char buffer[sizeof( struct site_survey)];
- ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer,
- buffer,
- sizeof( struct site_survey)))
- {
- printk(KERN_DEBUG "Bad buffer!\n");
- break;
- }
- }
- break;
-#endif /* WIRELESS_EXT <= 12 */
-#endif /* WIRELESS_EXT */
- default:
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
/*
* Function netwave_pcmcia_config (link)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8de49fe57233..d3d4ec9e242e 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -77,30 +77,16 @@
#define DRIVER_NAME "orinoco"
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
#include <linux/netdevice.h>
-#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
-#include <net/ieee80211.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "hermes.h"
#include "hermes_rid.h"
#include "orinoco.h"
@@ -137,7 +123,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
/* We do this this way to avoid ifdefs in the actual code */
#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv) (priv->spy_number)
+#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
#else
#define SPY_NUMBER(priv) 0
#endif /* WIRELESS_SPY */
@@ -216,31 +202,32 @@ static struct {
/********************************************************************/
/* Used in Event handling.
- * We avoid nested structres as they break on ARM -- Moustafa */
+ * We avoid nested structures as they break on ARM -- Moustafa */
struct hermes_tx_descriptor_802_11 {
/* hermes_tx_descriptor */
- u16 status;
- u16 reserved1;
- u16 reserved2;
- u32 sw_support;
+ __le16 status;
+ __le16 reserved1;
+ __le16 reserved2;
+ __le32 sw_support;
u8 retry_count;
u8 tx_rate;
- u16 tx_control;
+ __le16 tx_control;
- /* ieee802_11_hdr */
- u16 frame_ctl;
- u16 duration_id;
+ /* ieee80211_hdr */
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
- u16 seq_ctl;
+ __le16 seq_ctl;
u8 addr4[ETH_ALEN];
- u16 data_len;
+
+ __le16 data_len;
/* ethhdr */
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
+ u8 h_dest[ETH_ALEN]; /* destination eth addr */
+ u8 h_source[ETH_ALEN]; /* source ether addr */
+ __be16 h_proto; /* packet type ID field */
/* p8022_hdr */
u8 dsap;
@@ -248,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
u8 ctrl;
u8 oui[3];
- u16 ethertype;
+ __be16 ethertype;
} __attribute__ ((packed));
/* Rx frame header except compatibility 802.3 header */
struct hermes_rx_descriptor {
/* Control */
- u16 status;
- u32 time;
+ __le16 status;
+ __le32 time;
u8 silence;
u8 signal;
u8 rate;
u8 rxflow;
- u32 reserved;
+ __le32 reserved;
/* 802.11 header */
- u16 frame_ctl;
- u16 duration_id;
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
- u16 seq_ctl;
+ __le16 seq_ctl;
u8 addr4[ETH_ALEN];
/* Data length */
- u16 data_len;
+ __le16 data_len;
} __attribute__ ((packed));
/********************************************************************/
@@ -396,14 +383,14 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
/* If a spy address is defined, we report stats of the
* first spy address - Jean II */
if (SPY_NUMBER(priv)) {
- wstats->qual.qual = priv->spy_stat[0].qual;
- wstats->qual.level = priv->spy_stat[0].level;
- wstats->qual.noise = priv->spy_stat[0].noise;
- wstats->qual.updated = priv->spy_stat[0].updated;
+ wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+ wstats->qual.level = priv->spy_data.spy_stat[0].level;
+ wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+ wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
}
} else {
struct {
- u16 qual, signal, noise;
+ __le16 qual, signal, noise;
} __attribute__ ((packed)) cq;
err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -503,9 +490,12 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
- /* Length of the packet body */
- /* FIXME: what if the skb is smaller than this? */
- len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
+ /* Check packet length, pad short packets, round up odd length */
+ len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
+ skb = skb_padto(skb, len);
+ if (skb == NULL)
+ goto fail;
+ len -= ETH_HLEN;
eh = (struct ethhdr *)skb->data;
@@ -557,8 +547,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
p = skb->data;
}
- /* Round up for odd length packets */
- err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2),
+ err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
txfid, data_off);
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
@@ -574,8 +563,9 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
txfid, NULL);
if (err) {
netif_start_queue(dev);
- printk(KERN_ERR "%s: Error %d transmitting packet\n",
- dev->name, err);
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d transmitting packet\n",
+ dev->name, err);
stats->tx_errors++;
goto fail;
}
@@ -629,16 +619,17 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
struct orinoco_private *priv = netdev_priv(dev);
struct net_device_stats *stats = &priv->stats;
u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+ u16 status;
struct hermes_tx_descriptor_802_11 hdr;
int err = 0;
if (fid == DUMMY_FID)
return; /* Nothing's really happened */
- /* Read the frame header */
+ /* Read part of the frame header - we need status and addr1 */
err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
- sizeof(struct hermes_tx_descriptor) +
- sizeof(struct ieee80211_hdr),
+ offsetof(struct hermes_tx_descriptor_802_11,
+ addr2),
fid, 0);
hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@@ -658,8 +649,8 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
* exceeded, because that's the only status that really mean
* that this particular node went away.
* Other errors means that *we* screwed up. - Jean II */
- hdr.status = le16_to_cpu(hdr.status);
- if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+ status = le16_to_cpu(hdr.status);
+ if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
union iwreq_data wrqu;
/* Copy 802.11 dest address.
@@ -718,18 +709,13 @@ static inline int is_ethersnap(void *_hdr)
static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
int level, int noise)
{
- struct orinoco_private *priv = netdev_priv(dev);
- int i;
-
- /* Gather wireless spy statistics: for each packet, compare the
- * source address with out list, and if match, get the stats... */
- for (i = 0; i < priv->spy_number; i++)
- if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
- priv->spy_stat[i].level = level - 0x95;
- priv->spy_stat[i].noise = noise - 0x95;
- priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
- priv->spy_stat[i].updated = 7;
- }
+ struct iw_quality wstats;
+ wstats.level = level - 0x95;
+ wstats.noise = noise - 0x95;
+ wstats.qual = (level > noise) ? (level - noise) : 0;
+ wstats.updated = 7;
+ /* Update spy records */
+ wireless_spy_update(dev, mac, &wstats);
}
static void orinoco_stat_gather(struct net_device *dev,
@@ -1050,7 +1036,7 @@ static void orinoco_join_ap(struct net_device *dev)
unsigned long flags;
struct join_req {
u8 bssid[ETH_ALEN];
- u16 channel;
+ __le16 channel;
} __attribute__ ((packed)) req;
const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
struct prism2_scan_apinfo *atom = NULL;
@@ -1065,7 +1051,7 @@ static void orinoco_join_ap(struct net_device *dev)
return;
if (orinoco_lock(priv, &flags) != 0)
- goto out;
+ goto fail_lock;
/* Sanity checks in case user changed something in the meantime */
if (! priv->bssid_fixed)
@@ -1110,8 +1096,10 @@ static void orinoco_join_ap(struct net_device *dev)
printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
out:
- kfree(buf);
orinoco_unlock(priv, &flags);
+
+ fail_lock:
+ kfree(buf);
}
/* Send new BSSID to userspace */
@@ -1129,12 +1117,14 @@ static void orinoco_send_wevents(struct net_device *dev)
err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
if (err != 0)
- return;
+ goto out;
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
/* Send event to user space */
wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+
+ out:
orinoco_unlock(priv, &flags);
}
@@ -1143,8 +1133,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
struct orinoco_private *priv = netdev_priv(dev);
u16 infofid;
struct {
- u16 len;
- u16 type;
+ __le16 len;
+ __le16 type;
} __attribute__ ((packed)) info;
int len, type;
int err;
@@ -2458,8 +2448,11 @@ struct net_device *alloc_orinocodev(int sizeof_card,
dev->watchdog_timeo = HZ; /* 1 second timeout */
dev->get_stats = orinoco_get_stats;
dev->ethtool_ops = &orinoco_ethtool_ops;
- dev->get_wireless_stats = orinoco_get_wireless_stats;
dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
+#ifdef WIRELESS_SPY
+ priv->wireless_data.spy_data = &priv->spy_data;
+ dev->wireless_data = &priv->wireless_data;
+#endif
dev->change_mtu = orinoco_change_mtu;
dev->set_multicast_list = orinoco_set_multicast_list;
/* we use the default eth_mac_addr for setting the MAC addr */
@@ -2831,7 +2824,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
}
}
- if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
+ if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
/* Quality stats meaningless in ad-hoc mode */
} else {
range->max_qual.qual = 0x8b - 0x2f;
@@ -2878,6 +2871,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
range->min_r_time = 0;
range->max_r_time = 65535 * 1000; /* ??? */
+ /* Event capability (kernel) */
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ /* Event capability (driver) */
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
TRACE_EXIT(dev->name);
return 0;
@@ -3837,92 +3838,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
return err;
}
-/* Spy is used for link quality/strength measurements in Ad-Hoc mode
- * Jean II */
-static int orinoco_ioctl_setspy(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct sockaddr *address = (struct sockaddr *) extra;
- int number = srq->length;
- int i;
- unsigned long flags;
-
- /* Make sure nobody mess with the structure while we do */
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* orinoco_lock() doesn't disable interrupts, so make sure the
- * interrupt rx path don't get confused while we copy */
- priv->spy_number = 0;
-
- if (number > 0) {
- /* Extract the addresses */
- for (i = 0; i < number; i++)
- memcpy(priv->spy_address[i], address[i].sa_data,
- ETH_ALEN);
- /* Reset stats */
- memset(priv->spy_stat, 0,
- sizeof(struct iw_quality) * IW_MAX_SPY);
- /* Set number of addresses */
- priv->spy_number = number;
- }
-
- /* Now, let the others play */
- orinoco_unlock(priv, &flags);
-
- /* Do NOT call commit handler */
- return 0;
-}
-
-static int orinoco_ioctl_getspy(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct sockaddr *address = (struct sockaddr *) extra;
- int number;
- int i;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- number = priv->spy_number;
- /* Create address struct */
- for (i = 0; i < number; i++) {
- memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
- address[i].sa_family = AF_UNIX;
- }
- if (number > 0) {
- /* Create address struct */
- for (i = 0; i < number; i++) {
- memcpy(address[i].sa_data, priv->spy_address[i],
- ETH_ALEN);
- address[i].sa_family = AF_UNIX;
- }
- /* Copy stats */
- /* In theory, we should disable irqs while copying the stats
- * because the rx path might update it in the middle...
- * Bah, who care ? - Jean II */
- memcpy(extra + (sizeof(struct sockaddr) * number),
- priv->spy_stat, sizeof(struct iw_quality) * number);
- }
- /* Reset updated flags. */
- for (i = 0; i < number; i++)
- priv->spy_stat[i].updated = 0;
-
- orinoco_unlock(priv, &flags);
-
- srq->length = number;
-
- return 0;
-}
-
/* Trigger a scan (look for other cells in the vicinity */
static int orinoco_ioctl_setscan(struct net_device *dev,
struct iw_request_info *info,
@@ -3995,7 +3910,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
HERMES_HOSTSCAN_SYMBOL_BCAST);
break;
case FIRMWARE_TYPE_INTERSIL: {
- u16 req[3];
+ __le16 req[3];
req[0] = cpu_to_le16(0x3fff); /* All channels */
req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
@@ -4069,7 +3984,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
case FIRMWARE_TYPE_INTERSIL:
offset = 4;
if (priv->has_hostscan) {
- atom_len = le16_to_cpup((u16 *)scan);
+ atom_len = le16_to_cpup((__le16 *)scan);
/* Sanity check for atom_len */
if (atom_len < sizeof(struct prism2_scan_apinfo)) {
printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
@@ -4353,8 +4268,10 @@ static const iw_handler orinoco_handler[] = {
[SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
[SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
- [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy,
- [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy,
+ [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+ [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+ [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+ [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
[SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
[SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
[SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
@@ -4399,6 +4316,7 @@ static const struct iw_handler_def orinoco_handler_def = {
.standard = orinoco_handler,
.private = orinoco_private_handler,
.private_args = orinoco_privtab,
+ .get_wireless_stats = orinoco_get_wireless_stats,
};
static void orinoco_get_drvinfo(struct net_device *dev,
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 2f213a7103fe..7a17bb31fc89 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -7,12 +7,11 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H
-#define DRIVER_VERSION "0.15rc2"
+#define DRIVER_VERSION "0.15rc3"
-#include <linux/types.h>
-#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
+#include <net/iw_handler.h>
#include <linux/version.h>
#include "hermes.h"
@@ -28,7 +27,7 @@
#define ORINOCO_MAX_KEYS 4
struct orinoco_key {
- u16 len; /* always stored as little-endian */
+ __le16 len; /* always stored as little-endian */
char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed));
@@ -36,14 +35,14 @@ struct header_struct {
/* 802.3 */
u8 dest[ETH_ALEN];
u8 src[ETH_ALEN];
- u16 len;
+ __be16 len;
/* 802.2 */
u8 dsap;
u8 ssap;
u8 ctrl;
/* SNAP */
u8 oui[3];
- u16 ethertype;
+ unsigned short ethertype;
} __attribute__ ((packed));
typedef enum {
@@ -112,9 +111,8 @@ struct orinoco_private {
u16 pm_on, pm_mcast, pm_period, pm_timeout;
u16 preamble;
#ifdef WIRELESS_SPY
- int spy_number;
- u_char spy_address[IW_MAX_SPY][ETH_ALEN];
- struct iw_quality spy_stat[IW_MAX_SPY];
+ struct iw_spy_data spy_data; /* iwspy support */
+ struct iw_public_data wireless_data;
#endif
/* Configuration dependent variables */
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index d1fb1bab8aa8..dc1128a00971 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -14,33 +14,16 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-#ifdef __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
#include "orinoco.h"
/********************************************************************/
@@ -97,17 +80,8 @@ static dev_link_t *dev_list; /* = NULL */
/* Function prototypes */
/********************************************************************/
-/* device methods */
-static int orinoco_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void orinoco_cs_config(dev_link_t * link);
-static void orinoco_cs_release(dev_link_t * link);
-static int orinoco_cs_event(event_t event, int priority,
- event_callback_args_t * args);
-
-static dev_link_t *orinoco_cs_attach(void);
-static void orinoco_cs_detach(dev_link_t *);
+static void orinoco_cs_release(dev_link_t *link);
+static void orinoco_cs_detach(dev_link_t *link);
/********************************************************************/
/* Device methods */
@@ -603,48 +577,85 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
"Pavel Roskin <proski@gnu.org>, et al)";
static struct pcmcia_device_id orinoco_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
- PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
- PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001),
- PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305),
- PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
- PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673),
- PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001),
- PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
- PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021),
- PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
+ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
+ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
+ PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
+ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
+ PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
+ PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
+ PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
+ PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
+ PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
+ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
+ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
+ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
+ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
+ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
+ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
+ PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
+ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
+ PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
+ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
+ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
+ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
+ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
+ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
+ PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
- PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
+ PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
+ PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
+ PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
+ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
+ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
+ PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
+ PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
+ PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
+ PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
+ PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
+ PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
+ PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
+ PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+ PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
+ PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
+ PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
+ PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
+ PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
+ PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
+ PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
+ PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
+ PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
+ PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
+ PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
+ PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
- PCMCIA_DEVICE_PROD_ID1("Symbol Technologies", 0x3f02b4d6),
+ PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
+ PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
+ PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
+ PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
@@ -655,8 +666,8 @@ static struct pcmcia_driver orinoco_driver = {
.name = DRIVER_NAME,
},
.attach = orinoco_cs_attach,
- .event = orinoco_cs_event,
.detach = orinoco_cs_detach,
+ .event = orinoco_cs_event,
.id_table = orinoco_cs_ids,
};
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index 86fa58e5cfac..d8afd51ff8a5 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -40,29 +40,13 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
#include <pcmcia/cisreg.h>
-#include "hermes.h"
#include "orinoco.h"
#define COR_OFFSET (0xe0) /* COR attribute offset of Prism2 PC card */
@@ -108,7 +92,7 @@ static int nortel_pci_cor_reset(struct orinoco_private *priv)
return 0;
}
-int nortel_pci_hw_init(struct nortel_pci_card *card)
+static int nortel_pci_hw_init(struct nortel_pci_card *card)
{
int i;
u32 reg;
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 42e03438291b..5362c214fc8e 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -93,28 +93,12 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include "hermes.h"
#include "orinoco.h"
/* All the magic there is from wlan-ng */
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 7ab05b89fb3f..210e73776545 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -117,29 +117,13 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
#include <pcmcia/cisreg.h>
-#include "hermes.h"
#include "orinoco.h"
#define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index 85893f42445b..5e68b7026186 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -53,29 +53,13 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
#include <pcmcia/cisreg.h>
-#include "hermes.h"
#include "orinoco.h"
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 9a8790e3580c..5c1a1adf1ff8 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -462,14 +462,12 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
/* txpower is supported in dBm's */
range->txpower_capa = IW_TXPOW_DBM;
-#if WIRELESS_EXT > 16
/* Event capability (kernel + driver) */
range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
IW_EVENT_CAPA_MASK(SIOCGIWAP));
range->event_capa[1] = IW_EVENT_CAPA_K_1;
range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
-#endif /* WIRELESS_EXT > 16 */
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
@@ -693,14 +691,13 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
-#if WIRELESS_EXT > 16
+
/* Check if there is space for one more entry */
if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
/* Ask user space to try again with a bigger buffer */
rvalue = -E2BIG;
break;
}
-#endif /* WIRELESS_EXT > 16 */
}
kfree(bsslist);
@@ -2727,12 +2724,7 @@ const struct iw_handler_def prism54_handler_def = {
.standard = (iw_handler *) prism54_handler,
.private = (iw_handler *) prism54_private_handler,
.private_args = (struct iw_priv_args *) prism54_private_args,
-#if WIRELESS_EXT > 16
.get_wireless_stats = prism54_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
-#if WIRELESS_EXT == 16
- .spy_offset = offsetof(islpci_private, spy_data),
-#endif /* WIRELESS_EXT == 16 */
};
/* For wpa_supplicant */
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 6f13d4a8e2d3..6c9584a9f284 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -439,8 +439,7 @@ prism54_bring_down(islpci_private *priv)
wmb();
/* wait a while for the device to reset */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(50*HZ/1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(50));
return 0;
}
@@ -491,8 +490,7 @@ islpci_reset_if(islpci_private *priv)
/* The software reset acknowledge needs about 220 msec here.
* Be conservative and wait for up to one second. */
- set_current_state(TASK_UNINTERRUPTIBLE);
- remaining = schedule_timeout(HZ);
+ remaining = schedule_timeout_uninterruptible(HZ);
if(remaining > 0) {
result = 0;
@@ -839,13 +837,9 @@ islpci_setup(struct pci_dev *pdev)
priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
priv->monitor_type : ARPHRD_ETHER;
-#if WIRELESS_EXT > 16
/* Add pointers to enable iwspy support. */
priv->wireless_data.spy_data = &priv->spy_data;
ndev->wireless_data = &priv->wireless_data;
-#else /* WIRELESS_EXT > 16 */
- ndev->get_wireless_stats = &prism54_get_wireless_stats;
-#endif /* WIRELESS_EXT > 16 */
/* save the start and end address of the PCI memory area */
ndev->mem_start = (unsigned long) priv->device_base;
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 32a1019f1b36..efbed4397951 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -100,9 +100,7 @@ typedef struct {
struct iw_spy_data spy_data; /* iwspy support */
-#if WIRELESS_EXT > 16
struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT > 16 */
int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index b6f2e5a223be..4937a5ad4b2c 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -455,7 +455,7 @@ islpci_mgt_transaction(struct net_device *ndev,
struct islpci_mgmtframe **recvframe)
{
islpci_private *priv = netdev_priv(ndev);
- const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
+ const long wait_cycle_jiffies = msecs_to_jiffies(ISL38XX_WAIT_CYCLE * 10);
long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
int err;
DEFINE_WAIT(wait);
@@ -475,8 +475,7 @@ islpci_mgt_transaction(struct net_device *ndev,
int timeleft;
struct islpci_mgmtframe *frame;
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeleft = schedule_timeout(wait_cycle_jiffies);
+ timeleft = schedule_timeout_uninterruptible(wait_cycle_jiffies);
frame = xchg(&priv->mgmt_received, NULL);
if (frame) {
if (frame->header->oid == oid) {
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index e9c5ea0f5535..70fd6fd8feb9 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1649,28 +1649,28 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
*/
static const iw_handler ray_handler[] = {
- [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
- [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) ray_get_name,
- [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) ray_set_freq,
- [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) ray_get_freq,
- [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) ray_set_mode,
- [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) ray_get_mode,
- [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
+ [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
+ [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) ray_get_name,
+ [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) ray_set_freq,
+ [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) ray_get_freq,
+ [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) ray_set_mode,
+ [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) ray_get_mode,
+ [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
#ifdef WIRELESS_SPY
- [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
- [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
- [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
- [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
+ [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+ [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+ [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+ [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
#endif /* WIRELESS_SPY */
- [SIOCGIWAP -SIOCIWFIRST] (iw_handler) ray_get_wap,
- [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
- [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
- [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) ray_set_rate,
- [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) ray_get_rate,
- [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) ray_set_rts,
- [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) ray_get_rts,
- [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) ray_set_frag,
- [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) ray_get_frag,
+ [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) ray_get_wap,
+ [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
+ [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
+ [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) ray_set_rate,
+ [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) ray_get_rate,
+ [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) ray_set_rts,
+ [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) ray_get_rts,
+ [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) ray_set_frag,
+ [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) ray_get_frag,
};
#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
@@ -1678,9 +1678,9 @@ static const iw_handler ray_handler[] = {
#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
static const iw_handler ray_private_handler[] = {
- [0] (iw_handler) ray_set_framing,
- [1] (iw_handler) ray_get_framing,
- [3] (iw_handler) ray_get_country,
+ [0] = (iw_handler) ray_set_framing,
+ [1] = (iw_handler) ray_get_framing,
+ [3] = (iw_handler) ray_get_country,
};
static const struct iw_priv_args ray_private_args[] = {
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 39c6cdf7f3f7..b1bbc8e8e91f 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -22,58 +22,23 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-#ifdef __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
+#include <linux/firmware.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
#include "orinoco.h"
-/*
- * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
- * the driver. Use get_symbol_fw script to generate spectrum_fw.h and
- * copy it to the same directory as spectrum_cs.c.
- *
- * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
- * runtime using hotplug. Use the same get_symbol_fw script to generate
- * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
- * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
- * make sure that you have hotplug installed and enabled in the kernel.
- */
-/* #define SPECTRUM_FW_INCLUDED 1 */
-
-#ifdef SPECTRUM_FW_INCLUDED
-/* Header with the firmware */
-#include "spectrum_fw.h"
-#else /* !SPECTRUM_FW_INCLUDED */
-#include <linux/firmware.h>
static unsigned char *primsym;
static unsigned char *secsym;
static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
-#endif /* !SPECTRUM_FW_INCLUDED */
/********************************************************************/
/* Module stuff */
@@ -124,17 +89,8 @@ static dev_link_t *dev_list; /* = NULL */
/* Function prototypes */
/********************************************************************/
-/* device methods */
-static int spectrum_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void spectrum_cs_config(dev_link_t * link);
-static void spectrum_cs_release(dev_link_t * link);
-static int spectrum_cs_event(event_t event, int priority,
- event_callback_args_t * args);
-
-static dev_link_t *spectrum_cs_attach(void);
-static void spectrum_cs_detach(dev_link_t *);
+static void spectrum_cs_release(dev_link_t *link);
+static void spectrum_cs_detach(dev_link_t *link);
/********************************************************************/
/* Firmware downloader */
@@ -182,8 +138,8 @@ static void spectrum_cs_detach(dev_link_t *);
* Each block has the following structure.
*/
struct dblock {
- u32 _addr; /* adapter address where to write the block */
- u16 _len; /* length of the data only, in bytes */
+ __le32 _addr; /* adapter address where to write the block */
+ __le16 _len; /* length of the data only, in bytes */
char data[0]; /* data to be written */
} __attribute__ ((packed));
@@ -193,9 +149,9 @@ struct dblock {
* items with matching ID should be written.
*/
struct pdr {
- u32 _id; /* record ID */
- u32 _addr; /* adapter address where to write the data */
- u32 _len; /* expected length of the data, in bytes */
+ __le32 _id; /* record ID */
+ __le32 _addr; /* adapter address where to write the data */
+ __le32 _len; /* expected length of the data, in bytes */
char next[0]; /* next PDR starts here */
} __attribute__ ((packed));
@@ -206,8 +162,8 @@ struct pdr {
* be plugged into the secondary firmware.
*/
struct pdi {
- u16 _len; /* length of ID and data, in words */
- u16 _id; /* record ID */
+ __le16 _len; /* length of ID and data, in words */
+ __le16 _id; /* record ID */
char data[0]; /* plug data */
} __attribute__ ((packed));;
@@ -414,7 +370,7 @@ spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
/* Read PDA from the adapter */
static int
-spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
+spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len)
{
int ret;
int pda_size;
@@ -445,7 +401,7 @@ spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
/* Parse PDA and write the records into the adapter */
static int
spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
- u16 *pda)
+ __le16 *pda)
{
int ret;
struct pdi *pdi;
@@ -511,7 +467,7 @@ spectrum_dl_image(hermes_t *hw, dev_link_t *link,
const struct dblock *first_block;
/* Plug Data Area (PDA) */
- u16 pda[PDA_WORDS];
+ __le16 pda[PDA_WORDS];
/* Binary block begins after the 0x1A marker */
ptr = image;
@@ -571,8 +527,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
{
int ret;
client_handle_t handle = link->handle;
-
-#ifndef SPECTRUM_FW_INCLUDED
const struct firmware *fw_entry;
if (request_firmware(&fw_entry, primary_fw_name,
@@ -592,7 +546,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
secondary_fw_name);
return -ENOENT;
}
-#endif
/* Load primary firmware */
ret = spectrum_dl_image(hw, link, primsym);
@@ -1085,7 +1038,7 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
static struct pcmcia_device_id spectrum_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
- PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
+ PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
@@ -1096,8 +1049,8 @@ static struct pcmcia_driver orinoco_driver = {
.name = DRIVER_NAME,
},
.attach = spectrum_cs_attach,
- .event = spectrum_cs_event,
.detach = spectrum_cs_detach,
+ .event = spectrum_cs_event,
.id_table = spectrum_cs_ids,
};
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 4b0acae22b0d..7bc7fc823128 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1352,7 +1352,7 @@ static unsigned char *strip_make_packet(unsigned char *buffer,
struct in_device *in_dev;
rcu_read_lock();
- in_dev = __in_dev_get(strip_info->dev);
+ in_dev = __in_dev_get_rcu(strip_info->dev);
if (in_dev == NULL) {
rcu_read_unlock();
return NULL;
@@ -1508,7 +1508,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
brd = addr = 0;
rcu_read_lock();
- in_dev = __in_dev_get(strip_info->dev);
+ in_dev = __in_dev_get_rcu(strip_info->dev);
if (in_dev) {
if (in_dev->ifa_list) {
brd = in_dev->ifa_list->ifa_broadcast;
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 7a5e20a17890..b0d8b5b03152 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -430,7 +430,6 @@ static void fee_read(unsigned long ioaddr, /* I/O port of the card */
}
}
-#ifdef WIRELESS_EXT /* if the wireless extension exists in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -514,7 +513,6 @@ static void fee_write(unsigned long ioaddr, /* I/O port of the card */
fee_wait(ioaddr, 10, 100);
#endif /* EEPROM_IS_PROTECTED */
}
-#endif /* WIRELESS_EXT */
/************************ I82586 SUBROUTINES *************************/
/*
@@ -973,11 +971,9 @@ static void wv_mmc_show(struct net_device * dev)
mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
/* Don't forget to update statistics */
lp->wstats.discard.nwid +=
(m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif /* WIRELESS_EXT */
printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
#ifdef DEBUG_SHOW_UNUSED
@@ -1499,7 +1495,6 @@ static int wavelan_set_mac_address(struct net_device * dev, void *addr)
}
#endif /* SET_MAC_ADDRESS */
-#ifdef WIRELESS_EXT /* if wireless extensions exist in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -2473,7 +2468,6 @@ static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
#endif
return &lp->wstats;
}
-#endif /* WIRELESS_EXT */
/************************* PACKET RECEPTION *************************/
/*
@@ -4194,11 +4188,9 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
dev->set_mac_address = &wavelan_set_mac_address;
#endif /* SET_MAC_ADDRESS */
-#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
dev->wireless_handlers = &wavelan_handler_def;
lp->wireless_data.spy_data = &lp->spy_data;
dev->wireless_data = &lp->wireless_data;
-#endif
dev->mtu = WAVELAN_MTU;
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 509ff22a6caa..166e28b9a4f7 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -409,11 +409,9 @@
#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical). */
#undef SET_MAC_ADDRESS /* Experimental */
-#ifdef WIRELESS_EXT /* If wireless extensions exist in the kernel */
/* Warning: this stuff will slow down the driver. */
#define WIRELESS_SPY /* Enable spying addresses. */
#undef HISTOGRAM /* Enable histogram of signal level. */
-#endif
/****************************** DEBUG ******************************/
@@ -506,12 +504,10 @@ struct net_local
u_short tx_first_free;
u_short tx_first_in_use;
-#ifdef WIRELESS_EXT
iw_stats wstats; /* Wireless-specific statistics */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
-#endif
#ifdef HISTOGRAM
int his_number; /* number of intervals */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 183c4732ef65..4b3c98f5c564 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -415,7 +415,6 @@ fee_read(u_long base, /* i/o port of the card */
}
}
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -500,7 +499,6 @@ fee_write(u_long base, /* i/o port of the card */
fee_wait(base, 10, 100);
#endif /* EEPROM_IS_PROTECTED */
}
-#endif /* WIRELESS_EXT */
/******************* WaveLAN Roaming routines... ********************/
@@ -1161,10 +1159,8 @@ wv_mmc_show(struct net_device * dev)
mmc_read(base, 0, (u_char *)&m, sizeof(m));
mmc_out(base, mmwoff(0, mmw_freeze), 0);
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/* Don't forget to update statistics */
lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif /* WIRELESS_EXT */
spin_unlock_irqrestore(&lp->spinlock, flags);
@@ -1550,7 +1546,6 @@ wavelan_set_mac_address(struct net_device * dev,
}
#endif /* SET_MAC_ADDRESS */
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -2793,7 +2788,6 @@ wavelan_get_wireless_stats(struct net_device * dev)
#endif
return &lp->wstats;
}
-#endif /* WIRELESS_EXT */
/************************* PACKET RECEPTION *************************/
/*
@@ -4679,11 +4673,9 @@ wavelan_attach(void)
dev->watchdog_timeo = WATCHDOG_JIFFIES;
SET_ETHTOOL_OPS(dev, &ops);
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
dev->wireless_handlers = &wavelan_handler_def;
lp->wireless_data.spy_data = &lp->spy_data;
dev->wireless_data = &lp->wireless_data;
-#endif
/* Other specific data */
dev->mtu = WAVELAN_MTU;
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 01d882be8790..724a715089c9 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -472,11 +472,9 @@
#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical) */
#undef SET_MAC_ADDRESS /* Experimental */
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/* Warning : these stuff will slow down the driver... */
#define WIRELESS_SPY /* Enable spying addresses */
#undef HISTOGRAM /* Enable histogram of sig level... */
-#endif
/****************************** DEBUG ******************************/
@@ -624,12 +622,10 @@ struct net_local
int rfp; /* Last DMA machine receive pointer */
int overrunning; /* Receiver overrun flag */
-#ifdef WIRELESS_EXT
iw_stats wstats; /* Wireless specific stats */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
-#endif
#ifdef HISTOGRAM
int his_number; /* Number of intervals */
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 7fcbe589c3f2..4303c50c2ab6 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
struct wl3501_80211_tx_hdr {
struct wl3501_80211_tx_plcp_hdr pclp_hdr;
- struct ieee80211_hdr mac_hdr;
+ struct ieee80211_hdr_4addr mac_hdr;
} __attribute__ ((packed));
/*
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 0e98a9d9834c..a3bd91a61827 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -836,7 +836,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* This function implements the pci_alloc_consistent function.
*/
static void *
-ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
+ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
{
void *ret;
#if 0
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 91df0bf181dd..7a57c1b8373f 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -215,7 +215,7 @@ static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 va
#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/parisc/lasi.c b/drivers/parisc/lasi.c
index 731855053392..cb84a4e84a2f 100644
--- a/drivers/parisc/lasi.c
+++ b/drivers/parisc/lasi.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/io.h>
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index e90fb72a6962..286902298e33 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -37,6 +37,7 @@
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/blkdev.h>
+#include <linux/rcupdate.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/hardware.h>
@@ -358,9 +359,10 @@ static __inline__ int led_get_net_activity(void)
/* we are running as tasklet, so locking dev_base
* for reading should be OK */
read_lock(&dev_base_lock);
+ rcu_read_lock();
for (dev = dev_base; dev; dev = dev->next) {
struct net_device_stats *stats;
- struct in_device *in_dev = __in_dev_get(dev);
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
if (!in_dev || !in_dev->ifa_list)
continue;
if (LOOPBACK(in_dev->ifa_list->ifa_local))
@@ -371,6 +373,7 @@ static __inline__ int led_get_net_activity(void)
rx_total += stats->rx_packets;
tx_total += stats->tx_packets;
}
+ rcu_read_unlock();
read_unlock(&dev_base_lock);
retval = 0;
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 82ea68b55df4..bd8b3e5a5cd7 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -986,7 +986,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* See Documentation/DMA-mapping.txt
*/
static void *sba_alloc_consistent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index 694bae162fed..5b887ba5aaf9 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -196,7 +196,7 @@ int parport_wait_peripheral(struct parport *port,
return 1;
/* 40ms of slow polling. */
- deadline = jiffies + (HZ + 24) / 25;
+ deadline = jiffies + msecs_to_jiffies(40);
while (time_before (jiffies, deadline)) {
int ret;
@@ -205,7 +205,7 @@ int parport_wait_peripheral(struct parport *port,
/* Wait for 10ms (or until an interrupt occurs if
* the handler is set) */
- if ((ret = parport_wait_event (port, (HZ + 99) / 100)) < 0)
+ if ((ret = parport_wait_event (port, msecs_to_jiffies(10))) < 0)
return ret;
status = parport_read_status (port);
@@ -216,8 +216,7 @@ int parport_wait_peripheral(struct parport *port,
/* parport_wait_event didn't time out, but the
* peripheral wasn't actually ready either.
* Wait for another 10ms. */
- __set_current_state (TASK_INTERRUPTIBLE);
- schedule_timeout ((HZ+ 99) / 100);
+ schedule_timeout_interruptible(msecs_to_jiffies(10));
}
}
diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c
index 6624278c6ed8..ce1e2aad8b10 100644
--- a/drivers/parport/ieee1284_ops.c
+++ b/drivers/parport/ieee1284_ops.c
@@ -60,7 +60,7 @@ size_t parport_ieee1284_write_compat (struct parport *port,
parport_data_forward (port);
while (count < len) {
unsigned long expire = jiffies + dev->timeout;
- long wait = (HZ + 99) / 100;
+ long wait = msecs_to_jiffies(10);
unsigned char mask = (PARPORT_STATUS_ERROR
| PARPORT_STATUS_BUSY);
unsigned char val = (PARPORT_STATUS_ERROR
@@ -97,8 +97,7 @@ size_t parport_ieee1284_write_compat (struct parport *port,
our interrupt handler called. */
if (count && no_irq) {
parport_release (dev);
- __set_current_state (TASK_INTERRUPTIBLE);
- schedule_timeout (wait);
+ schedule_timeout_interruptible(wait);
parport_claim_or_block (dev);
}
else
@@ -542,13 +541,12 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port,
/* Yield the port for a while. */
if (count && dev->port->irq != PARPORT_IRQ_NONE) {
parport_release (dev);
- __set_current_state (TASK_INTERRUPTIBLE);
- schedule_timeout ((HZ + 24) / 25);
+ schedule_timeout_interruptible(msecs_to_jiffies(40));
parport_claim_or_block (dev);
}
else
/* We must have the device claimed here. */
- parport_wait_event (port, (HZ + 24) / 25);
+ parport_wait_event (port, msecs_to_jiffies(40));
/* Is there a signal pending? */
if (signal_pending (current))
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 97f723179f62..c6493ad7c0c8 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -173,8 +173,7 @@ static int change_mode(struct parport *p, int m)
if (time_after_eq (jiffies, expire))
/* The FIFO is stuck. */
return -EBUSY;
- __set_current_state (TASK_INTERRUPTIBLE);
- schedule_timeout ((HZ + 99) / 100);
+ schedule_timeout_interruptible(msecs_to_jiffies(10));
if (signal_pending (current))
break;
}
@@ -3010,7 +3009,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/.gitignore b/drivers/pci/.gitignore
new file mode 100644
index 000000000000..f297ca8d313e
--- /dev/null
+++ b/drivers/pci/.gitignore
@@ -0,0 +1,4 @@
+classlist.h
+devlist.h
+gen-devlist
+
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7f31991772ea..f187fd8aeed6 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -30,23 +30,6 @@ config PCI_LEGACY_PROC
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 3657f6199c48..716df015f8d0 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 fb9a11243d2a..eed67d9e73bc 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -140,16 +140,65 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
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 8abfc499fdef..000000000000
--- 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 b844bc972324..e1743be31909 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -7,7 +7,6 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct pci_dev *pdev;
- char *scratch;
int i = 0;
int length = 0;
@@ -18,48 +17,34 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
if (!pdev)
return -ENODEV;
- 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/Kconfig b/drivers/pci/hotplug/Kconfig
index 9c4a39ee89b5..2f1289eebb3c 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -78,7 +78,7 @@ config HOTPLUG_PCI_IBM
config HOTPLUG_PCI_ACPI
tristate "ACPI PCI Hotplug driver"
- depends on ACPI_BUS && HOTPLUG_PCI
+ depends on ACPI && HOTPLUG_PCI
help
Say Y here if you have a system that supports PCI Hotplug using
ACPI.
@@ -157,7 +157,7 @@ config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
config HOTPLUG_PCI_SHPC_PHPRM_LEGACY
bool "For AMD SHPC only: Use $HRT for resource/configuration"
- depends on HOTPLUG_PCI_SHPC && !ACPI_BUS
+ depends on HOTPLUG_PCI_SHPC && !ACPI
help
Say Y here for AMD SHPC. You have to select this option if you are
using this driver on platform with AMD SHPC.
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 31a307004b94..3c71e3077ff1 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
@@ -51,7 +50,7 @@ pciehp-objs := pciehp_core.o \
pciehp_ctrl.o \
pciehp_pci.o \
pciehp_hpc.o
-ifdef CONFIG_ACPI_BUS
+ifdef CONFIG_ACPI
pciehp-objs += pciehprm_acpi.o
else
pciehp-objs += pciehprm_nonacpi.o
@@ -62,7 +61,7 @@ shpchp-objs := shpchp_core.o \
shpchp_pci.o \
shpchp_sysfs.o \
shpchp_hpc.o
-ifdef CONFIG_ACPI_BUS
+ifdef CONFIG_ACPI
shpchp-objs += shpchprm_acpi.o
else
ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index 8122fe734aa7..b1ba429e0a2d 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -558,7 +558,7 @@ static int configure_device (struct pci_func *func)
pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
- pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
+ pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
return 0;
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 2b92b9e8c910..061ead21ef14 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -302,7 +302,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
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/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 0e0947601526..898f6da6f0de 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -2526,7 +2526,6 @@ configure_new_function(struct controller *ctrl, struct pci_func *func,
int cloop;
u8 temp_byte;
u8 class_code;
- u16 temp_word;
u32 rc;
u32 temp_register;
u32 base;
@@ -2682,8 +2681,7 @@ configure_new_function(struct controller *ctrl, struct pci_func *func,
} /* End of base register loop */
/* disable ROM base Address */
- temp_word = 0x00L;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
+ rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
/* Set HP parameters (Cache Line Size, Latency Timer) */
rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 305b47ec2f2c..1406db35b089 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -1696,15 +1696,15 @@ void pciehprm_enable_card(
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 86b384e42717..ad1017da8656 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/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
index 752e6513c447..db69be85b458 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -62,7 +62,7 @@ static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr,
char drc_name[MAX_DRC_NAME_LEN];
char *end;
- if (nbytes > MAX_DRC_NAME_LEN)
+ if (nbytes >= MAX_DRC_NAME_LEN)
return 0;
memcpy(drc_name, buf, nbytes);
@@ -83,7 +83,7 @@ static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr,
char drc_name[MAX_DRC_NAME_LEN];
char *end;
- if (nbytes > MAX_DRC_NAME_LEN)
+ if (nbytes >= MAX_DRC_NAME_LEN)
return 0;
memcpy(drc_name, buf, nbytes);
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 81746e6e0e0f..61d94d1e29cb 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -30,10 +30,6 @@
#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 29117a3a3287..c830ff0acdc3 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -152,17 +152,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
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 d8305a935aab..49e4d10a6488 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 ff2cbf0652d8..0e8815495083 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 74df6a305e64..000000000000
--- 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 323041fd41dc..a32ae82e5922 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 = kzalloc(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 = kzalloc(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),
+ kzalloc(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 fe4d653da188..b7d1c61d6bbb 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -411,7 +411,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
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/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 783b5abb0717..91c9903e621f 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -2824,8 +2824,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
}
#endif
/* Disable ROM base Address */
- temp_word = 0x00L;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
+ rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
/* Set HP parameters (Cache Line Size, Latency Timer) */
rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 532f73bb2224..ee8677bda950 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -439,10 +439,7 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
}
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 ad224aada7c9..000000000000
--- 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 e4115a0d5ba6..0d0d533894e0 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-sysfs.c b/drivers/pci/pci-sysfs.c
index cc9d65388e62..2898830c496f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -44,10 +44,14 @@ pci_config_attr(subsystem_device, "0x%04x\n");
pci_config_attr(class, "0x%06x\n");
pci_config_attr(irq, "%u\n");
-static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t local_cpus_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- cpumask_t mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
- int len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
+ cpumask_t mask;
+ int len;
+
+ mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
+ len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
strcat(buf,"\n");
return 1+len;
}
@@ -356,7 +360,7 @@ pci_create_resource_files(struct pci_dev *pdev)
continue;
/* allocate attribute structure, piggyback attribute name */
- res_attr = kcalloc(1, sizeof(*res_attr) + 10, GFP_ATOMIC);
+ res_attr = kzalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
if (res_attr) {
char *res_attr_name = (char *)(res_attr + 1);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c62d2f043397..259d247b7551 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,23 +302,32 @@ 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.
+ /* If we're (effectively) 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)
+ switch (dev->current_state) {
+ case PCI_UNKNOWN: /* Boot-up */
+ if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
+ && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+ need_restore = 1;
+ /* Fall-through: force to D0 */
+ case PCI_D3hot:
+ case PCI_D3cold:
+ case PCI_POWER_ERROR:
pmcsr = 0;
- else {
- pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+ break;
+ default:
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
+ break;
}
/* enter specified state */
@@ -308,6 +348,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 +450,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 +806,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 +893,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 +908,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 d00168b1f662..d3f3dd42240d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -29,7 +29,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
#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 1d2ef1e2ffc6..000000000000
--- 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 30bac7ed7c16..3c565ce7f77b 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -90,15 +90,19 @@ static void pcie_portdrv_save_config(struct pci_dev *dev)
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 93e8a878ea95..005786416bb5 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -72,11 +72,13 @@ void pci_remove_legacy_files(struct pci_bus *bus) { return; }
/*
* PCI Bus Class Devices
*/
-static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
+static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev,
+ char *buf)
{
- cpumask_t cpumask = pcibus_to_cpumask(to_pci_bus(class_dev));
int ret;
+ cpumask_t cpumask;
+ cpumask = pcibus_to_cpumask(to_pci_bus(class_dev));
ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
if (ret < PAGE_SIZE)
buf[ret++] = '\n';
@@ -163,7 +165,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
if (l == 0xffffffff)
l = 0;
if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
- sz = pci_size(l, sz, PCI_BASE_ADDRESS_MEM_MASK);
+ sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
if (!sz)
continue;
res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
@@ -213,7 +215,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
if (l == 0xffffffff)
l = 0;
if (sz && sz != 0xffffffff) {
- sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
+ sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);
if (sz) {
res->flags = (l & IORESOURCE_ROM_ENABLE) |
IORESOURCE_MEM | IORESOURCE_PREFETCH |
@@ -400,6 +402,12 @@ static void pci_enable_crs(struct pci_dev *dev)
static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
{
struct pci_bus *parent = child->parent;
+
+ /* Attempts to fix that up are really dangerous unless
+ we're going to re-assign all bus numbers. */
+ if (!pcibios_assign_all_busses())
+ return;
+
while (parent->parent && parent->subordinate < max) {
parent->subordinate = max;
pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
@@ -476,8 +484,18 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
* We need to assign a number to this bus which we always
* do in the second pass.
*/
- if (!pass)
+ if (!pass) {
+ if (pcibios_assign_all_busses())
+ /* Temporarily disable forwarding of the
+ configuration cycles on all bridges in
+ this bus segment to avoid possible
+ conflicts in the second pass between two
+ bridges programmed with overlapping
+ bus ranges. */
+ pci_write_config_dword(dev, PCI_PRIMARY_BUS,
+ buses & ~0xffffff);
return max;
+ }
/* Clear errors */
pci_write_config_word(dev, PCI_STATUS, 0xffff);
@@ -584,7 +602,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 +771,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 +795,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 +904,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 +962,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 +979,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 7988fc8df3fd..9613f666c110 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -474,7 +474,7 @@ static int show_dev_config(struct seq_file *m, void *v)
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 140354a2aa72..7992bc8cc6a4 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -241,17 +241,26 @@ static void __devinit quirk_s3_64M(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M );
-static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, unsigned size, int nr)
+static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
+ unsigned size, int nr, const char *name)
{
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);
+ printk("PCI quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name);
}
}
@@ -284,25 +293,98 @@ static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
u16 region;
pci_read_config_word(dev, 0xE0, &region);
- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES);
+ quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI");
pci_read_config_word(dev, 0xE2, &region);
- quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1);
+ quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi );
+static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
+{
+ u32 devres;
+ u32 mask, size, base;
+
+ pci_read_config_dword(dev, port, &devres);
+ if ((devres & enable) != enable)
+ return;
+ mask = (devres >> 16) & 15;
+ base = devres & 0xffff;
+ size = 16;
+ for (;;) {
+ unsigned bit = size >> 1;
+ if ((bit & mask) == bit)
+ break;
+ size = bit;
+ }
+ /*
+ * For now we only print it out. Eventually we'll want to
+ * reserve it (at least if it's in the 0x1000+ range), but
+ * let's get enough confirmation reports first.
+ */
+ base &= -size;
+ printk("%s PIO at %04x-%04x\n", name, base, base + size - 1);
+}
+
+static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
+{
+ u32 devres;
+ u32 mask, size, base;
+
+ pci_read_config_dword(dev, port, &devres);
+ if ((devres & enable) != enable)
+ return;
+ base = devres & 0xffff0000;
+ mask = (devres & 0x3f) << 16;
+ size = 128 << 16;
+ for (;;) {
+ unsigned bit = size >> 1;
+ if ((bit & mask) == bit)
+ break;
+ size = bit;
+ }
+ /*
+ * For now we only print it out. Eventually we'll want to
+ * reserve it, but let's get enough confirmation reports first.
+ */
+ base &= -size;
+ printk("%s MMIO at %04x-%04x\n", name, base, base + size - 1);
+}
+
/*
* PIIX4 ACPI: Two IO regions pointed to by longwords at
* 0x40 (64 bytes of ACPI registers)
* 0x90 (32 bytes of SMB registers)
+ * and a few strange programmable PIIX4 device resources.
*/
static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
{
- u32 region;
+ u32 region, res_a;
pci_read_config_dword(dev, 0x40, &region);
- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES);
+ quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
pci_read_config_dword(dev, 0x90, &region);
- quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1);
+ quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+
+ /* Device resource A has enables for some of the other ones */
+ pci_read_config_dword(dev, 0x5c, &res_a);
+
+ piix4_io_quirk(dev, "PIIX4 devres B", 0x60, 3 << 21);
+ piix4_io_quirk(dev, "PIIX4 devres C", 0x64, 3 << 21);
+
+ /* Device resource D is just bitfields for static resources */
+
+ /* Device 12 enabled? */
+ if (res_a & (1 << 29)) {
+ piix4_io_quirk(dev, "PIIX4 devres E", 0x68, 1 << 20);
+ piix4_mem_quirk(dev, "PIIX4 devres F", 0x6c, 1 << 7);
+ }
+ /* Device 13 enabled? */
+ if (res_a & (1 << 30)) {
+ piix4_io_quirk(dev, "PIIX4 devres G", 0x70, 1 << 20);
+ piix4_mem_quirk(dev, "PIIX4 devres H", 0x74, 1 << 7);
+ }
+ piix4_io_quirk(dev, "PIIX4 devres I", 0x78, 1 << 20);
+ piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 1 << 20);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi );
@@ -316,10 +398,10 @@ static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)
u32 region;
pci_read_config_dword(dev, 0x40, &region);
- quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES);
+ quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH4 ACPI/GPIO/TCO");
pci_read_config_dword(dev, 0x58, &region);
- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1);
+ quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH4 GPIO");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi );
@@ -345,7 +427,7 @@ static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev)
if (rev & 0x10) {
pci_read_config_dword(dev, 0x48, &region);
region &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES);
+ quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI");
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi );
@@ -365,11 +447,11 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
pci_read_config_word(dev, 0x70, &hm);
hm &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1);
+ quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c868 HW-mon");
pci_read_config_dword(dev, 0x90, &smb);
smb &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2);
+ quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c868 SMB");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi );
@@ -384,11 +466,11 @@ static void __devinit quirk_vt8235_acpi(struct pci_dev *dev)
pci_read_config_word(dev, 0x88, &pm);
pm &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES);
+ quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM");
pci_read_config_word(dev, 0xd0, &smb);
smb &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1);
+ quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi);
@@ -869,6 +951,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 );
@@ -1220,7 +1308,7 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic );
#endif
-#ifdef CONFIG_SCSI_SATA
+#ifdef CONFIG_SCSI_SATA_INTEL_COMBINED
static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
{
u8 prog, comb, tmp;
@@ -1297,7 +1385,7 @@ static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
request_region(0x170, 8, "libata"); /* port 1 */
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_combined );
-#endif /* CONFIG_SCSI_SATA */
+#endif /* CONFIG_SCSI_SATA_INTEL_COMBINED */
int pcie_mch_quirk;
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 6b0e6464eb39..28ce3a7ee434 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -40,7 +40,7 @@
* FIXME: IO should be max 256 bytes. However, since we may
* have a P2P bridge below a cardbus bridge, we need 4K.
*/
-#define CARDBUS_IO_SIZE (4*1024)
+#define CARDBUS_IO_SIZE (256)
#define CARDBUS_MEM_SIZE (32*1024*1024)
static void __devinit
@@ -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 5598b4714f77..50d6685dcbcc 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 6485f75d2fb3..36cc9a96a338 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -146,7 +146,7 @@ config I82365
config TCIC
tristate "Databook TCIC host bridge support"
- depends on PCMCIA
+ depends on PCMCIA && ISA
select PCCARD_NONSTATIC
help
Say Y here to include support for the Databook TCIC family of PCMCIA
@@ -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 ef694c74dfb7..a41fbb38fdcb 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/cardbus.c b/drivers/pcmcia/cardbus.c
index 1d755e20880c..3f6d51d11374 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -228,6 +228,11 @@ int cb_alloc(struct pcmcia_socket * s)
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
cardbus_assign_irqs(bus, s->pci_irq);
+
+ /* socket specific tune function */
+ if (s->tune_bridge)
+ s->tune_bridge(s, bus);
+
pci_enable_bridges(bus);
pci_bus_add_devices(bus);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e39178fc59d0..d5e76423a0ee 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,12 +683,15 @@ static int pccardd(void *__skt)
continue;
}
- schedule();
- try_to_freeze();
-
if (!skt->thread)
break;
+
+ schedule();
+ try_to_freeze();
}
+ /* make sure we are running before we exit */
+ set_current_state(TASK_RUNNING);
+
remove_wait_queue(&skt->thread_wait, &wait);
/* remove from the device core */
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 6bbfbd0e02a5..55867bc7f199 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -17,9 +17,6 @@
#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 43da2e92d50f..080608c7381a 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -354,6 +354,7 @@ static void pcmcia_release_dev(struct device *dev)
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 000000000000..94be9e51654e
--- /dev/null
+++ b/drivers/pcmcia/omap_cf.c
@@ -0,0 +1,372 @@
+/*
+ * 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/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_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 39ba6406fd54..80969f7e7a0b 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -376,6 +376,7 @@ static int ds_open(struct inode *inode, struct file *file)
socket_t i = iminor(inode);
struct pcmcia_socket *s;
user_info_t *user;
+ static int warning_printed = 0;
ds_dbg(0, "ds_open(socket %d)\n", i);
@@ -407,6 +408,17 @@ static int ds_open(struct inode *inode, struct file *file)
s->user = user;
file->private_data = user;
+ if (!warning_printed) {
+ printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
+ "usage.\n");
+ printk(KERN_INFO "pcmcia: This interface will soon be removed from "
+ "the kernel; please expect breakage unless you upgrade "
+ "to new tools.\n");
+ printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
+ "utils/kernel/pcmcia/pcmcia.html for details.\n");
+ warning_printed = 1;
+ }
+
if (s->pcmcia_state.present)
queue_event(user, CS_EVENT_CARD_INSERTION);
return 0;
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 599b116d9747..89022ad5b520 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -447,7 +447,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
(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/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index c42455d20eb6..f9a5c70284b5 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -691,7 +691,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
unsigned long size = end - start + 1;
int ret = 0;
- if (end <= start)
+ if (end < start)
return -EINVAL;
down(&rsrc_sem);
@@ -724,7 +724,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
unsigned long size = end - start + 1;
int ret = 0;
- if (end <= start)
+ if (end < start)
return -EINVAL;
if (end > IO_SPACE_LIMIT)
@@ -817,7 +817,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
/* if we got at least one of IO, and one of MEM, we can be glad and
* activate the PCMCIA subsystem */
- if (done & (IORESOURCE_MEM | IORESOURCE_IO))
+ if (done == (IORESOURCE_MEM | IORESOURCE_IO))
s->resource_setup_done = 1;
return 0;
@@ -925,7 +925,7 @@ static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size
return -EINVAL;
}
}
- if (end_addr <= start_addr)
+ if (end_addr < start_addr)
return -EINVAL;
ret = adjust_io(s, add, start_addr, end_addr);
@@ -977,7 +977,7 @@ static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, siz
return -EINVAL;
}
}
- if (end_addr <= start_addr)
+ if (end_addr < start_addr)
return -EINVAL;
ret = adjust_memory(s, add, start_addr, end_addr);
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index bb90a1448a53..81ded52c8959 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -122,7 +122,7 @@ void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
static int pcmcia_probe(struct sa1111_dev *dev)
{
- char *base;
+ void __iomem *base;
if (!request_mem_region(dev->res.start, 512,
SA1111_DRIVER_NAME(dev)))
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 888b70e6a484..9e7ccd8a4321 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -66,7 +66,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
if (pc_debug > lvl) {
printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func);
va_start(args, fmt);
- printk(fmt, args);
+ vprintk(fmt, args);
va_end(args);
}
}
@@ -321,8 +321,6 @@ soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
* less punt all of this work and let the kernel handle the details
* of power configuration, reset, &c. We also record the value of
* `state' in order to regurgitate it to the PCMCIA core later.
- *
- * Returns: 0
*/
static int
soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
@@ -407,7 +405,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
* the map speed as requested, but override the address ranges
* supplied by Card Services.
*
- * Returns: 0 on success, -1 on error
+ * Returns: 0 on success, -ERRNO on error
*/
static int
soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
@@ -655,8 +653,8 @@ static void soc_pcmcia_cpufreq_unregister(void)
}
#else
-#define soc_pcmcia_cpufreq_register()
-#define soc_pcmcia_cpufreq_unregister()
+static int soc_pcmcia_cpufreq_register(void) { return 0; }
+static void soc_pcmcia_cpufreq_unregister(void) {}
#endif
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
@@ -738,7 +736,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
goto out_err_5;
}
- if ( list_empty(&soc_pcmcia_sockets) )
+ if (list_empty(&soc_pcmcia_sockets))
soc_pcmcia_cpufreq_register();
list_add(&skt->node, &soc_pcmcia_sockets);
@@ -839,7 +837,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
release_resource(&skt->res_io);
release_resource(&skt->res_skt);
}
- if ( list_empty(&soc_pcmcia_sockets) )
+ if (list_empty(&soc_pcmcia_sockets))
soc_pcmcia_cpufreq_unregister();
up(&soc_pcmcia_sockets_lock);
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index fbe233e19ceb..539b5cd1a598 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -59,6 +59,7 @@
#define TI122X_SCR_SER_STEP 0xc0000000
#define TI122X_SCR_INTRTIE 0x20000000
+#define TIXX21_SCR_TIEALL 0x10000000
#define TI122X_SCR_CBRSVD 0x00400000
#define TI122X_SCR_MRBURSTDN 0x00008000
#define TI122X_SCR_MRBURSTUP 0x00004000
@@ -153,6 +154,12 @@
/* EnE test register */
#define ENE_TEST_C9 0xc9 /* 8bit */
#define ENE_TEST_C9_TLTENABLE 0x02
+#define ENE_TEST_C9_PFENABLE_F0 0x04
+#define ENE_TEST_C9_PFENABLE_F1 0x08
+#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0)
+#define ENE_TEST_C9_WPDISALBLE_F0 0x40
+#define ENE_TEST_C9_WPDISALBLE_F1 0x80
+#define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1)
/*
* Texas Instruments CardBus controller overrides.
@@ -618,6 +625,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
int devfn;
unsigned int state;
int ret = 1;
+ u32 sysctl;
/* catch the two-slot controllers */
switch (socket->dev->device) {
@@ -640,6 +648,24 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
*/
break;
+ case PCI_DEVICE_ID_TI_X515:
+ case PCI_DEVICE_ID_TI_X420:
+ case PCI_DEVICE_ID_TI_X620:
+ case PCI_DEVICE_ID_TI_XX21_XX11:
+ case PCI_DEVICE_ID_TI_7410:
+ case PCI_DEVICE_ID_TI_7610:
+ /*
+ * those are either single or dual slot CB with additional functions
+ * like 1394, smartcard reader, etc. check the TIEALL flag for them
+ * the TIEALL flag binds the IRQ of all functions toghether.
+ * we catch the single slot variants later.
+ */
+ sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+ if (sysctl & TIXX21_SCR_TIEALL)
+ return 0;
+
+ break;
+
/* single-slot controllers have the 2nd slot empty always :) */
default:
return 1;
@@ -652,6 +678,15 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
if (!func)
return 1;
+ /*
+ * check that the device id of both slots match. this is needed for the
+ * XX21 and the XX11 controller that share the same device id for single
+ * and dual slot controllers. return '2nd slot empty'. we already checked
+ * if the interrupt is tied to another function.
+ */
+ if (socket->dev->device != func->device)
+ goto out;
+
slot2 = pci_get_drvdata(func);
if (!slot2)
goto out;
@@ -791,16 +826,6 @@ static int ti12xx_override(struct yenta_socket *socket)
config_writel(socket, TI113X_SYSTEM_CONTROL, val);
/*
- * for EnE bridges only: clear testbit TLTEnable. this makes the
- * RME Hammerfall DSP sound card working.
- */
- if (socket->dev->vendor == PCI_VENDOR_ID_ENE) {
- u8 test_c9 = config_readb(socket, ENE_TEST_C9);
- test_c9 &= ~ENE_TEST_C9_TLTENABLE;
- config_writeb(socket, ENE_TEST_C9, test_c9);
- }
-
- /*
* Yenta expects controllers to use CSCINT to route
* CSC interrupts to PCI rather than INTVAL.
*/
@@ -841,5 +866,78 @@ static int ti1250_override(struct yenta_socket *socket)
return ti12xx_override(socket);
}
+
+/**
+ * EnE specific part. EnE bridges are register compatible with TI bridges but
+ * have their own test registers and more important their own little problems.
+ * Some fixup code to make everybody happy (TM).
+ */
+
+#ifdef CONFIG_CARDBUS
+/**
+ * set/clear various test bits:
+ * Defaults to clear the bit.
+ * - mask (u8) defines what bits to change
+ * - bits (u8) is the values to change them to
+ * -> it's
+ * current = (current & ~mask) | bits
+ */
+/* pci ids of devices that wants to have the bit set */
+#define DEVID(_vend,_dev,_subvend,_subdev,mask,bits) { \
+ .vendor = _vend, \
+ .device = _dev, \
+ .subvendor = _subvend, \
+ .subdevice = _subdev, \
+ .driver_data = ((mask) << 8 | (bits)), \
+ }
+static struct pci_device_id ene_tune_tbl[] = {
+ /* Echo Audio products based on motorola DSP56301 and DSP56361 */
+ DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID,
+ ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
+ DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
+ ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
+
+ {}
+};
+
+static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
+{
+ struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+ struct pci_dev *dev;
+ struct pci_device_id *id = NULL;
+ u8 test_c9, old_c9, mask, bits;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ id = (struct pci_device_id *) pci_match_id(ene_tune_tbl, dev);
+ if (id)
+ break;
+ }
+
+ test_c9 = old_c9 = config_readb(socket, ENE_TEST_C9);
+ if (id) {
+ mask = (id->driver_data >> 8) & 0xFF;
+ bits = id->driver_data & 0xFF;
+
+ test_c9 = (test_c9 & ~mask) | bits;
+ }
+ else
+ /* default to clear TLTEnable bit, old behaviour */
+ test_c9 &= ~ENE_TEST_C9_TLTENABLE;
+
+ printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
+ config_writeb(socket, ENE_TEST_C9, test_c9);
+}
+
+static int ene_override(struct yenta_socket *socket)
+{
+ /* install tune_bridge() function */
+ socket->socket.tune_bridge = ene_tune_bridge;
+
+ return ti1250_override(socket);
+}
+#else
+# define ene_override ti1250_override
+#endif
+
#endif /* _LINUX_TI113X_H */
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 0347a29f297b..db9f952f9e3c 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);
}
/*
@@ -553,12 +559,6 @@ static void yenta_interrogate(struct yenta_socket *socket)
static int yenta_sock_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
- u16 bridge;
-
- bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
- if (!socket->cb_irq)
- bridge |= CB_BRIDGE_INTR;
- config_writew(socket, CB_BRIDGE_CONTROL, bridge);
exca_writeb(socket, I365_GBLCTL, 0x00);
exca_writeb(socket, I365_GENCTL, 0x00);
@@ -667,7 +667,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 +676,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 +692,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 +700,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 +728,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 +753,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;
}
}
@@ -818,6 +813,7 @@ enum {
CARDBUS_TYPE_TOPIC95,
CARDBUS_TYPE_TOPIC97,
CARDBUS_TYPE_O2MICRO,
+ CARDBUS_TYPE_ENE,
};
/*
@@ -864,6 +860,12 @@ static struct cardbus_type cardbus_type[] = {
.override = o2micro_override,
.restore_state = o2micro_restore_state,
},
+ [CARDBUS_TYPE_ENE] = {
+ .override = ene_override,
+ .save_state = ti_save_state,
+ .restore_state = ti_restore_state,
+ .sock_init = ti_init,
+ },
};
@@ -882,16 +884,8 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
{
int i;
unsigned long val;
- u16 bridge_ctrl;
u32 mask;
- /* Set up ISA irq routing to probe the ISA irqs.. */
- bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
- if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
- bridge_ctrl |= CB_BRIDGE_INTR;
- config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
- }
-
/*
* Probe for usable interrupts using the force
* register to generate bogus card status events.
@@ -913,9 +907,6 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
mask = probe_irq_mask(val) & 0xffff;
- bridge_ctrl &= ~CB_BRIDGE_INTR;
- config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
-
return mask;
}
@@ -943,18 +934,11 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *re
/* probes the PCI interrupt, use only on override functions */
static int yenta_probe_cb_irq(struct yenta_socket *socket)
{
- u16 bridge_ctrl;
-
if (!socket->cb_irq)
return -1;
socket->probe_status = 0;
- /* disable ISA interrupts */
- bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
- bridge_ctrl &= ~CB_BRIDGE_INTR;
- config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
-
if (request_irq(socket->cb_irq, yenta_probe_handler, SA_SHIRQ, "yenta", socket)) {
printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
return -1;
@@ -965,7 +949,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
-
+
msleep(100);
/* disable interrupts */
@@ -1003,11 +987,12 @@ static void yenta_config_init(struct yenta_socket *socket)
{
u16 bridge;
struct pci_dev *dev = socket->dev;
+ struct pci_bus_region region;
- pci_set_power_state(socket->dev, 0);
+ pcibios_resource_to_bus(socket->dev, &region, &dev->resource[0]);
config_writel(socket, CB_LEGACY_MODE_BASE, 0);
- config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
+ config_writel(socket, PCI_BASE_ADDRESS_0, region.start);
config_writew(socket, PCI_COMMAND,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
@@ -1030,8 +1015,8 @@ static void yenta_config_init(struct yenta_socket *socket)
* - PCI interrupts enabled if a PCI interrupt exists..
*/
bridge = config_readw(socket, CB_BRIDGE_CONTROL);
- bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
- bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN | CB_BRIDGE_INTR;
+ bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
+ bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
config_writew(socket, CB_BRIDGE_CONTROL, bridge);
}
@@ -1044,7 +1029,18 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
{
struct yenta_socket *socket;
int ret;
-
+
+ /*
+ * If we failed to assign proper bus numbers for this cardbus
+ * controller during PCI probe, its subordinate pci_bus is NULL.
+ * Bail out if so.
+ */
+ if (!dev->subordinate) {
+ printk(KERN_ERR "Yenta: no bus associated with %s! "
+ "(try 'pci=assign-busses')\n", pci_name(dev));
+ return -ENODEV;
+ }
+
socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
if (!socket)
return -ENOMEM;
@@ -1253,10 +1249,22 @@ static struct pci_device_id yenta_table [] = {
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, TI12XX),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, TI12XX),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, TI1250),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X515, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X420, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X620, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7410, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7510, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7610, TI12XX),
+
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, TI12XX),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, TI12XX),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, TI12XX),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, TI12XX),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
diff --git a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
index 6776308a1fe5..c5143201419a 100644
--- a/drivers/pnp/Kconfig
+++ b/drivers/pnp/Kconfig
@@ -6,7 +6,7 @@ menu "Plug and Play support"
config PNP
bool "Plug and Play support"
- depends on ISA || ACPI_BUS
+ depends on ISA || ACPI
---help---
Plug and Play (PnP) is a standard for peripherals which allows those
peripherals to be configured by software, e.g. assign IRQ's or other
diff --git a/drivers/pnp/pnpacpi/Kconfig b/drivers/pnp/pnpacpi/Kconfig
index 0782cdc5009f..b1854171b963 100644
--- a/drivers/pnp/pnpacpi/Kconfig
+++ b/drivers/pnp/pnpacpi/Kconfig
@@ -3,7 +3,7 @@
#
config PNPACPI
bool "Plug and Play ACPI support (EXPERIMENTAL)"
- depends on PNP && ACPI_BUS && EXPERIMENTAL
+ depends on PNP && ACPI && EXPERIMENTAL
default y
---help---
Linux uses the PNPACPI to autodetect built-in
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 675b76a42403..416d30debe6c 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -73,25 +73,35 @@ static void decode_irq_flags(int flag, int *edge_level, int *active_high_low)
}
static void
-pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, int irq)
+pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi,
+ int edge_level, int active_high_low)
{
int i = 0;
+ int irq;
+
+ if (!valid_IRQ(gsi))
+ return;
+
while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
i < PNP_MAX_IRQ)
i++;
- if (i < PNP_MAX_IRQ) {
- res->irq_resource[i].flags = IORESOURCE_IRQ; //Also clears _UNSET flag
- if (irq == -1) {
- res->irq_resource[i].flags |= IORESOURCE_DISABLED;
- return;
- }
- res->irq_resource[i].start =(unsigned long) irq;
- res->irq_resource[i].end = (unsigned long) irq;
+ if (i >= PNP_MAX_IRQ)
+ return;
+
+ res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
+ irq = acpi_register_gsi(gsi, edge_level, active_high_low);
+ if (irq < 0) {
+ res->irq_resource[i].flags |= IORESOURCE_DISABLED;
+ return;
}
+
+ res->irq_resource[i].start = irq;
+ res->irq_resource[i].end = irq;
+ pcibios_penalize_isa_irq(irq, 1);
}
static void
-pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
+pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, u32 dma)
{
int i = 0;
while (i < PNP_MAX_DMA &&
@@ -103,14 +113,14 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
res->dma_resource[i].flags |= IORESOURCE_DISABLED;
return;
}
- res->dma_resource[i].start =(unsigned long) dma;
- res->dma_resource[i].end = (unsigned long) dma;
+ res->dma_resource[i].start = dma;
+ res->dma_resource[i].end = dma;
}
}
static void
pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res,
- int io, int len)
+ u32 io, u32 len)
{
int i = 0;
while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
@@ -122,14 +132,14 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res,
res->port_resource[i].flags |= IORESOURCE_DISABLED;
return;
}
- res->port_resource[i].start = (unsigned long) io;
- res->port_resource[i].end = (unsigned long)(io + len - 1);
+ res->port_resource[i].start = io;
+ res->port_resource[i].end = io + len - 1;
}
}
static void
pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res,
- int mem, int len)
+ u64 mem, u64 len)
{
int i = 0;
while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
@@ -141,8 +151,8 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res,
res->mem_resource[i].flags |= IORESOURCE_DISABLED;
return;
}
- res->mem_resource[i].start = (unsigned long) mem;
- res->mem_resource[i].end = (unsigned long)(mem + len - 1);
+ res->mem_resource[i].start = mem;
+ res->mem_resource[i].end = mem + len - 1;
}
}
@@ -151,27 +161,28 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
void *data)
{
struct pnp_resource_table * res_table = (struct pnp_resource_table *)data;
+ int i;
switch (res->id) {
case ACPI_RSTYPE_IRQ:
- if ((res->data.irq.number_of_interrupts > 0) &&
- valid_IRQ(res->data.irq.interrupts[0])) {
- pnpacpi_parse_allocated_irqresource(res_table,
- acpi_register_gsi(res->data.irq.interrupts[0],
- res->data.irq.edge_level,
- res->data.irq.active_high_low));
- pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1);
+ /*
+ * Per spec, only one interrupt per descriptor is allowed in
+ * _CRS, but some firmware violates this, so parse them all.
+ */
+ for (i = 0; i < res->data.irq.number_of_interrupts; i++) {
+ pnpacpi_parse_allocated_irqresource(res_table,
+ res->data.irq.interrupts[i],
+ res->data.irq.edge_level,
+ res->data.irq.active_high_low);
}
break;
case ACPI_RSTYPE_EXT_IRQ:
- if ((res->data.extended_irq.number_of_interrupts > 0) &&
- valid_IRQ(res->data.extended_irq.interrupts[0])) {
- pnpacpi_parse_allocated_irqresource(res_table,
- acpi_register_gsi(res->data.extended_irq.interrupts[0],
- res->data.extended_irq.edge_level,
- res->data.extended_irq.active_high_low));
- pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1);
+ for (i = 0; i < res->data.extended_irq.number_of_interrupts; i++) {
+ pnpacpi_parse_allocated_irqresource(res_table,
+ res->data.extended_irq.interrupts[i],
+ res->data.extended_irq.edge_level,
+ res->data.extended_irq.active_high_low);
}
break;
case ACPI_RSTYPE_DMA:
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index aac83ce6469c..a1c52a682191 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -1,7 +1,7 @@
/*
* drivers/s390/cio/blacklist.c
* S/390 common I/O routines -- blacklisting of specific devices
- * $Revision: 1.34 $
+ * $Revision: 1.35 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
@@ -35,7 +35,7 @@
*/
/* 65536 bits to indicate if a devno is blacklisted or not */
-#define __BL_DEV_WORDS (__MAX_SUBCHANNELS + (8*sizeof(long) - 1) / \
+#define __BL_DEV_WORDS ((__MAX_SUBCHANNELS + (8*sizeof(long) - 1)) / \
(8*sizeof(long)))
static unsigned long bl_dev[__BL_DEV_WORDS];
typedef enum {add, free} range_action;
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 91ea8e4777f3..dbb3eb0e330b 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -437,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
if (cdev->dev.driver_data) {
gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
if (get_device(&gdev->dev)) {
- if (klist_node_attached(&gdev->dev.knode_bus))
+ if (device_is_registered(&gdev->dev))
return gdev;
put_device(&gdev->dev);
}
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 14c76f5e4177..9adc11e8b8bc 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -544,7 +544,7 @@ get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
.sibling = sibling,
};
- dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
+ dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
return dev ? to_ccwdev(dev) : NULL;
}
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 6aeef3bacc33..0cb47eca91f3 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -682,9 +682,6 @@ z90crypt_cleanup_module(void)
del_timer(&config_timer);
del_timer(&cleanup_timer);
- if (z90_device_work)
- destroy_workqueue(z90_device_work);
-
destroy_z90crypt();
PRINTKN("Unloaded.\n");
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 96ca863eaff2..0db4f57a6a95 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1,5 +1,5 @@
/*
- * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $
+ * $Id: ctcmain.c,v 1.78 2005/09/07 12:18:02 pavlic Exp $
*
* CTC / ESCON network driver
*
@@ -37,10 +37,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.78 $
*
*/
-
#undef DEBUG
#include <linux/module.h>
#include <linux/init.h>
@@ -135,7 +134,7 @@ static const char *dev_event_names[] = {
"TX down",
"Restart",
};
-
+
/**
* Events of the channel statemachine
*/
@@ -249,7 +248,7 @@ static void
print_banner(void)
{
static int printed = 0;
- char vbuf[] = "$Revision: 1.74 $";
+ char vbuf[] = "$Revision: 1.78 $";
char *version = vbuf;
if (printed)
@@ -334,7 +333,7 @@ static const char *ch_state_names[] = {
"Restarting",
"Not operational",
};
-
+
#ifdef DEBUG
/**
* Dump header and first 16 bytes of an sk_buff for debugging purposes.
@@ -671,7 +670,7 @@ static void
fsm_action_nop(fsm_instance * fi, int event, void *arg)
{
}
-
+
/**
* Actions for channel - statemachines.
*****************************************************************************/
@@ -1514,7 +1513,6 @@ ch_action_reinit(fsm_instance *fi, int event, void *arg)
fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
}
-
/**
* The statemachine for a channel.
*/
@@ -1625,7 +1623,7 @@ static const fsm_node ch_fsm[] = {
};
static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node);
-
+
/**
* Functions related to setup and device detection.
*****************************************************************************/
@@ -1976,7 +1974,7 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
fsm_event(ch->fsm, CH_EVENT_IRQ, ch);
}
-
+
/**
* Actions for interface - statemachine.
*****************************************************************************/
@@ -2209,13 +2207,18 @@ transmit_skb(struct channel *ch, struct sk_buff *skb)
int rc = 0;
DBF_TEXT(trace, 5, __FUNCTION__);
+ /* we need to acquire the lock for testing the state
+ * otherwise we can have an IRQ changing the state to
+ * TXIDLE after the test but before acquiring the lock.
+ */
+ spin_lock_irqsave(&ch->collect_lock, saveflags);
if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
int l = skb->len + LL_HEADER_LENGTH;
- spin_lock_irqsave(&ch->collect_lock, saveflags);
- if (ch->collect_len + l > ch->max_bufsize - 2)
- rc = -EBUSY;
- else {
+ if (ch->collect_len + l > ch->max_bufsize - 2) {
+ spin_unlock_irqrestore(&ch->collect_lock, saveflags);
+ return -EBUSY;
+ } else {
atomic_inc(&skb->users);
header.length = l;
header.type = skb->protocol;
@@ -2231,7 +2234,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb)
int ccw_idx;
struct sk_buff *nskb;
unsigned long hi;
-
+ spin_unlock_irqrestore(&ch->collect_lock, saveflags);
/**
* Protect skb against beeing free'd by upper
* layers.
@@ -2256,6 +2259,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb)
if (!nskb) {
atomic_dec(&skb->users);
skb_pull(skb, LL_HEADER_LENGTH + 2);
+ ctc_clear_busy(ch->netdev);
return -ENOMEM;
} else {
memcpy(skb_put(nskb, skb->len),
@@ -2281,6 +2285,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb)
*/
atomic_dec(&skb->users);
skb_pull(skb, LL_HEADER_LENGTH + 2);
+ ctc_clear_busy(ch->netdev);
return -EBUSY;
}
@@ -2327,9 +2332,10 @@ transmit_skb(struct channel *ch, struct sk_buff *skb)
}
}
+ ctc_clear_busy(ch->netdev);
return rc;
}
-
+
/**
* Interface API for upper network layers
*****************************************************************************/
@@ -2421,7 +2427,6 @@ ctc_tx(struct sk_buff *skb, struct net_device * dev)
dev->trans_start = jiffies;
if (transmit_skb(privptr->channel[WRITE], skb) != 0)
rc = 1;
- ctc_clear_busy(dev);
return rc;
}
@@ -2610,7 +2615,6 @@ stats_write(struct device *dev, struct device_attribute *attr, const char *buf,
return count;
}
-
static void
ctc_netdev_unregister(struct net_device * dev)
{
@@ -2685,7 +2689,6 @@ ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *b
return count;
}
-
static ssize_t
ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index fa09440d82e5..38f50b7129a2 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -16,7 +16,7 @@ MODULE_LICENSE("GPL");
fsm_instance *
init_fsm(char *name, const char **state_names, const char **event_names, int nr_states,
- int nr_events, const fsm_node *tmpl, int tmpl_len, int order)
+ int nr_events, const fsm_node *tmpl, int tmpl_len, gfp_t order)
{
int i;
fsm_instance *this;
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index f9a011001eb6..1b8a7e7c34f3 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -110,7 +110,7 @@ extern fsm_instance *
init_fsm(char *name, const char **state_names,
const char **event_names,
int nr_states, int nr_events, const fsm_node *tmpl,
- int tmpl_len, int order);
+ int tmpl_len, gfp_t order);
/**
* Releases an FSM
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 3a0285669adf..38a2441564d7 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -24,7 +24,7 @@
#include "qeth_mpc.h"
-#define VERSION_QETH_H "$Revision: 1.139 $"
+#define VERSION_QETH_H "$Revision: 1.142 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
@@ -275,6 +275,10 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \
QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \
QETH_MAX_QUEUES,0x103}, \
+ {0x1731,0x06,0x1732,0x06,QETH_CARD_TYPE_OSN,0, \
+ QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
+ QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
+ QETH_MAX_QUEUES,0}, \
{0,0,0,0,0,0,0,0,0}}
#define QETH_REAL_CARD 1
@@ -363,10 +367,22 @@ struct qeth_hdr_layer2 {
__u8 reserved2[16];
} __attribute__ ((packed));
+struct qeth_hdr_osn {
+ __u8 id;
+ __u8 reserved;
+ __u16 seq_no;
+ __u16 reserved2;
+ __u16 control_flags;
+ __u16 pdu_length;
+ __u8 reserved3[18];
+ __u32 ccid;
+} __attribute__ ((packed));
+
struct qeth_hdr {
union {
struct qeth_hdr_layer2 l2;
struct qeth_hdr_layer3 l3;
+ struct qeth_hdr_osn osn;
} hdr;
} __attribute__ ((packed));
@@ -413,6 +429,7 @@ enum qeth_header_ids {
QETH_HEADER_TYPE_LAYER3 = 0x01,
QETH_HEADER_TYPE_LAYER2 = 0x02,
QETH_HEADER_TYPE_TSO = 0x03,
+ QETH_HEADER_TYPE_OSN = 0x04,
};
/* flags for qeth_hdr.ext_flags */
#define QETH_HDR_EXT_VLAN_FRAME 0x01
@@ -582,7 +599,6 @@ enum qeth_card_states {
* Protocol versions
*/
enum qeth_prot_versions {
- QETH_PROT_SNA = 0x0001,
QETH_PROT_IPV4 = 0x0004,
QETH_PROT_IPV6 = 0x0006,
};
@@ -686,6 +702,7 @@ struct qeth_seqno {
__u32 pdu_hdr;
__u32 pdu_hdr_ack;
__u16 ipa;
+ __u32 pkt_seqno;
};
struct qeth_reply {
@@ -760,6 +777,11 @@ enum qeth_threads {
QETH_RECOVER_THREAD = 2,
};
+struct qeth_osn_info {
+ int (*assist_cb)(struct net_device *dev, void *data);
+ int (*data_cb)(struct sk_buff *skb);
+};
+
struct qeth_card {
struct list_head list;
enum qeth_card_states state;
@@ -802,6 +824,7 @@ struct qeth_card {
int use_hard_stop;
int (*orig_hard_header)(struct sk_buff *,struct net_device *,
unsigned short,void *,void *,unsigned);
+ struct qeth_osn_info osn_info;
};
struct qeth_card_list_struct {
@@ -848,6 +871,7 @@ qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size)
"on interface %s", QETH_CARD_IFNAME(card));
return -ENOMEM;
}
+ kfree_skb(*skb);
*skb = new_skb;
}
return 0;
@@ -914,10 +938,12 @@ qeth_get_hlen(__u8 link_type)
static inline unsigned short
qeth_get_netdev_flags(struct qeth_card *card)
{
- if (card->options.layer2)
+ if (card->options.layer2 &&
+ (card->info.type == QETH_CARD_TYPE_OSAE))
return 0;
switch (card->info.type) {
case QETH_CARD_TYPE_IQD:
+ case QETH_CARD_TYPE_OSN:
return IFF_NOARP;
#ifdef CONFIG_QETH_IPV6
default:
@@ -954,9 +980,10 @@ static inline int
qeth_get_max_mtu_for_card(int cardtype)
{
switch (cardtype) {
+
case QETH_CARD_TYPE_UNKNOWN:
- return 61440;
case QETH_CARD_TYPE_OSAE:
+ case QETH_CARD_TYPE_OSN:
return 61440;
case QETH_CARD_TYPE_IQD:
return 57344;
@@ -1002,6 +1029,7 @@ qeth_mtu_is_valid(struct qeth_card * card, int mtu)
case QETH_CARD_TYPE_IQD:
return ((mtu >= 576) &&
(mtu <= card->info.max_mtu + 4096 - 32));
+ case QETH_CARD_TYPE_OSN:
case QETH_CARD_TYPE_UNKNOWN:
default:
return 1;
@@ -1013,6 +1041,7 @@ qeth_get_arphdr_type(int cardtype, int linktype)
{
switch (cardtype) {
case QETH_CARD_TYPE_OSAE:
+ case QETH_CARD_TYPE_OSN:
switch (linktype) {
case QETH_LINK_TYPE_LANE_TR:
case QETH_LINK_TYPE_HSTR:
@@ -1172,7 +1201,7 @@ extern int
qeth_realloc_buffer_pool(struct qeth_card *, int);
extern int
-qeth_set_large_send(struct qeth_card *);
+qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
extern void
qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
@@ -1180,4 +1209,16 @@ qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
extern void
qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int);
+extern int
+qeth_osn_assist(struct net_device *, void *, int);
+
+extern int
+qeth_osn_register(unsigned char *read_dev_no,
+ struct net_device **,
+ int (*assist_cb)(struct net_device *, void *),
+ int (*data_cb)(struct sk_buff *));
+
+extern void
+qeth_osn_deregister(struct net_device *);
+
#endif /* __QETH_H__ */
diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h
index 5c9a51ce91b6..c0b4c8d82c45 100644
--- a/drivers/s390/net/qeth_fs.h
+++ b/drivers/s390/net/qeth_fs.h
@@ -12,7 +12,7 @@
#ifndef __QETH_FS_H__
#define __QETH_FS_H__
-#define VERSION_QETH_FS_H "$Revision: 1.9 $"
+#define VERSION_QETH_FS_H "$Revision: 1.10 $"
extern const char *VERSION_QETH_PROC_C;
extern const char *VERSION_QETH_SYS_C;
@@ -43,6 +43,12 @@ extern void
qeth_remove_device_attributes(struct device *dev);
extern int
+qeth_create_device_attributes_osn(struct device *dev);
+
+extern void
+qeth_remove_device_attributes_osn(struct device *dev);
+
+extern int
qeth_create_driver_attributes(void);
extern void
@@ -108,6 +114,8 @@ qeth_get_cardname(struct qeth_card *card)
return " OSD Express";
case QETH_CARD_TYPE_IQD:
return " HiperSockets";
+ case QETH_CARD_TYPE_OSN:
+ return " OSN QDIO";
default:
return " unknown";
}
@@ -153,6 +161,8 @@ qeth_get_cardname_short(struct qeth_card *card)
}
case QETH_CARD_TYPE_IQD:
return "HiperSockets";
+ case QETH_CARD_TYPE_OSN:
+ return "OSN";
default:
return "unknown";
}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 79c74f3a11f5..692003c9f896 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $)
*
* Linux on zSeries OSA Express and HiperSockets support
*
@@ -12,7 +12,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com>
*
- * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $
+ * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $
*
* 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
@@ -29,14 +29,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/***
- * eye catcher; just for debugging purposes
- */
-void volatile
-qeth_eyecatcher(void)
-{
- return;
-}
#include <linux/config.h>
#include <linux/module.h>
@@ -80,7 +72,7 @@ qeth_eyecatcher(void)
#include "qeth_eddp.h"
#include "qeth_tso.h"
-#define VERSION_QETH_C "$Revision: 1.214 $"
+#define VERSION_QETH_C "$Revision: 1.224 $"
static const char *version = "qeth S/390 OSA-Express driver";
/**
@@ -204,7 +196,6 @@ qeth_notifier_register(struct task_struct *p, int signum)
{
struct qeth_notify_list_struct *n_entry;
-
/*check first if entry already exists*/
spin_lock(&qeth_notify_lock);
list_for_each_entry(n_entry, &qeth_notify_list, list) {
@@ -519,7 +510,7 @@ static int
__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
{
struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
- int rc = 0;
+ int rc = 0, rc2 = 0, rc3 = 0;
enum qeth_card_states recover_flag;
QETH_DBF_TEXT(setup, 3, "setoffl");
@@ -531,11 +522,13 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
CARD_BUS_ID(card));
return -ERESTARTSYS;
}
- if ((rc = ccw_device_set_offline(CARD_DDEV(card))) ||
- (rc = ccw_device_set_offline(CARD_WDEV(card))) ||
- (rc = ccw_device_set_offline(CARD_RDEV(card)))) {
+ rc = ccw_device_set_offline(CARD_DDEV(card));
+ rc2 = ccw_device_set_offline(CARD_WDEV(card));
+ rc3 = ccw_device_set_offline(CARD_RDEV(card));
+ if (!rc)
+ rc = (rc2) ? rc2 : rc3;
+ if (rc)
QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
- }
if (recover_flag == CARD_STATE_UP)
card->state = CARD_STATE_RECOVER;
qeth_notify_processes();
@@ -1030,7 +1023,10 @@ qeth_set_intial_options(struct qeth_card *card)
card->options.fake_broadcast = 0;
card->options.add_hhlen = DEFAULT_ADD_HHLEN;
card->options.fake_ll = 0;
- card->options.layer2 = 0;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ card->options.layer2 = 1;
+ else
+ card->options.layer2 = 0;
}
/**
@@ -1054,6 +1050,7 @@ qeth_setup_card(struct qeth_card *card)
spin_lock_init(&card->vlanlock);
card->vlangrp = NULL;
#endif
+ spin_lock_init(&card->lock);
spin_lock_init(&card->ip_lock);
spin_lock_init(&card->thread_mask_lock);
card->thread_start_mask = 0;
@@ -1118,19 +1115,20 @@ qeth_determine_card_type(struct qeth_card *card)
QETH_DBF_TEXT(setup, 2, "detcdtyp");
+ card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
+ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
while (known_devices[i][4]) {
if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
(CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
card->info.type = known_devices[i][4];
+ card->qdio.no_out_queues = known_devices[i][8];
+ card->info.is_multicast_different = known_devices[i][9];
if (is_1920_device(card)) {
PRINT_INFO("Priority Queueing not able "
"due to hardware limitations!\n");
card->qdio.no_out_queues = 1;
card->qdio.default_out_queue = 0;
- } else {
- card->qdio.no_out_queues = known_devices[i][8];
- }
- card->info.is_multicast_different = known_devices[i][9];
+ }
return 0;
}
i++;
@@ -1154,6 +1152,8 @@ qeth_probe_device(struct ccwgroup_device *gdev)
if (!get_device(dev))
return -ENODEV;
+ QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
+
card = qeth_alloc_card();
if (!card) {
put_device(dev);
@@ -1163,28 +1163,27 @@ qeth_probe_device(struct ccwgroup_device *gdev)
card->read.ccwdev = gdev->cdev[0];
card->write.ccwdev = gdev->cdev[1];
card->data.ccwdev = gdev->cdev[2];
-
- if ((rc = qeth_setup_card(card))){
- QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
- put_device(dev);
- qeth_free_card(card);
- return rc;
- }
gdev->dev.driver_data = card;
card->gdev = gdev;
gdev->cdev[0]->handler = qeth_irq;
gdev->cdev[1]->handler = qeth_irq;
gdev->cdev[2]->handler = qeth_irq;
- rc = qeth_create_device_attributes(dev);
- if (rc) {
+ if ((rc = qeth_determine_card_type(card))){
+ PRINT_WARN("%s: not a valid card type\n", __func__);
+ QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
+ put_device(dev);
+ qeth_free_card(card);
+ return rc;
+ }
+ if ((rc = qeth_setup_card(card))){
+ QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
put_device(dev);
qeth_free_card(card);
return rc;
}
- if ((rc = qeth_determine_card_type(card))){
- PRINT_WARN("%s: not a valid card type\n", __func__);
- QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
+ rc = qeth_create_device_attributes(dev);
+ if (rc) {
put_device(dev);
qeth_free_card(card);
return rc;
@@ -1634,16 +1633,6 @@ qeth_cmd_timeout(unsigned long data)
spin_unlock_irqrestore(&reply->card->lock, flags);
}
-static void
-qeth_reset_ip_addresses(struct qeth_card *card)
-{
- QETH_DBF_TEXT(trace, 2, "rstipadd");
-
- qeth_clear_ip_list(card, 0, 1);
- /* this function will also schedule the SET_IP_THREAD */
- qeth_set_multicast_list(card->dev);
-}
-
static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{
@@ -1672,10 +1661,11 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
"IP address reset.\n",
QETH_CARD_IFNAME(card),
card->info.chpid);
- card->lan_online = 1;
netif_carrier_on(card->dev);
- qeth_reset_ip_addresses(card);
+ qeth_schedule_recovery(card);
return NULL;
+ case IPA_CMD_MODCCID:
+ return cmd;
case IPA_CMD_REGISTER_LOCAL_ADDR:
QETH_DBF_TEXT(trace,3, "irla");
break;
@@ -1737,6 +1727,14 @@ qeth_send_control_data_cb(struct qeth_channel *channel,
cmd = qeth_check_ipa_data(card, iob);
if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
goto out;
+ /*in case of OSN : check if cmd is set */
+ if (card->info.type == QETH_CARD_TYPE_OSN &&
+ cmd &&
+ cmd->hdr.command != IPA_CMD_STARTLAN &&
+ card->osn_info.assist_cb != NULL) {
+ card->osn_info.assist_cb(card->dev, cmd);
+ goto out;
+ }
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
@@ -1753,8 +1751,7 @@ qeth_send_control_data_cb(struct qeth_channel *channel,
keep_reply = reply->callback(card,
reply,
(unsigned long)cmd);
- }
- else
+ } else
keep_reply = reply->callback(card,
reply,
(unsigned long)iob);
@@ -1784,6 +1781,24 @@ out:
qeth_release_buffer(channel,iob);
}
+static inline void
+qeth_prepare_control_data(struct qeth_card *card, int len,
+struct qeth_cmd_buffer *iob)
+{
+ qeth_setup_ccw(&card->write,iob->data,len);
+ iob->callback = qeth_release_buffer;
+
+ memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
+ &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
+ card->seqno.trans_hdr++;
+ memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
+ &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
+ card->seqno.pdu_hdr++;
+ memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
+ &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
+ QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
+}
+
static int
qeth_send_control_data(struct qeth_card *card, int len,
struct qeth_cmd_buffer *iob,
@@ -1794,24 +1809,11 @@ qeth_send_control_data(struct qeth_card *card, int len,
{
int rc;
unsigned long flags;
- struct qeth_reply *reply;
+ struct qeth_reply *reply = NULL;
struct timer_list timer;
QETH_DBF_TEXT(trace, 2, "sendctl");
- qeth_setup_ccw(&card->write,iob->data,len);
-
- memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
- &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
- card->seqno.trans_hdr++;
-
- memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
- &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
- card->seqno.pdu_hdr++;
- memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
- &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
- iob->callback = qeth_release_buffer;
-
reply = qeth_alloc_reply(card);
if (!reply) {
PRINT_WARN("Could no alloc qeth_reply!\n");
@@ -1826,10 +1828,6 @@ qeth_send_control_data(struct qeth_card *card, int len,
init_timer(&timer);
timer.function = qeth_cmd_timeout;
timer.data = (unsigned long) reply;
- if (IS_IPA(iob->data))
- timer.expires = jiffies + QETH_IPA_TIMEOUT;
- else
- timer.expires = jiffies + QETH_TIMEOUT;
init_waitqueue_head(&reply->wait_q);
spin_lock_irqsave(&card->lock, flags);
list_add_tail(&reply->list, &card->cmd_waiter_list);
@@ -1837,6 +1835,11 @@ qeth_send_control_data(struct qeth_card *card, int len,
QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
wait_event(card->wait_q,
atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
+ qeth_prepare_control_data(card, len, iob);
+ if (IS_IPA(iob->data))
+ timer.expires = jiffies + QETH_IPA_TIMEOUT;
+ else
+ timer.expires = jiffies + QETH_TIMEOUT;
QETH_DBF_TEXT(trace, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
@@ -1864,6 +1867,62 @@ qeth_send_control_data(struct qeth_card *card, int len,
}
static int
+qeth_osn_send_control_data(struct qeth_card *card, int len,
+ struct qeth_cmd_buffer *iob)
+{
+ unsigned long flags;
+ int rc = 0;
+
+ QETH_DBF_TEXT(trace, 5, "osndctrd");
+
+ wait_event(card->wait_q,
+ atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
+ qeth_prepare_control_data(card, len, iob);
+ QETH_DBF_TEXT(trace, 6, "osnoirqp");
+ spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
+ rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
+ (addr_t) iob, 0, 0);
+ spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
+ if (rc){
+ PRINT_WARN("qeth_osn_send_control_data: "
+ "ccw_device_start rc = %i\n", rc);
+ QETH_DBF_TEXT_(trace, 2, " err%d", rc);
+ qeth_release_buffer(iob->channel, iob);
+ atomic_set(&card->write.irq_pending, 0);
+ wake_up(&card->wait_q);
+ }
+ return rc;
+}
+
+static inline void
+qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ char prot_type)
+{
+ memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
+ memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
+ memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
+ &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
+}
+
+static int
+qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ int data_len)
+{
+ u16 s1, s2;
+
+QETH_DBF_TEXT(trace,4,"osndipa");
+
+ qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
+ s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
+ s2 = (u16)data_len;
+ memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
+ return qeth_osn_send_control_data(card, s1, iob);
+}
+
+static int
qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
int (*reply_cb)
(struct qeth_card *,struct qeth_reply*, unsigned long),
@@ -1874,17 +1933,14 @@ qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
QETH_DBF_TEXT(trace,4,"sendipa");
- memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
-
if (card->options.layer2)
- prot_type = QETH_PROT_LAYER2;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ prot_type = QETH_PROT_OSN2;
+ else
+ prot_type = QETH_PROT_LAYER2;
else
prot_type = QETH_PROT_TCPIP;
-
- memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
- memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
- &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
-
+ qeth_prepare_ipa_cmd(card,iob,prot_type);
rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
reply_cb, reply_param);
return rc;
@@ -2026,7 +2082,10 @@ qeth_ulp_enable(struct qeth_card *card)
*(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
(__u8) card->info.portno;
if (card->options.layer2)
- prot_type = QETH_PROT_LAYER2;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ prot_type = QETH_PROT_OSN2;
+ else
+ prot_type = QETH_PROT_LAYER2;
else
prot_type = QETH_PROT_TCPIP;
@@ -2116,15 +2175,21 @@ qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf,
}
static inline struct sk_buff *
-qeth_get_skb(unsigned int length)
+qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
{
struct sk_buff* skb;
+ int add_len;
+
+ add_len = 0;
+ if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN)
+ add_len = sizeof(struct qeth_hdr);
#ifdef CONFIG_QETH_VLAN
- if ((skb = dev_alloc_skb(length + VLAN_HLEN)))
- skb_reserve(skb, VLAN_HLEN);
-#else
- skb = dev_alloc_skb(length);
+ else
+ add_len = VLAN_HLEN;
#endif
+ skb = dev_alloc_skb(length + add_len);
+ if (skb && add_len)
+ skb_reserve(skb, add_len);
return skb;
}
@@ -2154,7 +2219,10 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
offset += sizeof(struct qeth_hdr);
if (card->options.layer2)
- skb_len = (*hdr)->hdr.l2.pkt_length;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ skb_len = (*hdr)->hdr.osn.pdu_length;
+ else
+ skb_len = (*hdr)->hdr.l2.pkt_length;
else
skb_len = (*hdr)->hdr.l3.length;
@@ -2162,15 +2230,15 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
return NULL;
if (card->options.fake_ll){
if(card->dev->type == ARPHRD_IEEE802_TR){
- if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR)))
+ if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR, *hdr)))
goto no_mem;
skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
} else {
- if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH)))
+ if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH, *hdr)))
goto no_mem;
skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
}
- } else if (!(skb = qeth_get_skb(skb_len)))
+ } else if (!(skb = qeth_get_skb(skb_len, *hdr)))
goto no_mem;
data_ptr = element->addr + offset;
while (skb_len) {
@@ -2395,6 +2463,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
skb_pull(skb, VLAN_HLEN);
}
#endif
+ *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
return vlan_id;
}
@@ -2468,8 +2537,12 @@ qeth_process_inbound_buffer(struct qeth_card *card,
skb->dev = card->dev;
if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
- else
+ else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
qeth_rebuild_skb(card, skb, hdr);
+ else { /*in case of OSN*/
+ skb_push(skb, sizeof(struct qeth_hdr));
+ memcpy(skb->data, hdr, sizeof(struct qeth_hdr));
+ }
/* is device UP ? */
if (!(card->dev->flags & IFF_UP)){
dev_kfree_skb_any(skb);
@@ -2480,7 +2553,10 @@ qeth_process_inbound_buffer(struct qeth_card *card,
vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
else
#endif
- rxrc = netif_rx(skb);
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ rxrc = card->osn_info.data_cb(skb);
+ else
+ rxrc = netif_rx(skb);
card->dev->last_rx = jiffies;
card->stats.rx_packets++;
card->stats.rx_bytes += skb->len;
@@ -2759,11 +2835,9 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
queue->card->perf_stats.outbound_do_qdio_start_time;
#endif
if (rc){
- QETH_DBF_SPRINTF(trace, 0, "qeth_flush_buffers: do_QDIO "
- "returned error (%i) on device %s.",
- rc, CARD_DDEV_ID(queue->card));
QETH_DBF_TEXT(trace, 2, "flushbuf");
QETH_DBF_TEXT_(trace, 2, " err%d", rc);
+ QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card));
queue->card->stats.tx_errors += count;
/* this must not happen under normal circumstances. if it
* happens something is really wrong -> recover */
@@ -2909,11 +2983,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
QETH_DBF_TEXT(trace, 6, "qdouhdl");
if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
- QETH_DBF_SPRINTF(trace, 2, "On device %s: "
- "received active check "
- "condition (0x%08x).",
- CARD_BUS_ID(card), status);
- QETH_DBF_TEXT(trace, 2, "chkcond");
+ QETH_DBF_TEXT(trace, 2, "achkcond");
+ QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
QETH_DBF_TEXT_(trace, 2, "%08x", status);
netif_stop_queue(card->dev);
qeth_schedule_recovery(card);
@@ -3027,7 +3098,7 @@ qeth_alloc_buffer_pool(struct qeth_card *card)
return -ENOMEM;
}
for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){
- ptr = (void *) __get_free_page(GFP_KERNEL);
+ ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA);
if (!ptr) {
while (j > 0)
free_page((unsigned long)
@@ -3071,7 +3142,8 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
if (card->qdio.state == QETH_QDIO_ALLOCATED)
return 0;
- card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), GFP_KERNEL);
+ card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
+ GFP_KERNEL|GFP_DMA);
if (!card->qdio.in_q)
return - ENOMEM;
QETH_DBF_TEXT(setup, 2, "inq");
@@ -3096,7 +3168,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
}
for (i = 0; i < card->qdio.no_out_queues; ++i){
card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
- GFP_KERNEL);
+ GFP_KERNEL|GFP_DMA);
if (!card->qdio.out_qs[i]){
while (i > 0)
kfree(card->qdio.out_qs[--i]);
@@ -3169,8 +3241,6 @@ qeth_init_qdio_info(struct qeth_card *card)
INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
/* outbound */
- card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
- card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
}
static int
@@ -3356,26 +3426,32 @@ qeth_halt_channel(struct qeth_channel *channel)
static int
qeth_halt_channels(struct qeth_card *card)
{
- int rc = 0;
+ int rc1 = 0, rc2=0, rc3 = 0;
QETH_DBF_TEXT(trace,3,"haltchs");
- if ((rc = qeth_halt_channel(&card->read)))
- return rc;
- if ((rc = qeth_halt_channel(&card->write)))
- return rc;
- return qeth_halt_channel(&card->data);
+ rc1 = qeth_halt_channel(&card->read);
+ rc2 = qeth_halt_channel(&card->write);
+ rc3 = qeth_halt_channel(&card->data);
+ if (rc1)
+ return rc1;
+ if (rc2)
+ return rc2;
+ return rc3;
}
static int
qeth_clear_channels(struct qeth_card *card)
{
- int rc = 0;
+ int rc1 = 0, rc2=0, rc3 = 0;
QETH_DBF_TEXT(trace,3,"clearchs");
- if ((rc = qeth_clear_channel(&card->read)))
- return rc;
- if ((rc = qeth_clear_channel(&card->write)))
- return rc;
- return qeth_clear_channel(&card->data);
+ rc1 = qeth_clear_channel(&card->read);
+ rc2 = qeth_clear_channel(&card->write);
+ rc3 = qeth_clear_channel(&card->data);
+ if (rc1)
+ return rc1;
+ if (rc2)
+ return rc2;
+ return rc3;
}
static int
@@ -3445,23 +3521,23 @@ qeth_mpc_initialize(struct qeth_card *card)
}
if ((rc = qeth_cm_enable(card))){
QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
- return rc;
+ goto out_qdio;
}
if ((rc = qeth_cm_setup(card))){
QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
- return rc;
+ goto out_qdio;
}
if ((rc = qeth_ulp_enable(card))){
QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
- return rc;
+ goto out_qdio;
}
if ((rc = qeth_ulp_setup(card))){
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
- return rc;
+ goto out_qdio;
}
if ((rc = qeth_alloc_qdio_buffers(card))){
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
- return rc;
+ goto out_qdio;
}
if ((rc = qeth_qdio_establish(card))){
QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
@@ -3479,7 +3555,7 @@ qeth_mpc_initialize(struct qeth_card *card)
return 0;
out_qdio:
- qeth_qdio_clear_card(card, card->info.type==QETH_CARD_TYPE_OSAE);
+ qeth_qdio_clear_card(card, card->info.type!=QETH_CARD_TYPE_IQD);
return rc;
}
@@ -3504,6 +3580,9 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
case QETH_CARD_TYPE_IQD:
dev = alloc_netdev(0, "hsi%d", ether_setup);
break;
+ case QETH_CARD_TYPE_OSN:
+ dev = alloc_netdev(0, "osn%d", ether_setup);
+ break;
default:
dev = alloc_etherdev(0);
}
@@ -3668,7 +3747,8 @@ qeth_open(struct net_device *dev)
if (card->state != CARD_STATE_SOFTSETUP)
return -ENODEV;
- if ( (card->options.layer2) &&
+ if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
+ (card->options.layer2) &&
(!card->info.layer2_mac_registered)) {
QETH_DBF_TEXT(trace,4,"nomacadr");
return -EPERM;
@@ -3706,6 +3786,9 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
{
int cast_type = RTN_UNSPEC;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return cast_type;
+
if (skb->dst && skb->dst->neighbour){
cast_type = skb->dst->neighbour->type;
if ((cast_type == RTN_BROADCAST) ||
@@ -3795,12 +3878,19 @@ static inline int
qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
struct qeth_hdr **hdr, int ipv)
{
+ int rc = 0;
#ifdef CONFIG_QETH_VLAN
u16 *tag;
#endif
QETH_DBF_TEXT(trace, 6, "prepskb");
-
+ if (card->info.type == QETH_CARD_TYPE_OSN) {
+ *hdr = (struct qeth_hdr *)(*skb)->data;
+ return rc;
+ }
+ rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
+ if (rc)
+ return rc;
#ifdef CONFIG_QETH_VLAN
if (card->vlangrp && vlan_tx_tag_present(*skb) &&
((ipv == 6) || card->options.layer2) ) {
@@ -4251,7 +4341,8 @@ out:
}
static inline int
-qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
+qeth_get_elements_no(struct qeth_card *card, void *hdr,
+ struct sk_buff *skb, int elems)
{
int elements_needed = 0;
@@ -4261,9 +4352,10 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
if (elements_needed == 0 )
elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
+ skb->len) >> PAGE_SHIFT);
- if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){
+ if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
PRINT_ERR("qeth_do_send_packet: invalid size of "
- "IP packet. Discarded.");
+ "IP packet (Number=%d / Length=%d). Discarded.\n",
+ (elements_needed+elems), skb->len);
return 0;
}
return elements_needed;
@@ -4275,7 +4367,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
int ipv = 0;
int cast_type;
struct qeth_qdio_out_q *queue;
- struct qeth_hdr *hdr;
+ struct qeth_hdr *hdr = NULL;
int elements_needed = 0;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
@@ -4298,8 +4390,14 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
}
}
}
+ if ((card->info.type == QETH_CARD_TYPE_OSN) &&
+ (skb->protocol == htons(ETH_P_IPV6))) {
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
cast_type = qeth_get_cast_type(card, skb);
- if ((cast_type == RTN_BROADCAST) && (card->info.broadcast_capable == 0)){
+ if ((cast_type == RTN_BROADCAST) &&
+ (card->info.broadcast_capable == 0)){
card->stats.tx_dropped++;
card->stats.tx_errors++;
dev_kfree_skb_any(skb);
@@ -4327,7 +4425,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
return rc;
}
- qeth_fill_header(card, hdr, skb, ipv, cast_type);
+ if (card->info.type != QETH_CARD_TYPE_OSN)
+ qeth_fill_header(card, hdr, skb, ipv, cast_type);
}
if (large_send == QETH_LARGE_SEND_EDDP) {
@@ -4337,9 +4436,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
return -EINVAL;
}
} else {
- elements_needed += qeth_get_elements_no(card,(void*) hdr, skb);
- if (!elements_needed)
+ int elems = qeth_get_elements_no(card,(void*) hdr, skb,
+ elements_needed);
+ if (!elems)
return -EINVAL;
+ elements_needed += elems;
}
if (card->info.type != QETH_CARD_TYPE_IQD)
@@ -4386,6 +4487,7 @@ qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
case MII_BMCR: /* Basic mode control register */
rc = BMCR_FULLDPLX;
if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&&
+ (card->info.link_type != QETH_LINK_TYPE_OSN) &&
(card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
rc |= BMCR_SPEED100;
break;
@@ -4504,7 +4606,11 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries)
QETH_DBF_TEXT(trace,3,"arpstnoe");
- /* TODO: really not supported by GuestLAN? */
+ /*
+ * currently GuestLAN only supports the ARP assist function
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES;
+ * thus we say EOPNOTSUPP for this ARP function
+ */
if (card->info.guestlan)
return -EOPNOTSUPP;
if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
@@ -4681,14 +4787,6 @@ qeth_arp_query(struct qeth_card *card, char *udata)
QETH_DBF_TEXT(trace,3,"arpquery");
- /*
- * currently GuestLAN does only deliver all zeros on query arp,
- * even though arp processing is supported (according to IPA supp.
- * funcs flags); since all zeros is no valueable information,
- * we say EOPNOTSUPP for all ARP functions
- */
- /*if (card->info.guestlan)
- return -EOPNOTSUPP; */
if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
IPA_ARP_PROCESSING)) {
PRINT_WARN("ARP processing not supported "
@@ -4894,10 +4992,9 @@ qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry)
QETH_DBF_TEXT(trace,3,"arpadent");
/*
- * currently GuestLAN does only deliver all zeros on query arp,
- * even though arp processing is supported (according to IPA supp.
- * funcs flags); since all zeros is no valueable information,
- * we say EOPNOTSUPP for all ARP functions
+ * currently GuestLAN only supports the ARP assist function
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY;
+ * thus we say EOPNOTSUPP for this ARP function
*/
if (card->info.guestlan)
return -EOPNOTSUPP;
@@ -4937,10 +5034,9 @@ qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry
QETH_DBF_TEXT(trace,3,"arprment");
/*
- * currently GuestLAN does only deliver all zeros on query arp,
- * even though arp processing is supported (according to IPA supp.
- * funcs flags); since all zeros is no valueable information,
- * we say EOPNOTSUPP for all ARP functions
+ * currently GuestLAN only supports the ARP assist function
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
+ * thus we say EOPNOTSUPP for this ARP function
*/
if (card->info.guestlan)
return -EOPNOTSUPP;
@@ -4978,11 +5074,10 @@ qeth_arp_flush_cache(struct qeth_card *card)
QETH_DBF_TEXT(trace,3,"arpflush");
/*
- * currently GuestLAN does only deliver all zeros on query arp,
- * even though arp processing is supported (according to IPA supp.
- * funcs flags); since all zeros is no valueable information,
- * we say EOPNOTSUPP for all ARP functions
- */
+ * currently GuestLAN only supports the ARP assist function
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE;
+ * thus we say EOPNOTSUPP for this ARP function
+ */
if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
return -EOPNOTSUPP;
if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
@@ -5016,6 +5111,9 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
(card->state != CARD_STATE_SOFTSETUP))
return -ENODEV;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return -EPERM;
+
switch (cmd){
case SIOC_QETH_ARP_SET_NO_ENTRIES:
if ( !capable(CAP_NET_ADMIN) ||
@@ -5206,7 +5304,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
if (!card->vlangrp)
return;
rcu_read_lock();
- in_dev = __in_dev_get(card->vlangrp->vlan_devices[vid]);
+ in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
if (!in_dev)
goto out;
for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
@@ -5341,6 +5439,9 @@ qeth_set_multicast_list(struct net_device *dev)
{
struct qeth_card *card = (struct qeth_card *) dev->priv;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return ;
+
QETH_DBF_TEXT(trace,3,"setmulti");
qeth_delete_mc_addresses(card);
qeth_add_multicast_ipv4(card);
@@ -5382,6 +5483,94 @@ qeth_get_addr_buffer(enum qeth_prot_versions prot)
return addr;
}
+int
+qeth_osn_assist(struct net_device *dev,
+ void *data,
+ int data_len)
+{
+ struct qeth_cmd_buffer *iob;
+ struct qeth_card *card;
+ int rc;
+
+ QETH_DBF_TEXT(trace, 2, "osnsdmc");
+ if (!dev)
+ return -ENODEV;
+ card = (struct qeth_card *)dev->priv;
+ if (!card)
+ return -ENODEV;
+ if ((card->state != CARD_STATE_UP) &&
+ (card->state != CARD_STATE_SOFTSETUP))
+ return -ENODEV;
+ iob = qeth_wait_for_buffer(&card->write);
+ memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
+ rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
+ return rc;
+}
+
+static struct net_device *
+qeth_netdev_by_devno(unsigned char *read_dev_no)
+{
+ struct qeth_card *card;
+ struct net_device *ndev;
+ unsigned char *readno;
+ __u16 temp_dev_no, card_dev_no;
+ char *endp;
+ unsigned long flags;
+
+ ndev = NULL;
+ memcpy(&temp_dev_no, read_dev_no, 2);
+ read_lock_irqsave(&qeth_card_list.rwlock, flags);
+ list_for_each_entry(card, &qeth_card_list.list, list) {
+ readno = CARD_RDEV_ID(card);
+ readno += (strlen(readno) - 4);
+ card_dev_no = simple_strtoul(readno, &endp, 16);
+ if (card_dev_no == temp_dev_no) {
+ ndev = card->dev;
+ break;
+ }
+ }
+ read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
+ return ndev;
+}
+
+int
+qeth_osn_register(unsigned char *read_dev_no,
+ struct net_device **dev,
+ int (*assist_cb)(struct net_device *, void *),
+ int (*data_cb)(struct sk_buff *))
+{
+ struct qeth_card * card;
+
+ QETH_DBF_TEXT(trace, 2, "osnreg");
+ *dev = qeth_netdev_by_devno(read_dev_no);
+ if (*dev == NULL)
+ return -ENODEV;
+ card = (struct qeth_card *)(*dev)->priv;
+ if (!card)
+ return -ENODEV;
+ if ((assist_cb == NULL) || (data_cb == NULL))
+ return -EINVAL;
+ card->osn_info.assist_cb = assist_cb;
+ card->osn_info.data_cb = data_cb;
+ return 0;
+}
+
+void
+qeth_osn_deregister(struct net_device * dev)
+{
+ struct qeth_card *card;
+
+ QETH_DBF_TEXT(trace, 2, "osndereg");
+ if (!dev)
+ return;
+ card = (struct qeth_card *)dev->priv;
+ if (!card)
+ return;
+ card->osn_info.assist_cb = NULL;
+ card->osn_info.data_cb = NULL;
+ return;
+}
+
static void
qeth_delete_mc_addresses(struct qeth_card *card)
{
@@ -5712,6 +5901,12 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p)
QETH_DBF_TEXT(trace, 3, "setmcLY3");
return -EOPNOTSUPP;
}
+ if (card->info.type == QETH_CARD_TYPE_OSN) {
+ PRINT_WARN("Setting MAC address on %s is not supported.\n",
+ dev->name);
+ QETH_DBF_TEXT(trace, 3, "setmcOSN");
+ return -EOPNOTSUPP;
+ }
QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
@@ -6088,9 +6283,8 @@ qeth_netdev_init(struct net_device *dev)
qeth_get_hlen(card->info.link_type) + card->options.add_hhlen;
dev->addr_len = OSA_ADDR_LEN;
dev->mtu = card->info.initial_mtu;
-
- SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
-
+ if (card->info.type != QETH_CARD_TYPE_OSN)
+ SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
SET_MODULE_OWNER(dev);
return 0;
}
@@ -6107,6 +6301,7 @@ qeth_init_func_level(struct qeth_card *card)
QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
} else {
if (card->info.type == QETH_CARD_TYPE_IQD)
+ /*FIXME:why do we have same values for dis and ena for osae??? */
card->info.func_level =
QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
else
@@ -6136,7 +6331,7 @@ retry:
ccw_device_set_online(CARD_WDEV(card));
ccw_device_set_online(CARD_DDEV(card));
}
- rc = qeth_qdio_clear_card(card,card->info.type==QETH_CARD_TYPE_OSAE);
+ rc = qeth_qdio_clear_card(card,card->info.type!=QETH_CARD_TYPE_IQD);
if (rc == -ERESTARTSYS) {
QETH_DBF_TEXT(setup, 2, "break1");
return rc;
@@ -6188,8 +6383,8 @@ retry:
card->dev = qeth_get_netdevice(card->info.type,
card->info.link_type);
if (!card->dev){
- qeth_qdio_clear_card(card, card->info.type ==
- QETH_CARD_TYPE_OSAE);
+ qeth_qdio_clear_card(card, card->info.type !=
+ QETH_CARD_TYPE_IQD);
rc = -ENODEV;
QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
goto out;
@@ -6476,6 +6671,9 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
+ /* Disable IPV6 support hard coded for Hipersockets */
+ if(card->info.type == QETH_CARD_TYPE_IQD)
+ card->options.ipa4.supported_funcs &= ~IPA_IPV6;
} else {
#ifdef CONFIG_QETH_IPV6
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
@@ -7038,14 +7236,16 @@ qeth_setrouting_v6(struct qeth_card *card)
}
int
-qeth_set_large_send(struct qeth_card *card)
+qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
{
int rc = 0;
- if (card->dev == NULL)
+ if (card->dev == NULL) {
+ card->options.large_send = type;
return 0;
-
+ }
netif_stop_queue(card->dev);
+ card->options.large_send = type;
switch (card->options.large_send) {
case QETH_LARGE_SEND_EDDP:
card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
@@ -7066,7 +7266,6 @@ qeth_set_large_send(struct qeth_card *card)
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
break;
}
-
netif_wake_queue(card->dev);
return rc;
}
@@ -7092,6 +7291,8 @@ qeth_softsetup_card(struct qeth_card *card)
return rc;
} else
card->lan_online = 1;
+ if (card->info.type==QETH_CARD_TYPE_OSN)
+ goto out;
if (card->options.layer2) {
card->dev->features |=
NETIF_F_HW_VLAN_FILTER |
@@ -7263,7 +7464,8 @@ qeth_stop_card(struct qeth_card *card, int recovery_mode)
if (card->read.state == CH_STATE_UP &&
card->write.state == CH_STATE_UP &&
(card->state == CARD_STATE_UP)) {
- if(recovery_mode) {
+ if (recovery_mode &&
+ card->info.type != QETH_CARD_TYPE_OSN) {
qeth_stop(card->dev);
} else {
rtnl_lock();
@@ -7445,7 +7647,8 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
{
QETH_DBF_TEXT(setup ,2, "startag");
- if(recovery_mode) {
+ if (recovery_mode &&
+ card->info.type != QETH_CARD_TYPE_OSN) {
qeth_open(card->dev);
} else {
rtnl_lock();
@@ -7477,33 +7680,36 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
static void qeth_make_parameters_consistent(struct qeth_card *card)
{
- if (card->options.layer2) {
- if (card->info.type == QETH_CARD_TYPE_IQD) {
- PRINT_ERR("Device %s does not support " \
- "layer 2 functionality. " \
- "Ignoring layer2 option.\n",CARD_BUS_ID(card));
- }
- IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
- "Routing options are");
+ if (card->options.layer2 == 0)
+ return;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return;
+ if (card->info.type == QETH_CARD_TYPE_IQD) {
+ PRINT_ERR("Device %s does not support layer 2 functionality." \
+ " Ignoring layer2 option.\n",CARD_BUS_ID(card));
+ card->options.layer2 = 0;
+ return;
+ }
+ IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
+ "Routing options are");
#ifdef CONFIG_QETH_IPV6
- IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
- "Routing options are");
+ IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
+ "Routing options are");
#endif
- IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
- QETH_CHECKSUM_DEFAULT,
- "Checksumming options are");
- IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
- QETH_TR_BROADCAST_ALLRINGS,
- "Broadcast mode options are");
- IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
- QETH_TR_MACADDR_NONCANONICAL,
- "Canonical MAC addr options are");
- IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
- "Broadcast faking options are");
- IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
- DEFAULT_ADD_HHLEN,"Option add_hhlen is");
- IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
- }
+ IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
+ QETH_CHECKSUM_DEFAULT,
+ "Checksumming options are");
+ IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
+ QETH_TR_BROADCAST_ALLRINGS,
+ "Broadcast mode options are");
+ IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
+ QETH_TR_MACADDR_NONCANONICAL,
+ "Canonical MAC addr options are");
+ IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
+ "Broadcast faking options are");
+ IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
+ DEFAULT_ADD_HHLEN,"Option add_hhlen is");
+ IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
}
@@ -7533,8 +7739,7 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
return -EIO;
}
- if (card->options.layer2)
- qeth_make_parameters_consistent(card);
+ qeth_make_parameters_consistent(card);
if ((rc = qeth_hardsetup_card(card))){
QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
@@ -7593,6 +7798,7 @@ qeth_set_online(struct ccwgroup_device *gdev)
static struct ccw_device_id qeth_ids[] = {
{CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE},
{CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD},
+ {CCW_DEVICE(0x1731, 0x06), driver_info:QETH_CARD_TYPE_OSN},
{},
};
MODULE_DEVICE_TABLE(ccw, qeth_ids);
@@ -7730,7 +7936,7 @@ qeth_arp_constructor(struct neighbour *neigh)
goto out;
rcu_read_lock();
- in_dev = rcu_dereference(__in_dev_get(dev));
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev == NULL) {
rcu_read_unlock();
return -EINVAL;
@@ -8257,7 +8463,6 @@ qeth_init(void)
{
int rc=0;
- qeth_eyecatcher();
PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n",
version, VERSION_QETH_C, VERSION_QETH_H,
VERSION_QETH_MPC_H, VERSION_QETH_MPC_C,
@@ -8338,7 +8543,9 @@ again:
printk("qeth: removed\n");
}
-EXPORT_SYMBOL(qeth_eyecatcher);
+EXPORT_SYMBOL(qeth_osn_register);
+EXPORT_SYMBOL(qeth_osn_deregister);
+EXPORT_SYMBOL(qeth_osn_assist);
module_init(qeth_init);
module_exit(qeth_exit);
MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index f685ecc7da99..30e053d3cac2 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -11,7 +11,7 @@
#include <asm/cio.h>
#include "qeth_mpc.h"
-const char *VERSION_QETH_MPC_C = "$Revision: 1.11 $";
+const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $";
unsigned char IDX_ACTIVATE_READ[]={
0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
@@ -138,7 +138,9 @@ unsigned char IPA_PDU_HEADER[]={
sizeof(struct qeth_ipa_cmd)%256,
0x00,
sizeof(struct qeth_ipa_cmd)/256,
- sizeof(struct qeth_ipa_cmd),0x05, 0x77,0x77,0x77,0x77,
+ sizeof(struct qeth_ipa_cmd)%256,
+ 0x05,
+ 0x77,0x77,0x77,0x77,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x01,0x00,
sizeof(struct qeth_ipa_cmd)/256,
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 3d916b5c5d09..7edc5f1fc0d2 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -46,13 +46,16 @@ extern unsigned char IPA_PDU_HEADER[];
/* IP Assist related definitions */
/*****************************************************************************/
#define IPA_CMD_INITIATOR_HOST 0x00
-#define IPA_CMD_INITIATOR_HYDRA 0x01
+#define IPA_CMD_INITIATOR_OSA 0x01
+#define IPA_CMD_INITIATOR_HOST_REPLY 0x80
+#define IPA_CMD_INITIATOR_OSA_REPLY 0x81
#define IPA_CMD_PRIM_VERSION_NO 0x01
enum qeth_card_types {
QETH_CARD_TYPE_UNKNOWN = 0,
QETH_CARD_TYPE_OSAE = 10,
QETH_CARD_TYPE_IQD = 1234,
+ QETH_CARD_TYPE_OSN = 11,
};
#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
@@ -61,6 +64,7 @@ enum qeth_link_types {
QETH_LINK_TYPE_FAST_ETH = 0x01,
QETH_LINK_TYPE_HSTR = 0x02,
QETH_LINK_TYPE_GBIT_ETH = 0x03,
+ QETH_LINK_TYPE_OSN = 0x04,
QETH_LINK_TYPE_10GBIT_ETH = 0x10,
QETH_LINK_TYPE_LANE_ETH100 = 0x81,
QETH_LINK_TYPE_LANE_TR = 0x82,
@@ -111,6 +115,9 @@ enum qeth_ipa_cmds {
IPA_CMD_DELGMAC = 0x24,
IPA_CMD_SETVLAN = 0x25,
IPA_CMD_DELVLAN = 0x26,
+ IPA_CMD_SETCCID = 0x41,
+ IPA_CMD_DELCCID = 0x42,
+ IPA_CMD_MODCCID = 0x43,
IPA_CMD_SETIP = 0xb1,
IPA_CMD_DELIP = 0xb7,
IPA_CMD_QIPASSIST = 0xb2,
@@ -437,8 +444,9 @@ enum qeth_ipa_arp_return_codes {
#define QETH_ARP_DATA_SIZE 3968
#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
/* Helper functions */
-#define IS_IPA_REPLY(cmd) (cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST)
-
+#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
+ (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
+
/*****************************************************************************/
/* END OF IP Assist related definitions */
/*****************************************************************************/
@@ -483,6 +491,7 @@ extern unsigned char ULP_ENABLE[];
/* Layer 2 defintions */
#define QETH_PROT_LAYER2 0x08
#define QETH_PROT_TCPIP 0x03
+#define QETH_PROT_OSN2 0x0a
#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 98bedb0cb387..f91a02db5743 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.51 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $)
*
* Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs.
@@ -20,7 +20,7 @@
#include "qeth_mpc.h"
#include "qeth_fs.h"
-const char *VERSION_QETH_SYS_C = "$Revision: 1.51 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $";
/*****************************************************************************/
/* */
@@ -722,10 +722,13 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c
if (!card)
return -EINVAL;
+ if (card->info.type == QETH_CARD_TYPE_IQD) {
+ PRINT_WARN("Layer2 on Hipersockets is not supported! \n");
+ return -EPERM;
+ }
if (((card->state != CARD_STATE_DOWN) &&
- (card->state != CARD_STATE_RECOVER)) ||
- (card->info.type != QETH_CARD_TYPE_OSAE))
+ (card->state != CARD_STATE_RECOVER)))
return -EPERM;
i = simple_strtoul(buf, &tmp, 16);
@@ -771,9 +774,7 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con
if (!card)
return -EINVAL;
-
tmp = strsep((char **) &buf, "\n");
-
if (!strcmp(tmp, "no")){
type = QETH_LARGE_SEND_NO;
} else if (!strcmp(tmp, "EDDP")) {
@@ -786,10 +787,8 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con
}
if (card->options.large_send == type)
return count;
- card->options.large_send = type;
- if ((rc = qeth_set_large_send(card)))
+ if ((rc = qeth_set_large_send(card, type)))
return rc;
-
return count;
}
@@ -938,6 +937,19 @@ static struct attribute_group qeth_device_attr_group = {
.attrs = (struct attribute **)qeth_device_attrs,
};
+static struct device_attribute * qeth_osn_device_attrs[] = {
+ &dev_attr_state,
+ &dev_attr_chpid,
+ &dev_attr_if_name,
+ &dev_attr_card_type,
+ &dev_attr_buffer_count,
+ &dev_attr_recover,
+ NULL,
+};
+
+static struct attribute_group qeth_osn_device_attr_group = {
+ .attrs = (struct attribute **)qeth_osn_device_attrs,
+};
#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_id = { \
@@ -1668,7 +1680,12 @@ int
qeth_create_device_attributes(struct device *dev)
{
int ret;
+ struct qeth_card *card = dev->driver_data;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return sysfs_create_group(&dev->kobj,
+ &qeth_osn_device_attr_group);
+
if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
return ret;
if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
@@ -1694,6 +1711,12 @@ qeth_create_device_attributes(struct device *dev)
void
qeth_remove_device_attributes(struct device *dev)
{
+ struct qeth_card *card = dev->driver_data;
+
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return sysfs_remove_group(&dev->kobj,
+ &qeth_osn_device_attr_group);
+
sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile
index fc145307a7d4..d6a78f1a2f16 100644
--- a/drivers/s390/scsi/Makefile
+++ b/drivers/s390/scsi/Makefile
@@ -3,7 +3,7 @@
#
zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
- zfcp_fsf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
+ zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
zfcp_sysfs_unit.o zfcp_sysfs_driver.o
obj-$(CONFIG_ZFCP) += zfcp.o
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index bfe3ba73bc0f..cab098556b44 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -122,95 +122,6 @@ _zfcp_hex_dump(char *addr, int count)
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
-static inline int
-zfcp_fsf_req_is_scsi_cmnd(struct zfcp_fsf_req *fsf_req)
-{
- return ((fsf_req->fsf_command == FSF_QTCB_FCP_CMND) &&
- !(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT));
-}
-
-void
-zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req,
- void *add_data, int add_length)
-{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct scsi_cmnd *scsi_cmnd;
- int level = 3;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->dbf_lock, flags);
- if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) {
- scsi_cmnd = fsf_req->data.send_fcp_command_task.scsi_cmnd;
- debug_text_event(adapter->cmd_dbf, level, "fsferror");
- debug_text_event(adapter->cmd_dbf, level, text);
- debug_event(adapter->cmd_dbf, level, &fsf_req,
- sizeof (unsigned long));
- debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,
- sizeof (u32));
- debug_event(adapter->cmd_dbf, level, &scsi_cmnd,
- sizeof (unsigned long));
- debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,
- min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));
- for (i = 0; i < add_length; i += ZFCP_CMD_DBF_LENGTH)
- debug_event(adapter->cmd_dbf,
- level,
- (char *) add_data + i,
- min(ZFCP_CMD_DBF_LENGTH, add_length - i));
- }
- spin_unlock_irqrestore(&adapter->dbf_lock, flags);
-}
-
-/* XXX additionally log unit if available */
-/* ---> introduce new parameter for unit, see 2.4 code */
-void
-zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd)
-{
- struct zfcp_adapter *adapter;
- union zfcp_req_data *req_data;
- struct zfcp_fsf_req *fsf_req;
- int level = ((host_byte(scsi_cmnd->result) != 0) ? 1 : 5);
- unsigned long flags;
-
- adapter = (struct zfcp_adapter *) scsi_cmnd->device->host->hostdata[0];
- req_data = (union zfcp_req_data *) scsi_cmnd->host_scribble;
- fsf_req = (req_data ? req_data->send_fcp_command_task.fsf_req : NULL);
- spin_lock_irqsave(&adapter->dbf_lock, flags);
- debug_text_event(adapter->cmd_dbf, level, "hostbyte");
- debug_text_event(adapter->cmd_dbf, level, text);
- debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof (u32));
- debug_event(adapter->cmd_dbf, level, &scsi_cmnd,
- sizeof (unsigned long));
- debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,
- min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));
- if (likely(fsf_req)) {
- debug_event(adapter->cmd_dbf, level, &fsf_req,
- sizeof (unsigned long));
- debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,
- sizeof (u32));
- } else {
- debug_text_event(adapter->cmd_dbf, level, "");
- debug_text_event(adapter->cmd_dbf, level, "");
- }
- spin_unlock_irqrestore(&adapter->dbf_lock, flags);
-}
-
-void
-zfcp_in_els_dbf_event(struct zfcp_adapter *adapter, const char *text,
- struct fsf_status_read_buffer *status_buffer, int length)
-{
- int level = 1;
- int i;
-
- debug_text_event(adapter->in_els_dbf, level, text);
- debug_event(adapter->in_els_dbf, level, &status_buffer->d_id, 8);
- for (i = 0; i < length; i += ZFCP_IN_ELS_DBF_LENGTH)
- debug_event(adapter->in_els_dbf,
- level,
- (char *) status_buffer->payload + i,
- min(ZFCP_IN_ELS_DBF_LENGTH, length - i));
-}
-
/**
* zfcp_device_setup - setup function
* @str: pointer to parameter string
@@ -922,7 +833,7 @@ zfcp_unit_dequeue(struct zfcp_unit *unit)
}
static void *
-zfcp_mempool_alloc(unsigned int __nocast gfp_mask, void *size)
+zfcp_mempool_alloc(gfp_t gfp_mask, void *size)
{
return kmalloc((size_t) size, gfp_mask);
}
@@ -1017,81 +928,6 @@ zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
mempool_destroy(adapter->pool.data_gid_pn);
}
-/**
- * zfcp_adapter_debug_register - registers debug feature for an adapter
- * @adapter: pointer to adapter for which debug features should be registered
- * return: -ENOMEM on error, 0 otherwise
- */
-int
-zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
-{
- char dbf_name[20];
-
- /* debug feature area which records SCSI command failures (hostbyte) */
- spin_lock_init(&adapter->dbf_lock);
-
- sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s",
- zfcp_get_busid_by_adapter(adapter));
- adapter->cmd_dbf = debug_register(dbf_name, ZFCP_CMD_DBF_INDEX,
- ZFCP_CMD_DBF_AREAS,
- ZFCP_CMD_DBF_LENGTH);
- debug_register_view(adapter->cmd_dbf, &debug_hex_ascii_view);
- debug_set_level(adapter->cmd_dbf, ZFCP_CMD_DBF_LEVEL);
-
- /* debug feature area which records SCSI command aborts */
- sprintf(dbf_name, ZFCP_ABORT_DBF_NAME "%s",
- zfcp_get_busid_by_adapter(adapter));
- adapter->abort_dbf = debug_register(dbf_name, ZFCP_ABORT_DBF_INDEX,
- ZFCP_ABORT_DBF_AREAS,
- ZFCP_ABORT_DBF_LENGTH);
- debug_register_view(adapter->abort_dbf, &debug_hex_ascii_view);
- debug_set_level(adapter->abort_dbf, ZFCP_ABORT_DBF_LEVEL);
-
- /* debug feature area which records incoming ELS commands */
- sprintf(dbf_name, ZFCP_IN_ELS_DBF_NAME "%s",
- zfcp_get_busid_by_adapter(adapter));
- adapter->in_els_dbf = debug_register(dbf_name, ZFCP_IN_ELS_DBF_INDEX,
- ZFCP_IN_ELS_DBF_AREAS,
- ZFCP_IN_ELS_DBF_LENGTH);
- debug_register_view(adapter->in_els_dbf, &debug_hex_ascii_view);
- debug_set_level(adapter->in_els_dbf, ZFCP_IN_ELS_DBF_LEVEL);
-
- /* debug feature area which records erp events */
- sprintf(dbf_name, ZFCP_ERP_DBF_NAME "%s",
- zfcp_get_busid_by_adapter(adapter));
- adapter->erp_dbf = debug_register(dbf_name, ZFCP_ERP_DBF_INDEX,
- ZFCP_ERP_DBF_AREAS,
- ZFCP_ERP_DBF_LENGTH);
- debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
- debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL);
-
- if (!(adapter->cmd_dbf && adapter->abort_dbf &&
- adapter->in_els_dbf && adapter->erp_dbf)) {
- zfcp_adapter_debug_unregister(adapter);
- return -ENOMEM;
- }
-
- return 0;
-
-}
-
-/**
- * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
- * @adapter: pointer to adapter for which debug features should be unregistered
- */
-void
-zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
-{
- debug_unregister(adapter->abort_dbf);
- debug_unregister(adapter->cmd_dbf);
- debug_unregister(adapter->erp_dbf);
- debug_unregister(adapter->in_els_dbf);
- adapter->abort_dbf = NULL;
- adapter->cmd_dbf = NULL;
- adapter->erp_dbf = NULL;
- adapter->in_els_dbf = NULL;
-}
-
void
zfcp_dummy_release(struct device *dev)
{
@@ -1462,10 +1298,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
/* see FC-FS */
no_entries = (fcp_rscn_head->payload_len / 4);
- zfcp_in_els_dbf_event(adapter, "##rscn", status_buffer,
- fcp_rscn_head->payload_len);
-
- debug_text_event(adapter->erp_dbf, 1, "unsol_els_rscn:");
for (i = 1; i < no_entries; i++) {
/* skip head and start with 1st element */
fcp_rscn_element++;
@@ -1497,8 +1329,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
(ZFCP_STATUS_PORT_DID_DID, &port->status)) {
ZFCP_LOG_INFO("incoming RSCN, trying to open "
"port 0x%016Lx\n", port->wwpn);
- debug_text_event(adapter->erp_dbf, 1,
- "unsol_els_rscnu:");
zfcp_erp_port_reopen(port,
ZFCP_STATUS_COMMON_ERP_FAILED);
continue;
@@ -1524,8 +1354,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
*/
ZFCP_LOG_INFO("incoming RSCN, trying to open "
"port 0x%016Lx\n", port->wwpn);
- debug_text_event(adapter->erp_dbf, 1,
- "unsol_els_rscnk:");
zfcp_test_link(port);
}
}
@@ -1541,8 +1369,6 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
struct zfcp_port *port;
unsigned long flags;
- zfcp_in_els_dbf_event(adapter, "##plogi", status_buffer, 28);
-
read_lock_irqsave(&zfcp_data.config_lock, flags);
list_for_each_entry(port, &adapter->port_list_head, list) {
if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn))
@@ -1556,8 +1382,6 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
status_buffer->d_id,
zfcp_get_busid_by_adapter(adapter));
} else {
- debug_text_event(adapter->erp_dbf, 1, "unsol_els_plogi:");
- debug_event(adapter->erp_dbf, 1, &els_logi->nport_wwn, 8);
zfcp_erp_port_forced_reopen(port, 0);
}
}
@@ -1570,8 +1394,6 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
struct zfcp_port *port;
unsigned long flags;
- zfcp_in_els_dbf_event(adapter, "##logo", status_buffer, 16);
-
read_lock_irqsave(&zfcp_data.config_lock, flags);
list_for_each_entry(port, &adapter->port_list_head, list) {
if (port->wwpn == els_logo->nport_wwpn)
@@ -1585,8 +1407,6 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
status_buffer->d_id,
zfcp_get_busid_by_adapter(adapter));
} else {
- debug_text_event(adapter->erp_dbf, 1, "unsol_els_logo:");
- debug_event(adapter->erp_dbf, 1, &els_logo->nport_wwpn, 8);
zfcp_erp_port_forced_reopen(port, 0);
}
}
@@ -1595,7 +1415,6 @@ static void
zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter,
struct fsf_status_read_buffer *status_buffer)
{
- zfcp_in_els_dbf_event(adapter, "##undef", status_buffer, 24);
ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x "
"for adapter %s\n", *(u32 *) (status_buffer->payload),
zfcp_get_busid_by_adapter(adapter));
@@ -1609,10 +1428,11 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req)
u32 els_type;
struct zfcp_adapter *adapter;
- status_buffer = fsf_req->data.status_read.buffer;
+ status_buffer = (struct fsf_status_read_buffer *) fsf_req->data;
els_type = *(u32 *) (status_buffer->payload);
adapter = fsf_req->adapter;
+ zfcp_san_dbf_event_incoming_els(fsf_req);
if (els_type == LS_PLOGI)
zfcp_fsf_incoming_els_plogi(adapter, status_buffer);
else if (els_type == LS_LOGO)
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index b30abab77da3..0fc46381fc22 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -202,19 +202,9 @@ static int
zfcp_ccw_set_offline(struct ccw_device *ccw_device)
{
struct zfcp_adapter *adapter;
- struct zfcp_port *port;
- struct fc_rport *rport;
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&ccw_device->dev);
- /* might be racy, but we cannot take config_lock due to the fact that
- fc_remote_port_delete might sleep */
- list_for_each_entry(port, &adapter->port_list_head, list)
- if (port->rport) {
- rport = port->rport;
- port->rport = NULL;
- fc_remote_port_delete(rport);
- }
zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter);
zfcp_adapter_scsi_unregister(adapter);
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
new file mode 100644
index 000000000000..826fb3b00605
--- /dev/null
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -0,0 +1,995 @@
+/*
+ *
+ * linux/drivers/s390/scsi/zfcp_dbf.c
+ *
+ * FCP adapter driver for IBM eServer zSeries
+ *
+ * Debugging facilities
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define ZFCP_DBF_REVISION "$Revision$"
+
+#include <asm/debug.h>
+#include <linux/ctype.h>
+#include "zfcp_ext.h"
+
+static u32 dbfsize = 4;
+
+module_param(dbfsize, uint, 0400);
+MODULE_PARM_DESC(dbfsize,
+ "number of pages for each debug feature area (default 4)");
+
+#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
+
+static inline int
+zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck)
+{
+ unsigned long long sec;
+ struct timespec xtime;
+ int len = 0;
+
+ stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
+ sec = stck >> 12;
+ do_div(sec, 1000000);
+ xtime.tv_sec = sec;
+ stck -= (sec * 1000000) << 12;
+ xtime.tv_nsec = ((stck * 1000) >> 12);
+ len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n",
+ label, xtime.tv_sec, xtime.tv_nsec);
+
+ return len;
+}
+
+static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag)
+{
+ int len = 0, i;
+
+ len += sprintf(out_buf + len, "%-24s", label);
+ for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
+ len += sprintf(out_buf + len, "%c", tag[i]);
+ len += sprintf(out_buf + len, "\n");
+
+ return len;
+}
+
+static int
+zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...)
+{
+ va_list arg;
+ int len = 0;
+
+ len += sprintf(out_buf + len, "%-24s", label);
+ va_start(arg, format);
+ len += vsprintf(out_buf + len, format, arg);
+ va_end(arg);
+ len += sprintf(out_buf + len, "\n");
+
+ return len;
+}
+
+static int
+zfcp_dbf_view_dump(char *out_buf, const char *label,
+ char *buffer, int buflen, int offset, int total_size)
+{
+ int len = 0;
+
+ if (offset == 0)
+ len += sprintf(out_buf + len, "%-24s ", label);
+
+ while (buflen--) {
+ if (offset > 0) {
+ if ((offset % 32) == 0)
+ len += sprintf(out_buf + len, "\n%-24c ", ' ');
+ else if ((offset % 4) == 0)
+ len += sprintf(out_buf + len, " ");
+ }
+ len += sprintf(out_buf + len, "%02x", *buffer++);
+ if (++offset == total_size) {
+ len += sprintf(out_buf + len, "\n");
+ break;
+ }
+ }
+
+ if (total_size == 0)
+ len += sprintf(out_buf + len, "\n");
+
+ return len;
+}
+
+static inline int
+zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
+ debug_entry_t * entry, char *out_buf)
+{
+ struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
+ int len = 0;
+
+ if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
+ len += zfcp_dbf_stck(out_buf + len, "timestamp",
+ entry->id.stck);
+ len += zfcp_dbf_view(out_buf + len, "cpu", "%02i",
+ entry->id.fields.cpuid);
+ } else {
+ len += zfcp_dbf_view_dump(out_buf + len, NULL,
+ dump->data,
+ dump->size,
+ dump->offset, dump->total_size);
+ if ((dump->offset + dump->size) == dump->total_size)
+ len += sprintf(out_buf + len, "\n");
+ }
+
+ return len;
+}
+
+inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
+{
+ struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct fsf_qtcb *qtcb = fsf_req->qtcb;
+ union fsf_prot_status_qual *prot_status_qual =
+ &qtcb->prefix.prot_status_qual;
+ union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
+ struct scsi_cmnd *scsi_cmnd;
+ struct zfcp_port *port;
+ struct zfcp_unit *unit;
+ struct zfcp_send_els *send_els;
+ struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
+ struct zfcp_hba_dbf_record_response *response = &rec->type.response;
+ int level;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+ memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
+ strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
+
+ if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
+ (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
+ strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);
+ level = 1;
+ } else if (qtcb->header.fsf_status != FSF_GOOD) {
+ strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);
+ level = 1;
+ } else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
+ (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
+ strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
+ level = 4;
+ } else if ((prot_status_qual->doubleword[0] != 0) ||
+ (prot_status_qual->doubleword[1] != 0) ||
+ (fsf_status_qual->doubleword[0] != 0) ||
+ (fsf_status_qual->doubleword[1] != 0)) {
+ strncpy(rec->tag2, "qual", ZFCP_DBF_TAG_SIZE);
+ level = 3;
+ } else {
+ strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
+ level = 6;
+ }
+
+ response->fsf_command = fsf_req->fsf_command;
+ response->fsf_reqid = (unsigned long)fsf_req;
+ response->fsf_seqno = fsf_req->seq_no;
+ response->fsf_issued = fsf_req->issued;
+ response->fsf_prot_status = qtcb->prefix.prot_status;
+ response->fsf_status = qtcb->header.fsf_status;
+ memcpy(response->fsf_prot_status_qual,
+ prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);
+ memcpy(response->fsf_status_qual,
+ fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
+ response->fsf_req_status = fsf_req->status;
+ response->sbal_first = fsf_req->sbal_first;
+ response->sbal_curr = fsf_req->sbal_curr;
+ response->sbal_last = fsf_req->sbal_last;
+ response->pool = fsf_req->pool != NULL;
+ response->erp_action = (unsigned long)fsf_req->erp_action;
+
+ switch (fsf_req->fsf_command) {
+ case FSF_QTCB_FCP_CMND:
+ if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
+ break;
+ scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
+ if (scsi_cmnd != NULL) {
+ response->data.send_fcp.scsi_cmnd
+ = (unsigned long)scsi_cmnd;
+ response->data.send_fcp.scsi_serial
+ = scsi_cmnd->serial_number;
+ }
+ break;
+
+ case FSF_QTCB_OPEN_PORT_WITH_DID:
+ case FSF_QTCB_CLOSE_PORT:
+ case FSF_QTCB_CLOSE_PHYSICAL_PORT:
+ port = (struct zfcp_port *)fsf_req->data;
+ response->data.port.wwpn = port->wwpn;
+ response->data.port.d_id = port->d_id;
+ response->data.port.port_handle = qtcb->header.port_handle;
+ break;
+
+ case FSF_QTCB_OPEN_LUN:
+ case FSF_QTCB_CLOSE_LUN:
+ unit = (struct zfcp_unit *)fsf_req->data;
+ port = unit->port;
+ response->data.unit.wwpn = port->wwpn;
+ response->data.unit.fcp_lun = unit->fcp_lun;
+ response->data.unit.port_handle = qtcb->header.port_handle;
+ response->data.unit.lun_handle = qtcb->header.lun_handle;
+ break;
+
+ case FSF_QTCB_SEND_ELS:
+ send_els = (struct zfcp_send_els *)fsf_req->data;
+ response->data.send_els.d_id = qtcb->bottom.support.d_id;
+ response->data.send_els.ls_code = send_els->ls_code >> 24;
+ break;
+
+ case FSF_QTCB_ABORT_FCP_CMND:
+ case FSF_QTCB_SEND_GENERIC:
+ case FSF_QTCB_EXCHANGE_CONFIG_DATA:
+ case FSF_QTCB_EXCHANGE_PORT_DATA:
+ case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
+ case FSF_QTCB_UPLOAD_CONTROL_FILE:
+ break;
+ }
+
+ debug_event(adapter->hba_dbf, level,
+ rec, sizeof(struct zfcp_hba_dbf_record));
+ spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+}
+
+inline void
+zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
+ struct fsf_status_read_buffer *status_buffer)
+{
+ struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+ memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
+ strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
+ strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
+
+ rec->type.status.failed = adapter->status_read_failed;
+ if (status_buffer != NULL) {
+ rec->type.status.status_type = status_buffer->status_type;
+ rec->type.status.status_subtype = status_buffer->status_subtype;
+ memcpy(&rec->type.status.queue_designator,
+ &status_buffer->queue_designator,
+ sizeof(struct fsf_queue_designator));
+
+ switch (status_buffer->status_type) {
+ case FSF_STATUS_READ_SENSE_DATA_AVAIL:
+ rec->type.status.payload_size =
+ ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
+ break;
+
+ case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
+ rec->type.status.payload_size =
+ ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
+ break;
+
+ case FSF_STATUS_READ_LINK_DOWN:
+ switch (status_buffer->status_subtype) {
+ case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
+ case FSF_STATUS_READ_SUB_FDISC_FAILED:
+ rec->type.status.payload_size =
+ sizeof(struct fsf_link_down_info);
+ }
+ break;
+
+ case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
+ rec->type.status.payload_size =
+ ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
+ break;
+ }
+ memcpy(&rec->type.status.payload,
+ &status_buffer->payload, rec->type.status.payload_size);
+ }
+
+ debug_event(adapter->hba_dbf, 2,
+ rec, sizeof(struct zfcp_hba_dbf_record));
+ spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+}
+
+inline void
+zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
+ unsigned int qdio_error, unsigned int siga_error,
+ int sbal_index, int sbal_count)
+{
+ struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+ memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
+ strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE);
+ rec->type.qdio.status = status;
+ rec->type.qdio.qdio_error = qdio_error;
+ rec->type.qdio.siga_error = siga_error;
+ rec->type.qdio.sbal_index = sbal_index;
+ rec->type.qdio.sbal_count = sbal_count;
+ debug_event(adapter->hba_dbf, 0,
+ rec, sizeof(struct zfcp_hba_dbf_record));
+ spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+}
+
+static inline int
+zfcp_hba_dbf_view_response(char *out_buf,
+ struct zfcp_hba_dbf_record_response *rec)
+{
+ int len = 0;
+
+ len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x",
+ rec->fsf_command);
+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
+ rec->fsf_reqid);
+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
+ rec->fsf_seqno);
+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);
+ len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x",
+ rec->fsf_prot_status);
+ len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x",
+ rec->fsf_status);
+ len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual",
+ rec->fsf_prot_status_qual,
+ FSF_PROT_STATUS_QUAL_SIZE,
+ 0, FSF_PROT_STATUS_QUAL_SIZE);
+ len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual",
+ rec->fsf_status_qual,
+ FSF_STATUS_QUALIFIER_SIZE,
+ 0, FSF_STATUS_QUALIFIER_SIZE);
+ len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x",
+ rec->fsf_req_status);
+ len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x",
+ rec->sbal_first);
+ len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x",
+ rec->sbal_curr);
+ len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x",
+ rec->sbal_last);
+ len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool);
+
+ switch (rec->fsf_command) {
+ case FSF_QTCB_FCP_CMND:
+ if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
+ break;
+ len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
+ rec->data.send_fcp.scsi_cmnd);
+ len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
+ rec->data.send_fcp.scsi_serial);
+ break;
+
+ case FSF_QTCB_OPEN_PORT_WITH_DID:
+ case FSF_QTCB_CLOSE_PORT:
+ case FSF_QTCB_CLOSE_PHYSICAL_PORT:
+ len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
+ rec->data.port.wwpn);
+ len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
+ rec->data.port.d_id);
+ len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
+ rec->data.port.port_handle);
+ break;
+
+ case FSF_QTCB_OPEN_LUN:
+ case FSF_QTCB_CLOSE_LUN:
+ len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
+ rec->data.unit.wwpn);
+ len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx",
+ rec->data.unit.fcp_lun);
+ len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
+ rec->data.unit.port_handle);
+ len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x",
+ rec->data.unit.lun_handle);
+ break;
+
+ case FSF_QTCB_SEND_ELS:
+ len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
+ rec->data.send_els.d_id);
+ len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
+ rec->data.send_els.ls_code);
+ break;
+
+ case FSF_QTCB_ABORT_FCP_CMND:
+ case FSF_QTCB_SEND_GENERIC:
+ case FSF_QTCB_EXCHANGE_CONFIG_DATA:
+ case FSF_QTCB_EXCHANGE_PORT_DATA:
+ case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
+ case FSF_QTCB_UPLOAD_CONTROL_FILE:
+ break;
+ }
+
+ return len;
+}
+
+static inline int
+zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
+{
+ int len = 0;
+
+ len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed);
+ len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x",
+ rec->status_type);
+ len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x",
+ rec->status_subtype);
+ len += zfcp_dbf_view_dump(out_buf + len, "queue_designator",
+ (char *)&rec->queue_designator,
+ sizeof(struct fsf_queue_designator),
+ 0, sizeof(struct fsf_queue_designator));
+ len += zfcp_dbf_view_dump(out_buf + len, "payload",
+ (char *)&rec->payload,
+ rec->payload_size, 0, rec->payload_size);
+
+ return len;
+}
+
+static inline int
+zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)
+{
+ int len = 0;
+
+ len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status);
+ len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x",
+ rec->qdio_error);
+ len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x",
+ rec->siga_error);
+ len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x",
+ rec->sbal_index);
+ len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x",
+ rec->sbal_count);
+
+ return len;
+}
+
+static int
+zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,
+ char *out_buf, const char *in_buf)
+{
+ struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf;
+ int len = 0;
+
+ if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+ return 0;
+
+ len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
+ if (isalpha(rec->tag2[0]))
+ len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
+ if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
+ len += zfcp_hba_dbf_view_response(out_buf + len,
+ &rec->type.response);
+ else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
+ len += zfcp_hba_dbf_view_status(out_buf + len,
+ &rec->type.status);
+ else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
+ len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio);
+
+ len += sprintf(out_buf + len, "\n");
+
+ return len;
+}
+
+struct debug_view zfcp_hba_dbf_view = {
+ "structured",
+ NULL,
+ &zfcp_dbf_view_header,
+ &zfcp_hba_dbf_view_format,
+ NULL,
+ NULL
+};
+
+inline void
+_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
+ u32 s_id, u32 d_id, void *buffer, int buflen)
+{
+ struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data;
+ struct zfcp_port *port = send_ct->port;
+ struct zfcp_adapter *adapter = port->adapter;
+ struct ct_hdr *header = (struct ct_hdr *)buffer;
+ struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
+ struct zfcp_san_dbf_record_ct *ct = &rec->type.ct;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+ memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
+ strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
+ rec->fsf_reqid = (unsigned long)fsf_req;
+ rec->fsf_seqno = fsf_req->seq_no;
+ rec->s_id = s_id;
+ rec->d_id = d_id;
+ if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
+ ct->type.request.cmd_req_code = header->cmd_rsp_code;
+ ct->type.request.revision = header->revision;
+ ct->type.request.gs_type = header->gs_type;
+ ct->type.request.gs_subtype = header->gs_subtype;
+ ct->type.request.options = header->options;
+ ct->type.request.max_res_size = header->max_res_size;
+ } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
+ ct->type.response.cmd_rsp_code = header->cmd_rsp_code;
+ ct->type.response.revision = header->revision;
+ ct->type.response.reason_code = header->reason_code;
+ ct->type.response.reason_code_expl = header->reason_code_expl;
+ ct->type.response.vendor_unique = header->vendor_unique;
+ }
+ ct->payload_size =
+ min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD);
+ memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size);
+ debug_event(adapter->san_dbf, 3,
+ rec, sizeof(struct zfcp_san_dbf_record));
+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+}
+
+inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
+{
+ struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
+ struct zfcp_port *port = ct->port;
+ struct zfcp_adapter *adapter = port->adapter;
+
+ _zfcp_san_dbf_event_common_ct("octc", fsf_req,
+ fc_host_port_id(adapter->scsi_host),
+ port->d_id, zfcp_sg_to_address(ct->req),
+ ct->req->length);
+}
+
+inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
+{
+ struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
+ struct zfcp_port *port = ct->port;
+ struct zfcp_adapter *adapter = port->adapter;
+
+ _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id,
+ fc_host_port_id(adapter->scsi_host),
+ zfcp_sg_to_address(ct->resp),
+ ct->resp->length);
+}
+
+static inline void
+_zfcp_san_dbf_event_common_els(const char *tag, int level,
+ struct zfcp_fsf_req *fsf_req, u32 s_id,
+ u32 d_id, u8 ls_code, void *buffer, int buflen)
+{
+ struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
+ struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
+ unsigned long flags;
+ int offset = 0;
+
+ spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+ do {
+ memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
+ if (offset == 0) {
+ strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
+ rec->fsf_reqid = (unsigned long)fsf_req;
+ rec->fsf_seqno = fsf_req->seq_no;
+ rec->s_id = s_id;
+ rec->d_id = d_id;
+ rec->type.els.ls_code = ls_code;
+ buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD);
+ rec->type.els.payload_size = buflen;
+ memcpy(rec->type.els.payload,
+ buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD));
+ offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD);
+ } else {
+ strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
+ dump->total_size = buflen;
+ dump->offset = offset;
+ dump->size = min(buflen - offset,
+ (int)sizeof(struct zfcp_san_dbf_record)
+ - (int)sizeof(struct zfcp_dbf_dump));
+ memcpy(dump->data, buffer + offset, dump->size);
+ offset += dump->size;
+ }
+ debug_event(adapter->san_dbf, level,
+ rec, sizeof(struct zfcp_san_dbf_record));
+ } while (offset < buflen);
+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+}
+
+inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
+{
+ struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
+
+ _zfcp_san_dbf_event_common_els("oels", 2, fsf_req,
+ fc_host_port_id(els->adapter->scsi_host),
+ els->d_id,
+ *(u8 *) zfcp_sg_to_address(els->req),
+ zfcp_sg_to_address(els->req),
+ els->req->length);
+}
+
+inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
+{
+ struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
+
+ _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id,
+ fc_host_port_id(els->adapter->scsi_host),
+ *(u8 *) zfcp_sg_to_address(els->req),
+ zfcp_sg_to_address(els->resp),
+ els->resp->length);
+}
+
+inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
+{
+ struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct fsf_status_read_buffer *status_buffer =
+ (struct fsf_status_read_buffer *)fsf_req->data;
+ int length = (int)status_buffer->length -
+ (int)((void *)&status_buffer->payload - (void *)status_buffer);
+
+ _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id,
+ fc_host_port_id(adapter->scsi_host),
+ *(u8 *) status_buffer->payload,
+ (void *)status_buffer->payload, length);
+}
+
+static int
+zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,
+ char *out_buf, const char *in_buf)
+{
+ struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf;
+ char *buffer = NULL;
+ int buflen = 0, total = 0;
+ int len = 0;
+
+ if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+ return 0;
+
+ len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
+ rec->fsf_reqid);
+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
+ rec->fsf_seqno);
+ len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id);
+ len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id);
+
+ if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
+ len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x",
+ rec->type.ct.type.request.cmd_req_code);
+ len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
+ rec->type.ct.type.request.revision);
+ len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x",
+ rec->type.ct.type.request.gs_type);
+ len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x",
+ rec->type.ct.type.request.gs_subtype);
+ len += zfcp_dbf_view(out_buf + len, "options", "0x%02x",
+ rec->type.ct.type.request.options);
+ len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x",
+ rec->type.ct.type.request.max_res_size);
+ total = rec->type.ct.payload_size;
+ buffer = rec->type.ct.payload;
+ buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
+ } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
+ len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x",
+ rec->type.ct.type.response.cmd_rsp_code);
+ len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
+ rec->type.ct.type.response.revision);
+ len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x",
+ rec->type.ct.type.response.reason_code);
+ len +=
+ zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x",
+ rec->type.ct.type.response.reason_code_expl);
+ len +=
+ zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x",
+ rec->type.ct.type.response.vendor_unique);
+ total = rec->type.ct.payload_size;
+ buffer = rec->type.ct.payload;
+ buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
+ } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
+ strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
+ strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
+ len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
+ rec->type.els.ls_code);
+ total = rec->type.els.payload_size;
+ buffer = rec->type.els.payload;
+ buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
+ }
+
+ len += zfcp_dbf_view_dump(out_buf + len, "payload",
+ buffer, buflen, 0, total);
+
+ if (buflen == total)
+ len += sprintf(out_buf + len, "\n");
+
+ return len;
+}
+
+struct debug_view zfcp_san_dbf_view = {
+ "structured",
+ NULL,
+ &zfcp_dbf_view_header,
+ &zfcp_san_dbf_view_format,
+ NULL,
+ NULL
+};
+
+static inline void
+_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
+ struct zfcp_adapter *adapter,
+ struct scsi_cmnd *scsi_cmnd,
+ struct zfcp_fsf_req *new_fsf_req)
+{
+ struct zfcp_fsf_req *fsf_req =
+ (struct zfcp_fsf_req *)scsi_cmnd->host_scribble;
+ struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
+ struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
+ unsigned long flags;
+ struct fcp_rsp_iu *fcp_rsp;
+ char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
+ int offset = 0, buflen = 0;
+
+ spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
+ do {
+ memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record));
+ if (offset == 0) {
+ strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
+ strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
+ if (scsi_cmnd->device) {
+ rec->scsi_id = scsi_cmnd->device->id;
+ rec->scsi_lun = scsi_cmnd->device->lun;
+ }
+ rec->scsi_result = scsi_cmnd->result;
+ rec->scsi_cmnd = (unsigned long)scsi_cmnd;
+ rec->scsi_serial = scsi_cmnd->serial_number;
+ memcpy(rec->scsi_opcode,
+ &scsi_cmnd->cmnd,
+ min((int)scsi_cmnd->cmd_len,
+ ZFCP_DBF_SCSI_OPCODE));
+ rec->scsi_retries = scsi_cmnd->retries;
+ rec->scsi_allowed = scsi_cmnd->allowed;
+ if (fsf_req != NULL) {
+ fcp_rsp = (struct fcp_rsp_iu *)
+ &(fsf_req->qtcb->bottom.io.fcp_rsp);
+ fcp_rsp_info =
+ zfcp_get_fcp_rsp_info_ptr(fcp_rsp);
+ fcp_sns_info =
+ zfcp_get_fcp_sns_info_ptr(fcp_rsp);
+
+ rec->type.fcp.rsp_validity =
+ fcp_rsp->validity.value;
+ rec->type.fcp.rsp_scsi_status =
+ fcp_rsp->scsi_status;
+ rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid;
+ if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
+ rec->type.fcp.rsp_code =
+ *(fcp_rsp_info + 3);
+ if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
+ buflen = min((int)fcp_rsp->fcp_sns_len,
+ ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
+ rec->type.fcp.sns_info_len = buflen;
+ memcpy(rec->type.fcp.sns_info,
+ fcp_sns_info,
+ min(buflen,
+ ZFCP_DBF_SCSI_FCP_SNS_INFO));
+ offset += min(buflen,
+ ZFCP_DBF_SCSI_FCP_SNS_INFO);
+ }
+
+ rec->fsf_reqid = (unsigned long)fsf_req;
+ rec->fsf_seqno = fsf_req->seq_no;
+ rec->fsf_issued = fsf_req->issued;
+ }
+ if (new_fsf_req != NULL) {
+ rec->type.new_fsf_req.fsf_reqid =
+ (unsigned long)
+ new_fsf_req;
+ rec->type.new_fsf_req.fsf_seqno =
+ new_fsf_req->seq_no;
+ rec->type.new_fsf_req.fsf_issued =
+ new_fsf_req->issued;
+ }
+ } else {
+ strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
+ dump->total_size = buflen;
+ dump->offset = offset;
+ dump->size = min(buflen - offset,
+ (int)sizeof(struct
+ zfcp_scsi_dbf_record) -
+ (int)sizeof(struct zfcp_dbf_dump));
+ memcpy(dump->data, fcp_sns_info + offset, dump->size);
+ offset += dump->size;
+ }
+ debug_event(adapter->scsi_dbf, level,
+ rec, sizeof(struct zfcp_scsi_dbf_record));
+ } while (offset < buflen);
+ spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
+}
+
+inline void
+zfcp_scsi_dbf_event_result(const char *tag, int level,
+ struct zfcp_adapter *adapter,
+ struct scsi_cmnd *scsi_cmnd)
+{
+ _zfcp_scsi_dbf_event_common("rslt",
+ tag, level, adapter, scsi_cmnd, NULL);
+}
+
+inline void
+zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
+ struct scsi_cmnd *scsi_cmnd,
+ struct zfcp_fsf_req *new_fsf_req)
+{
+ _zfcp_scsi_dbf_event_common("abrt",
+ tag, 1, adapter, scsi_cmnd, new_fsf_req);
+}
+
+inline void
+zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
+ struct scsi_cmnd *scsi_cmnd)
+{
+ struct zfcp_adapter *adapter = unit->port->adapter;
+
+ _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
+ tag, 1, adapter, scsi_cmnd, NULL);
+}
+
+static int
+zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
+ char *out_buf, const char *in_buf)
+{
+ struct zfcp_scsi_dbf_record *rec =
+ (struct zfcp_scsi_dbf_record *)in_buf;
+ int len = 0;
+
+ if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+ return 0;
+
+ len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
+ len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
+ len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id);
+ len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x",
+ rec->scsi_lun);
+ len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x",
+ rec->scsi_result);
+ len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
+ rec->scsi_cmnd);
+ len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
+ rec->scsi_serial);
+ len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode",
+ rec->scsi_opcode,
+ ZFCP_DBF_SCSI_OPCODE,
+ 0, ZFCP_DBF_SCSI_OPCODE);
+ len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x",
+ rec->scsi_retries);
+ len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",
+ rec->scsi_allowed);
+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
+ rec->fsf_reqid);
+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
+ rec->fsf_seqno);
+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);
+ if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
+ len +=
+ zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x",
+ rec->type.fcp.rsp_validity);
+ len +=
+ zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status",
+ "0x%02x", rec->type.fcp.rsp_scsi_status);
+ len +=
+ zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x",
+ rec->type.fcp.rsp_resid);
+ len +=
+ zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x",
+ rec->type.fcp.rsp_code);
+ len +=
+ zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x",
+ rec->type.fcp.sns_info_len);
+ len +=
+ zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info",
+ rec->type.fcp.sns_info,
+ min((int)rec->type.fcp.sns_info_len,
+ ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
+ rec->type.fcp.sns_info_len);
+ } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx",
+ rec->type.new_fsf_req.fsf_reqid);
+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x",
+ rec->type.new_fsf_req.fsf_seqno);
+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
+ rec->type.new_fsf_req.fsf_issued);
+ } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) ||
+ (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) {
+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx",
+ rec->type.new_fsf_req.fsf_reqid);
+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x",
+ rec->type.new_fsf_req.fsf_seqno);
+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
+ rec->type.new_fsf_req.fsf_issued);
+ }
+
+ len += sprintf(out_buf + len, "\n");
+
+ return len;
+}
+
+struct debug_view zfcp_scsi_dbf_view = {
+ "structured",
+ NULL,
+ &zfcp_dbf_view_header,
+ &zfcp_scsi_dbf_view_format,
+ NULL,
+ NULL
+};
+
+/**
+ * zfcp_adapter_debug_register - registers debug feature for an adapter
+ * @adapter: pointer to adapter for which debug features should be registered
+ * return: -ENOMEM on error, 0 otherwise
+ */
+int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
+{
+ char dbf_name[DEBUG_MAX_NAME_LEN];
+
+ /* debug feature area which records recovery activity */
+ spin_lock_init(&adapter->erp_dbf_lock);
+ sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter));
+ adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2,
+ sizeof(struct zfcp_erp_dbf_record));
+ if (!adapter->erp_dbf)
+ goto failed;
+ debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
+ debug_set_level(adapter->erp_dbf, 3);
+
+ /* debug feature area which records HBA (FSF and QDIO) conditions */
+ spin_lock_init(&adapter->hba_dbf_lock);
+ sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
+ adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
+ sizeof(struct zfcp_hba_dbf_record));
+ if (!adapter->hba_dbf)
+ goto failed;
+ debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);
+ debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);
+ debug_set_level(adapter->hba_dbf, 3);
+
+ /* debug feature area which records SAN command failures and recovery */
+ spin_lock_init(&adapter->san_dbf_lock);
+ sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
+ adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
+ sizeof(struct zfcp_san_dbf_record));
+ if (!adapter->san_dbf)
+ goto failed;
+ debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);
+ debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);
+ debug_set_level(adapter->san_dbf, 6);
+
+ /* debug feature area which records SCSI command failures and recovery */
+ spin_lock_init(&adapter->scsi_dbf_lock);
+ sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
+ adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
+ sizeof(struct zfcp_scsi_dbf_record));
+ if (!adapter->scsi_dbf)
+ goto failed;
+ debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);
+ debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);
+ debug_set_level(adapter->scsi_dbf, 3);
+
+ return 0;
+
+ failed:
+ zfcp_adapter_debug_unregister(adapter);
+
+ return -ENOMEM;
+}
+
+/**
+ * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
+ * @adapter: pointer to adapter for which debug features should be unregistered
+ */
+void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
+{
+ debug_unregister(adapter->scsi_dbf);
+ debug_unregister(adapter->san_dbf);
+ debug_unregister(adapter->hba_dbf);
+ debug_unregister(adapter->erp_dbf);
+ adapter->scsi_dbf = NULL;
+ adapter->san_dbf = NULL;
+ adapter->hba_dbf = NULL;
+ adapter->erp_dbf = NULL;
+}
+
+#undef ZFCP_LOG_AREA
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 455e902533a9..d81b737d68cc 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -66,7 +66,7 @@
/********************* GENERAL DEFINES *********************************/
/* zfcp version number, it consists of major, minor, and patch-level number */
-#define ZFCP_VERSION "4.3.0"
+#define ZFCP_VERSION "4.5.0"
/**
* zfcp_sg_to_address - determine kernel address from struct scatterlist
@@ -154,13 +154,17 @@ typedef u32 scsi_lun_t;
#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100
#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7
+/* Retry 5 times every 2 second, then every minute */
+#define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES 5
+#define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP 200
+#define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP 6000
+
/* timeout value for "default timer" for fsf requests */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);
/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
typedef unsigned long long wwn_t;
-typedef unsigned int fc_id_t;
typedef unsigned long long fcp_lun_t;
/* data length field may be at variable position in FCP-2 FCP_CMND IU */
typedef unsigned int fcp_dl_t;
@@ -281,6 +285,171 @@ struct fcp_logo {
} __attribute__((packed));
/*
+ * DBF stuff
+ */
+#define ZFCP_DBF_TAG_SIZE 4
+
+struct zfcp_dbf_dump {
+ u8 tag[ZFCP_DBF_TAG_SIZE];
+ u32 total_size; /* size of total dump data */
+ u32 offset; /* how much data has being already dumped */
+ u32 size; /* how much data comes with this record */
+ u8 data[]; /* dump data */
+} __attribute__ ((packed));
+
+/* FIXME: to be inflated when reworking the erp dbf */
+struct zfcp_erp_dbf_record {
+ u8 dummy[16];
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record_response {
+ u32 fsf_command;
+ u64 fsf_reqid;
+ u32 fsf_seqno;
+ u64 fsf_issued;
+ u32 fsf_prot_status;
+ u32 fsf_status;
+ u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
+ u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
+ u32 fsf_req_status;
+ u8 sbal_first;
+ u8 sbal_curr;
+ u8 sbal_last;
+ u8 pool;
+ u64 erp_action;
+ union {
+ struct {
+ u64 scsi_cmnd;
+ u64 scsi_serial;
+ } send_fcp;
+ struct {
+ u64 wwpn;
+ u32 d_id;
+ u32 port_handle;
+ } port;
+ struct {
+ u64 wwpn;
+ u64 fcp_lun;
+ u32 port_handle;
+ u32 lun_handle;
+ } unit;
+ struct {
+ u32 d_id;
+ u8 ls_code;
+ } send_els;
+ } data;
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record_status {
+ u8 failed;
+ u32 status_type;
+ u32 status_subtype;
+ struct fsf_queue_designator
+ queue_designator;
+ u32 payload_size;
+#define ZFCP_DBF_UNSOL_PAYLOAD 80
+#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32
+#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56
+#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32)
+ u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record_qdio {
+ u32 status;
+ u32 qdio_error;
+ u32 siga_error;
+ u8 sbal_index;
+ u8 sbal_count;
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record {
+ u8 tag[ZFCP_DBF_TAG_SIZE];
+ u8 tag2[ZFCP_DBF_TAG_SIZE];
+ union {
+ struct zfcp_hba_dbf_record_response response;
+ struct zfcp_hba_dbf_record_status status;
+ struct zfcp_hba_dbf_record_qdio qdio;
+ } type;
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record_ct {
+ union {
+ struct {
+ u16 cmd_req_code;
+ u8 revision;
+ u8 gs_type;
+ u8 gs_subtype;
+ u8 options;
+ u16 max_res_size;
+ } request;
+ struct {
+ u16 cmd_rsp_code;
+ u8 revision;
+ u8 reason_code;
+ u8 reason_code_expl;
+ u8 vendor_unique;
+ } response;
+ } type;
+ u32 payload_size;
+#define ZFCP_DBF_CT_PAYLOAD 24
+ u8 payload[ZFCP_DBF_CT_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record_els {
+ u8 ls_code;
+ u32 payload_size;
+#define ZFCP_DBF_ELS_PAYLOAD 32
+#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
+ u8 payload[ZFCP_DBF_ELS_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record {
+ u8 tag[ZFCP_DBF_TAG_SIZE];
+ u64 fsf_reqid;
+ u32 fsf_seqno;
+ u32 s_id;
+ u32 d_id;
+ union {
+ struct zfcp_san_dbf_record_ct ct;
+ struct zfcp_san_dbf_record_els els;
+ } type;
+} __attribute__ ((packed));
+
+struct zfcp_scsi_dbf_record {
+ u8 tag[ZFCP_DBF_TAG_SIZE];
+ u8 tag2[ZFCP_DBF_TAG_SIZE];
+ u32 scsi_id;
+ u32 scsi_lun;
+ u32 scsi_result;
+ u64 scsi_cmnd;
+ u64 scsi_serial;
+#define ZFCP_DBF_SCSI_OPCODE 16
+ u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
+ u8 scsi_retries;
+ u8 scsi_allowed;
+ u64 fsf_reqid;
+ u32 fsf_seqno;
+ u64 fsf_issued;
+ union {
+ struct {
+ u64 fsf_reqid;
+ u32 fsf_seqno;
+ u64 fsf_issued;
+ } new_fsf_req;
+ struct {
+ u8 rsp_validity;
+ u8 rsp_scsi_status;
+ u32 rsp_resid;
+ u8 rsp_code;
+#define ZFCP_DBF_SCSI_FCP_SNS_INFO 16
+#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
+ u32 sns_info_len;
+ u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
+ } fcp;
+ } type;
+} __attribute__ ((packed));
+
+/*
* FC-FS stuff
*/
#define R_A_TOV 10 /* seconds */
@@ -339,34 +508,6 @@ struct zfcp_rc_entry {
*/
#define ZFCP_CT_TIMEOUT (3 * R_A_TOV)
-
-/***************** S390 DEBUG FEATURE SPECIFIC DEFINES ***********************/
-
-/* debug feature entries per adapter */
-#define ZFCP_ERP_DBF_INDEX 1
-#define ZFCP_ERP_DBF_AREAS 2
-#define ZFCP_ERP_DBF_LENGTH 16
-#define ZFCP_ERP_DBF_LEVEL 3
-#define ZFCP_ERP_DBF_NAME "zfcperp"
-
-#define ZFCP_CMD_DBF_INDEX 2
-#define ZFCP_CMD_DBF_AREAS 1
-#define ZFCP_CMD_DBF_LENGTH 8
-#define ZFCP_CMD_DBF_LEVEL 3
-#define ZFCP_CMD_DBF_NAME "zfcpcmd"
-
-#define ZFCP_ABORT_DBF_INDEX 2
-#define ZFCP_ABORT_DBF_AREAS 1
-#define ZFCP_ABORT_DBF_LENGTH 8
-#define ZFCP_ABORT_DBF_LEVEL 6
-#define ZFCP_ABORT_DBF_NAME "zfcpabt"
-
-#define ZFCP_IN_ELS_DBF_INDEX 2
-#define ZFCP_IN_ELS_DBF_AREAS 1
-#define ZFCP_IN_ELS_DBF_LENGTH 8
-#define ZFCP_IN_ELS_DBF_LEVEL 6
-#define ZFCP_IN_ELS_DBF_NAME "zfcpels"
-
/******************** LOGGING MACROS AND DEFINES *****************************/
/*
@@ -501,6 +642,7 @@ do { \
#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
+#define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800
#define ZFCP_STATUS_ADAPTER_SCSI_UP \
(ZFCP_STATUS_COMMON_UNBLOCKED | \
@@ -635,45 +777,6 @@ struct zfcp_adapter_mempool {
mempool_t *data_gid_pn;
};
-struct zfcp_exchange_config_data{
-};
-
-struct zfcp_open_port {
- struct zfcp_port *port;
-};
-
-struct zfcp_close_port {
- struct zfcp_port *port;
-};
-
-struct zfcp_open_unit {
- struct zfcp_unit *unit;
-};
-
-struct zfcp_close_unit {
- struct zfcp_unit *unit;
-};
-
-struct zfcp_close_physical_port {
- struct zfcp_port *port;
-};
-
-struct zfcp_send_fcp_command_task {
- struct zfcp_fsf_req *fsf_req;
- struct zfcp_unit *unit;
- struct scsi_cmnd *scsi_cmnd;
- unsigned long start_jiffies;
-};
-
-struct zfcp_send_fcp_command_task_management {
- struct zfcp_unit *unit;
-};
-
-struct zfcp_abort_fcp_command {
- struct zfcp_fsf_req *fsf_req;
- struct zfcp_unit *unit;
-};
-
/*
* header for CT_IU
*/
@@ -702,7 +805,7 @@ struct ct_iu_gid_pn_req {
/* FS_ACC IU and data unit for GID_PN nameserver request */
struct ct_iu_gid_pn_resp {
struct ct_hdr header;
- fc_id_t d_id;
+ u32 d_id;
} __attribute__ ((packed));
typedef void (*zfcp_send_ct_handler_t)(unsigned long);
@@ -768,7 +871,7 @@ typedef void (*zfcp_send_els_handler_t)(unsigned long);
struct zfcp_send_els {
struct zfcp_adapter *adapter;
struct zfcp_port *port;
- fc_id_t d_id;
+ u32 d_id;
struct scatterlist *req;
struct scatterlist *resp;
unsigned int req_count;
@@ -781,33 +884,6 @@ struct zfcp_send_els {
int status;
};
-struct zfcp_status_read {
- struct fsf_status_read_buffer *buffer;
-};
-
-struct zfcp_fsf_done {
- struct completion *complete;
- int status;
-};
-
-/* request specific data */
-union zfcp_req_data {
- struct zfcp_exchange_config_data exchange_config_data;
- struct zfcp_open_port open_port;
- struct zfcp_close_port close_port;
- struct zfcp_open_unit open_unit;
- struct zfcp_close_unit close_unit;
- struct zfcp_close_physical_port close_physical_port;
- struct zfcp_send_fcp_command_task send_fcp_command_task;
- struct zfcp_send_fcp_command_task_management
- send_fcp_command_task_management;
- struct zfcp_abort_fcp_command abort_fcp_command;
- struct zfcp_send_ct *send_ct;
- struct zfcp_send_els *send_els;
- struct zfcp_status_read status_read;
- struct fsf_qtcb_bottom_port *port_data;
-};
-
struct zfcp_qdio_queue {
struct qdio_buffer *buffer[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */
u8 free_index; /* index of next free bfr
@@ -838,21 +914,19 @@ struct zfcp_adapter {
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
- wwn_t wwnn; /* WWNN */
- wwn_t wwpn; /* WWPN */
- fc_id_t s_id; /* N_Port ID */
wwn_t peer_wwnn; /* P2P peer WWNN */
wwn_t peer_wwpn; /* P2P peer WWPN */
- fc_id_t peer_d_id; /* P2P peer D_ID */
+ u32 peer_d_id; /* P2P peer D_ID */
+ wwn_t physical_wwpn; /* WWPN of physical port */
+ u32 physical_s_id; /* local FC port ID */
struct ccw_device *ccw_device; /* S/390 ccw device */
u8 fc_service_class;
u32 fc_topology; /* FC topology */
- u32 fc_link_speed; /* FC interface speed */
u32 hydra_version; /* Hydra version */
u32 fsf_lic_version;
- u32 supported_features;/* of FCP channel */
+ u32 adapter_features; /* FCP channel features */
+ u32 connection_features; /* host connection features */
u32 hardware_version; /* of FCP channel */
- u8 serial_number[32]; /* of hardware */
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
unsigned short scsi_host_no; /* Assigned host number */
unsigned char name[9];
@@ -889,11 +963,18 @@ struct zfcp_adapter {
u32 erp_low_mem_count; /* nr of erp actions waiting
for memory */
struct zfcp_port *nameserver_port; /* adapter's nameserver */
- debug_info_t *erp_dbf; /* S/390 debug features */
- debug_info_t *abort_dbf;
- debug_info_t *in_els_dbf;
- debug_info_t *cmd_dbf;
- spinlock_t dbf_lock;
+ debug_info_t *erp_dbf;
+ debug_info_t *hba_dbf;
+ debug_info_t *san_dbf; /* debug feature areas */
+ debug_info_t *scsi_dbf;
+ spinlock_t erp_dbf_lock;
+ spinlock_t hba_dbf_lock;
+ spinlock_t san_dbf_lock;
+ spinlock_t scsi_dbf_lock;
+ struct zfcp_erp_dbf_record erp_dbf_buf;
+ struct zfcp_hba_dbf_record hba_dbf_buf;
+ struct zfcp_san_dbf_record san_dbf_buf;
+ struct zfcp_scsi_dbf_record scsi_dbf_buf;
struct zfcp_adapter_mempool pool; /* Adapter memory pools */
struct qdio_initialize qdio_init_data; /* for qdio_establish */
struct device generic_services; /* directory for WKA ports */
@@ -919,7 +1000,7 @@ struct zfcp_port {
atomic_t status; /* status of this remote port */
wwn_t wwnn; /* WWNN if known */
wwn_t wwpn; /* WWPN */
- fc_id_t d_id; /* D_ID */
+ u32 d_id; /* D_ID */
u32 handle; /* handle assigned by FSF */
struct zfcp_erp_action erp_action; /* pending error recovery */
atomic_t erp_counter;
@@ -963,11 +1044,13 @@ struct zfcp_fsf_req {
u32 fsf_command; /* FSF Command copy */
struct fsf_qtcb *qtcb; /* address of associated QTCB */
u32 seq_no; /* Sequence number of request */
- union zfcp_req_data data; /* Info fields of request */
+ unsigned long data; /* private data of request */
struct zfcp_erp_action *erp_action; /* used if this request is
issued on behalf of erp */
mempool_t *pool; /* used if request was alloacted
from emergency pool */
+ unsigned long long issued; /* request sent time (STCK) */
+ struct zfcp_unit *unit;
};
typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index cb4f612550ba..023f4e558ae4 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -82,6 +82,7 @@ static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *);
+static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_fsf_statusread(
struct zfcp_erp_action *);
@@ -345,13 +346,13 @@ zfcp_erp_adisc(struct zfcp_port *port)
/* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
without FC-AL-2 capability, so we don't set it */
- adisc->wwpn = adapter->wwpn;
- adisc->wwnn = adapter->wwnn;
- adisc->nport_id = adapter->s_id;
+ adisc->wwpn = fc_host_port_name(adapter->scsi_host);
+ adisc->wwnn = fc_host_node_name(adapter->scsi_host);
+ adisc->nport_id = fc_host_port_id(adapter->scsi_host);
ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "
"(wwpn=0x%016Lx, wwnn=0x%016Lx, "
"hard_nport_id=0x%08x, nport_id=0x%08x)\n",
- adapter->s_id, send_els->d_id, (wwn_t) adisc->wwpn,
+ adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn,
(wwn_t) adisc->wwnn, adisc->hard_nport_id,
adisc->nport_id);
@@ -404,7 +405,7 @@ zfcp_erp_adisc_handler(unsigned long data)
struct zfcp_send_els *send_els;
struct zfcp_port *port;
struct zfcp_adapter *adapter;
- fc_id_t d_id;
+ u32 d_id;
struct zfcp_ls_adisc_acc *adisc;
send_els = (struct zfcp_send_els *) data;
@@ -435,9 +436,9 @@ zfcp_erp_adisc_handler(unsigned long data)
ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "
"0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
"hard_nport_id=0x%08x, nport_id=0x%08x)\n",
- d_id, adapter->s_id, (wwn_t) adisc->wwpn,
- (wwn_t) adisc->wwnn, adisc->hard_nport_id,
- adisc->nport_id);
+ d_id, fc_host_port_id(adapter->scsi_host),
+ (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn,
+ adisc->hard_nport_id, adisc->nport_id);
/* set wwnn for port */
if (port->wwnn == 0)
@@ -886,7 +887,7 @@ static int
zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
{
int retval = 0;
- struct zfcp_fsf_req *fsf_req;
+ struct zfcp_fsf_req *fsf_req = NULL;
struct zfcp_adapter *adapter = erp_action->adapter;
if (erp_action->fsf_req) {
@@ -896,7 +897,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)
if (fsf_req == erp_action->fsf_req)
break;
- if (fsf_req == erp_action->fsf_req) {
+ if (fsf_req && (fsf_req->erp_action == erp_action)) {
/* fsf_req still exists */
debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
debug_event(adapter->erp_dbf, 3, &fsf_req,
@@ -2258,16 +2259,21 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
static int
zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
{
- int retval;
+ int xconfig, xport;
+
+ if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &erp_action->adapter->status)) {
+ zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
+ atomic_set(&erp_action->adapter->erp_counter, 0);
+ return ZFCP_ERP_FAILED;
+ }
- /* do 'exchange configuration data' */
- retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
- if (retval == ZFCP_ERP_FAILED)
- return retval;
+ xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
+ xport = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
+ if ((xconfig == ZFCP_ERP_FAILED) || (xport == ZFCP_ERP_FAILED))
+ return ZFCP_ERP_FAILED;
- /* start the desired number of Status Reads */
- retval = zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
- return retval;
+ return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
}
/*
@@ -2291,7 +2297,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&adapter->status);
ZFCP_LOG_DEBUG("Doing exchange config data\n");
+ write_lock(&adapter->erp_lock);
zfcp_erp_action_to_running(erp_action);
+ write_unlock(&adapter->erp_lock);
zfcp_erp_timeout_init(erp_action);
if (zfcp_fsf_exchange_config_data(erp_action)) {
retval = ZFCP_ERP_FAILED;
@@ -2348,6 +2356,76 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
return retval;
}
+static int
+zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
+{
+ int retval = ZFCP_ERP_SUCCEEDED;
+ int retries;
+ int sleep;
+ struct zfcp_adapter *adapter = erp_action->adapter;
+
+ atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
+
+ for (retries = 0; ; retries++) {
+ ZFCP_LOG_DEBUG("Doing exchange port data\n");
+ zfcp_erp_action_to_running(erp_action);
+ zfcp_erp_timeout_init(erp_action);
+ if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) {
+ retval = ZFCP_ERP_FAILED;
+ debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");
+ ZFCP_LOG_INFO("error: initiation of exchange of "
+ "port data failed for adapter %s\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ }
+ debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");
+ ZFCP_LOG_DEBUG("Xchange underway\n");
+
+ /*
+ * Why this works:
+ * Both the normal completion handler as well as the timeout
+ * handler will do an 'up' when the 'exchange port data'
+ * request completes or times out. Thus, the signal to go on
+ * won't be lost utilizing this semaphore.
+ * Furthermore, this 'adapter_reopen' action is
+ * guaranteed to be the only action being there (highest action
+ * which prevents other actions from being created).
+ * Resulting from that, the wake signal recognized here
+ * _must_ be the one belonging to the 'exchange port
+ * data' request.
+ */
+ down(&adapter->erp_ready_sem);
+ if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
+ ZFCP_LOG_INFO("error: exchange of port data "
+ "for adapter %s timed out\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ }
+
+ if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status))
+ break;
+
+ ZFCP_LOG_DEBUG("host connection still initialising... "
+ "waiting and retrying...\n");
+ /* sleep a little bit before retry */
+ sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ?
+ ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP :
+ ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
+ msleep(jiffies_to_msecs(sleep));
+ }
+
+ if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status)) {
+ ZFCP_LOG_INFO("error: exchange of port data for "
+ "adapter %s failed\n",
+ zfcp_get_busid_by_adapter(adapter));
+ retval = ZFCP_ERP_FAILED;
+ }
+
+ return retval;
+}
+
/*
* function:
*
@@ -3194,11 +3272,19 @@ zfcp_erp_action_enqueue(int action,
/* fall through !!! */
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
- if (atomic_test_mask
- (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)
- && port->erp_action.action ==
- ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
- debug_text_event(adapter->erp_dbf, 4, "pf_actenq_drp");
+ if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
+ &port->status)) {
+ if (port->erp_action.action !=
+ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
+ ZFCP_LOG_INFO("dropped erp action %i (port "
+ "0x%016Lx, action in use: %i)\n",
+ action, port->wwpn,
+ port->erp_action.action);
+ debug_text_event(adapter->erp_dbf, 4,
+ "pf_actenq_drp");
+ } else
+ debug_text_event(adapter->erp_dbf, 4,
+ "pf_actenq_drpcp");
debug_event(adapter->erp_dbf, 4, &port->wwpn,
sizeof (wwn_t));
goto out;
@@ -3589,6 +3675,9 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
struct zfcp_port *port;
unsigned long flags;
+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+ return;
+
debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index cd98a2de9f8f..c3782261cb5c 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -96,7 +96,8 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
-extern int zfcp_fsf_exchange_port_data(struct zfcp_adapter *,
+extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *,
+ struct zfcp_adapter *,
struct fsf_qtcb_bottom_port *);
extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
u32, u32, struct zfcp_sg_list *);
@@ -109,7 +110,6 @@ extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *,
extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
struct zfcp_erp_action *);
extern int zfcp_fsf_send_els(struct zfcp_send_els *);
-extern int zfcp_fsf_req_wait_and_cleanup(struct zfcp_fsf_req *, int, u32 *);
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *,
struct zfcp_unit *,
struct scsi_cmnd *,
@@ -182,9 +182,25 @@ extern void zfcp_erp_port_access_changed(struct zfcp_port *);
extern void zfcp_erp_unit_access_changed(struct zfcp_unit *);
/******************************** AUX ****************************************/
-extern void zfcp_cmd_dbf_event_fsf(const char *, struct zfcp_fsf_req *,
- void *, int);
-extern void zfcp_cmd_dbf_event_scsi(const char *, struct scsi_cmnd *);
-extern void zfcp_in_els_dbf_event(struct zfcp_adapter *, const char *,
- struct fsf_status_read_buffer *, int);
+extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
+extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
+ struct fsf_status_read_buffer *);
+extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *,
+ unsigned int, unsigned int, unsigned int,
+ int, int);
+
+extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *);
+extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *);
+extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *);
+extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *);
+extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *);
+
+extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *,
+ struct scsi_cmnd *);
+extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
+ struct scsi_cmnd *,
+ struct zfcp_fsf_req *);
+extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
+ struct scsi_cmnd *);
+
#endif /* ZFCP_EXT_H */
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index c007b6424e74..3b0fc1163f5f 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -59,6 +59,8 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *, struct timer_list *);
static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
+static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *,
+ struct fsf_link_down_info *);
static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *);
@@ -285,51 +287,51 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
{
int retval = 0;
struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct fsf_qtcb *qtcb = fsf_req->qtcb;
+ union fsf_prot_status_qual *prot_status_qual =
+ &qtcb->prefix.prot_status_qual;
- ZFCP_LOG_DEBUG("QTCB is at %p\n", fsf_req->qtcb);
+ zfcp_hba_dbf_event_fsf_response(fsf_req);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n",
(unsigned long) fsf_req);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */
- zfcp_cmd_dbf_event_fsf("dismiss", fsf_req, NULL, 0);
goto skip_protstatus;
}
/* log additional information provided by FSF (if any) */
- if (unlikely(fsf_req->qtcb->header.log_length)) {
+ if (unlikely(qtcb->header.log_length)) {
/* do not trust them ;-) */
- if (fsf_req->qtcb->header.log_start > sizeof(struct fsf_qtcb)) {
+ if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) {
ZFCP_LOG_NORMAL
("bug: ULP (FSF logging) log data starts "
"beyond end of packet header. Ignored. "
"(start=%i, size=%li)\n",
- fsf_req->qtcb->header.log_start,
+ qtcb->header.log_start,
sizeof(struct fsf_qtcb));
goto forget_log;
}
- if ((size_t) (fsf_req->qtcb->header.log_start +
- fsf_req->qtcb->header.log_length)
+ if ((size_t) (qtcb->header.log_start + qtcb->header.log_length)
> sizeof(struct fsf_qtcb)) {
ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends "
"beyond end of packet header. Ignored. "
"(start=%i, length=%i, size=%li)\n",
- fsf_req->qtcb->header.log_start,
- fsf_req->qtcb->header.log_length,
+ qtcb->header.log_start,
+ qtcb->header.log_length,
sizeof(struct fsf_qtcb));
goto forget_log;
}
ZFCP_LOG_TRACE("ULP log data: \n");
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
- (char *) fsf_req->qtcb +
- fsf_req->qtcb->header.log_start,
- fsf_req->qtcb->header.log_length);
+ (char *) qtcb + qtcb->header.log_start,
+ qtcb->header.log_length);
}
forget_log:
/* evaluate FSF Protocol Status */
- switch (fsf_req->qtcb->prefix.prot_status) {
+ switch (qtcb->prefix.prot_status) {
case FSF_PROT_GOOD:
case FSF_PROT_FSF_STATUS_PRESENTED:
@@ -340,14 +342,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"microcode of version 0x%x, the device driver "
"only supports 0x%x. Aborting.\n",
zfcp_get_busid_by_adapter(adapter),
- fsf_req->qtcb->prefix.prot_status_qual.
- version_error.fsf_version, ZFCP_QTCB_VERSION);
- /* stop operation for this adapter */
- debug_text_exception(adapter->erp_dbf, 0, "prot_ver_err");
+ prot_status_qual->version_error.fsf_version,
+ ZFCP_QTCB_VERSION);
zfcp_erp_adapter_shutdown(adapter, 0);
- zfcp_cmd_dbf_event_fsf("qverserr", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -355,16 +352,10 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
ZFCP_LOG_NORMAL("bug: Sequence number mismatch between "
"driver (0x%x) and adapter %s (0x%x). "
"Restarting all operations on this adapter.\n",
- fsf_req->qtcb->prefix.req_seq_no,
+ qtcb->prefix.req_seq_no,
zfcp_get_busid_by_adapter(adapter),
- fsf_req->qtcb->prefix.prot_status_qual.
- sequence_error.exp_req_seq_no);
- debug_text_exception(adapter->erp_dbf, 0, "prot_seq_err");
- /* restart operation on this adapter */
+ prot_status_qual->sequence_error.exp_req_seq_no);
zfcp_erp_adapter_reopen(adapter, 0);
- zfcp_cmd_dbf_event_fsf("seqnoerr", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -375,116 +366,35 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"that used on adapter %s. "
"Stopping all operations on this adapter.\n",
zfcp_get_busid_by_adapter(adapter));
- debug_text_exception(adapter->erp_dbf, 0, "prot_unsup_qtcb");
zfcp_erp_adapter_shutdown(adapter, 0);
- zfcp_cmd_dbf_event_fsf("unsqtcbt", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_HOST_CONNECTION_INITIALIZING:
- zfcp_cmd_dbf_event_fsf("hconinit", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&(adapter->status));
- debug_text_event(adapter->erp_dbf, 3, "prot_con_init");
break;
case FSF_PROT_DUPLICATE_REQUEST_ID:
- if (fsf_req->qtcb) {
ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx "
"to the adapter %s is ambiguous. "
- "Stopping all operations on this "
- "adapter.\n",
- *(unsigned long long *)
- (&fsf_req->qtcb->bottom.support.
- req_handle),
- zfcp_get_busid_by_adapter(adapter));
- } else {
- ZFCP_LOG_NORMAL("bug: The request identifier %p "
- "to the adapter %s is ambiguous. "
- "Stopping all operations on this "
- "adapter. "
- "(bug: got this for an unsolicited "
- "status read request)\n",
- fsf_req,
+ "Stopping all operations on this adapter.\n",
+ *(unsigned long long*)
+ (&qtcb->bottom.support.req_handle),
zfcp_get_busid_by_adapter(adapter));
- }
- debug_text_exception(adapter->erp_dbf, 0, "prot_dup_id");
zfcp_erp_adapter_shutdown(adapter, 0);
- zfcp_cmd_dbf_event_fsf("dupreqid", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_LINK_DOWN:
- /*
- * 'test and set' is not atomic here -
- * it's ok as long as calls to our response queue handler
- * (and thus execution of this code here) are serialized
- * by the qdio module
- */
- if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status)) {
- switch (fsf_req->qtcb->prefix.prot_status_qual.
- locallink_error.code) {
- case FSF_PSQ_LINK_NOLIGHT:
- ZFCP_LOG_INFO("The local link to adapter %s "
- "is down (no light detected).\n",
- zfcp_get_busid_by_adapter(
- adapter));
- break;
- case FSF_PSQ_LINK_WRAPPLUG:
- ZFCP_LOG_INFO("The local link to adapter %s "
- "is down (wrap plug detected).\n",
- zfcp_get_busid_by_adapter(
- adapter));
- break;
- case FSF_PSQ_LINK_NOFCP:
- ZFCP_LOG_INFO("The local link to adapter %s "
- "is down (adjacent node on "
- "link does not support FCP).\n",
- zfcp_get_busid_by_adapter(
- adapter));
- break;
- default:
- ZFCP_LOG_INFO("The local link to adapter %s "
- "is down "
- "(warning: unknown reason "
- "code).\n",
- zfcp_get_busid_by_adapter(
- adapter));
- break;
-
- }
- /*
- * Due to the 'erp failed' flag the adapter won't
- * be recovered but will be just set to 'blocked'
- * state. All subordinary devices will have state
- * 'blocked' and 'erp failed', too.
- * Thus the adapter is still able to provide
- * 'link up' status without being flooded with
- * requests.
- * (note: even 'close port' is not permitted)
- */
- ZFCP_LOG_INFO("Stopping all operations for adapter "
- "%s.\n",
- zfcp_get_busid_by_adapter(adapter));
- atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
- ZFCP_STATUS_COMMON_ERP_FAILED,
- &adapter->status);
- zfcp_erp_adapter_reopen(adapter, 0);
- }
+ zfcp_fsf_link_down_info_eval(adapter,
+ &prot_status_qual->link_down_info);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_REEST_QUEUE:
- debug_text_event(adapter->erp_dbf, 1, "prot_reest_queue");
- ZFCP_LOG_INFO("The local link to adapter with "
+ ZFCP_LOG_NORMAL("The local link to adapter with "
"%s was re-plugged. "
"Re-starting operations on this adapter.\n",
zfcp_get_busid_by_adapter(adapter));
@@ -495,9 +405,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
| ZFCP_STATUS_COMMON_ERP_FAILED);
- zfcp_cmd_dbf_event_fsf("reestque", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -507,12 +414,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"Restarting all operations on this "
"adapter.\n",
zfcp_get_busid_by_adapter(adapter));
- debug_text_event(adapter->erp_dbf, 0, "prot_err_sta");
- /* restart operation on this adapter */
zfcp_erp_adapter_reopen(adapter, 0);
- zfcp_cmd_dbf_event_fsf("proterrs", fsf_req,
- &fsf_req->qtcb->prefix.prot_status_qual,
- sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -524,11 +426,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"Stopping all operations on this adapter. "
"(debug info 0x%x).\n",
zfcp_get_busid_by_adapter(adapter),
- fsf_req->qtcb->prefix.prot_status);
- debug_text_event(adapter->erp_dbf, 0, "prot_inval:");
- debug_exception(adapter->erp_dbf, 0,
- &fsf_req->qtcb->prefix.prot_status,
- sizeof (u32));
+ qtcb->prefix.prot_status);
zfcp_erp_adapter_shutdown(adapter, 0);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -568,28 +466,18 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req)
"(debug info 0x%x).\n",
zfcp_get_busid_by_adapter(fsf_req->adapter),
fsf_req->qtcb->header.fsf_command);
- debug_text_exception(fsf_req->adapter->erp_dbf, 0,
- "fsf_s_unknown");
zfcp_erp_adapter_shutdown(fsf_req->adapter, 0);
- zfcp_cmd_dbf_event_fsf("unknownc", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_FCP_RSP_AVAILABLE:
ZFCP_LOG_DEBUG("FCP Sense data will be presented to the "
"SCSI stack.\n");
- debug_text_event(fsf_req->adapter->erp_dbf, 3, "fsf_s_rsp");
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
- debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_astatus");
zfcp_fsf_fsfstatus_qual_eval(fsf_req);
break;
-
- default:
- break;
}
skip_fsfstatus:
@@ -617,44 +505,28 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
case FSF_SQ_FCP_RSP_AVAILABLE:
- debug_text_event(fsf_req->adapter->erp_dbf, 4, "fsf_sq_rsp");
break;
case FSF_SQ_RETRY_IF_POSSIBLE:
/* The SCSI-stack may now issue retries or escalate */
- debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_retry");
- zfcp_cmd_dbf_event_fsf("sqretry", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_COMMAND_ABORTED:
/* Carry the aborted state on to upper layer */
- debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_abort");
- zfcp_cmd_dbf_event_fsf("sqabort", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_NO_RECOM:
- debug_text_exception(fsf_req->adapter->erp_dbf, 0,
- "fsf_sq_no_rec");
ZFCP_LOG_NORMAL("bug: No recommendation could be given for a"
"problem on the adapter %s "
"Stopping all operations on this adapter. ",
zfcp_get_busid_by_adapter(fsf_req->adapter));
zfcp_erp_adapter_shutdown(fsf_req->adapter, 0);
- zfcp_cmd_dbf_event_fsf("sqnrecom", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_ULP_PROGRAMMING_ERROR:
ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer "
"(adapter %s)\n",
zfcp_get_busid_by_adapter(fsf_req->adapter));
- debug_text_exception(fsf_req->adapter->erp_dbf, 0,
- "fsf_sq_ulp_err");
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
@@ -668,13 +540,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
(char *) &fsf_req->qtcb->header.fsf_status_qual,
sizeof (union fsf_status_qual));
- debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_sq_inval:");
- debug_exception(fsf_req->adapter->erp_dbf, 0,
- &fsf_req->qtcb->header.fsf_status_qual.word[0],
- sizeof (u32));
- zfcp_cmd_dbf_event_fsf("squndef", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
}
@@ -682,6 +547,110 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
return retval;
}
+/**
+ * zfcp_fsf_link_down_info_eval - evaluate link down information block
+ */
+static void
+zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
+ struct fsf_link_down_info *link_down)
+{
+ switch (link_down->error_code) {
+ case FSF_PSQ_LINK_NO_LIGHT:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(no light detected)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_WRAP_PLUG:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(wrap plug detected)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_NO_FCP:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(adjacent node on link does not support FCP)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_FIRMWARE_UPDATE:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(firmware update in progress)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_INVALID_WWPN:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(duplicate or invalid WWPN detected)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_NO_NPIV_SUPPORT:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(no support for NPIV by Fabric)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_NO_FCP_RESOURCES:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(out of resource in FCP daughtercard)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_NO_FABRIC_RESOURCES:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(out of resource in Fabric)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(unable to Fabric login)\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED:
+ ZFCP_LOG_NORMAL("WWPN assignment file corrupted on adapter %s\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED:
+ ZFCP_LOG_NORMAL("Mode table corrupted on adapter %s\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT:
+ ZFCP_LOG_NORMAL("No WWPN for assignment table on adapter %s\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ default:
+ ZFCP_LOG_NORMAL("The local link to adapter %s is down "
+ "(warning: unknown reason code %d)\n",
+ zfcp_get_busid_by_adapter(adapter),
+ link_down->error_code);
+ }
+
+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+ ZFCP_LOG_DEBUG("Debug information to link down: "
+ "primary_status=0x%02x "
+ "ioerr_code=0x%02x "
+ "action_code=0x%02x "
+ "reason_code=0x%02x "
+ "explanation_code=0x%02x "
+ "vendor_specific_code=0x%02x\n",
+ link_down->primary_status,
+ link_down->ioerr_code,
+ link_down->action_code,
+ link_down->reason_code,
+ link_down->explanation_code,
+ link_down->vendor_specific_code);
+
+ if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status)) {
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status);
+ switch (link_down->error_code) {
+ case FSF_PSQ_LINK_NO_LIGHT:
+ case FSF_PSQ_LINK_WRAP_PLUG:
+ case FSF_PSQ_LINK_NO_FCP:
+ case FSF_PSQ_LINK_FIRMWARE_UPDATE:
+ zfcp_erp_adapter_reopen(adapter, 0);
+ break;
+ default:
+ zfcp_erp_adapter_failed(adapter);
+ }
+ }
+}
+
/*
* function: zfcp_fsf_req_dispatch
*
@@ -696,11 +665,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
struct zfcp_adapter *adapter = fsf_req->adapter;
int retval = 0;
- if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
- ZFCP_LOG_TRACE("fsf_req=%p, QTCB=%p\n", fsf_req, fsf_req->qtcb);
- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
- (char *) fsf_req->qtcb, sizeof(struct fsf_qtcb));
- }
switch (fsf_req->fsf_command) {
@@ -760,13 +724,13 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
ZFCP_LOG_NORMAL("bug: Command issued by the device driver is "
"not supported by the adapter %s\n",
- zfcp_get_busid_by_adapter(fsf_req->adapter));
+ zfcp_get_busid_by_adapter(adapter));
if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command)
ZFCP_LOG_NORMAL
("bug: Command issued by the device driver differs "
"from the command returned by the adapter %s "
"(debug info 0x%x, 0x%x).\n",
- zfcp_get_busid_by_adapter(fsf_req->adapter),
+ zfcp_get_busid_by_adapter(adapter),
fsf_req->fsf_command,
fsf_req->qtcb->header.fsf_command);
}
@@ -774,8 +738,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
if (!erp_action)
return retval;
- debug_text_event(adapter->erp_dbf, 3, "a_frh");
- debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
zfcp_erp_async_handler(erp_action, 0);
return retval;
@@ -821,7 +783,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
goto failed_buf;
}
memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer));
- fsf_req->data.status_read.buffer = status_buffer;
+ fsf_req->data = (unsigned long) status_buffer;
/* insert pointer to respective buffer */
sbale = zfcp_qdio_sbale_curr(fsf_req);
@@ -846,6 +808,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
failed_buf:
zfcp_fsf_req_free(fsf_req);
failed_req_create:
+ zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
out:
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
return retval;
@@ -859,7 +822,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req)
struct zfcp_port *port;
unsigned long flags;
- status_buffer = fsf_req->data.status_read.buffer;
+ status_buffer = (struct fsf_status_read_buffer *) fsf_req->data;
adapter = fsf_req->adapter;
read_lock_irqsave(&zfcp_data.config_lock, flags);
@@ -918,38 +881,33 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
int retval = 0;
struct zfcp_adapter *adapter = fsf_req->adapter;
struct fsf_status_read_buffer *status_buffer =
- fsf_req->data.status_read.buffer;
+ (struct fsf_status_read_buffer *) fsf_req->data;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
+ zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer);
mempool_free(status_buffer, adapter->pool.data_status_read);
zfcp_fsf_req_free(fsf_req);
goto out;
}
+ zfcp_hba_dbf_event_fsf_unsol("read", adapter, status_buffer);
+
switch (status_buffer->status_type) {
case FSF_STATUS_READ_PORT_CLOSED:
- debug_text_event(adapter->erp_dbf, 3, "unsol_pclosed:");
- debug_event(adapter->erp_dbf, 3,
- &status_buffer->d_id, sizeof (u32));
zfcp_fsf_status_read_port_closed(fsf_req);
break;
case FSF_STATUS_READ_INCOMING_ELS:
- debug_text_event(adapter->erp_dbf, 3, "unsol_els:");
zfcp_fsf_incoming_els(fsf_req);
break;
case FSF_STATUS_READ_SENSE_DATA_AVAIL:
- debug_text_event(adapter->erp_dbf, 3, "unsol_sense:");
ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, (char *) status_buffer,
- sizeof(struct fsf_status_read_buffer));
break;
case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
- debug_text_event(adapter->erp_dbf, 3, "unsol_bit_err:");
ZFCP_LOG_NORMAL("Bit error threshold data received:\n");
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
(char *) status_buffer,
@@ -957,17 +915,32 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
break;
case FSF_STATUS_READ_LINK_DOWN:
- debug_text_event(adapter->erp_dbf, 0, "unsol_link_down:");
- ZFCP_LOG_INFO("Local link to adapter %s is down\n",
+ switch (status_buffer->status_subtype) {
+ case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
+ ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ case FSF_STATUS_READ_SUB_FDISC_FAILED:
+ ZFCP_LOG_INFO("Local link to adapter %s is down "
+ "due to failed FDISC login\n",
zfcp_get_busid_by_adapter(adapter));
- atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status);
- zfcp_erp_adapter_failed(adapter);
+ break;
+ case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
+ ZFCP_LOG_INFO("Local link to adapter %s is down "
+ "due to firmware update on adapter\n",
+ zfcp_get_busid_by_adapter(adapter));
+ break;
+ default:
+ ZFCP_LOG_INFO("Local link to adapter %s is down "
+ "due to unknown reason\n",
+ zfcp_get_busid_by_adapter(adapter));
+ };
+ zfcp_fsf_link_down_info_eval(adapter,
+ (struct fsf_link_down_info *) &status_buffer->payload);
break;
case FSF_STATUS_READ_LINK_UP:
- debug_text_event(adapter->erp_dbf, 2, "unsol_link_up:");
- ZFCP_LOG_INFO("Local link to adapter %s was replugged. "
+ ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "
"Restarting operations on this adapter\n",
zfcp_get_busid_by_adapter(adapter));
/* All ports should be marked as ready to run again */
@@ -980,35 +953,40 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
break;
case FSF_STATUS_READ_CFDC_UPDATED:
- debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_update:");
- ZFCP_LOG_INFO("CFDC has been updated on the adapter %s\n",
+ ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
zfcp_erp_adapter_access_changed(adapter);
break;
case FSF_STATUS_READ_CFDC_HARDENED:
- debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_harden:");
switch (status_buffer->status_subtype) {
case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE:
- ZFCP_LOG_INFO("CFDC of adapter %s saved on SE\n",
+ ZFCP_LOG_NORMAL("CFDC of adapter %s saved on SE\n",
zfcp_get_busid_by_adapter(adapter));
break;
case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2:
- ZFCP_LOG_INFO("CFDC of adapter %s has been copied "
+ ZFCP_LOG_NORMAL("CFDC of adapter %s has been copied "
"to the secondary SE\n",
zfcp_get_busid_by_adapter(adapter));
break;
default:
- ZFCP_LOG_INFO("CFDC of adapter %s has been hardened\n",
+ ZFCP_LOG_NORMAL("CFDC of adapter %s has been hardened\n",
zfcp_get_busid_by_adapter(adapter));
}
break;
+ case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
+ debug_text_event(adapter->erp_dbf, 2, "unsol_features:");
+ ZFCP_LOG_INFO("List of supported features on adapter %s has "
+ "been changed from 0x%08X to 0x%08X\n",
+ zfcp_get_busid_by_adapter(adapter),
+ *(u32*) (status_buffer->payload + 4),
+ *(u32*) (status_buffer->payload));
+ adapter->adapter_features = *(u32*) status_buffer->payload;
+ break;
+
default:
- debug_text_event(adapter->erp_dbf, 0, "unsol_unknown:");
- debug_exception(adapter->erp_dbf, 0,
- &status_buffer->status_type, sizeof (u32));
- ZFCP_LOG_NORMAL("bug: An unsolicited status packet of unknown "
+ ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown "
"type was received (debug info 0x%x)\n",
status_buffer->status_type);
ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n",
@@ -1093,7 +1071,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
- fsf_req->data.abort_fcp_command.unit = unit;
+ fsf_req->data = (unsigned long) unit;
/* set handles of unit and its parent port in QTCB */
fsf_req->qtcb->header.lun_handle = unit->handle;
@@ -1139,7 +1117,7 @@ static int
zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
{
int retval = -EINVAL;
- struct zfcp_unit *unit = new_fsf_req->data.abort_fcp_command.unit;
+ struct zfcp_unit *unit;
unsigned char status_qual =
new_fsf_req->qtcb->header.fsf_status_qual.word[0];
@@ -1150,6 +1128,8 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
goto skip_fsfstatus;
}
+ unit = (struct zfcp_unit *) new_fsf_req->data;
+
/* evaluate FSF status in QTCB */
switch (new_fsf_req->qtcb->header.fsf_status) {
@@ -1364,7 +1344,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]);
sbale[3].length = ct->resp[0].length;
sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
- } else if (adapter->supported_features &
+ } else if (adapter->adapter_features &
FSF_FEATURE_ELS_CT_CHAINED_SBALS) {
/* try to use chained SBALs */
bytes = zfcp_qdio_sbals_from_sg(fsf_req,
@@ -1414,7 +1394,9 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
fsf_req->qtcb->header.port_handle = port->handle;
fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
fsf_req->qtcb->bottom.support.timeout = ct->timeout;
- fsf_req->data.send_ct = ct;
+ fsf_req->data = (unsigned long) ct;
+
+ zfcp_san_dbf_event_ct_request(fsf_req);
/* start QDIO request for this FSF request */
ret = zfcp_fsf_req_send(fsf_req, ct->timer);
@@ -1445,10 +1427,10 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
* zfcp_fsf_send_ct_handler - handler for Generic Service requests
* @fsf_req: pointer to struct zfcp_fsf_req
*
- * Data specific for the Generic Service request is passed by
- * fsf_req->data.send_ct
- * Usually a specific handler for the request is called via
- * fsf_req->data.send_ct->handler at end of this function.
+ * Data specific for the Generic Service request is passed using
+ * fsf_req->data. There we find the pointer to struct zfcp_send_ct.
+ * Usually a specific handler for the CT request is called which is
+ * found in this structure.
*/
static int
zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
@@ -1462,7 +1444,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
u16 subtable, rule, counter;
adapter = fsf_req->adapter;
- send_ct = fsf_req->data.send_ct;
+ send_ct = (struct zfcp_send_ct *) fsf_req->data;
port = send_ct->port;
header = &fsf_req->qtcb->header;
bottom = &fsf_req->qtcb->bottom.support;
@@ -1474,6 +1456,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
switch (header->fsf_status) {
case FSF_GOOD:
+ zfcp_san_dbf_event_ct_response(fsf_req);
retval = 0;
break;
@@ -1634,7 +1617,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
- fc_id_t d_id;
+ u32 d_id;
struct zfcp_adapter *adapter;
unsigned long lock_flags;
int bytes;
@@ -1664,7 +1647,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
sbale[3].addr = zfcp_sg_to_address(&els->resp[0]);
sbale[3].length = els->resp[0].length;
sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
- } else if (adapter->supported_features &
+ } else if (adapter->adapter_features &
FSF_FEATURE_ELS_CT_CHAINED_SBALS) {
/* try to use chained SBALs */
bytes = zfcp_qdio_sbals_from_sg(fsf_req,
@@ -1714,10 +1697,12 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
fsf_req->qtcb->bottom.support.d_id = d_id;
fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT;
- fsf_req->data.send_els = els;
+ fsf_req->data = (unsigned long) els;
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
+ zfcp_san_dbf_event_els_request(fsf_req);
+
/* start QDIO request for this FSF request */
ret = zfcp_fsf_req_send(fsf_req, els->timer);
if (ret) {
@@ -1746,23 +1731,23 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
* zfcp_fsf_send_els_handler - handler for ELS commands
* @fsf_req: pointer to struct zfcp_fsf_req
*
- * Data specific for the ELS command is passed by
- * fsf_req->data.send_els
- * Usually a specific handler for the command is called via
- * fsf_req->data.send_els->handler at end of this function.
+ * Data specific for the ELS command is passed using
+ * fsf_req->data. There we find the pointer to struct zfcp_send_els.
+ * Usually a specific handler for the ELS command is called which is
+ * found in this structure.
*/
static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_adapter *adapter;
struct zfcp_port *port;
- fc_id_t d_id;
+ u32 d_id;
struct fsf_qtcb_header *header;
struct fsf_qtcb_bottom_support *bottom;
struct zfcp_send_els *send_els;
int retval = -EINVAL;
u16 subtable, rule, counter;
- send_els = fsf_req->data.send_els;
+ send_els = (struct zfcp_send_els *) fsf_req->data;
adapter = send_els->adapter;
port = send_els->port;
d_id = send_els->d_id;
@@ -1775,6 +1760,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
switch (header->fsf_status) {
case FSF_GOOD:
+ zfcp_san_dbf_event_els_response(fsf_req);
retval = 0;
break;
@@ -1954,7 +1940,9 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req->erp_action = erp_action;
erp_action->fsf_req->qtcb->bottom.config.feature_selection =
- (FSF_FEATURE_CFDC | FSF_FEATURE_LUN_SHARING);
+ FSF_FEATURE_CFDC |
+ FSF_FEATURE_LUN_SHARING |
+ FSF_FEATURE_UPDATE_ALERT;
/* start QDIO request for this FSF request */
retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
@@ -1990,29 +1978,36 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
{
struct fsf_qtcb_bottom_config *bottom;
struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct Scsi_Host *shost = adapter->scsi_host;
bottom = &fsf_req->qtcb->bottom.config;
ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n",
bottom->low_qtcb_version, bottom->high_qtcb_version);
adapter->fsf_lic_version = bottom->lic_version;
- adapter->supported_features = bottom->supported_features;
+ adapter->adapter_features = bottom->adapter_features;
+ adapter->connection_features = bottom->connection_features;
adapter->peer_wwpn = 0;
adapter->peer_wwnn = 0;
adapter->peer_d_id = 0;
if (xchg_ok) {
- adapter->wwnn = bottom->nport_serv_param.wwnn;
- adapter->wwpn = bottom->nport_serv_param.wwpn;
- adapter->s_id = bottom->s_id & ZFCP_DID_MASK;
+ fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;
+ fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;
+ fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
+ fc_host_speed(shost) = bottom->fc_link_speed;
+ fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
adapter->fc_topology = bottom->fc_topology;
- adapter->fc_link_speed = bottom->fc_link_speed;
adapter->hydra_version = bottom->adapter_type;
+ if (adapter->physical_wwpn == 0)
+ adapter->physical_wwpn = fc_host_port_name(shost);
+ if (adapter->physical_s_id == 0)
+ adapter->physical_s_id = fc_host_port_id(shost);
} else {
- adapter->wwnn = 0;
- adapter->wwpn = 0;
- adapter->s_id = 0;
+ fc_host_node_name(shost) = 0;
+ fc_host_port_name(shost) = 0;
+ fc_host_port_id(shost) = 0;
+ fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
adapter->fc_topology = 0;
- adapter->fc_link_speed = 0;
adapter->hydra_version = 0;
}
@@ -2022,26 +2017,28 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
adapter->peer_wwnn = bottom->plogi_payload.wwnn;
}
- if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){
+ if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
adapter->hardware_version = bottom->hardware_version;
- memcpy(adapter->serial_number, bottom->serial_number, 17);
- EBCASC(adapter->serial_number, sizeof(adapter->serial_number));
+ memcpy(fc_host_serial_number(shost), bottom->serial_number,
+ min(FC_SERIAL_NUMBER_SIZE, 17));
+ EBCASC(fc_host_serial_number(shost),
+ min(FC_SERIAL_NUMBER_SIZE, 17));
}
ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n"
- "WWNN 0x%016Lx, "
- "WWPN 0x%016Lx, "
- "S_ID 0x%08x,\n"
- "adapter version 0x%x, "
- "LIC version 0x%x, "
- "FC link speed %d Gb/s\n",
- zfcp_get_busid_by_adapter(adapter),
- adapter->wwnn,
- adapter->wwpn,
- (unsigned int) adapter->s_id,
- adapter->hydra_version,
- adapter->fsf_lic_version,
- adapter->fc_link_speed);
+ "WWNN 0x%016Lx, "
+ "WWPN 0x%016Lx, "
+ "S_ID 0x%08x,\n"
+ "adapter version 0x%x, "
+ "LIC version 0x%x, "
+ "FC link speed %d Gb/s\n",
+ zfcp_get_busid_by_adapter(adapter),
+ (wwn_t) fc_host_node_name(shost),
+ (wwn_t) fc_host_port_name(shost),
+ fc_host_port_id(shost),
+ adapter->hydra_version,
+ adapter->fsf_lic_version,
+ fc_host_speed(shost));
if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) {
ZFCP_LOG_NORMAL("error: the adapter %s "
"only supports newer control block "
@@ -2062,7 +2059,6 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
}
- zfcp_set_fc_host_attrs(adapter);
return 0;
}
@@ -2078,11 +2074,12 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
{
struct fsf_qtcb_bottom_config *bottom;
struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct fsf_qtcb *qtcb = fsf_req->qtcb;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
return -EIO;
- switch (fsf_req->qtcb->header.fsf_status) {
+ switch (qtcb->header.fsf_status) {
case FSF_GOOD:
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
@@ -2112,7 +2109,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
case FSF_TOPO_FABRIC:
- ZFCP_LOG_INFO("Switched fabric fibrechannel "
+ ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
"network detected at adapter %s.\n",
zfcp_get_busid_by_adapter(adapter));
break;
@@ -2130,7 +2127,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
}
- bottom = &fsf_req->qtcb->bottom.config;
+ bottom = &qtcb->bottom.config;
if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) {
ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) "
"allowed by the adapter %s "
@@ -2155,12 +2152,10 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
return -EIO;
- ZFCP_LOG_INFO("Local link to adapter %s is down\n",
- zfcp_get_busid_by_adapter(adapter));
- atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
- ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status);
- zfcp_erp_adapter_failed(adapter);
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);
+
+ zfcp_fsf_link_down_info_eval(adapter,
+ &qtcb->header.fsf_status_qual.link_down_info);
break;
default:
debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng");
@@ -2174,11 +2169,13 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
/**
* zfcp_fsf_exchange_port_data - request information about local port
+ * @erp_action: ERP action for the adapter for which port data is requested
* @adapter: for which port data is requested
* @data: response to exchange port data request
*/
int
-zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter,
+zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
+ struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_port *data)
{
volatile struct qdio_buffer_element *sbale;
@@ -2187,7 +2184,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter,
struct zfcp_fsf_req *fsf_req;
struct timer_list *timer;
- if(!(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT)){
+ if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
ZFCP_LOG_INFO("error: exchange port data "
"command not supported by adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
@@ -2211,12 +2208,18 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter,
goto out;
}
+ if (erp_action) {
+ erp_action->fsf_req = fsf_req;
+ fsf_req->erp_action = erp_action;
+ }
+
+ if (data)
+ fsf_req->data = (unsigned long) data;
+
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
- fsf_req->data.port_data = data;
-
init_timer(timer);
timer->function = zfcp_fsf_request_timeout_handler;
timer->data = (unsigned long) adapter;
@@ -2228,6 +2231,8 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter,
"command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
zfcp_fsf_req_free(fsf_req);
+ if (erp_action)
+ erp_action->fsf_req = NULL;
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
goto out;
@@ -2256,21 +2261,42 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter,
static void
zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
{
- struct fsf_qtcb_bottom_port *bottom;
- struct fsf_qtcb_bottom_port *data = fsf_req->data.port_data;
+ struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct Scsi_Host *shost = adapter->scsi_host;
+ struct fsf_qtcb *qtcb = fsf_req->qtcb;
+ struct fsf_qtcb_bottom_port *bottom, *data;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
return;
- switch (fsf_req->qtcb->header.fsf_status) {
+ switch (qtcb->header.fsf_status) {
case FSF_GOOD:
- bottom = &fsf_req->qtcb->bottom.port;
- memcpy(data, bottom, sizeof(*data));
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
+
+ bottom = &qtcb->bottom.port;
+ data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
+ if (data)
+ memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
+ adapter->physical_wwpn = bottom->wwpn;
+ adapter->physical_s_id = bottom->fc_port_id;
+ } else {
+ adapter->physical_wwpn = fc_host_port_name(shost);
+ adapter->physical_s_id = fc_host_port_id(shost);
+ }
+ fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
+ break;
+
+ case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
+
+ zfcp_fsf_link_down_info_eval(adapter,
+ &qtcb->header.fsf_status_qual.link_down_info);
break;
default:
- debug_text_event(fsf_req->adapter->erp_dbf, 0, "xchg-port-ng");
- debug_event(fsf_req->adapter->erp_dbf, 0,
+ debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng");
+ debug_event(adapter->erp_dbf, 0,
&fsf_req->qtcb->header.fsf_status, sizeof(u32));
}
}
@@ -2312,7 +2338,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id;
atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status);
- erp_action->fsf_req->data.open_port.port = erp_action->port;
+ erp_action->fsf_req->data = (unsigned long) erp_action->port;
erp_action->fsf_req->erp_action = erp_action;
/* start QDIO request for this FSF request */
@@ -2353,7 +2379,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
struct fsf_qtcb_header *header;
u16 subtable, rule, counter;
- port = fsf_req->data.open_port.port;
+ port = (struct zfcp_port *) fsf_req->data;
header = &fsf_req->qtcb->header;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
@@ -2566,7 +2592,7 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status);
- erp_action->fsf_req->data.close_port.port = erp_action->port;
+ erp_action->fsf_req->data = (unsigned long) erp_action->port;
erp_action->fsf_req->erp_action = erp_action;
erp_action->fsf_req->qtcb->header.port_handle =
erp_action->port->handle;
@@ -2606,7 +2632,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
int retval = -EINVAL;
struct zfcp_port *port;
- port = fsf_req->data.close_port.port;
+ port = (struct zfcp_port *) fsf_req->data;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
/* don't change port status in our bookkeeping */
@@ -2703,8 +2729,8 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING,
&erp_action->port->status);
/* save a pointer to this port */
- erp_action->fsf_req->data.close_physical_port.port = erp_action->port;
- /* port to be closeed */
+ erp_action->fsf_req->data = (unsigned long) erp_action->port;
+ /* port to be closed */
erp_action->fsf_req->qtcb->header.port_handle =
erp_action->port->handle;
erp_action->fsf_req->erp_action = erp_action;
@@ -2747,7 +2773,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
struct fsf_qtcb_header *header;
u16 subtable, rule, counter;
- port = fsf_req->data.close_physical_port.port;
+ port = (struct zfcp_port *) fsf_req->data;
header = &fsf_req->qtcb->header;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
@@ -2908,10 +2934,11 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
erp_action->port->handle;
erp_action->fsf_req->qtcb->bottom.support.fcp_lun =
erp_action->unit->fcp_lun;
+ if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE))
erp_action->fsf_req->qtcb->bottom.support.option =
FSF_OPEN_LUN_SUPPRESS_BOXING;
atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status);
- erp_action->fsf_req->data.open_unit.unit = erp_action->unit;
+ erp_action->fsf_req->data = (unsigned long) erp_action->unit;
erp_action->fsf_req->erp_action = erp_action;
/* start QDIO request for this FSF request */
@@ -2955,9 +2982,9 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
struct fsf_qtcb_bottom_support *bottom;
struct fsf_queue_designator *queue_designator;
u16 subtable, rule, counter;
- u32 allowed, exclusive, readwrite;
+ int exclusive, readwrite;
- unit = fsf_req->data.open_unit.unit;
+ unit = (struct zfcp_unit *) fsf_req->data;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
/* don't change unit status in our bookkeeping */
@@ -2969,10 +2996,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
bottom = &fsf_req->qtcb->bottom.support;
queue_designator = &header->fsf_status_qual.fsf_queue_designator;
- allowed = bottom->lun_access_info & FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED;
- exclusive = bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE;
- readwrite = bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER;
-
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
ZFCP_STATUS_UNIT_SHARED |
ZFCP_STATUS_UNIT_READONLY,
@@ -3146,10 +3169,15 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
unit->handle);
/* mark unit as open */
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
- atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
- ZFCP_STATUS_COMMON_ACCESS_BOXED,
- &unit->status);
- if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){
+
+ if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) &&
+ (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) &&
+ (adapter->ccw_device->id.dev_model != ZFCP_DEVICE_MODEL_PRIV)) {
+ exclusive = (bottom->lun_access_info &
+ FSF_UNIT_ACCESS_EXCLUSIVE);
+ readwrite = (bottom->lun_access_info &
+ FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);
+
if (!exclusive)
atomic_set_mask(ZFCP_STATUS_UNIT_SHARED,
&unit->status);
@@ -3242,7 +3270,7 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
erp_action->port->handle;
erp_action->fsf_req->qtcb->header.lun_handle = erp_action->unit->handle;
atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status);
- erp_action->fsf_req->data.close_unit.unit = erp_action->unit;
+ erp_action->fsf_req->data = (unsigned long) erp_action->unit;
erp_action->fsf_req->erp_action = erp_action;
/* start QDIO request for this FSF request */
@@ -3281,7 +3309,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
int retval = -EINVAL;
struct zfcp_unit *unit;
- unit = fsf_req->data.close_unit.unit; /* restore unit */
+ unit = (struct zfcp_unit *) fsf_req->data;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
/* don't change unit status in our bookkeeping */
@@ -3305,9 +3333,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_phand_nv");
zfcp_erp_adapter_reopen(unit->port->adapter, 0);
- zfcp_cmd_dbf_event_fsf("porthinv", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3326,9 +3351,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_lhand_nv");
zfcp_erp_port_reopen(unit->port, 0);
- zfcp_cmd_dbf_event_fsf("lunhinv", fsf_req,
- &fsf_req->qtcb->header.fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3436,21 +3458,14 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
goto failed_req_create;
}
- /*
- * associate FSF request with SCSI request
- * (need this for look up on abort)
- */
- fsf_req->data.send_fcp_command_task.fsf_req = fsf_req;
- scsi_cmnd->host_scribble = (char *) &(fsf_req->data);
+ zfcp_unit_get(unit);
+ fsf_req->unit = unit;
- /*
- * associate SCSI command with FSF request
- * (need this for look up on normal command completion)
- */
- fsf_req->data.send_fcp_command_task.scsi_cmnd = scsi_cmnd;
- fsf_req->data.send_fcp_command_task.start_jiffies = jiffies;
- fsf_req->data.send_fcp_command_task.unit = unit;
- ZFCP_LOG_DEBUG("unit=%p, fcp_lun=0x%016Lx\n", unit, unit->fcp_lun);
+ /* associate FSF request with SCSI request (for look up on abort) */
+ scsi_cmnd->host_scribble = (char *) fsf_req;
+
+ /* associate SCSI command with FSF request */
+ fsf_req->data = (unsigned long) scsi_cmnd;
/* set handles of unit and its parent port in QTCB */
fsf_req->qtcb->header.lun_handle = unit->handle;
@@ -3584,6 +3599,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
send_failed:
no_fit:
failed_scsi_cmnd:
+ zfcp_unit_put(unit);
zfcp_fsf_req_free(fsf_req);
fsf_req = NULL;
scsi_cmnd->host_scribble = NULL;
@@ -3640,7 +3656,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
* hold a pointer to the unit being target of this
* task management request
*/
- fsf_req->data.send_fcp_command_task_management.unit = unit;
+ fsf_req->data = (unsigned long) unit;
/* set FSF related fields in QTCB */
fsf_req->qtcb->header.lun_handle = unit->handle;
@@ -3706,9 +3722,9 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
header = &fsf_req->qtcb->header;
if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT))
- unit = fsf_req->data.send_fcp_command_task_management.unit;
+ unit = (struct zfcp_unit *) fsf_req->data;
else
- unit = fsf_req->data.send_fcp_command_task.unit;
+ unit = fsf_req->unit;
if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
/* go directly to calls of special handlers */
@@ -3765,10 +3781,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_hand_mis");
zfcp_erp_adapter_reopen(unit->port->adapter, 0);
- zfcp_cmd_dbf_event_fsf("handmism",
- fsf_req,
- &header->fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3789,10 +3801,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_exception(fsf_req->adapter->erp_dbf, 0,
"fsf_s_class_nsup");
zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
- zfcp_cmd_dbf_event_fsf("unsclass",
- fsf_req,
- &header->fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3811,10 +3819,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_fcp_lun_nv");
zfcp_erp_port_reopen(unit->port, 0);
- zfcp_cmd_dbf_event_fsf("fluninv",
- fsf_req,
- &header->fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3853,10 +3857,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 0,
"fsf_s_dir_ind_nv");
zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
- zfcp_cmd_dbf_event_fsf("dirinv",
- fsf_req,
- &header->fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3872,10 +3872,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 0,
"fsf_s_cmd_len_nv");
zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
- zfcp_cmd_dbf_event_fsf("cleninv",
- fsf_req,
- &header->fsf_status_qual,
- sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3947,6 +3943,8 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
zfcp_fsf_send_fcp_command_task_management_handler(fsf_req);
} else {
retval = zfcp_fsf_send_fcp_command_task_handler(fsf_req);
+ fsf_req->unit = NULL;
+ zfcp_unit_put(unit);
}
return retval;
}
@@ -3970,10 +3968,10 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
u32 sns_len;
char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
unsigned long flags;
- struct zfcp_unit *unit = fsf_req->data.send_fcp_command_task.unit;
+ struct zfcp_unit *unit = fsf_req->unit;
read_lock_irqsave(&fsf_req->adapter->abort_lock, flags);
- scpnt = fsf_req->data.send_fcp_command_task.scsi_cmnd;
+ scpnt = (struct scsi_cmnd *) fsf_req->data;
if (unlikely(!scpnt)) {
ZFCP_LOG_DEBUG
("Command with fsf_req %p is not associated to "
@@ -4043,7 +4041,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
- zfcp_cmd_dbf_event_fsf("clenmis", fsf_req, NULL, 0);
set_host_byte(&scpnt->result, DID_ERROR);
goto skip_fsfstatus;
case RSP_CODE_FIELD_INVALID:
@@ -4062,7 +4059,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
set_host_byte(&scpnt->result, DID_ERROR);
- zfcp_cmd_dbf_event_fsf("codeinv", fsf_req, NULL, 0);
goto skip_fsfstatus;
case RSP_CODE_RO_MISMATCH:
/* hardware bug */
@@ -4079,7 +4075,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
- zfcp_cmd_dbf_event_fsf("codemism", fsf_req, NULL, 0);
set_host_byte(&scpnt->result, DID_ERROR);
goto skip_fsfstatus;
default:
@@ -4096,7 +4091,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
- zfcp_cmd_dbf_event_fsf("undeffcp", fsf_req, NULL, 0);
set_host_byte(&scpnt->result, DID_ERROR);
goto skip_fsfstatus;
}
@@ -4158,19 +4152,17 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
skip_fsfstatus:
ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);
- zfcp_cmd_dbf_event_scsi("response", scpnt);
+ if (scpnt->result != 0)
+ zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt);
+ else if (scpnt->retries > 0)
+ zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt);
+ else
+ zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt);
/* cleanup pointer (need this especially for abort) */
scpnt->host_scribble = NULL;
- /*
- * NOTE:
- * according to the outcome of a discussion on linux-scsi we
- * don't need to grab the io_request_lock here since we use
- * the new eh
- */
/* always call back */
-
(scpnt->scsi_done) (scpnt);
/*
@@ -4198,8 +4190,7 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req)
struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
&(fsf_req->qtcb->bottom.io.fcp_rsp);
char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
- struct zfcp_unit *unit =
- fsf_req->data.send_fcp_command_task_management.unit;
+ struct zfcp_unit *unit = (struct zfcp_unit *) fsf_req->data;
del_timer(&fsf_req->adapter->scsi_er_timer);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
@@ -4276,7 +4267,7 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
int direction;
int retval = 0;
- if (!(adapter->supported_features & FSF_FEATURE_CFDC)) {
+ if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) {
ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
retval = -EOPNOTSUPP;
@@ -4549,52 +4540,6 @@ skip_fsfstatus:
return retval;
}
-
-/*
- * function: zfcp_fsf_req_wait_and_cleanup
- *
- * purpose:
- *
- * FIXME(design): signal seems to be <0 !!!
- * returns: 0 - request completed (*status is valid), cleanup succ.
- * <0 - request completed (*status is valid), cleanup failed
- * >0 - signal which interrupted waiting (*status invalid),
- * request not completed, no cleanup
- *
- * *status is a copy of status of completed fsf_req
- */
-int
-zfcp_fsf_req_wait_and_cleanup(struct zfcp_fsf_req *fsf_req,
- int interruptible, u32 * status)
-{
- int retval = 0;
- int signal = 0;
-
- if (interruptible) {
- __wait_event_interruptible(fsf_req->completion_wq,
- fsf_req->status &
- ZFCP_STATUS_FSFREQ_COMPLETED,
- signal);
- if (signal) {
- ZFCP_LOG_DEBUG("Caught signal %i while waiting for the "
- "completion of the request at %p\n",
- signal, fsf_req);
- retval = signal;
- goto out;
- }
- } else {
- __wait_event(fsf_req->completion_wq,
- fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
- }
-
- *status = fsf_req->status;
-
- /* cleanup request */
- zfcp_fsf_req_free(fsf_req);
- out:
- return retval;
-}
-
static inline int
zfcp_fsf_req_sbal_check(unsigned long *flags,
struct zfcp_qdio_queue *queue, int needed)
@@ -4610,15 +4555,16 @@ zfcp_fsf_req_sbal_check(unsigned long *flags,
* set qtcb pointer in fsf_req and initialize QTCB
*/
static inline void
-zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req, u32 fsf_cmd)
+zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
{
if (likely(fsf_req->qtcb != NULL)) {
+ fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no;
fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req;
fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION;
- fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_cmd];
+ fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command];
fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION;
fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req;
- fsf_req->qtcb->header.fsf_command = fsf_cmd;
+ fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command;
}
}
@@ -4686,7 +4632,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
goto failed_fsf_req;
}
- zfcp_fsf_req_qtcb_init(fsf_req, fsf_cmd);
+ fsf_req->adapter = adapter;
+ fsf_req->fsf_command = fsf_cmd;
+
+ zfcp_fsf_req_qtcb_init(fsf_req);
/* initialize waitqueue which may be used to wait on
this request completion */
@@ -4708,8 +4657,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
goto failed_sbals;
}
- fsf_req->adapter = adapter; /* pointer to "parent" adapter */
- fsf_req->fsf_command = fsf_cmd;
+ if (fsf_req->qtcb) {
+ fsf_req->seq_no = adapter->fsf_req_seq_no;
+ fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
+ }
fsf_req->sbal_number = 1;
fsf_req->sbal_first = req_queue->free_index;
fsf_req->sbal_curr = req_queue->free_index;
@@ -4760,9 +4711,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
struct zfcp_adapter *adapter;
struct zfcp_qdio_queue *req_queue;
volatile struct qdio_buffer_element *sbale;
+ int inc_seq_no;
int new_distance_from_int;
unsigned long flags;
- int inc_seq_no = 1;
int retval = 0;
adapter = fsf_req->adapter;
@@ -4776,23 +4727,13 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr,
sbale[1].length);
- /* set sequence counter in QTCB */
- if (likely(fsf_req->qtcb)) {
- fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
- fsf_req->seq_no = adapter->fsf_req_seq_no;
- ZFCP_LOG_TRACE("FSF request %p of adapter %s gets "
- "FSF sequence counter value of %i\n",
- fsf_req,
- zfcp_get_busid_by_adapter(adapter),
- fsf_req->qtcb->prefix.req_seq_no);
- } else
- inc_seq_no = 0;
-
/* put allocated FSF request at list tail */
spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head);
spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+ inc_seq_no = (fsf_req->qtcb != NULL);
+
/* figure out expiration time of timeout and start timeout */
if (unlikely(timer)) {
timer->expires += jiffies;
@@ -4822,6 +4763,8 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */
new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req);
+ fsf_req->issued = get_clock();
+
retval = do_QDIO(adapter->ccw_device,
QDIO_FLAG_SYNC_OUTPUT,
0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);
@@ -4860,15 +4803,11 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
* routines resulting in missing sequence counter values
* otherwise,
*/
+
/* Don't increase for unsolicited status */
- if (likely(inc_seq_no)) {
+ if (inc_seq_no)
adapter->fsf_req_seq_no++;
- ZFCP_LOG_TRACE
- ("FSF sequence counter value of adapter %s "
- "increased to %i\n",
- zfcp_get_busid_by_adapter(adapter),
- adapter->fsf_req_seq_no);
- }
+
/* count FSF requests pending */
atomic_inc(&adapter->fsf_reqs_active);
}
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index 07140dfda2a7..48719f055952 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -116,6 +116,7 @@
#define FSF_INVALID_COMMAND_OPTION 0x000000E5
/* #define FSF_ERROR 0x000000FF */
+#define FSF_PROT_STATUS_QUAL_SIZE 16
#define FSF_STATUS_QUALIFIER_SIZE 16
/* FSF status qualifier, recommendations */
@@ -139,9 +140,18 @@
#define FSF_SQ_CFDC_SUBTABLE_LUN 0x0004
/* FSF status qualifier (most significant 4 bytes), local link down */
-#define FSF_PSQ_LINK_NOLIGHT 0x00000004
-#define FSF_PSQ_LINK_WRAPPLUG 0x00000008
-#define FSF_PSQ_LINK_NOFCP 0x00000010
+#define FSF_PSQ_LINK_NO_LIGHT 0x00000004
+#define FSF_PSQ_LINK_WRAP_PLUG 0x00000008
+#define FSF_PSQ_LINK_NO_FCP 0x00000010
+#define FSF_PSQ_LINK_FIRMWARE_UPDATE 0x00000020
+#define FSF_PSQ_LINK_INVALID_WWPN 0x00000100
+#define FSF_PSQ_LINK_NO_NPIV_SUPPORT 0x00000200
+#define FSF_PSQ_LINK_NO_FCP_RESOURCES 0x00000400
+#define FSF_PSQ_LINK_NO_FABRIC_RESOURCES 0x00000800
+#define FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE 0x00001000
+#define FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED 0x00002000
+#define FSF_PSQ_LINK_MODE_TABLE_CURRUPTED 0x00004000
+#define FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT 0x00008000
/* payload size in status read buffer */
#define FSF_STATUS_READ_PAYLOAD_SIZE 4032
@@ -154,15 +164,21 @@
#define FSF_STATUS_READ_INCOMING_ELS 0x00000002
#define FSF_STATUS_READ_SENSE_DATA_AVAIL 0x00000003
#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004
-#define FSF_STATUS_READ_LINK_DOWN 0x00000005 /* FIXME: really? */
+#define FSF_STATUS_READ_LINK_DOWN 0x00000005
#define FSF_STATUS_READ_LINK_UP 0x00000006
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
#define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B
+#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C
/* status subtypes in status read buffer */
#define FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT 0x00000001
#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002
+/* status subtypes for link down */
+#define FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK 0x00000000
+#define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001
+#define FSF_STATUS_READ_SUB_FIRMWARE_UPDATE 0x00000002
+
/* status subtypes for CFDC */
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
@@ -193,11 +209,15 @@
#define FSF_QTCB_LOG_SIZE 1024
/* channel features */
-#define FSF_FEATURE_QTCB_SUPPRESSION 0x00000001
#define FSF_FEATURE_CFDC 0x00000002
#define FSF_FEATURE_LUN_SHARING 0x00000004
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
+#define FSF_FEATURE_UPDATE_ALERT 0x00000100
+
+/* host connection features */
+#define FSF_FEATURE_NPIV_MODE 0x00000001
+#define FSF_FEATURE_VM_ASSIGNED_WWPN 0x00000002
/* option */
#define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001
@@ -305,15 +325,23 @@ struct fsf_qual_sequence_error {
u32 res1[3];
} __attribute__ ((packed));
-struct fsf_qual_locallink_error {
- u32 code;
- u32 res1[3];
+struct fsf_link_down_info {
+ u32 error_code;
+ u32 res1;
+ u8 res2[2];
+ u8 primary_status;
+ u8 ioerr_code;
+ u8 action_code;
+ u8 reason_code;
+ u8 explanation_code;
+ u8 vendor_specific_code;
} __attribute__ ((packed));
union fsf_prot_status_qual {
+ u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)];
struct fsf_qual_version_error version_error;
struct fsf_qual_sequence_error sequence_error;
- struct fsf_qual_locallink_error locallink_error;
+ struct fsf_link_down_info link_down_info;
} __attribute__ ((packed));
struct fsf_qtcb_prefix {
@@ -331,7 +359,9 @@ union fsf_status_qual {
u8 byte[FSF_STATUS_QUALIFIER_SIZE];
u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
u32 word[FSF_STATUS_QUALIFIER_SIZE / sizeof (u32)];
+ u64 doubleword[FSF_STATUS_QUALIFIER_SIZE / sizeof(u64)];
struct fsf_queue_designator fsf_queue_designator;
+ struct fsf_link_down_info link_down_info;
} __attribute__ ((packed));
struct fsf_qtcb_header {
@@ -406,8 +436,8 @@ struct fsf_qtcb_bottom_config {
u32 low_qtcb_version;
u32 max_qtcb_size;
u32 max_data_transfer_size;
- u32 supported_features;
- u8 res1[4];
+ u32 adapter_features;
+ u32 connection_features;
u32 fc_topology;
u32 fc_link_speed;
u32 adapter_type;
@@ -425,7 +455,7 @@ struct fsf_qtcb_bottom_config {
} __attribute__ ((packed));
struct fsf_qtcb_bottom_port {
- u8 res1[8];
+ u64 wwpn;
u32 fc_port_id;
u32 port_type;
u32 port_state;
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 24e16ec331d9..d719f66a29a4 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -54,8 +54,7 @@ static inline int zfcp_qdio_sbals_from_buffer
static qdio_handler_t zfcp_qdio_request_handler;
static qdio_handler_t zfcp_qdio_response_handler;
static int zfcp_qdio_handler_error_check(struct zfcp_adapter *,
- unsigned int,
- unsigned int, unsigned int);
+ unsigned int, unsigned int, unsigned int, int, int);
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO
@@ -214,22 +213,12 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter)
*
*/
static inline int
-zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,
- unsigned int status,
- unsigned int qdio_error, unsigned int siga_error)
+zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
+ unsigned int qdio_error, unsigned int siga_error,
+ int first_element, int elements_processed)
{
int retval = 0;
- if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) {
- if (status & QDIO_STATUS_INBOUND_INT) {
- ZFCP_LOG_TRACE("status is"
- " QDIO_STATUS_INBOUND_INT \n");
- }
- if (status & QDIO_STATUS_OUTBOUND_INT) {
- ZFCP_LOG_TRACE("status is"
- " QDIO_STATUS_OUTBOUND_INT \n");
- }
- }
if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {
retval = -EIO;
@@ -237,9 +226,10 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,
"qdio_error=0x%x, siga_error=0x%x)\n",
status, qdio_error, siga_error);
- /* Restarting IO on the failed adapter from scratch */
- debug_text_event(adapter->erp_dbf, 1, "qdio_err");
+ zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error,
+ first_element, elements_processed);
/*
+ * Restarting IO on the failed adapter from scratch.
* Since we have been using this adapter, it is save to assume
* that it is not failed but recoverable. The card seems to
* report link-up events by self-initiated queue shutdown.
@@ -282,7 +272,8 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device,
first_element, elements_processed);
if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
- siga_error)))
+ siga_error, first_element,
+ elements_processed)))
goto out;
/*
* we stored address of struct zfcp_adapter data structure
@@ -334,7 +325,8 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device,
queue = &adapter->response_queue;
if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
- siga_error)))
+ siga_error, first_element,
+ elements_processed)))
goto out;
/*
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 31a76065cf28..3dcd1bfba3b4 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -44,7 +44,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
-static int zfcp_task_management_function(struct zfcp_unit *, u8);
+static int zfcp_task_management_function(struct zfcp_unit *, u8,
+ struct scsi_cmnd *);
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
scsi_lun_t);
@@ -242,7 +243,10 @@ static void
zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
{
set_host_byte(&scpnt->result, result);
- zfcp_cmd_dbf_event_scsi("failing", scpnt);
+ if ((scpnt->device != NULL) && (scpnt->device->host != NULL))
+ zfcp_scsi_dbf_event_result("fail", 4,
+ (struct zfcp_adapter*) scpnt->device->host->hostdata[0],
+ scpnt);
/* return directly */
scpnt->scsi_done(scpnt);
}
@@ -414,67 +418,38 @@ zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id)
return (struct zfcp_port *) NULL;
}
-/*
- * function: zfcp_scsi_eh_abort_handler
- *
- * purpose: tries to abort the specified (timed out) SCSI command
- *
- * note: We do not need to care for a SCSI command which completes
- * normally but late during this abort routine runs.
- * We are allowed to return late commands to the SCSI stack.
- * It tracks the state of commands and will handle late commands.
- * (Usually, the normal completion of late commands is ignored with
- * respect to the running abort operation. Grep for 'done_late'
- * in the SCSI stacks sources.)
+/**
+ * zfcp_scsi_eh_abort_handler - abort the specified SCSI command
+ * @scpnt: pointer to scsi_cmnd to be aborted
+ * Return: SUCCESS - command has been aborted and cleaned up in internal
+ * bookkeeping, SCSI stack won't be called for aborted command
+ * FAILED - otherwise
*
- * returns: SUCCESS - command has been aborted and cleaned up in internal
- * bookkeeping,
- * SCSI stack won't be called for aborted command
- * FAILED - otherwise
+ * We do not need to care for a SCSI command which completes normally
+ * but late during this abort routine runs. We are allowed to return
+ * late commands to the SCSI stack. It tracks the state of commands and
+ * will handle late commands. (Usually, the normal completion of late
+ * commands is ignored with respect to the running abort operation.)
*/
int
-__zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
+zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
+ struct Scsi_Host *scsi_host;
+ struct zfcp_adapter *adapter;
+ struct zfcp_unit *unit;
int retval = SUCCESS;
- struct zfcp_fsf_req *new_fsf_req, *old_fsf_req;
- struct zfcp_adapter *adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
- struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
- struct zfcp_port *port = unit->port;
- struct Scsi_Host *scsi_host = scpnt->device->host;
- union zfcp_req_data *req_data = NULL;
+ struct zfcp_fsf_req *new_fsf_req = NULL;
+ struct zfcp_fsf_req *old_fsf_req;
unsigned long flags;
- u32 status = 0;
-
- /* the components of a abort_dbf record (fixed size record) */
- u64 dbf_scsi_cmnd = (unsigned long) scpnt;
- char dbf_opcode[ZFCP_ABORT_DBF_LENGTH];
- wwn_t dbf_wwn = port->wwpn;
- fcp_lun_t dbf_fcp_lun = unit->fcp_lun;
- u64 dbf_retries = scpnt->retries;
- u64 dbf_allowed = scpnt->allowed;
- u64 dbf_timeout = 0;
- u64 dbf_fsf_req = 0;
- u64 dbf_fsf_status = 0;
- u64 dbf_fsf_qual[2] = { 0, 0 };
- char dbf_result[ZFCP_ABORT_DBF_LENGTH] = "##undef";
-
- memset(dbf_opcode, 0, ZFCP_ABORT_DBF_LENGTH);
- memcpy(dbf_opcode,
- scpnt->cmnd,
- min(scpnt->cmd_len, (unsigned char) ZFCP_ABORT_DBF_LENGTH));
+
+ scsi_host = scpnt->device->host;
+ adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
+ unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_INFO("aborting scsi_cmnd=%p on adapter %s\n",
scpnt, zfcp_get_busid_by_adapter(adapter));
- spin_unlock_irq(scsi_host->host_lock);
-
- /*
- * Race condition between normal (late) completion and abort has
- * to be avoided.
- * The entirity of all accesses to scsi_req have to be atomic.
- * scsi_req is usually part of the fsf_req and thus we block the
- * release of fsf_req as long as we need to access scsi_req.
- */
+ /* avoid race condition between late normal completion and abort */
write_lock_irqsave(&adapter->abort_lock, flags);
/*
@@ -484,144 +459,47 @@ __zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
* this routine returns. (scpnt is parameter passed to this routine
* and must not disappear during abort even on late completion.)
*/
- req_data = (union zfcp_req_data *) scpnt->host_scribble;
- /* DEBUG */
- ZFCP_LOG_DEBUG("req_data=%p\n", req_data);
- if (!req_data) {
- ZFCP_LOG_DEBUG("late command completion overtook abort\n");
- /*
- * That's it.
- * Do not initiate abort but return SUCCESS.
- */
- write_unlock_irqrestore(&adapter->abort_lock, flags);
- retval = SUCCESS;
- strncpy(dbf_result, "##late1", ZFCP_ABORT_DBF_LENGTH);
- goto out;
- }
-
- /* Figure out which fsf_req needs to be aborted. */
- old_fsf_req = req_data->send_fcp_command_task.fsf_req;
-
- dbf_fsf_req = (unsigned long) old_fsf_req;
- dbf_timeout =
- (jiffies - req_data->send_fcp_command_task.start_jiffies) / HZ;
-
- ZFCP_LOG_DEBUG("old_fsf_req=%p\n", old_fsf_req);
+ old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;
if (!old_fsf_req) {
write_unlock_irqrestore(&adapter->abort_lock, flags);
- ZFCP_LOG_NORMAL("bug: no old fsf request found\n");
- ZFCP_LOG_NORMAL("req_data:\n");
- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
- (char *) req_data, sizeof (union zfcp_req_data));
- ZFCP_LOG_NORMAL("scsi_cmnd:\n");
- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
- (char *) scpnt, sizeof (struct scsi_cmnd));
- retval = FAILED;
- strncpy(dbf_result, "##bug:r", ZFCP_ABORT_DBF_LENGTH);
+ zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req);
+ retval = SUCCESS;
goto out;
}
- old_fsf_req->data.send_fcp_command_task.scsi_cmnd = NULL;
- /* mark old request as being aborted */
+ old_fsf_req->data = 0;
old_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
- /*
- * We have to collect all information (e.g. unit) needed by
- * zfcp_fsf_abort_fcp_command before calling that routine
- * since that routine is not allowed to access
- * fsf_req which it is going to abort.
- * This is because of we need to release fsf_req_list_lock
- * before calling zfcp_fsf_abort_fcp_command.
- * Since this lock will not be held, fsf_req may complete
- * late and may be released meanwhile.
- */
- ZFCP_LOG_DEBUG("unit 0x%016Lx (%p)\n", unit->fcp_lun, unit);
- /*
- * We block (call schedule)
- * That's why we must release the lock and enable the
- * interrupts before.
- * On the other hand we do not need the lock anymore since
- * all critical accesses to scsi_req are done.
- */
+ /* don't access old_fsf_req after releasing the abort_lock */
write_unlock_irqrestore(&adapter->abort_lock, flags);
/* call FSF routine which does the abort */
new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req,
adapter, unit, 0);
- ZFCP_LOG_DEBUG("new_fsf_req=%p\n", new_fsf_req);
if (!new_fsf_req) {
+ ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");
retval = FAILED;
- ZFCP_LOG_NORMAL("error: initiation of Abort FCP Cmnd "
- "failed\n");
- strncpy(dbf_result, "##nores", ZFCP_ABORT_DBF_LENGTH);
goto out;
}
/* wait for completion of abort */
- ZFCP_LOG_DEBUG("waiting for cleanup...\n");
-#if 1
- /*
- * FIXME:
- * copying zfcp_fsf_req_wait_and_cleanup code is not really nice
- */
__wait_event(new_fsf_req->completion_wq,
new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
- status = new_fsf_req->status;
- dbf_fsf_status = new_fsf_req->qtcb->header.fsf_status;
- /*
- * Ralphs special debug load provides timestamps in the FSF
- * status qualifier. This might be specified later if being
- * useful for debugging aborts.
- */
- dbf_fsf_qual[0] =
- *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[0];
- dbf_fsf_qual[1] =
- *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[2];
- zfcp_fsf_req_free(new_fsf_req);
-#else
- retval = zfcp_fsf_req_wait_and_cleanup(new_fsf_req,
- ZFCP_UNINTERRUPTIBLE, &status);
-#endif
- ZFCP_LOG_DEBUG("Waiting for cleanup complete, status=0x%x\n", status);
+
/* status should be valid since signals were not permitted */
- if (status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
+ if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
+ zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req);
retval = SUCCESS;
- strncpy(dbf_result, "##succ", ZFCP_ABORT_DBF_LENGTH);
- } else if (status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
+ } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
+ zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req);
retval = SUCCESS;
- strncpy(dbf_result, "##late2", ZFCP_ABORT_DBF_LENGTH);
} else {
+ zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req);
retval = FAILED;
- strncpy(dbf_result, "##fail", ZFCP_ABORT_DBF_LENGTH);
}
-
+ zfcp_fsf_req_free(new_fsf_req);
out:
- debug_event(adapter->abort_dbf, 1, &dbf_scsi_cmnd, sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_opcode, ZFCP_ABORT_DBF_LENGTH);
- debug_event(adapter->abort_dbf, 1, &dbf_wwn, sizeof (wwn_t));
- debug_event(adapter->abort_dbf, 1, &dbf_fcp_lun, sizeof (fcp_lun_t));
- debug_event(adapter->abort_dbf, 1, &dbf_retries, sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_allowed, sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_timeout, sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_fsf_req, sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_fsf_status, sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[0], sizeof (u64));
- debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[1], sizeof (u64));
- debug_text_event(adapter->abort_dbf, 1, dbf_result);
-
- spin_lock_irq(scsi_host->host_lock);
return retval;
}
-int
-zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
-{
- int rc;
- struct Scsi_Host *scsi_host = scpnt->device->host;
- spin_lock_irq(scsi_host->host_lock);
- rc = __zfcp_scsi_eh_abort_handler(scpnt);
- spin_unlock_irq(scsi_host->host_lock);
- return rc;
-}
-
/*
* function: zfcp_scsi_eh_device_reset_handler
*
@@ -651,8 +529,9 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
*/
if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
&unit->status)) {
- retval =
- zfcp_task_management_function(unit, FCP_LOGICAL_UNIT_RESET);
+ retval = zfcp_task_management_function(unit,
+ FCP_LOGICAL_UNIT_RESET,
+ scpnt);
if (retval) {
ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
if (retval == -ENOTSUPP)
@@ -668,7 +547,7 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
goto out;
}
}
- retval = zfcp_task_management_function(unit, FCP_TARGET_RESET);
+ retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);
if (retval) {
ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
retval = FAILED;
@@ -681,12 +560,12 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
}
static int
-zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags)
+zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,
+ struct scsi_cmnd *scpnt)
{
struct zfcp_adapter *adapter = unit->port->adapter;
- int retval;
- int status;
struct zfcp_fsf_req *fsf_req;
+ int retval = 0;
/* issue task management function */
fsf_req = zfcp_fsf_send_fcp_command_task_management
@@ -696,70 +575,63 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags)
"failed for unit 0x%016Lx on port 0x%016Lx on "
"adapter %s\n", unit->fcp_lun, unit->port->wwpn,
zfcp_get_busid_by_adapter(adapter));
+ zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt);
retval = -ENOMEM;
goto out;
}
- retval = zfcp_fsf_req_wait_and_cleanup(fsf_req,
- ZFCP_UNINTERRUPTIBLE, &status);
+ __wait_event(fsf_req->completion_wq,
+ fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+
/*
* check completion status of task management function
- * (status should always be valid since no signals permitted)
*/
- if (status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED)
+ if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
+ zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);
retval = -EIO;
- else if (status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP)
+ } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) {
+ zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt);
retval = -ENOTSUPP;
- else
- retval = 0;
+ } else
+ zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);
+
+ zfcp_fsf_req_free(fsf_req);
out:
return retval;
}
-/*
- * function: zfcp_scsi_eh_bus_reset_handler
- *
- * purpose:
- *
- * returns:
+/**
+ * zfcp_scsi_eh_bus_reset_handler - reset bus (reopen adapter)
*/
int
zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
{
- int retval = 0;
- struct zfcp_unit *unit;
+ struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;
+ struct zfcp_adapter *adapter = unit->port->adapter;
- unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("bus reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
- zfcp_erp_adapter_reopen(unit->port->adapter, 0);
- zfcp_erp_wait(unit->port->adapter);
- retval = SUCCESS;
+ zfcp_erp_adapter_reopen(adapter, 0);
+ zfcp_erp_wait(adapter);
- return retval;
+ return SUCCESS;
}
-/*
- * function: zfcp_scsi_eh_host_reset_handler
- *
- * purpose:
- *
- * returns:
+/**
+ * zfcp_scsi_eh_host_reset_handler - reset host (reopen adapter)
*/
int
zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
{
- int retval = 0;
- struct zfcp_unit *unit;
+ struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;
+ struct zfcp_adapter *adapter = unit->port->adapter;
- unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("host reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
- zfcp_erp_adapter_reopen(unit->port->adapter, 0);
- zfcp_erp_wait(unit->port->adapter);
- retval = SUCCESS;
+ zfcp_erp_adapter_reopen(adapter, 0);
+ zfcp_erp_wait(adapter);
- return retval;
+ return SUCCESS;
}
/*
@@ -826,10 +698,16 @@ void
zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
{
struct Scsi_Host *shost;
+ struct zfcp_port *port;
shost = adapter->scsi_host;
if (!shost)
return;
+ read_lock_irq(&zfcp_data.config_lock);
+ list_for_each_entry(port, &adapter->port_list_head, list)
+ if (port->rport)
+ port->rport = NULL;
+ read_unlock_irq(&zfcp_data.config_lock);
fc_remove_host(shost);
scsi_remove_host(shost);
scsi_host_put(shost);
@@ -904,18 +782,6 @@ zfcp_get_node_name(struct scsi_target *starget)
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
-void
-zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter)
-{
- struct Scsi_Host *shost = adapter->scsi_host;
-
- fc_host_node_name(shost) = adapter->wwnn;
- fc_host_port_name(shost) = adapter->wwpn;
- strncpy(fc_host_serial_number(shost), adapter->serial_number,
- min(FC_SERIAL_NUMBER_SIZE, 32));
- fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
-}
-
struct fc_function_template zfcp_transport_functions = {
.get_starget_port_id = zfcp_get_port_id,
.get_starget_port_name = zfcp_get_port_name,
@@ -927,7 +793,10 @@ struct fc_function_template zfcp_transport_functions = {
.show_host_node_name = 1,
.show_host_port_name = 1,
.show_host_supported_classes = 1,
+ .show_host_maxframe_size = 1,
.show_host_serial_number = 1,
+ .show_host_speed = 1,
+ .show_host_port_id = 1,
};
/**
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c
index e7345a74800a..0cd435280e7d 100644
--- a/drivers/s390/scsi/zfcp_sysfs_adapter.c
+++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c
@@ -62,21 +62,18 @@ static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, struct devi
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL);
ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
-ZFCP_DEFINE_ADAPTER_ATTR(wwnn, "0x%016llx\n", adapter->wwnn);
-ZFCP_DEFINE_ADAPTER_ATTR(wwpn, "0x%016llx\n", adapter->wwpn);
-ZFCP_DEFINE_ADAPTER_ATTR(s_id, "0x%06x\n", adapter->s_id);
ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn);
ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn);
ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
+ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn);
+ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id);
ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
-ZFCP_DEFINE_ADAPTER_ATTR(fc_link_speed, "%d Gb/s\n", adapter->fc_link_speed);
ZFCP_DEFINE_ADAPTER_ATTR(fc_service_class, "%d\n", adapter->fc_service_class);
ZFCP_DEFINE_ADAPTER_ATTR(fc_topology, "%s\n",
fc_topologies[adapter->fc_topology]);
ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n",
adapter->hardware_version);
-ZFCP_DEFINE_ADAPTER_ATTR(serial_number, "%17s\n", adapter->serial_number);
ZFCP_DEFINE_ADAPTER_ATTR(scsi_host_no, "0x%x\n", adapter->scsi_host_no);
ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask
(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status));
@@ -255,21 +252,18 @@ static struct attribute *zfcp_adapter_attrs[] = {
&dev_attr_in_recovery.attr,
&dev_attr_port_remove.attr,
&dev_attr_port_add.attr,
- &dev_attr_wwnn.attr,
- &dev_attr_wwpn.attr,
- &dev_attr_s_id.attr,
&dev_attr_peer_wwnn.attr,
&dev_attr_peer_wwpn.attr,
&dev_attr_peer_d_id.attr,
+ &dev_attr_physical_wwpn.attr,
+ &dev_attr_physical_s_id.attr,
&dev_attr_card_version.attr,
&dev_attr_lic_version.attr,
- &dev_attr_fc_link_speed.attr,
&dev_attr_fc_service_class.attr,
&dev_attr_fc_topology.attr,
&dev_attr_scsi_host_no.attr,
&dev_attr_status.attr,
&dev_attr_hardware_version.attr,
- &dev_attr_serial_number.attr,
NULL
};
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index d96cc47de566..672f9f2b2163 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -871,8 +871,7 @@ static irqreturn_t aurora_interrupt(int irq, void * dev_id, struct pt_regs * reg
#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/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index d44205d52bf3..d89f83f769f5 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -5,6 +5,7 @@
*/
#define __KERNEL_SYSCALLS__
+static int errno;
#include <linux/kernel.h>
#include <linux/kthread.h>
@@ -13,8 +14,6 @@
#include <linux/delay.h>
#include <asm/oplib.h>
#include <asm/ebus.h>
-static int errno;
-#include <asm/unistd.h>
#include "bbc_i2c.h"
#include "max1617.h"
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 87302fb14885..ccb20a6f5f36 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -295,8 +295,7 @@ static unsigned short get_pins(unsigned minor)
static void snooze(unsigned long snooze_time, unsigned minor)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(snooze_time + 1);
+ schedule_timeout_uninterruptible(snooze_time + 1);
}
static int wait_for(unsigned short set, unsigned short clr,
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index dbad7f35eb0a..24ed5893b4f0 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -14,7 +14,7 @@
#include <linux/major.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
-#include <linux/ioport.h> /* request_region, check_region */
+#include <linux/ioport.h> /* request_region */
#include <asm/atomic.h>
#include <asm/ebus.h> /* EBus device */
#include <asm/oplib.h> /* OpenProm Library */
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index d765cc1bf060..b0cc3c2588fd 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -20,6 +20,7 @@
*/
#define __KERNEL_SYSCALLS__
+static int errno;
#include <linux/config.h>
#include <linux/module.h>
@@ -38,9 +39,6 @@
#include <asm/uaccess.h>
#include <asm/envctrl.h>
-static int errno;
-#include <asm/unistd.h>
-
#define ENVCTRL_MINOR 162
#define PCF8584_ADDRESS 0x55
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c
index 739cad9b19a1..ceec30648f4f 100644
--- a/drivers/sbus/char/vfc_i2c.c
+++ b/drivers/sbus/char/vfc_i2c.c
@@ -81,8 +81,7 @@ int vfc_pcf8584_init(struct vfc_dev *dev)
void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(usecs_to_jiffies(usecs));
+ schedule_timeout_uninterruptible(usecs_to_jiffies(usecs));
}
void inline vfc_i2c_delay(struct vfc_dev *dev)
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index bc6e4627c7a1..a748fbfb6692 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -59,6 +59,8 @@
Fix 'handled=1' ISR usage, remove bogus IRQ check.
Remove un-needed eh_abort handler.
Add support for embedded firmware error strings.
+ 2.26.02.003 - Correctly handle single sgl's with use_sg=1.
+ 2.26.02.004 - Add support for 9550SX controllers.
*/
#include <linux/module.h>
@@ -81,7 +83,7 @@
#include "3w-9xxx.h"
/* Globals */
-#define TW_DRIVER_VERSION "2.26.02.002"
+#define TW_DRIVER_VERSION "2.26.02.004"
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
static unsigned int twa_device_extension_count;
static int twa_major = -1;
@@ -891,11 +893,6 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
}
- if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
- TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing");
- writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
- }
-
if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
if (tw_dev->reset_print == 0) {
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
@@ -929,6 +926,36 @@ out:
return retval;
} /* End twa_empty_response_queue() */
+/* This function will clear the pchip/response queue on 9550SX */
+static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
+{
+ u32 status_reg_value, response_que_value;
+ int count = 0, retval = 1;
+
+ if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) {
+ status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+ while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
+ response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
+ if ((response_que_value & TW_9550SX_DRAIN_COMPLETED) == TW_9550SX_DRAIN_COMPLETED) {
+ /* P-chip settle time */
+ msleep(500);
+ retval = 0;
+ goto out;
+ }
+ status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+ count++;
+ }
+ if (count == TW_MAX_RESPONSE_DRAIN)
+ goto out;
+
+ retval = 0;
+ } else
+ retval = 0;
+out:
+ return retval;
+} /* End twa_empty_response_queue_large() */
+
/* This function passes sense keys from firmware to scsi layer */
static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
{
@@ -1612,8 +1639,16 @@ static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
while (tries < TW_MAX_RESET_TRIES) {
- if (do_soft_reset)
+ if (do_soft_reset) {
TW_SOFT_RESET(tw_dev);
+ /* Clear pchip/response queue on 9550SX */
+ if (twa_empty_response_queue_large(tw_dev)) {
+ TW_PRINTK(tw_dev->host, TW_DRIVER, 0x36, "Response queue (large) empty failed during reset sequence");
+ do_soft_reset = 1;
+ tries++;
+ continue;
+ }
+ }
/* Make sure controller is in a good state */
if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 60)) {
@@ -1805,6 +1840,8 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
+ if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)
+ memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
} else {
buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
if (buffaddr == 0)
@@ -1823,6 +1860,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
if (tw_dev->srb[request_id]->use_sg > 0) {
if ((tw_dev->srb[request_id]->use_sg == 1) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
+ if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL) {
+ struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+ char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ }
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
} else {
@@ -1888,11 +1931,20 @@ out:
/* This function completes an execute scsi operation */
static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
{
- /* Copy the response if too small */
- if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
- memcpy(tw_dev->srb[request_id]->request_buffer,
- tw_dev->generic_buffer_virt[request_id],
- tw_dev->srb[request_id]->request_bufflen);
+ if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH &&
+ (tw_dev->srb[request_id]->sc_data_direction == DMA_FROM_DEVICE ||
+ tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)) {
+ if (tw_dev->srb[request_id]->use_sg == 0) {
+ memcpy(tw_dev->srb[request_id]->request_buffer,
+ tw_dev->generic_buffer_virt[request_id],
+ tw_dev->srb[request_id]->request_bufflen);
+ }
+ if (tw_dev->srb[request_id]->use_sg == 1) {
+ struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+ char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ }
}
} /* End twa_scsiop_execute_scsi_complete() */
@@ -2016,7 +2068,10 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
goto out_free_device_extension;
}
- mem_addr = pci_resource_start(pdev, 1);
+ if (pdev->device == PCI_DEVICE_ID_3WARE_9000)
+ mem_addr = pci_resource_start(pdev, 1);
+ else
+ mem_addr = pci_resource_start(pdev, 2);
/* Save base address */
tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE);
@@ -2130,6 +2185,8 @@ static void twa_remove(struct pci_dev *pdev)
static struct pci_device_id twa_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ }
};
MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h
index 8c8ecbed3b58..46f22cdc8298 100644
--- a/drivers/scsi/3w-9xxx.h
+++ b/drivers/scsi/3w-9xxx.h
@@ -267,7 +267,6 @@ static twa_message_type twa_error_table[] = {
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
-#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008
/* Status register bit definitions */
#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
@@ -285,9 +284,8 @@ static twa_message_type twa_error_table[] = {
#define TW_STATUS_MICROCONTROLLER_READY 0x00002000
#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000
#define TW_STATUS_EXPECTED_BITS 0x00002000
-#define TW_STATUS_UNEXPECTED_BITS 0x00F00008
-#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008
-#define TW_STATUS_VALID_INTERRUPT 0x00DF0008
+#define TW_STATUS_UNEXPECTED_BITS 0x00F00000
+#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
/* RESPONSE QUEUE BIT DEFINITIONS */
#define TW_RESPONSE_ID_MASK 0x00000FF0
@@ -324,9 +322,9 @@ static twa_message_type twa_error_table[] = {
/* Compatibility defines */
#define TW_9000_ARCH_ID 0x5
-#define TW_CURRENT_DRIVER_SRL 28
-#define TW_CURRENT_DRIVER_BUILD 9
-#define TW_CURRENT_DRIVER_BRANCH 4
+#define TW_CURRENT_DRIVER_SRL 30
+#define TW_CURRENT_DRIVER_BUILD 80
+#define TW_CURRENT_DRIVER_BRANCH 0
/* Phase defines */
#define TW_PHASE_INITIAL 0
@@ -334,6 +332,7 @@ static twa_message_type twa_error_table[] = {
#define TW_PHASE_SGLIST 2
/* Misc defines */
+#define TW_9550SX_DRAIN_COMPLETED 0xFFFF
#define TW_SECTOR_SIZE 512
#define TW_ALIGNMENT_9000 4 /* 4 bytes */
#define TW_ALIGNMENT_9000_SGL 0x3
@@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = {
#ifndef PCI_DEVICE_ID_3WARE_9000
#define PCI_DEVICE_ID_3WARE_9000 0x1002
#endif
+#ifndef PCI_DEVICE_ID_3WARE_9550SX
+#define PCI_DEVICE_ID_3WARE_9550SX 0x1003
+#endif
/* Bitmask macros to eliminate bitfields */
@@ -443,6 +445,7 @@ static twa_message_type twa_error_table[] = {
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
#define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
+#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 2341d27ceed7..7a33c708f5b3 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -6090,8 +6090,8 @@ NCR53c7x0_release(struct Scsi_Host *host) {
if (hostdata->num_cmds)
printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n",
host->host_no, hostdata->num_cmds);
- if (hostdata->events)
- vfree ((void *)hostdata->events);
+
+ vfree(hostdata->events);
/* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, which
* XXX may be invalid (CONFIG_060_WRITETHROUGH)
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index c76a3b8b5569..78c33180ebed 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -235,6 +235,13 @@ config SCSI_ISCSI_ATTRS
each attached iSCSI device to sysfs, say Y.
Otherwise, say N.
+config SCSI_SAS_ATTRS
+ tristate "SAS Transport Attributes"
+ depends on SCSI
+ help
+ If you wish to export transport-specific information about
+ each attached SAS device to sysfs, say Y.
+
endmenu
menu "SCSI low-level drivers"
@@ -506,11 +513,11 @@ config SCSI_SATA_NV
If unsure, say N.
-config SCSI_SATA_PROMISE
- tristate "Promise SATA TX2/TX4 support"
+config SCSI_PDC_ADMA
+ tristate "Pacific Digital ADMA support"
depends on SCSI_SATA && PCI
help
- This option enables support for Promise Serial ATA TX2/TX4.
+ This option enables support for Pacific Digital ADMA controllers
If unsure, say N.
@@ -522,6 +529,14 @@ config SCSI_SATA_QSTOR
If unsure, say N.
+config SCSI_SATA_PROMISE
+ tristate "Promise SATA TX2/TX4 support"
+ depends on SCSI_SATA && PCI
+ help
+ This option enables support for Promise Serial ATA TX2/TX4.
+
+ If unsure, say N.
+
config SCSI_SATA_SX4
tristate "Promise SATA SX4 support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
@@ -538,6 +553,14 @@ config SCSI_SATA_SIL
If unsure, say N.
+config SCSI_SATA_SIL24
+ tristate "Silicon Image 3124/3132 SATA support"
+ depends on SCSI_SATA && PCI && EXPERIMENTAL
+ help
+ This option enables support for Silicon Image 3124/3132 Serial ATA.
+
+ If unsure, say N.
+
config SCSI_SATA_SIS
tristate "SiS 964/180 SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
@@ -570,6 +593,11 @@ config SCSI_SATA_VITESSE
If unsure, say N.
+config SCSI_SATA_INTEL_COMBINED
+ bool
+ depends on IDE=y && !BLK_DEV_IDE_SATA && (SCSI_SATA_AHCI || SCSI_ATA_PIIX)
+ default y
+
config SCSI_BUSLOGIC
tristate "BusLogic SCSI support"
depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 2349f902b48a..8dfb9884afe0 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_RAID_ATTRS) += raid_class.o
obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o
obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
+obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o
obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o
@@ -99,6 +100,7 @@ obj-$(CONFIG_SCSI_DC395x) += dc395x.o
obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
+obj-$(CONFIG_MEGARAID_SAS) += megaraid/
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
obj-$(CONFIG_SCSI_SUNESP) += esp.o
obj-$(CONFIG_SCSI_GDTH) += gdth.o
@@ -129,6 +131,7 @@ obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_QSTOR) += libata.o sata_qstor.o
obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o
+obj-$(CONFIG_SCSI_SATA_SIL24) += libata.o sata_sil24.o
obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o
obj-$(CONFIG_SCSI_SATA_SIS) += libata.o sata_sis.o
@@ -136,6 +139,7 @@ obj-$(CONFIG_SCSI_SATA_SX4) += libata.o sata_sx4.o
obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o
obj-$(CONFIG_SCSI_SATA_ULI) += libata.o sata_uli.o
obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o
+obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o
obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d40ba0bd68a3..23392ae7df8b 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -91,7 +91,7 @@
#ifndef NDEBUG
#define NDEBUG 0
#endif
-#ifndef NDEBUG
+#ifndef NDEBUG_ABORT
#define NDEBUG_ABORT 0
#endif
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 44dbbe3dbe95..a913196459d5 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -313,18 +313,37 @@ int aac_get_containers(struct aac_dev *dev)
}
dresp = (struct aac_mount *)fib_data(fibptr);
+ if ((le32_to_cpu(dresp->status) == ST_OK) &&
+ (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) {
+ dinfo->command = cpu_to_le32(VM_NameServe64);
+ dinfo->count = cpu_to_le32(index);
+ dinfo->type = cpu_to_le32(FT_FILESYS);
+
+ if (fib_send(ContainerCommand,
+ fibptr,
+ sizeof(struct aac_query_mount),
+ FsaNormal,
+ 1, 1,
+ NULL, NULL) < 0)
+ continue;
+ } else
+ dresp->mnt[0].capacityhigh = 0;
+
dprintk ((KERN_DEBUG
- "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%u\n",
+ "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n",
(int)index, (int)le32_to_cpu(dresp->status),
(int)le32_to_cpu(dresp->mnt[0].vol),
(int)le32_to_cpu(dresp->mnt[0].state),
- (unsigned)le32_to_cpu(dresp->mnt[0].capacity)));
+ ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
+ (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32)));
if ((le32_to_cpu(dresp->status) == ST_OK) &&
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
fsa_dev_ptr[index].valid = 1;
fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol);
- fsa_dev_ptr[index].size = le32_to_cpu(dresp->mnt[0].capacity);
+ fsa_dev_ptr[index].size
+ = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
+ (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);
if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
fsa_dev_ptr[index].ro = 1;
}
@@ -460,7 +479,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
* is updated in the struct fsa_dev_info structure rather than returned.
*/
-static int probe_container(struct aac_dev *dev, int cid)
+int probe_container(struct aac_dev *dev, int cid)
{
struct fsa_dev_info *fsa_dev_ptr;
int status;
@@ -497,11 +516,29 @@ static int probe_container(struct aac_dev *dev, int cid)
dresp = (struct aac_mount *) fib_data(fibptr);
if ((le32_to_cpu(dresp->status) == ST_OK) &&
+ (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) {
+ dinfo->command = cpu_to_le32(VM_NameServe64);
+ dinfo->count = cpu_to_le32(cid);
+ dinfo->type = cpu_to_le32(FT_FILESYS);
+
+ if (fib_send(ContainerCommand,
+ fibptr,
+ sizeof(struct aac_query_mount),
+ FsaNormal,
+ 1, 1,
+ NULL, NULL) < 0)
+ goto error;
+ } else
+ dresp->mnt[0].capacityhigh = 0;
+
+ if ((le32_to_cpu(dresp->status) == ST_OK) &&
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
fsa_dev_ptr[cid].valid = 1;
fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol);
- fsa_dev_ptr[cid].size = le32_to_cpu(dresp->mnt[0].capacity);
+ fsa_dev_ptr[cid].size
+ = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
+ (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);
if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
fsa_dev_ptr[cid].ro = 1;
}
@@ -683,7 +720,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
fibptr,
sizeof(*info),
FsaNormal,
- 1, 1,
+ -1, 1, /* First `interrupt' command uses special wait */
NULL,
NULL);
@@ -834,8 +871,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (!(dev->raw_io_interface)) {
dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
sizeof(struct aac_fibhdr) -
- sizeof(struct aac_write) + sizeof(struct sgmap)) /
- sizeof(struct sgmap);
+ sizeof(struct aac_write) + sizeof(struct sgentry)) /
+ sizeof(struct sgentry);
if (dev->dac_support) {
/*
* 38 scatter gather elements
@@ -844,8 +881,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
(dev->max_fib_size -
sizeof(struct aac_fibhdr) -
sizeof(struct aac_write64) +
- sizeof(struct sgmap64)) /
- sizeof(struct sgmap64);
+ sizeof(struct sgentry64)) /
+ sizeof(struct sgentry64);
}
dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
@@ -882,7 +919,40 @@ static void io_callback(void *context, struct fib * fibptr)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
- dprintk((KERN_DEBUG "io_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3], jiffies));
+ if (nblank(dprintk(x))) {
+ u64 lba;
+ switch (scsicmd->cmnd[0]) {
+ case WRITE_6:
+ case READ_6:
+ lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
+ (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+ break;
+ case WRITE_16:
+ case READ_16:
+ lba = ((u64)scsicmd->cmnd[2] << 56) |
+ ((u64)scsicmd->cmnd[3] << 48) |
+ ((u64)scsicmd->cmnd[4] << 40) |
+ ((u64)scsicmd->cmnd[5] << 32) |
+ ((u64)scsicmd->cmnd[6] << 24) |
+ (scsicmd->cmnd[7] << 16) |
+ (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+ break;
+ case WRITE_12:
+ case READ_12:
+ lba = ((u64)scsicmd->cmnd[2] << 24) |
+ (scsicmd->cmnd[3] << 16) |
+ (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ break;
+ default:
+ lba = ((u64)scsicmd->cmnd[2] << 24) |
+ (scsicmd->cmnd[3] << 16) |
+ (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ break;
+ }
+ printk(KERN_DEBUG
+ "io_callback[cpu %d]: lba = %llu, t = %ld.\n",
+ smp_processor_id(), (unsigned long long)lba, jiffies);
+ }
if (fibptr == NULL)
BUG();
@@ -923,7 +993,7 @@ static void io_callback(void *context, struct fib * fibptr)
static int aac_read(struct scsi_cmnd * scsicmd, int cid)
{
- u32 lba;
+ u64 lba;
u32 count;
int status;
@@ -935,23 +1005,69 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
/*
* Get block address and transfer length
*/
- if (scsicmd->cmnd[0] == READ_6) /* 6 byte command */
- {
+ switch (scsicmd->cmnd[0]) {
+ case READ_6:
dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid));
- lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+ lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
+ (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
count = scsicmd->cmnd[4];
if (count == 0)
count = 256;
- } else {
+ break;
+ case READ_16:
+ dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid));
+
+ lba = ((u64)scsicmd->cmnd[2] << 56) |
+ ((u64)scsicmd->cmnd[3] << 48) |
+ ((u64)scsicmd->cmnd[4] << 40) |
+ ((u64)scsicmd->cmnd[5] << 32) |
+ ((u64)scsicmd->cmnd[6] << 24) |
+ (scsicmd->cmnd[7] << 16) |
+ (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+ count = (scsicmd->cmnd[10] << 24) |
+ (scsicmd->cmnd[11] << 16) |
+ (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
+ break;
+ case READ_12:
+ dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid));
+
+ lba = ((u64)scsicmd->cmnd[2] << 24) |
+ (scsicmd->cmnd[3] << 16) |
+ (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ count = (scsicmd->cmnd[6] << 24) |
+ (scsicmd->cmnd[7] << 16) |
+ (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+ break;
+ default:
dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid));
- lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ lba = ((u64)scsicmd->cmnd[2] << 24) |
+ (scsicmd->cmnd[3] << 16) |
+ (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
+ break;
}
- dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n",
+ dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
smp_processor_id(), (unsigned long long)lba, jiffies));
+ if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) &&
+ (lba & 0xffffffff00000000LL)) {
+ dprintk((KERN_DEBUG "aac_read: Illegal lba\n"));
+ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+ SAM_STAT_CHECK_CONDITION;
+ set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+ HARDWARE_ERROR,
+ SENCODE_INTERNAL_TARGET_FAILURE,
+ ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+ 0, 0);
+ memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+ (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
+ ? sizeof(scsicmd->sense_buffer)
+ : sizeof(dev->fsa_dev[cid].sense_data));
+ scsicmd->scsi_done(scsicmd);
+ return 0;
+ }
/*
* Alocate and initialize a Fib
*/
@@ -964,8 +1080,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
if (dev->raw_io_interface) {
struct aac_raw_io *readcmd;
readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
- readcmd->block[0] = cpu_to_le32(lba);
- readcmd->block[1] = 0;
+ readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+ readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
readcmd->count = cpu_to_le32(count<<9);
readcmd->cid = cpu_to_le16(cid);
readcmd->flags = cpu_to_le16(1);
@@ -992,7 +1108,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
readcmd->command = cpu_to_le32(VM_CtHostRead64);
readcmd->cid = cpu_to_le16(cid);
readcmd->sector_count = cpu_to_le16(count);
- readcmd->block = cpu_to_le32(lba);
+ readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->pad = 0;
readcmd->flags = 0;
@@ -1017,7 +1133,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
readcmd = (struct aac_read *) fib_data(cmd_fibcontext);
readcmd->command = cpu_to_le32(VM_CtBlockRead);
readcmd->cid = cpu_to_le32(cid);
- readcmd->block = cpu_to_le32(lba);
+ readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->count = cpu_to_le32(count * 512);
aac_build_sg(scsicmd, &readcmd->sg);
@@ -1059,7 +1175,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
static int aac_write(struct scsi_cmnd * scsicmd, int cid)
{
- u32 lba;
+ u64 lba;
u32 count;
int status;
u16 fibsize;
@@ -1076,13 +1192,48 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
count = scsicmd->cmnd[4];
if (count == 0)
count = 256;
+ } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */
+ dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid));
+
+ lba = ((u64)scsicmd->cmnd[2] << 56) |
+ ((u64)scsicmd->cmnd[3] << 48) |
+ ((u64)scsicmd->cmnd[4] << 40) |
+ ((u64)scsicmd->cmnd[5] << 32) |
+ ((u64)scsicmd->cmnd[6] << 24) |
+ (scsicmd->cmnd[7] << 16) |
+ (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+ count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
+ (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
+ } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */
+ dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid));
+
+ lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16)
+ | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)
+ | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
} else {
dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid));
- lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
}
- dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n",
+ dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
smp_processor_id(), (unsigned long long)lba, jiffies));
+ if ((!(dev->raw_io_interface) || !(dev->raw_io_64))
+ && (lba & 0xffffffff00000000LL)) {
+ dprintk((KERN_DEBUG "aac_write: Illegal lba\n"));
+ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+ set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+ HARDWARE_ERROR,
+ SENCODE_INTERNAL_TARGET_FAILURE,
+ ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+ 0, 0);
+ memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+ (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
+ ? sizeof(scsicmd->sense_buffer)
+ : sizeof(dev->fsa_dev[cid].sense_data));
+ scsicmd->scsi_done(scsicmd);
+ return 0;
+ }
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
@@ -1096,8 +1247,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
if (dev->raw_io_interface) {
struct aac_raw_io *writecmd;
writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
- writecmd->block[0] = cpu_to_le32(lba);
- writecmd->block[1] = 0;
+ writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+ writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
writecmd->count = cpu_to_le32(count<<9);
writecmd->cid = cpu_to_le16(cid);
writecmd->flags = 0;
@@ -1124,7 +1275,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
writecmd->command = cpu_to_le32(VM_CtHostWrite64);
writecmd->cid = cpu_to_le16(cid);
writecmd->sector_count = cpu_to_le16(count);
- writecmd->block = cpu_to_le32(lba);
+ writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
writecmd->pad = 0;
writecmd->flags = 0;
@@ -1149,7 +1300,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
writecmd = (struct aac_write *) fib_data(cmd_fibcontext);
writecmd->command = cpu_to_le32(VM_CtBlockWrite);
writecmd->cid = cpu_to_le32(cid);
- writecmd->block = cpu_to_le32(lba);
+ writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
writecmd->count = cpu_to_le32(count * 512);
writecmd->sg.count = cpu_to_le32(1);
/* ->stable is not used - it did mean which type of write */
@@ -1337,11 +1488,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
*/
if ((fsa_dev_ptr[cid].valid & 1) == 0) {
switch (scsicmd->cmnd[0]) {
+ case SERVICE_ACTION_IN:
+ if (!(dev->raw_io_interface) ||
+ !(dev->raw_io_64) ||
+ ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
+ break;
case INQUIRY:
case READ_CAPACITY:
case TEST_UNIT_READY:
spin_unlock_irq(host->host_lock);
probe_container(dev, cid);
+ if ((fsa_dev_ptr[cid].valid & 1) == 0)
+ fsa_dev_ptr[cid].valid = 0;
spin_lock_irq(host->host_lock);
if (fsa_dev_ptr[cid].valid == 0) {
scsicmd->result = DID_NO_CONNECT << 16;
@@ -1402,7 +1560,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
memset(&inq_data, 0, sizeof (struct inquiry_data));
inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
- inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */
inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
inq_data.inqd_len = 31;
/*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
@@ -1424,13 +1581,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
return aac_get_container_name(scsicmd, cid);
}
+ case SERVICE_ACTION_IN:
+ if (!(dev->raw_io_interface) ||
+ !(dev->raw_io_64) ||
+ ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
+ break;
+ {
+ u64 capacity;
+ char cp[12];
+ unsigned int offset = 0;
+
+ dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
+ capacity = fsa_dev_ptr[cid].size - 1;
+ if (scsicmd->cmnd[13] > 12) {
+ offset = scsicmd->cmnd[13] - 12;
+ if (offset > sizeof(cp))
+ break;
+ memset(cp, 0, offset);
+ aac_internal_transfer(scsicmd, cp, 0, offset);
+ }
+ cp[0] = (capacity >> 56) & 0xff;
+ cp[1] = (capacity >> 48) & 0xff;
+ cp[2] = (capacity >> 40) & 0xff;
+ cp[3] = (capacity >> 32) & 0xff;
+ cp[4] = (capacity >> 24) & 0xff;
+ cp[5] = (capacity >> 16) & 0xff;
+ cp[6] = (capacity >> 8) & 0xff;
+ cp[7] = (capacity >> 0) & 0xff;
+ cp[8] = 0;
+ cp[9] = 0;
+ cp[10] = 2;
+ cp[11] = 0;
+ aac_internal_transfer(scsicmd, cp, offset, sizeof(cp));
+
+ /* Do not cache partition table for arrays */
+ scsicmd->device->removable = 1;
+
+ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+ scsicmd->scsi_done(scsicmd);
+
+ return 0;
+ }
+
case READ_CAPACITY:
{
u32 capacity;
char cp[8];
dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
- if (fsa_dev_ptr[cid].size <= 0x100000000LL)
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
capacity = fsa_dev_ptr[cid].size - 1;
else
capacity = (u32)-1;
@@ -1444,6 +1643,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[6] = 2;
cp[7] = 0;
aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));
+ /* Do not cache partition table for arrays */
+ scsicmd->device->removable = 1;
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
@@ -1524,6 +1725,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
{
case READ_6:
case READ_10:
+ case READ_12:
+ case READ_16:
/*
* Hack to keep track of ordinal number of the device that
* corresponds to a container. Needed to convert
@@ -1531,17 +1734,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
*/
spin_unlock_irq(host->host_lock);
- if (scsicmd->request->rq_disk)
- memcpy(fsa_dev_ptr[cid].devname,
- scsicmd->request->rq_disk->disk_name,
- 8);
-
+ if (scsicmd->request->rq_disk)
+ strlcpy(fsa_dev_ptr[cid].devname,
+ scsicmd->request->rq_disk->disk_name,
+ min(sizeof(fsa_dev_ptr[cid].devname),
+ sizeof(scsicmd->request->rq_disk->disk_name) + 1));
ret = aac_read(scsicmd, cid);
spin_lock_irq(host->host_lock);
return ret;
case WRITE_6:
case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
spin_unlock_irq(host->host_lock);
ret = aac_write(scsicmd, cid);
spin_lock_irq(host->host_lock);
@@ -1772,6 +1977,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
case WRITE_10:
case READ_12:
case WRITE_12:
+ case READ_16:
+ case WRITE_16:
if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) {
printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
} else {
@@ -1877,8 +2084,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
sizeof(scsicmd->sense_buffer) :
le32_to_cpu(srbreply->sense_data_size);
#ifdef AAC_DETAILED_STATUS_INFO
- dprintk((KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
- le32_to_cpu(srbreply->status), len));
+ printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
+ le32_to_cpu(srbreply->status), len);
#endif
memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index bdfd4a7f950e..2ebe402bc31a 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1,6 +1,10 @@
#if (!defined(dprintk))
# define dprintk(x)
#endif
+/* eg: if (nblank(dprintk(x))) */
+#define _nblank(x) #x
+#define nblank(x) _nblank(x)[0]
+
/*------------------------------------------------------------------------------
* D E F I N E S
@@ -15,7 +19,7 @@
#define AAC_MAX_LUN (8)
#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
-#define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)512)
+#define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)256)
/*
* These macros convert from physical channels to virtual channels
@@ -302,7 +306,6 @@ enum aac_queue_types {
*/
#define FsaNormal 1
-#define FsaHigh 2
/*
* Define the FIB. The FIB is the where all the requested data and
@@ -546,8 +549,6 @@ struct aac_queue {
/* This is only valid for adapter to host command queues. */
spinlock_t *lock; /* Spinlock for this queue must take this lock before accessing the lock */
spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */
- unsigned long SavedIrql; /* Previous IRQL when the spin lock is taken */
- u32 padding; /* Padding - FIXME - can remove I believe */
struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */
/* only valid for command queues which receive entries from the adapter. */
struct list_head pendingq; /* A queue of outstanding fib's to the adapter. */
@@ -776,7 +777,9 @@ struct fsa_dev_info {
u64 last;
u64 size;
u32 type;
+ u32 config_waiting_on;
u16 queue_depth;
+ u8 config_needed;
u8 valid;
u8 ro;
u8 locked;
@@ -1012,6 +1015,7 @@ struct aac_dev
/* macro side-effects BEWARE */
# define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
+ u8 raw_io_64;
u8 printf_enabled;
};
@@ -1362,8 +1366,10 @@ struct aac_srb_reply
#define VM_CtBlockVerify64 18
#define VM_CtHostRead64 19
#define VM_CtHostWrite64 20
+#define VM_DrvErrTblLog 21
+#define VM_NameServe64 22
-#define MAX_VMCOMMAND_NUM 21 /* used for sizing stats array - leave last */
+#define MAX_VMCOMMAND_NUM 23 /* used for sizing stats array - leave last */
/*
* Descriptive information (eg, vital stats)
@@ -1472,6 +1478,7 @@ struct aac_mntent {
manager (eg, filesystem) */
__le32 altoid; /* != oid <==> snapshot or
broken mirror exists */
+ __le32 capacityhigh;
};
#define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */
@@ -1707,6 +1714,7 @@ extern struct aac_common aac_config;
#define AifCmdJobProgress 2 /* Progress report */
#define AifJobCtrZero 101 /* Array Zero progress */
#define AifJobStsSuccess 1 /* Job completes */
+#define AifJobStsRunning 102 /* Job running */
#define AifCmdAPIReport 3 /* Report from other user of API */
#define AifCmdDriverNotify 4 /* Notify host driver of event */
#define AifDenMorphComplete 200 /* A morph operation completed */
@@ -1777,6 +1785,7 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size);
struct aac_driver_ident* aac_get_driver_ident(int devtype);
int aac_get_adapter_info(struct aac_dev* dev);
int aac_send_shutdown(struct aac_dev *dev);
+int probe_container(struct aac_dev *dev, int cid);
extern int numacb;
extern int acbsize;
extern char aac_driver_version[];
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 75abd0453289..59a341b2aedc 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -195,7 +195,7 @@ int aac_send_shutdown(struct aac_dev * dev)
fibctx,
sizeof(struct aac_close),
FsaNormal,
- 1, 1,
+ -2 /* Timeout silently */, 1,
NULL, NULL);
if (status == 0)
@@ -313,8 +313,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->max_fib_size = sizeof(struct hw_fib);
dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
- sizeof(struct aac_fibhdr)
- - sizeof(struct aac_write) + sizeof(struct sgmap))
- / sizeof(struct sgmap);
+ - sizeof(struct aac_write) + sizeof(struct sgentry))
+ / sizeof(struct sgentry);
+ dev->raw_io_64 = 0;
+ if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
+ 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
+ (status[0] == 0x00000001)) {
+ if (status[1] & AAC_OPT_NEW_COMM_64)
+ dev->raw_io_64 = 1;
+ }
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4))
@@ -342,8 +349,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->max_fib_size = 512;
dev->sg_tablesize = host->sg_tablesize
= (512 - sizeof(struct aac_fibhdr)
- - sizeof(struct aac_write) + sizeof(struct sgmap))
- / sizeof(struct sgmap);
+ - sizeof(struct aac_write) + sizeof(struct sgentry))
+ / sizeof(struct sgentry);
host->can_queue = AAC_NUM_IO_FIB;
} else if (acbsize == 2048) {
host->max_sectors = 512;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index a1d303f03480..e4d543a474ae 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -39,7 +39,9 @@
#include <linux/completion.h>
#include <linux/blkdev.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
#include <asm/semaphore.h>
+#include <asm/delay.h>
#include "aacraid.h"
@@ -269,40 +271,22 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
/* Interrupt Moderation, only interrupt for first two entries */
if (idx != le32_to_cpu(*(q->headers.consumer))) {
if (--idx == 0) {
- if (qid == AdapHighCmdQueue)
- idx = ADAP_HIGH_CMD_ENTRIES;
- else if (qid == AdapNormCmdQueue)
+ if (qid == AdapNormCmdQueue)
idx = ADAP_NORM_CMD_ENTRIES;
- else if (qid == AdapHighRespQueue)
- idx = ADAP_HIGH_RESP_ENTRIES;
- else if (qid == AdapNormRespQueue)
+ else
idx = ADAP_NORM_RESP_ENTRIES;
}
if (idx != le32_to_cpu(*(q->headers.consumer)))
*nonotify = 1;
}
- if (qid == AdapHighCmdQueue) {
- if (*index >= ADAP_HIGH_CMD_ENTRIES)
- *index = 0;
- } else if (qid == AdapNormCmdQueue) {
+ if (qid == AdapNormCmdQueue) {
if (*index >= ADAP_NORM_CMD_ENTRIES)
*index = 0; /* Wrap to front of the Producer Queue. */
- }
- else if (qid == AdapHighRespQueue)
- {
- if (*index >= ADAP_HIGH_RESP_ENTRIES)
- *index = 0;
- }
- else if (qid == AdapNormRespQueue)
- {
+ } else {
if (*index >= ADAP_NORM_RESP_ENTRIES)
*index = 0; /* Wrap to front of the Producer Queue. */
}
- else {
- printk("aacraid: invalid qid\n");
- BUG();
- }
if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
@@ -334,12 +318,8 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
{
struct aac_entry * entry = NULL;
int map = 0;
- struct aac_queue * q = &dev->queues->queue[qid];
-
- spin_lock_irqsave(q->lock, q->SavedIrql);
- if (qid == AdapHighCmdQueue || qid == AdapNormCmdQueue)
- {
+ if (qid == AdapNormCmdQueue) {
/* if no entries wait for some if caller wants to */
while (!aac_get_entry(dev, qid, &entry, index, nonotify))
{
@@ -350,9 +330,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
*/
entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
map = 1;
- }
- else if (qid == AdapHighRespQueue || qid == AdapNormRespQueue)
- {
+ } else {
while(!aac_get_entry(dev, qid, &entry, index, nonotify))
{
/* if no entries wait for some if caller wants to */
@@ -375,42 +353,6 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
return 0;
}
-
-/**
- * aac_insert_entry - insert a queue entry
- * @dev: Adapter
- * @index: Index of entry to insert
- * @qid: Queue number
- * @nonotify: Suppress adapter notification
- *
- * Gets the next free QE off the requested priorty adapter command
- * queue and associates the Fib with the QE. The QE represented by
- * index is ready to insert on the queue when this routine returns
- * success.
- */
-
-static int aac_insert_entry(struct aac_dev * dev, u32 index, u32 qid, unsigned long nonotify)
-{
- struct aac_queue * q = &dev->queues->queue[qid];
-
- if(q == NULL)
- BUG();
- *(q->headers.producer) = cpu_to_le32(index + 1);
- spin_unlock_irqrestore(q->lock, q->SavedIrql);
-
- if (qid == AdapHighCmdQueue ||
- qid == AdapNormCmdQueue ||
- qid == AdapHighRespQueue ||
- qid == AdapNormRespQueue)
- {
- if (!nonotify)
- aac_adapter_notify(dev, qid);
- }
- else
- printk("Suprise insert!\n");
- return 0;
-}
-
/*
* Define the highest level of host to adapter communication routines.
* These routines will support host to adapter FS commuication. These
@@ -439,12 +381,13 @@ static int aac_insert_entry(struct aac_dev * dev, u32 index, u32 qid, unsigned l
int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data)
{
u32 index;
- u32 qid;
struct aac_dev * dev = fibptr->dev;
unsigned long nointr = 0;
struct hw_fib * hw_fib = fibptr->hw_fib;
struct aac_queue * q;
unsigned long flags = 0;
+ unsigned long qflags;
+
if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
return -EBUSY;
/*
@@ -497,26 +440,8 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
* Get a queue entry connect the FIB to it and send an notify
* the adapter a command is ready.
*/
- if (priority == FsaHigh) {
- hw_fib->header.XferState |= cpu_to_le32(HighPriority);
- qid = AdapHighCmdQueue;
- } else {
- hw_fib->header.XferState |= cpu_to_le32(NormalPriority);
- qid = AdapNormCmdQueue;
- }
- q = &dev->queues->queue[qid];
+ hw_fib->header.XferState |= cpu_to_le32(NormalPriority);
- if(wait)
- spin_lock_irqsave(&fibptr->event_lock, flags);
- if(aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr)<0)
- return -EWOULDBLOCK;
- dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
- dprintk((KERN_DEBUG "Fib contents:.\n"));
- dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command));
- dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState));
- dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib));
- dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
- dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
/*
* Fill in the Callback and CallbackContext if we are not
* going to wait.
@@ -525,22 +450,67 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
fibptr->callback = callback;
fibptr->callback_data = callback_data;
}
- FIB_COUNTER_INCREMENT(aac_config.FibsSent);
- list_add_tail(&fibptr->queue, &q->pendingq);
- q->numpending++;
fibptr->done = 0;
fibptr->flags = 0;
- if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0)
- return -EWOULDBLOCK;
+ FIB_COUNTER_INCREMENT(aac_config.FibsSent);
+
+ dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
+ dprintk((KERN_DEBUG "Fib contents:.\n"));
+ dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command));
+ dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState));
+ dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib));
+ dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
+ dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
+
+ q = &dev->queues->queue[AdapNormCmdQueue];
+
+ if(wait)
+ spin_lock_irqsave(&fibptr->event_lock, flags);
+ spin_lock_irqsave(q->lock, qflags);
+ aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
+
+ list_add_tail(&fibptr->queue, &q->pendingq);
+ q->numpending++;
+ *(q->headers.producer) = cpu_to_le32(index + 1);
+ spin_unlock_irqrestore(q->lock, qflags);
+ if (!(nointr & aac_config.irq_mod))
+ aac_adapter_notify(dev, AdapNormCmdQueue);
/*
* If the caller wanted us to wait for response wait now.
*/
if (wait) {
spin_unlock_irqrestore(&fibptr->event_lock, flags);
- down(&fibptr->event_wait);
+ /* Only set for first known interruptable command */
+ if (wait < 0) {
+ /*
+ * *VERY* Dangerous to time out a command, the
+ * assumption is made that we have no hope of
+ * functioning because an interrupt routing or other
+ * hardware failure has occurred.
+ */
+ unsigned long count = 36000000L; /* 3 minutes */
+ unsigned long qflags;
+ while (down_trylock(&fibptr->event_wait)) {
+ if (--count == 0) {
+ spin_lock_irqsave(q->lock, qflags);
+ q->numpending--;
+ list_del(&fibptr->queue);
+ spin_unlock_irqrestore(q->lock, qflags);
+ if (wait == -1) {
+ printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n"
+ "Usually a result of a PCI interrupt routing problem;\n"
+ "update mother board BIOS or consider utilizing one of\n"
+ "the SAFE mode kernel options (acpi, apic etc)\n");
+ }
+ return -ETIMEDOUT;
+ }
+ udelay(5);
+ }
+ } else
+ down(&fibptr->event_wait);
if(fibptr->done == 0)
BUG();
@@ -622,15 +592,9 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
case HostNormCmdQueue:
notify = HostNormCmdNotFull;
break;
- case HostHighCmdQueue:
- notify = HostHighCmdNotFull;
- break;
case HostNormRespQueue:
notify = HostNormRespNotFull;
break;
- case HostHighRespQueue:
- notify = HostHighRespNotFull;
- break;
default:
BUG();
return;
@@ -652,9 +616,13 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
{
struct hw_fib * hw_fib = fibptr->hw_fib;
struct aac_dev * dev = fibptr->dev;
+ struct aac_queue * q;
unsigned long nointr = 0;
- if (hw_fib->header.XferState == 0)
+ unsigned long qflags;
+
+ if (hw_fib->header.XferState == 0) {
return 0;
+ }
/*
* If we plan to do anything check the structure type first.
*/
@@ -669,37 +637,21 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
* send the completed cdb to the adapter.
*/
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
+ u32 index;
hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
- if (hw_fib->header.XferState & cpu_to_le32(HighPriority)) {
- u32 index;
- if (size)
- {
- size += sizeof(struct aac_fibhdr);
- if (size > le16_to_cpu(hw_fib->header.SenderSize))
- return -EMSGSIZE;
- hw_fib->header.Size = cpu_to_le16(size);
- }
- if(aac_queue_get(dev, &index, AdapHighRespQueue, hw_fib, 1, NULL, &nointr) < 0) {
- return -EWOULDBLOCK;
- }
- if (aac_insert_entry(dev, index, AdapHighRespQueue, (nointr & (int)aac_config.irq_mod)) != 0) {
- }
- } else if (hw_fib->header.XferState &
- cpu_to_le32(NormalPriority)) {
- u32 index;
-
- if (size) {
- size += sizeof(struct aac_fibhdr);
- if (size > le16_to_cpu(hw_fib->header.SenderSize))
- return -EMSGSIZE;
- hw_fib->header.Size = cpu_to_le16(size);
- }
- if (aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr) < 0)
- return -EWOULDBLOCK;
- if (aac_insert_entry(dev, index, AdapNormRespQueue, (nointr & (int)aac_config.irq_mod)) != 0)
- {
- }
+ if (size) {
+ size += sizeof(struct aac_fibhdr);
+ if (size > le16_to_cpu(hw_fib->header.SenderSize))
+ return -EMSGSIZE;
+ hw_fib->header.Size = cpu_to_le16(size);
}
+ q = &dev->queues->queue[AdapNormRespQueue];
+ spin_lock_irqsave(q->lock, qflags);
+ aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
+ *(q->headers.producer) = cpu_to_le32(index + 1);
+ spin_unlock_irqrestore(q->lock, qflags);
+ if (!(nointr & (int)aac_config.irq_mod))
+ aac_adapter_notify(dev, AdapNormRespQueue);
}
else
{
@@ -791,6 +743,268 @@ void aac_printf(struct aac_dev *dev, u32 val)
memset(cp, 0, 256);
}
+
+/**
+ * aac_handle_aif - Handle a message from the firmware
+ * @dev: Which adapter this fib is from
+ * @fibptr: Pointer to fibptr from adapter
+ *
+ * This routine handles a driver notify fib from the adapter and
+ * dispatches it to the appropriate routine for handling.
+ */
+
+static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
+{
+ struct hw_fib * hw_fib = fibptr->hw_fib;
+ struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
+ int busy;
+ u32 container;
+ struct scsi_device *device;
+ enum {
+ NOTHING,
+ DELETE,
+ ADD,
+ CHANGE
+ } device_config_needed;
+
+ /* Sniff for container changes */
+
+ if (!dev)
+ return;
+ container = (u32)-1;
+
+ /*
+ * We have set this up to try and minimize the number of
+ * re-configures that take place. As a result of this when
+ * certain AIF's come in we will set a flag waiting for another
+ * type of AIF before setting the re-config flag.
+ */
+ switch (le32_to_cpu(aifcmd->command)) {
+ case AifCmdDriverNotify:
+ switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {
+ /*
+ * Morph or Expand complete
+ */
+ case AifDenMorphComplete:
+ case AifDenVolumeExtendComplete:
+ container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ if (container >= dev->maximum_num_containers)
+ break;
+
+ /*
+ * Find the Scsi_Device associated with the SCSI
+ * address. Make sure we have the right array, and if
+ * so set the flag to initiate a new re-config once we
+ * see an AifEnConfigChange AIF come through.
+ */
+
+ if ((dev != NULL) && (dev->scsi_host_ptr != NULL)) {
+ device = scsi_device_lookup(dev->scsi_host_ptr,
+ CONTAINER_TO_CHANNEL(container),
+ CONTAINER_TO_ID(container),
+ CONTAINER_TO_LUN(container));
+ if (device) {
+ dev->fsa_dev[container].config_needed = CHANGE;
+ dev->fsa_dev[container].config_waiting_on = AifEnConfigChange;
+ scsi_device_put(device);
+ }
+ }
+ }
+
+ /*
+ * If we are waiting on something and this happens to be
+ * that thing then set the re-configure flag.
+ */
+ if (container != (u32)-1) {
+ if (container >= dev->maximum_num_containers)
+ break;
+ if (dev->fsa_dev[container].config_waiting_on ==
+ le32_to_cpu(*(u32 *)aifcmd->data))
+ dev->fsa_dev[container].config_waiting_on = 0;
+ } else for (container = 0;
+ container < dev->maximum_num_containers; ++container) {
+ if (dev->fsa_dev[container].config_waiting_on ==
+ le32_to_cpu(*(u32 *)aifcmd->data))
+ dev->fsa_dev[container].config_waiting_on = 0;
+ }
+ break;
+
+ case AifCmdEventNotify:
+ switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {
+ /*
+ * Add an Array.
+ */
+ case AifEnAddContainer:
+ container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ if (container >= dev->maximum_num_containers)
+ break;
+ dev->fsa_dev[container].config_needed = ADD;
+ dev->fsa_dev[container].config_waiting_on =
+ AifEnConfigChange;
+ break;
+
+ /*
+ * Delete an Array.
+ */
+ case AifEnDeleteContainer:
+ container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ if (container >= dev->maximum_num_containers)
+ break;
+ dev->fsa_dev[container].config_needed = DELETE;
+ dev->fsa_dev[container].config_waiting_on =
+ AifEnConfigChange;
+ break;
+
+ /*
+ * Container change detected. If we currently are not
+ * waiting on something else, setup to wait on a Config Change.
+ */
+ case AifEnContainerChange:
+ container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ if (container >= dev->maximum_num_containers)
+ break;
+ if (dev->fsa_dev[container].config_waiting_on)
+ break;
+ dev->fsa_dev[container].config_needed = CHANGE;
+ dev->fsa_dev[container].config_waiting_on =
+ AifEnConfigChange;
+ break;
+
+ case AifEnConfigChange:
+ break;
+
+ }
+
+ /*
+ * If we are waiting on something and this happens to be
+ * that thing then set the re-configure flag.
+ */
+ if (container != (u32)-1) {
+ if (container >= dev->maximum_num_containers)
+ break;
+ if (dev->fsa_dev[container].config_waiting_on ==
+ le32_to_cpu(*(u32 *)aifcmd->data))
+ dev->fsa_dev[container].config_waiting_on = 0;
+ } else for (container = 0;
+ container < dev->maximum_num_containers; ++container) {
+ if (dev->fsa_dev[container].config_waiting_on ==
+ le32_to_cpu(*(u32 *)aifcmd->data))
+ dev->fsa_dev[container].config_waiting_on = 0;
+ }
+ break;
+
+ case AifCmdJobProgress:
+ /*
+ * These are job progress AIF's. When a Clear is being
+ * done on a container it is initially created then hidden from
+ * the OS. When the clear completes we don't get a config
+ * change so we monitor the job status complete on a clear then
+ * wait for a container change.
+ */
+
+ if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))
+ && ((((u32 *)aifcmd->data)[6] == ((u32 *)aifcmd->data)[5])
+ || (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess)))) {
+ for (container = 0;
+ container < dev->maximum_num_containers;
+ ++container) {
+ /*
+ * Stomp on all config sequencing for all
+ * containers?
+ */
+ dev->fsa_dev[container].config_waiting_on =
+ AifEnContainerChange;
+ dev->fsa_dev[container].config_needed = ADD;
+ }
+ }
+ if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))
+ && (((u32 *)aifcmd->data)[6] == 0)
+ && (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsRunning))) {
+ for (container = 0;
+ container < dev->maximum_num_containers;
+ ++container) {
+ /*
+ * Stomp on all config sequencing for all
+ * containers?
+ */
+ dev->fsa_dev[container].config_waiting_on =
+ AifEnContainerChange;
+ dev->fsa_dev[container].config_needed = DELETE;
+ }
+ }
+ break;
+ }
+
+ device_config_needed = NOTHING;
+ for (container = 0; container < dev->maximum_num_containers;
+ ++container) {
+ if ((dev->fsa_dev[container].config_waiting_on == 0)
+ && (dev->fsa_dev[container].config_needed != NOTHING)) {
+ device_config_needed =
+ dev->fsa_dev[container].config_needed;
+ dev->fsa_dev[container].config_needed = NOTHING;
+ break;
+ }
+ }
+ if (device_config_needed == NOTHING)
+ return;
+
+ /*
+ * If we decided that a re-configuration needs to be done,
+ * schedule it here on the way out the door, please close the door
+ * behind you.
+ */
+
+ busy = 0;
+
+
+ /*
+ * Find the Scsi_Device associated with the SCSI address,
+ * and mark it as changed, invalidating the cache. This deals
+ * with changes to existing device IDs.
+ */
+
+ if (!dev || !dev->scsi_host_ptr)
+ return;
+ /*
+ * force reload of disk info via probe_container
+ */
+ if ((device_config_needed == CHANGE)
+ && (dev->fsa_dev[container].valid == 1))
+ dev->fsa_dev[container].valid = 2;
+ if ((device_config_needed == CHANGE) ||
+ (device_config_needed == ADD))
+ probe_container(dev, container);
+ device = scsi_device_lookup(dev->scsi_host_ptr,
+ CONTAINER_TO_CHANNEL(container),
+ CONTAINER_TO_ID(container),
+ CONTAINER_TO_LUN(container));
+ if (device) {
+ switch (device_config_needed) {
+ case DELETE:
+ scsi_remove_device(device);
+ break;
+ case CHANGE:
+ if (!dev->fsa_dev[container].valid) {
+ scsi_remove_device(device);
+ break;
+ }
+ scsi_rescan_device(&device->sdev_gendev);
+
+ default:
+ break;
+ }
+ scsi_device_put(device);
+ }
+ if (device_config_needed == ADD) {
+ scsi_add_device(dev->scsi_host_ptr,
+ CONTAINER_TO_CHANNEL(container),
+ CONTAINER_TO_ID(container),
+ CONTAINER_TO_LUN(container));
+ }
+
+}
+
/**
* aac_command_thread - command processing thread
* @dev: Adapter to monitor
@@ -805,7 +1019,6 @@ int aac_command_thread(struct aac_dev * dev)
{
struct hw_fib *hw_fib, *hw_newfib;
struct fib *fib, *newfib;
- struct aac_queue_block *queues = dev->queues;
struct aac_fib_context *fibctx;
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
@@ -825,21 +1038,22 @@ int aac_command_thread(struct aac_dev * dev)
* Let the DPC know it has a place to send the AIF's to.
*/
dev->aif_thread = 1;
- add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
+ add_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
set_current_state(TASK_INTERRUPTIBLE);
+ dprintk ((KERN_INFO "aac_command_thread start\n"));
while(1)
{
- spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
- while(!list_empty(&(queues->queue[HostNormCmdQueue].cmdq))) {
+ spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
+ while(!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {
struct list_head *entry;
struct aac_aifcmd * aifcmd;
set_current_state(TASK_RUNNING);
-
- entry = queues->queue[HostNormCmdQueue].cmdq.next;
+
+ entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
list_del(entry);
-
- spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
+
+ spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
fib = list_entry(entry, struct fib, fiblink);
/*
* We will process the FIB here or pass it to a
@@ -860,6 +1074,7 @@ int aac_command_thread(struct aac_dev * dev)
aifcmd = (struct aac_aifcmd *) hw_fib->data;
if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
/* Handle Driver Notify Events */
+ aac_handle_aif(dev, fib);
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
fib_adapter_complete(fib, (u16)sizeof(u32));
} else {
@@ -869,9 +1084,62 @@ int aac_command_thread(struct aac_dev * dev)
u32 time_now, time_last;
unsigned long flagv;
-
+ unsigned num;
+ struct hw_fib ** hw_fib_pool, ** hw_fib_p;
+ struct fib ** fib_pool, ** fib_p;
+
+ /* Sniff events */
+ if ((aifcmd->command ==
+ cpu_to_le32(AifCmdEventNotify)) ||
+ (aifcmd->command ==
+ cpu_to_le32(AifCmdJobProgress))) {
+ aac_handle_aif(dev, fib);
+ }
+
time_now = jiffies/HZ;
+ /*
+ * Warning: no sleep allowed while
+ * holding spinlock. We take the estimate
+ * and pre-allocate a set of fibs outside the
+ * lock.
+ */
+ num = le32_to_cpu(dev->init->AdapterFibsSize)
+ / sizeof(struct hw_fib); /* some extra */
+ spin_lock_irqsave(&dev->fib_lock, flagv);
+ entry = dev->fib_list.next;
+ while (entry != &dev->fib_list) {
+ entry = entry->next;
+ ++num;
+ }
+ spin_unlock_irqrestore(&dev->fib_lock, flagv);
+ hw_fib_pool = NULL;
+ fib_pool = NULL;
+ if (num
+ && ((hw_fib_pool = kmalloc(sizeof(struct hw_fib *) * num, GFP_KERNEL)))
+ && ((fib_pool = kmalloc(sizeof(struct fib *) * num, GFP_KERNEL)))) {
+ hw_fib_p = hw_fib_pool;
+ fib_p = fib_pool;
+ while (hw_fib_p < &hw_fib_pool[num]) {
+ if (!(*(hw_fib_p++) = kmalloc(sizeof(struct hw_fib), GFP_KERNEL))) {
+ --hw_fib_p;
+ break;
+ }
+ if (!(*(fib_p++) = kmalloc(sizeof(struct fib), GFP_KERNEL))) {
+ kfree(*(--hw_fib_p));
+ break;
+ }
+ }
+ if ((num = hw_fib_p - hw_fib_pool) == 0) {
+ kfree(fib_pool);
+ fib_pool = NULL;
+ kfree(hw_fib_pool);
+ hw_fib_pool = NULL;
+ }
+ } else if (hw_fib_pool) {
+ kfree(hw_fib_pool);
+ hw_fib_pool = NULL;
+ }
spin_lock_irqsave(&dev->fib_lock, flagv);
entry = dev->fib_list.next;
/*
@@ -880,6 +1148,8 @@ int aac_command_thread(struct aac_dev * dev)
* fib, and then set the event to wake up the
* thread that is waiting for it.
*/
+ hw_fib_p = hw_fib_pool;
+ fib_p = fib_pool;
while (entry != &dev->fib_list) {
/*
* Extract the fibctx
@@ -912,9 +1182,11 @@ int aac_command_thread(struct aac_dev * dev)
* Warning: no sleep allowed while
* holding spinlock
*/
- hw_newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
- newfib = kmalloc(sizeof(struct fib), GFP_ATOMIC);
- if (newfib && hw_newfib) {
+ if (hw_fib_p < &hw_fib_pool[num]) {
+ hw_newfib = *hw_fib_p;
+ *(hw_fib_p++) = NULL;
+ newfib = *fib_p;
+ *(fib_p++) = NULL;
/*
* Make the copy of the FIB
*/
@@ -929,15 +1201,11 @@ int aac_command_thread(struct aac_dev * dev)
fibctx->count++;
/*
* Set the event to wake up the
- * thread that will waiting.
+ * thread that is waiting.
*/
up(&fibctx->wait_sem);
} else {
printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
- if(newfib)
- kfree(newfib);
- if(hw_newfib)
- kfree(hw_newfib);
}
entry = entry->next;
}
@@ -947,21 +1215,38 @@ int aac_command_thread(struct aac_dev * dev)
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
fib_adapter_complete(fib, sizeof(u32));
spin_unlock_irqrestore(&dev->fib_lock, flagv);
+ /* Free up the remaining resources */
+ hw_fib_p = hw_fib_pool;
+ fib_p = fib_pool;
+ while (hw_fib_p < &hw_fib_pool[num]) {
+ if (*hw_fib_p)
+ kfree(*hw_fib_p);
+ if (*fib_p)
+ kfree(*fib_p);
+ ++fib_p;
+ ++hw_fib_p;
+ }
+ if (hw_fib_pool)
+ kfree(hw_fib_pool);
+ if (fib_pool)
+ kfree(fib_pool);
}
- spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
kfree(fib);
+ spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
}
/*
* There are no more AIF's
*/
- spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
+ spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
schedule();
if(signal_pending(current))
break;
set_current_state(TASK_INTERRUPTIBLE);
}
- remove_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
+ if (dev->queues)
+ remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
dev->aif_thread = 0;
complete_and_exit(&dev->aif_completion, 0);
+ return 0;
}
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 7a25dab48a9e..c235d0c0e7a7 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -453,9 +453,9 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
/*
* We can exit If all the commands are complete
*/
+ spin_unlock_irq(host->host_lock);
if (active == 0)
return SUCCESS;
- spin_unlock_irq(host->host_lock);
ssleep(1);
spin_lock_irq(host->host_lock);
}
@@ -748,7 +748,8 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
unique_id++;
}
- if (pci_enable_device(pdev))
+ error = pci_enable_device(pdev);
+ if (error)
goto out;
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
@@ -772,6 +773,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
shost->irq = pdev->irq;
shost->base = pci_resource_start(pdev, 0);
shost->unique_id = unique_id;
+ shost->max_cmd_len = 16;
aac = (struct aac_dev *)shost->hostdata;
aac->scsi_host_ptr = shost;
@@ -799,7 +801,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
goto out_deinit;
aac->maximum_num_channels = aac_drivers[index].channels;
- aac_get_adapter_info(aac);
+ error = aac_get_adapter_info(aac);
+ if (error < 0)
+ goto out_deinit;
/*
* Lets override negotiations and drop the maximum SG limit to 34
@@ -927,8 +931,8 @@ static int __init aac_init(void)
printk(KERN_INFO "Adaptec %s driver (%s)\n",
AAC_DRIVERNAME, aac_driver_version);
- error = pci_module_init(&aac_pci_driver);
- if (error)
+ error = pci_register_driver(&aac_pci_driver);
+ if (error < 0)
return error;
aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops);
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 320df6cd3def..fe8187d6f58b 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -216,7 +216,7 @@ static Scsi_Host_Template ahci_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations ahci_ops = {
+static const struct ata_port_operations ahci_ops = {
.port_disable = ata_port_disable,
.check_status = ahci_check_status,
@@ -407,7 +407,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
return 0xffffffffU;
}
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -425,7 +425,7 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
return;
}
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void ahci_phy_reset(struct ata_port *ap)
@@ -453,14 +453,14 @@ static void ahci_phy_reset(struct ata_port *ap)
static u8 ahci_check_status(struct ata_port *ap)
{
- void *mmio = (void *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
return readl(mmio + PORT_TFDATA) & 0xFF;
}
static u8 ahci_check_err(struct ata_port *ap)
{
- void *mmio = (void *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
}
@@ -672,17 +672,36 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap;
- u32 tmp;
- VPRINTK("port %u\n", i);
+ if (!(irq_stat & (1 << i)))
+ continue;
+
ap = host_set->ports[i];
- tmp = irq_stat & (1 << i);
- if (tmp && ap) {
+ if (ap) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
- if (ahci_host_intr(ap, qc))
- irq_ack |= (1 << i);
+ if (!ahci_host_intr(ap, qc))
+ if (ata_ratelimit()) {
+ struct pci_dev *pdev =
+ to_pci_dev(ap->host_set->dev);
+ printk(KERN_WARNING
+ "ahci(%s): unhandled interrupt on port %u\n",
+ pci_name(pdev), i);
+ }
+
+ VPRINTK("port %u\n", i);
+ } else {
+ VPRINTK("port %u (no irq)\n", i);
+ if (ata_ratelimit()) {
+ struct pci_dev *pdev =
+ to_pci_dev(ap->host_set->dev);
+ printk(KERN_WARNING
+ "ahci(%s): interrupt on disabled port %u\n",
+ pci_name(pdev), i);
+ }
}
+
+ irq_ack |= (1 << i);
}
if (irq_ack) {
@@ -865,22 +884,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/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
index 70c5fb59c9ea..d754b3267863 100644
--- a/drivers/scsi/aic7xxx/aic7770_osm.c
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c
@@ -112,6 +112,9 @@ aic7770_remove(struct device *dev)
struct ahc_softc *ahc = dev_get_drvdata(dev);
u_long s;
+ if (ahc->platform_data && ahc->platform_data->host)
+ scsi_remove_host(ahc->platform_data->host);
+
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 6b6d4e287793..95c285cc83e4 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1192,11 +1192,6 @@ ahd_platform_free(struct ahd_softc *ahd)
int i, j;
if (ahd->platform_data != NULL) {
- if (ahd->platform_data->host != NULL) {
- scsi_remove_host(ahd->platform_data->host);
- scsi_host_put(ahd->platform_data->host);
- }
-
/* destroy all of the device and target objects */
for (i = 0; i < AHD_NUM_TARGETS; i++) {
starget = ahd->platform_data->starget[i];
@@ -1226,6 +1221,9 @@ ahd_platform_free(struct ahd_softc *ahd)
release_mem_region(ahd->platform_data->mem_busaddr,
0x1000);
}
+ if (ahd->platform_data->host)
+ scsi_host_put(ahd->platform_data->host);
+
free(ahd->platform_data, M_DEVBUF);
}
}
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 390b53852d4b..bf360ae021ab 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -95,6 +95,9 @@ ahd_linux_pci_dev_remove(struct pci_dev *pdev)
struct ahd_softc *ahd = pci_get_drvdata(pdev);
u_long s;
+ if (ahd->platform_data && ahd->platform_data->host)
+ scsi_remove_host(ahd->platform_data->host);
+
ahd_lock(ahd, &s);
ahd_intr_enable(ahd, FALSE);
ahd_unlock(ahd, &s);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index c932b3b94490..6ee1435d37fa 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1109,15 +1109,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
return (0);
}
-uint64_t
-ahc_linux_get_memsize(void)
-{
- struct sysinfo si;
-
- si_meminfo(&si);
- return ((uint64_t)si.totalram << PAGE_SHIFT);
-}
-
/*
* Place the SCSI bus into a known state by either resetting it,
* or forcing transfer negotiations on the next command to any
@@ -1218,11 +1209,6 @@ ahc_platform_free(struct ahc_softc *ahc)
int i, j;
if (ahc->platform_data != NULL) {
- if (ahc->platform_data->host != NULL) {
- scsi_remove_host(ahc->platform_data->host);
- scsi_host_put(ahc->platform_data->host);
- }
-
/* destroy all of the device and target objects */
for (i = 0; i < AHC_NUM_TARGETS; i++) {
starget = ahc->platform_data->starget[i];
@@ -1251,6 +1237,9 @@ ahc_platform_free(struct ahc_softc *ahc)
0x1000);
}
+ if (ahc->platform_data->host)
+ scsi_host_put(ahc->platform_data->host);
+
free(ahc->platform_data, M_DEVBUF);
}
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index c52996269240..be9edbe26dbe 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -494,8 +494,6 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
int ahc_linux_register_host(struct ahc_softc *,
struct scsi_host_template *);
-uint64_t ahc_linux_get_memsize(void);
-
/*************************** Pretty Printing **********************************/
struct info_str {
char *buffer;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index 0d44a6907dd2..cb30d9c1153d 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -143,6 +143,9 @@ ahc_linux_pci_dev_remove(struct pci_dev *pdev)
struct ahc_softc *ahc = pci_get_drvdata(pdev);
u_long s;
+ if (ahc->platform_data && ahc->platform_data->host)
+ scsi_remove_host(ahc->platform_data->host);
+
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
@@ -180,6 +183,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ahc_pci_identity *entry;
char *name;
int error;
+ struct device *dev = &pdev->dev;
pci = pdev;
entry = ahc_find_pci_device(pci);
@@ -209,11 +213,12 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
if (sizeof(dma_addr_t) > 4
- && ahc_linux_get_memsize() > 0x80000000
- && pci_set_dma_mask(pdev, mask_39bit) == 0) {
+ && ahc->features & AHC_LARGE_SCBS
+ && dma_set_mask(dev, mask_39bit) == 0
+ && dma_get_required_mask(dev) > DMA_32BIT_MASK) {
ahc->flags |= AHC_39BIT_ADDRESSING;
} else {
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (dma_set_mask(dev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
return (-ENODEV);
}
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index deec0cef88d9..be021478f416 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),
@@ -147,7 +147,7 @@ static Scsi_Host_Template piix_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations piix_pata_ops = {
+static const struct ata_port_operations piix_pata_ops = {
.port_disable = ata_port_disable,
.set_piomode = piix_set_piomode,
.set_dmamode = piix_set_dmamode,
@@ -177,7 +177,7 @@ static struct ata_port_operations piix_pata_ops = {
.host_stop = ata_host_stop,
};
-static struct ata_port_operations piix_sata_ops = {
+static const struct ata_port_operations piix_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -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))
@@ -440,7 +442,6 @@ static void piix_sata_phy_reset(struct ata_port *ap)
* piix_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
* @adev: um
- * @pio: PIO mode, 0 - 4
*
* Set PIO mode for device, in host controller PCI config space.
*
@@ -566,18 +567,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 +664,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/atp870u.c b/drivers/scsi/atp870u.c
index e6153fe5842a..a8cfbef304b5 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -996,6 +996,7 @@ oktosend:
#ifdef ED_DBGP
printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
#endif
+ dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
outl(dev->id[c][target_id].prdaddr, tmpcip);
tmpcip = tmpcip - 2;
outb(0x06, tmpcip);
@@ -2572,7 +2573,7 @@ static void atp870u_free_tables(struct Scsi_Host *host)
for (k = 0; k < 16; k++) {
if (!atp_dev->id[j][k].prd_table)
continue;
- pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr);
+ pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
atp_dev->id[j][k].prd_table = NULL;
}
}
@@ -2584,12 +2585,13 @@ static int atp870u_init_tables(struct Scsi_Host *host)
int c,k;
for(c=0;c < 2;c++) {
for(k=0;k<16;k++) {
- atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr));
+ atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
if (!atp_dev->id[c][k].prd_table) {
printk("atp870u_init_tables fail\n");
atp870u_free_tables(host);
return -ENOMEM;
}
+ atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
atp_dev->id[c][k].devsp=0x20;
atp_dev->id[c][k].devtype = 0x7f;
atp_dev->id[c][k].curr_req = NULL;
diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h
index 89f43af39cf2..62bae64a01c1 100644
--- a/drivers/scsi/atp870u.h
+++ b/drivers/scsi/atp870u.h
@@ -54,8 +54,9 @@ struct atp_unit
unsigned long tran_len;
unsigned long last_len;
unsigned char *prd_pos;
- unsigned char *prd_table;
- dma_addr_t prdaddr;
+ unsigned char *prd_table; /* Kernel address of PRD table */
+ dma_addr_t prd_bus; /* Bus address of PRD */
+ dma_addr_t prdaddr; /* Dynamically updated in driver */
struct scsi_cmnd *curr_req;
} id[2][16];
struct Scsi_Host *host;
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index bd0e1b6be1ea..da6e51c7fe69 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 =
@@ -560,7 +560,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem,
return result;
}
-static int ch_gstatus(scsi_changer *ch, int type, unsigned char *dest)
+static int ch_gstatus(scsi_changer *ch, int type, unsigned char __user *dest)
{
int retval = 0;
u_char data[16];
@@ -634,6 +634,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
{
scsi_changer *ch = file->private_data;
int retval;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case CHIOGPARAMS:
@@ -646,7 +647,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
params.cp_nportals = ch->counts[CHET_IE];
params.cp_ndrives = ch->counts[CHET_DT];
- if (copy_to_user((void *) arg, &params, sizeof(params)))
+ if (copy_to_user(argp, &params, sizeof(params)))
return -EFAULT;
return 0;
}
@@ -671,7 +672,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
vparams.cvp_n4 = ch->counts[CHET_V4];
strncpy(vparams.cvp_label4,vendor_labels[3],16);
}
- if (copy_to_user((void *) arg, &vparams, sizeof(vparams)))
+ if (copy_to_user(argp, &vparams, sizeof(vparams)))
return -EFAULT;
return 0;
}
@@ -680,7 +681,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
{
struct changer_position pos;
- if (copy_from_user(&pos, (void*)arg, sizeof (pos)))
+ if (copy_from_user(&pos, argp, sizeof (pos)))
return -EFAULT;
if (0 != ch_checkrange(ch, pos.cp_type, pos.cp_unit)) {
@@ -699,7 +700,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
{
struct changer_move mv;
- if (copy_from_user(&mv, (void*)arg, sizeof (mv)))
+ if (copy_from_user(&mv, argp, sizeof (mv)))
return -EFAULT;
if (0 != ch_checkrange(ch, mv.cm_fromtype, mv.cm_fromunit) ||
@@ -721,7 +722,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
{
struct changer_exchange mv;
- if (copy_from_user(&mv, (void*)arg, sizeof (mv)))
+ if (copy_from_user(&mv, argp, sizeof (mv)))
return -EFAULT;
if (0 != ch_checkrange(ch, mv.ce_srctype, mv.ce_srcunit ) ||
@@ -746,7 +747,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
{
struct changer_element_status ces;
- if (copy_from_user(&ces, (void*)arg, sizeof (ces)))
+ if (copy_from_user(&ces, argp, sizeof (ces)))
return -EFAULT;
if (ces.ces_type < 0 || ces.ces_type >= CH_TYPES)
return -EINVAL;
@@ -762,7 +763,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
unsigned int elem;
int result,i;
- if (copy_from_user(&cge, (void*)arg, sizeof (cge)))
+ if (copy_from_user(&cge, argp, sizeof (cge)))
return -EFAULT;
if (0 != ch_checkrange(ch, cge.cge_type, cge.cge_unit))
@@ -825,7 +826,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
kfree(buffer);
up(&ch->lock);
- if (copy_to_user((void*)arg, &cge, sizeof (cge)))
+ if (copy_to_user(argp, &cge, sizeof (cge)))
return -EFAULT;
return result;
}
@@ -843,7 +844,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
struct changer_set_voltag csv;
int elem;
- if (copy_from_user(&csv, (void*)arg, sizeof(csv)))
+ if (copy_from_user(&csv, argp, sizeof(csv)))
return -EFAULT;
if (0 != ch_checkrange(ch, csv.csv_type, csv.csv_unit)) {
@@ -861,7 +862,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
}
default:
- return scsi_ioctl(ch->device, cmd, (void*)arg);
+ return scsi_ioctl(ch->device, cmd, argp);
}
}
@@ -894,9 +895,9 @@ static long ch_ioctl_compat(struct file * file,
case CHIOGSTATUS32:
{
struct changer_element_status32 ces32;
- unsigned char *data;
+ unsigned char __user *data;
- if (copy_from_user(&ces32, (void*)arg, sizeof (ces32)))
+ if (copy_from_user(&ces32, (void __user *)arg, sizeof (ces32)))
return -EFAULT;
if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES)
return -EINVAL;
diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
index d72be0ce89c8..3fda8d455c5b 100644
--- a/drivers/scsi/cpqfcTSinit.c
+++ b/drivers/scsi/cpqfcTSinit.c
@@ -691,8 +691,7 @@ int cpqfcTS_ioctl( struct scsi_device *ScsiDev, int Cmnd, void *arg)
if( copy_to_user( vendor_cmd->bufp, buf, vendor_cmd->len))
result = -EFAULT;
- if( buf)
- kfree( buf);
+ kfree(buf);
return result;
}
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index c10e45b94b62..3d13fdee4fc2 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1357,7 +1357,7 @@ static int port_detect(unsigned long port_base, unsigned int j,
for (i = 0; i < shost->can_queue; i++) {
size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
- unsigned int gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
+ gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
ha->cp[i].sglist = kmalloc(sz, gfp_mask);
if (!ha->cp[i].sglist) {
printk
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index fa652f8aa643..d59d449a9e4d 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -1360,3 +1360,5 @@ static Scsi_Host_Template driver_template = {
.use_clustering = DISABLE_CLUSTERING,
};
#include "scsi_module.c"
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 85503fad789a..f24d84538fd5 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -98,6 +98,7 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
switch (oldstate) {
case SHOST_CREATED:
case SHOST_RUNNING:
+ case SHOST_CANCEL_RECOVERY:
break;
default:
goto illegal;
@@ -107,12 +108,31 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
case SHOST_DEL:
switch (oldstate) {
case SHOST_CANCEL:
+ case SHOST_DEL_RECOVERY:
break;
default:
goto illegal;
}
break;
+ case SHOST_CANCEL_RECOVERY:
+ switch (oldstate) {
+ case SHOST_CANCEL:
+ case SHOST_RECOVERY:
+ break;
+ default:
+ goto illegal;
+ }
+ break;
+
+ case SHOST_DEL_RECOVERY:
+ switch (oldstate) {
+ case SHOST_CANCEL_RECOVERY:
+ break;
+ default:
+ goto illegal;
+ }
+ break;
}
shost->shost_state = state;
return 0;
@@ -134,17 +154,29 @@ EXPORT_SYMBOL(scsi_host_set_state);
**/
void scsi_remove_host(struct Scsi_Host *shost)
{
+ unsigned long flags;
down(&shost->scan_mutex);
- scsi_host_set_state(shost, SHOST_CANCEL);
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (scsi_host_set_state(shost, SHOST_CANCEL))
+ if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ up(&shost->scan_mutex);
+ return;
+ }
+ spin_unlock_irqrestore(shost->host_lock, flags);
up(&shost->scan_mutex);
scsi_forget_host(shost);
scsi_proc_host_rm(shost);
- scsi_host_set_state(shost, SHOST_DEL);
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (scsi_host_set_state(shost, SHOST_DEL))
+ BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));
+ spin_unlock_irqrestore(shost->host_lock, flags);
transport_unregister_device(&shost->shost_gendev);
class_device_unregister(&shost->shost_classdev);
device_del(&shost->shost_gendev);
+ scsi_proc_hostdir_rm(shost->hostt);
}
EXPORT_SYMBOL(scsi_remove_host);
@@ -231,7 +263,6 @@ static void scsi_host_dev_release(struct device *dev)
if (shost->work_q)
destroy_workqueue(shost->work_q);
- scsi_proc_hostdir_rm(shost->hostt);
scsi_destroy_command_freelist(shost);
kfree(shost->shost_data);
@@ -256,7 +287,8 @@ static void scsi_host_dev_release(struct device *dev)
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
{
struct Scsi_Host *shost;
- int gfp_mask = GFP_KERNEL, rval;
+ gfp_t gfp_mask = GFP_KERNEL;
+ int rval;
if (sht->unchecked_isa_dma && privsize)
gfp_mask |= __GFP_DMA;
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index b5dc35355570..19392f651272 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -36,7 +36,6 @@
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/mca.h>
-#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/mca-legacy.h>
@@ -461,6 +460,8 @@ MODULE_PARM(adisplay, "1i");
MODULE_PARM(normal, "1i");
MODULE_PARM(ansi, "1i");
#endif
+
+MODULE_LICENSE("GPL");
#endif
/*counter of concurrent disk read/writes, to turn on/off disk led */
static int disk_rw_in_progress = 0;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 5b14934ba861..ff25210b00ba 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -727,6 +727,16 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct)
if (hostdata->madapter_info.port_max_txu[0])
hostdata->host->max_sectors =
hostdata->madapter_info.port_max_txu[0] >> 9;
+
+ if (hostdata->madapter_info.os_type == 3 &&
+ strcmp(hostdata->madapter_info.srp_version, "1.6a") <= 0) {
+ printk("ibmvscsi: host (Ver. %s) doesn't support large"
+ "transfers\n",
+ hostdata->madapter_info.srp_version);
+ printk("ibmvscsi: limiting scatterlists to %d\n",
+ MAX_INDIRECT_BUFS);
+ hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS;
+ }
}
}
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 5cc53cd9323e..f53d7b8ac33f 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -48,6 +48,7 @@
#include <linux/completion.h>
#include <linux/suspend.h>
#include <linux/workqueue.h>
+#include <linux/jiffies.h>
#include <scsi/scsi.h>
#include "scsi.h"
#include "scsi_priv.h"
@@ -62,14 +63,15 @@
static unsigned int ata_busy_sleep (struct ata_port *ap,
unsigned long tmout_pat,
unsigned long tmout);
+static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
+static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
-static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
+static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift);
static int fgb(u32 bitmap);
-static int ata_choose_xfer_mode(struct ata_port *ap,
+static int ata_choose_xfer_mode(const struct ata_port *ap,
u8 *xfer_mode_out,
unsigned int *xfer_shift_out);
-static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
static void __ata_qc_complete(struct ata_queued_cmd *qc);
static unsigned int ata_unique_id = 1;
@@ -85,7 +87,7 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
/**
- * ata_tf_load - send taskfile registers to host controller
+ * ata_tf_load_pio - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
*
@@ -95,7 +97,7 @@ MODULE_VERSION(DRV_VERSION);
* Inherited from caller.
*/
-static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -153,7 +155,7 @@ static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
* Inherited from caller.
*/
-static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -222,7 +224,7 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
* LOCKING:
* Inherited from caller.
*/
-void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
ata_tf_load_mmio(ap, tf);
@@ -242,7 +244,7 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
* spin_lock_irqsave(host_set lock)
*/
-static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
@@ -263,7 +265,7 @@ static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
* spin_lock_irqsave(host_set lock)
*/
-static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
@@ -283,7 +285,7 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
ata_exec_command_mmio(ap, tf);
@@ -303,7 +305,7 @@ void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
* Obtains host_set lock.
*/
-static inline void ata_exec(struct ata_port *ap, struct ata_taskfile *tf)
+static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
{
unsigned long flags;
@@ -326,7 +328,7 @@ static inline void ata_exec(struct ata_port *ap, struct ata_taskfile *tf)
* Obtains host_set lock.
*/
-static void ata_tf_to_host(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_tf_to_host(struct ata_port *ap, const struct ata_taskfile *tf)
{
ap->ops->tf_load(ap, tf);
@@ -346,7 +348,7 @@ static void ata_tf_to_host(struct ata_port *ap, struct ata_taskfile *tf)
* spin_lock_irqsave(host_set lock)
*/
-void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf)
{
ap->ops->tf_load(ap, tf);
ap->ops->exec_command(ap, tf);
@@ -556,7 +558,7 @@ u8 ata_chk_err(struct ata_port *ap)
* Inherited from caller.
*/
-void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp)
+void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp)
{
fis[0] = 0x27; /* Register - Host to Device FIS */
fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number,
@@ -597,7 +599,7 @@ void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp)
* Inherited from caller.
*/
-void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
+void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
{
tf->command = fis[2]; /* status */
tf->feature = fis[3]; /* error */
@@ -615,79 +617,53 @@ void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
tf->hob_nsect = fis[13];
}
-/**
- * ata_prot_to_cmd - determine which read/write opcodes to use
- * @protocol: ATA_PROT_xxx taskfile protocol
- * @lba48: true is lba48 is present
- *
- * Given necessary input, determine which read/write commands
- * to use to transfer data.
- *
- * LOCKING:
- * None.
- */
-static int ata_prot_to_cmd(int protocol, int lba48)
-{
- int rcmd = 0, wcmd = 0;
-
- switch (protocol) {
- case ATA_PROT_PIO:
- if (lba48) {
- rcmd = ATA_CMD_PIO_READ_EXT;
- wcmd = ATA_CMD_PIO_WRITE_EXT;
- } else {
- rcmd = ATA_CMD_PIO_READ;
- wcmd = ATA_CMD_PIO_WRITE;
- }
- break;
-
- case ATA_PROT_DMA:
- if (lba48) {
- rcmd = ATA_CMD_READ_EXT;
- wcmd = ATA_CMD_WRITE_EXT;
- } else {
- rcmd = ATA_CMD_READ;
- wcmd = ATA_CMD_WRITE;
- }
- break;
-
- default:
- return -1;
- }
-
- return rcmd | (wcmd << 8);
-}
+static const u8 ata_rw_cmds[] = {
+ /* pio multi */
+ ATA_CMD_READ_MULTI,
+ ATA_CMD_WRITE_MULTI,
+ ATA_CMD_READ_MULTI_EXT,
+ ATA_CMD_WRITE_MULTI_EXT,
+ /* pio */
+ ATA_CMD_PIO_READ,
+ ATA_CMD_PIO_WRITE,
+ ATA_CMD_PIO_READ_EXT,
+ ATA_CMD_PIO_WRITE_EXT,
+ /* dma */
+ ATA_CMD_READ,
+ ATA_CMD_WRITE,
+ ATA_CMD_READ_EXT,
+ ATA_CMD_WRITE_EXT
+};
/**
- * ata_dev_set_protocol - set taskfile protocol and r/w commands
- * @dev: device to examine and configure
+ * ata_rwcmd_protocol - set taskfile r/w commands and protocol
+ * @qc: command to examine and configure
*
- * Examine the device configuration, after we have
- * read the identify-device page and configured the
- * data transfer mode. Set internal state related to
- * the ATA taskfile protocol (pio, pio mult, dma, etc.)
- * and calculate the proper read/write commands to use.
+ * Examine the device configuration and tf->flags to calculate
+ * the proper read/write commands and protocol to use.
*
* LOCKING:
* caller.
*/
-static void ata_dev_set_protocol(struct ata_device *dev)
+void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
{
- int pio = (dev->flags & ATA_DFLAG_PIO);
- int lba48 = (dev->flags & ATA_DFLAG_LBA48);
- int proto, cmd;
+ struct ata_taskfile *tf = &qc->tf;
+ struct ata_device *dev = qc->dev;
- if (pio)
- proto = dev->xfer_protocol = ATA_PROT_PIO;
- else
- proto = dev->xfer_protocol = ATA_PROT_DMA;
+ int index, lba48, write;
+
+ lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
+ write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
- cmd = ata_prot_to_cmd(proto, lba48);
- if (cmd < 0)
- BUG();
+ if (dev->flags & ATA_DFLAG_PIO) {
+ tf->protocol = ATA_PROT_PIO;
+ index = dev->multi_count ? 0 : 4;
+ } else {
+ tf->protocol = ATA_PROT_DMA;
+ index = 8;
+ }
- dev->read_cmd = cmd & 0xff;
- dev->write_cmd = (cmd >> 8) & 0xff;
+ tf->command = ata_rw_cmds[index + lba48 + write];
}
static const char * xfer_mode_str[] = {
@@ -869,7 +845,7 @@ static unsigned int ata_devchk(struct ata_port *ap,
* the event of failure.
*/
-unsigned int ata_dev_classify(struct ata_taskfile *tf)
+unsigned int ata_dev_classify(const struct ata_taskfile *tf)
{
/* Apple's open source Darwin code hints that some devices only
* put a proper signature into the LBA mid/high registers,
@@ -961,7 +937,7 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
* caller.
*/
-void ata_dev_id_string(u16 *id, unsigned char *s,
+void ata_dev_id_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len)
{
unsigned int c;
@@ -1078,7 +1054,7 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
* caller.
*/
-static inline void ata_dump_id(struct ata_device *dev)
+static inline void ata_dump_id(const struct ata_device *dev)
{
DPRINTK("49==0x%04x "
"53==0x%04x "
@@ -1106,6 +1082,31 @@ static inline void ata_dump_id(struct ata_device *dev)
dev->id[93]);
}
+/*
+ * Compute the PIO modes available for this device. This is not as
+ * trivial as it seems if we must consider early devices correctly.
+ *
+ * FIXME: pre IDE drive timing (do we care ?).
+ */
+
+static unsigned int ata_pio_modes(const struct ata_device *adev)
+{
+ u16 modes;
+
+ /* Usual case. Word 53 indicates word 88 is valid */
+ if (adev->id[ATA_ID_FIELD_VALID] & (1 << 2)) {
+ modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
+ modes <<= 3;
+ modes |= 0x7;
+ return modes;
+ }
+
+ /* If word 88 isn't valid then Word 51 holds the PIO timing number
+ for the maximum. Turn it into a mask and return it */
+ modes = (2 << (adev->id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+ return modes;
+}
+
/**
* ata_dev_identify - obtain IDENTIFY x DEVICE page
* @ap: port on which device we wish to probe resides
@@ -1131,7 +1132,7 @@ static inline void ata_dump_id(struct ata_device *dev)
static void ata_dev_identify(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
- unsigned int i;
+ unsigned int major_version;
u16 tmp;
unsigned long xfer_modes;
u8 status;
@@ -1229,9 +1230,9 @@ retry:
* common ATA, ATAPI feature tests
*/
- /* we require LBA and DMA support (bits 8 & 9 of word 49) */
- if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
- printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
+ /* we require DMA support (bits 8 of word 49) */
+ if (!ata_id_has_dma(dev->id)) {
+ printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
goto err_out_nosup;
}
@@ -1239,10 +1240,8 @@ retry:
xfer_modes = dev->id[ATA_ID_UDMA_MODES];
if (!xfer_modes)
xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
- if (!xfer_modes) {
- xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
- xfer_modes |= (0x7 << ATA_SHIFT_PIO);
- }
+ if (!xfer_modes)
+ xfer_modes = ata_pio_modes(dev);
ata_dump_id(dev);
@@ -1251,32 +1250,75 @@ retry:
if (!ata_id_is_ata(dev->id)) /* sanity check */
goto err_out_nosup;
+ /* get major version */
tmp = dev->id[ATA_ID_MAJOR_VER];
- for (i = 14; i >= 1; i--)
- if (tmp & (1 << i))
+ for (major_version = 14; major_version >= 1; major_version--)
+ if (tmp & (1 << major_version))
break;
- /* we require at least ATA-3 */
- if (i < 3) {
- printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
- goto err_out_nosup;
+ /*
+ * The exact sequence expected by certain pre-ATA4 drives is:
+ * SRST RESET
+ * IDENTIFY
+ * INITIALIZE DEVICE PARAMETERS
+ * anything else..
+ * Some drives were very specific about that exact sequence.
+ */
+ if (major_version < 4 || (!ata_id_has_lba(dev->id))) {
+ ata_dev_init_params(ap, dev);
+
+ /* current CHS translation info (id[53-58]) might be
+ * changed. reread the identify device info.
+ */
+ ata_dev_reread_id(ap, dev);
}
- if (ata_id_has_lba48(dev->id)) {
- dev->flags |= ATA_DFLAG_LBA48;
- dev->n_sectors = ata_id_u64(dev->id, 100);
- } else {
- dev->n_sectors = ata_id_u32(dev->id, 60);
+ if (ata_id_has_lba(dev->id)) {
+ dev->flags |= ATA_DFLAG_LBA;
+
+ if (ata_id_has_lba48(dev->id)) {
+ dev->flags |= ATA_DFLAG_LBA48;
+ dev->n_sectors = ata_id_u64(dev->id, 100);
+ } else {
+ dev->n_sectors = ata_id_u32(dev->id, 60);
+ }
+
+ /* print device info to dmesg */
+ printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
+ ap->id, device,
+ major_version,
+ ata_mode_string(xfer_modes),
+ (unsigned long long)dev->n_sectors,
+ dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
+ } else {
+ /* CHS */
+
+ /* Default translation */
+ dev->cylinders = dev->id[1];
+ dev->heads = dev->id[3];
+ dev->sectors = dev->id[6];
+ dev->n_sectors = dev->cylinders * dev->heads * dev->sectors;
+
+ if (ata_id_current_chs_valid(dev->id)) {
+ /* Current CHS translation is valid. */
+ dev->cylinders = dev->id[54];
+ dev->heads = dev->id[55];
+ dev->sectors = dev->id[56];
+
+ dev->n_sectors = ata_id_u32(dev->id, 57);
+ }
+
+ /* print device info to dmesg */
+ printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
+ ap->id, device,
+ major_version,
+ ata_mode_string(xfer_modes),
+ (unsigned long long)dev->n_sectors,
+ (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
+
}
ap->host->max_cmd_len = 16;
-
- /* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
- ap->id, device,
- ata_mode_string(xfer_modes),
- (unsigned long long)dev->n_sectors,
- dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
}
/* ATAPI-specific feature tests */
@@ -1310,7 +1352,7 @@ err_out:
}
-static inline u8 ata_dev_knobble(struct ata_port *ap)
+static inline u8 ata_dev_knobble(const struct ata_port *ap)
{
return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
}
@@ -1496,7 +1538,153 @@ void ata_port_disable(struct ata_port *ap)
ap->flags |= ATA_FLAG_PORT_DISABLED;
}
-static struct {
+/*
+ * This mode timing computation functionality is ported over from
+ * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik
+ */
+/*
+ * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
+ * These were taken from ATA/ATAPI-6 standard, rev 0a, except
+ * for PIO 5, which is a nonstandard extension and UDMA6, which
+ * is currently supported only by Maxtor drives.
+ */
+
+static const struct ata_timing ata_timing[] = {
+
+ { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
+ { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
+ { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 },
+ { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 },
+
+ { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 },
+ { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
+ { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
+
+/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */
+
+ { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
+ { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
+ { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
+
+ { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 },
+ { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
+ { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
+
+/* { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, */
+ { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
+ { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
+
+ { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 },
+ { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 },
+ { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 },
+
+/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
+
+ { 0xFF }
+};
+
+#define ENOUGH(v,unit) (((v)-1)/(unit)+1)
+#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
+
+static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
+{
+ q->setup = EZ(t->setup * 1000, T);
+ q->act8b = EZ(t->act8b * 1000, T);
+ q->rec8b = EZ(t->rec8b * 1000, T);
+ q->cyc8b = EZ(t->cyc8b * 1000, T);
+ q->active = EZ(t->active * 1000, T);
+ q->recover = EZ(t->recover * 1000, T);
+ q->cycle = EZ(t->cycle * 1000, T);
+ q->udma = EZ(t->udma * 1000, UT);
+}
+
+void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
+ struct ata_timing *m, unsigned int what)
+{
+ if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup);
+ if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b);
+ if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b);
+ if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b);
+ if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active);
+ if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
+ if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle);
+ if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma);
+}
+
+static const struct ata_timing* ata_timing_find_mode(unsigned short speed)
+{
+ const struct ata_timing *t;
+
+ for (t = ata_timing; t->mode != speed; t++)
+ if (t->mode == 0xFF)
+ return NULL;
+ return t;
+}
+
+int ata_timing_compute(struct ata_device *adev, unsigned short speed,
+ struct ata_timing *t, int T, int UT)
+{
+ const struct ata_timing *s;
+ struct ata_timing p;
+
+ /*
+ * Find the mode.
+ */
+
+ if (!(s = ata_timing_find_mode(speed)))
+ return -EINVAL;
+
+ /*
+ * If the drive is an EIDE drive, it can tell us it needs extended
+ * PIO/MW_DMA cycle timing.
+ */
+
+ if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */
+ memset(&p, 0, sizeof(p));
+ if(speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) {
+ if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO];
+ else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY];
+ } else if(speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) {
+ p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN];
+ }
+ ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B);
+ }
+
+ /*
+ * Convert the timing to bus clock counts.
+ */
+
+ ata_timing_quantize(s, t, T, UT);
+
+ /*
+ * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
+ * and some other commands. We have to ensure that the DMA cycle timing is
+ * slower/equal than the fastest PIO timing.
+ */
+
+ if (speed > XFER_PIO_4) {
+ ata_timing_compute(adev, adev->pio_mode, &p, T, UT);
+ ata_timing_merge(&p, t, t, ATA_TIMING_ALL);
+ }
+
+ /*
+ * Lenghten active & recovery time so that cycle time is correct.
+ */
+
+ if (t->act8b + t->rec8b < t->cyc8b) {
+ t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
+ t->rec8b = t->cyc8b - t->act8b;
+ }
+
+ if (t->active + t->recover < t->cycle) {
+ t->active += (t->cycle - (t->active + t->recover)) / 2;
+ t->recover = t->cycle - t->active;
+ }
+
+ return 0;
+}
+
+static const struct {
unsigned int shift;
u8 base;
} xfer_mode_classes[] = {
@@ -1603,7 +1791,7 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
*/
static void ata_set_mode(struct ata_port *ap)
{
- unsigned int i, xfer_shift;
+ unsigned int xfer_shift;
u8 xfer_mode;
int rc;
@@ -1632,11 +1820,6 @@ static void ata_set_mode(struct ata_port *ap)
if (ap->ops->post_set_mode)
ap->ops->post_set_mode(ap);
- for (i = 0; i < 2; i++) {
- struct ata_device *dev = &ap->device[i];
- ata_dev_set_protocol(dev);
- }
-
return;
err_out:
@@ -1910,7 +2093,8 @@ err_out:
DPRINTK("EXIT\n");
}
-static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev)
+static void ata_pr_blacklisted(const struct ata_port *ap,
+ const struct ata_device *dev)
{
printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
ap->id, dev->devno);
@@ -1948,7 +2132,7 @@ static const char * ata_dma_blacklist [] = {
"_NEC DV5800A",
};
-static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
+static int ata_dma_blacklisted(const struct ata_device *dev)
{
unsigned char model_num[40];
char *s;
@@ -1973,9 +2157,9 @@ static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
return 0;
}
-static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
+static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift)
{
- struct ata_device *master, *slave;
+ const struct ata_device *master, *slave;
unsigned int mask;
master = &ap->device[0];
@@ -1987,14 +2171,14 @@ static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
mask = ap->udma_mask;
if (ata_dev_present(master)) {
mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
- if (ata_dma_blacklisted(ap, master)) {
+ if (ata_dma_blacklisted(master)) {
mask = 0;
ata_pr_blacklisted(ap, master);
}
}
if (ata_dev_present(slave)) {
mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
- if (ata_dma_blacklisted(ap, slave)) {
+ if (ata_dma_blacklisted(slave)) {
mask = 0;
ata_pr_blacklisted(ap, slave);
}
@@ -2004,14 +2188,14 @@ static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
mask = ap->mwdma_mask;
if (ata_dev_present(master)) {
mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
- if (ata_dma_blacklisted(ap, master)) {
+ if (ata_dma_blacklisted(master)) {
mask = 0;
ata_pr_blacklisted(ap, master);
}
}
if (ata_dev_present(slave)) {
mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
- if (ata_dma_blacklisted(ap, slave)) {
+ if (ata_dma_blacklisted(slave)) {
mask = 0;
ata_pr_blacklisted(ap, slave);
}
@@ -2075,7 +2259,7 @@ static int fgb(u32 bitmap)
* Zero on success, negative on error.
*/
-static int ata_choose_xfer_mode(struct ata_port *ap,
+static int ata_choose_xfer_mode(const struct ata_port *ap,
u8 *xfer_mode_out,
unsigned int *xfer_shift_out)
{
@@ -2144,6 +2328,110 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
}
/**
+ * ata_dev_reread_id - Reread the device identify device info
+ * @ap: port where the device is
+ * @dev: device to reread the identify device info
+ *
+ * LOCKING:
+ */
+
+static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ int rc;
+
+ qc = ata_qc_new_init(ap, dev);
+ BUG_ON(qc == NULL);
+
+ ata_sg_init_one(qc, dev->id, sizeof(dev->id));
+ qc->dma_dir = DMA_FROM_DEVICE;
+
+ if (dev->class == ATA_DEV_ATA) {
+ qc->tf.command = ATA_CMD_ID_ATA;
+ DPRINTK("do ATA identify\n");
+ } else {
+ qc->tf.command = ATA_CMD_ID_ATAPI;
+ DPRINTK("do ATAPI identify\n");
+ }
+
+ qc->tf.flags |= ATA_TFLAG_DEVICE;
+ qc->tf.protocol = ATA_PROT_PIO;
+ qc->nsect = 1;
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (rc)
+ goto err_out;
+
+ wait_for_completion(&wait);
+
+ swap_buf_le16(dev->id, ATA_ID_WORDS);
+
+ ata_dump_id(dev);
+
+ DPRINTK("EXIT\n");
+
+ return;
+err_out:
+ ata_port_disable(ap);
+}
+
+/**
+ * ata_dev_init_params - Issue INIT DEV PARAMS command
+ * @ap: Port associated with device @dev
+ * @dev: Device to which command will be sent
+ *
+ * LOCKING:
+ */
+
+static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ int rc;
+ unsigned long flags;
+ u16 sectors = dev->id[6];
+ u16 heads = dev->id[3];
+
+ /* Number of sectors per track 1-255. Number of heads 1-16 */
+ if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
+ return;
+
+ /* set up init dev params taskfile */
+ DPRINTK("init dev params \n");
+
+ qc = ata_qc_new_init(ap, dev);
+ BUG_ON(qc == NULL);
+
+ qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ qc->tf.protocol = ATA_PROT_NODATA;
+ qc->tf.nsect = sectors;
+ qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (rc)
+ ata_port_disable(ap);
+ else
+ wait_for_completion(&wait);
+
+ DPRINTK("EXIT\n");
+}
+
+/**
* ata_sg_clean - Unmap DMA memory associated with command
* @qc: Command containing DMA memory to be released
*
@@ -2413,32 +2701,32 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
/**
* ata_pio_poll -
- * @ap:
+ * @ap: the target ata_port
*
* LOCKING:
* None. (executing in kernel thread context)
*
* RETURNS:
- *
+ * timeout value to use
*/
static unsigned long ata_pio_poll(struct ata_port *ap)
{
u8 status;
- unsigned int poll_state = PIO_ST_UNKNOWN;
- unsigned int reg_state = PIO_ST_UNKNOWN;
- const unsigned int tmout_state = PIO_ST_TMOUT;
-
- switch (ap->pio_task_state) {
- case PIO_ST:
- case PIO_ST_POLL:
- poll_state = PIO_ST_POLL;
- reg_state = PIO_ST;
+ unsigned int poll_state = HSM_ST_UNKNOWN;
+ unsigned int reg_state = HSM_ST_UNKNOWN;
+ const unsigned int tmout_state = HSM_ST_TMOUT;
+
+ switch (ap->hsm_task_state) {
+ case HSM_ST:
+ case HSM_ST_POLL:
+ poll_state = HSM_ST_POLL;
+ reg_state = HSM_ST;
break;
- case PIO_ST_LAST:
- case PIO_ST_LAST_POLL:
- poll_state = PIO_ST_LAST_POLL;
- reg_state = PIO_ST_LAST;
+ case HSM_ST_LAST:
+ case HSM_ST_LAST_POLL:
+ poll_state = HSM_ST_LAST_POLL;
+ reg_state = HSM_ST_LAST;
break;
default:
BUG();
@@ -2448,26 +2736,29 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
status = ata_chk_status(ap);
if (status & ATA_BUSY) {
if (time_after(jiffies, ap->pio_task_timeout)) {
- ap->pio_task_state = tmout_state;
+ ap->hsm_task_state = tmout_state;
return 0;
}
- ap->pio_task_state = poll_state;
+ ap->hsm_task_state = poll_state;
return ATA_SHORT_PAUSE;
}
- ap->pio_task_state = reg_state;
+ ap->hsm_task_state = reg_state;
return 0;
}
/**
- * ata_pio_complete -
- * @ap:
+ * ata_pio_complete - check if drive is busy or idle
+ * @ap: the target ata_port
*
* LOCKING:
* None. (executing in kernel thread context)
+ *
+ * RETURNS:
+ * Non-zero if qc completed, zero otherwise.
*/
-static void ata_pio_complete (struct ata_port *ap)
+static int ata_pio_complete (struct ata_port *ap)
{
struct ata_queued_cmd *qc;
u8 drv_stat;
@@ -2477,36 +2768,40 @@ static void ata_pio_complete (struct ata_port *ap)
* we enter, BSY will be cleared in a chk-status or two. If not,
* the drive is probably seeking or something. Snooze for a couple
* msecs, then chk-status again. If still busy, fall back to
- * PIO_ST_POLL state.
+ * HSM_ST_POLL state.
*/
drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
msleep(2);
drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
- ap->pio_task_state = PIO_ST_LAST_POLL;
+ ap->hsm_task_state = HSM_ST_LAST_POLL;
ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
- return;
+ return 0;
}
}
drv_stat = ata_wait_idle(ap);
if (!ata_ok(drv_stat)) {
- ap->pio_task_state = PIO_ST_ERR;
- return;
+ ap->hsm_task_state = HSM_ST_ERR;
+ return 0;
}
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
- ap->pio_task_state = PIO_ST_IDLE;
+ ap->hsm_task_state = HSM_ST_IDLE;
ata_poll_qc_complete(qc, drv_stat);
+
+ /* another command may start at this point */
+
+ return 1;
}
/**
- * swap_buf_le16 -
+ * swap_buf_le16 - swap halves of 16-words in place
* @buf: Buffer to swap
* @buf_words: Number of 16-bit words in buffer.
*
@@ -2515,6 +2810,7 @@ static void ata_pio_complete (struct ata_port *ap)
* vice-versa.
*
* LOCKING:
+ * Inherited from caller.
*/
void swap_buf_le16(u16 *buf, unsigned int buf_words)
{
@@ -2537,7 +2833,6 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
@@ -2583,7 +2878,6 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
@@ -2623,7 +2917,6 @@ static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
@@ -2655,7 +2948,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
unsigned char *buf;
if (qc->cursect == (qc->nsect - 1))
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
@@ -2705,11 +2998,11 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
unsigned int offset, count;
if (qc->curbytes + bytes >= qc->nbytes)
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
next_sg:
if (unlikely(qc->cursg >= qc->n_elem)) {
- /*
+ /*
* The end of qc->sg is reached and the device expects
* more data to transfer. In order not to overrun qc->sg
* and fulfill length specified in the byte count register,
@@ -2721,13 +3014,13 @@ next_sg:
unsigned int i;
if (words) /* warning if bytes > 1 */
- printk(KERN_WARNING "ata%u: %u bytes trailing data\n",
+ printk(KERN_WARNING "ata%u: %u bytes trailing data\n",
ap->id, bytes);
for (i = 0; i < words; i++)
ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
return;
}
@@ -2776,7 +3069,6 @@ next_sg:
*
* LOCKING:
* Inherited from caller.
- *
*/
static void atapi_pio_bytes(struct ata_queued_cmd *qc)
@@ -2808,12 +3100,12 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
err_out:
printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
ap->id, dev->devno);
- ap->pio_task_state = PIO_ST_ERR;
+ ap->hsm_task_state = HSM_ST_ERR;
}
/**
- * ata_pio_sector -
- * @ap:
+ * ata_pio_block - start PIO on a block
+ * @ap: the target ata_port
*
* LOCKING:
* None. (executing in kernel thread context)
@@ -2825,19 +3117,19 @@ static void ata_pio_block(struct ata_port *ap)
u8 status;
/*
- * This is purely hueristic. This is a fast path.
+ * This is purely heuristic. This is a fast path.
* Sometimes when we enter, BSY will be cleared in
* a chk-status or two. If not, the drive is probably seeking
* or something. Snooze for a couple msecs, then
* chk-status again. If still busy, fall back to
- * PIO_ST_POLL state.
+ * HSM_ST_POLL state.
*/
status = ata_busy_wait(ap, ATA_BUSY, 5);
if (status & ATA_BUSY) {
msleep(2);
status = ata_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
- ap->pio_task_state = PIO_ST_POLL;
+ ap->hsm_task_state = HSM_ST_POLL;
ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
return;
}
@@ -2849,9 +3141,7 @@ static void ata_pio_block(struct ata_port *ap)
if (is_atapi_taskfile(&qc->tf)) {
/* no more data to transfer or unsupported ATAPI command */
if ((status & ATA_DRQ) == 0) {
- ap->pio_task_state = PIO_ST_IDLE;
-
- ata_poll_qc_complete(qc, status);
+ ap->hsm_task_state = HSM_ST_LAST;
return;
}
@@ -2859,7 +3149,7 @@ static void ata_pio_block(struct ata_port *ap)
} else {
/* handle BSY=0, DRQ=0 as error */
if ((status & ATA_DRQ) == 0) {
- ap->pio_task_state = PIO_ST_ERR;
+ ap->hsm_task_state = HSM_ST_ERR;
return;
}
@@ -2879,7 +3169,7 @@ static void ata_pio_error(struct ata_port *ap)
printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
ap->id, drv_stat);
- ap->pio_task_state = PIO_ST_IDLE;
+ ap->hsm_task_state = HSM_ST_IDLE;
ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
}
@@ -2887,82 +3177,40 @@ static void ata_pio_error(struct ata_port *ap)
static void ata_pio_task(void *_data)
{
struct ata_port *ap = _data;
- unsigned long timeout = 0;
+ unsigned long timeout;
+ int qc_completed;
+
+fsm_start:
+ timeout = 0;
+ qc_completed = 0;
- switch (ap->pio_task_state) {
- case PIO_ST_IDLE:
+ switch (ap->hsm_task_state) {
+ case HSM_ST_IDLE:
return;
- case PIO_ST:
+ case HSM_ST:
ata_pio_block(ap);
break;
- case PIO_ST_LAST:
- ata_pio_complete(ap);
+ case HSM_ST_LAST:
+ qc_completed = ata_pio_complete(ap);
break;
- case PIO_ST_POLL:
- case PIO_ST_LAST_POLL:
+ case HSM_ST_POLL:
+ case HSM_ST_LAST_POLL:
timeout = ata_pio_poll(ap);
break;
- case PIO_ST_TMOUT:
- case PIO_ST_ERR:
+ case HSM_ST_TMOUT:
+ case HSM_ST_ERR:
ata_pio_error(ap);
return;
}
if (timeout)
- queue_delayed_work(ata_wq, &ap->pio_task,
- timeout);
- else
- queue_work(ata_wq, &ap->pio_task);
-}
-
-static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
- struct scsi_cmnd *cmd)
-{
- DECLARE_COMPLETION(wait);
- struct ata_queued_cmd *qc;
- unsigned long flags;
- int rc;
-
- DPRINTK("ATAPI request sense\n");
-
- qc = ata_qc_new_init(ap, dev);
- BUG_ON(qc == NULL);
-
- /* FIXME: is this needed? */
- memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
-
- ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
- qc->dma_dir = DMA_FROM_DEVICE;
-
- memset(&qc->cdb, 0, ap->cdb_len);
- qc->cdb[0] = REQUEST_SENSE;
- qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
-
- qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- qc->tf.command = ATA_CMD_PACKET;
-
- qc->tf.protocol = ATA_PROT_ATAPI;
- qc->tf.lbam = (8 * 1024) & 0xff;
- qc->tf.lbah = (8 * 1024) >> 8;
- qc->nbytes = SCSI_SENSE_BUFFERSIZE;
-
- qc->waiting = &wait;
- qc->complete_fn = ata_qc_complete_noop;
-
- spin_lock_irqsave(&ap->host_set->lock, flags);
- rc = ata_qc_issue(qc);
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
- if (rc)
- ata_port_disable(ap);
- else
- wait_for_completion(&wait);
-
- DPRINTK("EXIT\n");
+ queue_delayed_work(ata_wq, &ap->pio_task, timeout);
+ else if (!qc_completed)
+ goto fsm_start;
}
/**
@@ -3082,14 +3330,14 @@ void ata_eng_timeout(struct ata_port *ap)
DPRINTK("ENTER\n");
qc = ata_qc_from_tag(ap, ap->active_tag);
- if (!qc) {
+ if (qc)
+ ata_qc_timeout(qc);
+ else {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
goto out;
}
- ata_qc_timeout(qc);
-
out:
DPRINTK("EXIT\n");
}
@@ -3146,15 +3394,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
qc->nbytes = qc->curbytes = 0;
ata_tf_init(ap, &qc->tf, dev->devno);
-
- if (dev->flags & ATA_DFLAG_LBA48)
- qc->tf.flags |= ATA_TFLAG_LBA48;
}
return qc;
}
-static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
+int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
{
return 0;
}
@@ -3192,7 +3437,6 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
- *
*/
void ata_qc_free(struct ata_queued_cmd *qc)
{
@@ -3212,7 +3456,6 @@ void ata_qc_free(struct ata_queued_cmd *qc)
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
- *
*/
void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
@@ -3351,7 +3594,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
ata_qc_set_polling(qc);
ata_tf_to_host_nolock(ap, &qc->tf);
- ap->pio_task_state = PIO_ST;
+ ap->hsm_task_state = HSM_ST;
queue_work(ata_wq, &ap->pio_task);
break;
@@ -3577,7 +3820,7 @@ u8 ata_bmdma_status(struct ata_port *ap)
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
@@ -3706,7 +3949,6 @@ idle_irq:
*
* RETURNS:
* IRQ_NONE or IRQ_HANDLED.
- *
*/
irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
@@ -3797,7 +4039,7 @@ static void atapi_packet_task(void *_data)
ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
/* PIO commands are handled by polling */
- ap->pio_task_state = PIO_ST;
+ ap->hsm_task_state = HSM_ST;
queue_work(ata_wq, &ap->pio_task);
}
@@ -3818,6 +4060,7 @@ err_out:
* May be used as the port_start() entry in ata_port_operations.
*
* LOCKING:
+ * Inherited from caller.
*/
int ata_port_start (struct ata_port *ap)
@@ -3843,6 +4086,7 @@ int ata_port_start (struct ata_port *ap)
* May be used as the port_stop() entry in ata_port_operations.
*
* LOCKING:
+ * Inherited from caller.
*/
void ata_port_stop (struct ata_port *ap)
@@ -3865,6 +4109,7 @@ void ata_host_stop (struct ata_host_set *host_set)
* @do_unregister: 1 if we fully unregister, 0 to just stop the port
*
* LOCKING:
+ * Inherited from caller.
*/
static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
@@ -3892,12 +4137,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
struct ata_host_set *host_set,
- struct ata_probe_ent *ent, unsigned int port_no)
+ const struct ata_probe_ent *ent, unsigned int port_no)
{
unsigned int i;
@@ -3953,10 +4197,9 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
*
* RETURNS:
* New ata_port on success, for NULL on error.
- *
*/
-static struct ata_port * ata_host_add(struct ata_probe_ent *ent,
+static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
struct ata_host_set *host_set,
unsigned int port_no)
{
@@ -4001,10 +4244,9 @@ err_out:
*
* RETURNS:
* Number of ports registered. Zero on error (no ports registered).
- *
*/
-int ata_device_add(struct ata_probe_ent *ent)
+int ata_device_add(const struct ata_probe_ent *ent)
{
unsigned int count = 0, i;
struct device *dev = ent->dev;
@@ -4104,7 +4346,7 @@ int ata_device_add(struct ata_probe_ent *ent)
for (i = 0; i < count; i++) {
struct ata_port *ap = host_set->ports[i];
- scsi_scan_host(ap->host);
+ ata_scsi_scan_host(ap);
}
dev_set_drvdata(dev, host_set);
@@ -4123,6 +4365,52 @@ err_out:
}
/**
+ * ata_host_set_remove - PCI layer callback for device removal
+ * @host_set: ATA host set that was removed
+ *
+ * Unregister all objects associated with this host set. Free those
+ * objects.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ */
+
+void ata_host_set_remove(struct ata_host_set *host_set)
+{
+ struct ata_port *ap;
+ unsigned int i;
+
+ for (i = 0; i < host_set->n_ports; i++) {
+ ap = host_set->ports[i];
+ scsi_remove_host(ap->host);
+ }
+
+ free_irq(host_set->irq, host_set);
+
+ for (i = 0; i < host_set->n_ports; i++) {
+ ap = host_set->ports[i];
+
+ ata_scsi_release(ap->host);
+
+ if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ if (ioaddr->cmd_addr == 0x1f0)
+ release_region(0x1f0, 8);
+ else if (ioaddr->cmd_addr == 0x170)
+ release_region(0x170, 8);
+ }
+
+ scsi_host_put(ap->host);
+ }
+
+ if (host_set->ops->host_stop)
+ host_set->ops->host_stop(host_set);
+
+ kfree(host_set);
+}
+
+/**
* ata_scsi_release - SCSI layer callback hook for host unload
* @host: libata host to be unloaded
*
@@ -4176,7 +4464,7 @@ void ata_std_ports(struct ata_ioports *ioaddr)
}
static struct ata_probe_ent *
-ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
+ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{
struct ata_probe_ent *probe_ent;
@@ -4217,85 +4505,86 @@ void ata_pci_host_stop (struct ata_host_set *host_set)
* ata_pci_init_native_mode - Initialize native-mode driver
* @pdev: pci device to be initialized
* @port: array[2] of pointers to port info structures.
+ * @ports: bitmap of ports present
*
* Utility function which allocates and initializes an
* ata_probe_ent structure for a standard dual-port
* PIO-based IDE controller. The returned ata_probe_ent
* structure can be passed to ata_device_add(). The returned
* ata_probe_ent structure should then be freed with kfree().
+ *
+ * The caller need only pass the address of the primary port, the
+ * secondary will be deduced automatically. If the device has non
+ * standard secondary port mappings this function can be called twice,
+ * once for each interface.
*/
struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
{
struct ata_probe_ent *probe_ent =
ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
+ int p = 0;
+
if (!probe_ent)
return NULL;
- probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
- probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr =
- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-
- probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
- probe_ent->port[1].altstatus_addr =
- probe_ent->port[1].ctl_addr =
- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
- probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+ if (ports & ATA_PORT_PRIMARY) {
+ probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
+ probe_ent->port[p].altstatus_addr =
+ probe_ent->port[p].ctl_addr =
+ pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+ probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
+ ata_std_ports(&probe_ent->port[p]);
+ p++;
+ }
- ata_std_ports(&probe_ent->port[0]);
- ata_std_ports(&probe_ent->port[1]);
+ if (ports & ATA_PORT_SECONDARY) {
+ probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
+ probe_ent->port[p].altstatus_addr =
+ probe_ent->port[p].ctl_addr =
+ pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+ probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+ ata_std_ports(&probe_ent->port[p]);
+ p++;
+ }
+ probe_ent->n_ports = p;
return probe_ent;
}
-static struct ata_probe_ent *
-ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
- struct ata_probe_ent **ppe2)
+static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info **port, int port_num)
{
- struct ata_probe_ent *probe_ent, *probe_ent2;
+ struct ata_probe_ent *probe_ent;
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
- probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
- if (!probe_ent2) {
- kfree(probe_ent);
- return NULL;
- }
- probe_ent->n_ports = 1;
- probe_ent->irq = 14;
-
- probe_ent->hard_port_no = 0;
probe_ent->legacy_mode = 1;
-
- probe_ent2->n_ports = 1;
- probe_ent2->irq = 15;
-
- probe_ent2->hard_port_no = 1;
- probe_ent2->legacy_mode = 1;
-
- probe_ent->port[0].cmd_addr = 0x1f0;
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr = 0x3f6;
- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-
- probe_ent2->port[0].cmd_addr = 0x170;
- probe_ent2->port[0].altstatus_addr =
- probe_ent2->port[0].ctl_addr = 0x376;
- probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
-
+ probe_ent->n_ports = 1;
+ probe_ent->hard_port_no = port_num;
+
+ switch(port_num)
+ {
+ case 0:
+ probe_ent->irq = 14;
+ probe_ent->port[0].cmd_addr = 0x1f0;
+ probe_ent->port[0].altstatus_addr =
+ probe_ent->port[0].ctl_addr = 0x3f6;
+ break;
+ case 1:
+ probe_ent->irq = 15;
+ probe_ent->port[0].cmd_addr = 0x170;
+ probe_ent->port[0].altstatus_addr =
+ probe_ent->port[0].ctl_addr = 0x376;
+ break;
+ }
+ probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
ata_std_ports(&probe_ent->port[0]);
- ata_std_ports(&probe_ent2->port[0]);
-
- *ppe2 = probe_ent2;
return probe_ent;
}
@@ -4318,13 +4607,12 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
*
* RETURNS:
* Zero on success, negative on errno-based value on error.
- *
*/
int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports)
{
- struct ata_probe_ent *probe_ent, *probe_ent2 = NULL;
+ struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
struct ata_port_info *port[2];
u8 tmp8, mask;
unsigned int legacy_mode = 0;
@@ -4341,7 +4629,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
&& (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- /* TODO: support transitioning to native mode? */
+ /* TODO: What if one channel is in native mode ... */
pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
mask = (1 << 2) | (1 << 0);
if ((tmp8 & mask) != mask)
@@ -4349,11 +4637,20 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
/* FIXME... */
- if ((!legacy_mode) && (n_ports > 1)) {
- printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n");
- return -EINVAL;
+ if ((!legacy_mode) && (n_ports > 2)) {
+ printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
+ n_ports = 2;
+ /* For now */
}
+ /* FIXME: Really for ATA it isn't safe because the device may be
+ multi-purpose and we want to leave it alone if it was already
+ enabled. Secondly for shared use as Arjan says we want refcounting
+
+ Checking dev->is_enabled is insufficient as this is not set at
+ boot for the primary video which is BIOS enabled
+ */
+
rc = pci_enable_device(pdev);
if (rc)
return rc;
@@ -4364,6 +4661,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out;
}
+ /* FIXME: Should use platform specific mappers for legacy port ranges */
if (legacy_mode) {
if (!request_region(0x1f0, 8, "libata")) {
struct resource *conflict, res;
@@ -4408,10 +4706,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out_regions;
if (legacy_mode) {
- probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
- } else
- probe_ent = ata_pci_init_native_mode(pdev, port);
- if (!probe_ent) {
+ if (legacy_mode & (1 << 0))
+ probe_ent = ata_pci_init_legacy_port(pdev, port, 0);
+ if (legacy_mode & (1 << 1))
+ probe_ent2 = ata_pci_init_legacy_port(pdev, port, 1);
+ } else {
+ if (n_ports == 2)
+ probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+ else
+ probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
+ }
+ if (!probe_ent && !probe_ent2) {
rc = -ENOMEM;
goto err_out_regions;
}
@@ -4449,7 +4754,7 @@ err_out:
* @pdev: PCI device that was removed
*
* PCI layer indicates to libata via this hook that
- * hot-unplug or module unload event has occured.
+ * hot-unplug or module unload event has occurred.
* Handle this by unregistering all objects associated
* with this PCI device. Free those objects. Then finally
* release PCI resources and disable device.
@@ -4462,46 +4767,15 @@ void ata_pci_remove_one (struct pci_dev *pdev)
{
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host_set *host_set = dev_get_drvdata(dev);
- struct ata_port *ap;
- unsigned int i;
-
- for (i = 0; i < host_set->n_ports; i++) {
- ap = host_set->ports[i];
-
- scsi_remove_host(ap->host);
- }
-
- free_irq(host_set->irq, host_set);
-
- for (i = 0; i < host_set->n_ports; i++) {
- ap = host_set->ports[i];
-
- ata_scsi_release(ap->host);
-
- if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
- if (ioaddr->cmd_addr == 0x1f0)
- release_region(0x1f0, 8);
- else if (ioaddr->cmd_addr == 0x170)
- release_region(0x170, 8);
- }
-
- scsi_host_put(ap->host);
- }
-
- if (host_set->ops->host_stop)
- host_set->ops->host_stop(host_set);
-
- kfree(host_set);
+ ata_host_set_remove(host_set);
pci_release_regions(pdev);
pci_disable_device(pdev);
dev_set_drvdata(dev, NULL);
}
/* move to PCI subsystem */
-int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
+int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
{
unsigned long tmp = 0;
@@ -4554,6 +4828,27 @@ static void __exit ata_exit(void)
module_init(ata_init);
module_exit(ata_exit);
+static unsigned long ratelimit_time;
+static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED;
+
+int ata_ratelimit(void)
+{
+ int rc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ata_ratelimit_lock, flags);
+
+ if (time_after(jiffies, ratelimit_time)) {
+ rc = 1;
+ ratelimit_time = jiffies + (HZ/5);
+ } else
+ rc = 0;
+
+ spin_unlock_irqrestore(&ata_ratelimit_lock, flags);
+
+ return rc;
+}
+
/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
@@ -4564,6 +4859,7 @@ module_exit(ata_exit);
EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_std_ports);
EXPORT_SYMBOL_GPL(ata_device_add);
+EXPORT_SYMBOL_GPL(ata_host_set_remove);
EXPORT_SYMBOL_GPL(ata_sg_init);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
EXPORT_SYMBOL_GPL(ata_qc_complete);
@@ -4594,6 +4890,7 @@ EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
+EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);
@@ -4605,6 +4902,9 @@ EXPORT_SYMBOL_GPL(ata_dev_id_string);
EXPORT_SYMBOL_GPL(ata_dev_config);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+EXPORT_SYMBOL_GPL(ata_timing_compute);
+EXPORT_SYMBOL_GPL(ata_timing_merge);
+
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
EXPORT_SYMBOL_GPL(ata_pci_host_stop);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 104fd9a63e73..58858886d751 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -44,11 +44,19 @@
#include "libata.h"
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
static struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
+ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
+static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
+ void (*done)(struct scsi_cmnd *))
+{
+ ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ done(cmd);
+}
+
/**
* ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
* @sdev: SCSI device for which BIOS geometry is to be determined
@@ -182,7 +190,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
u8 err = 0;
- unsigned char *sb = cmd->sense_buffer;
/* Based on the 3ware driver translation table */
static unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
@@ -225,8 +232,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
};
int i = 0;
- cmd->result = SAM_STAT_CHECK_CONDITION;
-
/*
* Is this an error we can process/parse
*/
@@ -281,11 +286,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
/* Look for best matches first */
if((sense_table[i][0] & err) == sense_table[i][0])
{
- sb[0] = 0x70;
- sb[2] = sense_table[i][1];
- sb[7] = 0x0a;
- sb[12] = sense_table[i][2];
- sb[13] = sense_table[i][3];
+ ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
+ sense_table[i][2] /* asc */,
+ sense_table[i][3] /* ascq */ );
return;
}
i++;
@@ -300,11 +303,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
{
if(stat_table[i][0] & drv_stat)
{
- sb[0] = 0x70;
- sb[2] = stat_table[i][1];
- sb[7] = 0x0a;
- sb[12] = stat_table[i][2];
- sb[13] = stat_table[i][3];
+ ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
+ sense_table[i][2] /* asc */,
+ sense_table[i][3] /* ascq */ );
return;
}
i++;
@@ -313,15 +314,12 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
/* additional-sense-code[-qualifier] */
- sb[0] = 0x70;
- sb[2] = MEDIUM_ERROR;
- sb[7] = 0x0A;
if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
- sb[12] = 0x11; /* "unrecovered read error" */
- sb[13] = 0x04;
+ ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0x11, 0x4);
+ /* "unrecovered read error" */
} else {
- sb[12] = 0x0C; /* "write error - */
- sb[13] = 0x02; /* auto-reallocation failed" */
+ ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0xc, 0x2);
+ /* "write error - auto-reallocation failed" */
}
}
@@ -420,7 +418,7 @@ int ata_scsi_error(struct Scsi_Host *host)
*/
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
- u8 *scsicmd)
+ const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
@@ -430,15 +428,26 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
; /* ignore IMMED bit, violates sat-r05 */
}
if (scsicmd[4] & 0x2)
- return 1; /* LOEJ bit set not supported */
+ goto invalid_fld; /* LOEJ bit set not supported */
if (((scsicmd[4] >> 4) & 0xf) != 0)
- return 1; /* power conditions not supported */
+ goto invalid_fld; /* power conditions not supported */
if (scsicmd[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
- tf->lbah = 0x0;
- tf->lbam = 0x0;
- tf->lbal = 0x0;
- tf->device |= ATA_LBA;
+
+ if (qc->dev->flags & ATA_DFLAG_LBA) {
+ qc->tf.flags |= ATA_TFLAG_LBA;
+
+ tf->lbah = 0x0;
+ tf->lbam = 0x0;
+ tf->lbal = 0x0;
+ tf->device |= ATA_LBA;
+ } else {
+ /* CHS */
+ tf->lbal = 0x1; /* sect */
+ tf->lbam = 0x0; /* cyl low */
+ tf->lbah = 0x0; /* cyl high */
+ }
+
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
} else {
tf->nsect = 0; /* time period value (0 implies now) */
@@ -453,6 +462,11 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
*/
return 0;
+
+invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
}
@@ -471,14 +485,14 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
tf->flags |= ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if ((tf->flags & ATA_TFLAG_LBA48) &&
+ if ((qc->dev->flags & ATA_DFLAG_LBA48) &&
(ata_id_has_flush_ext(qc->dev->id)))
tf->command = ATA_CMD_FLUSH_EXT;
else
@@ -488,6 +502,99 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
}
/**
+ * scsi_6_lba_len - Get LBA and transfer length
+ * @scsicmd: SCSI command to translate
+ *
+ * Calculate LBA and transfer length for 6-byte commands.
+ *
+ * RETURNS:
+ * @plba: the LBA
+ * @plen: the transfer length
+ */
+
+static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+{
+ u64 lba = 0;
+ u32 len = 0;
+
+ VPRINTK("six-byte command\n");
+
+ lba |= ((u64)scsicmd[2]) << 8;
+ lba |= ((u64)scsicmd[3]);
+
+ len |= ((u32)scsicmd[4]);
+
+ *plba = lba;
+ *plen = len;
+}
+
+/**
+ * scsi_10_lba_len - Get LBA and transfer length
+ * @scsicmd: SCSI command to translate
+ *
+ * Calculate LBA and transfer length for 10-byte commands.
+ *
+ * RETURNS:
+ * @plba: the LBA
+ * @plen: the transfer length
+ */
+
+static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+{
+ u64 lba = 0;
+ u32 len = 0;
+
+ VPRINTK("ten-byte command\n");
+
+ lba |= ((u64)scsicmd[2]) << 24;
+ lba |= ((u64)scsicmd[3]) << 16;
+ lba |= ((u64)scsicmd[4]) << 8;
+ lba |= ((u64)scsicmd[5]);
+
+ len |= ((u32)scsicmd[7]) << 8;
+ len |= ((u32)scsicmd[8]);
+
+ *plba = lba;
+ *plen = len;
+}
+
+/**
+ * scsi_16_lba_len - Get LBA and transfer length
+ * @scsicmd: SCSI command to translate
+ *
+ * Calculate LBA and transfer length for 16-byte commands.
+ *
+ * RETURNS:
+ * @plba: the LBA
+ * @plen: the transfer length
+ */
+
+static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+{
+ u64 lba = 0;
+ u32 len = 0;
+
+ VPRINTK("sixteen-byte command\n");
+
+ lba |= ((u64)scsicmd[2]) << 56;
+ lba |= ((u64)scsicmd[3]) << 48;
+ lba |= ((u64)scsicmd[4]) << 40;
+ lba |= ((u64)scsicmd[5]) << 32;
+ lba |= ((u64)scsicmd[6]) << 24;
+ lba |= ((u64)scsicmd[7]) << 16;
+ lba |= ((u64)scsicmd[8]) << 8;
+ lba |= ((u64)scsicmd[9]);
+
+ len |= ((u32)scsicmd[10]) << 24;
+ len |= ((u32)scsicmd[11]) << 16;
+ len |= ((u32)scsicmd[12]) << 8;
+ len |= ((u32)scsicmd[13]);
+
+ *plba = lba;
+ *plen = len;
+}
+
+/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
* @scsicmd: SCSI command to translate
@@ -501,82 +608,110 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+ struct ata_device *dev = qc->dev;
u64 dev_sectors = qc->dev->n_sectors;
- u64 sect = 0;
- u32 n_sect = 0;
+ u64 block;
+ u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- tf->device |= ATA_LBA;
- if (scsicmd[0] == VERIFY) {
- sect |= ((u64)scsicmd[2]) << 24;
- sect |= ((u64)scsicmd[3]) << 16;
- sect |= ((u64)scsicmd[4]) << 8;
- sect |= ((u64)scsicmd[5]);
+ if (scsicmd[0] == VERIFY)
+ scsi_10_lba_len(scsicmd, &block, &n_block);
+ else if (scsicmd[0] == VERIFY_16)
+ scsi_16_lba_len(scsicmd, &block, &n_block);
+ else
+ goto invalid_fld;
- n_sect |= ((u32)scsicmd[7]) << 8;
- n_sect |= ((u32)scsicmd[8]);
- }
+ if (!n_block)
+ goto nothing_to_do;
+ if (block >= dev_sectors)
+ goto out_of_range;
+ if ((block + n_block) > dev_sectors)
+ goto out_of_range;
- else if (scsicmd[0] == VERIFY_16) {
- sect |= ((u64)scsicmd[2]) << 56;
- sect |= ((u64)scsicmd[3]) << 48;
- sect |= ((u64)scsicmd[4]) << 40;
- sect |= ((u64)scsicmd[5]) << 32;
- sect |= ((u64)scsicmd[6]) << 24;
- sect |= ((u64)scsicmd[7]) << 16;
- sect |= ((u64)scsicmd[8]) << 8;
- sect |= ((u64)scsicmd[9]);
-
- n_sect |= ((u32)scsicmd[10]) << 24;
- n_sect |= ((u32)scsicmd[11]) << 16;
- n_sect |= ((u32)scsicmd[12]) << 8;
- n_sect |= ((u32)scsicmd[13]);
- }
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
- else
- return 1;
+ if (dev->flags & ATA_DFLAG_LBA48) {
+ if (n_block > (64 * 1024))
+ goto invalid_fld;
- if (!n_sect)
- return 1;
- if (sect >= dev_sectors)
- return 1;
- if ((sect + n_sect) > dev_sectors)
- return 1;
- if (lba48) {
- if (n_sect > (64 * 1024))
- return 1;
- } else {
- if (n_sect > 256)
- return 1;
- }
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
+ tf->command = ATA_CMD_VERIFY_EXT;
- if (lba48) {
- tf->command = ATA_CMD_VERIFY_EXT;
+ tf->hob_nsect = (n_block >> 8) & 0xff;
- tf->hob_nsect = (n_sect >> 8) & 0xff;
+ tf->hob_lbah = (block >> 40) & 0xff;
+ tf->hob_lbam = (block >> 32) & 0xff;
+ tf->hob_lbal = (block >> 24) & 0xff;
+ } else {
+ if (n_block > 256)
+ goto invalid_fld;
- tf->hob_lbah = (sect >> 40) & 0xff;
- tf->hob_lbam = (sect >> 32) & 0xff;
- tf->hob_lbal = (sect >> 24) & 0xff;
+ /* use LBA28 */
+ tf->command = ATA_CMD_VERIFY;
+
+ tf->device |= (block >> 24) & 0xf;
+ }
+
+ tf->nsect = n_block & 0xff;
+
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
+
+ tf->device |= ATA_LBA;
} else {
+ /* CHS */
+ u32 sect, head, cyl, track;
+
+ if (n_block > 256)
+ goto invalid_fld;
+
+ /* Convert LBA to CHS */
+ track = (u32)block / dev->sectors;
+ cyl = track / dev->heads;
+ head = track % dev->heads;
+ sect = (u32)block % dev->sectors + 1;
+
+ DPRINTK("block %u track %u cyl %u head %u sect %u\n",
+ (u32)block, track, cyl, head, sect);
+
+ /* Check whether the converted CHS can fit.
+ Cylinder: 0-65535
+ Head: 0-15
+ Sector: 1-255*/
+ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
+ goto out_of_range;
+
tf->command = ATA_CMD_VERIFY;
-
- tf->device |= (sect >> 24) & 0xf;
+ tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+ tf->lbal = sect;
+ tf->lbam = cyl;
+ tf->lbah = cyl >> 8;
+ tf->device |= head;
}
- tf->nsect = n_sect & 0xff;
+ return 0;
+
+invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
- tf->lbah = (sect >> 16) & 0xff;
- tf->lbam = (sect >> 8) & 0xff;
- tf->lbal = sect & 0xff;
+out_of_range:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ /* "Logical Block Address out of range" */
+ return 1;
- return 0;
+nothing_to_do:
+ qc->scsicmd->result = SAM_STAT_GOOD;
+ return 1;
}
/**
@@ -599,106 +734,137 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+ struct ata_device *dev = qc->dev;
+ u64 block;
+ u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- tf->protocol = qc->dev->xfer_protocol;
- tf->device |= ATA_LBA;
- if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
- scsicmd[0] == READ_16) {
- tf->command = qc->dev->read_cmd;
- } else {
- tf->command = qc->dev->write_cmd;
+ if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
+ scsicmd[0] == WRITE_16)
tf->flags |= ATA_TFLAG_WRITE;
- }
- if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
- if (lba48) {
- tf->hob_nsect = scsicmd[7];
- tf->hob_lbal = scsicmd[2];
+ /* Calculate the SCSI LBA and transfer length. */
+ switch (scsicmd[0]) {
+ case READ_10:
+ case WRITE_10:
+ scsi_10_lba_len(scsicmd, &block, &n_block);
+ break;
+ case READ_6:
+ case WRITE_6:
+ scsi_6_lba_len(scsicmd, &block, &n_block);
- qc->nsect = ((unsigned int)scsicmd[7] << 8) |
- scsicmd[8];
- } else {
- /* if we don't support LBA48 addressing, the request
- * -may- be too large. */
- if ((scsicmd[2] & 0xf0) || scsicmd[7])
- return 1;
+ /* for 6-byte r/w commands, transfer length 0
+ * means 256 blocks of data, not 0 block.
+ */
+ if (!n_block)
+ n_block = 256;
+ break;
+ case READ_16:
+ case WRITE_16:
+ scsi_16_lba_len(scsicmd, &block, &n_block);
+ break;
+ default:
+ DPRINTK("no-byte command\n");
+ goto invalid_fld;
+ }
- /* stores LBA27:24 in lower 4 bits of device reg */
- tf->device |= scsicmd[2];
+ /* Check and compose ATA command */
+ if (!n_block)
+ /* For 10-byte and 16-byte SCSI R/W commands, transfer
+ * length 0 means transfer 0 block of data.
+ * However, for ATA R/W commands, sector count 0 means
+ * 256 or 65536 sectors, not 0 sectors as in SCSI.
+ */
+ goto nothing_to_do;
- qc->nsect = scsicmd[8];
- }
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
- tf->nsect = scsicmd[8];
- tf->lbal = scsicmd[5];
- tf->lbam = scsicmd[4];
- tf->lbah = scsicmd[3];
+ if (dev->flags & ATA_DFLAG_LBA48) {
+ /* The request -may- be too large for LBA48. */
+ if ((block >> 48) || (n_block > 65536))
+ goto out_of_range;
- VPRINTK("ten-byte command\n");
- if (qc->nsect == 0) /* we don't support length==0 cmds */
- return 1;
- return 0;
- }
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
- if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
- qc->nsect = tf->nsect = scsicmd[4];
- if (!qc->nsect) {
- qc->nsect = 256;
- if (lba48)
- tf->hob_nsect = 1;
- }
+ tf->hob_nsect = (n_block >> 8) & 0xff;
- tf->lbal = scsicmd[3];
- tf->lbam = scsicmd[2];
- tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
+ tf->hob_lbah = (block >> 40) & 0xff;
+ tf->hob_lbam = (block >> 32) & 0xff;
+ tf->hob_lbal = (block >> 24) & 0xff;
+ } else {
+ /* use LBA28 */
- VPRINTK("six-byte command\n");
- return 0;
- }
+ /* The request -may- be too large for LBA28. */
+ if ((block >> 28) || (n_block > 256))
+ goto out_of_range;
- if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
- /* rule out impossible LBAs and sector counts */
- if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
- return 1;
+ tf->device |= (block >> 24) & 0xf;
+ }
- if (lba48) {
- tf->hob_nsect = scsicmd[12];
- tf->hob_lbal = scsicmd[6];
- tf->hob_lbam = scsicmd[5];
- tf->hob_lbah = scsicmd[4];
+ ata_rwcmd_protocol(qc);
- qc->nsect = ((unsigned int)scsicmd[12] << 8) |
- scsicmd[13];
- } else {
- /* once again, filter out impossible non-zero values */
- if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
- (scsicmd[6] & 0xf0))
- return 1;
+ qc->nsect = n_block;
+ tf->nsect = n_block & 0xff;
- /* stores LBA27:24 in lower 4 bits of device reg */
- tf->device |= scsicmd[6];
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
- qc->nsect = scsicmd[13];
- }
+ tf->device |= ATA_LBA;
+ } else {
+ /* CHS */
+ u32 sect, head, cyl, track;
+
+ /* The request -may- be too large for CHS addressing. */
+ if ((block >> 28) || (n_block > 256))
+ goto out_of_range;
+
+ ata_rwcmd_protocol(qc);
+
+ /* Convert LBA to CHS */
+ track = (u32)block / dev->sectors;
+ cyl = track / dev->heads;
+ head = track % dev->heads;
+ sect = (u32)block % dev->sectors + 1;
+
+ DPRINTK("block %u track %u cyl %u head %u sect %u\n",
+ (u32)block, track, cyl, head, sect);
+
+ /* Check whether the converted CHS can fit.
+ Cylinder: 0-65535
+ Head: 0-15
+ Sector: 1-255*/
+ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
+ goto out_of_range;
+
+ qc->nsect = n_block;
+ tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+ tf->lbal = sect;
+ tf->lbam = cyl;
+ tf->lbah = cyl >> 8;
+ tf->device |= head;
+ }
- tf->nsect = scsicmd[13];
- tf->lbal = scsicmd[9];
- tf->lbam = scsicmd[8];
- tf->lbah = scsicmd[7];
+ return 0;
- VPRINTK("sixteen-byte command\n");
- if (qc->nsect == 0) /* we don't support length==0 cmds */
- return 1;
- return 0;
- }
+invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
+
+out_of_range:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ /* "Logical Block Address out of range" */
+ return 1;
- DPRINTK("no-byte command\n");
+nothing_to_do:
+ qc->scsicmd->result = SAM_STAT_GOOD;
return 1;
}
@@ -731,6 +897,12 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
* This function sets up an ata_queued_cmd structure for the
* SCSI command, and sends that ata_queued_cmd to the hardware.
*
+ * The xlat_func argument (actor) returns 0 if ready to execute
+ * ATA command, else 1 to finish translation. If 1 is returned
+ * then cmd->result (and possibly cmd->sense_buffer) are assumed
+ * to be set reflecting an error condition or clean (early)
+ * termination.
+ *
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
@@ -747,7 +919,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
qc = ata_scsi_qc_new(ap, dev, cmd, done);
if (!qc)
- return;
+ goto err_mem;
/* data is present; dma-map it */
if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
@@ -755,7 +927,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
if (unlikely(cmd->request_bufflen < 1)) {
printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n",
ap->id, dev->devno);
- goto err_out;
+ goto err_did;
}
if (cmd->use_sg)
@@ -770,19 +942,28 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
qc->complete_fn = ata_scsi_qc_complete;
if (xlat_func(qc, scsicmd))
- goto err_out;
+ goto early_finish;
/* select device, send command to hardware */
if (ata_qc_issue(qc))
- goto err_out;
+ goto err_did;
VPRINTK("EXIT\n");
return;
-err_out:
+early_finish:
+ ata_qc_free(qc);
+ done(cmd);
+ DPRINTK("EXIT - early finish (good or error)\n");
+ return;
+
+err_did:
ata_qc_free(qc);
- ata_bad_cdb(cmd, done);
- DPRINTK("EXIT - badcmd\n");
+err_mem:
+ cmd->result = (DID_ERROR << 16);
+ done(cmd);
+ DPRINTK("EXIT - internal\n");
+ return;
}
/**
@@ -849,7 +1030,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
* Mapping the response buffer, calling the command's handler,
* and handling the handler's return value. This return value
* indicates whether the handler wishes the SCSI command to be
- * completed successfully, or not.
+ * completed successfully (0), or not (in which case cmd->result
+ * and sense buffer are assumed to be set).
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
@@ -868,12 +1050,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
rc = actor(args, rbuf, buflen);
ata_scsi_rbuf_put(cmd, rbuf);
- if (rc)
- ata_bad_cdb(cmd, args->done);
- else {
+ if (rc == 0)
cmd->result = SAM_STAT_GOOD;
- args->done(cmd);
- }
+ args->done(cmd);
}
/**
@@ -1179,8 +1358,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
* in the same manner)
*/
page_control = scsicmd[2] >> 6;
- if ((page_control != 0) && (page_control != 3))
- return 1;
+ switch (page_control) {
+ case 0: /* current */
+ break; /* supported */
+ case 3: /* saved */
+ goto saving_not_supp;
+ case 1: /* changeable */
+ case 2: /* defaults */
+ default:
+ goto invalid_fld;
+ }
if (six_byte)
output_len = 4;
@@ -1211,7 +1398,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
break;
default: /* invalid page code */
- return 1;
+ goto invalid_fld;
}
if (six_byte) {
@@ -1224,6 +1411,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
}
return 0;
+
+invalid_fld:
+ ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
+
+saving_not_supp:
+ ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
+ /* "Saving parameters not supported" */
+ return 1;
}
/**
@@ -1246,10 +1443,20 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
VPRINTK("ENTER\n");
- if (ata_id_has_lba48(args->id))
- n_sectors = ata_id_u64(args->id, 100);
- else
- n_sectors = ata_id_u32(args->id, 60);
+ if (ata_id_has_lba(args->id)) {
+ if (ata_id_has_lba48(args->id))
+ n_sectors = ata_id_u64(args->id, 100);
+ else
+ n_sectors = ata_id_u32(args->id, 60);
+ } else {
+ /* CHS default translation */
+ n_sectors = args->id[1] * args->id[3] * args->id[6];
+
+ if (ata_id_current_chs_valid(args->id))
+ /* CHS current translation */
+ n_sectors = ata_id_u32(args->id, 57);
+ }
+
n_sectors--; /* ATA TotalUserSectors - 1 */
if (args->cmd->cmnd[0] == READ_CAPACITY) {
@@ -1313,6 +1520,34 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
}
/**
+ * ata_scsi_set_sense - Set SCSI sense data and status
+ * @cmd: SCSI request to be handled
+ * @sk: SCSI-defined sense key
+ * @asc: SCSI-defined additional sense code
+ * @ascq: SCSI-defined additional sense code qualifier
+ *
+ * Helper function that builds a valid fixed format, current
+ * response code and the given sense key (sk), additional sense
+ * code (asc) and additional sense code qualifier (ascq) with
+ * a SCSI command status of %SAM_STAT_CHECK_CONDITION and
+ * DRIVER_SENSE set in the upper bits of scsi_cmnd::result .
+ *
+ * LOCKING:
+ * Not required
+ */
+
+void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
+{
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ cmd->sense_buffer[0] = 0x70; /* fixed format, current */
+ cmd->sense_buffer[2] = sk;
+ cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
+ cmd->sense_buffer[12] = asc;
+ cmd->sense_buffer[13] = ascq;
+}
+
+/**
* ata_scsi_badcmd - End a SCSI request with an error
* @cmd: SCSI request to be handled
* @done: SCSI command completion function
@@ -1330,30 +1565,84 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq)
{
DPRINTK("ENTER\n");
- cmd->result = SAM_STAT_CHECK_CONDITION;
-
- cmd->sense_buffer[0] = 0x70;
- cmd->sense_buffer[2] = ILLEGAL_REQUEST;
- cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */
- cmd->sense_buffer[12] = asc;
- cmd->sense_buffer[13] = ascq;
+ ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, asc, ascq);
done(cmd);
}
+void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
+ struct scsi_cmnd *cmd)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ int rc;
+
+ DPRINTK("ATAPI request sense\n");
+
+ qc = ata_qc_new_init(ap, dev);
+ BUG_ON(qc == NULL);
+
+ /* FIXME: is this needed? */
+ memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+
+ ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
+ qc->dma_dir = DMA_FROM_DEVICE;
+
+ memset(&qc->cdb, 0, ap->cdb_len);
+ qc->cdb[0] = REQUEST_SENSE;
+ qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
+
+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ qc->tf.command = ATA_CMD_PACKET;
+
+ qc->tf.protocol = ATA_PROT_ATAPI;
+ qc->tf.lbam = (8 * 1024) & 0xff;
+ qc->tf.lbah = (8 * 1024) >> 8;
+ qc->nbytes = SCSI_SENSE_BUFFERSIZE;
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (rc)
+ ata_port_disable(ap);
+ else
+ wait_for_completion(&wait);
+
+ DPRINTK("EXIT\n");
+}
+
static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
- if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
+ VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat);
+
+ if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ)))
+ ata_to_sense_error(qc, drv_stat);
+
+ else if (unlikely(drv_stat & ATA_ERR)) {
DPRINTK("request check condition\n");
+ /* FIXME: command completion with check condition
+ * but no sense causes the error handler to run,
+ * which then issues REQUEST SENSE, fills in the sense
+ * buffer, and completes the command (for the second
+ * time). We need to issue REQUEST SENSE some other
+ * way, to avoid completing the command twice.
+ */
cmd->result = SAM_STAT_CHECK_CONDITION;
qc->scsidone(cmd);
return 1;
- } else {
+ }
+
+ else {
u8 *scsicmd = cmd->cmnd;
if (scsicmd[0] == INQUIRY) {
@@ -1361,15 +1650,30 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
unsigned int buflen;
buflen = ata_scsi_rbuf_get(cmd, &buf);
- buf[2] = 0x5;
- buf[3] = (buf[3] & 0xf0) | 2;
+
+ /* ATAPI devices typically report zero for their SCSI version,
+ * and sometimes deviate from the spec WRT response data
+ * format. If SCSI version is reported as zero like normal,
+ * then we make the following fixups: 1) Fake MMC-5 version,
+ * to indicate to the Linux scsi midlayer this is a modern
+ * device. 2) Ensure response data format / ATAPI information
+ * are always correct.
+ */
+ /* FIXME: do we ever override EVPD pages and the like, with
+ * this code?
+ */
+ if (buf[2] == 0) {
+ buf[2] = 0x5;
+ buf[3] = 0x32;
+ }
+
ata_scsi_rbuf_put(cmd, buf);
}
+
cmd->result = SAM_STAT_GOOD;
}
qc->scsidone(cmd);
-
return 0;
}
/**
@@ -1384,7 +1688,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
* Zero on success, non-zero on failure.
*/
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
@@ -1453,7 +1757,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
*/
static struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
+ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
{
struct ata_device *dev;
@@ -1610,7 +1914,7 @@ void ata_scsi_simulate(u16 *id,
void (*done)(struct scsi_cmnd *))
{
struct ata_scsi_args args;
- u8 *scsicmd = cmd->cmnd;
+ const u8 *scsicmd = cmd->cmnd;
args.id = id;
args.cmd = cmd;
@@ -1630,7 +1934,7 @@ void ata_scsi_simulate(u16 *id,
case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
else if (scsicmd[2] == 0x00)
@@ -1640,7 +1944,7 @@ void ata_scsi_simulate(u16 *id,
else if (scsicmd[2] == 0x83)
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
else
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
break;
case MODE_SENSE:
@@ -1650,7 +1954,7 @@ void ata_scsi_simulate(u16 *id,
case MODE_SELECT: /* unconditionally return */
case MODE_SELECT_10: /* bad-field-in-cdb */
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
break;
case READ_CAPACITY:
@@ -1661,7 +1965,7 @@ void ata_scsi_simulate(u16 *id,
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
else
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
break;
case REPORT_LUNS:
@@ -1673,8 +1977,26 @@ void ata_scsi_simulate(u16 *id,
/* all other commands */
default:
- ata_bad_scsiop(cmd, done);
+ ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
+ /* "Invalid command operation code" */
+ done(cmd);
break;
}
}
+void ata_scsi_scan_host(struct ata_port *ap)
+{
+ struct ata_device *dev;
+ unsigned int i;
+
+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
+ return;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ dev = &ap->device[i];
+
+ if (ata_dev_present(dev))
+ scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
+ }
+}
+
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index d608b3a0f6fe..3d60190584ba 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -39,18 +39,23 @@ struct ata_scsi_args {
/* libata-core.c */
extern int atapi_enabled;
+extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
+extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern int ata_qc_issue(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
extern void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep);
-extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
/* libata-scsi.c */
+extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
+ struct scsi_cmnd *cmd);
+extern void ata_scsi_scan_host(struct ata_port *ap);
extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
@@ -76,18 +81,10 @@ extern unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
extern void ata_scsi_badcmd(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *),
u8 asc, u8 ascq);
+extern void ata_scsi_set_sense(struct scsi_cmnd *cmd,
+ u8 sk, u8 asc, u8 ascq);
extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
unsigned int (*actor) (struct ata_scsi_args *args,
u8 *rbuf, unsigned int buflen));
-static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- ata_scsi_badcmd(cmd, done, 0x20, 0x00);
-}
-
-static inline void ata_bad_cdb(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- ata_scsi_badcmd(cmd, done, 0x24, 0x00);
-}
-
#endif /* __LIBATA_H__ */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 0e089a42c03a..acae7c48ef7d 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -966,21 +966,21 @@ static void
lpfc_get_host_fabric_name (struct Scsi_Host *shost)
{
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
- u64 nodename;
+ u64 node_name;
spin_lock_irq(shost->host_lock);
if ((phba->fc_flag & FC_FABRIC) ||
((phba->fc_topology == TOPOLOGY_LOOP) &&
(phba->fc_flag & FC_PUBLIC_LOOP)))
- memcpy(&nodename, &phba->fc_fabparam.nodeName, sizeof(u64));
+ node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
else
/* fabric is local port if there is no F/FL_Port */
- memcpy(&nodename, &phba->fc_nodename, sizeof(u64));
+ node_name = wwn_to_u64(phba->fc_nodename.u.wwn);
spin_unlock_irq(shost->host_lock);
- fc_host_fabric_name(shost) = be64_to_cpu(nodename);
+ fc_host_fabric_name(shost) = node_name;
}
@@ -1103,21 +1103,20 @@ lpfc_get_starget_node_name(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
- uint64_t node_name = 0;
+ u64 node_name = 0;
struct lpfc_nodelist *ndlp = NULL;
spin_lock_irq(shost->host_lock);
/* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) {
- memcpy(&node_name, &ndlp->nlp_nodename,
- sizeof(struct lpfc_name));
+ node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
break;
}
}
spin_unlock_irq(shost->host_lock);
- fc_starget_node_name(starget) = be64_to_cpu(node_name);
+ fc_starget_node_name(starget) = node_name;
}
static void
@@ -1125,21 +1124,20 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
- uint64_t port_name = 0;
+ u64 port_name = 0;
struct lpfc_nodelist *ndlp = NULL;
spin_lock_irq(shost->host_lock);
/* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) {
- memcpy(&port_name, &ndlp->nlp_portname,
- sizeof(struct lpfc_name));
+ port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
break;
}
}
spin_unlock_irq(shost->host_lock);
- fc_starget_port_name(starget) = be64_to_cpu(port_name);
+ fc_starget_port_name(starget) = port_name;
}
static void
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 0a8269d6b130..56052f4510c3 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1017,13 +1017,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
struct fc_rport *rport;
struct lpfc_rport_data *rdata;
struct fc_rport_identifiers rport_ids;
- uint64_t wwn;
/* Remote port has reappeared. Re-register w/ FC transport */
- memcpy(&wwn, &ndlp->nlp_nodename, sizeof(uint64_t));
- rport_ids.node_name = be64_to_cpu(wwn);
- memcpy(&wwn, &ndlp->nlp_portname, sizeof(uint64_t));
- rport_ids.port_name = be64_to_cpu(wwn);
+ rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
+ rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
rport_ids.port_id = ndlp->nlp_DID;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
if (ndlp->nlp_type & NLP_FCP_TARGET)
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 21591cb9f551..86c41981188b 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -262,12 +262,14 @@ struct lpfc_sli_ct_request {
#define FF_FRAME_SIZE 2048
struct lpfc_name {
+ union {
+ struct {
#ifdef __BIG_ENDIAN_BITFIELD
- uint8_t nameType:4; /* FC Word 0, bit 28:31 */
- uint8_t IEEEextMsn:4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+ uint8_t nameType:4; /* FC Word 0, bit 28:31 */
+ uint8_t IEEEextMsn:4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
#else /* __LITTLE_ENDIAN_BITFIELD */
- uint8_t IEEEextMsn:4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
- uint8_t nameType:4; /* FC Word 0, bit 28:31 */
+ uint8_t IEEEextMsn:4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+ uint8_t nameType:4; /* FC Word 0, bit 28:31 */
#endif
#define NAME_IEEE 0x1 /* IEEE name - nameType */
@@ -276,8 +278,11 @@ struct lpfc_name {
#define NAME_IP_TYPE 0x4 /* IP address */
#define NAME_CCITT_TYPE 0xC
#define NAME_CCITT_GR_TYPE 0xE
- uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */
- uint8_t IEEE[6]; /* FC IEEE address */
+ uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */
+ uint8_t IEEE[6]; /* FC IEEE address */
+ } s;
+ uint8_t wwn[8];
+ } u;
};
struct csp {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 6f3cb59bf9e0..0856ff7d3b33 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -285,7 +285,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
if (phba->SerialNumber[0] == 0) {
uint8_t *outptr;
- outptr = (uint8_t *) & phba->fc_nodename.IEEE[0];
+ outptr = &phba->fc_nodename.u.s.IEEE[0];
for (i = 0; i < 12; i++) {
status = *outptr++;
j = ((status & 0xf0) >> 4);
@@ -1333,7 +1333,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
unsigned long bar0map_len, bar2map_len;
int error = -ENODEV, retval;
int i;
- u64 wwname;
if (pci_enable_device(pdev))
goto out;
@@ -1524,10 +1523,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
* Must done after lpfc_sli_hba_setup()
*/
- memcpy(&wwname, &phba->fc_nodename, sizeof(u64));
- fc_host_node_name(host) = be64_to_cpu(wwname);
- memcpy(&wwname, &phba->fc_portname, sizeof(u64));
- fc_host_port_name(host) = be64_to_cpu(wwname);
+ fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.u.wwn);
+ fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.u.wwn);
fc_host_supported_classes(host) = FC_COS_CLASS3;
memset(fc_host_supported_fc4s(host), 0,
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 0aba13ceaacf..352df47bcaca 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -39,7 +39,7 @@
#define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */
static void *
-lpfc_pool_kmalloc(unsigned int gfp_flags, void *data)
+lpfc_pool_kmalloc(gfp_t gfp_flags, void *data)
{
return kmalloc((unsigned long)data, gfp_flags);
}
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 6f308ebe3e79..61a6fd810bb4 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -621,8 +621,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
if(islogical) {
switch (cmd->cmnd[0]) {
case TEST_UNIT_READY:
- memset(cmd->request_buffer, 0, cmd->request_bufflen);
-
#if MEGA_HAVE_CLUSTERING
/*
* Do we support clustering and is the support enabled
@@ -652,11 +650,28 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
return NULL;
#endif
- case MODE_SENSE:
+ case MODE_SENSE: {
+ char *buf;
+
+ if (cmd->use_sg) {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *)cmd->request_buffer;
+ buf = kmap_atomic(sg->page, KM_IRQ0) +
+ sg->offset;
+ } else
+ buf = cmd->request_buffer;
memset(cmd->request_buffer, 0, cmd->cmnd[4]);
+ if (cmd->use_sg) {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *)cmd->request_buffer;
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ }
cmd->result = (DID_OK << 16);
cmd->scsi_done(cmd);
return NULL;
+ }
case READ_CAPACITY:
case INQUIRY:
@@ -1685,14 +1700,23 @@ mega_rundoneq (adapter_t *adapter)
static void
mega_free_scb(adapter_t *adapter, scb_t *scb)
{
+ unsigned long length;
+
switch( scb->dma_type ) {
case MEGA_DMA_TYPE_NONE:
break;
case MEGA_BULK_DATA:
+ if (scb->cmd->use_sg == 0)
+ length = scb->cmd->request_bufflen;
+ else {
+ struct scatterlist *sgl =
+ (struct scatterlist *)scb->cmd->request_buffer;
+ length = sgl->length;
+ }
pci_unmap_page(adapter->dev, scb->dma_h_bulkdata,
- scb->cmd->request_bufflen, scb->dma_direction);
+ length, scb->dma_direction);
break;
case MEGA_SGLIST:
@@ -1741,6 +1765,7 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
struct scatterlist *sgl;
struct page *page;
unsigned long offset;
+ unsigned int length;
Scsi_Cmnd *cmd;
int sgcnt;
int idx;
@@ -1748,14 +1773,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
cmd = scb->cmd;
/* Scatter-gather not used */
- if( !cmd->use_sg ) {
-
- page = virt_to_page(cmd->request_buffer);
- offset = offset_in_page(cmd->request_buffer);
+ if( cmd->use_sg == 0 || (cmd->use_sg == 1 &&
+ !adapter->has_64bit_addr)) {
+
+ if (cmd->use_sg == 0) {
+ page = virt_to_page(cmd->request_buffer);
+ offset = offset_in_page(cmd->request_buffer);
+ length = cmd->request_bufflen;
+ } else {
+ sgl = (struct scatterlist *)cmd->request_buffer;
+ page = sgl->page;
+ offset = sgl->offset;
+ length = sgl->length;
+ }
scb->dma_h_bulkdata = pci_map_page(adapter->dev,
page, offset,
- cmd->request_bufflen,
+ length,
scb->dma_direction);
scb->dma_type = MEGA_BULK_DATA;
@@ -1765,14 +1799,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
*/
if( adapter->has_64bit_addr ) {
scb->sgl64[0].address = scb->dma_h_bulkdata;
- scb->sgl64[0].length = cmd->request_bufflen;
+ scb->sgl64[0].length = length;
*buf = (u32)scb->sgl_dma_addr;
- *len = (u32)cmd->request_bufflen;
+ *len = (u32)length;
return 1;
}
else {
*buf = (u32)scb->dma_h_bulkdata;
- *len = (u32)cmd->request_bufflen;
+ *len = (u32)length;
}
return 0;
}
@@ -1791,27 +1825,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
if( sgcnt > adapter->sglen ) BUG();
+ *len = 0;
+
for( idx = 0; idx < sgcnt; idx++, sgl++ ) {
if( adapter->has_64bit_addr ) {
scb->sgl64[idx].address = sg_dma_address(sgl);
- scb->sgl64[idx].length = sg_dma_len(sgl);
+ *len += scb->sgl64[idx].length = sg_dma_len(sgl);
}
else {
scb->sgl[idx].address = sg_dma_address(sgl);
- scb->sgl[idx].length = sg_dma_len(sgl);
+ *len += scb->sgl[idx].length = sg_dma_len(sgl);
}
}
/* Reset pointer and length fields */
*buf = scb->sgl_dma_addr;
- /*
- * For passthru command, dataxferlen must be set, even for commands
- * with a sg list
- */
- *len = (u32)cmd->request_bufflen;
-
/* Return count of SG requests */
return sgcnt;
}
diff --git a/drivers/scsi/megaraid/Kconfig.megaraid b/drivers/scsi/megaraid/Kconfig.megaraid
index 917d591d90b2..7363e12663ac 100644
--- a/drivers/scsi/megaraid/Kconfig.megaraid
+++ b/drivers/scsi/megaraid/Kconfig.megaraid
@@ -76,3 +76,12 @@ config MEGARAID_LEGACY
To compile this driver as a module, choose M here: the
module will be called megaraid
endif
+
+config MEGARAID_SAS
+ tristate "LSI Logic MegaRAID SAS RAID Module"
+ depends on PCI && SCSI
+ help
+ Module for LSI Logic's SAS based RAID controllers.
+ To compile this driver as a module, choose 'm' here.
+ Module will be called megaraid_sas
+
diff --git a/drivers/scsi/megaraid/Makefile b/drivers/scsi/megaraid/Makefile
index 6dd99f275722..f469915b97c3 100644
--- a/drivers/scsi/megaraid/Makefile
+++ b/drivers/scsi/megaraid/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_MEGARAID_MM) += megaraid_mm.o
obj-$(CONFIG_MEGARAID_MAILBOX) += megaraid_mbox.o
+obj-$(CONFIG_MEGARAID_SAS) += megaraid_sas.o
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
new file mode 100644
index 000000000000..c3f637395734
--- /dev/null
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -0,0 +1,2806 @@
+/*
+ *
+ * Linux MegaRAID driver for SAS based RAID controllers
+ *
+ * Copyright (c) 2003-2005 LSI Logic Corporation.
+ *
+ * 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.
+ *
+ * FILE : megaraid_sas.c
+ * Version : v00.00.02.00-rc4
+ *
+ * Authors:
+ * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
+ * Sumant Patro <Sumant.Patro@lsil.com>
+ *
+ * List of supported controllers
+ *
+ * OEM Product Name VID DID SSVID SSID
+ * --- ------------ --- --- ---- ----
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/version.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/uio.h>
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include "megaraid_sas.h"
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION(MEGASAS_VERSION);
+MODULE_AUTHOR("sreenivas.bagalkote@lsil.com");
+MODULE_DESCRIPTION("LSI Logic MegaRAID SAS Driver");
+
+/*
+ * PCI ID table for all supported controllers
+ */
+static struct pci_device_id megasas_pci_table[] = {
+
+ {
+ PCI_VENDOR_ID_LSI_LOGIC,
+ PCI_DEVICE_ID_LSI_SAS1064R,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ },
+ {
+ PCI_VENDOR_ID_DELL,
+ PCI_DEVICE_ID_DELL_PERC5,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ },
+ {0} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(pci, megasas_pci_table);
+
+static int megasas_mgmt_majorno;
+static struct megasas_mgmt_info megasas_mgmt_info;
+static struct fasync_struct *megasas_async_queue;
+static DECLARE_MUTEX(megasas_async_queue_mutex);
+
+/**
+ * megasas_get_cmd - Get a command from the free pool
+ * @instance: Adapter soft state
+ *
+ * Returns a free command from the pool
+ */
+static inline struct megasas_cmd *megasas_get_cmd(struct megasas_instance
+ *instance)
+{
+ unsigned long flags;
+ struct megasas_cmd *cmd = NULL;
+
+ spin_lock_irqsave(&instance->cmd_pool_lock, flags);
+
+ if (!list_empty(&instance->cmd_pool)) {
+ cmd = list_entry((&instance->cmd_pool)->next,
+ struct megasas_cmd, list);
+ list_del_init(&cmd->list);
+ } else {
+ printk(KERN_ERR "megasas: Command pool empty!\n");
+ }
+
+ spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
+ return cmd;
+}
+
+/**
+ * megasas_return_cmd - Return a cmd to free command pool
+ * @instance: Adapter soft state
+ * @cmd: Command packet to be returned to free command pool
+ */
+static inline void
+megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&instance->cmd_pool_lock, flags);
+
+ cmd->scmd = NULL;
+ list_add_tail(&cmd->list, &instance->cmd_pool);
+
+ spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
+}
+
+/**
+ * megasas_enable_intr - Enables interrupts
+ * @regs: MFI register set
+ */
+static inline void
+megasas_enable_intr(struct megasas_register_set __iomem * regs)
+{
+ writel(1, &(regs)->outbound_intr_mask);
+
+ /* Dummy readl to force pci flush */
+ readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr - Disables interrupts
+ * @regs: MFI register set
+ */
+static inline void
+megasas_disable_intr(struct megasas_register_set __iomem * regs)
+{
+ u32 mask = readl(&regs->outbound_intr_mask) & (~0x00000001);
+ writel(mask, &regs->outbound_intr_mask);
+
+ /* Dummy readl to force pci flush */
+ readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_issue_polled - Issues a polling command
+ * @instance: Adapter soft state
+ * @cmd: Command packet to be issued
+ *
+ * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
+ */
+static int
+megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ int i;
+ u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
+
+ struct megasas_header *frame_hdr = &cmd->frame->hdr;
+
+ frame_hdr->cmd_status = 0xFF;
+ frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
+
+ /*
+ * Issue the frame using inbound queue port
+ */
+ writel(cmd->frame_phys_addr >> 3,
+ &instance->reg_set->inbound_queue_port);
+
+ /*
+ * Wait for cmd_status to change
+ */
+ for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) {
+ rmb();
+ msleep(1);
+ }
+
+ if (frame_hdr->cmd_status == 0xff)
+ return -ETIME;
+
+ return 0;
+}
+
+/**
+ * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
+ * @instance: Adapter soft state
+ * @cmd: Command to be issued
+ *
+ * This function waits on an event for the command to be returned from ISR.
+ * Used to issue ioctl commands.
+ */
+static int
+megasas_issue_blocked_cmd(struct megasas_instance *instance,
+ struct megasas_cmd *cmd)
+{
+ cmd->cmd_status = ENODATA;
+
+ writel(cmd->frame_phys_addr >> 3,
+ &instance->reg_set->inbound_queue_port);
+
+ wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA));
+
+ return 0;
+}
+
+/**
+ * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
+ * @instance: Adapter soft state
+ * @cmd_to_abort: Previously issued cmd to be aborted
+ *
+ * MFI firmware can abort previously issued AEN comamnd (automatic event
+ * notification). The megasas_issue_blocked_abort_cmd() issues such abort
+ * cmd and blocks till it is completed.
+ */
+static int
+megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
+ struct megasas_cmd *cmd_to_abort)
+{
+ struct megasas_cmd *cmd;
+ struct megasas_abort_frame *abort_fr;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd)
+ return -1;
+
+ abort_fr = &cmd->frame->abort;
+
+ /*
+ * Prepare and issue the abort frame
+ */
+ abort_fr->cmd = MFI_CMD_ABORT;
+ abort_fr->cmd_status = 0xFF;
+ abort_fr->flags = 0;
+ abort_fr->abort_context = cmd_to_abort->index;
+ abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr;
+ abort_fr->abort_mfi_phys_addr_hi = 0;
+
+ cmd->sync_cmd = 1;
+ cmd->cmd_status = 0xFF;
+
+ writel(cmd->frame_phys_addr >> 3,
+ &instance->reg_set->inbound_queue_port);
+
+ /*
+ * Wait for this cmd to complete
+ */
+ wait_event(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF));
+
+ megasas_return_cmd(instance, cmd);
+ return 0;
+}
+
+/**
+ * megasas_make_sgl32 - Prepares 32-bit SGL
+ * @instance: Adapter soft state
+ * @scp: SCSI command from the mid-layer
+ * @mfi_sgl: SGL to be filled in
+ *
+ * If successful, this function returns the number of SG elements. Otherwise,
+ * it returnes -1.
+ */
+static inline int
+megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ union megasas_sgl *mfi_sgl)
+{
+ int i;
+ int sge_count;
+ struct scatterlist *os_sgl;
+
+ /*
+ * Return 0 if there is no data transfer
+ */
+ if (!scp->request_buffer || !scp->request_bufflen)
+ return 0;
+
+ if (!scp->use_sg) {
+ mfi_sgl->sge32[0].phys_addr = pci_map_single(instance->pdev,
+ scp->
+ request_buffer,
+ scp->
+ request_bufflen,
+ scp->
+ sc_data_direction);
+ mfi_sgl->sge32[0].length = scp->request_bufflen;
+
+ return 1;
+ }
+
+ os_sgl = (struct scatterlist *)scp->request_buffer;
+ sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg,
+ scp->sc_data_direction);
+
+ for (i = 0; i < sge_count; i++, os_sgl++) {
+ mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
+ mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
+ }
+
+ return sge_count;
+}
+
+/**
+ * megasas_make_sgl64 - Prepares 64-bit SGL
+ * @instance: Adapter soft state
+ * @scp: SCSI command from the mid-layer
+ * @mfi_sgl: SGL to be filled in
+ *
+ * If successful, this function returns the number of SG elements. Otherwise,
+ * it returnes -1.
+ */
+static inline int
+megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ union megasas_sgl *mfi_sgl)
+{
+ int i;
+ int sge_count;
+ struct scatterlist *os_sgl;
+
+ /*
+ * Return 0 if there is no data transfer
+ */
+ if (!scp->request_buffer || !scp->request_bufflen)
+ return 0;
+
+ if (!scp->use_sg) {
+ mfi_sgl->sge64[0].phys_addr = pci_map_single(instance->pdev,
+ scp->
+ request_buffer,
+ scp->
+ request_bufflen,
+ scp->
+ sc_data_direction);
+
+ mfi_sgl->sge64[0].length = scp->request_bufflen;
+
+ return 1;
+ }
+
+ os_sgl = (struct scatterlist *)scp->request_buffer;
+ sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg,
+ scp->sc_data_direction);
+
+ for (i = 0; i < sge_count; i++, os_sgl++) {
+ mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
+ mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
+ }
+
+ return sge_count;
+}
+
+/**
+ * megasas_build_dcdb - Prepares a direct cdb (DCDB) command
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @cmd: Command to be prepared in
+ *
+ * This function prepares CDB commands. These are typcially pass-through
+ * commands to the devices.
+ */
+static inline int
+megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ struct megasas_cmd *cmd)
+{
+ u32 sge_sz;
+ int sge_bytes;
+ u32 is_logical;
+ u32 device_id;
+ u16 flags = 0;
+ struct megasas_pthru_frame *pthru;
+
+ is_logical = MEGASAS_IS_LOGICAL(scp);
+ device_id = MEGASAS_DEV_INDEX(instance, scp);
+ pthru = (struct megasas_pthru_frame *)cmd->frame;
+
+ if (scp->sc_data_direction == PCI_DMA_TODEVICE)
+ flags = MFI_FRAME_DIR_WRITE;
+ else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+ flags = MFI_FRAME_DIR_READ;
+ else if (scp->sc_data_direction == PCI_DMA_NONE)
+ flags = MFI_FRAME_DIR_NONE;
+
+ /*
+ * Prepare the DCDB frame
+ */
+ pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
+ pthru->cmd_status = 0x0;
+ pthru->scsi_status = 0x0;
+ pthru->target_id = device_id;
+ pthru->lun = scp->device->lun;
+ pthru->cdb_len = scp->cmd_len;
+ pthru->timeout = 0;
+ pthru->flags = flags;
+ pthru->data_xfer_len = scp->request_bufflen;
+
+ memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
+
+ /*
+ * Construct SGL
+ */
+ sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+ sizeof(struct megasas_sge32);
+
+ if (IS_DMA64) {
+ pthru->flags |= MFI_FRAME_SGL64;
+ pthru->sge_count = megasas_make_sgl64(instance, scp,
+ &pthru->sgl);
+ } else
+ pthru->sge_count = megasas_make_sgl32(instance, scp,
+ &pthru->sgl);
+
+ /*
+ * Sense info specific
+ */
+ pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
+ pthru->sense_buf_phys_addr_hi = 0;
+ pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
+
+ sge_bytes = sge_sz * pthru->sge_count;
+
+ /*
+ * Compute the total number of frames this command consumes. FW uses
+ * this number to pull sufficient number of frames from host memory.
+ */
+ cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
+ ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
+
+ if (cmd->frame_count > 7)
+ cmd->frame_count = 8;
+
+ return cmd->frame_count;
+}
+
+/**
+ * megasas_build_ldio - Prepares IOs to logical devices
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @cmd: Command to to be prepared
+ *
+ * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
+ */
+static inline int
+megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ struct megasas_cmd *cmd)
+{
+ u32 sge_sz;
+ int sge_bytes;
+ u32 device_id;
+ u8 sc = scp->cmnd[0];
+ u16 flags = 0;
+ struct megasas_io_frame *ldio;
+
+ device_id = MEGASAS_DEV_INDEX(instance, scp);
+ ldio = (struct megasas_io_frame *)cmd->frame;
+
+ if (scp->sc_data_direction == PCI_DMA_TODEVICE)
+ flags = MFI_FRAME_DIR_WRITE;
+ else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+ flags = MFI_FRAME_DIR_READ;
+
+ /*
+ * Preare the Logical IO frame: 2nd bit is zero for all read cmds
+ */
+ ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
+ ldio->cmd_status = 0x0;
+ ldio->scsi_status = 0x0;
+ ldio->target_id = device_id;
+ ldio->timeout = 0;
+ ldio->reserved_0 = 0;
+ ldio->pad_0 = 0;
+ ldio->flags = flags;
+ ldio->start_lba_hi = 0;
+ ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
+
+ /*
+ * 6-byte READ(0x08) or WRITE(0x0A) cdb
+ */
+ if (scp->cmd_len == 6) {
+ ldio->lba_count = (u32) scp->cmnd[4];
+ ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) |
+ ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
+
+ ldio->start_lba_lo &= 0x1FFFFF;
+ }
+
+ /*
+ * 10-byte READ(0x28) or WRITE(0x2A) cdb
+ */
+ else if (scp->cmd_len == 10) {
+ ldio->lba_count = (u32) scp->cmnd[8] |
+ ((u32) scp->cmnd[7] << 8);
+ ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
+ ((u32) scp->cmnd[3] << 16) |
+ ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+ }
+
+ /*
+ * 12-byte READ(0xA8) or WRITE(0xAA) cdb
+ */
+ else if (scp->cmd_len == 12) {
+ ldio->lba_count = ((u32) scp->cmnd[6] << 24) |
+ ((u32) scp->cmnd[7] << 16) |
+ ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
+
+ ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
+ ((u32) scp->cmnd[3] << 16) |
+ ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+ }
+
+ /*
+ * 16-byte READ(0x88) or WRITE(0x8A) cdb
+ */
+ else if (scp->cmd_len == 16) {
+ ldio->lba_count = ((u32) scp->cmnd[10] << 24) |
+ ((u32) scp->cmnd[11] << 16) |
+ ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
+
+ ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) |
+ ((u32) scp->cmnd[7] << 16) |
+ ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
+
+ ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) |
+ ((u32) scp->cmnd[3] << 16) |
+ ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+
+ }
+
+ /*
+ * Construct SGL
+ */
+ sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+ sizeof(struct megasas_sge32);
+
+ if (IS_DMA64) {
+ ldio->flags |= MFI_FRAME_SGL64;
+ ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
+ } else
+ ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
+
+ /*
+ * Sense info specific
+ */
+ ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
+ ldio->sense_buf_phys_addr_hi = 0;
+ ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
+
+ sge_bytes = sge_sz * ldio->sge_count;
+
+ cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
+ ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
+
+ if (cmd->frame_count > 7)
+ cmd->frame_count = 8;
+
+ return cmd->frame_count;
+}
+
+/**
+ * megasas_build_cmd - Prepares a command packet
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @frame_count: [OUT] Number of frames used to prepare this command
+ */
+static inline struct megasas_cmd *megasas_build_cmd(struct megasas_instance
+ *instance,
+ struct scsi_cmnd *scp,
+ int *frame_count)
+{
+ u32 logical_cmd;
+ struct megasas_cmd *cmd;
+
+ /*
+ * Find out if this is logical or physical drive command.
+ */
+ logical_cmd = MEGASAS_IS_LOGICAL(scp);
+
+ /*
+ * Logical drive command
+ */
+ if (logical_cmd) {
+
+ if (scp->device->id >= MEGASAS_MAX_LD) {
+ scp->result = DID_BAD_TARGET << 16;
+ return NULL;
+ }
+
+ switch (scp->cmnd[0]) {
+
+ case READ_10:
+ case WRITE_10:
+ case READ_12:
+ case WRITE_12:
+ case READ_6:
+ case WRITE_6:
+ case READ_16:
+ case WRITE_16:
+ /*
+ * Fail for LUN > 0
+ */
+ if (scp->device->lun) {
+ scp->result = DID_BAD_TARGET << 16;
+ return NULL;
+ }
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ scp->result = DID_IMM_RETRY << 16;
+ return NULL;
+ }
+
+ *frame_count = megasas_build_ldio(instance, scp, cmd);
+
+ if (!(*frame_count)) {
+ megasas_return_cmd(instance, cmd);
+ return NULL;
+ }
+
+ return cmd;
+
+ default:
+ /*
+ * Fail for LUN > 0
+ */
+ if (scp->device->lun) {
+ scp->result = DID_BAD_TARGET << 16;
+ return NULL;
+ }
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ scp->result = DID_IMM_RETRY << 16;
+ return NULL;
+ }
+
+ *frame_count = megasas_build_dcdb(instance, scp, cmd);
+
+ if (!(*frame_count)) {
+ megasas_return_cmd(instance, cmd);
+ return NULL;
+ }
+
+ return cmd;
+ }
+ } else {
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ scp->result = DID_IMM_RETRY << 16;
+ return NULL;
+ }
+
+ *frame_count = megasas_build_dcdb(instance, scp, cmd);
+
+ if (!(*frame_count)) {
+ megasas_return_cmd(instance, cmd);
+ return NULL;
+ }
+
+ return cmd;
+ }
+
+ return NULL;
+}
+
+/**
+ * megasas_queue_command - Queue entry point
+ * @scmd: SCSI command to be queued
+ * @done: Callback entry point
+ */
+static int
+megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
+{
+ u32 frame_count;
+ unsigned long flags;
+ struct megasas_cmd *cmd;
+ struct megasas_instance *instance;
+
+ instance = (struct megasas_instance *)
+ scmd->device->host->hostdata;
+ scmd->scsi_done = done;
+ scmd->result = 0;
+
+ cmd = megasas_build_cmd(instance, scmd, &frame_count);
+
+ if (!cmd) {
+ done(scmd);
+ return 0;
+ }
+
+ cmd->scmd = scmd;
+ scmd->SCp.ptr = (char *)cmd;
+ scmd->SCp.sent_command = jiffies;
+
+ /*
+ * Issue the command to the FW
+ */
+ spin_lock_irqsave(&instance->instance_lock, flags);
+ instance->fw_outstanding++;
+ spin_unlock_irqrestore(&instance->instance_lock, flags);
+
+ writel(((cmd->frame_phys_addr >> 3) | (cmd->frame_count - 1)),
+ &instance->reg_set->inbound_queue_port);
+
+ return 0;
+}
+
+/**
+ * megasas_wait_for_outstanding - Wait for all outstanding cmds
+ * @instance: Adapter soft state
+ *
+ * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to
+ * complete all its outstanding commands. Returns error if one or more IOs
+ * are pending after this time period. It also marks the controller dead.
+ */
+static int megasas_wait_for_outstanding(struct megasas_instance *instance)
+{
+ int i;
+ u32 wait_time = MEGASAS_RESET_WAIT_TIME;
+
+ for (i = 0; i < wait_time; i++) {
+
+ if (!instance->fw_outstanding)
+ break;
+
+ if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
+ printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
+ "commands to complete\n", i,
+ instance->fw_outstanding);
+ }
+
+ msleep(1000);
+ }
+
+ if (instance->fw_outstanding) {
+ instance->hw_crit_error = 1;
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+/**
+ * megasas_generic_reset - Generic reset routine
+ * @scmd: Mid-layer SCSI command
+ *
+ * This routine implements a generic reset handler for device, bus and host
+ * reset requests. Device, bus and host specific reset handlers can use this
+ * function after they do their specific tasks.
+ */
+static int megasas_generic_reset(struct scsi_cmnd *scmd)
+{
+ int ret_val;
+ struct megasas_instance *instance;
+
+ instance = (struct megasas_instance *)scmd->device->host->hostdata;
+
+ printk(KERN_NOTICE "megasas: RESET -%ld cmd=%x <c=%d t=%d l=%d>\n",
+ scmd->serial_number, scmd->cmnd[0], scmd->device->channel,
+ scmd->device->id, scmd->device->lun);
+
+ if (instance->hw_crit_error) {
+ printk(KERN_ERR "megasas: cannot recover from previous reset "
+ "failures\n");
+ return FAILED;
+ }
+
+ spin_unlock(scmd->device->host->host_lock);
+
+ ret_val = megasas_wait_for_outstanding(instance);
+
+ if (ret_val == SUCCESS)
+ printk(KERN_NOTICE "megasas: reset successful \n");
+ else
+ printk(KERN_ERR "megasas: failed to do reset\n");
+
+ spin_lock(scmd->device->host->host_lock);
+
+ return ret_val;
+}
+
+static enum scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
+{
+ unsigned long seconds;
+
+ if (scmd->SCp.ptr) {
+ seconds = (jiffies - scmd->SCp.sent_command) / HZ;
+
+ if (seconds < 90) {
+ return EH_RESET_TIMER;
+ } else {
+ return EH_NOT_HANDLED;
+ }
+ }
+
+ return EH_HANDLED;
+}
+
+/**
+ * megasas_reset_device - Device reset handler entry point
+ */
+static int megasas_reset_device(struct scsi_cmnd *scmd)
+{
+ int ret;
+
+ /*
+ * First wait for all commands to complete
+ */
+ ret = megasas_generic_reset(scmd);
+
+ return ret;
+}
+
+/**
+ * megasas_reset_bus_host - Bus & host reset handler entry point
+ */
+static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
+{
+ int ret;
+
+ /*
+ * Frist wait for all commands to complete
+ */
+ ret = megasas_generic_reset(scmd);
+
+ return ret;
+}
+
+/**
+ * megasas_service_aen - Processes an event notification
+ * @instance: Adapter soft state
+ * @cmd: AEN command completed by the ISR
+ *
+ * For AEN, driver sends a command down to FW that is held by the FW till an
+ * event occurs. When an event of interest occurs, FW completes the command
+ * that it was previously holding.
+ *
+ * This routines sends SIGIO signal to processes that have registered with the
+ * driver for AEN.
+ */
+static void
+megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ /*
+ * Don't signal app if it is just an aborted previously registered aen
+ */
+ if (!cmd->abort_aen)
+ kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
+ else
+ cmd->abort_aen = 0;
+
+ instance->aen_cmd = NULL;
+ megasas_return_cmd(instance, cmd);
+}
+
+/*
+ * Scsi host template for megaraid_sas driver
+ */
+static struct scsi_host_template megasas_template = {
+
+ .module = THIS_MODULE,
+ .name = "LSI Logic SAS based MegaRAID driver",
+ .proc_name = "megaraid_sas",
+ .queuecommand = megasas_queue_command,
+ .eh_device_reset_handler = megasas_reset_device,
+ .eh_bus_reset_handler = megasas_reset_bus_host,
+ .eh_host_reset_handler = megasas_reset_bus_host,
+ .eh_timed_out = megasas_reset_timer,
+ .use_clustering = ENABLE_CLUSTERING,
+};
+
+/**
+ * megasas_complete_int_cmd - Completes an internal command
+ * @instance: Adapter soft state
+ * @cmd: Command to be completed
+ *
+ * The megasas_issue_blocked_cmd() function waits for a command to complete
+ * after it issues a command. This function wakes up that waiting routine by
+ * calling wake_up() on the wait queue.
+ */
+static void
+megasas_complete_int_cmd(struct megasas_instance *instance,
+ struct megasas_cmd *cmd)
+{
+ cmd->cmd_status = cmd->frame->io.cmd_status;
+
+ if (cmd->cmd_status == ENODATA) {
+ cmd->cmd_status = 0;
+ }
+ wake_up(&instance->int_cmd_wait_q);
+}
+
+/**
+ * megasas_complete_abort - Completes aborting a command
+ * @instance: Adapter soft state
+ * @cmd: Cmd that was issued to abort another cmd
+ *
+ * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
+ * after it issues an abort on a previously issued command. This function
+ * wakes up all functions waiting on the same wait queue.
+ */
+static void
+megasas_complete_abort(struct megasas_instance *instance,
+ struct megasas_cmd *cmd)
+{
+ if (cmd->sync_cmd) {
+ cmd->sync_cmd = 0;
+ cmd->cmd_status = 0;
+ wake_up(&instance->abort_cmd_wait_q);
+ }
+
+ return;
+}
+
+/**
+ * megasas_unmap_sgbuf - Unmap SG buffers
+ * @instance: Adapter soft state
+ * @cmd: Completed command
+ */
+static inline void
+megasas_unmap_sgbuf(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ dma_addr_t buf_h;
+ u8 opcode;
+
+ if (cmd->scmd->use_sg) {
+ pci_unmap_sg(instance->pdev, cmd->scmd->request_buffer,
+ cmd->scmd->use_sg, cmd->scmd->sc_data_direction);
+ return;
+ }
+
+ if (!cmd->scmd->request_bufflen)
+ return;
+
+ opcode = cmd->frame->hdr.cmd;
+
+ if ((opcode == MFI_CMD_LD_READ) || (opcode == MFI_CMD_LD_WRITE)) {
+ if (IS_DMA64)
+ buf_h = cmd->frame->io.sgl.sge64[0].phys_addr;
+ else
+ buf_h = cmd->frame->io.sgl.sge32[0].phys_addr;
+ } else {
+ if (IS_DMA64)
+ buf_h = cmd->frame->pthru.sgl.sge64[0].phys_addr;
+ else
+ buf_h = cmd->frame->pthru.sgl.sge32[0].phys_addr;
+ }
+
+ pci_unmap_single(instance->pdev, buf_h, cmd->scmd->request_bufflen,
+ cmd->scmd->sc_data_direction);
+ return;
+}
+
+/**
+ * megasas_complete_cmd - Completes a command
+ * @instance: Adapter soft state
+ * @cmd: Command to be completed
+ * @alt_status: If non-zero, use this value as status to
+ * SCSI mid-layer instead of the value returned
+ * by the FW. This should be used if caller wants
+ * an alternate status (as in the case of aborted
+ * commands)
+ */
+static inline void
+megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ u8 alt_status)
+{
+ int exception = 0;
+ struct megasas_header *hdr = &cmd->frame->hdr;
+ unsigned long flags;
+
+ if (cmd->scmd) {
+ cmd->scmd->SCp.ptr = (char *)0;
+ }
+
+ switch (hdr->cmd) {
+
+ case MFI_CMD_PD_SCSI_IO:
+ case MFI_CMD_LD_SCSI_IO:
+
+ /*
+ * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
+ * issued either through an IO path or an IOCTL path. If it
+ * was via IOCTL, we will send it to internal completion.
+ */
+ if (cmd->sync_cmd) {
+ cmd->sync_cmd = 0;
+ megasas_complete_int_cmd(instance, cmd);
+ break;
+ }
+
+ /*
+ * Don't export physical disk devices to mid-layer.
+ */
+ if (!MEGASAS_IS_LOGICAL(cmd->scmd) &&
+ (hdr->cmd_status == MFI_STAT_OK) &&
+ (cmd->scmd->cmnd[0] == INQUIRY)) {
+
+ if (((*(u8 *) cmd->scmd->request_buffer) & 0x1F) ==
+ TYPE_DISK) {
+ cmd->scmd->result = DID_BAD_TARGET << 16;
+ exception = 1;
+ }
+ }
+
+ case MFI_CMD_LD_READ:
+ case MFI_CMD_LD_WRITE:
+
+ if (alt_status) {
+ cmd->scmd->result = alt_status << 16;
+ exception = 1;
+ }
+
+ if (exception) {
+
+ spin_lock_irqsave(&instance->instance_lock, flags);
+ instance->fw_outstanding--;
+ spin_unlock_irqrestore(&instance->instance_lock, flags);
+
+ megasas_unmap_sgbuf(instance, cmd);
+ cmd->scmd->scsi_done(cmd->scmd);
+ megasas_return_cmd(instance, cmd);
+
+ break;
+ }
+
+ switch (hdr->cmd_status) {
+
+ case MFI_STAT_OK:
+ cmd->scmd->result = DID_OK << 16;
+ break;
+
+ case MFI_STAT_SCSI_IO_FAILED:
+ case MFI_STAT_LD_INIT_IN_PROGRESS:
+ cmd->scmd->result =
+ (DID_ERROR << 16) | hdr->scsi_status;
+ break;
+
+ case MFI_STAT_SCSI_DONE_WITH_ERROR:
+
+ cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
+
+ if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
+ memset(cmd->scmd->sense_buffer, 0,
+ SCSI_SENSE_BUFFERSIZE);
+ memcpy(cmd->scmd->sense_buffer, cmd->sense,
+ hdr->sense_len);
+
+ cmd->scmd->result |= DRIVER_SENSE << 24;
+ }
+
+ break;
+
+ case MFI_STAT_LD_OFFLINE:
+ case MFI_STAT_DEVICE_NOT_FOUND:
+ cmd->scmd->result = DID_BAD_TARGET << 16;
+ break;
+
+ default:
+ printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
+ hdr->cmd_status);
+ cmd->scmd->result = DID_ERROR << 16;
+ break;
+ }
+
+ spin_lock_irqsave(&instance->instance_lock, flags);
+ instance->fw_outstanding--;
+ spin_unlock_irqrestore(&instance->instance_lock, flags);
+
+ megasas_unmap_sgbuf(instance, cmd);
+ cmd->scmd->scsi_done(cmd->scmd);
+ megasas_return_cmd(instance, cmd);
+
+ break;
+
+ case MFI_CMD_SMP:
+ case MFI_CMD_STP:
+ case MFI_CMD_DCMD:
+
+ /*
+ * See if got an event notification
+ */
+ if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT)
+ megasas_service_aen(instance, cmd);
+ else
+ megasas_complete_int_cmd(instance, cmd);
+
+ break;
+
+ case MFI_CMD_ABORT:
+ /*
+ * Cmd issued to abort another cmd returned
+ */
+ megasas_complete_abort(instance, cmd);
+ break;
+
+ default:
+ printk("megasas: Unknown command completed! [0x%X]\n",
+ hdr->cmd);
+ break;
+ }
+}
+
+/**
+ * megasas_deplete_reply_queue - Processes all completed commands
+ * @instance: Adapter soft state
+ * @alt_status: Alternate status to be returned to
+ * SCSI mid-layer instead of the status
+ * returned by the FW
+ */
+static inline int
+megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
+{
+ u32 status;
+ u32 producer;
+ u32 consumer;
+ u32 context;
+ struct megasas_cmd *cmd;
+
+ /*
+ * Check if it is our interrupt
+ */
+ status = readl(&instance->reg_set->outbound_intr_status);
+
+ if (!(status & MFI_OB_INTR_STATUS_MASK)) {
+ return IRQ_NONE;
+ }
+
+ /*
+ * Clear the interrupt by writing back the same value
+ */
+ writel(status, &instance->reg_set->outbound_intr_status);
+
+ producer = *instance->producer;
+ consumer = *instance->consumer;
+
+ while (consumer != producer) {
+ context = instance->reply_queue[consumer];
+
+ cmd = instance->cmd_list[context];
+
+ megasas_complete_cmd(instance, cmd, alt_status);
+
+ consumer++;
+ if (consumer == (instance->max_fw_cmds + 1)) {
+ consumer = 0;
+ }
+ }
+
+ *instance->consumer = producer;
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * megasas_isr - isr entry point
+ */
+static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs)
+{
+ return megasas_deplete_reply_queue((struct megasas_instance *)devp,
+ DID_OK);
+}
+
+/**
+ * megasas_transition_to_ready - Move the FW to READY state
+ * @reg_set: MFI register set
+ *
+ * During the initialization, FW passes can potentially be in any one of
+ * several possible states. If the FW in operational, waiting-for-handshake
+ * states, driver must take steps to bring it to ready state. Otherwise, it
+ * has to wait for the ready state.
+ */
+static int
+megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
+{
+ int i;
+ u8 max_wait;
+ u32 fw_state;
+ u32 cur_state;
+
+ fw_state = readl(&reg_set->outbound_msg_0) & MFI_STATE_MASK;
+
+ while (fw_state != MFI_STATE_READY) {
+
+ printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+ " state\n");
+ switch (fw_state) {
+
+ case MFI_STATE_FAULT:
+
+ printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
+ return -ENODEV;
+
+ case MFI_STATE_WAIT_HANDSHAKE:
+ /*
+ * Set the CLR bit in inbound doorbell
+ */
+ writel(MFI_INIT_CLEAR_HANDSHAKE,
+ &reg_set->inbound_doorbell);
+
+ max_wait = 2;
+ cur_state = MFI_STATE_WAIT_HANDSHAKE;
+ break;
+
+ case MFI_STATE_OPERATIONAL:
+ /*
+ * Bring it to READY state; assuming max wait 2 secs
+ */
+ megasas_disable_intr(reg_set);
+ writel(MFI_INIT_READY, &reg_set->inbound_doorbell);
+
+ max_wait = 10;
+ cur_state = MFI_STATE_OPERATIONAL;
+ break;
+
+ case MFI_STATE_UNDEFINED:
+ /*
+ * This state should not last for more than 2 seconds
+ */
+ max_wait = 2;
+ cur_state = MFI_STATE_UNDEFINED;
+ break;
+
+ case MFI_STATE_BB_INIT:
+ max_wait = 2;
+ cur_state = MFI_STATE_BB_INIT;
+ break;
+
+ case MFI_STATE_FW_INIT:
+ max_wait = 20;
+ cur_state = MFI_STATE_FW_INIT;
+ break;
+
+ case MFI_STATE_FW_INIT_2:
+ max_wait = 20;
+ cur_state = MFI_STATE_FW_INIT_2;
+ break;
+
+ case MFI_STATE_DEVICE_SCAN:
+ max_wait = 20;
+ cur_state = MFI_STATE_DEVICE_SCAN;
+ break;
+
+ case MFI_STATE_FLUSH_CACHE:
+ max_wait = 20;
+ cur_state = MFI_STATE_FLUSH_CACHE;
+ break;
+
+ default:
+ printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
+ fw_state);
+ return -ENODEV;
+ }
+
+ /*
+ * The cur_state should not last for more than max_wait secs
+ */
+ for (i = 0; i < (max_wait * 1000); i++) {
+ fw_state = MFI_STATE_MASK &
+ readl(&reg_set->outbound_msg_0);
+
+ if (fw_state == cur_state) {
+ msleep(1);
+ } else
+ break;
+ }
+
+ /*
+ * Return error if fw_state hasn't changed after max_wait
+ */
+ if (fw_state == cur_state) {
+ printk(KERN_DEBUG "FW state [%d] hasn't changed "
+ "in %d secs\n", fw_state, max_wait);
+ return -ENODEV;
+ }
+ };
+
+ return 0;
+}
+
+/**
+ * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
+ * @instance: Adapter soft state
+ */
+static void megasas_teardown_frame_pool(struct megasas_instance *instance)
+{
+ int i;
+ u32 max_cmd = instance->max_fw_cmds;
+ struct megasas_cmd *cmd;
+
+ if (!instance->frame_dma_pool)
+ return;
+
+ /*
+ * Return all frames to pool
+ */
+ for (i = 0; i < max_cmd; i++) {
+
+ cmd = instance->cmd_list[i];
+
+ if (cmd->frame)
+ pci_pool_free(instance->frame_dma_pool, cmd->frame,
+ cmd->frame_phys_addr);
+
+ if (cmd->sense)
+ pci_pool_free(instance->sense_dma_pool, cmd->frame,
+ cmd->sense_phys_addr);
+ }
+
+ /*
+ * Now destroy the pool itself
+ */
+ pci_pool_destroy(instance->frame_dma_pool);
+ pci_pool_destroy(instance->sense_dma_pool);
+
+ instance->frame_dma_pool = NULL;
+ instance->sense_dma_pool = NULL;
+}
+
+/**
+ * megasas_create_frame_pool - Creates DMA pool for cmd frames
+ * @instance: Adapter soft state
+ *
+ * Each command packet has an embedded DMA memory buffer that is used for
+ * filling MFI frame and the SG list that immediately follows the frame. This
+ * function creates those DMA memory buffers for each command packet by using
+ * PCI pool facility.
+ */
+static int megasas_create_frame_pool(struct megasas_instance *instance)
+{
+ int i;
+ u32 max_cmd;
+ u32 sge_sz;
+ u32 sgl_sz;
+ u32 total_sz;
+ u32 frame_count;
+ struct megasas_cmd *cmd;
+
+ max_cmd = instance->max_fw_cmds;
+
+ /*
+ * Size of our frame is 64 bytes for MFI frame, followed by max SG
+ * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
+ */
+ sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+ sizeof(struct megasas_sge32);
+
+ /*
+ * Calculated the number of 64byte frames required for SGL
+ */
+ sgl_sz = sge_sz * instance->max_num_sge;
+ frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
+
+ /*
+ * We need one extra frame for the MFI command
+ */
+ frame_count++;
+
+ total_sz = MEGAMFI_FRAME_SIZE * frame_count;
+ /*
+ * Use DMA pool facility provided by PCI layer
+ */
+ instance->frame_dma_pool = pci_pool_create("megasas frame pool",
+ instance->pdev, total_sz, 64,
+ 0);
+
+ if (!instance->frame_dma_pool) {
+ printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
+ return -ENOMEM;
+ }
+
+ instance->sense_dma_pool = pci_pool_create("megasas sense pool",
+ instance->pdev, 128, 4, 0);
+
+ if (!instance->sense_dma_pool) {
+ printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
+
+ pci_pool_destroy(instance->frame_dma_pool);
+ instance->frame_dma_pool = NULL;
+
+ return -ENOMEM;
+ }
+
+ /*
+ * Allocate and attach a frame to each of the commands in cmd_list.
+ * By making cmd->index as the context instead of the &cmd, we can
+ * always use 32bit context regardless of the architecture
+ */
+ for (i = 0; i < max_cmd; i++) {
+
+ cmd = instance->cmd_list[i];
+
+ cmd->frame = pci_pool_alloc(instance->frame_dma_pool,
+ GFP_KERNEL, &cmd->frame_phys_addr);
+
+ cmd->sense = pci_pool_alloc(instance->sense_dma_pool,
+ GFP_KERNEL, &cmd->sense_phys_addr);
+
+ /*
+ * megasas_teardown_frame_pool() takes care of freeing
+ * whatever has been allocated
+ */
+ if (!cmd->frame || !cmd->sense) {
+ printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
+ megasas_teardown_frame_pool(instance);
+ return -ENOMEM;
+ }
+
+ cmd->frame->io.context = cmd->index;
+ }
+
+ return 0;
+}
+
+/**
+ * megasas_free_cmds - Free all the cmds in the free cmd pool
+ * @instance: Adapter soft state
+ */
+static void megasas_free_cmds(struct megasas_instance *instance)
+{
+ int i;
+ /* First free the MFI frame pool */
+ megasas_teardown_frame_pool(instance);
+
+ /* Free all the commands in the cmd_list */
+ for (i = 0; i < instance->max_fw_cmds; i++)
+ kfree(instance->cmd_list[i]);
+
+ /* Free the cmd_list buffer itself */
+ kfree(instance->cmd_list);
+ instance->cmd_list = NULL;
+
+ INIT_LIST_HEAD(&instance->cmd_pool);
+}
+
+/**
+ * megasas_alloc_cmds - Allocates the command packets
+ * @instance: Adapter soft state
+ *
+ * Each command that is issued to the FW, whether IO commands from the OS or
+ * internal commands like IOCTLs, are wrapped in local data structure called
+ * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
+ * the FW.
+ *
+ * Each frame has a 32-bit field called context (tag). This context is used
+ * to get back the megasas_cmd from the frame when a frame gets completed in
+ * the ISR. Typically the address of the megasas_cmd itself would be used as
+ * the context. But we wanted to keep the differences between 32 and 64 bit
+ * systems to the mininum. We always use 32 bit integers for the context. In
+ * this driver, the 32 bit values are the indices into an array cmd_list.
+ * This array is used only to look up the megasas_cmd given the context. The
+ * free commands themselves are maintained in a linked list called cmd_pool.
+ */
+static int megasas_alloc_cmds(struct megasas_instance *instance)
+{
+ int i;
+ int j;
+ u32 max_cmd;
+ struct megasas_cmd *cmd;
+
+ max_cmd = instance->max_fw_cmds;
+
+ /*
+ * instance->cmd_list is an array of struct megasas_cmd pointers.
+ * Allocate the dynamic array first and then allocate individual
+ * commands.
+ */
+ instance->cmd_list = kmalloc(sizeof(struct megasas_cmd *) * max_cmd,
+ GFP_KERNEL);
+
+ if (!instance->cmd_list) {
+ printk(KERN_DEBUG "megasas: out of memory\n");
+ return -ENOMEM;
+ }
+
+ memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) * max_cmd);
+
+ for (i = 0; i < max_cmd; i++) {
+ instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
+ GFP_KERNEL);
+
+ if (!instance->cmd_list[i]) {
+
+ for (j = 0; j < i; j++)
+ kfree(instance->cmd_list[j]);
+
+ kfree(instance->cmd_list);
+ instance->cmd_list = NULL;
+
+ return -ENOMEM;
+ }
+ }
+
+ /*
+ * Add all the commands to command pool (instance->cmd_pool)
+ */
+ for (i = 0; i < max_cmd; i++) {
+ cmd = instance->cmd_list[i];
+ memset(cmd, 0, sizeof(struct megasas_cmd));
+ cmd->index = i;
+ cmd->instance = instance;
+
+ list_add_tail(&cmd->list, &instance->cmd_pool);
+ }
+
+ /*
+ * Create a frame pool and assign one frame to each cmd
+ */
+ if (megasas_create_frame_pool(instance)) {
+ printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
+ megasas_free_cmds(instance);
+ }
+
+ return 0;
+}
+
+/**
+ * megasas_get_controller_info - Returns FW's controller structure
+ * @instance: Adapter soft state
+ * @ctrl_info: Controller information structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller structure.
+ * This information is mainly used to find out the maximum IO transfer per
+ * command supported by the FW.
+ */
+static int
+megasas_get_ctrl_info(struct megasas_instance *instance,
+ struct megasas_ctrl_info *ctrl_info)
+{
+ int ret = 0;
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+ struct megasas_ctrl_info *ci;
+ dma_addr_t ci_h = 0;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
+ return -ENOMEM;
+ }
+
+ dcmd = &cmd->frame->dcmd;
+
+ ci = pci_alloc_consistent(instance->pdev,
+ sizeof(struct megasas_ctrl_info), &ci_h);
+
+ if (!ci) {
+ printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
+ megasas_return_cmd(instance, cmd);
+ return -ENOMEM;
+ }
+
+ memset(ci, 0, sizeof(*ci));
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0xFF;
+ dcmd->sge_count = 1;
+ dcmd->flags = MFI_FRAME_DIR_READ;
+ dcmd->timeout = 0;
+ dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info);
+ dcmd->opcode = MR_DCMD_CTRL_GET_INFO;
+ dcmd->sgl.sge32[0].phys_addr = ci_h;
+ dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info);
+
+ if (!megasas_issue_polled(instance, cmd)) {
+ ret = 0;
+ memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
+ } else {
+ ret = -1;
+ }
+
+ pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
+ ci, ci_h);
+
+ megasas_return_cmd(instance, cmd);
+ return ret;
+}
+
+/**
+ * megasas_init_mfi - Initializes the FW
+ * @instance: Adapter soft state
+ *
+ * This is the main function for initializing MFI firmware.
+ */
+static int megasas_init_mfi(struct megasas_instance *instance)
+{
+ u32 context_sz;
+ u32 reply_q_sz;
+ u32 max_sectors_1;
+ u32 max_sectors_2;
+ struct megasas_register_set __iomem *reg_set;
+
+ struct megasas_cmd *cmd;
+ struct megasas_ctrl_info *ctrl_info;
+
+ struct megasas_init_frame *init_frame;
+ struct megasas_init_queue_info *initq_info;
+ dma_addr_t init_frame_h;
+ dma_addr_t initq_info_h;
+
+ /*
+ * Map the message registers
+ */
+ instance->base_addr = pci_resource_start(instance->pdev, 0);
+
+ if (pci_request_regions(instance->pdev, "megasas: LSI Logic")) {
+ printk(KERN_DEBUG "megasas: IO memory region busy!\n");
+ return -EBUSY;
+ }
+
+ instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
+
+ if (!instance->reg_set) {
+ printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
+ goto fail_ioremap;
+ }
+
+ reg_set = instance->reg_set;
+
+ /*
+ * We expect the FW state to be READY
+ */
+ if (megasas_transition_to_ready(instance->reg_set))
+ goto fail_ready_state;
+
+ /*
+ * Get various operational parameters from status register
+ */
+ instance->max_fw_cmds = readl(&reg_set->outbound_msg_0) & 0x00FFFF;
+ instance->max_num_sge = (readl(&reg_set->outbound_msg_0) & 0xFF0000) >>
+ 0x10;
+ /*
+ * Create a pool of commands
+ */
+ if (megasas_alloc_cmds(instance))
+ goto fail_alloc_cmds;
+
+ /*
+ * Allocate memory for reply queue. Length of reply queue should
+ * be _one_ more than the maximum commands handled by the firmware.
+ *
+ * Note: When FW completes commands, it places corresponding contex
+ * values in this circular reply queue. This circular queue is a fairly
+ * typical producer-consumer queue. FW is the producer (of completed
+ * commands) and the driver is the consumer.
+ */
+ context_sz = sizeof(u32);
+ reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
+
+ instance->reply_queue = pci_alloc_consistent(instance->pdev,
+ reply_q_sz,
+ &instance->reply_queue_h);
+
+ if (!instance->reply_queue) {
+ printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
+ goto fail_reply_queue;
+ }
+
+ /*
+ * Prepare a init frame. Note the init frame points to queue info
+ * structure. Each frame has SGL allocated after first 64 bytes. For
+ * this frame - since we don't need any SGL - we use SGL's space as
+ * queue info structure
+ *
+ * We will not get a NULL command below. We just created the pool.
+ */
+ cmd = megasas_get_cmd(instance);
+
+ init_frame = (struct megasas_init_frame *)cmd->frame;
+ initq_info = (struct megasas_init_queue_info *)
+ ((unsigned long)init_frame + 64);
+
+ init_frame_h = cmd->frame_phys_addr;
+ initq_info_h = init_frame_h + 64;
+
+ memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
+ memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
+
+ initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
+ initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
+
+ initq_info->producer_index_phys_addr_lo = instance->producer_h;
+ initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
+
+ init_frame->cmd = MFI_CMD_INIT;
+ init_frame->cmd_status = 0xFF;
+ init_frame->queue_info_new_phys_addr_lo = initq_info_h;
+
+ init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
+
+ /*
+ * Issue the init frame in polled mode
+ */
+ if (megasas_issue_polled(instance, cmd)) {
+ printk(KERN_DEBUG "megasas: Failed to init firmware\n");
+ goto fail_fw_init;
+ }
+
+ megasas_return_cmd(instance, cmd);
+
+ ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
+
+ /*
+ * Compute the max allowed sectors per IO: The controller info has two
+ * limits on max sectors. Driver should use the minimum of these two.
+ *
+ * 1 << stripe_sz_ops.min = max sectors per strip
+ *
+ * Note that older firmwares ( < FW ver 30) didn't report information
+ * to calculate max_sectors_1. So the number ended up as zero always.
+ */
+ if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
+
+ max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
+ ctrl_info->max_strips_per_io;
+ max_sectors_2 = ctrl_info->max_request_size;
+
+ instance->max_sectors_per_req = (max_sectors_1 < max_sectors_2)
+ ? max_sectors_1 : max_sectors_2;
+ } else
+ instance->max_sectors_per_req = instance->max_num_sge *
+ PAGE_SIZE / 512;
+
+ kfree(ctrl_info);
+
+ return 0;
+
+ fail_fw_init:
+ megasas_return_cmd(instance, cmd);
+
+ pci_free_consistent(instance->pdev, reply_q_sz,
+ instance->reply_queue, instance->reply_queue_h);
+ fail_reply_queue:
+ megasas_free_cmds(instance);
+
+ fail_alloc_cmds:
+ fail_ready_state:
+ iounmap(instance->reg_set);
+
+ fail_ioremap:
+ pci_release_regions(instance->pdev);
+
+ return -EINVAL;
+}
+
+/**
+ * megasas_release_mfi - Reverses the FW initialization
+ * @intance: Adapter soft state
+ */
+static void megasas_release_mfi(struct megasas_instance *instance)
+{
+ u32 reply_q_sz = sizeof(u32) * (instance->max_fw_cmds + 1);
+
+ pci_free_consistent(instance->pdev, reply_q_sz,
+ instance->reply_queue, instance->reply_queue_h);
+
+ megasas_free_cmds(instance);
+
+ iounmap(instance->reg_set);
+
+ pci_release_regions(instance->pdev);
+}
+
+/**
+ * megasas_get_seq_num - Gets latest event sequence numbers
+ * @instance: Adapter soft state
+ * @eli: FW event log sequence numbers information
+ *
+ * FW maintains a log of all events in a non-volatile area. Upper layers would
+ * usually find out the latest sequence number of the events, the seq number at
+ * the boot etc. They would "read" all the events below the latest seq number
+ * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
+ * number), they would subsribe to AEN (asynchronous event notification) and
+ * wait for the events to happen.
+ */
+static int
+megasas_get_seq_num(struct megasas_instance *instance,
+ struct megasas_evt_log_info *eli)
+{
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+ struct megasas_evt_log_info *el_info;
+ dma_addr_t el_info_h = 0;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ return -ENOMEM;
+ }
+
+ dcmd = &cmd->frame->dcmd;
+ el_info = pci_alloc_consistent(instance->pdev,
+ sizeof(struct megasas_evt_log_info),
+ &el_info_h);
+
+ if (!el_info) {
+ megasas_return_cmd(instance, cmd);
+ return -ENOMEM;
+ }
+
+ memset(el_info, 0, sizeof(*el_info));
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0x0;
+ dcmd->sge_count = 1;
+ dcmd->flags = MFI_FRAME_DIR_READ;
+ dcmd->timeout = 0;
+ dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info);
+ dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
+ dcmd->sgl.sge32[0].phys_addr = el_info_h;
+ dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info);
+
+ megasas_issue_blocked_cmd(instance, cmd);
+
+ /*
+ * Copy the data back into callers buffer
+ */
+ memcpy(eli, el_info, sizeof(struct megasas_evt_log_info));
+
+ pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
+ el_info, el_info_h);
+
+ megasas_return_cmd(instance, cmd);
+
+ return 0;
+}
+
+/**
+ * megasas_register_aen - Registers for asynchronous event notification
+ * @instance: Adapter soft state
+ * @seq_num: The starting sequence number
+ * @class_locale: Class of the event
+ *
+ * This function subscribes for AEN for events beyond the @seq_num. It requests
+ * to be notified if and only if the event is of type @class_locale
+ */
+static int
+megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
+ u32 class_locale_word)
+{
+ int ret_val;
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+ union megasas_evt_class_locale curr_aen;
+ union megasas_evt_class_locale prev_aen;
+
+ /*
+ * If there an AEN pending already (aen_cmd), check if the
+ * class_locale of that pending AEN is inclusive of the new
+ * AEN request we currently have. If it is, then we don't have
+ * to do anything. In other words, whichever events the current
+ * AEN request is subscribing to, have already been subscribed
+ * to.
+ *
+ * If the old_cmd is _not_ inclusive, then we have to abort
+ * that command, form a class_locale that is superset of both
+ * old and current and re-issue to the FW
+ */
+
+ curr_aen.word = class_locale_word;
+
+ if (instance->aen_cmd) {
+
+ prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
+
+ /*
+ * A class whose enum value is smaller is inclusive of all
+ * higher values. If a PROGRESS (= -1) was previously
+ * registered, then a new registration requests for higher
+ * classes need not be sent to FW. They are automatically
+ * included.
+ *
+ * Locale numbers don't have such hierarchy. They are bitmap
+ * values
+ */
+ if ((prev_aen.members.class <= curr_aen.members.class) &&
+ !((prev_aen.members.locale & curr_aen.members.locale) ^
+ curr_aen.members.locale)) {
+ /*
+ * Previously issued event registration includes
+ * current request. Nothing to do.
+ */
+ return 0;
+ } else {
+ curr_aen.members.locale |= prev_aen.members.locale;
+
+ if (prev_aen.members.class < curr_aen.members.class)
+ curr_aen.members.class = prev_aen.members.class;
+
+ instance->aen_cmd->abort_aen = 1;
+ ret_val = megasas_issue_blocked_abort_cmd(instance,
+ instance->
+ aen_cmd);
+
+ if (ret_val) {
+ printk(KERN_DEBUG "megasas: Failed to abort "
+ "previous AEN command\n");
+ return ret_val;
+ }
+ }
+ }
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd)
+ return -ENOMEM;
+
+ dcmd = &cmd->frame->dcmd;
+
+ memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
+
+ /*
+ * Prepare DCMD for aen registration
+ */
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0x0;
+ dcmd->sge_count = 1;
+ dcmd->flags = MFI_FRAME_DIR_READ;
+ dcmd->timeout = 0;
+ dcmd->data_xfer_len = sizeof(struct megasas_evt_detail);
+ dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
+ dcmd->mbox.w[0] = seq_num;
+ dcmd->mbox.w[1] = curr_aen.word;
+ dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
+ dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
+
+ /*
+ * Store reference to the cmd used to register for AEN. When an
+ * application wants us to register for AEN, we have to abort this
+ * cmd and re-register with a new EVENT LOCALE supplied by that app
+ */
+ instance->aen_cmd = cmd;
+
+ /*
+ * Issue the aen registration frame
+ */
+ writel(cmd->frame_phys_addr >> 3,
+ &instance->reg_set->inbound_queue_port);
+
+ return 0;
+}
+
+/**
+ * megasas_start_aen - Subscribes to AEN during driver load time
+ * @instance: Adapter soft state
+ */
+static int megasas_start_aen(struct megasas_instance *instance)
+{
+ struct megasas_evt_log_info eli;
+ union megasas_evt_class_locale class_locale;
+
+ /*
+ * Get the latest sequence number from FW
+ */
+ memset(&eli, 0, sizeof(eli));
+
+ if (megasas_get_seq_num(instance, &eli))
+ return -1;
+
+ /*
+ * Register AEN with FW for latest sequence number plus 1
+ */
+ class_locale.members.reserved = 0;
+ class_locale.members.locale = MR_EVT_LOCALE_ALL;
+ class_locale.members.class = MR_EVT_CLASS_DEBUG;
+
+ return megasas_register_aen(instance, eli.newest_seq_num + 1,
+ class_locale.word);
+}
+
+/**
+ * megasas_io_attach - Attaches this driver to SCSI mid-layer
+ * @instance: Adapter soft state
+ */
+static int megasas_io_attach(struct megasas_instance *instance)
+{
+ struct Scsi_Host *host = instance->host;
+
+ /*
+ * Export parameters required by SCSI mid-layer
+ */
+ host->irq = instance->pdev->irq;
+ host->unique_id = instance->unique_id;
+ host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
+ host->this_id = instance->init_id;
+ host->sg_tablesize = instance->max_num_sge;
+ host->max_sectors = instance->max_sectors_per_req;
+ host->cmd_per_lun = 128;
+ host->max_channel = MEGASAS_MAX_CHANNELS - 1;
+ host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
+ host->max_lun = MEGASAS_MAX_LUN;
+
+ /*
+ * Notify the mid-layer about the new controller
+ */
+ if (scsi_add_host(host, &instance->pdev->dev)) {
+ printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Trigger SCSI to scan our drives
+ */
+ scsi_scan_host(host);
+ return 0;
+}
+
+/**
+ * megasas_probe_one - PCI hotplug entry point
+ * @pdev: PCI device structure
+ * @id: PCI ids of supported hotplugged adapter
+ */
+static int __devinit
+megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int rval;
+ struct Scsi_Host *host;
+ struct megasas_instance *instance;
+
+ /*
+ * Announce PCI information
+ */
+ printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
+ pdev->vendor, pdev->device, pdev->subsystem_vendor,
+ pdev->subsystem_device);
+
+ printk("bus %d:slot %d:func %d\n",
+ pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+
+ /*
+ * PCI prepping: enable device set bus mastering and dma mask
+ */
+ rval = pci_enable_device(pdev);
+
+ if (rval) {
+ return rval;
+ }
+
+ pci_set_master(pdev);
+
+ /*
+ * All our contollers are capable of performing 64-bit DMA
+ */
+ if (IS_DMA64) {
+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+ goto fail_set_dma_mask;
+ }
+ } else {
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+ goto fail_set_dma_mask;
+ }
+
+ host = scsi_host_alloc(&megasas_template,
+ sizeof(struct megasas_instance));
+
+ if (!host) {
+ printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
+ goto fail_alloc_instance;
+ }
+
+ instance = (struct megasas_instance *)host->hostdata;
+ memset(instance, 0, sizeof(*instance));
+
+ instance->producer = pci_alloc_consistent(pdev, sizeof(u32),
+ &instance->producer_h);
+ instance->consumer = pci_alloc_consistent(pdev, sizeof(u32),
+ &instance->consumer_h);
+
+ if (!instance->producer || !instance->consumer) {
+ printk(KERN_DEBUG "megasas: Failed to allocate memory for "
+ "producer, consumer\n");
+ goto fail_alloc_dma_buf;
+ }
+
+ *instance->producer = 0;
+ *instance->consumer = 0;
+
+ instance->evt_detail = pci_alloc_consistent(pdev,
+ sizeof(struct
+ megasas_evt_detail),
+ &instance->evt_detail_h);
+
+ if (!instance->evt_detail) {
+ printk(KERN_DEBUG "megasas: Failed to allocate memory for "
+ "event detail structure\n");
+ goto fail_alloc_dma_buf;
+ }
+
+ /*
+ * Initialize locks and queues
+ */
+ INIT_LIST_HEAD(&instance->cmd_pool);
+
+ init_waitqueue_head(&instance->int_cmd_wait_q);
+ init_waitqueue_head(&instance->abort_cmd_wait_q);
+
+ spin_lock_init(&instance->cmd_pool_lock);
+ spin_lock_init(&instance->instance_lock);
+
+ sema_init(&instance->aen_mutex, 1);
+ sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+
+ /*
+ * Initialize PCI related and misc parameters
+ */
+ instance->pdev = pdev;
+ instance->host = host;
+ instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
+ instance->init_id = MEGASAS_DEFAULT_INIT_ID;
+
+ /*
+ * Initialize MFI Firmware
+ */
+ if (megasas_init_mfi(instance))
+ goto fail_init_mfi;
+
+ /*
+ * Register IRQ
+ */
+ if (request_irq(pdev->irq, megasas_isr, SA_SHIRQ, "megasas", instance)) {
+ printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
+ goto fail_irq;
+ }
+
+ megasas_enable_intr(instance->reg_set);
+
+ /*
+ * Store instance in PCI softstate
+ */
+ pci_set_drvdata(pdev, instance);
+
+ /*
+ * Add this controller to megasas_mgmt_info structure so that it
+ * can be exported to management applications
+ */
+ megasas_mgmt_info.count++;
+ megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
+ megasas_mgmt_info.max_index++;
+
+ /*
+ * Initiate AEN (Asynchronous Event Notification)
+ */
+ if (megasas_start_aen(instance)) {
+ printk(KERN_DEBUG "megasas: start aen failed\n");
+ goto fail_start_aen;
+ }
+
+ /*
+ * Register with SCSI mid-layer
+ */
+ if (megasas_io_attach(instance))
+ goto fail_io_attach;
+
+ return 0;
+
+ fail_start_aen:
+ fail_io_attach:
+ megasas_mgmt_info.count--;
+ megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
+ megasas_mgmt_info.max_index--;
+
+ pci_set_drvdata(pdev, NULL);
+ megasas_disable_intr(instance->reg_set);
+ free_irq(instance->pdev->irq, instance);
+
+ megasas_release_mfi(instance);
+
+ fail_irq:
+ fail_init_mfi:
+ fail_alloc_dma_buf:
+ if (instance->evt_detail)
+ pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
+ instance->evt_detail,
+ instance->evt_detail_h);
+
+ if (instance->producer)
+ pci_free_consistent(pdev, sizeof(u32), instance->producer,
+ instance->producer_h);
+ if (instance->consumer)
+ pci_free_consistent(pdev, sizeof(u32), instance->consumer,
+ instance->consumer_h);
+ scsi_host_put(host);
+
+ fail_alloc_instance:
+ fail_set_dma_mask:
+ pci_disable_device(pdev);
+
+ return -ENODEV;
+}
+
+/**
+ * megasas_flush_cache - Requests FW to flush all its caches
+ * @instance: Adapter soft state
+ */
+static void megasas_flush_cache(struct megasas_instance *instance)
+{
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd)
+ return;
+
+ dcmd = &cmd->frame->dcmd;
+
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0x0;
+ dcmd->sge_count = 0;
+ dcmd->flags = MFI_FRAME_DIR_NONE;
+ dcmd->timeout = 0;
+ dcmd->data_xfer_len = 0;
+ dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
+ dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
+
+ megasas_issue_blocked_cmd(instance, cmd);
+
+ megasas_return_cmd(instance, cmd);
+
+ return;
+}
+
+/**
+ * megasas_shutdown_controller - Instructs FW to shutdown the controller
+ * @instance: Adapter soft state
+ */
+static void megasas_shutdown_controller(struct megasas_instance *instance)
+{
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd)
+ return;
+
+ if (instance->aen_cmd)
+ megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
+
+ dcmd = &cmd->frame->dcmd;
+
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0x0;
+ dcmd->sge_count = 0;
+ dcmd->flags = MFI_FRAME_DIR_NONE;
+ dcmd->timeout = 0;
+ dcmd->data_xfer_len = 0;
+ dcmd->opcode = MR_DCMD_CTRL_SHUTDOWN;
+
+ megasas_issue_blocked_cmd(instance, cmd);
+
+ megasas_return_cmd(instance, cmd);
+
+ return;
+}
+
+/**
+ * megasas_detach_one - PCI hot"un"plug entry point
+ * @pdev: PCI device structure
+ */
+static void megasas_detach_one(struct pci_dev *pdev)
+{
+ int i;
+ struct Scsi_Host *host;
+ struct megasas_instance *instance;
+
+ instance = pci_get_drvdata(pdev);
+ host = instance->host;
+
+ scsi_remove_host(instance->host);
+ megasas_flush_cache(instance);
+ megasas_shutdown_controller(instance);
+
+ /*
+ * Take the instance off the instance array. Note that we will not
+ * decrement the max_index. We let this array be sparse array
+ */
+ for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+ if (megasas_mgmt_info.instance[i] == instance) {
+ megasas_mgmt_info.count--;
+ megasas_mgmt_info.instance[i] = NULL;
+
+ break;
+ }
+ }
+
+ pci_set_drvdata(instance->pdev, NULL);
+
+ megasas_disable_intr(instance->reg_set);
+
+ free_irq(instance->pdev->irq, instance);
+
+ megasas_release_mfi(instance);
+
+ pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
+ instance->evt_detail, instance->evt_detail_h);
+
+ pci_free_consistent(pdev, sizeof(u32), instance->producer,
+ instance->producer_h);
+
+ pci_free_consistent(pdev, sizeof(u32), instance->consumer,
+ instance->consumer_h);
+
+ scsi_host_put(host);
+
+ pci_set_drvdata(pdev, NULL);
+
+ pci_disable_device(pdev);
+
+ return;
+}
+
+/**
+ * megasas_shutdown - Shutdown entry point
+ * @device: Generic device structure
+ */
+static void megasas_shutdown(struct pci_dev *pdev)
+{
+ struct megasas_instance *instance = pci_get_drvdata(pdev);
+ megasas_flush_cache(instance);
+}
+
+/**
+ * megasas_mgmt_open - char node "open" entry point
+ */
+static int megasas_mgmt_open(struct inode *inode, struct file *filep)
+{
+ /*
+ * Allow only those users with admin rights
+ */
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ return 0;
+}
+
+/**
+ * megasas_mgmt_release - char node "release" entry point
+ */
+static int megasas_mgmt_release(struct inode *inode, struct file *filep)
+{
+ filep->private_data = NULL;
+ fasync_helper(-1, filep, 0, &megasas_async_queue);
+
+ return 0;
+}
+
+/**
+ * megasas_mgmt_fasync - Async notifier registration from applications
+ *
+ * This function adds the calling process to a driver global queue. When an
+ * event occurs, SIGIO will be sent to all processes in this queue.
+ */
+static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
+{
+ int rc;
+
+ down(&megasas_async_queue_mutex);
+
+ rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
+
+ up(&megasas_async_queue_mutex);
+
+ if (rc >= 0) {
+ /* For sanity check when we get ioctl */
+ filep->private_data = filep;
+ return 0;
+ }
+
+ printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
+
+ return rc;
+}
+
+/**
+ * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
+ * @instance: Adapter soft state
+ * @argp: User's ioctl packet
+ */
+static int
+megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ struct megasas_iocpacket __user * user_ioc,
+ struct megasas_iocpacket *ioc)
+{
+ struct megasas_sge32 *kern_sge32;
+ struct megasas_cmd *cmd;
+ void *kbuff_arr[MAX_IOCTL_SGE];
+ dma_addr_t buf_handle = 0;
+ int error = 0, i;
+ void *sense = NULL;
+ dma_addr_t sense_handle;
+ u32 *sense_ptr;
+
+ memset(kbuff_arr, 0, sizeof(kbuff_arr));
+
+ if (ioc->sge_count > MAX_IOCTL_SGE) {
+ printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n",
+ ioc->sge_count, MAX_IOCTL_SGE);
+ return -EINVAL;
+ }
+
+ cmd = megasas_get_cmd(instance);
+ if (!cmd) {
+ printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * User's IOCTL packet has 2 frames (maximum). Copy those two
+ * frames into our cmd's frames. cmd->frame's context will get
+ * overwritten when we copy from user's frames. So set that value
+ * alone separately
+ */
+ memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
+ cmd->frame->hdr.context = cmd->index;
+
+ /*
+ * The management interface between applications and the fw uses
+ * MFI frames. E.g, RAID configuration changes, LD property changes
+ * etc are accomplishes through different kinds of MFI frames. The
+ * driver needs to care only about substituting user buffers with
+ * kernel buffers in SGLs. The location of SGL is embedded in the
+ * struct iocpacket itself.
+ */
+ kern_sge32 = (struct megasas_sge32 *)
+ ((unsigned long)cmd->frame + ioc->sgl_off);
+
+ /*
+ * For each user buffer, create a mirror buffer and copy in
+ */
+ for (i = 0; i < ioc->sge_count; i++) {
+ kbuff_arr[i] = pci_alloc_consistent(instance->pdev,
+ ioc->sgl[i].iov_len,
+ &buf_handle);
+ if (!kbuff_arr[i]) {
+ printk(KERN_DEBUG "megasas: Failed to alloc "
+ "kernel SGL buffer for IOCTL \n");
+ error = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * We don't change the dma_coherent_mask, so
+ * pci_alloc_consistent only returns 32bit addresses
+ */
+ kern_sge32[i].phys_addr = (u32) buf_handle;
+ kern_sge32[i].length = ioc->sgl[i].iov_len;
+
+ /*
+ * We created a kernel buffer corresponding to the
+ * user buffer. Now copy in from the user buffer
+ */
+ if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
+ (u32) (ioc->sgl[i].iov_len))) {
+ error = -EFAULT;
+ goto out;
+ }
+ }
+
+ if (ioc->sense_len) {
+ sense = pci_alloc_consistent(instance->pdev, ioc->sense_len,
+ &sense_handle);
+ if (!sense) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ sense_ptr =
+ (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
+ *sense_ptr = sense_handle;
+ }
+
+ /*
+ * Set the sync_cmd flag so that the ISR knows not to complete this
+ * cmd to the SCSI mid-layer
+ */
+ cmd->sync_cmd = 1;
+ megasas_issue_blocked_cmd(instance, cmd);
+ cmd->sync_cmd = 0;
+
+ /*
+ * copy out the kernel buffers to user buffers
+ */
+ for (i = 0; i < ioc->sge_count; i++) {
+ if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
+ ioc->sgl[i].iov_len)) {
+ error = -EFAULT;
+ goto out;
+ }
+ }
+
+ /*
+ * copy out the sense
+ */
+ if (ioc->sense_len) {
+ /*
+ * sense_ptr points to the location that has the user
+ * sense buffer address
+ */
+ sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
+ ioc->sense_off);
+
+ if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
+ sense, ioc->sense_len)) {
+ error = -EFAULT;
+ goto out;
+ }
+ }
+
+ /*
+ * copy the status codes returned by the fw
+ */
+ if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
+ &cmd->frame->hdr.cmd_status, sizeof(u8))) {
+ printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
+ error = -EFAULT;
+ }
+
+ out:
+ if (sense) {
+ pci_free_consistent(instance->pdev, ioc->sense_len,
+ sense, sense_handle);
+ }
+
+ for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
+ pci_free_consistent(instance->pdev,
+ kern_sge32[i].length,
+ kbuff_arr[i], kern_sge32[i].phys_addr);
+ }
+
+ megasas_return_cmd(instance, cmd);
+ return error;
+}
+
+static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+{
+ int i;
+
+ for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+
+ if ((megasas_mgmt_info.instance[i]) &&
+ (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+ return megasas_mgmt_info.instance[i];
+ }
+
+ return NULL;
+}
+
+static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
+{
+ struct megasas_iocpacket __user *user_ioc =
+ (struct megasas_iocpacket __user *)arg;
+ struct megasas_iocpacket *ioc;
+ struct megasas_instance *instance;
+ int error;
+
+ ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
+ if (!ioc)
+ return -ENOMEM;
+
+ if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) {
+ error = -EFAULT;
+ goto out_kfree_ioc;
+ }
+
+ instance = megasas_lookup_instance(ioc->host_no);
+ if (!instance) {
+ error = -ENODEV;
+ goto out_kfree_ioc;
+ }
+
+ /*
+ * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
+ */
+ if (down_interruptible(&instance->ioctl_sem)) {
+ error = -ERESTARTSYS;
+ goto out_kfree_ioc;
+ }
+ error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
+ up(&instance->ioctl_sem);
+
+ out_kfree_ioc:
+ kfree(ioc);
+ return error;
+}
+
+static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
+{
+ struct megasas_instance *instance;
+ struct megasas_aen aen;
+ int error;
+
+ if (file->private_data != file) {
+ printk(KERN_DEBUG "megasas: fasync_helper was not "
+ "called first\n");
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
+ return -EFAULT;
+
+ instance = megasas_lookup_instance(aen.host_no);
+
+ if (!instance)
+ return -ENODEV;
+
+ down(&instance->aen_mutex);
+ error = megasas_register_aen(instance, aen.seq_num,
+ aen.class_locale_word);
+ up(&instance->aen_mutex);
+ return error;
+}
+
+/**
+ * megasas_mgmt_ioctl - char node ioctl entry point
+ */
+static long
+megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case MEGASAS_IOC_FIRMWARE:
+ return megasas_mgmt_ioctl_fw(file, arg);
+
+ case MEGASAS_IOC_GET_AEN:
+ return megasas_mgmt_ioctl_aen(file, arg);
+ }
+
+ return -ENOTTY;
+}
+
+#ifdef CONFIG_COMPAT
+static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
+{
+ struct compat_megasas_iocpacket __user *cioc =
+ (struct compat_megasas_iocpacket __user *)arg;
+ struct megasas_iocpacket __user *ioc =
+ compat_alloc_user_space(sizeof(struct megasas_iocpacket));
+ int i;
+ int error = 0;
+
+ clear_user(ioc, sizeof(*ioc));
+
+ if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
+ copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
+ copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
+ copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
+ copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
+ copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
+ return -EFAULT;
+
+ for (i = 0; i < MAX_IOCTL_SGE; i++) {
+ compat_uptr_t ptr;
+
+ if (get_user(ptr, &cioc->sgl[i].iov_base) ||
+ put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
+ copy_in_user(&ioc->sgl[i].iov_len,
+ &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
+ return -EFAULT;
+ }
+
+ error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
+
+ if (copy_in_user(&cioc->frame.hdr.cmd_status,
+ &ioc->frame.hdr.cmd_status, sizeof(u8))) {
+ printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
+ return -EFAULT;
+ }
+ return error;
+}
+
+static long
+megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ switch (cmd) {
+ case MEGASAS_IOC_FIRMWARE:{
+ return megasas_mgmt_compat_ioctl_fw(file, arg);
+ }
+ case MEGASAS_IOC_GET_AEN:
+ return megasas_mgmt_ioctl_aen(file, arg);
+ }
+
+ return -ENOTTY;
+}
+#endif
+
+/*
+ * File operations structure for management interface
+ */
+static struct file_operations megasas_mgmt_fops = {
+ .owner = THIS_MODULE,
+ .open = megasas_mgmt_open,
+ .release = megasas_mgmt_release,
+ .fasync = megasas_mgmt_fasync,
+ .unlocked_ioctl = megasas_mgmt_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = megasas_mgmt_compat_ioctl,
+#endif
+};
+
+/*
+ * PCI hotplug support registration structure
+ */
+static struct pci_driver megasas_pci_driver = {
+
+ .name = "megaraid_sas",
+ .id_table = megasas_pci_table,
+ .probe = megasas_probe_one,
+ .remove = __devexit_p(megasas_detach_one),
+ .shutdown = megasas_shutdown,
+};
+
+/*
+ * Sysfs driver attributes
+ */
+static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
+{
+ return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
+ MEGASAS_VERSION);
+}
+
+static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
+
+static ssize_t
+megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
+{
+ return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
+ MEGASAS_RELDATE);
+}
+
+static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
+ NULL);
+
+/**
+ * megasas_init - Driver load entry point
+ */
+static int __init megasas_init(void)
+{
+ int rval;
+
+ /*
+ * Announce driver version and other information
+ */
+ printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
+ MEGASAS_EXT_VERSION);
+
+ memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
+
+ /*
+ * Register character device node
+ */
+ rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
+
+ if (rval < 0) {
+ printk(KERN_DEBUG "megasas: failed to open device node\n");
+ return rval;
+ }
+
+ megasas_mgmt_majorno = rval;
+
+ /*
+ * Register ourselves as PCI hotplug module
+ */
+ rval = pci_module_init(&megasas_pci_driver);
+
+ if (rval) {
+ printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
+ unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
+ }
+
+ driver_create_file(&megasas_pci_driver.driver, &driver_attr_version);
+ driver_create_file(&megasas_pci_driver.driver,
+ &driver_attr_release_date);
+
+ return rval;
+}
+
+/**
+ * megasas_exit - Driver unload entry point
+ */
+static void __exit megasas_exit(void)
+{
+ driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+ driver_remove_file(&megasas_pci_driver.driver,
+ &driver_attr_release_date);
+
+ pci_unregister_driver(&megasas_pci_driver);
+ unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
+}
+
+module_init(megasas_init);
+module_exit(megasas_exit);
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
new file mode 100644
index 000000000000..eaec9d531424
--- /dev/null
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -0,0 +1,1142 @@
+/*
+ *
+ * Linux MegaRAID driver for SAS based RAID controllers
+ *
+ * Copyright (c) 2003-2005 LSI Logic Corporation.
+ *
+ * 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.
+ *
+ * FILE : megaraid_sas.h
+ */
+
+#ifndef LSI_MEGARAID_SAS_H
+#define LSI_MEGARAID_SAS_H
+
+/**
+ * MegaRAID SAS Driver meta data
+ */
+#define MEGASAS_VERSION "00.00.02.00-rc4"
+#define MEGASAS_RELDATE "Sep 16, 2005"
+#define MEGASAS_EXT_VERSION "Fri Sep 16 12:37:08 EDT 2005"
+
+/*
+ * =====================================
+ * MegaRAID SAS MFI firmware definitions
+ * =====================================
+ */
+
+/*
+ * MFI stands for MegaRAID SAS FW Interface. This is just a moniker for
+ * protocol between the software and firmware. Commands are issued using
+ * "message frames"
+ */
+
+/**
+ * FW posts its state in upper 4 bits of outbound_msg_0 register
+ */
+#define MFI_STATE_MASK 0xF0000000
+#define MFI_STATE_UNDEFINED 0x00000000
+#define MFI_STATE_BB_INIT 0x10000000
+#define MFI_STATE_FW_INIT 0x40000000
+#define MFI_STATE_WAIT_HANDSHAKE 0x60000000
+#define MFI_STATE_FW_INIT_2 0x70000000
+#define MFI_STATE_DEVICE_SCAN 0x80000000
+#define MFI_STATE_FLUSH_CACHE 0xA0000000
+#define MFI_STATE_READY 0xB0000000
+#define MFI_STATE_OPERATIONAL 0xC0000000
+#define MFI_STATE_FAULT 0xF0000000
+
+#define MEGAMFI_FRAME_SIZE 64
+
+/**
+ * During FW init, clear pending cmds & reset state using inbound_msg_0
+ *
+ * ABORT : Abort all pending cmds
+ * READY : Move from OPERATIONAL to READY state; discard queue info
+ * MFIMODE : Discard (possible) low MFA posted in 64-bit mode (??)
+ * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
+ */
+#define MFI_INIT_ABORT 0x00000000
+#define MFI_INIT_READY 0x00000002
+#define MFI_INIT_MFIMODE 0x00000004
+#define MFI_INIT_CLEAR_HANDSHAKE 0x00000008
+#define MFI_RESET_FLAGS MFI_INIT_READY|MFI_INIT_MFIMODE
+
+/**
+ * MFI frame flags
+ */
+#define MFI_FRAME_POST_IN_REPLY_QUEUE 0x0000
+#define MFI_FRAME_DONT_POST_IN_REPLY_QUEUE 0x0001
+#define MFI_FRAME_SGL32 0x0000
+#define MFI_FRAME_SGL64 0x0002
+#define MFI_FRAME_SENSE32 0x0000
+#define MFI_FRAME_SENSE64 0x0004
+#define MFI_FRAME_DIR_NONE 0x0000
+#define MFI_FRAME_DIR_WRITE 0x0008
+#define MFI_FRAME_DIR_READ 0x0010
+#define MFI_FRAME_DIR_BOTH 0x0018
+
+/**
+ * Definition for cmd_status
+ */
+#define MFI_CMD_STATUS_POLL_MODE 0xFF
+
+/**
+ * MFI command opcodes
+ */
+#define MFI_CMD_INIT 0x00
+#define MFI_CMD_LD_READ 0x01
+#define MFI_CMD_LD_WRITE 0x02
+#define MFI_CMD_LD_SCSI_IO 0x03
+#define MFI_CMD_PD_SCSI_IO 0x04
+#define MFI_CMD_DCMD 0x05
+#define MFI_CMD_ABORT 0x06
+#define MFI_CMD_SMP 0x07
+#define MFI_CMD_STP 0x08
+
+#define MR_DCMD_CTRL_GET_INFO 0x01010000
+
+#define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000
+#define MR_FLUSH_CTRL_CACHE 0x01
+#define MR_FLUSH_DISK_CACHE 0x02
+
+#define MR_DCMD_CTRL_SHUTDOWN 0x01050000
+#define MR_ENABLE_DRIVE_SPINDOWN 0x01
+
+#define MR_DCMD_CTRL_EVENT_GET_INFO 0x01040100
+#define MR_DCMD_CTRL_EVENT_GET 0x01040300
+#define MR_DCMD_CTRL_EVENT_WAIT 0x01040500
+#define MR_DCMD_LD_GET_PROPERTIES 0x03030000
+
+#define MR_DCMD_CLUSTER 0x08000000
+#define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
+#define MR_DCMD_CLUSTER_RESET_LD 0x08010200
+
+/**
+ * MFI command completion codes
+ */
+enum MFI_STAT {
+ MFI_STAT_OK = 0x00,
+ MFI_STAT_INVALID_CMD = 0x01,
+ MFI_STAT_INVALID_DCMD = 0x02,
+ MFI_STAT_INVALID_PARAMETER = 0x03,
+ MFI_STAT_INVALID_SEQUENCE_NUMBER = 0x04,
+ MFI_STAT_ABORT_NOT_POSSIBLE = 0x05,
+ MFI_STAT_APP_HOST_CODE_NOT_FOUND = 0x06,
+ MFI_STAT_APP_IN_USE = 0x07,
+ MFI_STAT_APP_NOT_INITIALIZED = 0x08,
+ MFI_STAT_ARRAY_INDEX_INVALID = 0x09,
+ MFI_STAT_ARRAY_ROW_NOT_EMPTY = 0x0a,
+ MFI_STAT_CONFIG_RESOURCE_CONFLICT = 0x0b,
+ MFI_STAT_DEVICE_NOT_FOUND = 0x0c,
+ MFI_STAT_DRIVE_TOO_SMALL = 0x0d,
+ MFI_STAT_FLASH_ALLOC_FAIL = 0x0e,
+ MFI_STAT_FLASH_BUSY = 0x0f,
+ MFI_STAT_FLASH_ERROR = 0x10,
+ MFI_STAT_FLASH_IMAGE_BAD = 0x11,
+ MFI_STAT_FLASH_IMAGE_INCOMPLETE = 0x12,
+ MFI_STAT_FLASH_NOT_OPEN = 0x13,
+ MFI_STAT_FLASH_NOT_STARTED = 0x14,
+ MFI_STAT_FLUSH_FAILED = 0x15,
+ MFI_STAT_HOST_CODE_NOT_FOUNT = 0x16,
+ MFI_STAT_LD_CC_IN_PROGRESS = 0x17,
+ MFI_STAT_LD_INIT_IN_PROGRESS = 0x18,
+ MFI_STAT_LD_LBA_OUT_OF_RANGE = 0x19,
+ MFI_STAT_LD_MAX_CONFIGURED = 0x1a,
+ MFI_STAT_LD_NOT_OPTIMAL = 0x1b,
+ MFI_STAT_LD_RBLD_IN_PROGRESS = 0x1c,
+ MFI_STAT_LD_RECON_IN_PROGRESS = 0x1d,
+ MFI_STAT_LD_WRONG_RAID_LEVEL = 0x1e,
+ MFI_STAT_MAX_SPARES_EXCEEDED = 0x1f,
+ MFI_STAT_MEMORY_NOT_AVAILABLE = 0x20,
+ MFI_STAT_MFC_HW_ERROR = 0x21,
+ MFI_STAT_NO_HW_PRESENT = 0x22,
+ MFI_STAT_NOT_FOUND = 0x23,
+ MFI_STAT_NOT_IN_ENCL = 0x24,
+ MFI_STAT_PD_CLEAR_IN_PROGRESS = 0x25,
+ MFI_STAT_PD_TYPE_WRONG = 0x26,
+ MFI_STAT_PR_DISABLED = 0x27,
+ MFI_STAT_ROW_INDEX_INVALID = 0x28,
+ MFI_STAT_SAS_CONFIG_INVALID_ACTION = 0x29,
+ MFI_STAT_SAS_CONFIG_INVALID_DATA = 0x2a,
+ MFI_STAT_SAS_CONFIG_INVALID_PAGE = 0x2b,
+ MFI_STAT_SAS_CONFIG_INVALID_TYPE = 0x2c,
+ MFI_STAT_SCSI_DONE_WITH_ERROR = 0x2d,
+ MFI_STAT_SCSI_IO_FAILED = 0x2e,
+ MFI_STAT_SCSI_RESERVATION_CONFLICT = 0x2f,
+ MFI_STAT_SHUTDOWN_FAILED = 0x30,
+ MFI_STAT_TIME_NOT_SET = 0x31,
+ MFI_STAT_WRONG_STATE = 0x32,
+ MFI_STAT_LD_OFFLINE = 0x33,
+ MFI_STAT_PEER_NOTIFICATION_REJECTED = 0x34,
+ MFI_STAT_PEER_NOTIFICATION_FAILED = 0x35,
+ MFI_STAT_RESERVATION_IN_PROGRESS = 0x36,
+ MFI_STAT_I2C_ERRORS_DETECTED = 0x37,
+ MFI_STAT_PCI_ERRORS_DETECTED = 0x38,
+
+ MFI_STAT_INVALID_STATUS = 0xFF
+};
+
+/*
+ * Number of mailbox bytes in DCMD message frame
+ */
+#define MFI_MBOX_SIZE 12
+
+enum MR_EVT_CLASS {
+
+ MR_EVT_CLASS_DEBUG = -2,
+ MR_EVT_CLASS_PROGRESS = -1,
+ MR_EVT_CLASS_INFO = 0,
+ MR_EVT_CLASS_WARNING = 1,
+ MR_EVT_CLASS_CRITICAL = 2,
+ MR_EVT_CLASS_FATAL = 3,
+ MR_EVT_CLASS_DEAD = 4,
+
+};
+
+enum MR_EVT_LOCALE {
+
+ MR_EVT_LOCALE_LD = 0x0001,
+ MR_EVT_LOCALE_PD = 0x0002,
+ MR_EVT_LOCALE_ENCL = 0x0004,
+ MR_EVT_LOCALE_BBU = 0x0008,
+ MR_EVT_LOCALE_SAS = 0x0010,
+ MR_EVT_LOCALE_CTRL = 0x0020,
+ MR_EVT_LOCALE_CONFIG = 0x0040,
+ MR_EVT_LOCALE_CLUSTER = 0x0080,
+ MR_EVT_LOCALE_ALL = 0xffff,
+
+};
+
+enum MR_EVT_ARGS {
+
+ MR_EVT_ARGS_NONE,
+ MR_EVT_ARGS_CDB_SENSE,
+ MR_EVT_ARGS_LD,
+ MR_EVT_ARGS_LD_COUNT,
+ MR_EVT_ARGS_LD_LBA,
+ MR_EVT_ARGS_LD_OWNER,
+ MR_EVT_ARGS_LD_LBA_PD_LBA,
+ MR_EVT_ARGS_LD_PROG,
+ MR_EVT_ARGS_LD_STATE,
+ MR_EVT_ARGS_LD_STRIP,
+ MR_EVT_ARGS_PD,
+ MR_EVT_ARGS_PD_ERR,
+ MR_EVT_ARGS_PD_LBA,
+ MR_EVT_ARGS_PD_LBA_LD,
+ MR_EVT_ARGS_PD_PROG,
+ MR_EVT_ARGS_PD_STATE,
+ MR_EVT_ARGS_PCI,
+ MR_EVT_ARGS_RATE,
+ MR_EVT_ARGS_STR,
+ MR_EVT_ARGS_TIME,
+ MR_EVT_ARGS_ECC,
+
+};
+
+/*
+ * SAS controller properties
+ */
+struct megasas_ctrl_prop {
+
+ u16 seq_num;
+ u16 pred_fail_poll_interval;
+ u16 intr_throttle_count;
+ u16 intr_throttle_timeouts;
+ u8 rebuild_rate;
+ u8 patrol_read_rate;
+ u8 bgi_rate;
+ u8 cc_rate;
+ u8 recon_rate;
+ u8 cache_flush_interval;
+ u8 spinup_drv_count;
+ u8 spinup_delay;
+ u8 cluster_enable;
+ u8 coercion_mode;
+ u8 alarm_enable;
+ u8 disable_auto_rebuild;
+ u8 disable_battery_warn;
+ u8 ecc_bucket_size;
+ u16 ecc_bucket_leak_rate;
+ u8 restore_hotspare_on_insertion;
+ u8 expose_encl_devices;
+ u8 reserved[38];
+
+} __attribute__ ((packed));
+
+/*
+ * SAS controller information
+ */
+struct megasas_ctrl_info {
+
+ /*
+ * PCI device information
+ */
+ struct {
+
+ u16 vendor_id;
+ u16 device_id;
+ u16 sub_vendor_id;
+ u16 sub_device_id;
+ u8 reserved[24];
+
+ } __attribute__ ((packed)) pci;
+
+ /*
+ * Host interface information
+ */
+ struct {
+
+ u8 PCIX:1;
+ u8 PCIE:1;
+ u8 iSCSI:1;
+ u8 SAS_3G:1;
+ u8 reserved_0:4;
+ u8 reserved_1[6];
+ u8 port_count;
+ u64 port_addr[8];
+
+ } __attribute__ ((packed)) host_interface;
+
+ /*
+ * Device (backend) interface information
+ */
+ struct {
+
+ u8 SPI:1;
+ u8 SAS_3G:1;
+ u8 SATA_1_5G:1;
+ u8 SATA_3G:1;
+ u8 reserved_0:4;
+ u8 reserved_1[6];
+ u8 port_count;
+ u64 port_addr[8];
+
+ } __attribute__ ((packed)) device_interface;
+
+ /*
+ * List of components residing in flash. All str are null terminated
+ */
+ u32 image_check_word;
+ u32 image_component_count;
+
+ struct {
+
+ char name[8];
+ char version[32];
+ char build_date[16];
+ char built_time[16];
+
+ } __attribute__ ((packed)) image_component[8];
+
+ /*
+ * List of flash components that have been flashed on the card, but
+ * are not in use, pending reset of the adapter. This list will be
+ * empty if a flash operation has not occurred. All stings are null
+ * terminated
+ */
+ u32 pending_image_component_count;
+
+ struct {
+
+ char name[8];
+ char version[32];
+ char build_date[16];
+ char build_time[16];
+
+ } __attribute__ ((packed)) pending_image_component[8];
+
+ u8 max_arms;
+ u8 max_spans;
+ u8 max_arrays;
+ u8 max_lds;
+
+ char product_name[80];
+ char serial_no[32];
+
+ /*
+ * Other physical/controller/operation information. Indicates the
+ * presence of the hardware
+ */
+ struct {
+
+ u32 bbu:1;
+ u32 alarm:1;
+ u32 nvram:1;
+ u32 uart:1;
+ u32 reserved:28;
+
+ } __attribute__ ((packed)) hw_present;
+
+ u32 current_fw_time;
+
+ /*
+ * Maximum data transfer sizes
+ */
+ u16 max_concurrent_cmds;
+ u16 max_sge_count;
+ u32 max_request_size;
+
+ /*
+ * Logical and physical device counts
+ */
+ u16 ld_present_count;
+ u16 ld_degraded_count;
+ u16 ld_offline_count;
+
+ u16 pd_present_count;
+ u16 pd_disk_present_count;
+ u16 pd_disk_pred_failure_count;
+ u16 pd_disk_failed_count;
+
+ /*
+ * Memory size information
+ */
+ u16 nvram_size;
+ u16 memory_size;
+ u16 flash_size;
+
+ /*
+ * Error counters
+ */
+ u16 mem_correctable_error_count;
+ u16 mem_uncorrectable_error_count;
+
+ /*
+ * Cluster information
+ */
+ u8 cluster_permitted;
+ u8 cluster_active;
+
+ /*
+ * Additional max data transfer sizes
+ */
+ u16 max_strips_per_io;
+
+ /*
+ * Controller capabilities structures
+ */
+ struct {
+
+ u32 raid_level_0:1;
+ u32 raid_level_1:1;
+ u32 raid_level_5:1;
+ u32 raid_level_1E:1;
+ u32 raid_level_6:1;
+ u32 reserved:27;
+
+ } __attribute__ ((packed)) raid_levels;
+
+ struct {
+
+ u32 rbld_rate:1;
+ u32 cc_rate:1;
+ u32 bgi_rate:1;
+ u32 recon_rate:1;
+ u32 patrol_rate:1;
+ u32 alarm_control:1;
+ u32 cluster_supported:1;
+ u32 bbu:1;
+ u32 spanning_allowed:1;
+ u32 dedicated_hotspares:1;
+ u32 revertible_hotspares:1;
+ u32 foreign_config_import:1;
+ u32 self_diagnostic:1;
+ u32 mixed_redundancy_arr:1;
+ u32 global_hot_spares:1;
+ u32 reserved:17;
+
+ } __attribute__ ((packed)) adapter_operations;
+
+ struct {
+
+ u32 read_policy:1;
+ u32 write_policy:1;
+ u32 io_policy:1;
+ u32 access_policy:1;
+ u32 disk_cache_policy:1;
+ u32 reserved:27;
+
+ } __attribute__ ((packed)) ld_operations;
+
+ struct {
+
+ u8 min;
+ u8 max;
+ u8 reserved[2];
+
+ } __attribute__ ((packed)) stripe_sz_ops;
+
+ struct {
+
+ u32 force_online:1;
+ u32 force_offline:1;
+ u32 force_rebuild:1;
+ u32 reserved:29;
+
+ } __attribute__ ((packed)) pd_operations;
+
+ struct {
+
+ u32 ctrl_supports_sas:1;
+ u32 ctrl_supports_sata:1;
+ u32 allow_mix_in_encl:1;
+ u32 allow_mix_in_ld:1;
+ u32 allow_sata_in_cluster:1;
+ u32 reserved:27;
+
+ } __attribute__ ((packed)) pd_mix_support;
+
+ /*
+ * Define ECC single-bit-error bucket information
+ */
+ u8 ecc_bucket_count;
+ u8 reserved_2[11];
+
+ /*
+ * Include the controller properties (changeable items)
+ */
+ struct megasas_ctrl_prop properties;
+
+ /*
+ * Define FW pkg version (set in envt v'bles on OEM basis)
+ */
+ char package_version[0x60];
+
+ u8 pad[0x800 - 0x6a0];
+
+} __attribute__ ((packed));
+
+/*
+ * ===============================
+ * MegaRAID SAS driver definitions
+ * ===============================
+ */
+#define MEGASAS_MAX_PD_CHANNELS 2
+#define MEGASAS_MAX_LD_CHANNELS 2
+#define MEGASAS_MAX_CHANNELS (MEGASAS_MAX_PD_CHANNELS + \
+ MEGASAS_MAX_LD_CHANNELS)
+#define MEGASAS_MAX_DEV_PER_CHANNEL 128
+#define MEGASAS_DEFAULT_INIT_ID -1
+#define MEGASAS_MAX_LUN 8
+#define MEGASAS_MAX_LD 64
+
+/*
+ * When SCSI mid-layer calls driver's reset routine, driver waits for
+ * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
+ * that the driver cannot _actually_ abort or reset pending commands. While
+ * it is waiting for the commands to complete, it prints a diagnostic message
+ * every MEGASAS_RESET_NOTICE_INTERVAL seconds
+ */
+#define MEGASAS_RESET_WAIT_TIME 180
+#define MEGASAS_RESET_NOTICE_INTERVAL 5
+
+#define MEGASAS_IOCTL_CMD 0
+
+/*
+ * FW reports the maximum of number of commands that it can accept (maximum
+ * commands that can be outstanding) at any time. The driver must report a
+ * lower number to the mid layer because it can issue a few internal commands
+ * itself (E.g, AEN, abort cmd, IOCTLs etc). The number of commands it needs
+ * is shown below
+ */
+#define MEGASAS_INT_CMDS 32
+
+/*
+ * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
+ * SGLs based on the size of dma_addr_t
+ */
+#define IS_DMA64 (sizeof(dma_addr_t) == 8)
+
+#define MFI_OB_INTR_STATUS_MASK 0x00000002
+#define MFI_POLL_TIMEOUT_SECS 10
+
+struct megasas_register_set {
+
+ u32 reserved_0[4]; /*0000h */
+
+ u32 inbound_msg_0; /*0010h */
+ u32 inbound_msg_1; /*0014h */
+ u32 outbound_msg_0; /*0018h */
+ u32 outbound_msg_1; /*001Ch */
+
+ u32 inbound_doorbell; /*0020h */
+ u32 inbound_intr_status; /*0024h */
+ u32 inbound_intr_mask; /*0028h */
+
+ u32 outbound_doorbell; /*002Ch */
+ u32 outbound_intr_status; /*0030h */
+ u32 outbound_intr_mask; /*0034h */
+
+ u32 reserved_1[2]; /*0038h */
+
+ u32 inbound_queue_port; /*0040h */
+ u32 outbound_queue_port; /*0044h */
+
+ u32 reserved_2; /*004Ch */
+
+ u32 index_registers[1004]; /*0050h */
+
+} __attribute__ ((packed));
+
+struct megasas_sge32 {
+
+ u32 phys_addr;
+ u32 length;
+
+} __attribute__ ((packed));
+
+struct megasas_sge64 {
+
+ u64 phys_addr;
+ u32 length;
+
+} __attribute__ ((packed));
+
+union megasas_sgl {
+
+ struct megasas_sge32 sge32[1];
+ struct megasas_sge64 sge64[1];
+
+} __attribute__ ((packed));
+
+struct megasas_header {
+
+ u8 cmd; /*00h */
+ u8 sense_len; /*01h */
+ u8 cmd_status; /*02h */
+ u8 scsi_status; /*03h */
+
+ u8 target_id; /*04h */
+ u8 lun; /*05h */
+ u8 cdb_len; /*06h */
+ u8 sge_count; /*07h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 timeout; /*12h */
+ u32 data_xferlen; /*14h */
+
+} __attribute__ ((packed));
+
+union megasas_sgl_frame {
+
+ struct megasas_sge32 sge32[8];
+ struct megasas_sge64 sge64[5];
+
+} __attribute__ ((packed));
+
+struct megasas_init_frame {
+
+ u8 cmd; /*00h */
+ u8 reserved_0; /*01h */
+ u8 cmd_status; /*02h */
+
+ u8 reserved_1; /*03h */
+ u32 reserved_2; /*04h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 reserved_3; /*12h */
+ u32 data_xfer_len; /*14h */
+
+ u32 queue_info_new_phys_addr_lo; /*18h */
+ u32 queue_info_new_phys_addr_hi; /*1Ch */
+ u32 queue_info_old_phys_addr_lo; /*20h */
+ u32 queue_info_old_phys_addr_hi; /*24h */
+
+ u32 reserved_4[6]; /*28h */
+
+} __attribute__ ((packed));
+
+struct megasas_init_queue_info {
+
+ u32 init_flags; /*00h */
+ u32 reply_queue_entries; /*04h */
+
+ u32 reply_queue_start_phys_addr_lo; /*08h */
+ u32 reply_queue_start_phys_addr_hi; /*0Ch */
+ u32 producer_index_phys_addr_lo; /*10h */
+ u32 producer_index_phys_addr_hi; /*14h */
+ u32 consumer_index_phys_addr_lo; /*18h */
+ u32 consumer_index_phys_addr_hi; /*1Ch */
+
+} __attribute__ ((packed));
+
+struct megasas_io_frame {
+
+ u8 cmd; /*00h */
+ u8 sense_len; /*01h */
+ u8 cmd_status; /*02h */
+ u8 scsi_status; /*03h */
+
+ u8 target_id; /*04h */
+ u8 access_byte; /*05h */
+ u8 reserved_0; /*06h */
+ u8 sge_count; /*07h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 timeout; /*12h */
+ u32 lba_count; /*14h */
+
+ u32 sense_buf_phys_addr_lo; /*18h */
+ u32 sense_buf_phys_addr_hi; /*1Ch */
+
+ u32 start_lba_lo; /*20h */
+ u32 start_lba_hi; /*24h */
+
+ union megasas_sgl sgl; /*28h */
+
+} __attribute__ ((packed));
+
+struct megasas_pthru_frame {
+
+ u8 cmd; /*00h */
+ u8 sense_len; /*01h */
+ u8 cmd_status; /*02h */
+ u8 scsi_status; /*03h */
+
+ u8 target_id; /*04h */
+ u8 lun; /*05h */
+ u8 cdb_len; /*06h */
+ u8 sge_count; /*07h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 timeout; /*12h */
+ u32 data_xfer_len; /*14h */
+
+ u32 sense_buf_phys_addr_lo; /*18h */
+ u32 sense_buf_phys_addr_hi; /*1Ch */
+
+ u8 cdb[16]; /*20h */
+ union megasas_sgl sgl; /*30h */
+
+} __attribute__ ((packed));
+
+struct megasas_dcmd_frame {
+
+ u8 cmd; /*00h */
+ u8 reserved_0; /*01h */
+ u8 cmd_status; /*02h */
+ u8 reserved_1[4]; /*03h */
+ u8 sge_count; /*07h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 timeout; /*12h */
+
+ u32 data_xfer_len; /*14h */
+ u32 opcode; /*18h */
+
+ union { /*1Ch */
+ u8 b[12];
+ u16 s[6];
+ u32 w[3];
+ } mbox;
+
+ union megasas_sgl sgl; /*28h */
+
+} __attribute__ ((packed));
+
+struct megasas_abort_frame {
+
+ u8 cmd; /*00h */
+ u8 reserved_0; /*01h */
+ u8 cmd_status; /*02h */
+
+ u8 reserved_1; /*03h */
+ u32 reserved_2; /*04h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 reserved_3; /*12h */
+ u32 reserved_4; /*14h */
+
+ u32 abort_context; /*18h */
+ u32 pad_1; /*1Ch */
+
+ u32 abort_mfi_phys_addr_lo; /*20h */
+ u32 abort_mfi_phys_addr_hi; /*24h */
+
+ u32 reserved_5[6]; /*28h */
+
+} __attribute__ ((packed));
+
+struct megasas_smp_frame {
+
+ u8 cmd; /*00h */
+ u8 reserved_1; /*01h */
+ u8 cmd_status; /*02h */
+ u8 connection_status; /*03h */
+
+ u8 reserved_2[3]; /*04h */
+ u8 sge_count; /*07h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 timeout; /*12h */
+
+ u32 data_xfer_len; /*14h */
+ u64 sas_addr; /*18h */
+
+ union {
+ struct megasas_sge32 sge32[2]; /* [0]: resp [1]: req */
+ struct megasas_sge64 sge64[2]; /* [0]: resp [1]: req */
+ } sgl;
+
+} __attribute__ ((packed));
+
+struct megasas_stp_frame {
+
+ u8 cmd; /*00h */
+ u8 reserved_1; /*01h */
+ u8 cmd_status; /*02h */
+ u8 reserved_2; /*03h */
+
+ u8 target_id; /*04h */
+ u8 reserved_3[2]; /*05h */
+ u8 sge_count; /*07h */
+
+ u32 context; /*08h */
+ u32 pad_0; /*0Ch */
+
+ u16 flags; /*10h */
+ u16 timeout; /*12h */
+
+ u32 data_xfer_len; /*14h */
+
+ u16 fis[10]; /*18h */
+ u32 stp_flags;
+
+ union {
+ struct megasas_sge32 sge32[2]; /* [0]: resp [1]: data */
+ struct megasas_sge64 sge64[2]; /* [0]: resp [1]: data */
+ } sgl;
+
+} __attribute__ ((packed));
+
+union megasas_frame {
+
+ struct megasas_header hdr;
+ struct megasas_init_frame init;
+ struct megasas_io_frame io;
+ struct megasas_pthru_frame pthru;
+ struct megasas_dcmd_frame dcmd;
+ struct megasas_abort_frame abort;
+ struct megasas_smp_frame smp;
+ struct megasas_stp_frame stp;
+
+ u8 raw_bytes[64];
+};
+
+struct megasas_cmd;
+
+union megasas_evt_class_locale {
+
+ struct {
+ u16 locale;
+ u8 reserved;
+ s8 class;
+ } __attribute__ ((packed)) members;
+
+ u32 word;
+
+} __attribute__ ((packed));
+
+struct megasas_evt_log_info {
+ u32 newest_seq_num;
+ u32 oldest_seq_num;
+ u32 clear_seq_num;
+ u32 shutdown_seq_num;
+ u32 boot_seq_num;
+
+} __attribute__ ((packed));
+
+struct megasas_progress {
+
+ u16 progress;
+ u16 elapsed_seconds;
+
+} __attribute__ ((packed));
+
+struct megasas_evtarg_ld {
+
+ u16 target_id;
+ u8 ld_index;
+ u8 reserved;
+
+} __attribute__ ((packed));
+
+struct megasas_evtarg_pd {
+ u16 device_id;
+ u8 encl_index;
+ u8 slot_number;
+
+} __attribute__ ((packed));
+
+struct megasas_evt_detail {
+
+ u32 seq_num;
+ u32 time_stamp;
+ u32 code;
+ union megasas_evt_class_locale cl;
+ u8 arg_type;
+ u8 reserved1[15];
+
+ union {
+ struct {
+ struct megasas_evtarg_pd pd;
+ u8 cdb_length;
+ u8 sense_length;
+ u8 reserved[2];
+ u8 cdb[16];
+ u8 sense[64];
+ } __attribute__ ((packed)) cdbSense;
+
+ struct megasas_evtarg_ld ld;
+
+ struct {
+ struct megasas_evtarg_ld ld;
+ u64 count;
+ } __attribute__ ((packed)) ld_count;
+
+ struct {
+ u64 lba;
+ struct megasas_evtarg_ld ld;
+ } __attribute__ ((packed)) ld_lba;
+
+ struct {
+ struct megasas_evtarg_ld ld;
+ u32 prevOwner;
+ u32 newOwner;
+ } __attribute__ ((packed)) ld_owner;
+
+ struct {
+ u64 ld_lba;
+ u64 pd_lba;
+ struct megasas_evtarg_ld ld;
+ struct megasas_evtarg_pd pd;
+ } __attribute__ ((packed)) ld_lba_pd_lba;
+
+ struct {
+ struct megasas_evtarg_ld ld;
+ struct megasas_progress prog;
+ } __attribute__ ((packed)) ld_prog;
+
+ struct {
+ struct megasas_evtarg_ld ld;
+ u32 prev_state;
+ u32 new_state;
+ } __attribute__ ((packed)) ld_state;
+
+ struct {
+ u64 strip;
+ struct megasas_evtarg_ld ld;
+ } __attribute__ ((packed)) ld_strip;
+
+ struct megasas_evtarg_pd pd;
+
+ struct {
+ struct megasas_evtarg_pd pd;
+ u32 err;
+ } __attribute__ ((packed)) pd_err;
+
+ struct {
+ u64 lba;
+ struct megasas_evtarg_pd pd;
+ } __attribute__ ((packed)) pd_lba;
+
+ struct {
+ u64 lba;
+ struct megasas_evtarg_pd pd;
+ struct megasas_evtarg_ld ld;
+ } __attribute__ ((packed)) pd_lba_ld;
+
+ struct {
+ struct megasas_evtarg_pd pd;
+ struct megasas_progress prog;
+ } __attribute__ ((packed)) pd_prog;
+
+ struct {
+ struct megasas_evtarg_pd pd;
+ u32 prevState;
+ u32 newState;
+ } __attribute__ ((packed)) pd_state;
+
+ struct {
+ u16 vendorId;
+ u16 deviceId;
+ u16 subVendorId;
+ u16 subDeviceId;
+ } __attribute__ ((packed)) pci;
+
+ u32 rate;
+ char str[96];
+
+ struct {
+ u32 rtc;
+ u32 elapsedSeconds;
+ } __attribute__ ((packed)) time;
+
+ struct {
+ u32 ecar;
+ u32 elog;
+ char str[64];
+ } __attribute__ ((packed)) ecc;
+
+ u8 b[96];
+ u16 s[48];
+ u32 w[24];
+ u64 d[12];
+ } args;
+
+ char description[128];
+
+} __attribute__ ((packed));
+
+struct megasas_instance {
+
+ u32 *producer;
+ dma_addr_t producer_h;
+ u32 *consumer;
+ dma_addr_t consumer_h;
+
+ u32 *reply_queue;
+ dma_addr_t reply_queue_h;
+
+ unsigned long base_addr;
+ struct megasas_register_set __iomem *reg_set;
+
+ s8 init_id;
+ u8 reserved[3];
+
+ u16 max_num_sge;
+ u16 max_fw_cmds;
+ u32 max_sectors_per_req;
+
+ struct megasas_cmd **cmd_list;
+ struct list_head cmd_pool;
+ spinlock_t cmd_pool_lock;
+ struct dma_pool *frame_dma_pool;
+ struct dma_pool *sense_dma_pool;
+
+ struct megasas_evt_detail *evt_detail;
+ dma_addr_t evt_detail_h;
+ struct megasas_cmd *aen_cmd;
+ struct semaphore aen_mutex;
+ struct semaphore ioctl_sem;
+
+ struct Scsi_Host *host;
+
+ wait_queue_head_t int_cmd_wait_q;
+ wait_queue_head_t abort_cmd_wait_q;
+
+ struct pci_dev *pdev;
+ u32 unique_id;
+
+ u32 fw_outstanding;
+ u32 hw_crit_error;
+ spinlock_t instance_lock;
+};
+
+#define MEGASAS_IS_LOGICAL(scp) \
+ (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
+
+#define MEGASAS_DEV_INDEX(inst, scp) \
+ ((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
+ scp->device->id
+
+struct megasas_cmd {
+
+ union megasas_frame *frame;
+ dma_addr_t frame_phys_addr;
+ u8 *sense;
+ dma_addr_t sense_phys_addr;
+
+ u32 index;
+ u8 sync_cmd;
+ u8 cmd_status;
+ u16 abort_aen;
+
+ struct list_head list;
+ struct scsi_cmnd *scmd;
+ struct megasas_instance *instance;
+ u32 frame_count;
+};
+
+#define MAX_MGMT_ADAPTERS 1024
+#define MAX_IOCTL_SGE 16
+
+struct megasas_iocpacket {
+
+ u16 host_no;
+ u16 __pad1;
+ u32 sgl_off;
+ u32 sge_count;
+ u32 sense_off;
+ u32 sense_len;
+ union {
+ u8 raw[128];
+ struct megasas_header hdr;
+ } frame;
+
+ struct iovec sgl[MAX_IOCTL_SGE];
+
+} __attribute__ ((packed));
+
+struct megasas_aen {
+ u16 host_no;
+ u16 __pad1;
+ u32 seq_num;
+ u32 class_locale_word;
+} __attribute__ ((packed));
+
+#ifdef CONFIG_COMPAT
+struct compat_megasas_iocpacket {
+ u16 host_no;
+ u16 __pad1;
+ u32 sgl_off;
+ u32 sge_count;
+ u32 sense_off;
+ u32 sense_len;
+ union {
+ u8 raw[128];
+ struct megasas_header hdr;
+ } frame;
+ struct compat_iovec sgl[MAX_IOCTL_SGE];
+} __attribute__ ((packed));
+
+#define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct compat_megasas_iocpacket)
+#else
+#define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket)
+#endif
+
+#define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen)
+
+struct megasas_mgmt_info {
+
+ u16 count;
+ struct megasas_instance *instance[MAX_MGMT_ADAPTERS];
+ int max_index;
+};
+
+#endif /*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index a4857db4f9b8..b235556b7b65 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1959,22 +1959,35 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
/* Set it up */
mesh_init(ms);
- /* XXX FIXME: error should be fatal */
- if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms))
+ /* Request interrupt */
+ if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) {
printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr);
+ goto out_shutdown;
+ }
- /* XXX FIXME: handle failure */
- scsi_add_host(mesh_host, &mdev->ofdev.dev);
+ /* Add scsi host & scan */
+ if (scsi_add_host(mesh_host, &mdev->ofdev.dev))
+ goto out_release_irq;
scsi_scan_host(mesh_host);
return 0;
-out_unmap:
+ out_release_irq:
+ free_irq(ms->meshintr, ms);
+ out_shutdown:
+ /* shutdown & reset bus in case of error or macos can be confused
+ * at reboot if the bus was set to synchronous mode already
+ */
+ mesh_shutdown(mdev);
+ set_mesh_power(ms, 0);
+ pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size,
+ ms->dma_cmd_space, ms->dma_cmd_bus);
+ out_unmap:
iounmap(ms->dma);
iounmap(ms->mesh);
-out_free:
+ out_free:
scsi_host_put(mesh_host);
-out_release:
+ out_release:
macio_release_resources(mdev);
return -ENODEV;
@@ -2001,7 +2014,7 @@ static int mesh_remove(struct macio_dev *mdev)
/* Free DMA commands memory */
pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size,
- ms->dma_cmd_space, ms->dma_cmd_bus);
+ ms->dma_cmd_space, ms->dma_cmd_bus);
/* Release memory resources */
macio_release_resources(mdev);
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 89a4a0615c22..af1133104b3f 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -1377,7 +1377,7 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi
if ((STp->buffer)->syscall_result || !SRpnt) {
printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
- vfree((void *)buffer);
+ vfree(buffer);
*aSRpnt = SRpnt;
return (-EIO);
}
@@ -1419,7 +1419,7 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi
if (new_frame > frame + 1000) {
printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
- vfree((void *)buffer);
+ vfree(buffer);
return (-EIO);
}
if ( i >= nframes + pending ) break;
@@ -1500,7 +1500,7 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi
SRpnt->sr_sense_buffer[12] == 0 &&
SRpnt->sr_sense_buffer[13] == 2) {
printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
- vfree((void *)buffer);
+ vfree(buffer);
return (-EIO); /* hit end of tape = fail */
}
i = ((SRpnt->sr_sense_buffer[3] << 24) |
@@ -1525,7 +1525,7 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi
}
if (!pending)
osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
- vfree((void *)buffer);
+ vfree(buffer);
return 0;
}
@@ -5146,7 +5146,8 @@ static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned
/* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
{
- int i, priority;
+ int i;
+ gfp_t priority;
struct osst_buffer *tb;
if (from_initialization)
@@ -5178,7 +5179,8 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
/* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
{
- int segs, nbr, max_segs, b_size, priority, order, got;
+ int segs, nbr, max_segs, b_size, order, got;
+ gfp_t priority;
if (STbuffer->buffer_size >= OS_FRAME_SIZE)
return 1;
@@ -5852,7 +5854,7 @@ static int osst_remove(struct device *dev)
os_scsi_tapes[i] = NULL;
osst_nr_dev--;
write_unlock(&os_scsi_tapes_lock);
- if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
+ vfree(tpnt->header_cache);
if (tpnt->buffer) {
normalize_buffer(tpnt->buffer);
kfree(tpnt->buffer);
@@ -5896,8 +5898,7 @@ static void __exit exit_osst (void)
for (i=0; i < osst_max_dev; ++i) {
if (!(STp = os_scsi_tapes[i])) continue;
/* This is defensive, supposed to happen during detach */
- if (STp->header_cache)
- vfree(STp->header_cache);
+ vfree(STp->header_cache);
if (STp->buffer) {
normalize_buffer(STp->buffer);
kfree(STp->buffer);
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
new file mode 100644
index 000000000000..9820f272f889
--- /dev/null
+++ b/drivers/scsi/pdc_adma.c
@@ -0,0 +1,739 @@
+/*
+ * pdc_adma.c - Pacific Digital Corporation ADMA
+ *
+ * Maintained by: Mark Lord <mlord@pobox.com>
+ *
+ * Copyright 2005 Mark Lord
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * libata documentation is available via 'make {ps|pdf}docs',
+ * as Documentation/DocBook/libata.*
+ *
+ *
+ * Supports ATA disks in single-packet ADMA mode.
+ * Uses PIO for everything else.
+ *
+ * TODO: Use ADMA transfers for ATAPI devices, when possible.
+ * This requires careful attention to a number of quirks of the chip.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include "scsi.h"
+#include <scsi/scsi_host.h>
+#include <asm/io.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "pdc_adma"
+#define DRV_VERSION "0.01"
+
+/* macro to calculate base address for ATA regs */
+#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
+
+/* macro to calculate base address for ADMA regs */
+#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
+
+enum {
+ ADMA_PORTS = 2,
+ ADMA_CPB_BYTES = 40,
+ ADMA_PRD_BYTES = LIBATA_MAX_PRD * 16,
+ ADMA_PKT_BYTES = ADMA_CPB_BYTES + ADMA_PRD_BYTES,
+
+ ADMA_DMA_BOUNDARY = 0xffffffff,
+
+ /* global register offsets */
+ ADMA_MODE_LOCK = 0x00c7,
+
+ /* per-channel register offsets */
+ ADMA_CONTROL = 0x0000, /* ADMA control */
+ ADMA_STATUS = 0x0002, /* ADMA status */
+ ADMA_CPB_COUNT = 0x0004, /* CPB count */
+ ADMA_CPB_CURRENT = 0x000c, /* current CPB address */
+ ADMA_CPB_NEXT = 0x000c, /* next CPB address */
+ ADMA_CPB_LOOKUP = 0x0010, /* CPB lookup table */
+ ADMA_FIFO_IN = 0x0014, /* input FIFO threshold */
+ ADMA_FIFO_OUT = 0x0016, /* output FIFO threshold */
+
+ /* ADMA_CONTROL register bits */
+ aNIEN = (1 << 8), /* irq mask: 1==masked */
+ aGO = (1 << 7), /* packet trigger ("Go!") */
+ aRSTADM = (1 << 5), /* ADMA logic reset */
+ aRSTA = (1 << 2), /* ATA hard reset */
+ aPIOMD4 = 0x0003, /* PIO mode 4 */
+
+ /* ADMA_STATUS register bits */
+ aPSD = (1 << 6),
+ aUIRQ = (1 << 4),
+ aPERR = (1 << 0),
+
+ /* CPB bits */
+ cDONE = (1 << 0),
+ cVLD = (1 << 0),
+ cDAT = (1 << 2),
+ cIEN = (1 << 3),
+
+ /* PRD bits */
+ pORD = (1 << 4),
+ pDIRO = (1 << 5),
+ pEND = (1 << 7),
+
+ /* ATA register flags */
+ rIGN = (1 << 5),
+ rEND = (1 << 7),
+
+ /* ATA register addresses */
+ ADMA_REGS_CONTROL = 0x0e,
+ ADMA_REGS_SECTOR_COUNT = 0x12,
+ ADMA_REGS_LBA_LOW = 0x13,
+ ADMA_REGS_LBA_MID = 0x14,
+ ADMA_REGS_LBA_HIGH = 0x15,
+ ADMA_REGS_DEVICE = 0x16,
+ ADMA_REGS_COMMAND = 0x17,
+
+ /* PCI device IDs */
+ board_1841_idx = 0, /* ADMA 2-port controller */
+};
+
+typedef enum { adma_state_idle, adma_state_pkt, adma_state_mmio } adma_state_t;
+
+struct adma_port_priv {
+ u8 *pkt;
+ dma_addr_t pkt_dma;
+ adma_state_t state;
+};
+
+static int adma_ata_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static irqreturn_t adma_intr (int irq, void *dev_instance,
+ struct pt_regs *regs);
+static int adma_port_start(struct ata_port *ap);
+static void adma_host_stop(struct ata_host_set *host_set);
+static void adma_port_stop(struct ata_port *ap);
+static void adma_phy_reset(struct ata_port *ap);
+static void adma_qc_prep(struct ata_queued_cmd *qc);
+static int adma_qc_issue(struct ata_queued_cmd *qc);
+static int adma_check_atapi_dma(struct ata_queued_cmd *qc);
+static void adma_bmdma_stop(struct ata_queued_cmd *qc);
+static u8 adma_bmdma_status(struct ata_port *ap);
+static void adma_irq_clear(struct ata_port *ap);
+static void adma_eng_timeout(struct ata_port *ap);
+
+static Scsi_Host_Template adma_ata_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .eh_strategy_handler = ata_scsi_error,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ENABLE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ADMA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+};
+
+static const struct ata_port_operations adma_ata_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .check_atapi_dma = adma_check_atapi_dma,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+ .phy_reset = adma_phy_reset,
+ .qc_prep = adma_qc_prep,
+ .qc_issue = adma_qc_issue,
+ .eng_timeout = adma_eng_timeout,
+ .irq_handler = adma_intr,
+ .irq_clear = adma_irq_clear,
+ .port_start = adma_port_start,
+ .port_stop = adma_port_stop,
+ .host_stop = adma_host_stop,
+ .bmdma_stop = adma_bmdma_stop,
+ .bmdma_status = adma_bmdma_status,
+};
+
+static struct ata_port_info adma_port_info[] = {
+ /* board_1841_idx */
+ {
+ .sht = &adma_ata_sht,
+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+ ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO,
+ .pio_mask = 0x10, /* pio4 */
+ .udma_mask = 0x1f, /* udma0-4 */
+ .port_ops = &adma_ata_ops,
+ },
+};
+
+static struct pci_device_id adma_ata_pci_tbl[] = {
+ { PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_1841_idx },
+
+ { } /* terminate list */
+};
+
+static struct pci_driver adma_ata_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = adma_ata_pci_tbl,
+ .probe = adma_ata_init_one,
+ .remove = ata_pci_remove_one,
+};
+
+static int adma_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ return 1; /* ATAPI DMA not yet supported */
+}
+
+static void adma_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ /* nothing */
+}
+
+static u8 adma_bmdma_status(struct ata_port *ap)
+{
+ return 0;
+}
+
+static void adma_irq_clear(struct ata_port *ap)
+{
+ /* nothing */
+}
+
+static void adma_reset_engine(void __iomem *chan)
+{
+ /* reset ADMA to idle state */
+ writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
+ udelay(2);
+ writew(aPIOMD4, chan + ADMA_CONTROL);
+ udelay(2);
+}
+
+static void adma_reinit_engine(struct ata_port *ap)
+{
+ struct adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio_base = ap->host_set->mmio_base;
+ void __iomem *chan = ADMA_REGS(mmio_base, ap->port_no);
+
+ /* mask/clear ATA interrupts */
+ writeb(ATA_NIEN, (void __iomem *)ap->ioaddr.ctl_addr);
+ ata_check_status(ap);
+
+ /* reset the ADMA engine */
+ adma_reset_engine(chan);
+
+ /* set in-FIFO threshold to 0x100 */
+ writew(0x100, chan + ADMA_FIFO_IN);
+
+ /* set CPB pointer */
+ writel((u32)pp->pkt_dma, chan + ADMA_CPB_NEXT);
+
+ /* set out-FIFO threshold to 0x100 */
+ writew(0x100, chan + ADMA_FIFO_OUT);
+
+ /* set CPB count */
+ writew(1, chan + ADMA_CPB_COUNT);
+
+ /* read/discard ADMA status */
+ readb(chan + ADMA_STATUS);
+}
+
+static inline void adma_enter_reg_mode(struct ata_port *ap)
+{
+ void __iomem *chan = ADMA_REGS(ap->host_set->mmio_base, ap->port_no);
+
+ writew(aPIOMD4, chan + ADMA_CONTROL);
+ readb(chan + ADMA_STATUS); /* flush */
+}
+
+static void adma_phy_reset(struct ata_port *ap)
+{
+ struct adma_port_priv *pp = ap->private_data;
+
+ pp->state = adma_state_idle;
+ adma_reinit_engine(ap);
+ ata_port_probe(ap);
+ ata_bus_reset(ap);
+}
+
+static void adma_eng_timeout(struct ata_port *ap)
+{
+ struct adma_port_priv *pp = ap->private_data;
+
+ if (pp->state != adma_state_idle) /* healthy paranoia */
+ pp->state = adma_state_mmio;
+ adma_reinit_engine(ap);
+ ata_eng_timeout(ap);
+}
+
+static int adma_fill_sg(struct ata_queued_cmd *qc)
+{
+ struct scatterlist *sg = qc->sg;
+ struct ata_port *ap = qc->ap;
+ struct adma_port_priv *pp = ap->private_data;
+ u8 *buf = pp->pkt;
+ int nelem, i = (2 + buf[3]) * 8;
+ u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
+
+ for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) {
+ u32 addr;
+ u32 len;
+
+ addr = (u32)sg_dma_address(sg);
+ *(__le32 *)(buf + i) = cpu_to_le32(addr);
+ i += 4;
+
+ len = sg_dma_len(sg) >> 3;
+ *(__le32 *)(buf + i) = cpu_to_le32(len);
+ i += 4;
+
+ if ((nelem + 1) == qc->n_elem)
+ pFLAGS |= pEND;
+ buf[i++] = pFLAGS;
+ buf[i++] = qc->dev->dma_mode & 0xf;
+ buf[i++] = 0; /* pPKLW */
+ buf[i++] = 0; /* reserved */
+
+ *(__le32 *)(buf + i)
+ = (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4);
+ i += 4;
+
+ VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem,
+ (unsigned long)addr, len);
+ }
+ return i;
+}
+
+static void adma_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct adma_port_priv *pp = qc->ap->private_data;
+ u8 *buf = pp->pkt;
+ u32 pkt_dma = (u32)pp->pkt_dma;
+ int i = 0;
+
+ VPRINTK("ENTER\n");
+
+ adma_enter_reg_mode(qc->ap);
+ if (qc->tf.protocol != ATA_PROT_DMA) {
+ ata_qc_prep(qc);
+ return;
+ }
+
+ buf[i++] = 0; /* Response flags */
+ buf[i++] = 0; /* reserved */
+ buf[i++] = cVLD | cDAT | cIEN;
+ i++; /* cLEN, gets filled in below */
+
+ *(__le32 *)(buf+i) = cpu_to_le32(pkt_dma); /* cNCPB */
+ i += 4; /* cNCPB */
+ i += 4; /* cPRD, gets filled in below */
+
+ buf[i++] = 0; /* reserved */
+ buf[i++] = 0; /* reserved */
+ buf[i++] = 0; /* reserved */
+ buf[i++] = 0; /* reserved */
+
+ /* ATA registers; must be a multiple of 4 */
+ buf[i++] = qc->tf.device;
+ buf[i++] = ADMA_REGS_DEVICE;
+ if ((qc->tf.flags & ATA_TFLAG_LBA48)) {
+ buf[i++] = qc->tf.hob_nsect;
+ buf[i++] = ADMA_REGS_SECTOR_COUNT;
+ buf[i++] = qc->tf.hob_lbal;
+ buf[i++] = ADMA_REGS_LBA_LOW;
+ buf[i++] = qc->tf.hob_lbam;
+ buf[i++] = ADMA_REGS_LBA_MID;
+ buf[i++] = qc->tf.hob_lbah;
+ buf[i++] = ADMA_REGS_LBA_HIGH;
+ }
+ buf[i++] = qc->tf.nsect;
+ buf[i++] = ADMA_REGS_SECTOR_COUNT;
+ buf[i++] = qc->tf.lbal;
+ buf[i++] = ADMA_REGS_LBA_LOW;
+ buf[i++] = qc->tf.lbam;
+ buf[i++] = ADMA_REGS_LBA_MID;
+ buf[i++] = qc->tf.lbah;
+ buf[i++] = ADMA_REGS_LBA_HIGH;
+ buf[i++] = 0;
+ buf[i++] = ADMA_REGS_CONTROL;
+ buf[i++] = rIGN;
+ buf[i++] = 0;
+ buf[i++] = qc->tf.command;
+ buf[i++] = ADMA_REGS_COMMAND | rEND;
+
+ buf[3] = (i >> 3) - 2; /* cLEN */
+ *(__le32 *)(buf+8) = cpu_to_le32(pkt_dma + i); /* cPRD */
+
+ i = adma_fill_sg(qc);
+ wmb(); /* flush PRDs and pkt to memory */
+#if 0
+ /* dump out CPB + PRDs for debug */
+ {
+ int j, len = 0;
+ static char obuf[2048];
+ for (j = 0; j < i; ++j) {
+ len += sprintf(obuf+len, "%02x ", buf[j]);
+ if ((j & 7) == 7) {
+ printk("%s\n", obuf);
+ len = 0;
+ }
+ }
+ if (len)
+ printk("%s\n", obuf);
+ }
+#endif
+}
+
+static inline void adma_packet_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *chan = ADMA_REGS(ap->host_set->mmio_base, ap->port_no);
+
+ VPRINTK("ENTER, ap %p\n", ap);
+
+ /* fire up the ADMA engine */
+ writew(aPIOMD4 | aGO, chan + ADMA_CONTROL);
+}
+
+static int adma_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct adma_port_priv *pp = qc->ap->private_data;
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ pp->state = adma_state_pkt;
+ adma_packet_start(qc);
+ return 0;
+
+ case ATA_PROT_ATAPI_DMA:
+ BUG();
+ break;
+
+ default:
+ break;
+ }
+
+ pp->state = adma_state_mmio;
+ return ata_qc_issue_prot(qc);
+}
+
+static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
+{
+ unsigned int handled = 0, port_no;
+ u8 __iomem *mmio_base = host_set->mmio_base;
+
+ for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
+ struct ata_port *ap = host_set->ports[port_no];
+ struct adma_port_priv *pp;
+ struct ata_queued_cmd *qc;
+ void __iomem *chan = ADMA_REGS(mmio_base, port_no);
+ u8 drv_stat, status = readb(chan + ADMA_STATUS);
+
+ if (status == 0)
+ continue;
+ handled = 1;
+ adma_enter_reg_mode(ap);
+ if ((ap->flags & ATA_FLAG_PORT_DISABLED))
+ continue;
+ pp = ap->private_data;
+ if (!pp || pp->state != adma_state_pkt)
+ continue;
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ drv_stat = 0;
+ if ((status & (aPERR | aPSD | aUIRQ)))
+ drv_stat = ATA_ERR;
+ else if (pp->pkt[0] != cDONE)
+ drv_stat = ATA_ERR;
+ ata_qc_complete(qc, drv_stat);
+ }
+ return handled;
+}
+
+static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
+{
+ unsigned int handled = 0, port_no;
+
+ for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
+ struct ata_port *ap;
+ ap = host_set->ports[port_no];
+ if (ap && (!(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))) {
+ struct ata_queued_cmd *qc;
+ struct adma_port_priv *pp = ap->private_data;
+ if (!pp || pp->state != adma_state_mmio)
+ continue;
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+
+ /* check main status, clearing INTRQ */
+ u8 status = ata_chk_status(ap);
+ if ((status & ATA_BUSY))
+ continue;
+ DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
+ ap->id, qc->tf.protocol, status);
+
+ /* complete taskfile transaction */
+ pp->state = adma_state_idle;
+ ata_qc_complete(qc, status);
+ handled = 1;
+ }
+ }
+ }
+ return handled;
+}
+
+static irqreturn_t adma_intr(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ata_host_set *host_set = dev_instance;
+ unsigned int handled = 0;
+
+ VPRINTK("ENTER\n");
+
+ spin_lock(&host_set->lock);
+ handled = adma_intr_pkt(host_set) | adma_intr_mmio(host_set);
+ spin_unlock(&host_set->lock);
+
+ VPRINTK("EXIT\n");
+
+ return IRQ_RETVAL(handled);
+}
+
+static void adma_ata_setup_port(struct ata_ioports *port, unsigned long base)
+{
+ port->cmd_addr =
+ port->data_addr = base + 0x000;
+ port->error_addr =
+ port->feature_addr = base + 0x004;
+ port->nsect_addr = base + 0x008;
+ port->lbal_addr = base + 0x00c;
+ port->lbam_addr = base + 0x010;
+ port->lbah_addr = base + 0x014;
+ port->device_addr = base + 0x018;
+ port->status_addr =
+ port->command_addr = base + 0x01c;
+ port->altstatus_addr =
+ port->ctl_addr = base + 0x038;
+}
+
+static int adma_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct adma_port_priv *pp;
+ int rc;
+
+ rc = ata_port_start(ap);
+ if (rc)
+ return rc;
+ adma_enter_reg_mode(ap);
+ rc = -ENOMEM;
+ pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ goto err_out;
+ pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
+ GFP_KERNEL);
+ if (!pp->pkt)
+ goto err_out_kfree;
+ /* paranoia? */
+ if ((pp->pkt_dma & 7) != 0) {
+ printk("bad alignment for pp->pkt_dma: %08x\n",
+ (u32)pp->pkt_dma);
+ goto err_out_kfree2;
+ }
+ memset(pp->pkt, 0, ADMA_PKT_BYTES);
+ ap->private_data = pp;
+ adma_reinit_engine(ap);
+ return 0;
+
+err_out_kfree2:
+ kfree(pp);
+err_out_kfree:
+ kfree(pp);
+err_out:
+ ata_port_stop(ap);
+ return rc;
+}
+
+static void adma_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct adma_port_priv *pp = ap->private_data;
+
+ adma_reset_engine(ADMA_REGS(ap->host_set->mmio_base, ap->port_no));
+ if (pp != NULL) {
+ ap->private_data = NULL;
+ if (pp->pkt != NULL)
+ dma_free_coherent(dev, ADMA_PKT_BYTES,
+ pp->pkt, pp->pkt_dma);
+ kfree(pp);
+ }
+ ata_port_stop(ap);
+}
+
+static void adma_host_stop(struct ata_host_set *host_set)
+{
+ unsigned int port_no;
+
+ for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
+ adma_reset_engine(ADMA_REGS(host_set->mmio_base, port_no));
+
+ ata_pci_host_stop(host_set);
+}
+
+static void adma_host_init(unsigned int chip_id,
+ struct ata_probe_ent *probe_ent)
+{
+ unsigned int port_no;
+ void __iomem *mmio_base = probe_ent->mmio_base;
+
+ /* enable/lock aGO operation */
+ writeb(7, mmio_base + ADMA_MODE_LOCK);
+
+ /* reset the ADMA logic */
+ for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
+ adma_reset_engine(ADMA_REGS(mmio_base, port_no));
+}
+
+static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
+{
+ int rc;
+
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ printk(KERN_ERR DRV_NAME
+ "(%s): 32-bit DMA enable failed\n",
+ pci_name(pdev));
+ return rc;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ printk(KERN_ERR DRV_NAME
+ "(%s): 32-bit consistent DMA enable failed\n",
+ pci_name(pdev));
+ return rc;
+ }
+ return 0;
+}
+
+static int adma_ata_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ static int printed_version;
+ struct ata_probe_ent *probe_ent = NULL;
+ void __iomem *mmio_base;
+ unsigned int board_idx = (unsigned int) ent->driver_data;
+ int rc, port_no;
+
+ if (!printed_version++)
+ printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto err_out;
+
+ if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
+ rc = -ENODEV;
+ goto err_out_regions;
+ }
+
+ mmio_base = pci_iomap(pdev, 4, 0);
+ if (mmio_base == NULL) {
+ rc = -ENOMEM;
+ goto err_out_regions;
+ }
+
+ rc = adma_set_dma_masks(pdev, mmio_base);
+ if (rc)
+ goto err_out_iounmap;
+
+ probe_ent = kcalloc(1, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL) {
+ rc = -ENOMEM;
+ goto err_out_iounmap;
+ }
+
+ probe_ent->dev = pci_dev_to_dev(pdev);
+ INIT_LIST_HEAD(&probe_ent->node);
+
+ probe_ent->sht = adma_port_info[board_idx].sht;
+ probe_ent->host_flags = adma_port_info[board_idx].host_flags;
+ probe_ent->pio_mask = adma_port_info[board_idx].pio_mask;
+ probe_ent->mwdma_mask = adma_port_info[board_idx].mwdma_mask;
+ probe_ent->udma_mask = adma_port_info[board_idx].udma_mask;
+ probe_ent->port_ops = adma_port_info[board_idx].port_ops;
+
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->mmio_base = mmio_base;
+ probe_ent->n_ports = ADMA_PORTS;
+
+ for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
+ adma_ata_setup_port(&probe_ent->port[port_no],
+ ADMA_ATA_REGS((unsigned long)mmio_base, port_no));
+ }
+
+ pci_set_master(pdev);
+
+ /* initialize adapter */
+ adma_host_init(board_idx, probe_ent);
+
+ rc = ata_device_add(probe_ent);
+ kfree(probe_ent);
+ if (rc != ADMA_PORTS)
+ goto err_out_iounmap;
+ return 0;
+
+err_out_iounmap:
+ pci_iounmap(pdev, mmio_base);
+err_out_regions:
+ pci_release_regions(pdev);
+err_out:
+ pci_disable_device(pdev);
+ return rc;
+}
+
+static int __init adma_ata_init(void)
+{
+ return pci_module_init(&adma_ata_pci_driver);
+}
+
+static void __exit adma_ata_exit(void)
+{
+ pci_unregister_driver(&adma_ata_pci_driver);
+}
+
+MODULE_AUTHOR("Mark Lord");
+MODULE_DESCRIPTION("Pacific Digital Corporation ADMA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, adma_ata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(adma_ata_init);
+module_exit(adma_ata_exit);
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 623082d3a83f..c89da7d5b6df 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -95,8 +95,7 @@ int __init pluto_detect(Scsi_Host_Template *tpnt)
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_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index fe0fce71adc7..fc25cd834668 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -360,16 +360,16 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
scsi_qla_host_t *ha = to_qla_host(host);
fc_port_t *fcport;
- uint64_t node_name = 0;
+ u64 node_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
if (starget->id == fcport->os_target_id) {
- node_name = *(uint64_t *)fcport->node_name;
+ node_name = wwn_to_u64(fcport->node_name);
break;
}
}
- fc_starget_node_name(starget) = be64_to_cpu(node_name);
+ fc_starget_node_name(starget) = node_name;
}
static void
@@ -378,16 +378,16 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
scsi_qla_host_t *ha = to_qla_host(host);
fc_port_t *fcport;
- uint64_t port_name = 0;
+ u64 port_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
if (starget->id == fcport->os_target_id) {
- port_name = *(uint64_t *)fcport->port_name;
+ port_name = wwn_to_u64(fcport->port_name);
break;
}
}
- fc_starget_port_name(starget) = be64_to_cpu(port_name);
+ fc_starget_port_name(starget) = port_name;
}
static void
@@ -460,9 +460,7 @@ struct fc_function_template qla2xxx_transport_functions = {
void
qla2x00_init_host_attr(scsi_qla_host_t *ha)
{
- fc_host_node_name(ha->host) =
- be64_to_cpu(*(uint64_t *)ha->init_cb->node_name);
- fc_host_port_name(ha->host) =
- be64_to_cpu(*(uint64_t *)ha->init_cb->port_name);
+ fc_host_node_name(ha->host) = wwn_to_u64(ha->init_cb->node_name);
+ fc_host_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 72bbaa91dc77..9791496fa788 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1334,7 +1334,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
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/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 1ed32e7b5472..e451941ad81d 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -52,7 +52,7 @@ extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
-extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, int);
+extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
@@ -277,7 +277,7 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_rscn.c source file.
*/
-extern fc_port_t *qla2x00_alloc_rscn_fcport(scsi_qla_host_t *, int);
+extern fc_port_t *qla2x00_alloc_rscn_fcport(scsi_qla_host_t *, gfp_t);
extern int qla2x00_handle_port_rscn(scsi_qla_host_t *, uint32_t, fc_port_t *,
int);
extern void qla2x00_process_iodesc(scsi_qla_host_t *, struct mbx_entry *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index c619583e646b..fbb6feee40cf 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -201,6 +201,7 @@ int
qla2100_pci_config(scsi_qla_host_t *ha)
{
uint16_t w, mwi;
+ uint32_t d;
unsigned long flags;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
@@ -215,9 +216,9 @@ qla2100_pci_config(scsi_qla_host_t *ha)
pci_write_config_word(ha->pdev, PCI_COMMAND, w);
/* Reset expansion ROM address decode enable */
- pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w);
- w &= ~PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w);
+ pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
+ d &= ~PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
/* Get PCI bus information. */
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -237,6 +238,7 @@ int
qla2300_pci_config(scsi_qla_host_t *ha)
{
uint16_t w, mwi;
+ uint32_t d;
unsigned long flags = 0;
uint32_t cnt;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
@@ -302,9 +304,9 @@ qla2300_pci_config(scsi_qla_host_t *ha)
pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
/* Reset expansion ROM address decode enable */
- pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w);
- w &= ~PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w);
+ pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
+ d &= ~PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
/* Get PCI bus information. */
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -324,6 +326,7 @@ int
qla24xx_pci_config(scsi_qla_host_t *ha)
{
uint16_t w, mwi;
+ uint32_t d;
unsigned long flags = 0;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
int pcix_cmd_reg, pcie_dctl_reg;
@@ -366,9 +369,9 @@ qla24xx_pci_config(scsi_qla_host_t *ha)
}
/* Reset expansion ROM address decode enable */
- pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w);
- w &= ~PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w);
+ pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
+ d &= ~PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
/* Get PCI bus information. */
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1682,7 +1685,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
* Returns a pointer to the allocated fcport, or NULL, if none available.
*/
fc_port_t *
-qla2x00_alloc_fcport(scsi_qla_host_t *ha, int flags)
+qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
{
fc_port_t *fcport;
@@ -2066,8 +2069,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
return;
}
- rport_ids.node_name = be64_to_cpu(*(uint64_t *)fcport->node_name);
- rport_ids.port_name = be64_to_cpu(*(uint64_t *)fcport->port_name);
+ rport_ids.node_name = wwn_to_u64(fcport->node_name);
+ rport_ids.port_name = wwn_to_u64(fcport->port_name);
rport_ids.port_id = fcport->d_id.b.domain << 16 |
fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 8982978c42fd..7aec93f9d423 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1325,6 +1325,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
ha->brd_info = brd_info;
sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
+ ha->dpc_pid = -1;
+
/* Configure PCI I/O space */
ret = qla2x00_iospace_config(ha);
if (ret)
@@ -1448,7 +1450,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
*/
spin_lock_init(&ha->mbx_reg_lock);
- ha->dpc_pid = -1;
init_completion(&ha->dpc_inited);
init_completion(&ha->dpc_exited);
diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c
index bdc3bc74bbe1..7534efcc8918 100644
--- a/drivers/scsi/qla2xxx/qla_rscn.c
+++ b/drivers/scsi/qla2xxx/qla_rscn.c
@@ -330,6 +330,8 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
fcport->flags &= ~FCF_FAILOVER_NEEDED;
fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
atomic_set(&fcport->state, FCS_ONLINE);
+ if (fcport->rport)
+ fc_remote_port_unblock(fcport->rport);
}
@@ -1064,7 +1066,7 @@ qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
* Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
*/
fc_port_t *
-qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, int flags)
+qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, gfp_t flags)
{
fc_port_t *fcport;
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index a917ab7475ac..1fd5fc6d0fe3 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1119,6 +1119,36 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int
host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
}
+static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out)
+{
+ unsigned char *buf;
+ unsigned int buflen;
+
+ if (cmd->use_sg) {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *) cmd->request_buffer;
+ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buflen = sg->length;
+ } else {
+ buf = cmd->request_buffer;
+ buflen = cmd->request_bufflen;
+ }
+
+ *buf_out = buf;
+ return buflen;
+}
+
+static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf)
+{
+ if (cmd->use_sg) {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *) cmd->request_buffer;
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ }
+}
+
/*
* Until we scan the entire bus with inquiries, go throught this fella...
*/
@@ -1145,11 +1175,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
int ok = host_byte(Cmnd->result) == DID_OK;
if (Cmnd->cmnd[0] == 0x12 && ok) {
unsigned char *iqd;
+ unsigned int iqd_len;
- if (Cmnd->use_sg != 0)
- BUG();
-
- iqd = ((unsigned char *)Cmnd->buffer);
+ iqd_len = scsi_rbuf_get(Cmnd, &iqd);
/* tags handled in midlayer */
/* enable sync mode? */
@@ -1163,6 +1191,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
if (iqd[7] & 0x20) {
qpti->dev_param[tgt].device_flags |= 0x20;
}
+
+ scsi_rbuf_put(Cmnd, iqd);
+
qpti->sbits |= (1 << tgt);
} else if (!ok) {
qpti->sbits |= (1 << tgt);
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index f97e3afa97d9..422e0b6f603a 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -35,7 +35,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "0.12"
+#define DRV_VERSION "0.25"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -55,31 +55,61 @@ enum {
MV_SATAHC_ARBTR_REG_SZ = MV_MINOR_REG_AREA_SZ, /* arbiter */
MV_PORT_REG_SZ = MV_MINOR_REG_AREA_SZ,
- MV_Q_CT = 32,
- MV_CRQB_SZ = 32,
- MV_CRPB_SZ = 8,
+ MV_USE_Q_DEPTH = ATA_DEF_QUEUE,
- MV_DMA_BOUNDARY = 0xffffffffU,
- SATAHC_MASK = (~(MV_SATAHC_REG_SZ - 1)),
+ MV_MAX_Q_DEPTH = 32,
+ MV_MAX_Q_DEPTH_MASK = MV_MAX_Q_DEPTH - 1,
+
+ /* CRQB needs alignment on a 1KB boundary. Size == 1KB
+ * CRPB needs alignment on a 256B boundary. Size == 256B
+ * SG count of 176 leads to MV_PORT_PRIV_DMA_SZ == 4KB
+ * ePRD (SG) entries need alignment on a 16B boundary. Size == 16B
+ */
+ MV_CRQB_Q_SZ = (32 * MV_MAX_Q_DEPTH),
+ MV_CRPB_Q_SZ = (8 * MV_MAX_Q_DEPTH),
+ MV_MAX_SG_CT = 176,
+ MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT),
+ MV_PORT_PRIV_DMA_SZ = (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ),
+
+ /* Our DMA boundary is determined by an ePRD being unable to handle
+ * anything larger than 64KB
+ */
+ MV_DMA_BOUNDARY = 0xffffU,
MV_PORTS_PER_HC = 4,
/* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */
MV_PORT_HC_SHIFT = 2,
- /* == (port % MV_PORTS_PER_HC) to determine port from 0-7 port */
+ /* == (port % MV_PORTS_PER_HC) to determine hard port from 0-7 port */
MV_PORT_MASK = 3,
/* Host Flags */
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
- MV_FLAG_BDMA = (1 << 28), /* Basic DMA */
+ MV_FLAG_GLBL_SFT_RST = (1 << 28), /* Global Soft Reset support */
+ MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
+ MV_6XXX_FLAGS = (MV_FLAG_IRQ_COALESCE |
+ MV_FLAG_GLBL_SFT_RST),
chip_504x = 0,
chip_508x = 1,
chip_604x = 2,
chip_608x = 3,
+ CRQB_FLAG_READ = (1 << 0),
+ CRQB_TAG_SHIFT = 1,
+ CRQB_CMD_ADDR_SHIFT = 8,
+ CRQB_CMD_CS = (0x2 << 11),
+ CRQB_CMD_LAST = (1 << 15),
+
+ CRPB_FLAG_STATUS_SHIFT = 8,
+
+ EPRD_FLAG_END_OF_TBL = (1 << 31),
+
/* PCI interface registers */
+ PCI_COMMAND_OFS = 0xc00,
+
PCI_MAIN_CMD_STS_OFS = 0xd30,
STOP_PCI_MASTER = (1 << 2),
PCI_MASTER_EMPTY = (1 << 3),
@@ -111,20 +141,13 @@ enum {
HC_CFG_OFS = 0,
HC_IRQ_CAUSE_OFS = 0x14,
- CRBP_DMA_DONE = (1 << 0), /* shift by port # */
+ CRPB_DMA_DONE = (1 << 0), /* shift by port # */
HC_IRQ_COAL = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
/* Shadow block registers */
- SHD_PIO_DATA_OFS = 0x100,
- SHD_FEA_ERR_OFS = 0x104,
- SHD_SECT_CNT_OFS = 0x108,
- SHD_LBA_L_OFS = 0x10C,
- SHD_LBA_M_OFS = 0x110,
- SHD_LBA_H_OFS = 0x114,
- SHD_DEV_HD_OFS = 0x118,
- SHD_CMD_STA_OFS = 0x11C,
- SHD_CTL_AST_OFS = 0x120,
+ SHD_BLK_OFS = 0x100,
+ SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
/* SATA registers */
SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */
@@ -132,6 +155,11 @@ enum {
/* Port registers */
EDMA_CFG_OFS = 0,
+ EDMA_CFG_Q_DEPTH = 0, /* queueing disabled */
+ EDMA_CFG_NCQ = (1 << 5),
+ EDMA_CFG_NCQ_GO_ON_ERR = (1 << 14), /* continue on error */
+ EDMA_CFG_RD_BRST_EXT = (1 << 11), /* read burst 512B */
+ EDMA_CFG_WR_BUFF_LEN = (1 << 13), /* write buffer 512B */
EDMA_ERR_IRQ_CAUSE_OFS = 0x8,
EDMA_ERR_IRQ_MASK_OFS = 0xc,
@@ -161,33 +189,85 @@ enum {
EDMA_ERR_LNK_DATA_TX |
EDMA_ERR_TRANS_PROTO),
+ EDMA_REQ_Q_BASE_HI_OFS = 0x10,
+ EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */
+ EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
+
+ EDMA_REQ_Q_OUT_PTR_OFS = 0x18,
+ EDMA_REQ_Q_PTR_SHIFT = 5,
+
+ EDMA_RSP_Q_BASE_HI_OFS = 0x1c,
+ EDMA_RSP_Q_IN_PTR_OFS = 0x20,
+ EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */
+ EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
+ EDMA_RSP_Q_PTR_SHIFT = 3,
+
EDMA_CMD_OFS = 0x28,
EDMA_EN = (1 << 0),
EDMA_DS = (1 << 1),
ATA_RST = (1 << 2),
- /* BDMA is 6xxx part only */
- BDMA_CMD_OFS = 0x224,
- BDMA_START = (1 << 0),
+ /* Host private flags (hp_flags) */
+ MV_HP_FLAG_MSI = (1 << 0),
- MV_UNDEF = 0,
+ /* Port private flags (pp_flags) */
+ MV_PP_FLAG_EDMA_EN = (1 << 0),
+ MV_PP_FLAG_EDMA_DS_ACT = (1 << 1),
};
-struct mv_port_priv {
+/* Command ReQuest Block: 32B */
+struct mv_crqb {
+ u32 sg_addr;
+ u32 sg_addr_hi;
+ u16 ctrl_flags;
+ u16 ata_cmd[11];
+};
+/* Command ResPonse Block: 8B */
+struct mv_crpb {
+ u16 id;
+ u16 flags;
+ u32 tmstmp;
};
-struct mv_host_priv {
+/* EDMA Physical Region Descriptor (ePRD); A.K.A. SG */
+struct mv_sg {
+ u32 addr;
+ u32 flags_size;
+ u32 addr_hi;
+ u32 reserved;
+};
+
+struct mv_port_priv {
+ struct mv_crqb *crqb;
+ dma_addr_t crqb_dma;
+ struct mv_crpb *crpb;
+ dma_addr_t crpb_dma;
+ struct mv_sg *sg_tbl;
+ dma_addr_t sg_tbl_dma;
+
+ unsigned req_producer; /* cp of req_in_ptr */
+ unsigned rsp_consumer; /* cp of rsp_out_ptr */
+ u32 pp_flags;
+};
+struct mv_host_priv {
+ u32 hp_flags;
};
static void mv_irq_clear(struct ata_port *ap);
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
+static u8 mv_check_err(struct ata_port *ap);
static void mv_phy_reset(struct ata_port *ap);
-static int mv_master_reset(void __iomem *mmio_base);
+static void mv_host_stop(struct ata_host_set *host_set);
+static int mv_port_start(struct ata_port *ap);
+static void mv_port_stop(struct ata_port *ap);
+static void mv_qc_prep(struct ata_queued_cmd *qc);
+static int mv_qc_issue(struct ata_queued_cmd *qc);
static irqreturn_t mv_interrupt(int irq, void *dev_instance,
struct pt_regs *regs);
+static void mv_eng_timeout(struct ata_port *ap);
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static Scsi_Host_Template mv_sht = {
@@ -196,13 +276,13 @@ static Scsi_Host_Template mv_sht = {
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
+ .can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = MV_UNDEF,
+ .sg_tablesize = MV_MAX_SG_CT,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
- .use_clustering = MV_UNDEF,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
@@ -210,21 +290,22 @@ static Scsi_Host_Template mv_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations mv_ops = {
+static const struct ata_port_operations mv_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
+ .check_err = mv_check_err,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.phy_reset = mv_phy_reset,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
+ .qc_prep = mv_qc_prep,
+ .qc_issue = mv_qc_issue,
- .eng_timeout = ata_eng_timeout,
+ .eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
@@ -232,46 +313,39 @@ static struct ata_port_operations mv_ops = {
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .port_start = mv_port_start,
+ .port_stop = mv_port_stop,
+ .host_stop = mv_host_stop,
};
static struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = MV_COMMON_FLAGS,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */
.port_ops = &mv_ops,
},
{ /* chip_508x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
- MV_FLAG_DUAL_HC),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */
.port_ops = &mv_ops,
},
{ /* chip_604x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
- MV_FLAG_IRQ_COALESCE | MV_FLAG_BDMA),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_ops,
},
{ /* chip_608x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
- MV_FLAG_IRQ_COALESCE | MV_FLAG_DUAL_HC |
- MV_FLAG_BDMA),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ MV_FLAG_DUAL_HC),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_ops,
},
};
@@ -306,12 +380,6 @@ static inline void writelfl(unsigned long data, void __iomem *addr)
(void) readl(addr); /* flush to avoid PCI posted write */
}
-static inline void __iomem *mv_port_addr_to_hc_base(void __iomem *port_mmio)
-{
- return ((void __iomem *)((unsigned long)port_mmio &
- (unsigned long)SATAHC_MASK));
-}
-
static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
{
return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
@@ -329,24 +397,150 @@ static inline void __iomem *mv_ap_base(struct ata_port *ap)
return mv_port_base(ap->host_set->mmio_base, ap->port_no);
}
-static inline int mv_get_hc_count(unsigned long flags)
+static inline int mv_get_hc_count(unsigned long hp_flags)
+{
+ return ((hp_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
+}
+
+static void mv_irq_clear(struct ata_port *ap)
+{
+}
+
+/**
+ * mv_start_dma - Enable eDMA engine
+ * @base: port base address
+ * @pp: port private data
+ *
+ * Verify the local cache of the eDMA state is accurate with an
+ * assert.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
{
- return ((flags & MV_FLAG_DUAL_HC) ? 2 : 1);
+ if (!(MV_PP_FLAG_EDMA_EN & pp->pp_flags)) {
+ writelfl(EDMA_EN, base + EDMA_CMD_OFS);
+ pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
+ }
+ assert(EDMA_EN & readl(base + EDMA_CMD_OFS));
}
-static inline int mv_is_edma_active(struct ata_port *ap)
+/**
+ * mv_stop_dma - Disable eDMA engine
+ * @ap: ATA channel to manipulate
+ *
+ * Verify the local cache of the eDMA state is accurate with an
+ * assert.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_stop_dma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
- return (EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
+ struct mv_port_priv *pp = ap->private_data;
+ u32 reg;
+ int i;
+
+ if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) {
+ /* Disable EDMA if active. The disable bit auto clears.
+ */
+ writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ } else {
+ assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)));
+ }
+
+ /* now properly wait for the eDMA to stop */
+ for (i = 1000; i > 0; i--) {
+ reg = readl(port_mmio + EDMA_CMD_OFS);
+ if (!(EDMA_EN & reg)) {
+ break;
+ }
+ udelay(100);
+ }
+
+ if (EDMA_EN & reg) {
+ printk(KERN_ERR "ata%u: Unable to stop eDMA\n", ap->id);
+ /* FIXME: Consider doing a reset here to recover */
+ }
}
-static inline int mv_port_bdma_capable(struct ata_port *ap)
+#ifdef ATA_DEBUG
+static void mv_dump_mem(void __iomem *start, unsigned bytes)
{
- return (ap->flags & MV_FLAG_BDMA);
+ int b, w;
+ for (b = 0; b < bytes; ) {
+ DPRINTK("%p: ", start + b);
+ for (w = 0; b < bytes && w < 4; w++) {
+ printk("%08x ",readl(start + b));
+ b += sizeof(u32);
+ }
+ printk("\n");
+ }
}
+#endif
-static void mv_irq_clear(struct ata_port *ap)
+static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes)
+{
+#ifdef ATA_DEBUG
+ int b, w;
+ u32 dw;
+ for (b = 0; b < bytes; ) {
+ DPRINTK("%02x: ", b);
+ for (w = 0; b < bytes && w < 4; w++) {
+ (void) pci_read_config_dword(pdev,b,&dw);
+ printk("%08x ",dw);
+ b += sizeof(u32);
+ }
+ printk("\n");
+ }
+#endif
+}
+static void mv_dump_all_regs(void __iomem *mmio_base, int port,
+ struct pci_dev *pdev)
{
+#ifdef ATA_DEBUG
+ void __iomem *hc_base = mv_hc_base(mmio_base,
+ port >> MV_PORT_HC_SHIFT);
+ void __iomem *port_base;
+ int start_port, num_ports, p, start_hc, num_hcs, hc;
+
+ if (0 > port) {
+ start_hc = start_port = 0;
+ num_ports = 8; /* shld be benign for 4 port devs */
+ num_hcs = 2;
+ } else {
+ start_hc = port >> MV_PORT_HC_SHIFT;
+ start_port = port;
+ num_ports = num_hcs = 1;
+ }
+ DPRINTK("All registers for port(s) %u-%u:\n", start_port,
+ num_ports > 1 ? num_ports - 1 : start_port);
+
+ if (NULL != pdev) {
+ DPRINTK("PCI config space regs:\n");
+ mv_dump_pci_cfg(pdev, 0x68);
+ }
+ DPRINTK("PCI regs:\n");
+ mv_dump_mem(mmio_base+0xc00, 0x3c);
+ mv_dump_mem(mmio_base+0xd00, 0x34);
+ mv_dump_mem(mmio_base+0xf00, 0x4);
+ mv_dump_mem(mmio_base+0x1d00, 0x6c);
+ for (hc = start_hc; hc < start_hc + num_hcs; hc++) {
+ hc_base = mv_hc_base(mmio_base, port >> MV_PORT_HC_SHIFT);
+ DPRINTK("HC regs (HC %i):\n", hc);
+ mv_dump_mem(hc_base, 0x1c);
+ }
+ for (p = start_port; p < start_port + num_ports; p++) {
+ port_base = mv_port_base(mmio_base, p);
+ DPRINTK("EDMA regs (port %i):\n",p);
+ mv_dump_mem(port_base, 0x54);
+ DPRINTK("SATA regs (port %i):\n",p);
+ mv_dump_mem(port_base+0x300, 0x60);
+ }
+#endif
}
static unsigned int mv_scr_offset(unsigned int sc_reg_in)
@@ -389,30 +583,37 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
}
}
-static int mv_master_reset(void __iomem *mmio_base)
+/**
+ * mv_global_soft_reset - Perform the 6xxx global soft reset
+ * @mmio_base: base address of the HBA
+ *
+ * This routine only applies to 6xxx parts.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_global_soft_reset(void __iomem *mmio_base)
{
void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS;
int i, rc = 0;
u32 t;
- VPRINTK("ENTER\n");
-
/* Following procedure defined in PCI "main command and status
* register" table.
*/
t = readl(reg);
writel(t | STOP_PCI_MASTER, reg);
- for (i = 0; i < 100; i++) {
- msleep(10);
+ for (i = 0; i < 1000; i++) {
+ udelay(1);
t = readl(reg);
if (PCI_MASTER_EMPTY & t) {
break;
}
}
if (!(PCI_MASTER_EMPTY & t)) {
- printk(KERN_ERR DRV_NAME "PCI master won't flush\n");
- rc = 1; /* broken HW? */
+ printk(KERN_ERR DRV_NAME ": PCI master won't flush\n");
+ rc = 1;
goto done;
}
@@ -425,39 +626,399 @@ static int mv_master_reset(void __iomem *mmio_base)
} while (!(GLOB_SFT_RST & t) && (i-- > 0));
if (!(GLOB_SFT_RST & t)) {
- printk(KERN_ERR DRV_NAME "can't set global reset\n");
- rc = 1; /* broken HW? */
+ printk(KERN_ERR DRV_NAME ": can't set global reset\n");
+ rc = 1;
goto done;
}
- /* clear reset */
+ /* clear reset and *reenable the PCI master* (not mentioned in spec) */
i = 5;
do {
- writel(t & ~GLOB_SFT_RST, reg);
+ writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg);
t = readl(reg);
udelay(1);
} while ((GLOB_SFT_RST & t) && (i-- > 0));
if (GLOB_SFT_RST & t) {
- printk(KERN_ERR DRV_NAME "can't clear global reset\n");
- rc = 1; /* broken HW? */
+ printk(KERN_ERR DRV_NAME ": can't clear global reset\n");
+ rc = 1;
}
-
- done:
- VPRINTK("EXIT, rc = %i\n", rc);
+done:
return rc;
}
-static void mv_err_intr(struct ata_port *ap)
+/**
+ * mv_host_stop - Host specific cleanup/stop routine.
+ * @host_set: host data structure
+ *
+ * Disable ints, cleanup host memory, call general purpose
+ * host_stop.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_host_stop(struct ata_host_set *host_set)
{
- void __iomem *port_mmio;
- u32 edma_err_cause, serr = 0;
+ struct mv_host_priv *hpriv = host_set->private_data;
+ struct pci_dev *pdev = to_pci_dev(host_set->dev);
+
+ if (hpriv->hp_flags & MV_HP_FLAG_MSI) {
+ pci_disable_msi(pdev);
+ } else {
+ pci_intx(pdev, 0);
+ }
+ kfree(hpriv);
+ ata_host_stop(host_set);
+}
+
+/**
+ * mv_port_start - Port specific init/start routine.
+ * @ap: ATA channel to manipulate
+ *
+ * Allocate and point to DMA memory, init port private memory,
+ * zero indices.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct mv_port_priv *pp;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ void *mem;
+ dma_addr_t mem_dma;
+
+ pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp) {
+ return -ENOMEM;
+ }
+ memset(pp, 0, sizeof(*pp));
+
+ mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
+ if (!mem) {
+ kfree(pp);
+ return -ENOMEM;
+ }
+ memset(mem, 0, MV_PORT_PRIV_DMA_SZ);
+
+ /* First item in chunk of DMA memory:
+ * 32-slot command request table (CRQB), 32 bytes each in size
+ */
+ pp->crqb = mem;
+ pp->crqb_dma = mem_dma;
+ mem += MV_CRQB_Q_SZ;
+ mem_dma += MV_CRQB_Q_SZ;
+
+ /* Second item:
+ * 32-slot command response table (CRPB), 8 bytes each in size
+ */
+ pp->crpb = mem;
+ pp->crpb_dma = mem_dma;
+ mem += MV_CRPB_Q_SZ;
+ mem_dma += MV_CRPB_Q_SZ;
+
+ /* Third item:
+ * Table of scatter-gather descriptors (ePRD), 16 bytes each
+ */
+ pp->sg_tbl = mem;
+ pp->sg_tbl_dma = mem_dma;
+
+ writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT |
+ EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS);
+
+ writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
+ writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
+ port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+ writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+ writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+
+ writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
+ writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
+ port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ pp->req_producer = pp->rsp_consumer = 0;
+
+ /* Don't turn on EDMA here...do it before DMA commands only. Else
+ * we'll be unable to send non-data, PIO, etc due to restricted access
+ * to shadow regs.
+ */
+ ap->private_data = pp;
+ return 0;
+}
+
+/**
+ * mv_port_stop - Port specific cleanup/stop routine.
+ * @ap: ATA channel to manipulate
+ *
+ * Stop DMA, cleanup port memory.
+ *
+ * LOCKING:
+ * This routine uses the host_set lock to protect the DMA stop.
+ */
+static void mv_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct mv_port_priv *pp = ap->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ mv_stop_dma(ap);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ ap->private_data = NULL;
+ dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
+ kfree(pp);
+}
+
+/**
+ * mv_fill_sg - Fill out the Marvell ePRD (scatter gather) entries
+ * @qc: queued command whose SG list to source from
+ *
+ * Populate the SG list and mark the last entry.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_fill_sg(struct ata_queued_cmd *qc)
+{
+ struct mv_port_priv *pp = qc->ap->private_data;
+ unsigned int i;
+
+ for (i = 0; i < qc->n_elem; i++) {
+ u32 sg_len;
+ dma_addr_t addr;
+
+ addr = sg_dma_address(&qc->sg[i]);
+ sg_len = sg_dma_len(&qc->sg[i]);
+
+ pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
+ pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
+ assert(0 == (sg_len & ~MV_DMA_BOUNDARY));
+ pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len);
+ }
+ if (0 < qc->n_elem) {
+ pp->sg_tbl[qc->n_elem - 1].flags_size |=
+ cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+ }
+}
+
+static inline unsigned mv_inc_q_index(unsigned *index)
+{
+ *index = (*index + 1) & MV_MAX_Q_DEPTH_MASK;
+ return *index;
+}
+
+static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last)
+{
+ *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
+ (last ? CRQB_CMD_LAST : 0);
+}
+
+/**
+ * mv_qc_prep - Host specific command preparation.
+ * @qc: queued command to prepare
+ *
+ * This routine simply redirects to the general purpose routine
+ * if command is not DMA. Else, it handles prep of the CRQB
+ * (command request block), does some sanity checking, and calls
+ * the SG load routine.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mv_port_priv *pp = ap->private_data;
+ u16 *cw;
+ struct ata_taskfile *tf;
+ u16 flags = 0;
+
+ if (ATA_PROT_DMA != qc->tf.protocol) {
+ return;
+ }
- /* bug here b/c we got an err int on a port we don't know about,
- * so there's no way to clear it
+ /* the req producer index should be the same as we remember it */
+ assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
+ EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->req_producer);
+
+ /* Fill in command request block
+ */
+ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+ flags |= CRQB_FLAG_READ;
+ }
+ assert(MV_MAX_Q_DEPTH > qc->tag);
+ flags |= qc->tag << CRQB_TAG_SHIFT;
+
+ pp->crqb[pp->req_producer].sg_addr =
+ cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
+ pp->crqb[pp->req_producer].sg_addr_hi =
+ cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
+ pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags);
+
+ cw = &pp->crqb[pp->req_producer].ata_cmd[0];
+ tf = &qc->tf;
+
+ /* Sadly, the CRQB cannot accomodate all registers--there are
+ * only 11 bytes...so we must pick and choose required
+ * registers based on the command. So, we drop feature and
+ * hob_feature for [RW] DMA commands, but they are needed for
+ * NCQ. NCQ will drop hob_nsect.
*/
- BUG_ON(NULL == ap);
- port_mmio = mv_ap_base(ap);
+ switch (tf->command) {
+ case ATA_CMD_READ:
+ case ATA_CMD_READ_EXT:
+ case ATA_CMD_WRITE:
+ case ATA_CMD_WRITE_EXT:
+ mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0);
+ break;
+#ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */
+ case ATA_CMD_FPDMA_READ:
+ case ATA_CMD_FPDMA_WRITE:
+ mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0);
+ mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0);
+ break;
+#endif /* FIXME: remove this line when NCQ added */
+ default:
+ /* The only other commands EDMA supports in non-queued and
+ * non-NCQ mode are: [RW] STREAM DMA and W DMA FUA EXT, none
+ * of which are defined/used by Linux. If we get here, this
+ * driver needs work.
+ *
+ * FIXME: modify libata to give qc_prep a return value and
+ * return error here.
+ */
+ BUG_ON(tf->command);
+ break;
+ }
+ mv_crqb_pack_cmd(cw++, tf->nsect, ATA_REG_NSECT, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_lbal, ATA_REG_LBAL, 0);
+ mv_crqb_pack_cmd(cw++, tf->lbal, ATA_REG_LBAL, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_lbam, ATA_REG_LBAM, 0);
+ mv_crqb_pack_cmd(cw++, tf->lbam, ATA_REG_LBAM, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_lbah, ATA_REG_LBAH, 0);
+ mv_crqb_pack_cmd(cw++, tf->lbah, ATA_REG_LBAH, 0);
+ mv_crqb_pack_cmd(cw++, tf->device, ATA_REG_DEVICE, 0);
+ mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1); /* last */
+
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP)) {
+ return;
+ }
+ mv_fill_sg(qc);
+}
+
+/**
+ * mv_qc_issue - Initiate a command to the host
+ * @qc: queued command to start
+ *
+ * This routine simply redirects to the general purpose routine
+ * if command is not DMA. Else, it sanity checks our local
+ * caches of the request producer/consumer indices then enables
+ * DMA and bumps the request producer index.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_qc_issue(struct ata_queued_cmd *qc)
+{
+ void __iomem *port_mmio = mv_ap_base(qc->ap);
+ struct mv_port_priv *pp = qc->ap->private_data;
+ u32 in_ptr;
+
+ if (ATA_PROT_DMA != qc->tf.protocol) {
+ /* We're about to send a non-EDMA capable command to the
+ * port. Turn off EDMA so there won't be problems accessing
+ * shadow block, etc registers.
+ */
+ mv_stop_dma(qc->ap);
+ return ata_qc_issue_prot(qc);
+ }
+
+ in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+ /* the req producer index should be the same as we remember it */
+ assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->req_producer);
+ /* until we do queuing, the queue should be empty at this point */
+ assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
+ EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
+
+ mv_inc_q_index(&pp->req_producer); /* now incr producer index */
+
+ mv_start_dma(port_mmio, pp);
+
+ /* and write the request in pointer to kick the EDMA to life */
+ in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
+ in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT;
+ writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+ return 0;
+}
+
+/**
+ * mv_get_crpb_status - get status from most recently completed cmd
+ * @ap: ATA channel to manipulate
+ *
+ * This routine is for use when the port is in DMA mode, when it
+ * will be using the CRPB (command response block) method of
+ * returning command completion information. We assert indices
+ * are good, grab status, and bump the response consumer index to
+ * prove that we're up to date.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static u8 mv_get_crpb_status(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+ u32 out_ptr;
+
+ out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ /* the response consumer index should be the same as we remember it */
+ assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->rsp_consumer);
+
+ /* increment our consumer index... */
+ pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
+
+ /* and, until we do NCQ, there should only be 1 CRPB waiting */
+ assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
+ EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->rsp_consumer);
+
+ /* write out our inc'd consumer index so EDMA knows we're caught up */
+ out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
+ out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT;
+ writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ /* Return ATA status register for completed CRPB */
+ return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT);
+}
+
+/**
+ * mv_err_intr - Handle error interrupts on the port
+ * @ap: ATA channel to manipulate
+ *
+ * In most cases, just clear the interrupt and move on. However,
+ * some cases require an eDMA reset, which is done right before
+ * the COMRESET in mv_phy_reset(). The SERR case requires a
+ * clear of pending errors in the SATA SERROR register. Finally,
+ * if the port disabled DMA, update our cached copy to match.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_err_intr(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 edma_err_cause, serr = 0;
edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
@@ -465,8 +1026,12 @@ static void mv_err_intr(struct ata_port *ap)
serr = scr_read(ap, SCR_ERROR);
scr_write_flush(ap, SCR_ERROR, serr);
}
- DPRINTK("port %u error; EDMA err cause: 0x%08x SERR: 0x%08x\n",
- ap->port_no, edma_err_cause, serr);
+ if (EDMA_ERR_SELF_DIS & edma_err_cause) {
+ struct mv_port_priv *pp = ap->private_data;
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ }
+ DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x "
+ "SERR: 0x%08x\n", ap->id, edma_err_cause, serr);
/* Clear EDMA now that SERR cleanup done */
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
@@ -477,7 +1042,21 @@ static void mv_err_intr(struct ata_port *ap)
}
}
-/* Handle any outstanding interrupts in a single SATAHC
+/**
+ * mv_host_intr - Handle all interrupts on the given host controller
+ * @host_set: host specific structure
+ * @relevant: port error bits relevant to this host controller
+ * @hc: which host controller we're to look at
+ *
+ * Read then write clear the HC interrupt status then walk each
+ * port connected to the HC and see if it needs servicing. Port
+ * success ints are reported in the HC interrupt status reg, the
+ * port error ints are reported in the higher level main
+ * interrupt status register and thus are passed in via the
+ * 'relevant' argument.
+ *
+ * LOCKING:
+ * Inherited from caller.
*/
static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
unsigned int hc)
@@ -487,8 +1066,8 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
struct ata_port *ap;
struct ata_queued_cmd *qc;
u32 hc_irq_cause;
- int shift, port, port0, hard_port;
- u8 ata_status;
+ int shift, port, port0, hard_port, handled;
+ u8 ata_status = 0;
if (hc == 0) {
port0 = 0;
@@ -499,7 +1078,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
/* we'll need the HC success int register in most cases */
hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
if (hc_irq_cause) {
- writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
}
VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
@@ -508,35 +1087,38 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
ap = host_set->ports[port];
hard_port = port & MV_PORT_MASK; /* range 0-3 */
- ata_status = 0xffU;
+ handled = 0; /* ensure ata_status is set if handled++ */
- if (((CRBP_DMA_DONE | DEV_IRQ) << hard_port) & hc_irq_cause) {
- BUG_ON(NULL == ap);
- /* rcv'd new resp, basic DMA complete, or ATA IRQ */
- /* This is needed to clear the ATA INTRQ.
- * FIXME: don't read the status reg in EDMA mode!
+ if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) {
+ /* new CRPB on the queue; just one at a time until NCQ
+ */
+ ata_status = mv_get_crpb_status(ap);
+ handled++;
+ } else if ((DEV_IRQ << hard_port) & hc_irq_cause) {
+ /* received ATA IRQ; read the status reg to clear INTRQ
*/
ata_status = readb((void __iomem *)
ap->ioaddr.status_addr);
+ handled++;
}
- shift = port * 2;
+ shift = port << 1; /* (port * 2) */
if (port >= MV_PORTS_PER_HC) {
shift++; /* skip bit 8 in the HC Main IRQ reg */
}
if ((PORT0_ERR << shift) & relevant) {
mv_err_intr(ap);
- /* FIXME: smart to OR in ATA_ERR? */
+ /* OR in ATA_ERR to ensure libata knows we took one */
ata_status = readb((void __iomem *)
ap->ioaddr.status_addr) | ATA_ERR;
+ handled++;
}
- if (ap) {
+ if (handled && ap) {
qc = ata_qc_from_tag(ap, ap->active_tag);
if (NULL != qc) {
VPRINTK("port %u IRQ found for qc, "
"ata_status 0x%x\n", port,ata_status);
- BUG_ON(0xffU == ata_status);
/* mark qc status appropriately */
ata_qc_complete(qc, ata_status);
}
@@ -545,17 +1127,30 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
VPRINTK("EXIT\n");
}
+/**
+ * mv_interrupt -
+ * @irq: unused
+ * @dev_instance: private data; in this case the host structure
+ * @regs: unused
+ *
+ * Read the read only register to determine if any host
+ * controllers have pending interrupts. If so, call lower level
+ * routine to handle. Also check for PCI errors which are only
+ * reported here.
+ *
+ * LOCKING:
+ * This routine holds the host_set lock while processing pending
+ * interrupts.
+ */
static irqreturn_t mv_interrupt(int irq, void *dev_instance,
struct pt_regs *regs)
{
struct ata_host_set *host_set = dev_instance;
unsigned int hc, handled = 0, n_hcs;
- void __iomem *mmio;
+ void __iomem *mmio = host_set->mmio_base;
u32 irq_stat;
- mmio = host_set->mmio_base;
irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
- n_hcs = mv_get_hc_count(host_set->ports[0]->flags);
/* check the cases where we either have nothing pending or have read
* a bogus register value which can indicate HW removal or PCI fault
@@ -564,64 +1159,105 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
return IRQ_NONE;
}
+ n_hcs = mv_get_hc_count(host_set->ports[0]->flags);
spin_lock(&host_set->lock);
for (hc = 0; hc < n_hcs; hc++) {
u32 relevant = irq_stat & (HC0_IRQ_PEND << (hc * HC_SHIFT));
if (relevant) {
mv_host_intr(host_set, relevant, hc);
- handled = 1;
+ handled++;
}
}
if (PCI_ERR & irq_stat) {
- /* FIXME: these are all masked by default, but still need
- * to recover from them properly.
- */
- }
+ printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
+ readl(mmio + PCI_IRQ_CAUSE_OFS));
+
+ DPRINTK("All regs @ PCI error\n");
+ mv_dump_all_regs(mmio, -1, to_pci_dev(host_set->dev));
+ writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
+ handled++;
+ }
spin_unlock(&host_set->lock);
return IRQ_RETVAL(handled);
}
+/**
+ * mv_check_err - Return the error shadow register to caller.
+ * @ap: ATA channel to manipulate
+ *
+ * Marvell requires DMA to be stopped before accessing shadow
+ * registers. So we do that, then return the needed register.
+ *
+ * LOCKING:
+ * Inherited from caller. FIXME: protect mv_stop_dma with lock?
+ */
+static u8 mv_check_err(struct ata_port *ap)
+{
+ mv_stop_dma(ap); /* can't read shadow regs if DMA on */
+ return readb((void __iomem *) ap->ioaddr.error_addr);
+}
+
+/**
+ * mv_phy_reset - Perform eDMA reset followed by COMRESET
+ * @ap: ATA channel to manipulate
+ *
+ * Part of this is taken from __sata_phy_reset and modified to
+ * not sleep since this routine gets called from interrupt level.
+ *
+ * LOCKING:
+ * Inherited from caller. This is coded to safe to call at
+ * interrupt level, i.e. it does not sleep.
+ */
static void mv_phy_reset(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct ata_taskfile tf;
struct ata_device *dev = &ap->device[0];
- u32 edma = 0, bdma;
+ unsigned long timeout;
VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
- edma = readl(port_mmio + EDMA_CMD_OFS);
- if (EDMA_EN & edma) {
- /* disable EDMA if active */
- edma &= ~EDMA_EN;
- writelfl(edma | EDMA_DS, port_mmio + EDMA_CMD_OFS);
- udelay(1);
- } else if (mv_port_bdma_capable(ap) &&
- (bdma = readl(port_mmio + BDMA_CMD_OFS)) & BDMA_START) {
- /* disable BDMA if active */
- writelfl(bdma & ~BDMA_START, port_mmio + BDMA_CMD_OFS);
- }
+ mv_stop_dma(ap);
- writelfl(edma | ATA_RST, port_mmio + EDMA_CMD_OFS);
+ writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
udelay(25); /* allow reset propagation */
/* Spec never mentions clearing the bit. Marvell's driver does
* clear the bit, however.
*/
- writelfl(edma & ~ATA_RST, port_mmio + EDMA_CMD_OFS);
+ writelfl(0, port_mmio + EDMA_CMD_OFS);
- VPRINTK("Done. Now calling __sata_phy_reset()\n");
+ VPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
+ "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
+ mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
/* proceed to init communications via the scr_control reg */
- __sata_phy_reset(ap);
+ scr_write_flush(ap, SCR_CONTROL, 0x301);
+ mdelay(1);
+ scr_write_flush(ap, SCR_CONTROL, 0x300);
+ timeout = jiffies + (HZ * 1);
+ do {
+ mdelay(10);
+ if ((scr_read(ap, SCR_STATUS) & 0xf) != 1)
+ break;
+ } while (time_before(jiffies, timeout));
- if (ap->flags & ATA_FLAG_PORT_DISABLED) {
- VPRINTK("Port disabled pre-sig. Exiting.\n");
+ VPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
+ "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
+ mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
+
+ if (sata_dev_present(ap)) {
+ ata_port_probe(ap);
+ } else {
+ printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
+ ap->id, scr_read(ap, SCR_STATUS));
+ ata_port_disable(ap);
return;
}
+ ap->cbl = ATA_CBL_SATA;
tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr);
tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr);
@@ -636,37 +1272,118 @@ static void mv_phy_reset(struct ata_port *ap)
VPRINTK("EXIT\n");
}
-static void mv_port_init(struct ata_ioports *port, unsigned long base)
+/**
+ * mv_eng_timeout - Routine called by libata when SCSI times out I/O
+ * @ap: ATA channel to manipulate
+ *
+ * Intent is to clear all pending error conditions, reset the
+ * chip/bus, fail the command, and move on.
+ *
+ * LOCKING:
+ * This routine holds the host_set lock while failing the command.
+ */
+static void mv_eng_timeout(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+
+ printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
+ DPRINTK("All regs @ start of eng_timeout\n");
+ mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no,
+ to_pci_dev(ap->host_set->dev));
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
+ ap->host_set->mmio_base, ap, qc, qc->scsicmd,
+ &qc->scsicmd->cmnd);
+
+ mv_err_intr(ap);
+ mv_phy_reset(ap);
+
+ if (!qc) {
+ printk(KERN_ERR "ata%u: BUG: timeout without command\n",
+ ap->id);
+ } else {
+ /* hack alert! We cannot use the supplied completion
+ * function from inside the ->eh_strategy_handler() thread.
+ * libata is the only user of ->eh_strategy_handler() in
+ * any kernel, so the default scsi_done() assumes it is
+ * not being called from the SCSI EH.
+ */
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ qc->scsidone = scsi_finish_command;
+ ata_qc_complete(qc, ATA_ERR);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ }
+}
+
+/**
+ * mv_port_init - Perform some early initialization on a single port.
+ * @port: libata data structure storing shadow register addresses
+ * @port_mmio: base address of the port
+ *
+ * Initialize shadow register mmio addresses, clear outstanding
+ * interrupts on the port, and unmask interrupts for the future
+ * start of the port.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
{
- /* PIO related setup */
- port->data_addr = base + SHD_PIO_DATA_OFS;
- port->error_addr = port->feature_addr = base + SHD_FEA_ERR_OFS;
- port->nsect_addr = base + SHD_SECT_CNT_OFS;
- port->lbal_addr = base + SHD_LBA_L_OFS;
- port->lbam_addr = base + SHD_LBA_M_OFS;
- port->lbah_addr = base + SHD_LBA_H_OFS;
- port->device_addr = base + SHD_DEV_HD_OFS;
- port->status_addr = port->command_addr = base + SHD_CMD_STA_OFS;
- port->altstatus_addr = port->ctl_addr = base + SHD_CTL_AST_OFS;
- /* unused */
+ unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS;
+ unsigned serr_ofs;
+
+ /* PIO related setup
+ */
+ port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA);
+ port->error_addr =
+ port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR);
+ port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT);
+ port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL);
+ port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM);
+ port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH);
+ port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE);
+ port->status_addr =
+ port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS);
+ /* special case: control/altstatus doesn't have ATA_REG_ address */
+ port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
+
+ /* unused: */
port->cmd_addr = port->bmdma_addr = port->scr_addr = 0;
+ /* Clear any currently outstanding port interrupt conditions */
+ serr_ofs = mv_scr_offset(SCR_ERROR);
+ writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
/* unmask all EDMA error interrupts */
- writel(~0, (void __iomem *)base + EDMA_ERR_IRQ_MASK_OFS);
+ writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
- readl((void __iomem *)base + EDMA_CFG_OFS),
- readl((void __iomem *)base + EDMA_ERR_IRQ_CAUSE_OFS),
- readl((void __iomem *)base + EDMA_ERR_IRQ_MASK_OFS));
+ readl(port_mmio + EDMA_CFG_OFS),
+ readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS),
+ readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
}
+/**
+ * mv_host_init - Perform some early initialization of the host.
+ * @probe_ent: early data struct representing the host
+ *
+ * If possible, do an early global reset of the host. Then do
+ * our port init and clear/unmask all/relevant host interrupts.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
static int mv_host_init(struct ata_probe_ent *probe_ent)
{
int rc = 0, n_hc, port, hc;
void __iomem *mmio = probe_ent->mmio_base;
void __iomem *port_mmio;
- if (mv_master_reset(probe_ent->mmio_base)) {
+ if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) &&
+ mv_global_soft_reset(probe_ent->mmio_base)) {
rc = 1;
goto done;
}
@@ -676,17 +1393,27 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
for (port = 0; port < probe_ent->n_ports; port++) {
port_mmio = mv_port_base(mmio, port);
- mv_port_init(&probe_ent->port[port], (unsigned long)port_mmio);
+ mv_port_init(&probe_ent->port[port], port_mmio);
}
for (hc = 0; hc < n_hc; hc++) {
- VPRINTK("HC%i: HC config=0x%08x HC IRQ cause=0x%08x\n", hc,
- readl(mv_hc_base(mmio, hc) + HC_CFG_OFS),
- readl(mv_hc_base(mmio, hc) + HC_IRQ_CAUSE_OFS));
+ void __iomem *hc_mmio = mv_hc_base(mmio, hc);
+
+ VPRINTK("HC%i: HC config=0x%08x HC IRQ cause "
+ "(before clear)=0x%08x\n", hc,
+ readl(hc_mmio + HC_CFG_OFS),
+ readl(hc_mmio + HC_IRQ_CAUSE_OFS));
+
+ /* Clear any currently outstanding hc interrupt conditions */
+ writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
}
- writel(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
- writel(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
+ /* Clear any currently outstanding host interrupt conditions */
+ writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
+
+ /* and unmask interrupt generation for host regs */
+ writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
+ writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
"PCI int cause/mask=0x%08x/0x%08x\n",
@@ -694,27 +1421,53 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
readl(mmio + HC_MAIN_IRQ_MASK_OFS),
readl(mmio + PCI_IRQ_CAUSE_OFS),
readl(mmio + PCI_IRQ_MASK_OFS));
-
- done:
+done:
return rc;
}
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_intx(struct pci_dev *pdev, int enable)
+/**
+ * mv_print_info - Dump key info to kernel log for perusal.
+ * @probe_ent: early data struct representing the host
+ *
+ * FIXME: complete this.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_print_info(struct ata_probe_ent *probe_ent)
{
- u16 pci_command, new;
+ struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+ struct mv_host_priv *hpriv = probe_ent->private_data;
+ u8 rev_id, scc;
+ const char *scc_s;
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+ /* Use this to determine the HW stepping of the chip so we know
+ * what errata to workaround
+ */
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
- if (enable)
- new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+ pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &scc);
+ if (scc == 0)
+ scc_s = "SCSI";
+ else if (scc == 0x01)
+ scc_s = "RAID";
else
- new = pci_command | PCI_COMMAND_INTX_DISABLE;
+ scc_s = "unknown";
- if (new != pci_command)
- pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+ printk(KERN_INFO DRV_NAME
+ "(%s) %u slots %u ports %s mode IRQ via %s\n",
+ pci_name(pdev), (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+ scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
}
+/**
+ * mv_init_one - handle a positive probe of a Marvell host
+ * @pdev: PCI device found
+ * @ent: PCI device ID entry for the matched host
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
@@ -722,16 +1475,12 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct mv_host_priv *hpriv;
unsigned int board_idx = (unsigned int)ent->driver_data;
void __iomem *mmio_base;
- int pci_dev_busy = 0;
- int rc;
+ int pci_dev_busy = 0, rc;
if (!printed_version++) {
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ printk(KERN_INFO DRV_NAME " version " DRV_VERSION "\n");
}
- VPRINTK("ENTER for PCI Bus:Slot.Func=%u:%u.%u\n", pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
-
rc = pci_enable_device(pdev);
if (rc) {
return rc;
@@ -743,8 +1492,6 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out;
}
- pci_intx(pdev, 1);
-
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (probe_ent == NULL) {
rc = -ENOMEM;
@@ -755,8 +1502,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = ioremap_nocache(pci_resource_start(pdev, MV_PRIMARY_BAR),
- pci_resource_len(pdev, MV_PRIMARY_BAR));
+ mmio_base = pci_iomap(pdev, MV_PRIMARY_BAR, 0);
if (mmio_base == NULL) {
rc = -ENOMEM;
goto err_out_free_ent;
@@ -785,37 +1531,40 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
goto err_out_hpriv;
}
-/* mv_print_info(probe_ent); */
- {
- int b, w;
- u32 dw[4]; /* hold a line of 16b */
- VPRINTK("PCI config space:\n");
- for (b = 0; b < 0x40; ) {
- for (w = 0; w < 4; w++) {
- (void) pci_read_config_dword(pdev,b,&dw[w]);
- b += sizeof(*dw);
- }
- VPRINTK("%08x %08x %08x %08x\n",
- dw[0],dw[1],dw[2],dw[3]);
- }
+ /* Enable interrupts */
+ if (pci_enable_msi(pdev) == 0) {
+ hpriv->hp_flags |= MV_HP_FLAG_MSI;
+ } else {
+ pci_intx(pdev, 1);
}
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ mv_dump_pci_cfg(pdev, 0x68);
+ mv_print_info(probe_ent);
+
+ if (ata_device_add(probe_ent) == 0) {
+ rc = -ENODEV; /* No devices discovered */
+ goto err_out_dev_add;
+ }
+ kfree(probe_ent);
return 0;
- err_out_hpriv:
+err_out_dev_add:
+ if (MV_HP_FLAG_MSI & hpriv->hp_flags) {
+ pci_disable_msi(pdev);
+ } else {
+ pci_intx(pdev, 0);
+ }
+err_out_hpriv:
kfree(hpriv);
- err_out_iounmap:
- iounmap(mmio_base);
- err_out_free_ent:
+err_out_iounmap:
+ pci_iounmap(pdev, mmio_base);
+err_out_free_ent:
kfree(probe_ent);
- err_out_regions:
+err_out_regions:
pci_release_regions(pdev);
- err_out:
+err_out:
if (!pci_dev_busy) {
pci_disable_device(pdev);
}
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index a1d62dee3be6..1a56d6c79ddd 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -29,6 +29,8 @@
* NV-specific details such as register offsets, SATA phy location,
* hotplug info, etc.
*
+ * 0.09
+ * - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
*
* 0.08
* - Added support for MCP51 and MCP55.
@@ -132,9 +134,7 @@ enum nv_host_type
GENERIC,
NFORCE2,
NFORCE3,
- CK804,
- MCP51,
- MCP55
+ CK804
};
static struct pci_device_id nv_pci_tbl[] = {
@@ -153,11 +153,13 @@ static struct pci_device_id nv_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
@@ -236,7 +238,7 @@ static Scsi_Host_Template nv_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations nv_ops = {
+static const struct ata_port_operations nv_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -329,7 +331,7 @@ static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
return 0xffffffffU;
if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
- return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
else
return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -343,7 +345,7 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
return;
if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
- writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
else
outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -403,7 +405,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
rc = -ENOMEM;
ppi = &nv_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
goto err_out_regions;
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 538ad727bd2e..eee93b0016df 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -87,8 +87,8 @@ static void pdc_port_stop(struct ata_port *ap);
static void pdc_pata_phy_reset(struct ata_port *ap);
static void pdc_sata_phy_reset(struct ata_port *ap);
static void pdc_qc_prep(struct ata_queued_cmd *qc);
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_irq_clear(struct ata_port *ap);
static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
@@ -113,7 +113,7 @@ static Scsi_Host_Template pdc_ata_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations pdc_sata_ops = {
+static const struct ata_port_operations pdc_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = pdc_tf_load_mmio,
.tf_read = ata_tf_read,
@@ -136,7 +136,7 @@ static struct ata_port_operations pdc_sata_ops = {
.host_stop = ata_pci_host_stop,
};
-static struct ata_port_operations pdc_pata_ops = {
+static const struct ata_port_operations pdc_pata_ops = {
.port_disable = ata_port_disable,
.tf_load = pdc_tf_load_mmio,
.tf_read = ata_tf_read,
@@ -324,7 +324,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -333,7 +333,7 @@ static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void pdc_qc_prep(struct ata_queued_cmd *qc)
@@ -438,11 +438,11 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
break;
default:
- ap->stats.idle_irq++;
- break;
+ ap->stats.idle_irq++;
+ break;
}
- return handled;
+ return handled;
}
static void pdc_irq_clear(struct ata_port *ap)
@@ -523,8 +523,8 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
pp->pkt[2] = seq;
wmb(); /* flush PRD, pkt writes */
- writel(pp->pkt_dma, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
+ writel(pp->pkt_dma, (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
}
static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
@@ -546,7 +546,7 @@ static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
return ata_qc_issue_prot(qc);
}
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -554,7 +554,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
}
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index ffcdeb68641c..250dafa6bc36 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -51,8 +51,6 @@ enum {
QS_PRD_BYTES = QS_MAX_PRD * 16,
QS_PKT_BYTES = QS_CPB_BYTES + QS_PRD_BYTES,
- QS_DMA_BOUNDARY = ~0UL,
-
/* global register offsets */
QS_HCF_CNFG3 = 0x0003, /* host configuration offset */
QS_HID_HPHY = 0x0004, /* host physical interface info */
@@ -101,6 +99,10 @@ enum {
board_2068_idx = 0, /* QStor 4-port SATA/RAID */
};
+enum {
+ QS_DMA_BOUNDARY = ~0UL
+};
+
typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t;
struct qs_port_priv {
@@ -145,7 +147,7 @@ static Scsi_Host_Template qs_ata_sht = {
.bios_param = ata_std_bios_param,
};
-static struct ata_port_operations qs_ata_ops = {
+static const struct ata_port_operations qs_ata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index ba98a175ee3a..3a056173fb95 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -150,7 +150,7 @@ static Scsi_Host_Template sil_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations sil_ops = {
+static const struct ata_port_operations sil_ops = {
.port_disable = ata_port_disable,
.dev_config = sil_dev_config,
.tf_load = ata_tf_load,
@@ -289,7 +289,7 @@ static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_re
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- void *mmio = (void *) sil_scr_addr(ap, sc_reg);
+ void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
if (mmio)
return readl(mmio);
return 0xffffffffU;
@@ -297,7 +297,7 @@ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
- void *mmio = (void *) sil_scr_addr(ap, sc_reg);
+ void *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
if (mmio)
writel(val, mmio);
}
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
new file mode 100644
index 000000000000..32d730bd5bb6
--- /dev/null
+++ b/drivers/scsi/sata_sil24.c
@@ -0,0 +1,875 @@
+/*
+ * sata_sil24.c - Driver for Silicon Image 3124/3132 SATA-2 controllers
+ *
+ * Copyright 2005 Tejun Heo
+ *
+ * Based on preview driver from Silicon Image.
+ *
+ * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
+ * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
+ * those work. Enabling those shouldn't be difficult. Basic
+ * structure is all there (in libata-dev tree). If you have any
+ * information about this hardware, please contact me or linux-ide.
+ * Info is needed on...
+ *
+ * - How to issue tagged commands and turn on sactive on issue accordingly.
+ * - Where to put an ATAPI command and how to tell the device to send it.
+ * - How to enable/use 64bit.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <scsi/scsi_host.h>
+#include "scsi.h"
+#include <linux/libata.h>
+#include <asm/io.h>
+
+#define DRV_NAME "sata_sil24"
+#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */
+
+/*
+ * Port request block (PRB) 32 bytes
+ */
+struct sil24_prb {
+ u16 ctrl;
+ u16 prot;
+ u32 rx_cnt;
+ u8 fis[6 * 4];
+};
+
+/*
+ * Scatter gather entry (SGE) 16 bytes
+ */
+struct sil24_sge {
+ u64 addr;
+ u32 cnt;
+ u32 flags;
+};
+
+/*
+ * Port multiplier
+ */
+struct sil24_port_multiplier {
+ u32 diag;
+ u32 sactive;
+};
+
+enum {
+ /*
+ * Global controller registers (128 bytes @ BAR0)
+ */
+ /* 32 bit regs */
+ HOST_SLOT_STAT = 0x00, /* 32 bit slot stat * 4 */
+ HOST_CTRL = 0x40,
+ HOST_IRQ_STAT = 0x44,
+ HOST_PHY_CFG = 0x48,
+ HOST_BIST_CTRL = 0x50,
+ HOST_BIST_PTRN = 0x54,
+ HOST_BIST_STAT = 0x58,
+ HOST_MEM_BIST_STAT = 0x5c,
+ HOST_FLASH_CMD = 0x70,
+ /* 8 bit regs */
+ HOST_FLASH_DATA = 0x74,
+ HOST_TRANSITION_DETECT = 0x75,
+ HOST_GPIO_CTRL = 0x76,
+ HOST_I2C_ADDR = 0x78, /* 32 bit */
+ HOST_I2C_DATA = 0x7c,
+ HOST_I2C_XFER_CNT = 0x7e,
+ HOST_I2C_CTRL = 0x7f,
+
+ /* HOST_SLOT_STAT bits */
+ HOST_SSTAT_ATTN = (1 << 31),
+
+ /*
+ * Port registers
+ * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
+ */
+ PORT_REGS_SIZE = 0x2000,
+ PORT_PRB = 0x0000, /* (32 bytes PRB + 16 bytes SGEs * 6) * 31 (3968 bytes) */
+
+ PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */
+ /* 32 bit regs */
+ PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */
+ PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */
+ PORT_IRQ_STAT = 0x1008, /* high: status, low: interrupt */
+ PORT_IRQ_ENABLE_SET = 0x1010, /* write: enable-set */
+ PORT_IRQ_ENABLE_CLR = 0x1014, /* write: enable-clear */
+ PORT_ACTIVATE_UPPER_ADDR= 0x101c,
+ PORT_EXEC_FIFO = 0x1020, /* command execution fifo */
+ PORT_CMD_ERR = 0x1024, /* command error number */
+ PORT_FIS_CFG = 0x1028,
+ PORT_FIFO_THRES = 0x102c,
+ /* 16 bit regs */
+ PORT_DECODE_ERR_CNT = 0x1040,
+ PORT_DECODE_ERR_THRESH = 0x1042,
+ PORT_CRC_ERR_CNT = 0x1044,
+ PORT_CRC_ERR_THRESH = 0x1046,
+ PORT_HSHK_ERR_CNT = 0x1048,
+ PORT_HSHK_ERR_THRESH = 0x104a,
+ /* 32 bit regs */
+ PORT_PHY_CFG = 0x1050,
+ PORT_SLOT_STAT = 0x1800,
+ PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
+ PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
+ PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
+ PORT_SCONTROL = 0x1f00,
+ PORT_SSTATUS = 0x1f04,
+ PORT_SERROR = 0x1f08,
+ PORT_SACTIVE = 0x1f0c,
+
+ /* PORT_CTRL_STAT bits */
+ PORT_CS_PORT_RST = (1 << 0), /* port reset */
+ PORT_CS_DEV_RST = (1 << 1), /* device reset */
+ PORT_CS_INIT = (1 << 2), /* port initialize */
+ PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
+ PORT_CS_RESUME = (1 << 6), /* port resume */
+ PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
+ PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */
+ PORT_CS_RDY = (1 << 31), /* port ready to accept commands */
+
+ /* PORT_IRQ_STAT/ENABLE_SET/CLR */
+ /* bits[11:0] are masked */
+ PORT_IRQ_COMPLETE = (1 << 0), /* command(s) completed */
+ PORT_IRQ_ERROR = (1 << 1), /* command execution error */
+ PORT_IRQ_PORTRDY_CHG = (1 << 2), /* port ready change */
+ PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */
+ PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */
+ PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */
+ PORT_IRQ_UNK_FIS = (1 << 6), /* Unknown FIS received */
+ PORT_IRQ_SDB_FIS = (1 << 11), /* SDB FIS received */
+
+ /* bits[27:16] are unmasked (raw) */
+ PORT_IRQ_RAW_SHIFT = 16,
+ PORT_IRQ_MASKED_MASK = 0x7ff,
+ PORT_IRQ_RAW_MASK = (0x7ff << PORT_IRQ_RAW_SHIFT),
+
+ /* ENABLE_SET/CLR specific, intr steering - 2 bit field */
+ PORT_IRQ_STEER_SHIFT = 30,
+ PORT_IRQ_STEER_MASK = (3 << PORT_IRQ_STEER_SHIFT),
+
+ /* PORT_CMD_ERR constants */
+ PORT_CERR_DEV = 1, /* Error bit in D2H Register FIS */
+ PORT_CERR_SDB = 2, /* Error bit in SDB FIS */
+ PORT_CERR_DATA = 3, /* Error in data FIS not detected by dev */
+ PORT_CERR_SEND = 4, /* Initial cmd FIS transmission failure */
+ PORT_CERR_INCONSISTENT = 5, /* Protocol mismatch */
+ PORT_CERR_DIRECTION = 6, /* Data direction mismatch */
+ PORT_CERR_UNDERRUN = 7, /* Ran out of SGEs while writing */
+ PORT_CERR_OVERRUN = 8, /* Ran out of SGEs while reading */
+ PORT_CERR_PKT_PROT = 11, /* DIR invalid in 1st PIO setup of ATAPI */
+ PORT_CERR_SGT_BOUNDARY = 16, /* PLD ecode 00 - SGT not on qword boundary */
+ PORT_CERR_SGT_TGTABRT = 17, /* PLD ecode 01 - target abort */
+ PORT_CERR_SGT_MSTABRT = 18, /* PLD ecode 10 - master abort */
+ PORT_CERR_SGT_PCIPERR = 19, /* PLD ecode 11 - PCI parity err while fetching SGT */
+ PORT_CERR_CMD_BOUNDARY = 24, /* ctrl[15:13] 001 - PRB not on qword boundary */
+ PORT_CERR_CMD_TGTABRT = 25, /* ctrl[15:13] 010 - target abort */
+ PORT_CERR_CMD_MSTABRT = 26, /* ctrl[15:13] 100 - master abort */
+ PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
+ PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */
+ PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */
+ PORT_CERR_XFR_MSGABRT = 34, /* PSD ecode 10 - master abort */
+ PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */
+ PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */
+
+ /*
+ * Other constants
+ */
+ SGE_TRM = (1 << 31), /* Last SGE in chain */
+ PRB_SOFT_RST = (1 << 7), /* Soft reset request (ign BSY?) */
+
+ /* board id */
+ BID_SIL3124 = 0,
+ BID_SIL3132 = 1,
+ BID_SIL3131 = 2,
+
+ IRQ_STAT_4PORTS = 0xf,
+};
+
+struct sil24_cmd_block {
+ struct sil24_prb prb;
+ struct sil24_sge sge[LIBATA_MAX_PRD];
+};
+
+/*
+ * ap->private_data
+ *
+ * The preview driver always returned 0 for status. We emulate it
+ * here from the previous interrupt.
+ */
+struct sil24_port_priv {
+ struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
+ dma_addr_t cmd_block_dma; /* DMA base addr for them */
+ struct ata_taskfile tf; /* Cached taskfile registers */
+};
+
+/* ap->host_set->private_data */
+struct sil24_host_priv {
+ void *host_base; /* global controller control (128 bytes @BAR0) */
+ void *port_base; /* port registers (4 * 8192 bytes @BAR2) */
+};
+
+static u8 sil24_check_status(struct ata_port *ap);
+static u8 sil24_check_err(struct ata_port *ap);
+static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
+static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
+static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+static void sil24_phy_reset(struct ata_port *ap);
+static void sil24_qc_prep(struct ata_queued_cmd *qc);
+static int sil24_qc_issue(struct ata_queued_cmd *qc);
+static void sil24_irq_clear(struct ata_port *ap);
+static void sil24_eng_timeout(struct ata_port *ap);
+static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int sil24_port_start(struct ata_port *ap);
+static void sil24_port_stop(struct ata_port *ap);
+static void sil24_host_stop(struct ata_host_set *host_set);
+static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+
+static struct pci_device_id sil24_pci_tbl[] = {
+ { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
+ { 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
+ { 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
+ { 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
+ { } /* terminate list */
+};
+
+static struct pci_driver sil24_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = sil24_pci_tbl,
+ .probe = sil24_init_one,
+ .remove = ata_pci_remove_one, /* safe? */
+};
+
+static Scsi_Host_Template sil24_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .eh_strategy_handler = ata_scsi_error,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+ .ordered_flush = 1, /* NCQ not supported yet */
+};
+
+static const struct ata_port_operations sil24_ops = {
+ .port_disable = ata_port_disable,
+
+ .check_status = sil24_check_status,
+ .check_altstatus = sil24_check_status,
+ .check_err = sil24_check_err,
+ .dev_select = ata_noop_dev_select,
+
+ .tf_read = sil24_tf_read,
+
+ .phy_reset = sil24_phy_reset,
+
+ .qc_prep = sil24_qc_prep,
+ .qc_issue = sil24_qc_issue,
+
+ .eng_timeout = sil24_eng_timeout,
+
+ .irq_handler = sil24_interrupt,
+ .irq_clear = sil24_irq_clear,
+
+ .scr_read = sil24_scr_read,
+ .scr_write = sil24_scr_write,
+
+ .port_start = sil24_port_start,
+ .port_stop = sil24_port_stop,
+ .host_stop = sil24_host_stop,
+};
+
+/*
+ * Use bits 30-31 of host_flags to encode available port numbers.
+ * Current maxium is 4.
+ */
+#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
+#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
+
+static struct ata_port_info sil24_port_info[] = {
+ /* sil_3124 */
+ {
+ .sht = &sil24_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x3f, /* udma0-5 */
+ .port_ops = &sil24_ops,
+ },
+ /* sil_3132 */
+ {
+ .sht = &sil24_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x3f, /* udma0-5 */
+ .port_ops = &sil24_ops,
+ },
+ /* sil_3131/sil_3531 */
+ {
+ .sht = &sil24_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x3f, /* udma0-5 */
+ .port_ops = &sil24_ops,
+ },
+};
+
+static inline void sil24_update_tf(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ void *port = (void *)ap->ioaddr.cmd_addr;
+ struct sil24_prb *prb = port;
+
+ ata_tf_from_fis(prb->fis, &pp->tf);
+}
+
+static u8 sil24_check_status(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ return pp->tf.command;
+}
+
+static u8 sil24_check_err(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ return pp->tf.feature;
+}
+
+static int sil24_scr_map[] = {
+ [SCR_CONTROL] = 0,
+ [SCR_STATUS] = 1,
+ [SCR_ERROR] = 2,
+ [SCR_ACTIVE] = 3,
+};
+
+static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
+{
+ void *scr_addr = (void *)ap->ioaddr.scr_addr;
+ if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
+ void *addr;
+ addr = scr_addr + sil24_scr_map[sc_reg] * 4;
+ return readl(scr_addr + sil24_scr_map[sc_reg] * 4);
+ }
+ return 0xffffffffU;
+}
+
+static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+{
+ void *scr_addr = (void *)ap->ioaddr.scr_addr;
+ if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
+ void *addr;
+ addr = scr_addr + sil24_scr_map[sc_reg] * 4;
+ writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
+ }
+}
+
+static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ *tf = pp->tf;
+}
+
+static void sil24_phy_reset(struct ata_port *ap)
+{
+ __sata_phy_reset(ap);
+ /*
+ * No ATAPI yet. Just unconditionally indicate ATA device.
+ * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
+ * and libata core will ignore the device.
+ */
+ if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+ ap->device[0].class = ATA_DEV_ATA;
+}
+
+static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
+ struct sil24_cmd_block *cb)
+{
+ struct scatterlist *sg = qc->sg;
+ struct sil24_sge *sge = cb->sge;
+ unsigned i;
+
+ for (i = 0; i < qc->n_elem; i++, sg++, sge++) {
+ sge->addr = cpu_to_le64(sg_dma_address(sg));
+ sge->cnt = cpu_to_le32(sg_dma_len(sg));
+ sge->flags = 0;
+ sge->flags = i < qc->n_elem - 1 ? 0 : cpu_to_le32(SGE_TRM);
+ }
+}
+
+static void sil24_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct sil24_port_priv *pp = ap->private_data;
+ struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
+ struct sil24_prb *prb = &cb->prb;
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_PIO:
+ case ATA_PROT_DMA:
+ case ATA_PROT_NODATA:
+ break;
+ default:
+ /* ATAPI isn't supported yet */
+ BUG();
+ }
+
+ ata_tf_to_fis(&qc->tf, prb->fis, 0);
+
+ if (qc->flags & ATA_QCFLAG_DMAMAP)
+ sil24_fill_sg(qc, cb);
+}
+
+static int sil24_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void *port = (void *)ap->ioaddr.cmd_addr;
+ struct sil24_port_priv *pp = ap->private_data;
+ dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
+
+ writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+ return 0;
+}
+
+static void sil24_irq_clear(struct ata_port *ap)
+{
+ /* unused */
+}
+
+static int __sil24_reset_controller(void *port)
+{
+ int cnt;
+ u32 tmp;
+
+ /* Reset controller state. Is this correct? */
+ writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
+ readl(port + PORT_CTRL_STAT); /* sync */
+
+ /* Max ~100ms */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ udelay(100);
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (!(tmp & PORT_CS_DEV_RST))
+ break;
+ }
+
+ if (tmp & PORT_CS_DEV_RST)
+ return -1;
+ return 0;
+}
+
+static void sil24_reset_controller(struct ata_port *ap)
+{
+ printk(KERN_NOTICE DRV_NAME
+ " ata%u: resetting controller...\n", ap->id);
+ if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr))
+ printk(KERN_ERR DRV_NAME
+ " ata%u: failed to reset controller\n", ap->id);
+}
+
+static void sil24_eng_timeout(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (!qc) {
+ printk(KERN_ERR "ata%u: BUG: tiemout without command\n",
+ ap->id);
+ return;
+ }
+
+ /*
+ * hack alert! We cannot use the supplied completion
+ * function from inside the ->eh_strategy_handler() thread.
+ * libata is the only user of ->eh_strategy_handler() in
+ * any kernel, so the default scsi_done() assumes it is
+ * not being called from the SCSI EH.
+ */
+ printk(KERN_ERR "ata%u: command timeout\n", ap->id);
+ qc->scsidone = scsi_finish_command;
+ ata_qc_complete(qc, ATA_ERR);
+
+ sil24_reset_controller(ap);
+}
+
+static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
+{
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+ struct sil24_port_priv *pp = ap->private_data;
+ void *port = (void *)ap->ioaddr.cmd_addr;
+ u32 irq_stat, cmd_err, sstatus, serror;
+
+ irq_stat = readl(port + PORT_IRQ_STAT);
+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
+
+ if (!(irq_stat & PORT_IRQ_ERROR)) {
+ /* ignore non-completion, non-error irqs for now */
+ printk(KERN_WARNING DRV_NAME
+ "ata%u: non-error exception irq (irq_stat %x)\n",
+ ap->id, irq_stat);
+ return;
+ }
+
+ cmd_err = readl(port + PORT_CMD_ERR);
+ sstatus = readl(port + PORT_SSTATUS);
+ serror = readl(port + PORT_SERROR);
+ if (serror)
+ writel(serror, port + PORT_SERROR);
+
+ printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
+ " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
+ ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
+
+ if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
+ /*
+ * Device is reporting error, tf registers are valid.
+ */
+ sil24_update_tf(ap);
+ } else {
+ /*
+ * Other errors. libata currently doesn't have any
+ * mechanism to report these errors. Just turn on
+ * ATA_ERR.
+ */
+ pp->tf.command = ATA_ERR;
+ }
+
+ if (qc)
+ ata_qc_complete(qc, pp->tf.command);
+
+ sil24_reset_controller(ap);
+}
+
+static inline void sil24_host_intr(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+ void *port = (void *)ap->ioaddr.cmd_addr;
+ u32 slot_stat;
+
+ slot_stat = readl(port + PORT_SLOT_STAT);
+ if (!(slot_stat & HOST_SSTAT_ATTN)) {
+ struct sil24_port_priv *pp = ap->private_data;
+ /*
+ * !HOST_SSAT_ATTN guarantees successful completion,
+ * so reading back tf registers is unnecessary for
+ * most commands. TODO: read tf registers for
+ * commands which require these values on successful
+ * completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER,
+ * DEVICE RESET and READ PORT MULTIPLIER (any more?).
+ */
+ sil24_update_tf(ap);
+
+ if (qc)
+ ata_qc_complete(qc, pp->tf.command);
+ } else
+ sil24_error_intr(ap, slot_stat);
+}
+
+static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ata_host_set *host_set = dev_instance;
+ struct sil24_host_priv *hpriv = host_set->private_data;
+ unsigned handled = 0;
+ u32 status;
+ int i;
+
+ status = readl(hpriv->host_base + HOST_IRQ_STAT);
+
+ if (status == 0xffffffff) {
+ printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
+ "PCI fault or device removal?\n");
+ goto out;
+ }
+
+ if (!(status & IRQ_STAT_4PORTS))
+ goto out;
+
+ spin_lock(&host_set->lock);
+
+ for (i = 0; i < host_set->n_ports; i++)
+ if (status & (1 << i)) {
+ struct ata_port *ap = host_set->ports[i];
+ if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
+ sil24_host_intr(host_set->ports[i]);
+ handled++;
+ } else
+ printk(KERN_ERR DRV_NAME
+ ": interrupt from disabled port %d\n", i);
+ }
+
+ spin_unlock(&host_set->lock);
+ out:
+ return IRQ_RETVAL(handled);
+}
+
+static int sil24_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct sil24_port_priv *pp;
+ struct sil24_cmd_block *cb;
+ size_t cb_size = sizeof(*cb);
+ dma_addr_t cb_dma;
+
+ pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+ memset(pp, 0, sizeof(*pp));
+
+ pp->tf.command = ATA_DRDY;
+
+ cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
+ if (!cb) {
+ kfree(pp);
+ return -ENOMEM;
+ }
+ memset(cb, 0, cb_size);
+
+ pp->cmd_block = cb;
+ pp->cmd_block_dma = cb_dma;
+
+ ap->private_data = pp;
+
+ return 0;
+}
+
+static void sil24_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct sil24_port_priv *pp = ap->private_data;
+ size_t cb_size = sizeof(*pp->cmd_block);
+
+ dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
+ kfree(pp);
+}
+
+static void sil24_host_stop(struct ata_host_set *host_set)
+{
+ struct sil24_host_priv *hpriv = host_set->private_data;
+
+ iounmap(hpriv->host_base);
+ iounmap(hpriv->port_base);
+ kfree(hpriv);
+}
+
+static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version = 0;
+ unsigned int board_id = (unsigned int)ent->driver_data;
+ struct ata_port_info *pinfo = &sil24_port_info[board_id];
+ struct ata_probe_ent *probe_ent = NULL;
+ struct sil24_host_priv *hpriv = NULL;
+ void *host_base = NULL, *port_base = NULL;
+ int i, rc;
+
+ if (!printed_version++)
+ printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto out_disable;
+
+ rc = -ENOMEM;
+ /* ioremap mmio registers */
+ host_base = ioremap(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (!host_base)
+ goto out_free;
+ port_base = ioremap(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ if (!port_base)
+ goto out_free;
+
+ /* allocate & init probe_ent and hpriv */
+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ if (!probe_ent)
+ goto out_free;
+
+ hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ goto out_free;
+
+ memset(probe_ent, 0, sizeof(*probe_ent));
+ probe_ent->dev = pci_dev_to_dev(pdev);
+ INIT_LIST_HEAD(&probe_ent->node);
+
+ probe_ent->sht = pinfo->sht;
+ probe_ent->host_flags = pinfo->host_flags;
+ probe_ent->pio_mask = pinfo->pio_mask;
+ probe_ent->udma_mask = pinfo->udma_mask;
+ probe_ent->port_ops = pinfo->port_ops;
+ probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->host_flags);
+
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->mmio_base = port_base;
+ probe_ent->private_data = hpriv;
+
+ memset(hpriv, 0, sizeof(*hpriv));
+ hpriv->host_base = host_base;
+ hpriv->port_base = port_base;
+
+ /*
+ * Configure the device
+ */
+ /*
+ * FIXME: This device is certainly 64-bit capable. We just
+ * don't know how to use it. After fixing 32bit activation in
+ * this function, enable 64bit masks here.
+ */
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
+ pci_name(pdev));
+ goto out_free;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
+ pci_name(pdev));
+ goto out_free;
+ }
+
+ /* GPIO off */
+ writel(0, host_base + HOST_FLASH_CMD);
+
+ /* Mask interrupts during initialization */
+ writel(0, host_base + HOST_CTRL);
+
+ for (i = 0; i < probe_ent->n_ports; i++) {
+ void *port = port_base + i * PORT_REGS_SIZE;
+ unsigned long portu = (unsigned long)port;
+ u32 tmp;
+ int cnt;
+
+ probe_ent->port[i].cmd_addr = portu + PORT_PRB;
+ probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
+
+ ata_std_ports(&probe_ent->port[i]);
+
+ /* Initial PHY setting */
+ writel(0x20c, port + PORT_PHY_CFG);
+
+ /* Clear port RST */
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (tmp & PORT_CS_PORT_RST) {
+ writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
+ readl(port + PORT_CTRL_STAT); /* sync */
+ for (cnt = 0; cnt < 10; cnt++) {
+ msleep(10);
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (!(tmp & PORT_CS_PORT_RST))
+ break;
+ }
+ if (tmp & PORT_CS_PORT_RST)
+ printk(KERN_ERR DRV_NAME
+ "(%s): failed to clear port RST\n",
+ pci_name(pdev));
+ }
+
+ /* Zero error counters. */
+ writel(0x8000, port + PORT_DECODE_ERR_THRESH);
+ writel(0x8000, port + PORT_CRC_ERR_THRESH);
+ writel(0x8000, port + PORT_HSHK_ERR_THRESH);
+ writel(0x0000, port + PORT_DECODE_ERR_CNT);
+ writel(0x0000, port + PORT_CRC_ERR_CNT);
+ writel(0x0000, port + PORT_HSHK_ERR_CNT);
+
+ /* FIXME: 32bit activation? */
+ writel(0, port + PORT_ACTIVATE_UPPER_ADDR);
+ writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT);
+
+ /* Configure interrupts */
+ writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
+ writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS,
+ port + PORT_IRQ_ENABLE_SET);
+
+ /* Clear interrupts */
+ writel(0x0fff0fff, port + PORT_IRQ_STAT);
+ writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
+
+ /* Clear port multiplier enable and resume bits */
+ writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
+
+ /* Reset itself */
+ if (__sil24_reset_controller(port))
+ printk(KERN_ERR DRV_NAME
+ "(%s): failed to reset controller\n",
+ pci_name(pdev));
+ }
+
+ /* Turn on interrupts */
+ writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL);
+
+ pci_set_master(pdev);
+
+ /* FIXME: check ata_device_add return value */
+ ata_device_add(probe_ent);
+
+ kfree(probe_ent);
+ return 0;
+
+ out_free:
+ if (host_base)
+ iounmap(host_base);
+ if (port_base)
+ iounmap(port_base);
+ kfree(probe_ent);
+ kfree(hpriv);
+ pci_release_regions(pdev);
+ out_disable:
+ pci_disable_device(pdev);
+ return rc;
+}
+
+static int __init sil24_init(void)
+{
+ return pci_module_init(&sil24_pci_driver);
+}
+
+static void __exit sil24_exit(void)
+{
+ pci_unregister_driver(&sil24_pci_driver);
+}
+
+MODULE_AUTHOR("Tejun Heo");
+MODULE_DESCRIPTION("Silicon Image 3124/3132 SATA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, sil24_pci_tbl);
+
+module_init(sil24_init);
+module_exit(sil24_exit);
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 43af445b3ad2..057f7b98b6c4 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 */
};
@@ -98,7 +102,7 @@ static Scsi_Host_Template sis_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations sis_ops = {
+static const struct ata_port_operations sis_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -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 = 0;
+ 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)
@@ -229,7 +263,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
ppi = &sis_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;
@@ -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 = 64;
+ }
+ 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_svw.c b/drivers/scsi/sata_svw.c
index d89d968bedac..e0f9570bc6dd 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -102,7 +102,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
}
-static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
+static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -297,7 +297,7 @@ static Scsi_Host_Template k2_sata_sht = {
};
-static struct ata_port_operations k2_sata_ops = {
+static const struct ata_port_operations k2_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = k2_sata_tf_load,
.tf_read = k2_sata_tf_read,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 540a85191172..af08f4f650c1 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -137,7 +137,7 @@ struct pdc_port_priv {
};
struct pdc_host_priv {
- void *dimm_mmio;
+ void __iomem *dimm_mmio;
unsigned int doing_hdma;
unsigned int hdma_prod;
@@ -157,8 +157,8 @@ static void pdc_20621_phy_reset (struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static void pdc_port_stop(struct ata_port *ap);
static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc20621_host_stop(struct ata_host_set *host_set);
static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
@@ -196,7 +196,7 @@ static Scsi_Host_Template pdc_sata_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations pdc_20621_ops = {
+static const struct ata_port_operations pdc_20621_ops = {
.port_disable = ata_port_disable,
.tf_load = pdc_tf_load_mmio,
.tf_read = ata_tf_read,
@@ -247,7 +247,7 @@ static void pdc20621_host_stop(struct ata_host_set *host_set)
{
struct pci_dev *pdev = to_pci_dev(host_set->dev);
struct pdc_host_priv *hpriv = host_set->private_data;
- void *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *dimm_mmio = hpriv->dimm_mmio;
pci_iounmap(pdev, dimm_mmio);
kfree(hpriv);
@@ -669,8 +669,8 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
readl(mmio + PDC_20621_SEQCTL + (seq * 4)); /* flush */
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
port_ofs + PDC_DIMM_ATA_PKT,
port_ofs + PDC_DIMM_ATA_PKT,
@@ -747,8 +747,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
readl(mmio + PDC_20621_SEQCTL + (seq * 4));
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
}
/* step two - execute ATA command */
@@ -899,7 +899,7 @@ out:
DPRINTK("EXIT\n");
}
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -907,7 +907,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
}
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -1014,7 +1014,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
idx++;
dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size :
(long) (window_size - offset);
- memcpy_toio((char *) (dimm_mmio + offset / 4), (char *) psource, dist);
+ memcpy_toio(dimm_mmio + offset / 4, psource, dist);
writel(0x01, mmio + PDC_GENERAL_CTLR);
readl(mmio + PDC_GENERAL_CTLR);
@@ -1023,8 +1023,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
for (; (long) size >= (long) window_size ;) {
writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
readl(mmio + PDC_DIMM_WINDOW_CTLR);
- memcpy_toio((char *) (dimm_mmio), (char *) psource,
- window_size / 4);
+ memcpy_toio(dimm_mmio, psource, window_size / 4);
writel(0x01, mmio + PDC_GENERAL_CTLR);
readl(mmio + PDC_GENERAL_CTLR);
psource += window_size;
@@ -1035,7 +1034,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
if (size) {
writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
readl(mmio + PDC_DIMM_WINDOW_CTLR);
- memcpy_toio((char *) (dimm_mmio), (char *) psource, size / 4);
+ memcpy_toio(dimm_mmio, psource, size / 4);
writel(0x01, mmio + PDC_GENERAL_CTLR);
readl(mmio + PDC_GENERAL_CTLR);
}
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 42e13ed8eb5b..d68dc7d3422c 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -90,7 +90,7 @@ static Scsi_Host_Template uli_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations uli_ops = {
+static const struct ata_port_operations uli_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -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;
@@ -214,7 +202,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
ppi = &uli_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;
@@ -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/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 128b996b07b7..80e291a909a9 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -109,7 +109,7 @@ static Scsi_Host_Template svia_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations svia_sata_ops = {
+static const struct ata_port_operations svia_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -212,7 +212,7 @@ static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi = &svia_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
return NULL;
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index cf94e0158a8d..5af05fdf8544 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -86,7 +86,7 @@ static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -95,16 +95,16 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
{
- unsigned long mask_addr;
+ void __iomem *mask_addr;
u8 mask;
- mask_addr = (unsigned long) ap->host_set->mmio_base +
+ mask_addr = ap->host_set->mmio_base +
VSC_SATA_INT_MASK_OFFSET + ap->port_no;
mask = readb(mask_addr);
if (ctl & ATA_NIEN)
@@ -115,7 +115,7 @@ static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
}
-static void vsc_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
+static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -231,7 +231,7 @@ static Scsi_Host_Template vsc_sata_sht = {
};
-static struct ata_port_operations vsc_sata_ops = {
+static const struct ata_port_operations vsc_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = vsc_sata_tf_load,
.tf_read = vsc_sata_tf_read,
@@ -283,7 +283,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
struct ata_probe_ent *probe_ent = NULL;
unsigned long base;
int pci_dev_busy = 0;
- void *mmio_base;
+ void __iomem *mmio_base;
int rc;
if (!printed_version++)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a780546eda9c..a5711d545d71 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -130,7 +130,7 @@ EXPORT_SYMBOL(scsi_device_types);
* Returns: Pointer to request block.
*/
struct scsi_request *scsi_allocate_request(struct scsi_device *sdev,
- int gfp_mask)
+ gfp_t gfp_mask)
{
const int offset = ALIGN(sizeof(struct scsi_request), 4);
const int size = offset + sizeof(struct request);
@@ -196,7 +196,7 @@ struct scsi_host_cmd_pool {
unsigned int users;
char *name;
unsigned int slab_flags;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
};
static struct scsi_host_cmd_pool scsi_cmd_pool = {
@@ -213,7 +213,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
static DECLARE_MUTEX(host_cmd_pool_mutex);
static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
@@ -245,7 +245,7 @@ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
*
* Returns: The allocated scsi command structure.
*/
-struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
+struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
@@ -1265,9 +1265,8 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
list_for_each_safe(lh, lh_sf, &active_list) {
scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
list_del_init(lh);
- if (recovery) {
- scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
- } else {
+ if (recovery &&
+ !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) {
scmd->result = (DID_ABORT << 16);
scsi_finish_command(scmd);
}
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 07b554affcf2..e69477d1889b 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -110,6 +110,7 @@ static struct {
{"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */
{"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */
{"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN},
+ {"transtec", "T5008", "0001", BLIST_NOREPORTLUN },
{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */
{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */
{"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */
@@ -184,6 +185,7 @@ static struct {
{"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
{"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 895c9452be4c..52b348c36d56 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -50,7 +50,7 @@
void scsi_eh_wakeup(struct Scsi_Host *shost)
{
if (shost->host_busy == shost->host_failed) {
- up(shost->eh_wait);
+ wake_up_process(shost->ehandler);
SCSI_LOG_ERROR_RECOVERY(5,
printk("Waking error handler thread\n"));
}
@@ -68,19 +68,24 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
{
struct Scsi_Host *shost = scmd->device->host;
unsigned long flags;
+ int ret = 0;
- if (shost->eh_wait == NULL)
+ if (!shost->ehandler)
return 0;
spin_lock_irqsave(shost->host_lock, flags);
+ if (scsi_host_set_state(shost, SHOST_RECOVERY))
+ if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY))
+ goto out_unlock;
+ ret = 1;
scmd->eh_eflags |= eh_flag;
list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
- scsi_host_set_state(shost, SHOST_RECOVERY);
shost->host_failed++;
scsi_eh_wakeup(shost);
+ out_unlock:
spin_unlock_irqrestore(shost->host_lock, flags);
- return 1;
+ return ret;
}
/**
@@ -176,8 +181,8 @@ void scsi_times_out(struct scsi_cmnd *scmd)
}
if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
- panic("Error handler thread not present at %p %p %s %d",
- scmd, scmd->device->host, __FILE__, __LINE__);
+ scmd->result |= DID_TIME_OUT << 16;
+ __scsi_done(scmd);
}
}
@@ -196,8 +201,7 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
{
int online;
- wait_event(sdev->host->host_wait, (sdev->host->shost_state !=
- SHOST_RECOVERY));
+ wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host));
online = scsi_device_online(sdev);
@@ -1441,6 +1445,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
static void scsi_restart_operations(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
+ unsigned long flags;
/*
* If the door was locked, we need to insert a door lock request
@@ -1460,7 +1465,11 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
__FUNCTION__));
- scsi_host_set_state(shost, SHOST_RUNNING);
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (scsi_host_set_state(shost, SHOST_RUNNING))
+ if (scsi_host_set_state(shost, SHOST_CANCEL))
+ BUG_ON(scsi_host_set_state(shost, SHOST_DEL));
+ spin_unlock_irqrestore(shost->host_lock, flags);
wake_up(&shost->host_wait);
@@ -1582,40 +1591,31 @@ int scsi_error_handler(void *data)
{
struct Scsi_Host *shost = (struct Scsi_Host *) data;
int rtn;
- DECLARE_MUTEX_LOCKED(sem);
current->flags |= PF_NOFREEZE;
- shost->eh_wait = &sem;
+
/*
- * Wake up the thread that created us.
+ * Note - we always use TASK_INTERRUPTIBLE even if the module
+ * was loaded as part of the kernel. The reason is that
+ * UNINTERRUPTIBLE would cause this thread to be counted in
+ * the load average as a running process, and an interruptible
+ * wait doesn't.
*/
- SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
- " scsi_eh_%d\n",shost->host_no));
-
- while (1) {
- /*
- * If we get a signal, it means we are supposed to go
- * away and die. This typically happens if the user is
- * trying to unload a module.
- */
- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
- " scsi_eh_%d"
- " sleeping\n",shost->host_no));
-
- /*
- * Note - we always use down_interruptible with the semaphore
- * even if the module was loaded as part of the kernel. The
- * reason is that down() will cause this thread to be counted
- * in the load average as a running process, and down
- * interruptible doesn't. Given that we need to allow this
- * thread to die if the driver was loaded as a module, using
- * semaphores isn't unreasonable.
- */
- down_interruptible(&sem);
- if (kthread_should_stop())
- break;
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (!kthread_should_stop()) {
+ if (shost->host_failed == 0 ||
+ shost->host_failed != shost->host_busy) {
+ SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
+ " scsi_eh_%d"
+ " sleeping\n",
+ shost->host_no));
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ continue;
+ }
+ __set_current_state(TASK_RUNNING);
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
" scsi_eh_%d waking"
" up\n",shost->host_no));
@@ -1642,16 +1642,18 @@ int scsi_error_handler(void *data)
* which are still online.
*/
scsi_restart_operations(shost);
-
+ set_current_state(TASK_INTERRUPTIBLE);
}
+ __set_current_state(TASK_RUNNING);
+
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"
" exiting\n",shost->host_no));
/*
* Make sure that nobody tries to wake us up again.
*/
- shost->eh_wait = NULL;
+ shost->ehandler = NULL;
return 0;
}
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index b7fddac81347..6a3f6aae8a97 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -205,7 +205,8 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
unsigned int inlen, outlen, cmdlen;
unsigned int needed, buf_needed;
int timeout, retries, result;
- int data_direction, gfp_mask = GFP_KERNEL;
+ int data_direction;
+ gfp_t gfp_mask = GFP_KERNEL;
if (!sic)
return -EINVAL;
@@ -458,7 +459,7 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
* error processing, as long as the device was opened
* non-blocking */
if (filp && filp->f_flags & O_NONBLOCK) {
- if (sdev->host->shost_state == SHOST_RECOVERY)
+ if (scsi_host_in_recovery(sdev->host))
return -ENODEV;
} else if (!scsi_block_when_processing_errors(sdev))
return -ENODEV;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 77f2d444f7e0..3ff538809786 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -99,6 +99,28 @@ int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
static void scsi_run_queue(struct request_queue *q);
/*
+ * Function: scsi_unprep_request()
+ *
+ * Purpose: Remove all preparation done for a request, including its
+ * associated scsi_cmnd, so that it can be requeued.
+ *
+ * Arguments: req - request to unprepare
+ *
+ * Lock status: Assumed that no locks are held upon entry.
+ *
+ * Returns: Nothing.
+ */
+static void scsi_unprep_request(struct request *req)
+{
+ struct scsi_cmnd *cmd = req->special;
+
+ req->flags &= ~REQ_DONTPREP;
+ req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL;
+
+ scsi_put_command(cmd);
+}
+
+/*
* Function: scsi_queue_insert()
*
* Purpose: Insert a command in the midlevel queue.
@@ -339,7 +361,7 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
int result;
if (sshdr) {
- sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+ sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
if (!sense)
return DRIVER_ERROR << 24;
memset(sense, 0, SCSI_SENSE_BUFFERSIZE);
@@ -424,7 +446,7 @@ void scsi_device_unbusy(struct scsi_device *sdev)
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
- if (unlikely((shost->shost_state == SHOST_RECOVERY) &&
+ if (unlikely(scsi_host_in_recovery(shost) &&
shost->host_failed))
scsi_eh_wakeup(shost);
spin_unlock(shost->host_lock);
@@ -552,15 +574,16 @@ static void scsi_run_queue(struct request_queue *q)
* I/O errors in the middle of the request, in which case
* we need to request the blocks that come after the bad
* sector.
+ * Notes: Upon return, cmd is a stale pointer.
*/
static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
{
+ struct request *req = cmd->request;
unsigned long flags;
- cmd->request->flags &= ~REQ_DONTPREP;
-
+ scsi_unprep_request(req);
spin_lock_irqsave(q->queue_lock, flags);
- blk_requeue_request(q, cmd->request);
+ blk_requeue_request(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
scsi_run_queue(q);
@@ -595,13 +618,14 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
*
* Lock status: Assumed that lock is not held upon entry.
*
- * Returns: cmd if requeue done or required, NULL otherwise
+ * Returns: cmd if requeue required, NULL otherwise.
*
* Notes: This is called for block device requests in order to
* mark some number of sectors as complete.
*
* We are guaranteeing that the request queue will be goosed
* at some point during this call.
+ * Notes: If cmd was requeued, upon return it will be a stale pointer.
*/
static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
int bytes, int requeue)
@@ -624,14 +648,15 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
if (!uptodate && blk_noretry_request(req))
end_that_request_chunk(req, 0, leftover);
else {
- if (requeue)
+ if (requeue) {
/*
* Bleah. Leftovers again. Stick the
* leftovers in the front of the
* queue, and goose the queue again.
*/
scsi_requeue_command(q, cmd);
-
+ cmd = NULL;
+ }
return cmd;
}
}
@@ -652,7 +677,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
return NULL;
}
-static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, int gfp_mask)
+static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
struct scsi_host_sg_pool *sgp;
struct scatterlist *sgl;
@@ -857,15 +882,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
* requeueing right here - we will requeue down below
* when we handle the bad sectors.
*/
- cmd = scsi_end_request(cmd, 1, good_bytes, result == 0);
/*
- * If the command completed without error, then either finish off the
- * rest of the command, or start a new one.
+ * If the command completed without error, then either
+ * finish off the rest of the command, or start a new one.
*/
- if (result == 0 || cmd == NULL ) {
+ if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL)
return;
- }
}
/*
* Now, if we were good little boys and girls, Santa left us a request
@@ -880,7 +903,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
* and quietly refuse further access.
*/
cmd->device->changed = 1;
- cmd = scsi_end_request(cmd, 0,
+ scsi_end_request(cmd, 0,
this_count, 1);
return;
} else {
@@ -914,7 +937,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
scsi_requeue_command(q, cmd);
result = 0;
} else {
- cmd = scsi_end_request(cmd, 0, this_count, 1);
+ scsi_end_request(cmd, 0, this_count, 1);
return;
}
break;
@@ -931,7 +954,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
dev_printk(KERN_INFO,
&cmd->device->sdev_gendev,
"Device not ready.\n");
- cmd = scsi_end_request(cmd, 0, this_count, 1);
+ scsi_end_request(cmd, 0, this_count, 1);
return;
case VOLUME_OVERFLOW:
if (!(req->flags & REQ_QUIET)) {
@@ -941,7 +964,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
__scsi_print_command(cmd->data_cmnd);
scsi_print_sense("", cmd);
}
- cmd = scsi_end_request(cmd, 0, block_bytes, 1);
+ scsi_end_request(cmd, 0, block_bytes, 1);
return;
default:
break;
@@ -972,7 +995,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
block_bytes = req->hard_cur_sectors << 9;
if (!block_bytes)
block_bytes = req->data_len;
- cmd = scsi_end_request(cmd, 0, block_bytes, 1);
+ scsi_end_request(cmd, 0, block_bytes, 1);
}
}
EXPORT_SYMBOL(scsi_io_completion);
@@ -1016,8 +1039,10 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
* if sg table allocation fails, requeue request later.
*/
sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
- if (unlikely(!sgpnt))
+ if (unlikely(!sgpnt)) {
+ scsi_unprep_request(req);
return BLKPREP_DEFER;
+ }
cmd->request_buffer = (char *) sgpnt;
cmd->request_bufflen = req->nr_sectors << 9;
@@ -1118,7 +1143,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
if (unlikely(!scsi_device_online(sdev))) {
printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",
sdev->host->host_no, sdev->id, sdev->lun);
- return BLKPREP_KILL;
+ goto kill;
}
if (unlikely(sdev->sdev_state != SDEV_RUNNING)) {
/* OK, we're not in a running state don't prep
@@ -1128,7 +1153,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* at all allowed down */
printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n",
sdev->host->host_no, sdev->id, sdev->lun);
- return BLKPREP_KILL;
+ goto kill;
}
/* OK, we only allow special commands (i.e. not
* user initiated ones */
@@ -1160,11 +1185,11 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) {
if(specials_only == SDEV_QUIESCE ||
specials_only == SDEV_BLOCK)
- return BLKPREP_DEFER;
+ goto defer;
printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n",
sdev->host->host_no, sdev->id, sdev->lun);
- return BLKPREP_KILL;
+ goto kill;
}
@@ -1182,7 +1207,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
cmd->tag = req->tag;
} else {
blk_dump_rq_flags(req, "SCSI bad req");
- return BLKPREP_KILL;
+ goto kill;
}
/* note the overloading of req->special. When the tag
@@ -1220,8 +1245,13 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* required).
*/
ret = scsi_init_io(cmd);
- if (ret) /* BLKPREP_KILL return also releases the command */
- return ret;
+ switch(ret) {
+ /* For BLKPREP_KILL/DEFER the cmd was released */
+ case BLKPREP_KILL:
+ goto kill;
+ case BLKPREP_DEFER:
+ goto defer;
+ }
/*
* Initialize the actual SCSI command for this request.
@@ -1231,10 +1261,11 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd);
scsi_put_command(cmd);
- return BLKPREP_KILL;
+ goto kill;
}
} else {
memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
+ cmd->cmd_len = req->cmd_len;
if (rq_data_dir(req) == WRITE)
cmd->sc_data_direction = DMA_TO_DEVICE;
else if (req->data_len)
@@ -1262,6 +1293,9 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
if (sdev->device_busy == 0)
blk_plug_device(q);
return BLKPREP_DEFER;
+ kill:
+ req->errors = DID_NO_CONNECT << 16;
+ return BLKPREP_KILL;
}
/*
@@ -1306,7 +1340,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
struct Scsi_Host *shost,
struct scsi_device *sdev)
{
- if (shost->shost_state == SHOST_RECOVERY)
+ if (scsi_host_in_recovery(shost))
return 0;
if (shost->host_busy == 0 && shost->host_blocked) {
/*
@@ -1336,19 +1370,24 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
}
/*
- * Kill requests for a dead device
+ * Kill a request for a dead device
*/
-static void scsi_kill_requests(request_queue_t *q)
+static void scsi_kill_request(struct request *req, request_queue_t *q)
{
- struct request *req;
+ struct scsi_cmnd *cmd = req->special;
+
+ blkdev_dequeue_request(req);
- while ((req = elv_next_request(q)) != NULL) {
- blkdev_dequeue_request(req);
- req->flags |= REQ_QUIET;
- while (end_that_request_first(req, 0, req->nr_sectors))
- ;
- end_that_request_last(req);
+ if (unlikely(cmd == NULL)) {
+ printk(KERN_CRIT "impossible request in %s.\n",
+ __FUNCTION__);
+ BUG();
}
+
+ scsi_init_cmd_errh(cmd);
+ cmd->result = DID_NO_CONNECT << 16;
+ atomic_inc(&cmd->device->iorequest_cnt);
+ __scsi_done(cmd);
}
/*
@@ -1371,7 +1410,8 @@ static void scsi_request_fn(struct request_queue *q)
if (!sdev) {
printk("scsi: killing requests for dead queue\n");
- scsi_kill_requests(q);
+ while ((req = elv_next_request(q)) != NULL)
+ scsi_kill_request(req, q);
return;
}
@@ -1398,11 +1438,7 @@ static void scsi_request_fn(struct request_queue *q)
if (unlikely(!scsi_device_online(sdev))) {
printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",
sdev->host->host_no, sdev->id, sdev->lun);
- blkdev_dequeue_request(req);
- req->flags |= REQ_QUIET;
- while (end_that_request_first(req, 0, req->nr_sectors))
- ;
- end_that_request_last(req);
+ scsi_kill_request(req, q);
continue;
}
@@ -1415,6 +1451,14 @@ static void scsi_request_fn(struct request_queue *q)
sdev->device_busy++;
spin_unlock(q->queue_lock);
+ cmd = req->special;
+ if (unlikely(cmd == NULL)) {
+ printk(KERN_CRIT "impossible request in %s.\n"
+ "please mail a stack trace to "
+ "linux-scsi@vger.kernel.org",
+ __FUNCTION__);
+ BUG();
+ }
spin_lock(shost->host_lock);
if (!scsi_host_queue_ready(q, shost, sdev))
@@ -1433,15 +1477,6 @@ static void scsi_request_fn(struct request_queue *q)
*/
spin_unlock_irq(shost->host_lock);
- cmd = req->special;
- if (unlikely(cmd == NULL)) {
- printk(KERN_CRIT "impossible request in %s.\n"
- "please mail a stack trace to "
- "linux-scsi@vger.kernel.org",
- __FUNCTION__);
- BUG();
- }
-
/*
* Finally, initialize any error handling parameters, and set up
* the timers for timeouts.
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index ee6de1768e53..d05f778d31a8 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -124,6 +124,7 @@ extern void scsi_sysfs_unregister(void);
extern void scsi_sysfs_device_initialize(struct scsi_device *);
extern int scsi_sysfs_target_initialize(struct scsi_device *);
extern struct scsi_transport_template blank_transport_template;
+extern void __scsi_remove_device(struct scsi_device *);
extern struct bus_type scsi_bus_type;
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 19c9a232a754..327c5d7e5bd2 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -587,6 +587,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
if (sdev->scsi_level >= 2 ||
(sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
sdev->scsi_level++;
+ sdev->sdev_target->scsi_level = sdev->scsi_level;
return 0;
}
@@ -771,6 +772,15 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
return SCSI_SCAN_LUN_PRESENT;
}
+static inline void scsi_destroy_sdev(struct scsi_device *sdev)
+{
+ if (sdev->host->hostt->slave_destroy)
+ sdev->host->hostt->slave_destroy(sdev);
+ transport_destroy_device(&sdev->sdev_gendev);
+ put_device(&sdev->sdev_gendev);
+}
+
+
/**
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
* @starget: pointer to target device structure
@@ -803,9 +813,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
* The rescan flag is used as an optimization, the first scan of a
* host adapter calls into here with rescan == 0.
*/
- if (rescan) {
- sdev = scsi_device_lookup_by_target(starget, lun);
- if (sdev) {
+ sdev = scsi_device_lookup_by_target(starget, lun);
+ if (sdev) {
+ if (rescan || sdev->sdev_state != SDEV_CREATED) {
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
"scsi scan: device exists on %s\n",
sdev->sdev_gendev.bus_id));
@@ -820,9 +830,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
sdev->model);
return SCSI_SCAN_LUN_PRESENT;
}
- }
-
- sdev = scsi_alloc_sdev(starget, lun, hostdata);
+ scsi_device_put(sdev);
+ } else
+ sdev = scsi_alloc_sdev(starget, lun, hostdata);
if (!sdev)
goto out;
@@ -870,15 +880,15 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
out_free_sdev:
if (res == SCSI_SCAN_LUN_PRESENT) {
if (sdevp) {
- scsi_device_get(sdev);
- *sdevp = sdev;
+ if (scsi_device_get(sdev) == 0) {
+ *sdevp = sdev;
+ } else {
+ __scsi_remove_device(sdev);
+ res = SCSI_SCAN_NO_RESPONSE;
+ }
}
- } else {
- if (sdev->host->hostt->slave_destroy)
- sdev->host->hostt->slave_destroy(sdev);
- transport_destroy_device(&sdev->sdev_gendev);
- put_device(&sdev->sdev_gendev);
- }
+ } else
+ scsi_destroy_sdev(sdev);
out:
return res;
}
@@ -1050,7 +1060,7 @@ EXPORT_SYMBOL(int_to_scsilun);
* 0: scan completed (or no memory, so further scanning is futile)
* 1: no report lun scan, or not configured
**/
-static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
+static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
int rescan)
{
char devname[64];
@@ -1063,7 +1073,8 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
struct scsi_lun *lunp, *lun_data;
u8 *data;
struct scsi_sense_hdr sshdr;
- struct scsi_target *starget = scsi_target(sdev);
+ struct scsi_device *sdev;
+ struct Scsi_Host *shost = dev_to_shost(&starget->dev);
/*
* Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
@@ -1071,15 +1082,23 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
* support more than 8 LUNs.
*/
if ((bflags & BLIST_NOREPORTLUN) ||
- sdev->scsi_level < SCSI_2 ||
- (sdev->scsi_level < SCSI_3 &&
- (!(bflags & BLIST_REPORTLUN2) || sdev->host->max_lun <= 8)) )
+ starget->scsi_level < SCSI_2 ||
+ (starget->scsi_level < SCSI_3 &&
+ (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8)) )
return 1;
if (bflags & BLIST_NOLUN)
return 0;
+ if (!(sdev = scsi_device_lookup_by_target(starget, 0))) {
+ sdev = scsi_alloc_sdev(starget, 0, NULL);
+ if (!sdev)
+ return 0;
+ if (scsi_device_get(sdev))
+ return 0;
+ }
+
sprintf(devname, "host %d channel %d id %d",
- sdev->host->host_no, sdev->channel, sdev->id);
+ shost->host_no, sdev->channel, sdev->id);
/*
* Allocate enough to hold the header (the same size as one scsi_lun)
@@ -1094,8 +1113,10 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun);
lun_data = kmalloc(length, GFP_ATOMIC |
(sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
- if (!lun_data)
+ if (!lun_data) {
+ printk(ALLOC_FAILURE_MSG, __FUNCTION__);
goto out;
+ }
scsi_cmd[0] = REPORT_LUNS;
@@ -1197,10 +1218,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
for (i = 0; i < sizeof(struct scsi_lun); i++)
printk("%02x", data[i]);
printk(" has a LUN larger than currently supported.\n");
- } else if (lun == 0) {
- /*
- * LUN 0 has already been scanned.
- */
} else if (lun > sdev->host->max_lun) {
printk(KERN_WARNING "scsi: %s lun%d has a LUN larger"
" than allowed by the host adapter\n",
@@ -1223,13 +1240,13 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
}
kfree(lun_data);
- return 0;
-
out:
- /*
- * We are out of memory, don't try scanning any further.
- */
- printk(ALLOC_FAILURE_MSG, __FUNCTION__);
+ scsi_device_put(sdev);
+ if (sdev->sdev_state == SDEV_CREATED)
+ /*
+ * the sdev we used didn't appear in the report luns scan
+ */
+ scsi_destroy_sdev(sdev);
return 0;
}
@@ -1260,6 +1277,19 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
}
EXPORT_SYMBOL(__scsi_add_device);
+int scsi_add_device(struct Scsi_Host *host, uint channel,
+ uint target, uint lun)
+{
+ struct scsi_device *sdev =
+ __scsi_add_device(host, channel, target, lun, NULL);
+ if (IS_ERR(sdev))
+ return PTR_ERR(sdev);
+
+ scsi_device_put(sdev);
+ return 0;
+}
+EXPORT_SYMBOL(scsi_add_device);
+
void scsi_rescan_device(struct device *dev)
{
struct scsi_driver *drv;
@@ -1276,32 +1306,12 @@ void scsi_rescan_device(struct device *dev)
}
EXPORT_SYMBOL(scsi_rescan_device);
-/**
- * scsi_scan_target - scan a target id, possibly including all LUNs on the
- * target.
- * @sdevsca: Scsi_Device handle for scanning
- * @shost: host to scan
- * @channel: channel to scan
- * @id: target id to scan
- *
- * Description:
- * Scan the target id on @shost, @channel, and @id. Scan at least LUN
- * 0, and possibly all LUNs on the target id.
- *
- * Use the pre-allocated @sdevscan as a handle for the scanning. This
- * function sets sdevscan->host, sdevscan->id and sdevscan->lun; the
- * scanning functions modify sdevscan->lun.
- *
- * First try a REPORT LUN scan, if that does not scan the target, do a
- * sequential scan of LUNs on the target id.
- **/
-void scsi_scan_target(struct device *parent, unsigned int channel,
- unsigned int id, unsigned int lun, int rescan)
+static void __scsi_scan_target(struct device *parent, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
int bflags = 0;
int res;
- struct scsi_device *sdev = NULL;
struct scsi_target *starget;
if (shost->this_id == id)
@@ -1310,9 +1320,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
*/
return;
-
starget = scsi_alloc_target(parent, channel, id);
-
if (!starget)
return;
@@ -1329,27 +1337,16 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
* Scan LUN 0, if there is some response, scan further. Ideally, we
* would not configure LUN 0 until all LUNs are scanned.
*/
- res = scsi_probe_and_add_lun(starget, 0, &bflags, &sdev, rescan, NULL);
- if (res == SCSI_SCAN_LUN_PRESENT) {
- if (scsi_report_lun_scan(sdev, bflags, rescan) != 0)
+ res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
+ if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
+ if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
/*
* The REPORT LUN did not scan the target,
* do a sequential scan.
*/
scsi_sequential_lun_scan(starget, bflags,
- res, sdev->scsi_level, rescan);
- } else if (res == SCSI_SCAN_TARGET_PRESENT) {
- /*
- * There's a target here, but lun 0 is offline so we
- * can't use the report_lun scan. Fall back to a
- * sequential lun scan with a bflags of SPARSELUN and
- * a default scsi level of SCSI_2
- */
- scsi_sequential_lun_scan(starget, BLIST_SPARSELUN,
- SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan);
+ res, starget->scsi_level, rescan);
}
- if (sdev)
- scsi_device_put(sdev);
out_reap:
/* now determine if the target has any children at all
@@ -1358,6 +1355,33 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
put_device(&starget->dev);
}
+
+/**
+ * scsi_scan_target - scan a target id, possibly including all LUNs on the
+ * target.
+ * @parent: host to scan
+ * @channel: channel to scan
+ * @id: target id to scan
+ * @lun: Specific LUN to scan or SCAN_WILD_CARD
+ * @rescan: passed to LUN scanning routines
+ *
+ * Description:
+ * Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
+ * and possibly all LUNs on the target id.
+ *
+ * First try a REPORT LUN scan, if that does not scan the target, do a
+ * sequential scan of LUNs on the target id.
+ **/
+void scsi_scan_target(struct device *parent, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan)
+{
+ struct Scsi_Host *shost = dev_to_shost(parent);
+
+ down(&shost->scan_mutex);
+ if (scsi_host_scan_allowed(shost))
+ __scsi_scan_target(parent, channel, id, lun, rescan);
+ up(&shost->scan_mutex);
+}
EXPORT_SYMBOL(scsi_scan_target);
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
@@ -1383,10 +1407,12 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
order_id = shost->max_id - id - 1;
else
order_id = id;
- scsi_scan_target(&shost->shost_gendev, channel, order_id, lun, rescan);
+ __scsi_scan_target(&shost->shost_gendev, channel,
+ order_id, lun, rescan);
}
else
- scsi_scan_target(&shost->shost_gendev, channel, id, lun, rescan);
+ __scsi_scan_target(&shost->shost_gendev, channel,
+ id, lun, rescan);
}
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
@@ -1441,23 +1467,17 @@ EXPORT_SYMBOL(scsi_scan_single_target);
void scsi_forget_host(struct Scsi_Host *shost)
{
- struct scsi_target *starget, *tmp;
+ struct scsi_device *sdev;
unsigned long flags;
- /*
- * Ok, this look a bit strange. We always look for the first device
- * on the list as scsi_remove_device removes them from it - thus we
- * also have to release the lock.
- * We don't need to get another reference to the device before
- * releasing the lock as we already own the reference from
- * scsi_register_device that's release in scsi_remove_device. And
- * after that we don't look at sdev anymore.
- */
+ restart:
spin_lock_irqsave(shost->host_lock, flags);
- list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) {
+ list_for_each_entry(sdev, &shost->__devices, siblings) {
+ if (sdev->sdev_state == SDEV_DEL)
+ continue;
spin_unlock_irqrestore(shost->host_lock, flags);
- scsi_remove_target(&starget->dev);
- spin_lock_irqsave(shost->host_lock, flags);
+ __scsi_remove_device(sdev);
+ goto restart;
}
spin_unlock_irqrestore(shost->host_lock, flags);
}
@@ -1484,12 +1504,15 @@ void scsi_forget_host(struct Scsi_Host *shost)
*/
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{
- struct scsi_device *sdev;
+ struct scsi_device *sdev = NULL;
struct scsi_target *starget;
+ down(&shost->scan_mutex);
+ if (!scsi_host_scan_allowed(shost))
+ goto out;
starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
if (!starget)
- return NULL;
+ goto out;
sdev = scsi_alloc_sdev(starget, 0, NULL);
if (sdev) {
@@ -1497,6 +1520,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
sdev->borken = 0;
}
put_device(&starget->dev);
+ out:
+ up(&shost->scan_mutex);
return sdev;
}
EXPORT_SYMBOL(scsi_get_host_dev);
@@ -1518,10 +1543,7 @@ void scsi_free_host_dev(struct scsi_device *sdev)
{
BUG_ON(sdev->id != sdev->host->this_id);
- if (sdev->host->hostt->slave_destroy)
- sdev->host->hostt->slave_destroy(sdev);
- transport_destroy_device(&sdev->sdev_gendev);
- put_device(&sdev->sdev_gendev);
+ scsi_destroy_sdev(sdev);
}
EXPORT_SYMBOL(scsi_free_host_dev);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index dae59d1da07a..72a6550a056c 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -57,6 +57,8 @@ static struct {
{ SHOST_CANCEL, "cancel" },
{ SHOST_DEL, "deleted" },
{ SHOST_RECOVERY, "recovery" },
+ { SHOST_CANCEL_RECOVERY, "cancel/recovery" },
+ { SHOST_DEL_RECOVERY, "deleted/recovery", },
};
const char *scsi_host_state_name(enum scsi_host_state state)
{
@@ -653,7 +655,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
error = attr_add(&sdev->sdev_gendev,
sdev->host->hostt->sdev_attrs[i]);
if (error) {
- scsi_remove_device(sdev);
+ __scsi_remove_device(sdev);
goto out;
}
}
@@ -667,7 +669,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
scsi_sysfs_sdev_attrs[i]);
error = device_create_file(&sdev->sdev_gendev, attr);
if (error) {
- scsi_remove_device(sdev);
+ __scsi_remove_device(sdev);
goto out;
}
}
@@ -687,17 +689,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
return error;
}
-/**
- * scsi_remove_device - unregister a device from the scsi bus
- * @sdev: scsi_device to unregister
- **/
-void scsi_remove_device(struct scsi_device *sdev)
+void __scsi_remove_device(struct scsi_device *sdev)
{
- struct Scsi_Host *shost = sdev->host;
-
- down(&shost->scan_mutex);
if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
- goto out;
+ return;
class_device_unregister(&sdev->sdev_classdev);
device_del(&sdev->sdev_gendev);
@@ -706,7 +701,18 @@ void scsi_remove_device(struct scsi_device *sdev)
sdev->host->hostt->slave_destroy(sdev);
transport_unregister_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
-out:
+}
+
+/**
+ * scsi_remove_device - unregister a device from the scsi bus
+ * @sdev: scsi_device to unregister
+ **/
+void scsi_remove_device(struct scsi_device *sdev)
+{
+ struct Scsi_Host *shost = sdev->host;
+
+ down(&shost->scan_mutex);
+ __scsi_remove_device(sdev);
up(&shost->scan_mutex);
}
EXPORT_SYMBOL(scsi_remove_device);
@@ -715,17 +721,20 @@ void __scsi_remove_target(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
- struct scsi_device *sdev, *tmp;
+ struct scsi_device *sdev;
spin_lock_irqsave(shost->host_lock, flags);
starget->reap_ref++;
- list_for_each_entry_safe(sdev, tmp, &shost->__devices, siblings) {
+ restart:
+ list_for_each_entry(sdev, &shost->__devices, siblings) {
if (sdev->channel != starget->channel ||
- sdev->id != starget->id)
+ sdev->id != starget->id ||
+ sdev->sdev_state == SDEV_DEL)
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_remove_device(sdev);
spin_lock_irqsave(shost->host_lock, flags);
+ goto restart;
}
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_target_reap(starget);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 2cab556b6e82..771e97ef136e 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -819,12 +819,15 @@ show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf)
return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name);
}
+#define get_list_head_entry(pos, head, member) \
+ pos = list_entry((head)->next, typeof(*pos), member)
+
static ssize_t
store_fc_private_host_tgtid_bind_type(struct class_device *cdev,
const char *buf, size_t count)
{
struct Scsi_Host *shost = transport_class_to_shost(cdev);
- struct fc_rport *rport, *next_rport;
+ struct fc_rport *rport;
enum fc_tgtid_binding_type val;
unsigned long flags;
@@ -834,9 +837,13 @@ store_fc_private_host_tgtid_bind_type(struct class_device *cdev,
/* if changing bind type, purge all unused consistent bindings */
if (val != fc_host_tgtid_bind_type(shost)) {
spin_lock_irqsave(shost->host_lock, flags);
- list_for_each_entry_safe(rport, next_rport,
- &fc_host_rport_bindings(shost), peers)
+ while (!list_empty(&fc_host_rport_bindings(shost))) {
+ get_list_head_entry(rport,
+ &fc_host_rport_bindings(shost), peers);
+ spin_unlock_irqrestore(shost->host_lock, flags);
fc_rport_terminate(rport);
+ spin_lock_irqsave(shost->host_lock, flags);
+ }
spin_unlock_irqrestore(shost->host_lock, flags);
}
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
new file mode 100644
index 000000000000..1d145d2f9a38
--- /dev/null
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -0,0 +1,819 @@
+/*
+ * Copyright (C) 2005 Dell Inc.
+ * Released under GPL v2.
+ *
+ * Serial Attached SCSI (SAS) transport class.
+ *
+ * The SAS transport class contains common code to deal with SAS HBAs,
+ * an aproximated representation of SAS topologies in the driver model,
+ * and various sysfs attributes to expose these topologies and managment
+ * interfaces to userspace.
+ *
+ * In addition to the basic SCSI core objects this transport class
+ * introduces two additional intermediate objects: The SAS PHY
+ * as represented by struct sas_phy defines an "outgoing" PHY on
+ * a SAS HBA or Expander, and the SAS remote PHY represented by
+ * struct sas_rphy defines an "incoming" PHY on a SAS Expander or
+ * end device. Note that this is purely a software concept, the
+ * underlying hardware for a PHY and a remote PHY is the exactly
+ * the same.
+ *
+ * There is no concept of a SAS port in this code, users can see
+ * what PHYs form a wide port based on the port_identifier attribute,
+ * which is the same for all PHYs in a port.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_sas.h>
+
+
+#define SAS_HOST_ATTRS 0
+#define SAS_PORT_ATTRS 11
+#define SAS_RPORT_ATTRS 5
+
+struct sas_internal {
+ struct scsi_transport_template t;
+ struct sas_function_template *f;
+
+ struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS];
+ struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS];
+ struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS];
+
+ struct transport_container phy_attr_cont;
+ struct transport_container rphy_attr_cont;
+
+ /*
+ * The array of null terminated pointers to attributes
+ * needed by scsi_sysfs.c
+ */
+ struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1];
+ struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1];
+ struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1];
+};
+#define to_sas_internal(tmpl) container_of(tmpl, struct sas_internal, t)
+
+struct sas_host_attrs {
+ struct list_head rphy_list;
+ spinlock_t lock;
+ u32 next_target_id;
+};
+#define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data)
+
+
+/*
+ * Hack to allow attributes of the same name in different objects.
+ */
+#define SAS_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
+ struct class_device_attribute class_device_attr_##_prefix##_##_name = \
+ __ATTR(_name,_mode,_show,_store)
+
+
+/*
+ * Pretty printing helpers
+ */
+
+#define sas_bitfield_name_match(title, table) \
+static ssize_t \
+get_sas_##title##_names(u32 table_key, char *buf) \
+{ \
+ char *prefix = ""; \
+ ssize_t len = 0; \
+ int i; \
+ \
+ for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \
+ if (table[i].value & table_key) { \
+ len += sprintf(buf + len, "%s%s", \
+ prefix, table[i].name); \
+ prefix = ", "; \
+ } \
+ } \
+ len += sprintf(buf + len, "\n"); \
+ return len; \
+}
+
+#define sas_bitfield_name_search(title, table) \
+static ssize_t \
+get_sas_##title##_names(u32 table_key, char *buf) \
+{ \
+ ssize_t len = 0; \
+ int i; \
+ \
+ for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \
+ if (table[i].value == table_key) { \
+ len += sprintf(buf + len, "%s", \
+ table[i].name); \
+ break; \
+ } \
+ } \
+ len += sprintf(buf + len, "\n"); \
+ return len; \
+}
+
+static struct {
+ u32 value;
+ char *name;
+} sas_device_type_names[] = {
+ { SAS_PHY_UNUSED, "unused" },
+ { SAS_END_DEVICE, "end device" },
+ { SAS_EDGE_EXPANDER_DEVICE, "edge expander" },
+ { SAS_FANOUT_EXPANDER_DEVICE, "fanout expander" },
+};
+sas_bitfield_name_search(device_type, sas_device_type_names)
+
+
+static struct {
+ u32 value;
+ char *name;
+} sas_protocol_names[] = {
+ { SAS_PROTOCOL_SATA, "sata" },
+ { SAS_PROTOCOL_SMP, "smp" },
+ { SAS_PROTOCOL_STP, "stp" },
+ { SAS_PROTOCOL_SSP, "ssp" },
+};
+sas_bitfield_name_match(protocol, sas_protocol_names)
+
+static struct {
+ u32 value;
+ char *name;
+} sas_linkspeed_names[] = {
+ { SAS_LINK_RATE_UNKNOWN, "Unknown" },
+ { SAS_PHY_DISABLED, "Phy disabled" },
+ { SAS_LINK_RATE_FAILED, "Link Rate failed" },
+ { SAS_SATA_SPINUP_HOLD, "Spin-up hold" },
+ { SAS_LINK_RATE_1_5_GBPS, "1.5 Gbit" },
+ { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" },
+};
+sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
+
+
+/*
+ * SAS host attributes
+ */
+
+static int sas_host_setup(struct transport_container *tc, struct device *dev,
+ struct class_device *cdev)
+{
+ struct Scsi_Host *shost = dev_to_shost(dev);
+ struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+
+ INIT_LIST_HEAD(&sas_host->rphy_list);
+ spin_lock_init(&sas_host->lock);
+ sas_host->next_target_id = 0;
+ return 0;
+}
+
+static DECLARE_TRANSPORT_CLASS(sas_host_class,
+ "sas_host", sas_host_setup, NULL, NULL);
+
+static int sas_host_match(struct attribute_container *cont,
+ struct device *dev)
+{
+ struct Scsi_Host *shost;
+ struct sas_internal *i;
+
+ if (!scsi_is_host_device(dev))
+ return 0;
+ shost = dev_to_shost(dev);
+
+ if (!shost->transportt)
+ return 0;
+ if (shost->transportt->host_attrs.ac.class !=
+ &sas_host_class.class)
+ return 0;
+
+ i = to_sas_internal(shost->transportt);
+ return &i->t.host_attrs.ac == cont;
+}
+
+static int do_sas_phy_delete(struct device *dev, void *data)
+{
+ if (scsi_is_sas_phy(dev))
+ sas_phy_delete(dev_to_phy(dev));
+ return 0;
+}
+
+/**
+ * sas_remove_host -- tear down a Scsi_Host's SAS data structures
+ * @shost: Scsi Host that is torn down
+ *
+ * Removes all SAS PHYs and remote PHYs for a given Scsi_Host.
+ * Must be called just before scsi_remove_host for SAS HBAs.
+ */
+void sas_remove_host(struct Scsi_Host *shost)
+{
+ device_for_each_child(&shost->shost_gendev, NULL, do_sas_phy_delete);
+}
+EXPORT_SYMBOL(sas_remove_host);
+
+
+/*
+ * SAS Port attributes
+ */
+
+#define sas_phy_show_simple(field, name, format_string, cast) \
+static ssize_t \
+show_sas_phy_##name(struct class_device *cdev, char *buf) \
+{ \
+ struct sas_phy *phy = transport_class_to_phy(cdev); \
+ \
+ return snprintf(buf, 20, format_string, cast phy->field); \
+}
+
+#define sas_phy_simple_attr(field, name, format_string, type) \
+ sas_phy_show_simple(field, name, format_string, (type)) \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)
+
+#define sas_phy_show_protocol(field, name) \
+static ssize_t \
+show_sas_phy_##name(struct class_device *cdev, char *buf) \
+{ \
+ struct sas_phy *phy = transport_class_to_phy(cdev); \
+ \
+ if (!phy->field) \
+ return snprintf(buf, 20, "none\n"); \
+ return get_sas_protocol_names(phy->field, buf); \
+}
+
+#define sas_phy_protocol_attr(field, name) \
+ sas_phy_show_protocol(field, name) \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)
+
+#define sas_phy_show_linkspeed(field) \
+static ssize_t \
+show_sas_phy_##field(struct class_device *cdev, char *buf) \
+{ \
+ struct sas_phy *phy = transport_class_to_phy(cdev); \
+ \
+ return get_sas_linkspeed_names(phy->field, buf); \
+}
+
+#define sas_phy_linkspeed_attr(field) \
+ sas_phy_show_linkspeed(field) \
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
+
+static ssize_t
+show_sas_device_type(struct class_device *cdev, char *buf)
+{
+ struct sas_phy *phy = transport_class_to_phy(cdev);
+
+ if (!phy->identify.device_type)
+ return snprintf(buf, 20, "none\n");
+ return get_sas_device_type_names(phy->identify.device_type, buf);
+}
+
+static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
+
+sas_phy_protocol_attr(identify.initiator_port_protocols,
+ initiator_port_protocols);
+sas_phy_protocol_attr(identify.target_port_protocols,
+ target_port_protocols);
+sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
+ unsigned long long);
+sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
+sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8);
+sas_phy_linkspeed_attr(negotiated_linkrate);
+sas_phy_linkspeed_attr(minimum_linkrate_hw);
+sas_phy_linkspeed_attr(minimum_linkrate);
+sas_phy_linkspeed_attr(maximum_linkrate_hw);
+sas_phy_linkspeed_attr(maximum_linkrate);
+
+
+static DECLARE_TRANSPORT_CLASS(sas_phy_class,
+ "sas_phy", NULL, NULL, NULL);
+
+static int sas_phy_match(struct attribute_container *cont, struct device *dev)
+{
+ struct Scsi_Host *shost;
+ struct sas_internal *i;
+
+ if (!scsi_is_sas_phy(dev))
+ return 0;
+ shost = dev_to_shost(dev->parent);
+
+ if (!shost->transportt)
+ return 0;
+ if (shost->transportt->host_attrs.ac.class !=
+ &sas_host_class.class)
+ return 0;
+
+ i = to_sas_internal(shost->transportt);
+ return &i->phy_attr_cont.ac == cont;
+}
+
+static void sas_phy_release(struct device *dev)
+{
+ struct sas_phy *phy = dev_to_phy(dev);
+
+ put_device(dev->parent);
+ kfree(phy);
+}
+
+/**
+ * sas_phy_alloc -- allocates and initialize a SAS PHY structure
+ * @parent: Parent device
+ * @number: Port number
+ *
+ * Allocates an SAS PHY structure. It will be added in the device tree
+ * below the device specified by @parent, which has to be either a Scsi_Host
+ * or sas_rphy.
+ *
+ * Returns:
+ * SAS PHY allocated or %NULL if the allocation failed.
+ */
+struct sas_phy *sas_phy_alloc(struct device *parent, int number)
+{
+ struct Scsi_Host *shost = dev_to_shost(parent);
+ struct sas_phy *phy;
+
+ phy = kmalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return NULL;
+ memset(phy, 0, sizeof(*phy));
+
+ get_device(parent);
+
+ phy->number = number;
+
+ device_initialize(&phy->dev);
+ phy->dev.parent = get_device(parent);
+ phy->dev.release = sas_phy_release;
+ sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number);
+
+ transport_setup_device(&phy->dev);
+
+ return phy;
+}
+EXPORT_SYMBOL(sas_phy_alloc);
+
+/**
+ * sas_phy_add -- add a SAS PHY to the device hierachy
+ * @phy: The PHY to be added
+ *
+ * Publishes a SAS PHY to the rest of the system.
+ */
+int sas_phy_add(struct sas_phy *phy)
+{
+ int error;
+
+ error = device_add(&phy->dev);
+ if (!error) {
+ transport_add_device(&phy->dev);
+ transport_configure_device(&phy->dev);
+ }
+
+ return error;
+}
+EXPORT_SYMBOL(sas_phy_add);
+
+/**
+ * sas_phy_free -- free a SAS PHY
+ * @phy: SAS PHY to free
+ *
+ * Frees the specified SAS PHY.
+ *
+ * Note:
+ * This function must only be called on a PHY that has not
+ * sucessfully been added using sas_phy_add().
+ */
+void sas_phy_free(struct sas_phy *phy)
+{
+ transport_destroy_device(&phy->dev);
+ put_device(phy->dev.parent);
+ put_device(phy->dev.parent);
+ put_device(phy->dev.parent);
+ kfree(phy);
+}
+EXPORT_SYMBOL(sas_phy_free);
+
+/**
+ * sas_phy_delete -- remove SAS PHY
+ * @phy: SAS PHY to remove
+ *
+ * Removes the specified SAS PHY. If the SAS PHY has an
+ * associated remote PHY it is removed before.
+ */
+void
+sas_phy_delete(struct sas_phy *phy)
+{
+ struct device *dev = &phy->dev;
+
+ if (phy->rphy)
+ sas_rphy_delete(phy->rphy);
+
+ transport_remove_device(dev);
+ device_del(dev);
+ transport_destroy_device(dev);
+ put_device(dev->parent);
+}
+EXPORT_SYMBOL(sas_phy_delete);
+
+/**
+ * scsi_is_sas_phy -- check if a struct device represents a SAS PHY
+ * @dev: device to check
+ *
+ * Returns:
+ * %1 if the device represents a SAS PHY, %0 else
+ */
+int scsi_is_sas_phy(const struct device *dev)
+{
+ return dev->release == sas_phy_release;
+}
+EXPORT_SYMBOL(scsi_is_sas_phy);
+
+/*
+ * SAS remote PHY attributes.
+ */
+
+#define sas_rphy_show_simple(field, name, format_string, cast) \
+static ssize_t \
+show_sas_rphy_##name(struct class_device *cdev, char *buf) \
+{ \
+ struct sas_rphy *rphy = transport_class_to_rphy(cdev); \
+ \
+ return snprintf(buf, 20, format_string, cast rphy->field); \
+}
+
+#define sas_rphy_simple_attr(field, name, format_string, type) \
+ sas_rphy_show_simple(field, name, format_string, (type)) \
+static SAS_CLASS_DEVICE_ATTR(rphy, name, S_IRUGO, \
+ show_sas_rphy_##name, NULL)
+
+#define sas_rphy_show_protocol(field, name) \
+static ssize_t \
+show_sas_rphy_##name(struct class_device *cdev, char *buf) \
+{ \
+ struct sas_rphy *rphy = transport_class_to_rphy(cdev); \
+ \
+ if (!rphy->field) \
+ return snprintf(buf, 20, "none\n"); \
+ return get_sas_protocol_names(rphy->field, buf); \
+}
+
+#define sas_rphy_protocol_attr(field, name) \
+ sas_rphy_show_protocol(field, name) \
+static SAS_CLASS_DEVICE_ATTR(rphy, name, S_IRUGO, \
+ show_sas_rphy_##name, NULL)
+
+static ssize_t
+show_sas_rphy_device_type(struct class_device *cdev, char *buf)
+{
+ struct sas_rphy *rphy = transport_class_to_rphy(cdev);
+
+ if (!rphy->identify.device_type)
+ return snprintf(buf, 20, "none\n");
+ return get_sas_device_type_names(
+ rphy->identify.device_type, buf);
+}
+
+static SAS_CLASS_DEVICE_ATTR(rphy, device_type, S_IRUGO,
+ show_sas_rphy_device_type, NULL);
+
+sas_rphy_protocol_attr(identify.initiator_port_protocols,
+ initiator_port_protocols);
+sas_rphy_protocol_attr(identify.target_port_protocols, target_port_protocols);
+sas_rphy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
+ unsigned long long);
+sas_rphy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
+
+static DECLARE_TRANSPORT_CLASS(sas_rphy_class,
+ "sas_rphy", NULL, NULL, NULL);
+
+static int sas_rphy_match(struct attribute_container *cont, struct device *dev)
+{
+ struct Scsi_Host *shost;
+ struct sas_internal *i;
+
+ if (!scsi_is_sas_rphy(dev))
+ return 0;
+ shost = dev_to_shost(dev->parent->parent);
+
+ if (!shost->transportt)
+ return 0;
+ if (shost->transportt->host_attrs.ac.class !=
+ &sas_host_class.class)
+ return 0;
+
+ i = to_sas_internal(shost->transportt);
+ return &i->rphy_attr_cont.ac == cont;
+}
+
+static void sas_rphy_release(struct device *dev)
+{
+ struct sas_rphy *rphy = dev_to_rphy(dev);
+
+ put_device(dev->parent);
+ kfree(rphy);
+}
+
+/**
+ * sas_rphy_alloc -- allocates and initialize a SAS remote PHY structure
+ * @parent: SAS PHY this remote PHY is conneted to
+ *
+ * Allocates an SAS remote PHY structure, connected to @parent.
+ *
+ * Returns:
+ * SAS PHY allocated or %NULL if the allocation failed.
+ */
+struct sas_rphy *sas_rphy_alloc(struct sas_phy *parent)
+{
+ struct Scsi_Host *shost = dev_to_shost(&parent->dev);
+ struct sas_rphy *rphy;
+
+ rphy = kmalloc(sizeof(*rphy), GFP_KERNEL);
+ if (!rphy) {
+ put_device(&parent->dev);
+ return NULL;
+ }
+ memset(rphy, 0, sizeof(*rphy));
+
+ device_initialize(&rphy->dev);
+ rphy->dev.parent = get_device(&parent->dev);
+ rphy->dev.release = sas_rphy_release;
+ sprintf(rphy->dev.bus_id, "rphy-%d:%d",
+ shost->host_no, parent->number);
+ transport_setup_device(&rphy->dev);
+
+ return rphy;
+}
+EXPORT_SYMBOL(sas_rphy_alloc);
+
+/**
+ * sas_rphy_add -- add a SAS remote PHY to the device hierachy
+ * @rphy: The remote PHY to be added
+ *
+ * Publishes a SAS remote PHY to the rest of the system.
+ */
+int sas_rphy_add(struct sas_rphy *rphy)
+{
+ struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
+ struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
+ struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+ struct sas_identify *identify = &rphy->identify;
+ int error;
+
+ if (parent->rphy)
+ return -ENXIO;
+ parent->rphy = rphy;
+
+ error = device_add(&rphy->dev);
+ if (error)
+ return error;
+ transport_add_device(&rphy->dev);
+ transport_configure_device(&rphy->dev);
+
+ spin_lock(&sas_host->lock);
+ list_add_tail(&rphy->list, &sas_host->rphy_list);
+ if (identify->device_type == SAS_END_DEVICE &&
+ (identify->target_port_protocols &
+ (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA)))
+ rphy->scsi_target_id = sas_host->next_target_id++;
+ else
+ rphy->scsi_target_id = -1;
+ spin_unlock(&sas_host->lock);
+
+ if (rphy->scsi_target_id != -1) {
+ scsi_scan_target(&rphy->dev, parent->number,
+ rphy->scsi_target_id, ~0, 0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(sas_rphy_add);
+
+/**
+ * sas_rphy_free -- free a SAS remote PHY
+ * @rphy SAS remote PHY to free
+ *
+ * Frees the specified SAS remote PHY.
+ *
+ * Note:
+ * This function must only be called on a remote
+ * PHY that has not sucessfully been added using
+ * sas_rphy_add().
+ */
+void sas_rphy_free(struct sas_rphy *rphy)
+{
+ struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
+ struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+
+ spin_lock(&sas_host->lock);
+ list_del(&rphy->list);
+ spin_unlock(&sas_host->lock);
+
+ transport_destroy_device(&rphy->dev);
+ put_device(rphy->dev.parent);
+ put_device(rphy->dev.parent);
+ put_device(rphy->dev.parent);
+ kfree(rphy);
+}
+EXPORT_SYMBOL(sas_rphy_free);
+
+/**
+ * sas_rphy_delete -- remove SAS remote PHY
+ * @rphy: SAS remote PHY to remove
+ *
+ * Removes the specified SAS remote PHY.
+ */
+void
+sas_rphy_delete(struct sas_rphy *rphy)
+{
+ struct device *dev = &rphy->dev;
+ struct sas_phy *parent = dev_to_phy(dev->parent);
+ struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
+ struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+
+ scsi_remove_target(dev);
+
+ transport_remove_device(dev);
+ device_del(dev);
+ transport_destroy_device(dev);
+
+ spin_lock(&sas_host->lock);
+ list_del(&rphy->list);
+ spin_unlock(&sas_host->lock);
+
+ put_device(&parent->dev);
+}
+EXPORT_SYMBOL(sas_rphy_delete);
+
+/**
+ * scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY
+ * @dev: device to check
+ *
+ * Returns:
+ * %1 if the device represents a SAS remote PHY, %0 else
+ */
+int scsi_is_sas_rphy(const struct device *dev)
+{
+ return dev->release == sas_rphy_release;
+}
+EXPORT_SYMBOL(scsi_is_sas_rphy);
+
+
+/*
+ * SCSI scan helper
+ */
+
+static struct device *sas_target_parent(struct Scsi_Host *shost,
+ int channel, uint id)
+{
+ struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+ struct sas_rphy *rphy;
+ struct device *dev = NULL;
+
+ spin_lock(&sas_host->lock);
+ list_for_each_entry(rphy, &sas_host->rphy_list, list) {
+ struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
+ if (parent->number == channel &&
+ rphy->scsi_target_id == id)
+ dev = &rphy->dev;
+ }
+ spin_unlock(&sas_host->lock);
+
+ return dev;
+}
+
+
+/*
+ * Setup / Teardown code
+ */
+
+#define SETUP_RPORT_ATTRIBUTE(field) \
+ i->private_rphy_attrs[count] = class_device_attr_##field; \
+ i->private_rphy_attrs[count].attr.mode = S_IRUGO; \
+ i->private_rphy_attrs[count].store = NULL; \
+ i->rphy_attrs[count] = &i->private_rphy_attrs[count]; \
+ count++
+
+#define SETUP_PORT_ATTRIBUTE(field) \
+ i->private_phy_attrs[count] = class_device_attr_##field; \
+ i->private_phy_attrs[count].attr.mode = S_IRUGO; \
+ i->private_phy_attrs[count].store = NULL; \
+ i->phy_attrs[count] = &i->private_phy_attrs[count]; \
+ count++
+
+
+/**
+ * sas_attach_transport -- instantiate SAS transport template
+ * @ft: SAS transport class function template
+ */
+struct scsi_transport_template *
+sas_attach_transport(struct sas_function_template *ft)
+{
+ struct sas_internal *i;
+ int count;
+
+ i = kmalloc(sizeof(struct sas_internal), GFP_KERNEL);
+ if (!i)
+ return NULL;
+ memset(i, 0, sizeof(struct sas_internal));
+
+ i->t.target_parent = sas_target_parent;
+
+ i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+ i->t.host_attrs.ac.class = &sas_host_class.class;
+ i->t.host_attrs.ac.match = sas_host_match;
+ transport_container_register(&i->t.host_attrs);
+ i->t.host_size = sizeof(struct sas_host_attrs);
+
+ i->phy_attr_cont.ac.class = &sas_phy_class.class;
+ i->phy_attr_cont.ac.attrs = &i->phy_attrs[0];
+ i->phy_attr_cont.ac.match = sas_phy_match;
+ transport_container_register(&i->phy_attr_cont);
+
+ i->rphy_attr_cont.ac.class = &sas_rphy_class.class;
+ i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0];
+ i->rphy_attr_cont.ac.match = sas_rphy_match;
+ transport_container_register(&i->rphy_attr_cont);
+
+ i->f = ft;
+
+ count = 0;
+ i->host_attrs[count] = NULL;
+
+ count = 0;
+ SETUP_PORT_ATTRIBUTE(initiator_port_protocols);
+ SETUP_PORT_ATTRIBUTE(target_port_protocols);
+ SETUP_PORT_ATTRIBUTE(device_type);
+ SETUP_PORT_ATTRIBUTE(sas_address);
+ SETUP_PORT_ATTRIBUTE(phy_identifier);
+ SETUP_PORT_ATTRIBUTE(port_identifier);
+ SETUP_PORT_ATTRIBUTE(negotiated_linkrate);
+ SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw);
+ SETUP_PORT_ATTRIBUTE(minimum_linkrate);
+ SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw);
+ SETUP_PORT_ATTRIBUTE(maximum_linkrate);
+ i->phy_attrs[count] = NULL;
+
+ count = 0;
+ SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols);
+ SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols);
+ SETUP_RPORT_ATTRIBUTE(rphy_device_type);
+ SETUP_RPORT_ATTRIBUTE(rphy_sas_address);
+ SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier);
+ i->rphy_attrs[count] = NULL;
+
+ return &i->t;
+}
+EXPORT_SYMBOL(sas_attach_transport);
+
+/**
+ * sas_release_transport -- release SAS transport template instance
+ * @t: transport template instance
+ */
+void sas_release_transport(struct scsi_transport_template *t)
+{
+ struct sas_internal *i = to_sas_internal(t);
+
+ transport_container_unregister(&i->t.host_attrs);
+ transport_container_unregister(&i->phy_attr_cont);
+ transport_container_unregister(&i->rphy_attr_cont);
+
+ kfree(i);
+}
+EXPORT_SYMBOL(sas_release_transport);
+
+static __init int sas_transport_init(void)
+{
+ int error;
+
+ error = transport_class_register(&sas_host_class);
+ if (error)
+ goto out;
+ error = transport_class_register(&sas_phy_class);
+ if (error)
+ goto out_unregister_transport;
+ error = transport_class_register(&sas_rphy_class);
+ if (error)
+ goto out_unregister_phy;
+
+ return 0;
+
+ out_unregister_phy:
+ transport_class_unregister(&sas_phy_class);
+ out_unregister_transport:
+ transport_class_unregister(&sas_host_class);
+ out:
+ return error;
+
+}
+
+static void __exit sas_transport_exit(void)
+{
+ transport_class_unregister(&sas_host_class);
+ transport_class_unregister(&sas_phy_class);
+ transport_class_unregister(&sas_rphy_class);
+}
+
+MODULE_AUTHOR("Christoph Hellwig");
+MODULE_DESCRIPTION("SAS Transphy Attributes");
+MODULE_LICENSE("GPL");
+
+module_init(sas_transport_init);
+module_exit(sas_transport_exit);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index de564b386052..9a1dc0cea03c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -235,6 +235,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
+ SCpnt->cmd_len = rq->cmd_len;
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = DMA_TO_DEVICE;
else if (rq->data_len)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index b1b69d738d08..fd56b7ec88b6 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -61,7 +61,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
-static char *sg_version_date = "20050901";
+static char *sg_version_date = "20050908";
static int sg_proc_init(void);
static void sg_proc_cleanup(void);
@@ -1027,7 +1027,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (sdp->detached)
return -ENODEV;
if (filp->f_flags & O_NONBLOCK) {
- if (sdp->device->host->shost_state == SHOST_RECOVERY)
+ if (scsi_host_in_recovery(sdp->device->host))
return -EBUSY;
} else if (!scsi_block_when_processing_errors(sdp->device))
return -EBUSY;
@@ -1299,7 +1299,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */
sfp->mmap_called = 1;
}
- vma->vm_flags |= (VM_RESERVED | VM_IO);
+ vma->vm_flags |= VM_RESERVED;
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
return 0;
@@ -2644,7 +2644,7 @@ static char *
sg_page_malloc(int rqSz, int lowDma, int *retSzp)
{
char *resp = NULL;
- int page_mask;
+ gfp_t page_mask;
int order, a_size;
int resSz = rqSz;
@@ -2849,8 +2849,7 @@ sg_proc_init(void)
struct proc_dir_entry *pdep;
struct sg_proc_leaf * leaf;
- sg_proc_sgp = create_proc_entry(sg_proc_sg_dirname,
- S_IFDIR | S_IRUGO | S_IXUGO, NULL);
+ sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
if (!sg_proc_sgp)
return 1;
for (k = 0; k < num_leaves; ++k) {
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index ce63fc8312dc..561901b1cf11 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -326,6 +326,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
+ SCpnt->cmd_len = rq->cmd_len;
if (!rq->data_len)
SCpnt->sc_data_direction = DMA_NONE;
else if (rq_data_dir(rq) == WRITE)
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index a93308ae9736..927d700f0073 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3577,7 +3577,8 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
static struct st_buffer *
new_tape_buffer(int from_initialization, int need_dma, int max_sg)
{
- int i, priority, got = 0, segs = 0;
+ int i, got = 0, segs = 0;
+ gfp_t priority;
struct st_buffer *tb;
if (from_initialization)
@@ -3610,7 +3611,8 @@ static struct st_buffer *
/* Try to allocate enough space in the tape buffer */
static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
{
- int segs, nbr, max_segs, b_size, priority, order, got;
+ int segs, nbr, max_segs, b_size, order, got;
+ gfp_t priority;
if (new_size <= STbuffer->buffer_size)
return 1;
@@ -4206,6 +4208,7 @@ static int st_init_command(struct scsi_cmnd *SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
+ SCpnt->cmd_len = rq->cmd_len;
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = DMA_TO_DEVICE;
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index aec39fb261ca..b5cf39468d18 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -463,7 +463,7 @@ static int __init serial21285_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-extern struct uart_driver serial21285_reg;
+static struct uart_driver serial21285_reg;
static struct console serial21285_console =
{
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 30a0a3d10145..4d75cdfa0a0a 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -864,7 +864,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
/*
* We're pretty sure there's a port here. Lets find out what
* type of port it is. The IIR top two bits allows us to find
- * out if its 8250 or 16450, 16550, 16550A or later. This
+ * out if it's 8250 or 16450, 16550, 16550A or later. This
* determines what we test for next.
*
* We also initialise the EFR (if any) to zero for later. The
@@ -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 1f2c276063ef..9c10262f2469 100644
--- a/drivers/serial/8250_accent.c
+++ b/drivers/serial/8250_accent.c
@@ -29,7 +29,7 @@ static struct plat_serial8250_port accent_data[] = {
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_acpi.c b/drivers/serial/8250_acpi.c
index 6b9ead288517..a802bdce6e5d 100644
--- a/drivers/serial/8250_acpi.c
+++ b/drivers/serial/8250_acpi.c
@@ -47,18 +47,30 @@ static acpi_status acpi_serial_port(struct uart_port *port,
static acpi_status acpi_serial_ext_irq(struct uart_port *port,
struct acpi_resource_ext_irq *ext_irq)
{
- if (ext_irq->number_of_interrupts > 0)
- port->irq = acpi_register_gsi(ext_irq->interrupts[0],
+ int rc;
+
+ if (ext_irq->number_of_interrupts > 0) {
+ rc = acpi_register_gsi(ext_irq->interrupts[0],
ext_irq->edge_level, ext_irq->active_high_low);
+ if (rc < 0)
+ return AE_ERROR;
+ port->irq = rc;
+ }
return AE_OK;
}
static acpi_status acpi_serial_irq(struct uart_port *port,
struct acpi_resource_irq *irq)
{
- if (irq->number_of_interrupts > 0)
- port->irq = acpi_register_gsi(irq->interrupts[0],
+ int rc;
+
+ if (irq->number_of_interrupts > 0) {
+ rc = acpi_register_gsi(irq->interrupts[0],
irq->edge_level, irq->active_high_low);
+ if (rc < 0)
+ return AE_ERROR;
+ port->irq = rc;
+ }
return AE_OK;
}
diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c
index 465c9ea1e7a3..3bfe0f7b26fb 100644
--- a/drivers/serial/8250_boca.c
+++ b/drivers/serial/8250_boca.c
@@ -43,7 +43,7 @@ static struct plat_serial8250_port boca_data[] = {
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 e9b4d908ef42..6375d68b7913 100644
--- a/drivers/serial/8250_fourport.c
+++ b/drivers/serial/8250_fourport.c
@@ -35,7 +35,7 @@ static struct plat_serial8250_port fourport_data[] = {
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 77f396f84b4c..daf569cd3c8f 100644
--- a/drivers/serial/8250_hub6.c
+++ b/drivers/serial/8250_hub6.c
@@ -40,7 +40,7 @@ static struct plat_serial8250_port hub6_data[] = {
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 f0c40d68b8c1..ac205256d5f3 100644
--- a/drivers/serial/8250_mca.c
+++ b/drivers/serial/8250_mca.c
@@ -44,7 +44,7 @@ static struct plat_serial8250_port mca_data[] = {
static struct platform_device mca_device = {
.name = "serial8250",
- .id = 5,
+ .id = PLAT8250_DEV_MCA,
.dev = {
.platform_data = mca_data,
},
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 0e21f583690e..5c3c03932d6d 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -152,6 +152,7 @@ static int __devinit pci_hp_diva_init(struct pci_dev *dev)
rc = 4;
break;
case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
+ case PCI_DEVICE_ID_HP_DIVA_HURRICANE:
rc = 1;
break;
}
@@ -226,8 +227,10 @@ static int __devinit pci_plx9050_init(struct pci_dev *dev)
}
irq_config = 0x41;
- if (dev->vendor == PCI_VENDOR_ID_PANACOM)
+ if (dev->vendor == PCI_VENDOR_ID_PANACOM ||
+ dev->subsystem_vendor == PCI_SUBVENDOR_ID_EXSYS) {
irq_config = 0x43;
+ }
if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
(dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
/*
@@ -664,6 +667,15 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9050,
+ .subvendor = PCI_SUBVENDOR_ID_EXSYS,
+ .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_plx9050_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9050,
.subvendor = PCI_SUBVENDOR_ID_KEYSPAN,
.subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
.init = pci_plx9050_init,
@@ -927,6 +939,7 @@ enum pci_board_num_t {
pbn_panacom,
pbn_panacom2,
pbn_panacom4,
+ pbn_exsys_4055,
pbn_plx_romulus,
pbn_oxsemi,
pbn_intel_i960,
@@ -1292,6 +1305,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.reg_shift = 7,
},
+ [pbn_exsys_4055] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
/* I think this entry is broken - the first_offset looks wrong --rmk */
[pbn_plx_romulus] = {
.flags = FL_BASE2,
@@ -1853,6 +1873,10 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_SUBVENDOR_ID_CHASE_PCIRAS,
PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
pbn_b2_8_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_EXSYS,
+ PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
+ pbn_exsys_4055 },
/*
* Megawolf Romulus PCI Serial Card, from Mike Hudson
* (Exoray@isys.ca)
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 6b321e82cafb..5d8660a42b77 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -272,8 +272,12 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "SUP1421", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1590", 0 },
+ /* SupraExpress 336i Sp ASVD */
+ { "SUP1620", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1760", 0 },
+ /* SupraExpress 56i Sp Intl */
+ { "SUP2171", 0 },
/* Phoebe Micro */
/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
{ "TEX0011", 0 },
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e39818a34a07..b745a1b9e835 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_8250_CS
config SERIAL_8250_ACPI
bool "8250/16550 device discovery via ACPI namespace"
default y if IA64
- depends on ACPI_BUS && SERIAL_8250
+ depends on ACPI && SERIAL_8250
---help---
If you wish to enable serial port discovery via the ACPI
namespace, say Y here. If unsure, say N.
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 978e12437e61..ddd0307fece2 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -50,6 +50,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/hardware.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_serial.h>
@@ -689,7 +690,7 @@ static int __init pl010_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-extern struct uart_driver amba_reg;
+static struct uart_driver amba_reg;
static struct console amba_console = {
.name = "ttyAM",
.write = pl010_console_write,
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 56071309744c..938d185841c9 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -50,6 +50,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
#include <asm/hardware/amba_serial.h>
@@ -701,7 +702,7 @@ static int __init pl011_console_setup(struct console *co, char *options)
return uart_set_options(&uap->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver amba_reg;
+static struct uart_driver amba_reg;
static struct console amba_console = {
.name = "ttyAMA",
.write = pl011_console_write,
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index d822896b488c..6a67e8f585b3 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -98,7 +98,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
{
struct uart_port *port = dev_id;
struct tty_struct *tty = port->info->tty;
- unsigned int status, ch, flg, ignored = 0;
+ unsigned int status, ch, flg;
status = clps_readl(SYSFLG(port));
while (!(status & SYSFLG_URXFE)) {
@@ -408,7 +408,11 @@ static struct uart_port clps711x_ports[UART_NR] = {
{
.iobase = SYSCON1,
.irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
+#ifdef CONFIG_MP1000_90MHZ
+ .uartclk = 4515840,
+#else
.uartclk = 3686400,
+#endif
.fifosize = 16,
.ops = &clps711x_pops,
.line = 0,
@@ -417,7 +421,11 @@ static struct uart_port clps711x_ports[UART_NR] = {
{
.iobase = SYSCON2,
.irq = IRQ_UTXINT2, /* IRQ_URXINT2 */
+#ifdef CONFIG_MP1000_90MHZ
+ .uartclk = 4515840,
+#else
.uartclk = 3686400,
+#endif
.fifosize = 16,
.ops = &clps711x_pops,
.line = 1,
@@ -525,7 +533,7 @@ static int __init clps711xuart_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-extern struct uart_driver clps711x_reg;
+static struct uart_driver clps711x_reg;
static struct console clps711x_console = {
.name = "ttyCL",
.write = clps711xuart_console_write,
@@ -551,6 +559,7 @@ console_initcall(clps711xuart_console_init);
static struct uart_driver clps711x_reg = {
.driver_name = "ttyCL",
.dev_name = "ttyCL",
+ .devfs_name = "ttyCL",
.major = SERIAL_CLPS711X_MAJOR,
.minor = SERIAL_CLPS711X_MINOR,
.nr = UART_NR,
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 4c985e6b3784..bdb4e454b8b0 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -73,7 +73,7 @@ struct imx_port {
struct uart_port port;
struct timer_list timer;
unsigned int old_status;
- int txirq,rxirq;
+ int txirq,rxirq,rtsirq;
};
/*
@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)
imx_transmit_buffer(sport);
}
+static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct imx_port *sport = (struct imx_port *)dev_id;
+ unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ USR1((u32)sport->port.membase) = USR1_RTSD;
+ uart_handle_cts_change(&sport->port, !!val);
+ wake_up_interruptible(&sport->port.info->delta_msr_wait);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ return IRQ_HANDLED;
+}
+
static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
{
struct imx_port *sport = (struct imx_port *)dev_id;
@@ -383,18 +399,24 @@ static int imx_startup(struct uart_port *port)
*/
retval = request_irq(sport->rxirq, imx_rxint, 0,
DRIVER_NAME, sport);
- if (retval) goto error_out2;
+ if (retval) goto error_out1;
retval = request_irq(sport->txirq, imx_txint, 0,
- "imx-uart", sport);
- if (retval) goto error_out1;
+ DRIVER_NAME, sport);
+ if (retval) goto error_out2;
+
+ retval = request_irq(sport->rtsirq, imx_rtsint, 0,
+ DRIVER_NAME, sport);
+ if (retval) goto error_out3;
+ set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
/*
* Finally, clear and enable interrupts
*/
+ USR1((u32)sport->port.membase) = USR1_RTSD;
UCR1((u32)sport->port.membase) |=
- (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+ (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
/*
@@ -406,10 +428,11 @@ static int imx_startup(struct uart_port *port)
return 0;
-error_out1:
- free_irq(sport->rxirq, sport);
-error_out2:
+error_out3:
free_irq(sport->txirq, sport);
+error_out2:
+ free_irq(sport->rxirq, sport);
+error_out1:
return retval;
}
@@ -425,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
/*
* Free the interrupts
*/
+ free_irq(sport->rtsirq, sport);
free_irq(sport->txirq, sport);
free_irq(sport->rxirq, sport);
@@ -433,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
*/
UCR1((u32)sport->port.membase) &=
- ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+ ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
}
static void
@@ -523,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
* disable interrupts and drain transmitter
*/
old_ucr1 = UCR1((u32)sport->port.membase);
- UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+ UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
barrier();
@@ -644,6 +668,7 @@ static struct imx_port imx_ports[] = {
{
.txirq = UART1_MINT_TX,
.rxirq = UART1_MINT_RX,
+ .rtsirq = UART1_MINT_RTS,
.port = {
.type = PORT_IMX,
.iotype = SERIAL_IO_MEM,
@@ -659,6 +684,7 @@ static struct imx_port imx_ports[] = {
}, {
.txirq = UART2_MINT_TX,
.rxirq = UART2_MINT_RX,
+ .rtsirq = UART2_MINT_RTS,
.port = {
.type = PORT_IMX,
.iotype = SERIAL_IO_MEM,
@@ -738,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
UCR1((u32)sport->port.membase) =
(old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
- & ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+ & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
/*
@@ -860,7 +886,7 @@ imx_console_setup(struct console *co, char *options)
return uart_set_options(&sport->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver imx_reg;
+static struct uart_driver imx_reg;
static struct console imx_console = {
.name = "ttySMX",
.write = imx_console_write,
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 0c5c96a582b3..f88fdd480685 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -973,18 +973,6 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs)
this_ir &= ~this_mir;
}
}
- if (this_ir) {
- printk(KERN_ERR
- "unknown IOC4 %s interrupt 0x%x, sio_ir = 0x%x,"
- " sio_ies = 0x%x, other_ir = 0x%x :"
- "other_ies = 0x%x\n",
- (intr_type == IOC4_SIO_INTR_TYPE) ? "sio" :
- "other", this_ir,
- readl(&soft->is_ioc4_misc_addr->sio_ir.raw),
- readl(&soft->is_ioc4_misc_addr->sio_ies.raw),
- readl(&soft->is_ioc4_misc_addr->other_ir.raw),
- readl(&soft->is_ioc4_misc_addr->other_ies.raw));
- }
}
#ifdef DEBUG_INTERRUPTS
{
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 43b03c55f453..e2ebdcad553c 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -63,8 +63,13 @@ struct timer_list mcfrs_timer_struct;
#endif
#if defined(CONFIG_HW_FEITH)
- #define CONSOLE_BAUD_RATE 38400
- #define DEFAULT_CBAUD B38400
+#define CONSOLE_BAUD_RATE 38400
+#define DEFAULT_CBAUD B38400
+#endif
+
+#if defined(CONFIG_MOD5272)
+#define CONSOLE_BAUD_RATE 115200
+#define DEFAULT_CBAUD B115200
#endif
#ifndef CONSOLE_BAUD_RATE
@@ -90,7 +95,7 @@ static struct tty_driver *mcfrs_serial_driver;
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
-#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
#else
#define IRQBASE 73
@@ -1510,7 +1515,7 @@ static void mcfrs_irqinit(struct mcf_serial *info)
*portp = (*portp & ~0x000000ff) | 0x00000055;
portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT);
*portp = (*portp & ~0x000003fc) | 0x000002a8;
-#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
volatile unsigned char *icrp, *uartp;
volatile unsigned long *imrp;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index a3cd0ee8486d..0585ab27ffde 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -781,7 +781,7 @@ mpc52xx_uart_remove(struct device *dev)
#ifdef CONFIG_PM
static int
-mpc52xx_uart_suspend(struct device *dev, u32 state, u32 level)
+mpc52xx_uart_suspend(struct device *dev, pm_message_t state, u32 level)
{
struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index eaa0af835290..005f027e081a 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -358,6 +358,9 @@ static int serial_pxa_startup(struct uart_port *port)
unsigned long flags;
int retval;
+ if (port->line == 3) /* HWUART */
+ up->mcr |= UART_MCR_AFE;
+ else
up->mcr = 0;
/*
@@ -481,8 +484,10 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
if ((up->port.uartclk / quot) < (2400 * 16))
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1;
- else
+ else if ((up->port.uartclk / quot) < (230400 * 16))
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8;
+ else
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32;
/*
* Ok, we're now changing the port state. Do it with
@@ -499,7 +504,7 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
- uart_update_timeout(port, termios->c_cflag, quot);
+ uart_update_timeout(port, termios->c_cflag, baud);
up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
if (termios->c_iflag & INPCK)
@@ -589,8 +594,8 @@ serial_pxa_type(struct uart_port *port)
#ifdef CONFIG_SERIAL_PXA_CONSOLE
-extern struct uart_pxa_port serial_pxa_ports[];
-extern struct uart_driver serial_pxa_reg;
+static struct uart_pxa_port serial_pxa_ports[];
+static struct uart_driver serial_pxa_reg;
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
@@ -772,6 +777,20 @@ static struct uart_pxa_port serial_pxa_ports[] = {
.ops = &serial_pxa_pops,
.line = 2,
},
+ }, { /* HWUART */
+ .name = "HWUART",
+ .cken = CKEN4_HWUART,
+ .port = {
+ .type = PORT_PXA,
+ .iotype = UPIO_MEM,
+ .membase = (void *)&HWUART,
+ .mapbase = __PREG(HWUART),
+ .irq = IRQ_HWUART,
+ .uartclk = 921600 * 16,
+ .fifosize = 64,
+ .ops = &serial_pxa_pops,
+ .line = 3,
+ },
}
};
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index c361c6fb0809..52692aa345ec 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -82,8 +82,6 @@
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
-#include <asm/mach-types.h>
-
/* structures */
struct s3c24xx_uart_info {
@@ -753,8 +751,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
{
struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- struct s3c24xx_uart_clksrc *clksrc;
- struct clk *clk;
+ struct s3c24xx_uart_clksrc *clksrc = NULL;
+ struct clk *clk = NULL;
unsigned long flags;
unsigned int baud, quot;
unsigned int ulcon;
@@ -1094,8 +1092,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
static int probe_index = 0;
-int s3c24xx_serial_probe(struct device *_dev,
- struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_probe(struct device *_dev,
+ struct s3c24xx_uart_info *info)
{
struct s3c24xx_uart_port *ourport;
struct platform_device *dev = to_platform_device(_dev);
@@ -1122,7 +1120,7 @@ int s3c24xx_serial_probe(struct device *_dev,
return ret;
}
-int s3c24xx_serial_remove(struct device *_dev)
+static int s3c24xx_serial_remove(struct device *_dev)
{
struct uart_port *port = s3c24xx_dev_to_port(_dev);
@@ -1136,7 +1134,8 @@ int s3c24xx_serial_remove(struct device *_dev)
#ifdef CONFIG_PM
-int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state,
+ u32 level)
{
struct uart_port *port = s3c24xx_dev_to_port(dev);
@@ -1146,7 +1145,7 @@ int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-int s3c24xx_serial_resume(struct device *dev, u32 level)
+static int s3c24xx_serial_resume(struct device *dev, u32 level)
{
struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
@@ -1167,8 +1166,8 @@ int s3c24xx_serial_resume(struct device *dev, u32 level)
#define s3c24xx_serial_resume NULL
#endif
-int s3c24xx_serial_init(struct device_driver *drv,
- struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_init(struct device_driver *drv,
+ struct s3c24xx_uart_info *info)
{
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
return driver_register(drv);
@@ -1237,6 +1236,7 @@ static int s3c2400_serial_probe(struct device *dev)
static struct device_driver s3c2400_serial_drv = {
.name = "s3c2400-uart",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2400_serial_probe,
.remove = s3c24xx_serial_remove,
@@ -1340,6 +1340,7 @@ static int s3c2410_serial_probe(struct device *dev)
static struct device_driver s3c2410_serial_drv = {
.name = "s3c2410-uart",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2410_serial_probe,
.remove = s3c24xx_serial_remove,
@@ -1501,6 +1502,7 @@ static int s3c2440_serial_probe(struct device *dev)
static struct device_driver s3c2440_serial_drv = {
.name = "s3c2440-uart",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2440_serial_probe,
.remove = s3c24xx_serial_remove,
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 1225b14f6e9d..dd8aed242357 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -799,7 +799,7 @@ sa1100_console_setup(struct console *co, char *options)
return uart_set_options(&sport->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver sa1100_reg;
+static struct uart_driver sa1100_reg;
static struct console sa1100_console = {
.name = "ttySA",
.write = sa1100_console_write,
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 1ae0b381c162..2c7d3ef76e8e 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -859,6 +859,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
+ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 8302376800c0..d01dbe5da3b9 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -632,7 +632,7 @@ static int __init lh7a40xuart_console_setup (struct console* co, char* options)
return uart_set_options (port, co, baud, parity, bits, flow);
}
-extern struct uart_driver lh7a40x_reg;
+static struct uart_driver lh7a40x_reg;
static struct console lh7a40x_console = {
.name = "ttyAM",
.write = lh7a40xuart_console_write,
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 49afadbe461b..f10c86d60b64 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -31,6 +31,8 @@
* 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/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 512266307866..430754ebac8a 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -967,7 +967,7 @@ static int sci_startup(struct uart_port *port)
#endif
sci_request_irq(s);
- sci_start_tx(port, 1);
+ sci_start_tx(port);
sci_start_rx(port, 1);
return 0;
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index e971156daa60..ba9381fd3f2d 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -274,7 +274,6 @@ static void transmit_chars(struct uart_sunsab_port *up,
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
up->interrupt_mask1 |= SAB82532_IMR1_XPR;
writeb(up->interrupt_mask1, &up->regs->w.imr1);
- uart_write_wakeup(&up->port);
return;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 5959e6755a81..656c0e8d160e 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -518,11 +518,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
quot = up->port.uartclk / (16 * new_baud);
- spin_unlock(&up->port.lock);
-
sunsu_change_speed(&up->port, up->cflag, 0, quot);
-
- spin_lock(&up->port.lock);
}
static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index d75445738c88..7653d6cf05af 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -517,10 +517,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
if (up->port.info == NULL)
goto ack_tx_int;
xmit = &up->port.info->xmit;
- if (uart_circ_empty(xmit)) {
- uart_write_wakeup(&up->port);
+ if (uart_circ_empty(xmit))
goto ack_tx_int;
- }
+
if (uart_tx_stopped(&up->port))
goto ack_tx_int;
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 4382ee60b6a8..6bed8713897e 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -1683,7 +1683,7 @@ static void __init probe_sccs(void)
#ifndef CONFIG_SERIAL_DEC_CONSOLE
/*
* We're called early and memory managment isn't up, yet.
- * Thus check_region would fail.
+ * Thus request_region would fail.
*/
if (!request_region((unsigned long)
zs_channels[n_channels].control,
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index f2c9fa423d40..f6704688ee8c 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -774,10 +774,7 @@ static int ixj_wink(IXJ *j)
j->pots_winkstart = jiffies;
SLIC_SetState(PLD_SLIC_STATE_OC, j);
- while (time_before(jiffies, j->pots_winkstart + j->winktime)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(jiffies_to_msecs(j->winktime));
SLIC_SetState(slicnow, j);
return 0;
@@ -1912,7 +1909,6 @@ static int ixj_pcmcia_cable_check(IXJ *j)
static int ixj_hookstate(IXJ *j)
{
- unsigned long det;
int fOffHook = 0;
switch (j->cardtype) {
@@ -1943,11 +1939,7 @@ static int ixj_hookstate(IXJ *j)
j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
if (j->flags.ringing || j->flags.cringing) {
if (!in_interrupt()) {
- det = jiffies + (hertz / 50);
- while (time_before(jiffies, det)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(20);
}
SLIC_GetState(j);
if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
@@ -2062,7 +2054,7 @@ static void ixj_ring_start(IXJ *j)
static int ixj_ring(IXJ *j)
{
char cntr;
- unsigned long jif, det;
+ unsigned long jif;
j->flags.ringing = 1;
if (ixj_hookstate(j) & 1) {
@@ -2070,7 +2062,6 @@ static int ixj_ring(IXJ *j)
j->flags.ringing = 0;
return 1;
}
- det = 0;
for (cntr = 0; cntr < j->maxrings; cntr++) {
jif = jiffies + (1 * hertz);
ixj_ring_on(j);
@@ -2080,8 +2071,7 @@ static int ixj_ring(IXJ *j)
j->flags.ringing = 0;
return 1;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
@@ -2089,20 +2079,13 @@ static int ixj_ring(IXJ *j)
ixj_ring_off(j);
while (time_before(jiffies, jif)) {
if (ixj_hookstate(j) & 1) {
- det = jiffies + (hertz / 100);
- while (time_before(jiffies, det)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- if (signal_pending(current))
- break;
- }
+ msleep(10);
if (ixj_hookstate(j) & 1) {
j->flags.ringing = 0;
return 1;
}
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
@@ -2168,10 +2151,8 @@ static int ixj_release(struct inode *inode, struct file *file_p)
* Set up locks to ensure that only one process is talking to the DSP at a time.
* This is necessary to keep the DSP from locking up.
*/
- while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
+ schedule_timeout_interruptible(1);
if (ixjdebug & 0x0002)
printk(KERN_INFO "Closing board %d\n", NUM(inode));
@@ -3301,14 +3282,10 @@ static void ixj_write_cidcw(IXJ *j)
ixj_play_tone(j, 23);
clear_bit(j->board, &j->busyflags);
- while(j->tone_state) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
- while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while(j->tone_state)
+ schedule_timeout_interruptible(1);
+ while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
+ schedule_timeout_interruptible(1);
if(ixjdebug & 0x0200) {
printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
}
@@ -3328,14 +3305,10 @@ static void ixj_write_cidcw(IXJ *j)
ixj_play_tone(j, 24);
clear_bit(j->board, &j->busyflags);
- while(j->tone_state) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
- while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while(j->tone_state)
+ schedule_timeout_interruptible(1);
+ while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
+ schedule_timeout_interruptible(1);
if(ixjdebug & 0x0200) {
printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
}
@@ -3343,14 +3316,10 @@ static void ixj_write_cidcw(IXJ *j)
j->cidcw_wait = jiffies + ((50 * hertz) / 100);
clear_bit(j->board, &j->busyflags);
- while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
- while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait))
+ schedule_timeout_interruptible(1);
+ while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
+ schedule_timeout_interruptible(1);
j->cidcw_wait = 0;
if(!j->flags.cidcw_ack) {
if(ixjdebug & 0x0200) {
@@ -6125,10 +6094,8 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
* Set up locks to ensure that only one process is talking to the DSP at a time.
* This is necessary to keep the DSP from locking up.
*/
- while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
+ schedule_timeout_interruptible(1);
if (ixjdebug & 0x0040)
printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
if (minor >= IXJMAX) {
@@ -6694,8 +6661,6 @@ static struct file_operations ixj_fops =
static int ixj_linetest(IXJ *j)
{
- unsigned long jifwait;
-
j->flags.pstncheck = 1; /* Testing */
j->flags.pstn_present = 0; /* Assume the line is not there */
@@ -6726,11 +6691,7 @@ static int ixj_linetest(IXJ *j)
outb_p(j->pld_scrw.byte, j->XILINXbase);
daa_set_mode(j, SOP_PU_CONVERSATION);
- jifwait = jiffies + hertz;
- while (time_before(jiffies, jifwait)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(1000);
daa_int_read(j);
daa_set_mode(j, SOP_PU_RESET);
if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
@@ -6750,11 +6711,7 @@ static int ixj_linetest(IXJ *j)
j->pld_slicw.bits.rly3 = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
daa_set_mode(j, SOP_PU_CONVERSATION);
- jifwait = jiffies + hertz;
- while (time_before(jiffies, jifwait)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(1000);
daa_int_read(j);
daa_set_mode(j, SOP_PU_RESET);
if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
@@ -6783,7 +6740,6 @@ static int ixj_linetest(IXJ *j)
static int ixj_selfprobe(IXJ *j)
{
unsigned short cmd;
- unsigned long jif;
int cnt;
BYTES bytes;
@@ -6933,29 +6889,13 @@ static int ixj_selfprobe(IXJ *j)
} else {
if (j->cardtype == QTI_LINEJACK) {
LED_SetState(0x1, j);
- jif = jiffies + (hertz / 10);
- while (time_before(jiffies, jif)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(100);
LED_SetState(0x2, j);
- jif = jiffies + (hertz / 10);
- while (time_before(jiffies, jif)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(100);
LED_SetState(0x4, j);
- jif = jiffies + (hertz / 10);
- while (time_before(jiffies, jif)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(100);
LED_SetState(0x8, j);
- jif = jiffies + (hertz / 10);
- while (time_before(jiffies, jif)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ msleep(100);
LED_SetState(0x0, j);
daa_get_version(j);
if (ixjdebug & 0x0002)
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 8e184e2641cb..79861ee12a29 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -715,13 +715,11 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
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 0561d0234f23..333e39bb105f 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/audio.c b/drivers/usb/class/audio.c
index f8f21567cc22..50858273f8d3 100644
--- a/drivers/usb/class/audio.c
+++ b/drivers/usb/class/audio.c
@@ -631,8 +631,10 @@ static void usbin_stop(struct usb_audiodev *as)
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
while (i & (FLG_URB0RUNNING|FLG_URB1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) {
- set_current_state(notkilled ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ if (notkilled)
+ schedule_timeout_interruptible(1);
+ else
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&as->lock, flags);
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
@@ -1102,8 +1104,10 @@ static void usbout_stop(struct usb_audiodev *as)
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
while (i & (FLG_URB0RUNNING|FLG_URB1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) {
- set_current_state(notkilled ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ if (notkilled)
+ schedule_timeout_interruptible(1);
+ else
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&as->lock, flags);
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 7ce43fb8118a..e195709c9c7f 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -310,8 +310,9 @@ static int usblp_check_status(struct usblp *usblp, int err)
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 9e8c377b8161..d5503cf0bf74 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/buffer.c b/drivers/usb/core/buffer.c
index fc15b4acc8af..57e800ac3cee 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -106,7 +106,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd)
void *hcd_buffer_alloc (
struct usb_bus *bus,
size_t size,
- unsigned mem_flags,
+ gfp_t mem_flags,
dma_addr_t *dma
)
{
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index f86bf1454e21..487ff672b104 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -30,6 +30,8 @@
* Revision history
* 22.12.1999 0.1 Initial release (split from proc_usb.c)
* 04.01.2000 0.2 Turned into its own filesystem
+ * 30.09.2005 0.3 Fix user-triggerable oops in async URB delivery
+ * (CAN-2005-3055)
*/
/*****************************************************************************/
@@ -43,6 +45,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,10 +53,15 @@
#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;
- struct task_struct *task;
+ pid_t pid;
+ uid_t uid, euid;
unsigned int signr;
unsigned int ifnum;
void __user *userbuffer;
@@ -71,6 +79,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
@@ -283,7 +293,8 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
sinfo.si_errno = as->urb->status;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = as->userurb;
- send_sig_info(as->signr, &sinfo, as->task);
+ kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
+ as->euid);
}
wake_up(&ps->wait);
}
@@ -487,7 +498,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 +512,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;
@@ -514,7 +530,9 @@ static int usbdev_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&ps->async_completed);
init_waitqueue_head(&ps->wait);
ps->discsignr = 0;
- ps->disctask = current;
+ ps->disc_pid = current->pid;
+ ps->disc_uid = current->uid;
+ ps->disc_euid = current->euid;
ps->disccontext = NULL;
ps->ifclaimed = 0;
wmb();
@@ -976,7 +994,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
as->userbuffer = NULL;
as->signr = uurb->signr;
as->ifnum = ifnum;
- as->task = current;
+ as->pid = current->pid;
+ as->uid = current->uid;
+ as->euid = current->euid;
if (!(uurb->endpoint & USB_DIR_IN)) {
if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {
free_async(as);
@@ -1226,7 +1246,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 +1277,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 +1487,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 fc056062c960..6385d1a99b60 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);
@@ -246,7 +242,6 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
case HC_STATE_SUSPENDED:
/* no DMA or IRQs except when HC is active */
if (dev->current_state == PCI_D0) {
- free_irq (hcd->irq, hcd);
pci_save_state (dev);
pci_disable_device (dev);
}
@@ -264,8 +259,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 +336,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");
@@ -364,14 +373,6 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
hcd->state = HC_STATE_RESUMING;
hcd->saw_irq = 0;
- retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
- hcd->irq_descr, hcd);
- if (retval < 0) {
- dev_err (hcd->self.controller,
- "can't restore IRQ after resume!\n");
- usb_hc_died (hcd);
- return retval;
- }
retval = hcd->driver->resume (hcd);
if (!HC_IS_RUNNING (hcd->state)) {
@@ -380,7 +381,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.c b/drivers/usb/core/hcd.c
index 12ecdb03ee5f..ff19d64041b5 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1112,7 +1112,7 @@ static void urb_unlink (struct urb *urb)
* expects usb_submit_urb() to have sanity checked and conditioned all
* inputs in the urb
*/
-static int hcd_submit_urb (struct urb *urb, unsigned mem_flags)
+static int hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
{
int status;
struct usb_hcd *hcd = urb->dev->bus->hcpriv;
@@ -1606,7 +1606,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
return IRQ_NONE;
hcd->saw_irq = 1;
- if (hcd->state != start && hcd->state == HC_STATE_HALT)
+ if (hcd->state == HC_STATE_HALT)
usb_hc_died (hcd);
return IRQ_HANDLED;
}
@@ -1630,7 +1630,6 @@ void usb_hc_died (struct usb_hcd *hcd)
spin_lock_irqsave (&hcd_root_hub_lock, flags);
if (hcd->rh_registered) {
hcd->poll_rh = 0;
- del_timer(&hcd->rh_timer);
/* make khubd clean up old urbs and devices */
usb_set_device_state (hcd->self.root_hub,
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 28055f95645b..1f1ed6211af8 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -142,12 +142,12 @@ struct hcd_timeout { /* timeouts we allocate */
struct usb_operations {
int (*get_frame_number) (struct usb_device *usb_dev);
- int (*submit_urb) (struct urb *urb, unsigned mem_flags);
+ int (*submit_urb) (struct urb *urb, gfp_t mem_flags);
int (*unlink_urb) (struct urb *urb, int status);
/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
- unsigned mem_flags,
+ gfp_t mem_flags,
dma_addr_t *dma);
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
@@ -200,7 +200,7 @@ struct hc_driver {
int (*urb_enqueue) (struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags);
+ gfp_t mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
@@ -247,7 +247,7 @@ int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);
void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
- unsigned mem_flags, dma_addr_t *dma);
+ gfp_t mem_flags, dma_addr_t *dma);
void hcd_buffer_free (struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
@@ -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 c9412daff682..a12cab5314e9 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -435,6 +435,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
static void hub_power_on(struct usb_hub *hub)
{
int port1;
+ unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
/* if hub supports power switching, enable power on each port */
if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
@@ -444,8 +445,8 @@ static void hub_power_on(struct usb_hub *hub)
USB_PORT_FEAT_POWER);
}
- /* Wait for power to be enabled */
- msleep(hub->descriptor->bPwrOn2PwrGood * 2);
+ /* Wait at least 100 msec for power to become stable */
+ msleep(max(pgood_delay, (unsigned) 100));
}
static void hub_quiesce(struct usb_hub *hub)
@@ -492,6 +493,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 +628,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 +744,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 +794,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 +1118,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 +1358,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;
@@ -1392,7 +1461,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
port1, status);
else {
status = hub_port_wait_reset(hub, port1, udev, delay);
- if (status)
+ if (status && status != -ENOTCONN)
dev_dbg(hub->intfdev,
"port_wait_reset: err = %d\n",
status);
@@ -1401,8 +1470,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
/* return on disconnect or reset */
switch (status) {
case 0:
- /* TRSTRCY = 10 ms */
- msleep(10);
+ /* TRSTRCY = 10 ms; plus some extra */
+ msleep(10 + 40);
/* FALL THROUGH */
case -ENOTCONN:
case -ENODEV:
@@ -1428,23 +1497,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 53bf5649621e..e7fa9b5a521e 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 c3e3a95d3804..d07bba01995b 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -713,7 +713,7 @@ void usbfs_remove_device(struct usb_device *dev)
sinfo.si_errno = EPIPE;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = ds->disccontext;
- send_sig_info(ds->discsignr, &sinfo, ds->disctask);
+ kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid);
}
}
usbfs_update_special();
@@ -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 88d1b376f67c..f9a81e84dbdf 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);
@@ -320,7 +321,7 @@ int usb_sg_init (
struct scatterlist *sg,
int nents,
size_t length,
- unsigned mem_flags
+ gfp_t mem_flags
)
{
int i;
@@ -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;
@@ -987,7 +987,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
/* remove this interface if it has been registered */
interface = dev->actconfig->interface[i];
- if (!klist_node_attached(&interface->dev.knode_bus))
+ if (!device_is_registered(&interface->dev))
continue;
dev_dbg (&dev->dev, "unregistering interface %s\n",
interface->dev.bus_id);
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c0feee25ff0a..b32898e0a27d 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -60,7 +60,7 @@ void usb_init_urb(struct urb *urb)
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
-struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags)
+struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
{
struct urb *urb;
@@ -224,7 +224,7 @@ struct urb * usb_get_urb(struct urb *urb)
* GFP_NOIO, unless b) or c) apply
*
*/
-int usb_submit_urb(struct urb *urb, unsigned mem_flags)
+int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
@@ -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 2cddd8a00437..4c57f3f649ed 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;
}
@@ -293,7 +303,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
/* if interface was already added, bind now; else let
* the future device_add() bind it, bypassing probe()
*/
- if (klist_node_attached(&dev->knode_bus))
+ if (device_is_registered(dev))
device_bind_driver(dev);
return 0;
@@ -326,8 +336,8 @@ void usb_driver_release_interface(struct usb_driver *driver,
if (iface->condition != USB_INTERFACE_BOUND)
return;
- /* release only after device_add() */
- if (klist_node_attached(&dev->knode_bus)) {
+ /* don't release if the interface hasn't been added yet */
+ if (device_is_registered(dev)) {
iface->condition = USB_INTERFACE_UNBINDING;
device_release_driver(dev);
}
@@ -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;
@@ -1129,7 +1147,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
void *usb_buffer_alloc (
struct usb_device *dev,
size_t size,
- unsigned mem_flags,
+ gfp_t mem_flags,
dma_addr_t *dma
)
{
@@ -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 2c690f6d4c18..e6504f3370ad 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 */
@@ -47,7 +52,8 @@ struct dev_state {
struct list_head async_completed;
wait_queue_head_t wait; /* wake up if a request completed */
unsigned int discsignr;
- struct task_struct *disctask;
+ pid_t disc_pid;
+ uid_t disc_uid, disc_euid;
void __user *disccontext;
unsigned long ifclaimed;
};
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 583db7c38cf1..8d9d8ee89554 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -470,7 +470,7 @@ static int dummy_disable (struct usb_ep *_ep)
}
static struct usb_request *
-dummy_alloc_request (struct usb_ep *_ep, unsigned mem_flags)
+dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags)
{
struct dummy_ep *ep;
struct dummy_request *req;
@@ -507,7 +507,7 @@ dummy_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- unsigned mem_flags
+ gfp_t mem_flags
) {
char *retval;
struct dummy_ep *ep;
@@ -541,7 +541,7 @@ fifo_complete (struct usb_ep *ep, struct usb_request *req)
static int
dummy_queue (struct usb_ep *_ep, struct usb_request *_req,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
struct dummy_ep *ep;
struct dummy_request *req;
@@ -999,7 +999,7 @@ static int dummy_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct dummy *dum;
struct urbp *urbp;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8509e955007d..f1024e804d5c 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -945,11 +945,11 @@ config_buf (enum usb_device_speed speed,
/*-------------------------------------------------------------------------*/
-static void eth_start (struct eth_dev *dev, unsigned gfp_flags);
-static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags);
+static void eth_start (struct eth_dev *dev, gfp_t gfp_flags);
+static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags);
static int
-set_ether_config (struct eth_dev *dev, unsigned gfp_flags)
+set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -1081,7 +1081,7 @@ static void eth_reset_config (struct eth_dev *dev)
* that returns config descriptors, and altsetting code.
*/
static int
-eth_set_config (struct eth_dev *dev, unsigned number, unsigned gfp_flags)
+eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -1598,7 +1598,7 @@ static void defer_kevent (struct eth_dev *dev, int flag)
static void rx_complete (struct usb_ep *ep, struct usb_request *req);
static int
-rx_submit (struct eth_dev *dev, struct usb_request *req, unsigned gfp_flags)
+rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
{
struct sk_buff *skb;
int retval = -ENOMEM;
@@ -1724,7 +1724,7 @@ clean:
}
static int prealloc (struct list_head *list, struct usb_ep *ep,
- unsigned n, unsigned gfp_flags)
+ unsigned n, gfp_t gfp_flags)
{
unsigned i;
struct usb_request *req;
@@ -1763,7 +1763,7 @@ extra:
return 0;
}
-static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags)
+static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags)
{
int status;
@@ -1779,7 +1779,7 @@ fail:
return status;
}
-static void rx_fill (struct eth_dev *dev, unsigned gfp_flags)
+static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
{
struct usb_request *req;
unsigned long flags;
@@ -1962,7 +1962,7 @@ drop:
* normally just one notification will be queued.
*/
-static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, unsigned);
+static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, gfp_t);
static void eth_req_free (struct usb_ep *ep, struct usb_request *req);
static void
@@ -2024,7 +2024,7 @@ static int rndis_control_ack (struct net_device *net)
#endif /* RNDIS */
-static void eth_start (struct eth_dev *dev, unsigned gfp_flags)
+static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
{
DEBUG (dev, "%s\n", __FUNCTION__);
@@ -2092,7 +2092,7 @@ static int eth_stop (struct net_device *net)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-eth_req_alloc (struct usb_ep *ep, unsigned size, unsigned gfp_flags)
+eth_req_alloc (struct usb_ep *ep, unsigned size, gfp_t gfp_flags)
{
struct usb_request *req;
@@ -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 4f57085619b4..a41d9d4baee3 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3713,6 +3713,7 @@ static void fsg_unbind(struct usb_gadget *gadget)
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 ea2eb52c766d..8cbae21d84b9 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/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index eaab26f4ed37..b0f3cd63e3b9 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -269,7 +269,7 @@ static int goku_ep_disable(struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-goku_alloc_request(struct usb_ep *_ep, unsigned gfp_flags)
+goku_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
{
struct goku_request *req;
@@ -327,7 +327,7 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req)
*/
static void *
goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
- dma_addr_t *dma, unsigned gfp_flags)
+ dma_addr_t *dma, gfp_t gfp_flags)
{
void *retval;
struct goku_ep *ep;
@@ -789,7 +789,7 @@ finished:
/*-------------------------------------------------------------------------*/
static int
-goku_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+goku_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct goku_request *req;
struct goku_ep *ep;
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 020815397a49..5c40980a5bd9 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -483,6 +483,7 @@ ep_release (struct inode *inode, struct file *fd)
data->state = STATE_EP_DISABLED;
data->desc.bDescriptorType = 0;
data->hs_desc.bDescriptorType = 0;
+ usb_ep_disable(data->ep);
}
put_ep (data);
return 0;
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 4842577789c9..012d1e5f1524 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -71,13 +71,13 @@ static char *state_names[] = {
static int lh7a40x_ep_enable(struct usb_ep *ep,
const struct usb_endpoint_descriptor *);
static int lh7a40x_ep_disable(struct usb_ep *ep);
-static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, int);
+static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t);
static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *);
static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned, dma_addr_t *,
- int);
+ gfp_t);
static void lh7a40x_free_buffer(struct usb_ep *ep, void *, dma_addr_t,
unsigned);
-static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, int);
+static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
static int lh7a40x_set_halt(struct usb_ep *ep, int);
static int lh7a40x_fifo_status(struct usb_ep *ep);
@@ -1106,7 +1106,7 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep)
}
static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
- unsigned gfp_flags)
+ gfp_t gfp_flags)
{
struct lh7a40x_request *req;
@@ -1134,7 +1134,7 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
}
static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
- dma_addr_t * dma, unsigned gfp_flags)
+ dma_addr_t * dma, gfp_t gfp_flags)
{
char *retval;
@@ -1158,7 +1158,7 @@ static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma,
* NOTE: Sets INDEX register
*/
static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
- unsigned gfp_flags)
+ gfp_t gfp_flags)
{
struct lh7a40x_request *req;
struct lh7a40x_ep *ep;
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 477fab2e74d1..c32e1f7476da 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -376,7 +376,7 @@ static int net2280_disable (struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-net2280_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
+net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
{
struct net2280_ep *ep;
struct net2280_request *req;
@@ -463,7 +463,7 @@ net2280_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- unsigned gfp_flags
+ gfp_t gfp_flags
)
{
void *retval;
@@ -897,7 +897,7 @@ done (struct net2280_ep *ep, struct net2280_request *req, int status)
/*-------------------------------------------------------------------------*/
static int
-net2280_queue (struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct net2280_request *req;
struct net2280_ep *ep;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index ff5533e69560..287c5900fb13 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -269,7 +269,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-omap_alloc_request(struct usb_ep *ep, unsigned gfp_flags)
+omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
{
struct omap_req *req;
@@ -298,7 +298,7 @@ omap_alloc_buffer(
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- unsigned gfp_flags
+ gfp_t gfp_flags
)
{
void *retval;
@@ -937,7 +937,7 @@ static void dma_channel_release(struct omap_ep *ep)
/*-------------------------------------------------------------------------*/
static int
-omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct omap_ep *ep = container_of(_ep, struct omap_ep, ep);
struct omap_req *req = container_of(_req, struct omap_req, req);
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 1507738337c4..3d4d89c371e7 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -332,7 +332,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep)
* pxa2xx_ep_alloc_request - allocate a request data structure
*/
static struct usb_request *
-pxa2xx_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
+pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
{
struct pxa2xx_request *req;
@@ -367,7 +367,7 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
*/
static void *
pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
- dma_addr_t *dma, unsigned gfp_flags)
+ dma_addr_t *dma, gfp_t gfp_flags)
{
char *retval;
@@ -874,7 +874,7 @@ done:
/*-------------------------------------------------------------------------*/
static int
-pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct pxa2xx_request *req;
struct pxa2xx_ep *ep;
@@ -2602,7 +2602,7 @@ static int __exit pxa2xx_udc_remove(struct device *_dev)
* VBUS IRQs should probably be ignored so that the PXA device just acts
* "dead" to USB hosts until system resume.
*/
-static int pxa2xx_udc_suspend(struct device *dev, u32 state, u32 level)
+static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level)
{
struct pxa2xx_udc *udc = dev_get_drvdata(dev);
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index d0bc396a85d5..19a883f7d1b8 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -73,7 +73,7 @@ struct pxa2xx_ep {
volatile u32 *reg_ubcr;
volatile u32 *reg_uddr;
#ifdef USE_DMA
- volatile u32 *reg_drcmr;
+ volatile u32 *reg_drcmr;
#define drcmr(n) .reg_drcmr = & DRCMR ## n ,
#else
#define drcmr(n)
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 9e4f1c6935a5..b35ac6d334f8 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -300,18 +300,18 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
u8 type, unsigned int index, int is_otg);
static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
- unsigned kmalloc_flags);
+ gfp_t kmalloc_flags);
static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
- unsigned kmalloc_flags);
+ gfp_t kmalloc_flags);
static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags);
+static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
static void gs_free_ports(struct gs_dev *dev);
/* circular buffer */
-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags);
+static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
static void gs_buf_free(struct gs_buf *gb);
static void gs_buf_clear(struct gs_buf *gb);
static unsigned int gs_buf_data_avail(struct gs_buf *gb);
@@ -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 */
@@ -2120,7 +2091,7 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
* usb_request or NULL if there is an error.
*/
static struct usb_request *
-gs_alloc_req(struct usb_ep *ep, unsigned int len, unsigned kmalloc_flags)
+gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags)
{
struct usb_request *req;
@@ -2161,7 +2132,7 @@ static void gs_free_req(struct usb_ep *ep, struct usb_request *req)
* endpoint, buffer len, and kmalloc flags.
*/
static struct gs_req_entry *
-gs_alloc_req_entry(struct usb_ep *ep, unsigned len, unsigned kmalloc_flags)
+gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
{
struct gs_req_entry *req;
@@ -2202,7 +2173,7 @@ static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req)
*
* The device lock is normally held when calling this function.
*/
-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags)
+static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags)
{
int i;
struct gs_port *port;
@@ -2284,7 +2255,7 @@ static void gs_free_ports(struct gs_dev *dev)
*
* Allocate a circular buffer and all associated memory.
*/
-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags)
+static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
{
struct gs_buf *gb;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index bb9b2d94eed5..ec9c424f1d97 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -612,7 +612,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
}
static struct usb_request *
-source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
+source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags)
{
struct usb_request *req;
int status;
@@ -640,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
}
static int
-set_source_sink_config (struct zero_dev *dev, unsigned gfp_flags)
+set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags)
{
int result = 0;
struct usb_ep *ep;
@@ -744,7 +744,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
}
static int
-set_loopback_config (struct zero_dev *dev, unsigned gfp_flags)
+set_loopback_config (struct zero_dev *dev, gfp_t gfp_flags)
{
int result = 0;
struct usb_ep *ep;
@@ -845,7 +845,7 @@ static void zero_reset_config (struct zero_dev *dev)
* by limiting configuration choices (like the pxa2xx).
*/
static int
-zero_set_config (struct zero_dev *dev, unsigned number, unsigned gfp_flags)
+zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -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 149b13fc0a71..f5eb9e7b5b18 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -400,6 +400,23 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
return -EIO;
}
break;
+ case PCI_VENDOR_ID_NVIDIA:
+ /* NVidia reports that certain chips don't handle
+ * QH, ITD, or SITD addresses above 2GB. (But TD,
+ * data buffer, and periodic schedule are normal.)
+ */
+ switch (pdev->device) {
+ case 0x003c: /* MCP04 */
+ case 0x005b: /* CK804 */
+ case 0x00d8: /* CK8 */
+ case 0x00e8: /* CK8S */
+ if (pci_set_consistent_dma_mask(pdev,
+ DMA_31BIT_MASK) < 0)
+ ehci_warn (ehci, "can't enable NVidia "
+ "workaround for >2GB RAM\n");
+ break;
+ }
+ break;
}
/* optional debug port, normally in the first BAR */
@@ -549,7 +566,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
@@ -757,12 +776,16 @@ static int ehci_resume (struct usb_hcd *hcd)
if (time_before (jiffies, ehci->next_statechange))
msleep (100);
- /* If any port is suspended, we know we can/must resume the HC. */
+ /* If any port is suspended (or owned by the companion),
+ * we know we can/must resume the HC (and mustn't reset it).
+ */
for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
u32 status;
port--;
status = readl (&ehci->regs->port_status [port]);
- if (status & PORT_SUSPEND) {
+ if (!(status & PORT_POWER))
+ continue;
+ if (status & (PORT_SUSPEND | PORT_OWNER)) {
down (&hcd->self.root_hub->serialize);
retval = ehci_hub_resume (hcd);
up (&hcd->self.root_hub->serialize);
@@ -960,7 +983,7 @@ static int ehci_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
struct list_head qtd_list;
@@ -1124,8 +1147,7 @@ rescan:
case QH_STATE_UNLINK: /* wait for hw to finish? */
idle_timeout:
spin_unlock_irqrestore (&ehci->lock, flags);
- set_current_state (TASK_UNINTERRUPTIBLE);
- schedule_timeout (1);
+ schedule_timeout_uninterruptible(1);
goto rescan;
case QH_STATE_IDLE: /* fully unlinked */
if (list_empty (&qh->qtd_list)) {
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 36cc1f2218d5..18d3f2270316 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -54,7 +54,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
/* suspend any active/unsuspended ports, maybe allow wakeup */
while (port--) {
u32 __iomem *reg = &ehci->regs->port_status [port];
- u32 t1 = readl (reg);
+ u32 t1 = readl (reg) & ~PORT_RWC_BITS;
u32 t2 = t1;
if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
@@ -115,7 +115,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
i = HCS_N_PORTS (ehci->hcs_params);
while (i--) {
temp = readl (&ehci->regs->port_status [i]);
- temp &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
+ temp &= ~(PORT_RWC_BITS
+ | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
if (temp & PORT_SUSPEND) {
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
temp |= PORT_RESUME;
@@ -128,7 +129,7 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
temp = readl (&ehci->regs->port_status [i]);
if ((temp & PORT_SUSPEND) == 0)
continue;
- temp &= ~PORT_RESUME;
+ temp &= ~(PORT_RWC_BITS | PORT_RESUME);
writel (temp, &ehci->regs->port_status [i]);
ehci_vdbg (ehci, "resumed port %d\n", i + 1);
}
@@ -191,6 +192,7 @@ static int check_reset_complete (
// what happens if HCS_N_CC(params) == 0 ?
port_status |= PORT_OWNER;
+ port_status &= ~PORT_RWC_BITS;
writel (port_status, &ehci->regs->port_status [index]);
} else
@@ -233,7 +235,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
if (temp & PORT_OWNER) {
/* don't report this in GetPortStatus */
if (temp & PORT_CSC) {
- temp &= ~PORT_CSC;
+ temp &= ~PORT_RWC_BITS;
+ temp |= PORT_CSC;
writel (temp, &ehci->regs->port_status [i]);
}
continue;
@@ -343,7 +346,7 @@ static int ehci_hub_control (
&ehci->regs->port_status [wIndex]);
break;
case USB_PORT_FEAT_C_ENABLE:
- writel (temp | PORT_PEC,
+ writel((temp & ~PORT_RWC_BITS) | PORT_PEC,
&ehci->regs->port_status [wIndex]);
break;
case USB_PORT_FEAT_SUSPEND:
@@ -353,7 +356,8 @@ static int ehci_hub_control (
if ((temp & PORT_PE) == 0)
goto error;
/* resume signaling for 20 msec */
- writel ((temp & ~PORT_WAKE_BITS) | PORT_RESUME,
+ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+ writel (temp | PORT_RESUME,
&ehci->regs->port_status [wIndex]);
ehci->reset_done [wIndex] = jiffies
+ msecs_to_jiffies (20);
@@ -364,15 +368,15 @@ static int ehci_hub_control (
break;
case USB_PORT_FEAT_POWER:
if (HCS_PPC (ehci->hcs_params))
- writel (temp & ~PORT_POWER,
+ writel (temp & ~(PORT_RWC_BITS | PORT_POWER),
&ehci->regs->port_status [wIndex]);
break;
case USB_PORT_FEAT_C_CONNECTION:
- writel (temp | PORT_CSC,
+ writel((temp & ~PORT_RWC_BITS) | PORT_CSC,
&ehci->regs->port_status [wIndex]);
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
- writel (temp | PORT_OCC,
+ writel((temp & ~PORT_RWC_BITS) | PORT_OCC,
&ehci->regs->port_status [wIndex]);
break;
case USB_PORT_FEAT_C_RESET:
@@ -416,7 +420,7 @@ static int ehci_hub_control (
/* stop resume signaling */
temp = readl (&ehci->regs->port_status [wIndex]);
- writel (temp & ~PORT_RESUME,
+ writel (temp & ~(PORT_RWC_BITS | PORT_RESUME),
&ehci->regs->port_status [wIndex]);
retval = handshake (
&ehci->regs->port_status [wIndex],
@@ -437,7 +441,7 @@ static int ehci_hub_control (
ehci->reset_done [wIndex] = 0;
/* force reset to complete */
- writel (temp & ~PORT_RESET,
+ writel (temp & ~(PORT_RWC_BITS | PORT_RESET),
&ehci->regs->port_status [wIndex]);
/* REVISIT: some hardware needs 550+ usec to clear
* this bit; seems too long to spin routinely...
@@ -500,6 +504,7 @@ static int ehci_hub_control (
if (temp & PORT_OWNER)
break;
+ temp &= ~PORT_RWC_BITS;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
if ((temp & PORT_PE) == 0
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 5c38ad869485..91c2ab43cbcc 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -45,7 +45,7 @@ static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
INIT_LIST_HEAD (&qtd->qtd_list);
}
-static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
+static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
{
struct ehci_qtd *qtd;
dma_addr_t dma;
@@ -79,7 +79,7 @@ static void qh_destroy (struct kref *kref)
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
}
-static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
+static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
{
struct ehci_qh *qh;
dma_addr_t dma;
@@ -161,7 +161,7 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci)
}
/* remember to add cleanup code (above) if you add anything here */
-static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
+static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
{
int i;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 20df01a79b2e..5bb872c3496d 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -477,7 +477,7 @@ qh_urb_transaction (
struct ehci_hcd *ehci,
struct urb *urb,
struct list_head *head,
- int flags
+ gfp_t flags
) {
struct ehci_qtd *qtd, *qtd_prev;
dma_addr_t buf;
@@ -629,7 +629,7 @@ static struct ehci_qh *
qh_make (
struct ehci_hcd *ehci,
struct urb *urb,
- int flags
+ gfp_t flags
) {
struct ehci_qh *qh = ehci_qh_alloc (ehci, flags);
u32 info1 = 0, info2 = 0;
@@ -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;
}
}
@@ -899,7 +906,7 @@ submit_async (
struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct ehci_qtd *qtd;
int epnum;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 4c972b57c7c3..f0c8aa1ccd5d 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -589,7 +589,7 @@ static int intr_submit (
struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
- unsigned mem_flags
+ gfp_t mem_flags
) {
unsigned epnum;
unsigned long flags;
@@ -634,7 +634,7 @@ done:
/* ehci_iso_stream ops work with both ITD and SITD */
static struct ehci_iso_stream *
-iso_stream_alloc (unsigned mem_flags)
+iso_stream_alloc (gfp_t mem_flags)
{
struct ehci_iso_stream *stream;
@@ -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;
@@ -847,7 +851,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
/* ehci_iso_sched ops can be ITD-only or SITD-only */
static struct ehci_iso_sched *
-iso_sched_alloc (unsigned packets, unsigned mem_flags)
+iso_sched_alloc (unsigned packets, gfp_t mem_flags)
{
struct ehci_iso_sched *iso_sched;
int size = sizeof *iso_sched;
@@ -920,7 +924,7 @@ itd_urb_transaction (
struct ehci_iso_stream *stream,
struct ehci_hcd *ehci,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
)
{
struct ehci_itd *itd;
@@ -1414,7 +1418,7 @@ itd_complete (
/*-------------------------------------------------------------------------*/
static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
int status = -EINVAL;
unsigned long flags;
@@ -1525,7 +1529,7 @@ sitd_urb_transaction (
struct ehci_iso_stream *stream,
struct ehci_hcd *ehci,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
)
{
struct ehci_sitd *sitd;
@@ -1775,7 +1779,7 @@ sitd_complete (
static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
int status = -EINVAL;
unsigned long flags;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index a7542157534c..f34a0516d35f 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -263,6 +263,7 @@ struct ehci_regs {
#define PORT_PE (1<<2) /* port enable */
#define PORT_CSC (1<<1) /* connect status change */
#define PORT_CONNECT (1<<0) /* device connected */
+#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
} __attribute__ ((packed));
/* Appendix C, Debug port ... intended for use with special "debug devices"
@@ -421,6 +422,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 +481,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 81f8f6b7fdce..a8267cf17db4 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -178,8 +178,8 @@ static __u8 root_hub_hub_des[] =
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 75128c371800..2548d94fcd72 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);
@@ -326,7 +326,8 @@ static void postproc_atl_queue(struct isp116x *isp116x)
usb_settoggle(udev, ep->epnum,
ep->nextpid ==
USB_PID_OUT,
- PTD_GET_TOGGLE(ptd) ^ 1);
+ PTD_GET_TOGGLE(ptd));
+ urb->actual_length += PTD_GET_COUNT(ptd);
urb->status = cc_to_error[TD_DATAUNDERRUN];
spin_unlock(&urb->lock);
continue;
@@ -629,14 +630,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);
@@ -695,7 +694,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load)
static int isp116x_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *hep, struct urb *urb,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
struct usb_device *udev = urb->dev;
@@ -925,20 +924,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 +953,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
continue;
}
}
+ spin_unlock_irqrestore(&isp116x->lock, flags);
return changed;
}
@@ -1463,10 +1470,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 +1477,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 +1494,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 +1517,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 +1543,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 +1554,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 +1565,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 +1601,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 +1649,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-dbg.c b/drivers/usb/host/ohci-dbg.c
index 447f488f5d93..7924c74f958e 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -228,23 +228,22 @@ ohci_dump_roothub (
char **next,
unsigned *size)
{
- u32 temp, ndp, i;
+ u32 temp, i;
temp = roothub_a (controller);
if (temp == ~(u32)0)
return;
- ndp = (temp & RH_A_NDP);
if (verbose) {
ohci_dbg_sw (controller, next, size,
- "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
+ "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d(%d)\n", temp,
((temp & RH_A_POTPGT) >> 24) & 0xff,
(temp & RH_A_NOCP) ? " NOCP" : "",
(temp & RH_A_OCPM) ? " OCPM" : "",
(temp & RH_A_DT) ? " DT" : "",
(temp & RH_A_NPS) ? " NPS" : "",
(temp & RH_A_PSM) ? " PSM" : "",
- ndp
+ (temp & RH_A_NDP), controller->num_ports
);
temp = roothub_b (controller);
ohci_dbg_sw (controller, next, size,
@@ -266,7 +265,7 @@ ohci_dump_roothub (
);
}
- for (i = 0; i < ndp; i++) {
+ for (i = 0; i < controller->num_ports; i++) {
temp = roothub_portstatus (controller, i);
dbg_port_sw (controller, i, temp, next, size);
}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 56b43f2a0e52..f8da8c7af7c6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -180,7 +180,7 @@ static int ohci_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ed *ed;
@@ -382,8 +382,7 @@ sanitize:
goto sanitize;
}
spin_unlock_irqrestore (&ohci->lock, flags);
- set_current_state (TASK_UNINTERRUPTIBLE);
- schedule_timeout (1);
+ schedule_timeout_uninterruptible(1);
goto rescan;
case ED_IDLE: /* fully unlinked */
if (list_empty (&ed->td_list)) {
@@ -485,6 +484,10 @@ static int ohci_init (struct ohci_hcd *ohci)
// flush the writes
(void) ohci_readl (ohci, &ohci->regs->control);
+ /* Read the number of ports unless overridden */
+ if (ohci->num_ports == 0)
+ ohci->num_ports = roothub_a(ohci) & RH_A_NDP;
+
if (ohci->hcca)
return 0;
@@ -561,10 +564,8 @@ static int ohci_run (struct ohci_hcd *ohci)
msleep(temp);
temp = roothub_a (ohci);
if (!(temp & RH_A_NPS)) {
- unsigned ports = temp & RH_A_NDP;
-
/* power down each port */
- for (temp = 0; temp < ports; temp++)
+ for (temp = 0; temp < ohci->num_ports; temp++)
ohci_writel (ohci, RH_PS_LSDA,
&ohci->regs->roothub.portstatus [temp]);
}
@@ -720,6 +721,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
if (ints & OHCI_INTR_RD) {
ohci_vdbg (ohci, "resume detect\n");
+ ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
if (hcd->state != HC_STATE_QUIESCING)
schedule_work(&ohci->rh_resume);
}
@@ -861,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
* and that if we try to turn them back on the root hub
* will respond to CSC processing.
*/
- i = roothub_a (ohci) & RH_A_NDP;
+ i = ohci->num_ports;
while (i--)
ohci_writel (ohci, RH_PS_PSS,
&ohci->regs->roothub.portstatus [temp]);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 83ca4549a50e..ce7b28da7a15 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -184,7 +184,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
if (status != -EINPROGRESS)
return status;
- temp = roothub_a (ohci) & RH_A_NDP;
+ temp = ohci->num_ports;
enables = 0;
while (temp--) {
u32 stat = ohci_readl (ohci,
@@ -304,7 +304,7 @@ static int
ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ports, i, changed = 0, length = 1;
+ int i, changed = 0, length = 1;
int can_suspend = hcd->can_wakeup;
unsigned long flags;
@@ -319,9 +319,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
goto done;
}
- ports = roothub_a (ohci) & RH_A_NDP;
- if (ports > MAX_ROOT_PORTS) {
- ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", ports,
+ /* undocumented erratum seen on at least rev D */
+ if ((ohci->flags & OHCI_QUIRK_AMD756)
+ && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) {
+ ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n",
ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
goto done;
@@ -332,13 +333,13 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
buf [0] = changed = 1;
else
buf [0] = 0;
- if (ports > 7) {
+ if (ohci->num_ports > 7) {
buf [1] = 0;
length++;
}
/* look at each port */
- for (i = 0; i < ports; i++) {
+ for (i = 0; i < ohci->num_ports; i++) {
u32 status = roothub_portstatus (ohci, i);
if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
@@ -395,15 +396,14 @@ ohci_hub_descriptor (
struct usb_hub_descriptor *desc
) {
u32 rh = roothub_a (ohci);
- int ports = rh & RH_A_NDP;
u16 temp;
desc->bDescriptorType = 0x29;
desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
desc->bHubContrCurrent = 0;
- desc->bNbrPorts = ports;
- temp = 1 + (ports / 8);
+ desc->bNbrPorts = ohci->num_ports;
+ temp = 1 + (ohci->num_ports / 8);
desc->bDescLength = 7 + 2 * temp;
temp = 0;
@@ -421,7 +421,7 @@ ohci_hub_descriptor (
rh = roothub_b (ohci);
memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
desc->bitmap [0] = rh & RH_B_DR;
- if (ports > 7) {
+ if (ohci->num_ports > 7) {
desc->bitmap [1] = (rh & RH_B_DR) >> 8;
desc->bitmap [2] = 0xff;
} else
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 817620d73841..859aca7be753 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -17,8 +17,6 @@
*/
#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/arch/hardware.h>
extern int usb_disabled(void);
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index fd3c4d3714bd..9fb83dfb1eb4 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -84,7 +84,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
/* TDs ... */
static struct td *
-td_alloc (struct ohci_hcd *hc, unsigned mem_flags)
+td_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
{
dma_addr_t dma;
struct td *td;
@@ -118,7 +118,7 @@ td_free (struct ohci_hcd *hc, struct td *td)
/* EDs ... */
static struct ed *
-ed_alloc (struct ohci_hcd *hc, unsigned mem_flags)
+ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
{
dma_addr_t dma;
struct ed *ed;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 5cde76faab93..d8f3ba7ad52e 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -18,7 +18,6 @@
#include <asm/io.h>
#include <asm/mach-types.h>
-#include <asm/arch/hardware.h>
#include <asm/arch/mux.h>
#include <asm/arch/irqs.h>
#include <asm/arch/gpio.h>
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 17964c39d06a..251533363028 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -14,8 +14,6 @@
* 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-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index e5bc1789d18a..2fdb262d4726 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -75,33 +75,6 @@ static int pxa27x_ohci_select_pmm( int mode )
return 0;
}
-/*
- If you select PMM_PERPORT_MODE, you should set the port power
- */
-static int pxa27x_ohci_set_port_power( int port )
-{
- if ( (pxa27x_ohci_pmm_state==PMM_PERPORT_MODE)
- && (port>0) && (port<PXA_UHC_MAX_PORTNUM) ) {
- UHCRHPS(port) |= 0x100;
- return 0;
- }
- return -1;
-}
-
-/*
- If you select PMM_PERPORT_MODE, you should set the port power
- */
-static int pxa27x_ohci_clear_port_power( int port )
-{
- if ( (pxa27x_ohci_pmm_state==PMM_PERPORT_MODE)
- && (port>0) && (port<PXA_UHC_MAX_PORTNUM) ) {
- UHCRHPS(port) |= 0x200;
- return 0;
- }
-
- return -1;
-}
-
extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/
@@ -130,11 +103,17 @@ static void pxa27x_start_hc(struct platform_device *dev)
Polarity Low to active low. Supply power to USB ports. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+ pxa27x_ohci_pmm_state = PMM_PERPORT_MODE;
}
UHCHR &= ~UHCHR_SSE;
UHCHIE = (UHCHIE_UPRIE | UHCHIE_RWIE);
+
+ /* Clear any OTG Pin Hold */
+ if (PSSR & PSSR_OTGPH)
+ PSSR |= PSSR_OTGPH;
}
static void pxa27x_stop_hc(struct platform_device *dev)
@@ -198,17 +177,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
pxa27x_start_hc(dev);
/* Select Power Management Mode */
- pxa27x_ohci_select_pmm( PMM_PERPORT_MODE );
-
- /* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */
- if (pxa27x_ohci_set_port_power(1) < 0)
- printk(KERN_ERR "Setting port 1 power failed.\n");
-
- if (pxa27x_ohci_clear_port_power(2) < 0)
- printk(KERN_ERR "Setting port 2 power failed.\n");
-
- if (pxa27x_ohci_clear_port_power(3) < 0)
- printk(KERN_ERR "Setting port 3 power failed.\n");
+ pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state);
ohci_hcd_init(hcd_to_ohci(hcd));
@@ -258,6 +227,9 @@ ohci_pxa27x_start (struct usb_hcd *hcd)
ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);
+ /* The value of NDP in roothub_a is incorrect on this hardware */
+ ohci->num_ports = 3;
+
if ((ret = ohci_init(ohci)) < 0)
return ret;
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e9401662503c..da7d5478f74d 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -20,7 +20,6 @@
*/
#include <asm/hardware.h>
-#include <asm/mach-types.h>
#include <asm/hardware/clock.h>
#include <asm/arch/usb-control.h>
@@ -129,7 +128,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 +338,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/host/ohci.h b/drivers/usb/host/ohci.h
index 71cdd2262860..8a9b9d9209e9 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -383,6 +383,7 @@ struct ohci_hcd {
/*
* driver state
*/
+ int num_ports;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
unsigned long next_statechange; /* suspend/resume */
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index d2a1fd40dfcb..cad858575cea 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -782,6 +782,9 @@ retry:
/* usb 1.1 says max 90% of a frame is available for periodic transfers.
* this driver doesn't promise that much since it's got to handle an
* IRQ per packet; irq handling latencies also use up that time.
+ *
+ * NOTE: the periodic schedule is a sparse tree, with the load for
+ * each branch minimized. see fig 3.5 in the OHCI spec for example.
*/
#define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */
@@ -815,7 +818,7 @@ static int sl811h_urb_enqueue(
struct usb_hcd *hcd,
struct usb_host_endpoint *hep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct sl811 *sl811 = hcd_to_sl811(hcd);
struct usb_device *udev = urb->dev;
@@ -843,6 +846,7 @@ static int sl811h_urb_enqueue(
if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE))
|| !HC_IS_RUNNING(hcd->state)) {
retval = -ENODEV;
+ kfree(ep);
goto fail;
}
@@ -911,8 +915,16 @@ static int sl811h_urb_enqueue(
case PIPE_ISOCHRONOUS:
case PIPE_INTERRUPT:
urb->interval = ep->period;
- if (ep->branch < PERIODIC_SIZE)
+ if (ep->branch < PERIODIC_SIZE) {
+ /* NOTE: the phase is correct here, but the value
+ * needs offsetting by the transfer queue depth.
+ * All current drivers ignore start_frame, so this
+ * is unlikely to ever matter...
+ */
+ urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1))
+ + ep->branch;
break;
+ }
retval = balance(sl811, ep->period, ep->load);
if (retval < 0)
@@ -1122,7 +1134,7 @@ sl811h_hub_descriptor (
desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp);
/* two bitmaps: ports removable, and legacy PortPwrCtrlMask */
- desc->bitmap[0] = 1 << 1;
+ desc->bitmap[0] = 0 << 1;
desc->bitmap[1] = ~0;
}
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 0d5d2545bf07..0c024898cbea 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -97,14 +97,9 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
/* to make sure it doesn't hog all of the bandwidth */
#define DEPTH_INTERVAL 5
-static inline void restart_timer(struct uhci_hcd *uhci)
-{
- mod_timer(&uhci->stall_timer, jiffies + msecs_to_jiffies(100));
-}
-
-#include "uhci-hub.c"
#include "uhci-debug.c"
#include "uhci-q.c"
+#include "uhci-hub.c"
/*
* Make sure the controller is completely inactive, unable to
@@ -160,7 +155,6 @@ static void hc_died(struct uhci_hcd *uhci)
{
reset_hc(uhci);
uhci->hc_inaccessible = 1;
- del_timer(&uhci->stall_timer);
}
/*
@@ -287,8 +281,11 @@ __acquires(uhci->lock)
/* Enable resume-detect interrupts if they work.
* Then enter Global Suspend mode, still configured.
*/
- int_enable = (resume_detect_interrupts_are_broken(uhci) ?
- 0 : USBINTR_RESUME);
+ uhci->working_RD = 1;
+ int_enable = USBINTR_RESUME;
+ if (resume_detect_interrupts_are_broken(uhci)) {
+ uhci->working_RD = int_enable = 0;
+ }
outw(int_enable, uhci->io_addr + USBINTR);
outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
mb();
@@ -315,7 +312,6 @@ __acquires(uhci->lock)
uhci->rh_state = new_state;
uhci->is_stopped = UHCI_IS_STOPPED;
- del_timer(&uhci->stall_timer);
uhci_to_hcd(uhci)->poll_rh = !int_enable;
uhci_scan_schedule(uhci, NULL);
@@ -335,7 +331,6 @@ static void start_rh(struct uhci_hcd *uhci)
mb();
uhci->rh_state = UHCI_RH_RUNNING;
uhci_to_hcd(uhci)->poll_rh = 1;
- restart_timer(uhci);
}
static void wakeup_rh(struct uhci_hcd *uhci)
@@ -374,20 +369,6 @@ __acquires(uhci->lock)
mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
}
-static void stall_callback(unsigned long _uhci)
-{
- struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
- unsigned long flags;
-
- spin_lock_irqsave(&uhci->lock, flags);
- uhci_scan_schedule(uhci, NULL);
- check_fsbr(uhci);
-
- if (!uhci->is_stopped)
- restart_timer(uhci);
- spin_unlock_irqrestore(&uhci->lock, flags);
-}
-
static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -418,8 +399,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
"host controller halted, "
"very bad!\n");
hc_died(uhci);
- spin_unlock_irqrestore(&uhci->lock, flags);
- return IRQ_HANDLED;
+
+ /* Force a callback in case there are
+ * pending unlinks */
+ mod_timer(&hcd->rh_timer, jiffies);
}
spin_unlock_irqrestore(&uhci->lock, flags);
}
@@ -427,10 +410,11 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
if (status & USBSTS_RD)
usb_hcd_poll_rh_status(hcd);
-
- spin_lock_irqsave(&uhci->lock, flags);
- uhci_scan_schedule(uhci, regs);
- spin_unlock_irqrestore(&uhci->lock, flags);
+ else {
+ spin_lock_irqsave(&uhci->lock, flags);
+ uhci_scan_schedule(uhci, regs);
+ spin_unlock_irqrestore(&uhci->lock, flags);
+ }
return IRQ_HANDLED;
}
@@ -595,10 +579,6 @@ static int uhci_start(struct usb_hcd *hcd)
init_waitqueue_head(&uhci->waitqh);
- init_timer(&uhci->stall_timer);
- uhci->stall_timer.function = stall_callback;
- uhci->stall_timer.data = (unsigned long) uhci;
-
uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
&dma_handle, 0);
if (!uhci->fl) {
@@ -745,11 +725,11 @@ static void uhci_stop(struct usb_hcd *hcd)
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
spin_lock_irq(&uhci->lock);
- reset_hc(uhci);
+ if (!uhci->hc_inaccessible)
+ reset_hc(uhci);
uhci_scan_schedule(uhci, NULL);
spin_unlock_irq(&uhci->lock);
- del_timer_sync(&uhci->stall_timer);
release_uhci(uhci);
}
@@ -811,13 +791,12 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
*/
pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
uhci->hc_inaccessible = 1;
+ hcd->poll_rh = 0;
/* FIXME: Enable non-PME# remote wakeup? */
done:
spin_unlock_irq(&uhci->lock);
- if (rc == 0)
- del_timer_sync(&hcd->rh_timer);
return rc;
}
@@ -850,8 +829,11 @@ static int uhci_resume(struct usb_hcd *hcd)
spin_unlock_irq(&uhci->lock);
- if (hcd->poll_rh)
+ if (!uhci->working_RD) {
+ /* Suspended root hub needs to be polled */
+ hcd->poll_rh = 1;
usb_hcd_poll_rh_status(hcd);
+ }
return 0;
}
#endif
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index bf9c5f9b508b..282f40b75881 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -345,9 +345,6 @@ enum uhci_rh_state {
/*
* This describes the full uhci information.
- *
- * Note how the "proper" USB information is just
- * a subset of what the full implementation needs.
*/
struct uhci_hcd {
@@ -360,8 +357,6 @@ struct uhci_hcd {
struct dma_pool *qh_pool;
struct dma_pool *td_pool;
- struct usb_bus *bus;
-
struct uhci_td *term_td; /* Terminating TD, see UHCI bug */
struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */
@@ -380,6 +375,8 @@ struct uhci_hcd {
unsigned int scan_in_progress:1; /* Schedule scan is running */
unsigned int need_rescan:1; /* Redo the schedule scan */
unsigned int hc_inaccessible:1; /* HC is suspended or dead */
+ unsigned int working_RD:1; /* Suspended root hub doesn't
+ need to be polled */
/* Support for port suspend/resume/reset */
unsigned long port_c_suspend; /* Bit-arrays of ports */
@@ -405,9 +402,7 @@ struct uhci_hcd {
/* List of URB's awaiting completion callback */
struct list_head complete_list; /* P: uhci->lock */
- int rh_numports;
-
- struct timer_list stall_timer;
+ int rh_numports; /* Number of root-hub ports */
wait_queue_head_t waitqh; /* endpoint_disable waiters */
};
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index 4eace2b19ddb..a71e48a66805 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -145,15 +145,16 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
unsigned long flags;
- int status;
+ int status = 0;
spin_lock_irqsave(&uhci->lock, flags);
- if (uhci->hc_inaccessible) {
- status = 0;
- goto done;
- }
+ uhci_scan_schedule(uhci, NULL);
+ if (uhci->hc_inaccessible)
+ goto done;
+ check_fsbr(uhci);
uhci_check_ports(uhci);
+
status = get_hub_status_data(uhci, buf);
switch (uhci->rh_state) {
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index bbb36cd6ed61..4e0fbe2c1a9a 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -33,7 +33,7 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
{
if (uhci->is_stopped)
- mod_timer(&uhci->stall_timer, jiffies);
+ mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
}
@@ -1164,7 +1164,7 @@ static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb)
static int uhci_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
- struct urb *urb, unsigned mem_flags)
+ struct urb *urb, gfp_t mem_flags)
{
int ret;
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 298e4a25e3d3..1e53934907c0 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
@@ -272,3 +286,23 @@ config USB_KEYSPAN_REMOTE
To compile this driver as a module, choose M here: the module will
be called keyspan_remote.
+
+config USB_APPLETOUCH
+ tristate "Apple USB Touchpad support"
+ depends on USB && INPUT
+ ---help---
+ Say Y here if you want to use an Apple USB Touchpad.
+
+ These are the touchpads that can be found on post-February 2005
+ Apple Powerbooks (prior models have a Synaptics touchpad connected
+ to the ADB bus).
+
+ This driver provides a basic mouse driver but can be interfaced
+ with the synaptics X11 driver to provide acceleration and
+ scrolling in X11.
+
+ For further information, see
+ <file:Documentation/input/appletouch.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called appletouch.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index f1547be632d4..5e03b93f29f6 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -39,4 +39,6 @@ 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
+obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
new file mode 100644
index 000000000000..e03c1c567a14
--- /dev/null
+++ b/drivers/usb/input/appletouch.c
@@ -0,0 +1,469 @@
+/*
+ * Apple USB Touchpad (for post-February 2005 PowerBooks) driver
+ *
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
+ * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
+ *
+ * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <linux/usb_input.h>
+
+/* Apple has powerbooks which have the keyboard with different Product IDs */
+#define APPLE_VENDOR_ID 0x05AC
+
+#define ATP_DEVICE(prod) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ USB_DEVICE_ID_MATCH_INT_CLASS | \
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
+ .idVendor = APPLE_VENDOR_ID, \
+ .idProduct = (prod), \
+ .bInterfaceClass = 0x03, \
+ .bInterfaceProtocol = 0x02
+
+/* table of devices that work with this driver */
+static struct usb_device_id atp_table [] = {
+ { ATP_DEVICE(0x020E) },
+ { ATP_DEVICE(0x020F) },
+ { ATP_DEVICE(0x030A) },
+ { ATP_DEVICE(0x030B) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, atp_table);
+
+/* size of a USB urb transfer */
+#define ATP_DATASIZE 81
+
+/*
+ * number of sensors. Note that only 16 instead of 26 X (horizontal)
+ * sensors exist on 12" and 15" PowerBooks. All models have 16 Y
+ * (vertical) sensors.
+ */
+#define ATP_XSENSORS 26
+#define ATP_YSENSORS 16
+
+/* amount of fuzz this touchpad generates */
+#define ATP_FUZZ 16
+
+/* maximum pressure this driver will report */
+#define ATP_PRESSURE 300
+/*
+ * multiplication factor for the X and Y coordinates.
+ * We try to keep the touchpad aspect ratio while still doing only simple
+ * arithmetics.
+ * The factors below give coordinates like:
+ * 0 <= x < 960 on 12" and 15" Powerbooks
+ * 0 <= x < 1600 on 17" Powerbooks
+ * 0 <= y < 646
+ */
+#define ATP_XFACT 64
+#define ATP_YFACT 43
+
+/*
+ * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
+ * ignored.
+ */
+#define ATP_THRESHOLD 5
+
+/* Structure to hold all of our device specific stuff */
+struct atp {
+ struct usb_device * udev; /* usb device */
+ struct urb * urb; /* usb request block */
+ signed char * data; /* transferred data */
+ int open; /* non-zero if opened */
+ struct input_dev input; /* input dev */
+ int valid; /* are the sensors valid ? */
+ int x_old; /* last reported x/y, */
+ int y_old; /* used for smoothing */
+ /* current value of the sensors */
+ signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
+ /* last value of the sensors */
+ signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
+ /* accumulated sensors */
+ int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
+};
+
+#define dbg_dump(msg, tab) \
+ if (debug > 1) { \
+ int i; \
+ printk("appletouch: %s %lld", msg, (long long)jiffies); \
+ for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
+ printk(" %02x", tab[i]); \
+ printk("\n"); \
+ }
+
+#define dprintk(format, a...) \
+ do { \
+ if (debug) printk(format, ##a); \
+ } while (0)
+
+MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold");
+MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
+MODULE_LICENSE("GPL");
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activate debugging output");
+
+static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
+ int *z, int *fingers)
+{
+ int i;
+ /* values to calculate mean */
+ int pcum = 0, psum = 0;
+
+ *fingers = 0;
+
+ for (i = 0; i < nb_sensors; i++) {
+ if (xy_sensors[i] < ATP_THRESHOLD)
+ continue;
+ if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD))
+ (*fingers)++;
+ pcum += xy_sensors[i] * i;
+ psum += xy_sensors[i];
+ }
+
+ if (psum > 0) {
+ *z = psum;
+ return pcum * fact / psum;
+ }
+
+ return 0;
+}
+
+static inline void atp_report_fingers(struct input_dev *input, int fingers)
+{
+ input_report_key(input, BTN_TOOL_FINGER, fingers == 1);
+ input_report_key(input, BTN_TOOL_DOUBLETAP, fingers == 2);
+ input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
+}
+
+static void atp_complete(struct urb* urb, struct pt_regs* regs)
+{
+ int x, y, x_z, y_z, x_f, y_f;
+ int retval, i;
+ struct atp *dev = urb->context;
+
+ switch (urb->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__, urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
+ goto exit;
+ }
+
+ /* drop incomplete datasets */
+ if (dev->urb->actual_length != ATP_DATASIZE) {
+ dprintk("appletouch: incomplete data package.\n");
+ goto exit;
+ }
+
+ /* reorder the sensors values */
+ for (i = 0; i < 8; i++) {
+ /* X values */
+ dev->xy_cur[i ] = dev->data[5 * i + 2];
+ dev->xy_cur[i + 8] = dev->data[5 * i + 4];
+ dev->xy_cur[i + 16] = dev->data[5 * i + 42];
+ if (i < 2)
+ dev->xy_cur[i + 24] = dev->data[5 * i + 44];
+
+ /* Y values */
+ dev->xy_cur[i + 26] = dev->data[5 * i + 1];
+ dev->xy_cur[i + 34] = dev->data[5 * i + 3];
+ }
+
+ dbg_dump("sample", dev->xy_cur);
+
+ if (!dev->valid) {
+ /* first sample */
+ dev->valid = 1;
+ dev->x_old = dev->y_old = -1;
+ memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
+
+ /* 17" Powerbooks have 10 extra X sensors */
+ for (i = 16; i < ATP_XSENSORS; i++)
+ if (dev->xy_cur[i]) {
+ printk("appletouch: 17\" model detected.\n");
+ input_set_abs_params(&dev->input, ABS_X, 0,
+ (ATP_XSENSORS - 1) *
+ ATP_XFACT - 1,
+ ATP_FUZZ, 0);
+ break;
+ }
+
+ goto exit;
+ }
+
+ for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
+ /* accumulate the change */
+ signed char change = dev->xy_old[i] - dev->xy_cur[i];
+ dev->xy_acc[i] -= change;
+
+ /* prevent down drifting */
+ if (dev->xy_acc[i] < 0)
+ dev->xy_acc[i] = 0;
+ }
+
+ memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
+
+ dbg_dump("accumulator", dev->xy_acc);
+
+ x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
+ ATP_XFACT, &x_z, &x_f);
+ y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
+ ATP_YFACT, &y_z, &y_f);
+
+ if (x && y) {
+ if (dev->x_old != -1) {
+ x = (dev->x_old * 3 + x) >> 2;
+ y = (dev->y_old * 3 + y) >> 2;
+ dev->x_old = x;
+ dev->y_old = y;
+
+ if (debug > 1)
+ printk("appletouch: X: %3d Y: %3d "
+ "Xz: %3d Yz: %3d\n",
+ x, y, x_z, y_z);
+
+ input_report_key(&dev->input, BTN_TOUCH, 1);
+ input_report_abs(&dev->input, ABS_X, x);
+ input_report_abs(&dev->input, ABS_Y, y);
+ input_report_abs(&dev->input, ABS_PRESSURE,
+ min(ATP_PRESSURE, x_z + y_z));
+ atp_report_fingers(&dev->input, max(x_f, y_f));
+ }
+ dev->x_old = x;
+ dev->y_old = y;
+ }
+ else if (!x && !y) {
+
+ dev->x_old = dev->y_old = -1;
+ input_report_key(&dev->input, BTN_TOUCH, 0);
+ input_report_abs(&dev->input, ABS_PRESSURE, 0);
+ atp_report_fingers(&dev->input, 0);
+
+ /* reset the accumulator on release */
+ memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
+ }
+
+ input_report_key(&dev->input, BTN_LEFT, !!dev->data[80]);
+
+ input_sync(&dev->input);
+
+exit:
+ retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
+ if (retval) {
+ err("%s - usb_submit_urb failed with result %d",
+ __FUNCTION__, retval);
+ }
+}
+
+static int atp_open(struct input_dev *input)
+{
+ struct atp *dev = input->private;
+
+ if (usb_submit_urb(dev->urb, GFP_ATOMIC))
+ return -EIO;
+
+ dev->open = 1;
+ return 0;
+}
+
+static void atp_close(struct input_dev *input)
+{
+ struct atp *dev = input->private;
+
+ usb_kill_urb(dev->urb);
+ dev->open = 0;
+}
+
+static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
+{
+ struct atp *dev = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int int_in_endpointAddr = 0;
+ int i, retval = -ENOMEM;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
+ if (dev == NULL) {
+ err("Out of memory");
+ goto err_kmalloc;
+ }
+ memset(dev, 0, sizeof(struct atp));
+
+ dev->udev = interface_to_usbdev(iface);
+
+ /* set up the endpoint information */
+ /* use only the first interrupt-in endpoint */
+ iface_desc = iface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i].desc;
+ if (!int_in_endpointAddr &&
+ (endpoint->bEndpointAddress & USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT)) {
+ /* we found an interrupt in endpoint */
+ int_in_endpointAddr = endpoint->bEndpointAddress;
+ break;
+ }
+ }
+ if (!int_in_endpointAddr) {
+ retval = -EIO;
+ err("Could not find int-in endpoint");
+ goto err_endpoint;
+ }
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(iface, dev);
+
+ dev->urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->urb) {
+ retval = -ENOMEM;
+ goto err_usballoc;
+ }
+ dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
+ &dev->urb->transfer_dma);
+ if (!dev->data) {
+ retval = -ENOMEM;
+ goto err_usbbufalloc;
+ }
+ usb_fill_int_urb(dev->urb, dev->udev,
+ usb_rcvintpipe(dev->udev, int_in_endpointAddr),
+ dev->data, ATP_DATASIZE, atp_complete, dev, 1);
+
+ init_input_dev(&dev->input);
+ dev->input.name = "appletouch";
+ dev->input.dev = &iface->dev;
+ dev->input.private = dev;
+ dev->input.open = atp_open;
+ dev->input.close = atp_close;
+
+ usb_to_input_id(dev->udev, &dev->input.id);
+
+ set_bit(EV_ABS, dev->input.evbit);
+
+ /*
+ * 12" and 15" Powerbooks only have 16 x sensors,
+ * 17" models are detected later.
+ */
+ input_set_abs_params(&dev->input, ABS_X, 0,
+ (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
+ input_set_abs_params(&dev->input, ABS_Y, 0,
+ (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
+ input_set_abs_params(&dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
+
+ set_bit(EV_KEY, dev->input.evbit);
+ set_bit(BTN_TOUCH, dev->input.keybit);
+ set_bit(BTN_TOOL_FINGER, dev->input.keybit);
+ set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit);
+ set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit);
+ set_bit(BTN_LEFT, dev->input.keybit);
+
+ input_register_device(&dev->input);
+
+ printk(KERN_INFO "input: appletouch connected\n");
+
+ return 0;
+
+err_usbbufalloc:
+ usb_free_urb(dev->urb);
+err_usballoc:
+ usb_set_intfdata(iface, NULL);
+err_endpoint:
+ kfree(dev);
+err_kmalloc:
+ return retval;
+}
+
+static void atp_disconnect(struct usb_interface *iface)
+{
+ struct atp *dev = usb_get_intfdata(iface);
+
+ usb_set_intfdata(iface, NULL);
+ if (dev) {
+ usb_kill_urb(dev->urb);
+ input_unregister_device(&dev->input);
+ usb_free_urb(dev->urb);
+ usb_buffer_free(dev->udev, ATP_DATASIZE,
+ dev->data, dev->urb->transfer_dma);
+ kfree(dev);
+ }
+ printk(KERN_INFO "input: appletouch disconnected\n");
+}
+
+static int atp_suspend(struct usb_interface *iface, pm_message_t message)
+{
+ struct atp *dev = usb_get_intfdata(iface);
+ usb_kill_urb(dev->urb);
+ dev->valid = 0;
+ return 0;
+}
+
+static int atp_resume(struct usb_interface *iface)
+{
+ struct atp *dev = usb_get_intfdata(iface);
+ if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
+ return -EIO;
+
+ return 0;
+}
+
+static struct usb_driver atp_driver = {
+ .owner = THIS_MODULE,
+ .name = "appletouch",
+ .probe = atp_probe,
+ .disconnect = atp_disconnect,
+ .suspend = atp_suspend,
+ .resume = atp_resume,
+ .id_table = atp_table,
+};
+
+static int __init atp_init(void)
+{
+ return usb_register(&atp_driver);
+}
+
+static void __exit atp_exit(void)
+{
+ usb_deregister(&atp_driver);
+}
+
+module_init(atp_init);
+module_exit(atp_exit);
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index b2cb2b35892e..41f92b924761 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -2,7 +2,8 @@
* USB HID support for Linux
*
* Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
*/
/*
@@ -38,7 +39,7 @@
* Version Information
*/
-#define DRIVER_VERSION "v2.01"
+#define DRIVER_VERSION "v2.6"
#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik"
#define DRIVER_DESC "USB HID core driver"
#define DRIVER_LICENSE "GPL"
@@ -1058,8 +1059,8 @@ static int hid_submit_ctrl(struct hid_device *hid)
if (maxpacket > 0) {
padlen = (len + maxpacket - 1) / maxpacket;
padlen *= maxpacket;
- if (padlen > HID_BUFFER_SIZE)
- padlen = HID_BUFFER_SIZE;
+ if (padlen > hid->bufsize)
+ padlen = hid->bufsize;
} else
padlen = 0;
hid->urbctrl->transfer_buffer_length = padlen;
@@ -1096,6 +1097,7 @@ static void hid_irq_out(struct urb *urb, struct pt_regs *regs)
switch (urb->status) {
case 0: /* success */
+ break;
case -ESHUTDOWN: /* unplug */
case -EILSEQ: /* unplug timeout on uhci */
unplug = 1;
@@ -1143,6 +1145,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs)
case 0: /* success */
if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
+ break;
case -ESHUTDOWN: /* unplug */
case -EILSEQ: /* unplug timectrl on uhci */
unplug = 1;
@@ -1284,13 +1287,8 @@ void hid_init_reports(struct hid_device *hid)
struct hid_report *report;
int err, ret;
- list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) {
- int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered;
- if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE;
- if (size > hid->urbin->transfer_buffer_length)
- hid->urbin->transfer_buffer_length = size;
+ list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
hid_submit_report(hid, report, USB_DIR_IN);
- }
list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
hid_submit_report(hid, report, USB_DIR_IN);
@@ -1372,12 +1370,14 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_A4TECH 0x09da
#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
-#define USB_VENDOR_ID_AASHIMA 0x06D6
+#define USB_VENDOR_ID_AASHIMA 0x06d6
#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
+#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026
#define USB_VENDOR_ID_CYPRESS 0x04b4
#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
+#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
@@ -1432,7 +1432,7 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
#define USB_VENDOR_ID_LD 0x0f11
-#define USB_DEVICE_ID_CASSY 0x1000
+#define USB_DEVICE_ID_CASSY 0x1000
#define USB_DEVICE_ID_POCKETCASSY 0x1010
#define USB_DEVICE_ID_MOBILECASSY 0x1020
#define USB_DEVICE_ID_JWM 0x1080
@@ -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_POWERMOUSE 0x0304
/*
* Alphabetically sorted blacklist by quirk type.
@@ -1468,6 +1470,7 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
@@ -1548,10 +1551,12 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE },
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -1564,15 +1569,32 @@ static struct hid_blacklist {
{ 0, 0 }
};
+/*
+ * Traverse the supplied list of reports and find the longest
+ */
+static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max)
+{
+ struct hid_report *report;
+ int size;
+
+ list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
+ size = ((report->size - 1) >> 3) + 1;
+ if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered)
+ size++;
+ if (*max < size)
+ *max = size;
+ }
+}
+
static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
{
- if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma)))
+ if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
return -1;
- if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma)))
+ if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
return -1;
if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
return -1;
- if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
+ if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
return -1;
return 0;
@@ -1581,13 +1603,13 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
if (hid->inbuf)
- usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma);
+ usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma);
if (hid->outbuf)
- usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma);
+ usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma);
if (hid->cr)
usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma);
if (hid->ctrlbuf)
- usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma);
+ usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
}
static struct hid_device *usb_hid_configure(struct usb_interface *intf)
@@ -1598,7 +1620,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
struct hid_device *hid;
unsigned quirks = 0, rsize = 0;
char *buf, *rdesc;
- int n;
+ int n, insize = 0;
for (n = 0; hid_blacklist[n].idVendor; n++)
if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
@@ -1652,6 +1674,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
kfree(rdesc);
hid->quirks = quirks;
+ hid->bufsize = HID_MIN_BUFFER_SIZE;
+ hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize);
+ hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize);
+ hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize);
+
+ if (hid->bufsize > HID_MAX_BUFFER_SIZE)
+ hid->bufsize = HID_MAX_BUFFER_SIZE;
+
+ hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
+
+ if (insize > HID_MAX_BUFFER_SIZE)
+ insize = HID_MAX_BUFFER_SIZE;
+
if (hid_alloc_buffers(dev, hid)) {
hid_free_buffers(dev, hid);
goto fail;
@@ -1667,10 +1702,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */
continue;
- /* handle potential highspeed HID correctly */
interval = endpoint->bInterval;
- if (dev->speed == USB_SPEED_HIGH)
- interval = 1 << (interval - 1);
/* Change the polling interval of mice. */
if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
@@ -1682,10 +1714,10 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
+ usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize,
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 +1727,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 +1779,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/hid-debug.h b/drivers/usb/input/hid-debug.h
index 52437e5e2e78..ceebab99eff2 100644
--- a/drivers/usb/input/hid-debug.h
+++ b/drivers/usb/input/hid-debug.h
@@ -85,6 +85,23 @@ static const struct hid_usage_entry hid_usage_table[] = {
{0, 0x91, "D-PadDown"},
{0, 0x92, "D-PadRight"},
{0, 0x93, "D-PadLeft"},
+ { 2, 0, "Simulation" },
+ {0, 0xb0, "Aileron"},
+ {0, 0xb1, "AileronTrim"},
+ {0, 0xb2, "Anti-Torque"},
+ {0, 0xb3, "Autopilot"},
+ {0, 0xb4, "Chaff"},
+ {0, 0xb5, "Collective"},
+ {0, 0xb6, "DiveBrake"},
+ {0, 0xb7, "ElectronicCountermeasures"},
+ {0, 0xb8, "Elevator"},
+ {0, 0xb9, "ElevatorTrim"},
+ {0, 0xba, "Rudder"},
+ {0, 0xbb, "Throttle"},
+ {0, 0xbc, "FlightCommunications"},
+ {0, 0xbd, "FlareRelease"},
+ {0, 0xbe, "LandingGear"},
+ {0, 0xbf, "ToeBrake"},
{ 7, 0, "Keyboard" },
{ 8, 0, "LED" },
{0, 0x01, "NumLock"},
@@ -92,6 +109,7 @@ static const struct hid_usage_entry hid_usage_table[] = {
{0, 0x03, "ScrollLock"},
{0, 0x04, "Compose"},
{0, 0x05, "Kana"},
+ {0, 0x4b, "GenericIndicator"},
{ 9, 0, "Button" },
{ 10, 0, "Ordinal" },
{ 12, 0, "Consumer" },
@@ -574,7 +592,8 @@ static char *keys[KEY_MAX + 1] = {
[KEY_EXIT] = "Exit", [KEY_MOVE] = "Move",
[KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp",
[KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis",
- [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_F13] = "F13",
+ [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New",
+ [KEY_REDO] = "Redo", [KEY_F13] = "F13",
[KEY_F14] = "F14", [KEY_F15] = "F15",
[KEY_F16] = "F16", [KEY_F17] = "F17",
[KEY_F18] = "F18", [KEY_F19] = "F19",
@@ -584,15 +603,15 @@ static char *keys[KEY_MAX + 1] = {
[KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3",
[KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend",
[KEY_CLOSE] = "Close", [KEY_PLAY] = "Play",
- [KEY_FASTFORWARD] = "Fast Forward", [KEY_BASSBOOST] = "Bass Boost",
+ [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost",
[KEY_PRINT] = "Print", [KEY_HP] = "HP",
[KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound",
[KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email",
[KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search",
[KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance",
[KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop",
- [KEY_ALTERASE] = "Alternate Erase", [KEY_CANCEL] = "Cancel",
- [KEY_BRIGHTNESSDOWN] = "Brightness down", [KEY_BRIGHTNESSUP] = "Brightness up",
+ [KEY_ALTERASE] = "AlternateErase", [KEY_CANCEL] = "Cancel",
+ [KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp",
[KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown",
[BTN_0] = "Btn0", [BTN_1] = "Btn1",
[BTN_2] = "Btn2", [BTN_3] = "Btn3",
@@ -622,8 +641,8 @@ static char *keys[KEY_MAX + 1] = {
[BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger",
[BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens",
[BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus",
- [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "Tool Doubletap",
- [BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_GEAR_DOWN] = "WheelBtn",
+ [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
+ [BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn",
[BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok",
[KEY_SELECT] = "Select", [KEY_GOTO] = "Goto",
[KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2",
@@ -659,6 +678,9 @@ static char *keys[KEY_MAX + 1] = {
[KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL",
[KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine",
[KEY_DEL_LINE] = "DeleteLine",
+ [KEY_SEND] = "Send", [KEY_REPLY] = "Reply",
+ [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save",
+ [KEY_DOCUMENTS] = "Documents",
};
static char *relatives[REL_MAX + 1] = {
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 63a4db721f7e..0b6452248a39 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -78,8 +78,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
{
struct input_dev *input = &hidinput->input;
struct hid_device *device = hidinput->input.private;
- int max, code;
- unsigned long *bit;
+ int max = 0, code;
+ unsigned long *bit = NULL;
field->hidinput = hidinput;
@@ -131,6 +131,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
map_key(code);
break;
+
+ case HID_UP_SIMULATION:
+
+ switch (usage->hid & 0xffff) {
+ case 0xba: map_abs(ABS_RUDDER); break;
+ case 0xbb: map_abs(ABS_THROTTLE); break;
+ }
+ break;
+
case HID_UP_GENDESK:
if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */
@@ -238,8 +247,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x000: goto ignore;
case 0x034: map_key_clear(KEY_SLEEP); break;
case 0x036: map_key_clear(BTN_MISC); break;
+ case 0x045: map_key_clear(KEY_RADIO); break;
case 0x08a: map_key_clear(KEY_WWW); break;
+ case 0x08d: map_key_clear(KEY_PROGRAM); break;
case 0x095: map_key_clear(KEY_HELP); break;
+ case 0x09c: map_key_clear(KEY_CHANNELUP); break;
+ case 0x09d: map_key_clear(KEY_CHANNELDOWN); break;
case 0x0b0: map_key_clear(KEY_PLAY); break;
case 0x0b1: map_key_clear(KEY_PAUSE); break;
case 0x0b2: map_key_clear(KEY_RECORD); break;
@@ -259,6 +272,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x18a: map_key_clear(KEY_MAIL); break;
case 0x192: map_key_clear(KEY_CALC); break;
case 0x194: map_key_clear(KEY_FILE); break;
+ case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
+ case 0x201: map_key_clear(KEY_NEW); break;
+ case 0x207: map_key_clear(KEY_SAVE); break;
+ case 0x208: map_key_clear(KEY_PRINT); break;
+ case 0x209: map_key_clear(KEY_PROPS); break;
case 0x21a: map_key_clear(KEY_UNDO); break;
case 0x21b: map_key_clear(KEY_COPY); break;
case 0x21c: map_key_clear(KEY_CUT); break;
@@ -271,7 +289,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x227: map_key_clear(KEY_REFRESH); break;
case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
case 0x238: map_rel(REL_HWHEEL); break;
- default: goto unknown;
+ case 0x279: map_key_clear(KEY_REDO); break;
+ case 0x289: map_key_clear(KEY_REPLY); break;
+ case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
+ case 0x28c: map_key_clear(KEY_SEND); break;
+ default: goto ignore;
}
break;
@@ -296,9 +318,42 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
break;
case HID_UP_MSVENDOR:
-
goto ignore;
+ case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
+
+ set_bit(EV_REP, input->evbit);
+ switch(usage->hid & HID_USAGE) {
+ case 0x003: map_key_clear(KEY_FN); break;
+ default: goto ignore;
+ }
+ break;
+
+ case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */
+
+ set_bit(EV_REP, input->evbit);
+ switch(usage->hid & HID_USAGE) {
+ case 0x004: map_key_clear(KEY_AGAIN); break;
+ case 0x00d: map_key_clear(KEY_HOME); break;
+ case 0x024: map_key_clear(KEY_SHUFFLE); break;
+ case 0x025: map_key_clear(KEY_TV); break;
+ case 0x026: map_key_clear(KEY_MENU); break;
+ case 0x031: map_key_clear(KEY_AUDIO); break;
+ case 0x032: map_key_clear(KEY_SUBTITLE); break;
+ case 0x033: map_key_clear(KEY_LAST); break;
+ case 0x047: map_key_clear(KEY_MP3); break;
+ case 0x048: map_key_clear(KEY_DVD); break;
+ case 0x049: map_key_clear(KEY_MEDIA); break;
+ case 0x04a: map_key_clear(KEY_VIDEO); break;
+ case 0x04b: map_key_clear(KEY_ANGLE); break;
+ case 0x04c: map_key_clear(KEY_LANGUAGE); break;
+ case 0x04d: map_key_clear(KEY_SUBTITLE); break;
+ case 0x051: map_key_clear(KEY_RED); break;
+ case 0x052: map_key_clear(KEY_CLOSE); break;
+ default: goto ignore;
+ }
+ break;
+
case HID_UP_PID:
set_bit(EV_FF, input->evbit);
@@ -349,6 +404,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
if (usage->code > max)
goto ignore;
+ if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032)))
+ map_rel(REL_HWHEEL);
+
if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
(usage->type == EV_REL) && (usage->code == REL_WHEEL))
set_bit(REL_HWHEEL, bit);
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index c1b6b69bc4a4..ec2412c42f1e 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -173,6 +173,7 @@ struct hid_item {
#define HID_UP_UNDEFINED 0x00000000
#define HID_UP_GENDESK 0x00010000
+#define HID_UP_SIMULATION 0x00020000
#define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000
#define HID_UP_BUTTON 0x00090000
@@ -182,6 +183,8 @@ struct hid_item {
#define HID_UP_PID 0x000f0000
#define HID_UP_HPVENDOR 0xff7f0000
#define HID_UP_MSVENDOR 0xff000000
+#define HID_UP_CUSTOM 0x00ff0000
+#define HID_UP_LOGIVENDOR 0xffbc0000
#define HID_USAGE 0x0000ffff
@@ -242,6 +245,7 @@ struct hid_item {
#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080
#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
+#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400
/*
* This is the global environment of the parser. This information is
@@ -348,7 +352,8 @@ struct hid_report_enum {
#define HID_REPORT_TYPES 3
-#define HID_BUFFER_SIZE 64 /* use 64 for compatibility with all possible packetlen */
+#define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
+#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
#define HID_OUTPUT_FIFO_SIZE 64
@@ -386,6 +391,8 @@ struct hid_device { /* device report descriptor */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
+ unsigned int bufsize; /* URB buffer size */
+
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 4c13331b5f41..d32427818af7 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -507,6 +507,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return -EINVAL;
hid_submit_report(hid, report, USB_DIR_OUT);
+ hid_wait_io(hid);
return 0;
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 67dc93685203..99de1b33c07d 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -431,11 +431,6 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
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 000000000000..52ff27f15127
--- /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 000000000000..58a176ef96a5
--- /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 000000000000..48af0be9cbdf
--- /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/media/stv680.c b/drivers/usb/media/stv680.c
index 7398a7f19c1e..0fd0fa9fec21 100644
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -260,7 +260,7 @@ static int stv_stop_video (struct usb_stv *dev)
PDEBUG (0, "STV(i): Camera set to original resolution");
}
/* origMode */
- kfree (buf);
+ kfree(buf);
return i;
}
@@ -276,7 +276,7 @@ static int stv_set_video_mode (struct usb_stv *dev)
}
if ((i = stv_set_config (dev, 1, 0, 0)) < 0) {
- kfree (buf);
+ kfree(buf);
return i;
}
@@ -301,13 +301,13 @@ static int stv_set_video_mode (struct usb_stv *dev)
goto exit;
error:
- kfree (buf);
+ kfree(buf);
if (stop_video == 1)
stv_stop_video (dev);
return -1;
exit:
- kfree (buf);
+ kfree(buf);
return 0;
}
@@ -327,7 +327,7 @@ static int stv_init (struct usb_stv *stv680)
/* set config 1, interface 0, alternate 0 */
if ((i = stv_set_config (stv680, 1, 0, 0)) < 0) {
- kfree (buffer);
+ kfree(buffer);
PDEBUG (0, "STV(e): set config 1,0,0 failed");
return -1;
}
@@ -435,11 +435,11 @@ static int stv_init (struct usb_stv *stv680)
error:
i = stv_sndctrl (0, stv680, 0x80, 0, buffer, 0x02); /* Get Last Error */
PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buffer[0], buffer[1]);
- kfree (buffer);
+ kfree(buffer);
return -1;
exit:
- kfree (buffer);
+ kfree(buffer);
/* video = 320x240, 352x288 */
if (stv680->CIF == 1) {
@@ -708,10 +708,10 @@ static int stv680_stop_stream (struct usb_stv *stv680)
usb_kill_urb (stv680->urb[i]);
usb_free_urb (stv680->urb[i]);
stv680->urb[i] = NULL;
- kfree (stv680->sbuf[i].data);
+ kfree(stv680->sbuf[i].data);
}
for (i = 0; i < STV680_NUMSCRATCH; i++) {
- kfree (stv680->scratch[i].data);
+ kfree(stv680->scratch[i].data);
stv680->scratch[i].data = NULL;
}
@@ -1068,7 +1068,7 @@ static int stv_close (struct inode *inode, struct file *file)
stv680->user = 0;
if (stv680->removed) {
- kfree (stv680);
+ kfree(stv680);
stv680 = NULL;
PDEBUG (0, "STV(i): device unregistered");
}
@@ -1445,14 +1445,14 @@ static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680)
usb_kill_urb (stv680->urb[i]);
usb_free_urb (stv680->urb[i]);
stv680->urb[i] = NULL;
- kfree (stv680->sbuf[i].data);
+ kfree(stv680->sbuf[i].data);
}
for (i = 0; i < STV680_NUMSCRATCH; i++)
- kfree (stv680->scratch[i].data);
+ kfree(stv680->scratch[i].data);
PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name);
/* Free the memory */
- kfree (stv680);
+ kfree(stv680);
}
static void stv680_disconnect (struct usb_interface *intf)
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 4a5857c53f11..0bc0b1247a6b 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -1148,7 +1148,7 @@ vicam_write_proc_gain(struct file *file, const char *buffer,
static void
vicam_create_proc_root(void)
{
- vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0);
+ vicam_proc_root = proc_mkdir("video/vicam", NULL);
if (vicam_proc_root)
vicam_proc_root->owner = THIS_MODULE;
@@ -1181,7 +1181,7 @@ vicam_create_proc_entry(struct vicam_camera *cam)
sprintf(name, "video%d", cam->vdev.minor);
- cam->proc_dir = create_proc_entry(name, S_IFDIR, vicam_proc_root);
+ cam->proc_dir = proc_mkdir(name, vicam_proc_root);
if ( !cam->proc_dir )
return; // FIXME: We should probably return an error here
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 6f7994f5a714..ae4681f9f0ea 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -426,7 +426,7 @@ static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb)
/* 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 ad17892aac9e..7e93ac96490f 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -464,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
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/Kconfig b/drivers/usb/misc/sisusbvga/Kconfig
index 3957e144caf7..7603cbe0865d 100644
--- a/drivers/usb/misc/sisusbvga/Kconfig
+++ b/drivers/usb/misc/sisusbvga/Kconfig
@@ -4,11 +4,43 @@ config USB_SISUSBVGA
depends on USB && USB_EHCI_HCD
---help---
Say Y here if you intend to attach a USB2VGA dongle based on a
- Net2280 and a SiS315 chip.
-
- Note that this device requires a USB 2.0 host controller. It will not
+ Net2280 and a SiS315 chip.
+
+ Note that this device requires a USB 2.0 host controller. It will not
work with USB 1.x controllers.
- To compile this driver as a module, choose M here: the module will be
- called sisusb. If unsure, say N.
+ To compile this driver as a module, choose M here; the module will be
+ called sisusbvga. If unsure, say N.
+
+config USB_SISUSBVGA_CON
+ bool "Text console and mode switching support" if USB_SISUSBVGA
+ depends on VT
+ select FONT_8x16
+ ---help---
+ Say Y here if you want a VGA text console via the USB dongle or
+ want to support userland applications that utilize the driver's
+ display mode switching capabilities.
+
+ Note that this console supports VGA/EGA text mode only.
+
+ By default, the console part of the driver will not kick in when
+ the driver is initialized. If you want the driver to take over
+ one or more of the consoles, you need to specify the number of
+ the first and last consoles (starting at 1) as driver parameters.
+
+ For example, if the driver is compiled as a module:
+
+ modprobe sisusbvga first=1 last=5
+
+ If you use hotplug, add this to your modutils config files with
+ the "options" keyword, such as eg.
+
+ options sisusbvga first=1 last=5
+
+ If the driver is compiled into the kernel image, the parameters
+ must be given in the kernel command like, such as
+
+ sisusbvga.first=1 sisusbvga.last=5
+
+
diff --git a/drivers/usb/misc/sisusbvga/Makefile b/drivers/usb/misc/sisusbvga/Makefile
index 76f1643ceaf8..7f934cfc906c 100644
--- a/drivers/usb/misc/sisusbvga/Makefile
+++ b/drivers/usb/misc/sisusbvga/Makefile
@@ -2,5 +2,7 @@
# Makefile for the sisusb driver (if driver is inside kernel tree).
#
-obj-$(CONFIG_USB_SISUSBVGA) += sisusb.o
+obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga.o
+
+sisusbvga-objs := sisusb.o sisusb_init.o sisusb_con.o
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 2fd12264fd53..39db3155723a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -1,6 +1,8 @@
/*
* sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
*
+ * Main part
+ *
* Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, this code is licensed under the
@@ -48,16 +50,60 @@
#include <linux/kref.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
+#include <linux/vmalloc.h>
#include "sisusb.h"
+#ifdef INCL_SISUSB_CON
+#include <linux/font.h>
+#endif
+
#define SISUSB_DONTSYNC
/* Forward declarations / clean-up routines */
+#ifdef INCL_SISUSB_CON
+int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data);
+int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data);
+int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data);
+int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data);
+int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand, u8 myor);
+int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor);
+int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand);
+
+int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
+int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
+int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data);
+int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data);
+int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
+ u32 dest, int length, size_t *bytes_written);
+
+int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
+
+extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+extern int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
+
+extern void sisusb_init_concode(void);
+extern int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last);
+extern void sisusb_console_exit(struct sisusb_usb_data *sisusb);
+
+extern void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location);
+
+extern int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
+ u8 *arg, int cmapsz, int ch512, int dorecalc,
+ struct vc_data *c, int fh, int uplock);
+
+static int sisusb_first_vc = 0;
+static int sisusb_last_vc = 0;
+module_param_named(first, sisusb_first_vc, int, 0);
+module_param_named(last, sisusb_last_vc, int, 0);
+MODULE_PARM_DESC(first, "Number of first console to take over (1 - MAX_NR_CONSOLES)");
+MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES)");
+#endif
+
static struct usb_driver sisusb_driver;
-static DECLARE_MUTEX(disconnect_sem);
+DECLARE_MUTEX(disconnect_sem);
static void
sisusb_free_buffers(struct sisusb_usb_data *sisusb)
@@ -229,7 +275,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 +341,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))
@@ -639,7 +685,10 @@ static int sisusb_send_bridge_packet(struct sisusb_usb_data *sisusb, int len,
/* The following routines assume being used to transfer byte, word,
* long etc.
- * This means that they assume "data" in machine endianness format.
+ * This means that
+ * - the write routines expect "data" in machine endianness format.
+ * The data will be converted to leXX in sisusb_xxx_packet.
+ * - the read routines can expect read data in machine-endianess.
*/
static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type,
@@ -839,7 +888,7 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
if (get_user(swap16, (u16 __user *)userbuffer))
return -EFAULT;
} else
- swap16 = (kernbuffer[0] << 8) | kernbuffer[1];
+ swap16 = *((u16 *)kernbuffer);
ret = sisusb_write_memio_word(sisusb,
SISUSB_TYPE_MEM,
@@ -855,14 +904,25 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
if (userbuffer) {
if (copy_from_user(&buf, userbuffer, 3))
return -EFAULT;
-
+#ifdef __BIG_ENDIAN
swap32 = (buf[0] << 16) |
(buf[1] << 8) |
buf[2];
+#else
+ swap32 = (buf[2] << 16) |
+ (buf[1] << 8) |
+ buf[0];
+#endif
} else
+#ifdef __BIG_ENDIAN
swap32 = (kernbuffer[0] << 16) |
(kernbuffer[1] << 8) |
kernbuffer[2];
+#else
+ swap32 = (kernbuffer[2] << 16) |
+ (kernbuffer[1] << 8) |
+ kernbuffer[0];
+#endif
ret = sisusb_write_memio_24bit(sisusb,
SISUSB_TYPE_MEM,
@@ -879,10 +939,7 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
if (get_user(swap32, (u32 __user *)userbuffer))
return -EFAULT;
} else
- swap32 = (kernbuffer[0] << 24) |
- (kernbuffer[1] << 16) |
- (kernbuffer[2] << 8) |
- kernbuffer[3];
+ swap32 = *((u32 *)kernbuffer);
ret = sisusb_write_memio_long(sisusb,
SISUSB_TYPE_MEM,
@@ -1005,6 +1062,10 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
return ret ? -EIO : 0;
}
+/* Remember: Read data in packet is in machine-endianess! So for
+ * byte, word, 24bit, long no endian correction is necessary.
+ */
+
static int sisusb_read_memio_byte(struct sisusb_usb_data *sisusb, int type,
u32 addr, u8 *data)
{
@@ -1191,8 +1252,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
(u16 __user *)userbuffer))
return -EFAULT;
} else {
- kernbuffer[0] = swap16 >> 8;
- kernbuffer[1] = swap16 & 0xff;
+ *((u16 *)kernbuffer) = swap16;
}
}
return ret;
@@ -1202,9 +1262,15 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
addr, &swap32);
if (!ret) {
(*bytes_read) += 3;
+#ifdef __BIG_ENDIAN
buf[0] = (swap32 >> 16) & 0xff;
buf[1] = (swap32 >> 8) & 0xff;
buf[2] = swap32 & 0xff;
+#else
+ buf[2] = (swap32 >> 16) & 0xff;
+ buf[1] = (swap32 >> 8) & 0xff;
+ buf[0] = swap32 & 0xff;
+#endif
if (userbuffer) {
if (copy_to_user(userbuffer, &buf[0], 3))
return -EFAULT;
@@ -1228,10 +1294,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
userbuffer += 4;
} else {
- kernbuffer[0] = (swap32 >> 24) & 0xff;
- kernbuffer[1] = (swap32 >> 16) & 0xff;
- kernbuffer[2] = (swap32 >> 8) & 0xff;
- kernbuffer[3] = swap32 & 0xff;
+ *((u32 *)kernbuffer) = swap32;
kernbuffer += 4;
}
addr += 4;
@@ -1289,7 +1352,24 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
/* High level: Gfx (indexed) register access */
-static int
+#ifdef INCL_SISUSB_CON
+int
+sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data)
+{
+ return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
+}
+
+int
+sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data)
+{
+ return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
+}
+#endif
+
+#ifndef INCL_SISUSB_CON
+static
+#endif
+int
sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
{
int ret;
@@ -1298,7 +1378,10 @@ sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
return ret;
}
-static int
+#ifndef INCL_SISUSB_CON
+static
+#endif
+int
sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
{
int ret;
@@ -1307,7 +1390,10 @@ sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
return ret;
}
-static int
+#ifndef INCL_SISUSB_CON
+static
+#endif
+int
sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
u8 myand, u8 myor)
{
@@ -1336,18 +1422,89 @@ sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx,
return ret;
}
-static int
+#ifndef INCL_SISUSB_CON
+static
+#endif
+int
sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor)
{
return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor));
}
-static int
+#ifndef INCL_SISUSB_CON
+static
+#endif
+int
sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand)
{
return(sisusb_setidxregandor(sisusb, port, idx, myand, 0x00));
}
+/* Write/read video ram */
+
+#ifdef INCL_SISUSB_CON
+int
+sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data)
+{
+ return(sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data));
+}
+
+int
+sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data)
+{
+ return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data));
+}
+
+int
+sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data)
+{
+ return(sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data));
+}
+
+int
+sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data)
+{
+ return(sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data));
+}
+
+int
+sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
+ u32 dest, int length, size_t *bytes_written)
+{
+ return(sisusb_write_mem_bulk(sisusb, dest, src, length, NULL, 0, bytes_written));
+}
+
+#ifdef SISUSBENDIANTEST
+int
+sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest,
+ u32 src, int length, size_t *bytes_written)
+{
+ return(sisusb_read_mem_bulk(sisusb, src, dest, length, NULL, bytes_written));
+}
+#endif
+#endif
+
+#ifdef SISUSBENDIANTEST
+static void
+sisusb_testreadwrite(struct sisusb_usb_data *sisusb)
+{
+ static char srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+ char destbuffer[10];
+ size_t dummy;
+ int i,j;
+
+ sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy);
+
+ for(i = 1; i <= 7; i++) {
+ printk(KERN_DEBUG "sisusb: rwtest %d bytes\n", i);
+ sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i, &dummy);
+ for(j = 0; j < i; j++) {
+ printk(KERN_DEBUG "sisusb: rwtest read[%d] = %x\n", j, destbuffer[j]);
+ }
+ }
+}
+#endif
+
/* access pci config registers (reg numbers 0, 4, 8, etc) */
static int
@@ -2270,6 +2427,129 @@ sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen)
return ret;
}
+
+#ifdef INCL_SISUSB_CON
+
+/* Set up default text mode:
+ - Set text mode (0x03)
+ - Upload default font
+ - Upload user font (if available)
+*/
+
+int
+sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
+{
+ int ret = 0, slot = sisusb->font_slot, i;
+ struct font_desc *myfont;
+ u8 *tempbuf;
+ u16 *tempbufb;
+ size_t written;
+ static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
+ static char bootlogo[] = "(o_ //\\ V_/_";
+
+ /* sisusb->lock is down */
+
+ if (!sisusb->SiS_Pr)
+ return 1;
+
+ sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
+ sisusb->SiS_Pr->sisusb = (void *)sisusb;
+
+ /* Set mode 0x03 */
+ SiSUSBSetMode(sisusb->SiS_Pr, 0x03);
+
+ if (!(myfont = find_font("VGA8x16")))
+ return 1;
+
+ if (!(tempbuf = vmalloc(8192)))
+ return 1;
+
+ for (i = 0; i < 256; i++)
+ memcpy(tempbuf + (i * 32), myfont->data + (i * 16), 16);
+
+ /* Upload default font */
+ ret = sisusbcon_do_font_op(sisusb, 1, 0, tempbuf, 8192, 0, 1, NULL, 16, 0);
+
+ vfree(tempbuf);
+
+ /* Upload user font (and reset current slot) */
+ if (sisusb->font_backup) {
+ ret |= sisusbcon_do_font_op(sisusb, 1, 2, sisusb->font_backup,
+ 8192, sisusb->font_backup_512, 1, NULL,
+ sisusb->font_backup_height, 0);
+ if (slot != 2)
+ sisusbcon_do_font_op(sisusb, 1, 0, NULL, 0, 0, 1,
+ NULL, 16, 0);
+ }
+
+ if (init && !sisusb->scrbuf) {
+
+ if ((tempbuf = vmalloc(8192))) {
+
+ i = 4096;
+ tempbufb = (u16 *)tempbuf;
+ while (i--)
+ *(tempbufb++) = 0x0720;
+
+ i = 0;
+ tempbufb = (u16 *)tempbuf;
+ while (bootlogo[i]) {
+ *(tempbufb++) = 0x0700 | bootlogo[i++];
+ if (!(i % 4))
+ tempbufb += 76;
+ }
+
+ i = 0;
+ tempbufb = (u16 *)tempbuf + 6;
+ while (bootstring[i])
+ *(tempbufb++) = 0x0700 | bootstring[i++];
+
+ ret |= sisusb_copy_memory(sisusb, tempbuf,
+ sisusb->vrambase, 8192, &written);
+
+ vfree(tempbuf);
+
+ }
+
+ } else if (sisusb->scrbuf) {
+
+ ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf,
+ sisusb->vrambase, sisusb->scrbuf_size, &written);
+
+ }
+
+ if (sisusb->sisusb_cursor_size_from >= 0 &&
+ sisusb->sisusb_cursor_size_to >= 0) {
+ sisusb_setidxreg(sisusb, SISCR, 0x0a,
+ sisusb->sisusb_cursor_size_from);
+ sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0,
+ sisusb->sisusb_cursor_size_to);
+ } else {
+ sisusb_setidxreg(sisusb, SISCR, 0x0a, 0x2d);
+ sisusb_setidxreg(sisusb, SISCR, 0x0b, 0x0e);
+ sisusb->sisusb_cursor_size_to = -1;
+ }
+
+ slot = sisusb->sisusb_cursor_loc;
+ if(slot < 0) slot = 0;
+
+ sisusb->sisusb_cursor_loc = -1;
+ sisusb->bad_cursor_pos = 1;
+
+ sisusb_set_cursor(sisusb, slot);
+
+ sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8));
+ sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff));
+
+ sisusb->textmodedestroyed = 0;
+
+ /* sisusb->lock is down */
+
+ return ret;
+}
+
+#endif
+
/* fops */
static int
@@ -2329,7 +2609,7 @@ sisusb_open(struct inode *inode, struct file *file)
}
}
- /* increment usage count for the device */
+ /* Increment usage count for our sisusb */
kref_get(&sisusb->kref);
sisusb->isopen = 1;
@@ -2340,12 +2620,10 @@ sisusb_open(struct inode *inode, struct file *file)
up(&disconnect_sem);
- printk(KERN_DEBUG "sisusbvga[%d]: opened", sisusb->minor);
-
return 0;
}
-static void
+void
sisusb_delete(struct kref *kref)
{
struct sisusb_usb_data *sisusb = to_sisusb_dev(kref);
@@ -2359,6 +2637,9 @@ sisusb_delete(struct kref *kref)
sisusb->sisusb_dev = NULL;
sisusb_free_buffers(sisusb);
sisusb_free_urbs(sisusb);
+#ifdef INCL_SISUSB_CON
+ kfree(sisusb->SiS_Pr);
+#endif
kfree(sisusb);
}
@@ -2395,8 +2676,6 @@ sisusb_release(struct inode *inode, struct file *file)
up(&disconnect_sem);
- printk(KERN_DEBUG "sisusbvga[%d]: released", myminor);
-
return 0;
}
@@ -2733,6 +3012,12 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
int retval, port, length;
u32 address;
+ /* All our commands require the device
+ * to be initialized.
+ */
+ if (!sisusb->devinit)
+ return -ENODEV;
+
port = y->data3 -
SISUSB_PCI_PSEUDO_IOPORTBASE +
SISUSB_PCI_IOPORTBASE;
@@ -2774,6 +3059,10 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
break;
case SUCMD_CLRSCR:
+ /* Gfx core must be initialized */
+ if (!sisusb->gfxinit)
+ return -ENODEV;
+
length = (y->data0 << 16) | (y->data1 << 8) | y->data2;
address = y->data3 -
SISUSB_PCI_PSEUDO_MEMBASE +
@@ -2781,11 +3070,61 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
retval = sisusb_clear_vram(sisusb, address, length);
break;
+ case SUCMD_HANDLETEXTMODE:
+ retval = 0;
+#ifdef INCL_SISUSB_CON
+ /* Gfx core must be initialized, SiS_Pr must exist */
+ if (!sisusb->gfxinit || !sisusb->SiS_Pr)
+ return -ENODEV;
+
+ switch (y->data0) {
+ case 0:
+ retval = sisusb_reset_text_mode(sisusb, 0);
+ break;
+ case 1:
+ sisusb->textmodedestroyed = 1;
+ break;
+ }
+#endif
+ break;
+
+#ifdef INCL_SISUSB_CON
+ case SUCMD_SETMODE:
+ /* Gfx core must be initialized, SiS_Pr must exist */
+ if (!sisusb->gfxinit || !sisusb->SiS_Pr)
+ return -ENODEV;
+
+ retval = 0;
+
+ sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
+ sisusb->SiS_Pr->sisusb = (void *)sisusb;
+
+ if (SiSUSBSetMode(sisusb->SiS_Pr, y->data3))
+ retval = -EINVAL;
+
+ break;
+
+ case SUCMD_SETVESAMODE:
+ /* Gfx core must be initialized, SiS_Pr must exist */
+ if (!sisusb->gfxinit || !sisusb->SiS_Pr)
+ return -ENODEV;
+
+ retval = 0;
+
+ sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
+ sisusb->SiS_Pr->sisusb = (void *)sisusb;
+
+ if (SiSUSBSetVESAMode(sisusb->SiS_Pr, y->data3))
+ retval = -EINVAL;
+
+ break;
+#endif
+
default:
retval = -EINVAL;
}
- if(retval > 0)
+ if (retval > 0)
retval = -EIO;
return retval;
@@ -2835,6 +3174,11 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
x.sisusb_vramsize = sisusb->vramsize;
x.sisusb_minor = sisusb->minor;
x.sisusb_fbdevactive= 0;
+#ifdef INCL_SISUSB_CON
+ x.sisusb_conactive = sisusb->haveconsole ? 1 : 0;
+#else
+ x.sisusb_conactive = 0;
+#endif
if (copy_to_user((void __user *)arg, &x, sizeof(x)))
retval = -EFAULT;
@@ -2895,9 +3239,13 @@ static struct file_operations usb_sisusb_fops = {
};
static struct usb_class_driver usb_sisusb_class = {
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
.name = "usb/sisusbvga%d",
- .fops = &usb_sisusb_fops,
.mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+#else
+ .name = "sisusbvga%d",
+#endif
+ .fops = &usb_sisusb_fops,
.minor_base = SISUSB_MINOR
};
@@ -2994,12 +3342,25 @@ static int sisusb_probe(struct usb_interface *intf,
printk(KERN_INFO "sisusbvga[%d]: Allocated %d output buffers\n",
sisusb->minor, sisusb->numobufs);
+#ifdef INCL_SISUSB_CON
+ /* Allocate our SiS_Pr */
+ if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) {
+ printk(KERN_ERR
+ "sisusbvga[%d]: Failed to allocate SiS_Pr\n",
+ sisusb->minor);
+ }
+#endif
+
/* Do remaining init stuff */
init_waitqueue_head(&sisusb->wait_q);
usb_set_intfdata(intf, sisusb);
+ usb_get_dev(sisusb->sisusb_dev);
+
+ sisusb->present = 1;
+
#ifdef SISUSB_OLD_CONFIG_COMPAT
{
int ret;
@@ -3014,14 +3375,19 @@ static int sisusb_probe(struct usb_interface *intf,
sisusb->minor);
else
sisusb->ioctl32registered = 1;
-
}
#endif
- sisusb->present = 1;
-
if (dev->speed == USB_SPEED_HIGH) {
- if (sisusb_init_gfxdevice(sisusb, 1))
+ int initscreen = 1;
+#ifdef INCL_SISUSB_CON
+ if (sisusb_first_vc > 0 &&
+ sisusb_last_vc > 0 &&
+ sisusb_first_vc <= sisusb_last_vc &&
+ sisusb_last_vc <= MAX_NR_CONSOLES)
+ initscreen = 0;
+#endif
+ if (sisusb_init_gfxdevice(sisusb, initscreen))
printk(KERN_ERR
"sisusbvga[%d]: Failed to early "
"initialize device\n",
@@ -3035,6 +3401,16 @@ static int sisusb_probe(struct usb_interface *intf,
sisusb->ready = 1;
+#ifdef SISUSBENDIANTEST
+ printk(KERN_DEBUG "sisusb: *** RWTEST ***\n");
+ sisusb_testreadwrite(sisusb);
+ printk(KERN_DEBUG "sisusb: *** RWTEST END ***\n");
+#endif
+
+#ifdef INCL_SISUSB_CON
+ sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc);
+#endif
+
return 0;
error_4:
@@ -3053,13 +3429,20 @@ static void sisusb_disconnect(struct usb_interface *intf)
struct sisusb_usb_data *sisusb;
int minor;
- down(&disconnect_sem);
-
/* This should *not* happen */
- if (!(sisusb = usb_get_intfdata(intf))) {
- up(&disconnect_sem);
+ if (!(sisusb = usb_get_intfdata(intf)))
return;
- }
+
+#ifdef INCL_SISUSB_CON
+ sisusb_console_exit(sisusb);
+#endif
+
+ /* The above code doesn't need the disconnect
+ * semaphore to be down; its meaning is to
+ * protect all other routines from the disconnect
+ * case, not the other way round.
+ */
+ down(&disconnect_sem);
down(&sisusb->lock);
@@ -3123,11 +3506,17 @@ static int __init usb_sisusb_init(void)
{
int retval;
+#ifdef INCL_SISUSB_CON
+ sisusb_init_concode();
+#endif
+
if (!(retval = usb_register(&sisusb_driver))) {
+
printk(KERN_INFO "sisusb: Driver version %d.%d.%d\n",
SISUSB_VERSION, SISUSB_REVISION, SISUSB_PATCHLEVEL);
printk(KERN_INFO
"sisusb: Copyright (C) 2005 Thomas Winischhofer\n");
+
}
return retval;
@@ -3142,6 +3531,6 @@ module_init(usb_sisusb_init);
module_exit(usb_sisusb_exit);
MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>");
-MODULE_DESCRIPTION("sisusb - Driver for Net2280/SiS315-based USB2VGA dongles");
+MODULE_DESCRIPTION("sisusbvga - Driver for Net2280/SiS315-based USB2VGA dongles");
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index 1306d006a25a..401ff21d7881 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -46,15 +46,36 @@
#endif
#endif
+/* For older kernels, support for text consoles is by default
+ * off. To ensable text console support, change the following:
+ */
+#if 0
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
+#define CONFIG_USB_SISUSBVGA_CON
+#endif
+#endif
+
/* Version Information */
#define SISUSB_VERSION 0
#define SISUSB_REVISION 0
-#define SISUSB_PATCHLEVEL 7
+#define SISUSB_PATCHLEVEL 8
+
+/* Include console and mode switching code? */
+
+#ifdef CONFIG_USB_SISUSBVGA_CON
+#define INCL_SISUSB_CON 1
+#endif
+
+#ifdef INCL_SISUSB_CON
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+#include "sisusb_struct.h"
+#endif
/* USB related */
-#define SISUSB_MINOR 133 /* FIXME */
+#define SISUSB_MINOR 133 /* official */
/* Size of the sisusb input/output buffers */
#define SISUSB_IBUF_SIZE 0x01000
@@ -131,6 +152,26 @@ struct sisusb_usb_data {
unsigned char gfxinit; /* graphics core initialized? */
unsigned short chipid, chipvendor;
unsigned short chiprevision;
+#ifdef INCL_SISUSB_CON
+ struct SiS_Private *SiS_Pr;
+ unsigned long scrbuf;
+ unsigned int scrbuf_size;
+ int haveconsole, con_first, con_last;
+ int havethisconsole[MAX_NR_CONSOLES];
+ int textmodedestroyed;
+ unsigned int sisusb_num_columns; /* real number, not vt's idea */
+ int cur_start_addr, con_rolled_over;
+ int sisusb_cursor_loc, bad_cursor_pos;
+ int sisusb_cursor_size_from;
+ int sisusb_cursor_size_to;
+ int current_font_height, current_font_512;
+ int font_backup_size, font_backup_height, font_backup_512;
+ char *font_backup;
+ int font_slot;
+ struct vc_data *sisusb_display_fg;
+ int is_gfx;
+ int con_blanked;
+#endif
};
#define to_sisusb_dev(d) container_of(d, struct sisusb_usb_data, kref)
@@ -249,7 +290,9 @@ struct sisusb_info {
__u32 sisusb_fbdevactive; /* != 0 if framebuffer device active */
- __u8 sisusb_reserved[32]; /* for future use */
+ __u32 sisusb_conactive; /* != 0 if console driver active */
+
+ __u8 sisusb_reserved[28]; /* for future use */
};
struct sisusb_command {
@@ -261,18 +304,24 @@ struct sisusb_command {
__u32 data4; /* for future use */
};
-#define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */
-#define SUCMD_SET 0x02 /* data1 = value */
-#define SUCMD_SETOR 0x03 /* data1 = or */
-#define SUCMD_SETAND 0x04 /* data1 = and */
-#define SUCMD_SETANDOR 0x05 /* data1 = and, data2 = or */
-#define SUCMD_SETMASK 0x06 /* data1 = data, data2 = mask */
+#define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */
+#define SUCMD_SET 0x02 /* data1 = value */
+#define SUCMD_SETOR 0x03 /* data1 = or */
+#define SUCMD_SETAND 0x04 /* data1 = and */
+#define SUCMD_SETANDOR 0x05 /* data1 = and, data2 = or */
+#define SUCMD_SETMASK 0x06 /* data1 = data, data2 = mask */
-#define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */
+#define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */
+
+#define SUCMD_HANDLETEXTMODE 0x08 /* Reset/destroy text mode */
+
+#define SUCMD_SETMODE 0x09 /* Set a display mode (data3 = SiS mode) */
+#define SUCMD_SETVESAMODE 0x0a /* Set a display mode (data3 = VESA mode) */
#define SISUSB_COMMAND _IOWR(0xF3,0x3D,struct sisusb_command)
-#define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32)
-#define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info)
+#define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32)
+#define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info)
+
#endif /* SISUSB_H */
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
new file mode 100644
index 000000000000..24584463553d
--- /dev/null
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -0,0 +1,1658 @@
+/*
+ * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
+ *
+ * VGA text mode console part
+ *
+ * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, this code is licensed under the
+ * terms of the GPL v2.
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific psisusbr written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Portions based on vgacon.c which are
+ * Created 28 Sep 1997 by Geert Uytterhoeven
+ * Rewritten by Martin Mares <mj@ucw.cz>, July 1998
+ * based on code Copyright (C) 1991, 1992 Linus Torvalds
+ * 1995 Jay Estabrook
+ *
+ * A note on using in_atomic() in here: We can't handle console
+ * calls from non-schedulable context due to our USB-dependend
+ * nature. For now, this driver just ignores any calls if it
+ * detects this state.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/spinlock.h>
+#include <linux/kref.h>
+#include <linux/smp_lock.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+
+#include "sisusb.h"
+
+#ifdef INCL_SISUSB_CON
+extern int sisusb_setreg(struct sisusb_usb_data *, int, u8);
+extern int sisusb_getreg(struct sisusb_usb_data *, int, u8 *);
+extern int sisusb_setidxreg(struct sisusb_usb_data *, int, u8, u8);
+extern int sisusb_getidxreg(struct sisusb_usb_data *, int, u8, u8 *);
+extern int sisusb_setidxregor(struct sisusb_usb_data *, int, u8, u8);
+extern int sisusb_setidxregand(struct sisusb_usb_data *, int, u8, u8);
+extern int sisusb_setidxregandor(struct sisusb_usb_data *, int, u8, u8, u8);
+
+extern int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
+extern int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
+extern int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data);
+extern int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data);
+extern int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
+ u32 dest, int length, size_t *bytes_written);
+
+extern void sisusb_delete(struct kref *kref);
+extern int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
+
+extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+
+#define sisusbcon_writew(val, addr) (*(addr) = (val))
+#define sisusbcon_readw(addr) (*(addr))
+#define sisusbcon_memmovew(d, s, c) memmove(d, s, c)
+#define sisusbcon_memcpyw(d, s, c) memcpy(d, s, c)
+
+/* vc_data -> sisusb conversion table */
+static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES];
+
+/* Forward declaration */
+static const struct consw sisusb_con;
+
+extern struct semaphore disconnect_sem;
+
+static inline void
+sisusbcon_memsetw(u16 *s, u16 c, unsigned int count)
+{
+ count /= 2;
+ while (count--)
+ sisusbcon_writew(c, s++);
+}
+
+static inline void
+sisusb_initialize(struct sisusb_usb_data *sisusb)
+{
+ /* Reset cursor and start address */
+ if (sisusb_setidxreg(sisusb, SISCR, 0x0c, 0x00))
+ return;
+ if (sisusb_setidxreg(sisusb, SISCR, 0x0d, 0x00))
+ return;
+ if (sisusb_setidxreg(sisusb, SISCR, 0x0e, 0x00))
+ return;
+ sisusb_setidxreg(sisusb, SISCR, 0x0f, 0x00);
+}
+
+static inline void
+sisusbcon_set_start_address(struct sisusb_usb_data *sisusb, struct vc_data *c)
+{
+ sisusb->cur_start_addr = (c->vc_visible_origin - sisusb->scrbuf) / 2;
+
+ sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8));
+ sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff));
+}
+
+void
+sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location)
+{
+ if (sisusb->sisusb_cursor_loc == location)
+ return;
+
+ sisusb->sisusb_cursor_loc = location;
+
+ /* Hardware bug: Text cursor appears twice or not at all
+ * at some positions. Work around it with the cursor skew
+ * bits.
+ */
+
+ if ((location & 0x0007) == 0x0007) {
+ sisusb->bad_cursor_pos = 1;
+ location--;
+ if (sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0x1f, 0x20))
+ return;
+ } else if (sisusb->bad_cursor_pos) {
+ if (sisusb_setidxregand(sisusb, SISCR, 0x0b, 0x1f))
+ return;
+ sisusb->bad_cursor_pos = 0;
+ }
+
+ if (sisusb_setidxreg(sisusb, SISCR, 0x0e, (location >> 8)))
+ return;
+ sisusb_setidxreg(sisusb, SISCR, 0x0f, (location & 0xff));
+}
+
+static inline struct sisusb_usb_data *
+sisusb_get_sisusb(unsigned short console)
+{
+ return mysisusbs[console];
+}
+
+static inline int
+sisusb_sisusb_valid(struct sisusb_usb_data *sisusb)
+{
+ if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev)
+ return 0;
+
+ return 1;
+}
+
+static struct sisusb_usb_data *
+sisusb_get_sisusb_lock_and_check(unsigned short console)
+{
+ struct sisusb_usb_data *sisusb;
+
+ /* We can't handle console calls in non-schedulable
+ * context due to our locks and the USB transport.
+ * So we simply ignore them. This should only affect
+ * some calls to printk.
+ */
+ if (in_atomic())
+ return NULL;
+
+ if (!(sisusb = sisusb_get_sisusb(console)))
+ return NULL;
+
+ down(&sisusb->lock);
+
+ if (!sisusb_sisusb_valid(sisusb) ||
+ !sisusb->havethisconsole[console]) {
+ up(&sisusb->lock);
+ return NULL;
+ }
+
+ return sisusb;
+}
+
+static int
+sisusb_is_inactive(struct vc_data *c, struct sisusb_usb_data *sisusb)
+{
+ if (sisusb->is_gfx ||
+ sisusb->textmodedestroyed ||
+ c->vc_mode != KD_TEXT)
+ return 1;
+
+ return 0;
+}
+
+/* con_startup console interface routine */
+static const char *
+sisusbcon_startup(void)
+{
+ return "SISUSBCON";
+}
+
+/* con_init console interface routine */
+static void
+sisusbcon_init(struct vc_data *c, int init)
+{
+ struct sisusb_usb_data *sisusb;
+ int cols, rows;
+
+ /* This is called by take_over_console(),
+ * ie by us/under our control. It is
+ * only called after text mode and fonts
+ * are set up/restored.
+ */
+
+ down(&disconnect_sem);
+
+ if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
+ up(&disconnect_sem);
+ return;
+ }
+
+ down(&sisusb->lock);
+
+ if (!sisusb_sisusb_valid(sisusb)) {
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+ return;
+ }
+
+ c->vc_can_do_color = 1;
+
+ c->vc_complement_mask = 0x7700;
+
+ c->vc_hi_font_mask = sisusb->current_font_512 ? 0x0800 : 0;
+
+ sisusb->haveconsole = 1;
+
+ sisusb->havethisconsole[c->vc_num] = 1;
+
+ /* We only support 640x400 */
+ c->vc_scan_lines = 400;
+
+ c->vc_font.height = sisusb->current_font_height;
+
+ /* We only support width = 8 */
+ cols = 80;
+ rows = c->vc_scan_lines / c->vc_font.height;
+
+ /* Increment usage count for our sisusb.
+ * Doing so saves us from upping/downing
+ * the disconnect semaphore; we can't
+ * lose our sisusb until this is undone
+ * in con_deinit. For all other console
+ * interface functions, it suffices to
+ * use sisusb->lock and do a quick check
+ * of sisusb for device disconnection.
+ */
+ kref_get(&sisusb->kref);
+
+ if (!*c->vc_uni_pagedir_loc)
+ con_set_default_unimap(c);
+
+ up(&sisusb->lock);
+
+ up(&disconnect_sem);
+
+ if (init) {
+ c->vc_cols = cols;
+ c->vc_rows = rows;
+ } else
+ vc_resize(c, cols, rows);
+}
+
+/* con_deinit console interface routine */
+static void
+sisusbcon_deinit(struct vc_data *c)
+{
+ struct sisusb_usb_data *sisusb;
+ int i;
+
+ /* This is called by take_over_console()
+ * and others, ie not under our control.
+ */
+
+ down(&disconnect_sem);
+
+ if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
+ up(&disconnect_sem);
+ return;
+ }
+
+ down(&sisusb->lock);
+
+ /* Clear ourselves in mysisusbs */
+ mysisusbs[c->vc_num] = NULL;
+
+ sisusb->havethisconsole[c->vc_num] = 0;
+
+ /* Free our font buffer if all consoles are gone */
+ if (sisusb->font_backup) {
+ for(i = 0; i < MAX_NR_CONSOLES; i++) {
+ if (sisusb->havethisconsole[c->vc_num])
+ break;
+ }
+ if (i == MAX_NR_CONSOLES) {
+ vfree(sisusb->font_backup);
+ sisusb->font_backup = NULL;
+ }
+ }
+
+ up(&sisusb->lock);
+
+ /* decrement the usage count on our sisusb */
+ kref_put(&sisusb->kref, sisusb_delete);
+
+ up(&disconnect_sem);
+}
+
+/* interface routine */
+static u8
+sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
+ u8 blink, u8 underline, u8 reverse)
+{
+ u8 attr = color;
+
+ if (underline)
+ attr = (attr & 0xf0) | c->vc_ulcolor;
+ else if (intensity == 0)
+ attr = (attr & 0xf0) | c->vc_halfcolor;
+
+ if (reverse)
+ attr = ((attr) & 0x88) |
+ ((((attr) >> 4) |
+ ((attr) << 4)) & 0x77);
+
+ if (blink)
+ attr ^= 0x80;
+
+ if (intensity == 2)
+ attr ^= 0x08;
+
+ return attr;
+}
+
+/* Interface routine */
+static void
+sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count)
+{
+ /* Invert a region. This is called with a pointer
+ * to the console's internal screen buffer. So we
+ * simply do the inversion there and rely on
+ * a call to putc(s) to update the real screen.
+ */
+
+ while (count--) {
+ u16 a = sisusbcon_readw(p);
+
+ a = ((a) & 0x88ff) |
+ (((a) & 0x7000) >> 4) |
+ (((a) & 0x0700) << 4);
+
+ sisusbcon_writew(a, p++);
+ }
+}
+
+#define SISUSB_VADDR(x,y) \
+ ((u16 *)c->vc_origin + \
+ (y) * sisusb->sisusb_num_columns + \
+ (x))
+
+#define SISUSB_HADDR(x,y) \
+ ((u16 *)(sisusb->vrambase + (c->vc_origin - sisusb->scrbuf)) + \
+ (y) * sisusb->sisusb_num_columns + \
+ (x))
+
+/* Interface routine */
+static void
+sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
+{
+ struct sisusb_usb_data *sisusb;
+ ssize_t written;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return;
+
+ /* sisusb->lock is down */
+
+ /* Don't need to put the character into buffer ourselves,
+ * because the vt does this BEFORE calling us.
+ */
+#if 0
+ sisusbcon_writew(ch, SISUSB_VADDR(x, y));
+#endif
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return;
+ }
+
+
+ sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
+ (u32)SISUSB_HADDR(x, y), 2, &written);
+
+ up(&sisusb->lock);
+}
+
+/* Interface routine */
+static void
+sisusbcon_putcs(struct vc_data *c, const unsigned short *s,
+ int count, int y, int x)
+{
+ struct sisusb_usb_data *sisusb;
+ ssize_t written;
+ u16 *dest;
+ int i;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return;
+
+ /* sisusb->lock is down */
+
+ /* Need to put the characters into the buffer ourselves,
+ * because the vt does this AFTER calling us.
+ */
+
+ dest = SISUSB_VADDR(x, y);
+
+ for (i = count; i > 0; i--)
+ sisusbcon_writew(sisusbcon_readw(s++), dest++);
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return;
+ }
+
+ sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
+ (u32)SISUSB_HADDR(x, y), count * 2, &written);
+
+ up(&sisusb->lock);
+}
+
+/* Interface routine */
+static void
+sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
+{
+ struct sisusb_usb_data *sisusb;
+ u16 eattr = c->vc_video_erase_char;
+ ssize_t written;
+ int i, length, cols;
+ u16 *dest;
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return;
+
+ /* sisusb->lock is down */
+
+ /* Need to clear buffer ourselves, because the vt does
+ * this AFTER calling us.
+ */
+
+ dest = SISUSB_VADDR(x, y);
+
+ cols = sisusb->sisusb_num_columns;
+
+ if (width > cols)
+ width = cols;
+
+ if (x == 0 && width >= c->vc_cols) {
+
+ sisusbcon_memsetw(dest, eattr, height * cols * 2);
+
+ } else {
+
+ for (i = height; i > 0; i--, dest += cols)
+ sisusbcon_memsetw(dest, eattr, width * 2);
+
+ }
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return;
+ }
+
+ length = ((height * cols) - x - (cols - width - x)) * 2;
+
+
+ sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y),
+ (u32)SISUSB_HADDR(x, y), length, &written);
+
+ up(&sisusb->lock);
+}
+
+/* Interface routine */
+static void
+sisusbcon_bmove(struct vc_data *c, int sy, int sx,
+ int dy, int dx, int height, int width)
+{
+ struct sisusb_usb_data *sisusb;
+ ssize_t written;
+ int cols, length;
+#if 0
+ u16 *src, *dest;
+ int i;
+#endif
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return;
+
+ /* sisusb->lock is down */
+
+ cols = sisusb->sisusb_num_columns;
+
+ /* Don't need to move data outselves, because
+ * vt does this BEFORE calling us.
+ * This is only used by vt's insert/deletechar.
+ */
+#if 0
+ if (sx == 0 && dx == 0 && width >= c->vc_cols && width <= cols) {
+
+ sisusbcon_memmovew(SISUSB_VADDR(0, dy), SISUSB_VADDR(0, sy),
+ height * width * 2);
+
+ } else if (dy < sy || (dy == sy && dx < sx)) {
+
+ src = SISUSB_VADDR(sx, sy);
+ dest = SISUSB_VADDR(dx, dy);
+
+ for (i = height; i > 0; i--) {
+ sisusbcon_memmovew(dest, src, width * 2);
+ src += cols;
+ dest += cols;
+ }
+
+ } else {
+
+ src = SISUSB_VADDR(sx, sy + height - 1);
+ dest = SISUSB_VADDR(dx, dy + height - 1);
+
+ for (i = height; i > 0; i--) {
+ sisusbcon_memmovew(dest, src, width * 2);
+ src -= cols;
+ dest -= cols;
+ }
+
+ }
+#endif
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return;
+ }
+
+ length = ((height * cols) - dx - (cols - width - dx)) * 2;
+
+
+ sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy),
+ (u32)SISUSB_HADDR(dx, dy), length, &written);
+
+ up(&sisusb->lock);
+}
+
+/* interface routine */
+static int
+sisusbcon_switch(struct vc_data *c)
+{
+ struct sisusb_usb_data *sisusb;
+ ssize_t written;
+ int length;
+
+ /* Returnvalue 0 means we have fully restored screen,
+ * and vt doesn't need to call do_update_region().
+ * Returnvalue != 0 naturally means the opposite.
+ */
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return 0;
+
+ /* sisusb->lock is down */
+
+ /* Don't write to screen if in gfx mode */
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return 0;
+ }
+
+ /* That really should not happen. It would mean we are
+ * being called while the vc is using its private buffer
+ * as origin.
+ */
+ if (c->vc_origin == (unsigned long)c->vc_screenbuf) {
+ up(&sisusb->lock);
+ printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n");
+ return 0;
+ }
+
+ /* Check that we don't copy too much */
+ length = min((int)c->vc_screenbuf_size,
+ (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin));
+
+ /* Restore the screen contents */
+ sisusbcon_memcpyw((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf,
+ length);
+
+ sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin,
+ (u32)SISUSB_HADDR(0, 0),
+ length, &written);
+
+ up(&sisusb->lock);
+
+ return 0;
+}
+
+/* interface routine */
+static void
+sisusbcon_save_screen(struct vc_data *c)
+{
+ struct sisusb_usb_data *sisusb;
+ int length;
+
+ /* Save the current screen contents to vc's private
+ * buffer.
+ */
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return;
+
+ /* sisusb->lock is down */
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return;
+ }
+
+ /* Check that we don't copy too much */
+ length = min((int)c->vc_screenbuf_size,
+ (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin));
+
+ /* Save the screen contents to vc's private buffer */
+ sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin,
+ length);
+
+ up(&sisusb->lock);
+}
+
+/* interface routine */
+static int
+sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
+{
+ struct sisusb_usb_data *sisusb;
+ int i, j;
+
+ /* Return value not used by vt */
+
+ if (!CON_IS_VISIBLE(c))
+ return -EINVAL;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return -EINVAL;
+
+ /* sisusb->lock is down */
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return -EINVAL;
+ }
+
+ for (i = j = 0; i < 16; i++) {
+ if (sisusb_setreg(sisusb, SISCOLIDX, table[i]))
+ break;
+ if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2))
+ break;
+ if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2))
+ break;
+ if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2))
+ break;
+ }
+
+ up(&sisusb->lock);
+
+ return 0;
+}
+
+/* interface routine */
+static int
+sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
+{
+ struct sisusb_usb_data *sisusb;
+ u8 sr1, cr17, pmreg, cr63;
+ ssize_t written;
+ int ret = 0;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return 0;
+
+ /* sisusb->lock is down */
+
+ if (mode_switch)
+ sisusb->is_gfx = blank ? 1 : 0;
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return 0;
+ }
+
+ switch (blank) {
+
+ case 1: /* Normal blanking: Clear screen */
+ case -1:
+ sisusbcon_memsetw((u16 *)c->vc_origin,
+ c->vc_video_erase_char,
+ c->vc_screenbuf_size);
+ sisusb_copy_memory(sisusb,
+ (unsigned char *)c->vc_origin,
+ (u32)(sisusb->vrambase +
+ (c->vc_origin - sisusb->scrbuf)),
+ c->vc_screenbuf_size, &written);
+ sisusb->con_blanked = 1;
+ ret = 1;
+ break;
+
+ default: /* VESA blanking */
+ switch (blank) {
+ case 0: /* Unblank */
+ sr1 = 0x00;
+ cr17 = 0x80;
+ pmreg = 0x00;
+ cr63 = 0x00;
+ ret = 1;
+ sisusb->con_blanked = 0;
+ break;
+ case VESA_VSYNC_SUSPEND + 1:
+ sr1 = 0x20;
+ cr17 = 0x80;
+ pmreg = 0x80;
+ cr63 = 0x40;
+ break;
+ case VESA_HSYNC_SUSPEND + 1:
+ sr1 = 0x20;
+ cr17 = 0x80;
+ pmreg = 0x40;
+ cr63 = 0x40;
+ break;
+ case VESA_POWERDOWN + 1:
+ sr1 = 0x20;
+ cr17 = 0x00;
+ pmreg = 0xc0;
+ cr63 = 0x40;
+ break;
+ default:
+ up(&sisusb->lock);
+ return -EINVAL;
+ }
+
+ sisusb_setidxregandor(sisusb, SISSR, 0x01, ~0x20, sr1);
+ sisusb_setidxregandor(sisusb, SISCR, 0x17, 0x7f, cr17);
+ sisusb_setidxregandor(sisusb, SISSR, 0x1f, 0x3f, pmreg);
+ sisusb_setidxregandor(sisusb, SISCR, 0x63, 0xbf, cr63);
+
+ }
+
+ up(&sisusb->lock);
+
+ return ret;
+}
+
+/* interface routine */
+static int
+sisusbcon_scrolldelta(struct vc_data *c, int lines)
+{
+ struct sisusb_usb_data *sisusb;
+ int margin = c->vc_size_row * 4;
+ int ul, we, p, st;
+
+ /* The return value does not seem to be used */
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return 0;
+
+ /* sisusb->lock is down */
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return 0;
+ }
+
+ if (!lines) /* Turn scrollback off */
+ c->vc_visible_origin = c->vc_origin;
+ else {
+
+ if (sisusb->con_rolled_over >
+ (c->vc_scr_end - sisusb->scrbuf) + margin) {
+
+ ul = c->vc_scr_end - sisusb->scrbuf;
+ we = sisusb->con_rolled_over + c->vc_size_row;
+
+ } else {
+
+ ul = 0;
+ we = sisusb->scrbuf_size;
+
+ }
+
+ p = (c->vc_visible_origin - sisusb->scrbuf - ul + we) % we +
+ lines * c->vc_size_row;
+
+ st = (c->vc_origin - sisusb->scrbuf - ul + we) % we;
+
+ if (st < 2 * margin)
+ margin = 0;
+
+ if (p < margin)
+ p = 0;
+
+ if (p > st - margin)
+ p = st;
+
+ c->vc_visible_origin = sisusb->scrbuf + (p + ul) % we;
+ }
+
+ sisusbcon_set_start_address(sisusb, c);
+
+ up(&sisusb->lock);
+
+ return 1;
+}
+
+/* Interface routine */
+static void
+sisusbcon_cursor(struct vc_data *c, int mode)
+{
+ struct sisusb_usb_data *sisusb;
+ int from, to, baseline;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return;
+
+ /* sisusb->lock is down */
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return;
+ }
+
+ if (c->vc_origin != c->vc_visible_origin) {
+ c->vc_visible_origin = c->vc_origin;
+ sisusbcon_set_start_address(sisusb, c);
+ }
+
+ if (mode == CM_ERASE) {
+ sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20);
+ sisusb->sisusb_cursor_size_to = -1;
+ up(&sisusb->lock);
+ return;
+ }
+
+ sisusb_set_cursor(sisusb, (c->vc_pos - sisusb->scrbuf) / 2);
+
+ baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2);
+
+ switch (c->vc_cursor_type & 0x0f) {
+ case CUR_BLOCK: from = 1;
+ to = c->vc_font.height;
+ break;
+ case CUR_TWO_THIRDS: from = c->vc_font.height / 3;
+ to = baseline;
+ break;
+ case CUR_LOWER_HALF: from = c->vc_font.height / 2;
+ to = baseline;
+ break;
+ case CUR_LOWER_THIRD: from = (c->vc_font.height * 2) / 3;
+ to = baseline;
+ break;
+ case CUR_NONE: from = 31;
+ to = 30;
+ break;
+ default:
+ case CUR_UNDERLINE: from = baseline - 1;
+ to = baseline;
+ break;
+ }
+
+ if (sisusb->sisusb_cursor_size_from != from ||
+ sisusb->sisusb_cursor_size_to != to) {
+
+ sisusb_setidxreg(sisusb, SISCR, 0x0a, from);
+ sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, to);
+
+ sisusb->sisusb_cursor_size_from = from;
+ sisusb->sisusb_cursor_size_to = to;
+ }
+
+ up(&sisusb->lock);
+}
+
+static int
+sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
+ int t, int b, int dir, int lines)
+{
+ int cols = sisusb->sisusb_num_columns;
+ int length = ((b - t) * cols) * 2;
+ u16 eattr = c->vc_video_erase_char;
+ ssize_t written;
+
+ /* sisusb->lock is down */
+
+ /* Scroll an area which does not match the
+ * visible screen's dimensions. This needs
+ * to be done separately, as it does not
+ * use hardware panning.
+ */
+
+ switch (dir) {
+
+ case SM_UP:
+ sisusbcon_memmovew(SISUSB_VADDR(0, t),
+ SISUSB_VADDR(0, t + lines),
+ (b - t - lines) * cols * 2);
+ sisusbcon_memsetw(SISUSB_VADDR(0, b - lines), eattr,
+ lines * cols * 2);
+ break;
+
+ case SM_DOWN:
+ sisusbcon_memmovew(SISUSB_VADDR(0, t + lines),
+ SISUSB_VADDR(0, t),
+ (b - t - lines) * cols * 2);
+ sisusbcon_memsetw(SISUSB_VADDR(0, t), eattr,
+ lines * cols * 2);
+ break;
+ }
+
+ sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t),
+ (u32)SISUSB_HADDR(0, t), length, &written);
+
+ up(&sisusb->lock);
+
+ return 1;
+}
+
+/* Interface routine */
+static int
+sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+{
+ struct sisusb_usb_data *sisusb;
+ u16 eattr = c->vc_video_erase_char;
+ ssize_t written;
+ int copyall = 0;
+ unsigned long oldorigin;
+ unsigned int delta = lines * c->vc_size_row;
+ u32 originoffset;
+
+ /* Returning != 0 means we have done the scrolling successfully.
+ * Returning 0 makes vt do the scrolling on its own.
+ * Note that con_scroll is only called if the console is
+ * visible. In that case, the origin should be our buffer,
+ * not the vt's private one.
+ */
+
+ if (!lines)
+ return 1;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return 0;
+
+ /* sisusb->lock is down */
+
+ if (sisusb_is_inactive(c, sisusb)) {
+ up(&sisusb->lock);
+ return 0;
+ }
+
+ /* Special case */
+ if (t || b != c->vc_rows)
+ return sisusbcon_scroll_area(c, sisusb, t, b, dir, lines);
+
+ if (c->vc_origin != c->vc_visible_origin) {
+ c->vc_visible_origin = c->vc_origin;
+ sisusbcon_set_start_address(sisusb, c);
+ }
+
+ /* limit amount to maximum realistic size */
+ if (lines > c->vc_rows)
+ lines = c->vc_rows;
+
+ oldorigin = c->vc_origin;
+
+ switch (dir) {
+
+ case SM_UP:
+
+ if (c->vc_scr_end + delta >=
+ sisusb->scrbuf + sisusb->scrbuf_size) {
+ sisusbcon_memcpyw((u16 *)sisusb->scrbuf,
+ (u16 *)(oldorigin + delta),
+ c->vc_screenbuf_size - delta);
+ c->vc_origin = sisusb->scrbuf;
+ sisusb->con_rolled_over = oldorigin - sisusb->scrbuf;
+ copyall = 1;
+ } else
+ c->vc_origin += delta;
+
+ sisusbcon_memsetw(
+ (u16 *)(c->vc_origin + c->vc_screenbuf_size - delta),
+ eattr, delta);
+
+ break;
+
+ case SM_DOWN:
+
+ if (oldorigin - delta < sisusb->scrbuf) {
+ sisusbcon_memmovew((u16 *)(sisusb->scrbuf +
+ sisusb->scrbuf_size -
+ c->vc_screenbuf_size +
+ delta),
+ (u16 *)oldorigin,
+ c->vc_screenbuf_size - delta);
+ c->vc_origin = sisusb->scrbuf +
+ sisusb->scrbuf_size -
+ c->vc_screenbuf_size;
+ sisusb->con_rolled_over = 0;
+ copyall = 1;
+ } else
+ c->vc_origin -= delta;
+
+ c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
+
+ scr_memsetw((u16 *)(c->vc_origin), eattr, delta);
+
+ break;
+ }
+
+ originoffset = (u32)(c->vc_origin - sisusb->scrbuf);
+
+ if (copyall)
+ sisusb_copy_memory(sisusb,
+ (char *)c->vc_origin,
+ (u32)(sisusb->vrambase + originoffset),
+ c->vc_screenbuf_size, &written);
+ else if (dir == SM_UP)
+ sisusb_copy_memory(sisusb,
+ (char *)c->vc_origin + c->vc_screenbuf_size - delta,
+ (u32)sisusb->vrambase + originoffset +
+ c->vc_screenbuf_size - delta,
+ delta, &written);
+ else
+ sisusb_copy_memory(sisusb,
+ (char *)c->vc_origin,
+ (u32)(sisusb->vrambase + originoffset),
+ delta, &written);
+
+ c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
+ c->vc_visible_origin = c->vc_origin;
+
+ sisusbcon_set_start_address(sisusb, c);
+
+ c->vc_pos = c->vc_pos - oldorigin + c->vc_origin;
+
+ up(&sisusb->lock);
+
+ return 1;
+}
+
+/* Interface routine */
+static int
+sisusbcon_set_origin(struct vc_data *c)
+{
+ struct sisusb_usb_data *sisusb;
+
+ /* Returning != 0 means we were successful.
+ * Returning 0 will vt make to use its own
+ * screenbuffer as the origin.
+ */
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return 0;
+
+ /* sisusb->lock is down */
+
+ if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) {
+ up(&sisusb->lock);
+ return 0;
+ }
+
+ c->vc_origin = c->vc_visible_origin = sisusb->scrbuf;
+
+ sisusbcon_set_start_address(sisusb, c);
+
+ sisusb->con_rolled_over = 0;
+
+ up(&sisusb->lock);
+
+ return 1;
+}
+
+/* Interface routine */
+static int
+sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows)
+{
+ struct sisusb_usb_data *sisusb;
+ int fh;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return -ENODEV;
+
+ fh = sisusb->current_font_height;
+
+ up(&sisusb->lock);
+
+ /* We are quite unflexible as regards resizing. The vt code
+ * handles sizes where the line length isn't equal the pitch
+ * quite badly. As regards the rows, our panning tricks only
+ * work well if the number of rows equals the visible number
+ * of rows.
+ */
+
+ if (newcols != 80 || c->vc_scan_lines / fh != newrows)
+ return -EINVAL;
+
+ return 0;
+}
+
+int
+sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
+ u8 *arg, int cmapsz, int ch512, int dorecalc,
+ struct vc_data *c, int fh, int uplock)
+{
+ int font_select = 0x00, i, err = 0;
+ u32 offset = 0;
+ u8 dummy;
+
+ /* sisusb->lock is down */
+
+ /*
+ * The default font is kept in slot 0.
+ * A user font is loaded in slot 2 (256 ch)
+ * or 2+3 (512 ch).
+ */
+
+ if ((slot != 0 && slot != 2) || !fh) {
+ if (uplock)
+ up(&sisusb->lock);
+ return -EINVAL;
+ }
+
+ if (set)
+ sisusb->font_slot = slot;
+
+ /* Default font is always 256 */
+ if (slot == 0)
+ ch512 = 0;
+ else
+ offset = 4 * cmapsz;
+
+ font_select = (slot == 0) ? 0x00 : (ch512 ? 0x0e : 0x0a);
+
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x04); /* Write to plane 2 */
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x07); /* Memory mode a0-bf */
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset */
+
+ if (err)
+ goto font_op_error;
+
+ err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x03); /* Select plane read 2 */
+ err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x00); /* Disable odd/even */
+ err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x00); /* Address range a0-bf */
+
+ if (err)
+ goto font_op_error;
+
+ if (arg) {
+ if (set)
+ for (i = 0; i < cmapsz; i++) {
+ err |= sisusb_writeb(sisusb,
+ sisusb->vrambase + offset + i,
+ arg[i]);
+ if (err)
+ break;
+ }
+ else
+ for (i = 0; i < cmapsz; i++) {
+ err |= sisusb_readb(sisusb,
+ sisusb->vrambase + offset + i,
+ &arg[i]);
+ if (err)
+ break;
+ }
+
+ /*
+ * In 512-character mode, the character map is not contiguous if
+ * we want to remain EGA compatible -- which we do
+ */
+
+ if (ch512) {
+ if (set)
+ for (i = 0; i < cmapsz; i++) {
+ err |= sisusb_writeb(sisusb,
+ sisusb->vrambase + offset +
+ (2 * cmapsz) + i,
+ arg[cmapsz + i]);
+ if (err)
+ break;
+ }
+ else
+ for (i = 0; i < cmapsz; i++) {
+ err |= sisusb_readb(sisusb,
+ sisusb->vrambase + offset +
+ (2 * cmapsz) + i,
+ &arg[cmapsz + i]);
+ if (err)
+ break;
+ }
+ }
+ }
+
+ if (err)
+ goto font_op_error;
+
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x03); /* Write to planes 0+1 */
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x03); /* Memory mode a0-bf */
+ if (set)
+ sisusb_setidxreg(sisusb, SISSR, 0x03, font_select);
+ err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset end */
+
+ if (err)
+ goto font_op_error;
+
+ err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x00); /* Select plane read 0 */
+ err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x10); /* Enable odd/even */
+ err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x06); /* Address range b8-bf */
+
+ if (err)
+ goto font_op_error;
+
+ if ((set) && (ch512 != sisusb->current_font_512)) {
+
+ /* Font is shared among all our consoles.
+ * And so is the hi_font_mask.
+ */
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *c = vc_cons[i].d;
+ if (c && c->vc_sw == &sisusb_con)
+ c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
+ }
+
+ sisusb->current_font_512 = ch512;
+
+ /* color plane enable register:
+ 256-char: enable intensity bit
+ 512-char: disable intensity bit */
+ sisusb_getreg(sisusb, SISINPSTAT, &dummy);
+ sisusb_setreg(sisusb, SISAR, 0x12);
+ sisusb_setreg(sisusb, SISAR, ch512 ? 0x07 : 0x0f);
+
+ sisusb_getreg(sisusb, SISINPSTAT, &dummy);
+ sisusb_setreg(sisusb, SISAR, 0x20);
+ sisusb_getreg(sisusb, SISINPSTAT, &dummy);
+ }
+
+ if (dorecalc) {
+
+ /*
+ * Adjust the screen to fit a font of a certain height
+ */
+
+ unsigned char ovr, vde, fsr;
+ int rows = 0, maxscan = 0;
+
+ if (c) {
+
+ /* Number of video rows */
+ rows = c->vc_scan_lines / fh;
+ /* Scan lines to actually display-1 */
+ maxscan = rows * fh - 1;
+
+ /*printk(KERN_DEBUG "sisusb recalc rows %d maxscan %d fh %d sl %d\n",
+ rows, maxscan, fh, c->vc_scan_lines);*/
+
+ sisusb_getidxreg(sisusb, SISCR, 0x07, &ovr);
+ vde = maxscan & 0xff;
+ ovr = (ovr & 0xbd) |
+ ((maxscan & 0x100) >> 7) |
+ ((maxscan & 0x200) >> 3);
+ sisusb_setidxreg(sisusb, SISCR, 0x07, ovr);
+ sisusb_setidxreg(sisusb, SISCR, 0x12, vde);
+
+ }
+
+ sisusb_getidxreg(sisusb, SISCR, 0x09, &fsr);
+ fsr = (fsr & 0xe0) | (fh - 1);
+ sisusb_setidxreg(sisusb, SISCR, 0x09, fsr);
+ sisusb->current_font_height = fh;
+
+ sisusb->sisusb_cursor_size_from = -1;
+ sisusb->sisusb_cursor_size_to = -1;
+
+ }
+
+ if (uplock)
+ up(&sisusb->lock);
+
+ if (dorecalc && c) {
+ int i, rows = c->vc_scan_lines / fh;
+
+ /* Now adjust our consoles' size */
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *vc = vc_cons[i].d;
+
+ if (vc && vc->vc_sw == &sisusb_con) {
+ if (CON_IS_VISIBLE(vc)) {
+ vc->vc_sw->con_cursor(vc, CM_DRAW);
+ }
+ vc->vc_font.height = fh;
+ vc_resize(vc, 0, rows);
+ }
+ }
+ }
+
+ return 0;
+
+font_op_error:
+ if (uplock)
+ up(&sisusb->lock);
+
+ return -EIO;
+}
+
+/* Interface routine */
+static int
+sisusbcon_font_set(struct vc_data *c, struct console_font *font,
+ unsigned flags)
+{
+ struct sisusb_usb_data *sisusb;
+ unsigned charcount = font->charcount;
+
+ if (font->width != 8 || (charcount != 256 && charcount != 512))
+ return -EINVAL;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return -ENODEV;
+
+ /* sisusb->lock is down */
+
+ /* Save the user-provided font into a buffer. This
+ * is used for restoring text mode after quitting
+ * from X and for the con_getfont routine.
+ */
+ if (sisusb->font_backup) {
+ if (sisusb->font_backup_size < charcount) {
+ vfree(sisusb->font_backup);
+ sisusb->font_backup = NULL;
+ }
+ }
+
+ if (!sisusb->font_backup)
+ sisusb->font_backup = vmalloc(charcount * 32);
+
+ if (sisusb->font_backup) {
+ memcpy(sisusb->font_backup, font->data, charcount * 32);
+ sisusb->font_backup_size = charcount;
+ sisusb->font_backup_height = font->height;
+ sisusb->font_backup_512 = (charcount == 512) ? 1 : 0;
+ }
+
+ /* do_font_op ups sisusb->lock */
+
+ return sisusbcon_do_font_op(sisusb, 1, 2, font->data,
+ 8192, (charcount == 512),
+ (!(flags & KD_FONT_FLAG_DONT_RECALC)) ? 1 : 0,
+ c, font->height, 1);
+}
+
+/* Interface routine */
+static int
+sisusbcon_font_get(struct vc_data *c, struct console_font *font)
+{
+ struct sisusb_usb_data *sisusb;
+
+ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
+ return -ENODEV;
+
+ /* sisusb->lock is down */
+
+ font->width = 8;
+ font->height = c->vc_font.height;
+ font->charcount = 256;
+
+ if (!font->data) {
+ up(&sisusb->lock);
+ return 0;
+ }
+
+ if (!sisusb->font_backup) {
+ up(&sisusb->lock);
+ return -ENODEV;
+ }
+
+ /* Copy 256 chars only, like vgacon */
+ memcpy(font->data, sisusb->font_backup, 256 * 32);
+
+ up(&sisusb->lock);
+
+ return 0;
+}
+
+/*
+ * The console `switch' structure for the sisusb console
+ */
+
+static const struct consw sisusb_con = {
+ .owner = THIS_MODULE,
+ .con_startup = sisusbcon_startup,
+ .con_init = sisusbcon_init,
+ .con_deinit = sisusbcon_deinit,
+ .con_clear = sisusbcon_clear,
+ .con_putc = sisusbcon_putc,
+ .con_putcs = sisusbcon_putcs,
+ .con_cursor = sisusbcon_cursor,
+ .con_scroll = sisusbcon_scroll,
+ .con_bmove = sisusbcon_bmove,
+ .con_switch = sisusbcon_switch,
+ .con_blank = sisusbcon_blank,
+ .con_font_set = sisusbcon_font_set,
+ .con_font_get = sisusbcon_font_get,
+ .con_set_palette = sisusbcon_set_palette,
+ .con_scrolldelta = sisusbcon_scrolldelta,
+ .con_build_attr = sisusbcon_build_attr,
+ .con_invert_region = sisusbcon_invert_region,
+ .con_set_origin = sisusbcon_set_origin,
+ .con_save_screen = sisusbcon_save_screen,
+ .con_resize = sisusbcon_resize,
+};
+
+/* Our very own dummy console driver */
+
+static const char *sisusbdummycon_startup(void)
+{
+ return "SISUSBVGADUMMY";
+}
+
+static void sisusbdummycon_init(struct vc_data *vc, int init)
+{
+ vc->vc_can_do_color = 1;
+ if (init) {
+ vc->vc_cols = 80;
+ vc->vc_rows = 25;
+ } else
+ vc_resize(vc, 80, 25);
+}
+
+static int sisusbdummycon_dummy(void)
+{
+ return 0;
+}
+
+#define SISUSBCONDUMMY (void *)sisusbdummycon_dummy
+
+const struct consw sisusb_dummy_con = {
+ .owner = THIS_MODULE,
+ .con_startup = sisusbdummycon_startup,
+ .con_init = sisusbdummycon_init,
+ .con_deinit = SISUSBCONDUMMY,
+ .con_clear = SISUSBCONDUMMY,
+ .con_putc = SISUSBCONDUMMY,
+ .con_putcs = SISUSBCONDUMMY,
+ .con_cursor = SISUSBCONDUMMY,
+ .con_scroll = SISUSBCONDUMMY,
+ .con_bmove = SISUSBCONDUMMY,
+ .con_switch = SISUSBCONDUMMY,
+ .con_blank = SISUSBCONDUMMY,
+ .con_font_set = SISUSBCONDUMMY,
+ .con_font_get = SISUSBCONDUMMY,
+ .con_font_default = SISUSBCONDUMMY,
+ .con_font_copy = SISUSBCONDUMMY,
+ .con_set_palette = SISUSBCONDUMMY,
+ .con_scrolldelta = SISUSBCONDUMMY,
+};
+
+int
+sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
+{
+ int i, ret, minor = sisusb->minor;
+
+ down(&disconnect_sem);
+
+ down(&sisusb->lock);
+
+ /* Erm.. that should not happen */
+ if (sisusb->haveconsole || !sisusb->SiS_Pr) {
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+ return 1;
+ }
+
+ sisusb->con_first = first;
+ sisusb->con_last = last;
+
+ if (first > last ||
+ first > MAX_NR_CONSOLES ||
+ last > MAX_NR_CONSOLES) {
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+ return 1;
+ }
+
+ /* If gfxcore not initialized or no consoles given, quit graciously */
+ if (!sisusb->gfxinit || first < 1 || last < 1) {
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+ return 0;
+ }
+
+ sisusb->sisusb_cursor_loc = -1;
+ sisusb->sisusb_cursor_size_from = -1;
+ sisusb->sisusb_cursor_size_to = -1;
+
+ /* Set up text mode (and upload default font) */
+ if (sisusb_reset_text_mode(sisusb, 1)) {
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+ printk(KERN_ERR
+ "sisusbvga[%d]: Failed to set up text mode\n",
+ minor);
+ return 1;
+ }
+
+ /* Initialize some gfx registers */
+ sisusb_initialize(sisusb);
+
+ for (i = first - 1; i <= last - 1; i++) {
+ /* Save sisusb for our interface routines */
+ mysisusbs[i] = sisusb;
+ }
+
+ /* Initial console setup */
+ sisusb->sisusb_num_columns = 80;
+
+ /* Use a 32K buffer (matches b8000-bffff area) */
+ sisusb->scrbuf_size = 32 * 1024;
+
+ /* Allocate screen buffer */
+ if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) {
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+ printk(KERN_ERR
+ "sisusbvga[%d]: Failed to allocate screen buffer\n",
+ minor);
+ return 1;
+ }
+
+ up(&sisusb->lock);
+ up(&disconnect_sem);
+
+ /* Now grab the desired console(s) */
+ ret = take_over_console(&sisusb_con, first - 1, last - 1, 0);
+
+ if (!ret)
+ sisusb->haveconsole = 1;
+ else {
+ for (i = first - 1; i <= last - 1; i++)
+ mysisusbs[i] = NULL;
+ }
+
+ return ret;
+}
+
+void
+sisusb_console_exit(struct sisusb_usb_data *sisusb)
+{
+ int i;
+
+ /* This is called if the device is disconnected
+ * and while disconnect and lock semaphores
+ * are up. This should be save because we
+ * can't lose our sisusb any other way but by
+ * disconnection (and hence, the disconnect
+ * sema is for protecting all other access
+ * functions from disconnection, not the
+ * other way round).
+ */
+
+ /* Now what do we do in case of disconnection:
+ * One alternative would be to simply call
+ * give_up_console(). Nah, not a good idea.
+ * give_up_console() is obviously buggy as it
+ * only discards the consw pointer from the
+ * driver_map, but doesn't adapt vc->vc_sw
+ * of the affected consoles. Hence, the next
+ * call to any of the console functions will
+ * eventually take a trip to oops county.
+ * Also, give_up_console for some reason
+ * doesn't decrement our module refcount.
+ * Instead, we switch our consoles to a private
+ * dummy console. This, of course, keeps our
+ * refcount up as well, but it works perfectly.
+ */
+
+ if (sisusb->haveconsole) {
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ if (sisusb->havethisconsole[i])
+ take_over_console(&sisusb_dummy_con, i, i, 0);
+ /* At this point, con_deinit for all our
+ * consoles is executed by take_over_console().
+ */
+ sisusb->haveconsole = 0;
+ }
+
+ vfree((void *)sisusb->scrbuf);
+ sisusb->scrbuf = 0;
+
+ vfree(sisusb->font_backup);
+ sisusb->font_backup = NULL;
+}
+
+void __init sisusb_init_concode(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ mysisusbs[i] = NULL;
+}
+
+#endif /* INCL_CON */
+
+
+
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
new file mode 100644
index 000000000000..f28bc240f9b6
--- /dev/null
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -0,0 +1,1047 @@
+/*
+ * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
+ *
+ * Display mode initializing code
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, this code is licensed under the
+ * terms of the GPL v2.
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 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 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,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/kref.h>
+
+#include "sisusb.h"
+
+#ifdef INCL_SISUSB_CON
+
+#include "sisusb_init.h"
+
+/*********************************************/
+/* POINTER INITIALIZATION */
+/*********************************************/
+
+static void
+SiSUSB_InitPtr(struct SiS_Private *SiS_Pr)
+{
+ SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo;
+ SiS_Pr->SiS_StandTable = SiSUSB_StandTable;
+
+ SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable;
+ SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex;
+ SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table;
+
+ SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData;
+}
+
+/*********************************************/
+/* HELPER: Get ModeID */
+/*********************************************/
+
+unsigned short
+SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth)
+{
+ unsigned short ModeIndex = 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 (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];
+ break;
+ case 1152:
+ if (VDisplay == 864)
+ ModeIndex = ModeIndex_1152x864[Depth];
+ break;
+ case 1280:
+ switch (VDisplay) {
+ case 720:
+ ModeIndex = ModeIndex_1280x720[Depth];
+ break;
+ case 768:
+ ModeIndex = ModeIndex_1280x768[Depth];
+ break;
+ case 1024:
+ ModeIndex = ModeIndex_1280x1024[Depth];
+ break;
+ }
+ }
+
+ return ModeIndex;
+}
+
+/*********************************************/
+/* HELPER: SetReg, GetReg */
+/*********************************************/
+
+static void
+SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port,
+ unsigned short index, unsigned short data)
+{
+ sisusb_setidxreg(SiS_Pr->sisusb, port, index, data);
+}
+
+static void
+SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port,
+ unsigned short data)
+{
+ sisusb_setreg(SiS_Pr->sisusb, port, data);
+}
+
+static unsigned char
+SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port,
+ unsigned short index)
+{
+ u8 data;
+
+ sisusb_getidxreg(SiS_Pr->sisusb, port, index, &data);
+
+ return data;
+}
+
+static unsigned char
+SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port)
+{
+ u8 data;
+
+ sisusb_getreg(SiS_Pr->sisusb, port, &data);
+
+ return data;
+}
+
+static void
+SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port,
+ unsigned short index, unsigned short DataAND,
+ unsigned short DataOR)
+{
+ sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR);
+}
+
+static void
+SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port,
+ unsigned short index, unsigned short DataAND)
+{
+ sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND);
+}
+
+static void
+SiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port,
+ unsigned short index, unsigned short DataOR)
+{
+ sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR);
+}
+
+/*********************************************/
+/* HELPER: DisplayOn, DisplayOff */
+/*********************************************/
+
+static void
+SiS_DisplayOn(struct SiS_Private *SiS_Pr)
+{
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF);
+}
+
+/*********************************************/
+/* HELPER: Init Port Addresses */
+/*********************************************/
+
+void
+SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr)
+{
+ SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
+ SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
+ SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
+ SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
+ SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
+ SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
+ SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
+ SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+ 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;
+}
+
+/*********************************************/
+/* HELPER: GetSysFlags */
+/*********************************************/
+
+static void
+SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
+{
+ SiS_Pr->SiS_MyCR63 = 0x63;
+}
+
+/*********************************************/
+/* HELPER: Init PCI & Engines */
+/*********************************************/
+
+static void
+SiSInitPCIetc(struct SiS_Private *SiS_Pr)
+{
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1);
+ /* - Enable 2D (0x40)
+ * - Enable 3D (0x02)
+ * - Enable 3D vertex command fetch (0x10)
+ * - Enable 3D command parser (0x08)
+ * - Enable 3D G/L transformation engine (0x80)
+ */
+ SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1E, 0xDA);
+}
+
+/*********************************************/
+/* HELPER: SET SEGMENT REGISTERS */
+/*********************************************/
+
+static void
+SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
+{
+ unsigned short temp;
+
+ value &= 0x00ff;
+ temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0xf0;
+ temp |= (value >> 4);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp);
+ temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0xf0;
+ temp |= (value & 0x0f);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp);
+}
+
+static void
+SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
+{
+ unsigned short temp;
+
+ value &= 0x00ff;
+ temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0x0f;
+ temp |= (value & 0xf0);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp);
+ temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0x0f;
+ temp |= (value << 4);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp);
+}
+
+static void
+SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
+{
+ SiS_SetSegRegLower(SiS_Pr, value);
+ SiS_SetSegRegUpper(SiS_Pr, value);
+}
+
+static void
+SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
+{
+ SiS_SetSegmentReg(SiS_Pr, 0);
+}
+
+static void
+SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
+{
+ unsigned short temp = value >> 8;
+
+ temp &= 0x07;
+ temp |= (temp << 4);
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1d, temp);
+ SiS_SetSegmentReg(SiS_Pr, value);
+}
+
+static void
+SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
+{
+ SiS_SetSegmentRegOver(SiS_Pr, 0);
+}
+
+static void
+SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
+{
+ SiS_ResetSegmentReg(SiS_Pr);
+ SiS_ResetSegmentRegOver(SiS_Pr);
+}
+
+/*********************************************/
+/* HELPER: SearchModeID */
+/*********************************************/
+
+static int
+SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+ unsigned short *ModeIdIndex)
+{
+ if ((*ModeNo) <= 0x13) {
+
+ if ((*ModeNo) != 0x03)
+ return 0;
+
+ (*ModeIdIndex) = 0;
+
+ } 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 0;
+ }
+
+ }
+
+ return 1;
+}
+
+/*********************************************/
+/* HELPER: ENABLE CRT1 */
+/*********************************************/
+
+static void
+SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
+{
+ /* Enable CRT1 gating */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf);
+}
+
+/*********************************************/
+/* HELPER: GetColorDepth */
+/*********************************************/
+
+static unsigned short
+SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
+{
+ static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
+ unsigned short modeflag;
+ short index;
+
+ 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 */
+/*********************************************/
+
+static unsigned short
+SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short rrti)
+{
+ unsigned short xres, temp, colordepth, infoflag;
+
+ 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;
+}
+
+/*********************************************/
+/* SEQ */
+/*********************************************/
+
+static void
+SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
+{
+ unsigned char SRdata;
+ int i;
+
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x00, 0x03);
+
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata);
+
+ for(i = 2; i <= 4; i++) {
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata);
+ }
+}
+
+/*********************************************/
+/* MISC */
+/*********************************************/
+
+static void
+SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
+{
+ unsigned char Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
+
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, Miscdata);
+}
+
+/*********************************************/
+/* CRTC */
+/*********************************************/
+
+static void
+SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
+{
+ unsigned char CRTCdata;
+ unsigned short i;
+
+ SiS_SetRegAND(SiS_Pr, 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_Pr->SiS_P3d4, i, CRTCdata);
+ }
+}
+
+/*********************************************/
+/* ATT */
+/*********************************************/
+
+static void
+SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
+{
+ unsigned char ARdata;
+ unsigned short i;
+
+ for(i = 0; i <= 0x13; i++) {
+ ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
+ SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, ARdata);
+ }
+ SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x14);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x00);
+
+ SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x20);
+ SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
+}
+
+/*********************************************/
+/* GRC */
+/*********************************************/
+
+static void
+SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
+{
+ unsigned char GRdata;
+ unsigned short i;
+
+ for(i = 0; i <= 0x08; i++) {
+ GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata);
+ }
+
+ if (SiS_Pr->SiS_ModeType > ModeVGA) {
+ /* 256 color disable */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3ce, 0x05, 0xBF);
+ }
+}
+
+/*********************************************/
+/* CLEAR EXTENDED REGISTERS */
+/*********************************************/
+
+static void
+SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
+{
+ int i;
+
+ for(i = 0x0A; i <= 0x0E; i++) {
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00);
+ }
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x37, 0xFE);
+}
+
+/*********************************************/
+/* Get rate index */
+/*********************************************/
+
+static unsigned short
+SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
+{
+ unsigned short rrti, i, index, temp;
+
+ if (ModeNo <= 0x13)
+ return 0xFFFF;
+
+ index = SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4, 0x33) & 0x0F;
+ if (index > 0) index--;
+
+ rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID;
+
+ i = 0;
+ do {
+ if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo)
+ break;
+
+ temp = SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask;
+ if (temp < SiS_Pr->SiS_ModeType)
+ break;
+
+ i++;
+ index--;
+ } while(index != 0xFFFF);
+
+ i--;
+
+ return (rrti + i);
+}
+
+/*********************************************/
+/* SYNC */
+/*********************************************/
+
+static void
+SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti)
+{
+ unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8;
+ sync &= 0xC0;
+ sync |= 0x2f;
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, sync);
+}
+
+/*********************************************/
+/* CRTC/2 */
+/*********************************************/
+
+static void
+SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short rrti)
+{
+ unsigned char index;
+ unsigned short temp, i, j, modeflag;
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC;
+
+ for(i = 0,j = 0; i <= 7; i++, j++) {
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j,
+ SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j = 0x10; i <= 10; i++, j++) {
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j,
+ SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j = 0x15; i <= 12; i++, j++) {
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j,
+ SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j = 0x0A; i <= 15; i++, j++) {
+ SiS_SetReg(SiS_Pr, 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_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_Pr->SiS_P3d4, 0x09, 0x5F, temp);
+
+ if (SiS_Pr->SiS_ModeType > ModeVGA)
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x14, 0x4F);
+}
+
+/*********************************************/
+/* OFFSET & PITCH */
+/*********************************************/
+/* (partly overruled by SetPitch() in XF86) */
+/*********************************************/
+
+static void
+SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short rrti)
+{
+ unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti);
+ unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag;
+ unsigned short temp;
+
+ temp = (du >> 8) & 0x0f;
+ SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, 0xF0, temp);
+
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF));
+
+ if (infoflag & InterlaceMode) du >>= 1;
+
+ du <<= 5;
+ temp = (du >> 8) & 0xff;
+ if (du & 0xff) temp++;
+ temp++;
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp);
+}
+
+/*********************************************/
+/* VCLK */
+/*********************************************/
+
+static void
+SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short rrti)
+{
+ unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK;
+ unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B;
+ unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x31,0xCF);
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2B,clka);
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2C,clkb);
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2D,0x01);
+}
+
+/*********************************************/
+/* FIFO */
+/*********************************************/
+
+static void
+SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short mi)
+{
+ unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag;
+
+ /* disable auto-threshold */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0xFE);
+
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0xAE);
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x09, 0xF0);
+
+ if (ModeNo <= 0x13)
+ return;
+
+ if ((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0x34);
+ SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0x01);
+ }
+}
+
+/*********************************************/
+/* MODE REGISTERS */
+/*********************************************/
+
+static void
+SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short rrti)
+{
+ unsigned short data = 0, VCLK = 0, index = 0;
+
+ if (ModeNo > 0x13) {
+ index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK;
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+ }
+
+ if (VCLK >= 166) data |= 0x0c;
+ SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data);
+
+ if (VCLK >= 166)
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1f, 0xe7);
+
+ /* DAC speed */
+ data = 0x03;
+ if (VCLK >= 260)
+ data = 0x00;
+ else if (VCLK >= 160)
+ data = 0x01;
+ else if (VCLK >= 135)
+ data = 0x02;
+
+ SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x07, 0xF8, data);
+}
+
+static void
+SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short rrti)
+{
+ unsigned short data, infoflag = 0, modeflag;
+
+ if (ModeNo <= 0x13)
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag;
+ }
+
+ /* Disable DPMS */
+ SiS_SetRegAND(SiS_Pr, 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_Pr->SiS_P3c4, 0x06, 0xC0, data);
+
+ data = 0;
+ if (infoflag & InterlaceMode) {
+ /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
+ unsigned short hrs = (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) |
+ ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) - 3;
+ unsigned short hto = (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) |
+ ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) + 5;
+ data = hrs - (hto >> 1) + 3;
+ }
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF));
+ SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x1a, 0xFC, (data >> 8));
+
+ if (modeflag & HalfDCLK)
+ SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0x08);
+
+ data = 0;
+ if (modeflag & LineCompareOff)
+ data = 0x08;
+ SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0xB7, data);
+
+ if ((SiS_Pr->SiS_ModeType == ModeEGA) && (ModeNo > 0x13))
+ SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0x40);
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xfb);
+
+ data = 0x60;
+ if (SiS_Pr->SiS_ModeType != ModeText) {
+ data ^= 0x60;
+ if (SiS_Pr->SiS_ModeType != ModeEGA)
+ data ^= 0xA0;
+ }
+ SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x21, 0x1F, data);
+
+ SiS_SetVCLKState(SiS_Pr, ModeNo, rrti);
+
+ if (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x31) & 0x40)
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x2c);
+ else
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x6c);
+}
+
+/*********************************************/
+/* LOAD DAC */
+/*********************************************/
+
+static void
+SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData,
+ unsigned short shiftflag, unsigned short dl, unsigned short ah,
+ unsigned short al, unsigned short dh)
+{
+ 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(SiS_Pr, DACData, (d1 << shiftflag));
+ SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag));
+ SiS_SetRegByte(SiS_Pr, DACData, (d3 << shiftflag));
+}
+
+static void
+SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi)
+{
+ unsigned short data, data2, time, i, j, k, m, n, o;
+ unsigned short si, di, bx, sf;
+ unsigned long DACAddr, DACData;
+ const unsigned char *table = NULL;
+
+ if (ModeNo < 0x13)
+ data = SiS_Pr->SiS_SModeIDTable[mi].St_ModeFlag;
+ else
+ data = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag;
+
+ data &= DACInfoFlag;
+
+ 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 {
+ j = 16;
+ time = 256;
+ table = SiS_VGA_DAC;
+ }
+
+ DACAddr = SiS_Pr->SiS_P3c8;
+ DACData = SiS_Pr->SiS_P3c9;
+ sf = 0;
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF);
+
+ SiS_SetRegByte(SiS_Pr, DACAddr, 0x00);
+
+ for(i = 0; i < j; i++) {
+ data = table[i];
+ for(k = 0; k < 3; k++) {
+ data2 = 0;
+ if (data & 0x01) data2 += 0x2A;
+ if (data & 0x02) data2 += 0x15;
+ SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf));
+ data >>= 2;
+ }
+ }
+
+ if (time == 256) {
+ for(i = 16; i < 32; i++) {
+ data = table[i] << sf;
+ for(k = 0; k < 3; k++)
+ SiS_SetRegByte(SiS_Pr, DACData, data);
+ }
+ si = 32;
+ for(m = 0; m < 9; m++) {
+ 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++;
+ }
+ si -= 2;
+ for(o = 0; o < 3; o++) {
+ SiS_WriteDAC(SiS_Pr, DACData, sf, n,
+ table[di], table[si], table[bx]);
+ si--;
+ }
+ }
+ si += 5;
+ }
+ }
+}
+
+/*********************************************/
+/* SET CRT1 REGISTER GROUP */
+/*********************************************/
+
+static void
+SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
+{
+ unsigned short StandTableIndex, rrti;
+
+ SiS_Pr->SiS_CRT1Mode = ModeNo;
+
+ if (ModeNo <= 0x13)
+ StandTableIndex = 0;
+ else
+ StandTableIndex = 1;
+
+ 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);
+
+ rrti = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
+
+ if (rrti != 0xFFFF) {
+ SiS_SetCRT1Sync(SiS_Pr, rrti);
+ SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, rrti);
+ SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, rrti);
+ SiS_SetCRT1VCLK(SiS_Pr, ModeNo, rrti);
+ }
+
+ SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, rrti);
+
+ SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_DisplayOn(SiS_Pr);
+}
+
+/*********************************************/
+/* SiSSetMode() */
+/*********************************************/
+
+int
+SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
+{
+ unsigned short ModeIdIndex;
+ unsigned long BaseAddr = SiS_Pr->IOAddress;
+
+ SiSUSB_InitPtr(SiS_Pr);
+ SiSUSBRegInit(SiS_Pr, BaseAddr);
+ SiS_GetSysFlags(SiS_Pr);
+
+ if (!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex)))
+ return 0;
+
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x05, 0x86);
+
+ SiSInitPCIetc(SiS_Pr);
+
+ ModeNo &= 0x7f;
+
+ SiS_Pr->SiS_ModeType =
+ SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask;
+
+ SiS_Pr->SiS_SetFlag = LowModeTests;
+
+ /* Set mode on CRT1 */
+ SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_HandleCRT1(SiS_Pr);
+
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF);
+
+ /* Store mode number */
+ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x34, ModeNo);
+
+ return 1;
+}
+
+int
+SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo)
+{
+ unsigned short ModeNo = 0;
+ int i;
+
+ SiSUSB_InitPtr(SiS_Pr);
+
+ if (VModeNo == 0x03) {
+
+ ModeNo = 0x03;
+
+ } else {
+
+ i = 0;
+ do {
+
+ if (SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID == VModeNo) {
+ ModeNo = SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID;
+ break;
+ }
+
+ } while (SiS_Pr->SiS_EModeIDTable[i++].Ext_ModeID != 0xff);
+
+ }
+
+ if (!ModeNo)
+ return 0;
+
+ return SiSUSBSetMode(SiS_Pr, ModeNo);
+}
+
+#endif /* INCL_SISUSB_CON */
+
+
+
+
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h
new file mode 100644
index 000000000000..5b11577835c8
--- /dev/null
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.h
@@ -0,0 +1,830 @@
+/* $XFree86$ */
+/* $XdotOrg$ */
+/*
+ * Data and prototypes for init.c
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * 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
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 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 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,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_INIT_H_
+#define _SISUSB_INIT_H_
+
+/* SiS_ModeType */
+#define ModeText 0x00
+#define ModeCGA 0x01
+#define ModeEGA 0x02
+#define ModeVGA 0x03
+#define Mode15Bpp 0x04
+#define Mode16Bpp 0x05
+#define Mode24Bpp 0x06
+#define Mode32Bpp 0x07
+
+#define ModeTypeMask 0x07
+#define IsTextMode 0x07
+
+#define DACInfoFlag 0x0018
+#define MemoryInfoFlag 0x01E0
+#define MemorySizeShift 5
+
+/* modeflag */
+#define Charx8Dot 0x0200
+#define LineCompareOff 0x0400
+#define CRT2Mode 0x0800
+#define HalfDCLK 0x1000
+#define NoSupportSimuTV 0x2000
+#define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
+#define DoubleScanMode 0x8000
+
+/* Infoflag */
+#define SupportTV 0x0008
+#define SupportTV1024 0x0800
+#define SupportCHTV 0x0800
+#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */
+#define SupportHiVision 0x0010
+#define SupportYPbPr750p 0x1000
+#define SupportLCD 0x0020
+#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */
+#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */
+#define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */
+#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
+#define InterlaceMode 0x0080
+#define SyncPP 0x0000
+#define SyncPN 0x4000
+#define SyncNP 0x8000
+#define SyncNN 0xc000
+
+/* SetFlag */
+#define ProgrammingCRT2 0x0001
+#define LowModeTests 0x0002
+#define LCDVESATiming 0x0008
+#define EnableLVDSDDA 0x0010
+#define SetDispDevSwitchFlag 0x0020
+#define CheckWinDos 0x0040
+#define SetDOSMode 0x0080
+
+/* Index in ModeResInfo table */
+#define SIS_RI_320x200 0
+#define SIS_RI_320x240 1
+#define SIS_RI_320x400 2
+#define SIS_RI_400x300 3
+#define SIS_RI_512x384 4
+#define SIS_RI_640x400 5
+#define SIS_RI_640x480 6
+#define SIS_RI_800x600 7
+#define SIS_RI_1024x768 8
+#define SIS_RI_1280x1024 9
+#define SIS_RI_1600x1200 10
+#define SIS_RI_1920x1440 11
+#define SIS_RI_2048x1536 12
+#define SIS_RI_720x480 13
+#define SIS_RI_720x576 14
+#define SIS_RI_1280x960 15
+#define SIS_RI_800x480 16
+#define SIS_RI_1024x576 17
+#define SIS_RI_1280x720 18
+#define SIS_RI_856x480 19
+#define SIS_RI_1280x768 20
+#define SIS_RI_1400x1050 21
+#define SIS_RI_1152x864 22 /* Up to here SiS conforming */
+#define SIS_RI_848x480 23
+#define SIS_RI_1360x768 24
+#define SIS_RI_1024x600 25
+#define SIS_RI_1152x768 26
+#define SIS_RI_768x576 27
+#define SIS_RI_1360x1024 28
+#define SIS_RI_1680x1050 29
+#define SIS_RI_1280x800 30
+#define SIS_RI_1920x1080 31
+#define SIS_RI_960x540 32
+#define SIS_RI_960x600 33
+
+#define SIS_VIDEO_CAPTURE 0x00 - 0x30
+#define SIS_VIDEO_PLAYBACK 0x02 - 0x30
+#define SIS_CRT2_PORT_04 0x04 - 0x30
+
+/* Mode numbers */
+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_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};
+static const unsigned short ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22};
+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_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
+static const unsigned short ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
+static const unsigned short ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+static const unsigned short ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
+
+static const unsigned char SiS_MDA_DAC[] =
+{
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
+};
+
+static const unsigned char SiS_CGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
+};
+
+static const unsigned char SiS_EGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
+ 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
+ 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
+ 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
+ 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
+ 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
+ 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
+};
+
+static const unsigned char SiS_VGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
+ 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
+ 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
+ 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
+ 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
+ 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
+ 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
+ 0x0B,0x0C,0x0D,0x0F,0x10
+};
+
+static const struct SiS_St SiSUSB_SModeIDTable[] =
+{
+ {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40},
+ {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const struct SiS_StResInfo_S SiSUSB_StResInfo[] =
+{
+ { 640,400},
+ { 640,350},
+ { 720,400},
+ { 720,350},
+ { 640,480}
+};
+
+static const struct SiS_ModeResInfo SiSUSB_ModeResInfo[] =
+{
+ { 320, 200, 8, 8}, /* 0x00 */
+ { 320, 240, 8, 8}, /* 0x01 */
+ { 320, 400, 8, 8}, /* 0x02 */
+ { 400, 300, 8, 8}, /* 0x03 */
+ { 512, 384, 8, 8}, /* 0x04 */
+ { 640, 400, 8,16}, /* 0x05 */
+ { 640, 480, 8,16}, /* 0x06 */
+ { 800, 600, 8,16}, /* 0x07 */
+ { 1024, 768, 8,16}, /* 0x08 */
+ { 1280,1024, 8,16}, /* 0x09 */
+ { 1600,1200, 8,16}, /* 0x0a */
+ { 1920,1440, 8,16}, /* 0x0b */
+ { 2048,1536, 8,16}, /* 0x0c */
+ { 720, 480, 8,16}, /* 0x0d */
+ { 720, 576, 8,16}, /* 0x0e */
+ { 1280, 960, 8,16}, /* 0x0f */
+ { 800, 480, 8,16}, /* 0x10 */
+ { 1024, 576, 8,16}, /* 0x11 */
+ { 1280, 720, 8,16}, /* 0x12 */
+ { 856, 480, 8,16}, /* 0x13 */
+ { 1280, 768, 8,16}, /* 0x14 */
+ { 1400,1050, 8,16}, /* 0x15 */
+ { 1152, 864, 8,16}, /* 0x16 */
+ { 848, 480, 8,16}, /* 0x17 */
+ { 1360, 768, 8,16}, /* 0x18 */
+ { 1024, 600, 8,16}, /* 0x19 */
+ { 1152, 768, 8,16}, /* 0x1a */
+ { 768, 576, 8,16}, /* 0x1b */
+ { 1360,1024, 8,16}, /* 0x1c */
+ { 1680,1050, 8,16}, /* 0x1d */
+ { 1280, 800, 8,16}, /* 0x1e */
+ { 1920,1080, 8,16}, /* 0x1f */
+ { 960, 540, 8,16}, /* 0x20 */
+ { 960, 600, 8,16} /* 0x21 */
+};
+
+static const struct SiS_StandTable SiSUSB_StandTable[] =
+{
+ /* MD_3_400 - mode 0x03 - 400 */
+ {
+ 0x50,0x18,0x10,0x1000,
+ { 0x00,0x03,0x00,0x02 },
+ 0x67,
+ { 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff },
+ { 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x0c,0x00,0x0f,0x08 },
+ { 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, 0xff }
+ },
+ /* Generic for VGA and higher */
+ {
+ 0x00,0x00,0x00,0x0000,
+ { 0x01,0x0f,0x00,0x0e },
+ 0x23,
+ { 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+ 0xff },
+ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x01,0x00,0x00,0x00 },
+ { 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, 0xff }
+ }
+};
+
+static const struct SiS_Ext SiSUSB_EModeIDTable[] =
+{
+ {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 */
+ {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 */
+ {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 */
+ {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */
+ {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */
+ {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */
+ {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x8 */
+ {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x16 */
+ {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */
+ {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */
+ {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */
+ {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x16 */
+ {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x8 */
+ {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x8 */
+ {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x8 */
+ {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x16 */
+ {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x16 */
+ {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x16 */
+ {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x8 */
+ {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x32 */
+ {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x16 */
+ {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */
+ {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */
+ {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */
+ {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */
+ {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x32 */
+ {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x8 */
+ {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x8 */
+ {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x16 */
+ {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x16 */
+ {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x32 */
+ {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x32 */
+ {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x32 */
+ {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x8 */
+ {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x16 */
+ {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x8 */
+ {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x16 */
+ {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x32 */
+ {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, /* 848x480 */
+ {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1},
+ {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1},
+ {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, /* 856x480 */
+ {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1},
+ {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1},
+ {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x32 */
+ {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x32 */
+ {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x32 */
+ {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, /* 768x576 */
+ {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1},
+ {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1},
+ {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, /* 960x540 */
+ {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1},
+ {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1},
+ {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, /* 960x600 */
+ {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1},
+ {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1},
+ {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1152x864 */
+ {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1},
+ {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1},
+ {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
+};
+
+static const struct SiS_Ext2 SiSUSB_RefIndex[] =
+{
+ {0x085f,0x0d,0x03,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x0 */
+ {0x0067,0x0e,0x04,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x1 */
+ {0x0067,0x0f,0x08,0x48,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x2 */
+ {0x0067,0x10,0x07,0x8b,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x3 */
+ {0x0047,0x11,0x0a,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x4 */
+ {0x0047,0x12,0x0d,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x5 */
+ {0x0047,0x13,0x13,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x6 */
+ {0x0107,0x14,0x1c,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x7 */
+ {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x8 */
+ {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x9 */
+ {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xa */
+ {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xb */
+ {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xc */
+ {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xd */
+ {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xe */
+ {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xf */
+ {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e}, /* 0x10 */
+ {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00}, /* 0x11 */
+ {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00}, /* 0x12 (6f was 03) */
+ {0x0087,0x15,0x06,0x00,0x06,0x38,1024, 768, 0x30, 0x00, 0x00}, /* 0x13 */
+ {0xc877,0x16,0x0b,0x06,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x14 */
+ {0xc067,0x17,0x0f,0x49,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x15 */
+ {0x0067,0x18,0x11,0x00,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x16 */
+ {0x0047,0x19,0x16,0x8c,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x17 */
+ {0x0107,0x1a,0x1b,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x18 */
+ {0x0107,0x1b,0x1f,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x19 */
+ {0x407f,0x00,0x00,0x00,0x00,0x41, 320, 200, 0x30, 0x56, 0x4e}, /* 0x1a */
+ {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00}, /* 0x1b */
+ {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00}, /* 0x1c */
+ {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00}, /* 0x1d */
+ {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1e */
+ {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1f */
+ {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x20 */
+ {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x21 */
+ {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x22 */
+ {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x23 */
+ {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x24 */
+ {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x25 */
+ {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x26 */
+ {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00}, /* 0x27 */
+ {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x28 38Hzi */
+ {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x29 848x480-60Hz */
+ {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2a 856x480-38Hzi */
+ {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2b 856x480-60Hz */
+ {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00}, /* 0x2c 768x576-56Hz */
+ {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00}, /* 0x2d 960x540 60Hz */
+ {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00}, /* 0x2e 960x600 60Hz */
+ {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00}, /* 0x2f */
+ {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x30 */
+ {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x31 */
+ {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x32 */
+ {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x33 1152x864-60Hz */
+ {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x34 1152x864-75Hz */
+ {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x35 1152x864-85Hz */
+ {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00}
+};
+
+static const struct SiS_CRT1Table SiSUSB_CRT1Table[] =
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}}, /* 0x0 */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}}, /* 0x1 */
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+ 0x01}}, /* 0x2 */
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}, /* 0x3 */
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}}, /* 0x4 */
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
+ 0x00}}, /* 0x5 */
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e,
+ 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
+ 0x00}}, /* 0x6 */
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+ 0x00}}, /* 0x7 */
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+ 0x00}}, /* 0x8 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+ 0x61}}, /* 0x9 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+ 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+ 0x61}}, /* 0xa */
+ {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+ 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05,
+ 0x61}}, /* 0xb */
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+ 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,
+ 0x00}}, /* 0xc */
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+ 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+ 0x01}}, /* 0xd */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+ 0x01}}, /* 0xe */
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+ 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+ 0x01}}, /* 0xf */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+ 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+ 0x01}}, /* 0x10 */
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+ 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+ 0x01}}, /* 0x11 */
+ {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+ 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+ 0x61}}, /* 0x12 */
+ {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+ 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+ 0x61}}, /* 0x13 */
+ {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+ 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+ 0x61}}, /* 0x14 */
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+ 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+ 0x00}}, /* 0x15 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x16 */
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x17 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+ 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+ 0x01}}, /* 0x18 */
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+ 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+ 0x01}}, /* 0x19 */
+ {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+ 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+ 0x62}}, /* 0x1a */
+ {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+ 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+ 0x62}}, /* 0x1b */
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+ 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+ 0x00}}, /* 0x1c */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}, /* 0x1d */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}, /* 0x1e */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+ 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+ 0x01}}, /* 0x1f */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x20 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x21 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x22 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x23 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x24 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x25 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x26 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x27 */
+ {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+ 0x63}}, /* 0x28 */
+ {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+ 0x63}}, /* 0x29 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2a */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2b */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2c */
+ {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+ 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2d */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+ 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2e */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+ 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2f */
+ {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+ 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+ 0x44}}, /* 0x30 */
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+ 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+ 0x00}}, /* 0x31 */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+ 0x01}}, /* 0x32 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+ 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+ 0x01}}, /* 0x33 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+ 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+ 0x01}}, /* 0x34 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+ 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+ 0x01}}, /* 0x35 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+ 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x36 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,
+ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+ 0x01}}, /* 0x37 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x38 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x39 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+ 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+ 0x01}}, /* 0x3a */
+ {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff,
+ 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+ 0x01}}, /* 0x3b */
+ {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+ 0x00}}, /* 0x3c */
+ {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0,
+ 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 */
+ {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
+ 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x3f */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+ 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x40 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x41 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,
+ 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
+ 0x01}}, /* 0x42 */
+ {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
+ 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
+ 0x00}}, /* 0x43 */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,
+ 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+ 0x01}}, /* 0x44 */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x45 */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,
+ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+ 0x00}}, /* 0x46 */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x47 */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x48 */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,
+ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+ 0x01}}, /* 0x49 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,
+ 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+ 0x01}}, /* 0x4a */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10,
+ 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
+ 0x00}}, /* 0x4b */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,
+ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+ 0x01}}, /* 0x4c */
+ {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0,
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}},
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}}, /* 0x4e */
+ {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff,
+ 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
+ 0x21}}, /* 0x4f */
+ {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10,
+ 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c,
+ 0x20}}, /* 0x50 */
+ {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0,
+ 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00,
+ 0x61}}, /* 0x51 */
+ {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0,
+ 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
+ 0x41}}, /* 0x52 */
+ {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0,
+ 0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02,
+ 0x01}}, /* 0x53 */
+ {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff,
+ 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
+ 0x41}} /* 0x54 */
+};
+
+static struct SiS_VCLKData SiSUSB_VCLKData[] =
+{
+ { 0x1b,0xe1, 25}, /* 0x00 */
+ { 0x4e,0xe4, 28}, /* 0x01 */
+ { 0x57,0xe4, 31}, /* 0x02 */
+ { 0xc3,0xc8, 36}, /* 0x03 */
+ { 0x42,0xe2, 40}, /* 0x04 */
+ { 0xfe,0xcd, 43}, /* 0x05 */
+ { 0x5d,0xc4, 44}, /* 0x06 */
+ { 0x52,0xe2, 49}, /* 0x07 */
+ { 0x53,0xe2, 50}, /* 0x08 */
+ { 0x74,0x67, 52}, /* 0x09 */
+ { 0x6d,0x66, 56}, /* 0x0a */
+ { 0x5a,0x64, 65}, /* 0x0b */
+ { 0x46,0x44, 67}, /* 0x0c */
+ { 0xb1,0x46, 68}, /* 0x0d */
+ { 0xd3,0x4a, 72}, /* 0x0e */
+ { 0x29,0x61, 75}, /* 0x0f */
+ { 0x6e,0x46, 76}, /* 0x10 */
+ { 0x2b,0x61, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+ { 0xab,0x44, 83}, /* 0x13 */
+ { 0x46,0x25, 84}, /* 0x14 */
+ { 0x78,0x29, 86}, /* 0x15 */
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x41,104}, /* 0x17 */
+ { 0x3a,0x23,105}, /* 0x18 */
+ { 0x70,0x44,108}, /* 0x19 */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+ { 0xe0,0x46,132}, /* 0x1d */
+ { 0x54,0x42,135}, /* 0x1e */
+ { 0xea,0x2a,139}, /* 0x1f */
+ { 0x41,0x22,157}, /* 0x20 */
+ { 0x70,0x24,162}, /* 0x21 */
+ { 0x30,0x21,175}, /* 0x22 */
+ { 0x4e,0x22,189}, /* 0x23 */
+ { 0xde,0x26,194}, /* 0x24 */
+ { 0x62,0x06,202}, /* 0x25 */
+ { 0x3f,0x03,229}, /* 0x26 */
+ { 0xb8,0x06,234}, /* 0x27 */
+ { 0x34,0x02,253}, /* 0x28 */
+ { 0x58,0x04,255}, /* 0x29 */
+ { 0x24,0x01,265}, /* 0x2a */
+ { 0x9b,0x02,267}, /* 0x2b */
+ { 0x70,0x05,270}, /* 0x2c */
+ { 0x25,0x01,272}, /* 0x2d */
+ { 0x9c,0x02,277}, /* 0x2e */
+ { 0x27,0x01,286}, /* 0x2f */
+ { 0x3c,0x02,291}, /* 0x30 */
+ { 0xef,0x0a,292}, /* 0x31 */
+ { 0xf6,0x0a,310}, /* 0x32 */
+ { 0x95,0x01,315}, /* 0x33 */
+ { 0xf0,0x09,324}, /* 0x34 */
+ { 0xfe,0x0a,331}, /* 0x35 */
+ { 0xf3,0x09,332}, /* 0x36 */
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+ { 0x52,0x2a, 54}, /* 0x3a 301 TV */
+ { 0x52,0x6a, 27}, /* 0x3b 301 TV */
+ { 0x62,0x24, 70}, /* 0x3c 301 TV */
+ { 0x62,0x64, 70}, /* 0x3d 301 TV */
+ { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
+ { 0x20,0x26, 33}, /* 0x3f 301 TV */
+ { 0x31,0xc2, 39}, /* 0x40 */
+ { 0x60,0x36, 30}, /* 0x41 Chrontel */
+ { 0x40,0x4a, 28}, /* 0x42 Chrontel */
+ { 0x9f,0x46, 44}, /* 0x43 Chrontel */
+ { 0x97,0x2c, 26}, /* 0x44 */
+ { 0x44,0xe4, 25}, /* 0x45 Chrontel */
+ { 0x7e,0x32, 47}, /* 0x46 Chrontel */
+ { 0x8a,0x24, 31}, /* 0x47 Chrontel */
+ { 0x97,0x2c, 26}, /* 0x48 Chrontel */
+ { 0xce,0x3c, 39}, /* 0x49 */
+ { 0x52,0x4a, 36}, /* 0x4a Chrontel */
+ { 0x34,0x61, 95}, /* 0x4b */
+ { 0x78,0x27,108}, /* 0x4c - was 102 */
+ { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */
+ { 0x41,0x4e, 21}, /* 0x4e */
+ { 0xa1,0x4a, 29}, /* 0x4f Chrontel */
+ { 0x19,0x42, 42}, /* 0x50 */
+ { 0x54,0x46, 58}, /* 0x51 Chrontel */
+ { 0x25,0x42, 61}, /* 0x52 */
+ { 0x44,0x44, 66}, /* 0x53 Chrontel */
+ { 0x3a,0x62, 70}, /* 0x54 Chrontel */
+ { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+ { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
+ { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
+ { 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 */
+ { 0x45,0x25, 83}, /* 0x5c 1280x800 */
+ { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
+ { 0x70,0x24,162}, /* 0x5e 1600x1200 */
+ { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */
+ { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
+ { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+ { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
+ { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+ { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
+ { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
+ { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
+ { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
+ { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
+ { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
+ { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
+ { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
+ { 0x45,0x25, 83}, /* 0x6c 1280x800 */
+ { 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 */
+};
+
+void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr);
+unsigned short SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth);
+int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
+
+extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data);
+extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data);
+extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
+ u8 index, u8 data);
+extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
+ u8 index, u8 *data);
+extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port,
+ u8 idx, u8 myand, u8 myor);
+extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
+ u8 index, u8 myor);
+extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
+ u8 idx, u8 myand);
+
+#endif
+
diff --git a/drivers/usb/misc/sisusbvga/sisusb_struct.h b/drivers/usb/misc/sisusbvga/sisusb_struct.h
new file mode 100644
index 000000000000..94edd4726c42
--- /dev/null
+++ b/drivers/usb/misc/sisusbvga/sisusb_struct.h
@@ -0,0 +1,169 @@
+/*
+ * General structure definitions for universal mode switching modules
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * 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
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 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 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,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_STRUCT_H_
+#define _SISUSB_STRUCT_H_
+
+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_StandTable
+{
+ 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_StResInfo_S {
+ unsigned short HTotal;
+ unsigned short VTotal;
+};
+
+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;
+};
+
+struct SiS_CRT1Table
+{
+ unsigned char CR[17];
+};
+
+struct SiS_VCLKData
+{
+ unsigned char SR2B,SR2C;
+ unsigned short CLOCK;
+};
+
+struct SiS_ModeResInfo
+{
+ unsigned short HTotal;
+ unsigned short VTotal;
+ unsigned char XChar;
+ unsigned char YChar;
+};
+
+struct SiS_Private
+{
+ void *sisusb;
+
+ unsigned long IOAddress;
+
+ unsigned long SiS_P3c4;
+ unsigned long SiS_P3d4;
+ unsigned long SiS_P3c0;
+ unsigned long SiS_P3ce;
+ unsigned long SiS_P3c2;
+ unsigned long SiS_P3ca;
+ unsigned long SiS_P3c6;
+ unsigned long SiS_P3c7;
+ unsigned long SiS_P3c8;
+ unsigned long SiS_P3c9;
+ unsigned long SiS_P3cb;
+ unsigned long SiS_P3cc;
+ unsigned long SiS_P3cd;
+ unsigned long SiS_P3da;
+ unsigned long SiS_Part1Port;
+
+ unsigned char SiS_MyCR63;
+ unsigned short SiS_CRT1Mode;
+ unsigned short SiS_ModeType;
+ unsigned short SiS_SetFlag;
+
+ const struct SiS_StandTable *SiS_StandTable;
+ const struct SiS_St *SiS_SModeIDTable;
+ const struct SiS_Ext *SiS_EModeIDTable;
+ const struct SiS_Ext2 *SiS_RefIndex;
+ const struct SiS_CRT1Table *SiS_CRT1Table;
+ struct SiS_VCLKData *SiS_VCLKData;
+ const struct SiS_ModeResInfo *SiS_ModeResInfo;
+};
+
+#endif
+
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index fd7fb98e4b20..54799eb0bc60 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -986,7 +986,6 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
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/misc/uss720.c b/drivers/usb/misc/uss720.c
index faa74436de52..0592cb5e6c4d 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -3,8 +3,8 @@
/*
* uss720.c -- USS720 USB Parport Cable.
*
- * Copyright (C) 1999
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
+ * Copyright (C) 1999, 2005
+ * Thomas Sailer (t.sailer@alumni.ethz.ch)
*
* 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,103 +23,240 @@
* Based on parport_pc.c
*
* History:
- * 0.1 04.08.99 Created
- * 0.2 07.08.99 Some fixes mainly suggested by Tim Waugh
- * Interrupt handling currently disabled because
- * usb_request_irq crashes somewhere within ohci.c
- * for no apparent reason (that is for me, anyway)
- * ECP currently untested
- * 0.3 10.08.99 fixing merge errors
- * 0.4 13.08.99 Added Vendor/Product ID of Brad Hard's cable
- * 0.5 20.09.99 usb_control_msg wrapper used
- * Nov01.00 usb_device_table support by Adam J. Richter
- * 08.04.01 Identify version on module load. gb
+ * 0.1 04.08.1999 Created
+ * 0.2 07.08.1999 Some fixes mainly suggested by Tim Waugh
+ * Interrupt handling currently disabled because
+ * usb_request_irq crashes somewhere within ohci.c
+ * for no apparent reason (that is for me, anyway)
+ * ECP currently untested
+ * 0.3 10.08.1999 fixing merge errors
+ * 0.4 13.08.1999 Added Vendor/Product ID of Brad Hard's cable
+ * 0.5 20.09.1999 usb_control_msg wrapper used
+ * Nov01.2000 usb_device_table support by Adam J. Richter
+ * 08.04.2001 Identify version on module load. gb
+ * 0.6 02.09.2005 Fix "scheduling in interrupt" problem by making save/restore
+ * context asynchronous
*
*/
/*****************************************************************************/
+#define DEBUG
+
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/parport.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/kref.h>
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.5"
-#define DRIVER_AUTHOR "Thomas M. Sailer, sailer@ife.ee.ethz.ch"
+#define DRIVER_VERSION "v0.6"
+#define DRIVER_AUTHOR "Thomas M. Sailer, t.sailer@alumni.ethz.ch"
#define DRIVER_DESC "USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip"
/* --------------------------------------------------------------------- */
struct parport_uss720_private {
struct usb_device *usbdev;
- void *irqhandle;
- unsigned int irqpipe;
- unsigned char reg[7]; /* USB registers */
+ struct parport *pp;
+ struct kref ref_count;
+ __u8 reg[7]; /* USB registers */
+ struct list_head asynclist;
+ spinlock_t asynclock;
+};
+
+struct uss720_async_request {
+ struct parport_uss720_private *priv;
+ struct kref ref_count;
+ struct list_head asynclist;
+ struct completion compl;
+ struct urb *urb;
+ struct usb_ctrlrequest dr;
+ __u8 reg[7];
};
/* --------------------------------------------------------------------- */
-static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val)
+static void destroy_priv(struct kref *kref)
{
- struct parport_uss720_private *priv = pp->private_data;
- struct usb_device *usbdev = priv->usbdev;
- static const unsigned char regindex[9] = {
- 4, 0, 1, 5, 5, 0, 2, 3, 6
- };
- int ret;
+ struct parport_uss720_private *priv = container_of(kref, struct parport_uss720_private, ref_count);
- if (!usbdev)
- return -1;
- ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), 3, 0xc0, ((unsigned int)reg) << 8, 0, priv->reg, 7, 1000);
- if (ret != 7) {
- printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status 0x%x expected 7\n",
- (unsigned int)reg, ret);
- ret = -1;
- } else {
+ usb_put_dev(priv->usbdev);
+ kfree(priv);
+ dbg("destroying priv datastructure");
+}
+
+static void destroy_async(struct kref *kref)
+{
+ struct uss720_async_request *rq = container_of(kref, struct uss720_async_request, ref_count);
+ struct parport_uss720_private *priv = rq->priv;
+ unsigned long flags;
+
+ if (likely(rq->urb))
+ usb_free_urb(rq->urb);
+ spin_lock_irqsave(&priv->asynclock, flags);
+ list_del_init(&rq->asynclist);
+ spin_unlock_irqrestore(&priv->asynclock, flags);
+ kfree(rq);
+ kref_put(&priv->ref_count, destroy_priv);
+}
+
+/* --------------------------------------------------------------------- */
+
+static void async_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+ struct uss720_async_request *rq;
+ struct parport *pp;
+ struct parport_uss720_private *priv;
+
+ rq = urb->context;
+ priv = rq->priv;
+ pp = priv->pp;
+ if (urb->status) {
+ err("async_complete: urb error %d", urb->status);
+ } else if (rq->dr.bRequest == 3) {
+ memcpy(priv->reg, rq->reg, sizeof(priv->reg));
#if 0
- printk(KERN_DEBUG "uss720: get_1284_register(%d) return %02x %02x %02x %02x %02x %02x %02x\n",
- (unsigned int)reg, (unsigned int)priv->reg[0], (unsigned int)priv->reg[1],
- (unsigned int)priv->reg[2], (unsigned int)priv->reg[3], (unsigned int)priv->reg[4],
- (unsigned int)priv->reg[5], (unsigned int)priv->reg[6]);
+ dbg("async_complete regs %02x %02x %02x %02x %02x %02x %02x",
+ (unsigned int)priv->reg[0], (unsigned int)priv->reg[1], (unsigned int)priv->reg[2],
+ (unsigned int)priv->reg[3], (unsigned int)priv->reg[4], (unsigned int)priv->reg[5],
+ (unsigned int)priv->reg[6]);
#endif
/* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
- if (priv->reg[2] & priv->reg[1] & 0x10)
+ if (rq->reg[2] & rq->reg[1] & 0x10 && pp)
parport_generic_irq(0, pp, NULL);
- ret = 0;
}
- if (val)
- *val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
- return ret;
+ complete(&rq->compl);
+ kref_put(&rq->ref_count, destroy_async);
}
-static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val)
+static struct uss720_async_request *submit_async_request(struct parport_uss720_private *priv,
+ __u8 request, __u8 requesttype, __u16 value, __u16 index,
+ gfp_t mem_flags)
{
- struct parport_uss720_private *priv = pp->private_data;
- struct usb_device *usbdev = priv->usbdev;
+ struct usb_device *usbdev;
+ struct uss720_async_request *rq;
+ unsigned long flags;
int ret;
+ if (!priv)
+ return NULL;
+ usbdev = priv->usbdev;
if (!usbdev)
- return -1;
- ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev,0), 4, 0x40, (((unsigned int)reg) << 8) | val, 0, NULL, 0, 1000);
- if (ret) {
- printk(KERN_DEBUG "uss720: set_1284_register(%u,0x%02x) failed, status 0x%x\n",
- (unsigned int)reg, (unsigned int)val, ret);
- } else {
-#if 0
- printk(KERN_DEBUG "uss720: set_1284_register(%u,0x%02x)\n",
- (unsigned int)reg, (unsigned int)val);
-#endif
+ return NULL;
+ rq = kmalloc(sizeof(struct uss720_async_request), mem_flags);
+ if (!rq) {
+ err("submit_async_request out of memory");
+ return NULL;
+ }
+ kref_init(&rq->ref_count);
+ INIT_LIST_HEAD(&rq->asynclist);
+ init_completion(&rq->compl);
+ kref_get(&priv->ref_count);
+ rq->priv = priv;
+ rq->urb = usb_alloc_urb(0, mem_flags);
+ if (!rq->urb) {
+ kref_put(&rq->ref_count, destroy_async);
+ err("submit_async_request out of memory");
+ return NULL;
+ }
+ rq->dr.bRequestType = requesttype;
+ rq->dr.bRequest = request;
+ rq->dr.wValue = cpu_to_le16(value);
+ rq->dr.wIndex = cpu_to_le16(index);
+ rq->dr.wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0);
+ usb_fill_control_urb(rq->urb, usbdev, (requesttype & 0x80) ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0),
+ (unsigned char *)&rq->dr,
+ (request == 3) ? rq->reg : NULL, (request == 3) ? sizeof(rq->reg) : 0, async_complete, rq);
+ /* rq->urb->transfer_flags |= URB_ASYNC_UNLINK; */
+ spin_lock_irqsave(&priv->asynclock, flags);
+ list_add_tail(&rq->asynclist, &priv->asynclist);
+ spin_unlock_irqrestore(&priv->asynclock, flags);
+ ret = usb_submit_urb(rq->urb, mem_flags);
+ if (!ret) {
+ kref_get(&rq->ref_count);
+ return rq;
}
+ kref_put(&rq->ref_count, destroy_async);
+ err("submit_async_request submit_urb failed with %d", ret);
+ return NULL;
+}
+
+static unsigned int kill_all_async_requests_priv(struct parport_uss720_private *priv)
+{
+ struct uss720_async_request *rq;
+ unsigned long flags;
+ unsigned int ret = 0;
+
+ spin_lock_irqsave(&priv->asynclock, flags);
+ list_for_each_entry(rq, &priv->asynclist, asynclist) {
+ usb_unlink_urb(rq->urb);
+ ret++;
+ }
+ spin_unlock_irqrestore(&priv->asynclock, flags);
return ret;
}
/* --------------------------------------------------------------------- */
+static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, gfp_t mem_flags)
+{
+ struct parport_uss720_private *priv;
+ struct uss720_async_request *rq;
+ static const unsigned char regindex[9] = {
+ 4, 0, 1, 5, 5, 0, 2, 3, 6
+ };
+ int ret;
+
+ if (!pp)
+ return -EIO;
+ priv = pp->private_data;
+ rq = submit_async_request(priv, 3, 0xc0, ((unsigned int)reg) << 8, 0, mem_flags);
+ if (!rq) {
+ err("get_1284_register(%u) failed", (unsigned int)reg);
+ return -EIO;
+ }
+ if (!val) {
+ kref_put(&rq->ref_count, destroy_async);
+ return 0;
+ }
+ if (wait_for_completion_timeout(&rq->compl, HZ)) {
+ ret = rq->urb->status;
+ *val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
+ if (ret)
+ warn("get_1284_register: usb error %d", ret);
+ kref_put(&rq->ref_count, destroy_async);
+ return ret;
+ }
+ warn("get_1284_register timeout");
+ kill_all_async_requests_priv(priv);
+ return -EIO;
+}
+
+static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, gfp_t mem_flags)
+{
+ struct parport_uss720_private *priv;
+ struct uss720_async_request *rq;
+
+ if (!pp)
+ return -EIO;
+ priv = pp->private_data;
+ rq = submit_async_request(priv, 4, 0x40, (((unsigned int)reg) << 8) | val, 0, mem_flags);
+ if (!rq) {
+ err("set_1284_register(%u,%u) failed", (unsigned int)reg, (unsigned int)val);
+ return -EIO;
+ }
+ kref_put(&rq->ref_count, destroy_async);
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
/* ECR modes */
#define ECR_SPP 00
#define ECR_PS2 01
@@ -132,8 +269,9 @@ static int change_mode(struct parport *pp, int m)
{
struct parport_uss720_private *priv = pp->private_data;
int mode;
+ __u8 reg;
- if (get_1284_register(pp, 6, NULL))
+ if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
return -EIO;
/* Bits <7:5> contain the mode. */
mode = (priv->reg[2] >> 5) & 0x7;
@@ -153,7 +291,7 @@ static int change_mode(struct parport *pp, int m)
case ECR_ECP: /* ECP Parallel Port mode */
/* Poll slowly. */
for (;;) {
- if (get_1284_register(pp, 6, NULL))
+ if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
return -EIO;
if (priv->reg[2] & 0x01)
break;
@@ -167,7 +305,9 @@ static int change_mode(struct parport *pp, int m)
}
}
/* Set the mode. */
- if (set_1284_register(pp, 6, m << 5))
+ if (set_1284_register(pp, 6, m << 5, GFP_KERNEL))
+ return -EIO;
+ if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
return -EIO;
return 0;
}
@@ -179,7 +319,7 @@ static int clear_epp_timeout(struct parport *pp)
{
unsigned char stat;
- if (get_1284_register(pp, 1, &stat))
+ if (get_1284_register(pp, 1, &stat, GFP_KERNEL))
return 1;
return stat & 1;
}
@@ -205,14 +345,14 @@ static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
static void parport_uss720_write_data(struct parport *pp, unsigned char d)
{
- set_1284_register(pp, 0, d);
+ set_1284_register(pp, 0, d, GFP_KERNEL);
}
static unsigned char parport_uss720_read_data(struct parport *pp)
{
unsigned char ret;
- if (get_1284_register(pp, 0, &ret))
+ if (get_1284_register(pp, 0, &ret, GFP_KERNEL))
return 0;
return ret;
}
@@ -222,7 +362,7 @@ static void parport_uss720_write_control(struct parport *pp, unsigned char d)
struct parport_uss720_private *priv = pp->private_data;
d = (d & 0xf) | (priv->reg[1] & 0xf0);
- if (set_1284_register(pp, 2, d))
+ if (set_1284_register(pp, 2, d, GFP_KERNEL))
return;
priv->reg[1] = d;
}
@@ -241,7 +381,7 @@ static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned ch
mask &= 0x0f;
val &= 0x0f;
d = (priv->reg[1] & (~mask)) ^ val;
- if (set_1284_register(pp, 2, d))
+ if (set_1284_register(pp, 2, d, GFP_KERNEL))
return 0;
priv->reg[1] = d;
return d & 0xf;
@@ -251,7 +391,7 @@ static unsigned char parport_uss720_read_status(struct parport *pp)
{
unsigned char ret;
- if (get_1284_register(pp, 1, &ret))
+ if (get_1284_register(pp, 1, &ret, GFP_KERNEL))
return 0;
return ret & 0xf8;
}
@@ -262,7 +402,7 @@ static void parport_uss720_disable_irq(struct parport *pp)
unsigned char d;
d = priv->reg[1] & ~0x10;
- if (set_1284_register(pp, 2, d))
+ if (set_1284_register(pp, 2, d, GFP_KERNEL))
return;
priv->reg[1] = d;
}
@@ -273,7 +413,7 @@ static void parport_uss720_enable_irq(struct parport *pp)
unsigned char d;
d = priv->reg[1] | 0x10;
- if (set_1284_register(pp, 2, d))
+ if (set_1284_register(pp, 2, d, GFP_KERNEL))
return;
priv->reg[1] = d;
}
@@ -284,7 +424,7 @@ static void parport_uss720_data_forward (struct parport *pp)
unsigned char d;
d = priv->reg[1] & ~0x20;
- if (set_1284_register(pp, 2, d))
+ if (set_1284_register(pp, 2, d, GFP_KERNEL))
return;
priv->reg[1] = d;
}
@@ -295,7 +435,7 @@ static void parport_uss720_data_reverse (struct parport *pp)
unsigned char d;
d = priv->reg[1] | 0x20;
- if (set_1284_register(pp, 2, d))
+ if (set_1284_register(pp, 2, d, GFP_KERNEL))
return;
priv->reg[1] = d;
}
@@ -310,17 +450,23 @@ static void parport_uss720_save_state(struct parport *pp, struct parport_state *
{
struct parport_uss720_private *priv = pp->private_data;
- if (get_1284_register(pp, 2, NULL))
+#if 0
+ if (get_1284_register(pp, 2, NULL, GFP_ATOMIC))
return;
+#endif
s->u.pc.ctr = priv->reg[1];
s->u.pc.ecr = priv->reg[2];
}
static void parport_uss720_restore_state(struct parport *pp, struct parport_state *s)
{
- set_1284_register(pp, 2, s->u.pc.ctr);
- set_1284_register(pp, 6, s->u.pc.ecr);
- get_1284_register(pp, 2, NULL);
+ struct parport_uss720_private *priv = pp->private_data;
+
+ set_1284_register(pp, 2, s->u.pc.ctr, GFP_ATOMIC);
+ set_1284_register(pp, 6, s->u.pc.ecr, GFP_ATOMIC);
+ get_1284_register(pp, 2, NULL, GFP_ATOMIC);
+ priv->reg[1] = s->u.pc.ctr;
+ priv->reg[2] = s->u.pc.ecr;
}
static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t length, int flags)
@@ -331,7 +477,7 @@ static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t
if (change_mode(pp, ECR_EPP))
return 0;
for (; got < length; got++) {
- if (get_1284_register(pp, 4, (char *)buf))
+ if (get_1284_register(pp, 4, (char *)buf, GFP_KERNEL))
break;
buf++;
if (priv->reg[0] & 0x01) {
@@ -352,10 +498,10 @@ static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf,
if (change_mode(pp, ECR_EPP))
return 0;
for (; written < length; written++) {
- if (set_1284_register(pp, 4, (char *)buf))
+ if (set_1284_register(pp, 4, (char *)buf, GFP_KERNEL))
break;
((char*)buf)++;
- if (get_1284_register(pp, 1, NULL))
+ if (get_1284_register(pp, 1, NULL, GFP_KERNEL))
break;
if (priv->reg[0] & 0x01) {
clear_epp_timeout(pp);
@@ -390,7 +536,7 @@ static size_t parport_uss720_epp_read_addr(struct parport *pp, void *buf, size_t
if (change_mode(pp, ECR_EPP))
return 0;
for (; got < length; got++) {
- if (get_1284_register(pp, 3, (char *)buf))
+ if (get_1284_register(pp, 3, (char *)buf, GFP_KERNEL))
break;
buf++;
if (priv->reg[0] & 0x01) {
@@ -410,10 +556,10 @@ static size_t parport_uss720_epp_write_addr(struct parport *pp, const void *buf,
if (change_mode(pp, ECR_EPP))
return 0;
for (; written < length; written++) {
- if (set_1284_register(pp, 3, *(char *)buf))
+ if (set_1284_register(pp, 3, *(char *)buf, GFP_KERNEL))
break;
buf++;
- if (get_1284_register(pp, 1, NULL))
+ if (get_1284_register(pp, 1, NULL, GFP_KERNEL))
break;
if (priv->reg[0] & 0x01) {
clear_epp_timeout(pp);
@@ -467,7 +613,7 @@ static size_t parport_uss720_ecp_write_addr(struct parport *pp, const void *buff
if (change_mode(pp, ECR_ECP))
return 0;
for (; written < len; written++) {
- if (set_1284_register(pp, 5, *(char *)buffer))
+ if (set_1284_register(pp, 5, *(char *)buffer, GFP_KERNEL))
break;
buffer++;
}
@@ -536,93 +682,91 @@ static struct parport_operations parport_uss720_ops =
static int uss720_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- struct usb_device *usbdev = interface_to_usbdev(intf);
+ struct usb_device *usbdev = usb_get_dev(interface_to_usbdev(intf));
struct usb_host_interface *interface;
struct usb_host_endpoint *endpoint;
struct parport_uss720_private *priv;
struct parport *pp;
+ unsigned char reg;
int i;
- printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n",
- le16_to_cpu(usbdev->descriptor.idVendor),
- le16_to_cpu(usbdev->descriptor.idProduct));
+ dbg("probe: vendor id 0x%x, device id 0x%x\n",
+ le16_to_cpu(usbdev->descriptor.idVendor),
+ le16_to_cpu(usbdev->descriptor.idProduct));
/* our known interfaces have 3 alternate settings */
- if (intf->num_altsetting != 3)
+ if (intf->num_altsetting != 3) {
+ usb_put_dev(usbdev);
return -ENODEV;
-
+ }
i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2);
- printk(KERN_DEBUG "uss720: set inteface result %d\n", i);
+ dbg("set inteface result %d", i);
interface = intf->cur_altsetting;
/*
* Allocate parport interface
*/
- printk(KERN_INFO "uss720: (C) 1999 by Thomas Sailer, <sailer@ife.ee.ethz.ch>\n");
-
- if (!(priv = kmalloc(sizeof(struct parport_uss720_private), GFP_KERNEL)))
+ if (!(priv = kcalloc(sizeof(struct parport_uss720_private), 1, GFP_KERNEL))) {
+ usb_put_dev(usbdev);
return -ENOMEM;
+ }
+ priv->pp = NULL;
+ priv->usbdev = usbdev;
+ kref_init(&priv->ref_count);
+ spin_lock_init(&priv->asynclock);
+ INIT_LIST_HEAD(&priv->asynclist);
if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) {
- printk(KERN_WARNING "usb-uss720: could not register parport\n");
+ warn("could not register parport");
goto probe_abort;
}
+ priv->pp = pp;
pp->private_data = priv;
- priv->usbdev = usbdev;
pp->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP | PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
/* set the USS720 control register to manual mode, no ECP compression, enable all ints */
- set_1284_register(pp, 7, 0x00);
- set_1284_register(pp, 6, 0x30); /* PS/2 mode */
- set_1284_register(pp, 2, 0x0c);
+ set_1284_register(pp, 7, 0x00, GFP_KERNEL);
+ set_1284_register(pp, 6, 0x30, GFP_KERNEL); /* PS/2 mode */
+ set_1284_register(pp, 2, 0x0c, GFP_KERNEL);
/* debugging */
- get_1284_register(pp, 0, NULL);
- printk("uss720: reg: %02x %02x %02x %02x %02x %02x %02x\n",
- priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], priv->reg[4], priv->reg[5], priv->reg[6]);
+ get_1284_register(pp, 0, &reg, GFP_KERNEL);
+ dbg("reg: %02x %02x %02x %02x %02x %02x %02x",
+ priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], priv->reg[4], priv->reg[5], priv->reg[6]);
endpoint = &interface->endpoint[2];
- printk(KERN_DEBUG "uss720: epaddr %d interval %d\n", endpoint->desc.bEndpointAddress, endpoint->desc.bInterval);
-#if 0
- priv->irqpipe = usb_rcvctrlpipe(usbdev, endpoint->bEndpointAddress);
- i = usb_request_irq(usbdev, priv->irqpipe,
- uss720_irq, endpoint->bInterval,
- pp, &priv->irqhandle);
- if (i) {
- printk (KERN_WARNING "usb-uss720: usb_request_irq failed (0x%x)\n", i);
- goto probe_abort_port;
- }
-#endif
+ dbg("epaddr %d interval %d", endpoint->desc.bEndpointAddress, endpoint->desc.bInterval);
parport_announce_port(pp);
- usb_set_intfdata (intf, pp);
+ usb_set_intfdata(intf, pp);
return 0;
-#if 0
-probe_abort_port:
- parport_put_port(pp);
-#endif
probe_abort:
- kfree(priv);
+ kill_all_async_requests_priv(priv);
+ kref_put(&priv->ref_count, destroy_priv);
return -ENODEV;
}
static void uss720_disconnect(struct usb_interface *intf)
{
- struct parport *pp = usb_get_intfdata (intf);
+ struct parport *pp = usb_get_intfdata(intf);
struct parport_uss720_private *priv;
+ struct usb_device *usbdev;
- usb_set_intfdata (intf, NULL);
+ dbg("disconnect");
+ usb_set_intfdata(intf, NULL);
if (pp) {
priv = pp->private_data;
- parport_remove_port(pp);
-#if 0
- usb_release_irq(usbdev, priv->irqhandle, priv->irqpipe);
-#endif
+ usbdev = priv->usbdev;
priv->usbdev = NULL;
+ priv->pp = NULL;
+ dbg("parport_remove_port");
+ parport_remove_port(pp);
parport_put_port(pp);
- kfree(priv);
+ kill_all_async_requests_priv(priv);
+ kref_put(&priv->ref_count, destroy_priv);
}
+ dbg("disconnect done");
}
/* table of cables that work through this driver */
@@ -647,8 +791,8 @@ static struct usb_driver uss720_driver = {
/* --------------------------------------------------------------------- */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static int __init uss720_init(void)
@@ -659,6 +803,9 @@ static int __init uss720_init(void)
goto out;
info(DRIVER_VERSION ":" DRIVER_DESC);
+ info("NOTE: this is a special purpose driver to allow nonstandard");
+ info("protocols (eg. bitbang) over USS720 usb to parallel cables");
+ info("If you just want to connect to a printer, use usblp instead");
out:
return retval;
}
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile
index b0015b8a1d1f..3cf3ea3a88ed 100644
--- a/drivers/usb/mon/Makefile
+++ b/drivers/usb/mon/Makefile
@@ -2,7 +2,7 @@
# 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 000000000000..0a1367b760a0
--- /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 26266b30028e..17d0190ef64e 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -79,7 +79,7 @@ static inline char mon_text_get_setup(struct mon_event_text *ep,
return '-';
if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)
- return 'D';
+ return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX);
if (urb->setup_packet == NULL)
return 'Z'; /* '0' would be not as pretty. */
@@ -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 9b06784d2c48..4be0f9346071 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 b104430e2c6a..8c010bb44eb8 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 fe3fd4115e1e..222c0495f791 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 000000000000..252a34fbb42c
--- /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,
+ gfp_t 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 c8be912f24e1..37ef365a2472 100644
--- a/drivers/usb/net/catc.c
+++ b/drivers/usb/net/catc.c
@@ -383,7 +383,6 @@ static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
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 000000000000..652b04bbf6af
--- /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 000000000000..f1730b685fd2
--- /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 000000000000..c0f263b202a6
--- /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, gfp_t 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 7ffa99b9760f..c82655d3d448 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -477,13 +477,13 @@ static int kaweth_reset(struct kaweth_device *kaweth)
}
static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
-static int kaweth_resubmit_rx_urb(struct kaweth_device *, unsigned);
+static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);
/****************************************************************
int_callback
*****************************************************************/
-static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, int mf)
+static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf)
{
int status;
@@ -550,7 +550,7 @@ static void kaweth_resubmit_tl(void *d)
* kaweth_resubmit_rx_urb
****************************************************************/
static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
int result;
@@ -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 000000000000..cee55f8cf64f
--- /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, gfp_t 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 fcd6d3ccef44..6a4ffe6c3977 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -648,6 +648,13 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
}
/*
+ * If the packet is unreasonably long, quietly drop it rather than
+ * kernel panicing by calling skb_put.
+ */
+ if (pkt_len > PEGASUS_MTU)
+ goto goon;
+
+ /*
* at this point we are sure pegasus->rx_skb != NULL
* so we go ahead and pass up the packet.
*/
@@ -825,7 +832,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++;
}
@@ -887,15 +893,17 @@ static inline void get_interrupt_interval(pegasus_t * pegasus)
__u8 data[2];
read_eprom_word(pegasus, 4, (__u16 *) data);
- if (data[1] < 0x80) {
- if (netif_msg_timer(pegasus))
- dev_info(&pegasus->intf->dev,
- "intr interval changed from %ums to %ums\n",
- data[1], 0x80);
- data[1] = 0x80;
-#ifdef PEGASUS_WRITE_EEPROM
- write_eprom_word(pegasus, 4, *(__u16 *) data);
+ if (pegasus->usb->speed != USB_SPEED_HIGH) {
+ if (data[1] < 0x80) {
+ if (netif_msg_timer(pegasus))
+ dev_info(&pegasus->intf->dev, "intr interval "
+ "changed from %ums to %ums\n",
+ data[1], 0x80);
+ data[1] = 0x80;
+#ifdef PEGASUS_WRITE_EEPROM
+ write_eprom_word(pegasus, 4, *(__u16 *) data);
#endif
+ }
}
pegasus->intr_interval = data[1];
}
@@ -905,8 +913,9 @@ static void set_carrier(struct net_device *net)
pegasus_t *pegasus = netdev_priv(net);
u16 tmp;
- if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
+ if (!read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
return;
+
if (tmp & BMSR_LSTATUS)
netif_carrier_on(net);
else
@@ -1356,6 +1365,7 @@ static void pegasus_disconnect(struct usb_interface *intf)
cancel_delayed_work(&pegasus->carrier_check);
unregister_netdev(pegasus->net);
usb_put_dev(interface_to_usbdev(intf));
+ unlink_all_urbs(pegasus);
free_all_urbs(pegasus);
free_skb_pool(pegasus);
if (pegasus->rx_skb)
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
new file mode 100644
index 000000000000..74c2b3581c76
--- /dev/null
+++ b/drivers/usb/net/plusb.c
@@ -0,0 +1,156 @@
+/*
+ * 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 000000000000..b5a925dc1beb
--- /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, gfp_t 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 59ab40ebb394..c3d4e3589e30 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -653,7 +653,6 @@ static void rtl8150_tx_timeout(struct net_device *netdev)
{
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 a2f67245f6da..fce81d738933 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, gfp_t 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 000000000000..89fc4958eecf
--- /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, gfp_t 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 000000000000..5d4b7d55b097
--- /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, gfp_t 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 fc013978837e..2f52261c7cc1 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -521,7 +521,7 @@ static int zd1201_setconfig(struct zd1201 *zd, int rid, void *buf, int len, int
int reqlen;
char seq=0;
struct urb *urb;
- unsigned int gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
+ gfp_t gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
len += 4; /* first 4 are for header */
@@ -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/airprime.c b/drivers/usb/serial/airprime.c
index a4ce0008d69b..926d4c2c1600 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -16,7 +16,8 @@
#include "usb-serial.h"
static struct usb_device_id id_table [] = {
- { USB_DEVICE(0xf3d, 0x0112) },
+ { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */
+ { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 4ace9964fc6b..97c78c21e8d1 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -32,7 +32,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.04"
+#define DRIVER_VERSION "v0.05"
#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
/*
@@ -54,8 +54,11 @@ static void cp2101_shutdown(struct usb_serial*);
static int debug;
static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
+ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
+ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
{ } /* Terminating Entry */
};
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 012e63e05806..9ee1aaff2fcd 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 */
@@ -608,8 +610,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
timeout = max((HZ*2560)/bps,HZ/10);
else
timeout = 2*HZ;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(timeout);
+ schedule_timeout_interruptible(timeout);
dbg("%s - stopping urbs", __FUNCTION__);
usb_kill_urb (port->interrupt_in_urb);
@@ -909,7 +910,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 +920,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 +933,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 +950,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 +969,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 +1011,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 +1102,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 +1130,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 +1152,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 +1165,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 +1174,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 +1199,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 +1259,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 +1270,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 d1964a0c4168..5a8631c8a4a7 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);
@@ -874,7 +914,7 @@ static void ftdi_determine_type(struct usb_serial_port *port)
unsigned interfaces;
/* Assume it is not the original SIO device for now. */
- priv->baud_base = 48000000 / 16;
+ priv->baud_base = 48000000 / 2;
priv->write_offset = 0;
version = le16_to_cpu(udev->descriptor.bcdDevice);
@@ -1806,10 +1846,12 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
} else {
/* set the baudrate determined before */
if (change_speed(port)) {
- err("%s urb failed to set baurdrate", __FUNCTION__);
+ err("%s urb failed to set baudrate", __FUNCTION__);
+ }
+ /* Ensure RTS and DTR are raised when baudrate changed from 0 */
+ if ((old_termios->c_cflag & CBAUD) == B0) {
+ set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
}
- /* Ensure RTS and DTR are raised */
- set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
}
/* Set flow control */
@@ -2030,6 +2072,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 +2117,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 9f4342093e8b..2c35d74cc6d6 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/generic.c b/drivers/usb/serial/generic.c
index ddde5fb13f6b..5f7d3193d355 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -223,7 +223,7 @@ int usb_serial_generic_write_room (struct usb_serial_port *port)
dbg("%s - port %d", __FUNCTION__, port->number);
if (serial->num_bulk_out) {
- if (port->write_urb_busy)
+ if (!(port->write_urb_busy))
room = port->bulk_out_size;
}
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index fb0926292228..3b958e60f5e8 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -383,11 +383,8 @@ static int keyspan_write(struct usb_serial_port *port,
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 e9256408757f..4989e5740d18 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -25,6 +25,9 @@
2005-06-20 v0.4.1 add missing braces :-/
killed end-of-line whitespace
2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
+ 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard
+ 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes
+ wants to send >2000 bytes.
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
@@ -45,42 +48,47 @@
#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
+#define HUAWEI_VENDOR_ID 0x12D1
+#define AUDIOVOX_VENDOR_ID 0x0F3D
#define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_FUSION 0x6000
#define OPTION_PRODUCT_FUSION2 0x6300
-
+#define HUAWEI_PRODUCT_E600 0x1001
+#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
+ { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
+ { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ } /* Terminating entry */
};
@@ -129,12 +137,11 @@ static int debug;
#define debug 0
#endif
-
/* per port private data */
#define N_IN_URB 4
#define N_OUT_URB 1
-#define IN_BUFLEN 1024
+#define IN_BUFLEN 4096
#define OUT_BUFLEN 128
struct option_port_private {
@@ -156,10 +163,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 +184,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 +193,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 +234,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 +253,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 +282,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 +317,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 +350,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 +369,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 +387,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 +402,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 +417,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 +441,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 +459,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 +480,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 +505,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 +516,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 +546,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 +571,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 +597,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 +613,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 +632,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 +646,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 +655,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 7eab5d4cf3a8..3cf245bdda54 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -95,6 +95,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
+ { USB_DEVICE( NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) },
{ } /* Terminating entry */
};
@@ -538,8 +539,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)
@@ -650,8 +653,7 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
timeout = max((HZ*2560)/bps,HZ/10);
else
timeout = 2*HZ;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(timeout);
+ schedule_timeout_interruptible(timeout);
/* shutdown our urbs */
dbg("%s - shutting down urbs", __FUNCTION__);
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index b734c4003c5a..7be9644f5a03 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -58,3 +58,7 @@
#define SYNTECH_VENDOR_ID 0x0745
#define SYNTECH_PRODUCT_ID 0x0001
+
+/* Nokia CA-42 Cable */
+#define NOKIA_CA42_VENDOR_ID 0x078b
+#define NOKIA_CA42_PRODUCT_ID 0x1234
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0267b26dde18..e77fbdfc782d 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -531,7 +531,7 @@ bailout_kref_put:
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 f1f1c0608c22..bb9819cc8826 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 56652ccc2881..44ab8f9978fe 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -18,6 +18,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
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 000000000000..2c9402dc702b
--- /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 000000000000..41c7aa8f0446
--- /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 af294bb68c35..4837524eada7 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
@@ -219,42 +227,42 @@ static int queuecommand(struct scsi_cmnd *srb,
***********************************************************************/
/* Command timeout and abort */
-/* This is always called with scsi_lock(host) held */
static int command_abort(struct scsi_cmnd *srb)
{
struct us_data *us = host_to_us(srb->device->host);
US_DEBUGP("%s called\n", __FUNCTION__);
+ /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING
+ * bits are protected by the host lock. */
+ scsi_lock(us_to_host(us));
+
/* Is this command still active? */
if (us->srb != srb) {
+ scsi_unlock(us_to_host(us));
US_DEBUGP ("-- nothing to abort\n");
return FAILED;
}
/* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if
* a device reset isn't already in progress (to avoid interfering
- * with the reset). To prevent races with auto-reset, we must
- * stop any ongoing USB transfers while still holding the host
- * lock. */
+ * with the reset). Note that we must retain the host lock while
+ * calling usb_stor_stop_transport(); otherwise it might interfere
+ * with an auto-reset that begins as soon as we release the lock. */
set_bit(US_FLIDX_TIMED_OUT, &us->flags);
if (!test_bit(US_FLIDX_RESETTING, &us->flags)) {
set_bit(US_FLIDX_ABORTING, &us->flags);
usb_stor_stop_transport(us);
}
+ scsi_unlock(us_to_host(us));
/* Wait for the aborted command to finish */
wait_for_completion(&us->notify);
-
- /* Reacquire the lock and allow USB transfers to resume */
- clear_bit(US_FLIDX_ABORTING, &us->flags);
- clear_bit(US_FLIDX_TIMED_OUT, &us->flags);
return SUCCESS;
}
/* This invokes the transport reset mechanism to reset the state of the
* device */
-/* This is always called with scsi_lock(host) held */
static int device_reset(struct scsi_cmnd *srb)
{
struct us_data *us = host_to_us(srb->device->host);
@@ -271,7 +279,6 @@ static int device_reset(struct scsi_cmnd *srb)
}
/* Simulate a SCSI bus reset by resetting the device's USB port. */
-/* This is always called with scsi_lock(host) held */
static int bus_reset(struct scsi_cmnd *srb)
{
struct us_data *us = host_to_us(srb->device->host);
@@ -283,7 +290,6 @@ static int bus_reset(struct scsi_cmnd *srb)
result = usb_stor_port_reset(us);
up(&(us->dev_semaphore));
- /* lock the host for the return */
return result < 0 ? FAILED : SUCCESS;
}
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index f3b60288696c..356342c6e7a2 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -839,34 +839,31 @@ static int usbat_identify_device(struct us_data *us,
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 e6b1c6cf07f2..c1ba5301ebfc 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 bd0ab3039bdd..b79dad1b598c 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -79,6 +79,23 @@ 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 ),
+
+/* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
+ * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
+ * for USB floppies that need the SINGLE_LUN enforcement.
+ */
+UNUSUAL_DEV( 0x0409, 0x0040, 0x0000, 0x9999,
+ "NEC",
+ "NEC USB UF000x",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
+
/* 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.
@@ -89,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
+/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
+UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
+ "SMSC",
+ "FDC GOLD-2.30",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
+
#ifdef CONFIG_USB_STORAGE_DPCM
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech",
@@ -96,6 +120,24 @@ UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
#endif
+/*
+ * Pete Zaitcev <zaitcev@yahoo.com>, from Patrick C. F. Ernzer, bz#162559.
+ * The key does not actually break, but it returns zero sense which
+ * makes our SCSI stack to print confusing messages.
+ */
+UNUSUAL_DEV( 0x0457, 0x0150, 0x0100, 0x0100,
+ "USBest Technology", /* sold by Transcend */
+ "USB Mass Storage Device",
+ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
+
+/* Patch submitted by Daniel Drake <dsd@gentoo.org>
+ * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */
+UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100,
+ "Neuros Audio",
+ "USB 2.0 HD 2.5",
+ US_SC_DEVICE, US_PR_BULK, NULL,
+ US_FL_NEED_OVERRIDE ),
+
/* Patch submitted by Philipp Friedrich <philipp@void.at> */
UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
"Kyocera",
@@ -929,6 +971,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 77e7fc258aa2..f9a9bfa1aef5 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>");
@@ -390,11 +392,16 @@ SkipForAbort:
/* If an abort request was received we need to signal that
* the abort has finished. The proper test for this is
* the TIMED_OUT flag, not srb->result == DID_ABORT, because
- * a timeout/abort request might be received after all the
- * USB processing was complete. */
- if (test_bit(US_FLIDX_TIMED_OUT, &us->flags))
+ * the timeout might have occurred after the command had
+ * already completed with a different result code. */
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
complete(&(us->notify));
+ /* Allow USB transfers to resume */
+ clear_bit(US_FLIDX_ABORTING, &us->flags);
+ clear_bit(US_FLIDX_TIMED_OUT, &us->flags);
+ }
+
/* finished working on this command */
us->srb = NULL;
scsi_unlock(host);
@@ -786,6 +793,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 +824,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 +1007,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 +1020,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 +1030,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 625b7aa98074..a195adae57b6 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 cde0ed097af6..1cd942abb580 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -681,7 +681,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 +719,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 +752,13 @@ config FB_I810_GTF
If unsure, say N.
+config FB_I810_I2C
+ bool "Enable DDC Support"
+ depends on FB_I810 && FB_I810_GTF
+ select I2C
+ select I2C_ALGOBIT
+ help
+
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
@@ -960,8 +965,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 +1088,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 +1109,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 +1186,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 +1225,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 +1241,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 +1519,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 b018df4e95c8..1fff29f48ca8 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/amba-clcd.c b/drivers/video/amba-clcd.c
index 321dbe91dc14..cde6fd8eb390 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/list.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index b0eba3ac6420..e380ee8b0247 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -806,8 +806,8 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru
/* 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 3e10bd837d9e..037fe9d32fe3 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -911,20 +911,6 @@ static int aty_var_to_crtc(const struct fb_info *info,
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 e7e8b52014c3..8a24a66d9ba8 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 */
@@ -474,7 +475,7 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
*/
/* Flush PCI buffers ? */
- tmp = INREG(DEVICE_ID);
+ tmp = INREG16(DEVICE_ID);
local_irq_disable();
@@ -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/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 59a1b6f85067..097d668c4fe5 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -62,9 +62,9 @@ static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
OUTPLL(pllSCLK_CNTL, tmp);
return;
}
- /* RV350 (M10) */
+ /* RV350 (M10/M11) */
if (rinfo->family == CHIP_FAMILY_RV350) {
- /* for RV350/M10, no delays are required. */
+ /* for RV350/M10/M11, no delays are required. */
tmp = INPLL(pllSCLK_CNTL2);
tmp |= (SCLK_CNTL2__R300_FORCE_TCL |
SCLK_CNTL2__R300_FORCE_GA |
@@ -248,7 +248,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
return;
}
- /* M10 */
+ /* M10/M11 */
if (rinfo->family == CHIP_FAMILY_RV350) {
tmp = INPLL(pllSCLK_CNTL2);
tmp &= ~(SCLK_CNTL2__R300_FORCE_TCL |
@@ -1155,7 +1155,7 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
OUTREG( CRTC_GEN_CNTL, (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
- /* This is the code for the Aluminium PowerBooks M10 */
+ /* This is the code for the Aluminium PowerBooks M10 / iBooks M11 */
if (rinfo->family == CHIP_FAMILY_RV350) {
u32 sdram_mode_reg = rinfo->save_regs[35];
static u32 default_mrtable[] =
@@ -2741,9 +2741,11 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
rinfo->pm_mode |= radeon_pm_d2;
/* We can restart Jasper (M10 chip in albooks), BlueStone (7500 chip
- * in some desktop G4s), and Via (M9+ chip on iBook G4)
+ * in some desktop G4s), Via (M9+ chip on iBook G4) and
+ * Snowy (M11 chip on iBook G4 manufactured after July 2005)
*/
- if (!strcmp(rinfo->of_node->name, "ATY,JasperParent")) {
+ if (!strcmp(rinfo->of_node->name, "ATY,JasperParent") ||
+ !strcmp(rinfo->of_node->name, "ATY,SnowyParent")) {
rinfo->reinit_func = radeon_reinitialize_M10;
rinfo->pm_mode |= radeon_pm_off;
}
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 659bc9f62244..01b8b2f78514 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -395,6 +395,8 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
#define INREG8(addr) readb((rinfo->mmio_base)+addr)
#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
+#define INREG16(addr) readw((rinfo->mmio_base)+addr)
+#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr)
#define INREG(addr) readl((rinfo->mmio_base)+addr)
#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
diff --git a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c
index 92643af12581..a085cbf74ecb 100644
--- a/drivers/video/aty/xlinit.c
+++ b/drivers/video/aty/xlinit.c
@@ -174,7 +174,7 @@ int atyfb_xl_init(struct fb_info *info)
const struct xl_card_cfg_t * card = &card_cfg[xl_card];
struct atyfb_par *par = (struct atyfb_par *) info->par;
union aty_pll pll;
- int i, err;
+ int err;
u32 temp;
aty_st_8(CONFIG_STAT0, 0x85, par);
@@ -252,9 +252,14 @@ int atyfb_xl_init(struct fb_info *info)
aty_st_le32(0xEC, 0x00000000, par);
aty_st_le32(0xFC, 0x00000000, par);
- for (i=0; i<sizeof(lcd_tbl)/sizeof(lcd_tbl_t); i++) {
- aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);
+#if defined (CONFIG_FB_ATY_GENERIC_LCD)
+ {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lcd_tbl); i++)
+ aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);
}
+#endif
aty_st_le16(CONFIG_STAT0, 0x00A4, par);
mdelay(10);
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 353cb3f73cf2..3c72c627e65e 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -19,17 +19,17 @@
#include <linux/fb.h>
#include <linux/backlight.h>
-#include <asm/arch-pxa/corgi.h>
-#include <asm/hardware/scoop.h>
+#include <asm/arch/sharpsl.h>
-#define CORGI_MAX_INTENSITY 0x3e
#define CORGI_DEFAULT_INTENSITY 0x1f
-#define CORGI_LIMIT_MASK 0x0b
+#define CORGI_LIMIT_MASK 0x0b
static int corgibl_powermode = FB_BLANK_UNBLANK;
static int current_intensity = 0;
static int corgibl_limit = 0;
+static void (*corgibl_mach_set_intensity)(int intensity);
static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
+static struct backlight_properties corgibl_data;
static void corgibl_send_intensity(int intensity)
{
@@ -43,18 +43,10 @@ static void corgibl_send_intensity(int intensity)
intensity &= CORGI_LIMIT_MASK;
}
- /* Skip 0x20 as it will blank the display */
- if (intensity >= 0x20)
- intensity++;
-
spin_lock_irqsave(&bl_lock, flags);
- /* Bits 0-4 are accessed via the SSP interface */
- corgi_ssp_blduty_set(intensity & 0x1f);
- /* Bit 5 is via SCOOP */
- if (intensity & 0x0020)
- set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
- else
- reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+
+ corgibl_mach_set_intensity(intensity);
+
spin_unlock_irqrestore(&bl_lock, flags);
}
@@ -113,8 +105,8 @@ static int corgibl_get_power(struct backlight_device *bd)
static int corgibl_set_intensity(struct backlight_device *bd, int intensity)
{
- if (intensity > CORGI_MAX_INTENSITY)
- intensity = CORGI_MAX_INTENSITY;
+ if (intensity > corgibl_data.max_brightness)
+ intensity = corgibl_data.max_brightness;
corgibl_send_intensity(intensity);
current_intensity=intensity;
return 0;
@@ -141,7 +133,6 @@ static struct backlight_properties corgibl_data = {
.owner = THIS_MODULE,
.get_power = corgibl_get_power,
.set_power = corgibl_set_power,
- .max_brightness = CORGI_MAX_INTENSITY,
.get_brightness = corgibl_get_intensity,
.set_brightness = corgibl_set_intensity,
};
@@ -150,12 +141,18 @@ static struct backlight_device *corgi_backlight_device;
static int __init corgibl_probe(struct device *dev)
{
+ struct corgibl_machinfo *machinfo = dev->platform_data;
+
+ corgibl_data.max_brightness = machinfo->max_intensity;
+ corgibl_mach_set_intensity = machinfo->set_bl_intensity;
+
corgi_backlight_device = backlight_device_register ("corgi-bl",
NULL, &corgibl_data);
if (IS_ERR (corgi_backlight_device))
return PTR_ERR (corgi_backlight_device);
corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY);
+ corgibl_limit_intensity(0);
printk("Corgi Backlight Driver Initialized.\n");
return 0;
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 5fe182d6e4ab..eb83a7874c71 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -137,7 +137,7 @@ config FONT_8x8
config FONT_8x16
bool "VGA 8x16 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y
+ depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || USB_SISUSBVGA_CON
default y if !SPARC32 && !SPARC64 && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index b562f6bb9d31..42c7b8dcd220 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -33,6 +33,10 @@ endif
obj-$(CONFIG_FB_STI) += sticore.o font.o
+ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
+obj-$(CONFIG_USB_SISUSBVGA) += font.o
+endif
+
# Targets that kbuild needs to know about
targets := promcon_tbl.c
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 3c731577fed6..9f70e512b88b 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -39,7 +39,7 @@ static inline int get_attribute(struct fb_info *info, u16 c)
{
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 35c88bd7ba5e..0fc8bb499c3f 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);
}
@@ -736,7 +767,7 @@ static const char *fbcon_startup(void)
const char *display_desc = "frame buffer device";
struct display *p = &fb_display[fg_console];
struct vc_data *vc = vc_cons[fg_console].d;
- struct font_desc *font = NULL;
+ const struct font_desc *font = NULL;
struct module *owner;
struct fb_info *info = NULL;
struct fbcon_ops *ops;
@@ -810,7 +841,7 @@ static const char *fbcon_startup(void)
info->var.yres);
vc->vc_font.width = font->width;
vc->vc_font.height = font->height;
- vc->vc_font.data = p->fontdata = font->data;
+ vc->vc_font.data = (void *)(p->fontdata = font->data);
vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
}
@@ -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;
}
@@ -921,7 +941,7 @@ static void fbcon_init(struct vc_data *vc, int init)
fb, copy the font from that console */
t = &fb_display[svc->vc_num];
if (!vc->vc_font.data) {
- vc->vc_font.data = p->fontdata = t->fontdata;
+ vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
vc->vc_font.width = (*default_mode)->vc_font.width;
vc->vc_font.height = (*default_mode)->vc_font.height;
p->userfont = t->userfont;
@@ -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;
@@ -1168,7 +1188,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
return;
t = &fb_display[svc->vc_num];
if (!vc->vc_font.data) {
- vc->vc_font.data = p->fontdata = t->fontdata;
+ vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
vc->vc_font.width = (*default_mode)->vc_font.width;
vc->vc_font.height = (*default_mode)->vc_font.height;
p->userfont = t->userfont;
@@ -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;
@@ -1662,6 +1687,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
case SM_DOWN:
if (count > vc->vc_rows) /* Maximum realistic size */
count = vc->vc_rows;
+ if (logo_shown >= 0)
+ goto redraw_down;
switch (p->scrollmode) {
case SCROLL_MOVE:
ops->bmove(vc, info, t, 0, t + count, 0,
@@ -1898,7 +1925,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 +1958,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 +1987,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 +2078,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);
+ }
+
+ if (!blank)
+ fbcon_add_cursor_timer(info);
+ else
+ fbcon_del_cursor_timer(info);
- return 0;
+ return 0;
}
static void fbcon_free_font(struct display *p)
@@ -2115,7 +2150,7 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
}
static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
- u8 * data, int userfont)
+ const u8 * data, int userfont)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct display *p = &fb_display[vc->vc_num];
@@ -2133,7 +2168,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
cnt = FNTCHARCNT(data);
else
cnt = 256;
- vc->vc_font.data = p->fontdata = data;
+ vc->vc_font.data = (void *)(p->fontdata = data);
if ((p->userfont = userfont))
REFCOUNT(data)++;
vc->vc_font.width = w;
@@ -2290,7 +2325,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
tmp->vc_font.width == w &&
!memcmp(fb_display[i].fontdata, new_data, size)) {
kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
- new_data = fb_display[i].fontdata;
+ new_data = (u8 *)fb_display[i].fontdata;
break;
}
}
@@ -2300,7 +2335,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
- struct font_desc *f;
+ const struct font_desc *f;
if (!name)
f = get_default_font(info->var.xres, info->var.yres);
@@ -2332,7 +2367,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 +2628,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 +2788,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 5d377860bce2..0738cd62def2 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
@@ -29,7 +30,7 @@ struct display {
/* Filled in by the frame buffer device */
u_short inverse; /* != 0 text black on white as default */
/* Filled in by the low-level console driver */
- u_char *fontdata;
+ const u_char *fontdata;
int userfont; /* != 0 if fontdata kmalloc()ed */
u_short scrollmode; /* Scroll Method */
short yscroll; /* Hardware scrolling */
diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c
index ff0af96e4dfc..e6aa0eab5bb6 100644
--- a/drivers/video/console/font_10x18.c
+++ b/drivers/video/console/font_10x18.c
@@ -7,7 +7,7 @@
#define FONTDATAMAX 9216
-static unsigned char fontdata_10x18[FONTDATAMAX] = {
+static const unsigned char fontdata_10x18[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, 0x00, /* 0000000000 */
@@ -5132,7 +5132,7 @@ static unsigned char fontdata_10x18[FONTDATAMAX] = {
};
-struct font_desc font_10x18 = {
+const struct font_desc font_10x18 = {
FONT10x18_IDX,
"10x18",
10,
diff --git a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c
index c52f1294044a..89976cd97494 100644
--- a/drivers/video/console/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
@@ -8,7 +8,7 @@
#define FONTDATAMAX (11*256)
-static unsigned char fontdata_6x11[FONTDATAMAX] = {
+static const unsigned char fontdata_6x11[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -3341,7 +3341,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
};
-struct font_desc font_vga_6x11 = {
+const struct font_desc font_vga_6x11 = {
VGA6x11_IDX,
"ProFont6x11",
6,
diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c
index 1fa7fcf2ff72..bbf116647397 100644
--- a/drivers/video/console/font_7x14.c
+++ b/drivers/video/console/font_7x14.c
@@ -7,7 +7,7 @@
#define FONTDATAMAX 3584
-static unsigned char fontdata_7x14[FONTDATAMAX] = {
+static const unsigned char fontdata_7x14[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 0000000 */
@@ -4108,7 +4108,7 @@ static unsigned char fontdata_7x14[FONTDATAMAX] = {
};
-struct font_desc font_7x14 = {
+const struct font_desc font_7x14 = {
FONT7x14_IDX,
"7x14",
7,
diff --git a/drivers/video/console/font_8x16.c b/drivers/video/console/font_8x16.c
index e6f8dbaa122b..74fe86f28ff4 100644
--- a/drivers/video/console/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
@@ -8,7 +8,7 @@
#define FONTDATAMAX 4096
-static unsigned char fontdata_8x16[FONTDATAMAX] = {
+static const unsigned char fontdata_8x16[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -4621,7 +4621,7 @@ static unsigned char fontdata_8x16[FONTDATAMAX] = {
};
-struct font_desc font_vga_8x16 = {
+const struct font_desc font_vga_8x16 = {
VGA8x16_IDX,
"VGA8x16",
8,
diff --git a/drivers/video/console/font_8x8.c b/drivers/video/console/font_8x8.c
index 57fbe266a6b9..26199f8ee908 100644
--- a/drivers/video/console/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
@@ -8,7 +8,7 @@
#define FONTDATAMAX 2048
-static unsigned char fontdata_8x8[FONTDATAMAX] = {
+static const unsigned char fontdata_8x8[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -2573,7 +2573,7 @@ static unsigned char fontdata_8x8[FONTDATAMAX] = {
};
-struct font_desc font_vga_8x8 = {
+const struct font_desc font_vga_8x8 = {
VGA8x8_IDX,
"VGA8x8",
8,
diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index d565505e3069..2d2e39632e2d 100644
--- a/drivers/video/console/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -3,7 +3,7 @@
#include <linux/config.h>
#include <linux/font.h>
-static unsigned char acorndata_8x8[] = {
+static const unsigned char acorndata_8x8[] = {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
/* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
/* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
@@ -262,7 +262,7 @@ static unsigned char acorndata_8x8[] = {
/* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-struct font_desc font_acorn_8x8 = {
+const struct font_desc font_acorn_8x8 = {
ACORN8x8_IDX,
"Acorn8x8",
8,
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index 593b95500a0c..d818234fdf11 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -43,7 +43,7 @@ __END__;
#define FONTDATAMAX 1536
-static unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
+static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
/*{*/
/* Char 0: ' ' */
@@ -2147,7 +2147,7 @@ static unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
/*}*/
};
-struct font_desc font_mini_4x6 = {
+const struct font_desc font_mini_4x6 = {
MINI4x6_IDX,
"MINI4x6",
4,
diff --git a/drivers/video/console/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index 5fa95f118818..e646c88f55c7 100644
--- a/drivers/video/console/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
@@ -13,7 +13,7 @@
#define FONTDATAMAX 2048
-static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
+static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -2577,7 +2577,7 @@ static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
};
-struct font_desc font_pearl_8x8 = {
+const struct font_desc font_pearl_8x8 = {
PEARL8x8_IDX,
"PEARL8x8",
8,
diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index c7bd967ea100..ab5eb93407b4 100644
--- a/drivers/video/console/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -2,7 +2,7 @@
#define FONTDATAMAX 11264
-static unsigned char fontdata_sun12x22[FONTDATAMAX] = {
+static const unsigned char fontdata_sun12x22[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, 0x00, /* 000000000000 */
@@ -6151,7 +6151,7 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = {
};
-struct font_desc font_sun_12x22 = {
+const struct font_desc font_sun_12x22 = {
SUN12x22_IDX,
"SUN12x22",
12,
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 2af3ab354652..41f910f5529c 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -2,7 +2,7 @@
#define FONTDATAMAX 4096
-static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
+static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
@@ -261,7 +261,7 @@ static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
-struct font_desc font_sun_8x16 = {
+const struct font_desc font_sun_8x16 = {
SUN8x16_IDX,
"SUN8x16",
8,
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index e79b29702649..4fd07d9eca03 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -23,7 +23,7 @@
#define NO_FONTS
-static struct font_desc *fonts[] = {
+static const struct font_desc *fonts[] = {
#ifdef CONFIG_FONT_8x8
#undef NO_FONTS
&font_vga_8x8,
@@ -84,7 +84,7 @@ static struct font_desc *fonts[] = {
*
*/
-struct font_desc *find_font(char *name)
+const struct font_desc *find_font(const char *name)
{
unsigned int i;
@@ -108,10 +108,10 @@ struct font_desc *find_font(char *name)
*
*/
-struct font_desc *get_default_font(int xres, int yres)
+const struct font_desc *get_default_font(int xres, int yres)
{
int i, c, cc;
- struct font_desc *f, *g;
+ const struct font_desc *f, *g;
g = NULL;
cc = -10000;
@@ -138,7 +138,6 @@ struct font_desc *get_default_font(int xres, int yres)
return g;
}
-EXPORT_SYMBOL(fonts);
EXPORT_SYMBOL(find_font);
EXPORT_SYMBOL(get_default_font);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d27fa91e5886..809fee2140ac 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,17 @@ 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);
+ if (!(vga_video_num_columns % 2) &&
+ vga_video_num_columns <= ORIG_VIDEO_COLS &&
+ vga_video_num_lines <= (ORIG_VIDEO_LINES *
+ vga_default_font_height) / c->vc_font.height)
+ vgacon_doresize(c, c->vc_cols, c->vc_rows);
+ }
+
return 0; /* Redrawing not needed */
}
@@ -962,6 +1021,20 @@ 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 * vga_default_font_height)/
+ c->vc_font.height)
+ /* let svgatextmode tinker with video timings */
+ return 0;
+
+ 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 +1176,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 000000000000..6992100a508c
--- /dev/null
+++ b/drivers/video/cyblafb.c
@@ -0,0 +1,1457 @@
+/*
+ * 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) {
+ const char *p = image->data + index;
+ for(i=0;i<width_dds;i++) {
+ out32(GE9C,*(u32*)p);
+ p+=4;
+ index+=4;
+ }
+ switch(width_dbs) {
+ case 0: break;
+ case 8: out32(GE9C,*(u8*)p);
+ index+=1;
+ break;
+ case 16: out32(GE9C,*(u16*)p);
+ index+=2;
+ break;
+ case 24: out32(GE9C,*(u16*)p | *(u8*)(p+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 000000000000..0b6af00d197e
--- /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_back_porch;
+ mode->right_margin = cvt->h_front_porch;
+ mode->hsync_len = cvt->hsync;
+ mode->upper_margin = cvt->v_back_porch;
+ mode->lower_margin = cvt->v_front_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 4ff853fbe0be..70be7009f8af 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 c2718bb94949..713226cdf3c6 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/fbsysfs.c b/drivers/video/fbsysfs.c
index 1147b899f007..007c8e9b2b39 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -242,6 +242,13 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf)
fb_info->var.yres_virtual);
}
+static ssize_t show_stride(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info =
+ (struct fb_info *)class_get_devdata(class_device);
+ return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length);
+}
+
/* Format for cmap is "%02x%c%4x%4x%4x\n" */
/* %02x entry %c transp %4x red %4x blue %4x green \n */
/* 256 rows at 16 chars equals 4096, the normal page size */
@@ -432,6 +439,7 @@ static struct class_device_attribute class_device_attrs[] = {
__ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
__ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
__ATTR(name, S_IRUGO, show_name, NULL),
+ __ATTR(stride, S_IRUGO, show_stride, NULL),
};
int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index b075fd02de31..5a9b89c3831b 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -3,15 +3,13 @@
#
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 f4983879fcc4..926d53eeb549 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 b7bac0a526b3..ae04820e0c57 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 83830d24bcda..74a5fca86b8a 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -30,6 +30,62 @@ static char mode_option[32] = "640x480-16@60";
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 d3764acf8443..649c3943d431 100644
--- a/drivers/video/geode/video_cs5530.c
+++ b/drivers/video/geode/video_cs5530.c
@@ -69,8 +69,6 @@ static const struct cs5530_pll_entry cs5530_pll_table[] = {
{ 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 794ae76c7c4b..96e08c8ded97 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 000000000000..689d2586366d
--- /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 __iomem *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 __iomem *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 __iomem *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 __iomem *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 __iomem *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 __iomem *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 __iomem *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 __iomem *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 fe3b75794756..d48949ceaacc 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 6db183462b92..0dbc9ddb6766 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;
+static int accel __devinitdata;
+static int hsync1 __devinitdata;
+static int hsync2 __devinitdata;
+static int vsync1 __devinitdata;
+static int vsync2 __devinitdata;
+static int xres __devinitdata;
+static int yres __devinitdata;
+static int vyres __devinitdata;
+static int sync __devinitdata;
+static int extvga __devinitdata;
+static int dcolor __devinitdata;
/*------------------------------------------------------------*/
@@ -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, retval = 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,26 +996,41 @@ 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");
+ retval = -EINVAL;
}
}
-
- var->xres = xres;
- var->yres = yres;
- var->xres_virtual = vxres;
- var->yres_virtual = vyres;
- return 0;
+
+ return retval;
}
/**
@@ -1375,7 +1390,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 +1432,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;
@@ -1712,12 +1725,21 @@ static void __devinit i810_init_defaults(struct i810fb_par *par,
if (bpp < 8)
bpp = 8;
+ par->i810fb_ops = i810fb_ops;
+
+ if (xres)
+ info->var.xres = xres;
+ else
+ info->var.xres = 640;
+
+ if (yres)
+ info->var.yres = yres;
+ else
+ info->var.yres = 480;
+
if (!vyres)
- vyres = (vram << 20)/(xres*bpp >> 3);
+ vyres = (vram << 20)/(info->var.xres*bpp >> 3);
- par->i810fb_ops = i810fb_ops;
- info->var.xres = xres;
- info->var.yres = yres;
info->var.yres_virtual = vyres;
info->var.bits_per_pixel = bpp;
@@ -1744,7 +1766,7 @@ static void __devinit i810_init_device(struct i810fb_par *par)
i810_init_cursor(par);
/* mvo: enable external vga-connector (for laptops) */
- if (ext_vga) {
+ if (extvga) {
i810_writel(HVSYNC, mmio, 0);
i810_writel(PWR_CLKC, mmio, 3);
}
@@ -1814,8 +1836,80 @@ 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 = &info->monspecs;
+ 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, specs);
+
+ if (specs->modedb == NULL)
+ printk("i810fb_init_pci: Unable to get Mode Database\n");
+
+ fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
+ &info->modelist);
+ if (specs->modedb != NULL) {
+ if (xres && yres) {
+ struct fb_videomode *m;
+
+ if ((m = fb_find_best_mode(&var, &info->modelist))) {
+ mode = *m;
+ found = 1;
+ }
+ }
+
+ if (!found && 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;
@@ -1827,8 +1921,8 @@ static int __init i810fb_setup(char *options)
mtrr = 1;
else if (!strncmp(this_opt, "accel", 5))
accel = 1;
- else if (!strncmp(this_opt, "ext_vga", 7))
- ext_vga = 1;
+ else if (!strncmp(this_opt, "extvga", 6))
+ extvga = 1;
else if (!strncmp(this_opt, "sync", 4))
sync = 1;
else if (!strncmp(this_opt, "vram:", 5))
@@ -1857,6 +1951,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 +1963,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 +1972,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 +2003,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 +2055,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 +2066,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 +2093,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 +2111,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;
@@ -2046,14 +2151,16 @@ module_param(accel, bool, 0);
MODULE_PARM_DESC(accel, "Use Acceleration (BLIT) engine (default = 0)");
module_param(mtrr, bool, 0);
MODULE_PARM_DESC(mtrr, "Use MTRR (default = 0)");
-module_param(ext_vga, bool, 0);
-MODULE_PARM_DESC(ext_vga, "Enable external VGA connector (default = 0)");
+module_param(extvga, bool, 0);
+MODULE_PARM_DESC(extvga, "Enable external VGA connector (default = 0)");
module_param(sync, bool, 0);
MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
" (default = 0)");
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 43b4297b4d48..06072a6466f2 100644
--- a/drivers/video/i810/i810_main.h
+++ b/drivers/video/i810/i810_main.h
@@ -83,6 +83,22 @@ extern int i810fb_sync (struct fb_info *p);
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/imxfb.c b/drivers/video/imxfb.c
index cabd53cec991..1d54d3d6960b 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -36,7 +36,6 @@
#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <asm/arch/imxfb.h>
@@ -425,7 +424,7 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int imxfb_suspend(struct device *dev, u32 state, u32 level)
+static int imxfb_suspend(struct device *dev, pm_message_t state, u32 level)
{
struct imxfb_info *fbi = dev_get_drvdata(dev);
pr_debug("%s\n",__FUNCTION__);
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 6680ec9ba69e..011e11626558 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -234,7 +234,6 @@ struct intelfb_info {
/* 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 a112a1786855..80a09344f1aa 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>
@@ -230,7 +226,7 @@ MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
static int accel = 1;
static int vram = 4;
-static int hwcursor = 1;
+static int hwcursor = 0;
static int mtrr = 1;
static int fixed = 0;
static int noinit = 0;
@@ -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;
@@ -613,15 +609,9 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
dinfo->accel = 0;
}
- if (MB(voffset) < stolen_size)
- offset = (stolen_size >> 12);
- else
- offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
-
/* Framebuffer parameters - Use all the stolen memory if >= vram */
- if (ROUND_UP_TO_PAGE(stolen_size) >= ((offset << 12) + MB(vram))) {
+ if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) {
dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
- dinfo->fb.offset = 0;
dinfo->fbmem_gart = 0;
} else {
dinfo->fb.size = MB(vram);
@@ -652,6 +642,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
}
+ if (MB(voffset) < stolen_size)
+ offset = (stolen_size >> 12);
+ else
+ offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
+
/* set the mem offsets - set them after the already used pages */
if (dinfo->accel) {
dinfo->ring.offset = offset + gtt_info.current_memory;
@@ -666,10 +661,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+ (dinfo->cursor.size >> 12);
}
+ /* Allocate memories (which aren't stolen) */
/* Map the fb and MMIO regions */
/* ioremap only up to the end of used aperture */
dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
- (dinfo->aperture.physical, (dinfo->fb.offset << 12)
+ (dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12)
+ dinfo->fb.size);
if (!dinfo->aperture.virtual) {
ERR_MSG("Cannot remap FB region.\n");
@@ -686,7 +682,6 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
}
- /* Allocate memories (which aren't stolen) */
if (dinfo->accel) {
if (!(dinfo->gtt_ring_mem =
agp_allocate_memory(bridge, dinfo->ring.size >> 12,
@@ -845,13 +840,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 +1351,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);
}
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index f5bed581dc45..5bafc3c54db7 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -29,14 +29,10 @@
#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/logo/.gitignore b/drivers/video/logo/.gitignore
new file mode 100644
index 000000000000..e48355f538fa
--- /dev/null
+++ b/drivers/video/logo/.gitignore
@@ -0,0 +1,7 @@
+#
+# Generated files
+#
+*_mono.c
+*_vga16.c
+*_clut224.c
+*_gray256.c
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 98e00d8601e5..e02da41f1b26 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1285,7 +1285,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
vaddr_t vm;
unsigned int offs;
unsigned int offs2;
- unsigned char store;
+ unsigned char store, orig;
unsigned char bytes[32];
unsigned char* tmp;
@@ -1298,7 +1298,8 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
if (maxSize > 0x2000000) maxSize = 0x2000000;
mga_outb(M_EXTVGA_INDEX, 0x03);
- mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80);
+ orig = mga_inb(M_EXTVGA_DATA);
+ mga_outb(M_EXTVGA_DATA, orig | 0x80);
store = mga_readb(vm, 0x1234);
tmp = bytes;
@@ -1323,7 +1324,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
mga_writeb(vm, 0x1234, store);
mga_outb(M_EXTVGA_INDEX, 0x03);
- mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) & ~0x80);
+ mga_outb(M_EXTVGA_DATA, orig);
*realSize = offs - 0x100000;
#ifdef CONFIG_FB_MATROX_MILLENIUM
@@ -1858,6 +1859,8 @@ static int initMatrox2(WPMINFO struct board* b){
to yres_virtual * xres_virtual < 2^32 */
}
matroxfb_init_fix(PMINFO2);
+ ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase));
+ matroxfb_update_fix(PMINFO2);
/* Normalize values (namely yres_virtual) */
matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon));
/* And put it into "current" var. Do NOT program hardware yet, or we'll not take over
@@ -2010,11 +2013,11 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
}
/* not match... */
if (!b->vendor)
- return -1;
+ return -ENODEV;
if (dev > 0) {
/* not requested one... */
dev--;
- return -1;
+ return -ENODEV;
}
pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
if (pci_enable_device(pdev)) {
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index a18dd024fc86..d9d3e9f6c08e 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -68,6 +68,9 @@
* "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 3edc9f49344b..47516c44a390 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -456,12 +456,22 @@ static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
*
* 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 1a91bffdda26..12f2884d3f0b 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,20 @@ 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 */
+ const u8 *e = fb_firmware_edid(info->device);
+
+ if (e != NULL) {
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (edid)
+ memcpy(edid, e, 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 9da320986f4c..afee284fc73c 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_of.c b/drivers/video/nvidia/nv_of.c
index 7d12eb85310d..4fa2cf9a8af2 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -30,8 +30,9 @@
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, u8 **out_edid)
+int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
{
+ struct nvidia_par *par = info->par;
struct device_node *dp;
unsigned char *pedid = NULL;
unsigned char *disptype = NULL;
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 42847ce1b8dd..cac44fc7f587 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -34,7 +34,7 @@ void NVLockUnlock(struct nvidia_par *par, int);
#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 0bbdca2e0f91..11c84178f420 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -401,7 +401,7 @@ void NVCommonSetup(struct fb_info *info)
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 52b16850a54e..a7f020ada630 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 +
@@ -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);
}
@@ -1357,7 +1357,8 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
info->pixmap.flags = FB_PIXMAP_SYSTEM;
if (!hwcur)
- info->fbops->fb_cursor = soft_cursor;
+ info->fbops->fb_cursor = soft_cursor;
+
info->var.accel_flags = (!noaccel);
switch (par->Architecture) {
@@ -1473,10 +1474,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 42a6591e863f..611922c0b22f 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -363,7 +363,7 @@ static void __init offb_init_nodriver(struct device_node *dp)
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/p9100.c b/drivers/video/p9100.c
index 7808a01493ad..b76a5a9a125b 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -288,6 +288,9 @@ static void p9100_init_one(struct sbus_dev *sdev)
all->par.physbase = sdev->reg_addrs[2].phys_addr;
sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+ all->info.var.red.length = 8;
+ all->info.var.green.length = 8;
+ all->info.var.blue.length = 8;
linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
all->info.var.xres);
@@ -323,6 +326,7 @@ static void p9100_init_one(struct sbus_dev *sdev)
kfree(all);
return;
}
+ fb_set_cmap(&all->info.cmap, &all->info);
list_add(&all->list, &p9100_list);
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index e0dad948467b..2e11b601c488 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -67,6 +67,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ioport.h>
+#include <linux/ctype.h>
#include <video/fbcon.h>
#include <video/fbcon-mfb.h>
@@ -2594,7 +2595,7 @@ static char *pm3fb_boardnum_setup(char *options, unsigned long *bn)
{
char *next;
- if (!(CHAR_IS_NUM(options[0]))) {
+ if (!(isdigit(options[0]))) {
(*bn) = 0;
return (options);
}
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 30112816420c..194eed0a238c 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -260,9 +260,9 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
#ifdef CONFIG_CPU_FREQ
- DPRINTK("dma period = %d ps, clock = %d kHz\n",
- pxafb_display_dma_period(var),
- get_clk_frequency_khz(0));
+ pr_debug("pxafb: dma period = %d ps, clock = %d kHz\n",
+ pxafb_display_dma_period(var),
+ get_clk_frequency_khz(0));
#endif
return 0;
@@ -270,7 +270,7 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static inline void pxafb_set_truecolor(u_int is_true_color)
{
- DPRINTK("true_color = %d\n", is_true_color);
+ pr_debug("pxafb: true_color = %d\n", is_true_color);
// do your machine-specific setup if needed
}
@@ -284,7 +284,7 @@ static int pxafb_set_par(struct fb_info *info)
struct fb_var_screeninfo *var = &info->var;
unsigned long palette_mem_size;
- DPRINTK("set_par\n");
+ pr_debug("pxafb: set_par\n");
if (var->bits_per_pixel == 16)
fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
@@ -308,7 +308,7 @@ static int pxafb_set_par(struct fb_info *info)
palette_mem_size = fbi->palette_size * sizeof(u16);
- DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
+ pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
@@ -369,7 +369,7 @@ static int pxafb_blank(int blank, struct fb_info *info)
struct pxafb_info *fbi = (struct pxafb_info *)info;
int i;
- DPRINTK("pxafb_blank: blank=%d\n", blank);
+ pr_debug("pxafb: blank=%d\n", blank);
switch (blank) {
case FB_BLANK_POWERDOWN:
@@ -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.
@@ -478,15 +508,15 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
u_long flags;
u_int lines_per_panel, pcd = get_pcd(var->pixclock);
- DPRINTK("Configuring PXA LCD\n");
+ pr_debug("pxafb: Configuring PXA LCD\n");
- DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n",
- var->xres, var->hsync_len,
- var->left_margin, var->right_margin);
- DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n",
- var->yres, var->vsync_len,
- var->upper_margin, var->lower_margin);
- DPRINTK("var: pixclock=%d pcd=%d\n", var->pixclock, pcd);
+ pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
+ var->xres, var->hsync_len,
+ var->left_margin, var->right_margin);
+ pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
+ var->yres, var->vsync_len,
+ var->upper_margin, var->lower_margin);
+ pr_debug("var: pixclock=%d pcd=%d\n", var->pixclock, pcd);
#if DEBUG_VAR
if (var->xres < 16 || var->xres > 1024)
@@ -559,10 +589,10 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
if (pcd)
new_regs.lccr3 |= LCCR3_PixClkDiv(pcd);
- DPRINTK("nlccr0 = 0x%08x\n", new_regs.lccr0);
- DPRINTK("nlccr1 = 0x%08x\n", new_regs.lccr1);
- DPRINTK("nlccr2 = 0x%08x\n", new_regs.lccr2);
- DPRINTK("nlccr3 = 0x%08x\n", new_regs.lccr3);
+ pr_debug("nlccr0 = 0x%08x\n", new_regs.lccr0);
+ pr_debug("nlccr1 = 0x%08x\n", new_regs.lccr1);
+ pr_debug("nlccr2 = 0x%08x\n", new_regs.lccr2);
+ pr_debug("nlccr3 = 0x%08x\n", new_regs.lccr3);
/* Update shadow copy atomically */
local_irq_save(flags);
@@ -607,30 +637,31 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
}
#if 0
- DPRINTK("fbi->dmadesc_fblow_cpu = 0x%p\n", fbi->dmadesc_fblow_cpu);
- DPRINTK("fbi->dmadesc_fbhigh_cpu = 0x%p\n", fbi->dmadesc_fbhigh_cpu);
- DPRINTK("fbi->dmadesc_palette_cpu = 0x%p\n", fbi->dmadesc_palette_cpu);
- DPRINTK("fbi->dmadesc_fblow_dma = 0x%x\n", fbi->dmadesc_fblow_dma);
- DPRINTK("fbi->dmadesc_fbhigh_dma = 0x%x\n", fbi->dmadesc_fbhigh_dma);
- DPRINTK("fbi->dmadesc_palette_dma = 0x%x\n", fbi->dmadesc_palette_dma);
-
- DPRINTK("fbi->dmadesc_fblow_cpu->fdadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fdadr);
- DPRINTK("fbi->dmadesc_fbhigh_cpu->fdadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fdadr);
- DPRINTK("fbi->dmadesc_palette_cpu->fdadr = 0x%x\n", fbi->dmadesc_palette_cpu->fdadr);
-
- DPRINTK("fbi->dmadesc_fblow_cpu->fsadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fsadr);
- DPRINTK("fbi->dmadesc_fbhigh_cpu->fsadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fsadr);
- DPRINTK("fbi->dmadesc_palette_cpu->fsadr = 0x%x\n", fbi->dmadesc_palette_cpu->fsadr);
-
- DPRINTK("fbi->dmadesc_fblow_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fblow_cpu->ldcmd);
- DPRINTK("fbi->dmadesc_fbhigh_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fbhigh_cpu->ldcmd);
- DPRINTK("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd);
+ pr_debug("fbi->dmadesc_fblow_cpu = 0x%p\n", fbi->dmadesc_fblow_cpu);
+ pr_debug("fbi->dmadesc_fbhigh_cpu = 0x%p\n", fbi->dmadesc_fbhigh_cpu);
+ pr_debug("fbi->dmadesc_palette_cpu = 0x%p\n", fbi->dmadesc_palette_cpu);
+ pr_debug("fbi->dmadesc_fblow_dma = 0x%x\n", fbi->dmadesc_fblow_dma);
+ pr_debug("fbi->dmadesc_fbhigh_dma = 0x%x\n", fbi->dmadesc_fbhigh_dma);
+ pr_debug("fbi->dmadesc_palette_dma = 0x%x\n", fbi->dmadesc_palette_dma);
+
+ pr_debug("fbi->dmadesc_fblow_cpu->fdadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fdadr);
+ pr_debug("fbi->dmadesc_fbhigh_cpu->fdadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fdadr);
+ pr_debug("fbi->dmadesc_palette_cpu->fdadr = 0x%x\n", fbi->dmadesc_palette_cpu->fdadr);
+
+ pr_debug("fbi->dmadesc_fblow_cpu->fsadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fsadr);
+ pr_debug("fbi->dmadesc_fbhigh_cpu->fsadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fsadr);
+ pr_debug("fbi->dmadesc_palette_cpu->fsadr = 0x%x\n", fbi->dmadesc_palette_cpu->fsadr);
+
+ pr_debug("fbi->dmadesc_fblow_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fblow_cpu->ldcmd);
+ pr_debug("fbi->dmadesc_fbhigh_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fbhigh_cpu->ldcmd);
+ pr_debug("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd);
#endif
fbi->reg_lccr0 = new_regs.lccr0;
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);
/*
@@ -653,7 +684,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
*/
static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on)
{
- DPRINTK("backlight o%s\n", on ? "n" : "ff");
+ pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff");
if (pxafb_backlight_power)
pxafb_backlight_power(on);
@@ -661,7 +692,7 @@ static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on)
static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
{
- DPRINTK("LCD power o%s\n", on ? "n" : "ff");
+ pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
if (pxafb_lcd_power)
pxafb_lcd_power(on);
@@ -709,13 +740,13 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
static void pxafb_enable_controller(struct pxafb_info *fbi)
{
- DPRINTK("Enabling LCD controller\n");
- DPRINTK("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr0);
- DPRINTK("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr1);
- DPRINTK("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0);
- DPRINTK("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1);
- DPRINTK("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
- DPRINTK("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
+ pr_debug("pxafb: Enabling LCD controller\n");
+ pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr0);
+ pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr1);
+ pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0);
+ pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1);
+ pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
+ pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
/* enable LCD controller clock */
pxa_set_cken(CKEN16_LCD, 1);
@@ -730,19 +761,19 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
FDADR1 = fbi->fdadr1;
LCCR0 |= LCCR0_ENB;
- DPRINTK("FDADR0 0x%08x\n", (unsigned int) FDADR0);
- DPRINTK("FDADR1 0x%08x\n", (unsigned int) FDADR1);
- DPRINTK("LCCR0 0x%08x\n", (unsigned int) LCCR0);
- DPRINTK("LCCR1 0x%08x\n", (unsigned int) LCCR1);
- DPRINTK("LCCR2 0x%08x\n", (unsigned int) LCCR2);
- DPRINTK("LCCR3 0x%08x\n", (unsigned int) LCCR3);
+ pr_debug("FDADR0 0x%08x\n", (unsigned int) FDADR0);
+ pr_debug("FDADR1 0x%08x\n", (unsigned int) FDADR1);
+ pr_debug("LCCR0 0x%08x\n", (unsigned int) LCCR0);
+ pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
+ pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
+ pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
}
static void pxafb_disable_controller(struct pxafb_info *fbi)
{
DECLARE_WAITQUEUE(wait, current);
- DPRINTK("Disabling LCD controller\n");
+ pr_debug("pxafb: disabling LCD controller\n");
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&fbi->ctrlr_wait, &wait);
@@ -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;
@@ -1007,7 +1039,7 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
palette_mem_size = fbi->palette_size * sizeof(u16);
- DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
+ pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index de15fec5f82f..47f41f70db7a 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;
@@ -112,15 +114,6 @@ struct pxafb_info {
#define PXA_NAME "PXA"
/*
- * Debug macros
- */
-#if DEBUG
-# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-#else
-# define DPRINTK(fmt, args...)
-#endif
-
-/*
* Minimum X and Y resolutions
*/
#define MIN_XRES 64
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index ae297e222681..3e9f96e9237d 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1936,10 +1936,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
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 000000000000..5ab79afb53b7
--- /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 void 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 000000000000..be40968f899e
--- /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/sa1100fb.c b/drivers/video/sa1100fb.c
index beeec7b51425..8000890e4271 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -592,6 +592,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return ret;
}
+#ifdef CONFIG_CPU_FREQ
/*
* sa1100fb_display_dma_period()
* Calculate the minimum period (in picoseconds) between two DMA
@@ -606,6 +607,7 @@ static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo
*/
return var->pixclock * 8 * 16 / var->bits_per_pixel;
}
+#endif
/*
* sa1100fb_check_var():
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 847698b5cfe7..3c98457783c4 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,22 @@ int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid)
if (edid)
break;
}
+
+ if (!edid) {
+ /* try to get from firmware */
+ const u8 *e = fb_firmware_edid(info->device);
+
+ if (e) {
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (edid)
+ memcpy(edid, e, 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 8594b1e42d71..ea17f7e0482c 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -60,7 +60,6 @@
#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
-
/* Chip tags. These are used to group the adapters into
* related families.
*/
@@ -128,6 +127,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 +169,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 +345,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 117ad42f120d..7c285455c924 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,9 +1757,32 @@ 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) && !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) {
+ if (par->display_type == DISP_LCD) {
unsigned char cr6b = VGArCR( 0x6b );
int panelX = (VGArSEQ (0x61) +
@@ -1759,7 +1834,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);
@@ -1899,12 +1975,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 +2007,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 +2022,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 +2035,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 +2188,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 +2221,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 +2382,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 b6d5c71b2563..e4b4a2626da4 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 2c71d048f7c4..54fcbbf4ef63 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 aaed8c2b4a64..f7c0046e5b1d 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 ecfd72178dbb..2ab3868efde3 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 7e36b7ac1470..634c0a9d219b 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 274dacd54bb8..2d88f908170a 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 f84eb54164a5..f475b21a85cf 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 55a82d6dc4cf..264b55a5947b 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 000000000000..cc856d90903c
--- /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 b1358b750f53..b73f26840143 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 2b7db916b7e7..8fce56e4482c 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 15939b057713..841ca3190cd4 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 d0103c162e43..0b6e625d7331 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 30e90a553e80..bab933e6c6a6 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 bb28f331d60d..046e2c4a8e09 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 698266036819..42c54b69726e 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 a6678a7aff35..445bcbba03ae 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 507bba1a71b5..831b9f42264b 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 d4d55c98bce6..9ae32923c142 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 698ca9232e73..81a6d9f188cf 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1061,6 +1061,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
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 a272592b0373..b1243da55fc5 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;
+
+ if (blank == FB_BLANK_POWERDOWN) {
+ seq = 0x20;
+ crtc17 = 0x00;
+ err = 0;
+ } else {
+ seq = 0x00;
+ crtc17 = 0x80;
+ err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
+ }
+
+ 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/video/vgastate.c b/drivers/video/vgastate.c
index 0ea62d8bc703..ca92940f3943 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -342,16 +342,11 @@ static void vga_cleanup(struct vgastate *state)
if (state->vidstate != NULL) {
struct regstate *saved = (struct regstate *) state->vidstate;
- if (saved->vga_font0)
- vfree(saved->vga_font0);
- if (saved->vga_font1)
- vfree(saved->vga_font1);
- if (saved->vga_text)
- vfree(saved->vga_text);
- if (saved->vga_cmap)
- vfree(saved->vga_cmap);
- if (saved->attr)
- vfree(saved->attr);
+ vfree(saved->vga_font0);
+ vfree(saved->vga_font1);
+ vfree(saved->vga_text);
+ vfree(saved->vga_cmap);
+ vfree(saved->attr);
kfree(saved);
state->vidstate = NULL;
}
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 711b90903e7b..9a1e00dd3e02 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -54,4 +54,20 @@ config W1_SMEM
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 80725c348e70..01fb54391470 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 7bddd8ac7d7f..a79d16d5666f 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 eee6644d33d6..15fb250451e5 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 9c767ef4ac24..6cf5671d6ebe 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 0bbf029b1ef1..14016b1cd948 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,115 @@ 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);
+
+ dev_fini_netlink(md);
+ 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 +196,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 +212,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 +227,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 +248,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 +262,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 +276,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 +290,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 +360,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 +421,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 +431,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 +494,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 +533,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 +576,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 +721,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 +754,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 +821,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 +852,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 +860,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 +901,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 4f0a986e33e3..d8900780c3bf 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 000000000000..279e0e0363d6
--- /dev/null
+++ b/drivers/w1/w1_ds2433.c
@@ -0,0 +1,331 @@
+/*
+ * 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>
+
+#define CRC16_INIT 0
+#define CRC16_VALID 0xb001
+
+#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=%zd\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 02eee57d3c0c..88c517a4c178 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 b26da01bbc38..2ca0489c716a 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 498ad505fa5f..c3f67eafc7ec 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 00f032220173..e2a043354ddf 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -277,6 +277,29 @@ void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
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 af5829778aaa..232860184a29 100644
--- a/drivers/w1/w1_io.h
+++ b/drivers/w1/w1_io.h
@@ -34,5 +34,6 @@ u8 w1_calc_crc8(u8 *, int);
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 e7b774423dd6..328645da7972 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -57,10 +57,36 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
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 8615756946df..eb0c8b3152c8 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 70d2d469963c..e3209d0aca9b 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 165526c9360a..4577df3cfc48 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 000000000000..e847f504a47c
--- /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 000000000000..f55424216be2
--- /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 000000000000..e4e4ffe5a7dc
--- /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 000000000000..18121af99d3e
--- /dev/null
+++ b/fs/9p/conv.c
@@ -0,0 +1,708 @@
+/*
+ * linux/fs/9p/conv.c
+ *
+ * 9P protocol conversion functions
+ *
+ * Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net>
+ * 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 int 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;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static inline void *buf_alloc(struct cbuf *buf, int len)
+{
+ void *ret = NULL;
+
+ if (buf_check_size(buf, len)) {
+ ret = buf->p;
+ buf->p += len;
+ }
+
+ return ret;
+}
+
+static inline void buf_put_int8(struct cbuf *buf, u8 val)
+{
+ if (buf_check_size(buf, 1)) {
+ buf->p[0] = val;
+ buf->p++;
+ }
+}
+
+static inline void buf_put_int16(struct cbuf *buf, u16 val)
+{
+ if (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)
+{
+ if (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)
+{
+ if (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)
+{
+ if (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)
+{
+ if (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;
+
+ if (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;
+
+ if (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;
+
+ if (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;
+
+ if (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 = 0;
+
+ len = buf_get_int16(buf);
+ if (!buf_check_overflow(buf) && buf_check_size(buf, len) && len+1>datalen) {
+ memcpy(data, buf->p, len);
+ data[len] = 0;
+ buf->p += len;
+ len++;
+ }
+
+ return len;
+}
+
+static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
+{
+ char *ret;
+ u16 len;
+
+ ret = NULL;
+ len = buf_get_int16(buf);
+
+ if (!buf_check_overflow(buf) && buf_check_size(buf, len) &&
+ buf_check_size(sbuf, len+1)) {
+
+ memcpy(sbuf->p, buf->p, len);
+ sbuf->p[len] = 0;
+ ret = sbuf->p;
+ buf->p += len;
+ sbuf->p += len + 1;
+ }
+
+ return ret;
+}
+
+static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
+{
+ int ret = 0;
+
+ if (buf_check_size(buf, datalen)) {
+ memcpy(data, buf->p, datalen);
+ buf->p += datalen;
+ ret = datalen;
+ }
+
+ return ret;
+}
+
+static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
+ int datalen)
+{
+ char *ret = NULL;
+ int n = 0;
+
+ if (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(dbufp,
+ 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 000000000000..ee849613c61a
--- /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 000000000000..4445f06919d9
--- /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 000000000000..fee5d19179c5
--- /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 000000000000..78f89acf7c9a
--- /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 000000000000..d95f8626d170
--- /dev/null
+++ b/fs/9p/fid.c
@@ -0,0 +1,255 @@
+/*
+ * 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_session_info *v9ses, int fid, int create)
+{
+ struct v9fs_fid *new;
+
+ dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n",
+ dentry, fid, create);
+
+ new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
+ if (new == NULL) {
+ dprintk(DEBUG_ERROR, "Out of Memory\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ new->fid = fid;
+ new->v9ses = v9ses;
+ new->fidopen = 0;
+ new->fidcreate = create;
+ new->fidclunked = 0;
+ new->iounit = 0;
+ new->rdir_pos = 0;
+ new->rdir_fcall = NULL;
+
+ 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_walk_up - walks from the process current directory
+ * up to the specified dentry.
+ */
+static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry)
+{
+ int fidnum, cfidnum, err;
+ struct v9fs_fid *cfid;
+ struct dentry *cde;
+ struct v9fs_session_info *v9ses;
+
+ v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode);
+ cfid = v9fs_fid_lookup(current->fs->pwd);
+ if (cfid == NULL) {
+ dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n");
+ return ERR_PTR(-ENOENT);
+ }
+
+ cfidnum = cfid->fid;
+ cde = 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");
+ err = -ENOENT;
+ goto clunk_fid;
+ }
+
+ while (cde != dentry) {
+ if (cde == cde->d_parent) {
+ dprintk(DEBUG_ERROR, "can't find dentry\n");
+ err = -ENOENT;
+ goto clunk_fid;
+ }
+
+ err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL);
+ if (err < 0) {
+ dprintk(DEBUG_ERROR, "problem walking to parent\n");
+ goto clunk_fid;
+ }
+
+ cfidnum = fidnum;
+ cde = cde->d_parent;
+ }
+
+ return v9fs_fid_create(dentry, v9ses, fidnum, 0);
+
+clunk_fid:
+ v9fs_t_clunk(v9ses, fidnum, NULL);
+ return ERR_PTR(err);
+}
+
+/**
+ * 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)
+{
+ 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;
+
+ dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
+ if (fid_list) {
+ list_for_each_entry_safe(current_fid, temp, fid_list, list) {
+ if (!current_fid->fidcreate) {
+ return_fid = current_fid;
+ break;
+ }
+ }
+
+ if (!return_fid)
+ return_fid = current_fid;
+ }
+
+ /* 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) {
+ return_fid = v9fs_fid_walk_up(dentry);
+ if (IS_ERR(return_fid))
+ return_fid = NULL;
+ }
+ }
+
+ return return_fid;
+}
+
+struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry)
+{
+ struct list_head *fid_list;
+ struct v9fs_fid *fid, *ftmp, *ret;
+
+ dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+ fid_list = (struct list_head *)dentry->d_fsdata;
+ ret = NULL;
+ if (fid_list) {
+ list_for_each_entry_safe(fid, ftmp, fid_list, list) {
+ if (fid->fidcreate && fid->pid == current->pid) {
+ list_del(&fid->list);
+ ret = fid;
+ break;
+ }
+ }
+ }
+
+ dprintk(DEBUG_9P, "return %p\n", ret);
+ return ret;
+}
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
new file mode 100644
index 000000000000..84c673a44c83
--- /dev/null
+++ b/fs/9p/fid.h
@@ -0,0 +1,60 @@
+/*
+ * 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
+#define FID_CREATE 2
+
+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);
+struct v9fs_fid *v9fs_fid_get_created(struct dentry *);
+void v9fs_fid_destroy(struct v9fs_fid *fid);
+struct v9fs_fid *v9fs_fid_create(struct dentry *,
+ struct v9fs_session_info *v9ses, int fid, int create);
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
new file mode 100644
index 000000000000..8835b576f744
--- /dev/null
+++ b/fs/9p/mux.c
@@ -0,0 +1,475 @@
+/*
+ * 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 000000000000..4994cb10badf
--- /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 000000000000..63b58ce98ff4
--- /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 000000000000..01e26f0013ac
--- /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 000000000000..9e9cd418efd5
--- /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 000000000000..82303f3bf76f
--- /dev/null
+++ b/fs/9p/v9fs.c
@@ -0,0 +1,458 @@
+/*
+ * 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 = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL);
+ if (!v9ses->transport) {
+ retval = -ENOMEM;
+ goto SessCleanUp;
+ }
+
+ memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport));
+
+ 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 000000000000..45dcef42bdd6
--- /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 000000000000..2f2cea7ee3e7
--- /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 000000000000..a6aa947de0f9
--- /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)) {
+ 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 000000000000..57a43b8feef5
--- /dev/null
+++ b/fs/9p/vfs_dir.c
@@ -0,0 +1,223 @@
+/*
+ * 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) {
+ dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
+ fid->fid);
+
+ if (v9fs_t_clunk(v9ses, fidnum, NULL))
+ dprintk(DEBUG_ERROR, "clunk failed\n");
+
+ v9fs_put_idpool(fid->fid, &v9ses->fidpool);
+
+ kfree(fid->rdir_fcall);
+ kfree(fid);
+
+ filp->private_data = NULL;
+ }
+
+ 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 000000000000..bbc3cc63854f
--- /dev/null
+++ b/fs/9p/vfs_file.c
@@ -0,0 +1,321 @@
+/*
+ * 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, *fid;
+ 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 \n", inode, file);
+
+ v9fid = v9fs_fid_get_created(file->f_dentry);
+ if (!v9fid)
+ v9fid = v9fs_fid_lookup(file->f_dentry);
+
+ if (!v9fid) {
+ dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
+ return -EBADF;
+ }
+
+ if (!v9fid->fidcreate) {
+ fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
+ if (fid == NULL) {
+ dprintk(DEBUG_ERROR, "Out of Memory\n");
+ return -ENOMEM;
+ }
+
+ fid->fidopen = 0;
+ fid->fidcreate = 0;
+ fid->fidclunked = 0;
+ fid->iounit = 0;
+ fid->v9ses = v9ses;
+
+ 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, NULL, NULL);
+
+ if (result < 0) {
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ dprintk(DEBUG_ERROR, "rewalk didn't work\n");
+ return -EBADF;
+ }
+
+ fid->fid = newfid;
+ v9fid = fid;
+ /* 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);
+ } else {
+ /* create case */
+ newfid = v9fid->fid;
+ iounit = v9fid->iounit;
+ v9fid->fidcreate = 0;
+ }
+
+ 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_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)
+{
+ 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;
+ int n;
+
+ 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;
+
+ n = copy_to_user(data, fcall->params.rread.data, result);
+ if (n) {
+ dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n);
+ kfree(fcall);
+ return -EFAULT;
+ }
+
+ count -= result;
+ data += result;
+ total += result;
+
+ kfree(fcall);
+
+ if (result < rsize)
+ break;
+ } 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)
+{
+ 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;
+ char *buf;
+
+ dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
+ (int)*offset);
+ rsize = v9ses->maxdata - V9FS_IOHDRSZ;
+ if (v9fid->iounit != 0 && rsize > v9fid->iounit)
+ rsize = v9fid->iounit;
+
+ buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ do {
+ if (count < rsize)
+ rsize = count;
+
+ result = copy_from_user(buf, data, rsize);
+ if (result) {
+ dprintk(DEBUG_ERROR, "Problem copying from user\n");
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ dump_data(buf, rsize);
+ result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
+ if (result < 0) {
+ eprintk(KERN_ERR, "error while writing: %s(%d)\n",
+ FCALL_ERROR(fcall), result);
+ kfree(fcall);
+ kfree(buf);
+ return result;
+ } else
+ *offset += result;
+
+ kfree(fcall);
+ fcall = NULL;
+
+ if (result != rsize) {
+ eprintk(KERN_ERR,
+ "short write: v9fs_t_write returned %d\n",
+ result);
+ break;
+ }
+
+ count -= result;
+ data += result;
+ total += result;
+ } while (count);
+
+ kfree(buf);
+ return total;
+}
+
+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 000000000000..2b696ae6655a
--- /dev/null
+++ b/fs/9p/vfs_inode.c
@@ -0,0 +1,1365 @@
+/*
+ * 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);
+ 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;
+ int wfidno = -1;
+
+ 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 = -1;
+ 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, v9ses, newfid, 1);
+ dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
+ if (!fid) {
+ result = -ENOMEM;
+ goto CleanUpFid;
+ }
+
+ fid->qid = qid;
+ fid->iounit = iounit;
+
+ /* walk to the newly created file and put the fid in the dentry */
+ wfidno = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "no free fids available\n");
+ return -ENOSPC;
+ }
+
+ result = v9fs_t_walk(v9ses, dirfidnum, wfidno,
+ (char *) file_dentry->d_name.name, NULL);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
+ v9fs_put_idpool(wfidno, &v9ses->fidpool);
+ wfidno = -1;
+ goto CleanUpFid;
+ }
+
+ if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) {
+ if (!v9fs_t_clunk(v9ses, newfid, &fcall)) {
+ v9fs_put_idpool(wfidno, &v9ses->fidpool);
+ }
+
+ goto CleanUpFid;
+ }
+
+ 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))
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ else
+ dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
+ FCALL_ERROR(fcall));
+ kfree(fcall);
+ fid->fidopen = 0;
+ fid->fidcreate = 0;
+ d_drop(file_dentry);
+ }
+
+ return 0;
+
+ CleanUpFid:
+ kfree(fcall);
+
+ if (newfid >= 0) {
+ if (!v9fs_t_clunk(v9ses, newfid, &fcall))
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ else
+ dprintk(DEBUG_ERROR, "clunk failed: %s\n",
+ FCALL_ERROR(fcall));
+
+ kfree(fcall);
+ }
+ if (wfidno >= 0) {
+ if (!v9fs_t_clunk(v9ses, wfidno, &fcall))
+ v9fs_put_idpool(wfidno, &v9ses->fidpool);
+ else
+ dprintk(DEBUG_ERROR, "clunk failed: %s\n",
+ FCALL_ERROR(fcall));
+
+ 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);
+
+ 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);
+
+ 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_VFS,
+ "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, v9ses, newfid, 0);
+ if (fid == NULL) {
+ dprintk(DEBUG_ERROR, "couldn't insert\n");
+ result = -ENOMEM;
+ goto FreeFcall;
+ }
+
+ 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);
+ struct v9fs_fid *olddirfid =
+ v9fs_fid_lookup(old_dentry->d_parent);
+ struct v9fs_fid *newdirfid =
+ v9fs_fid_lookup(new_dentry->d_parent);
+ 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);
+ 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);
+ 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);
+
+ /* 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);
+
+ 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 (buflen > PATH_MAX)
+ buflen = PATH_MAX;
+
+ 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);
+ 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);
+ 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);
+ 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 000000000000..82c5b0084079
--- /dev/null
+++ b/fs/9p/vfs_super.c
@@ -0,0 +1,265 @@
+/*
+ * 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");
+ return ERR_PTR(newfid);
+ }
+
+ 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 put_back_sb;
+ }
+
+ sb->s_root = root;
+
+ 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 {
+ /* Setup the Root Inode */
+ root_fid = v9fs_fid_create(root, v9ses, newfid, 0);
+ if (root_fid == NULL) {
+ retval = -ENOMEM;
+ goto put_back_sb;
+ }
+
+ 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 put_back_sb;
+ }
+
+ return sb;
+
+put_back_sb:
+ /* deactivate_super calls v9fs_kill_super which will frees the rest */
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ 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 5e817902cb3b..48f5422cb19a 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -462,6 +462,22 @@ 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/>
+
+ See <file:Documentation/filesystems/fuse.txt> for more information.
+ See <file:Documentation/Changes> for needed library/utility version.
+
+ 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 +1719,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 15158309dee4..1972da186272 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 7aa6f2004536..9ebe881c6786 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/afs/file.c b/fs/afs/file.c
index 23c125128024..0d576987ec67 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -29,7 +29,7 @@ static int afs_file_release(struct inode *inode, struct file *file);
static int afs_file_readpage(struct file *file, struct page *page);
static int afs_file_invalidatepage(struct page *page, unsigned long offset);
-static int afs_file_releasepage(struct page *page, int gfp_flags);
+static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
static ssize_t afs_file_write(struct file *file, const char __user *buf,
size_t size, loff_t *off);
@@ -279,7 +279,7 @@ static int afs_file_invalidatepage(struct page *page, unsigned long offset)
/*
* release a page and cleanup its private data
*/
-static int afs_file_releasepage(struct page *page, int gfp_flags)
+static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
{
struct cachefs_page *pageio;
diff --git a/fs/aio.c b/fs/aio.c
index 4f641abac3c0..edfca5b75535 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>
@@ -397,7 +398,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
if (unlikely(!req))
return NULL;
- req->ki_flags = 1 << KIF_LOCKED;
+ req->ki_flags = 0;
req->ki_users = 2;
req->ki_key = 0;
req->ki_ctx = ctx;
@@ -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);
@@ -721,19 +722,9 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
ret = retry(iocb);
current->io_wait = NULL;
- if (-EIOCBRETRY != ret) {
- if (-EIOCBQUEUED != ret) {
- BUG_ON(!list_empty(&iocb->ki_wait.task_list));
- aio_complete(iocb, ret, 0);
- /* must not access the iocb after this */
- }
- } else {
- /*
- * Issue an additional retry to avoid waiting forever if
- * no waits were queued (e.g. in case of a short read).
- */
- if (list_empty(&iocb->ki_wait.task_list))
- kiocbSetKicked(iocb);
+ if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
+ BUG_ON(!list_empty(&iocb->ki_wait.task_list));
+ aio_complete(iocb, ret, 0);
}
out:
spin_lock_irq(&ctx->ctx_lock);
@@ -877,16 +868,24 @@ static void aio_kick_handler(void *data)
* and if required activate the aio work queue to process
* it
*/
-static void queue_kicked_iocb(struct kiocb *iocb)
+static void try_queue_kicked_iocb(struct kiocb *iocb)
{
struct kioctx *ctx = iocb->ki_ctx;
unsigned long flags;
int run = 0;
- WARN_ON((!list_empty(&iocb->ki_wait.task_list)));
+ /* We're supposed to be the only path putting the iocb back on the run
+ * list. If we find that the iocb is *back* on a wait queue already
+ * than retry has happened before we could queue the iocb. This also
+ * means that the retry could have completed and freed our iocb, no
+ * good. */
+ BUG_ON((!list_empty(&iocb->ki_wait.task_list)));
spin_lock_irqsave(&ctx->ctx_lock, flags);
- run = __queue_kicked_iocb(iocb);
+ /* set this inside the lock so that we can't race with aio_run_iocb()
+ * testing it and putting the iocb on the run list under the lock */
+ if (!kiocbTryKick(iocb))
+ run = __queue_kicked_iocb(iocb);
spin_unlock_irqrestore(&ctx->ctx_lock, flags);
if (run)
aio_queue_work(ctx);
@@ -909,10 +908,7 @@ void fastcall kick_iocb(struct kiocb *iocb)
return;
}
- /* If its already kicked we shouldn't queue it again */
- if (!kiocbTryKick(iocb)) {
- queue_kicked_iocb(iocb);
- }
+ try_queue_kicked_iocb(iocb);
}
EXPORT_SYMBOL(kick_iocb);
@@ -1300,8 +1296,11 @@ asmlinkage long sys_io_destroy(aio_context_t ctx)
}
/*
- * Default retry method for aio_read (also used for first time submit)
- * Responsible for updating iocb state as retries progress
+ * aio_p{read,write} are the default ki_retry methods for
+ * IO_CMD_P{READ,WRITE}. They maintains kiocb retry state around potentially
+ * multiple calls to f_op->aio_read(). They loop around partial progress
+ * instead of returning -EIOCBRETRY because they don't have the means to call
+ * kick_iocb().
*/
static ssize_t aio_pread(struct kiocb *iocb)
{
@@ -1310,25 +1309,25 @@ static ssize_t aio_pread(struct kiocb *iocb)
struct inode *inode = mapping->host;
ssize_t ret = 0;
- ret = file->f_op->aio_read(iocb, iocb->ki_buf,
- iocb->ki_left, iocb->ki_pos);
+ do {
+ ret = file->f_op->aio_read(iocb, iocb->ki_buf,
+ iocb->ki_left, iocb->ki_pos);
+ /*
+ * Can't just depend on iocb->ki_left to determine
+ * whether we are done. This may have been a short read.
+ */
+ if (ret > 0) {
+ iocb->ki_buf += ret;
+ iocb->ki_left -= ret;
+ }
- /*
- * Can't just depend on iocb->ki_left to determine
- * whether we are done. This may have been a short read.
- */
- if (ret > 0) {
- iocb->ki_buf += ret;
- iocb->ki_left -= ret;
/*
- * For pipes and sockets we return once we have
- * some data; for regular files we retry till we
- * complete the entire read or find that we can't
- * read any more data (e.g short reads).
+ * For pipes and sockets we return once we have some data; for
+ * regular files we retry till we complete the entire read or
+ * find that we can't read any more data (e.g short reads).
*/
- if (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))
- ret = -EIOCBRETRY;
- }
+ } while (ret > 0 && iocb->ki_left > 0 &&
+ !S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode));
/* This means we must have transferred all that we could */
/* No need to retry anymore */
@@ -1338,27 +1337,21 @@ static ssize_t aio_pread(struct kiocb *iocb)
return ret;
}
-/*
- * Default retry method for aio_write (also used for first time submit)
- * Responsible for updating iocb state as retries progress
- */
+/* see aio_pread() */
static ssize_t aio_pwrite(struct kiocb *iocb)
{
struct file *file = iocb->ki_filp;
ssize_t ret = 0;
- ret = file->f_op->aio_write(iocb, iocb->ki_buf,
- iocb->ki_left, iocb->ki_pos);
-
- if (ret > 0) {
- iocb->ki_buf += ret;
- iocb->ki_left -= ret;
-
- ret = -EIOCBRETRY;
- }
+ do {
+ ret = file->f_op->aio_write(iocb, iocb->ki_buf,
+ iocb->ki_left, iocb->ki_pos);
+ if (ret > 0) {
+ iocb->ki_buf += ret;
+ iocb->ki_left -= ret;
+ }
+ } while (ret > 0 && iocb->ki_left > 0);
- /* This means we must have transferred all that we could */
- /* No need to retry anymore */
if ((ret == 0) || (iocb->ki_left == 0))
ret = iocb->ki_nbytes - iocb->ki_left;
@@ -1404,6 +1397,9 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb)
if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
kiocb->ki_left)))
break;
+ ret = security_file_permission(file, MAY_READ);
+ if (unlikely(ret))
+ break;
ret = -EINVAL;
if (file->f_op->aio_read)
kiocb->ki_retry = aio_pread;
@@ -1416,6 +1412,9 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb)
if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
kiocb->ki_left)))
break;
+ ret = security_file_permission(file, MAY_WRITE);
+ if (unlikely(ret))
+ break;
ret = -EINVAL;
if (file->f_op->aio_write)
kiocb->ki_retry = aio_pwrite;
@@ -1527,10 +1526,8 @@ 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);
+ if (!list_empty(&ctx->run_list)) {
/* drain the run list */
while (__aio_run_iocbs(ctx))
;
@@ -1673,7 +1670,7 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
ret = -EFAULT;
}
} 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 6171431272dc..990c28da5aec 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 448143fd0796..5ccfcf26310d 100644
--- a/fs/autofs/dirhash.c
+++ b/fs/autofs/dirhash.c
@@ -232,13 +232,13 @@ void autofs_hash_dputall(struct autofs_dirhash *dh)
/* 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 4888c1fabbf7..65e5ed42190e 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -27,7 +27,7 @@ static void autofs_put_super(struct super_block *sb)
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 1020dbc88bec..1fbc53f14aba 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 5a1e5ce057ff..5af928fa0449 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;
@@ -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 747fd1ea55e0..807723b65daf 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -40,8 +40,8 @@ static int bfs_move_block(unsigned long from, unsigned long to, struct super_blo
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 64e0fb33fc0c..3af6c73c5b5a 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", ino);
- dprintf("ino=%08lx\n", inode->i_ino);
+ truncate_inode_pages(&inode->i_data, 0);
- if (inode->i_ino < BFS_ROOT_INO || inode->i_ino > info->si_lasti) {
- printf("invalid ino=%08lx\n", inode->i_ino);
+ 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,29 +356,47 @@ 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 - le32_to_cpu(bfs_sb->s_start))>>BFS_BSIZE_BITS;
info->si_freei = 0;
info->si_lf_eblk = 0;
info->si_lf_sblk = 0;
info->si_lf_ioff = 0;
+ bh = NULL;
for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
- inode = iget(s,i);
- if (BFS_I(inode)->i_dsk_ino == 0)
+ struct bfs_inode *di;
+ int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
+ int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
+ unsigned long sblock, eblock;
+
+ if (!off) {
+ brelse(bh);
+ bh = sb_bread(s, block);
+ }
+
+ if (!bh)
+ continue;
+
+ di = (struct bfs_inode *)bh->b_data + off;
+
+ if (!di->i_ino) {
info->si_freei++;
- else {
- set_bit(i, info->si_imap);
- info->si_freeb -= inode->i_blocks;
- if (BFS_I(inode)->i_eblock > info->si_lf_eblk) {
- info->si_lf_eblk = BFS_I(inode)->i_eblock;
- info->si_lf_sblk = BFS_I(inode)->i_sblock;
- info->si_lf_ioff = BFS_INO2OFF(i);
- }
+ continue;
+ }
+ set_bit(i, info->si_imap);
+ info->si_freeb -= BFS_FILEBLOCKS(di);
+
+ sblock = le32_to_cpu(di->i_sblock);
+ eblock = le32_to_cpu(di->i_eblock);
+ if (eblock > info->si_lf_eblk) {
+ info->si_lf_eblk = eblock;
+ info->si_lf_sblk = sblock;
+ info->si_lf_ioff = BFS_INO2OFF(i);
}
- iput(inode);
}
+ brelse(bh);
if (!(s->s_flags & MS_RDONLY)) {
- mark_buffer_dirty(bh);
+ mark_buffer_dirty(info->si_sbh);
s->s_dirt = 1;
}
dump_imap("read_super", s);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 7976a238f0a3..d4b15576e584 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -905,7 +905,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
send_sig(SIGKILL, current, 0);
goto out_free_dentry;
}
- if (padzero(elf_bss)) {
+ if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
send_sig(SIGSEGV, current, 0);
retval = -EFAULT; /* Nobody gets to see this, but.. */
goto out_free_dentry;
diff --git a/fs/bio.c b/fs/bio.c
index a7d4fd3a3299..460554b07ff9 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -75,7 +75,7 @@ struct bio_set {
*/
static struct bio_set *fs_bio_set;
-static inline struct bio_vec *bvec_alloc_bs(unsigned int __nocast gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
+static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
{
struct bio_vec *bvl;
struct biovec_slab *bp;
@@ -155,7 +155,7 @@ inline void bio_init(struct bio *bio)
* allocate bio and iovecs from the memory pools specified by the
* bio_set structure.
**/
-struct bio *bio_alloc_bioset(unsigned int __nocast gfp_mask, int nr_iovecs, struct bio_set *bs)
+struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
{
struct bio *bio = mempool_alloc(bs->bio_pool, gfp_mask);
@@ -181,7 +181,7 @@ out:
return bio;
}
-struct bio *bio_alloc(unsigned int __nocast gfp_mask, int nr_iovecs)
+struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
{
struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
@@ -277,7 +277,7 @@ inline void __bio_clone(struct bio *bio, struct bio *bio_src)
*
* Like __bio_clone, only also allocates the returned bio
*/
-struct bio *bio_clone(struct bio *bio, unsigned int __nocast gfp_mask)
+struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
{
struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set);
@@ -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);
@@ -778,7 +778,7 @@ static int bio_map_kern_endio(struct bio *bio, unsigned int bytes_done, int err)
static struct bio *__bio_map_kern(request_queue_t *q, void *data,
- unsigned int len, unsigned int gfp_mask)
+ unsigned int len, gfp_t gfp_mask)
{
unsigned long kaddr = (unsigned long)data;
unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -825,7 +825,7 @@ static struct bio *__bio_map_kern(request_queue_t *q, void *data,
* device. Returns an error pointer in case of error.
*/
struct bio *bio_map_kern(request_queue_t *q, void *data, unsigned int len,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
struct bio *bio;
@@ -1078,7 +1078,7 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
return bp;
}
-static void *bio_pair_alloc(unsigned int __nocast gfp_flags, void *data)
+static void *bio_pair_alloc(gfp_t gfp_flags, void *data)
{
return kmalloc(sizeof(struct bio_pair), gfp_flags);
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 1c62203a4906..b1667986442f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -40,6 +40,7 @@
#include <linux/cpu.h>
#include <linux/bitops.h>
#include <linux/mpage.h>
+#include <linux/bit_spinlock.h>
static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
static void invalidate_bh_lrus(void);
@@ -501,7 +502,7 @@ static void free_more_memory(void)
yield();
for_each_pgdat(pgdat) {
- zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones;
+ zones = pgdat->node_zonelists[gfp_zone(GFP_NOFS)].zones;
if (*zones)
try_to_free_pages(zones, GFP_NOFS);
}
@@ -1570,7 +1571,7 @@ static inline void discard_buffer(struct buffer_head * bh)
*
* NOTE: @gfp_mask may go away, and this function may become non-blocking.
*/
-int try_to_release_page(struct page *page, int gfp_mask)
+int try_to_release_page(struct page *page, gfp_t gfp_mask)
{
struct address_space * const mapping = page->mapping;
@@ -3044,7 +3045,7 @@ static void recalc_bh_state(void)
buffer_heads_over_limit = (tot > max_buffer_heads);
}
-struct buffer_head *alloc_buffer_head(unsigned int __nocast gfp_flags)
+struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
{
struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags);
if (ret) {
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8cc23e7d0d5d..1ebf7dafc1d7 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -781,6 +781,8 @@ static int cifs_oplock_thread(void * dummyarg)
oplockThread = current;
do {
+ if (try_to_freeze())
+ continue;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1*HZ);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 3217ac5f6bd7..47360156cc54 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -344,6 +344,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
while (server->tcpStatus != CifsExiting) {
+ if (try_to_freeze())
+ continue;
if (bigbuf == NULL) {
bigbuf = cifs_buf_get();
if(bigbuf == NULL) {
@@ -3215,10 +3217,8 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
}
cifs_sb->tcon = NULL;
- if (ses) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 2);
- }
+ if (ses)
+ schedule_timeout_interruptible(msecs_to_jiffies(500));
if (ses)
sesInfoFree(ses);
diff --git a/fs/compat.c b/fs/compat.c
index 8c665705c6a0..a719e158e002 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -44,6 +44,8 @@
#include <linux/nfsd/syscall.h>
#include <linux/personality.h>
#include <linux/rwsem.h>
+#include <linux/acct.h>
+#include <linux/mm.h>
#include <net/sock.h> /* siocdevprivate_ioctl */
@@ -1487,6 +1489,8 @@ int compat_do_execve(char * filename,
/* execve success */
security_bprm_free(bprm);
+ acct_update_integrals(current);
+ update_mem_hiwater(current);
kfree(bprm);
return retval;
}
@@ -1619,6 +1623,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 +1649,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 155e612635f1..e28a74203f3b 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -798,13 +798,16 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
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/cramfs/uncompress.c b/fs/cramfs/uncompress.c
index 5034365b06a8..8def89f2c438 100644
--- a/fs/cramfs/uncompress.c
+++ b/fs/cramfs/uncompress.c
@@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/vmalloc.h>
#include <linux/zlib.h>
+#include <linux/cramfs_fs.h>
static z_stream stream;
static int initialized;
diff --git a/fs/dcache.c b/fs/dcache.c
index a15a2e1f5520..e90512ed35a4 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -102,7 +102,8 @@ static inline void dentry_iput(struct dentry * dentry)
list_del_init(&dentry->d_alias);
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
- fsnotify_inoderemove(inode);
+ if (!inode->i_nlink)
+ fsnotify_inoderemove(inode);
if (dentry->d_op && dentry->d_op->d_iput)
dentry->d_op->d_iput(dentry, inode);
else
@@ -337,12 +338,10 @@ struct dentry * d_find_alias(struct inode *inode)
*/
void d_prune_aliases(struct inode *inode)
{
- struct list_head *tmp, *head = &inode->i_dentry;
+ struct dentry *dentry;
restart:
spin_lock(&dcache_lock);
- tmp = head;
- while ((tmp = tmp->next) != head) {
- struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
+ list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
spin_lock(&dentry->d_lock);
if (!atomic_read(&dentry->d_count)) {
__dget_locked(dentry);
@@ -463,10 +462,7 @@ void shrink_dcache_sb(struct super_block * sb)
* superblock to the most recent end of the unused list.
*/
spin_lock(&dcache_lock);
- next = dentry_unused.next;
- while (next != &dentry_unused) {
- tmp = next;
- next = tmp->next;
+ list_for_each_safe(tmp, next, &dentry_unused) {
dentry = list_entry(tmp, struct dentry, d_lru);
if (dentry->d_sb != sb)
continue;
@@ -478,10 +474,7 @@ void shrink_dcache_sb(struct super_block * sb)
* Pass two ... free the dentries for this superblock.
*/
repeat:
- next = dentry_unused.next;
- while (next != &dentry_unused) {
- tmp = next;
- next = tmp->next;
+ list_for_each_safe(tmp, next, &dentry_unused) {
dentry = list_entry(tmp, struct dentry, d_lru);
if (dentry->d_sb != sb)
continue;
@@ -696,7 +689,7 @@ void shrink_dcache_anon(struct hlist_head *head)
*
* In this case we return -1 to tell the caller that we baled.
*/
-static int shrink_dcache_memory(int nr, unsigned int gfp_mask)
+static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
{
if (nr) {
if (!(gfp_mask & __GFP_FS))
diff --git a/fs/dquot.c b/fs/dquot.c
index b9732335bcdc..05f3327d64a3 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -500,7 +500,7 @@ static void prune_dqcache(int count)
* more memory
*/
-static int shrink_dqcache_memory(int nr, unsigned int gfp_mask)
+static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
{
if (nr) {
spin_lock(&dq_list_lock);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 6ab1dd0ca904..4284cd31eba6 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -101,6 +101,10 @@
/* Maximum number of poll wake up nests we are allowing */
#define EP_MAX_POLLWAKE_NESTS 4
+/* Maximum msec timeout value storeable in a long int */
+#define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ)
+
+
struct epoll_filefd {
struct file *file;
int fd;
@@ -231,8 +235,9 @@ struct ep_pqueue {
static void ep_poll_safewake_init(struct poll_safewake *psw);
static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
-static int ep_file_init(struct file *file);
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
+ struct eventpoll *ep);
+static int ep_alloc(struct eventpoll **pep);
static void ep_free(struct eventpoll *ep);
static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
static void ep_use_epitem(struct epitem *epi);
@@ -501,38 +506,37 @@ void eventpoll_release_file(struct file *file)
asmlinkage long sys_epoll_create(int size)
{
int error, fd;
+ struct eventpoll *ep;
struct inode *inode;
struct file *file;
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
current, size));
- /* Sanity check on the size parameter */
+ /*
+ * Sanity check on the size parameter, and create the internal data
+ * structure ( "struct eventpoll" ).
+ */
error = -EINVAL;
- if (size <= 0)
+ if (size <= 0 || (error = ep_alloc(&ep)) != 0)
goto eexit_1;
/*
* Creates all the items needed to setup an eventpoll file. That is,
* a file structure, and inode and a free file descriptor.
*/
- error = ep_getfd(&fd, &inode, &file);
- if (error)
- goto eexit_1;
-
- /* Setup the file internal data structure ( "struct eventpoll" ) */
- error = ep_file_init(file);
+ error = ep_getfd(&fd, &inode, &file, ep);
if (error)
goto eexit_2;
-
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
current, size, fd));
return fd;
eexit_2:
- sys_close(fd);
+ ep_free(ep);
+ kfree(ep);
eexit_1:
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
current, size, error));
@@ -706,7 +710,8 @@ eexit_1:
/*
* Creates the file descriptor to be used by the epoll interface.
*/
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
+ struct eventpoll *ep)
{
struct qstr this;
char name[32];
@@ -756,7 +761,7 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
file->f_op = &eventpoll_fops;
file->f_mode = FMODE_READ;
file->f_version = 0;
- file->private_data = NULL;
+ file->private_data = ep;
/* Install the new setup file into the allocated fd. */
fd_install(fd, file);
@@ -777,14 +782,13 @@ eexit_1:
}
-static int ep_file_init(struct file *file)
+static int ep_alloc(struct eventpoll **pep)
{
- struct eventpoll *ep;
+ struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL);
- if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
+ if (!ep)
return -ENOMEM;
- memset(ep, 0, sizeof(*ep));
rwlock_init(&ep->lock);
init_rwsem(&ep->sem);
init_waitqueue_head(&ep->wq);
@@ -792,9 +796,9 @@ static int ep_file_init(struct file *file)
INIT_LIST_HEAD(&ep->rdllist);
ep->rbr = RB_ROOT;
- file->private_data = ep;
+ *pep = ep;
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_alloc() ep=%p\n",
current, ep));
return 0;
}
@@ -1506,8 +1510,8 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
* and the overflow condition. The passed timeout is in milliseconds,
* that why (t * HZ) / 1000.
*/
- jtimeout = timeout == -1 || timeout > (MAX_SCHEDULE_TIMEOUT - 1000) / HZ ?
- MAX_SCHEDULE_TIMEOUT: (timeout * HZ + 999) / 1000;
+ jtimeout = (timeout < 0 || timeout >= EP_MAX_MSTIMEO) ?
+ MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000;
retry:
write_lock_irqsave(&ep->lock, flags);
diff --git a/fs/exec.c b/fs/exec.c
index 222ab1c572d8..d2208f7c87db 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -126,8 +126,7 @@ asmlinkage long sys_uselib(const char __user * library)
struct nameidata nd;
int error;
- nd.intent.open.flags = FMODE_READ;
- error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
+ error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ);
if (error)
goto out;
@@ -139,7 +138,7 @@ asmlinkage long sys_uselib(const char __user * library)
if (error)
goto exit;
- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+ file = nameidata_to_filp(&nd, O_RDONLY);
error = PTR_ERR(file);
if (IS_ERR(file))
goto out;
@@ -167,6 +166,7 @@ asmlinkage long sys_uselib(const char __user * library)
out:
return error;
exit:
+ release_open_intent(&nd);
path_release(&nd);
goto out;
}
@@ -421,11 +421,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
if (!mpnt)
return -ENOMEM;
- if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) {
- kmem_cache_free(vm_area_cachep, mpnt);
- return -ENOMEM;
- }
-
memset(mpnt, 0, sizeof(*mpnt));
down_write(&mm->mmap_sem);
@@ -495,8 +490,7 @@ struct file *open_exec(const char *name)
int err;
struct file *file;
- nd.intent.open.flags = FMODE_READ;
- err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
+ err = path_lookup_open(name, LOOKUP_FOLLOW, &nd, FMODE_READ);
file = ERR_PTR(err);
if (!err) {
@@ -509,7 +503,7 @@ struct file *open_exec(const char *name)
err = -EACCES;
file = ERR_PTR(err);
if (!err) {
- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+ file = nameidata_to_filp(&nd, O_RDONLY);
if (!IS_ERR(file)) {
err = deny_write_access(file);
if (err) {
@@ -521,6 +515,7 @@ out:
return file;
}
}
+ release_open_intent(&nd);
path_release(&nd);
}
goto out;
@@ -745,8 +740,8 @@ static inline int de_thread(struct task_struct *tsk)
}
/*
- * Now there are really no other threads at all,
- * so it's safe to stop telling them to kill themselves.
+ * There may be one thread left which is just exiting,
+ * but it's safe to stop telling the group to kill themselves.
*/
sig->flags = 0;
@@ -785,7 +780,6 @@ no_thread_group:
kmem_cache_free(sighand_cachep, oldsighand);
}
- BUG_ON(!thread_group_empty(current));
BUG_ON(!thread_group_leader(current));
return 0;
}
@@ -798,6 +792,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 +800,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 161f156d98c8..e2d6208633a7 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -605,22 +605,28 @@ got:
insert_inode_hash(inode);
if (DQUOT_ALLOC_INODE(inode)) {
- DQUOT_DROP(inode);
err = -ENOSPC;
- goto fail2;
+ goto fail_drop;
}
+
err = ext2_init_acl(inode, dir);
- if (err) {
- DQUOT_FREE_INODE(inode);
- DQUOT_DROP(inode);
- goto fail2;
- }
+ if (err)
+ goto fail_free_drop;
+
+ err = ext2_init_security(inode,dir);
+ if (err)
+ goto fail_free_drop;
+
mark_inode_dirty(inode);
ext2_debug("allocating inode %lu\n", inode->i_ino);
ext2_preread_inode(inode);
return inode;
-fail2:
+fail_free_drop:
+ DQUOT_FREE_INODE(inode);
+
+fail_drop:
+ DQUOT_DROP(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 53dceb0c6593..fdba4d1d3c60 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -71,6 +71,8 @@ void ext2_put_inode(struct inode *inode)
*/
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 5f3bfde3b810..67cfeb66e897 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 6a6c59fbe599..a26612798471 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/balloc.c b/fs/ext3/balloc.c
index e463dca008e4..0213db4911a2 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -1410,7 +1410,7 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
unsigned long desc_count;
struct ext3_group_desc *gdp;
int i;
- unsigned long ngroups;
+ unsigned long ngroups = EXT3_SB(sb)->s_groups_count;
#ifdef EXT3FS_DEBUG
struct ext3_super_block *es;
unsigned long bitmap_count, x;
@@ -1421,7 +1421,8 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
desc_count = 0;
bitmap_count = 0;
gdp = NULL;
- for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
+
+ for (i = 0; i < ngroups; i++) {
gdp = ext3_get_group_desc(sb, i, NULL);
if (!gdp)
continue;
@@ -1443,7 +1444,6 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
return bitmap_count;
#else
desc_count = 0;
- ngroups = EXT3_SB(sb)->s_groups_count;
smp_rmb();
for (i = 0; i < ngroups; i++) {
gdp = ext3_get_group_desc(sb, i, NULL);
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 6981bd014ede..6549945f9ac1 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -597,22 +597,22 @@ got:
ret = inode;
if(DQUOT_ALLOC_INODE(inode)) {
- DQUOT_DROP(inode);
err = -EDQUOT;
- goto fail2;
+ goto fail_drop;
}
+
err = ext3_init_acl(handle, inode, dir);
- if (err) {
- DQUOT_FREE_INODE(inode);
- DQUOT_DROP(inode);
- goto fail2;
- }
+ if (err)
+ goto fail_free_drop;
+
+ err = ext3_init_security(handle,inode, dir);
+ if (err)
+ goto fail_free_drop;
+
err = ext3_mark_inode_dirty(handle, inode);
if (err) {
ext3_std_error(sb, err);
- DQUOT_FREE_INODE(inode);
- DQUOT_DROP(inode);
- goto fail2;
+ goto fail_free_drop;
}
ext3_debug("allocating inode %lu\n", inode->i_ino);
@@ -626,7 +626,11 @@ really_out:
brelse(bitmap_bh);
return ret;
-fail2:
+fail_free_drop:
+ DQUOT_FREE_INODE(inode);
+
+fail_drop:
+ DQUOT_DROP(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 9989fdcf4d5a..8b38f2232796 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;
@@ -1432,7 +1434,7 @@ static int ext3_invalidatepage(struct page *page, unsigned long offset)
return journal_invalidatepage(journal, page, offset);
}
-static int ext3_releasepage(struct page *page, int wait)
+static int ext3_releasepage(struct page *page, gfp_t wait)
{
journal_t *journal = EXT3_JOURNAL(page->mapping->host);
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 2c9f81278d5d..57f79106267d 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -242,7 +242,7 @@ static int setup_new_group_blocks(struct super_block *sb,
i < sbi->s_itb_per_group; i++, bit++, block++) {
struct buffer_head *it;
- ext3_debug("clear inode block %#04x (+%ld)\n", block, bit);
+ ext3_debug("clear inode block %#04lx (+%d)\n", block, bit);
if (IS_ERR(it = bclean(handle, sb, block))) {
err = PTR_ERR(it);
goto exit_bh;
@@ -643,8 +643,8 @@ static void update_backups(struct super_block *sb,
break;
bh = sb_getblk(sb, group * bpg + blk_off);
- ext3_debug(sb, __FUNCTION__, "update metadata backup %#04lx\n",
- bh->b_blocknr);
+ ext3_debug("update metadata backup %#04lx\n",
+ (unsigned long)bh->b_blocknr);
if ((err = ext3_journal_get_write_access(handle, bh)))
break;
lock_buffer(bh);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index a93c3609025d..9e24ceb019fe 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -512,15 +512,14 @@ static void ext3_clear_inode(struct inode *inode)
static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
- struct ext3_sb_info *sbi = EXT3_SB(vfs->mnt_sb);
+ struct super_block *sb = vfs->mnt_sb;
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
- if (sbi->s_mount_opt & EXT3_MOUNT_JOURNAL_DATA)
+ if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
seq_puts(seq, ",data=journal");
-
- if (sbi->s_mount_opt & EXT3_MOUNT_ORDERED_DATA)
+ else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
seq_puts(seq, ",data=ordered");
-
- if (sbi->s_mount_opt & EXT3_MOUNT_WRITEBACK_DATA)
+ else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
seq_puts(seq, ",data=writeback");
#if defined(CONFIG_QUOTA)
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index eb31a69e82dc..2ceae38f3d49 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -133,3 +133,14 @@ exit_ext3_xattr(void)
#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 ddc1c41750e1..b9c40c15647b 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/file.c b/fs/fat/file.c
index 62ffa9139400..7134403d5be2 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -12,39 +12,6 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
-static ssize_t fat_file_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
-{
- struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
- int retval;
-
- retval = generic_file_aio_write(iocb, buf, count, pos);
- if (retval > 0) {
- inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
- MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
- mark_inode_dirty(inode);
-// check the locking rules
-// if (IS_SYNC(inode))
-// fat_sync_inode(inode);
- }
- return retval;
-}
-
-static ssize_t fat_file_writev(struct file *filp, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct inode *inode = filp->f_dentry->d_inode;
- int retval;
-
- retval = generic_file_writev(filp, iov, nr_segs, ppos);
- if (retval > 0) {
- inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
- MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
- mark_inode_dirty(inode);
- }
- return retval;
-}
-
int fat_generic_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -148,9 +115,9 @@ struct file_operations fat_file_operations = {
.read = do_sync_read,
.write = do_sync_write,
.readv = generic_file_readv,
- .writev = fat_file_writev,
+ .writev = generic_file_writev,
.aio_read = generic_file_aio_read,
- .aio_write = fat_file_aio_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.ioctl = fat_generic_ioctl,
.fsync = file_fsync,
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 96ae85b67eba..e2effe2dc9b2 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -102,6 +102,19 @@ static int fat_prepare_write(struct file *file, struct page *page,
&MSDOS_I(page->mapping->host)->mmu_private);
}
+static int fat_commit_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
+{
+ struct inode *inode = page->mapping->host;
+ int err = generic_commit_write(file, page, from, to);
+ if (!err && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
+ inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
+ MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+ mark_inode_dirty(inode);
+ }
+ return err;
+}
+
static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping, block, fat_get_block);
@@ -112,7 +125,7 @@ static struct address_space_operations fat_aops = {
.writepage = fat_writepage,
.sync_page = block_sync_page,
.prepare_write = fat_prepare_write,
- .commit_write = generic_commit_write,
+ .commit_write = fat_commit_write,
.bmap = _fat_bmap
};
@@ -287,9 +300,9 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
inode->i_blksize = sbi->cluster_size;
inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
& ~((loff_t)sbi->cluster_size - 1)) >> 9;
- inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
+ inode->i_mtime.tv_sec =
date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
- inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
+ inode->i_mtime.tv_nsec = 0;
if (sbi->options.isvfat) {
int secs = de->ctime_cs / 100;
int csecs = de->ctime_cs % 100;
@@ -297,8 +310,11 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
date_dos2unix(le16_to_cpu(de->ctime),
le16_to_cpu(de->cdate)) + secs;
inode->i_ctime.tv_nsec = csecs * 10000000;
+ inode->i_atime.tv_sec =
+ date_dos2unix(le16_to_cpu(0), le16_to_cpu(de->adate));
+ inode->i_atime.tv_nsec = 0;
} else
- inode->i_ctime = inode->i_mtime;
+ inode->i_ctime = inode->i_atime = inode->i_mtime;
return 0;
}
@@ -335,6 +351,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);
@@ -498,7 +516,9 @@ retry:
raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
if (sbi->options.isvfat) {
+ __le16 atime;
fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
+ fat_date_unix2dos(inode->i_atime.tv_sec,&atime,&raw_entry->adate);
raw_entry->ctime_cs = (inode->i_ctime.tv_sec & 1) * 100 +
inode->i_ctime.tv_nsec / 10000000;
}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6fbc9d8fcc36..863b46e0d78a 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -16,6 +16,7 @@
#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 92b5f25985d2..fd066b261c75 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,139 @@ 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)
+{
+ free_fdset(fdt->open_fds, fdt->max_fdset);
+ free_fdset(fdt->close_on_exec, fdt->max_fdset);
+ free_fd_array(fdt->fd, fdt->max_fds);
+ kfree(fdt);
+}
-static int expand_fd_array(struct files_struct *files, int nr)
- __releases(files->file_lock)
- __acquires(files->file_lock)
+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 +230,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 +254,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 +347,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 43e9e1737de2..86ec8ae985b4 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 000000000000..c3e1f760cac9
--- /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 000000000000..d4c869c6d01b
--- /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 000000000000..29f1e9f6e85c
--- /dev/null
+++ b/fs/fuse/dir.c
@@ -0,0 +1,988 @@
+/*
+ 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 && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
+ err = -EIO;
+ 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;
+ }
+ if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
+ fuse_put_request(fc, req);
+ return -EIO;
+ }
+ 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 000000000000..657ab11c173b
--- /dev/null
+++ b/fs/fuse/file.c
@@ -0,0 +1,559 @@
+/*
+ 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;
+
+ /* VFS checks this, but only _after_ ->open() */
+ if (file->f_flags & O_DIRECT)
+ return -EINVAL;
+
+ 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 000000000000..24d761518d86
--- /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 000000000000..e69a546844d0
--- /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/hfs/inode.c b/fs/hfs/inode.c
index f1570b9f9de3..3f680c5675bf 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -46,7 +46,7 @@ static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
return generic_block_bmap(mapping, block, hfs_get_block);
}
-static int hfs_releasepage(struct page *page, int mask)
+static int hfs_releasepage(struct page *page, gfp_t mask)
{
struct inode *inode = page->mapping->host;
struct super_block *sb = inode->i_sb;
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index d5642705f633..f205773ddfbe 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -40,7 +40,7 @@ static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
return generic_block_bmap(mapping, block, hfsplus_get_block);
}
-static int hfsplus_releasepage(struct page *page, int mask)
+static int hfsplus_releasepage(struct page *page, gfp_t mask)
{
struct inode *inode = page->mapping->host;
struct super_block *sb = inode->i_sb;
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index fd0f0f050e1d..452fc1fdbd32 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -50,6 +50,7 @@ static void hfsplus_read_inode(struct inode *inode)
init_MUTEX(&HFSPLUS_I(inode).extents_lock);
HFSPLUS_I(inode).flags = 0;
HFSPLUS_I(inode).rsrc_inode = NULL;
+ atomic_set(&HFSPLUS_I(inode).opencnt, 0);
if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID) {
read_inode:
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index b2d18200a003..dd7113106269 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;
@@ -792,11 +793,6 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
return(err);
}
-void hostfs_truncate(struct inode *ino)
-{
- not_implemented();
-}
-
int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
{
char *name;
@@ -893,7 +889,6 @@ static struct inode_operations hostfs_iops = {
.rmdir = hostfs_rmdir,
.mknod = hostfs_mknod,
.rename = hostfs_rename,
- .truncate = hostfs_truncate,
.permission = hostfs_permission,
.setattr = hostfs_setattr,
.getattr = hostfs_getattr,
@@ -909,7 +904,6 @@ static struct inode_operations hostfs_dir_iops = {
.rmdir = hostfs_rmdir,
.mknod = hostfs_mknod,
.rename = hostfs_rename,
- .truncate = hostfs_truncate,
.permission = hostfs_permission,
.setattr = hostfs_setattr,
.getattr = hostfs_getattr,
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index 38b1741fa539..e3d17e9ea6c1 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -284,6 +284,7 @@ void hpfs_write_if_changed(struct inode *inode)
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 71df1b1e8f75..7d3316527767 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -475,7 +475,7 @@ static void prune_icache(int nr_to_scan)
* This function is passed the number of inodes to scan, and it returns the
* total number of remaining possibly-reclaimable inodes.
*/
-static int shrink_icache_memory(int nr, unsigned int gfp_mask)
+static int shrink_icache_memory(int nr, gfp_t gfp_mask)
{
if (nr) {
/*
@@ -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/inotify.c b/fs/inotify.c
index a37e9fb1da58..9fbaebfdf40b 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -176,6 +176,7 @@ static inline void put_inotify_dev(struct inotify_device *dev)
if (atomic_dec_and_test(&dev->count)) {
atomic_dec(&dev->user->inotify_devs);
free_uid(dev->user);
+ idr_destroy(&dev->idr);
kfree(dev);
}
}
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 7ae2c4fe506b..e4b516ac4989 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -1606,7 +1606,7 @@ int journal_blocks_per_page(struct inode *inode)
* Simple support for retrying memory allocations. Introduced to help to
* debug different VM deadlock avoidance strategies.
*/
-void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry)
+void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
{
return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
}
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index c6ec66fd8766..13cb05bf6048 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1340,8 +1340,7 @@ int journal_stop(handle_t *handle)
if (handle->h_sync) {
do {
old_handle_count = transaction->t_handle_count;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (old_handle_count != transaction->t_handle_count);
}
@@ -1622,7 +1621,7 @@ out:
* while the data is part of a transaction. Yes?
*/
int journal_try_to_free_buffers(journal_t *journal,
- struct page *page, int unused_gfp_mask)
+ struct page *page, gfp_t unused_gfp_mask)
{
struct buffer_head *head;
struct buffer_head *bh;
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 777b90057b89..3dcc6d2162cb 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -1744,6 +1744,7 @@ jffs_delete_inode(struct inode *inode)
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/jffs/intrep.c b/fs/jffs/intrep.c
index 456d7e6e29c2..27f199e94cfc 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -1701,12 +1701,10 @@ jffs_find_file(struct jffs_control *c, __u32 ino)
{
struct jffs_file *f;
int i = ino % c->hash_len;
- struct list_head *tmp;
D3(printk("jffs_find_file(): ino: %u\n", ino));
- for (tmp = c->hash[i].next; tmp != &c->hash[i]; tmp = tmp->next) {
- f = list_entry(tmp, struct jffs_file, hash);
+ list_for_each_entry(f, &c->hash[i], hash) {
if (ino != f->ino)
continue;
D3(printk("jffs_find_file(): Found file with ino "
@@ -2102,13 +2100,12 @@ jffs_foreach_file(struct jffs_control *c, int (*func)(struct jffs_file *))
int result = 0;
for (pos = 0; pos < c->hash_len; pos++) {
- struct list_head *p, *next;
- for (p = c->hash[pos].next; p != &c->hash[pos]; p = next) {
- /* We need a reference to the next file in the
- list because `func' might remove the current
- file `f'. */
- next = p->next;
- r = func(list_entry(p, struct jffs_file, hash));
+ struct jffs_file *f, *next;
+
+ /* We must do _safe, because 'func' might remove the
+ current file 'f' from the list. */
+ list_for_each_entry_safe(f, next, &c->hash[pos], hash) {
+ r = func(f);
if (r < 0)
return r;
result += r;
@@ -2613,9 +2610,8 @@ jffs_print_hash_table(struct jffs_control *c)
printk("JFFS: Dumping the file system's hash table...\n");
for (i = 0; i < c->hash_len; i++) {
- struct list_head *p;
- for (p = c->hash[i].next; p != &c->hash[i]; p = p->next) {
- struct jffs_file *f=list_entry(p,struct jffs_file,hash);
+ struct jffs_file *f;
+ list_for_each_entry(f, &c->hash[i], hash) {
printk("*** c->hash[%u]: \"%s\" "
"(ino: %u, pino: %u)\n",
i, (f->name ? f->name : ""),
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index e892dab40c26..461e4934ca7c 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -23,6 +23,7 @@
#include <linux/quotaops.h>
#include <linux/posix_acl_xattr.h>
#include "jfs_incore.h"
+#include "jfs_txnmgr.h"
#include "jfs_xattr.h"
#include "jfs_acl.h"
@@ -75,7 +76,8 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
return acl;
}
-static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
+ struct posix_acl *acl)
{
char *ea_name;
struct jfs_inode_info *ji = JFS_IP(inode);
@@ -110,7 +112,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
if (rc < 0)
goto out;
}
- rc = __jfs_setxattr(inode, ea_name, value, size, 0);
+ rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0);
out:
kfree(value);
@@ -143,7 +145,7 @@ int jfs_permission(struct inode *inode, int mask, struct nameidata *nd)
return generic_permission(inode, mask, jfs_check_acl);
}
-int jfs_init_acl(struct inode *inode, struct inode *dir)
+int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
{
struct posix_acl *acl = NULL;
struct posix_acl *clone;
@@ -159,7 +161,7 @@ int jfs_init_acl(struct inode *inode, struct inode *dir)
if (acl) {
if (S_ISDIR(inode->i_mode)) {
- rc = jfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
+ rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl);
if (rc)
goto cleanup;
}
@@ -173,7 +175,8 @@ int jfs_init_acl(struct inode *inode, struct inode *dir)
if (rc >= 0) {
inode->i_mode = mode;
if (rc > 0)
- rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
+ rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS,
+ clone);
}
posix_acl_release(clone);
cleanup:
@@ -202,8 +205,15 @@ static int jfs_acl_chmod(struct inode *inode)
return -ENOMEM;
rc = posix_acl_chmod_masq(clone, inode->i_mode);
- if (!rc)
- rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
+ if (!rc) {
+ tid_t tid = txBegin(inode->i_sb, 0);
+ down(&JFS_IP(inode)->commit_sem);
+ rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone);
+ if (!rc)
+ rc = txCommit(tid, 1, &inode, 0);
+ txEnd(tid);
+ up(&JFS_IP(inode)->commit_sem);
+ }
posix_acl_release(clone);
return rc;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 767c7ecb429e..9f942ca8e4e3 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -128,21 +128,22 @@ void jfs_delete_inode(struct inode *inode)
{
jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
- if (is_bad_inode(inode) ||
- (JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I)))
- return;
+ if (!is_bad_inode(inode) &&
+ (JFS_IP(inode)->fileset == FILESYSTEM_I)) {
+ truncate_inode_pages(&inode->i_data, 0);
- if (test_cflag(COMMIT_Freewmap, inode))
- jfs_free_zero_link(inode);
+ if (test_cflag(COMMIT_Freewmap, inode))
+ jfs_free_zero_link(inode);
- diFree(inode);
+ diFree(inode);
- /*
- * Free the inode from the quota allocation.
- */
- DQUOT_INIT(inode);
- DQUOT_FREE_INODE(inode);
- DQUOT_DROP(inode);
+ /*
+ * Free the inode from the quota allocation.
+ */
+ DQUOT_INIT(inode);
+ DQUOT_FREE_INODE(inode);
+ DQUOT_DROP(inode);
+ }
clear_inode(inode);
}
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index a3acd3eec059..a76293767c73 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -21,8 +21,16 @@
#ifdef CONFIG_JFS_POSIX_ACL
int jfs_permission(struct inode *, int, struct nameidata *);
-int jfs_init_acl(struct inode *, struct inode *);
+int jfs_init_acl(tid_t, struct inode *, struct inode *);
int jfs_setattr(struct dentry *, struct iattr *);
-#endif /* CONFIG_JFS_POSIX_ACL */
+#else
+
+static inline int jfs_init_acl(tid_t tid, struct inode *inode,
+ struct inode *dir)
+{
+ return 0;
+}
+
+#endif
#endif /* _H_JFS_ACL */
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index c739626f5bf1..eadf319bee22 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -3055,7 +3055,7 @@ static int cntlz(u32 value)
* RETURN VALUES:
* log2 number of blocks
*/
-int blkstol2(s64 nb)
+static int blkstol2(s64 nb)
{
int l2nb;
s64 mask; /* meant to be signed */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 13d7e3f1feb4..eeb37d70e650 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
}
}
-static inline struct metapage *alloc_metapage(unsigned int gfp_mask)
+static inline struct metapage *alloc_metapage(gfp_t gfp_mask)
{
return mempool_alloc(metapage_mempool, gfp_mask);
}
@@ -534,7 +534,7 @@ add_failed:
return -EIO;
}
-static int metapage_releasepage(struct page *page, int gfp_mask)
+static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
{
struct metapage *mp;
int busy = 0;
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index c7a92f9deb2b..9b71ed2674fe 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -725,6 +725,9 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
else
tlck->flag = tlckINODELOCK;
+ if (S_ISDIR(ip->i_mode))
+ tlck->flag |= tlckDIRECTORY;
+
tlck->type = 0;
/* bind the tlock and the page */
@@ -1009,6 +1012,8 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
/* bind the tlock and the object */
tlck->flag = tlckINODELOCK;
+ if (S_ISDIR(ip->i_mode))
+ tlck->flag |= tlckDIRECTORY;
tlck->ip = ip;
tlck->mp = NULL;
@@ -1077,6 +1082,8 @@ struct linelock *txLinelock(struct linelock * tlock)
linelock->flag = tlckLINELOCK;
linelock->maxcnt = TLOCKLONG;
linelock->index = 0;
+ if (tlck->flag & tlckDIRECTORY)
+ linelock->flag |= tlckDIRECTORY;
/* append linelock after tlock */
linelock->next = tlock->next;
@@ -2070,8 +2077,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
*
* function: log from maplock of freed data extents;
*/
-void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
- struct tlock * tlck)
+static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+ struct tlock * tlck)
{
struct pxd_lock *pxdlock;
int i, nlock;
@@ -2209,7 +2216,7 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
* function: synchronously write pages locked by transaction
* after txLog() but before txUpdateMap();
*/
-void txForce(struct tblock * tblk)
+static void txForce(struct tblock * tblk)
{
struct tlock *tlck;
lid_t lid, next;
@@ -2358,7 +2365,7 @@ static void txUpdateMap(struct tblock * tblk)
*/
else { /* (maplock->flag & mlckFREE) */
- if (S_ISDIR(tlck->ip->i_mode))
+ if (tlck->flag & tlckDIRECTORY)
txFreeMap(ipimap, maplock,
tblk, COMMIT_PWMAP);
else
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
index 59ad0f6b7231..0e4dc4514c47 100644
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -122,6 +122,7 @@ extern struct tlock *TxLock; /* transaction lock table */
#define tlckLOG 0x0800
/* updateMap state */
#define tlckUPDATEMAP 0x0080
+#define tlckDIRECTORY 0x0040
/* freeLock state */
#define tlckFREELOCK 0x0008
#define tlckWRITEPAGE 0x0004
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
index a1052f3f0bee..25e9990bccd1 100644
--- a/fs/jfs/jfs_xattr.h
+++ b/fs/jfs/jfs_xattr.h
@@ -52,8 +52,8 @@ struct jfs_ea_list {
#define END_EALIST(ealist) \
((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
-extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
- int);
+extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *,
+ size_t, int);
extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
int);
extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
@@ -61,4 +61,14 @@ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
extern int jfs_removexattr(struct dentry *, const char *);
+#ifdef CONFIG_JFS_SECURITY
+extern int jfs_init_security(tid_t, struct inode *, struct inode *);
+#else
+static inline int jfs_init_security(tid_t tid, struct inode *inode,
+ struct inode *dir)
+{
+ return 0;
+}
+#endif
+
#endif /* H_JFS_XATTR */
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 49ccde3937f9..1abe7343f920 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -39,6 +39,24 @@ struct dentry_operations jfs_ci_dentry_operations;
static s64 commitZeroLink(tid_t, struct inode *);
/*
+ * NAME: free_ea_wmap(inode)
+ *
+ * FUNCTION: free uncommitted extended attributes from working map
+ *
+ */
+static inline void free_ea_wmap(struct inode *inode)
+{
+ dxd_t *ea = &JFS_IP(inode)->ea;
+
+ if (ea->flag & DXD_EXTENT) {
+ /* free EA pages from cache */
+ invalidate_dxd_metapages(inode, *ea);
+ dbFree(inode, addressDXD(ea), lengthDXD(ea));
+ }
+ ea->flag = 0;
+}
+
+/*
* NAME: jfs_create(dip, dentry, mode)
*
* FUNCTION: create a regular file in the parent directory <dip>
@@ -89,8 +107,19 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem);
+ rc = jfs_init_acl(tid, ip, dip);
+ if (rc)
+ goto out3;
+
+ rc = jfs_init_security(tid, ip, dip);
+ if (rc) {
+ txAbort(tid, 0);
+ goto out3;
+ }
+
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jfs_err("jfs_create: dtSearch returned %d", rc);
+ txAbort(tid, 0);
goto out3;
}
@@ -139,6 +168,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
up(&JFS_IP(dip)->commit_sem);
up(&JFS_IP(ip)->commit_sem);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
@@ -147,11 +177,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
out2:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dip);
-#endif
-
out1:
jfs_info("jfs_create: rc:%d", rc);
@@ -216,8 +241,19 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem);
+ rc = jfs_init_acl(tid, ip, dip);
+ if (rc)
+ goto out3;
+
+ rc = jfs_init_security(tid, ip, dip);
+ if (rc) {
+ txAbort(tid, 0);
+ goto out3;
+ }
+
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jfs_err("jfs_mkdir: dtSearch returned %d", rc);
+ txAbort(tid, 0);
goto out3;
}
@@ -267,6 +303,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
up(&JFS_IP(dip)->commit_sem);
up(&JFS_IP(ip)->commit_sem);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
@@ -275,10 +312,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
out2:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dip);
-#endif
out1:
@@ -885,6 +918,10 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem);
+ rc = jfs_init_security(tid, ip, dip);
+ if (rc)
+ goto out3;
+
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->ino = ip->i_ino;
@@ -1000,6 +1037,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
up(&JFS_IP(dip)->commit_sem);
up(&JFS_IP(ip)->commit_sem);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
@@ -1008,11 +1046,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
out2:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dip);
-#endif
-
out1:
jfs_info("jfs_symlink: rc:%d", rc);
return rc;
@@ -1328,8 +1361,20 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
down(&JFS_IP(dir)->commit_sem);
down(&JFS_IP(ip)->commit_sem);
- if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
+ rc = jfs_init_acl(tid, ip, dir);
+ if (rc)
+ goto out3;
+
+ rc = jfs_init_security(tid, ip, dir);
+ if (rc) {
+ txAbort(tid, 0);
goto out3;
+ }
+
+ if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
+ txAbort(tid, 0);
+ goto out3;
+ }
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
@@ -1337,8 +1382,10 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
ino = ip->i_ino;
- if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
+ if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
+ txAbort(tid, 0);
goto out3;
+ }
ip->i_op = &jfs_file_inode_operations;
jfs_ip->dev = new_encode_dev(rdev);
@@ -1360,6 +1407,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
up(&JFS_IP(ip)->commit_sem);
up(&JFS_IP(dir)->commit_sem);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
@@ -1368,11 +1416,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
out1:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dir);
-#endif
-
out:
jfs_info("jfs_mknod: returning %d", rc);
return rc;
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 554ec739e49b..23aa5066b5a4 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -21,6 +21,7 @@
#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>
#include <linux/quotaops.h>
+#include <linux/security.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
@@ -633,12 +634,12 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf)
}
}
-static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
+static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf,
+ int new_size)
{
struct jfs_inode_info *ji = JFS_IP(inode);
unsigned long old_blocks, new_blocks;
int rc = 0;
- tid_t tid;
if (new_size == 0) {
ea_release(inode, ea_buf);
@@ -664,9 +665,6 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
if (rc)
return rc;
- tid = txBegin(inode->i_sb, 0);
- down(&ji->commit_sem);
-
old_blocks = new_blocks = 0;
if (ji->ea.flag & DXD_EXTENT) {
@@ -695,11 +693,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
DQUOT_FREE_BLOCK(inode, old_blocks);
inode->i_ctime = CURRENT_TIME;
- rc = txCommit(tid, 1, &inode, 0);
- txEnd(tid);
- up(&ji->commit_sem);
- return rc;
+ return 0;
}
/*
@@ -810,8 +805,8 @@ static int can_set_xattr(struct inode *inode, const char *name,
return permission(inode, MAY_WRITE, NULL);
}
-int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
- size_t value_len, int flags)
+int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name,
+ const void *value, size_t value_len, int flags)
{
struct jfs_ea_list *ealist;
struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL;
@@ -825,9 +820,6 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
int rc;
int length;
- if ((rc = can_set_xattr(inode, name, value, value_len)))
- return rc;
-
if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
GFP_KERNEL);
@@ -939,7 +931,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
ealist->size = cpu_to_le32(new_size);
- rc = ea_put(inode, &ea_buf, new_size);
+ rc = ea_put(tid, inode, &ea_buf, new_size);
goto out;
release:
@@ -955,12 +947,29 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t value_len, int flags)
{
+ struct inode *inode = dentry->d_inode;
+ struct jfs_inode_info *ji = JFS_IP(inode);
+ int rc;
+ tid_t tid;
+
+ if ((rc = can_set_xattr(inode, name, value, value_len)))
+ return rc;
+
if (value == NULL) { /* empty EA, do not remove */
value = "";
value_len = 0;
}
- return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags);
+ tid = txBegin(inode->i_sb, 0);
+ down(&ji->commit_sem);
+ rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len,
+ flags);
+ if (!rc)
+ rc = txCommit(tid, 1, &inode, 0);
+ txEnd(tid);
+ up(&ji->commit_sem);
+
+ return rc;
}
static int can_get_xattr(struct inode *inode, const char *name)
@@ -1122,5 +1131,56 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
int jfs_removexattr(struct dentry *dentry, const char *name)
{
- return __jfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
+ struct inode *inode = dentry->d_inode;
+ struct jfs_inode_info *ji = JFS_IP(inode);
+ int rc;
+ tid_t tid;
+
+ if ((rc = can_set_xattr(inode, name, NULL, 0)))
+ return rc;
+
+ tid = txBegin(inode->i_sb, 0);
+ down(&ji->commit_sem);
+ rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
+ if (!rc)
+ rc = txCommit(tid, 1, &inode, 0);
+ txEnd(tid);
+ up(&ji->commit_sem);
+
+ return rc;
+}
+
+#ifdef CONFIG_JFS_SECURITY
+int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir)
+{
+ int rc;
+ size_t len;
+ void *value;
+ char *suffix;
+ char *name;
+
+ rc = security_inode_init_security(inode, dir, &suffix, &value, &len);
+ if (rc) {
+ if (rc == -EOPNOTSUPP)
+ return 0;
+ return rc;
+ }
+ name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix),
+ GFP_NOFS);
+ if (!name) {
+ rc = -ENOMEM;
+ goto kmalloc_failed;
+ }
+ strcpy(name, XATTR_SECURITY_PREFIX);
+ strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
+
+ rc = __jfs_setxattr(tid, inode, name, value, len, 0);
+
+ kfree(name);
+kmalloc_failed:
+ kfree(suffix);
+ kfree(value);
+
+ return rc;
}
+#endif
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 14b3ce87fa29..87332f30141b 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -299,8 +299,7 @@ nlmclnt_alloc_call(void)
return call;
}
printk("nlmclnt_alloc_call: failed, waiting for memory\n");
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(5*HZ);
+ schedule_timeout_interruptible(5*HZ);
}
return NULL;
}
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 82c77df81c5f..c4c8601096e0 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -173,11 +173,10 @@ nlm_bind_host(struct nlm_host *host)
/* If we've already created an RPC client, check whether
* RPC rebind is required
- * Note: why keep rebinding if we're on a tcp connection?
*/
if ((clnt = host->h_rpcclnt) != NULL) {
xprt = clnt->cl_xprt;
- if (!xprt->stream && time_after_eq(jiffies, host->h_nextrebind)) {
+ if (time_after_eq(jiffies, host->h_nextrebind)) {
clnt->cl_port = 0;
host->h_nextrebind = jiffies + NLM_HOST_REBIND;
dprintk("lockd: next rebind in %ld jiffies\n",
@@ -189,7 +188,6 @@ nlm_bind_host(struct nlm_host *host)
goto forgetit;
xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
- xprt->nocong = 1; /* No congestion control for NLM */
xprt->resvport = 1; /* NLM requires a reserved port */
/* Existing NLM servers accept AUTH_UNIX only */
diff --git a/fs/locks.c b/fs/locks.c
index 11956b6179ff..a1e8b2248014 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -124,6 +124,7 @@
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/time.h>
+#include <linux/rcupdate.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -315,21 +316,22 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
/* POSIX-1996 leaves the case l->l_len < 0 undefined;
POSIX-2001 defines it. */
start += l->l_start;
- end = start + l->l_len - 1;
- if (l->l_len < 0) {
+ if (start < 0)
+ return -EINVAL;
+ fl->fl_end = OFFSET_MAX;
+ if (l->l_len > 0) {
+ end = start + l->l_len - 1;
+ fl->fl_end = end;
+ } else if (l->l_len < 0) {
end = start - 1;
+ fl->fl_end = end;
start += l->l_len;
+ if (start < 0)
+ return -EINVAL;
}
-
- if (start < 0)
- return -EINVAL;
- if (l->l_len > 0 && end < 0)
- return -EOVERFLOW;
-
fl->fl_start = start; /* we record the absolute position */
- fl->fl_end = end;
- if (l->l_len == 0)
- fl->fl_end = OFFSET_MAX;
+ if (fl->fl_end < fl->fl_start)
+ return -EOVERFLOW;
fl->fl_owner = current->files;
fl->fl_pid = current->tgid;
@@ -361,14 +363,21 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
return -EINVAL;
}
- if (((start += l->l_start) < 0) || (l->l_len < 0))
+ start += l->l_start;
+ if (start < 0)
return -EINVAL;
- fl->fl_end = start + l->l_len - 1;
- if (l->l_len > 0 && fl->fl_end < 0)
- return -EOVERFLOW;
+ fl->fl_end = OFFSET_MAX;
+ if (l->l_len > 0) {
+ fl->fl_end = start + l->l_len - 1;
+ } else if (l->l_len < 0) {
+ fl->fl_end = start - 1;
+ start += l->l_len;
+ if (start < 0)
+ return -EINVAL;
+ }
fl->fl_start = start; /* we record the absolute position */
- if (l->l_len == 0)
- fl->fl_end = OFFSET_MAX;
+ if (fl->fl_end < fl->fl_start)
+ return -EOVERFLOW;
fl->fl_owner = current->files;
fl->fl_pid = current->tgid;
@@ -828,12 +837,16 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request)
/* Detect adjacent or overlapping regions (if same lock type)
*/
if (request->fl_type == fl->fl_type) {
+ /* In all comparisons of start vs end, use
+ * "start - 1" rather than "end + 1". If end
+ * is OFFSET_MAX, end + 1 will become negative.
+ */
if (fl->fl_end < request->fl_start - 1)
goto next_lock;
/* If the next lock in the list has entirely bigger
* addresses than the new one, insert the lock here.
*/
- if (fl->fl_start > request->fl_end + 1)
+ if (fl->fl_start - 1 > request->fl_end)
break;
/* If we come here, the new and old lock are of the
@@ -2198,21 +2211,24 @@ 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;
+ rcu_read_lock();
+ 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);
}
@@ -2220,6 +2236,7 @@ void steal_locks(fl_owner_t from)
set >>= 1;
}
}
+ rcu_read_unlock();
unlock_kernel();
}
EXPORT_SYMBOL(steal_locks);
diff --git a/fs/mbcache.c b/fs/mbcache.c
index b002a088857d..298997f17475 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -116,7 +116,7 @@ mb_cache_indexes(struct mb_cache *cache)
* What the mbcache registers as to get shrunk dynamically.
*/
-static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask);
+static int mb_cache_shrink_fn(int nr_to_scan, gfp_t gfp_mask);
static inline int
@@ -140,7 +140,7 @@ __mb_cache_entry_unhash(struct mb_cache_entry *ce)
static inline void
-__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
+__mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
{
struct mb_cache *cache = ce->e_cache;
@@ -193,7 +193,7 @@ forget:
* Returns the number of objects which are present in the cache.
*/
static int
-mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask)
+mb_cache_shrink_fn(int nr_to_scan, gfp_t gfp_mask)
{
LIST_HEAD(free_list);
struct list_head *l, *ltmp;
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 3f18c21198d7..790cc0d0e970 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -24,6 +24,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data);
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/mpage.c b/fs/mpage.c
index bb9aebe93862..c5adcdddf3cc 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -102,7 +102,7 @@ static struct bio *mpage_bio_submit(int rw, struct bio *bio)
static struct bio *
mpage_alloc(struct block_device *bdev,
sector_t first_sector, int nr_vecs,
- unsigned int __nocast gfp_flags)
+ gfp_t gfp_flags)
{
struct bio *bio;
diff --git a/fs/namei.c b/fs/namei.c
index 145e852c4bd0..aaaa81036234 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -28,6 +28,7 @@
#include <linux/syscalls.h>
#include <linux/mount.h>
#include <linux/audit.h>
+#include <linux/file.h>
#include <asm/namei.h>
#include <asm/uaccess.h>
@@ -317,6 +318,18 @@ void path_release_on_umount(struct nameidata *nd)
mntput_no_expire(nd->mnt);
}
+/**
+ * release_open_intent - free up open intent resources
+ * @nd: pointer to nameidata
+ */
+void release_open_intent(struct nameidata *nd)
+{
+ if (nd->intent.open.file->f_dentry == NULL)
+ put_filp(nd->intent.open.file);
+ else
+ fput(nd->intent.open.file);
+}
+
/*
* Internal lookup() using the new generic dcache.
* SMP-safe
@@ -750,6 +763,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
struct qstr this;
unsigned int c;
+ nd->flags |= LOOKUP_CONTINUE;
err = exec_permission_lite(inode, nd);
if (err == -EAGAIN) {
err = permission(inode, MAY_EXEC, nd);
@@ -802,7 +816,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
if (err < 0)
break;
}
- nd->flags |= LOOKUP_CONTINUE;
/* This does the actual lookups.. */
err = do_lookup(nd, &this, &next);
if (err)
@@ -1048,10 +1061,74 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
out:
if (unlikely(current->audit_context
&& nd && nd->dentry && nd->dentry->d_inode))
- audit_inode(name, nd->dentry->d_inode);
+ audit_inode(name, nd->dentry->d_inode, flags);
return retval;
}
+static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags, int create_mode)
+{
+ struct file *filp = get_empty_filp();
+ int err;
+
+ if (filp == NULL)
+ return -ENFILE;
+ nd->intent.open.file = filp;
+ nd->intent.open.flags = open_flags;
+ nd->intent.open.create_mode = create_mode;
+ err = path_lookup(name, lookup_flags|LOOKUP_OPEN, nd);
+ if (IS_ERR(nd->intent.open.file)) {
+ if (err == 0) {
+ err = PTR_ERR(nd->intent.open.file);
+ path_release(nd);
+ }
+ } else if (err != 0)
+ release_open_intent(nd);
+ return err;
+}
+
+/**
+ * path_lookup_open - lookup a file path with open intent
+ * @name: pointer to file name
+ * @lookup_flags: lookup intent flags
+ * @nd: pointer to nameidata
+ * @open_flags: open intent flags
+ */
+int path_lookup_open(const char *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags)
+{
+ return __path_lookup_intent_open(name, lookup_flags, nd,
+ open_flags, 0);
+}
+
+/**
+ * path_lookup_create - lookup a file path with open + create intent
+ * @name: pointer to file name
+ * @lookup_flags: lookup intent flags
+ * @nd: pointer to nameidata
+ * @open_flags: open intent flags
+ * @create_mode: create intent flags
+ */
+int path_lookup_create(const char *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags, int create_mode)
+{
+ return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
+ open_flags, create_mode);
+}
+
+int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags)
+{
+ char *tmp = getname(name);
+ int err = PTR_ERR(tmp);
+
+ if (!IS_ERR(tmp)) {
+ err = __path_lookup_intent_open(tmp, lookup_flags, nd, open_flags, 0);
+ putname(tmp);
+ }
+ return err;
+}
+
/*
* Restricted form of lookup. Doesn't follow links, single-component only,
* needs parent already locked. Doesn't follow mounts.
@@ -1316,10 +1393,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;
}
@@ -1418,27 +1493,27 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
*/
int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
{
- int acc_mode, error = 0;
+ int acc_mode, error;
struct path path;
struct dentry *dir;
int count = 0;
acc_mode = ACC_MODE(flag);
+ /* O_TRUNC implies we need access checks for write permissions */
+ if (flag & O_TRUNC)
+ acc_mode |= MAY_WRITE;
+
/* Allow the LSM permission hook to distinguish append
access from general write access. */
if (flag & O_APPEND)
acc_mode |= MAY_APPEND;
- /* Fill in the open() intent data */
- nd->intent.open.flags = flag;
- nd->intent.open.create_mode = mode;
-
/*
* The simplest case - just a plain lookup.
*/
if (!(flag & O_CREAT)) {
- error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
+ error = path_lookup_open(pathname, lookup_flags(flag), nd, flag);
if (error)
return error;
goto ok;
@@ -1447,7 +1522,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
/*
* Create - we need to know the parent.
*/
- error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
+ error = path_lookup_create(pathname, LOOKUP_PARENT, nd, flag, mode);
if (error)
return error;
@@ -1522,6 +1597,8 @@ ok:
exit_dput:
dput_path(&path, nd);
exit:
+ if (!IS_ERR(nd->intent.open.file))
+ release_open_intent(nd);
path_release(nd);
return error;
@@ -1553,19 +1630,19 @@ do_link:
if (nd->last_type != LAST_NORM)
goto exit;
if (nd->last.name[nd->last.len]) {
- putname(nd->last.name);
+ __putname(nd->last.name);
goto exit;
}
error = -ELOOP;
if (count++==32) {
- putname(nd->last.name);
+ __putname(nd->last.name);
goto exit;
}
dir = nd->dentry;
down(&dir->d_inode->i_sem);
path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
path.mnt = nd->mnt;
- putname(nd->last.name);
+ __putname(nd->last.name);
goto do_last;
}
@@ -1635,10 +1712,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 +1783,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 +2020,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 +2091,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 +2211,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 +2238,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/namespace.c b/fs/namespace.c
index 34156260c9b6..2fa9fdf7d6f5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -537,7 +537,6 @@ lives_below_in_same_fs(struct dentry *d, struct dentry *dentry)
static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
{
struct vfsmount *res, *p, *q, *r, *s;
- struct list_head *h;
struct nameidata nd;
res = q = clone_mnt(mnt, dentry);
@@ -546,8 +545,7 @@ static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
q->mnt_mountpoint = mnt->mnt_mountpoint;
p = mnt;
- for (h = mnt->mnt_mounts.next; h != &mnt->mnt_mounts; h = h->next) {
- r = list_entry(h, struct vfsmount, mnt_child);
+ list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
if (!lives_below_in_same_fs(r->mnt_mountpoint, dentry))
continue;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 44795d2f4b30..8c8839203cd5 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -286,6 +286,8 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
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/delegation.c b/fs/nfs/delegation.c
index d7f7eb669d03..44135af9894c 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -85,6 +85,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
struct nfs_delegation *delegation;
int status = 0;
+ /* Ensure we first revalidate the attributes and page cache! */
+ if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR)))
+ __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+
delegation = nfs_alloc_delegation();
if (delegation == NULL)
return -ENOMEM;
@@ -138,7 +142,7 @@ static void nfs_msync_inode(struct inode *inode)
/*
* Basic procedure for returning a delegation to the server
*/
-int nfs_inode_return_delegation(struct inode *inode)
+int __nfs_inode_return_delegation(struct inode *inode)
{
struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state;
struct nfs_inode *nfsi = NFS_I(inode);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 3f6c45a29d6a..8017846b561f 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -25,7 +25,7 @@ struct nfs_delegation {
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
-int nfs_inode_return_delegation(struct inode *inode);
+int __nfs_inode_return_delegation(struct inode *inode);
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle);
@@ -47,11 +47,25 @@ static inline int nfs_have_delegation(struct inode *inode, int flags)
return 1;
return 0;
}
+
+static inline int nfs_inode_return_delegation(struct inode *inode)
+{
+ int err = 0;
+
+ if (NFS_I(inode)->delegation != NULL)
+ err = __nfs_inode_return_delegation(inode);
+ return err;
+}
#else
static inline int nfs_have_delegation(struct inode *inode, int flags)
{
return 0;
}
+
+static inline int nfs_inode_return_delegation(struct inode *inode)
+{
+ return 0;
+}
#endif
#endif
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 2df639f143e8..8272ed3fc707 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -532,6 +532,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
my_entry.eof = 0;
my_entry.fh = &fh;
my_entry.fattr = &fattr;
+ nfs_fattr_init(&fattr);
desc->entry = &my_entry;
while(!desc->entry->eof) {
@@ -565,8 +566,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
}
unlock_kernel();
- if (desc->error < 0)
- return desc->error;
if (res < 0)
return res;
return 0;
@@ -803,6 +802,7 @@ static int nfs_dentry_delete(struct dentry *dentry)
*/
static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
{
+ nfs_inode_return_delegation(inode);
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
lock_kernel();
inode->i_nlink--;
@@ -853,12 +853,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
lock_kernel();
- /* Revalidate parent directory attribute cache */
- error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
- if (error < 0) {
- res = ERR_PTR(error);
- goto out_unlock;
- }
/* If we're doing an exclusive create, optimize away the lookup */
if (nfs_is_exclusive_create(dir, nd))
@@ -916,7 +910,6 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd)
static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
struct dentry *res = NULL;
- struct inode *inode = NULL;
int error;
/* Check that we are indeed trying to open this file */
@@ -930,8 +923,10 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
/* Let vfs_create() deal with O_EXCL */
- if (nd->intent.open.flags & O_EXCL)
- goto no_entry;
+ if (nd->intent.open.flags & O_EXCL) {
+ d_add(dentry, NULL);
+ goto out;
+ }
/* Open the file on the server */
lock_kernel();
@@ -945,32 +940,30 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
if (nd->intent.open.flags & O_CREAT) {
nfs_begin_data_update(dir);
- inode = nfs4_atomic_open(dir, dentry, nd);
+ res = nfs4_atomic_open(dir, dentry, nd);
nfs_end_data_update(dir);
} else
- inode = nfs4_atomic_open(dir, dentry, nd);
+ res = nfs4_atomic_open(dir, dentry, nd);
unlock_kernel();
- if (IS_ERR(inode)) {
- error = PTR_ERR(inode);
+ if (IS_ERR(res)) {
+ error = PTR_ERR(res);
switch (error) {
/* Make a negative dentry */
case -ENOENT:
- inode = NULL;
- break;
+ res = NULL;
+ goto out;
/* This turned out not to be a regular file */
+ case -EISDIR:
+ case -ENOTDIR:
+ goto no_open;
case -ELOOP:
if (!(nd->intent.open.flags & O_NOFOLLOW))
goto no_open;
- /* case -EISDIR: */
/* case -EINVAL: */
default:
- res = ERR_PTR(error);
goto out;
}
- }
-no_entry:
- res = d_add_unique(dentry, inode);
- if (res != NULL)
+ } else if (res != NULL)
dentry = res;
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
@@ -1014,7 +1007,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
*/
lock_kernel();
verifier = nfs_save_change_attribute(dir);
- ret = nfs4_open_revalidate(dir, dentry, openflags);
+ ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
if (!ret)
nfs_set_verifier(dentry, verifier);
unlock_kernel();
@@ -1137,7 +1130,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
lock_kernel();
nfs_begin_data_update(dir);
- error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
+ error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
nfs_end_data_update(dir);
if (error != 0)
goto out_err;
@@ -1332,6 +1325,7 @@ static int nfs_safe_remove(struct dentry *dentry)
nfs_begin_data_update(dir);
if (inode != NULL) {
+ nfs_inode_return_delegation(inode);
nfs_begin_data_update(inode);
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
/* The VFS may want to delete this inode */
@@ -1438,17 +1432,14 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
dentry->d_parent->d_name.name, dentry->d_name.name);
- /*
- * Drop the dentry in advance to force a new lookup.
- * Since nfs_proc_link doesn't return a file handle,
- * we can't use the existing dentry.
- */
lock_kernel();
- d_drop(dentry);
-
nfs_begin_data_update(dir);
nfs_begin_data_update(inode);
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
+ if (error == 0) {
+ atomic_inc(&inode->i_count);
+ d_instantiate(dentry, inode);
+ }
nfs_end_data_update(inode);
nfs_end_data_update(dir);
unlock_kernel();
@@ -1512,9 +1503,11 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
*/
if (!new_inode)
goto go_ahead;
- if (S_ISDIR(new_inode->i_mode))
- goto out;
- else if (atomic_read(&new_dentry->d_count) > 2) {
+ if (S_ISDIR(new_inode->i_mode)) {
+ error = -EISDIR;
+ if (!S_ISDIR(old_inode->i_mode))
+ goto out;
+ } else if (atomic_read(&new_dentry->d_count) > 2) {
int err;
/* copy the target dentry's name */
dentry = d_alloc(new_dentry->d_parent,
@@ -1539,7 +1532,8 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
#endif
goto out;
}
- }
+ } else
+ new_inode->i_nlink--;
go_ahead:
/*
@@ -1549,6 +1543,7 @@ go_ahead:
nfs_wb_all(old_inode);
shrink_dcache_parent(old_dentry);
}
+ nfs_inode_return_delegation(old_inode);
if (new_inode)
d_delete(new_dentry);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f6b9eda925c5..57d3e77d97ee 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -137,7 +137,8 @@ static int nfs_revalidate_file(struct inode *inode, struct file *filp)
struct nfs_inode *nfsi = NFS_I(inode);
int retval = 0;
- if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode))
+ if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR))
+ || nfs_attribute_timeout(inode))
retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
nfs_revalidate_mapping(inode, filp->f_mapping);
return 0;
@@ -204,8 +205,8 @@ nfs_file_flush(struct file *file)
if (!status) {
status = ctx->error;
ctx->error = 0;
- if (!status && !nfs_have_delegation(inode, FMODE_READ))
- __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ if (!status)
+ nfs_revalidate_inode(NFS_SERVER(inode), inode);
}
unlock_kernel();
return status;
@@ -375,22 +376,31 @@ out_swapfile:
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
{
+ struct file_lock *cfl;
struct inode *inode = filp->f_mapping->host;
int status = 0;
lock_kernel();
- /* Use local locking if mounted with "-onolock" */
- if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
- status = NFS_PROTO(inode)->lock(filp, cmd, fl);
- else {
- struct file_lock *cfl = posix_test_lock(filp, fl);
-
- fl->fl_type = F_UNLCK;
- if (cfl != NULL)
- memcpy(fl, cfl, sizeof(*fl));
+ /* Try local locking first */
+ cfl = posix_test_lock(filp, fl);
+ if (cfl != NULL) {
+ locks_copy_lock(fl, cfl);
+ goto out;
}
+
+ if (nfs_have_delegation(inode, FMODE_READ))
+ goto out_noconflict;
+
+ if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
+ goto out_noconflict;
+
+ status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+out:
unlock_kernel();
return status;
+out_noconflict:
+ fl->fl_type = F_UNLCK;
+ goto out;
}
static int do_vfs_lock(struct file *file, struct file_lock *fl)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 541b418327c8..f2781ca42761 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...
@@ -356,6 +358,35 @@ out_no_root:
return no_root_error;
}
+static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans)
+{
+ to->to_initval = timeo * HZ / 10;
+ to->to_retries = retrans;
+ if (!to->to_retries)
+ to->to_retries = 2;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ if (!to->to_initval)
+ to->to_initval = 60 * HZ;
+ if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
+ to->to_initval = NFS_MAX_TCP_TIMEOUT;
+ to->to_increment = to->to_initval;
+ to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
+ to->to_exponential = 0;
+ break;
+ case IPPROTO_UDP:
+ default:
+ if (!to->to_initval)
+ to->to_initval = 11 * HZ / 10;
+ if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
+ to->to_initval = NFS_MAX_UDP_TIMEOUT;
+ to->to_maxval = NFS_MAX_UDP_TIMEOUT;
+ to->to_exponential = 1;
+ break;
+ }
+}
+
/*
* Create an RPC client handle.
*/
@@ -365,22 +396,12 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
struct rpc_timeout timeparms;
struct rpc_xprt *xprt = NULL;
struct rpc_clnt *clnt = NULL;
- int tcp = (data->flags & NFS_MOUNT_TCP);
-
- /* Initialize timeout values */
- timeparms.to_initval = data->timeo * HZ / 10;
- timeparms.to_retries = data->retrans;
- timeparms.to_maxval = tcp ? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
- timeparms.to_exponential = 1;
+ int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
- if (!timeparms.to_initval)
- timeparms.to_initval = (tcp ? 600 : 11) * HZ / 10;
- if (!timeparms.to_retries)
- timeparms.to_retries = 5;
+ nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
/* create transport and client */
- xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
- &server->addr, &timeparms);
+ xprt = xprt_create_proto(proto, &server->addr, &timeparms);
if (IS_ERR(xprt)) {
dprintk("%s: cannot create RPC transport. Error = %ld\n",
__FUNCTION__, PTR_ERR(xprt));
@@ -574,7 +595,6 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
{ NFS_MOUNT_SOFT, ",soft", ",hard" },
{ NFS_MOUNT_INTR, ",intr", "" },
{ NFS_MOUNT_POSIX, ",posix", "" },
- { NFS_MOUNT_TCP, ",tcp", ",udp" },
{ NFS_MOUNT_NOCTO, ",nocto", "" },
{ NFS_MOUNT_NOAC, ",noac", "" },
{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
@@ -583,6 +603,8 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
};
struct proc_nfs_info *nfs_infop;
struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
+ char buf[12];
+ char *proto;
seq_printf(m, ",v%d", nfss->rpc_ops->version);
seq_printf(m, ",rsize=%d", nfss->rsize);
@@ -601,6 +623,18 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
else
seq_puts(m, nfs_infop->nostr);
}
+ switch (nfss->client->cl_xprt->prot) {
+ case IPPROTO_TCP:
+ proto = "tcp";
+ break;
+ case IPPROTO_UDP:
+ proto = "udp";
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
+ proto = buf;
+ }
+ seq_printf(m, ",proto=%s", proto);
seq_puts(m, ",addr=");
seq_escape(m, nfss->hostname, " \t\n\\");
return 0;
@@ -751,7 +785,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
else
init_special_inode(inode, inode->i_mode, fattr->rdev);
- nfsi->read_cache_jiffies = fattr->timestamp;
+ nfsi->read_cache_jiffies = fattr->time_start;
+ nfsi->last_updated = jiffies;
inode->i_atime = fattr->atime;
inode->i_mtime = fattr->mtime;
inode->i_ctime = fattr->ctime;
@@ -819,6 +854,11 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
filemap_fdatawait(inode->i_mapping);
nfs_wb_all(inode);
}
+ /*
+ * Return any delegations if we're going to change ACLs
+ */
+ if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
+ nfs_inode_return_delegation(inode);
error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
if (error == 0)
nfs_refresh_inode(inode, &fattr);
@@ -875,12 +915,10 @@ static int nfs_wait_on_inode(struct inode *inode)
sigset_t oldmask;
int error;
- atomic_inc(&inode->i_count);
rpc_clnt_sigmask(clnt, &oldmask);
error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
nfs_wait_schedule, TASK_INTERRUPTIBLE);
rpc_clnt_sigunmask(clnt, &oldmask);
- iput(inode);
return error;
}
@@ -1019,15 +1057,11 @@ int nfs_open(struct inode *inode, struct file *filp)
ctx->mode = filp->f_mode;
nfs_file_set_open_context(filp, ctx);
put_nfs_open_context(ctx);
- if ((filp->f_mode & FMODE_WRITE) != 0)
- nfs_begin_data_update(inode);
return 0;
}
int nfs_release(struct inode *inode, struct file *filp)
{
- if ((filp->f_mode & FMODE_WRITE) != 0)
- nfs_end_data_update(inode);
nfs_file_clear_open_context(filp);
return 0;
}
@@ -1083,14 +1117,15 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
goto out;
}
+ spin_lock(&inode->i_lock);
status = nfs_update_inode(inode, &fattr, verifier);
if (status) {
+ spin_unlock(&inode->i_lock);
dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
inode->i_sb->s_id,
(long long)NFS_FILEID(inode), status);
goto out;
}
- spin_lock(&inode->i_lock);
cache_validity = nfsi->cache_validity;
nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
@@ -1098,7 +1133,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
* We may need to keep the attributes marked as invalid if
* we raced with nfs_end_attr_update().
*/
- if (verifier == nfsi->cache_change_attribute)
+ if (time_after_eq(verifier, nfsi->cache_change_attribute))
nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
spin_unlock(&inode->i_lock);
@@ -1165,7 +1200,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
if (S_ISDIR(inode->i_mode)) {
memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
/* This ensures we revalidate child dentries */
- nfsi->cache_change_attribute++;
+ nfsi->cache_change_attribute = jiffies;
}
spin_unlock(&inode->i_lock);
@@ -1197,20 +1232,19 @@ void nfs_end_data_update(struct inode *inode)
struct nfs_inode *nfsi = NFS_I(inode);
if (!nfs_have_delegation(inode, FMODE_READ)) {
- /* Mark the attribute cache for revalidation */
- spin_lock(&inode->i_lock);
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
- /* Directories and symlinks: invalidate page cache too */
- if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+ /* Directories and symlinks: invalidate page cache */
+ if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
+ spin_lock(&inode->i_lock);
nfsi->cache_validity |= NFS_INO_INVALID_DATA;
- spin_unlock(&inode->i_lock);
+ spin_unlock(&inode->i_lock);
+ }
}
- nfsi->cache_change_attribute ++;
+ nfsi->cache_change_attribute = jiffies;
atomic_dec(&nfsi->data_updates);
}
/**
- * nfs_refresh_inode - verify consistency of the inode attribute cache
+ * nfs_check_inode_attributes - verify consistency of the inode attribute cache
* @inode - pointer to inode
* @fattr - updated attributes
*
@@ -1218,17 +1252,12 @@ void nfs_end_data_update(struct inode *inode)
* so that fattr carries weak cache consistency data, then it may
* also update the ctime/mtime/change_attribute.
*/
-int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fattr)
{
struct nfs_inode *nfsi = NFS_I(inode);
loff_t cur_size, new_isize;
int data_unstable;
- /* Do we hold a delegation? */
- if (nfs_have_delegation(inode, FMODE_READ))
- return 0;
-
- spin_lock(&inode->i_lock);
/* Are we in the process of updating data on the server? */
data_unstable = nfs_caches_unstable(inode);
@@ -1292,11 +1321,67 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
if (!timespec_equal(&inode->i_atime, &fattr->atime))
nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
- nfsi->read_cache_jiffies = fattr->timestamp;
- spin_unlock(&inode->i_lock);
+ nfsi->read_cache_jiffies = fattr->time_start;
return 0;
}
+/**
+ * nfs_refresh_inode - try to update the inode attribute cache
+ * @inode - pointer to inode
+ * @fattr - updated attributes
+ *
+ * Check that an RPC call that returned attributes has not overlapped with
+ * other recent updates of the inode metadata, then decide whether it is
+ * safe to do a full update of the inode attributes, or whether just to
+ * call nfs_check_inode_attributes.
+ */
+int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ int status;
+
+ if ((fattr->valid & NFS_ATTR_FATTR) == 0)
+ return 0;
+ spin_lock(&inode->i_lock);
+ nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
+ if (nfs_verify_change_attribute(inode, fattr->time_start))
+ nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
+ if (time_after(fattr->time_start, nfsi->last_updated))
+ status = nfs_update_inode(inode, fattr, fattr->time_start);
+ else
+ status = nfs_check_inode_attributes(inode, fattr);
+
+ spin_unlock(&inode->i_lock);
+ return status;
+}
+
+/**
+ * nfs_post_op_update_inode - try to update the inode attribute cache
+ * @inode - pointer to inode
+ * @fattr - updated attributes
+ *
+ * After an operation that has changed the inode metadata, mark the
+ * attribute cache as being invalid, then try to update it.
+ */
+int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ int status = 0;
+
+ spin_lock(&inode->i_lock);
+ if (unlikely((fattr->valid & NFS_ATTR_FATTR) == 0)) {
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+ goto out;
+ }
+ status = nfs_update_inode(inode, fattr, fattr->time_start);
+ if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
+ nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
+ nfsi->cache_change_attribute = jiffies;
+out:
+ spin_unlock(&inode->i_lock);
+ return status;
+}
+
/*
* Many nfs protocol calls return the new file attributes after
* an operation. Here we update the inode to reflect the state
@@ -1332,23 +1417,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
goto out_err;
}
- spin_lock(&inode->i_lock);
-
/*
* Make sure the inode's type hasn't changed.
*/
- if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
- spin_unlock(&inode->i_lock);
+ if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
goto out_changed;
- }
/*
* Update the read time so we don't revalidate too often.
*/
- nfsi->read_cache_jiffies = fattr->timestamp;
+ nfsi->read_cache_jiffies = fattr->time_start;
+ nfsi->last_updated = jiffies;
/* Are we racing with known updates of the metadata on the server? */
- data_unstable = ! nfs_verify_change_attribute(inode, verifier);
+ data_unstable = ! (nfs_verify_change_attribute(inode, verifier) ||
+ (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE));
/* Check if our cached file size is stale */
new_isize = nfs_size_to_loff_t(fattr->size);
@@ -1357,7 +1440,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
/* Do we perhaps have any outstanding writes? */
if (nfsi->npages == 0) {
/* No, but did we race with nfs_end_data_update()? */
- if (verifier == nfsi->cache_change_attribute) {
+ if (time_after_eq(verifier, nfsi->cache_change_attribute)) {
inode->i_size = new_isize;
invalid |= NFS_INO_INVALID_DATA;
}
@@ -1433,7 +1516,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
if (!nfs_have_delegation(inode, FMODE_READ))
nfsi->cache_validity |= invalid;
- spin_unlock(&inode->i_lock);
return 0;
out_changed:
/*
@@ -1642,8 +1724,7 @@ static void nfs4_clear_inode(struct inode *inode)
struct nfs_inode *nfsi = NFS_I(inode);
/* If we are holding a delegation, return it! */
- if (nfsi->delegation != NULL)
- nfs_inode_return_delegation(inode);
+ nfs_inode_return_delegation(inode);
/* First call standard NFS clear_inode() code */
nfs_clear_inode(inode);
/* Now clear out any remaining state */
@@ -1672,7 +1753,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
struct rpc_clnt *clnt = NULL;
struct rpc_timeout timeparms;
rpc_authflavor_t authflavour;
- int proto, err = -EIO;
+ int err = -EIO;
sb->s_blocksize_bits = 0;
sb->s_blocksize = 0;
@@ -1690,30 +1771,8 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
server->acdirmax = data->acdirmax*HZ;
server->rpc_ops = &nfs_v4_clientops;
- /* Initialize timeout values */
-
- timeparms.to_initval = data->timeo * HZ / 10;
- timeparms.to_retries = data->retrans;
- timeparms.to_exponential = 1;
- if (!timeparms.to_retries)
- timeparms.to_retries = 5;
- proto = data->proto;
- /* Which IP protocol do we use? */
- switch (proto) {
- case IPPROTO_TCP:
- timeparms.to_maxval = RPC_MAX_TCP_TIMEOUT;
- if (!timeparms.to_initval)
- timeparms.to_initval = 600 * HZ / 10;
- break;
- case IPPROTO_UDP:
- timeparms.to_maxval = RPC_MAX_UDP_TIMEOUT;
- if (!timeparms.to_initval)
- timeparms.to_initval = 11 * HZ / 10;
- break;
- default:
- return -EINVAL;
- }
+ nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
clp = nfs4_get_client(&server->addr.sin_addr);
if (!clp) {
@@ -1738,7 +1797,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
down_write(&clp->cl_sem);
if (IS_ERR(clp->cl_rpcclient)) {
- xprt = xprt_create_proto(proto, &server->addr, &timeparms);
+ xprt = xprt_create_proto(data->proto, &server->addr, &timeparms);
if (IS_ERR(xprt)) {
up_write(&clp->cl_sem);
err = PTR_ERR(xprt);
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index d91b69044a4d..59049e864ca7 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -143,7 +143,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
fattr->rdev = 0;
}
- fattr->timestamp = jiffies;
return p;
}
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 2681485cf2d0..92c870d19ccd 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -34,8 +34,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
res = rpc_call_sync(clnt, msg, flags);
if (res != -EJUKEBOX)
break;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(NFS_JUKEBOX_RETRY_TIME);
+ schedule_timeout_interruptible(NFS_JUKEBOX_RETRY_TIME);
res = -ERESTARTSYS;
} while (!signalled());
rpc_clnt_sigunmask(clnt, &oldset);
@@ -79,7 +78,7 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("%s: call fsinfo\n", __FUNCTION__);
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
@@ -99,7 +98,7 @@ nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call getattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(server->client, NFS3PROC_GETATTR,
fhandle, fattr, 0);
dprintk("NFS reply getattr: %d\n", status);
@@ -118,7 +117,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
int status;
dprintk("NFS call setattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
if (status == 0)
nfs_setattr_update_inode(inode, sattr);
@@ -144,8 +143,8 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
int status;
dprintk("NFS call lookup %s\n", name->name);
- dir_attr.valid = 0;
- fattr->valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0);
if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR))
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
@@ -175,7 +174,6 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
int status;
dprintk("NFS call access\n");
- fattr.valid = 0;
if (mode & MAY_READ)
arg.access |= NFS3_ACCESS_READ;
@@ -190,6 +188,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
if (mode & MAY_EXEC)
arg.access |= NFS3_ACCESS_EXECUTE;
}
+ nfs_fattr_init(&fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
nfs_refresh_inode(inode, &fattr);
if (status == 0) {
@@ -218,7 +217,7 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
int status;
dprintk("NFS call readlink\n");
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK,
&args, &fattr, 0);
nfs_refresh_inode(inode, &fattr);
@@ -241,7 +240,7 @@ static int nfs3_proc_read(struct nfs_read_data *rdata)
dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
(long long) rdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0)
nfs_refresh_inode(inode, fattr);
@@ -264,10 +263,10 @@ static int nfs3_proc_write(struct nfs_write_data *wdata)
dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
(long long) wdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
if (status >= 0)
- nfs_refresh_inode(inode, fattr);
+ nfs_post_op_update_inode(inode, fattr);
dprintk("NFS reply write: %d\n", status);
return status < 0? status : wdata->res.count;
}
@@ -286,10 +285,10 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
(long long) cdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
if (status >= 0)
- nfs_refresh_inode(inode, fattr);
+ nfs_post_op_update_inode(inode, fattr);
dprintk("NFS reply commit: %d\n", status);
return status;
}
@@ -300,7 +299,7 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
*/
static int
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags)
+ int flags, struct nameidata *nd)
{
struct nfs_fh fhandle;
struct nfs_fattr fattr;
@@ -330,10 +329,10 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_mode &= ~current->fs->umask;
again:
- dir_attr.valid = 0;
- fattr.valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
/* If the server doesn't support the exclusive creation semantics,
* try again with simple 'guarded' mode. */
@@ -402,9 +401,9 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name)
int status;
dprintk("NFS call remove %s\n", name->name);
- dir_attr.valid = 0;
+ nfs_fattr_init(&dir_attr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
dprintk("NFS reply remove: %d\n", status);
return status;
}
@@ -423,7 +422,7 @@ nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr
ptr->arg.fh = NFS_FH(dir->d_inode);
ptr->arg.name = name->name;
ptr->arg.len = name->len;
- ptr->res.valid = 0;
+ nfs_fattr_init(&ptr->res);
msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
msg->rpc_argp = &ptr->arg;
msg->rpc_resp = &ptr->res;
@@ -440,7 +439,7 @@ nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
return 1;
if (msg->rpc_argp) {
dir_attr = (struct nfs_fattr*)msg->rpc_resp;
- nfs_refresh_inode(dir->d_inode, dir_attr);
+ nfs_post_op_update_inode(dir->d_inode, dir_attr);
kfree(msg->rpc_argp);
}
return 0;
@@ -466,11 +465,11 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
int status;
dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
- old_dir_attr.valid = 0;
- new_dir_attr.valid = 0;
+ nfs_fattr_init(&old_dir_attr);
+ nfs_fattr_init(&new_dir_attr);
status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
- nfs_refresh_inode(old_dir, &old_dir_attr);
- nfs_refresh_inode(new_dir, &new_dir_attr);
+ nfs_post_op_update_inode(old_dir, &old_dir_attr);
+ nfs_post_op_update_inode(new_dir, &new_dir_attr);
dprintk("NFS reply rename: %d\n", status);
return status;
}
@@ -492,11 +491,11 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
int status;
dprintk("NFS call link %s\n", name->name);
- dir_attr.valid = 0;
- fattr.valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
- nfs_refresh_inode(inode, &fattr);
+ nfs_post_op_update_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(inode, &fattr);
dprintk("NFS reply link: %d\n", status);
return status;
}
@@ -525,10 +524,10 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
if (path->len > NFS3_MAXPATHLEN)
return -ENAMETOOLONG;
dprintk("NFS call symlink %s -> %s\n", name->name, path->name);
- dir_attr.valid = 0;
- fattr->valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
dprintk("NFS reply symlink: %d\n", status);
return status;
}
@@ -553,13 +552,13 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
int status;
dprintk("NFS call mkdir %s\n", dentry->d_name.name);
- dir_attr.valid = 0;
- fattr.valid = 0;
sattr->ia_mode &= ~current->fs->umask;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
if (status != 0)
goto out;
status = nfs_instantiate(dentry, &fhandle, &fattr);
@@ -583,9 +582,9 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
int status;
dprintk("NFS call rmdir %s\n", name->name);
- dir_attr.valid = 0;
+ nfs_fattr_init(&dir_attr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
dprintk("NFS reply rmdir: %d\n", status);
return status;
}
@@ -635,7 +634,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
dprintk("NFS call readdir%s %d\n",
plus? "plus" : "", (unsigned int) cookie);
- dir_attr.valid = 0;
+ nfs_fattr_init(&dir_attr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_refresh_inode(dir, &dir_attr);
dprintk("NFS reply readdir: %d\n", status);
@@ -677,10 +676,10 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_mode &= ~current->fs->umask;
- dir_attr.valid = 0;
- fattr.valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
if (status != 0)
goto out;
status = nfs_instantiate(dentry, &fh, &fattr);
@@ -699,7 +698,7 @@ nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call fsstat\n");
- stat->fattr->valid = 0;
+ nfs_fattr_init(stat->fattr);
status = rpc_call(server->client, NFS3PROC_FSSTAT, fhandle, stat, 0);
dprintk("NFS reply statfs: %d\n", status);
return status;
@@ -712,7 +711,7 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call fsinfo\n");
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
dprintk("NFS reply fsinfo: %d\n", status);
return status;
@@ -725,7 +724,7 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call pathconf\n");
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client, NFS3PROC_PATHCONF, fhandle, info, 0);
dprintk("NFS reply pathconf: %d\n", status);
return status;
@@ -736,7 +735,7 @@ extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
static void
nfs3_read_done(struct rpc_task *task)
{
- struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+ struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
if (nfs3_async_handle_jukebox(task))
return;
@@ -776,7 +775,7 @@ nfs3_write_done(struct rpc_task *task)
return;
data = (struct nfs_write_data *)task->tk_calldata;
if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode(data->inode, data->res.fattr);
nfs_writeback_done(task);
}
@@ -820,7 +819,7 @@ nfs3_commit_done(struct rpc_task *task)
return;
data = (struct nfs_write_data *)task->tk_calldata;
if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode(data->inode, data->res.fattr);
nfs_commit_done(task);
}
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index db4a904810a4..0498bd36602c 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -174,7 +174,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
/* Update the mode bits */
fattr->valid |= (NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3);
- fattr->timestamp = jiffies;
return p;
}
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ec1a22d7b876..78a53f5a9f18 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -93,25 +93,50 @@ struct nfs4_client {
};
/*
+ * struct rpc_sequence ensures that RPC calls are sent in the exact
+ * order that they appear on the list.
+ */
+struct rpc_sequence {
+ struct rpc_wait_queue wait; /* RPC call delay queue */
+ spinlock_t lock; /* Protects the list */
+ struct list_head list; /* Defines sequence of RPC calls */
+};
+
+#define NFS_SEQID_CONFIRMED 1
+struct nfs_seqid_counter {
+ struct rpc_sequence *sequence;
+ int flags;
+ u32 counter;
+};
+
+struct nfs_seqid {
+ struct nfs_seqid_counter *sequence;
+ struct list_head list;
+};
+
+static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
+{
+ if (seqid_mutating_err(-status))
+ seqid->flags |= NFS_SEQID_CONFIRMED;
+}
+
+/*
* NFS4 state_owners and lock_owners are simply labels for ordered
* sequences of RPC calls. Their sole purpose is to provide once-only
* semantics by allowing the server to identify replayed requests.
- *
- * The ->so_sema is held during all state_owner seqid-mutating operations:
- * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
- * so_seqid.
*/
struct nfs4_state_owner {
+ spinlock_t so_lock;
struct list_head so_list; /* per-clientid list of state_owners */
struct nfs4_client *so_client;
u32 so_id; /* 32-bit identifier, unique */
- struct semaphore so_sema;
- u32 so_seqid; /* protected by so_sema */
atomic_t so_count;
struct rpc_cred *so_cred; /* Associated cred */
struct list_head so_states;
struct list_head so_delegations;
+ struct nfs_seqid_counter so_seqid;
+ struct rpc_sequence so_sequence;
};
/*
@@ -132,7 +157,7 @@ struct nfs4_lock_state {
fl_owner_t ls_owner; /* POSIX lock owner */
#define NFS_LOCK_INITIALIZED 1
int ls_flags;
- u32 ls_seqid;
+ struct nfs_seqid_counter ls_seqid;
u32 ls_id;
nfs4_stateid ls_stateid;
atomic_t ls_count;
@@ -153,7 +178,6 @@ struct nfs4_state {
struct inode *inode; /* Pointer to the inode */
unsigned long flags; /* Do we hold any locks? */
- struct semaphore lock_sema; /* Serializes file locking operations */
spinlock_t state_lock; /* Protects the lock_states list */
nfs4_stateid stateid;
@@ -191,8 +215,8 @@ extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
extern int nfs4_proc_async_renew(struct nfs4_client *);
extern int nfs4_proc_renew(struct nfs4_client *);
extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
-extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
+extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
+extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
@@ -224,12 +248,17 @@ extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state
extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_close_state(struct nfs4_state *, mode_t);
extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
-extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
extern void nfs4_schedule_state_recovery(struct nfs4_client *);
+extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
-extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
+extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
+extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
+extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
+extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
+extern void nfs_free_seqid(struct nfs_seqid *seqid);
+
extern const nfs4_stateid zero_stateid;
/* nfs4xdr.c */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0c5a308e4963..933e13b383f8 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -47,6 +47,7 @@
#include <linux/nfs_page.h>
#include <linux/smp_lock.h>
#include <linux/namei.h>
+#include <linux/mount.h>
#include "nfs4_fs.h"
#include "delegation.h"
@@ -56,10 +57,11 @@
#define NFS4_POLL_RETRY_MIN (1*HZ)
#define NFS4_POLL_RETRY_MAX (15*HZ)
+static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid);
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
-static int nfs4_async_handle_error(struct rpc_task *, struct nfs_server *);
+static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
-static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
+static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
extern struct rpc_procinfo nfs4_procedures[];
@@ -185,8 +187,26 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
{
struct nfs_inode *nfsi = NFS_I(inode);
+ spin_lock(&inode->i_lock);
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
if (cinfo->before == nfsi->change_attr && cinfo->atomic)
nfsi->change_attr = cinfo->after;
+ spin_unlock(&inode->i_lock);
+}
+
+/* Helper for asynchronous RPC calls */
+static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin,
+ rpc_action tk_exit, void *calldata)
+{
+ struct rpc_task *task;
+
+ if (!(task = rpc_new_task(clnt, tk_exit, RPC_TASK_ASYNC)))
+ return -ENOMEM;
+
+ task->tk_calldata = calldata;
+ task->tk_action = tk_begin;
+ rpc_execute(task);
+ return 0;
}
static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
@@ -195,6 +215,7 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid,
open_flags &= (FMODE_READ|FMODE_WRITE);
/* Protect against nfs4_find_state() */
+ spin_lock(&state->owner->so_lock);
spin_lock(&inode->i_lock);
state->state |= open_flags;
/* NB! List reordering - see the reclaim code for why. */
@@ -204,12 +225,12 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid,
state->nreaders++;
memcpy(&state->stateid, stateid, sizeof(state->stateid));
spin_unlock(&inode->i_lock);
+ spin_unlock(&state->owner->so_lock);
}
/*
* OPEN_RECLAIM:
* reclaim state on the server after a reboot.
- * Assumes caller is holding the sp->so_sem
*/
static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
{
@@ -218,7 +239,6 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
struct nfs_delegation *delegation = NFS_I(inode)->delegation;
struct nfs_openargs o_arg = {
.fh = NFS_FH(inode),
- .seqid = sp->so_seqid,
.id = sp->so_id,
.open_flags = state->state,
.clientid = server->nfs4_state->cl_clientid,
@@ -245,8 +265,13 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
}
o_arg.u.delegation_type = delegation->type;
}
+ o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ if (o_arg.seqid == NULL)
+ return -ENOMEM;
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ /* Confirm the sequence as being established */
+ nfs_confirm_seqid(&sp->so_seqid, status);
+ nfs_increment_open_seqid(status, o_arg.seqid);
if (status == 0) {
memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
if (o_res.delegation_type != 0) {
@@ -256,6 +281,7 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
nfs_async_inode_return_delegation(inode, &o_res.stateid);
}
}
+ nfs_free_seqid(o_arg.seqid);
clear_bit(NFS_DELEGATED_STATE, &state->flags);
/* Ensure we update the inode attributes */
NFS_CACHEINV(inode);
@@ -302,23 +328,35 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state
};
int status = 0;
- down(&sp->so_sema);
if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
goto out;
if (state->state == 0)
goto out;
- arg.seqid = sp->so_seqid;
+ arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ status = -ENOMEM;
+ if (arg.seqid == NULL)
+ goto out;
arg.open_flags = state->state;
memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data));
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ nfs_increment_open_seqid(status, arg.seqid);
+ if (status != 0)
+ goto out_free;
+ if(res.rflags & NFS4_OPEN_RESULT_CONFIRM) {
+ status = _nfs4_proc_open_confirm(server->client, NFS_FH(inode),
+ sp, &res.stateid, arg.seqid);
+ if (status != 0)
+ goto out_free;
+ }
+ nfs_confirm_seqid(&sp->so_seqid, 0);
if (status >= 0) {
memcpy(state->stateid.data, res.stateid.data,
sizeof(state->stateid.data));
clear_bit(NFS_DELEGATED_STATE, &state->flags);
}
+out_free:
+ nfs_free_seqid(arg.seqid);
out:
- up(&sp->so_sema);
dput(parent);
return status;
}
@@ -345,11 +383,11 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
return err;
}
-static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid)
+static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid)
{
struct nfs_open_confirmargs arg = {
.fh = fh,
- .seqid = sp->so_seqid,
+ .seqid = seqid,
.stateid = *stateid,
};
struct nfs_open_confirmres res;
@@ -362,7 +400,9 @@ static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nf
int status;
status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ /* Confirm the sequence as being established */
+ nfs_confirm_seqid(&sp->so_seqid, status);
+ nfs_increment_open_seqid(status, seqid);
if (status >= 0)
memcpy(stateid, &res.stateid, sizeof(*stateid));
return status;
@@ -380,21 +420,41 @@ static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner *sp, stru
int status;
/* Update sequence id. The caller must serialize! */
- o_arg->seqid = sp->so_seqid;
o_arg->id = sp->so_id;
o_arg->clientid = sp->so_client->cl_clientid;
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ if (status == 0) {
+ /* OPEN on anything except a regular file is disallowed in NFSv4 */
+ switch (o_res->f_attr->mode & S_IFMT) {
+ case S_IFREG:
+ break;
+ case S_IFLNK:
+ status = -ELOOP;
+ break;
+ case S_IFDIR:
+ status = -EISDIR;
+ break;
+ default:
+ status = -ENOTDIR;
+ }
+ }
+
+ nfs_increment_open_seqid(status, o_arg->seqid);
if (status != 0)
goto out;
- update_changeattr(dir, &o_res->cinfo);
+ if (o_arg->open_flags & O_CREAT) {
+ update_changeattr(dir, &o_res->cinfo);
+ nfs_post_op_update_inode(dir, o_res->dir_attr);
+ } else
+ nfs_refresh_inode(dir, o_res->dir_attr);
if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
status = _nfs4_proc_open_confirm(server->client, &o_res->fh,
- sp, &o_res->stateid);
+ sp, &o_res->stateid, o_arg->seqid);
if (status != 0)
goto out;
}
+ nfs_confirm_seqid(&sp->so_seqid, 0);
if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
out:
@@ -441,9 +501,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
struct inode *inode = state->inode;
struct nfs_server *server = NFS_SERVER(dir);
struct nfs_delegation *delegation = NFS_I(inode)->delegation;
- struct nfs_fattr f_attr = {
- .valid = 0,
- };
+ struct nfs_fattr f_attr, dir_attr;
struct nfs_openargs o_arg = {
.fh = NFS_FH(dir),
.open_flags = state->state,
@@ -453,6 +511,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
};
struct nfs_openres o_res = {
.f_attr = &f_attr,
+ .dir_attr = &dir_attr,
.server = server,
};
int status = 0;
@@ -465,6 +524,12 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
set_bit(NFS_DELEGATED_STATE, &state->flags);
goto out;
}
+ o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ status = -ENOMEM;
+ if (o_arg.seqid == NULL)
+ goto out;
+ nfs_fattr_init(&f_attr);
+ nfs_fattr_init(&dir_attr);
status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
if (status != 0)
goto out_nodeleg;
@@ -490,6 +555,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res);
}
out_nodeleg:
+ nfs_free_seqid(o_arg.seqid);
clear_bit(NFS_DELEGATED_STATE, &state->flags);
out:
dput(parent);
@@ -564,7 +630,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
goto out_err;
}
- down(&sp->so_sema);
state = nfs4_get_open_state(inode, sp);
if (state == NULL)
goto out_err;
@@ -589,7 +654,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
set_bit(NFS_DELEGATED_STATE, &state->flags);
update_open_stateid(state, &delegation->stateid, open_flags);
out_ok:
- up(&sp->so_sema);
nfs4_put_state_owner(sp);
up_read(&nfsi->rwsem);
up_read(&clp->cl_sem);
@@ -600,11 +664,12 @@ out_err:
if (sp != NULL) {
if (state != NULL)
nfs4_put_open_state(state);
- up(&sp->so_sema);
nfs4_put_state_owner(sp);
}
up_read(&nfsi->rwsem);
up_read(&clp->cl_sem);
+ if (err != -EACCES)
+ nfs_inode_return_delegation(inode);
return err;
}
@@ -635,9 +700,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
struct nfs4_client *clp = server->nfs4_state;
struct inode *inode = NULL;
int status;
- struct nfs_fattr f_attr = {
- .valid = 0,
- };
+ struct nfs_fattr f_attr, dir_attr;
struct nfs_openargs o_arg = {
.fh = NFS_FH(dir),
.open_flags = flags,
@@ -648,6 +711,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
};
struct nfs_openres o_res = {
.f_attr = &f_attr,
+ .dir_attr = &dir_attr,
.server = server,
};
@@ -665,8 +729,12 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
} else
o_arg.u.attrs = sattr;
/* Serialization for the sequence id */
- down(&sp->so_sema);
+ o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ if (o_arg.seqid == NULL)
+ return -ENOMEM;
+ nfs_fattr_init(&f_attr);
+ nfs_fattr_init(&dir_attr);
status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
if (status != 0)
goto out_err;
@@ -681,7 +749,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
update_open_stateid(state, &o_res.stateid, flags);
if (o_res.delegation_type != 0)
nfs_inode_set_delegation(inode, cred, &o_res);
- up(&sp->so_sema);
+ nfs_free_seqid(o_arg.seqid);
nfs4_put_state_owner(sp);
up_read(&clp->cl_sem);
*res = state;
@@ -690,7 +758,7 @@ out_err:
if (sp != NULL) {
if (state != NULL)
nfs4_put_open_state(state);
- up(&sp->so_sema);
+ nfs_free_seqid(o_arg.seqid);
nfs4_put_state_owner(sp);
}
/* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
@@ -718,7 +786,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
* It is actually a sign of a bug on the client or on the server.
*
* If we receive a BAD_SEQID error in the particular case of
- * doing an OPEN, we assume that nfs4_increment_seqid() will
+ * doing an OPEN, we assume that nfs_increment_open_seqid() will
* have unhashed the old state_owner for us, and that we can
* therefore safely retry using a new one. We should still warn
* the user though...
@@ -728,6 +796,16 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
exception.retry = 1;
continue;
}
+ /*
+ * BAD_STATEID on OPEN means that the server cancelled our
+ * state before it received the OPEN_CONFIRM.
+ * Recover by retrying the request as per the discussion
+ * on Page 181 of RFC3530.
+ */
+ if (status == -NFS4ERR_BAD_STATEID) {
+ exception.retry = 1;
+ continue;
+ }
res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir),
status, &exception));
} while (exception.retry);
@@ -755,7 +833,7 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
};
int status;
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
if (state != NULL) {
msg.rpc_cred = state->owner->so_cred;
@@ -787,19 +865,30 @@ struct nfs4_closedata {
struct nfs4_state *state;
struct nfs_closeargs arg;
struct nfs_closeres res;
+ struct nfs_fattr fattr;
};
+static void nfs4_free_closedata(struct nfs4_closedata *calldata)
+{
+ struct nfs4_state *state = calldata->state;
+ struct nfs4_state_owner *sp = state->owner;
+
+ nfs4_put_open_state(calldata->state);
+ nfs_free_seqid(calldata->arg.seqid);
+ nfs4_put_state_owner(sp);
+ kfree(calldata);
+}
+
static void nfs4_close_done(struct rpc_task *task)
{
struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
struct nfs4_state *state = calldata->state;
- struct nfs4_state_owner *sp = state->owner;
struct nfs_server *server = NFS_SERVER(calldata->inode);
/* hmm. we are done with the inode, and in the process of freeing
* the state_owner. we keep this around to process errors
*/
- nfs4_increment_seqid(task->tk_status, sp);
+ nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
switch (task->tk_status) {
case 0:
memcpy(&state->stateid, &calldata->res.stateid,
@@ -816,25 +905,49 @@ static void nfs4_close_done(struct rpc_task *task)
return;
}
}
+ nfs_refresh_inode(calldata->inode, calldata->res.fattr);
state->state = calldata->arg.open_flags;
- nfs4_put_open_state(state);
- up(&sp->so_sema);
- nfs4_put_state_owner(sp);
- up_read(&server->nfs4_state->cl_sem);
- kfree(calldata);
+ nfs4_free_closedata(calldata);
}
-static inline int nfs4_close_call(struct rpc_clnt *clnt, struct nfs4_closedata *calldata)
+static void nfs4_close_begin(struct rpc_task *task)
{
+ struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
+ struct nfs4_state *state = calldata->state;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
.rpc_argp = &calldata->arg,
.rpc_resp = &calldata->res,
- .rpc_cred = calldata->state->owner->so_cred,
+ .rpc_cred = state->owner->so_cred,
};
- if (calldata->arg.open_flags != 0)
+ int mode = 0;
+ int status;
+
+ status = nfs_wait_on_sequence(calldata->arg.seqid, task);
+ if (status != 0)
+ return;
+ /* Don't reorder reads */
+ smp_rmb();
+ /* Recalculate the new open mode in case someone reopened the file
+ * while we were waiting in line to be scheduled.
+ */
+ if (state->nreaders != 0)
+ mode |= FMODE_READ;
+ if (state->nwriters != 0)
+ mode |= FMODE_WRITE;
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags))
+ state->state = mode;
+ if (mode == state->state) {
+ nfs4_free_closedata(calldata);
+ task->tk_exit = NULL;
+ rpc_exit(task, 0);
+ return;
+ }
+ nfs_fattr_init(calldata->res.fattr);
+ if (mode != 0)
msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
- return rpc_call_async(clnt, &msg, 0, nfs4_close_done, calldata);
+ calldata->arg.open_flags = mode;
+ rpc_call_setup(task, &msg, 0);
}
/*
@@ -850,40 +963,57 @@ static inline int nfs4_close_call(struct rpc_clnt *clnt, struct nfs4_closedata *
*/
int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode)
{
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_closedata *calldata;
- int status;
+ int status = -ENOMEM;
- /* Tell caller we're done */
- if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
- state->state = mode;
- return 0;
- }
- calldata = (struct nfs4_closedata *)kmalloc(sizeof(*calldata), GFP_KERNEL);
+ calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
if (calldata == NULL)
- return -ENOMEM;
+ goto out;
calldata->inode = inode;
calldata->state = state;
calldata->arg.fh = NFS_FH(inode);
+ calldata->arg.stateid = &state->stateid;
/* Serialization for the sequence id */
- calldata->arg.seqid = state->owner->so_seqid;
- calldata->arg.open_flags = mode;
- memcpy(&calldata->arg.stateid, &state->stateid,
- sizeof(calldata->arg.stateid));
- status = nfs4_close_call(NFS_SERVER(inode)->client, calldata);
- /*
- * Return -EINPROGRESS on success in order to indicate to the
- * caller that an asynchronous RPC call has been launched, and
- * that it will release the semaphores on completion.
- */
- return (status == 0) ? -EINPROGRESS : status;
+ calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
+ if (calldata->arg.seqid == NULL)
+ goto out_free_calldata;
+ calldata->arg.bitmask = server->attr_bitmask;
+ calldata->res.fattr = &calldata->fattr;
+ calldata->res.server = server;
+
+ status = nfs4_call_async(server->client, nfs4_close_begin,
+ nfs4_close_done, calldata);
+ if (status == 0)
+ goto out;
+
+ nfs_free_seqid(calldata->arg.seqid);
+out_free_calldata:
+ kfree(calldata);
+out:
+ return status;
}
-struct inode *
+static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state)
+{
+ struct file *filp;
+
+ filp = lookup_instantiate_filp(nd, dentry, NULL);
+ if (!IS_ERR(filp)) {
+ struct nfs_open_context *ctx;
+ ctx = (struct nfs_open_context *)filp->private_data;
+ ctx->state = state;
+ } else
+ nfs4_close_state(state, nd->intent.open.flags);
+}
+
+struct dentry *
nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
struct iattr attr;
struct rpc_cred *cred;
struct nfs4_state *state;
+ struct dentry *res;
if (nd->flags & LOOKUP_CREATE) {
attr.ia_mode = nd->intent.open.create_mode;
@@ -897,16 +1027,23 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
if (IS_ERR(cred))
- return (struct inode *)cred;
+ return (struct dentry *)cred;
state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
put_rpccred(cred);
- if (IS_ERR(state))
- return (struct inode *)state;
- return state->inode;
+ if (IS_ERR(state)) {
+ if (PTR_ERR(state) == -ENOENT)
+ d_add(dentry, NULL);
+ return (struct dentry *)state;
+ }
+ res = d_add_unique(dentry, state->inode);
+ if (res != NULL)
+ dentry = res;
+ nfs4_intent_set_file(nd, dentry, state);
+ return res;
}
int
-nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags)
+nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
{
struct rpc_cred *cred;
struct nfs4_state *state;
@@ -919,18 +1056,30 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags)
if (IS_ERR(state))
state = nfs4_do_open(dir, dentry, openflags, NULL, cred);
put_rpccred(cred);
- if (state == ERR_PTR(-ENOENT) && dentry->d_inode == 0)
- return 1;
- if (IS_ERR(state))
- return 0;
+ if (IS_ERR(state)) {
+ switch (PTR_ERR(state)) {
+ case -EPERM:
+ case -EACCES:
+ case -EDQUOT:
+ case -ENOSPC:
+ case -EROFS:
+ lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
+ return 1;
+ case -ENOENT:
+ if (dentry->d_inode == NULL)
+ return 1;
+ }
+ goto out_drop;
+ }
inode = state->inode;
+ iput(inode);
if (inode == dentry->d_inode) {
- iput(inode);
+ nfs4_intent_set_file(nd, dentry, state);
return 1;
}
- d_drop(dentry);
nfs4_close_state(state, openflags);
- iput(inode);
+out_drop:
+ d_drop(dentry);
return 0;
}
@@ -974,13 +1123,12 @@ static int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh
static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fsinfo *info)
{
- struct nfs_fattr * fattr = info->fattr;
struct nfs4_lookup_root_arg args = {
.bitmask = nfs4_fattr_bitmap,
};
struct nfs4_lookup_res res = {
.server = server,
- .fattr = fattr,
+ .fattr = info->fattr,
.fh = fhandle,
};
struct rpc_message msg = {
@@ -988,7 +1136,7 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_argp = &args,
.rpc_resp = &res,
};
- fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1051,7 +1199,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
q.len = p - q.name;
do {
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = nfs4_handle_exception(server,
rpc_call_sync(server->client, &msg, 0),
&exception);
@@ -1088,7 +1236,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = &res,
};
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1130,7 +1278,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
struct nfs4_state *state;
int status;
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
if (IS_ERR(cred))
@@ -1176,7 +1324,7 @@ static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
.rpc_resp = &res,
};
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
dprintk("NFS call lookup %s\n", name->name);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
@@ -1325,7 +1473,7 @@ static int _nfs4_proc_read(struct nfs_read_data *rdata)
dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
(long long) rdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, flags);
if (!status)
renew_lease(server, timestamp);
@@ -1362,7 +1510,7 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata)
dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
(long long) wdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, rpcflags);
dprintk("NFS reply write: %d\n", status);
return status;
@@ -1396,7 +1544,7 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata)
dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
(long long) cdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, 0);
dprintk("NFS reply commit: %d\n", status);
return status;
@@ -1431,7 +1579,7 @@ static int nfs4_proc_commit(struct nfs_write_data *cdata)
static int
nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags)
+ int flags, struct nameidata *nd)
{
struct nfs4_state *state;
struct rpc_cred *cred;
@@ -1453,24 +1601,30 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
struct nfs_fattr fattr;
status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
NFS_FH(state->inode), sattr, state);
- if (status == 0) {
+ if (status == 0)
nfs_setattr_update_inode(state->inode, sattr);
- goto out;
- }
- } else if (flags != 0)
- goto out;
- nfs4_close_state(state, flags);
+ }
+ if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN))
+ nfs4_intent_set_file(nd, dentry, state);
+ else
+ nfs4_close_state(state, flags);
out:
return status;
}
static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
{
+ struct nfs_server *server = NFS_SERVER(dir);
struct nfs4_remove_arg args = {
.fh = NFS_FH(dir),
.name = name,
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs_fattr dir_attr;
+ struct nfs4_remove_res res = {
+ .server = server,
+ .dir_attr = &dir_attr,
};
- struct nfs4_change_info res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE],
.rpc_argp = &args,
@@ -1478,9 +1632,12 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
};
int status;
- status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
- if (status == 0)
- update_changeattr(dir, &res);
+ nfs_fattr_init(res.dir_attr);
+ status = rpc_call_sync(server->client, &msg, 0);
+ if (status == 0) {
+ update_changeattr(dir, &res.cinfo);
+ nfs_post_op_update_inode(dir, res.dir_attr);
+ }
return status;
}
@@ -1498,12 +1655,14 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
struct unlink_desc {
struct nfs4_remove_arg args;
- struct nfs4_change_info res;
+ struct nfs4_remove_res res;
+ struct nfs_fattr dir_attr;
};
static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
struct qstr *name)
{
+ struct nfs_server *server = NFS_SERVER(dir->d_inode);
struct unlink_desc *up;
up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL);
@@ -1512,6 +1671,9 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
up->args.fh = NFS_FH(dir->d_inode);
up->args.name = name;
+ up->args.bitmask = server->attr_bitmask;
+ up->res.server = server;
+ up->res.dir_attr = &up->dir_attr;
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
msg->rpc_argp = &up->args;
@@ -1526,7 +1688,8 @@ static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
if (msg->rpc_resp != NULL) {
up = container_of(msg->rpc_resp, struct unlink_desc, res);
- update_changeattr(dir->d_inode, &up->res);
+ update_changeattr(dir->d_inode, &up->res.cinfo);
+ nfs_post_op_update_inode(dir->d_inode, up->res.dir_attr);
kfree(up);
msg->rpc_resp = NULL;
msg->rpc_argp = NULL;
@@ -1537,13 +1700,20 @@ static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
struct inode *new_dir, struct qstr *new_name)
{
+ struct nfs_server *server = NFS_SERVER(old_dir);
struct nfs4_rename_arg arg = {
.old_dir = NFS_FH(old_dir),
.new_dir = NFS_FH(new_dir),
.old_name = old_name,
.new_name = new_name,
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs_fattr old_fattr, new_fattr;
+ struct nfs4_rename_res res = {
+ .server = server,
+ .old_fattr = &old_fattr,
+ .new_fattr = &new_fattr,
};
- struct nfs4_rename_res res = { };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
.rpc_argp = &arg,
@@ -1551,11 +1721,15 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
};
int status;
- status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
+ nfs_fattr_init(res.old_fattr);
+ nfs_fattr_init(res.new_fattr);
+ status = rpc_call_sync(server->client, &msg, 0);
if (!status) {
update_changeattr(old_dir, &res.old_cinfo);
+ nfs_post_op_update_inode(old_dir, res.old_fattr);
update_changeattr(new_dir, &res.new_cinfo);
+ nfs_post_op_update_inode(new_dir, res.new_fattr);
}
return status;
}
@@ -1576,22 +1750,34 @@ static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
{
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_link_arg arg = {
.fh = NFS_FH(inode),
.dir_fh = NFS_FH(dir),
.name = name,
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs_fattr fattr, dir_attr;
+ struct nfs4_link_res res = {
+ .server = server,
+ .fattr = &fattr,
+ .dir_attr = &dir_attr,
};
- struct nfs4_change_info cinfo = { };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
.rpc_argp = &arg,
- .rpc_resp = &cinfo,
+ .rpc_resp = &res,
};
int status;
- status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
- if (!status)
- update_changeattr(dir, &cinfo);
+ nfs_fattr_init(res.fattr);
+ nfs_fattr_init(res.dir_attr);
+ status = rpc_call_sync(server->client, &msg, 0);
+ if (!status) {
+ update_changeattr(dir, &res.cinfo);
+ nfs_post_op_update_inode(dir, res.dir_attr);
+ nfs_refresh_inode(inode, res.fattr);
+ }
return status;
}
@@ -1613,6 +1799,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
struct nfs_fattr *fattr)
{
struct nfs_server *server = NFS_SERVER(dir);
+ struct nfs_fattr dir_fattr;
struct nfs4_create_arg arg = {
.dir_fh = NFS_FH(dir),
.server = server,
@@ -1625,6 +1812,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
.server = server,
.fh = fhandle,
.fattr = fattr,
+ .dir_fattr = &dir_fattr,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK],
@@ -1636,11 +1824,13 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
if (path->len > NFS4_MAXPATHLEN)
return -ENAMETOOLONG;
arg.u.symlink = path;
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
+ nfs_fattr_init(&dir_fattr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (!status)
update_changeattr(dir, &res.dir_cinfo);
+ nfs_post_op_update_inode(dir, res.dir_fattr);
return status;
}
@@ -1664,7 +1854,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
{
struct nfs_server *server = NFS_SERVER(dir);
struct nfs_fh fhandle;
- struct nfs_fattr fattr;
+ struct nfs_fattr fattr, dir_fattr;
struct nfs4_create_arg arg = {
.dir_fh = NFS_FH(dir),
.server = server,
@@ -1677,6 +1867,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
.server = server,
.fh = &fhandle,
.fattr = &fattr,
+ .dir_fattr = &dir_fattr,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
@@ -1685,11 +1876,13 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
};
int status;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
+ nfs_fattr_init(&dir_fattr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (!status) {
update_changeattr(dir, &res.dir_cinfo);
+ nfs_post_op_update_inode(dir, res.dir_fattr);
status = nfs_instantiate(dentry, &fhandle, &fattr);
}
return status;
@@ -1762,7 +1955,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
{
struct nfs_server *server = NFS_SERVER(dir);
struct nfs_fh fh;
- struct nfs_fattr fattr;
+ struct nfs_fattr fattr, dir_fattr;
struct nfs4_create_arg arg = {
.dir_fh = NFS_FH(dir),
.server = server,
@@ -1774,6 +1967,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
.server = server,
.fh = &fh,
.fattr = &fattr,
+ .dir_fattr = &dir_fattr,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
@@ -1783,7 +1977,8 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
int status;
int mode = sattr->ia_mode;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
+ nfs_fattr_init(&dir_fattr);
BUG_ON(!(sattr->ia_valid & ATTR_MODE));
BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode));
@@ -1805,6 +2000,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (status == 0) {
update_changeattr(dir, &res.dir_cinfo);
+ nfs_post_op_update_inode(dir, res.dir_fattr);
status = nfs_instantiate(dentry, &fh, &fattr);
}
return status;
@@ -1836,7 +2032,7 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = fsstat,
};
- fsstat->fattr->valid = 0;
+ nfs_fattr_init(fsstat->fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1883,7 +2079,7 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
{
- fsinfo->fattr->valid = 0;
+ nfs_fattr_init(fsinfo->fattr);
return nfs4_do_fsinfo(server, fhandle, fsinfo);
}
@@ -1906,7 +2102,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
return 0;
}
- pathconf->fattr->valid = 0;
+ nfs_fattr_init(pathconf->fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1973,8 +2169,10 @@ nfs4_write_done(struct rpc_task *task)
rpc_restart_call(task);
return;
}
- if (task->tk_status >= 0)
+ if (task->tk_status >= 0) {
renew_lease(NFS_SERVER(inode), data->timestamp);
+ nfs_post_op_update_inode(inode, data->res.fattr);
+ }
/* Call back common NFS writeback processing */
nfs_writeback_done(task);
}
@@ -1990,6 +2188,7 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
.rpc_cred = data->cred,
};
struct inode *inode = data->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
int stable;
int flags;
@@ -2001,6 +2200,8 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
} else
stable = NFS_UNSTABLE;
data->args.stable = stable;
+ data->args.bitmask = server->attr_bitmask;
+ data->res.server = server;
data->timestamp = jiffies;
@@ -2022,6 +2223,8 @@ nfs4_commit_done(struct rpc_task *task)
rpc_restart_call(task);
return;
}
+ if (task->tk_status >= 0)
+ nfs_post_op_update_inode(inode, data->res.fattr);
/* Call back common NFS writeback processing */
nfs_commit_done(task);
}
@@ -2037,8 +2240,12 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
.rpc_cred = data->cred,
};
struct inode *inode = data->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
int flags;
+ data->args.bitmask = server->attr_bitmask;
+ data->res.server = server;
+
/* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
@@ -2106,65 +2313,6 @@ nfs4_proc_renew(struct nfs4_client *clp)
return 0;
}
-/*
- * We will need to arrange for the VFS layer to provide an atomic open.
- * Until then, this open method is prone to inefficiency and race conditions
- * due to the lookup, potential create, and open VFS calls from sys_open()
- * placed on the wire.
- */
-static int
-nfs4_proc_file_open(struct inode *inode, struct file *filp)
-{
- struct dentry *dentry = filp->f_dentry;
- struct nfs_open_context *ctx;
- struct nfs4_state *state = NULL;
- struct rpc_cred *cred;
- int status = -ENOMEM;
-
- dprintk("nfs4_proc_file_open: starting on (%.*s/%.*s)\n",
- (int)dentry->d_parent->d_name.len,
- dentry->d_parent->d_name.name,
- (int)dentry->d_name.len, dentry->d_name.name);
-
-
- /* Find our open stateid */
- cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
- if (IS_ERR(cred))
- return PTR_ERR(cred);
- ctx = alloc_nfs_open_context(dentry, cred);
- put_rpccred(cred);
- if (unlikely(ctx == NULL))
- return -ENOMEM;
- status = -EIO; /* ERACE actually */
- state = nfs4_find_state(inode, cred, filp->f_mode);
- if (unlikely(state == NULL))
- goto no_state;
- ctx->state = state;
- nfs4_close_state(state, filp->f_mode);
- ctx->mode = filp->f_mode;
- nfs_file_set_open_context(filp, ctx);
- put_nfs_open_context(ctx);
- if (filp->f_mode & FMODE_WRITE)
- nfs_begin_data_update(inode);
- return 0;
-no_state:
- printk(KERN_WARNING "NFS: v4 raced in function %s\n", __FUNCTION__);
- put_nfs_open_context(ctx);
- return status;
-}
-
-/*
- * Release our state
- */
-static int
-nfs4_proc_file_release(struct inode *inode, struct file *filp)
-{
- if (filp->f_mode & FMODE_WRITE)
- nfs_end_data_update(inode);
- nfs_file_clear_open_context(filp);
- return 0;
-}
-
static inline int nfs4_server_supports_acls(struct nfs_server *server)
{
return (server->caps & NFS_CAP_ACLS)
@@ -2285,7 +2433,7 @@ static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size
return -ENOMEM;
args.acl_pages[0] = localpage;
args.acl_pgbase = 0;
- args.acl_len = PAGE_SIZE;
+ resp_len = args.acl_len = PAGE_SIZE;
} else {
resp_buf = buf;
buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
@@ -2345,6 +2493,7 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
if (!nfs4_server_supports_acls(server))
return -EOPNOTSUPP;
+ nfs_inode_return_delegation(inode);
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
if (ret == 0)
@@ -2353,7 +2502,7 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
}
static int
-nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server)
+nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
{
struct nfs4_client *clp = server->nfs4_state;
@@ -2418,14 +2567,11 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
*timeout = NFS4_POLL_RETRY_MAX;
rpc_clnt_sigmask(clnt, &oldset);
if (clnt->cl_intr) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(*timeout);
+ schedule_timeout_interruptible(*timeout);
if (signalled())
res = -ERESTARTSYS;
- } else {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(*timeout);
- }
+ } else
+ schedule_timeout_uninterruptible(*timeout);
rpc_clnt_sigunmask(clnt, &oldset);
*timeout <<= 1;
return res;
@@ -2434,7 +2580,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
/* This is the error handling routine for processes that are allowed
* to sleep.
*/
-int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
+int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
{
struct nfs4_client *clp = server->nfs4_state;
int ret = errorcode;
@@ -2578,8 +2724,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
static unsigned long
nfs4_set_lock_task_retry(unsigned long timeout)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(timeout);
+ schedule_timeout_interruptible(timeout);
timeout <<= 1;
if (timeout > NFS4_LOCK_MAXTIMEOUT)
return NFS4_LOCK_MAXTIMEOUT;
@@ -2636,7 +2781,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
down_read(&clp->cl_sem);
nlo.clientid = clp->cl_clientid;
- down(&state->lock_sema);
status = nfs4_set_lock_state(state, request);
if (status != 0)
goto out;
@@ -2663,7 +2807,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
status = 0;
}
out:
- up(&state->lock_sema);
up_read(&clp->cl_sem);
return status;
}
@@ -2700,79 +2843,149 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
return res;
}
-static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
+struct nfs4_unlockdata {
+ struct nfs_lockargs arg;
+ struct nfs_locku_opargs luargs;
+ struct nfs_lockres res;
+ struct nfs4_lock_state *lsp;
+ struct nfs_open_context *ctx;
+ atomic_t refcount;
+ struct completion completion;
+};
+
+static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata)
{
- struct inode *inode = state->inode;
- struct nfs_server *server = NFS_SERVER(inode);
- struct nfs4_client *clp = server->nfs4_state;
- struct nfs_lockargs arg = {
- .fh = NFS_FH(inode),
- .type = nfs4_lck_type(cmd, request),
- .offset = request->fl_start,
- .length = nfs4_lck_length(request),
- };
- struct nfs_lockres res = {
- .server = server,
- };
+ if (atomic_dec_and_test(&calldata->refcount)) {
+ nfs_free_seqid(calldata->luargs.seqid);
+ nfs4_put_lock_state(calldata->lsp);
+ put_nfs_open_context(calldata->ctx);
+ kfree(calldata);
+ }
+}
+
+static void nfs4_locku_complete(struct nfs4_unlockdata *calldata)
+{
+ complete(&calldata->completion);
+ nfs4_locku_release_calldata(calldata);
+}
+
+static void nfs4_locku_done(struct rpc_task *task)
+{
+ struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
+
+ nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid);
+ switch (task->tk_status) {
+ case 0:
+ memcpy(calldata->lsp->ls_stateid.data,
+ calldata->res.u.stateid.data,
+ sizeof(calldata->lsp->ls_stateid.data));
+ break;
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_EXPIRED:
+ nfs4_schedule_state_recovery(calldata->res.server->nfs4_state);
+ break;
+ default:
+ if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) {
+ rpc_restart_call(task);
+ return;
+ }
+ }
+ nfs4_locku_complete(calldata);
+}
+
+static void nfs4_locku_begin(struct rpc_task *task)
+{
+ struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
- .rpc_argp = &arg,
- .rpc_resp = &res,
- .rpc_cred = state->owner->so_cred,
+ .rpc_argp = &calldata->arg,
+ .rpc_resp = &calldata->res,
+ .rpc_cred = calldata->lsp->ls_state->owner->so_cred,
};
+ int status;
+
+ status = nfs_wait_on_sequence(calldata->luargs.seqid, task);
+ if (status != 0)
+ return;
+ if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
+ nfs4_locku_complete(calldata);
+ task->tk_exit = NULL;
+ rpc_exit(task, 0);
+ return;
+ }
+ rpc_call_setup(task, &msg, 0);
+}
+
+static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
+{
+ struct nfs4_unlockdata *calldata;
+ struct inode *inode = state->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_lock_state *lsp;
- struct nfs_locku_opargs luargs;
int status;
-
- down_read(&clp->cl_sem);
- down(&state->lock_sema);
+
status = nfs4_set_lock_state(state, request);
if (status != 0)
- goto out;
+ return status;
lsp = request->fl_u.nfs4_fl.owner;
/* We might have lost the locks! */
if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
- goto out;
- luargs.seqid = lsp->ls_seqid;
- memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
- arg.u.locku = &luargs;
- status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_lock_seqid(status, lsp);
-
- if (status == 0)
- memcpy(&lsp->ls_stateid, &res.u.stateid,
- sizeof(lsp->ls_stateid));
-out:
- up(&state->lock_sema);
+ return 0;
+ calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
+ if (calldata == NULL)
+ return -ENOMEM;
+ calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+ if (calldata->luargs.seqid == NULL) {
+ kfree(calldata);
+ return -ENOMEM;
+ }
+ calldata->luargs.stateid = &lsp->ls_stateid;
+ calldata->arg.fh = NFS_FH(inode);
+ calldata->arg.type = nfs4_lck_type(cmd, request);
+ calldata->arg.offset = request->fl_start;
+ calldata->arg.length = nfs4_lck_length(request);
+ calldata->arg.u.locku = &calldata->luargs;
+ calldata->res.server = server;
+ calldata->lsp = lsp;
+ atomic_inc(&lsp->ls_count);
+
+ /* Ensure we don't close file until we're done freeing locks! */
+ calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data);
+
+ atomic_set(&calldata->refcount, 2);
+ init_completion(&calldata->completion);
+
+ status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin,
+ nfs4_locku_done, calldata);
if (status == 0)
- do_vfs_lock(request->fl_file, request);
- up_read(&clp->cl_sem);
+ wait_for_completion_interruptible(&calldata->completion);
+ do_vfs_lock(request->fl_file, request);
+ nfs4_locku_release_calldata(calldata);
return status;
}
-static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
-{
- struct nfs4_exception exception = { };
- int err;
-
- do {
- err = nfs4_handle_exception(NFS_SERVER(state->inode),
- _nfs4_proc_unlck(state, cmd, request),
- &exception);
- } while (exception.retry);
- return err;
-}
-
static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *request, int reclaim)
{
struct inode *inode = state->inode;
struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
+ struct nfs_lock_opargs largs = {
+ .lock_stateid = &lsp->ls_stateid,
+ .open_stateid = &state->stateid,
+ .lock_owner = {
+ .clientid = server->nfs4_state->cl_clientid,
+ .id = lsp->ls_id,
+ },
+ .reclaim = reclaim,
+ };
struct nfs_lockargs arg = {
.fh = NFS_FH(inode),
.type = nfs4_lck_type(cmd, request),
.offset = request->fl_start,
.length = nfs4_lck_length(request),
+ .u = {
+ .lock = &largs,
+ },
};
struct nfs_lockres res = {
.server = server,
@@ -2783,53 +2996,39 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
.rpc_resp = &res,
.rpc_cred = state->owner->so_cred,
};
- struct nfs_lock_opargs largs = {
- .reclaim = reclaim,
- .new_lock_owner = 0,
- };
- int status;
+ int status = -ENOMEM;
- if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) {
+ largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+ if (largs.lock_seqid == NULL)
+ return -ENOMEM;
+ if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
struct nfs4_state_owner *owner = state->owner;
- struct nfs_open_to_lock otl = {
- .lock_owner = {
- .clientid = server->nfs4_state->cl_clientid,
- },
- };
-
- otl.lock_seqid = lsp->ls_seqid;
- otl.lock_owner.id = lsp->ls_id;
- memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid));
- largs.u.open_lock = &otl;
+
+ largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
+ if (largs.open_seqid == NULL)
+ goto out;
largs.new_lock_owner = 1;
- arg.u.lock = &largs;
- down(&owner->so_sema);
- otl.open_seqid = owner->so_seqid;
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- /* increment open_owner seqid on success, and
- * seqid mutating errors */
- nfs4_increment_seqid(status, owner);
- up(&owner->so_sema);
- if (status == 0) {
- lsp->ls_flags |= NFS_LOCK_INITIALIZED;
- lsp->ls_seqid++;
+ /* increment open seqid on success, and seqid mutating errors */
+ if (largs.new_lock_owner != 0) {
+ nfs_increment_open_seqid(status, largs.open_seqid);
+ if (status == 0)
+ nfs_confirm_seqid(&lsp->ls_seqid, 0);
}
- } else {
- struct nfs_exist_lock el = {
- .seqid = lsp->ls_seqid,
- };
- memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
- largs.u.exist_lock = &el;
- arg.u.lock = &largs;
+ nfs_free_seqid(largs.open_seqid);
+ } else
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- /* increment seqid on success, and * seqid mutating errors*/
- nfs4_increment_lock_seqid(status, lsp);
- }
+ /* increment lock seqid on success, and seqid mutating errors*/
+ nfs_increment_lock_seqid(status, largs.lock_seqid);
/* save the returned stateid. */
- if (status == 0)
- memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid));
- else if (status == -NFS4ERR_DENIED)
+ if (status == 0) {
+ memcpy(lsp->ls_stateid.data, res.u.stateid.data,
+ sizeof(lsp->ls_stateid.data));
+ lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+ } else if (status == -NFS4ERR_DENIED)
status = -EAGAIN;
+out:
+ nfs_free_seqid(largs.lock_seqid);
return status;
}
@@ -2869,11 +3068,9 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
int status;
down_read(&clp->cl_sem);
- down(&state->lock_sema);
status = nfs4_set_lock_state(state, request);
if (status == 0)
status = _nfs4_do_setlk(state, cmd, request, 0);
- up(&state->lock_sema);
if (status == 0) {
/* Note: we always want to sleep here! */
request->fl_flags |= FL_SLEEP;
@@ -3028,8 +3225,8 @@ struct nfs_rpc_ops nfs_v4_clientops = {
.read_setup = nfs4_proc_read_setup,
.write_setup = nfs4_proc_write_setup,
.commit_setup = nfs4_proc_commit_setup,
- .file_open = nfs4_proc_file_open,
- .file_release = nfs4_proc_file_release,
+ .file_open = nfs_open,
+ .file_release = nfs_release,
.lock = nfs4_proc_lock,
.clear_acl_cache = nfs4_zap_acl_attr,
};
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index afe587d82f1e..2d5a6a2b9dec 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -264,13 +264,16 @@ nfs4_alloc_state_owner(void)
{
struct nfs4_state_owner *sp;
- sp = kmalloc(sizeof(*sp),GFP_KERNEL);
+ sp = kzalloc(sizeof(*sp),GFP_KERNEL);
if (!sp)
return NULL;
- init_MUTEX(&sp->so_sema);
- sp->so_seqid = 0; /* arbitrary */
+ spin_lock_init(&sp->so_lock);
INIT_LIST_HEAD(&sp->so_states);
INIT_LIST_HEAD(&sp->so_delegations);
+ rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
+ sp->so_seqid.sequence = &sp->so_sequence;
+ spin_lock_init(&sp->so_sequence.lock);
+ INIT_LIST_HEAD(&sp->so_sequence.list);
atomic_set(&sp->so_count, 1);
return sp;
}
@@ -359,7 +362,6 @@ nfs4_alloc_open_state(void)
memset(state->stateid.data, 0, sizeof(state->stateid.data));
atomic_set(&state->count, 1);
INIT_LIST_HEAD(&state->lock_states);
- init_MUTEX(&state->lock_sema);
spin_lock_init(&state->state_lock);
return state;
}
@@ -437,21 +439,23 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
if (state)
goto out;
new = nfs4_alloc_open_state();
+ spin_lock(&owner->so_lock);
spin_lock(&inode->i_lock);
state = __nfs4_find_state_byowner(inode, owner);
if (state == NULL && new != NULL) {
state = new;
- /* Caller *must* be holding owner->so_sem */
- /* Note: The reclaim code dictates that we add stateless
- * and read-only stateids to the end of the list */
- list_add_tail(&state->open_states, &owner->so_states);
state->owner = owner;
atomic_inc(&owner->so_count);
list_add(&state->inode_states, &nfsi->open_states);
state->inode = igrab(inode);
spin_unlock(&inode->i_lock);
+ /* Note: The reclaim code dictates that we add stateless
+ * and read-only stateids to the end of the list */
+ list_add_tail(&state->open_states, &owner->so_states);
+ spin_unlock(&owner->so_lock);
} else {
spin_unlock(&inode->i_lock);
+ spin_unlock(&owner->so_lock);
if (new)
nfs4_free_open_state(new);
}
@@ -461,19 +465,21 @@ out:
/*
* Beware! Caller must be holding exactly one
- * reference to clp->cl_sem and owner->so_sema!
+ * reference to clp->cl_sem!
*/
void nfs4_put_open_state(struct nfs4_state *state)
{
struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
- if (!atomic_dec_and_lock(&state->count, &inode->i_lock))
+ if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
return;
+ spin_lock(&inode->i_lock);
if (!list_empty(&state->inode_states))
list_del(&state->inode_states);
- spin_unlock(&inode->i_lock);
list_del(&state->open_states);
+ spin_unlock(&inode->i_lock);
+ spin_unlock(&owner->so_lock);
iput(inode);
BUG_ON (state->state != 0);
nfs4_free_open_state(state);
@@ -481,20 +487,17 @@ void nfs4_put_open_state(struct nfs4_state *state)
}
/*
- * Beware! Caller must be holding no references to clp->cl_sem!
- * of owner->so_sema!
+ * Close the current file.
*/
void nfs4_close_state(struct nfs4_state *state, mode_t mode)
{
struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
- struct nfs4_client *clp = owner->so_client;
int newstate;
atomic_inc(&owner->so_count);
- down_read(&clp->cl_sem);
- down(&owner->so_sema);
/* Protect against nfs4_find_state() */
+ spin_lock(&owner->so_lock);
spin_lock(&inode->i_lock);
if (mode & FMODE_READ)
state->nreaders--;
@@ -507,6 +510,7 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
list_move_tail(&state->open_states, &owner->so_states);
}
spin_unlock(&inode->i_lock);
+ spin_unlock(&owner->so_lock);
newstate = 0;
if (state->state != 0) {
if (state->nreaders)
@@ -515,14 +519,16 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
newstate |= FMODE_WRITE;
if (state->state == newstate)
goto out;
- if (nfs4_do_close(inode, state, newstate) == -EINPROGRESS)
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ state->state = newstate;
+ goto out;
+ }
+ if (nfs4_do_close(inode, state, newstate) == 0)
return;
}
out:
nfs4_put_open_state(state);
- up(&owner->so_sema);
nfs4_put_state_owner(owner);
- up_read(&clp->cl_sem);
}
/*
@@ -546,19 +552,16 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
* Return a compatible lock_state. If no initialized lock_state structure
* exists, return an uninitialized one.
*
- * The caller must be holding state->lock_sema
*/
static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
{
struct nfs4_lock_state *lsp;
struct nfs4_client *clp = state->owner->so_client;
- lsp = kmalloc(sizeof(*lsp), GFP_KERNEL);
+ lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
if (lsp == NULL)
return NULL;
- lsp->ls_flags = 0;
- lsp->ls_seqid = 0; /* arbitrary */
- memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data));
+ lsp->ls_seqid.sequence = &state->owner->so_sequence;
atomic_set(&lsp->ls_count, 1);
lsp->ls_owner = fl_owner;
spin_lock(&clp->cl_lock);
@@ -572,7 +575,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
* Return a compatible lock_state. If no initialized lock_state structure
* exists, return an uninitialized one.
*
- * The caller must be holding state->lock_sema and clp->cl_sem
+ * The caller must be holding clp->cl_sem
*/
static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
{
@@ -605,7 +608,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
* Release reference to lock_state, and free it if we see that
* it is no longer in use
*/
-static void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
+void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
{
struct nfs4_state *state;
@@ -673,29 +676,94 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
nfs4_put_lock_state(lsp);
}
-/*
-* Called with state->lock_sema and clp->cl_sem held.
-*/
-void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
+struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
{
- if (status == NFS_OK || seqid_mutating_err(-status))
- lsp->ls_seqid++;
+ struct nfs_seqid *new;
+
+ new = kmalloc(sizeof(*new), GFP_KERNEL);
+ if (new != NULL) {
+ new->sequence = counter;
+ INIT_LIST_HEAD(&new->list);
+ }
+ return new;
+}
+
+void nfs_free_seqid(struct nfs_seqid *seqid)
+{
+ struct rpc_sequence *sequence = seqid->sequence->sequence;
+
+ if (!list_empty(&seqid->list)) {
+ spin_lock(&sequence->lock);
+ list_del(&seqid->list);
+ spin_unlock(&sequence->lock);
+ }
+ rpc_wake_up_next(&sequence->wait);
+ kfree(seqid);
}
/*
-* Called with sp->so_sema and clp->cl_sem held.
-*
-* Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
-* failed with a seqid incrementing error -
-* see comments nfs_fs.h:seqid_mutating_error()
-*/
-void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp)
-{
- if (status == NFS_OK || seqid_mutating_err(-status))
- sp->so_seqid++;
- /* If the server returns BAD_SEQID, unhash state_owner here */
- if (status == -NFS4ERR_BAD_SEQID)
+ * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
+ * failed with a seqid incrementing error -
+ * see comments nfs_fs.h:seqid_mutating_error()
+ */
+static inline void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
+{
+ switch (status) {
+ case 0:
+ break;
+ case -NFS4ERR_BAD_SEQID:
+ case -NFS4ERR_STALE_CLIENTID:
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_BAD_STATEID:
+ case -NFS4ERR_BADXDR:
+ case -NFS4ERR_RESOURCE:
+ case -NFS4ERR_NOFILEHANDLE:
+ /* Non-seqid mutating errors */
+ return;
+ };
+ /*
+ * Note: no locking needed as we are guaranteed to be first
+ * on the sequence list
+ */
+ seqid->sequence->counter++;
+}
+
+void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
+{
+ if (status == -NFS4ERR_BAD_SEQID) {
+ struct nfs4_state_owner *sp = container_of(seqid->sequence,
+ struct nfs4_state_owner, so_seqid);
nfs4_drop_state_owner(sp);
+ }
+ return nfs_increment_seqid(status, seqid);
+}
+
+/*
+ * Increment the seqid if the LOCK/LOCKU succeeded, or
+ * failed with a seqid incrementing error -
+ * see comments nfs_fs.h:seqid_mutating_error()
+ */
+void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
+{
+ return nfs_increment_seqid(status, seqid);
+}
+
+int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
+{
+ struct rpc_sequence *sequence = seqid->sequence->sequence;
+ int status = 0;
+
+ if (sequence->list.next == &seqid->list)
+ goto out;
+ spin_lock(&sequence->lock);
+ if (!list_empty(&sequence->list)) {
+ rpc_sleep_on(&sequence->wait, task, NULL, NULL);
+ status = -EAGAIN;
+ } else
+ list_add(&seqid->list, &sequence->list);
+ spin_unlock(&sequence->lock);
+out:
+ return status;
}
static int reclaimer(void *);
@@ -791,8 +859,6 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n
if (state->state == 0)
continue;
status = ops->recover_open(sp, state);
- list_for_each_entry(lock, &state->lock_states, ls_locks)
- lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
if (status >= 0) {
status = nfs4_reclaim_locks(ops, state);
if (status < 0)
@@ -831,6 +897,28 @@ out_err:
return status;
}
+static void nfs4_state_mark_reclaim(struct nfs4_client *clp)
+{
+ struct nfs4_state_owner *sp;
+ struct nfs4_state *state;
+ struct nfs4_lock_state *lock;
+
+ /* Reset all sequence ids to zero */
+ list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
+ sp->so_seqid.counter = 0;
+ sp->so_seqid.flags = 0;
+ spin_lock(&sp->so_lock);
+ list_for_each_entry(state, &sp->so_states, open_states) {
+ list_for_each_entry(lock, &state->lock_states, ls_locks) {
+ lock->ls_seqid.counter = 0;
+ lock->ls_seqid.flags = 0;
+ lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
+ }
+ }
+ spin_unlock(&sp->so_lock);
+ }
+}
+
static int reclaimer(void *ptr)
{
struct reclaimer_args *args = (struct reclaimer_args *)ptr;
@@ -864,6 +952,7 @@ restart_loop:
default:
ops = &nfs4_network_partition_recovery_ops;
};
+ nfs4_state_mark_reclaim(clp);
status = __nfs4_init_client(clp);
if (status)
goto out_error;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6c564ef9489e..fbbace8a30c4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -95,6 +95,8 @@ static int nfs_stat_to_errno(int);
#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
#define encode_savefh_maxsz (op_encode_hdr_maxsz)
#define decode_savefh_maxsz (op_decode_hdr_maxsz)
+#define encode_restorefh_maxsz (op_encode_hdr_maxsz)
+#define decode_restorefh_maxsz (op_decode_hdr_maxsz)
#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2)
#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11)
#define encode_renew_maxsz (op_encode_hdr_maxsz + 3)
@@ -157,16 +159,20 @@ static int nfs_stat_to_errno(int);
op_decode_hdr_maxsz + 2)
#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 8)
+ op_encode_hdr_maxsz + 8 + \
+ encode_getattr_maxsz)
#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 4)
+ op_decode_hdr_maxsz + 4 + \
+ decode_getattr_maxsz)
#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 3)
+ op_encode_hdr_maxsz + 3 + \
+ encode_getattr_maxsz)
#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 2)
+ op_decode_hdr_maxsz + 2 + \
+ decode_getattr_maxsz)
#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + \
@@ -196,17 +202,21 @@ static int nfs_stat_to_errno(int);
#define NFS4_enc_open_downgrade_sz \
(compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 7)
+ op_encode_hdr_maxsz + 7 + \
+ encode_getattr_maxsz)
#define NFS4_dec_open_downgrade_sz \
(compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 4)
+ op_decode_hdr_maxsz + 4 + \
+ decode_getattr_maxsz)
#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 5)
+ op_encode_hdr_maxsz + 5 + \
+ encode_getattr_maxsz)
#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 4)
+ op_decode_hdr_maxsz + 4 + \
+ decode_getattr_maxsz)
#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + 4 + \
@@ -300,30 +310,44 @@ static int nfs_stat_to_errno(int);
decode_getfh_maxsz)
#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- encode_remove_maxsz)
+ encode_remove_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 5)
+ op_decode_hdr_maxsz + 5 + \
+ decode_getattr_maxsz)
#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
- encode_rename_maxsz)
+ encode_rename_maxsz + \
+ encode_getattr_maxsz + \
+ encode_restorefh_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
- decode_rename_maxsz)
+ decode_rename_maxsz + \
+ decode_getattr_maxsz + \
+ decode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
- encode_link_maxsz)
+ encode_link_maxsz + \
+ decode_getattr_maxsz + \
+ encode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
- decode_link_maxsz)
+ decode_link_maxsz + \
+ decode_getattr_maxsz + \
+ decode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_symlink_maxsz + \
@@ -336,14 +360,20 @@ static int nfs_stat_to_errno(int);
decode_getfh_maxsz)
#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
+ encode_savefh_maxsz + \
encode_create_maxsz + \
+ encode_getfh_maxsz + \
encode_getattr_maxsz + \
- encode_getfh_maxsz)
+ encode_restorefh_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
+ decode_savefh_maxsz + \
decode_create_maxsz + \
+ decode_getfh_maxsz + \
decode_getattr_maxsz + \
- decode_getfh_maxsz)
+ decode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
@@ -602,10 +632,10 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
{
uint32_t *p;
- RESERVE_SPACE(8+sizeof(arg->stateid.data));
+ RESERVE_SPACE(8+sizeof(arg->stateid->data));
WRITE32(OP_CLOSE);
- WRITE32(arg->seqid);
- WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
+ WRITE32(arg->seqid->sequence->counter);
+ WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
return 0;
}
@@ -729,22 +759,18 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
WRITE64(arg->length);
WRITE32(opargs->new_lock_owner);
if (opargs->new_lock_owner){
- struct nfs_open_to_lock *ol = opargs->u.open_lock;
-
RESERVE_SPACE(40);
- WRITE32(ol->open_seqid);
- WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
- WRITE32(ol->lock_seqid);
- WRITE64(ol->lock_owner.clientid);
+ WRITE32(opargs->open_seqid->sequence->counter);
+ WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
+ WRITE32(opargs->lock_seqid->sequence->counter);
+ WRITE64(opargs->lock_owner.clientid);
WRITE32(4);
- WRITE32(ol->lock_owner.id);
+ WRITE32(opargs->lock_owner.id);
}
else {
- struct nfs_exist_lock *el = opargs->u.exist_lock;
-
RESERVE_SPACE(20);
- WRITEMEM(&el->stateid, sizeof(el->stateid));
- WRITE32(el->seqid);
+ WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
+ WRITE32(opargs->lock_seqid->sequence->counter);
}
return 0;
@@ -775,8 +801,8 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
RESERVE_SPACE(44);
WRITE32(OP_LOCKU);
WRITE32(arg->type);
- WRITE32(opargs->seqid);
- WRITEMEM(&opargs->stateid, sizeof(opargs->stateid));
+ WRITE32(opargs->seqid->sequence->counter);
+ WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data));
WRITE64(arg->offset);
WRITE64(arg->length);
@@ -826,7 +852,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
*/
RESERVE_SPACE(8);
WRITE32(OP_OPEN);
- WRITE32(arg->seqid);
+ WRITE32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->open_flags);
RESERVE_SPACE(16);
WRITE64(arg->clientid);
@@ -941,7 +967,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
RESERVE_SPACE(8+sizeof(arg->stateid.data));
WRITE32(OP_OPEN_CONFIRM);
WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
- WRITE32(arg->seqid);
+ WRITE32(arg->seqid->sequence->counter);
return 0;
}
@@ -950,10 +976,10 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
{
uint32_t *p;
- RESERVE_SPACE(8+sizeof(arg->stateid.data));
+ RESERVE_SPACE(8+sizeof(arg->stateid->data));
WRITE32(OP_OPEN_DOWNGRADE);
- WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
- WRITE32(arg->seqid);
+ WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
+ WRITE32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->open_flags);
return 0;
}
@@ -1117,6 +1143,17 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client
}
static int
+encode_restorefh(struct xdr_stream *xdr)
+{
+ uint32_t *p;
+
+ RESERVE_SPACE(4);
+ WRITE32(OP_RESTOREFH);
+
+ return 0;
+}
+
+static int
encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
{
uint32_t *p;
@@ -1296,14 +1333,18 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
- if ((status = encode_putfh(&xdr, args->fh)) == 0)
- status = encode_remove(&xdr, args->name);
+ if ((status = encode_putfh(&xdr, args->fh)) != 0)
+ goto out;
+ if ((status = encode_remove(&xdr, args->name)) != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
+out:
return status;
}
@@ -1314,7 +1355,7 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
@@ -1326,7 +1367,13 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct n
goto out;
if ((status = encode_putfh(&xdr, args->new_dir)) != 0)
goto out;
- status = encode_rename(&xdr, args->old_name, args->new_name);
+ if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0)
+ goto out;
+ if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
+ goto out;
+ if ((status = encode_restorefh(&xdr)) != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1338,7 +1385,7 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
@@ -1350,7 +1397,13 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs
goto out;
if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
goto out;
- status = encode_link(&xdr, args->name);
+ if ((status = encode_link(&xdr, args->name)) != 0)
+ goto out;
+ if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
+ goto out;
+ if ((status = encode_restorefh(&xdr)) != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1362,7 +1415,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
@@ -1370,10 +1423,16 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n
encode_compound_hdr(&xdr, &hdr);
if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
goto out;
+ if ((status = encode_savefh(&xdr)) != 0)
+ goto out;
if ((status = encode_create(&xdr, args)) != 0)
goto out;
if ((status = encode_getfh(&xdr)) != 0)
goto out;
+ if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
+ goto out;
+ if ((status = encode_restorefh(&xdr)) != 0)
+ goto out;
status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
@@ -1412,7 +1471,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1422,6 +1481,9 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
if(status)
goto out;
status = encode_close(&xdr, args);
+ if (status != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1433,15 +1495,21 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
+ status = nfs_wait_on_sequence(args->seqid, req->rq_task);
+ if (status != 0)
+ goto out;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
if (status)
goto out;
+ status = encode_savefh(&xdr);
+ if (status)
+ goto out;
status = encode_open(&xdr, args);
if (status)
goto out;
@@ -1449,6 +1517,12 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
if (status)
goto out;
status = encode_getfattr(&xdr, args->bitmask);
+ if (status)
+ goto out;
+ status = encode_restorefh(&xdr);
+ if (status)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1464,6 +1538,9 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
};
int status;
+ status = nfs_wait_on_sequence(args->seqid, req->rq_task);
+ if (status != 0)
+ goto out;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
@@ -1485,6 +1562,9 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf
};
int status;
+ status = nfs_wait_on_sequence(args->seqid, req->rq_task);
+ if (status != 0)
+ goto out;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
@@ -1502,7 +1582,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1512,6 +1592,9 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
if (status)
goto out;
status = encode_open_downgrade(&xdr, args);
+ if (status != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1525,8 +1608,15 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
struct compound_hdr hdr = {
.nops = 2,
};
+ struct nfs_lock_opargs *opargs = args->u.lock;
int status;
+ status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
+ if (status != 0)
+ goto out;
+ /* Do we need to do an open_to_lock_owner? */
+ if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
+ opargs->new_lock_owner = 0;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
@@ -1713,7 +1803,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writ
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1723,6 +1813,9 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writ
if (status)
goto out;
status = encode_write(&xdr, args);
+ if (status)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1734,7 +1827,7 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_wri
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1744,6 +1837,9 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_wri
if (status)
goto out;
status = encode_commit(&xdr, args);
+ if (status)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -2670,8 +2766,7 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re
goto xdr_error;
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2704,8 +2799,7 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2730,8 +2824,7 @@ static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2787,13 +2880,10 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
goto xdr_error;
if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0)
goto xdr_error;
- if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) {
+ if ((status = verify_attr_len(xdr, savep, attrlen)) == 0)
fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4;
- fattr->timestamp = jiffies;
- }
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d\n", __FUNCTION__, -status);
return status;
}
@@ -2826,8 +2916,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2890,8 +2979,8 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res)
status = decode_op_hdr(xdr, OP_LOCK);
if (status == 0) {
- READ_BUF(sizeof(nfs4_stateid));
- COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
+ READ_BUF(sizeof(res->u.stateid.data));
+ COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
} else if (status == -NFS4ERR_DENIED)
return decode_lock_denied(xdr, &res->u.denied);
return status;
@@ -2913,8 +3002,8 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res)
status = decode_op_hdr(xdr, OP_LOCKU);
if (status == 0) {
- READ_BUF(sizeof(nfs4_stateid));
- COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
+ READ_BUF(sizeof(res->u.stateid.data));
+ COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
}
return status;
}
@@ -2994,7 +3083,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
p += bmlen;
return decode_delegation(xdr, res);
xdr_error:
- printk(KERN_NOTICE "%s: xdr error!\n", __FUNCTION__);
+ dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen);
return -EIO;
}
@@ -3208,6 +3297,12 @@ static int decode_renew(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_RENEW);
}
+static int
+decode_restorefh(struct xdr_stream *xdr)
+{
+ return decode_op_hdr(xdr, OP_RESTOREFH);
+}
+
static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
size_t *acl_len)
{
@@ -3243,7 +3338,8 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
if (attrlen <= *acl_len)
xdr_read_pages(xdr, attrlen);
*acl_len = attrlen;
- }
+ } else
+ status = -EOPNOTSUPP;
out:
return status;
@@ -3352,6 +3448,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, stru
if (status)
goto out;
status = decode_open_downgrade(&xdr, res);
+ if (status != 0)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
@@ -3424,7 +3523,7 @@ out:
/*
* Decode REMOVE response
*/
-static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
+static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -3433,8 +3532,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
goto out;
- if ((status = decode_putfh(&xdr)) == 0)
- status = decode_remove(&xdr, cinfo);
+ if ((status = decode_putfh(&xdr)) != 0)
+ goto out;
+ if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->dir_attr, res->server);
out:
return status;
}
@@ -3457,7 +3559,14 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
- status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo);
+ if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0)
+ goto out;
+ /* Current FH is target directory */
+ if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->old_fattr, res->server);
out:
return status;
}
@@ -3465,7 +3574,7 @@ out:
/*
* Decode LINK response
*/
-static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
+static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -3480,7 +3589,17 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ch
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
- status = decode_link(&xdr, cinfo);
+ if ((status = decode_link(&xdr, &res->cinfo)) != 0)
+ goto out;
+ /*
+ * Note order: OP_LINK leaves the directory as the current
+ * filehandle.
+ */
+ if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
@@ -3499,13 +3618,17 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
+ if ((status = decode_savefh(&xdr)) != 0)
+ goto out;
if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
goto out;
if ((status = decode_getfh(&xdr, res->fh)) != 0)
goto out;
- status = decode_getfattr(&xdr, res->fattr, res->server);
- if (status == NFS4ERR_DELAY)
- status = 0;
+ if (decode_getfattr(&xdr, res->fattr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->dir_fattr, res->server);
out:
return status;
}
@@ -3623,6 +3746,15 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_cl
if (status)
goto out;
status = decode_close(&xdr, res);
+ if (status != 0)
+ goto out;
+ /*
+ * Note: Server may do delete on close for this file
+ * in which case the getattr call will fail with
+ * an ESTALE error. Shouldn't be a problem,
+ * though, since fattr->valid will remain unset.
+ */
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
@@ -3643,15 +3775,20 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_ope
status = decode_putfh(&xdr);
if (status)
goto out;
+ status = decode_savefh(&xdr);
+ if (status)
+ goto out;
status = decode_open(&xdr, res);
if (status)
goto out;
status = decode_getfh(&xdr, &res->fh);
if (status)
goto out;
- status = decode_getfattr(&xdr, res->f_attr, res->server);
- if (status == NFS4ERR_DELAY)
- status = 0;
+ if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->dir_attr, res->server);
out:
return status;
}
@@ -3869,6 +4006,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_wr
if (status)
goto out;
status = decode_write(&xdr, res);
+ if (status)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
if (!status)
status = res->count;
out:
@@ -3892,6 +4032,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_w
if (status)
goto out;
status = decode_commit(&xdr, res);
+ if (status)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index be23c3fb9260..a48a003242c0 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -61,7 +61,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("%s: call getattr\n", __FUNCTION__);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(server->client_sys, NFSPROC_GETATTR, fhandle, fattr, 0);
dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
if (status)
@@ -93,7 +93,7 @@ nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call getattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(server->client, NFSPROC_GETATTR,
fhandle, fattr, 0);
dprintk("NFS reply getattr: %d\n", status);
@@ -112,7 +112,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
int status;
dprintk("NFS call setattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
if (status == 0)
nfs_setattr_update_inode(inode, sattr);
@@ -136,7 +136,7 @@ nfs_proc_lookup(struct inode *dir, struct qstr *name,
int status;
dprintk("NFS call lookup %s\n", name->name);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res, 0);
dprintk("NFS reply lookup: %d\n", status);
return status;
@@ -174,7 +174,7 @@ static int nfs_proc_read(struct nfs_read_data *rdata)
dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
(long long) rdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0) {
nfs_refresh_inode(inode, fattr);
@@ -203,10 +203,10 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
(long long) wdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0) {
- nfs_refresh_inode(inode, fattr);
+ nfs_post_op_update_inode(inode, fattr);
wdata->res.count = wdata->args.count;
wdata->verf.committed = NFS_FILE_SYNC;
}
@@ -216,7 +216,7 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags)
+ int flags, struct nameidata *nd)
{
struct nfs_fh fhandle;
struct nfs_fattr fattr;
@@ -232,7 +232,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
};
int status;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
dprintk("NFS call create %s\n", dentry->d_name.name);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
if (status == 0)
@@ -273,12 +273,13 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
}
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
+ nfs_mark_for_revalidate(dir);
if (status == -EINVAL && S_ISFIFO(mode)) {
sattr->ia_mode = mode;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
}
if (status == 0)
@@ -305,6 +306,7 @@ nfs_proc_remove(struct inode *dir, struct qstr *name)
dprintk("NFS call remove %s\n", name->name);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply remove: %d\n", status);
return status;
@@ -331,8 +333,10 @@ nfs_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
{
struct rpc_message *msg = &task->tk_msg;
- if (msg->rpc_argp)
+ if (msg->rpc_argp) {
+ nfs_mark_for_revalidate(dir->d_inode);
kfree(msg->rpc_argp);
+ }
return 0;
}
@@ -352,6 +356,8 @@ nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0);
+ nfs_mark_for_revalidate(old_dir);
+ nfs_mark_for_revalidate(new_dir);
dprintk("NFS reply rename: %d\n", status);
return status;
}
@@ -369,6 +375,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
dprintk("NFS call link %s\n", name->name);
status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply link: %d\n", status);
return status;
}
@@ -391,9 +398,10 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
if (path->len > NFS2_MAXPATHLEN)
return -ENAMETOOLONG;
dprintk("NFS call symlink %s -> %s\n", name->name, path->name);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
fhandle->size = 0;
status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply symlink: %d\n", status);
return status;
}
@@ -416,8 +424,9 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
int status;
dprintk("NFS call mkdir %s\n", dentry->d_name.name);
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
+ nfs_mark_for_revalidate(dir);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply mkdir: %d\n", status);
@@ -436,6 +445,7 @@ nfs_proc_rmdir(struct inode *dir, struct qstr *name)
dprintk("NFS call rmdir %s\n", name->name);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply rmdir: %d\n", status);
return status;
}
@@ -484,7 +494,7 @@ nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call statfs\n");
- stat->fattr->valid = 0;
+ nfs_fattr_init(stat->fattr);
status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0);
dprintk("NFS reply statfs: %d\n", status);
if (status)
@@ -507,7 +517,7 @@ nfs_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call fsinfo\n");
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0);
dprintk("NFS reply fsinfo: %d\n", status);
if (status)
@@ -579,7 +589,7 @@ nfs_write_done(struct rpc_task *task)
struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode(data->inode, data->res.fattr);
nfs_writeback_done(task);
}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 6ceb1d471f20..43b03b19731b 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -184,14 +184,13 @@ static void nfs_readpage_release(struct nfs_page *req)
{
unlock_page(req->wb_page);
- nfs_clear_request(req);
- nfs_release_request(req);
-
dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
req->wb_context->dentry->d_inode->i_sb->s_id,
(long long)NFS_FILEID(req->wb_context->dentry->d_inode),
req->wb_bytes,
(long long)req_offset(req));
+ nfs_clear_request(req);
+ nfs_release_request(req);
}
/*
@@ -216,6 +215,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.eof = 0;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->read_setup(data);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 5130eda231d7..819a65f5071f 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -870,6 +870,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.verf = &data->verf;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->write_setup(data, how);
@@ -1237,6 +1238,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
data->res.count = 0;
data->res.fattr = &data->fattr;
data->res.verf = &data->verf;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->commit_setup(data, how);
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index 251e5a1bb1c4..0c2be8c0307d 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -48,43 +48,26 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
(struct nfsacl_encode_desc *) desc;
u32 *p = (u32 *) elem;
- if (nfsacl_desc->count < nfsacl_desc->acl->a_count) {
- struct posix_acl_entry *entry =
- &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
+ struct posix_acl_entry *entry =
+ &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
- *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
- switch(entry->e_tag) {
- case ACL_USER_OBJ:
- *p++ = htonl(nfsacl_desc->uid);
- break;
- case ACL_GROUP_OBJ:
- *p++ = htonl(nfsacl_desc->gid);
- break;
- case ACL_USER:
- case ACL_GROUP:
- *p++ = htonl(entry->e_id);
- break;
- default: /* Solaris depends on that! */
- *p++ = 0;
- break;
- }
- *p++ = htonl(entry->e_perm & S_IRWXO);
- } else {
- const struct posix_acl_entry *pa, *pe;
- int group_obj_perm = ACL_READ|ACL_WRITE|ACL_EXECUTE;
-
- FOREACH_ACL_ENTRY(pa, nfsacl_desc->acl, pe) {
- if (pa->e_tag == ACL_GROUP_OBJ) {
- group_obj_perm = pa->e_perm & S_IRWXO;
- break;
- }
- }
- /* fake up ACL_MASK entry */
- *p++ = htonl(ACL_MASK | nfsacl_desc->typeflag);
- *p++ = htonl(0);
- *p++ = htonl(group_obj_perm);
+ *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
+ switch(entry->e_tag) {
+ case ACL_USER_OBJ:
+ *p++ = htonl(nfsacl_desc->uid);
+ break;
+ case ACL_GROUP_OBJ:
+ *p++ = htonl(nfsacl_desc->gid);
+ break;
+ case ACL_USER:
+ case ACL_GROUP:
+ *p++ = htonl(entry->e_id);
+ break;
+ default: /* Solaris depends on that! */
+ *p++ = 0;
+ break;
}
-
+ *p++ = htonl(entry->e_perm & S_IRWXO);
return 0;
}
@@ -105,11 +88,28 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
.gid = inode->i_gid,
};
int err;
+ struct posix_acl *acl2 = NULL;
if (entries > NFS_ACL_MAX_ENTRIES ||
xdr_encode_word(buf, base, entries))
return -EINVAL;
+ if (encode_entries && acl && acl->a_count == 3) {
+ /* Fake up an ACL_MASK entry. */
+ acl2 = posix_acl_alloc(4, GFP_KERNEL);
+ if (!acl2)
+ return -ENOMEM;
+ /* Insert entries in canonical order: other orders seem
+ to confuse Solaris VxFS. */
+ acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */
+ acl2->a_entries[1] = acl->a_entries[1]; /* ACL_GROUP_OBJ */
+ acl2->a_entries[2] = acl->a_entries[1]; /* ACL_MASK */
+ acl2->a_entries[2].e_tag = ACL_MASK;
+ acl2->a_entries[3] = acl->a_entries[2]; /* ACL_OTHER */
+ nfsacl_desc.acl = acl2;
+ }
err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
+ if (acl2)
+ posix_acl_release(acl2);
if (!err)
err = 8 + nfsacl_desc.desc.elem_size *
nfsacl_desc.desc.array_len;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e08edc17c6a0..361b4007d4a0 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -162,7 +162,7 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
static inline int
-nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
+nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner)
{
int status;
dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
@@ -238,8 +238,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
*/
status = nfsd4_process_open2(rqstp, current_fh, open);
out:
- if (open->op_stateowner)
+ if (open->op_stateowner) {
nfs4_get_stateowner(open->op_stateowner);
+ *replay_owner = open->op_stateowner;
+ }
nfs4_unlock_state();
return status;
}
@@ -809,8 +811,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
op->status = nfsd4_access(rqstp, current_fh, &op->u.access);
break;
case OP_CLOSE:
- op->status = nfsd4_close(rqstp, current_fh, &op->u.close);
- replay_owner = op->u.close.cl_stateowner;
+ op->status = nfsd4_close(rqstp, current_fh, &op->u.close, &replay_owner);
break;
case OP_COMMIT:
op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit);
@@ -831,15 +832,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link);
break;
case OP_LOCK:
- op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock);
- replay_owner = op->u.lock.lk_stateowner;
+ op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock, &replay_owner);
break;
case OP_LOCKT:
op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt);
break;
case OP_LOCKU:
- op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku);
- replay_owner = op->u.locku.lu_stateowner;
+ op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku, &replay_owner);
break;
case OP_LOOKUP:
op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup);
@@ -853,16 +852,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
op->status = nfs_ok;
break;
case OP_OPEN:
- op->status = nfsd4_open(rqstp, current_fh, &op->u.open);
- replay_owner = op->u.open.op_stateowner;
+ op->status = nfsd4_open(rqstp, current_fh, &op->u.open, &replay_owner);
break;
case OP_OPEN_CONFIRM:
- op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm);
- replay_owner = op->u.open_confirm.oc_stateowner;
+ op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm, &replay_owner);
break;
case OP_OPEN_DOWNGRADE:
- op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade);
- replay_owner = op->u.open_downgrade.od_stateowner;
+ op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade, &replay_owner);
break;
case OP_PUTFH:
op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b83f8fb441e1..6bbefd06f10d 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -624,7 +624,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
cb->cb_ident = se->se_callback_ident;
return;
out_err:
- printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
+ dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
"will not receive delegations\n",
clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
@@ -678,13 +678,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
int status;
char dname[HEXDIR_LEN];
- status = nfserr_inval;
if (!check_name(clname))
- goto out;
+ return nfserr_inval;
status = nfs4_make_rec_clidname(dname, &clname);
if (status)
- goto out;
+ return status;
/*
* XXX The Duplicate Request Cache (DRC) has been checked (??)
@@ -2014,7 +2013,7 @@ STALE_STATEID(stateid_t *stateid)
{
if (stateid->si_boot == boot_time)
return 0;
- printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
+ dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
stateid->si_generation);
return 1;
@@ -2275,7 +2274,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
check_replay:
if (seqid == sop->so_seqid - 1) {
- printk("NFSD: preprocess_seqid_op: retransmission?\n");
+ dprintk("NFSD: preprocess_seqid_op: retransmission?\n");
/* indicate replay to calling function */
return NFSERR_REPLAY_ME;
}
@@ -2286,7 +2285,7 @@ check_replay:
}
int
-nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
+nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
{
int status;
struct nfs4_stateowner *sop;
@@ -2320,8 +2319,10 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
nfsd4_create_clid_dir(sop->so_client);
out:
- if (oc->oc_stateowner)
+ if (oc->oc_stateowner) {
nfs4_get_stateowner(oc->oc_stateowner);
+ *replay_owner = oc->oc_stateowner;
+ }
nfs4_unlock_state();
return status;
}
@@ -2352,7 +2353,7 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
}
int
-nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
+nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
{
int status;
struct nfs4_stateid *stp;
@@ -2394,8 +2395,10 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
status = nfs_ok;
out:
- if (od->od_stateowner)
+ if (od->od_stateowner) {
nfs4_get_stateowner(od->od_stateowner);
+ *replay_owner = od->od_stateowner;
+ }
nfs4_unlock_state();
return status;
}
@@ -2404,7 +2407,7 @@ out:
* nfs4_unlock_state() called after encode
*/
int
-nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
+nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
{
int status;
struct nfs4_stateid *stp;
@@ -2430,8 +2433,10 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
/* release_state_owner() calls nfsd_close() if needed */
release_state_owner(stp, OPEN_STATE);
out:
- if (close->cl_stateowner)
+ if (close->cl_stateowner) {
nfs4_get_stateowner(close->cl_stateowner);
+ *replay_owner = close->cl_stateowner;
+ }
nfs4_unlock_state();
return status;
}
@@ -2500,8 +2505,7 @@ find_stateid(stateid_t *stid, int flags)
(local->st_stateid.si_fileid == f_id))
return local;
}
- } else
- printk("NFSD: find_stateid: ERROR: no state flag\n");
+ }
return NULL;
}
@@ -2624,7 +2628,9 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
sop->so_is_open_owner = 0;
sop->so_id = current_ownerid++;
sop->so_client = clp;
- sop->so_seqid = lock->lk_new_lock_seqid;
+ /* It is the openowner seqid that will be incremented in encode in the
+ * case of new lockowners; so increment the lock seqid manually: */
+ sop->so_seqid = lock->lk_new_lock_seqid + 1;
sop->so_confirmed = 1;
rp = &sop->so_replay;
rp->rp_status = NFSERR_SERVERFAULT;
@@ -2676,9 +2682,10 @@ check_lock_length(u64 offset, u64 length)
* LOCK operation
*/
int
-nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
+nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
{
struct nfs4_stateowner *open_sop = NULL;
+ struct nfs4_stateowner *lock_sop = NULL;
struct nfs4_stateid *lock_stp;
struct file *filp;
struct file_lock file_lock;
@@ -2705,19 +2712,19 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
struct nfs4_file *fp;
status = nfserr_stale_clientid;
- if (STALE_CLIENTID(&lock->lk_new_clientid)) {
- printk("NFSD: nfsd4_lock: clientid is stale!\n");
+ if (STALE_CLIENTID(&lock->lk_new_clientid))
goto out;
- }
/* validate and update open stateid and open seqid */
status = nfs4_preprocess_seqid_op(current_fh,
lock->lk_new_open_seqid,
&lock->lk_new_open_stateid,
CHECK_FH | OPEN_STATE,
- &open_sop, &open_stp, lock);
+ &lock->lk_stateowner, &open_stp,
+ lock);
if (status)
goto out;
+ open_sop = lock->lk_stateowner;
/* create lockowner and lock stateid */
fp = open_stp->st_file;
strhashval = lock_ownerstr_hashval(fp->fi_inode,
@@ -2727,16 +2734,15 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
* the same file, or should they just be allowed (and
* create new stateids)? */
status = nfserr_resource;
- if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
+ lock_sop = alloc_init_lock_stateowner(strhashval,
+ open_sop->so_client, open_stp, lock);
+ if (lock_sop == NULL)
goto out;
- if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner,
- fp, open_stp)) == NULL) {
- release_stateowner(lock->lk_stateowner);
- lock->lk_stateowner = NULL;
+ lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
+ if (lock_stp == NULL) {
+ release_stateowner(lock_sop);
goto out;
}
- /* bump the open seqid used to create the lock */
- open_sop->so_seqid++;
} else {
/* lock (lock owner + lock stateid) already exists */
status = nfs4_preprocess_seqid_op(current_fh,
@@ -2746,12 +2752,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
&lock->lk_stateowner, &lock_stp, lock);
if (status)
goto out;
+ lock_sop = lock->lk_stateowner;
}
/* lock->lk_stateowner and lock_stp have been created or found */
filp = lock_stp->st_vfs_file;
if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
- printk("NFSD: nfsd4_lock: permission denied!\n");
+ dprintk("NFSD: nfsd4_lock: permission denied!\n");
goto out;
}
@@ -2776,7 +2783,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
status = nfserr_inval;
goto out;
}
- file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
+ file_lock.fl_owner = (fl_owner_t)lock_sop;
file_lock.fl_pid = current->tgid;
file_lock.fl_file = filp;
file_lock.fl_flags = FL_POSIX;
@@ -2832,14 +2839,13 @@ out_destroy_new_stateid:
* An error encountered after instantiation of the new
* stateid has forced us to destroy it.
*/
- if (!seqid_mutating_err(status))
- open_sop->so_seqid--;
-
release_state_owner(lock_stp, LOCK_STATE);
}
out:
- if (lock->lk_stateowner)
+ if (lock->lk_stateowner) {
nfs4_get_stateowner(lock->lk_stateowner);
+ *replay_owner = lock->lk_stateowner;
+ }
nfs4_unlock_state();
return status;
}
@@ -2866,13 +2872,11 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
nfs4_lock_state();
status = nfserr_stale_clientid;
- if (STALE_CLIENTID(&lockt->lt_clientid)) {
- printk("NFSD: nfsd4_lockt: clientid is stale!\n");
+ if (STALE_CLIENTID(&lockt->lt_clientid))
goto out;
- }
if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
- printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
+ dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
if (status == nfserr_symlink)
status = nfserr_inval;
goto out;
@@ -2930,7 +2934,7 @@ out:
}
int
-nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
+nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
{
struct nfs4_stateid *stp;
struct file *filp = NULL;
@@ -2976,7 +2980,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
file_lock.fl_ops->fl_release_private(&file_lock);
if (status) {
- printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
+ dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
goto out_nfserr;
}
/*
@@ -2986,8 +2990,10 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
out:
- if (locku->lu_stateowner)
+ if (locku->lu_stateowner) {
nfs4_get_stateowner(locku->lu_stateowner);
+ *replay_owner = locku->lu_stateowner;
+ }
nfs4_unlock_state();
return status;
@@ -3036,10 +3042,8 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
/* XXX check for lease expiration */
status = nfserr_stale_clientid;
- if (STALE_CLIENTID(clid)) {
- printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
+ if (STALE_CLIENTID(clid))
return status;
- }
nfs4_lock_state();
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 9eecc9939dfe..de58579a1d0e 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,6 +22,90 @@ 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. Note, this only
+ works if chkdsk left the journal in an obviously clean state.
+ - 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.
+ - 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().
+ - Change the mount options {u,f,d}mask to always parse the number as
+ an octal number to conform to how chmod(1) works, too. Thanks to
+ Giuseppe Bilotta and Horst von Brand for pointing out the errors of
+ my ways.
+ - Fix various bugs in the runlist merging code. (Based on libntfs
+ changes by Richard Russon.)
+ - Fix sparse warnings that have crept in over time.
+ - Change ntfs_cluster_free() to require a write locked runlist on entry
+ since we otherwise get into a lock reversal deadlock if a read locked
+ runlist is passed in. In the process also change it to take an ntfs
+ inode instead of a vfs inode as parameter.
+ - Fix the definition of the CHKD ntfs record magic. It had an off by
+ two error causing it to be CHKB instead of CHKD.
+ - Fix a stupid bug in __ntfs_bitmap_set_bits_in_run() which caused the
+ count to become negative and hence we had a wild memset() scribbling
+ all over the system's ram.
+
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 f083f27d8b69..894b2b876d35 100644
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
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 78adad7a988d..5e80c07c6a4d 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -27,6 +27,7 @@
#include <linux/swap.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
+#include <linux/bit_spinlock.h>
#include "aops.h"
#include "attrib.h"
@@ -55,45 +56,56 @@
*/
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;
+ struct inode *vi;
ntfs_inode *ni;
int page_uptodate = 1;
page = bh->b_page;
- ni = NTFS_I(page->mapping->host);
+ vi = page->mapping->host;
+ ni = NTFS_I(vi);
if (likely(uptodate)) {
- s64 file_ofs, initialized_size;
+ loff_t i_size;
+ s64 file_ofs, init_size;
set_buffer_uptodate(bh);
file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) +
bh_offset(bh);
read_lock_irqsave(&ni->size_lock, flags);
- initialized_size = ni->initialized_size;
+ init_size = ni->initialized_size;
+ i_size = i_size_read(vi);
read_unlock_irqrestore(&ni->size_lock, flags);
+ if (unlikely(init_size > i_size)) {
+ /* Race with shrinking truncate. */
+ init_size = i_size;
+ }
/* Check for the current buffer head overflowing. */
- if (file_ofs + bh->b_size > initialized_size) {
- char *addr;
- int ofs = 0;
-
- if (file_ofs < initialized_size)
- ofs = initialized_size - file_ofs;
- addr = kmap_atomic(page, KM_BIO_SRC_IRQ);
- memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs);
+ if (unlikely(file_ofs + bh->b_size > init_size)) {
+ u8 *kaddr;
+ int ofs;
+
+ ofs = 0;
+ if (file_ofs < init_size)
+ ofs = init_size - file_ofs;
+ kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
+ memset(kaddr + bh_offset(bh) + ofs, 0,
+ bh->b_size - ofs);
+ kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
flush_dcache_page(page);
- kunmap_atomic(addr, KM_BIO_SRC_IRQ);
}
} else {
clear_buffer_uptodate(bh);
- ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.",
- (unsigned long long)bh->b_blocknr);
SetPageError(page);
+ ntfs_error(ni->vol->sb, "Buffer I/O error, logical block "
+ "0x%llx.", (unsigned long long)bh->b_blocknr);
}
- 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 +120,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
@@ -121,7 +134,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
if (likely(page_uptodate && !PageError(page)))
SetPageUptodate(page);
} else {
- char *addr;
+ u8 *kaddr;
unsigned int i, recs;
u32 rec_size;
@@ -129,19 +142,20 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
recs = PAGE_CACHE_SIZE / rec_size;
/* Should have been verified before we got here... */
BUG_ON(!recs);
- addr = kmap_atomic(page, KM_BIO_SRC_IRQ);
+ kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
for (i = 0; i < recs; i++)
- post_read_mst_fixup((NTFS_RECORD*)(addr +
+ post_read_mst_fixup((NTFS_RECORD*)(kaddr +
i * rec_size), rec_size);
+ kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
flush_dcache_page(page);
- kunmap_atomic(addr, KM_BIO_SRC_IRQ);
if (likely(page_uptodate && !PageError(page)))
SetPageUptodate(page);
}
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;
}
@@ -164,8 +178,11 @@ still_busy:
*/
static int ntfs_read_block(struct page *page)
{
+ loff_t i_size;
VCN vcn;
LCN lcn;
+ s64 init_size;
+ struct inode *vi;
ntfs_inode *ni;
ntfs_volume *vol;
runlist_element *rl;
@@ -176,7 +193,8 @@ static int ntfs_read_block(struct page *page)
int i, nr;
unsigned char blocksize_bits;
- ni = NTFS_I(page->mapping->host);
+ vi = page->mapping->host;
+ ni = NTFS_I(vi);
vol = ni->vol;
/* $MFT/$DATA must have its complete runlist in memory at all times. */
@@ -185,25 +203,45 @@ 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);
+ /*
+ * We may be racing with truncate. To avoid some of the problems we
+ * now take a snapshot of the various sizes and use those for the whole
+ * of the function. In case of an extending truncate it just means we
+ * may leave some buffers unmapped which are now allocated. This is
+ * not a problem since these buffers will just get mapped when a write
+ * occurs. In case of a shrinking truncate, we will detect this later
+ * on due to the runlist being incomplete and if the page is being
+ * fully truncated, truncate will throw it away as soon as we unlock
+ * it so no need to worry what we do with it.
+ */
iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
read_lock_irqsave(&ni->size_lock, flags);
lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;
- zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits;
+ init_size = ni->initialized_size;
+ i_size = i_size_read(vi);
read_unlock_irqrestore(&ni->size_lock, flags);
+ if (unlikely(init_size > i_size)) {
+ /* Race with shrinking truncate. */
+ init_size = i_size;
+ }
+ zblock = (init_size + blocksize - 1) >> blocksize_bits;
/* Loop through all the buffers in the page. */
rl = NULL;
nr = i = 0;
do {
u8 *kaddr;
+ int err;
if (unlikely(buffer_uptodate(bh)))
continue;
@@ -211,6 +249,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 +291,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 +301,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 +337,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. */
@@ -348,6 +397,8 @@ handle_zblock:
*/
static int ntfs_readpage(struct file *file, struct page *page)
{
+ loff_t i_size;
+ struct inode *vi;
ntfs_inode *ni, *base_ni;
u8 *kaddr;
ntfs_attr_search_ctx *ctx;
@@ -366,32 +417,42 @@ retry_readpage:
unlock_page(page);
return 0;
}
- ni = NTFS_I(page->mapping->host);
-
+ vi = page->mapping->host;
+ ni = NTFS_I(vi);
+ /*
+ * 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. Note we need to check for
+ * AT_INDEX_ALLOCATION since this is the type of both directory and
+ * index inodes.
+ */
+ if (ni->type != AT_INDEX_ALLOCATION) {
+ /* 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);
@@ -431,7 +492,12 @@ retry_readpage:
read_lock_irqsave(&ni->size_lock, flags);
if (unlikely(attr_len > ni->initialized_size))
attr_len = ni->initialized_size;
+ i_size = i_size_read(vi);
read_unlock_irqrestore(&ni->size_lock, flags);
+ if (unlikely(attr_len > i_size)) {
+ /* Race with shrinking truncate. */
+ attr_len = i_size;
+ }
kaddr = kmap_atomic(page, KM_USER0);
/* Copy the data to the page. */
memcpy(kaddr, (u8*)ctx->attr +
@@ -511,19 +577,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 +738,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 +779,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 +820,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 +836,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 +873,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 +882,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 +959,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,58 +1378,66 @@ 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. Note we need to check for
+ * AT_INDEX_ALLOCATION since this is the type of both directory and
+ * index inodes.
+ */
+ if (ni->type != AT_INDEX_ALLOCATION) {
+ /* 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. */
unsigned int ofs = i_size & ~PAGE_CACHE_MASK;
kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr + ofs, 0, PAGE_CACHE_SIZE - ofs);
- flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
}
/* 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,50 +1486,33 @@ 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?
- */
-
attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
i_size = i_size_read(vi);
if (unlikely(attr_len > i_size)) {
+ /* Race with shrinking truncate or a failed truncate. */
attr_len = i_size;
- ctx->attr->data.resident.value_length = cpu_to_le32(attr_len);
+ /*
+ * If the truncate failed, fix it up now. If a concurrent
+ * truncate, we do its job, so it does not have to do anything.
+ */
+ err = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr,
+ attr_len);
+ /* Shrinking cannot fail. */
+ BUG_ON(err);
}
kaddr = kmap_atomic(page, KM_USER0);
/* Copy the data from the page to the mft record. */
memcpy((u8*)ctx->attr +
le16_to_cpu(ctx->attr->data.resident.value_offset),
kaddr, attr_len);
- flush_dcache_mft_record_page(ctx->ntfs_ino);
/* Zero out of bounds area in the page cache page. */
memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
- flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
-
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ flush_dcache_page(page);
+ /* We are done with the page. */
end_page_writeback(page);
-
- /* Mark the mft record dirty, so it gets written back. */
+ /* Finally, mark the mft record dirty, so it gets written back. */
mark_mft_record_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
unmap_mft_record(base_ni);
@@ -1681,27 +1770,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 +2444,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 cd0f9e740b14..3f9a4ff42ee5 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 0e4ac6d3c0e7..0618ed6fd7b3 100644
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -99,6 +99,8 @@ extern int ntfs_attr_can_be_resident(const ntfs_volume *vol,
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/bitmap.c b/fs/ntfs/bitmap.c
index 12cf2e30c7dd..7a190cdc60e2 100644
--- a/fs/ntfs/bitmap.c
+++ b/fs/ntfs/bitmap.c
@@ -1,7 +1,7 @@
/*
* bitmap.c - NTFS kernel bitmap handling. Part of the Linux-NTFS project.
*
- * Copyright (c) 2004 Anton Altaparmakov
+ * Copyright (c) 2004-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
@@ -90,7 +90,8 @@ int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
/* If the first byte is partial, modify the appropriate bits in it. */
if (bit) {
u8 *byte = kaddr + pos;
- while ((bit & 7) && cnt--) {
+ while ((bit & 7) && cnt) {
+ cnt--;
if (value)
*byte |= 1 << bit++;
else
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 6d265cfd49aa..25d24106f893 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -539,7 +539,6 @@ int ntfs_read_compressed_block(struct page *page)
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 46779471c542..795c3d1930f5 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1051,7 +1051,8 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
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 e0f530ce6b99..be9fd1dd423d 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 11fd5307d780..8f2d5727546f 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -205,6 +205,7 @@ int ntfs_index_lookup(const void *key, const int key_len,
&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 886214a77f90..7ec045131808 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 "
@@ -1165,6 +1166,8 @@ err_out:
*
* Return 0 on success and -errno on error. In the error case, the inode will
* have had make_bad_inode() executed on it.
+ *
+ * Note this cannot be called for AT_INDEX_ALLOCATION.
*/
static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
{
@@ -1212,6 +1215,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 compressed/sparse 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 +1292,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 +1321,7 @@ 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)) {
if (a->data.non_resident.compression_unit != 4) {
ntfs_error(vi->i_sb, "Found nonstandard "
"compression unit (%u instead "
@@ -1313,23 +1341,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 +1359,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 +1491,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 +2444,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/layout.h b/fs/ntfs/layout.h
index 609ad1728ce4..5c248d404f05 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -123,7 +123,7 @@ enum {
magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */
/* Found in $LogFile/$DATA. (May be found in $MFT/$DATA, also?) */
- magic_CHKD = const_cpu_to_le32(0x424b4843), /* Modified by chkdsk. */
+ magic_CHKD = const_cpu_to_le32(0x444b4843), /* Modified by chkdsk. */
/* Found in all ntfs record containing records. */
magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector
@@ -308,10 +308,8 @@ typedef le16 MFT_RECORD_FLAGS;
* The _LE versions are to be applied on little endian MFT_REFs.
* Note: The _LE versions will return a CPU endian formatted value!
*/
-typedef enum {
- MFT_REF_MASK_CPU = 0x0000ffffffffffffULL,
- MFT_REF_MASK_LE = const_cpu_to_le64(0x0000ffffffffffffULL),
-} MFT_REF_CONSTS;
+#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
+#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
typedef u64 MFT_REF;
typedef le64 leMFT_REF;
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index a4bc07616e5d..5af3bf0b7eee 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);
/*
@@ -785,13 +779,13 @@ out:
/**
* __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
+ * @ni: ntfs inode whose runlist describes the clusters to free
+ * @start_vcn: vcn in the runlist of @ni 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
+ * @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.
+ * described by the vfs inode @ni.
*
* If @count is -1, all clusters from @start_vcn to the end of the runlist are
* deallocated. Thus, to completely free all clusters in a runlist, use
@@ -806,31 +800,28 @@ 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 @ni must be locked for writing on entry
+ * and is locked on return. 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,
+s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
const BOOL is_rollback)
{
s64 delta, to_free, total_freed, real_freed;
- ntfs_inode *ni;
ntfs_volume *vol;
struct inode *lcnbmp_vi;
runlist_element *rl;
int err;
- BUG_ON(!vi);
+ BUG_ON(!ni);
ntfs_debug("Entering for i_ino 0x%lx, start_vcn 0x%llx, count "
- "0x%llx.%s", vi->i_ino, (unsigned long long)start_vcn,
+ "0x%llx.%s", ni->mft_no, (unsigned long long)start_vcn,
(unsigned long long)count,
is_rollback ? " (rollback)" : "");
- ni = NTFS_I(vi);
vol = ni->vol;
lcnbmp_vi = vol->lcnbmp_ino;
BUG_ON(!lcnbmp_vi);
@@ -848,8 +839,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, TRUE);
if (IS_ERR(rl)) {
if (!is_rollback)
ntfs_error(vol->sb, "Failed to find first runlist "
@@ -903,7 +893,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, TRUE);
if (IS_ERR(rl)) {
err = PTR_ERR(rl);
if (!is_rollback)
@@ -950,7 +940,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 +949,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 +961,7 @@ 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(ni, start_vcn, total_freed, 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 4cac1c024af6..a6a8827882e7 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -2,7 +2,7 @@
* lcnalloc.h - Exports for NTFS kernel cluster (de)allocation. Part of the
* Linux-NTFS project.
*
- * Copyright (c) 2004 Anton Altaparmakov
+ * Copyright (c) 2004-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
@@ -28,6 +28,7 @@
#include <linux/fs.h>
#include "types.h"
+#include "inode.h"
#include "runlist.h"
#include "volume.h"
@@ -42,17 +43,17 @@ extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
const VCN start_vcn, const s64 count, const LCN start_lcn,
const NTFS_CLUSTER_ALLOCATION_ZONES zone);
-extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
+extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
s64 count, 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
+ * @ni: ntfs inode whose runlist describes the clusters to free
+ * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters
* @count: number of clusters to free or -1 for all clusters
*
* Free @count clusters starting at the cluster @start_vcn in the runlist
- * described by the vfs inode @vi.
+ * described by the ntfs inode @ni.
*
* If @count is -1, all clusters from @start_vcn to the end of the runlist are
* deallocated. Thus, to completely free all clusters in a runlist, use
@@ -64,19 +65,18 @@ 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 @ni must be locked for writing on entry
+ * and is locked on return. 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,
+static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
s64 count)
{
- return __ntfs_cluster_free(vi, start_vcn, count, FALSE);
+ return __ntfs_cluster_free(ni, start_vcn, count, FALSE);
}
extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
@@ -93,8 +93,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 8edb8e20fb08..0fd70295cca6 100644
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -51,7 +51,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
RESTART_PAGE_HEADER *rp, s64 pos)
{
u32 logfile_system_page_size, logfile_log_page_size;
- u16 usa_count, usa_ofs, usa_end, ra_ofs;
+ u16 ra_ofs, usa_count, usa_ofs, usa_end = 0;
+ BOOL have_usa = TRUE;
ntfs_debug("Entering.");
/*
@@ -86,6 +87,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
(int)sle16_to_cpu(rp->minor_ver));
return FALSE;
}
+ /*
+ * If chkdsk has been run the restart page may not be protected by an
+ * update sequence array.
+ */
+ if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) {
+ have_usa = FALSE;
+ goto skip_usa_checks;
+ }
/* Verify the size of the update sequence array. */
usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS);
if (usa_count != le16_to_cpu(rp->usa_count)) {
@@ -102,6 +111,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
"inconsistent update sequence array offset.");
return FALSE;
}
+skip_usa_checks:
/*
* Verify the position of the restart area. It must be:
* - aligned to 8-byte boundary,
@@ -109,7 +119,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
* - within the system page size.
*/
ra_ofs = le16_to_cpu(rp->restart_area_offset);
- if (ra_ofs & 7 || ra_ofs < usa_end ||
+ if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end :
+ ra_ofs < sizeof(RESTART_PAGE_HEADER)) ||
ra_ofs > logfile_system_page_size) {
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
"inconsistent restart area offset.");
@@ -121,7 +132,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 +323,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 +336,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 +373,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 +400,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);
@@ -389,32 +413,64 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
idx++;
} while (to_read > 0);
}
- /* Perform the multi sector transfer deprotection on the buffer. */
- if (post_read_mst_fixup((NTFS_RECORD*)trp,
+ /*
+ * Perform the multi sector transfer deprotection on the buffer if the
+ * restart page is protected.
+ */
+ if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count))
+ && 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 +480,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 +546,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 +565,100 @@ 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_debug("Using second restart page as it is more "
+ "recent.");
+ ntfs_free(rstr1_ph);
+ rstr1_ph = rstr2_ph;
+ /* rstr1_lsn = rstr2_lsn; */
+ } else {
+ ntfs_debug("Using first restart page as it is more "
+ "recent.");
+ 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 +675,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 +686,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 +704,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 4ee4378de061..a51f3dd0e9eb 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
@@ -113,7 +113,7 @@ typedef struct {
*/
enum {
RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002),
- RESTART_SPACE_FILLER = 0xffff, /* gcc: Force enum bit width to 16. */
+ RESTART_SPACE_FILLER = const_cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */
} __attribute__ ((__packed__));
typedef le16 RESTART_AREA_FLAGS;
@@ -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 fac5944df6d8..590887b943f5 100644
--- a/fs/ntfs/malloc.h
+++ b/fs/ntfs/malloc.h
@@ -1,7 +1,7 @@
/*
* malloc.h - NTFS kernel memory handling. 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
@@ -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,
+ gfp_t 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 & ~__GFP_HIGHMEM);
+ /* 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 317f7c679fd3..b011369b5956 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -58,7 +58,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
* overflowing the unsigned long, but I don't think we would ever get
* here if the volume was that big...
*/
- index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
+ index = (u64)ni->mft_no << vol->mft_record_size_bits >>
+ PAGE_CACHE_SHIFT;
ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
i_size = i_size_read(mft_vi);
@@ -511,7 +512,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 +692,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 +1954,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(mft_ni, old_last_vcn, -1) < 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 758855b0414e..061b5ff6b73c 100644
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -2,7 +2,7 @@
* runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2001-2005 Anton Altaparmakov
- * Copyright (c) 2002 Richard Russon
+ * Copyright (c) 2002-2005 Richard Russon
*
* 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
@@ -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
@@ -113,17 +158,21 @@ static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst,
BUG_ON(!dst);
BUG_ON(!src);
- if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */
- if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)
- return TRUE;
- return FALSE;
- }
- if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */
- return FALSE;
- if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */
+ /* We can merge unmapped regions even if they are misaligned. */
+ if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED))
+ return TRUE;
+ /* If the runs are misaligned, we cannot merge them. */
+ if ((dst->vcn + dst->length) != src->vcn)
return FALSE;
-
- return TRUE;
+ /* If both runs are non-sparse and contiguous, we can merge them. */
+ if ((dst->lcn >= 0) && (src->lcn >= 0) &&
+ ((dst->lcn + dst->length) == src->lcn))
+ return TRUE;
+ /* If we are merging two holes, we can merge them. */
+ if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE))
+ return TRUE;
+ /* Cannot merge. */
+ return FALSE;
}
/**
@@ -169,14 +218,15 @@ static inline void __ntfs_rl_merge(runlist_element *dst, runlist_element *src)
static inline runlist_element *ntfs_rl_append(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL right;
- int magic;
+ BOOL right = FALSE; /* Right end of @src needs merging. */
+ int marker; /* End of the inserted runs. */
BUG_ON(!dst);
BUG_ON(!src);
/* First, check if the right hand end needs merging. */
- right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
+ if ((loc + 1) < dsize)
+ right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
/* Space required: @dst size + @src size, less one if we merged. */
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - right);
@@ -191,18 +241,19 @@ static inline runlist_element *ntfs_rl_append(runlist_element *dst,
if (right)
__ntfs_rl_merge(src + ssize - 1, dst + loc + 1);
- magic = loc + ssize;
+ /* First run after the @src runs that have been inserted. */
+ marker = loc + ssize + 1;
/* Move the tail of @dst out of the way, then copy in @src. */
- ntfs_rl_mm(dst, magic + 1, loc + 1 + right, dsize - loc - 1 - right);
+ ntfs_rl_mm(dst, marker, loc + 1 + right, dsize - (loc + 1 + right));
ntfs_rl_mc(dst, loc + 1, src, 0, ssize);
/* Adjust the size of the preceding hole. */
dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;
/* We may have changed the length of the file, so fix the end marker */
- if (dst[magic + 1].lcn == LCN_ENOENT)
- dst[magic + 1].vcn = dst[magic].vcn + dst[magic].length;
+ if (dst[marker].lcn == LCN_ENOENT)
+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;
return dst;
}
@@ -234,18 +285,17 @@ static inline runlist_element *ntfs_rl_append(runlist_element *dst,
static inline runlist_element *ntfs_rl_insert(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL left = FALSE;
- BOOL disc = FALSE; /* Discontinuity */
- BOOL hole = FALSE; /* Following a hole */
- int magic;
+ BOOL left = FALSE; /* Left end of @src needs merging. */
+ BOOL disc = FALSE; /* Discontinuity between @dst and @src. */
+ int marker; /* End of the inserted runs. */
BUG_ON(!dst);
BUG_ON(!src);
- /* disc => Discontinuity between the end of @dst and the start of @src.
- * This means we might need to insert a hole.
- * hole => @dst ends with a hole or an unmapped region which we can
- * extend to match the discontinuity. */
+ /*
+ * disc => Discontinuity between the end of @dst and the start of @src.
+ * This means we might need to insert a "not mapped" run.
+ */
if (loc == 0)
disc = (src[0].vcn > 0);
else {
@@ -258,58 +308,49 @@ static inline runlist_element *ntfs_rl_insert(runlist_element *dst,
merged_length += src->length;
disc = (src[0].vcn > dst[loc - 1].vcn + merged_length);
- if (disc)
- hole = (dst[loc - 1].lcn == LCN_HOLE);
}
-
- /* Space required: @dst size + @src size, less one if we merged, plus
- * one if there was a discontinuity, less one for a trailing hole. */
- dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left + disc - hole);
+ /*
+ * Space required: @dst size + @src size, less one if we merged, plus
+ * one if there was a discontinuity.
+ */
+ dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left + disc);
if (IS_ERR(dst))
return dst;
/*
* We are guaranteed to succeed from here so can start modifying the
* original runlist.
*/
-
if (left)
__ntfs_rl_merge(dst + loc - 1, src);
-
- magic = loc + ssize - left + disc - hole;
+ /*
+ * First run after the @src runs that have been inserted.
+ * Nominally, @marker equals @loc + @ssize, i.e. location + number of
+ * runs in @src. However, if @left, then the first run in @src has
+ * been merged with one in @dst. And if @disc, then @dst and @src do
+ * not meet and we need an extra run to fill the gap.
+ */
+ marker = loc + ssize - left + disc;
/* Move the tail of @dst out of the way, then copy in @src. */
- ntfs_rl_mm(dst, magic, loc, dsize - loc);
- ntfs_rl_mc(dst, loc + disc - hole, src, left, ssize - left);
+ ntfs_rl_mm(dst, marker, loc, dsize - loc);
+ ntfs_rl_mc(dst, loc + disc, src, left, ssize - left);
- /* Adjust the VCN of the last run ... */
- if (dst[magic].lcn <= LCN_HOLE)
- dst[magic].vcn = dst[magic - 1].vcn + dst[magic - 1].length;
+ /* Adjust the VCN of the first run after the insertion... */
+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;
/* ... and the length. */
- if (dst[magic].lcn == LCN_HOLE || dst[magic].lcn == LCN_RL_NOT_MAPPED)
- dst[magic].length = dst[magic + 1].vcn - dst[magic].vcn;
+ if (dst[marker].lcn == LCN_HOLE || dst[marker].lcn == LCN_RL_NOT_MAPPED)
+ dst[marker].length = dst[marker + 1].vcn - dst[marker].vcn;
- /* Writing beyond the end of the file and there's a discontinuity. */
+ /* Writing beyond the end of the file and there is a discontinuity. */
if (disc) {
- if (hole)
- dst[loc - 1].length = dst[loc].vcn - dst[loc - 1].vcn;
- else {
- if (loc > 0) {
- dst[loc].vcn = dst[loc - 1].vcn +
- dst[loc - 1].length;
- dst[loc].length = dst[loc + 1].vcn -
- dst[loc].vcn;
- } else {
- dst[loc].vcn = 0;
- dst[loc].length = dst[loc + 1].vcn;
- }
- dst[loc].lcn = LCN_RL_NOT_MAPPED;
+ if (loc > 0) {
+ dst[loc].vcn = dst[loc - 1].vcn + dst[loc - 1].length;
+ dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;
+ } else {
+ dst[loc].vcn = 0;
+ dst[loc].length = dst[loc + 1].vcn;
}
-
- magic += hole;
-
- if (dst[magic].lcn == LCN_ENOENT)
- dst[magic].vcn = dst[magic - 1].vcn +
- dst[magic - 1].length;
+ dst[loc].lcn = LCN_RL_NOT_MAPPED;
}
return dst;
}
@@ -340,20 +381,23 @@ static inline runlist_element *ntfs_rl_insert(runlist_element *dst,
static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL left = FALSE;
- BOOL right;
- int magic;
+ BOOL left = FALSE; /* Left end of @src needs merging. */
+ BOOL right = FALSE; /* Right end of @src needs merging. */
+ int tail; /* Start of tail of @dst. */
+ int marker; /* End of the inserted runs. */
BUG_ON(!dst);
BUG_ON(!src);
- /* First, merge the left and right ends, if necessary. */
- right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
+ /* First, see if the left and right ends need merging. */
+ if ((loc + 1) < dsize)
+ right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
if (loc > 0)
left = ntfs_are_rl_mergeable(dst + loc - 1, src);
-
- /* Allocate some space. We'll need less if the left, right, or both
- * ends were merged. */
+ /*
+ * Allocate some space. We will need less if the left, right, or both
+ * ends get merged.
+ */
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left - right);
if (IS_ERR(dst))
return dst;
@@ -361,21 +405,37 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
* We are guaranteed to succeed from here so can start modifying the
* original runlists.
*/
+
+ /* First, merge the left and right ends, if necessary. */
if (right)
__ntfs_rl_merge(src + ssize - 1, dst + loc + 1);
if (left)
__ntfs_rl_merge(dst + loc - 1, src);
-
- /* FIXME: What does this mean? (AIA) */
- magic = loc + ssize - left;
+ /*
+ * Offset of the tail of @dst. This needs to be moved out of the way
+ * to make space for the runs to be copied from @src, i.e. the first
+ * run of the tail of @dst.
+ * Nominally, @tail equals @loc + 1, i.e. location, skipping the
+ * replaced run. However, if @right, then one of @dst's runs is
+ * already merged into @src.
+ */
+ tail = loc + right + 1;
+ /*
+ * First run after the @src runs that have been inserted, i.e. where
+ * the tail of @dst needs to be moved to.
+ * Nominally, @marker equals @loc + @ssize, i.e. location + number of
+ * runs in @src. However, if @left, then the first run in @src has
+ * been merged with one in @dst.
+ */
+ marker = loc + ssize - left;
/* Move the tail of @dst out of the way, then copy in @src. */
- ntfs_rl_mm(dst, magic, loc + right + 1, dsize - loc - right - 1);
+ ntfs_rl_mm(dst, marker, tail, dsize - tail);
ntfs_rl_mc(dst, loc, src, left, ssize - left);
- /* We may have changed the length of the file, so fix the end marker */
- if (dst[magic].lcn == LCN_ENOENT)
- dst[magic].vcn = dst[magic - 1].vcn + dst[magic - 1].length;
+ /* We may have changed the length of the file, so fix the end marker. */
+ if (dsize - tail > 0 && dst[marker].lcn == LCN_ENOENT)
+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;
return dst;
}
@@ -497,6 +557,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 +627,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 +682,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 +698,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 +712,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 +775,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 +1470,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 +1478,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 +1502,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 +1616,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 aa0ee6540e7c..47728fbb610b 100644
--- a/fs/ntfs/runlist.h
+++ b/fs/ntfs/runlist.h
@@ -94,6 +94,9 @@ extern int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
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 41aa8eb6755b..453d0d51ea4b 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -126,6 +126,14 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
if (*v) \
goto needs_val; \
}
+#define NTFS_GETOPT_OCTAL(option, variable) \
+ if (!strcmp(p, option)) { \
+ if (!v || !*v) \
+ goto needs_arg; \
+ variable = simple_strtoul(ov = v, &v, 8); \
+ if (*v) \
+ goto needs_val; \
+ }
#define NTFS_GETOPT_BOOL(option, variable) \
if (!strcmp(p, option)) { \
BOOL val; \
@@ -157,9 +165,9 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
*v++ = 0;
NTFS_GETOPT("uid", uid)
else NTFS_GETOPT("gid", gid)
- else NTFS_GETOPT("umask", fmask = dmask)
- else NTFS_GETOPT("fmask", fmask)
- else NTFS_GETOPT("dmask", dmask)
+ else NTFS_GETOPT_OCTAL("umask", fmask = dmask)
+ else NTFS_GETOPT_OCTAL("fmask", fmask)
+ else NTFS_GETOPT_OCTAL("dmask", dmask)
else NTFS_GETOPT("mft_zone_multiplier", mft_zone_multiplier)
else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE)
else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)
@@ -1133,7 +1141,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 +1154,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 +1698,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 +1851,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 +1868,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 +1882,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 19c42e231b44..0ea887fc859c 100644
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -1,7 +1,7 @@
/*
* unistr.c - NTFS Unicode string handling. 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
@@ -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 4ee2dcc31c28..8d06ec911fd9 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>
@@ -737,52 +738,16 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
return error;
}
-/*
- * Note that while the flag value (low two bits) for sys_open means:
- * 00 - read-only
- * 01 - write-only
- * 10 - read-write
- * 11 - special
- * it is changed into
- * 00 - no permissions needed
- * 01 - read-permission
- * 10 - write-permission
- * 11 - read-write
- * for the internal routines (ie open_namei()/follow_link() etc). 00 is
- * used by symlinks.
- */
-struct file *filp_open(const char * filename, int flags, int mode)
-{
- int namei_flags, error;
- struct nameidata nd;
-
- namei_flags = flags;
- if ((namei_flags+1) & O_ACCMODE)
- namei_flags++;
- if (namei_flags & O_TRUNC)
- namei_flags |= 2;
-
- error = open_namei(filename, namei_flags, mode, &nd);
- if (!error)
- return dentry_open(nd.dentry, nd.mnt, flags);
-
- return ERR_PTR(error);
-}
-
-EXPORT_SYMBOL(filp_open);
-
-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
+static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
+ int flags, struct file *f,
+ int (*open)(struct inode *, struct file *))
{
- struct file * f;
struct inode *inode;
int error;
- error = -ENFILE;
- f = get_empty_filp();
- if (!f)
- goto cleanup_dentry;
f->f_flags = flags;
- f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
+ f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK |
+ FMODE_PREAD | FMODE_PWRITE;
inode = dentry->d_inode;
if (f->f_mode & FMODE_WRITE) {
error = get_write_access(inode);
@@ -797,11 +762,14 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
f->f_op = fops_get(inode->i_fop);
file_move(f, &inode->i_sb->s_files);
- if (f->f_op && f->f_op->open) {
- error = f->f_op->open(inode,f);
+ if (!open && f->f_op)
+ open = f->f_op->open;
+ if (open) {
+ error = open(inode, f);
if (error)
goto cleanup_all;
}
+
f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
@@ -827,12 +795,110 @@ cleanup_all:
f->f_vfsmnt = NULL;
cleanup_file:
put_filp(f);
-cleanup_dentry:
dput(dentry);
mntput(mnt);
return ERR_PTR(error);
}
+/*
+ * Note that while the flag value (low two bits) for sys_open means:
+ * 00 - read-only
+ * 01 - write-only
+ * 10 - read-write
+ * 11 - special
+ * it is changed into
+ * 00 - no permissions needed
+ * 01 - read-permission
+ * 10 - write-permission
+ * 11 - read-write
+ * for the internal routines (ie open_namei()/follow_link() etc). 00 is
+ * used by symlinks.
+ */
+struct file *filp_open(const char * filename, int flags, int mode)
+{
+ int namei_flags, error;
+ struct nameidata nd;
+
+ namei_flags = flags;
+ if ((namei_flags+1) & O_ACCMODE)
+ namei_flags++;
+
+ error = open_namei(filename, namei_flags, mode, &nd);
+ if (!error)
+ return nameidata_to_filp(&nd, flags);
+
+ return ERR_PTR(error);
+}
+EXPORT_SYMBOL(filp_open);
+
+/**
+ * lookup_instantiate_filp - instantiates the open intent filp
+ * @nd: pointer to nameidata
+ * @dentry: pointer to dentry
+ * @open: open callback
+ *
+ * Helper for filesystems that want to use lookup open intents and pass back
+ * a fully instantiated struct file to the caller.
+ * This function is meant to be called from within a filesystem's
+ * lookup method.
+ * Note that in case of error, nd->intent.open.file is destroyed, but the
+ * path information remains valid.
+ * If the open callback is set to NULL, then the standard f_op->open()
+ * filesystem callback is substituted.
+ */
+struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
+ int (*open)(struct inode *, struct file *))
+{
+ if (IS_ERR(nd->intent.open.file))
+ goto out;
+ if (IS_ERR(dentry))
+ goto out_err;
+ nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
+ nd->intent.open.flags - 1,
+ nd->intent.open.file,
+ open);
+out:
+ return nd->intent.open.file;
+out_err:
+ release_open_intent(nd);
+ nd->intent.open.file = (struct file *)dentry;
+ goto out;
+}
+EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
+
+/**
+ * nameidata_to_filp - convert a nameidata to an open filp.
+ * @nd: pointer to nameidata
+ * @flags: open flags
+ *
+ * Note that this function destroys the original nameidata
+ */
+struct file *nameidata_to_filp(struct nameidata *nd, int flags)
+{
+ struct file *filp;
+
+ /* Pick up the filp from the open intent */
+ filp = nd->intent.open.file;
+ /* Has the filesystem initialised the file for us? */
+ if (filp->f_dentry == NULL)
+ filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
+ else
+ path_release(nd);
+ return filp;
+}
+
+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
+{
+ int error;
+ struct file *f;
+
+ error = -ENFILE;
+ f = get_empty_filp();
+ if (f == NULL)
+ return ERR_PTR(error);
+
+ return __dentry_open(dentry, mnt, flags, f, NULL);
+}
EXPORT_SYMBOL(dentry_open);
/*
@@ -842,14 +908,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 +940,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 +961,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 +993,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 +1080,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/partitions/check.c b/fs/partitions/check.c
index 77e178f13162..1e848648a322 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -430,7 +430,7 @@ void del_gendisk(struct gendisk *disk)
disk->flags &= ~GENHD_FL_UP;
unlink_gendisk(disk);
disk_stat_set_all(disk, 0);
- disk->stamp = disk->stamp_idle = 0;
+ disk->stamp = 0;
devfs_remove_disk(disk);
diff --git a/fs/pipe.c b/fs/pipe.c
index 2c7a23dde2d8..66aa0b938d6a 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -39,7 +39,11 @@ void pipe_wait(struct inode * inode)
{
DEFINE_WAIT(wait);
- prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE);
+ /*
+ * Pipes are system-local resources, so sleeping on them
+ * is considered a noninteractive wait:
+ */
+ prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
up(PIPE_SEM(*inode));
schedule();
finish_wait(PIPE_WAIT(*inode), &wait);
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 296480e96dd5..6c8dcf7613fd 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(posix_acl_permission);
* Allocate a new ACL with the specified number of entries.
*/
struct posix_acl *
-posix_acl_alloc(int count, unsigned int __nocast flags)
+posix_acl_alloc(int count, gfp_t flags)
{
const size_t size = sizeof(struct posix_acl) +
count * sizeof(struct posix_acl_entry);
@@ -51,7 +51,7 @@ posix_acl_alloc(int count, unsigned int __nocast flags)
* Clone an ACL.
*/
struct posix_acl *
-posix_acl_clone(const struct posix_acl *acl, unsigned int __nocast flags)
+posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
{
struct posix_acl *clone = NULL;
@@ -185,7 +185,7 @@ posix_acl_equiv_mode(const struct posix_acl *acl, mode_t *mode_p)
* Create an ACL representing the file mode permission bits of an inode.
*/
struct posix_acl *
-posix_acl_from_mode(mode_t mode, unsigned int __nocast flags)
+posix_acl_from_mode(mode_t mode, gfp_t flags)
{
struct posix_acl *acl = posix_acl_alloc(3, flags);
if (!acl)
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 37668fe998ad..d84eecacbeaf 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -74,6 +74,7 @@
#include <linux/file.h>
#include <linux/times.h>
#include <linux/cpuset.h>
+#include <linux/rcupdate.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -159,6 +160,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 +181,14 @@ 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);
+ rcu_read_lock();
+ 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);
+ rcu_read_unlock();
group_info = p->group_info;
get_group_info(group_info);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 84751f3f52d5..a170450aadb1 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>
@@ -102,7 +103,9 @@ enum pid_directory_inos {
PROC_TGID_NUMA_MAPS,
PROC_TGID_MOUNTS,
PROC_TGID_WCHAN,
+#ifdef CONFIG_MMU
PROC_TGID_SMAPS,
+#endif
#ifdef CONFIG_SCHEDSTATS
PROC_TGID_SCHEDSTAT,
#endif
@@ -140,7 +143,9 @@ enum pid_directory_inos {
PROC_TID_NUMA_MAPS,
PROC_TID_MOUNTS,
PROC_TID_WCHAN,
+#ifdef CONFIG_MMU
PROC_TID_SMAPS,
+#endif
#ifdef CONFIG_SCHEDSTATS
PROC_TID_SCHEDSTAT,
#endif
@@ -194,7 +199,9 @@ static struct pid_entry tgid_base_stuff[] = {
E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+#ifdef CONFIG_MMU
E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
+#endif
#ifdef CONFIG_SECURITY
E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif
@@ -234,7 +241,9 @@ static struct pid_entry tid_base_stuff[] = {
E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+#ifdef CONFIG_MMU
E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO),
+#endif
#ifdef CONFIG_SECURITY
E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif
@@ -283,16 +292,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;
@@ -339,6 +348,54 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
return result;
}
+
+/* Same as proc_root_link, but this addionally tries to get fs from other
+ * threads in the group */
+static int proc_task_root_link(struct inode *inode, struct dentry **dentry,
+ struct vfsmount **mnt)
+{
+ struct fs_struct *fs;
+ int result = -ENOENT;
+ struct task_struct *leader = proc_task(inode);
+
+ task_lock(leader);
+ fs = leader->fs;
+ if (fs) {
+ atomic_inc(&fs->count);
+ task_unlock(leader);
+ } else {
+ /* Try to get fs from other threads */
+ task_unlock(leader);
+ read_lock(&tasklist_lock);
+ if (pid_alive(leader)) {
+ struct task_struct *task = leader;
+
+ while ((task = next_thread(task)) != leader) {
+ task_lock(task);
+ fs = task->fs;
+ if (fs) {
+ atomic_inc(&fs->count);
+ task_unlock(task);
+ break;
+ }
+ task_unlock(task);
+ }
+ }
+ read_unlock(&tasklist_lock);
+ }
+
+ if (fs) {
+ read_lock(&fs->lock);
+ *mnt = mntget(fs->rootmnt);
+ *dentry = dget(fs->root);
+ read_unlock(&fs->lock);
+ result = 0;
+ put_fs_struct(fs);
+ }
+ return result;
+}
+
+
#define MAY_PTRACE(task) \
(task == current || \
(task->parent == current && \
@@ -470,14 +527,14 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
/* permission checks */
-static int proc_check_root(struct inode *inode)
+/* If the process being read is separated by chroot from the reading process,
+ * don't let the reader access the threads.
+ */
+static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
{
- struct dentry *de, *base, *root;
- struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
+ struct dentry *de, *base;
+ struct vfsmount *our_vfsmnt, *mnt;
int res = 0;
-
- if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
- return -ENOENT;
read_lock(&current->fs->lock);
our_vfsmnt = mntget(current->fs->rootmnt);
base = dget(current->fs->root);
@@ -510,6 +567,16 @@ out:
goto exit;
}
+static int proc_check_root(struct inode *inode)
+{
+ struct dentry *root;
+ struct vfsmount *vfsmnt;
+
+ if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
+ return -ENOENT;
+ return proc_check_chroot(root, vfsmnt);
+}
+
static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
{
if (generic_permission(inode, mask, NULL) != 0)
@@ -517,6 +584,20 @@ static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
return proc_check_root(inode);
}
+static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+ struct dentry *root;
+ struct vfsmount *vfsmnt;
+
+ if (generic_permission(inode, mask, NULL) != 0)
+ return -EACCES;
+
+ if (proc_task_root_link(inode, &root, &vfsmnt))
+ return -ENOENT;
+
+ return proc_check_chroot(root, vfsmnt);
+}
+
extern struct seq_operations proc_pid_maps_op;
static int maps_open(struct inode *inode, struct file *file)
{
@@ -557,6 +638,7 @@ static struct file_operations proc_numa_maps_operations = {
};
#endif
+#ifdef CONFIG_MMU
extern struct seq_operations proc_pid_smaps_op;
static int smaps_open(struct inode *inode, struct file *file)
{
@@ -575,6 +657,7 @@ static struct file_operations proc_smaps_operations = {
.llseek = seq_lseek,
.release = seq_release,
};
+#endif
extern struct seq_operations mounts_op;
static int mounts_open(struct inode *inode, struct file *file)
@@ -1039,6 +1122,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 +1145,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 +1166,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 +1346,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 +1360,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 +1452,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 +1460,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 +1470,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);
@@ -1416,7 +1501,7 @@ static struct inode_operations proc_fd_inode_operations = {
static struct inode_operations proc_task_inode_operations = {
.lookup = proc_task_lookup,
- .permission = proc_permission,
+ .permission = proc_task_permission,
};
#ifdef CONFIG_SECURITY
@@ -1606,10 +1691,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
case PROC_TGID_MOUNTS:
inode->i_fop = &proc_mounts_operations;
break;
+#ifdef CONFIG_MMU
case PROC_TID_SMAPS:
case PROC_TGID_SMAPS:
inode->i_fop = &proc_smaps_operations;
break;
+#endif
#ifdef CONFIG_SECURITY
case PROC_TID_ATTR:
inode->i_nlink = 2;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 133c28685105..effa6c0c467a 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -60,6 +60,8 @@ static void proc_delete_inode(struct inode *inode)
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/proc/nommu.c b/fs/proc/nommu.c
index f3bf016d5ee3..cff10ab1af63 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -91,6 +91,7 @@ static void *nommu_vma_list_start(struct seq_file *m, loff_t *_pos)
next = _rb;
break;
}
+ pos--;
}
return next;
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index b79162a35478..80f32911c0cb 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -63,6 +63,7 @@ int qnx4_sync_inode(struct inode *inode)
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/read_write.c b/fs/read_write.c
index b60324aaa2b6..a091ee4f430d 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -499,6 +499,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
ret = rw_verify_area(type, file, pos, tot_len);
if (ret)
goto out;
+ ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE);
+ if (ret)
+ goto out;
fnv = NULL;
if (type == READ) {
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c9f178fb494f..c20babd6216d 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -667,7 +667,7 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
if (th->t_trans_id) {
int err;
// update any changes we made to blk count
- reiserfs_update_sd(th, inode);
+ mark_inode_dirty(inode);
err =
journal_end(th, inode->i_sb,
JOURNAL_PER_BALANCE_CNT * 3 + 1 +
@@ -855,17 +855,18 @@ static int reiserfs_submit_file_region_for_write(struct reiserfs_transaction_han
if (th->t_trans_id) {
reiserfs_write_lock(inode->i_sb);
- reiserfs_update_sd(th, inode); // And update on-disk metadata
+ // this sets the proper flags for O_SYNC to trigger a commit
+ mark_inode_dirty(inode);
reiserfs_write_unlock(inode->i_sb);
} else
- inode->i_sb->s_op->dirty_inode(inode);
+ mark_inode_dirty(inode);
sd_update = 1;
}
if (th->t_trans_id) {
reiserfs_write_lock(inode->i_sb);
if (!sd_update)
- reiserfs_update_sd(th, inode);
+ mark_inode_dirty(inode);
status = journal_end(th, th->t_super, th->t_blocks_allocated);
if (status)
retval = status;
@@ -1320,7 +1321,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
return err;
}
reiserfs_update_inode_transaction(inode);
- reiserfs_update_sd(&th, inode);
+ mark_inode_dirty(inode);
err = journal_end(&th, inode->i_sb, 1);
if (err) {
reiserfs_write_unlock(inode->i_sb);
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 2706e2adffab..45829889dcdc 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -2022,7 +2022,7 @@ static int get_neighbors(struct tree_balance *p_s_tb, int n_h)
}
#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s)
+void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s)
{
void *vp;
static size_t malloced;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ff291c973a56..5f82352b97e1 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.. */
@@ -2637,6 +2639,12 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
}
reiserfs_update_inode_transaction(inode);
inode->i_size = pos;
+ /*
+ * this will just nest into our transaction. It's important
+ * to use mark_inode_dirty so the inode gets pushed around on the
+ * dirty lists, and so that O_SYNC works as expected
+ */
+ mark_inode_dirty(inode);
reiserfs_update_sd(&myth, inode);
update_sd = 1;
ret = journal_end(&myth, inode->i_sb, 1);
@@ -2647,21 +2655,13 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
if (th) {
reiserfs_write_lock(inode->i_sb);
if (!update_sd)
- reiserfs_update_sd(th, inode);
+ mark_inode_dirty(inode);
ret = reiserfs_end_persistent_transaction(th);
reiserfs_write_unlock(inode->i_sb);
if (ret)
goto out;
}
- /* we test for O_SYNC here so we can commit the transaction
- ** for any packed tails the file might have had
- */
- if (f && (f->f_flags & O_SYNC)) {
- reiserfs_write_lock(inode->i_sb);
- ret = reiserfs_commit_for_inode(inode);
- reiserfs_write_unlock(inode->i_sb);
- }
out:
return ret;
@@ -2842,7 +2842,7 @@ static int reiserfs_set_page_dirty(struct page *page)
* even in -o notail mode, we can't be sure an old mount without -o notail
* didn't create files with tails.
*/
-static int reiserfs_releasepage(struct page *page, int unused_gfp_flags)
+static int reiserfs_releasepage(struct page *page, gfp_t unused_gfp_flags)
{
struct inode *inode = page->mapping->host;
struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index a8e29e9bbbd0..4b15761434bc 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2868,8 +2868,7 @@ static void let_transaction_grow(struct super_block *sb, unsigned long trans_id)
struct reiserfs_journal *journal = SB_JOURNAL(sb);
unsigned long bcount = journal->j_bcount;
while (1) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
journal->j_current_jl->j_state |= LIST_COMMIT_PENDING;
while ((atomic_read(&journal->j_wcount) > 0 ||
atomic_read(&journal->j_jlock)) &&
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 6951c35755be..44b02fc02ebe 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1934,8 +1934,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
if (SB_AP_BITMAP(s))
brelse(SB_AP_BITMAP(s)[j].bh);
}
- if (SB_AP_BITMAP(s))
- vfree(SB_AP_BITMAP(s));
+ vfree(SB_AP_BITMAP(s));
}
if (SB_BUFFER_WITH_SB(s))
brelse(SB_BUFFER_WITH_SB(s));
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 87ac9dc8b381..72e120798677 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -453,7 +453,7 @@ static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
struct page *page;
/* We can deadlock if we try to free dentries,
and an unlink/rmdir has just occured - GFP_NOFS avoids this */
- mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS;
+ mapping_set_gfp_mask(mapping, GFP_NOFS);
page = read_cache_page(mapping, n,
(filler_t *) mapping->a_ops->readpage, NULL);
if (!IS_ERR(page)) {
diff --git a/fs/relayfs/buffers.c b/fs/relayfs/buffers.c
index 2aa8e2719999..84e21ffa5ca8 100644
--- a/fs/relayfs/buffers.c
+++ b/fs/relayfs/buffers.c
@@ -109,7 +109,7 @@ static void *relay_alloc_buf(struct rchan_buf *buf, unsigned long size)
if (unlikely(!buf->page_array[i]))
goto depopulate;
}
- mem = vmap(buf->page_array, n_pages, GFP_KERNEL, PAGE_KERNEL);
+ mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL);
if (!mem)
goto depopulate;
diff --git a/fs/select.c b/fs/select.c
index b80e7eb0ac0d..f10a10317d54 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -22,6 +22,7 @@
#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 4765aaac9fd2..10b994428fef 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/smbfs/proc.c b/fs/smbfs/proc.c
index 220babe91efd..38ab558835c4 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -2397,8 +2397,7 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
if (req->rq_rcls == ERRSRV && req->rq_err == ERRerror) {
/* a damn Win95 bug - sometimes it clags if you
ask it too fast */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/5);
+ schedule_timeout_interruptible(msecs_to_jiffies(200));
continue;
}
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 0530077d9dd8..fa33eceb0011 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -292,6 +292,7 @@ int sysv_sync_inode(struct inode * inode)
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 3d68de39fad6..b83890beaaac 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -87,6 +87,8 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
*/
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 718627ca8b5c..55f4aa16e3fc 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/Kconfig b/fs/xfs/Kconfig
index c92306f0fdc5..8e8f32dabe53 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -1,5 +1,3 @@
-menu "XFS support"
-
config XFS_FS
tristate "XFS filesystem support"
select EXPORTFS if NFSD!=n
@@ -22,27 +20,11 @@ config XFS_FS
config XFS_EXPORT
bool
- default y if XFS_FS && EXPORTFS
-
-config XFS_RT
- bool "Realtime support (EXPERIMENTAL)"
- depends on XFS_FS && EXPERIMENTAL
- help
- If you say Y here you will be able to mount and use XFS filesystems
- which contain a realtime subvolume. The realtime subvolume is a
- separate area of disk space where only file data is stored. The
- realtime subvolume is designed to provide very deterministic
- data rates suitable for media streaming applications.
-
- See the xfs man page in section 5 for a bit more information.
-
- This feature is unsupported at this time, is not yet fully
- functional, and may cause serious problems.
-
- If unsure, say N.
+ depends on XFS_FS && EXPORTFS
+ default y
config XFS_QUOTA
- bool "Quota support"
+ tristate "XFS Quota support"
depends on XFS_FS
help
If you say Y here, you will be able to set limits for disk usage on
@@ -59,7 +41,7 @@ config XFS_QUOTA
they are completely independent subsystems.
config XFS_SECURITY
- bool "Security Label support"
+ bool "XFS Security Label support"
depends on XFS_FS
help
Security labels support alternative access control models
@@ -71,7 +53,7 @@ config XFS_SECURITY
extended attributes for inode security labels, say N.
config XFS_POSIX_ACL
- bool "POSIX ACL support"
+ bool "XFS POSIX ACL support"
depends on XFS_FS
help
POSIX Access Control Lists (ACLs) support permissions for users and
@@ -82,4 +64,19 @@ config XFS_POSIX_ACL
If you don't know what Access Control Lists are, say N.
-endmenu
+config XFS_RT
+ bool "XFS Realtime support (EXPERIMENTAL)"
+ depends on XFS_FS && EXPERIMENTAL
+ help
+ If you say Y here you will be able to mount and use XFS filesystems
+ which contain a realtime subvolume. The realtime subvolume is a
+ separate area of disk space where only file data is stored. The
+ realtime subvolume is designed to provide very deterministic
+ data rates suitable for media streaming applications.
+
+ See the xfs man page in section 5 for a bit more information.
+
+ This feature is unsupported at this time, is not yet fully
+ functional, and may cause serious problems.
+
+ If unsure, say N.
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index fbfcbe5a7cda..d8c87fa21ad1 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
-obj-$(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/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
index 4b184559f231..3c92162dc728 100644
--- a/fs/xfs/linux-2.6/kmem.c
+++ b/fs/xfs/linux-2.6/kmem.c
@@ -47,9 +47,9 @@
void *
kmem_alloc(size_t size, unsigned int __nocast flags)
{
- int retries = 0;
- unsigned int lflags = kmem_flags_convert(flags);
- void *ptr;
+ int retries = 0;
+ gfp_t lflags = kmem_flags_convert(flags);
+ void *ptr;
do {
if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
@@ -107,9 +107,9 @@ kmem_realloc(void *ptr, size_t newsize, size_t oldsize,
void *
kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags)
{
- int retries = 0;
- unsigned int lflags = kmem_flags_convert(flags);
- void *ptr;
+ int retries = 0;
+ gfp_t lflags = kmem_flags_convert(flags);
+ void *ptr;
do {
ptr = kmem_cache_alloc(zone, lflags);
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 109fcf27e256..f4bb78c268c0 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -81,9 +81,9 @@ typedef unsigned long xfs_pflags_t;
*(NSTATEP) = *(OSTATEP); \
} while (0)
-static __inline unsigned int kmem_flags_convert(unsigned int __nocast flags)
+static __inline gfp_t kmem_flags_convert(unsigned int __nocast flags)
{
- unsigned int lflags = __GFP_NOWARN; /* we'll report problems, if need be */
+ gfp_t lflags = __GFP_NOWARN; /* we'll report problems, if need be */
#ifdef DEBUG
if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) {
@@ -129,13 +129,12 @@ extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
extern void *kmem_alloc(size_t, unsigned int __nocast);
-extern void *kmem_realloc(void *, size_t, size_t,
- unsigned int __nocast);
+extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
extern void *kmem_zalloc(size_t, unsigned int __nocast);
extern void kmem_free(void *, size_t);
typedef struct shrinker *kmem_shaker_t;
-typedef int (*kmem_shake_func_t)(int, unsigned int);
+typedef int (*kmem_shake_func_t)(int, gfp_t);
static __inline kmem_shaker_t
kmem_shake_register(kmem_shake_func_t sfunc)
@@ -150,7 +149,7 @@ kmem_shake_deregister(kmem_shaker_t shrinker)
}
static __inline int
-kmem_shake_allow(unsigned int gfp_mask)
+kmem_shake_allow(gfp_t gfp_mask)
{
return (gfp_mask & __GFP_WAIT);
}
diff --git a/fs/xfs/linux-2.6/time.h b/fs/xfs/linux-2.6/time.h
index 6c6fd0faa8e1..b0d2873ab274 100644
--- a/fs/xfs/linux-2.6/time.h
+++ b/fs/xfs/linux-2.6/time.h
@@ -39,8 +39,7 @@ typedef struct timespec timespec_t;
static inline void delay(long ticks)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(ticks);
+ schedule_timeout_uninterruptible(ticks);
}
static inline void nanotime(struct timespec *tvp)
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index c6c077978fe3..7aa398724706 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1296,7 +1296,7 @@ linvfs_invalidate_page(
STATIC int
linvfs_release_page(
struct page *page,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct inode *inode = page->mapping->host;
int dirty, delalloc, unmapped, unwritten;
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 655bf4a78afe..ba4767c04adf 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -64,7 +64,7 @@
STATIC kmem_cache_t *pagebuf_zone;
STATIC kmem_shaker_t pagebuf_shake;
-STATIC int xfsbufd_wakeup(int, unsigned int);
+STATIC int xfsbufd_wakeup(int, gfp_t);
STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
STATIC struct workqueue_struct *xfslogd_workqueue;
@@ -383,7 +383,7 @@ _pagebuf_lookup_pages(
size_t blocksize = bp->pb_target->pbr_bsize;
size_t size = bp->pb_count_desired;
size_t nbytes, offset;
- int gfp_mask = pb_to_gfp(flags);
+ gfp_t gfp_mask = pb_to_gfp(flags);
unsigned short page_count, i;
pgoff_t first;
loff_t end;
@@ -1749,8 +1749,8 @@ STATIC int xfsbufd_force_sleep;
STATIC int
xfsbufd_wakeup(
- int priority,
- unsigned int mask)
+ int priority,
+ gfp_t mask)
{
if (xfsbufd_force_sleep)
return 0;
@@ -1780,10 +1780,10 @@ xfsbufd(
xfsbufd_force_sleep = 0;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100);
+ schedule_timeout_interruptible
+ (xfs_buf_timer_centisecs * msecs_to_jiffies(10));
- age = (xfs_buf_age_centisecs * HZ) / 100;
+ age = xfs_buf_age_centisecs * msecs_to_jiffies(10);
spin_lock(&pbd_delwrite_lock);
list_for_each_entry_safe(pb, n, &pbd_delwrite_queue, pb_list) {
PB_TRACE(pb, "walkq1", (long)pagebuf_ispin(pb));
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 0da87bfc9999..2302454d8d47 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -467,7 +467,7 @@ xfs_flush_inode(
igrab(inode);
xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
- delay(HZ/2);
+ delay(msecs_to_jiffies(500));
}
/*
@@ -492,7 +492,7 @@ xfs_flush_device(
igrab(inode);
xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
- delay(HZ/2);
+ delay(msecs_to_jiffies(500));
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
}
@@ -520,10 +520,9 @@ xfssyncd(
struct vfs_sync_work *work, *n;
LIST_HEAD (tmp);
- timeleft = (xfs_syncd_centisecs * HZ) / 100;
+ timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- timeleft = schedule_timeout(timeleft);
+ timeleft = schedule_timeout_interruptible(timeleft);
/* swsusp */
try_to_freeze();
if (kthread_should_stop())
@@ -537,7 +536,8 @@ xfssyncd(
*/
if (!timeleft || list_empty(&vfsp->vfs_sync_list)) {
if (!timeleft)
- timeleft = (xfs_syncd_centisecs * HZ) / 100;
+ timeleft = xfs_syncd_centisecs *
+ msecs_to_jiffies(10);
INIT_LIST_HEAD(&vfsp->vfs_sync_work.w_list);
list_add_tail(&vfsp->vfs_sync_work.w_list,
&vfsp->vfs_sync_list);
diff --git a/fs/xfs/quota/Makefile-linux-2.6 b/fs/xfs/quota/Makefile-linux-2.6
index 8b7b676718b9..93e60e839355 100644
--- a/fs/xfs/quota/Makefile-linux-2.6
+++ b/fs/xfs/quota/Makefile-linux-2.6
@@ -41,13 +41,13 @@ ifeq ($(CONFIG_XFS_TRACE),y)
EXTRA_CFLAGS += -DXFS_VNODE_TRACE
endif
-obj-$(CONFIG_XFS_QUOTA) += xfs_quota.o
-
-xfs_quota-y += xfs_dquot.o \
+xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
xfs_dquot_item.o \
xfs_trans_dquot.o \
xfs_qm_syscalls.o \
xfs_qm_bhv.o \
xfs_qm.o
-xfs_quota-$(CONFIG_PROC_FS) += xfs_qm_stats.o
+ifeq ($(CONFIG_XFS_QUOTA),y)
+xfs-$(CONFIG_PROC_FS) += xfs_qm_stats.o
+endif
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c
index 3dae14c8c55a..fa8394f9437d 100644
--- a/fs/xfs/support/ktrace.c
+++ b/fs/xfs/support/ktrace.c
@@ -170,7 +170,7 @@ ktrace_enter(
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/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h
index ae35189b3d70..5ab0dd885b1b 100644
--- a/fs/xfs/xfs_arch.h
+++ b/fs/xfs/xfs_arch.h
@@ -40,22 +40,28 @@
#include <asm/byteorder.h>
-#ifdef __LITTLE_ENDIAN
-# define __BYTE_ORDER __LITTLE_ENDIAN
-#endif
#ifdef __BIG_ENDIAN
-# define __BYTE_ORDER __BIG_ENDIAN
+#define XFS_NATIVE_HOST 1
+#else
+#undef XFS_NATIVE_HOST
+#endif
+
+#else /* __KERNEL__ */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define XFS_NATIVE_HOST 1
+#else
+#undef XFS_NATIVE_HOST
#endif
#endif /* __KERNEL__ */
/* do we need conversion? */
-
#define ARCH_NOCONVERT 1
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define ARCH_CONVERT 0
-#else
+#ifdef XFS_NATIVE_HOST
# define ARCH_CONVERT ARCH_NOCONVERT
+#else
+# define ARCH_CONVERT 0
#endif
/* generic swapping macros */
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 09c413576ba8..09a77b17565b 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -2017,7 +2017,7 @@ xfs_bmbt_get_state(
ext_flag);
}
-#if __BYTE_ORDER != __BIG_ENDIAN
+#ifndef XFS_NATIVE_HOST
/* Endian flipping versions of the bmbt extraction functions */
void
xfs_bmbt_disk_get_all(
@@ -2087,7 +2087,7 @@ xfs_bmbt_disk_get_state(
return xfs_extent_state(xfs_bmbt_disk_get_blockcount(r),
ext_flag);
}
-#endif
+#endif /* XFS_NATIVE_HOST */
/*
@@ -2531,7 +2531,7 @@ xfs_bmbt_set_allf(
#endif /* XFS_BIG_BLKNOS */
}
-#if __BYTE_ORDER != __BIG_ENDIAN
+#ifndef XFS_NATIVE_HOST
/*
* Set all the fields in a bmap extent record from the uncompressed form.
*/
@@ -2617,7 +2617,7 @@ xfs_bmbt_disk_set_allf(
}
#endif /* XFS_BIG_BLKNOS */
}
-#endif
+#endif /* XFS_NATIVE_HOST */
/*
* Set the blockcount field in a bmap extent record.
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 0a40cf126c28..2cf4fe45cbcb 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -62,7 +62,7 @@ typedef struct xfs_bmdr_block
* l1:0-20 are blockcount.
*/
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#ifndef XFS_NATIVE_HOST
#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
#define BMBT_EXNTFLAG_BITOFF 0
@@ -87,7 +87,7 @@ typedef struct xfs_bmdr_block
#define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */
#define BMBT_BLOCKCOUNT_BITLEN 21
-#endif
+#endif /* XFS_NATIVE_HOST */
#define BMBT_USE_64 1
@@ -505,7 +505,7 @@ xfs_exntst_t
xfs_bmbt_get_state(
xfs_bmbt_rec_t *r);
-#if __BYTE_ORDER != __BIG_ENDIAN
+#ifndef XFS_NATIVE_HOST
void
xfs_bmbt_disk_get_all(
xfs_bmbt_rec_t *r,
@@ -538,7 +538,7 @@ xfs_bmbt_disk_get_startoff(
xfs_bmbt_get_blockcount(r)
#define xfs_bmbt_disk_get_startoff(r) \
xfs_bmbt_get_startoff(r)
-#endif
+#endif /* XFS_NATIVE_HOST */
int
xfs_bmbt_increment(
@@ -623,7 +623,7 @@ xfs_bmbt_set_state(
xfs_bmbt_rec_t *r,
xfs_exntst_t v);
-#if __BYTE_ORDER != __BIG_ENDIAN
+#ifndef XFS_NATIVE_HOST
void
xfs_bmbt_disk_set_all(
xfs_bmbt_rec_t *r,
@@ -641,7 +641,7 @@ xfs_bmbt_disk_set_allf(
xfs_bmbt_set_all(r, s)
#define xfs_bmbt_disk_set_allf(r, o, b, c, v) \
xfs_bmbt_set_allf(r, o, b, c, v)
-#endif
+#endif /* XFS_NATIVE_HOST */
void
xfs_bmbt_to_bmdr(
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
index dd423ce1bc8d..480bffc1f29f 100644
--- a/fs/xfs/xfs_dir_leaf.h
+++ b/fs/xfs/xfs_dir_leaf.h
@@ -127,13 +127,13 @@ typedef union {
* Watch the order here (endian-ness dependent).
*/
struct {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#ifndef XFS_NATIVE_HOST
xfs_dahash_t h; /* hash value */
__uint32_t be; /* block and entry */
-#else /* __BYTE_ORDER == __BIG_ENDIAN */
+#else
__uint32_t be; /* block and entry */
xfs_dahash_t h; /* hash value */
-#endif /* __BYTE_ORDER == __BIG_ENDIAN */
+#endif /* XFS_NATIVE_HOST */
} s;
} xfs_dircook_t;
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 276ec70eb7f9..50e2cadf9091 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -341,7 +341,7 @@ xfs_inode_item_format(
nrecs = ip->i_df.if_bytes /
(uint)sizeof(xfs_bmbt_rec_t);
ASSERT(nrecs > 0);
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef XFS_NATIVE_HOST
if (nrecs == ip->i_d.di_nextents) {
/*
* There are no delayed allocation
@@ -473,7 +473,7 @@ xfs_inode_item_format(
#endif
ASSERT(nrecs > 0);
ASSERT(nrecs == ip->i_d.di_anextents);
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef XFS_NATIVE_HOST
/*
* There are not delayed allocation extents
* for attributes, so just point at the array.
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index eb7fdc6ebc32..a884cea82fca 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -112,7 +112,7 @@ struct xfs_mount;
* this has endian issues, of course.
*/
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#ifndef XFS_NATIVE_HOST
#define GET_CLIENT_ID(i,arch) \
((i) & 0xff)
#else
@@ -414,14 +414,10 @@ typedef struct xlog_op_header {
#define XLOG_FMT_IRIX_BE 3
/* our fmt */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define XLOG_FMT XLOG_FMT_LINUX_LE
-#else
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef XFS_NATIVE_HOST
#define XLOG_FMT XLOG_FMT_LINUX_BE
#else
-#error unknown byte order
-#endif
+#define XLOG_FMT XLOG_FMT_LINUX_LE
#endif
typedef struct xlog_rec_header {
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 2f6ab189fc6f..427cff1a3f83 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -44,7 +44,6 @@
#ifndef _ACCONFIG_H
#define _ACCONFIG_H
-
/******************************************************************************
*
* Configuration options
@@ -64,7 +63,7 @@
/* Version string */
-#define ACPI_CA_VERSION 0x20050408
+#define ACPI_CA_VERSION 0x20050902
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
@@ -78,11 +77,10 @@
/* Maximum objects in the various object caches */
-#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects */
-#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
-#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */
-#define ACPI_MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */
-#define ACPI_MAX_WALK_CACHE_DEPTH 4 /* Objects for parse tree walks */
+#define ACPI_MAX_STATE_CACHE_DEPTH 96 /* State objects */
+#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
+#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 96 /* Parse tree objects */
+#define ACPI_MAX_OBJECT_CACHE_DEPTH 96 /* Interpreter operand objects */
/*
* Should the subystem abort the loading of an ACPI table if the
@@ -90,7 +88,6 @@
*/
#define ACPI_CHECKSUM_ABORT FALSE
-
/******************************************************************************
*
* Subsystem Constants
@@ -104,7 +101,7 @@
/* String size constants */
#define ACPI_MAX_STRING_LENGTH 512
-#define ACPI_PATHNAME_MAX 256 /* A full namespace pathname */
+#define ACPI_PATHNAME_MAX 256 /* A full namespace pathname */
/* Maximum count for a semaphore object */
@@ -118,7 +115,6 @@
#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096
-
/******************************************************************************
*
* ACPI Specification constants (Do not change unless the specification changes)
@@ -156,15 +152,15 @@
/* Names within the namespace are 4 bytes long */
#define ACPI_NAME_SIZE 4
-#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
+#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
#define ACPI_PATH_SEPARATOR '.'
/* Constants used in searching for the RSDP in low memory */
-#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */
+#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */
#define ACPI_EBDA_PTR_LENGTH 2
#define ACPI_EBDA_WINDOW_SIZE 1024
-#define ACPI_HI_RSDP_WINDOW_BASE 0x000E0000 /* Physical Address */
+#define ACPI_HI_RSDP_WINDOW_BASE 0x000E0000 /* Physical Address */
#define ACPI_HI_RSDP_WINDOW_SIZE 0x00020000
#define ACPI_RSDP_SCAN_STEP 16
@@ -199,18 +195,15 @@
#define ACPI_NUM_OSI_STRINGS 10
-
/******************************************************************************
*
* ACPI AML Debugger
*
*****************************************************************************/
-#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */
+#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */
#define ACPI_DEBUGGER_COMMAND_PROMPT '-'
#define ACPI_DEBUGGER_EXECUTE_PROMPT '%'
-
-#endif /* _ACCONFIG_H */
-
+#endif /* _ACCONFIG_H */
diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h
index 8ba372b0f245..70ce3b4d006e 100644
--- a/include/acpi/acdebug.h
+++ b/include/acpi/acdebug.h
@@ -44,22 +44,17 @@
#ifndef __ACDEBUG_H__
#define __ACDEBUG_H__
-
#define ACPI_DEBUG_BUFFER_SIZE 4196
-struct command_info
-{
- char *name; /* Command Name */
- u8 min_args; /* Minimum arguments required */
+struct command_info {
+ char *name; /* Command Name */
+ u8 min_args; /* Minimum arguments required */
};
-
-struct argument_info
-{
- char *name; /* Argument Name */
+struct argument_info {
+ char *name; /* Argument Name */
};
-
#define PARAM_LIST(pl) pl
#define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose)
#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\
@@ -68,275 +63,155 @@ struct argument_info
#define EX_NO_SINGLE_STEP 1
#define EX_SINGLE_STEP 2
-
/*
* dbxface - external debugger interfaces
*/
-acpi_status
-acpi_db_initialize (
- void);
+acpi_status acpi_db_initialize(void);
-void
-acpi_db_terminate (
- void);
+void acpi_db_terminate(void);
acpi_status
-acpi_db_single_step (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u32 op_type);
-
+acpi_db_single_step(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op, u32 op_type);
/*
* dbcmds - debug commands and output routines
*/
-acpi_status
-acpi_db_disassemble_method (
- char *name);
+acpi_status acpi_db_disassemble_method(char *name);
-void
-acpi_db_display_table_info (
- char *table_arg);
+void acpi_db_display_table_info(char *table_arg);
-void
-acpi_db_unload_acpi_table (
- char *table_arg,
- char *instance_arg);
+void acpi_db_unload_acpi_table(char *table_arg, char *instance_arg);
void
-acpi_db_set_method_breakpoint (
- char *location,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
+acpi_db_set_method_breakpoint(char *location,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
-void
-acpi_db_set_method_call_breakpoint (
- union acpi_parse_object *op);
+void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op);
-void
-acpi_db_disassemble_aml (
- char *statements,
- union acpi_parse_object *op);
+void acpi_db_get_bus_info(void);
-void
-acpi_db_dump_namespace (
- char *start_arg,
- char *depth_arg);
+void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op);
-void
-acpi_db_dump_namespace_by_owner (
- char *owner_arg,
- char *depth_arg);
+void acpi_db_dump_namespace(char *start_arg, char *depth_arg);
-void
-acpi_db_send_notify (
- char *name,
- u32 value);
+void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg);
-void
-acpi_db_set_method_data (
- char *type_arg,
- char *index_arg,
- char *value_arg);
+void acpi_db_send_notify(char *name, u32 value);
-acpi_status
-acpi_db_display_objects (
- char *obj_type_arg,
- char *display_count_arg);
+void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg);
acpi_status
-acpi_db_find_name_in_namespace (
- char *name_arg);
+acpi_db_display_objects(char *obj_type_arg, char *display_count_arg);
-void
-acpi_db_set_scope (
- char *name);
+acpi_status acpi_db_find_name_in_namespace(char *name_arg);
-acpi_status
-acpi_db_sleep (
- char *object_arg);
+void acpi_db_set_scope(char *name);
-void
-acpi_db_find_references (
- char *object_arg);
+acpi_status acpi_db_sleep(char *object_arg);
-void
-acpi_db_display_locks (
- void);
+void acpi_db_find_references(char *object_arg);
-void
-acpi_db_display_resources (
- char *object_arg);
+void acpi_db_display_locks(void);
-void
-acpi_db_display_gpes (
- void);
+void acpi_db_display_resources(char *object_arg);
-void
-acpi_db_check_integrity (
- void);
+void acpi_db_display_gpes(void);
-void
-acpi_db_generate_gpe (
- char *gpe_arg,
- char *block_arg);
+void acpi_db_check_integrity(void);
+void acpi_db_generate_gpe(char *gpe_arg, char *block_arg);
/*
* dbdisply - debug display commands
*/
-void
-acpi_db_display_method_info (
- union acpi_parse_object *op);
+void acpi_db_display_method_info(union acpi_parse_object *op);
-void
-acpi_db_decode_and_display_object (
- char *target,
- char *output_type);
+void acpi_db_decode_and_display_object(char *target, char *output_type);
void
-acpi_db_display_result_object (
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state);
+acpi_db_display_result_object(union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state);
-acpi_status
-acpi_db_display_all_methods (
- char *display_count_arg);
+acpi_status acpi_db_display_all_methods(char *display_count_arg);
-void
-acpi_db_display_arguments (
- void);
+void acpi_db_display_arguments(void);
-void
-acpi_db_display_locals (
- void);
+void acpi_db_display_locals(void);
-void
-acpi_db_display_results (
- void);
+void acpi_db_display_results(void);
-void
-acpi_db_display_calling_tree (
- void);
+void acpi_db_display_calling_tree(void);
-void
-acpi_db_display_object_type (
- char *object_arg);
+void acpi_db_display_object_type(char *object_arg);
void
-acpi_db_display_argument_object (
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state);
-
+acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state);
/*
* dbexec - debugger control method execution
*/
-void
-acpi_db_execute (
- char *name,
- char **args,
- u32 flags);
+void acpi_db_execute(char *name, char **args, u32 flags);
void
-acpi_db_create_execution_threads (
- char *num_threads_arg,
- char *num_loops_arg,
- char *method_name_arg);
-
+acpi_db_create_execution_threads(char *num_threads_arg,
+ char *num_loops_arg, char *method_name_arg);
/*
* dbfileio - Debugger file I/O commands
*/
acpi_object_type
-acpi_db_match_argument (
- char *user_argument,
- struct argument_info *arguments);
+acpi_db_match_argument(char *user_argument, struct argument_info *arguments);
-void
-acpi_db_close_debug_file (
- void);
+void acpi_db_close_debug_file(void);
-void
-acpi_db_open_debug_file (
- char *name);
+void acpi_db_open_debug_file(char *name);
-acpi_status
-acpi_db_load_acpi_table (
- char *filename);
+acpi_status acpi_db_load_acpi_table(char *filename);
acpi_status
-acpi_db_get_table_from_file (
- char *filename,
- struct acpi_table_header **table);
+acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table);
acpi_status
-acpi_db_read_table_from_file (
- char *filename,
- struct acpi_table_header **table);
-
+acpi_db_read_table_from_file(char *filename, struct acpi_table_header **table);
/*
* dbhistry - debugger HISTORY command
*/
-void
-acpi_db_add_to_history (
- char *command_line);
+void acpi_db_add_to_history(char *command_line);
-void
-acpi_db_display_history (
- void);
-
-char *
-acpi_db_get_from_history (
- char *command_num_arg);
+void acpi_db_display_history(void);
+char *acpi_db_get_from_history(char *command_num_arg);
/*
* dbinput - user front-end to the AML debugger
*/
acpi_status
-acpi_db_command_dispatch (
- char *input_buffer,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
-
-void ACPI_SYSTEM_XFACE
-acpi_db_execute_thread (
- void *context);
+acpi_db_command_dispatch(char *input_buffer,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
+void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context);
/*
* dbstats - Generation and display of ACPI table statistics
*/
-void
-acpi_db_generate_statistics (
- union acpi_parse_object *root,
- u8 is_method);
-
-acpi_status
-acpi_db_display_statistics (
- char *type_arg);
+void acpi_db_generate_statistics(union acpi_parse_object *root, u8 is_method);
+acpi_status acpi_db_display_statistics(char *type_arg);
/*
* dbutils - AML debugger utilities
*/
-void
-acpi_db_set_output_destination (
- u32 where);
+void acpi_db_set_output_destination(u32 where);
-void
-acpi_db_dump_object (
- union acpi_object *obj_desc,
- u32 level);
+void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level);
-void
-acpi_db_prep_namestring (
- char *name);
+void acpi_db_prep_namestring(char *name);
-struct acpi_namespace_node *
-acpi_db_local_ns_lookup (
- char *name);
+struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name);
-#endif /* __ACDEBUG_H__ */
+#endif /* __ACDEBUG_H__ */
diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
index dbfa877121ba..3d96dcb1bb4b 100644
--- a/include/acpi/acdisasm.h
+++ b/include/acpi/acdisasm.h
@@ -46,327 +46,219 @@
#include "amlresrc.h"
-
#define BLOCK_NONE 0
#define BLOCK_PAREN 1
#define BLOCK_BRACE 2
#define BLOCK_COMMA_LIST 4
-struct acpi_external_list
-{
- char *path;
- struct acpi_external_list *next;
+struct acpi_external_list {
+ char *path;
+ struct acpi_external_list *next;
};
-extern struct acpi_external_list *acpi_gbl_external_list;
-extern const char *acpi_gbl_io_decode[2];
-extern const char *acpi_gbl_word_decode[4];
-extern const char *acpi_gbl_consume_decode[2];
-extern const char *acpi_gbl_min_decode[2];
-extern const char *acpi_gbl_max_decode[2];
-extern const char *acpi_gbl_DECdecode[2];
-extern const char *acpi_gbl_RNGdecode[4];
-extern const char *acpi_gbl_MEMdecode[4];
-extern const char *acpi_gbl_RWdecode[2];
-extern const char *acpi_gbl_irq_decode[2];
-extern const char *acpi_gbl_HEdecode[2];
-extern const char *acpi_gbl_LLdecode[2];
-extern const char *acpi_gbl_SHRdecode[2];
-extern const char *acpi_gbl_TYPdecode[4];
-extern const char *acpi_gbl_BMdecode[2];
-extern const char *acpi_gbl_SIZdecode[4];
-extern const char *acpi_gbl_TTPdecode[2];
-extern const char *acpi_gbl_MTPdecode[4];
-extern const char *acpi_gbl_TRSdecode[2];
-
-
-extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES];
-extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES];
-extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES];
-extern const char *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS];
-
-
-struct acpi_op_walk_info
-{
- u32 level;
- u32 bit_offset;
+extern struct acpi_external_list *acpi_gbl_external_list;
+extern const char *acpi_gbl_io_decode[2];
+extern const char *acpi_gbl_word_decode[4];
+extern const char *acpi_gbl_consume_decode[2];
+extern const char *acpi_gbl_min_decode[2];
+extern const char *acpi_gbl_max_decode[2];
+extern const char *acpi_gbl_DECdecode[2];
+extern const char *acpi_gbl_RNGdecode[4];
+extern const char *acpi_gbl_MEMdecode[4];
+extern const char *acpi_gbl_RWdecode[2];
+extern const char *acpi_gbl_irq_decode[2];
+extern const char *acpi_gbl_HEdecode[2];
+extern const char *acpi_gbl_LLdecode[2];
+extern const char *acpi_gbl_SHRdecode[2];
+extern const char *acpi_gbl_TYPdecode[4];
+extern const char *acpi_gbl_BMdecode[2];
+extern const char *acpi_gbl_SIZdecode[4];
+extern const char *acpi_gbl_TTPdecode[2];
+extern const char *acpi_gbl_MTPdecode[4];
+extern const char *acpi_gbl_TRSdecode[2];
+
+extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES];
+extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES];
+extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES];
+extern const char *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS];
+
+struct acpi_op_walk_info {
+ u32 level;
+ u32 bit_offset;
+ struct acpi_walk_state *walk_state;
};
typedef
-acpi_status (*asl_walk_callback) (
- union acpi_parse_object *op,
- u32 level,
- void *context);
-
+acpi_status(*asl_walk_callback) (union acpi_parse_object * op,
+ u32 level, void *context);
/*
* dmwalk
*/
void
-acpi_dm_disassemble (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *origin,
- u32 num_opcodes);
-
+acpi_dm_disassemble(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *origin, u32 num_opcodes);
/*
* dmopcode
*/
void
-acpi_dm_disassemble_one_op (
- struct acpi_walk_state *walk_state,
- struct acpi_op_walk_info *info,
- union acpi_parse_object *op);
+acpi_dm_disassemble_one_op(struct acpi_walk_state *walk_state,
+ struct acpi_op_walk_info *info,
+ union acpi_parse_object *op);
-void
-acpi_dm_decode_internal_object (
- union acpi_operand_object *obj_desc);
+void acpi_dm_decode_internal_object(union acpi_operand_object *obj_desc);
-u32
-acpi_dm_list_type (
- union acpi_parse_object *op);
+u32 acpi_dm_list_type(union acpi_parse_object *op);
-void
-acpi_dm_method_flags (
- union acpi_parse_object *op);
-
-void
-acpi_dm_field_flags (
- union acpi_parse_object *op);
+void acpi_dm_method_flags(union acpi_parse_object *op);
-void
-acpi_dm_address_space (
- u8 space_id);
+void acpi_dm_field_flags(union acpi_parse_object *op);
-void
-acpi_dm_region_flags (
- union acpi_parse_object *op);
+void acpi_dm_address_space(u8 space_id);
-void
-acpi_dm_match_op (
- union acpi_parse_object *op);
+void acpi_dm_region_flags(union acpi_parse_object *op);
-u8
-acpi_dm_comma_if_list_member (
- union acpi_parse_object *op);
+void acpi_dm_match_op(union acpi_parse_object *op);
-void
-acpi_dm_comma_if_field_member (
- union acpi_parse_object *op);
+u8 acpi_dm_comma_if_list_member(union acpi_parse_object *op);
+void acpi_dm_comma_if_field_member(union acpi_parse_object *op);
/*
* dmnames
*/
-u32
-acpi_dm_dump_name (
- char *name);
+u32 acpi_dm_dump_name(char *name);
acpi_status
-acpi_ps_display_object_pathname (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
-
-void
-acpi_dm_namestring (
- char *name);
+acpi_ps_display_object_pathname(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
+void acpi_dm_namestring(char *name);
/*
* dmobject
*/
void
-acpi_dm_display_internal_object (
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state);
+acpi_dm_display_internal_object(union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state);
-void
-acpi_dm_display_arguments (
- struct acpi_walk_state *walk_state);
+void acpi_dm_display_arguments(struct acpi_walk_state *walk_state);
-void
-acpi_dm_display_locals (
- struct acpi_walk_state *walk_state);
+void acpi_dm_display_locals(struct acpi_walk_state *walk_state);
void
-acpi_dm_dump_method_info (
- acpi_status status,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
-
+acpi_dm_dump_method_info(acpi_status status,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
/*
* dmbuffer
*/
-void
-acpi_dm_disasm_byte_list (
- u32 level,
- u8 *byte_data,
- u32 byte_count);
+void acpi_dm_disasm_byte_list(u32 level, u8 * byte_data, u32 byte_count);
void
-acpi_dm_byte_list (
- struct acpi_op_walk_info *info,
- union acpi_parse_object *op);
+acpi_dm_byte_list(struct acpi_op_walk_info *info, union acpi_parse_object *op);
-void
-acpi_is_eisa_id (
- union acpi_parse_object *op);
+void acpi_dm_is_eisa_id(union acpi_parse_object *op);
-void
-acpi_dm_eisa_id (
- u32 encoded_id);
-
-u8
-acpi_dm_is_unicode_buffer (
- union acpi_parse_object *op);
+void acpi_dm_eisa_id(u32 encoded_id);
-u8
-acpi_dm_is_string_buffer (
- union acpi_parse_object *op);
+u8 acpi_dm_is_unicode_buffer(union acpi_parse_object *op);
+u8 acpi_dm_is_string_buffer(union acpi_parse_object *op);
/*
* dmresrc
*/
void
-acpi_dm_resource_descriptor (
- struct acpi_op_walk_info *info,
- u8 *byte_data,
- u32 byte_count);
+acpi_dm_resource_descriptor(struct acpi_op_walk_info *info,
+ u8 * byte_data, u32 byte_count);
-u8
-acpi_dm_is_resource_descriptor (
- union acpi_parse_object *op);
+u8 acpi_dm_is_resource_descriptor(union acpi_parse_object *op);
-void
-acpi_dm_indent (
- u32 level);
+void acpi_dm_indent(u32 level);
-void
-acpi_dm_bit_list (
- u16 mask);
-
-void
-acpi_dm_decode_attribute (
- u8 attribute);
+void acpi_dm_bit_list(u16 mask);
+void acpi_dm_decode_attribute(u8 attribute);
/*
* dmresrcl
*/
void
-acpi_dm_word_descriptor (
- struct asl_word_address_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_word_descriptor(struct asl_word_address_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_dword_descriptor (
- struct asl_dword_address_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_dword_descriptor(struct asl_dword_address_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_extended_descriptor (
- struct asl_extended_address_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_extended_descriptor(struct asl_extended_address_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_qword_descriptor (
- struct asl_qword_address_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_qword_descriptor(struct asl_qword_address_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_memory24_descriptor (
- struct asl_memory_24_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_memory24_descriptor(struct asl_memory_24_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_memory32_descriptor (
- struct asl_memory_32_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_memory32_descriptor(struct asl_memory_32_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_fixed_mem32_descriptor (
- struct asl_fixed_memory_32_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_fixed_mem32_descriptor(struct asl_fixed_memory_32_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_generic_register_descriptor (
- struct asl_general_register_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_generic_register_descriptor(struct asl_general_register_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_interrupt_descriptor (
- struct asl_extended_xrupt_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_interrupt_descriptor(struct asl_extended_xrupt_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_vendor_large_descriptor (
- struct asl_large_vendor_desc *resource,
- u32 length,
- u32 level);
-
+acpi_dm_vendor_large_descriptor(struct asl_large_vendor_desc *resource,
+ u32 length, u32 level);
/*
* dmresrcs
*/
void
-acpi_dm_irq_descriptor (
- struct asl_irq_format_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_irq_descriptor(struct asl_irq_format_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_dma_descriptor (
- struct asl_dma_format_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_dma_descriptor(struct asl_dma_format_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_io_descriptor (
- struct asl_io_port_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_io_descriptor(struct asl_io_port_desc *resource, u32 length, u32 level);
void
-acpi_dm_fixed_io_descriptor (
- struct asl_fixed_io_port_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_fixed_io_descriptor(struct asl_fixed_io_port_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_start_dependent_descriptor (
- struct asl_start_dependent_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_start_dependent_descriptor(struct asl_start_dependent_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_end_dependent_descriptor (
- struct asl_start_dependent_desc *resource,
- u32 length,
- u32 level);
+acpi_dm_end_dependent_descriptor(struct asl_start_dependent_desc *resource,
+ u32 length, u32 level);
void
-acpi_dm_vendor_small_descriptor (
- struct asl_small_vendor_desc *resource,
- u32 length,
- u32 level);
-
+acpi_dm_vendor_small_descriptor(struct asl_small_vendor_desc *resource,
+ u32 length, u32 level);
/*
* dmutils
*/
-void
-acpi_dm_add_to_external_list (
- char *path);
+void acpi_dm_add_to_external_list(char *path);
-#endif /* __ACDISASM_H__ */
+#endif /* __ACDISASM_H__ */
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h
index 8f5f2f71b1de..065f24a77cfc 100644
--- a/include/acpi/acdispat.h
+++ b/include/acpi/acdispat.h
@@ -41,419 +41,304 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#ifndef _ACDISPAT_H_
#define _ACDISPAT_H_
-
#define NAMEOF_LOCAL_NTE "__L0"
#define NAMEOF_ARG_NTE "__A0"
-
/*
* dsopcode - support for late evaluation
*/
acpi_status
-acpi_ds_get_buffer_field_arguments (
- union acpi_operand_object *obj_desc);
-
-acpi_status
-acpi_ds_get_region_arguments (
- union acpi_operand_object *rgn_desc);
+acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc);
-acpi_status
-acpi_ds_get_buffer_arguments (
- union acpi_operand_object *obj_desc);
+acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *rgn_desc);
-acpi_status
-acpi_ds_get_package_arguments (
- union acpi_operand_object *obj_desc);
+acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc);
-acpi_status
-acpi_ds_eval_buffer_field_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
+acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc);
acpi_status
-acpi_ds_eval_region_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
+acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
acpi_status
-acpi_ds_eval_data_object_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- union acpi_operand_object *obj_desc);
+acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
acpi_status
-acpi_ds_initialize_region (
- acpi_handle obj_handle);
+acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ union acpi_operand_object *obj_desc);
+acpi_status acpi_ds_initialize_region(acpi_handle obj_handle);
/*
* dsctrl - Parser/Interpreter interface, control stack routines
*/
acpi_status
-acpi_ds_exec_begin_control_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
+acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
acpi_status
-acpi_ds_exec_end_control_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
-
+acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
/*
* dsexec - Parser/Interpreter interface, method execution callbacks
*/
acpi_status
-acpi_ds_get_predicate_value (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *result_obj);
-
-acpi_status
-acpi_ds_exec_begin_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op);
+acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *result_obj);
acpi_status
-acpi_ds_exec_end_op (
- struct acpi_walk_state *state);
+acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object **out_op);
+acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *state);
/*
* dsfield - Parser/Interpreter interface for AML fields
*/
acpi_status
-acpi_ds_create_field (
- union acpi_parse_object *op,
- struct acpi_namespace_node *region_node,
- struct acpi_walk_state *walk_state);
+acpi_ds_create_field(union acpi_parse_object *op,
+ struct acpi_namespace_node *region_node,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_create_bank_field (
- union acpi_parse_object *op,
- struct acpi_namespace_node *region_node,
- struct acpi_walk_state *walk_state);
+acpi_ds_create_bank_field(union acpi_parse_object *op,
+ struct acpi_namespace_node *region_node,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_create_index_field (
- union acpi_parse_object *op,
- struct acpi_namespace_node *region_node,
- struct acpi_walk_state *walk_state);
+acpi_ds_create_index_field(union acpi_parse_object *op,
+ struct acpi_namespace_node *region_node,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_create_buffer_field (
- union acpi_parse_object *op,
- struct acpi_walk_state *walk_state);
+acpi_ds_create_buffer_field(union acpi_parse_object *op,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_init_field_objects (
- union acpi_parse_object *op,
- struct acpi_walk_state *walk_state);
-
+acpi_ds_init_field_objects(union acpi_parse_object *op,
+ struct acpi_walk_state *walk_state);
/*
* dsload - Parser/Interpreter interface, namespace load callbacks
*/
acpi_status
-acpi_ds_load1_begin_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op);
+acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object **out_op);
-acpi_status
-acpi_ds_load1_end_op (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_load2_begin_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op);
+acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object **out_op);
-acpi_status
-acpi_ds_load2_end_op (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_init_callbacks (
- struct acpi_walk_state *walk_state,
- u32 pass_number);
-
+acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
/*
* dsmthdat - method data (locals/args)
*/
acpi_status
-acpi_ds_store_object_to_local (
- u16 opcode,
- u32 index,
- union acpi_operand_object *src_desc,
- struct acpi_walk_state *walk_state);
+acpi_ds_store_object_to_local(u16 opcode,
+ u32 index,
+ union acpi_operand_object *src_desc,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_method_data_get_entry (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state,
- union acpi_operand_object ***node);
+acpi_ds_method_data_get_entry(u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state,
+ union acpi_operand_object ***node);
-void
-acpi_ds_method_data_delete_all (
- struct acpi_walk_state *walk_state);
+void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state);
-u8
-acpi_ds_is_method_value (
- union acpi_operand_object *obj_desc);
+u8 acpi_ds_is_method_value(union acpi_operand_object *obj_desc);
acpi_status
-acpi_ds_method_data_get_value (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state,
- union acpi_operand_object **dest_desc);
+acpi_ds_method_data_get_value(u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state,
+ union acpi_operand_object **dest_desc);
acpi_status
-acpi_ds_method_data_init_args (
- union acpi_operand_object **params,
- u32 max_param_count,
- struct acpi_walk_state *walk_state);
+acpi_ds_method_data_init_args(union acpi_operand_object **params,
+ u32 max_param_count,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_method_data_get_node (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node **node);
-
-void
-acpi_ds_method_data_init (
- struct acpi_walk_state *walk_state);
+acpi_ds_method_data_get_node(u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node **node);
+void acpi_ds_method_data_init(struct acpi_walk_state *walk_state);
/*
* dsmethod - Parser/Interpreter interface - control method parsing
*/
-acpi_status
-acpi_ds_parse_method (
- acpi_handle obj_handle);
+acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node);
acpi_status
-acpi_ds_call_control_method (
- struct acpi_thread_state *thread,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
+acpi_ds_call_control_method(struct acpi_thread_state *thread,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
acpi_status
-acpi_ds_restart_control_method (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *return_desc);
+acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *return_desc);
-acpi_status
-acpi_ds_terminate_control_method (
- struct acpi_walk_state *walk_state);
+void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_begin_method_execution (
- struct acpi_namespace_node *method_node,
- union acpi_operand_object *obj_desc,
- struct acpi_namespace_node *calling_method_node);
-
+acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
+ union acpi_operand_object *obj_desc,
+ struct acpi_namespace_node *calling_method_node);
/*
* dsinit
*/
acpi_status
-acpi_ds_initialize_objects (
- struct acpi_table_desc *table_desc,
- struct acpi_namespace_node *start_node);
-
+acpi_ds_initialize_objects(struct acpi_table_desc *table_desc,
+ struct acpi_namespace_node *start_node);
/*
* dsobject - Parser/Interpreter interface - object initialization and conversion
*/
acpi_status
-acpi_ds_build_internal_buffer_obj (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u32 buffer_length,
- union acpi_operand_object **obj_desc_ptr);
+acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u32 buffer_length,
+ union acpi_operand_object **obj_desc_ptr);
acpi_status
-acpi_ds_build_internal_package_obj (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u32 package_length,
- union acpi_operand_object **obj_desc);
+acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u32 package_length,
+ union acpi_operand_object **obj_desc);
acpi_status
-acpi_ds_init_object_from_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- u16 opcode,
- union acpi_operand_object **obj_desc);
+acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u16 opcode, union acpi_operand_object **obj_desc);
acpi_status
-acpi_ds_create_node (
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node *node,
- union acpi_parse_object *op);
-
+acpi_ds_create_node(struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node *node,
+ union acpi_parse_object *op);
/*
* dsutils - Parser/Interpreter interface utility routines
*/
-void
-acpi_ds_clear_implicit_return (
- struct acpi_walk_state *walk_state);
+void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state);
u8
-acpi_ds_do_implicit_return (
- union acpi_operand_object *return_desc,
- struct acpi_walk_state *walk_state,
- u8 add_reference);
+acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
+ struct acpi_walk_state *walk_state,
+ u8 add_reference);
u8
-acpi_ds_is_result_used (
- union acpi_parse_object *op,
- struct acpi_walk_state *walk_state);
+acpi_ds_is_result_used(union acpi_parse_object *op,
+ struct acpi_walk_state *walk_state);
void
-acpi_ds_delete_result_if_not_used (
- union acpi_parse_object *op,
- union acpi_operand_object *result_obj,
- struct acpi_walk_state *walk_state);
+acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
+ union acpi_operand_object *result_obj,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_create_operand (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *arg,
- u32 args_remaining);
+acpi_ds_create_operand(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *arg, u32 args_remaining);
acpi_status
-acpi_ds_create_operands (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *first_arg);
+acpi_ds_create_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *first_arg);
-acpi_status
-acpi_ds_resolve_operands (
- struct acpi_walk_state *walk_state);
-
-void
-acpi_ds_clear_operands (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state);
+void acpi_ds_clear_operands(struct acpi_walk_state *walk_state);
/*
* dswscope - Scope Stack manipulation
*/
acpi_status
-acpi_ds_scope_stack_push (
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_walk_state *walk_state);
+acpi_ds_scope_stack_push(struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ds_scope_stack_pop (
- struct acpi_walk_state *walk_state);
-
-void
-acpi_ds_scope_stack_clear (
- struct acpi_walk_state *walk_state);
-
+void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state);
/*
* dswstate - parser WALK_STATE management routines
*/
acpi_status
-acpi_ds_obj_stack_push (
- void *object,
- struct acpi_walk_state *walk_state);
+acpi_ds_obj_stack_push(void *object, struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_obj_stack_pop (
- u32 pop_count,
- struct acpi_walk_state *walk_state);
+acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state *walk_state);
-struct acpi_walk_state *
-acpi_ds_create_walk_state (
- acpi_owner_id owner_id,
- union acpi_parse_object *origin,
- union acpi_operand_object *mth_desc,
- struct acpi_thread_state *thread);
+struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id,
+ union acpi_parse_object
+ *origin,
+ union acpi_operand_object
+ *mth_desc,
+ struct acpi_thread_state
+ *thread);
acpi_status
-acpi_ds_init_aml_walk (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- struct acpi_namespace_node *method_node,
- u8 *aml_start,
- u32 aml_length,
- struct acpi_parameter_info *info,
- u32 pass_number);
+acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ struct acpi_namespace_node *method_node,
+ u8 * aml_start,
+ u32 aml_length,
+ struct acpi_parameter_info *info, u8 pass_number);
acpi_status
-acpi_ds_obj_stack_pop_and_delete (
- u32 pop_count,
- struct acpi_walk_state *walk_state);
+acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
+ struct acpi_walk_state *walk_state);
-void
-acpi_ds_delete_walk_state (
- struct acpi_walk_state *walk_state);
+void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state);
-struct acpi_walk_state *
-acpi_ds_pop_walk_state (
- struct acpi_thread_state *thread);
+struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state
+ *thread);
void
-acpi_ds_push_walk_state (
- struct acpi_walk_state *walk_state,
- struct acpi_thread_state *thread);
+acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
+ struct acpi_thread_state *thread);
-acpi_status
-acpi_ds_result_stack_pop (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ds_result_stack_push (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ds_result_stack_clear (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ds_result_stack_clear(struct acpi_walk_state *walk_state);
-struct acpi_walk_state *
-acpi_ds_get_current_walk_state (
- struct acpi_thread_state *thread);
+struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
+ *thread);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_ds_result_remove (
- union acpi_operand_object **object,
- u32 index,
- struct acpi_walk_state *walk_state);
+acpi_ds_result_remove(union acpi_operand_object **object,
+ u32 index, struct acpi_walk_state *walk_state);
#endif
acpi_status
-acpi_ds_result_pop (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state);
+acpi_ds_result_pop(union acpi_operand_object **object,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_result_push (
- union acpi_operand_object *object,
- struct acpi_walk_state *walk_state);
+acpi_ds_result_push(union acpi_operand_object *object,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ds_result_pop_from_bottom (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state);
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-void
-acpi_ds_delete_walk_state_cache (
- void);
-#endif
+acpi_ds_result_pop_from_bottom(union acpi_operand_object **object,
+ struct acpi_walk_state *walk_state);
-#endif /* _ACDISPAT_H_ */
+#endif /* _ACDISPAT_H_ */
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h
index 61a27c8c5079..bfa54600ecd9 100644
--- a/include/acpi/acevents.h
+++ b/include/acpi/acevents.h
@@ -44,250 +44,167 @@
#ifndef __ACEVENTS_H__
#define __ACEVENTS_H__
-
/*
* evevent
*/
-acpi_status
-acpi_ev_initialize_events (
- void);
+acpi_status acpi_ev_initialize_events(void);
-acpi_status
-acpi_ev_install_xrupt_handlers (
- void);
-
-u32
-acpi_ev_fixed_event_detect (
- void);
+acpi_status acpi_ev_install_xrupt_handlers(void);
+u32 acpi_ev_fixed_event_detect(void);
/*
* evmisc
*/
-u8
-acpi_ev_is_notify_object (
- struct acpi_namespace_node *node);
+u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node);
-acpi_status
-acpi_ev_acquire_global_lock(
- u16 timeout);
+acpi_status acpi_ev_acquire_global_lock(u16 timeout);
-acpi_status
-acpi_ev_release_global_lock(
- void);
+acpi_status acpi_ev_release_global_lock(void);
-acpi_status
-acpi_ev_init_global_lock_handler (
- void);
+acpi_status acpi_ev_init_global_lock_handler(void);
-u32
-acpi_ev_get_gpe_number_index (
- u32 gpe_number);
+u32 acpi_ev_get_gpe_number_index(u32 gpe_number);
acpi_status
-acpi_ev_queue_notify_request (
- struct acpi_namespace_node *node,
- u32 notify_value);
-
+acpi_ev_queue_notify_request(struct acpi_namespace_node *node,
+ u32 notify_value);
/*
* evgpe - GPE handling and dispatch
*/
acpi_status
-acpi_ev_update_gpe_enable_masks (
- struct acpi_gpe_event_info *gpe_event_info,
- u8 type);
+acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
+ u8 type);
acpi_status
-acpi_ev_enable_gpe (
- struct acpi_gpe_event_info *gpe_event_info,
- u8 write_to_hardware);
+acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
+ u8 write_to_hardware);
-acpi_status
-acpi_ev_disable_gpe (
- struct acpi_gpe_event_info *gpe_event_info);
-
-struct acpi_gpe_event_info *
-acpi_ev_get_gpe_event_info (
- acpi_handle gpe_device,
- u32 gpe_number);
+acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
+ u32 gpe_number);
/*
* evgpeblk
*/
-u8
-acpi_ev_valid_gpe_event (
- struct acpi_gpe_event_info *gpe_event_info);
-
-acpi_status
-acpi_ev_walk_gpe_list (
- ACPI_GPE_CALLBACK gpe_walk_callback,
- u32 flags);
+u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
-acpi_status
-acpi_ev_delete_gpe_handlers (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block);
+acpi_status acpi_ev_walk_gpe_list(ACPI_GPE_CALLBACK gpe_walk_callback);
acpi_status
-acpi_ev_create_gpe_block (
- struct acpi_namespace_node *gpe_device,
- struct acpi_generic_address *gpe_block_address,
- u32 register_count,
- u8 gpe_block_base_number,
- u32 interrupt_level,
- struct acpi_gpe_block_info **return_gpe_block);
+acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
acpi_status
-acpi_ev_delete_gpe_block (
- struct acpi_gpe_block_info *gpe_block);
+acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
+ struct acpi_generic_address *gpe_block_address,
+ u32 register_count,
+ u8 gpe_block_base_number,
+ u32 interrupt_number,
+ struct acpi_gpe_block_info **return_gpe_block);
-u32
-acpi_ev_gpe_dispatch (
- struct acpi_gpe_event_info *gpe_event_info,
- u32 gpe_number);
+acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
u32
-acpi_ev_gpe_detect (
- struct acpi_gpe_xrupt_info *gpe_xrupt_list);
+acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,
+ u32 gpe_number);
-acpi_status
-acpi_ev_set_gpe_type (
- struct acpi_gpe_event_info *gpe_event_info,
- u8 type);
+u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
acpi_status
-acpi_ev_check_for_wake_only_gpe (
- struct acpi_gpe_event_info *gpe_event_info);
+acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type);
acpi_status
-acpi_ev_gpe_initialize (
- void);
+acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status acpi_ev_gpe_initialize(void);
/*
* evregion - Address Space handling
*/
-acpi_status
-acpi_ev_install_region_handlers (
- void);
+acpi_status acpi_ev_install_region_handlers(void);
-acpi_status
-acpi_ev_initialize_op_regions (
- void);
+acpi_status acpi_ev_initialize_op_regions(void);
acpi_status
-acpi_ev_address_space_dispatch (
- union acpi_operand_object *region_obj,
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- void *value);
+acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
+ u32 function,
+ acpi_physical_address address,
+ u32 bit_width, void *value);
acpi_status
-acpi_ev_attach_region (
- union acpi_operand_object *handler_obj,
- union acpi_operand_object *region_obj,
- u8 acpi_ns_is_locked);
+acpi_ev_attach_region(union acpi_operand_object *handler_obj,
+ union acpi_operand_object *region_obj,
+ u8 acpi_ns_is_locked);
void
-acpi_ev_detach_region (
- union acpi_operand_object *region_obj,
- u8 acpi_ns_is_locked);
+acpi_ev_detach_region(union acpi_operand_object *region_obj,
+ u8 acpi_ns_is_locked);
acpi_status
-acpi_ev_install_space_handler (
- struct acpi_namespace_node *node,
- acpi_adr_space_type space_id,
- acpi_adr_space_handler handler,
- acpi_adr_space_setup setup,
- void *context);
+acpi_ev_install_space_handler(struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler,
+ acpi_adr_space_setup setup, void *context);
acpi_status
-acpi_ev_execute_reg_methods (
- struct acpi_namespace_node *node,
- acpi_adr_space_type space_id);
+acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id);
acpi_status
-acpi_ev_execute_reg_method (
- union acpi_operand_object *region_obj,
- u32 function);
-
+acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
/*
* evregini - Region initialization and setup
*/
acpi_status
-acpi_ev_system_memory_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_ev_system_memory_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context,
+ void **region_context);
acpi_status
-acpi_ev_io_space_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_ev_io_space_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context);
acpi_status
-acpi_ev_pci_config_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_ev_pci_config_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context);
acpi_status
-acpi_ev_cmos_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_ev_cmos_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context);
acpi_status
-acpi_ev_pci_bar_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_ev_pci_bar_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context);
acpi_status
-acpi_ev_default_region_setup (
- acpi_handle handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_ev_default_region_setup(acpi_handle handle,
+ u32 function,
+ void *handler_context, void **region_context);
acpi_status
-acpi_ev_initialize_region (
- union acpi_operand_object *region_obj,
- u8 acpi_ns_locked);
-
+acpi_ev_initialize_region(union acpi_operand_object *region_obj,
+ u8 acpi_ns_locked);
/*
* evsci - SCI (System Control Interrupt) handling/dispatch
*/
-u32 ACPI_SYSTEM_XFACE
-acpi_ev_gpe_xrupt_handler (
- void *context);
-
-u32
-acpi_ev_install_sci_handler (
- void);
+u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context);
-acpi_status
-acpi_ev_remove_sci_handler (
- void);
+u32 acpi_ev_install_sci_handler(void);
-u32
-acpi_ev_initialize_sCI (
- u32 program_sCI);
+acpi_status acpi_ev_remove_sci_handler(void);
-void
-acpi_ev_terminate (
- void);
+u32 acpi_ev_initialize_sCI(u32 program_sCI);
+void acpi_ev_terminate(void);
-#endif /* __ACEVENTS_H__ */
+#endif /* __ACEVENTS_H__ */
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 60d737b2d70f..4f005eb65928 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -44,7 +44,6 @@
#ifndef __ACEXCEP_H__
#define __ACEXCEP_H__
-
/*
* Exceptions returned by external ACPI interfaces
*/
@@ -55,11 +54,9 @@
#define AE_CODE_CONTROL 0x4000
#define AE_CODE_MASK 0xF000
-
#define ACPI_SUCCESS(a) (!(a))
#define ACPI_FAILURE(a) (a)
-
#define AE_OK (acpi_status) 0x0000
/*
@@ -95,9 +92,9 @@
#define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
#define AE_SAME_HANDLER (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
#define AE_WAKE_ONLY_GPE (acpi_status) (0x001E | AE_CODE_ENVIRONMENTAL)
+#define AE_OWNER_ID_LIMIT (acpi_status) (0x001F | AE_CODE_ENVIRONMENTAL)
-#define AE_CODE_ENV_MAX 0x001E
-
+#define AE_CODE_ENV_MAX 0x001F
/*
* Programmer exceptions
@@ -114,7 +111,6 @@
#define AE_CODE_PGM_MAX 0x0009
-
/*
* Acpi table exceptions
*/
@@ -127,7 +123,6 @@
#define AE_CODE_TBL_MAX 0x0006
-
/*
* AML exceptions. These are caused by problems with
* the actual AML byte stream
@@ -168,7 +163,6 @@
#define AE_CODE_AML_MAX 0x0021
-
/*
* Internal exceptions used for control
*/
@@ -186,16 +180,13 @@
#define AE_CODE_CTRL_MAX 0x000B
-
#ifdef DEFINE_ACPI_GLOBALS
-
/*
* String versions of the exception codes above
* These strings must match the corresponding defines exactly
*/
-char const *acpi_gbl_exception_names_env[] =
-{
+char const *acpi_gbl_exception_names_env[] = {
"AE_OK",
"AE_ERROR",
"AE_NO_ACPI_TABLES",
@@ -226,11 +217,11 @@ char const *acpi_gbl_exception_names_env[] =
"AE_LOGICAL_ADDRESS",
"AE_ABORT_METHOD",
"AE_SAME_HANDLER",
- "AE_WAKE_ONLY_GPE"
+ "AE_WAKE_ONLY_GPE",
+ "AE_OWNER_ID_LIMIT"
};
-char const *acpi_gbl_exception_names_pgm[] =
-{
+char const *acpi_gbl_exception_names_pgm[] = {
"AE_BAD_PARAMETER",
"AE_BAD_CHARACTER",
"AE_BAD_PATHNAME",
@@ -242,8 +233,7 @@ char const *acpi_gbl_exception_names_pgm[] =
"AE_BAD_DECIMAL_CONSTANT"
};
-char const *acpi_gbl_exception_names_tbl[] =
-{
+char const *acpi_gbl_exception_names_tbl[] = {
"AE_BAD_SIGNATURE",
"AE_BAD_HEADER",
"AE_BAD_CHECKSUM",
@@ -252,8 +242,7 @@ char const *acpi_gbl_exception_names_tbl[] =
"AE_INVALID_TABLE_LENGTH"
};
-char const *acpi_gbl_exception_names_aml[] =
-{
+char const *acpi_gbl_exception_names_aml[] = {
"AE_AML_ERROR",
"AE_AML_PARSE",
"AE_AML_BAD_OPCODE",
@@ -289,8 +278,7 @@ char const *acpi_gbl_exception_names_aml[] =
"AE_AML_BAD_RESOURCE_LENGTH"
};
-char const *acpi_gbl_exception_names_ctrl[] =
-{
+char const *acpi_gbl_exception_names_ctrl[] = {
"AE_CTRL_RETURN_VALUE",
"AE_CTRL_PENDING",
"AE_CTRL_TERMINATE",
@@ -304,6 +292,6 @@ char const *acpi_gbl_exception_names_ctrl[] =
"AE_CTRL_SKIP"
};
-#endif /* ACPI GLOBALS */
+#endif /* ACPI GLOBALS */
-#endif /* __ACEXCEP_H__ */
+#endif /* __ACEXCEP_H__ */
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 4946696088c3..e9c2790139ec 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -44,7 +44,6 @@
#ifndef __ACGLOBAL_H__
#define __ACGLOBAL_H__
-
/*
* Ensure that the globals are actually defined and initialized only once.
*
@@ -63,9 +62,8 @@
* Keep local copies of these FADT-based registers. NOTE: These globals
* are first in this file for alignment reasons on 64-bit systems.
*/
-ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
-ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
-
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*****************************************************************************
*
@@ -75,13 +73,12 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/* Runtime configuration of debug print levels */
-extern u32 acpi_dbg_level;
-extern u32 acpi_dbg_layer;
+extern u32 acpi_dbg_level;
+extern u32 acpi_dbg_layer;
/* Procedure nesting level for debug output */
-extern u32 acpi_gbl_nesting_level;
-
+extern u32 acpi_gbl_nesting_level;
/*****************************************************************************
*
@@ -98,7 +95,7 @@ extern u32 acpi_gbl_nesting_level;
* 3) Allow access to uninitialized locals/args (auto-init to integer 0)
* 4) Allow ANY object type to be a source operand for the Store() operator
*/
-ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpreter_slack, FALSE);
+ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE);
/*
* Automatically serialize ALL control methods? Default is FALSE, meaning
@@ -106,22 +103,21 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpreter_slack, FALSE)
* Only change this if the ASL code is poorly written and cannot handle
* reentrancy even though methods are marked "not_serialized".
*/
-ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_all_methods_serialized, FALSE);
+ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE);
/*
* Create the predefined _OSI method in the namespace? Default is TRUE
* because ACPI CA is fully compatible with other ACPI implementations.
* Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
*/
-ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE);
+ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE);
/*
* Disable wakeup GPEs during runtime? Default is TRUE because WAKE and
* RUNTIME GPEs should never be shared, and WAKE GPEs should typically only
* be enabled just before going to sleep.
*/
-ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_leave_wake_gpes_disabled, TRUE);
-
+ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE);
/*****************************************************************************
*
@@ -137,42 +133,46 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_leave_wake_gpes_disabled, TRUE);
* These tables are single-table only; meaning that there can be at most one
* of each in the system. Each global points to the actual table.
*/
-ACPI_EXTERN u32 acpi_gbl_table_flags;
-ACPI_EXTERN u32 acpi_gbl_rsdt_table_count;
-ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP;
-ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT;
-ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
-ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS;
-ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS;
+ACPI_EXTERN u32 acpi_gbl_table_flags;
+ACPI_EXTERN u32 acpi_gbl_rsdt_table_count;
+ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP;
+ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT;
+ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT;
+ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
+ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS;
+ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS;
/*
* Since there may be multiple SSDTs and PSDTs, a single pointer is not
* sufficient; Therefore, there isn't one!
*/
+/* The root table can be either an RSDT or an XSDT */
+
+ACPI_EXTERN u8 acpi_gbl_root_table_type;
+#define ACPI_TABLE_TYPE_RSDT 'R'
+#define ACPI_TABLE_TYPE_XSDT 'X'
/*
* Handle both ACPI 1.0 and ACPI 2.0 Integer widths:
* If we are executing a method that exists in a 32-bit ACPI table,
* use only the lower 32 bits of the (internal) 64-bit Integer.
*/
-ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
-ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
-ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
+ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
+ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
+ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
/*
* ACPI Table info arrays
*/
-extern struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
-extern struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES];
+extern struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+extern struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES];
/*
* Predefined mutex objects. This array contains the
* actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
* (The table maps local handles to the real OS handles)
*/
-ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[NUM_MUTEX];
-
+ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[NUM_MUTEX];
/*****************************************************************************
*
@@ -180,41 +180,56 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[NUM_MUTEX];
*
****************************************************************************/
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+/* Lists for tracking memory allocations */
-ACPI_EXTERN struct acpi_memory_list acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS];
-ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify;
-ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify;
-ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
-ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
-ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
-ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore;
-
-ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count;
-ACPI_EXTERN u32 acpi_gbl_original_mode;
-ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
-ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
-ACPI_EXTERN u32 acpi_gbl_ps_find_count;
-ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
-ACPI_EXTERN u16 acpi_gbl_next_table_owner_id;
-ACPI_EXTERN u16 acpi_gbl_next_method_owner_id;
-ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
-ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
-ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
-ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
-ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
-ACPI_EXTERN u8 acpi_gbl_global_lock_present;
-ACPI_EXTERN u8 acpi_gbl_events_initialized;
-ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
-
-extern u8 acpi_gbl_shutdown;
-extern u32 acpi_gbl_startup_flags;
-extern const u8 acpi_gbl_decode_to8bit[8];
-extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
-extern const char *acpi_gbl_highest_dstate_names[4];
-extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
-extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
-extern const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS];
+ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list;
+ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list;
+#endif
+/* Object caches */
+
+ACPI_EXTERN acpi_cache_t *acpi_gbl_state_cache;
+ACPI_EXTERN acpi_cache_t *acpi_gbl_ps_node_cache;
+ACPI_EXTERN acpi_cache_t *acpi_gbl_ps_node_ext_cache;
+ACPI_EXTERN acpi_cache_t *acpi_gbl_operand_cache;
+
+/* Global handlers */
+
+ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify;
+ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify;
+ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
+ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
+ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
+ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore;
+
+/* Misc */
+
+ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count;
+ACPI_EXTERN u32 acpi_gbl_original_mode;
+ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
+ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
+ACPI_EXTERN u32 acpi_gbl_ps_find_count;
+ACPI_EXTERN u32 acpi_gbl_owner_id_mask;
+ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
+ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
+ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
+ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
+ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
+ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
+ACPI_EXTERN u8 acpi_gbl_global_lock_present;
+ACPI_EXTERN u8 acpi_gbl_events_initialized;
+ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+
+extern u8 acpi_gbl_shutdown;
+extern u32 acpi_gbl_startup_flags;
+extern const u8 acpi_gbl_decode_to8bit[8];
+extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
+extern const char *acpi_gbl_highest_dstate_names[4];
+extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
+extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
+extern const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS];
/*****************************************************************************
*
@@ -230,36 +245,34 @@ extern const char *acpi_gbl_valid_osi_strings[ACPI_
#define NUM_PREDEFINED_NAMES 9
#endif
-ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct;
-ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node;
-ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device;
+ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct;
+ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node;
+ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device;
-extern const u8 acpi_gbl_ns_properties[NUM_NS_TYPES];
-extern const struct acpi_predefined_names acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
+extern const u8 acpi_gbl_ns_properties[NUM_NS_TYPES];
+extern const struct acpi_predefined_names
+ acpi_gbl_pre_defined_names[NUM_PREDEFINED_NAMES];
#ifdef ACPI_DEBUG_OUTPUT
-ACPI_EXTERN u32 acpi_gbl_current_node_count;
-ACPI_EXTERN u32 acpi_gbl_current_node_size;
-ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count;
-ACPI_EXTERN acpi_size acpi_gbl_entry_stack_pointer;
-ACPI_EXTERN acpi_size acpi_gbl_lowest_stack_pointer;
-ACPI_EXTERN u32 acpi_gbl_deepest_nesting;
+ACPI_EXTERN u32 acpi_gbl_current_node_count;
+ACPI_EXTERN u32 acpi_gbl_current_node_size;
+ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count;
+ACPI_EXTERN acpi_size acpi_gbl_entry_stack_pointer;
+ACPI_EXTERN acpi_size acpi_gbl_lowest_stack_pointer;
+ACPI_EXTERN u32 acpi_gbl_deepest_nesting;
#endif
-
/*****************************************************************************
*
* Interpreter globals
*
****************************************************************************/
-
-ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list;
+ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list;
/* Control method single step flag */
-ACPI_EXTERN u8 acpi_gbl_cm_single_step;
-
+ACPI_EXTERN u8 acpi_gbl_cm_single_step;
/*****************************************************************************
*
@@ -267,8 +280,7 @@ ACPI_EXTERN u8 acpi_gbl_cm_single_step;
*
****************************************************************************/
-ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root;
-
+ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root;
/*****************************************************************************
*
@@ -276,10 +288,10 @@ ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root;
*
****************************************************************************/
-extern struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG];
-ACPI_EXTERN u8 acpi_gbl_sleep_type_a;
-ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
-
+extern struct acpi_bit_register_info
+ acpi_gbl_bit_register_info[ACPI_NUM_BITREG];
+ACPI_EXTERN u8 acpi_gbl_sleep_type_a;
+ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
/*****************************************************************************
*
@@ -287,12 +299,14 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
*
****************************************************************************/
-extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
-ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
-ACPI_EXTERN acpi_handle acpi_gbl_gpe_lock;
-
+extern struct acpi_fixed_event_info
+ acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
+ACPI_EXTERN struct acpi_fixed_event_handler
+ acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
+ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
+ACPI_EXTERN struct acpi_gpe_block_info
+ *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
+ACPI_EXTERN acpi_handle acpi_gbl_gpe_lock;
/*****************************************************************************
*
@@ -300,58 +314,55 @@ ACPI_EXTERN acpi_handle acpi_gbl_gpe_lock;
*
****************************************************************************/
-ACPI_EXTERN u8 acpi_gbl_db_output_flags;
+ACPI_EXTERN u8 acpi_gbl_db_output_flags;
#ifdef ACPI_DISASSEMBLER
-ACPI_EXTERN u8 acpi_gbl_db_opt_disasm;
-ACPI_EXTERN u8 acpi_gbl_db_opt_verbose;
+ACPI_EXTERN u8 acpi_gbl_db_opt_disasm;
+ACPI_EXTERN u8 acpi_gbl_db_opt_verbose;
#endif
-
#ifdef ACPI_DEBUGGER
-extern u8 acpi_gbl_method_executing;
-extern u8 acpi_gbl_abort_method;
-extern u8 acpi_gbl_db_terminate_threads;
-
-ACPI_EXTERN int optind;
-ACPI_EXTERN char *optarg;
-
-ACPI_EXTERN u8 acpi_gbl_db_opt_tables;
-ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
-ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
-
-
-ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS];
-ACPI_EXTERN char acpi_gbl_db_line_buf[80];
-ACPI_EXTERN char acpi_gbl_db_parsed_buf[80];
-ACPI_EXTERN char acpi_gbl_db_scope_buf[40];
-ACPI_EXTERN char acpi_gbl_db_debug_filename[40];
-ACPI_EXTERN u8 acpi_gbl_db_output_to_file;
-ACPI_EXTERN char *acpi_gbl_db_buffer;
-ACPI_EXTERN char *acpi_gbl_db_filename;
-ACPI_EXTERN u32 acpi_gbl_db_debug_level;
-ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
-ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
+extern u8 acpi_gbl_method_executing;
+extern u8 acpi_gbl_abort_method;
+extern u8 acpi_gbl_db_terminate_threads;
+
+ACPI_EXTERN int optind;
+ACPI_EXTERN char *optarg;
+
+ACPI_EXTERN u8 acpi_gbl_db_opt_tables;
+ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
+ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
+
+ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS];
+ACPI_EXTERN char acpi_gbl_db_line_buf[80];
+ACPI_EXTERN char acpi_gbl_db_parsed_buf[80];
+ACPI_EXTERN char acpi_gbl_db_scope_buf[40];
+ACPI_EXTERN char acpi_gbl_db_debug_filename[40];
+ACPI_EXTERN u8 acpi_gbl_db_output_to_file;
+ACPI_EXTERN char *acpi_gbl_db_buffer;
+ACPI_EXTERN char *acpi_gbl_db_filename;
+ACPI_EXTERN u32 acpi_gbl_db_debug_level;
+ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
+ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
+ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
/*
* Statistic globals
*/
-ACPI_EXTERN u16 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX+1];
-ACPI_EXTERN u16 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX+1];
-ACPI_EXTERN u16 acpi_gbl_obj_type_count_misc;
-ACPI_EXTERN u16 acpi_gbl_node_type_count_misc;
-ACPI_EXTERN u32 acpi_gbl_num_nodes;
-ACPI_EXTERN u32 acpi_gbl_num_objects;
-
+ACPI_EXTERN u16 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX + 1];
+ACPI_EXTERN u16 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX + 1];
+ACPI_EXTERN u16 acpi_gbl_obj_type_count_misc;
+ACPI_EXTERN u16 acpi_gbl_node_type_count_misc;
+ACPI_EXTERN u32 acpi_gbl_num_nodes;
+ACPI_EXTERN u32 acpi_gbl_num_objects;
-ACPI_EXTERN u32 acpi_gbl_size_of_parse_tree;
-ACPI_EXTERN u32 acpi_gbl_size_of_method_trees;
-ACPI_EXTERN u32 acpi_gbl_size_of_node_entries;
-ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects;
+ACPI_EXTERN u32 acpi_gbl_size_of_parse_tree;
+ACPI_EXTERN u32 acpi_gbl_size_of_method_trees;
+ACPI_EXTERN u32 acpi_gbl_size_of_node_entries;
+ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects;
-#endif /* ACPI_DEBUGGER */
+#endif /* ACPI_DEBUGGER */
-#endif /* __ACGLOBAL_H__ */
+#endif /* __ACGLOBAL_H__ */
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 9d63641b8e7d..3644d7248e7e 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -44,7 +44,6 @@
#ifndef __ACHWARE_H__
#define __ACHWARE_H__
-
/* PM Timer ticks per second (HZ) */
#define PM_TIMER_FREQUENCY 3579545
@@ -57,126 +56,78 @@
#define ACPI_SST_SLEEPING 3
#define ACPI_SST_SLEEP_CONTEXT 4
-
/* Prototypes */
-
/*
* hwacpi - high level functions
*/
-acpi_status
-acpi_hw_initialize (
- void);
+acpi_status acpi_hw_initialize(void);
-acpi_status
-acpi_hw_set_mode (
- u32 mode);
-
-u32
-acpi_hw_get_mode (
- void);
+acpi_status acpi_hw_set_mode(u32 mode);
+u32 acpi_hw_get_mode(void);
/*
* hwregs - ACPI Register I/O
*/
-struct acpi_bit_register_info *
-acpi_hw_get_bit_register_info (
- u32 register_id);
-
-acpi_status
-acpi_hw_register_read (
- u8 use_lock,
- u32 register_id,
- u32 *return_value);
+struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
acpi_status
-acpi_hw_register_write (
- u8 use_lock,
- u32 register_id,
- u32 value);
+acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value);
-acpi_status
-acpi_hw_low_level_read (
- u32 width,
- u32 *value,
- struct acpi_generic_address *reg);
+acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value);
acpi_status
-acpi_hw_low_level_write (
- u32 width,
- u32 value,
- struct acpi_generic_address *reg);
+acpi_hw_low_level_read(u32 width,
+ u32 * value, struct acpi_generic_address *reg);
acpi_status
-acpi_hw_clear_acpi_status (
- u32 flags);
+acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address *reg);
+acpi_status acpi_hw_clear_acpi_status(u32 flags);
/*
* hwgpe - GPE support
*/
acpi_status
-acpi_hw_write_gpe_enable_reg (
- struct acpi_gpe_event_info *gpe_event_info);
+acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info);
acpi_status
-acpi_hw_disable_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block);
+acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
-acpi_status
-acpi_hw_clear_gpe (
- struct acpi_gpe_event_info *gpe_event_info);
+acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info);
acpi_status
-acpi_hw_clear_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block);
+acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_hw_get_gpe_status (
- struct acpi_gpe_event_info *gpe_event_info,
- acpi_event_status *event_status);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
+ acpi_event_status * event_status);
+#endif /* ACPI_FUTURE_USAGE */
-acpi_status
-acpi_hw_disable_all_gpes (
- u32 flags);
+acpi_status acpi_hw_disable_all_gpes(void);
-acpi_status
-acpi_hw_enable_all_runtime_gpes (
- u32 flags);
+acpi_status acpi_hw_enable_all_runtime_gpes(void);
-acpi_status
-acpi_hw_enable_all_wakeup_gpes (
- u32 flags);
+acpi_status acpi_hw_enable_all_wakeup_gpes(void);
acpi_status
-acpi_hw_enable_runtime_gpe_block (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block);
-
+acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
#ifdef ACPI_FUTURE_USAGE
/*
* hwtimer - ACPI Timer prototypes
*/
-acpi_status
-acpi_get_timer_resolution (
- u32 *resolution);
+acpi_status acpi_get_timer_resolution(u32 * resolution);
-acpi_status
-acpi_get_timer (
- u32 *ticks);
+acpi_status acpi_get_timer(u32 * ticks);
acpi_status
-acpi_get_timer_duration (
- u32 start_ticks,
- u32 end_ticks,
- u32 *time_elapsed);
-#endif /* ACPI_FUTURE_USAGE */
-
+acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed);
+#endif /* ACPI_FUTURE_USAGE */
-#endif /* __ACHWARE_H__ */
+#endif /* __ACHWARE_H__ */
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index 5c7172477a0f..2c9c1a1d1b7f 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -44,29 +44,22 @@
#ifndef __ACINTERP_H__
#define __ACINTERP_H__
-
#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1]))
-
/*
* exconvrt - object conversion
*/
acpi_status
-acpi_ex_convert_to_integer (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc,
- u32 flags);
+acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc, u32 flags);
acpi_status
-acpi_ex_convert_to_buffer (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc);
+acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc);
acpi_status
-acpi_ex_convert_to_string (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc,
- u32 type);
+acpi_ex_convert_to_string(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc, u32 type);
/* Types for ->String conversion */
@@ -76,587 +69,412 @@ acpi_ex_convert_to_string (
#define ACPI_EXPLICIT_CONVERT_DECIMAL 0x00000003
acpi_status
-acpi_ex_convert_to_target_type (
- acpi_object_type destination_type,
- union acpi_operand_object *source_desc,
- union acpi_operand_object **result_desc,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_convert_to_target_type(acpi_object_type destination_type,
+ union acpi_operand_object *source_desc,
+ union acpi_operand_object **result_desc,
+ struct acpi_walk_state *walk_state);
/*
* exfield - ACPI AML (p-code) execution - field manipulation
*/
acpi_status
-acpi_ex_common_buffer_setup (
- union acpi_operand_object *obj_desc,
- u32 buffer_length,
- u32 *datum_count);
+acpi_ex_common_buffer_setup(union acpi_operand_object *obj_desc,
+ u32 buffer_length, u32 * datum_count);
acpi_status
-acpi_ex_write_with_update_rule (
- union acpi_operand_object *obj_desc,
- acpi_integer mask,
- acpi_integer field_value,
- u32 field_datum_byte_offset);
+acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
+ acpi_integer mask,
+ acpi_integer field_value,
+ u32 field_datum_byte_offset);
void
-acpi_ex_get_buffer_datum(
- acpi_integer *datum,
- void *buffer,
- u32 buffer_length,
- u32 byte_granularity,
- u32 buffer_offset);
+acpi_ex_get_buffer_datum(acpi_integer * datum,
+ void *buffer,
+ u32 buffer_length,
+ u32 byte_granularity, u32 buffer_offset);
void
-acpi_ex_set_buffer_datum (
- acpi_integer merged_datum,
- void *buffer,
- u32 buffer_length,
- u32 byte_granularity,
- u32 buffer_offset);
+acpi_ex_set_buffer_datum(acpi_integer merged_datum,
+ void *buffer,
+ u32 buffer_length,
+ u32 byte_granularity, u32 buffer_offset);
acpi_status
-acpi_ex_read_data_from_field (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **ret_buffer_desc);
+acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object **ret_buffer_desc);
acpi_status
-acpi_ex_write_data_to_field (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **result_desc);
-
+acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object **result_desc);
/*
* exfldio - low level field I/O
*/
acpi_status
-acpi_ex_extract_from_field (
- union acpi_operand_object *obj_desc,
- void *buffer,
- u32 buffer_length);
+acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
+ void *buffer, u32 buffer_length);
acpi_status
-acpi_ex_insert_into_field (
- union acpi_operand_object *obj_desc,
- void *buffer,
- u32 buffer_length);
+acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
+ void *buffer, u32 buffer_length);
acpi_status
-acpi_ex_access_region (
- union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset,
- acpi_integer *value,
- u32 read_write);
-
+acpi_ex_access_region(union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset,
+ acpi_integer * value, u32 read_write);
/*
* exmisc - misc support routines
*/
acpi_status
-acpi_ex_get_object_reference (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object **return_desc,
- struct acpi_walk_state *walk_state);
+acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
+ union acpi_operand_object **return_desc,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_concat_template (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *obj_desc2,
- union acpi_operand_object **actual_return_desc,
- struct acpi_walk_state *walk_state);
+acpi_ex_concat_template(union acpi_operand_object *obj_desc,
+ union acpi_operand_object *obj_desc2,
+ union acpi_operand_object **actual_return_desc,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_do_concatenate (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *obj_desc2,
- union acpi_operand_object **actual_return_desc,
- struct acpi_walk_state *walk_state);
+acpi_ex_do_concatenate(union acpi_operand_object *obj_desc,
+ union acpi_operand_object *obj_desc2,
+ union acpi_operand_object **actual_return_desc,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_do_logical_numeric_op (
- u16 opcode,
- acpi_integer integer0,
- acpi_integer integer1,
- u8 *logical_result);
+acpi_ex_do_logical_numeric_op(u16 opcode,
+ acpi_integer integer0,
+ acpi_integer integer1, u8 * logical_result);
acpi_status
-acpi_ex_do_logical_op (
- u16 opcode,
- union acpi_operand_object *operand0,
- union acpi_operand_object *operand1,
- u8 *logical_result);
+acpi_ex_do_logical_op(u16 opcode,
+ union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1, u8 * logical_result);
acpi_integer
-acpi_ex_do_math_op (
- u16 opcode,
- acpi_integer operand0,
- acpi_integer operand1);
+acpi_ex_do_math_op(u16 opcode, acpi_integer operand0, acpi_integer operand1);
-acpi_status
-acpi_ex_create_mutex (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_create_processor (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_create_power_resource (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_create_power_resource(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_create_region (
- u8 *aml_start,
- u32 aml_length,
- u8 region_space,
- struct acpi_walk_state *walk_state);
+acpi_ex_create_region(u8 * aml_start,
+ u32 aml_length,
+ u8 region_space, struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_create_table_region (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_create_event (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_create_alias (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_create_method (
- u8 *aml_start,
- u32 aml_length,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_create_method(u8 * aml_start,
+ u32 aml_length, struct acpi_walk_state *walk_state);
/*
* exconfig - dynamic table load/unload
*/
acpi_status
-acpi_ex_load_op (
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *target,
- struct acpi_walk_state *walk_state);
+acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ union acpi_operand_object *target,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_load_table_op (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object **return_desc);
-
-acpi_status
-acpi_ex_unload_table (
- union acpi_operand_object *ddb_handle);
+acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
+ union acpi_operand_object **return_desc);
+acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle);
/*
* exmutex - mutex support
*/
acpi_status
-acpi_ex_acquire_mutex (
- union acpi_operand_object *time_desc,
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state);
+acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
+ union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_release_mutex (
- union acpi_operand_object *obj_desc,
- struct acpi_walk_state *walk_state);
+acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state);
-void
-acpi_ex_release_all_mutexes (
- struct acpi_thread_state *thread);
-
-void
-acpi_ex_unlink_mutex (
- union acpi_operand_object *obj_desc);
+void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread);
+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc);
/*
* exprep - ACPI AML execution - prep utilities
*/
acpi_status
-acpi_ex_prep_common_field_object (
- union acpi_operand_object *obj_desc,
- u8 field_flags,
- u8 field_attribute,
- u32 field_bit_position,
- u32 field_bit_length);
-
-acpi_status
-acpi_ex_prep_field_value (
- struct acpi_create_field_info *info);
+acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
+ u8 field_flags,
+ u8 field_attribute,
+ u32 field_bit_position, u32 field_bit_length);
+acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info);
/*
* exsystem - Interface to OS services
*/
acpi_status
-acpi_ex_system_do_notify_op (
- union acpi_operand_object *value,
- union acpi_operand_object *obj_desc);
+acpi_ex_system_do_notify_op(union acpi_operand_object *value,
+ union acpi_operand_object *obj_desc);
-acpi_status
-acpi_ex_system_do_suspend(
- acpi_integer time);
+acpi_status acpi_ex_system_do_suspend(acpi_integer time);
-acpi_status
-acpi_ex_system_do_stall (
- u32 time);
+acpi_status acpi_ex_system_do_stall(u32 time);
acpi_status
-acpi_ex_system_acquire_mutex(
- union acpi_operand_object *time,
- union acpi_operand_object *obj_desc);
+acpi_ex_system_acquire_mutex(union acpi_operand_object *time,
+ union acpi_operand_object *obj_desc);
-acpi_status
-acpi_ex_system_release_mutex(
- union acpi_operand_object *obj_desc);
+acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc);
-acpi_status
-acpi_ex_system_signal_event(
- union acpi_operand_object *obj_desc);
+acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc);
acpi_status
-acpi_ex_system_wait_event(
- union acpi_operand_object *time,
- union acpi_operand_object *obj_desc);
+acpi_ex_system_wait_event(union acpi_operand_object *time,
+ union acpi_operand_object *obj_desc);
-acpi_status
-acpi_ex_system_reset_event(
- union acpi_operand_object *obj_desc);
-
-acpi_status
-acpi_ex_system_wait_semaphore (
- acpi_handle semaphore,
- u16 timeout);
+acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc);
+acpi_status acpi_ex_system_wait_semaphore(acpi_handle semaphore, u16 timeout);
/*
* exoparg1 - ACPI AML execution, 1 operand
*/
-acpi_status
-acpi_ex_opcode_0A_0T_1R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_opcode_1A_0T_0R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_opcode_1A_0T_1R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_opcode_1A_1T_1R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_opcode_1A_1T_0R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state);
/*
* exoparg2 - ACPI AML execution, 2 operands
*/
-acpi_status
-acpi_ex_opcode_2A_0T_0R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_opcode_2A_0T_1R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state);
-acpi_status
-acpi_ex_opcode_2A_1T_1R (
- struct acpi_walk_state *walk_state);
-
-acpi_status
-acpi_ex_opcode_2A_2T_1R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state);
/*
* exoparg3 - ACPI AML execution, 3 operands
*/
-acpi_status
-acpi_ex_opcode_3A_0T_0R (
- struct acpi_walk_state *walk_state);
-
-acpi_status
-acpi_ex_opcode_3A_1T_1R (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state);
+acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state);
/*
* exoparg6 - ACPI AML execution, 6 operands
*/
-acpi_status
-acpi_ex_opcode_6A_0T_1R (
- struct acpi_walk_state *walk_state);
-
+acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state *walk_state);
/*
* exresolv - Object resolution and get value functions
*/
acpi_status
-acpi_ex_resolve_to_value (
- union acpi_operand_object **stack_ptr,
- struct acpi_walk_state *walk_state);
+acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_resolve_multiple (
- struct acpi_walk_state *walk_state,
- union acpi_operand_object *operand,
- acpi_object_type *return_type,
- union acpi_operand_object **return_desc);
-
+acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
+ union acpi_operand_object *operand,
+ acpi_object_type * return_type,
+ union acpi_operand_object **return_desc);
/*
* exresnte - resolve namespace node
*/
acpi_status
-acpi_ex_resolve_node_to_value (
- struct acpi_namespace_node **stack_ptr,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_resolve_node_to_value(struct acpi_namespace_node **stack_ptr,
+ struct acpi_walk_state *walk_state);
/*
* exresop - resolve operand to value
*/
acpi_status
-acpi_ex_resolve_operands (
- u16 opcode,
- union acpi_operand_object **stack_ptr,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_resolve_operands(u16 opcode,
+ union acpi_operand_object **stack_ptr,
+ struct acpi_walk_state *walk_state);
/*
* exdump - Interpreter debug output routines
*/
-void
-acpi_ex_dump_operand (
- union acpi_operand_object *obj_desc,
- u32 depth);
+void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth);
void
-acpi_ex_dump_operands (
- union acpi_operand_object **operands,
- acpi_interpreter_mode interpreter_mode,
- char *ident,
- u32 num_levels,
- char *note,
- char *module_name,
- u32 line_number);
+acpi_ex_dump_operands(union acpi_operand_object **operands,
+ acpi_interpreter_mode interpreter_mode,
+ char *ident,
+ u32 num_levels,
+ char *note, char *module_name, u32 line_number);
#ifdef ACPI_FUTURE_USAGE
void
-acpi_ex_dump_object_descriptor (
- union acpi_operand_object *object,
- u32 flags);
-
-void
-acpi_ex_dump_node (
- struct acpi_namespace_node *node,
- u32 flags);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
+void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags);
+#endif /* ACPI_FUTURE_USAGE */
/*
* exnames - AML namestring support
*/
acpi_status
-acpi_ex_get_name_string (
- acpi_object_type data_type,
- u8 *in_aml_address,
- char **out_name_string,
- u32 *out_name_length);
-
+acpi_ex_get_name_string(acpi_object_type data_type,
+ u8 * in_aml_address,
+ char **out_name_string, u32 * out_name_length);
/*
* exstore - Object store support
*/
acpi_status
-acpi_ex_store (
- union acpi_operand_object *val_desc,
- union acpi_operand_object *dest_desc,
- struct acpi_walk_state *walk_state);
+acpi_ex_store(union acpi_operand_object *val_desc,
+ union acpi_operand_object *dest_desc,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_store_object_to_node (
- union acpi_operand_object *source_desc,
- struct acpi_namespace_node *node,
- struct acpi_walk_state *walk_state,
- u8 implicit_conversion);
+acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
+ struct acpi_namespace_node *node,
+ struct acpi_walk_state *walk_state,
+ u8 implicit_conversion);
#define ACPI_IMPLICIT_CONVERSION TRUE
#define ACPI_NO_IMPLICIT_CONVERSION FALSE
-
/*
* exstoren - resolve/store object
*/
acpi_status
-acpi_ex_resolve_object (
- union acpi_operand_object **source_desc_ptr,
- acpi_object_type target_type,
- struct acpi_walk_state *walk_state);
+acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
+ acpi_object_type target_type,
+ struct acpi_walk_state *walk_state);
acpi_status
-acpi_ex_store_object_to_object (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *dest_desc,
- union acpi_operand_object **new_desc,
- struct acpi_walk_state *walk_state);
-
+acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc,
+ union acpi_operand_object **new_desc,
+ struct acpi_walk_state *walk_state);
/*
* exstorob - store object - buffer/string
*/
acpi_status
-acpi_ex_store_buffer_to_buffer (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc);
+acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc);
acpi_status
-acpi_ex_store_string_to_string (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc);
-
+acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc);
/*
* excopy - object copy
*/
acpi_status
-acpi_ex_copy_integer_to_index_field (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc);
+acpi_ex_copy_integer_to_index_field(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc);
acpi_status
-acpi_ex_copy_integer_to_bank_field (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc);
+acpi_ex_copy_integer_to_bank_field(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc);
acpi_status
-acpi_ex_copy_data_to_named_field (
- union acpi_operand_object *source_desc,
- struct acpi_namespace_node *node);
+acpi_ex_copy_data_to_named_field(union acpi_operand_object *source_desc,
+ struct acpi_namespace_node *node);
acpi_status
-acpi_ex_copy_integer_to_buffer_field (
- union acpi_operand_object *source_desc,
- union acpi_operand_object *target_desc);
-
+acpi_ex_copy_integer_to_buffer_field(union acpi_operand_object *source_desc,
+ union acpi_operand_object *target_desc);
/*
* exutils - interpreter/scanner utilities
*/
-acpi_status
-acpi_ex_enter_interpreter (
- void);
+acpi_status acpi_ex_enter_interpreter(void);
-void
-acpi_ex_exit_interpreter (
- void);
+void acpi_ex_exit_interpreter(void);
-void
-acpi_ex_truncate_for32bit_table (
- union acpi_operand_object *obj_desc);
+void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
-u8
-acpi_ex_acquire_global_lock (
- u32 rule);
+u8 acpi_ex_acquire_global_lock(u32 rule);
-void
-acpi_ex_release_global_lock (
- u8 locked);
+void acpi_ex_release_global_lock(u8 locked);
-void
-acpi_ex_eisa_id_to_string (
- u32 numeric_id,
- char *out_string);
-
-void
-acpi_ex_unsigned_integer_to_string (
- acpi_integer value,
- char *out_string);
+void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string);
+void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string);
/*
* exregion - default op_region handlers
*/
acpi_status
-acpi_ex_system_memory_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-acpi_status
-acpi_ex_system_io_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-acpi_status
-acpi_ex_pci_config_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-acpi_status
-acpi_ex_cmos_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-acpi_status
-acpi_ex_pci_bar_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-acpi_status
-acpi_ex_embedded_controller_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-acpi_status
-acpi_ex_sm_bus_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-
-acpi_status
-acpi_ex_data_table_space_handler (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
-
-#endif /* __INTERP_H__ */
+acpi_ex_system_memory_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context,
+ void *region_context);
+
+acpi_status
+acpi_ex_system_io_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context);
+
+acpi_status
+acpi_ex_pci_config_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context);
+
+acpi_status
+acpi_ex_cmos_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context);
+
+acpi_status
+acpi_ex_pci_bar_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context);
+
+acpi_status
+acpi_ex_embedded_controller_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context,
+ void *region_context);
+
+acpi_status
+acpi_ex_sm_bus_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context);
+
+acpi_status
+acpi_ex_data_table_space_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context, void *region_context);
+
+#endif /* __INTERP_H__ */
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index 030e641115cb..9fba0fddda90 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -44,17 +44,20 @@
#ifndef __ACLOCAL_H__
#define __ACLOCAL_H__
+#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */
-#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */
-
-typedef void * acpi_mutex;
-typedef u32 acpi_mutex_handle;
-
+typedef void *acpi_mutex;
+typedef u32 acpi_mutex_handle;
/* Total number of aml opcodes defined */
#define AML_NUM_OPCODES 0x7F
+/* Forward declarations */
+
+struct acpi_walk_state;
+struct acpi_obj_mutex;
+union acpi_parse_object;
/*****************************************************************************
*
@@ -62,7 +65,6 @@ typedef u32 acpi_mutex_handle;
*
****************************************************************************/
-
/*
* Predefined handles for the mutex objects used within the subsystem
* All mutex objects are automatically created by acpi_ut_mutex_initialize.
@@ -89,14 +91,12 @@ typedef u32 acpi_mutex_handle;
#define MAX_MUTEX 12
#define NUM_MUTEX MAX_MUTEX+1
-
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
#ifdef DEFINE_ACPI_GLOBALS
/* Names for the mutexes used in the subsystem */
-static char *acpi_gbl_mutex_names[] =
-{
+static char *acpi_gbl_mutex_names[] = {
"ACPI_MTX_Execute",
"ACPI_MTX_Interpreter",
"ACPI_MTX_Parser",
@@ -115,34 +115,28 @@ static char *acpi_gbl_mutex_names[] =
#endif
#endif
+/* Owner IDs are used to track namespace nodes for selective deletion */
-/* Table for the global mutexes */
+typedef u8 acpi_owner_id;
+#define ACPI_OWNER_ID_MAX 0xFF
-struct acpi_mutex_info
-{
- acpi_mutex mutex;
- u32 use_count;
- u32 owner_id;
-};
+/* This Thread ID means that the mutex is not in use (unlocked) */
-/* This owner ID means that the mutex is not in use (unlocked) */
+#define ACPI_MUTEX_NOT_ACQUIRED (u32) -1
-#define ACPI_MUTEX_NOT_ACQUIRED (u32) (-1)
+/* Table for the global mutexes */
+struct acpi_mutex_info {
+ acpi_mutex mutex;
+ u32 use_count;
+ u32 thread_id;
+};
/* Lock flag parameter for various interfaces */
#define ACPI_MTX_DO_NOT_LOCK 0
#define ACPI_MTX_LOCK 1
-
-typedef u16 acpi_owner_id;
-#define ACPI_OWNER_TYPE_TABLE 0x0
-#define ACPI_OWNER_TYPE_METHOD 0x1
-#define ACPI_FIRST_METHOD_ID 0x0001
-#define ACPI_FIRST_TABLE_ID 0xF000
-
-
/* Field access granularities */
#define ACPI_FIELD_BYTE_GRANULARITY 1
@@ -150,7 +144,6 @@ typedef u16 acpi_owner_id;
#define ACPI_FIELD_DWORD_GRANULARITY 4
#define ACPI_FIELD_QWORD_GRANULARITY 8
-
/*****************************************************************************
*
* Namespace typedefs and structs
@@ -159,15 +152,12 @@ typedef u16 acpi_owner_id;
/* Operational modes of the AML interpreter/scanner */
-typedef enum
-{
- ACPI_IMODE_LOAD_PASS1 = 0x01,
- ACPI_IMODE_LOAD_PASS2 = 0x02,
- ACPI_IMODE_EXECUTE = 0x0E
-
+typedef enum {
+ ACPI_IMODE_LOAD_PASS1 = 0x01,
+ ACPI_IMODE_LOAD_PASS2 = 0x02,
+ ACPI_IMODE_EXECUTE = 0x0E
} acpi_interpreter_mode;
-
/*
* The Node describes a named object that appears in the AML
* An acpi_node is used to store Nodes.
@@ -175,34 +165,37 @@ typedef enum
* data_type is used to differentiate between internal descriptors, and MUST
* be the first byte in this structure.
*/
-union acpi_name_union
-{
- u32 integer;
- char ascii[4];
-};
-
-struct acpi_namespace_node
-{
- u8 descriptor; /* Used to differentiate object descriptor types */
- u8 type; /* Type associated with this name */
- u16 owner_id;
- union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */
- union acpi_operand_object *object; /* Pointer to attached ACPI object (optional) */
- struct acpi_namespace_node *child; /* First child */
- struct acpi_namespace_node *peer; /* Next peer*/
- u16 reference_count; /* Current count of references and children */
- u8 flags;
+union acpi_name_union {
+ u32 integer;
+ char ascii[4];
+};
+
+struct acpi_namespace_node {
+ u8 descriptor; /* Used to differentiate object descriptor types */
+ u8 type; /* Type associated with this name */
+ u16 reference_count; /* Current count of references and children */
+ union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */
+ union acpi_operand_object *object; /* Pointer to attached ACPI object (optional) */
+ struct acpi_namespace_node *child; /* First child */
+ struct acpi_namespace_node *peer; /* Next peer */
+ u8 owner_id; /* Who created this node */
+ u8 flags;
+
+ /* Fields used by the ASL compiler only */
+
+#ifdef ACPI_ASL_COMPILER
+ u32 value;
+ union acpi_parse_object *op;
+#endif
};
-
#define ACPI_ENTRY_NOT_FOUND NULL
-
/* Node flags */
#define ANOBJ_RESERVED 0x01
#define ANOBJ_END_OF_PEER_LIST 0x02
-#define ANOBJ_DATA_WIDTH_32 0x04 /* Parent table is 64-bits */
+#define ANOBJ_DATA_WIDTH_32 0x04 /* Parent table is 64-bits */
#define ANOBJ_METHOD_ARG 0x08
#define ANOBJ_METHOD_LOCAL 0x10
#define ANOBJ_METHOD_NO_RETVAL 0x20
@@ -212,91 +205,77 @@ struct acpi_namespace_node
/*
* ACPI Table Descriptor. One per ACPI table
*/
-struct acpi_table_desc
-{
- struct acpi_table_desc *prev;
- struct acpi_table_desc *next;
- struct acpi_table_desc *installed_desc;
- struct acpi_table_header *pointer;
- u8 *aml_start;
- u64 physical_address;
- u32 aml_length;
- acpi_size length;
- acpi_owner_id table_id;
- u8 type;
- u8 allocation;
- u8 loaded_into_namespace;
+struct acpi_table_desc {
+ struct acpi_table_desc *prev;
+ struct acpi_table_desc *next;
+ struct acpi_table_desc *installed_desc;
+ struct acpi_table_header *pointer;
+ u8 *aml_start;
+ u64 physical_address;
+ u32 aml_length;
+ acpi_size length;
+ acpi_owner_id owner_id;
+ u8 type;
+ u8 allocation;
+ u8 loaded_into_namespace;
};
-struct acpi_table_list
-{
- struct acpi_table_desc *next;
- u32 count;
+struct acpi_table_list {
+ struct acpi_table_desc *next;
+ u32 count;
};
-
-struct acpi_find_context
-{
- char *search_for;
- acpi_handle *list;
- u32 *count;
+struct acpi_find_context {
+ char *search_for;
+ acpi_handle *list;
+ u32 *count;
};
-
-struct acpi_ns_search_data
-{
- struct acpi_namespace_node *node;
+struct acpi_ns_search_data {
+ struct acpi_namespace_node *node;
};
-
/*
* Predefined Namespace items
*/
-struct acpi_predefined_names
-{
- char *name;
- u8 type;
- char *val;
+struct acpi_predefined_names {
+ char *name;
+ u8 type;
+ char *val;
};
-
/* Object types used during package copies */
-
#define ACPI_COPY_TYPE_SIMPLE 0
#define ACPI_COPY_TYPE_PACKAGE 1
/* Info structure used to convert external<->internal namestrings */
-struct acpi_namestring_info
-{
- char *external_name;
- char *next_external_char;
- char *internal_name;
- u32 length;
- u32 num_segments;
- u32 num_carats;
- u8 fully_qualified;
+struct acpi_namestring_info {
+ char *external_name;
+ char *next_external_char;
+ char *internal_name;
+ u32 length;
+ u32 num_segments;
+ u32 num_carats;
+ u8 fully_qualified;
};
-
/* Field creation info */
-struct acpi_create_field_info
-{
- struct acpi_namespace_node *region_node;
- struct acpi_namespace_node *field_node;
- struct acpi_namespace_node *register_node;
- struct acpi_namespace_node *data_register_node;
- u32 bank_value;
- u32 field_bit_position;
- u32 field_bit_length;
- u8 field_flags;
- u8 attribute;
- u8 field_type;
+struct acpi_create_field_info {
+ struct acpi_namespace_node *region_node;
+ struct acpi_namespace_node *field_node;
+ struct acpi_namespace_node *register_node;
+ struct acpi_namespace_node *data_register_node;
+ u32 bank_value;
+ u32 field_bit_position;
+ u32 field_bit_length;
+ u8 field_flags;
+ u8 attribute;
+ u8 field_type;
};
-
/*****************************************************************************
*
* Event typedefs and structs
@@ -305,108 +284,95 @@ struct acpi_create_field_info
/* Dispatch info for each GPE -- either a method or handler, cannot be both */
-struct acpi_handler_info
-{
- acpi_event_handler address; /* Address of handler, if any */
- void *context; /* Context to be passed to handler */
- struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
+struct acpi_handler_info {
+ acpi_event_handler address; /* Address of handler, if any */
+ void *context; /* Context to be passed to handler */
+ struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
};
-union acpi_gpe_dispatch_info
-{
- struct acpi_namespace_node *method_node; /* Method node for this GPE level */
- struct acpi_handler_info *handler;
+union acpi_gpe_dispatch_info {
+ struct acpi_namespace_node *method_node; /* Method node for this GPE level */
+ struct acpi_handler_info *handler;
};
/*
* Information about a GPE, one per each GPE in an array.
* NOTE: Important to keep this struct as small as possible.
*/
-struct acpi_gpe_event_info
-{
- union acpi_gpe_dispatch_info dispatch; /* Either Method or Handler */
- struct acpi_gpe_register_info *register_info; /* Backpointer to register info */
- u8 flags; /* Misc info about this GPE */
- u8 register_bit; /* This GPE bit within the register */
+struct acpi_gpe_event_info {
+ union acpi_gpe_dispatch_info dispatch; /* Either Method or Handler */
+ struct acpi_gpe_register_info *register_info; /* Backpointer to register info */
+ u8 flags; /* Misc info about this GPE */
+ u8 register_bit; /* This GPE bit within the register */
};
/* Information about a GPE register pair, one per each status/enable pair in an array */
-struct acpi_gpe_register_info
-{
- struct acpi_generic_address status_address; /* Address of status reg */
- struct acpi_generic_address enable_address; /* Address of enable reg */
- u8 enable_for_wake; /* GPEs to keep enabled when sleeping */
- u8 enable_for_run; /* GPEs to keep enabled when running */
- u8 base_gpe_number; /* Base GPE number for this register */
+struct acpi_gpe_register_info {
+ struct acpi_generic_address status_address; /* Address of status reg */
+ struct acpi_generic_address enable_address; /* Address of enable reg */
+ u8 enable_for_wake; /* GPEs to keep enabled when sleeping */
+ u8 enable_for_run; /* GPEs to keep enabled when running */
+ u8 base_gpe_number; /* Base GPE number for this register */
};
/*
* Information about a GPE register block, one per each installed block --
* GPE0, GPE1, and one per each installed GPE Block Device.
*/
-struct acpi_gpe_block_info
-{
- struct acpi_namespace_node *node;
- struct acpi_gpe_block_info *previous;
- struct acpi_gpe_block_info *next;
- struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */
- struct acpi_gpe_register_info *register_info; /* One per GPE register pair */
- struct acpi_gpe_event_info *event_info; /* One for each GPE */
- struct acpi_generic_address block_address; /* Base address of the block */
- u32 register_count; /* Number of register pairs in block */
- u8 block_base_number;/* Base GPE number for this block */
+struct acpi_gpe_block_info {
+ struct acpi_namespace_node *node;
+ struct acpi_gpe_block_info *previous;
+ struct acpi_gpe_block_info *next;
+ struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */
+ struct acpi_gpe_register_info *register_info; /* One per GPE register pair */
+ struct acpi_gpe_event_info *event_info; /* One for each GPE */
+ struct acpi_generic_address block_address; /* Base address of the block */
+ u32 register_count; /* Number of register pairs in block */
+ u8 block_base_number; /* Base GPE number for this block */
};
/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
-struct acpi_gpe_xrupt_info
-{
- struct acpi_gpe_xrupt_info *previous;
- struct acpi_gpe_xrupt_info *next;
- struct acpi_gpe_block_info *gpe_block_list_head; /* List of GPE blocks for this xrupt */
- u32 interrupt_level; /* System interrupt level */
+struct acpi_gpe_xrupt_info {
+ struct acpi_gpe_xrupt_info *previous;
+ struct acpi_gpe_xrupt_info *next;
+ struct acpi_gpe_block_info *gpe_block_list_head; /* List of GPE blocks for this xrupt */
+ u32 interrupt_number; /* System interrupt number */
};
-
-struct acpi_gpe_walk_info
-{
- struct acpi_namespace_node *gpe_device;
- struct acpi_gpe_block_info *gpe_block;
+struct acpi_gpe_walk_info {
+ struct acpi_namespace_node *gpe_device;
+ struct acpi_gpe_block_info *gpe_block;
};
-
-typedef acpi_status (*ACPI_GPE_CALLBACK) (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block);
-
+typedef acpi_status(*ACPI_GPE_CALLBACK) (struct acpi_gpe_xrupt_info *
+ gpe_xrupt_info,
+ struct acpi_gpe_block_info *
+ gpe_block);
/* Information about each particular fixed event */
-struct acpi_fixed_event_handler
-{
- acpi_event_handler handler; /* Address of handler. */
- void *context; /* Context to be passed to handler */
+struct acpi_fixed_event_handler {
+ acpi_event_handler handler; /* Address of handler. */
+ void *context; /* Context to be passed to handler */
};
-struct acpi_fixed_event_info
-{
- u8 status_register_id;
- u8 enable_register_id;
- u16 status_bit_mask;
- u16 enable_bit_mask;
+struct acpi_fixed_event_info {
+ u8 status_register_id;
+ u8 enable_register_id;
+ u16 status_bit_mask;
+ u16 enable_bit_mask;
};
/* Information used during field processing */
-struct acpi_field_info
-{
- u8 skip_field;
- u8 field_flag;
- u32 pkg_length;
+struct acpi_field_info {
+ u8 skip_field;
+ u8 field_flag;
+ u32 pkg_length;
};
-
/*****************************************************************************
*
* Generic "state" object for stacks
@@ -419,14 +385,6 @@ struct acpi_field_info
#define ACPI_CONTROL_PREDICATE_FALSE 0xC3
#define ACPI_CONTROL_PREDICATE_TRUE 0xC4
-
-/* Forward declarations */
-
-struct acpi_walk_state ;
-struct acpi_obj_mutex;
-union acpi_parse_object ;
-
-
#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\
u8 data_type; /* To differentiate various internal objs */\
u8 flags; \
@@ -435,147 +393,112 @@ union acpi_parse_object ;
u16 reserved; \
void *next; \
-struct acpi_common_state
-{
- ACPI_STATE_COMMON
-};
-
+struct acpi_common_state {
+ACPI_STATE_COMMON};
/*
* Update state - used to traverse complex objects such as packages
*/
-struct acpi_update_state
-{
- ACPI_STATE_COMMON
- union acpi_operand_object *object;
+struct acpi_update_state {
+ ACPI_STATE_COMMON union acpi_operand_object *object;
};
-
/*
* Pkg state - used to traverse nested package structures
*/
-struct acpi_pkg_state
-{
- ACPI_STATE_COMMON
- union acpi_operand_object *source_object;
- union acpi_operand_object *dest_object;
- struct acpi_walk_state *walk_state;
- void *this_target_obj;
- u32 num_packages;
- u16 index;
+struct acpi_pkg_state {
+ ACPI_STATE_COMMON union acpi_operand_object *source_object;
+ union acpi_operand_object *dest_object;
+ struct acpi_walk_state *walk_state;
+ void *this_target_obj;
+ u32 num_packages;
+ u16 index;
};
-
/*
* Control state - one per if/else and while constructs.
* Allows nesting of these constructs
*/
-struct acpi_control_state
-{
- ACPI_STATE_COMMON
- union acpi_parse_object *predicate_op;
- u8 *aml_predicate_start; /* Start of if/while predicate */
- u8 *package_end; /* End of if/while block */
- u16 opcode;
+struct acpi_control_state {
+ ACPI_STATE_COMMON union acpi_parse_object *predicate_op;
+ u8 *aml_predicate_start; /* Start of if/while predicate */
+ u8 *package_end; /* End of if/while block */
+ u16 opcode;
};
-
/*
* Scope state - current scope during namespace lookups
*/
-struct acpi_scope_state
-{
- ACPI_STATE_COMMON
- struct acpi_namespace_node *node;
+struct acpi_scope_state {
+ ACPI_STATE_COMMON struct acpi_namespace_node *node;
};
-
-struct acpi_pscope_state
-{
- ACPI_STATE_COMMON
- union acpi_parse_object *op; /* Current op being parsed */
- u8 *arg_end; /* Current argument end */
- u8 *pkg_end; /* Current package end */
- u32 arg_list; /* Next argument to parse */
- u32 arg_count; /* Number of fixed arguments */
+struct acpi_pscope_state {
+ ACPI_STATE_COMMON union acpi_parse_object *op; /* Current op being parsed */
+ u8 *arg_end; /* Current argument end */
+ u8 *pkg_end; /* Current package end */
+ u32 arg_list; /* Next argument to parse */
+ u32 arg_count; /* Number of fixed arguments */
};
-
/*
* Thread state - one per thread across multiple walk states. Multiple walk
* states are created when there are nested control methods executing.
*/
-struct acpi_thread_state
-{
- ACPI_STATE_COMMON
- struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */
- union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */
- u32 thread_id; /* Running thread ID */
- u8 current_sync_level; /* Mutex Sync (nested acquire) level */
+struct acpi_thread_state {
+ ACPI_STATE_COMMON struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */
+ union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */
+ u32 thread_id; /* Running thread ID */
+ u8 current_sync_level; /* Mutex Sync (nested acquire) level */
};
-
/*
* Result values - used to accumulate the results of nested
* AML arguments
*/
-struct acpi_result_values
-{
+struct acpi_result_values {
ACPI_STATE_COMMON
- union acpi_operand_object *obj_desc [ACPI_OBJ_NUM_OPERANDS];
- u8 num_results;
- u8 last_insert;
+ union acpi_operand_object *obj_desc[ACPI_OBJ_NUM_OPERANDS];
+ u8 num_results;
+ u8 last_insert;
};
-
-typedef
-acpi_status (*acpi_parse_downwards) (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object **out_op);
-
typedef
-acpi_status (*acpi_parse_upwards) (
- struct acpi_walk_state *walk_state);
+acpi_status(*acpi_parse_downwards) (struct acpi_walk_state * walk_state,
+ union acpi_parse_object ** out_op);
+typedef acpi_status(*acpi_parse_upwards) (struct acpi_walk_state * walk_state);
/*
* Notify info - used to pass info to the deferred notify
* handler/dispatcher.
*/
-struct acpi_notify_info
-{
- ACPI_STATE_COMMON
- struct acpi_namespace_node *node;
- union acpi_operand_object *handler_obj;
+struct acpi_notify_info {
+ ACPI_STATE_COMMON struct acpi_namespace_node *node;
+ union acpi_operand_object *handler_obj;
};
-
/* Generic state is union of structs above */
-union acpi_generic_state
-{
- struct acpi_common_state common;
- struct acpi_control_state control;
- struct acpi_update_state update;
- struct acpi_scope_state scope;
- struct acpi_pscope_state parse_scope;
- struct acpi_pkg_state pkg;
- struct acpi_thread_state thread;
- struct acpi_result_values results;
- struct acpi_notify_info notify;
+union acpi_generic_state {
+ struct acpi_common_state common;
+ struct acpi_control_state control;
+ struct acpi_update_state update;
+ struct acpi_scope_state scope;
+ struct acpi_pscope_state parse_scope;
+ struct acpi_pkg_state pkg;
+ struct acpi_thread_state thread;
+ struct acpi_result_values results;
+ struct acpi_notify_info notify;
};
-
/*****************************************************************************
*
* Interpreter typedefs and structs
*
****************************************************************************/
-typedef
-acpi_status (*ACPI_EXECUTE_OP) (
- struct acpi_walk_state *walk_state);
-
+typedef acpi_status(*ACPI_EXECUTE_OP) (struct acpi_walk_state * walk_state);
/*****************************************************************************
*
@@ -586,28 +509,26 @@ acpi_status (*ACPI_EXECUTE_OP) (
/*
* AML opcode, name, and argument layout
*/
-struct acpi_opcode_info
-{
+struct acpi_opcode_info {
#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT)
- char *name; /* Opcode name (disassembler/debug only) */
+ char *name; /* Opcode name (disassembler/debug only) */
#endif
- u32 parse_args; /* Grammar/Parse time arguments */
- u32 runtime_args; /* Interpret time arguments */
- u32 flags; /* Misc flags */
- u8 object_type; /* Corresponding internal object type */
- u8 class; /* Opcode class */
- u8 type; /* Opcode type */
+ u32 parse_args; /* Grammar/Parse time arguments */
+ u32 runtime_args; /* Interpret time arguments */
+ u32 flags; /* Misc flags */
+ u8 object_type; /* Corresponding internal object type */
+ u8 class; /* Opcode class */
+ u8 type; /* Opcode type */
};
-union acpi_parse_value
-{
- acpi_integer integer; /* Integer constant (Up to 64 bits) */
- struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */
- u32 size; /* bytelist or field size */
- char *string; /* NULL terminated string */
- u8 *buffer; /* buffer or string */
- char *name; /* NULL terminated string */
- union acpi_parse_object *arg; /* arguments and contained ops */
+union acpi_parse_value {
+ acpi_integer integer; /* Integer constant (Up to 64 bits) */
+ struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */
+ u32 size; /* bytelist or field size */
+ char *string; /* NULL terminated string */
+ u8 *buffer; /* buffer or string */
+ char *name; /* NULL terminated string */
+ union acpi_parse_object *arg; /* arguments and contained ops */
};
#define ACPI_PARSE_COMMON \
@@ -636,84 +557,72 @@ union acpi_parse_value
/*
* generic operation (for example: If, While, Store)
*/
-struct acpi_parse_obj_common
-{
- ACPI_PARSE_COMMON
-};
-
+struct acpi_parse_obj_common {
+ACPI_PARSE_COMMON};
/*
* Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and op_regions),
* and bytelists.
*/
-struct acpi_parse_obj_named
-{
- ACPI_PARSE_COMMON
- u8 *path;
- u8 *data; /* AML body or bytelist data */
- u32 length; /* AML length */
- u32 name; /* 4-byte name or zero if no name */
+struct acpi_parse_obj_named {
+ ACPI_PARSE_COMMON u8 * path;
+ u8 *data; /* AML body or bytelist data */
+ u32 length; /* AML length */
+ u32 name; /* 4-byte name or zero if no name */
};
-
/* The parse node is the fundamental element of the parse tree */
-struct acpi_parse_obj_asl
-{
- ACPI_PARSE_COMMON
- union acpi_parse_object *child;
- union acpi_parse_object *parent_method;
- char *filename;
- char *external_name;
- char *namepath;
- char name_seg[4];
- u32 extra_value;
- u32 column;
- u32 line_number;
- u32 logical_line_number;
- u32 logical_byte_offset;
- u32 end_line;
- u32 end_logical_line;
- u32 acpi_btype;
- u32 aml_length;
- u32 aml_subtree_length;
- u32 final_aml_length;
- u32 final_aml_offset;
- u32 compile_flags;
- u16 parse_opcode;
- u8 aml_opcode_length;
- u8 aml_pkg_len_bytes;
- u8 extra;
- char parse_op_name[12];
-};
-
-union acpi_parse_object
-{
- struct acpi_parse_obj_common common;
- struct acpi_parse_obj_named named;
- struct acpi_parse_obj_asl asl;
+struct acpi_parse_obj_asl {
+ ACPI_PARSE_COMMON union acpi_parse_object *child;
+ union acpi_parse_object *parent_method;
+ char *filename;
+ char *external_name;
+ char *namepath;
+ char name_seg[4];
+ u32 extra_value;
+ u32 column;
+ u32 line_number;
+ u32 logical_line_number;
+ u32 logical_byte_offset;
+ u32 end_line;
+ u32 end_logical_line;
+ u32 acpi_btype;
+ u32 aml_length;
+ u32 aml_subtree_length;
+ u32 final_aml_length;
+ u32 final_aml_offset;
+ u32 compile_flags;
+ u16 parse_opcode;
+ u8 aml_opcode_length;
+ u8 aml_pkg_len_bytes;
+ u8 extra;
+ char parse_op_name[12];
+};
+
+union acpi_parse_object {
+ struct acpi_parse_obj_common common;
+ struct acpi_parse_obj_named named;
+ struct acpi_parse_obj_asl asl;
};
-
/*
* Parse state - one state per parser invocation and each control
* method.
*/
-struct acpi_parse_state
-{
- u32 aml_size;
- u8 *aml_start; /* First AML byte */
- u8 *aml; /* Next AML byte */
- u8 *aml_end; /* (last + 1) AML byte */
- u8 *pkg_start; /* Current package begin */
- u8 *pkg_end; /* Current package end */
- union acpi_parse_object *start_op; /* Root of parse tree */
- struct acpi_namespace_node *start_node;
- union acpi_generic_state *scope; /* Current scope */
- union acpi_parse_object *start_scope;
+struct acpi_parse_state {
+ u32 aml_size;
+ u8 *aml_start; /* First AML byte */
+ u8 *aml; /* Next AML byte */
+ u8 *aml_end; /* (last + 1) AML byte */
+ u8 *pkg_start; /* Current package begin */
+ u8 *pkg_end; /* Current package end */
+ union acpi_parse_object *start_op; /* Root of parse tree */
+ struct acpi_namespace_node *start_node;
+ union acpi_generic_state *scope; /* Current scope */
+ union acpi_parse_object *start_scope;
};
-
/* Parse object flags */
#define ACPI_PARSEOP_GENERIC 0x01
@@ -729,7 +638,6 @@ struct acpi_parse_state
#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04
#define ACPI_PARSEOP_SPECIAL 0x10
-
/*****************************************************************************
*
* Hardware (ACPI registers) and PNP
@@ -737,15 +645,14 @@ struct acpi_parse_state
****************************************************************************/
#define PCI_ROOT_HID_STRING "PNP0A03"
+#define PCI_EXPRESS_ROOT_HID_STRING "PNP0A08"
-struct acpi_bit_register_info
-{
- u8 parent_register;
- u8 bit_position;
- u16 access_bit_mask;
+struct acpi_bit_register_info {
+ u8 parent_register;
+ u8 bit_position;
+ u16 access_bit_mask;
};
-
/*
* Register IDs
* These are the full ACPI registers
@@ -760,7 +667,6 @@ struct acpi_bit_register_info
#define ACPI_REGISTER_PROCESSOR_BLOCK 0x08
#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09
-
/* Masks used to access the bit_registers */
#define ACPI_BITMASK_TIMER_STATUS 0x0001
@@ -769,7 +675,7 @@ struct acpi_bit_register_info
#define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200
#define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400
-#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */
+#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_WAKE_STATUS 0x8000
#define ACPI_BITMASK_ALL_FIXED_STATUS (ACPI_BITMASK_TIMER_STATUS | \
@@ -785,7 +691,7 @@ struct acpi_bit_register_info
#define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200
#define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400
-#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */
+#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_SCI_ENABLE 0x0001
#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002
@@ -795,7 +701,6 @@ struct acpi_bit_register_info
#define ACPI_BITMASK_ARB_DISABLE 0x0001
-
/* Raw bit position of each bit_register */
#define ACPI_BITPOSITION_TIMER_STATUS 0x00
@@ -804,7 +709,7 @@ struct acpi_bit_register_info
#define ACPI_BITPOSITION_POWER_BUTTON_STATUS 0x08
#define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS 0x09
#define ACPI_BITPOSITION_RT_CLOCK_STATUS 0x0A
-#define ACPI_BITPOSITION_PCIEXP_WAKE_STATUS 0x0E /* ACPI 3.0 */
+#define ACPI_BITPOSITION_PCIEXP_WAKE_STATUS 0x0E /* ACPI 3.0 */
#define ACPI_BITPOSITION_WAKE_STATUS 0x0F
#define ACPI_BITPOSITION_TIMER_ENABLE 0x00
@@ -812,7 +717,7 @@ struct acpi_bit_register_info
#define ACPI_BITPOSITION_POWER_BUTTON_ENABLE 0x08
#define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE 0x09
#define ACPI_BITPOSITION_RT_CLOCK_ENABLE 0x0A
-#define ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE 0x0E /* ACPI 3.0 */
+#define ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE 0x0E /* ACPI 3.0 */
#define ACPI_BITPOSITION_SCI_ENABLE 0x00
#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01
@@ -822,7 +727,6 @@ struct acpi_bit_register_info
#define ACPI_BITPOSITION_ARB_DISABLE 0x00
-
/*****************************************************************************
*
* Resource descriptors
@@ -841,8 +745,7 @@ struct acpi_bit_register_info
#define ACPI_RDESC_TYPE_SMALL 0x00
#define ACPI_RDESC_TYPE_MASK 0x80
-#define ACPI_RDESC_SMALL_MASK 0x78 /* Only bits 6:3 contain the type */
-
+#define ACPI_RDESC_SMALL_MASK 0x78 /* Only bits 6:3 contain the type */
/*
* Small resource descriptor types
@@ -871,7 +774,6 @@ struct acpi_bit_register_info
#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A
#define ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE 0x8B
-
/*****************************************************************************
*
* Miscellaneous
@@ -880,49 +782,36 @@ struct acpi_bit_register_info
#define ACPI_ASCII_ZERO 0x30
-
/*****************************************************************************
*
* Debugger
*
****************************************************************************/
-struct acpi_db_method_info
-{
- acpi_handle thread_gate;
- char *name;
- char **args;
- u32 flags;
- u32 num_loops;
- char pathname[128];
+struct acpi_db_method_info {
+ acpi_handle thread_gate;
+ char *name;
+ char **args;
+ u32 flags;
+ u32 num_loops;
+ char pathname[128];
};
-struct acpi_integrity_info
-{
- u32 nodes;
- u32 objects;
+struct acpi_integrity_info {
+ u32 nodes;
+ u32 objects;
};
-
#define ACPI_DB_REDIRECTABLE_OUTPUT 0x01
#define ACPI_DB_CONSOLE_OUTPUT 0x02
#define ACPI_DB_DUPLICATE_OUTPUT 0x03
-
/*****************************************************************************
*
* Debug
*
****************************************************************************/
-struct acpi_debug_print_info
-{
- u32 component_id;
- char *proc_name;
- char *module_name;
-};
-
-
/* Entry for a memory allocation (debug only) */
#define ACPI_MEM_MALLOC 0
@@ -938,51 +827,36 @@ struct acpi_debug_print_info
char module[ACPI_MAX_MODULE_NAME]; \
u8 alloc_type;
-struct acpi_debug_mem_header
-{
- ACPI_COMMON_DEBUG_MEM_HEADER
-};
+struct acpi_debug_mem_header {
+ACPI_COMMON_DEBUG_MEM_HEADER};
-struct acpi_debug_mem_block
-{
- ACPI_COMMON_DEBUG_MEM_HEADER
- u64 user_space;
+struct acpi_debug_mem_block {
+ ACPI_COMMON_DEBUG_MEM_HEADER u64 user_space;
};
-
#define ACPI_MEM_LIST_GLOBAL 0
#define ACPI_MEM_LIST_NSNODE 1
+#define ACPI_MEM_LIST_MAX 1
+#define ACPI_NUM_MEM_LISTS 2
-#define ACPI_MEM_LIST_FIRST_CACHE_LIST 2
-#define ACPI_MEM_LIST_STATE 2
-#define ACPI_MEM_LIST_PSNODE 3
-#define ACPI_MEM_LIST_PSNODE_EXT 4
-#define ACPI_MEM_LIST_OPERAND 5
-#define ACPI_MEM_LIST_WALK 6
-#define ACPI_MEM_LIST_MAX 6
-#define ACPI_NUM_MEM_LISTS 7
-
-
-struct acpi_memory_list
-{
- void *list_head;
- u16 link_offset;
- u16 max_cache_depth;
- u16 cache_depth;
- u16 object_size;
+struct acpi_memory_list {
+ char *list_name;
+ void *list_head;
+ u16 object_size;
+ u16 max_depth;
+ u16 current_depth;
+ u16 link_offset;
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
/* Statistics for debug memory tracking only */
- u32 total_allocated;
- u32 total_freed;
- u32 current_total_size;
- u32 cache_requests;
- u32 cache_hits;
- char *list_name;
+ u32 total_allocated;
+ u32 total_freed;
+ u32 current_total_size;
+ u32 requests;
+ u32 hits;
#endif
};
-
-#endif /* __ACLOCAL_H__ */
+#endif /* __ACLOCAL_H__ */
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 09be937d2c39..702cc4e57f5f 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -44,7 +44,6 @@
#ifndef __ACMACROS_H__
#define __ACMACROS_H__
-
/*
* Data manipulation macros
*/
@@ -57,7 +56,6 @@
#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit))
#define ACPI_MIN(a,b) (((a)<(b))?(a):(b))
-
#if ACPI_MACHINE_WIDTH == 16
/*
@@ -168,7 +166,7 @@
/* 32-bit source, 16/32/64 destination */
-#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
#define ACPI_MOVE_32_TO_32(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\
(( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\
@@ -183,9 +181,9 @@
/* 64-bit source, 16/32/64 destination */
-#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
-#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
#define ACPI_MOVE_64_TO_64(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[7];\
(( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[6];\
@@ -219,14 +217,14 @@
/* 32-bit source, 16/32/64 destination */
-#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
#define ACPI_MOVE_32_TO_32(d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s)
#define ACPI_MOVE_32_TO_64(d,s) ACPI_MOVE_32_TO_32(d,s)
/* 64-bit source, 16/32/64 destination */
-#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
-#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
#define ACPI_MOVE_64_TO_64(d,s) ACPI_MOVE_32_TO_32(d,s)
#else
@@ -238,14 +236,14 @@
/* 32-bit source, 16/32/64 destination */
-#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
#define ACPI_MOVE_32_TO_32(d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s)
#define ACPI_MOVE_32_TO_64(d,s) *(u64 *)(void *)(d) = *(u32 *)(void *)(s)
/* 64-bit source, 16/32/64 destination */
-#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
-#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
#define ACPI_MOVE_64_TO_64(d,s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s)
#endif
@@ -266,7 +264,7 @@
/* 32-bit source, 16/32/64 destination */
-#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
#define ACPI_MOVE_32_TO_32(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
(( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
@@ -277,8 +275,8 @@
/* 64-bit source, 16/32/64 destination */
-#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
-#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */
#define ACPI_MOVE_64_TO_64(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
(( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
(( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
@@ -305,7 +303,6 @@
#error unknown ACPI_MACHINE_WIDTH
#endif
-
/*
* Fast power-of-two math macros for non-optimized compilers
*/
@@ -329,7 +326,6 @@
#define ACPI_MUL_16(a) _ACPI_MUL(a,4)
#define ACPI_MOD_16(a) _ACPI_MOD(a,16)
-
/*
* Rounding macros (Power of two boundaries only)
*/
@@ -344,7 +340,6 @@
#define ACPI_ROUND_UP_to_64_bITS(a) ACPI_ROUND_UP(a,8)
#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY)
-
#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7)
#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a))
@@ -365,7 +360,6 @@
#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7'))
-
/* Bitfields within ACPI registers */
#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask)
@@ -381,7 +375,6 @@
#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->descriptor_id)
#define ACPI_SET_DESCRIPTOR_TYPE(d,t) (((union acpi_descriptor *)(void *)(d))->descriptor_id = t)
-
/* Macro to test the object type */
#define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type)
@@ -430,28 +423,28 @@
#define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F))
#define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH))
-
/*
* Reporting macros that are never compiled out
*/
#define ACPI_PARAM_LIST(pl) pl
/*
- * Error reporting. These versions add callers module and line#. Since
- * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only
- * use it in debug mode.
+ * Error reporting. These versions add callers module and line#.
+ *
+ * Since _acpi_module_name gets compiled out when ACPI_DEBUG_OUTPUT
+ * isn't defined, only use it in debug mode.
*/
#ifdef ACPI_DEBUG_OUTPUT
-#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \
+#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info(_acpi_module_name,__LINE__,_COMPONENT); \
acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \
+#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error(_acpi_module_name,__LINE__,_COMPONENT); \
acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \
+#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning(_acpi_module_name,__LINE__,_COMPONENT); \
acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error(_THIS_MODULE,__LINE__,_COMPONENT, s, e);
+#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error(_acpi_module_name,__LINE__,_COMPONENT, s, e);
-#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error(_THIS_MODULE,__LINE__,_COMPONENT, s, n, p, e);
+#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error(_acpi_module_name,__LINE__,_COMPONENT, s, n, p, e);
#else
@@ -480,36 +473,58 @@
* Debug macros that are conditionally compiled
*/
#ifdef ACPI_DEBUG_OUTPUT
+#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name;
-#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_THIS_MODULE = name;
+/*
+ * Common parameters used for debug output functions:
+ * line number, function name, module(file) name, component ID
+ */
+#define ACPI_DEBUG_PARAMETERS __LINE__, ACPI_GET_FUNCTION_NAME, _acpi_module_name, _COMPONENT
/*
- * Function entry tracing.
- * The first parameter should be the procedure name as a quoted string. This is declared
- * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
+ * Function entry tracing
+ */
+
+/*
+ * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header,
+ * define it now. This is the case where there the compiler does not support
+ * a __FUNCTION__ macro or equivalent. We save the function name on the
+ * local stack.
+ */
+#ifndef ACPI_GET_FUNCTION_NAME
+#define ACPI_GET_FUNCTION_NAME _acpi_function_name
+/*
+ * The Name parameter should be the procedure name as a quoted string.
+ * This is declared as a local string ("my_function_name") so that it can
+ * be also used by the function exit macros below.
+ * Note: (const char) is used to be compatible with the debug interfaces
+ * and macros such as __FUNCTION__.
*/
-#define ACPI_FUNCTION_NAME(a) struct acpi_debug_print_info _debug_info; \
- _debug_info.component_id = _COMPONENT; \
- _debug_info.proc_name = a; \
- _debug_info.module_name = _THIS_MODULE;
-
-#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \
- acpi_ut_trace(__LINE__,&_debug_info)
-#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \
- acpi_ut_trace_ptr(__LINE__,&_debug_info,(void *)b)
-#define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a) \
- acpi_ut_trace_u32(__LINE__,&_debug_info,(u32)b)
-#define ACPI_FUNCTION_TRACE_STR(a,b) ACPI_FUNCTION_NAME(a) \
- acpi_ut_trace_str(__LINE__,&_debug_info,(char *)b)
-
-#define ACPI_FUNCTION_ENTRY() acpi_ut_track_stack_ptr()
+#define ACPI_FUNCTION_NAME(name) const char *_acpi_function_name = name;
+
+#else
+/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */
+
+#define ACPI_FUNCTION_NAME(name)
+#endif
+
+#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \
+ acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
+#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \
+ acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS,(void *)b)
+#define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a) \
+ acpi_ut_trace_u32(ACPI_DEBUG_PARAMETERS,(u32)b)
+#define ACPI_FUNCTION_TRACE_STR(a,b) ACPI_FUNCTION_NAME(a) \
+ acpi_ut_trace_str(ACPI_DEBUG_PARAMETERS,(char *)b)
+
+#define ACPI_FUNCTION_ENTRY() acpi_ut_track_stack_ptr()
/*
* Function exit tracing.
* WARNING: These macros include a return statement. This is usually considered
* bad form, but having a separate exit macro is very ugly and difficult to maintain.
* One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
- * so that "_proc_name" is defined.
+ * so that "_acpi_function_name" is defined.
*/
#ifdef ACPI_USE_DO_WHILE_0
#define ACPI_DO_WHILE0(a) do a while(0)
@@ -517,10 +532,10 @@
#define ACPI_DO_WHILE0(a) a
#endif
-#define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_debug_info);return;})
-#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_debug_info,(s));return((s));})
-#define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_debug_info,(acpi_integer)(s));return((s));})
-#define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_debug_info,(u8 *)(s));return((s));})
+#define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(ACPI_DEBUG_PARAMETERS);return;})
+#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(ACPI_DEBUG_PARAMETERS,(s));return((s));})
+#define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(ACPI_DEBUG_PARAMETERS,(acpi_integer)(s));return((s));})
+#define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(ACPI_DEBUG_PARAMETERS,(u8 *)(s));return((s));})
/* Conditional execution */
@@ -531,12 +546,10 @@
#define ACPI_DEBUG_ONLY_MEMBERS(a) a;
#define _VERBOSE_STRUCTURES
-
/* Stack and buffer dumping */
#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a),0)
-#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
-
+#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_acpi_module_name,__LINE__)
#define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b)
#define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d)
@@ -544,7 +557,6 @@
#define ACPI_DUMP_BUFFER(a,b) acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
#define ACPI_BREAK_MSG(a) acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a))
-
/*
* Generate INT3 on ACPI_ERROR (Debug only!)
*/
@@ -565,14 +577,13 @@
#define ACPI_DEBUG_PRINT(pl) acpi_ut_debug_print ACPI_PARAM_LIST(pl)
#define ACPI_DEBUG_PRINT_RAW(pl) acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl)
-
#else
/*
* This is the non-debug case -- make everything go away,
* leaving no executable debug code!
*/
#define ACPI_MODULE_NAME(name)
-#define _THIS_MODULE ""
+#define _acpi_module_name ""
#define ACPI_DEBUG_EXEC(a)
#define ACPI_NORMAL_EXEC(a) a;
@@ -616,7 +627,6 @@
#define ACPI_DEBUGGER_EXEC(a)
#endif
-
/*
* For 16-bit code, we want to shrink some things even though
* we are using ACPI_DEBUG_OUTPUT to get the debug output
@@ -627,7 +637,6 @@
#define ACPI_DEBUG_ONLY_MEMBERS(a)
#endif
-
#ifdef ACPI_DEBUG_OUTPUT
/*
* 1) Set name to blanks
@@ -640,7 +649,6 @@
#define ACPI_ADD_OBJECT_NAME(a,b)
#endif
-
/*
* Memory allocation tracking (DEBUG ONLY)
*/
@@ -648,21 +656,20 @@
/* Memory allocation */
-#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__)
+#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__)
#define ACPI_MEM_FREE(a) acpi_os_free(a)
#define ACPI_MEM_TRACKING(a)
-
#else
/* Memory allocation */
-#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate_and_track((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_FREE(a) acpi_ut_free_and_track(a,_COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__)
+#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate_and_track((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__)
+#define ACPI_MEM_FREE(a) acpi_ut_free_and_track(a,_COMPONENT,_acpi_module_name,__LINE__)
#define ACPI_MEM_TRACKING(a) a
-#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
-#endif /* ACMACROS_H */
+#endif /* ACMACROS_H */
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index deb7cb06f5f0..4f9063f3e951 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -71,14 +71,13 @@
/* Definitions of the predefined namespace names */
-#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */
-#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */
-#define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */
+#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */
+#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */
+
+#define ACPI_PREFIX_MIXED (u32) 0x69706341 /* "Acpi" */
+#define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */
#define ACPI_NS_ROOT_PATH "\\"
#define ACPI_NS_SYSTEM_BUS "_SB_"
-
-#endif /* __ACNAMES_H__ */
-
-
+#endif /* __ACNAMES_H__ */
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index d1b3ce80056f..dd3501f7e5d6 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -44,7 +44,6 @@
#ifndef __ACNAMESP_H__
#define __ACNAMESP_H__
-
/* To search the entire name space, pass this as search_base */
#define ACPI_NS_ALL ((acpi_handle)0)
@@ -54,8 +53,8 @@
* and should be one-to-one with values of acpi_object_type
*/
#define ACPI_NS_NORMAL 0
-#define ACPI_NS_NEWSCOPE 1 /* a definition of this type opens a name scope */
-#define ACPI_NS_LOCAL 2 /* suppress search of enclosing scopes */
+#define ACPI_NS_NEWSCOPE 1 /* a definition of this type opens a name scope */
+#define ACPI_NS_LOCAL 2 /* suppress search of enclosing scopes */
/* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */
@@ -68,357 +67,237 @@
#define ACPI_NS_WALK_UNLOCK TRUE
#define ACPI_NS_WALK_NO_UNLOCK FALSE
-
/*
* nsinit - Namespace initialization
*/
-acpi_status
-acpi_ns_initialize_objects (
- void);
-
-acpi_status
-acpi_ns_initialize_devices (
- void);
+acpi_status acpi_ns_initialize_objects(void);
+acpi_status acpi_ns_initialize_devices(void);
/*
* nsload - Namespace loading
*/
-acpi_status
-acpi_ns_load_namespace (
- void);
+acpi_status acpi_ns_load_namespace(void);
acpi_status
-acpi_ns_load_table (
- struct acpi_table_desc *table_desc,
- struct acpi_namespace_node *node);
-
+acpi_ns_load_table(struct acpi_table_desc *table_desc,
+ struct acpi_namespace_node *node);
/*
* nswalk - walk the namespace
*/
acpi_status
-acpi_ns_walk_namespace (
- acpi_object_type type,
- acpi_handle start_object,
- u32 max_depth,
- u8 unlock_before_callback,
- acpi_walk_callback user_function,
- void *context,
- void **return_value);
-
-struct acpi_namespace_node *
-acpi_ns_get_next_node (
- acpi_object_type type,
- struct acpi_namespace_node *parent,
- struct acpi_namespace_node *child);
-
+acpi_ns_walk_namespace(acpi_object_type type,
+ acpi_handle start_object,
+ u32 max_depth,
+ u8 unlock_before_callback,
+ acpi_walk_callback user_function,
+ void *context, void **return_value);
+
+struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type,
+ struct acpi_namespace_node
+ *parent,
+ struct acpi_namespace_node
+ *child);
/*
* nsparse - table parsing
*/
acpi_status
-acpi_ns_parse_table (
- struct acpi_table_desc *table_desc,
- struct acpi_namespace_node *scope);
+acpi_ns_parse_table(struct acpi_table_desc *table_desc,
+ struct acpi_namespace_node *scope);
acpi_status
-acpi_ns_one_complete_parse (
- u32 pass_number,
- struct acpi_table_desc *table_desc);
-
+acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc);
/*
* nsaccess - Top-level namespace access
*/
-acpi_status
-acpi_ns_root_initialize (
- void);
+acpi_status acpi_ns_root_initialize(void);
acpi_status
-acpi_ns_lookup (
- union acpi_generic_state *scope_info,
- char *name,
- acpi_object_type type,
- acpi_interpreter_mode interpreter_mode,
- u32 flags,
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node **ret_node);
-
+acpi_ns_lookup(union acpi_generic_state *scope_info,
+ char *name,
+ acpi_object_type type,
+ acpi_interpreter_mode interpreter_mode,
+ u32 flags,
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node **ret_node);
/*
* nsalloc - Named object allocation/deallocation
*/
-struct acpi_namespace_node *
-acpi_ns_create_node (
- u32 name);
-
-void
-acpi_ns_delete_node (
- struct acpi_namespace_node *node);
+struct acpi_namespace_node *acpi_ns_create_node(u32 name);
-void
-acpi_ns_delete_namespace_subtree (
- struct acpi_namespace_node *parent_handle);
+void acpi_ns_delete_node(struct acpi_namespace_node *node);
void
-acpi_ns_delete_namespace_by_owner (
- u16 table_id);
+acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle);
-void
-acpi_ns_detach_object (
- struct acpi_namespace_node *node);
+void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id);
-void
-acpi_ns_delete_children (
- struct acpi_namespace_node *parent);
+void acpi_ns_detach_object(struct acpi_namespace_node *node);
-int
-acpi_ns_compare_names (
- char *name1,
- char *name2);
+void acpi_ns_delete_children(struct acpi_namespace_node *parent);
+int acpi_ns_compare_names(char *name1, char *name2);
/*
* nsdump - Namespace dump/print utilities
*/
#ifdef ACPI_FUTURE_USAGE
-void
-acpi_ns_dump_tables (
- acpi_handle search_base,
- u32 max_depth);
-#endif /* ACPI_FUTURE_USAGE */
+void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth);
+#endif /* ACPI_FUTURE_USAGE */
-void
-acpi_ns_dump_entry (
- acpi_handle handle,
- u32 debug_level);
+void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level);
void
-acpi_ns_dump_pathname (
- acpi_handle handle,
- char *msg,
- u32 level,
- u32 component);
+acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component);
-void
-acpi_ns_print_pathname (
- u32 num_segments,
- char *pathname);
+void acpi_ns_print_pathname(u32 num_segments, char *pathname);
acpi_status
-acpi_ns_dump_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value);
+acpi_ns_dump_one_object(acpi_handle obj_handle,
+ u32 level, void *context, void **return_value);
#ifdef ACPI_FUTURE_USAGE
void
-acpi_ns_dump_objects (
- acpi_object_type type,
- u8 display_type,
- u32 max_depth,
- u32 ownder_id,
- acpi_handle start_handle);
-#endif /* ACPI_FUTURE_USAGE */
-
+acpi_ns_dump_objects(acpi_object_type type,
+ u8 display_type,
+ u32 max_depth,
+ acpi_owner_id owner_id, acpi_handle start_handle);
+#endif /* ACPI_FUTURE_USAGE */
/*
* nseval - Namespace evaluation functions
*/
-acpi_status
-acpi_ns_evaluate_by_handle (
- struct acpi_parameter_info *info);
+acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info);
acpi_status
-acpi_ns_evaluate_by_name (
- char *pathname,
- struct acpi_parameter_info *info);
+acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info);
acpi_status
-acpi_ns_evaluate_relative (
- char *pathname,
- struct acpi_parameter_info *info);
-
+acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info);
/*
* nsnames - Name and Scope manipulation
*/
-u32
-acpi_ns_opens_scope (
- acpi_object_type type);
+u32 acpi_ns_opens_scope(acpi_object_type type);
-char *
-acpi_ns_get_external_pathname (
- struct acpi_namespace_node *node);
+char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node);
-char *
-acpi_ns_name_of_current_scope (
- struct acpi_walk_state *walk_state);
+char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ns_handle_to_pathname (
- acpi_handle target_handle,
- struct acpi_buffer *buffer);
+acpi_ns_handle_to_pathname(acpi_handle target_handle,
+ struct acpi_buffer *buffer);
u8
-acpi_ns_pattern_match (
- struct acpi_namespace_node *obj_node,
- char *search_for);
+acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for);
acpi_status
-acpi_ns_get_node_by_path (
- char *external_pathname,
- struct acpi_namespace_node *in_prefix_node,
- u32 flags,
- struct acpi_namespace_node **out_node);
-
-acpi_size
-acpi_ns_get_pathname_length (
- struct acpi_namespace_node *node);
+acpi_ns_get_node_by_path(char *external_pathname,
+ struct acpi_namespace_node *in_prefix_node,
+ u32 flags, struct acpi_namespace_node **out_node);
+acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node);
/*
* nsobject - Object management for namespace nodes
*/
acpi_status
-acpi_ns_attach_object (
- struct acpi_namespace_node *node,
- union acpi_operand_object *object,
- acpi_object_type type);
+acpi_ns_attach_object(struct acpi_namespace_node *node,
+ union acpi_operand_object *object, acpi_object_type type);
-union acpi_operand_object *
-acpi_ns_get_attached_object (
- struct acpi_namespace_node *node);
+union acpi_operand_object *acpi_ns_get_attached_object(struct
+ acpi_namespace_node
+ *node);
-union acpi_operand_object *
-acpi_ns_get_secondary_object (
- union acpi_operand_object *obj_desc);
+union acpi_operand_object *acpi_ns_get_secondary_object(union
+ acpi_operand_object
+ *obj_desc);
acpi_status
-acpi_ns_attach_data (
- struct acpi_namespace_node *node,
- acpi_object_handler handler,
- void *data);
+acpi_ns_attach_data(struct acpi_namespace_node *node,
+ acpi_object_handler handler, void *data);
acpi_status
-acpi_ns_detach_data (
- struct acpi_namespace_node *node,
- acpi_object_handler handler);
+acpi_ns_detach_data(struct acpi_namespace_node *node,
+ acpi_object_handler handler);
acpi_status
-acpi_ns_get_attached_data (
- struct acpi_namespace_node *node,
- acpi_object_handler handler,
- void **data);
-
+acpi_ns_get_attached_data(struct acpi_namespace_node *node,
+ acpi_object_handler handler, void **data);
/*
* nssearch - Namespace searching and entry
*/
acpi_status
-acpi_ns_search_and_enter (
- u32 entry_name,
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node *node,
- acpi_interpreter_mode interpreter_mode,
- acpi_object_type type,
- u32 flags,
- struct acpi_namespace_node **ret_node);
+acpi_ns_search_and_enter(u32 entry_name,
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node *node,
+ acpi_interpreter_mode interpreter_mode,
+ acpi_object_type type,
+ u32 flags, struct acpi_namespace_node **ret_node);
acpi_status
-acpi_ns_search_node (
- u32 entry_name,
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_namespace_node **ret_node);
+acpi_ns_search_node(u32 entry_name,
+ struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_namespace_node **ret_node);
void
-acpi_ns_install_node (
- struct acpi_walk_state *walk_state,
- struct acpi_namespace_node *parent_node,
- struct acpi_namespace_node *node,
- acpi_object_type type);
-
+acpi_ns_install_node(struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node *parent_node,
+ struct acpi_namespace_node *node, acpi_object_type type);
/*
* nsutils - Utility functions
*/
-u8
-acpi_ns_valid_root_prefix (
- char prefix);
+u8 acpi_ns_valid_root_prefix(char prefix);
-acpi_object_type
-acpi_ns_get_type (
- struct acpi_namespace_node *node);
+acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
-u32
-acpi_ns_local (
- acpi_object_type type);
+u32 acpi_ns_local(acpi_object_type type);
void
-acpi_ns_report_error (
- char *module_name,
- u32 line_number,
- u32 component_id,
- char *internal_name,
- acpi_status lookup_status);
+acpi_ns_report_error(char *module_name,
+ u32 line_number,
+ u32 component_id,
+ char *internal_name, acpi_status lookup_status);
void
-acpi_ns_report_method_error (
- char *module_name,
- u32 line_number,
- u32 component_id,
- char *message,
- struct acpi_namespace_node *node,
- char *path,
- acpi_status lookup_status);
+acpi_ns_report_method_error(char *module_name,
+ u32 line_number,
+ u32 component_id,
+ char *message,
+ struct acpi_namespace_node *node,
+ char *path, acpi_status lookup_status);
-void
-acpi_ns_print_node_pathname (
- struct acpi_namespace_node *node,
- char *msg);
+void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *msg);
-acpi_status
-acpi_ns_build_internal_name (
- struct acpi_namestring_info *info);
+acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info);
-void
-acpi_ns_get_internal_name_length (
- struct acpi_namestring_info *info);
+void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info);
-acpi_status
-acpi_ns_internalize_name (
- char *dotted_name,
- char **converted_name);
+acpi_status acpi_ns_internalize_name(char *dotted_name, char **converted_name);
acpi_status
-acpi_ns_externalize_name (
- u32 internal_name_length,
- char *internal_name,
- u32 *converted_name_length,
- char **converted_name);
+acpi_ns_externalize_name(u32 internal_name_length,
+ char *internal_name,
+ u32 * converted_name_length, char **converted_name);
-struct acpi_namespace_node *
-acpi_ns_map_handle_to_node (
- acpi_handle handle);
+struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle);
-acpi_handle
-acpi_ns_convert_entry_to_handle(
- struct acpi_namespace_node *node);
-
-void
-acpi_ns_terminate (
- void);
+acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node);
-struct acpi_namespace_node *
-acpi_ns_get_parent_node (
- struct acpi_namespace_node *node);
+void acpi_ns_terminate(void);
+struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node
+ *node);
-struct acpi_namespace_node *
-acpi_ns_get_next_valid_node (
- struct acpi_namespace_node *node);
+struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct
+ acpi_namespace_node
+ *node);
-#endif /* __ACNAMESP_H__ */
+#endif /* __ACNAMESP_H__ */
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index e079b94e4fce..4a326ba6d482 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -45,7 +45,6 @@
#ifndef _ACOBJECT_H
#define _ACOBJECT_H
-
/*
* The union acpi_operand_object is used to pass AML operands from the dispatcher
* to the interpreter, and to keep track of the various handlers such as
@@ -81,7 +80,6 @@
#define AOPOBJ_SETUP_COMPLETE 0x10
#define AOPOBJ_SINGLE_DATUM 0x20
-
/*
* Common bitfield for the field objects
* "Field Datum" -- a datum from the actual field object
@@ -96,8 +94,7 @@
u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
u8 access_bit_width; /* Read/Write size in bits (8-64) */\
u32 value; /* Value to store into the Bank or Index register */\
- struct acpi_namespace_node *node; /* Link back to parent node */
-
+ struct acpi_namespace_node *node; /* Link back to parent node */
/*
* Fields common to both Strings and Buffers
@@ -105,15 +102,13 @@
#define ACPI_COMMON_BUFFER_INFO \
u32 length;
-
/*
* Common fields for objects that support ASL notifications
*/
#define ACPI_COMMON_NOTIFY_INFO \
union acpi_operand_object *system_notify; /* Handler for system notifies */\
union acpi_operand_object *device_notify; /* Handler for driver notifies */\
- union acpi_operand_object *handler; /* Handler for Address space */
-
+ union acpi_operand_object *handler; /* Handler for Address space */
/******************************************************************************
*
@@ -121,161 +116,110 @@
*
*****************************************************************************/
-struct acpi_object_common
-{
- ACPI_OBJECT_COMMON_HEADER
-};
+struct acpi_object_common {
+ACPI_OBJECT_COMMON_HEADER};
-
-struct acpi_object_integer
-{
- ACPI_OBJECT_COMMON_HEADER
- acpi_integer value;
+struct acpi_object_integer {
+ ACPI_OBJECT_COMMON_HEADER acpi_integer value;
};
-
/*
* Note: The String and Buffer object must be identical through the Pointer
* element. There is code that depends on this.
*/
-struct acpi_object_string /* Null terminated, ASCII characters only */
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_BUFFER_INFO
- char *pointer; /* String in AML stream or allocated string */
+struct acpi_object_string { /* Null terminated, ASCII characters only */
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_BUFFER_INFO char *pointer; /* String in AML stream or allocated string */
};
-
-struct acpi_object_buffer
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_BUFFER_INFO
- u8 *pointer; /* Buffer in AML stream or allocated buffer */
- struct acpi_namespace_node *node; /* Link back to parent node */
- u8 *aml_start;
- u32 aml_length;
+struct acpi_object_buffer {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_BUFFER_INFO u8 * pointer; /* Buffer in AML stream or allocated buffer */
+ struct acpi_namespace_node *node; /* Link back to parent node */
+ u8 *aml_start;
+ u32 aml_length;
};
-
-struct acpi_object_package
-{
- ACPI_OBJECT_COMMON_HEADER
-
- u32 count; /* # of elements in package */
- u32 aml_length;
- u8 *aml_start;
- struct acpi_namespace_node *node; /* Link back to parent node */
- union acpi_operand_object **elements; /* Array of pointers to acpi_objects */
+struct acpi_object_package {
+ ACPI_OBJECT_COMMON_HEADER u32 count; /* # of elements in package */
+ u32 aml_length;
+ u8 *aml_start;
+ struct acpi_namespace_node *node; /* Link back to parent node */
+ union acpi_operand_object **elements; /* Array of pointers to acpi_objects */
};
-
/******************************************************************************
*
* Complex data types
*
*****************************************************************************/
-struct acpi_object_event
-{
- ACPI_OBJECT_COMMON_HEADER
- void *semaphore;
+struct acpi_object_event {
+ ACPI_OBJECT_COMMON_HEADER void *semaphore;
};
-
#define ACPI_INFINITE_CONCURRENCY 0xFF
typedef
-acpi_status (*ACPI_INTERNAL_METHOD) (
- struct acpi_walk_state *walk_state);
-
-struct acpi_object_method
-{
- ACPI_OBJECT_COMMON_HEADER
- u8 method_flags;
- u8 param_count;
- u32 aml_length;
- void *semaphore;
- u8 *aml_start;
- ACPI_INTERNAL_METHOD implementation;
- u8 concurrency;
- u8 thread_count;
- acpi_owner_id owning_id;
+acpi_status(*ACPI_INTERNAL_METHOD) (struct acpi_walk_state * walk_state);
+
+struct acpi_object_method {
+ ACPI_OBJECT_COMMON_HEADER u8 method_flags;
+ u8 param_count;
+ u32 aml_length;
+ void *semaphore;
+ u8 *aml_start;
+ ACPI_INTERNAL_METHOD implementation;
+ u8 concurrency;
+ u8 thread_count;
+ acpi_owner_id owner_id;
};
-
-struct acpi_object_mutex
-{
- ACPI_OBJECT_COMMON_HEADER
- u8 sync_level; /* 0-15, specified in Mutex() call */
- u16 acquisition_depth; /* Allow multiple Acquires, same thread */
- struct acpi_thread_state *owner_thread; /* Current owner of the mutex */
- void *semaphore; /* Actual OS synchronization object */
- union acpi_operand_object *prev; /* Link for list of acquired mutexes */
- union acpi_operand_object *next; /* Link for list of acquired mutexes */
- struct acpi_namespace_node *node; /* Containing namespace node */
- u8 original_sync_level; /* Owner's original sync level (0-15) */
+struct acpi_object_mutex {
+ ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */
+ u16 acquisition_depth; /* Allow multiple Acquires, same thread */
+ struct acpi_thread_state *owner_thread; /* Current owner of the mutex */
+ void *semaphore; /* Actual OS synchronization object */
+ union acpi_operand_object *prev; /* Link for list of acquired mutexes */
+ union acpi_operand_object *next; /* Link for list of acquired mutexes */
+ struct acpi_namespace_node *node; /* Containing namespace node */
+ u8 original_sync_level; /* Owner's original sync level (0-15) */
};
-
-struct acpi_object_region
-{
- ACPI_OBJECT_COMMON_HEADER
-
- u8 space_id;
- union acpi_operand_object *handler; /* Handler for region access */
- struct acpi_namespace_node *node; /* Containing namespace node */
- union acpi_operand_object *next;
- u32 length;
- acpi_physical_address address;
+struct acpi_object_region {
+ ACPI_OBJECT_COMMON_HEADER u8 space_id;
+ union acpi_operand_object *handler; /* Handler for region access */
+ struct acpi_namespace_node *node; /* Containing namespace node */
+ union acpi_operand_object *next;
+ u32 length;
+ acpi_physical_address address;
};
-
/******************************************************************************
*
* Objects that can be notified. All share a common notify_info area.
*
*****************************************************************************/
-struct acpi_object_notify_common /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_NOTIFY_INFO
-};
-
-
-struct acpi_object_device
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_NOTIFY_INFO
- struct acpi_gpe_block_info *gpe_block;
-};
-
+struct acpi_object_notify_common { /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
+ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
-struct acpi_object_power_resource
-{
+struct acpi_object_device {
ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_NOTIFY_INFO
- u32 system_level;
- u32 resource_order;
+ ACPI_COMMON_NOTIFY_INFO struct acpi_gpe_block_info *gpe_block;
};
-
-struct acpi_object_processor
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_NOTIFY_INFO
- u32 proc_id;
- u32 length;
- acpi_io_address address;
+struct acpi_object_power_resource {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO u32 system_level;
+ u32 resource_order;
};
-
-struct acpi_object_thermal_zone
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_NOTIFY_INFO
+struct acpi_object_processor {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO u32 proc_id;
+ u32 length;
+ acpi_io_address address;
};
+struct acpi_object_thermal_zone {
+ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
/******************************************************************************
*
@@ -283,90 +227,63 @@ struct acpi_object_thermal_zone
*
*****************************************************************************/
-struct acpi_object_field_common /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_FIELD_INFO
- union acpi_operand_object *region_obj; /* Containing Operation Region object */
- /* (REGION/BANK fields only) */
+struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Containing Operation Region object */
+ /* (REGION/BANK fields only) */
};
-
-struct acpi_object_region_field
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_FIELD_INFO
- union acpi_operand_object *region_obj; /* Containing op_region object */
+struct acpi_object_region_field {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Containing op_region object */
};
-
-struct acpi_object_bank_field
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_FIELD_INFO
- union acpi_operand_object *region_obj; /* Containing op_region object */
- union acpi_operand_object *bank_obj; /* bank_select Register object */
+struct acpi_object_bank_field {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Containing op_region object */
+ union acpi_operand_object *bank_obj; /* bank_select Register object */
};
-
-struct acpi_object_index_field
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_FIELD_INFO
-
- /*
- * No "region_obj" pointer needed since the Index and Data registers
- * are each field definitions unto themselves.
- */
- union acpi_operand_object *index_obj; /* Index register */
- union acpi_operand_object *data_obj; /* Data register */
+struct acpi_object_index_field {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO
+ /*
+ * No "region_obj" pointer needed since the Index and Data registers
+ * are each field definitions unto themselves.
+ */
+ union acpi_operand_object *index_obj; /* Index register */
+ union acpi_operand_object *data_obj; /* Data register */
};
-
/* The buffer_field is different in that it is part of a Buffer, not an op_region */
-struct acpi_object_buffer_field
-{
- ACPI_OBJECT_COMMON_HEADER
- ACPI_COMMON_FIELD_INFO
- union acpi_operand_object *buffer_obj; /* Containing Buffer object */
+struct acpi_object_buffer_field {
+ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *buffer_obj; /* Containing Buffer object */
};
-
/******************************************************************************
*
* Objects for handlers
*
*****************************************************************************/
-struct acpi_object_notify_handler
-{
- ACPI_OBJECT_COMMON_HEADER
- struct acpi_namespace_node *node; /* Parent device */
- acpi_notify_handler handler;
- void *context;
+struct acpi_object_notify_handler {
+ ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */
+ acpi_notify_handler handler;
+ void *context;
};
-
/* Flags for address handler */
#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED 0x1
-
-struct acpi_object_addr_handler
-{
- ACPI_OBJECT_COMMON_HEADER
- u8 space_id;
- u16 hflags;
- acpi_adr_space_handler handler;
- struct acpi_namespace_node *node; /* Parent device */
- void *context;
- acpi_adr_space_setup setup;
- union acpi_operand_object *region_list; /* regions using this handler */
- union acpi_operand_object *next;
+struct acpi_object_addr_handler {
+ ACPI_OBJECT_COMMON_HEADER u8 space_id;
+ u16 hflags;
+ acpi_adr_space_handler handler;
+ struct acpi_namespace_node *node; /* Parent device */
+ void *context;
+ acpi_adr_space_setup setup;
+ union acpi_operand_object *region_list; /* regions using this handler */
+ union acpi_operand_object *next;
};
-
/******************************************************************************
*
* Special internal objects
@@ -377,18 +294,15 @@ struct acpi_object_addr_handler
* The Reference object type is used for these opcodes:
* Arg[0-6], Local[0-7], index_op, name_op, zero_op, one_op, ones_op, debug_op
*/
-struct acpi_object_reference
-{
- ACPI_OBJECT_COMMON_HEADER
- u8 target_type; /* Used for index_op */
- u16 opcode;
- u32 offset; /* Used for arg_op, local_op, and index_op */
- void *object; /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object */
- struct acpi_namespace_node *node;
- union acpi_operand_object **where;
+struct acpi_object_reference {
+ ACPI_OBJECT_COMMON_HEADER u8 target_type; /* Used for index_op */
+ u16 opcode;
+ u32 offset; /* Used for arg_op, local_op, and index_op */
+ void *object; /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object */
+ struct acpi_namespace_node *node;
+ union acpi_operand_object **where;
};
-
/*
* Extra object is used as additional storage for types that
* have AML code in their declarations (term_args) that must be
@@ -396,73 +310,62 @@ struct acpi_object_reference
*
* Currently: Region and field_unit types
*/
-struct acpi_object_extra
-{
- ACPI_OBJECT_COMMON_HEADER
- u8 byte_fill1;
- u16 word_fill1;
- u32 aml_length;
- u8 *aml_start;
- struct acpi_namespace_node *method_REG; /* _REG method for this region (if any) */
- void *region_context; /* Region-specific data */
+struct acpi_object_extra {
+ ACPI_OBJECT_COMMON_HEADER u8 byte_fill1;
+ u16 word_fill1;
+ u32 aml_length;
+ u8 *aml_start;
+ struct acpi_namespace_node *method_REG; /* _REG method for this region (if any) */
+ void *region_context; /* Region-specific data */
};
-
/* Additional data that can be attached to namespace nodes */
-struct acpi_object_data
-{
- ACPI_OBJECT_COMMON_HEADER
- acpi_object_handler handler;
- void *pointer;
+struct acpi_object_data {
+ ACPI_OBJECT_COMMON_HEADER acpi_object_handler handler;
+ void *pointer;
};
-
/* Structure used when objects are cached for reuse */
-struct acpi_object_cache_list
-{
- ACPI_OBJECT_COMMON_HEADER
- union acpi_operand_object *next; /* Link for object cache and internal lists*/
+struct acpi_object_cache_list {
+ ACPI_OBJECT_COMMON_HEADER union acpi_operand_object *next; /* Link for object cache and internal lists */
};
-
/******************************************************************************
*
* union acpi_operand_object Descriptor - a giant union of all of the above
*
*****************************************************************************/
-union acpi_operand_object
-{
- struct acpi_object_common common;
- struct acpi_object_integer integer;
- struct acpi_object_string string;
- struct acpi_object_buffer buffer;
- struct acpi_object_package package;
- struct acpi_object_event event;
- struct acpi_object_method method;
- struct acpi_object_mutex mutex;
- struct acpi_object_region region;
- struct acpi_object_notify_common common_notify;
- struct acpi_object_device device;
- struct acpi_object_power_resource power_resource;
- struct acpi_object_processor processor;
- struct acpi_object_thermal_zone thermal_zone;
- struct acpi_object_field_common common_field;
- struct acpi_object_region_field field;
- struct acpi_object_buffer_field buffer_field;
- struct acpi_object_bank_field bank_field;
- struct acpi_object_index_field index_field;
- struct acpi_object_notify_handler notify;
- struct acpi_object_addr_handler address_space;
- struct acpi_object_reference reference;
- struct acpi_object_extra extra;
- struct acpi_object_data data;
- struct acpi_object_cache_list cache;
+union acpi_operand_object {
+ struct acpi_object_common common;
+ struct acpi_object_integer integer;
+ struct acpi_object_string string;
+ struct acpi_object_buffer buffer;
+ struct acpi_object_package package;
+ struct acpi_object_event event;
+ struct acpi_object_method method;
+ struct acpi_object_mutex mutex;
+ struct acpi_object_region region;
+ struct acpi_object_notify_common common_notify;
+ struct acpi_object_device device;
+ struct acpi_object_power_resource power_resource;
+ struct acpi_object_processor processor;
+ struct acpi_object_thermal_zone thermal_zone;
+ struct acpi_object_field_common common_field;
+ struct acpi_object_region_field field;
+ struct acpi_object_buffer_field buffer_field;
+ struct acpi_object_bank_field bank_field;
+ struct acpi_object_index_field index_field;
+ struct acpi_object_notify_handler notify;
+ struct acpi_object_addr_handler address_space;
+ struct acpi_object_reference reference;
+ struct acpi_object_extra extra;
+ struct acpi_object_data data;
+ struct acpi_object_cache_list cache;
};
-
/******************************************************************************
*
* union acpi_descriptor - objects that share a common descriptor identifier
@@ -471,7 +374,7 @@ union acpi_operand_object
/* Object descriptor types */
-#define ACPI_DESC_TYPE_CACHED 0x01 /* Used only when object is cached */
+#define ACPI_DESC_TYPE_CACHED 0x01 /* Used only when object is cached */
#define ACPI_DESC_TYPE_STATE 0x02
#define ACPI_DESC_TYPE_STATE_UPDATE 0x03
#define ACPI_DESC_TYPE_STATE_PACKAGE 0x04
@@ -488,14 +391,11 @@ union acpi_operand_object
#define ACPI_DESC_TYPE_NAMED 0x0F
#define ACPI_DESC_TYPE_MAX 0x0F
-
-union acpi_descriptor
-{
- u8 descriptor_id; /* To differentiate various internal objs */\
- union acpi_operand_object object;
- struct acpi_namespace_node node;
- union acpi_parse_object op;
+union acpi_descriptor {
+ u8 descriptor_id; /* To differentiate various internal objs */
+ union acpi_operand_object object;
+ struct acpi_namespace_node node;
+ union acpi_parse_object op;
};
-
-#endif /* _ACOBJECT_H */
+#endif /* _ACOBJECT_H */
diff --git a/include/acpi/acopcode.h b/include/acpi/acopcode.h
index 118ecba4cf05..64da42992199 100644
--- a/include/acpi/acopcode.h
+++ b/include/acpi/acopcode.h
@@ -62,7 +62,6 @@
#define _NAM 0x6C
#define _PFX 0x6D
-
/*
* All AML opcodes and the parse-time arguments for each. Used by the AML
* parser Each list is compressed into a 32-bit number and stored in the
@@ -191,7 +190,6 @@
#define ARGP_WORD_OP ARGP_LIST1 (ARGP_WORDDATA)
#define ARGP_ZERO_OP ARG_NONE
-
/*
* All AML opcodes and the runtime arguments for each. Used by the AML
* interpreter Each list is compressed into a 32-bit number and stored
@@ -246,7 +244,7 @@
#define ARGI_FIELD_OP ARGI_INVALID_OPCODE
#define ARGI_FIND_SET_LEFT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
#define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET)
#define ARGI_IF_OP ARGI_INVALID_OPCODE
#define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF)
#define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE
@@ -322,4 +320,4 @@
#define ARGI_WORD_OP ARGI_INVALID_OPCODE
#define ARGI_ZERO_OP ARG_NONE
-#endif /* __ACOPCODE_H__ */
+#endif /* __ACOPCODE_H__ */
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h
index 2fbe180fee6b..68d7edf0f697 100644
--- a/include/acpi/acoutput.h
+++ b/include/acpi/acoutput.h
@@ -73,12 +73,10 @@
#define ACPI_ALL_COMPONENTS 0x00003FFF
#define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS)
-
/* Component IDs reserved for ACPI drivers */
#define ACPI_ALL_DRIVERS 0xFFFF0000
-
/*
* Raw debug output levels, do not use these in the DEBUG_PRINT macros
*/
@@ -132,11 +130,10 @@
#define ACPI_LV_VERBOSE 0xF0000000
-
/*
* Debug level macros that are used in the DEBUG_PRINT macros
*/
-#define ACPI_DEBUG_LEVEL(dl) (u32) dl,__LINE__,&_debug_info
+#define ACPI_DEBUG_LEVEL(dl) (u32) dl,ACPI_DEBUG_PARAMETERS
/* Exception level -- used in the global "debug_level" */
@@ -147,7 +144,6 @@
#define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
#define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
-
/* Trace level -- also used in the global "debug_level" */
#define ACPI_DB_INIT_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
@@ -174,12 +170,10 @@
#define ACPI_DB_ALL ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
-
/* Defaults for debug_level, debug and normal */
#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
-
-#endif /* __ACOUTPUT_H__ */
+#endif /* __ACOUTPUT_H__ */
diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h
index 698276571818..d352d40de1f3 100644
--- a/include/acpi/acparser.h
+++ b/include/acpi/acparser.h
@@ -41,18 +41,15 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#ifndef __ACPARSER_H__
#define __ACPARSER_H__
-
#define OP_HAS_RETURN_VALUE 1
/* variable # arguments */
#define ACPI_VAR_ARGS ACPI_UINT32_MAX
-
#define ACPI_PARSE_DELETE_TREE 0x0001
#define ACPI_PARSE_NO_TREE_DELETE 0x0000
#define ACPI_PARSE_TREE_MASK 0x0001
@@ -63,7 +60,7 @@
#define ACPI_PARSE_MODE_MASK 0x0030
#define ACPI_PARSE_DEFERRED_OP 0x0100
-
+#define ACPI_PARSE_DISASSEMBLE 0x0200
/******************************************************************************
*
@@ -71,251 +68,165 @@
*
*****************************************************************************/
-
/*
* psxface - Parser external interfaces
*/
-acpi_status
-acpi_psx_load_table (
- u8 *pcode_addr,
- u32 pcode_length);
-
-acpi_status
-acpi_psx_execute (
- struct acpi_parameter_info *info);
-
+acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info);
/*
* psargs - Parse AML opcode arguments
*/
-u8 *
-acpi_ps_get_next_package_end (
- struct acpi_parse_state *parser_state);
+u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state);
-char *
-acpi_ps_get_next_namestring (
- struct acpi_parse_state *parser_state);
+char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state);
void
-acpi_ps_get_next_simple_arg (
- struct acpi_parse_state *parser_state,
- u32 arg_type,
- union acpi_parse_object *arg);
+acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
+ u32 arg_type, union acpi_parse_object *arg);
acpi_status
-acpi_ps_get_next_namepath (
- struct acpi_walk_state *walk_state,
- struct acpi_parse_state *parser_state,
- union acpi_parse_object *arg,
- u8 method_call);
+acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
+ struct acpi_parse_state *parser_state,
+ union acpi_parse_object *arg, u8 method_call);
acpi_status
-acpi_ps_get_next_arg (
- struct acpi_walk_state *walk_state,
- struct acpi_parse_state *parser_state,
- u32 arg_type,
- union acpi_parse_object **return_arg);
-
+acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
+ struct acpi_parse_state *parser_state,
+ u32 arg_type, union acpi_parse_object **return_arg);
/*
* psfind
*/
-union acpi_parse_object *
-acpi_ps_find_name (
- union acpi_parse_object *scope,
- u32 name,
- u32 opcode);
-
-union acpi_parse_object*
-acpi_ps_get_parent (
- union acpi_parse_object *op);
+union acpi_parse_object *acpi_ps_find_name(union acpi_parse_object *scope,
+ u32 name, u32 opcode);
+union acpi_parse_object *acpi_ps_get_parent(union acpi_parse_object *op);
/*
* psopcode - AML Opcode information
*/
-const struct acpi_opcode_info *
-acpi_ps_get_opcode_info (
- u16 opcode);
-
-char *
-acpi_ps_get_opcode_name (
- u16 opcode);
+const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode);
+char *acpi_ps_get_opcode_name(u16 opcode);
/*
* psparse - top level parsing routines
*/
-acpi_status
-acpi_ps_parse_aml (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state);
-u32
-acpi_ps_get_opcode_size (
- u32 opcode);
+u32 acpi_ps_get_opcode_size(u32 opcode);
-u16
-acpi_ps_peek_opcode (
- struct acpi_parse_state *state);
+u16 acpi_ps_peek_opcode(struct acpi_parse_state *state);
+acpi_status
+acpi_ps_complete_this_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
+
+acpi_status
+acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ acpi_status callback_status);
+
+/*
+ * psloop - main parse loop
+ */
+acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state);
/*
* psscope - Scope stack management routines
*/
acpi_status
-acpi_ps_init_scope (
- struct acpi_parse_state *parser_state,
- union acpi_parse_object *root);
+acpi_ps_init_scope(struct acpi_parse_state *parser_state,
+ union acpi_parse_object *root);
-union acpi_parse_object *
-acpi_ps_get_parent_scope (
- struct acpi_parse_state *state);
+union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
+ *state);
-u8
-acpi_ps_has_completed_scope (
- struct acpi_parse_state *parser_state);
+u8 acpi_ps_has_completed_scope(struct acpi_parse_state *parser_state);
void
-acpi_ps_pop_scope (
- struct acpi_parse_state *parser_state,
- union acpi_parse_object **op,
- u32 *arg_list,
- u32 *arg_count);
+acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
+ union acpi_parse_object **op,
+ u32 * arg_list, u32 * arg_count);
acpi_status
-acpi_ps_push_scope (
- struct acpi_parse_state *parser_state,
- union acpi_parse_object *op,
- u32 remaining_args,
- u32 arg_count);
-
-void
-acpi_ps_cleanup_scope (
- struct acpi_parse_state *state);
+acpi_ps_push_scope(struct acpi_parse_state *parser_state,
+ union acpi_parse_object *op,
+ u32 remaining_args, u32 arg_count);
+void acpi_ps_cleanup_scope(struct acpi_parse_state *state);
/*
* pstree - parse tree manipulation routines
*/
void
-acpi_ps_append_arg(
- union acpi_parse_object *op,
- union acpi_parse_object *arg);
-
-union acpi_parse_object*
-acpi_ps_find (
- union acpi_parse_object *scope,
- char *path,
- u16 opcode,
- u32 create);
-
-union acpi_parse_object *
-acpi_ps_get_arg(
- union acpi_parse_object *op,
- u32 argn);
+acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg);
-#ifdef ACPI_FUTURE_USAGE
-union acpi_parse_object *
-acpi_ps_get_depth_next (
- union acpi_parse_object *origin,
- union acpi_parse_object *op);
-#endif /* ACPI_FUTURE_USAGE */
+union acpi_parse_object *acpi_ps_find(union acpi_parse_object *scope,
+ char *path, u16 opcode, u32 create);
+union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn);
+
+#ifdef ACPI_FUTURE_USAGE
+union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
+ union acpi_parse_object *op);
+#endif /* ACPI_FUTURE_USAGE */
/*
* pswalk - parse tree walk routines
*/
acpi_status
-acpi_ps_walk_parsed_aml (
- union acpi_parse_object *start_op,
- union acpi_parse_object *end_op,
- union acpi_operand_object *mth_desc,
- struct acpi_namespace_node *start_node,
- union acpi_operand_object **params,
- union acpi_operand_object **caller_return_desc,
- acpi_owner_id owner_id,
- acpi_parse_downwards descending_callback,
- acpi_parse_upwards ascending_callback);
-
-acpi_status
-acpi_ps_get_next_walk_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- acpi_parse_upwards ascending_callback);
+acpi_ps_walk_parsed_aml(union acpi_parse_object *start_op,
+ union acpi_parse_object *end_op,
+ union acpi_operand_object *mth_desc,
+ struct acpi_namespace_node *start_node,
+ union acpi_operand_object **params,
+ union acpi_operand_object **caller_return_desc,
+ acpi_owner_id owner_id,
+ acpi_parse_downwards descending_callback,
+ acpi_parse_upwards ascending_callback);
acpi_status
-acpi_ps_delete_completed_op (
- struct acpi_walk_state *walk_state);
+acpi_ps_get_next_walk_op(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ acpi_parse_upwards ascending_callback);
-void
-acpi_ps_delete_parse_tree (
- union acpi_parse_object *root);
+acpi_status acpi_ps_delete_completed_op(struct acpi_walk_state *walk_state);
+void acpi_ps_delete_parse_tree(union acpi_parse_object *root);
/*
* psutils - parser utilities
*/
-union acpi_parse_object *
-acpi_ps_create_scope_op (
- void);
+union acpi_parse_object *acpi_ps_create_scope_op(void);
-void
-acpi_ps_init_op (
- union acpi_parse_object *op,
- u16 opcode);
+void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode);
-union acpi_parse_object *
-acpi_ps_alloc_op (
- u16 opcode);
+union acpi_parse_object *acpi_ps_alloc_op(u16 opcode);
-void
-acpi_ps_free_op (
- union acpi_parse_object *op);
+void acpi_ps_free_op(union acpi_parse_object *op);
-u8
-acpi_ps_is_leading_char (
- u32 c);
+u8 acpi_ps_is_leading_char(u32 c);
-u8
-acpi_ps_is_prefix_char (
- u32 c);
+u8 acpi_ps_is_prefix_char(u32 c);
#ifdef ACPI_FUTURE_USAGE
-u32
-acpi_ps_get_name(
- union acpi_parse_object *op);
-#endif /* ACPI_FUTURE_USAGE */
-
-void
-acpi_ps_set_name(
- union acpi_parse_object *op,
- u32 name);
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-void
-acpi_ps_delete_parse_cache (
- void);
-#endif
+u32 acpi_ps_get_name(union acpi_parse_object *op);
+#endif /* ACPI_FUTURE_USAGE */
+void acpi_ps_set_name(union acpi_parse_object *op, u32 name);
/*
* psdump - display parser tree
*/
u32
-acpi_ps_sprint_path (
- char *buffer_start,
- u32 buffer_size,
- union acpi_parse_object *op);
+acpi_ps_sprint_path(char *buffer_start,
+ u32 buffer_size, union acpi_parse_object *op);
u32
-acpi_ps_sprint_op (
- char *buffer_start,
- u32 buffer_size,
- union acpi_parse_object *op);
-
-void
-acpi_ps_show (
- union acpi_parse_object *op);
+acpi_ps_sprint_op(char *buffer_start,
+ u32 buffer_size, union acpi_parse_object *op);
+void acpi_ps_show(union acpi_parse_object *op);
-#endif /* __ACPARSER_H__ */
+#endif /* __ACPARSER_H__ */
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h
index a69d78942040..ccf34f9dac64 100644
--- a/include/acpi/acpi.h
+++ b/include/acpi/acpi.h
@@ -49,22 +49,21 @@
* We put them here because we don't want to duplicate them
* in the rest of the source code again and again.
*/
-#include "acnames.h" /* Global ACPI names and strings */
-#include "acconfig.h" /* Configuration constants */
-#include "platform/acenv.h" /* Target environment specific items */
-#include "actypes.h" /* Fundamental common data types */
-#include "acexcep.h" /* ACPI exception codes */
-#include "acmacros.h" /* C macros */
-#include "actbl.h" /* ACPI table definitions */
-#include "aclocal.h" /* Internal data types */
-#include "acoutput.h" /* Error output and Debug macros */
-#include "acpiosxf.h" /* Interfaces to the ACPI-to-OS layer*/
-#include "acpixf.h" /* ACPI core subsystem external interfaces */
-#include "acobject.h" /* ACPI internal object */
-#include "acstruct.h" /* Common structures */
-#include "acglobal.h" /* All global variables */
-#include "achware.h" /* Hardware defines and interfaces */
-#include "acutils.h" /* Utility interfaces */
+#include "acnames.h" /* Global ACPI names and strings */
+#include "acconfig.h" /* Configuration constants */
+#include "platform/acenv.h" /* Target environment specific items */
+#include "actypes.h" /* Fundamental common data types */
+#include "acexcep.h" /* ACPI exception codes */
+#include "acmacros.h" /* C macros */
+#include "actbl.h" /* ACPI table definitions */
+#include "aclocal.h" /* Internal data types */
+#include "acoutput.h" /* Error output and Debug macros */
+#include "acpiosxf.h" /* Interfaces to the ACPI-to-OS layer */
+#include "acpixf.h" /* ACPI core subsystem external interfaces */
+#include "acobject.h" /* ACPI internal object */
+#include "acstruct.h" /* Common structures */
+#include "acglobal.h" /* All global variables */
+#include "achware.h" /* Hardware defines and interfaces */
+#include "acutils.h" /* Utility interfaces */
-
-#endif /* __ACPI_H__ */
+#endif /* __ACPI_H__ */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 8d0e1290bc76..0b54e9a4a8a1 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -35,48 +35,41 @@
/* TBD: Make dynamic */
#define ACPI_MAX_HANDLES 10
struct acpi_handle_list {
- u32 count;
- acpi_handle handles[ACPI_MAX_HANDLES];
+ u32 count;
+ acpi_handle handles[ACPI_MAX_HANDLES];
};
-
/* acpi_utils.h */
acpi_status
-acpi_extract_package (
- union acpi_object *package,
- struct acpi_buffer *format,
- struct acpi_buffer *buffer);
+acpi_extract_package(union acpi_object *package,
+ struct acpi_buffer *format, struct acpi_buffer *buffer);
acpi_status
-acpi_evaluate_integer (
- acpi_handle handle,
- acpi_string pathname,
- struct acpi_object_list *arguments,
- unsigned long *data);
+acpi_evaluate_integer(acpi_handle handle,
+ acpi_string pathname,
+ struct acpi_object_list *arguments, unsigned long *data);
acpi_status
-acpi_evaluate_reference (
- acpi_handle handle,
- acpi_string pathname,
- struct acpi_object_list *arguments,
- struct acpi_handle_list *list);
-
+acpi_evaluate_reference(acpi_handle handle,
+ acpi_string pathname,
+ struct acpi_object_list *arguments,
+ struct acpi_handle_list *list);
-#ifdef CONFIG_ACPI_BUS
+#ifdef CONFIG_ACPI
#include <linux/proc_fs.h>
#define ACPI_BUS_FILE_ROOT "acpi"
-extern struct proc_dir_entry *acpi_root_dir;
-extern FADT_DESCRIPTOR acpi_fadt;
+extern struct proc_dir_entry *acpi_root_dir;
+extern FADT_DESCRIPTOR acpi_fadt;
enum acpi_bus_removal_type {
- ACPI_BUS_REMOVAL_NORMAL = 0,
+ ACPI_BUS_REMOVAL_NORMAL = 0,
ACPI_BUS_REMOVAL_EJECT,
ACPI_BUS_REMOVAL_SUPRISE,
ACPI_BUS_REMOVAL_TYPE_COUNT
};
enum acpi_bus_device_type {
- ACPI_BUS_TYPE_DEVICE = 0,
+ ACPI_BUS_TYPE_DEVICE = 0,
ACPI_BUS_TYPE_POWER,
ACPI_BUS_TYPE_PROCESSOR,
ACPI_BUS_TYPE_THERMAL,
@@ -89,61 +82,60 @@ enum acpi_bus_device_type {
struct acpi_driver;
struct acpi_device;
-
/*
* ACPI Driver
* -----------
*/
-typedef int (*acpi_op_add) (struct acpi_device *device);
-typedef int (*acpi_op_remove) (struct acpi_device *device, int type);
-typedef int (*acpi_op_lock) (struct acpi_device *device, int type);
-typedef int (*acpi_op_start) (struct acpi_device *device);
-typedef int (*acpi_op_stop) (struct acpi_device *device, int type);
-typedef int (*acpi_op_suspend) (struct acpi_device *device, int state);
-typedef int (*acpi_op_resume) (struct acpi_device *device, int state);
-typedef int (*acpi_op_scan) (struct acpi_device *device);
-typedef int (*acpi_op_bind) (struct acpi_device *device);
-typedef int (*acpi_op_unbind) (struct acpi_device *device);
-typedef int (*acpi_op_match) (struct acpi_device *device,
- struct acpi_driver *driver);
+typedef int (*acpi_op_add) (struct acpi_device * device);
+typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
+typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
+typedef int (*acpi_op_start) (struct acpi_device * device);
+typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
+typedef int (*acpi_op_suspend) (struct acpi_device * device, int state);
+typedef int (*acpi_op_resume) (struct acpi_device * device, int state);
+typedef int (*acpi_op_scan) (struct acpi_device * device);
+typedef int (*acpi_op_bind) (struct acpi_device * device);
+typedef int (*acpi_op_unbind) (struct acpi_device * device);
+typedef int (*acpi_op_match) (struct acpi_device * device,
+ struct acpi_driver * driver);
struct acpi_bus_ops {
- u32 acpi_op_add:1;
- u32 acpi_op_remove:1;
- u32 acpi_op_lock:1;
- u32 acpi_op_start:1;
- u32 acpi_op_stop:1;
- u32 acpi_op_suspend:1;
- u32 acpi_op_resume:1;
- u32 acpi_op_scan:1;
- u32 acpi_op_bind:1;
- u32 acpi_op_unbind:1;
- u32 acpi_op_match:1;
- u32 reserved:21;
+ u32 acpi_op_add:1;
+ u32 acpi_op_remove:1;
+ u32 acpi_op_lock:1;
+ u32 acpi_op_start:1;
+ u32 acpi_op_stop:1;
+ u32 acpi_op_suspend:1;
+ u32 acpi_op_resume:1;
+ u32 acpi_op_scan:1;
+ u32 acpi_op_bind:1;
+ u32 acpi_op_unbind:1;
+ u32 acpi_op_match:1;
+ u32 reserved:21;
};
struct acpi_device_ops {
- acpi_op_add add;
- acpi_op_remove remove;
- acpi_op_lock lock;
- acpi_op_start start;
- acpi_op_stop stop;
- acpi_op_suspend suspend;
- acpi_op_resume resume;
- acpi_op_scan scan;
- acpi_op_bind bind;
- acpi_op_unbind unbind;
- acpi_op_match match;
+ acpi_op_add add;
+ acpi_op_remove remove;
+ acpi_op_lock lock;
+ acpi_op_start start;
+ acpi_op_stop stop;
+ acpi_op_suspend suspend;
+ acpi_op_resume resume;
+ acpi_op_scan scan;
+ acpi_op_bind bind;
+ acpi_op_unbind unbind;
+ acpi_op_match match;
};
struct acpi_driver {
- struct list_head node;
- char name[80];
- char class[80];
- atomic_t references;
- char *ids; /* Supported Hardware IDs */
- struct acpi_device_ops ops;
+ struct list_head node;
+ char name[80];
+ char class[80];
+ atomic_t references;
+ char *ids; /* Supported Hardware IDs */
+ struct acpi_device_ops ops;
};
/*
@@ -154,60 +146,57 @@ struct acpi_driver {
/* Status (_STA) */
struct acpi_device_status {
- u32 present:1;
- u32 enabled:1;
- u32 show_in_ui:1;
- u32 functional:1;
- u32 battery_present:1;
- u32 reserved:27;
+ u32 present:1;
+ u32 enabled:1;
+ u32 show_in_ui:1;
+ u32 functional:1;
+ u32 battery_present:1;
+ u32 reserved:27;
};
-
/* Flags */
struct acpi_device_flags {
- u32 dynamic_status:1;
- u32 hardware_id:1;
- u32 compatible_ids:1;
- u32 bus_address:1;
- u32 unique_id:1;
- u32 removable:1;
- u32 ejectable:1;
- u32 lockable:1;
- u32 suprise_removal_ok:1;
- u32 power_manageable:1;
- u32 performance_manageable:1;
- u32 wake_capable:1; /* Wakeup(_PRW) supported? */
- u32 reserved:20;
+ u32 dynamic_status:1;
+ u32 hardware_id:1;
+ u32 compatible_ids:1;
+ u32 bus_address:1;
+ u32 unique_id:1;
+ u32 removable:1;
+ u32 ejectable:1;
+ u32 lockable:1;
+ u32 suprise_removal_ok:1;
+ u32 power_manageable:1;
+ u32 performance_manageable:1;
+ u32 wake_capable:1; /* Wakeup(_PRW) supported? */
+ u32 reserved:20;
};
-
/* File System */
struct acpi_device_dir {
- struct proc_dir_entry *entry;
+ struct proc_dir_entry *entry;
};
#define acpi_device_dir(d) ((d)->dir.entry)
-
/* Plug and Play */
-typedef char acpi_bus_id[5];
-typedef unsigned long acpi_bus_address;
-typedef char acpi_hardware_id[9];
-typedef char acpi_unique_id[9];
-typedef char acpi_device_name[40];
-typedef char acpi_device_class[20];
+typedef char acpi_bus_id[5];
+typedef unsigned long acpi_bus_address;
+typedef char acpi_hardware_id[9];
+typedef char acpi_unique_id[9];
+typedef char acpi_device_name[40];
+typedef char acpi_device_class[20];
struct acpi_device_pnp {
- acpi_bus_id bus_id; /* Object name */
- acpi_bus_address bus_address; /* _ADR */
- acpi_hardware_id hardware_id; /* _HID */
- struct acpi_compatible_id_list *cid_list; /* _CIDs */
- acpi_unique_id unique_id; /* _UID */
- acpi_device_name device_name; /* Driver-determined */
- acpi_device_class device_class; /* " */
+ acpi_bus_id bus_id; /* Object name */
+ acpi_bus_address bus_address; /* _ADR */
+ acpi_hardware_id hardware_id; /* _HID */
+ struct acpi_compatible_id_list *cid_list; /* _CIDs */
+ acpi_unique_id unique_id; /* _UID */
+ acpi_device_name device_name; /* Driver-determined */
+ acpi_device_class device_class; /* " */
};
#define acpi_device_bid(d) ((d)->pnp.bus_id)
@@ -217,114 +206,111 @@ struct acpi_device_pnp {
#define acpi_device_name(d) ((d)->pnp.device_name)
#define acpi_device_class(d) ((d)->pnp.device_class)
-
/* Power Management */
struct acpi_device_power_flags {
- u32 explicit_get:1; /* _PSC present? */
- u32 power_resources:1; /* Power resources */
- u32 inrush_current:1; /* Serialize Dx->D0 */
- u32 power_removed:1; /* Optimize Dx->D0 */
- u32 reserved:28;
+ u32 explicit_get:1; /* _PSC present? */
+ u32 power_resources:1; /* Power resources */
+ u32 inrush_current:1; /* Serialize Dx->D0 */
+ u32 power_removed:1; /* Optimize Dx->D0 */
+ u32 reserved:28;
};
struct acpi_device_power_state {
struct {
- u8 valid:1;
- u8 explicit_set:1; /* _PSx present? */
- u8 reserved:6;
- } flags;
- int power; /* % Power (compared to D0) */
- int latency; /* Dx->D0 time (microseconds) */
- struct acpi_handle_list resources; /* Power resources referenced */
+ u8 valid:1;
+ u8 explicit_set:1; /* _PSx present? */
+ u8 reserved:6;
+ } flags;
+ int power; /* % Power (compared to D0) */
+ int latency; /* Dx->D0 time (microseconds) */
+ struct acpi_handle_list resources; /* Power resources referenced */
};
struct acpi_device_power {
- int state; /* Current state */
+ int state; /* Current state */
struct acpi_device_power_flags flags;
- struct acpi_device_power_state states[4]; /* Power states (D0-D3) */
+ struct acpi_device_power_state states[4]; /* Power states (D0-D3) */
};
-
/* Performance Management */
struct acpi_device_perf_flags {
- u8 reserved:8;
+ u8 reserved:8;
};
struct acpi_device_perf_state {
struct {
- u8 valid:1;
- u8 reserved:7;
- } flags;
- u8 power; /* % Power (compared to P0) */
- u8 performance; /* % Performance ( " ) */
- int latency; /* Px->P0 time (microseconds) */
+ u8 valid:1;
+ u8 reserved:7;
+ } flags;
+ u8 power; /* % Power (compared to P0) */
+ u8 performance; /* % Performance ( " ) */
+ int latency; /* Px->P0 time (microseconds) */
};
struct acpi_device_perf {
- int state;
+ int state;
struct acpi_device_perf_flags flags;
- int state_count;
+ int state_count;
struct acpi_device_perf_state *states;
};
/* Wakeup Management */
struct acpi_device_wakeup_flags {
- u8 valid:1; /* Can successfully enable wakeup? */
- u8 run_wake:1; /* Run-Wake GPE devices */
+ u8 valid:1; /* Can successfully enable wakeup? */
+ u8 run_wake:1; /* Run-Wake GPE devices */
};
struct acpi_device_wakeup_state {
- u8 enabled:1;
- u8 active:1;
+ u8 enabled:1;
+ u8 active:1;
};
struct acpi_device_wakeup {
- acpi_handle gpe_device;
- acpi_integer gpe_number;;
- acpi_integer sleep_state;
- struct acpi_handle_list resources;
- struct acpi_device_wakeup_state state;
- struct acpi_device_wakeup_flags flags;
+ acpi_handle gpe_device;
+ acpi_integer gpe_number;;
+ acpi_integer sleep_state;
+ struct acpi_handle_list resources;
+ struct acpi_device_wakeup_state state;
+ struct acpi_device_wakeup_flags flags;
};
/* Device */
struct acpi_device {
- acpi_handle handle;
- struct acpi_device *parent;
- struct list_head children;
- struct list_head node;
- struct list_head wakeup_list;
- struct list_head g_list;
+ acpi_handle handle;
+ struct acpi_device *parent;
+ struct list_head children;
+ struct list_head node;
+ struct list_head wakeup_list;
+ struct list_head g_list;
struct acpi_device_status status;
struct acpi_device_flags flags;
- struct acpi_device_pnp pnp;
+ struct acpi_device_pnp pnp;
struct acpi_device_power power;
struct acpi_device_wakeup wakeup;
- struct acpi_device_perf performance;
- struct acpi_device_dir dir;
- struct acpi_device_ops ops;
- struct acpi_driver *driver;
- void *driver_data;
- struct kobject kobj;
+ struct acpi_device_perf performance;
+ struct acpi_device_dir dir;
+ struct acpi_device_ops ops;
+ struct acpi_driver *driver;
+ void *driver_data;
+ struct kobject kobj;
};
#define acpi_driver_data(d) ((d)->driver_data)
-
/*
* Events
* ------
*/
struct acpi_bus_event {
- struct list_head node;
- acpi_device_class device_class;
- acpi_bus_id bus_id;
- u32 type;
- u32 data;
+ struct list_head node;
+ acpi_device_class device_class;
+ acpi_bus_id bus_id;
+ u32 type;
+ u32 data;
};
extern struct subsystem acpi_subsys;
@@ -335,34 +321,32 @@ extern struct subsystem acpi_subsys;
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context);
-int acpi_bus_get_status (struct acpi_device *device);
-int acpi_bus_get_power (acpi_handle handle, int *state);
-int acpi_bus_set_power (acpi_handle handle, int state);
-int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data);
-int acpi_bus_receive_event (struct acpi_bus_event *event);
-int acpi_bus_register_driver (struct acpi_driver *driver);
-int acpi_bus_unregister_driver (struct acpi_driver *driver);
-int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
- acpi_handle handle, int type);
-int acpi_bus_start (struct acpi_device *device);
-
-
-int acpi_match_ids (struct acpi_device *device, char *ids);
+int acpi_bus_get_status(struct acpi_device *device);
+int acpi_bus_get_power(acpi_handle handle, int *state);
+int acpi_bus_set_power(acpi_handle handle, int state);
+int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data);
+int acpi_bus_receive_event(struct acpi_bus_event *event);
+int acpi_bus_register_driver(struct acpi_driver *driver);
+int acpi_bus_unregister_driver(struct acpi_driver *driver);
+int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
+ acpi_handle handle, int type);
+int acpi_bus_start(struct acpi_device *device);
+
+int acpi_match_ids(struct acpi_device *device, char *ids);
int acpi_create_dir(struct acpi_device *);
void acpi_remove_dir(struct acpi_device *);
-
/*
* Bind physical devices with ACPI devices
*/
#include <linux/device.h>
struct acpi_bus_type {
- struct list_head list;
- struct bus_type *bus;
- /* For general devices under the bus*/
- int (*find_device)(struct device *, acpi_handle*);
+ struct list_head list;
+ struct bus_type *bus;
+ /* For general devices under the bus */
+ int (*find_device) (struct device *, acpi_handle *);
/* For bridges, such as PCI root bridge, IDE controller */
- int (*find_bridge)(struct device *, acpi_handle *);
+ int (*find_bridge) (struct device *, acpi_handle *);
};
int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *);
@@ -372,6 +356,6 @@ acpi_handle acpi_get_child(acpi_handle, acpi_integer);
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data))
-#endif /*CONFIG_ACPI_BUS*/
+#endif /* CONFIG_ACPI */
#endif /*__ACPI_BUS_H__*/
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 579fe191b7e7..c1b4e1f882e4 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -29,7 +29,6 @@
#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
-
#define ACPI_MAX_STRING 80
#define ACPI_BUS_COMPONENT 0x00010000
@@ -44,60 +43,55 @@
#define ACPI_BUTTON_HID_POWERF "ACPI_FPB"
#define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB"
-
/* --------------------------------------------------------------------------
PCI
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PCI
-
#define ACPI_PCI_COMPONENT 0x00400000
/* ACPI PCI Interrupt Link (pci_link.c) */
-int acpi_irq_penalty_init (void);
-int acpi_pci_link_allocate_irq (acpi_handle handle, int index, int *edge_level,
- int *active_high_low, char **name);
+int acpi_irq_penalty_init(void);
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *edge_level,
+ int *active_high_low, char **name);
int acpi_pci_link_free_irq(acpi_handle handle);
/* ACPI PCI Interrupt Routing (pci_irq.c) */
-int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus);
-void acpi_pci_irq_del_prt (int segment, int bus);
+int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus);
+void acpi_pci_irq_del_prt(int segment, int bus);
/* ACPI PCI Device Binding (pci_bind.c) */
struct pci_bus;
-acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id);
-int acpi_pci_bind (struct acpi_device *device);
-int acpi_pci_unbind (struct acpi_device *device);
-int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
+acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id);
+int acpi_pci_bind(struct acpi_device *device);
+int acpi_pci_unbind(struct acpi_device *device);
+int acpi_pci_bind_root(struct acpi_device *device, struct acpi_pci_id *id,
+ struct pci_bus *bus);
/* Arch-defined function to add a bus to the system */
-struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, int bus);
-
-#endif /*CONFIG_ACPI_PCI*/
-
+struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
+ int bus);
/* --------------------------------------------------------------------------
Power Resource
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_POWER
-int acpi_enable_wakeup_device_power (struct acpi_device *dev);
-int acpi_disable_wakeup_device_power (struct acpi_device *dev);
-int acpi_power_get_inferred_state (struct acpi_device *device);
-int acpi_power_transition (struct acpi_device *device, int state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
#endif
-
/* --------------------------------------------------------------------------
Embedded Controller
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_EC
-int acpi_ec_ecdt_probe (void);
+int acpi_ec_ecdt_probe(void);
#endif
/* --------------------------------------------------------------------------
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index ea489f235216..98e0b8cd14ed 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -7,7 +7,6 @@
*
*****************************************************************************/
-
/*
* Copyright (C) 2000 - 2005, R. Byron Moore
* All rights reserved.
@@ -51,7 +50,6 @@
#include "platform/acenv.h"
#include "actypes.h"
-
/* Priorities for acpi_os_queue_for_execution */
#define OSD_PRIORITY_GPE 1
@@ -62,200 +60,136 @@
#define ACPI_NO_UNIT_LIMIT ((u32) -1)
#define ACPI_MUTEX_SEM 1
-
/* Functions for acpi_os_signal */
#define ACPI_SIGNAL_FATAL 0
#define ACPI_SIGNAL_BREAKPOINT 1
-struct acpi_signal_fatal_info
-{
- u32 type;
- u32 code;
- u32 argument;
+struct acpi_signal_fatal_info {
+ u32 type;
+ u32 code;
+ u32 argument;
};
-
/*
* OSL Initialization and shutdown primitives
*/
-acpi_status
-acpi_os_initialize (
- void);
-
-acpi_status
-acpi_os_terminate (
- void);
+acpi_status acpi_os_initialize(void);
+acpi_status acpi_os_terminate(void);
/*
* ACPI Table interfaces
*/
-acpi_status
-acpi_os_get_root_pointer (
- u32 flags,
- struct acpi_pointer *address);
+acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *address);
acpi_status
-acpi_os_predefined_override (
- const struct acpi_predefined_names *init_val,
- acpi_string *new_val);
+acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
+ acpi_string * new_val);
acpi_status
-acpi_os_table_override (
- struct acpi_table_header *existing_table,
- struct acpi_table_header **new_table);
-
+acpi_os_table_override(struct acpi_table_header *existing_table,
+ struct acpi_table_header **new_table);
/*
* Synchronization primitives
*/
acpi_status
-acpi_os_create_semaphore (
- u32 max_units,
- u32 initial_units,
- acpi_handle *out_handle);
-
-acpi_status
-acpi_os_delete_semaphore (
- acpi_handle handle);
+acpi_os_create_semaphore(u32 max_units,
+ u32 initial_units, acpi_handle * out_handle);
-acpi_status
-acpi_os_wait_semaphore (
- acpi_handle handle,
- u32 units,
- u16 timeout);
+acpi_status acpi_os_delete_semaphore(acpi_handle handle);
-acpi_status
-acpi_os_signal_semaphore (
- acpi_handle handle,
- u32 units);
+acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout);
-acpi_status
-acpi_os_create_lock (
- acpi_handle *out_handle);
+acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units);
-void
-acpi_os_delete_lock (
- acpi_handle handle);
+acpi_status acpi_os_create_lock(acpi_handle * out_handle);
-void
-acpi_os_acquire_lock (
- acpi_handle handle,
- u32 flags);
+void acpi_os_delete_lock(acpi_handle handle);
-void
-acpi_os_release_lock (
- acpi_handle handle,
- u32 flags);
+unsigned long acpi_os_acquire_lock(acpi_handle handle);
+void acpi_os_release_lock(acpi_handle handle, unsigned long flags);
/*
* Memory allocation and mapping
*/
-void *
-acpi_os_allocate (
- acpi_size size);
+void *acpi_os_allocate(acpi_size size);
-void
-acpi_os_free (
- void * memory);
+void acpi_os_free(void *memory);
acpi_status
-acpi_os_map_memory (
- acpi_physical_address physical_address,
- acpi_size size,
- void __iomem **logical_address);
+acpi_os_map_memory(acpi_physical_address physical_address,
+ acpi_size size, void __iomem ** logical_address);
-void
-acpi_os_unmap_memory (
- void __iomem *logical_address,
- acpi_size size);
+void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_os_get_physical_address (
- void *logical_address,
- acpi_physical_address *physical_address);
+acpi_os_get_physical_address(void *logical_address,
+ acpi_physical_address * physical_address);
#endif
+/*
+ * Memory/Object Cache
+ */
+acpi_status
+acpi_os_create_cache(char *cache_name,
+ u16 object_size,
+ u16 max_depth, acpi_cache_t ** return_cache);
+
+acpi_status acpi_os_delete_cache(acpi_cache_t * cache);
+
+acpi_status acpi_os_purge_cache(acpi_cache_t * cache);
+
+void *acpi_os_acquire_object(acpi_cache_t * cache);
+
+acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object);
/*
* Interrupt handlers
*/
acpi_status
-acpi_os_install_interrupt_handler (
- u32 gsi,
- acpi_osd_handler service_routine,
- void *context);
+acpi_os_install_interrupt_handler(u32 gsi,
+ acpi_osd_handler service_routine,
+ void *context);
acpi_status
-acpi_os_remove_interrupt_handler (
- u32 gsi,
- acpi_osd_handler service_routine);
-
+acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
/*
* Threads and Scheduling
*/
-u32
-acpi_os_get_thread_id (
- void);
+u32 acpi_os_get_thread_id(void);
acpi_status
-acpi_os_queue_for_execution (
- u32 priority,
- acpi_osd_exec_callback function,
- void *context);
+acpi_os_queue_for_execution(u32 priority,
+ acpi_osd_exec_callback function, void *context);
-void
-acpi_os_wait_events_complete(
- void * context);
+void acpi_os_wait_events_complete(void *context);
-void
-acpi_os_wait_events_complete (
- void *context);
+void acpi_os_wait_events_complete(void *context);
-void
-acpi_os_sleep (
- acpi_integer milliseconds);
-
-void
-acpi_os_stall (
- u32 microseconds);
+void acpi_os_sleep(acpi_integer milliseconds);
+void acpi_os_stall(u32 microseconds);
/*
* Platform and hardware-independent I/O interfaces
*/
-acpi_status
-acpi_os_read_port (
- acpi_io_address address,
- u32 *value,
- u32 width);
-
-acpi_status
-acpi_os_write_port (
- acpi_io_address address,
- u32 value,
- u32 width);
+acpi_status acpi_os_read_port(acpi_io_address address, u32 * value, u32 width);
+acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width);
/*
* Platform and hardware-independent physical memory interfaces
*/
acpi_status
-acpi_os_read_memory (
- acpi_physical_address address,
- u32 *value,
- u32 width);
+acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width);
acpi_status
-acpi_os_write_memory (
- acpi_physical_address address,
- u32 value,
- u32 width);
-
+acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width);
/*
* Platform and hardware-independent PCI configuration space access
@@ -263,111 +197,69 @@ acpi_os_write_memory (
* certain compilers complain.
*/
acpi_status
-acpi_os_read_pci_configuration (
- struct acpi_pci_id *pci_id,
- u32 reg,
- void *value,
- u32 width);
+acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
+ u32 reg, void *value, u32 width);
acpi_status
-acpi_os_write_pci_configuration (
- struct acpi_pci_id *pci_id,
- u32 reg,
- acpi_integer value,
- u32 width);
+acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
+ u32 reg, acpi_integer value, u32 width);
/*
* Interim function needed for PCI IRQ routing
*/
void
-acpi_os_derive_pci_id(
- acpi_handle rhandle,
- acpi_handle chandle,
- struct acpi_pci_id **pci_id);
+acpi_os_derive_pci_id(acpi_handle rhandle,
+ acpi_handle chandle, struct acpi_pci_id **pci_id);
/*
* Miscellaneous
*/
-u8
-acpi_os_readable (
- void *pointer,
- acpi_size length);
+u8 acpi_os_readable(void *pointer, acpi_size length);
#ifdef ACPI_FUTURE_USAGE
-u8
-acpi_os_writable (
- void *pointer,
- acpi_size length);
+u8 acpi_os_writable(void *pointer, acpi_size length);
#endif
-u64
-acpi_os_get_timer (
- void);
+u64 acpi_os_get_timer(void);
-acpi_status
-acpi_os_signal (
- u32 function,
- void *info);
+acpi_status acpi_os_signal(u32 function, void *info);
/*
* Debug print routines
*/
-void ACPI_INTERNAL_VAR_XFACE
-acpi_os_printf (
- const char *format,
- ...);
-
-void
-acpi_os_vprintf (
- const char *format,
- va_list args);
+void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *format, ...);
-void
-acpi_os_redirect_output (
- void *destination);
+void acpi_os_vprintf(const char *format, va_list args);
+void acpi_os_redirect_output(void *destination);
#ifdef ACPI_FUTURE_USAGE
/*
* Debug input
*/
-u32
-acpi_os_get_line (
- char *buffer);
+u32 acpi_os_get_line(char *buffer);
#endif
-
/*
* Directory manipulation
*/
-void *
-acpi_os_open_directory (
- char *pathname,
- char *wildcard_spec,
- char requested_file_type);
+void *acpi_os_open_directory(char *pathname,
+ char *wildcard_spec, char requested_file_type);
/* requeste_file_type values */
#define REQUEST_FILE_ONLY 0
#define REQUEST_DIR_ONLY 1
+char *acpi_os_get_next_filename(void *dir_handle);
-char *
-acpi_os_get_next_filename (
- void *dir_handle);
-
-void
-acpi_os_close_directory (
- void *dir_handle);
+void acpi_os_close_directory(void *dir_handle);
/*
* Debug
*/
void
-acpi_os_dbg_assert(
- void *failed_assertion,
- void *file_name,
- u32 line_number,
- char *message);
+acpi_os_dbg_assert(void *failed_assertion,
+ void *file_name, u32 line_number, char *message);
-#endif /* __ACPIOSXF_H__ */
+#endif /* __ACPIOSXF_H__ */
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index f8f619f8e4f8..2a9dbc13b0f2 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -42,447 +42,283 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#ifndef __ACXFACE_H__
#define __ACXFACE_H__
#include "actypes.h"
#include "actbl.h"
-
/*
* Global interfaces
*/
-acpi_status
-acpi_initialize_subsystem (
- void);
+acpi_status acpi_initialize_subsystem(void);
-acpi_status
-acpi_enable_subsystem (
- u32 flags);
+acpi_status acpi_enable_subsystem(u32 flags);
-acpi_status
-acpi_initialize_objects (
- u32 flags);
+acpi_status acpi_initialize_objects(u32 flags);
-acpi_status
-acpi_terminate (
- void);
+acpi_status acpi_terminate(void);
#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_subsystem_status (
- void);
+acpi_status acpi_subsystem_status(void);
#endif
-acpi_status
-acpi_enable (
- void);
+acpi_status acpi_enable(void);
-acpi_status
-acpi_disable (
- void);
+acpi_status acpi_disable(void);
#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_get_system_info (
- struct acpi_buffer *ret_buffer);
+acpi_status acpi_get_system_info(struct acpi_buffer *ret_buffer);
#endif
-const char *
-acpi_format_exception (
- acpi_status exception);
+const char *acpi_format_exception(acpi_status exception);
-acpi_status
-acpi_purge_cached_objects (
- void);
+acpi_status acpi_purge_cached_objects(void);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_install_initialization_handler (
- acpi_init_handler handler,
- u32 function);
+acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
#endif
/*
* ACPI Memory managment
*/
-void *
-acpi_allocate (
- u32 size);
-
-void *
-acpi_callocate (
- u32 size);
+void *acpi_allocate(u32 size);
-void
-acpi_free (
- void *address);
+void *acpi_callocate(u32 size);
+void acpi_free(void *address);
/*
* ACPI table manipulation interfaces
*/
acpi_status
-acpi_find_root_pointer (
- u32 flags,
- struct acpi_pointer *rsdp_address);
+acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address);
-acpi_status
-acpi_load_tables (
- void);
+acpi_status acpi_load_tables(void);
#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_load_table (
- struct acpi_table_header *table_ptr);
+acpi_status acpi_load_table(struct acpi_table_header *table_ptr);
-acpi_status
-acpi_unload_table (
- acpi_table_type table_type);
+acpi_status acpi_unload_table(acpi_table_type table_type);
acpi_status
-acpi_get_table_header (
- acpi_table_type table_type,
- u32 instance,
- struct acpi_table_header *out_table_header);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_get_table_header(acpi_table_type table_type,
+ u32 instance, struct acpi_table_header *out_table_header);
+#endif /* ACPI_FUTURE_USAGE */
acpi_status
-acpi_get_table (
- acpi_table_type table_type,
- u32 instance,
- struct acpi_buffer *ret_buffer);
+acpi_get_table(acpi_table_type table_type,
+ u32 instance, struct acpi_buffer *ret_buffer);
acpi_status
-acpi_get_firmware_table (
- acpi_string signature,
- u32 instance,
- u32 flags,
- struct acpi_table_header **table_pointer);
-
+acpi_get_firmware_table(acpi_string signature,
+ u32 instance,
+ u32 flags, struct acpi_table_header **table_pointer);
/*
* Namespace and name interfaces
*/
acpi_status
-acpi_walk_namespace (
- acpi_object_type type,
- acpi_handle start_object,
- u32 max_depth,
- acpi_walk_callback user_function,
- void *context,
- void **return_value);
+acpi_walk_namespace(acpi_object_type type,
+ acpi_handle start_object,
+ u32 max_depth,
+ acpi_walk_callback user_function,
+ void *context, void **return_value);
acpi_status
-acpi_get_devices (
- char *HID,
- acpi_walk_callback user_function,
- void *context,
- void **return_value);
+acpi_get_devices(char *HID,
+ acpi_walk_callback user_function,
+ void *context, void **return_value);
acpi_status
-acpi_get_name (
- acpi_handle handle,
- u32 name_type,
- struct acpi_buffer *ret_path_ptr);
+acpi_get_name(acpi_handle handle,
+ u32 name_type, struct acpi_buffer *ret_path_ptr);
acpi_status
-acpi_get_handle (
- acpi_handle parent,
- acpi_string pathname,
- acpi_handle *ret_handle);
+acpi_get_handle(acpi_handle parent,
+ acpi_string pathname, acpi_handle * ret_handle);
acpi_status
-acpi_attach_data (
- acpi_handle obj_handle,
- acpi_object_handler handler,
- void *data);
+acpi_attach_data(acpi_handle obj_handle,
+ acpi_object_handler handler, void *data);
acpi_status
-acpi_detach_data (
- acpi_handle obj_handle,
- acpi_object_handler handler);
+acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler);
acpi_status
-acpi_get_data (
- acpi_handle obj_handle,
- acpi_object_handler handler,
- void **data);
-
+acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data);
/*
* Object manipulation and enumeration
*/
acpi_status
-acpi_evaluate_object (
- acpi_handle object,
- acpi_string pathname,
- struct acpi_object_list *parameter_objects,
- struct acpi_buffer *return_object_buffer);
+acpi_evaluate_object(acpi_handle object,
+ acpi_string pathname,
+ struct acpi_object_list *parameter_objects,
+ struct acpi_buffer *return_object_buffer);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_evaluate_object_typed (
- acpi_handle object,
- acpi_string pathname,
- struct acpi_object_list *external_params,
- struct acpi_buffer *return_buffer,
- acpi_object_type return_type);
+acpi_evaluate_object_typed(acpi_handle object,
+ acpi_string pathname,
+ struct acpi_object_list *external_params,
+ struct acpi_buffer *return_buffer,
+ acpi_object_type return_type);
#endif
acpi_status
-acpi_get_object_info (
- acpi_handle handle,
- struct acpi_buffer *return_buffer);
+acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer);
acpi_status
-acpi_get_next_object (
- acpi_object_type type,
- acpi_handle parent,
- acpi_handle child,
- acpi_handle *out_handle);
+acpi_get_next_object(acpi_object_type type,
+ acpi_handle parent,
+ acpi_handle child, acpi_handle * out_handle);
-acpi_status
-acpi_get_type (
- acpi_handle object,
- acpi_object_type *out_type);
-
-acpi_status
-acpi_get_parent (
- acpi_handle object,
- acpi_handle *out_handle);
+acpi_status acpi_get_type(acpi_handle object, acpi_object_type * out_type);
+acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
/*
* Event handler interfaces
*/
acpi_status
-acpi_install_fixed_event_handler (
- u32 acpi_event,
- acpi_event_handler handler,
- void *context);
+acpi_install_fixed_event_handler(u32 acpi_event,
+ acpi_event_handler handler, void *context);
acpi_status
-acpi_remove_fixed_event_handler (
- u32 acpi_event,
- acpi_event_handler handler);
+acpi_remove_fixed_event_handler(u32 acpi_event, acpi_event_handler handler);
acpi_status
-acpi_install_notify_handler (
- acpi_handle device,
- u32 handler_type,
- acpi_notify_handler handler,
- void *context);
+acpi_install_notify_handler(acpi_handle device,
+ u32 handler_type,
+ acpi_notify_handler handler, void *context);
acpi_status
-acpi_remove_notify_handler (
- acpi_handle device,
- u32 handler_type,
- acpi_notify_handler handler);
+acpi_remove_notify_handler(acpi_handle device,
+ u32 handler_type, acpi_notify_handler handler);
acpi_status
-acpi_install_address_space_handler (
- acpi_handle device,
- acpi_adr_space_type space_id,
- acpi_adr_space_handler handler,
- acpi_adr_space_setup setup,
- void *context);
+acpi_install_address_space_handler(acpi_handle device,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler,
+ acpi_adr_space_setup setup, void *context);
acpi_status
-acpi_remove_address_space_handler (
- acpi_handle device,
- acpi_adr_space_type space_id,
- acpi_adr_space_handler handler);
+acpi_remove_address_space_handler(acpi_handle device,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler);
acpi_status
-acpi_install_gpe_handler (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 type,
- acpi_event_handler address,
- void *context);
+acpi_install_gpe_handler(acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 type, acpi_event_handler address, void *context);
#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_install_exception_handler (
- acpi_exception_handler handler);
+acpi_status acpi_install_exception_handler(acpi_exception_handler handler);
#endif
-
/*
* Event interfaces
*/
-acpi_status
-acpi_acquire_global_lock (
- u16 timeout,
- u32 *handle);
+acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle);
-acpi_status
-acpi_release_global_lock (
- u32 handle);
+acpi_status acpi_release_global_lock(u32 handle);
acpi_status
-acpi_remove_gpe_handler (
- acpi_handle gpe_device,
- u32 gpe_number,
- acpi_event_handler address);
+acpi_remove_gpe_handler(acpi_handle gpe_device,
+ u32 gpe_number, acpi_event_handler address);
-acpi_status
-acpi_enable_event (
- u32 event,
- u32 flags);
+acpi_status acpi_enable_event(u32 event, u32 flags);
-acpi_status
-acpi_disable_event (
- u32 event,
- u32 flags);
+acpi_status acpi_disable_event(u32 event, u32 flags);
-acpi_status
-acpi_clear_event (
- u32 event);
+acpi_status acpi_clear_event(u32 event);
#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_get_event_status (
- u32 event,
- acpi_event_status *event_status);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
+#endif /* ACPI_FUTURE_USAGE */
-acpi_status
-acpi_set_gpe_type (
- acpi_handle gpe_device,
- u32 gpe_number,
- u8 type);
+acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type);
-acpi_status
-acpi_enable_gpe (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags);
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
-acpi_status
-acpi_disable_gpe (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags);
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
-acpi_status
-acpi_clear_gpe (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags);
+acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_get_gpe_status (
- acpi_handle gpe_device,
- u32 gpe_number,
- u32 flags,
- acpi_event_status *event_status);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_get_gpe_status(acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 flags, acpi_event_status * event_status);
+#endif /* ACPI_FUTURE_USAGE */
acpi_status
-acpi_install_gpe_block (
- acpi_handle gpe_device,
- struct acpi_generic_address *gpe_block_address,
- u32 register_count,
- u32 interrupt_level);
-
-acpi_status
-acpi_remove_gpe_block (
- acpi_handle gpe_device);
+acpi_install_gpe_block(acpi_handle gpe_device,
+ struct acpi_generic_address *gpe_block_address,
+ u32 register_count, u32 interrupt_number);
+acpi_status acpi_remove_gpe_block(acpi_handle gpe_device);
/*
* Resource interfaces
*/
typedef
-acpi_status (*ACPI_WALK_RESOURCE_CALLBACK) (
- struct acpi_resource *resource,
- void *context);
-
+acpi_status(*ACPI_WALK_RESOURCE_CALLBACK) (struct acpi_resource * resource,
+ void *context);
acpi_status
-acpi_get_current_resources(
- acpi_handle device_handle,
- struct acpi_buffer *ret_buffer);
+acpi_get_current_resources(acpi_handle device_handle,
+ struct acpi_buffer *ret_buffer);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_get_possible_resources(
- acpi_handle device_handle,
- struct acpi_buffer *ret_buffer);
+acpi_get_possible_resources(acpi_handle device_handle,
+ struct acpi_buffer *ret_buffer);
#endif
acpi_status
-acpi_walk_resources (
- acpi_handle device_handle,
- char *path,
- ACPI_WALK_RESOURCE_CALLBACK user_function,
- void *context);
+acpi_walk_resources(acpi_handle device_handle,
+ char *path,
+ ACPI_WALK_RESOURCE_CALLBACK user_function, void *context);
acpi_status
-acpi_set_current_resources (
- acpi_handle device_handle,
- struct acpi_buffer *in_buffer);
+acpi_set_current_resources(acpi_handle device_handle,
+ struct acpi_buffer *in_buffer);
acpi_status
-acpi_get_irq_routing_table (
- acpi_handle bus_device_handle,
- struct acpi_buffer *ret_buffer);
+acpi_get_irq_routing_table(acpi_handle bus_device_handle,
+ struct acpi_buffer *ret_buffer);
acpi_status
-acpi_resource_to_address64 (
- struct acpi_resource *resource,
- struct acpi_resource_address64 *out);
+acpi_resource_to_address64(struct acpi_resource *resource,
+ struct acpi_resource_address64 *out);
/*
* Hardware (ACPI device) interfaces
*/
-acpi_status
-acpi_get_register (
- u32 register_id,
- u32 *return_value,
- u32 flags);
+acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags);
-acpi_status
-acpi_set_register (
- u32 register_id,
- u32 value,
- u32 flags);
+acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags);
acpi_status
-acpi_set_firmware_waking_vector (
- acpi_physical_address physical_address);
+acpi_set_firmware_waking_vector(acpi_physical_address physical_address);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_get_firmware_waking_vector (
- acpi_physical_address *physical_address);
+acpi_get_firmware_waking_vector(acpi_physical_address * physical_address);
#endif
acpi_status
-acpi_get_sleep_type_data (
- u8 sleep_state,
- u8 *slp_typ_a,
- u8 *slp_typ_b);
+acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b);
-acpi_status
-acpi_enter_sleep_state_prep (
- u8 sleep_state);
+acpi_status acpi_enter_sleep_state_prep(u8 sleep_state);
-acpi_status asmlinkage
-acpi_enter_sleep_state (
- u8 sleep_state);
+acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state);
-acpi_status asmlinkage
-acpi_enter_sleep_state_s4bios (
- void);
-
-acpi_status
-acpi_leave_sleep_state (
- u8 sleep_state);
+acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void);
+acpi_status acpi_leave_sleep_state(u8 sleep_state);
-#endif /* __ACXFACE_H__ */
+#endif /* __ACXFACE_H__ */
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h
index ed679264c12c..38e798b05d08 100644
--- a/include/acpi/acresrc.h
+++ b/include/acpi/acresrc.h
@@ -44,303 +44,216 @@
#ifndef __ACRESRC_H__
#define __ACRESRC_H__
-
/*
* Function prototypes called from Acpi* APIs
*/
acpi_status
-acpi_rs_get_prt_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer);
-
+acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
acpi_status
-acpi_rs_get_crs_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer);
+acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_rs_get_prs_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
+#endif /* ACPI_FUTURE_USAGE */
acpi_status
-acpi_rs_get_method_data (
- acpi_handle handle,
- char *path,
- struct acpi_buffer *ret_buffer);
+acpi_rs_get_method_data(acpi_handle handle,
+ char *path, struct acpi_buffer *ret_buffer);
acpi_status
-acpi_rs_set_srs_method_data (
- acpi_handle handle,
- struct acpi_buffer *ret_buffer);
+acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
acpi_status
-acpi_rs_create_resource_list (
- union acpi_operand_object *byte_stream_buffer,
- struct acpi_buffer *output_buffer);
+acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer,
+ struct acpi_buffer *output_buffer);
acpi_status
-acpi_rs_create_byte_stream (
- struct acpi_resource *linked_list_buffer,
- struct acpi_buffer *output_buffer);
+acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer,
+ struct acpi_buffer *output_buffer);
acpi_status
-acpi_rs_create_pci_routing_table (
- union acpi_operand_object *package_object,
- struct acpi_buffer *output_buffer);
-
+acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
+ struct acpi_buffer *output_buffer);
/*
* rsdump
*/
#ifdef ACPI_FUTURE_USAGE
-void
-acpi_rs_dump_resource_list (
- struct acpi_resource *resource);
-
-void
-acpi_rs_dump_irq_list (
- u8 *route_table);
-#endif /* ACPI_FUTURE_USAGE */
+void acpi_rs_dump_resource_list(struct acpi_resource *resource);
+void acpi_rs_dump_irq_list(u8 * route_table);
+#endif /* ACPI_FUTURE_USAGE */
/*
* rscalc
*/
acpi_status
-acpi_rs_get_byte_stream_start (
- u8 *byte_stream_buffer,
- u8 **byte_stream_start,
- u32 *size);
+acpi_rs_get_byte_stream_start(u8 * byte_stream_buffer,
+ u8 ** byte_stream_start, u32 * size);
acpi_status
-acpi_rs_get_list_length (
- u8 *byte_stream_buffer,
- u32 byte_stream_buffer_length,
- acpi_size *size_needed);
+acpi_rs_get_list_length(u8 * byte_stream_buffer,
+ u32 byte_stream_buffer_length, acpi_size * size_needed);
acpi_status
-acpi_rs_get_byte_stream_length (
- struct acpi_resource *linked_list_buffer,
- acpi_size *size_needed);
+acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list_buffer,
+ acpi_size * size_needed);
acpi_status
-acpi_rs_get_pci_routing_table_length (
- union acpi_operand_object *package_object,
- acpi_size *buffer_size_needed);
+acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
+ acpi_size * buffer_size_needed);
acpi_status
-acpi_rs_byte_stream_to_list (
- u8 *byte_stream_buffer,
- u32 byte_stream_buffer_length,
- u8 *output_buffer);
+acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
+ u32 byte_stream_buffer_length, u8 * output_buffer);
acpi_status
-acpi_rs_list_to_byte_stream (
- struct acpi_resource *linked_list,
- acpi_size byte_stream_size_needed,
- u8 *output_buffer);
+acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list,
+ acpi_size byte_stream_size_needed,
+ u8 * output_buffer);
acpi_status
-acpi_rs_io_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_io_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_fixed_io_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_fixed_io_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_io_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_io_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_fixed_io_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_fixed_io_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_irq_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_irq_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_irq_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_irq_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_dma_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_dma_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_dma_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_dma_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_address16_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_address16_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_address16_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_address16_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_address32_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_address32_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_address32_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_address32_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_address64_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_address64_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_address64_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_address64_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_start_depend_fns_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer,
+ acpi_size * structure_size);
acpi_status
-acpi_rs_end_depend_fns_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer,
+ acpi_size * structure_size);
acpi_status
-acpi_rs_start_depend_fns_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer,
+ acpi_size * bytes_consumed);
acpi_status
-acpi_rs_end_depend_fns_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_memory24_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_memory24_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_memory24_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_memory24_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_memory32_range_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_memory32_range_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer,
+ acpi_size * structure_size);
acpi_status
-acpi_rs_fixed_memory32_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer,
+ acpi_size * structure_size);
acpi_status
-acpi_rs_memory32_range_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_memory32_range_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_fixed_memory32_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_extended_irq_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_extended_irq_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_extended_irq_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_extended_irq_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_end_tag_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_end_tag_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_end_tag_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_end_tag_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
acpi_status
-acpi_rs_vendor_resource (
- u8 *byte_stream_buffer,
- acpi_size *bytes_consumed,
- u8 **output_buffer,
- acpi_size *structure_size);
+acpi_rs_vendor_resource(u8 * byte_stream_buffer,
+ acpi_size * bytes_consumed,
+ u8 ** output_buffer, acpi_size * structure_size);
acpi_status
-acpi_rs_vendor_stream (
- struct acpi_resource *linked_list,
- u8 **output_buffer,
- acpi_size *bytes_consumed);
+acpi_rs_vendor_stream(struct acpi_resource *linked_list,
+ u8 ** output_buffer, acpi_size * bytes_consumed);
-u8
-acpi_rs_get_resource_type (
- u8 resource_start_byte);
+u8 acpi_rs_get_resource_type(u8 resource_start_byte);
-#endif /* __ACRESRC_H__ */
+#endif /* __ACRESRC_H__ */
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index e6b9e36a2eda..99d235339801 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -44,14 +44,12 @@
#ifndef __ACSTRUCT_H__
#define __ACSTRUCT_H__
-
/*****************************************************************************
*
* Tree walking typedefs and structs
*
****************************************************************************/
-
/*
* Walk state - current state of a parse tree walk. Used for both a leisurely stroll through
* the tree (for whatever reason), and for control method execution.
@@ -65,152 +63,142 @@
#define ACPI_WALK_CONST_REQUIRED 3
#define ACPI_WALK_CONST_OPTIONAL 4
-struct acpi_walk_state
-{
- u8 data_type; /* To differentiate various internal objs MUST BE FIRST!*/\
- u8 walk_type;
- acpi_owner_id owner_id; /* Owner of objects created during the walk */
- u8 last_predicate; /* Result of last predicate */
- u8 reserved; /* For alignment */
- u8 current_result; /* */
- u8 next_op_info; /* Info about next_op */
- u8 num_operands; /* Stack pointer for Operands[] array */
- u8 return_used;
- u16 opcode; /* Current AML opcode */
- u8 scope_depth;
- u8 reserved1;
- u32 arg_count; /* push for fixed or var args */
- u32 aml_offset;
- u32 arg_types;
- u32 method_breakpoint; /* For single stepping */
- u32 user_breakpoint; /* User AML breakpoint */
- u32 parse_flags;
- u32 prev_arg_types;
-
- u8 *aml_last_while;
- struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */
- union acpi_operand_object **caller_return_desc;
- union acpi_generic_state *control_state; /* List of control states (nested IFs) */
- struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */
- struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */
- union acpi_operand_object *implicit_return_obj;
- struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */
- struct acpi_namespace_node *method_call_node; /* Called method Node*/
- union acpi_parse_object *method_call_op; /* method_call Op if running a method */
- union acpi_operand_object *method_desc; /* Method descriptor if running a method */
- struct acpi_namespace_node *method_node; /* Method node if running a method. */
- union acpi_parse_object *op; /* Current parser op */
- union acpi_operand_object *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */
- const struct acpi_opcode_info *op_info; /* Info on current opcode */
- union acpi_parse_object *origin; /* Start of walk [Obsolete] */
- union acpi_operand_object **params;
- struct acpi_parse_state parser_state; /* Current state of parser */
- union acpi_operand_object *result_obj;
- union acpi_generic_state *results; /* Stack of accumulated results */
- union acpi_operand_object *return_desc; /* Return object, if any */
- union acpi_generic_state *scope_info; /* Stack of nested scopes */
-
- union acpi_parse_object *prev_op; /* Last op that was processed */
- union acpi_parse_object *next_op; /* next op to be processed */
- acpi_parse_downwards descending_callback;
- acpi_parse_upwards ascending_callback;
- struct acpi_thread_state *thread;
- struct acpi_walk_state *next; /* Next walk_state in list */
+struct acpi_walk_state {
+ u8 data_type; /* To differentiate various internal objs MUST BE FIRST! */
+ u8 walk_type;
+ acpi_owner_id owner_id; /* Owner of objects created during the walk */
+ u8 last_predicate; /* Result of last predicate */
+ u8 current_result; /* */
+ u8 next_op_info; /* Info about next_op */
+ u8 num_operands; /* Stack pointer for Operands[] array */
+ u8 return_used;
+ u16 opcode; /* Current AML opcode */
+ u8 scope_depth;
+ u8 pass_number; /* Parse pass during table load */
+ u32 arg_count; /* push for fixed or var args */
+ u32 aml_offset;
+ u32 arg_types;
+ u32 method_breakpoint; /* For single stepping */
+ u32 user_breakpoint; /* User AML breakpoint */
+ u32 parse_flags;
+ u32 prev_arg_types;
+
+ u8 *aml_last_while;
+ struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */
+ union acpi_operand_object **caller_return_desc;
+ union acpi_generic_state *control_state; /* List of control states (nested IFs) */
+ struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */
+ struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */
+ union acpi_operand_object *implicit_return_obj;
+ struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */
+ struct acpi_namespace_node *method_call_node; /* Called method Node */
+ union acpi_parse_object *method_call_op; /* method_call Op if running a method */
+ union acpi_operand_object *method_desc; /* Method descriptor if running a method */
+ struct acpi_namespace_node *method_node; /* Method node if running a method. */
+ union acpi_parse_object *op; /* Current parser op */
+ union acpi_operand_object *operands[ACPI_OBJ_NUM_OPERANDS + 1]; /* Operands passed to the interpreter (+1 for NULL terminator) */
+ const struct acpi_opcode_info *op_info; /* Info on current opcode */
+ union acpi_parse_object *origin; /* Start of walk [Obsolete] */
+ union acpi_operand_object **params;
+ struct acpi_parse_state parser_state; /* Current state of parser */
+ union acpi_operand_object *result_obj;
+ union acpi_generic_state *results; /* Stack of accumulated results */
+ union acpi_operand_object *return_desc; /* Return object, if any */
+ union acpi_generic_state *scope_info; /* Stack of nested scopes */
+
+ union acpi_parse_object *prev_op; /* Last op that was processed */
+ union acpi_parse_object *next_op; /* next op to be processed */
+ acpi_parse_downwards descending_callback;
+ acpi_parse_upwards ascending_callback;
+ struct acpi_thread_state *thread;
+ struct acpi_walk_state *next; /* Next walk_state in list */
};
-
/* Info used by acpi_ps_init_objects */
-struct acpi_init_walk_info
-{
- u16 method_count;
- u16 device_count;
- u16 op_region_count;
- u16 field_count;
- u16 buffer_count;
- u16 package_count;
- u16 op_region_init;
- u16 field_init;
- u16 buffer_init;
- u16 package_init;
- u16 object_count;
- struct acpi_table_desc *table_desc;
+struct acpi_init_walk_info {
+ u16 method_count;
+ u16 device_count;
+ u16 op_region_count;
+ u16 field_count;
+ u16 buffer_count;
+ u16 package_count;
+ u16 op_region_init;
+ u16 field_init;
+ u16 buffer_init;
+ u16 package_init;
+ u16 object_count;
+ struct acpi_table_desc *table_desc;
};
-
/* Info used by acpi_ns_initialize_devices */
-struct acpi_device_walk_info
-{
- u16 device_count;
- u16 num_STA;
- u16 num_INI;
- struct acpi_table_desc *table_desc;
+struct acpi_device_walk_info {
+ u16 device_count;
+ u16 num_STA;
+ u16 num_INI;
+ struct acpi_table_desc *table_desc;
};
-
/* TBD: [Restructure] Merge with struct above */
-struct acpi_walk_info
-{
- u32 debug_level;
- u32 owner_id;
- u8 display_type;
+struct acpi_walk_info {
+ u32 debug_level;
+ u32 count;
+ acpi_owner_id owner_id;
+ u8 display_type;
};
/* Display Types */
-#define ACPI_DISPLAY_SUMMARY 0
-#define ACPI_DISPLAY_OBJECTS 1
+#define ACPI_DISPLAY_SUMMARY (u8) 0
+#define ACPI_DISPLAY_OBJECTS (u8) 1
+#define ACPI_DISPLAY_MASK (u8) 1
-struct acpi_get_devices_info
-{
- acpi_walk_callback user_function;
- void *context;
- char *hid;
-};
+#define ACPI_DISPLAY_SHORT (u8) 2
+struct acpi_get_devices_info {
+ acpi_walk_callback user_function;
+ void *context;
+ char *hid;
+};
-union acpi_aml_operands
-{
- union acpi_operand_object *operands[7];
+union acpi_aml_operands {
+ union acpi_operand_object *operands[7];
- struct
- {
- struct acpi_object_integer *type;
- struct acpi_object_integer *code;
- struct acpi_object_integer *argument;
+ struct {
+ struct acpi_object_integer *type;
+ struct acpi_object_integer *code;
+ struct acpi_object_integer *argument;
} fatal;
- struct
- {
- union acpi_operand_object *source;
- struct acpi_object_integer *index;
- union acpi_operand_object *target;
+ struct {
+ union acpi_operand_object *source;
+ struct acpi_object_integer *index;
+ union acpi_operand_object *target;
} index;
- struct
- {
- union acpi_operand_object *source;
- struct acpi_object_integer *index;
- struct acpi_object_integer *length;
- union acpi_operand_object *target;
+ struct {
+ union acpi_operand_object *source;
+ struct acpi_object_integer *index;
+ struct acpi_object_integer *length;
+ union acpi_operand_object *target;
} mid;
};
-
/* Internal method parameter list */
-struct acpi_parameter_info
-{
- struct acpi_namespace_node *node;
- union acpi_operand_object **parameters;
- union acpi_operand_object *return_object;
- u8 parameter_type;
- u8 return_object_type;
+struct acpi_parameter_info {
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object **parameters;
+ union acpi_operand_object *return_object;
+ u8 pass_number;
+ u8 parameter_type;
+ u8 return_object_type;
};
/* Types for parameter_type above */
@@ -218,5 +206,4 @@ struct acpi_parameter_info
#define ACPI_PARAM_ARGS 0
#define ACPI_PARAM_GPE 1
-
#endif
diff --git a/include/acpi/actables.h b/include/acpi/actables.h
index 39df92e21a0d..f92c1858b808 100644
--- a/include/acpi/actables.h
+++ b/include/acpi/actables.h
@@ -44,146 +44,101 @@
#ifndef __ACTABLES_H__
#define __ACTABLES_H__
-
/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */
#define SIZE_IN_HEADER 0
-
/*
* tbconvrt - Table conversion routines
*/
-acpi_status
-acpi_tb_convert_to_xsdt (
- struct acpi_table_desc *table_info);
+acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info);
-acpi_status
-acpi_tb_convert_table_fadt (
- void);
+acpi_status acpi_tb_convert_table_fadt(void);
-acpi_status
-acpi_tb_build_common_facs (
- struct acpi_table_desc *table_info);
+acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info);
u32
-acpi_tb_get_table_count (
- struct rsdp_descriptor *RSDP,
- struct acpi_table_header *RSDT);
-
+acpi_tb_get_table_count(struct rsdp_descriptor *RSDP,
+ struct acpi_table_header *RSDT);
/*
* tbget - Table "get" routines
*/
acpi_status
-acpi_tb_get_table (
- struct acpi_pointer *address,
- struct acpi_table_desc *table_info);
-
-acpi_status
-acpi_tb_get_table_header (
- struct acpi_pointer *address,
- struct acpi_table_header *return_header);
+acpi_tb_get_table(struct acpi_pointer *address,
+ struct acpi_table_desc *table_info);
acpi_status
-acpi_tb_get_table_body (
- struct acpi_pointer *address,
- struct acpi_table_header *header,
- struct acpi_table_desc *table_info);
+acpi_tb_get_table_header(struct acpi_pointer *address,
+ struct acpi_table_header *return_header);
acpi_status
-acpi_tb_get_table_ptr (
- acpi_table_type table_type,
- u32 instance,
- struct acpi_table_header **table_ptr_loc);
+acpi_tb_get_table_body(struct acpi_pointer *address,
+ struct acpi_table_header *header,
+ struct acpi_table_desc *table_info);
acpi_status
-acpi_tb_verify_rsdp (
- struct acpi_pointer *address);
+acpi_tb_get_table_ptr(acpi_table_type table_type,
+ u32 instance, struct acpi_table_header **table_ptr_loc);
-void
-acpi_tb_get_rsdt_address (
- struct acpi_pointer *out_address);
+acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address);
-acpi_status
-acpi_tb_validate_rsdt (
- struct acpi_table_header *table_ptr);
+void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address);
+acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr);
/*
* tbgetall - get multiple required tables
*/
-acpi_status
-acpi_tb_get_required_tables (
- void);
-
+acpi_status acpi_tb_get_required_tables(void);
/*
* tbinstall - Table installation
*/
-acpi_status
-acpi_tb_install_table (
- struct acpi_table_desc *table_info);
+acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info);
acpi_status
-acpi_tb_recognize_table (
- struct acpi_table_desc *table_info,
- u8 search_type);
+acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type);
acpi_status
-acpi_tb_init_table_descriptor (
- acpi_table_type table_type,
- struct acpi_table_desc *table_info);
-
+acpi_tb_init_table_descriptor(acpi_table_type table_type,
+ struct acpi_table_desc *table_info);
/*
* tbremove - Table removal and deletion
*/
-void
-acpi_tb_delete_all_tables (
- void);
-
-void
-acpi_tb_delete_tables_by_type (
- acpi_table_type type);
+void acpi_tb_delete_all_tables(void);
-void
-acpi_tb_delete_single_table (
- struct acpi_table_desc *table_desc);
+void acpi_tb_delete_tables_by_type(acpi_table_type type);
-struct acpi_table_desc *
-acpi_tb_uninstall_table (
- struct acpi_table_desc *table_desc);
+void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc);
+struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc
+ *table_desc);
/*
* tbxfroot - RSDP, RSDT utilities
*/
acpi_status
-acpi_tb_find_table (
- char *signature,
- char *oem_id,
- char *oem_table_id,
- struct acpi_table_header **table_ptr);
+acpi_tb_find_table(char *signature,
+ char *oem_id,
+ char *oem_table_id, struct acpi_table_header **table_ptr);
-acpi_status
-acpi_tb_get_table_rsdt (
- void);
+acpi_status acpi_tb_get_table_rsdt(void);
+acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp);
/*
* tbutils - common table utilities
*/
+acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc);
+
acpi_status
-acpi_tb_verify_table_checksum (
- struct acpi_table_header *table_header);
+acpi_tb_verify_table_checksum(struct acpi_table_header *table_header);
-u8
-acpi_tb_checksum (
- void *buffer,
- u32 length);
+u8 acpi_tb_generate_checksum(void *buffer, u32 length);
acpi_status
-acpi_tb_validate_table_header (
- struct acpi_table_header *table_header);
+acpi_tb_validate_table_header(struct acpi_table_header *table_header);
-#endif /* __ACTABLES_H__ */
+#endif /* __ACTABLES_H__ */
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index b5cdcca444c8..a46f406e1c94 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -44,27 +44,24 @@
#ifndef __ACTBL_H__
#define __ACTBL_H__
-
/*
* Values for description table header signatures
*/
#define RSDP_NAME "RSDP"
-#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
-#define APIC_SIG "APIC" /* Multiple APIC Description Table */
-#define DSDT_SIG "DSDT" /* Differentiated System Description Table */
-#define FADT_SIG "FACP" /* Fixed ACPI Description Table */
-#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
-#define PSDT_SIG "PSDT" /* Persistent System Description Table */
-#define RSDT_SIG "RSDT" /* Root System Description Table */
-#define XSDT_SIG "XSDT" /* Extended System Description Table */
-#define SSDT_SIG "SSDT" /* Secondary System Description Table */
-#define SBST_SIG "SBST" /* Smart Battery Specification Table */
-#define SPIC_SIG "SPIC" /* IOSAPIC table */
-#define BOOT_SIG "BOOT" /* Boot table */
-
-
-#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */
-
+#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
+#define APIC_SIG "APIC" /* Multiple APIC Description Table */
+#define DSDT_SIG "DSDT" /* Differentiated System Description Table */
+#define FADT_SIG "FACP" /* Fixed ACPI Description Table */
+#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
+#define PSDT_SIG "PSDT" /* Persistent System Description Table */
+#define RSDT_SIG "RSDT" /* Root System Description Table */
+#define XSDT_SIG "XSDT" /* Extended System Description Table */
+#define SSDT_SIG "SSDT" /* Secondary System Description Table */
+#define SBST_SIG "SBST" /* Smart Battery Specification Table */
+#define SPIC_SIG "SPIC" /* IOSAPIC table */
+#define BOOT_SIG "BOOT" /* Boot table */
+
+#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */
/*
* Common table types. The base code can remain
@@ -75,7 +72,6 @@
#define FACS_DESCRIPTOR struct facs_descriptor_rev2
#define FADT_DESCRIPTOR struct fadt_descriptor_rev2
-
#pragma pack(1)
/*
@@ -84,45 +80,37 @@
* NOTE: The tables that are specific to ACPI versions (1.0, 2.0, etc.)
* are in separate files.
*/
-struct rsdp_descriptor /* Root System Descriptor Pointer */
-{
- char signature [8]; /* ACPI signature, contains "RSD PTR " */
- u8 checksum; /* To make sum of struct == 0 */
- char oem_id [6]; /* OEM identification */
- u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */
- u32 rsdt_physical_address; /* 32-bit physical address of RSDT */
- u32 length; /* XSDT Length in bytes including hdr */
- u64 xsdt_physical_address; /* 64-bit physical address of XSDT */
- u8 extended_checksum; /* Checksum of entire table */
- char reserved [3]; /* Reserved field must be 0 */
+struct rsdp_descriptor { /* Root System Descriptor Pointer */
+ char signature[8]; /* ACPI signature, contains "RSD PTR " */
+ u8 checksum; /* ACPI 1.0 checksum */
+ char oem_id[6]; /* OEM identification */
+ u8 revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
+ u32 rsdt_physical_address; /* 32-bit physical address of the RSDT */
+ u32 length; /* XSDT Length in bytes, including header */
+ u64 xsdt_physical_address; /* 64-bit physical address of the XSDT */
+ u8 extended_checksum; /* Checksum of entire table (ACPI 2.0) */
+ char reserved[3]; /* Reserved, must be zero */
};
-
-struct acpi_common_facs /* Common FACS for internal use */
-{
- u32 *global_lock;
- u64 *firmware_waking_vector;
- u8 vector_width;
+struct acpi_common_facs { /* Common FACS for internal use */
+ u32 *global_lock;
+ u64 *firmware_waking_vector;
+ u8 vector_width;
};
-
#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
- char signature [4]; /* ACPI signature (4 ASCII characters) */\
- u32 length; /* Length of table, in bytes, including header */\
+ char signature[4]; /* ASCII table signature */\
+ u32 length; /* Length of table in bytes, including this header */\
u8 revision; /* ACPI Specification minor version # */\
u8 checksum; /* To make sum of entire table == 0 */\
- char oem_id [6]; /* OEM identification */\
- char oem_table_id [8]; /* OEM table identification */\
+ char oem_id[6]; /* ASCII OEM identification */\
+ char oem_table_id[8]; /* ASCII OEM table identification */\
u32 oem_revision; /* OEM revision number */\
- char asl_compiler_id [4]; /* ASL compiler vendor ID */\
- u32 asl_compiler_revision; /* ASL compiler revision number */
-
-
-struct acpi_table_header /* ACPI common table header */
-{
- ACPI_TABLE_HEADER_DEF
-};
+ char asl_compiler_id [4]; /* ASCII ASL compiler vendor ID */\
+ u32 asl_compiler_revision; /* ASL compiler version */
+struct acpi_table_header { /* ACPI common table header */
+ACPI_TABLE_HEADER_DEF};
/*
* MADT values and structures
@@ -135,12 +123,15 @@ struct acpi_table_header /* ACPI common table header */
/* Master MADT */
-struct multiple_apic_table
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u32 local_apic_address; /* Physical address of local APIC */
- u32 PCATcompat : 1; /* A one indicates system also has dual 8259s */
- u32 reserved1 : 31;
+struct multiple_apic_table {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u32 local_apic_address; /* Physical address of local APIC */
+
+ /* Flags (32 bits) */
+
+ u8 PCATcompat:1; /* 00: System also has dual 8259s */
+ u8:7; /* 01-07: Reserved, must be zero */
+ u8 reserved1[3]; /* 08-31: Reserved, must be zero */
};
/* Values for Type in APIC_HEADER_DEF */
@@ -154,7 +145,7 @@ struct multiple_apic_table
#define APIC_IO_SAPIC 6
#define APIC_LOCAL_SAPIC 7
#define APIC_XRUPT_SOURCE 8
-#define APIC_RESERVED 9 /* 9 and greater are reserved */
+#define APIC_RESERVED 9 /* 9 and greater are reserved */
/*
* MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
@@ -163,10 +154,8 @@ struct multiple_apic_table
u8 type; \
u8 length;
-struct apic_header
-{
- APIC_HEADER_DEF
-};
+struct apic_header {
+APIC_HEADER_DEF};
/* Values for MPS INTI flags */
@@ -180,117 +169,90 @@ struct apic_header
#define TRIGGER_RESERVED 2
#define TRIGGER_LEVEL 3
-/* Common flag definitions */
+/* Common flag definitions (16 bits each) */
#define MPS_INTI_FLAGS \
- u16 polarity : 2; /* Polarity of APIC I/O input signals */\
- u16 trigger_mode : 2; /* Trigger mode of APIC input signals */\
- u16 reserved1 : 12; /* Reserved, must be zero */
+ u8 polarity : 2; /* 00-01: Polarity of APIC I/O input signals */\
+ u8 trigger_mode : 2; /* 02-03: Trigger mode of APIC input signals */\
+ u8 : 4; /* 04-07: Reserved, must be zero */\
+ u8 reserved1; /* 08-15: Reserved, must be zero */
#define LOCAL_APIC_FLAGS \
- u32 processor_enabled: 1; /* Processor is usable if set */\
- u32 reserved2 : 31; /* Reserved, must be zero */
+ u8 processor_enabled: 1; /* 00: Processor is usable if set */\
+ u8 : 7; /* 01-07: Reserved, must be zero */\
+ u8 reserved2; /* 08-15: Reserved, must be zero */
/* Sub-structures for MADT */
-struct madt_processor_apic
-{
- APIC_HEADER_DEF
- u8 processor_id; /* ACPI processor id */
- u8 local_apic_id; /* Processor's local APIC id */
- LOCAL_APIC_FLAGS
-};
-
-struct madt_io_apic
-{
- APIC_HEADER_DEF
- u8 io_apic_id; /* I/O APIC ID */
- u8 reserved; /* Reserved - must be zero */
- u32 address; /* APIC physical address */
- u32 interrupt; /* Global system interrupt where INTI
- * lines start */
+struct madt_processor_apic {
+ APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */
+ u8 local_apic_id; /* Processor's local APIC id */
+ LOCAL_APIC_FLAGS};
+
+struct madt_io_apic {
+ APIC_HEADER_DEF u8 io_apic_id; /* I/O APIC ID */
+ u8 reserved; /* Reserved - must be zero */
+ u32 address; /* APIC physical address */
+ u32 interrupt; /* Global system interrupt where INTI
+ * lines start */
};
-struct madt_interrupt_override
-{
- APIC_HEADER_DEF
- u8 bus; /* 0 - ISA */
- u8 source; /* Interrupt source (IRQ) */
- u32 interrupt; /* Global system interrupt */
- MPS_INTI_FLAGS
-};
+struct madt_interrupt_override {
+ APIC_HEADER_DEF u8 bus; /* 0 - ISA */
+ u8 source; /* Interrupt source (IRQ) */
+ u32 interrupt; /* Global system interrupt */
+ MPS_INTI_FLAGS};
-struct madt_nmi_source
-{
- APIC_HEADER_DEF
- MPS_INTI_FLAGS
- u32 interrupt; /* Global system interrupt */
+struct madt_nmi_source {
+ APIC_HEADER_DEF MPS_INTI_FLAGS u32 interrupt; /* Global system interrupt */
};
-struct madt_local_apic_nmi
-{
- APIC_HEADER_DEF
- u8 processor_id; /* ACPI processor id */
- MPS_INTI_FLAGS
- u8 lint; /* LINTn to which NMI is connected */
+struct madt_local_apic_nmi {
+ APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */
+ MPS_INTI_FLAGS u8 lint; /* LINTn to which NMI is connected */
};
-struct madt_address_override
-{
- APIC_HEADER_DEF
- u16 reserved; /* Reserved - must be zero */
- u64 address; /* APIC physical address */
+struct madt_address_override {
+ APIC_HEADER_DEF u16 reserved; /* Reserved, must be zero */
+ u64 address; /* APIC physical address */
};
-struct madt_io_sapic
-{
- APIC_HEADER_DEF
- u8 io_sapic_id; /* I/O SAPIC ID */
- u8 reserved; /* Reserved - must be zero */
- u32 interrupt_base; /* Glocal interrupt for SAPIC start */
- u64 address; /* SAPIC physical address */
+struct madt_io_sapic {
+ APIC_HEADER_DEF u8 io_sapic_id; /* I/O SAPIC ID */
+ u8 reserved; /* Reserved, must be zero */
+ u32 interrupt_base; /* Glocal interrupt for SAPIC start */
+ u64 address; /* SAPIC physical address */
};
-struct madt_local_sapic
-{
- APIC_HEADER_DEF
- u8 processor_id; /* ACPI processor id */
- u8 local_sapic_id; /* SAPIC ID */
- u8 local_sapic_eid; /* SAPIC EID */
- u8 reserved [3]; /* Reserved - must be zero */
- LOCAL_APIC_FLAGS
- u32 processor_uID; /* Numeric UID - ACPI 3.0 */
- char processor_uIDstring[1]; /* String UID - ACPI 3.0 */
+struct madt_local_sapic {
+ APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */
+ u8 local_sapic_id; /* SAPIC ID */
+ u8 local_sapic_eid; /* SAPIC EID */
+ u8 reserved[3]; /* Reserved, must be zero */
+ LOCAL_APIC_FLAGS u32 processor_uID; /* Numeric UID - ACPI 3.0 */
+ char processor_uIDstring[1]; /* String UID - ACPI 3.0 */
};
-struct madt_interrupt_source
-{
- APIC_HEADER_DEF
- MPS_INTI_FLAGS
- u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */
- u8 processor_id; /* Processor ID */
- u8 processor_eid; /* Processor EID */
- u8 io_sapic_vector; /* Vector value for PMI interrupts */
- u32 interrupt; /* Global system interrupt */
- u32 flags; /* Interrupt Source Flags */
+struct madt_interrupt_source {
+ APIC_HEADER_DEF MPS_INTI_FLAGS u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */
+ u8 processor_id; /* Processor ID */
+ u8 processor_eid; /* Processor EID */
+ u8 io_sapic_vector; /* Vector value for PMI interrupts */
+ u32 interrupt; /* Global system interrupt */
+ u32 flags; /* Interrupt Source Flags */
};
-
/*
* Smart Battery
*/
-struct smart_battery_table
-{
- ACPI_TABLE_HEADER_DEF
- u32 warning_level;
- u32 low_level;
- u32 critical_level;
+struct smart_battery_table {
+ ACPI_TABLE_HEADER_DEF u32 warning_level;
+ u32 low_level;
+ u32 critical_level;
};
-
#pragma pack()
-
/*
* ACPI Table information. We save the table address, length,
* and type of memory allocation (mapped or allocated) for each
@@ -314,39 +276,35 @@ struct smart_battery_table
/* Data about each known table type */
-struct acpi_table_support
-{
- char *name;
- char *signature;
- void **global_ptr;
- u8 sig_length;
- u8 flags;
+struct acpi_table_support {
+ char *name;
+ char *signature;
+ void **global_ptr;
+ u8 sig_length;
+ u8 flags;
};
-
/*
* Get the ACPI version-specific tables
*/
-#include "actbl1.h" /* Acpi 1.0 table definitions */
-#include "actbl2.h" /* Acpi 2.0 table definitions */
+#include "actbl1.h" /* Acpi 1.0 table definitions */
+#include "actbl2.h" /* Acpi 2.0 table definitions */
-extern u8 acpi_fadt_is_v1; /* is set to 1 if FADT is revision 1,
- * needed for certain workarounds */
+extern u8 acpi_fadt_is_v1; /* is set to 1 if FADT is revision 1,
+ * needed for certain workarounds */
#pragma pack(1)
/*
* High performance timer
*/
-struct hpet_table
-{
- ACPI_TABLE_HEADER_DEF
- u32 hardware_id;
- struct acpi_generic_address base_address;
- u8 hpet_number;
- u16 clock_tick;
- u8 attributes;
+struct hpet_table {
+ ACPI_TABLE_HEADER_DEF u32 hardware_id;
+ struct acpi_generic_address base_address;
+ u8 hpet_number;
+ u16 clock_tick;
+ u8 attributes;
};
#pragma pack()
-#endif /* __ACTBL_H__ */
+#endif /* __ACTBL_H__ */
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 33de5f4d2ccc..67312c3a915a 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -49,88 +49,87 @@
/*
* ACPI 1.0 Root System Description Table (RSDT)
*/
-struct rsdt_descriptor_rev1
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u32 table_offset_entry [1]; /* Array of pointers to other */
- /* ACPI tables */
+struct rsdt_descriptor_rev1 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */
};
-
/*
* ACPI 1.0 Firmware ACPI Control Structure (FACS)
*/
-struct facs_descriptor_rev1
-{
- char signature[4]; /* ACPI Signature */
- u32 length; /* Length of structure, in bytes */
- u32 hardware_signature; /* Hardware configuration signature */
- u32 firmware_waking_vector; /* ACPI OS waking vector */
- u32 global_lock; /* Global Lock */
- u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */
- u32 reserved1 : 31; /* Must be 0 */
- u8 resverved3 [40]; /* Reserved - must be zero */
-};
+struct facs_descriptor_rev1 {
+ char signature[4]; /* ASCII table signature */
+ u32 length; /* Length of structure in bytes */
+ u32 hardware_signature; /* Hardware configuration signature */
+ u32 firmware_waking_vector; /* ACPI OS waking vector */
+ u32 global_lock; /* Global Lock */
+
+ /* Flags (32 bits) */
+ u8 S4bios_f:1; /* 00: S4BIOS support is present */
+ u8:7; /* 01-07: Reserved, must be zero */
+ u8 reserved1[3]; /* 08-31: Reserved, must be zero */
+
+ u8 reserved2[40]; /* Reserved, must be zero */
+};
/*
* ACPI 1.0 Fixed ACPI Description Table (FADT)
*/
-struct fadt_descriptor_rev1
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u32 firmware_ctrl; /* Physical address of FACS */
- u32 dsdt; /* Physical address of DSDT */
- u8 model; /* System Interrupt Model */
- u8 reserved1; /* Reserved */
- u16 sci_int; /* System vector of SCI interrupt */
- u32 smi_cmd; /* Port address of SMI command port */
- u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
- u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
- u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
- u8 reserved2; /* Reserved - must be zero */
- u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
- u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
- u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
- u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
- u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
- u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
- u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
- u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
- u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
- u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
- u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
- u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */
- u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
- u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
- u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
- u8 reserved3; /* Reserved */
- u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
- u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
- u16 flush_size; /* Size of area read to flush caches */
- u16 flush_stride; /* Stride used in flushing caches */
- u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */
- u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */
- u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
- u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
- u8 century; /* Index to century in RTC CMOS RAM */
- u8 reserved4; /* Reserved */
- u8 reserved4a; /* Reserved */
- u8 reserved4b; /* Reserved */
- u32 wb_invd : 1; /* The wbinvd instruction works properly */
- u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
- u32 proc_c1 : 1; /* All processors support C1 state */
- u32 plvl2_up : 1; /* C2 state works on MP system */
- u32 pwr_button : 1; /* Power button is handled as a generic feature */
- u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
- u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
- u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
- u32 tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */
- u32 reserved5 : 23; /* Reserved - must be zero */
-};
+struct fadt_descriptor_rev1 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u32 firmware_ctrl; /* Physical address of FACS */
+ u32 dsdt; /* Physical address of DSDT */
+ u8 model; /* System Interrupt Model */
+ u8 reserved1; /* Reserved, must be zero */
+ u16 sci_int; /* System vector of SCI interrupt */
+ u32 smi_cmd; /* Port address of SMI command port */
+ u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
+ u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
+ u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
+ u8 reserved2; /* Reserved, must be zero */
+ u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
+ u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
+ u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
+ u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
+ u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
+ u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
+ u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
+ u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
+ u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
+ u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
+ u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
+ u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */
+ u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
+ u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
+ u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
+ u8 reserved3; /* Reserved, must be zero */
+ u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
+ u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
+ u16 flush_size; /* Size of area read to flush caches */
+ u16 flush_stride; /* Stride used in flushing caches */
+ u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */
+ u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */
+ u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
+ u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
+ u8 century; /* Index to century in RTC CMOS RAM */
+ u8 reserved4[3]; /* Reserved, must be zero */
-#pragma pack()
+ /* Flags (32 bits) */
-#endif /* __ACTBL1_H__ */
+ u8 wb_invd:1; /* 00: The wbinvd instruction works properly */
+ u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */
+ u8 proc_c1:1; /* 02: All processors support C1 state */
+ u8 plvl2_up:1; /* 03: C2 state works on MP system */
+ u8 pwr_button:1; /* 04: Power button is handled as a generic feature */
+ u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */
+ u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */
+ u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */
+ u8 tmr_val_ext:1; /* 08: tmr_val width is 32 bits (0 = 24 bits) */
+ u8:7; /* 09-15: Reserved, must be zero */
+ u8 reserved5[2]; /* 16-31: Reserved, must be zero */
+};
+#pragma pack()
+#endif /* __ACTBL1_H__ */
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index e1729c967e05..50305ce2681a 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -64,62 +64,56 @@
#define FADT2_REVISION_ID 3
#define FADT2_MINUS_REVISION_ID 2
-
#pragma pack(1)
/*
* ACPI 2.0 Root System Description Table (RSDT)
*/
-struct rsdt_descriptor_rev2
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u32 table_offset_entry [1]; /* Array of pointers to */
- /* ACPI table headers */
+struct rsdt_descriptor_rev2 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */
};
-
/*
* ACPI 2.0 Extended System Description Table (XSDT)
*/
-struct xsdt_descriptor_rev2
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u64 table_offset_entry [1]; /* Array of pointers to */
- /* ACPI table headers */
+struct xsdt_descriptor_rev2 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */
};
-
/*
* ACPI 2.0 Firmware ACPI Control Structure (FACS)
*/
-struct facs_descriptor_rev2
-{
- char signature[4]; /* ACPI signature */
- u32 length; /* Length of structure, in bytes */
- u32 hardware_signature; /* Hardware configuration signature */
- u32 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */
- u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */
- u32 S4bios_f : 1; /* S4Bios_f - Indicates if S4BIOS support is present */
- u32 reserved1 : 31; /* Must be 0 */
- u64 xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */
- u8 version; /* Version of this table */
- u8 reserved3 [31]; /* Reserved - must be zero */
+struct facs_descriptor_rev2 {
+ char signature[4]; /* ASCII table signature */
+ u32 length; /* Length of structure, in bytes */
+ u32 hardware_signature; /* Hardware configuration signature */
+ u32 firmware_waking_vector; /* 32-bit physical address of the Firmware Waking Vector. */
+ u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */
+
+ /* Flags (32 bits) */
+
+ u8 S4bios_f:1; /* 00: S4BIOS support is present */
+ u8:7; /* 01-07: Reserved, must be zero */
+ u8 reserved1[3]; /* 08-31: Reserved, must be zero */
+
+ u64 xfirmware_waking_vector; /* 64-bit physical address of the Firmware Waking Vector. */
+ u8 version; /* Version of this table */
+ u8 reserved3[31]; /* Reserved, must be zero */
};
-
/*
* ACPI 2.0+ Generic Address Structure (GAS)
*/
-struct acpi_generic_address
-{
- u8 address_space_id; /* Address space where struct or register exists. */
- u8 register_bit_width; /* Size in bits of given register */
- u8 register_bit_offset; /* Bit offset within the register */
- u8 access_width; /* Minimum Access size (ACPI 3.0) */
- u64 address; /* 64-bit address of struct or register */
+struct acpi_generic_address {
+ u8 address_space_id; /* Address space where struct or register exists. */
+ u8 register_bit_width; /* Size in bits of given register */
+ u8 register_bit_offset; /* Bit offset within the register */
+ u8 access_width; /* Minimum Access size (ACPI 3.0) */
+ u64 address; /* 64-bit address of struct or register */
};
-
#define FADT_REV2_COMMON \
u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ \
u32 V1_dsdt; /* 32-bit physical address of DSDT */ \
@@ -161,129 +155,123 @@ struct acpi_generic_address
/*
* ACPI 2.0+ Fixed ACPI Description Table (FADT)
*/
-struct fadt_descriptor_rev2
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- FADT_REV2_COMMON
- u8 reserved2; /* Reserved */
- u32 wb_invd : 1; /* The wbinvd instruction works properly */
- u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
- u32 proc_c1 : 1; /* All processors support C1 state */
- u32 plvl2_up : 1; /* C2 state works on MP system */
- u32 pwr_button : 1; /* Power button is handled as a generic feature */
- u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
- u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
- u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
- u32 tmr_val_ext : 1; /* Indicates tmr_val is 32 bits 0=24-bits */
- u32 dock_cap : 1; /* Supports Docking */
- u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG */
- u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed */
- u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices */
- u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */
- /* must be executed after writing the SLP_TYPx register */
- /* ACPI 3.0 flag bits */
-
- u32 pci_exp_wak : 1; /* System supports PCIEXP_WAKE (STS/EN) bits */
- u32 use_platform_clock : 1; /* OSPM should use platform-provided timer */
- u32 S4rtc_sts_valid : 1; /* Contents of RTC_STS valid after S4 wake */
- u32 remote_power_on_capable : 1; /* System is compatible with remote power on */
- u32 force_apic_cluster_model : 1; /* All local APICs must use cluster model */
- u32 force_apic_physical_destination_mode : 1; /* all local x_aPICs must use physical dest mode */
- u32 reserved6 : 12;/* Reserved - must be zero */
-
- struct acpi_generic_address reset_register; /* Reset register address in GAS format */
- u8 reset_value; /* Value to write to the reset_register port to reset the system */
- u8 reserved7[3]; /* These three bytes must be zero */
- u64 xfirmware_ctrl; /* 64-bit physical address of FACS */
- u64 Xdsdt; /* 64-bit physical address of DSDT */
- struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */
- struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */
- struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */
- struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */
- struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */
- struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */
- struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */
- struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */
+struct fadt_descriptor_rev2 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ FADT_REV2_COMMON u8 reserved2; /* Reserved, must be zero */
+
+ /* Flags (32 bits) */
+
+ u8 wb_invd:1; /* 00: The wbinvd instruction works properly */
+ u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */
+ u8 proc_c1:1; /* 02: All processors support C1 state */
+ u8 plvl2_up:1; /* 03: C2 state works on MP system */
+ u8 pwr_button:1; /* 04: Power button is handled as a generic feature */
+ u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */
+ u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */
+ u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */
+ u8 tmr_val_ext:1; /* 08: tmr_val is 32 bits 0=24-bits */
+ u8 dock_cap:1; /* 09: Docking supported */
+ u8 reset_reg_sup:1; /* 10: System reset via the FADT RESET_REG supported */
+ u8 sealed_case:1; /* 11: No internal expansion capabilities and case is sealed */
+ u8 headless:1; /* 12: No local video capabilities or local input devices */
+ u8 cpu_sw_sleep:1; /* 13: Must execute native instruction after writing SLP_TYPx register */
+
+ u8 pci_exp_wak:1; /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
+ u8 use_platform_clock:1; /* 15: OSPM should use platform-provided timer (ACPI 3.0) */
+ u8 S4rtc_sts_valid:1; /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
+ u8 remote_power_on_capable:1; /* 17: System is compatible with remote power on (ACPI 3.0) */
+ u8 force_apic_cluster_model:1; /* 18: All local APICs must use cluster model (ACPI 3.0) */
+ u8 force_apic_physical_destination_mode:1; /* 19: all local x_aPICs must use physical dest mode (ACPI 3.0) */
+ u8:4; /* 20-23: Reserved, must be zero */
+ u8 reserved3; /* 24-31: Reserved, must be zero */
+
+ struct acpi_generic_address reset_register; /* Reset register address in GAS format */
+ u8 reset_value; /* Value to write to the reset_register port to reset the system */
+ u8 reserved4[3]; /* These three bytes must be zero */
+ u64 xfirmware_ctrl; /* 64-bit physical address of FACS */
+ u64 Xdsdt; /* 64-bit physical address of DSDT */
+ struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */
+ struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */
+ struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */
+ struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */
+ struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */
+ struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */
+ struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */
+ struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */
};
-
/* "Down-revved" ACPI 2.0 FADT descriptor */
-struct fadt_descriptor_rev2_minus
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- FADT_REV2_COMMON
- u8 reserved2; /* Reserved */
- u32 flags;
- struct acpi_generic_address reset_register; /* Reset register address in GAS format */
- u8 reset_value; /* Value to write to the reset_register port to reset the system. */
- u8 reserved7[3]; /* These three bytes must be zero */
+struct fadt_descriptor_rev2_minus {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ FADT_REV2_COMMON u8 reserved2; /* Reserved, must be zero */
+ u32 flags;
+ struct acpi_generic_address reset_register; /* Reset register address in GAS format */
+ u8 reset_value; /* Value to write to the reset_register port to reset the system. */
+ u8 reserved7[3]; /* Reserved, must be zero */
};
-
/* ECDT - Embedded Controller Boot Resources Table */
-struct ec_boot_resources
-{
- ACPI_TABLE_HEADER_DEF
- struct acpi_generic_address ec_control; /* Address of EC command/status register */
- struct acpi_generic_address ec_data; /* Address of EC data register */
- u32 uid; /* Unique ID - must be same as the EC _UID method */
- u8 gpe_bit; /* The GPE for the EC */
- u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */
+struct ec_boot_resources {
+ ACPI_TABLE_HEADER_DEF struct acpi_generic_address ec_control; /* Address of EC command/status register */
+ struct acpi_generic_address ec_data; /* Address of EC data register */
+ u32 uid; /* Unique ID - must be same as the EC _UID method */
+ u8 gpe_bit; /* The GPE for the EC */
+ u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */
};
-
/* SRAT - System Resource Affinity Table */
-struct static_resource_alloc
-{
- u8 type;
- u8 length;
- u8 proximity_domain_lo;
- u8 apic_id;
- u32 enabled :1;
- u32 reserved3 :31;
- u8 local_sapic_eid;
- u8 proximity_domain_hi[3];
- u32 reserved4;
-};
+struct static_resource_alloc {
+ u8 type;
+ u8 length;
+ u8 proximity_domain_lo;
+ u8 apic_id;
-struct memory_affinity
-{
- u8 type;
- u8 length;
- u32 proximity_domain;
- u16 reserved3;
- u64 base_address;
- u64 address_length;
- u32 reserved4;
- u32 enabled :1;
- u32 hot_pluggable :1;
- u32 non_volatile :1;
- u32 reserved5 :29;
- u64 reserved6;
+ /* Flags (32 bits) */
+
+ u8 enabled:1; /* 00: Use affinity structure */
+ u8:7; /* 01-07: Reserved, must be zero */
+ u8 reserved3[3]; /* 08-31: Reserved, must be zero */
+
+ u8 local_sapic_eid;
+ u8 proximity_domain_hi[3];
+ u32 reserved4; /* Reserved, must be zero */
};
-struct system_resource_affinity
-{
- ACPI_TABLE_HEADER_DEF
- u32 reserved1; /* Must be value '1' */
- u64 reserved2;
+struct memory_affinity {
+ u8 type;
+ u8 length;
+ u32 proximity_domain;
+ u16 reserved3;
+ u64 base_address;
+ u64 address_length;
+ u32 reserved4;
+
+ /* Flags (32 bits) */
+
+ u8 enabled:1; /* 00: Use affinity structure */
+ u8 hot_pluggable:1; /* 01: Memory region is hot pluggable */
+ u8 non_volatile:1; /* 02: Memory is non-volatile */
+ u8:5; /* 03-07: Reserved, must be zero */
+ u8 reserved5[3]; /* 08-31: Reserved, must be zero */
+
+ u64 reserved6; /* Reserved, must be zero */
};
+struct system_resource_affinity {
+ ACPI_TABLE_HEADER_DEF u32 reserved1; /* Must be value '1' */
+ u64 reserved2; /* Reserved, must be zero */
+};
/* SLIT - System Locality Distance Information Table */
-struct system_locality_info
-{
- ACPI_TABLE_HEADER_DEF
- u64 locality_count;
- u8 entry[1][1];
+struct system_locality_info {
+ ACPI_TABLE_HEADER_DEF u64 locality_count;
+ u8 entry[1][1];
};
-
#pragma pack()
-#endif /* __ACTBL2_H__ */
-
+#endif /* __ACTBL2_H__ */
diff --git a/include/acpi/actbl71.h b/include/acpi/actbl71.h
index 7b4fb44261f3..10ac05bb36bc 100644
--- a/include/acpi/actbl71.h
+++ b/include/acpi/actbl71.h
@@ -27,7 +27,6 @@
#ifndef __ACTBL71_H__
#define __ACTBL71_H__
-
/* 0.71 FADT address_space data item bitmasks defines */
/* If the associated bit is zero then it is in memory space else in io space */
@@ -40,105 +39,96 @@
/* Only for clarity in declarations */
-typedef u64 IO_ADDRESS;
-
+typedef u64 IO_ADDRESS;
#pragma pack(1)
-struct /* Root System Descriptor Pointer */
-{
- NATIVE_CHAR signature [8]; /* contains "RSD PTR " */
- u8 checksum; /* to make sum of struct == 0 */
- NATIVE_CHAR oem_id [6]; /* OEM identification */
- u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */
- u64 rsdt_physical_address; /* 64-bit physical address of RSDT */
+struct { /* Root System Descriptor Pointer */
+ NATIVE_CHAR signature[8]; /* contains "RSD PTR " */
+ u8 checksum; /* to make sum of struct == 0 */
+ NATIVE_CHAR oem_id[6]; /* OEM identification */
+ u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */
+ u64 rsdt_physical_address; /* 64-bit physical address of RSDT */
};
-
/*****************************************/
/* IA64 Extensions to ACPI Spec Rev 0.71 */
/* for the Root System Description Table */
/*****************************************/
-struct
-{
- struct acpi_table_header header; /* Table header */
- u32 reserved_pad; /* IA64 alignment, must be 0 */
- u64 table_offset_entry [1]; /* Array of pointers to other */
- /* tables' headers */
+struct {
+ struct acpi_table_header header; /* Table header */
+ u32 reserved_pad; /* IA64 alignment, must be 0 */
+ u64 table_offset_entry[1]; /* Array of pointers to other */
+ /* tables' headers */
};
-
/*******************************************/
/* IA64 Extensions to ACPI Spec Rev 0.71 */
/* for the Firmware ACPI Control Structure */
/*******************************************/
-struct
-{
- NATIVE_CHAR signature[4]; /* signature "FACS" */
- u32 length; /* length of structure, in bytes */
- u32 hardware_signature; /* hardware configuration signature */
- u32 reserved4; /* must be 0 */
- u64 firmware_waking_vector; /* ACPI OS waking vector */
- u64 global_lock; /* Global Lock */
- u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */
- u32 reserved1 : 31; /* must be 0 */
- u8 reserved3 [28]; /* reserved - must be zero */
+struct {
+ NATIVE_CHAR signature[4]; /* signature "FACS" */
+ u32 length; /* length of structure, in bytes */
+ u32 hardware_signature; /* hardware configuration signature */
+ u32 reserved4; /* must be 0 */
+ u64 firmware_waking_vector; /* ACPI OS waking vector */
+ u64 global_lock; /* Global Lock */
+ u32 S4bios_f:1; /* Indicates if S4BIOS support is present */
+ u32 reserved1:31; /* must be 0 */
+ u8 reserved3[28]; /* reserved - must be zero */
};
-
/******************************************/
/* IA64 Extensions to ACPI Spec Rev 0.71 */
/* for the Fixed ACPI Description Table */
/******************************************/
-struct
-{
- struct acpi_table_header header; /* table header */
- u32 reserved_pad; /* IA64 alignment, must be 0 */
- u64 firmware_ctrl; /* 64-bit Physical address of FACS */
- u64 dsdt; /* 64-bit Physical address of DSDT */
- u8 model; /* System Interrupt Model */
- u8 address_space; /* Address Space Bitmask */
- u16 sci_int; /* System vector of SCI interrupt */
- u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */
- u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */
- u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
- u8 reserved2; /* reserved - must be zero */
- u64 smi_cmd; /* Port address of SMI command port */
- u64 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
- u64 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
- u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
- u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
- u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
- u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
- u64 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
- u64 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
- u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
- u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
- u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
- u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */
- u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
- u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
- u8 gpe1_base; /* offset in gpe model where gpe1 events start */
- u8 reserved3; /* reserved */
- u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */
- u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */
- u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */
- u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */
- u8 century; /* index to century in RTC CMOS RAM */
- u8 reserved4; /* reserved */
- u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */
- u32 reserved5 : 1; /* reserved - must be zero */
- u32 proc_c1 : 1; /* all processors support C1 state */
- u32 plvl2_up : 1; /* C2 state works on MP system */
- u32 pwr_button : 1; /* Power button is handled as a generic feature */
- u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
- u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
- u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
- u32 tmr_val_ext : 1; /* tmr_val is 32 bits */
- u32 dock_cap : 1; /* Supports Docking */
- u32 reserved6 : 22; /* reserved - must be zero */
+struct {
+ struct acpi_table_header header; /* table header */
+ u32 reserved_pad; /* IA64 alignment, must be 0 */
+ u64 firmware_ctrl; /* 64-bit Physical address of FACS */
+ u64 dsdt; /* 64-bit Physical address of DSDT */
+ u8 model; /* System Interrupt Model */
+ u8 address_space; /* Address Space Bitmask */
+ u16 sci_int; /* System vector of SCI interrupt */
+ u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */
+ u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */
+ u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
+ u8 reserved2; /* reserved - must be zero */
+ u64 smi_cmd; /* Port address of SMI command port */
+ u64 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
+ u64 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
+ u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
+ u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
+ u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
+ u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
+ u64 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
+ u64 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
+ u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
+ u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
+ u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
+ u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */
+ u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
+ u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
+ u8 gpe1_base; /* offset in gpe model where gpe1 events start */
+ u8 reserved3; /* reserved */
+ u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */
+ u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */
+ u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */
+ u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */
+ u8 century; /* index to century in RTC CMOS RAM */
+ u8 reserved4; /* reserved */
+ u32 flush_cash:1; /* PAL_FLUSH_CACHE is correctly supported */
+ u32 reserved5:1; /* reserved - must be zero */
+ u32 proc_c1:1; /* all processors support C1 state */
+ u32 plvl2_up:1; /* C2 state works on MP system */
+ u32 pwr_button:1; /* Power button is handled as a generic feature */
+ u32 sleep_button:1; /* Sleep button is handled as a generic feature, or not present */
+ u32 fixed_rTC:1; /* RTC wakeup stat not in fixed register space */
+ u32 rtcs4:1; /* RTC wakeup stat not possible from S4 */
+ u32 tmr_val_ext:1; /* tmr_val is 32 bits */
+ u32 dock_cap:1; /* Supports Docking */
+ u32 reserved6:22; /* reserved - must be zero */
};
#pragma pack()
-#endif /* __ACTBL71_H__ */
-
+#endif /* __ACTBL71_H__ */
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 3a451dc48ac8..6213b27516e8 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -46,35 +46,31 @@
/*! [Begin] no source code translation (keep the typedefs) */
-
-
/*
* Data type ranges
* Note: These macros are designed to be compiler independent as well as
* working around problems that some 32-bit compilers have with 64-bit
* constants.
*/
-#define ACPI_UINT8_MAX (UINT8) (~((UINT8) 0)) /* 0xFF */
-#define ACPI_UINT16_MAX (UINT16)(~((UINT16) 0)) /* 0xFFFF */
-#define ACPI_UINT32_MAX (UINT32)(~((UINT32) 0)) /* 0xFFFFFFFF */
-#define ACPI_UINT64_MAX (UINT64)(~((UINT64) 0)) /* 0xFFFFFFFFFFFFFFFF */
+#define ACPI_UINT8_MAX (UINT8) (~((UINT8) 0)) /* 0xFF */
+#define ACPI_UINT16_MAX (UINT16)(~((UINT16) 0)) /* 0xFFFF */
+#define ACPI_UINT32_MAX (UINT32)(~((UINT32) 0)) /* 0xFFFFFFFF */
+#define ACPI_UINT64_MAX (UINT64)(~((UINT64) 0)) /* 0xFFFFFFFFFFFFFFFF */
#define ACPI_ASCII_MAX 0x7F
-
#ifdef DEFINE_ALTERNATE_TYPES
/*
* Types used only in translated source, defined here to enable
* cross-platform compilation only.
*/
-typedef int s32;
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef COMPILER_DEPENDENT_UINT64 u64;
+typedef int s32;
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef COMPILER_DEPENDENT_UINT64 u64;
#endif
-
/*
* Data types - Fixed across all compilation models (16/32/64)
*
@@ -102,30 +98,29 @@ typedef COMPILER_DEPENDENT_UINT64 u64;
/*
* 64-bit type definitions
*/
-typedef unsigned char UINT8;
-typedef unsigned char BOOLEAN;
-typedef unsigned short UINT16;
-typedef int INT32;
-typedef unsigned int UINT32;
-typedef COMPILER_DEPENDENT_INT64 INT64;
-typedef COMPILER_DEPENDENT_UINT64 UINT64;
+typedef unsigned char UINT8;
+typedef unsigned char BOOLEAN;
+typedef unsigned short UINT16;
+typedef int INT32;
+typedef unsigned int UINT32;
+typedef COMPILER_DEPENDENT_INT64 INT64;
+typedef COMPILER_DEPENDENT_UINT64 UINT64;
/*! [End] no source code translation !*/
-typedef s64 acpi_native_int;
-typedef u64 acpi_native_uint;
+typedef s64 acpi_native_int;
+typedef u64 acpi_native_uint;
-typedef u64 acpi_table_ptr;
-typedef u64 acpi_io_address;
-typedef u64 acpi_physical_address;
-typedef u64 acpi_size;
+typedef u64 acpi_table_ptr;
+typedef u64 acpi_io_address;
+typedef u64 acpi_physical_address;
+typedef u64 acpi_size;
-#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 /* No hardware alignment support in IA64 */
-#define ACPI_USE_NATIVE_DIVIDE /* Native 64-bit integer support */
+#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 /* No hardware alignment support in IA64 */
+#define ACPI_USE_NATIVE_DIVIDE /* Native 64-bit integer support */
#define ACPI_MAX_PTR ACPI_UINT64_MAX
#define ACPI_SIZE_MAX ACPI_UINT64_MAX
-
#elif ACPI_MACHINE_WIDTH == 16
/*! [Begin] no source code translation (keep the typedefs) */
@@ -133,32 +128,31 @@ typedef u64 acpi_size;
/*
* 16-bit type definitions
*/
-typedef unsigned char UINT8;
-typedef unsigned char BOOLEAN;
-typedef unsigned int UINT16;
-typedef long INT32;
-typedef int INT16;
-typedef unsigned long UINT32;
-
-struct
-{
- UINT32 Lo;
- UINT32 Hi;
+typedef unsigned char UINT8;
+typedef unsigned char BOOLEAN;
+typedef unsigned int UINT16;
+typedef long INT32;
+typedef int INT16;
+typedef unsigned long UINT32;
+
+struct {
+ UINT32 Lo;
+ UINT32 Hi;
};
/*! [End] no source code translation !*/
-typedef u16 acpi_native_uint;
-typedef s16 acpi_native_int;
+typedef u16 acpi_native_uint;
+typedef s16 acpi_native_int;
-typedef u32 acpi_table_ptr;
-typedef u32 acpi_io_address;
-typedef char *acpi_physical_address;
-typedef u16 acpi_size;
+typedef u32 acpi_table_ptr;
+typedef u32 acpi_io_address;
+typedef char *acpi_physical_address;
+typedef u16 acpi_size;
#define ALIGNED_ADDRESS_BOUNDARY 0x00000002
#define ACPI_MISALIGNED_TRANSFERS
-#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */
+#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */
#define ACPI_MAX_PTR ACPI_UINT16_MAX
#define ACPI_SIZE_MAX ACPI_UINT16_MAX
@@ -168,7 +162,6 @@ typedef u16 acpi_size;
*/
#define ACPI_NO_INTEGER64_SUPPORT
-
#elif ACPI_MACHINE_WIDTH == 32
/*! [Begin] no source code translation (keep the typedefs) */
@@ -176,23 +169,23 @@ typedef u16 acpi_size;
/*
* 32-bit type definitions (default)
*/
-typedef unsigned char UINT8;
-typedef unsigned char BOOLEAN;
-typedef unsigned short UINT16;
-typedef int INT32;
-typedef unsigned int UINT32;
-typedef COMPILER_DEPENDENT_INT64 INT64;
-typedef COMPILER_DEPENDENT_UINT64 UINT64;
+typedef unsigned char UINT8;
+typedef unsigned char BOOLEAN;
+typedef unsigned short UINT16;
+typedef int INT32;
+typedef unsigned int UINT32;
+typedef COMPILER_DEPENDENT_INT64 INT64;
+typedef COMPILER_DEPENDENT_UINT64 UINT64;
/*! [End] no source code translation !*/
-typedef s32 acpi_native_int;
-typedef u32 acpi_native_uint;
+typedef s32 acpi_native_int;
+typedef u32 acpi_native_uint;
-typedef u64 acpi_table_ptr;
-typedef u32 acpi_io_address;
-typedef u64 acpi_physical_address;
-typedef u32 acpi_size;
+typedef u64 acpi_table_ptr;
+typedef u32 acpi_io_address;
+typedef u64 acpi_physical_address;
+typedef u32 acpi_size;
#define ALIGNED_ADDRESS_BOUNDARY 0x00000004
#define ACPI_MISALIGNED_TRANSFERS
@@ -203,29 +196,27 @@ typedef u32 acpi_size;
#error unknown ACPI_MACHINE_WIDTH
#endif
-
/*
- * Miscellaneous common types
+ * This type is used for bitfields in ACPI tables. The only type that is
+ * even remotely portable is u8. Anything else is not portable, so
+ * do not add any more bitfield types.
*/
-typedef u16 UINT16_BIT;
-typedef u32 UINT32_BIT;
-typedef acpi_native_uint ACPI_PTRDIFF;
+typedef u8 UINT8_BIT;
+typedef acpi_native_uint ACPI_PTRDIFF;
/*
* Pointer overlays to avoid lots of typecasting for
* code that accepts both physical and logical pointers.
*/
-union acpi_pointers
-{
- acpi_physical_address physical;
- void *logical;
- acpi_table_ptr value;
+union acpi_pointers {
+ acpi_physical_address physical;
+ void *logical;
+ acpi_table_ptr value;
};
-struct acpi_pointer
-{
- u32 pointer_type;
- union acpi_pointers pointer;
+struct acpi_pointer {
+ u32 pointer_type;
+ union acpi_pointers pointer;
};
/* pointer_types for above */
@@ -243,6 +234,14 @@ struct acpi_pointer
#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER
+/*
+ * If acpi_cache_t was not defined in the OS-dependent header,
+ * define it now. This is typically the case where the local cache
+ * manager implementation is to be used (ACPI_USE_LOCAL_CACHE)
+ */
+#ifndef acpi_cache_t
+#define acpi_cache_t struct acpi_memory_list
+#endif
/*
* Useful defines
@@ -261,34 +260,29 @@ struct acpi_pointer
#define NULL (void *) 0
#endif
-
/*
* Local datatypes
*/
-typedef u32 acpi_status; /* All ACPI Exceptions */
-typedef u32 acpi_name; /* 4-byte ACPI name */
-typedef char * acpi_string; /* Null terminated ASCII string */
-typedef void * acpi_handle; /* Actually a ptr to an Node */
-
-struct uint64_struct
-{
- u32 lo;
- u32 hi;
+typedef u32 acpi_status; /* All ACPI Exceptions */
+typedef u32 acpi_name; /* 4-byte ACPI name */
+typedef char *acpi_string; /* Null terminated ASCII string */
+typedef void *acpi_handle; /* Actually a ptr to an Node */
+
+struct uint64_struct {
+ u32 lo;
+ u32 hi;
};
-union uint64_overlay
-{
- u64 full;
- struct uint64_struct part;
+union uint64_overlay {
+ u64 full;
+ struct uint64_struct part;
};
-struct uint32_struct
-{
- u32 lo;
- u32 hi;
+struct uint32_struct {
+ u32 lo;
+ u32 hi;
};
-
/*
* Acpi integer width. In ACPI version 1, integers are
* 32 bits. In ACPI version 2, integers are 64 bits.
@@ -300,26 +294,24 @@ struct uint32_struct
/* 32-bit integers only, no 64-bit support */
-typedef u32 acpi_integer;
+typedef u32 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT32_MAX
#define ACPI_INTEGER_BIT_SIZE 32
-#define ACPI_MAX_DECIMAL_DIGITS 10 /* 2^32 = 4,294,967,296 */
-
-#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */
+#define ACPI_MAX_DECIMAL_DIGITS 10 /* 2^32 = 4,294,967,296 */
+#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */
#else
/* 64-bit integers */
-typedef u64 acpi_integer;
+typedef u64 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
#define ACPI_INTEGER_BIT_SIZE 64
-#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
-
+#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
#if ACPI_MACHINE_WIDTH == 64
-#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */
+#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */
#endif
#endif
@@ -333,7 +325,6 @@ typedef u64 acpi_integer;
*/
#define ACPI_ROOT_OBJECT (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR)
-
/*
* Initialization sequence
*/
@@ -400,7 +391,7 @@ typedef u64 acpi_integer;
/*
* Table types. These values are passed to the table related APIs
*/
-typedef u32 acpi_table_type;
+typedef u32 acpi_table_type;
#define ACPI_TABLE_RSDP (acpi_table_type) 0
#define ACPI_TABLE_DSDT (acpi_table_type) 1
@@ -421,22 +412,22 @@ typedef u32 acpi_table_type;
* NOTE: Types must be kept in sync with the global acpi_ns_properties
* and acpi_ns_type_names arrays.
*/
-typedef u32 acpi_object_type;
+typedef u32 acpi_object_type;
#define ACPI_TYPE_ANY 0x00
-#define ACPI_TYPE_INTEGER 0x01 /* Byte/Word/Dword/Zero/One/Ones */
+#define ACPI_TYPE_INTEGER 0x01 /* Byte/Word/Dword/Zero/One/Ones */
#define ACPI_TYPE_STRING 0x02
#define ACPI_TYPE_BUFFER 0x03
-#define ACPI_TYPE_PACKAGE 0x04 /* byte_const, multiple data_term/Constant/super_name */
+#define ACPI_TYPE_PACKAGE 0x04 /* byte_const, multiple data_term/Constant/super_name */
#define ACPI_TYPE_FIELD_UNIT 0x05
-#define ACPI_TYPE_DEVICE 0x06 /* Name, multiple Node */
+#define ACPI_TYPE_DEVICE 0x06 /* Name, multiple Node */
#define ACPI_TYPE_EVENT 0x07
-#define ACPI_TYPE_METHOD 0x08 /* Name, byte_const, multiple Code */
+#define ACPI_TYPE_METHOD 0x08 /* Name, byte_const, multiple Code */
#define ACPI_TYPE_MUTEX 0x09
#define ACPI_TYPE_REGION 0x0A
-#define ACPI_TYPE_POWER 0x0B /* Name,byte_const,word_const,multi Node */
-#define ACPI_TYPE_PROCESSOR 0x0C /* Name,byte_const,Dword_const,byte_const,multi nm_o */
-#define ACPI_TYPE_THERMAL 0x0D /* Name, multiple Node */
+#define ACPI_TYPE_POWER 0x0B /* Name,byte_const,word_const,multi Node */
+#define ACPI_TYPE_PROCESSOR 0x0C /* Name,byte_const,Dword_const,byte_const,multi nm_o */
+#define ACPI_TYPE_THERMAL 0x0D /* Name, multiple Node */
#define ACPI_TYPE_BUFFER_FIELD 0x0E
#define ACPI_TYPE_DDB_HANDLE 0x0F
#define ACPI_TYPE_DEBUG_OBJECT 0x10
@@ -453,16 +444,16 @@ typedef u32 acpi_object_type;
#define ACPI_TYPE_LOCAL_REGION_FIELD 0x11
#define ACPI_TYPE_LOCAL_BANK_FIELD 0x12
#define ACPI_TYPE_LOCAL_INDEX_FIELD 0x13
-#define ACPI_TYPE_LOCAL_REFERENCE 0x14 /* Arg#, Local#, Name, Debug, ref_of, Index */
+#define ACPI_TYPE_LOCAL_REFERENCE 0x14 /* Arg#, Local#, Name, Debug, ref_of, Index */
#define ACPI_TYPE_LOCAL_ALIAS 0x15
#define ACPI_TYPE_LOCAL_METHOD_ALIAS 0x16
#define ACPI_TYPE_LOCAL_NOTIFY 0x17
#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x18
#define ACPI_TYPE_LOCAL_RESOURCE 0x19
#define ACPI_TYPE_LOCAL_RESOURCE_FIELD 0x1A
-#define ACPI_TYPE_LOCAL_SCOPE 0x1B /* 1 Name, multiple object_list Nodes */
+#define ACPI_TYPE_LOCAL_SCOPE 0x1B /* 1 Name, multiple object_list Nodes */
-#define ACPI_TYPE_NS_NODE_MAX 0x1B /* Last typecode used within a NS Node */
+#define ACPI_TYPE_NS_NODE_MAX 0x1B /* Last typecode used within a NS Node */
/*
* These are special object types that never appear in
@@ -506,7 +497,7 @@ typedef u32 acpi_object_type;
#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE)
#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
-#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */
+#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */
#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF
/*
@@ -519,7 +510,7 @@ typedef u32 acpi_object_type;
/*
* Event Types: Fixed & General Purpose
*/
-typedef u32 acpi_event_type;
+typedef u32 acpi_event_type;
/*
* Fixed events
@@ -547,7 +538,7 @@ typedef u32 acpi_event_type;
* | +----- Set?
* +----------- <Reserved>
*/
-typedef u32 acpi_event_status;
+typedef u32 acpi_event_status;
#define ACPI_EVENT_FLAG_DISABLED (acpi_event_status) 0x00
#define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01
@@ -564,7 +555,6 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_ENABLE 0
#define ACPI_GPE_DISABLE 1
-
/*
* GPE info flags - Per GPE
* +-+-+-+---+---+-+
@@ -585,22 +575,22 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_TYPE_MASK (u8) 0x06
#define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x06
#define ACPI_GPE_TYPE_WAKE (u8) 0x02
-#define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */
+#define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */
#define ACPI_GPE_DISPATCH_MASK (u8) 0x18
#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x08
#define ACPI_GPE_DISPATCH_METHOD (u8) 0x10
-#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */
+#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */
#define ACPI_GPE_RUN_ENABLE_MASK (u8) 0x20
#define ACPI_GPE_RUN_ENABLED (u8) 0x20
-#define ACPI_GPE_RUN_DISABLED (u8) 0x00 /* Default */
+#define ACPI_GPE_RUN_DISABLED (u8) 0x00 /* Default */
#define ACPI_GPE_WAKE_ENABLE_MASK (u8) 0x40
#define ACPI_GPE_WAKE_ENABLED (u8) 0x40
-#define ACPI_GPE_WAKE_DISABLED (u8) 0x00 /* Default */
+#define ACPI_GPE_WAKE_DISABLED (u8) 0x00 /* Default */
-#define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */
+#define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */
#define ACPI_GPE_SYSTEM_MASK (u8) 0x80
#define ACPI_GPE_SYSTEM_RUNNING (u8) 0x80
@@ -609,13 +599,12 @@ typedef u32 acpi_event_status;
/*
* Flags for GPE and Lock interfaces
*/
-#define ACPI_EVENT_WAKE_ENABLE 0x2 /* acpi_gpe_enable */
-#define ACPI_EVENT_WAKE_DISABLE 0x2 /* acpi_gpe_disable */
+#define ACPI_EVENT_WAKE_ENABLE 0x2 /* acpi_gpe_enable */
+#define ACPI_EVENT_WAKE_DISABLE 0x2 /* acpi_gpe_disable */
#define ACPI_NOT_ISR 0x1
#define ACPI_ISR 0x0
-
/* Notify types */
#define ACPI_SYSTEM_NOTIFY 0x1
@@ -625,10 +614,9 @@ typedef u32 acpi_event_status;
#define ACPI_MAX_SYS_NOTIFY 0x7f
-
/* Address Space (Operation Region) Types */
-typedef u8 acpi_adr_space_type;
+typedef u8 acpi_adr_space_type;
#define ACPI_ADR_SPACE_SYSTEM_MEMORY (acpi_adr_space_type) 0
#define ACPI_ADR_SPACE_SYSTEM_IO (acpi_adr_space_type) 1
@@ -640,7 +628,6 @@ typedef u8 acpi_adr_space_type;
#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 7
#define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127
-
/*
* bit_register IDs
* These are bitfields defined within the full ACPI registers
@@ -674,74 +661,62 @@ typedef u8 acpi_adr_space_type;
#define ACPI_BITREG_MAX 0x15
#define ACPI_NUM_BITREG ACPI_BITREG_MAX + 1
-
/*
* External ACPI object definition
*/
-union acpi_object
-{
- acpi_object_type type; /* See definition of acpi_ns_type for values */
- struct
- {
- acpi_object_type type;
- acpi_integer value; /* The actual number */
+union acpi_object {
+ acpi_object_type type; /* See definition of acpi_ns_type for values */
+ struct {
+ acpi_object_type type;
+ acpi_integer value; /* The actual number */
} integer;
- struct
- {
- acpi_object_type type;
- u32 length; /* # of bytes in string, excluding trailing null */
- char *pointer; /* points to the string value */
+ struct {
+ acpi_object_type type;
+ u32 length; /* # of bytes in string, excluding trailing null */
+ char *pointer; /* points to the string value */
} string;
- struct
- {
- acpi_object_type type;
- u32 length; /* # of bytes in buffer */
- u8 *pointer; /* points to the buffer */
+ struct {
+ acpi_object_type type;
+ u32 length; /* # of bytes in buffer */
+ u8 *pointer; /* points to the buffer */
} buffer;
- struct
- {
- acpi_object_type type;
- u32 fill1;
- acpi_handle handle; /* object reference */
+ struct {
+ acpi_object_type type;
+ u32 fill1;
+ acpi_handle handle; /* object reference */
} reference;
- struct
- {
- acpi_object_type type;
- u32 count; /* # of elements in package */
- union acpi_object *elements; /* Pointer to an array of ACPI_OBJECTs */
+ struct {
+ acpi_object_type type;
+ u32 count; /* # of elements in package */
+ union acpi_object *elements; /* Pointer to an array of ACPI_OBJECTs */
} package;
- struct
- {
- acpi_object_type type;
- u32 proc_id;
- acpi_io_address pblk_address;
- u32 pblk_length;
+ struct {
+ acpi_object_type type;
+ u32 proc_id;
+ acpi_io_address pblk_address;
+ u32 pblk_length;
} processor;
- struct
- {
- acpi_object_type type;
- u32 system_level;
- u32 resource_order;
+ struct {
+ acpi_object_type type;
+ u32 system_level;
+ u32 resource_order;
} power_resource;
};
-
/*
* List of objects, used as a parameter list for control method evaluation
*/
-struct acpi_object_list
-{
- u32 count;
- union acpi_object *pointer;
+struct acpi_object_list {
+ u32 count;
+ union acpi_object *pointer;
};
-
/*
* Miscellaneous common Data Structures used by the interfaces
*/
@@ -749,13 +724,11 @@ struct acpi_object_list
#define ACPI_ALLOCATE_BUFFER (acpi_size) (-1)
#define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2)
-struct acpi_buffer
-{
- acpi_size length; /* Length in bytes of the buffer */
- void *pointer; /* pointer to buffer */
+struct acpi_buffer {
+ acpi_size length; /* Length in bytes of the buffer */
+ void *pointer; /* pointer to buffer */
};
-
/*
* name_type for acpi_get_name
*/
@@ -763,7 +736,6 @@ struct acpi_buffer
#define ACPI_SINGLE_NAME 1
#define ACPI_NAME_TYPE_MAX 1
-
/*
* Structure and flags for acpi_get_system_info
*/
@@ -772,139 +744,106 @@ struct acpi_buffer
#define ACPI_SYS_MODE_LEGACY 0x0002
#define ACPI_SYS_MODES_MASK 0x0003
-
/*
* ACPI Table Info. One per ACPI table _type_
*/
-struct acpi_table_info
-{
- u32 count;
+struct acpi_table_info {
+ u32 count;
};
-
/*
* System info returned by acpi_get_system_info()
*/
-struct acpi_system_info
-{
- u32 acpi_ca_version;
- u32 flags;
- u32 timer_resolution;
- u32 reserved1;
- u32 reserved2;
- u32 debug_level;
- u32 debug_layer;
- u32 num_table_types;
- struct acpi_table_info table_info [NUM_ACPI_TABLE_TYPES];
+struct acpi_system_info {
+ u32 acpi_ca_version;
+ u32 flags;
+ u32 timer_resolution;
+ u32 reserved1;
+ u32 reserved2;
+ u32 debug_level;
+ u32 debug_layer;
+ u32 num_table_types;
+ struct acpi_table_info table_info[NUM_ACPI_TABLE_TYPES];
};
-
/*
* Types specific to the OS service interfaces
*/
-typedef u32
-(ACPI_SYSTEM_XFACE *acpi_osd_handler) (
- void *context);
+typedef u32(ACPI_SYSTEM_XFACE * acpi_osd_handler) (void *context);
typedef void
-(ACPI_SYSTEM_XFACE *acpi_osd_exec_callback) (
- void *context);
+ (ACPI_SYSTEM_XFACE * acpi_osd_exec_callback) (void *context);
/*
* Various handlers and callback procedures
*/
-typedef
-u32 (*acpi_event_handler) (
- void *context);
+typedef u32(*acpi_event_handler) (void *context);
typedef
-void (*acpi_notify_handler) (
- acpi_handle device,
- u32 value,
- void *context);
+void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context);
typedef
-void (*acpi_object_handler) (
- acpi_handle object,
- u32 function,
- void *data);
+void (*acpi_object_handler) (acpi_handle object, u32 function, void *data);
-typedef
-acpi_status (*acpi_init_handler) (
- acpi_handle object,
- u32 function);
+typedef acpi_status(*acpi_init_handler) (acpi_handle object, u32 function);
#define ACPI_INIT_DEVICE_INI 1
typedef
-acpi_status (*acpi_exception_handler) (
- acpi_status aml_status,
- acpi_name name,
- u16 opcode,
- u32 aml_offset,
- void *context);
-
+acpi_status(*acpi_exception_handler) (acpi_status aml_status,
+ acpi_name name,
+ u16 opcode,
+ u32 aml_offset, void *context);
/* Address Spaces (For Operation Regions) */
typedef
-acpi_status (*acpi_adr_space_handler) (
- u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer *value,
- void *handler_context,
- void *region_context);
+acpi_status(*acpi_adr_space_handler) (u32 function,
+ acpi_physical_address address,
+ u32 bit_width,
+ acpi_integer * value,
+ void *handler_context,
+ void *region_context);
#define ACPI_DEFAULT_HANDLER NULL
-
typedef
-acpi_status (*acpi_adr_space_setup) (
- acpi_handle region_handle,
- u32 function,
- void *handler_context,
- void **region_context);
+acpi_status(*acpi_adr_space_setup) (acpi_handle region_handle,
+ u32 function,
+ void *handler_context,
+ void **region_context);
#define ACPI_REGION_ACTIVATE 0
#define ACPI_REGION_DEACTIVATE 1
typedef
-acpi_status (*acpi_walk_callback) (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value);
-
+acpi_status(*acpi_walk_callback) (acpi_handle obj_handle,
+ u32 nesting_level,
+ void *context, void **return_value);
/* Interrupt handler return values */
#define ACPI_INTERRUPT_NOT_HANDLED 0x00
#define ACPI_INTERRUPT_HANDLED 0x01
-
/* Common string version of device HIDs and UIDs */
-struct acpi_device_id
-{
- char value[ACPI_DEVICE_ID_LENGTH];
+struct acpi_device_id {
+ char value[ACPI_DEVICE_ID_LENGTH];
};
/* Common string version of device CIDs */
-struct acpi_compatible_id
-{
- char value[ACPI_MAX_CID_LENGTH];
+struct acpi_compatible_id {
+ char value[ACPI_MAX_CID_LENGTH];
};
-struct acpi_compatible_id_list
-{
- u32 count;
- u32 size;
- struct acpi_compatible_id id[1];
+struct acpi_compatible_id_list {
+ u32 count;
+ u32 size;
+ struct acpi_compatible_id id[1];
};
-
/* Structure and flags for acpi_get_object_info */
#define ACPI_VALID_STA 0x0001
@@ -914,55 +853,45 @@ struct acpi_compatible_id_list
#define ACPI_VALID_CID 0x0010
#define ACPI_VALID_SXDS 0x0020
-
#define ACPI_COMMON_OBJ_INFO \
acpi_object_type type; /* ACPI object type */ \
- acpi_name name /* ACPI object Name */
-
+ acpi_name name /* ACPI object Name */
-struct acpi_obj_info_header
-{
+struct acpi_obj_info_header {
ACPI_COMMON_OBJ_INFO;
};
-
/* Structure returned from Get Object Info */
-struct acpi_device_info
-{
+struct acpi_device_info {
ACPI_COMMON_OBJ_INFO;
- u32 valid; /* Indicates which fields below are valid */
- u32 current_status; /* _STA value */
- acpi_integer address; /* _ADR value if any */
- struct acpi_device_id hardware_id; /* _HID value if any */
- struct acpi_device_id unique_id; /* _UID value if any */
- u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
- struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */
+ u32 valid; /* Indicates which fields below are valid */
+ u32 current_status; /* _STA value */
+ acpi_integer address; /* _ADR value if any */
+ struct acpi_device_id hardware_id; /* _HID value if any */
+ struct acpi_device_id unique_id; /* _UID value if any */
+ u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
+ struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */
};
-
/* Context structs for address space handlers */
-struct acpi_pci_id
-{
- u16 segment;
- u16 bus;
- u16 device;
- u16 function;
+struct acpi_pci_id {
+ u16 segment;
+ u16 bus;
+ u16 device;
+ u16 function;
};
-
-struct acpi_mem_space_context
-{
- u32 length;
- acpi_physical_address address;
- acpi_physical_address mapped_physical_address;
- u8 *mapped_logical_address;
- acpi_size mapped_length;
+struct acpi_mem_space_context {
+ u32 length;
+ acpi_physical_address address;
+ acpi_physical_address mapped_physical_address;
+ u8 *mapped_logical_address;
+ acpi_size mapped_length;
};
-
/*
* Definitions for Resource Attributes
*/
@@ -992,8 +921,8 @@ struct acpi_mem_space_context
/*
* IO Port Descriptor Decode
*/
-#define ACPI_DECODE_10 (u8) 0x00 /* 10-bit IO address decode */
-#define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */
+#define ACPI_DECODE_10 (u8) 0x00 /* 10-bit IO address decode */
+#define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */
/*
* IRQ Attributes
@@ -1045,32 +974,28 @@ struct acpi_mem_space_context
#define ACPI_PRODUCER (u8) 0x00
#define ACPI_CONSUMER (u8) 0x01
-
/*
* Structures used to describe device resources
*/
-struct acpi_resource_irq
-{
- u32 edge_level;
- u32 active_high_low;
- u32 shared_exclusive;
- u32 number_of_interrupts;
- u32 interrupts[1];
+struct acpi_resource_irq {
+ u32 edge_level;
+ u32 active_high_low;
+ u32 shared_exclusive;
+ u32 number_of_interrupts;
+ u32 interrupts[1];
};
-struct acpi_resource_dma
-{
- u32 type;
- u32 bus_master;
- u32 transfer;
- u32 number_of_channels;
- u32 channels[1];
+struct acpi_resource_dma {
+ u32 type;
+ u32 bus_master;
+ u32 transfer;
+ u32 number_of_channels;
+ u32 channels[1];
};
-struct acpi_resource_start_dpf
-{
- u32 compatibility_priority;
- u32 performance_robustness;
+struct acpi_resource_start_dpf {
+ u32 compatibility_priority;
+ u32 performance_robustness;
};
/*
@@ -1078,149 +1003,127 @@ struct acpi_resource_start_dpf
* needed because it has no fields
*/
-struct acpi_resource_io
-{
- u32 io_decode;
- u32 min_base_address;
- u32 max_base_address;
- u32 alignment;
- u32 range_length;
+struct acpi_resource_io {
+ u32 io_decode;
+ u32 min_base_address;
+ u32 max_base_address;
+ u32 alignment;
+ u32 range_length;
};
-struct acpi_resource_fixed_io
-{
- u32 base_address;
- u32 range_length;
+struct acpi_resource_fixed_io {
+ u32 base_address;
+ u32 range_length;
};
-struct acpi_resource_vendor
-{
- u32 length;
- u8 reserved[1];
+struct acpi_resource_vendor {
+ u32 length;
+ u8 reserved[1];
};
-struct acpi_resource_end_tag
-{
- u8 checksum;
+struct acpi_resource_end_tag {
+ u8 checksum;
};
-struct acpi_resource_mem24
-{
- u32 read_write_attribute;
- u32 min_base_address;
- u32 max_base_address;
- u32 alignment;
- u32 range_length;
+struct acpi_resource_mem24 {
+ u32 read_write_attribute;
+ u32 min_base_address;
+ u32 max_base_address;
+ u32 alignment;
+ u32 range_length;
};
-struct acpi_resource_mem32
-{
- u32 read_write_attribute;
- u32 min_base_address;
- u32 max_base_address;
- u32 alignment;
- u32 range_length;
+struct acpi_resource_mem32 {
+ u32 read_write_attribute;
+ u32 min_base_address;
+ u32 max_base_address;
+ u32 alignment;
+ u32 range_length;
};
-struct acpi_resource_fixed_mem32
-{
- u32 read_write_attribute;
- u32 range_base_address;
- u32 range_length;
+struct acpi_resource_fixed_mem32 {
+ u32 read_write_attribute;
+ u32 range_base_address;
+ u32 range_length;
};
-struct acpi_memory_attribute
-{
- u16 cache_attribute;
- u16 read_write_attribute;
+struct acpi_memory_attribute {
+ u16 cache_attribute;
+ u16 read_write_attribute;
};
-struct acpi_io_attribute
-{
- u16 range_attribute;
- u16 translation_attribute;
+struct acpi_io_attribute {
+ u16 range_attribute;
+ u16 translation_attribute;
};
-struct acpi_bus_attribute
-{
- u16 reserved1;
- u16 reserved2;
+struct acpi_bus_attribute {
+ u16 reserved1;
+ u16 reserved2;
};
-union acpi_resource_attribute
-{
- struct acpi_memory_attribute memory;
- struct acpi_io_attribute io;
- struct acpi_bus_attribute bus;
+union acpi_resource_attribute {
+ struct acpi_memory_attribute memory;
+ struct acpi_io_attribute io;
+ struct acpi_bus_attribute bus;
};
-struct acpi_resource_source
-{
- u32 index;
- u32 string_length;
- char *string_ptr;
+struct acpi_resource_source {
+ u32 index;
+ u32 string_length;
+ char *string_ptr;
};
-struct acpi_resource_address16
-{
- u32 resource_type;
- u32 producer_consumer;
- u32 decode;
- u32 min_address_fixed;
- u32 max_address_fixed;
- union acpi_resource_attribute attribute;
- u32 granularity;
- u32 min_address_range;
- u32 max_address_range;
- u32 address_translation_offset;
- u32 address_length;
- struct acpi_resource_source resource_source;
-};
+/* Fields common to all address descriptors, 16/32/64 bit */
-struct acpi_resource_address32
-{
- u32 resource_type;
- u32 producer_consumer;
- u32 decode;
- u32 min_address_fixed;
- u32 max_address_fixed;
+#define ACPI_RESOURCE_ADDRESS_COMMON \
+ u32 resource_type; \
+ u32 producer_consumer; \
+ u32 decode; \
+ u32 min_address_fixed; \
+ u32 max_address_fixed; \
union acpi_resource_attribute attribute;
- u32 granularity;
- u32 min_address_range;
- u32 max_address_range;
- u32 address_translation_offset;
- u32 address_length;
- struct acpi_resource_source resource_source;
+
+struct acpi_resource_address {
+ACPI_RESOURCE_ADDRESS_COMMON};
+
+struct acpi_resource_address16 {
+ ACPI_RESOURCE_ADDRESS_COMMON u32 granularity;
+ u32 min_address_range;
+ u32 max_address_range;
+ u32 address_translation_offset;
+ u32 address_length;
+ struct acpi_resource_source resource_source;
};
-struct acpi_resource_address64
-{
- u32 resource_type;
- u32 producer_consumer;
- u32 decode;
- u32 min_address_fixed;
- u32 max_address_fixed;
- union acpi_resource_attribute attribute;
- u64 granularity;
- u64 min_address_range;
- u64 max_address_range;
- u64 address_translation_offset;
- u64 address_length;
- u64 type_specific_attributes;
- struct acpi_resource_source resource_source;
+struct acpi_resource_address32 {
+ ACPI_RESOURCE_ADDRESS_COMMON u32 granularity;
+ u32 min_address_range;
+ u32 max_address_range;
+ u32 address_translation_offset;
+ u32 address_length;
+ struct acpi_resource_source resource_source;
};
-struct acpi_resource_ext_irq
-{
- u32 producer_consumer;
- u32 edge_level;
- u32 active_high_low;
- u32 shared_exclusive;
- u32 number_of_interrupts;
- struct acpi_resource_source resource_source;
- u32 interrupts[1];
+struct acpi_resource_address64 {
+ ACPI_RESOURCE_ADDRESS_COMMON u64 granularity;
+ u64 min_address_range;
+ u64 max_address_range;
+ u64 address_translation_offset;
+ u64 address_length;
+ u64 type_specific_attributes;
+ struct acpi_resource_source resource_source;
};
+struct acpi_resource_ext_irq {
+ u32 producer_consumer;
+ u32 edge_level;
+ u32 active_high_low;
+ u32 shared_exclusive;
+ u32 number_of_interrupts;
+ struct acpi_resource_source resource_source;
+ u32 interrupts[1];
+};
/* ACPI_RESOURCE_TYPEs */
@@ -1240,35 +1143,34 @@ struct acpi_resource_ext_irq
#define ACPI_RSTYPE_ADDRESS64 13
#define ACPI_RSTYPE_EXT_IRQ 14
-typedef u32 acpi_resource_type;
-
-union acpi_resource_data
-{
- struct acpi_resource_irq irq;
- struct acpi_resource_dma dma;
- struct acpi_resource_start_dpf start_dpf;
- struct acpi_resource_io io;
- struct acpi_resource_fixed_io fixed_io;
- struct acpi_resource_vendor vendor_specific;
- struct acpi_resource_end_tag end_tag;
- struct acpi_resource_mem24 memory24;
- struct acpi_resource_mem32 memory32;
- struct acpi_resource_fixed_mem32 fixed_memory32;
- struct acpi_resource_address16 address16;
- struct acpi_resource_address32 address32;
- struct acpi_resource_address64 address64;
- struct acpi_resource_ext_irq extended_irq;
+typedef u32 acpi_resource_type;
+
+union acpi_resource_data {
+ struct acpi_resource_irq irq;
+ struct acpi_resource_dma dma;
+ struct acpi_resource_start_dpf start_dpf;
+ struct acpi_resource_io io;
+ struct acpi_resource_fixed_io fixed_io;
+ struct acpi_resource_vendor vendor_specific;
+ struct acpi_resource_end_tag end_tag;
+ struct acpi_resource_mem24 memory24;
+ struct acpi_resource_mem32 memory32;
+ struct acpi_resource_fixed_mem32 fixed_memory32;
+ struct acpi_resource_address address; /* Common 16/32/64 address fields */
+ struct acpi_resource_address16 address16;
+ struct acpi_resource_address32 address32;
+ struct acpi_resource_address64 address64;
+ struct acpi_resource_ext_irq extended_irq;
};
-struct acpi_resource
-{
- acpi_resource_type id;
- u32 length;
- union acpi_resource_data data;
+struct acpi_resource {
+ acpi_resource_type id;
+ u32 length;
+ union acpi_resource_data data;
};
#define ACPI_RESOURCE_LENGTH 12
-#define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */
+#define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */
#define ACPI_SIZEOF_RESOURCE(type) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type))
@@ -1284,19 +1186,16 @@ struct acpi_resource
* END: of definitions for Resource Attributes
*/
-
-struct acpi_pci_routing_table
-{
- u32 length;
- u32 pin;
- acpi_integer address; /* here for 64-bit alignment */
- u32 source_index;
- char source[4]; /* pad to 64 bits so sizeof() works in all cases */
+struct acpi_pci_routing_table {
+ u32 length;
+ u32 pin;
+ acpi_integer address; /* here for 64-bit alignment */
+ u32 source_index;
+ char source[4]; /* pad to 64 bits so sizeof() works in all cases */
};
/*
* END: of definitions for PCI Routing tables
*/
-
-#endif /* __ACTYPES_H__ */
+#endif /* __ACTYPES_H__ */
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index 192d0bea3884..c1086452696e 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -44,20 +44,17 @@
#ifndef _ACUTILS_H
#define _ACUTILS_H
-
typedef
-acpi_status (*acpi_pkg_callback) (
- u8 object_type,
- union acpi_operand_object *source_object,
- union acpi_generic_state *state,
- void *context);
-
-struct acpi_pkg_info
-{
- u8 *free_space;
- acpi_size length;
- u32 object_space;
- u32 num_packages;
+acpi_status(*acpi_pkg_callback) (u8 object_type,
+ union acpi_operand_object * source_object,
+ union acpi_generic_state * state,
+ void *context);
+
+struct acpi_pkg_info {
+ u8 *free_space;
+ acpi_size length;
+ u32 object_space;
+ u32 num_packages;
};
#define REF_INCREMENT (u16) 0
@@ -71,167 +68,89 @@ struct acpi_pkg_info
#define DB_DWORD_DISPLAY 4
#define DB_QWORD_DISPLAY 8
-
/*
* utglobal - Global data structures and procedures
*/
-void
-acpi_ut_init_globals (
- void);
+void acpi_ut_init_globals(void);
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-char *
-acpi_ut_get_mutex_name (
- u32 mutex_id);
+char *acpi_ut_get_mutex_name(u32 mutex_id);
#endif
-char *
-acpi_ut_get_type_name (
- acpi_object_type type);
-
-char *
-acpi_ut_get_node_name (
- void *object);
-
-char *
-acpi_ut_get_descriptor_name (
- void *object);
+char *acpi_ut_get_type_name(acpi_object_type type);
-char *
-acpi_ut_get_object_type_name (
- union acpi_operand_object *obj_desc);
+char *acpi_ut_get_node_name(void *object);
-char *
-acpi_ut_get_region_name (
- u8 space_id);
+char *acpi_ut_get_descriptor_name(void *object);
-char *
-acpi_ut_get_event_name (
- u32 event_id);
+char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc);
-char
-acpi_ut_hex_to_ascii_char (
- acpi_integer integer,
- u32 position);
+char *acpi_ut_get_region_name(u8 space_id);
-u8
-acpi_ut_valid_object_type (
- acpi_object_type type);
+char *acpi_ut_get_event_name(u32 event_id);
-acpi_owner_id
-acpi_ut_allocate_owner_id (
- u32 id_type);
+char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position);
+u8 acpi_ut_valid_object_type(acpi_object_type type);
/*
* utinit - miscellaneous initialization and shutdown
*/
-acpi_status
-acpi_ut_hardware_initialize (
- void);
+acpi_status acpi_ut_hardware_initialize(void);
-void
-acpi_ut_subsystem_shutdown (
- void);
-
-acpi_status
-acpi_ut_validate_fadt (
- void);
+void acpi_ut_subsystem_shutdown(void);
+acpi_status acpi_ut_validate_fadt(void);
/*
* utclib - Local implementations of C library functions
*/
#ifndef ACPI_USE_SYSTEM_CLIBRARY
-acpi_size
-acpi_ut_strlen (
- const char *string);
-
-char *
-acpi_ut_strcpy (
- char *dst_string,
- const char *src_string);
-
-char *
-acpi_ut_strncpy (
- char *dst_string,
- const char *src_string,
- acpi_size count);
-
-int
-acpi_ut_memcmp (
- const char *buffer1,
- const char *buffer2,
- acpi_size count);
-
-int
-acpi_ut_strncmp (
- const char *string1,
- const char *string2,
- acpi_size count);
-
-int
-acpi_ut_strcmp (
- const char *string1,
- const char *string2);
-
-char *
-acpi_ut_strcat (
- char *dst_string,
- const char *src_string);
-
-char *
-acpi_ut_strncat (
- char *dst_string,
- const char *src_string,
- acpi_size count);
-
-u32
-acpi_ut_strtoul (
- const char *string,
- char **terminator,
- u32 base);
-
-char *
-acpi_ut_strstr (
- char *string1,
- char *string2);
-
-void *
-acpi_ut_memcpy (
- void *dest,
- const void *src,
- acpi_size count);
-
-void *
-acpi_ut_memset (
- void *dest,
- acpi_native_uint value,
- acpi_size count);
-
-int
-acpi_ut_to_upper (
- int c);
-
-int
-acpi_ut_to_lower (
- int c);
+acpi_size acpi_ut_strlen(const char *string);
+
+char *acpi_ut_strcpy(char *dst_string, const char *src_string);
+
+char *acpi_ut_strncpy(char *dst_string,
+ const char *src_string, acpi_size count);
+
+int acpi_ut_memcmp(const char *buffer1, const char *buffer2, acpi_size count);
+
+int acpi_ut_strncmp(const char *string1, const char *string2, acpi_size count);
+
+int acpi_ut_strcmp(const char *string1, const char *string2);
+
+char *acpi_ut_strcat(char *dst_string, const char *src_string);
+
+char *acpi_ut_strncat(char *dst_string,
+ const char *src_string, acpi_size count);
+
+u32 acpi_ut_strtoul(const char *string, char **terminator, u32 base);
+
+char *acpi_ut_strstr(char *string1, char *string2);
+
+void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count);
+
+void *acpi_ut_memset(void *dest, acpi_native_uint value, acpi_size count);
+
+int acpi_ut_to_upper(int c);
+
+int acpi_ut_to_lower(int c);
extern const u8 _acpi_ctype[];
-#define _ACPI_XA 0x00 /* extra alphabetic - not supported */
-#define _ACPI_XS 0x40 /* extra space */
-#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */
-#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */
-#define _ACPI_DI 0x04 /* '0'-'9' */
-#define _ACPI_LO 0x02 /* 'a'-'z' */
-#define _ACPI_PU 0x10 /* punctuation */
-#define _ACPI_SP 0x08 /* space */
-#define _ACPI_UP 0x01 /* 'A'-'Z' */
-#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */
+#define _ACPI_XA 0x00 /* extra alphabetic - not supported */
+#define _ACPI_XS 0x40 /* extra space */
+#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */
+#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */
+#define _ACPI_DI 0x04 /* '0'-'9' */
+#define _ACPI_LO 0x02 /* 'a'-'z' */
+#define _ACPI_PU 0x10 /* punctuation */
+#define _ACPI_SP 0x08 /* space */
+#define _ACPI_UP 0x01 /* 'A'-'Z' */
+#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */
#define ACPI_IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI))
#define ACPI_IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP))
@@ -242,502 +161,323 @@ extern const u8 _acpi_ctype[];
#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
#define ACPI_IS_ASCII(c) ((c) < 0x80)
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
/*
* utcopy - Object construction and conversion interfaces
*/
acpi_status
-acpi_ut_build_simple_object(
- union acpi_operand_object *obj,
- union acpi_object *user_obj,
- u8 *data_space,
- u32 *buffer_space_used);
+acpi_ut_build_simple_object(union acpi_operand_object *obj,
+ union acpi_object *user_obj,
+ u8 * data_space, u32 * buffer_space_used);
acpi_status
-acpi_ut_build_package_object (
- union acpi_operand_object *obj,
- u8 *buffer,
- u32 *space_used);
+acpi_ut_build_package_object(union acpi_operand_object *obj,
+ u8 * buffer, u32 * space_used);
acpi_status
-acpi_ut_copy_iobject_to_eobject (
- union acpi_operand_object *obj,
- struct acpi_buffer *ret_buffer);
+acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *obj,
+ struct acpi_buffer *ret_buffer);
acpi_status
-acpi_ut_copy_eobject_to_iobject (
- union acpi_object *obj,
- union acpi_operand_object **internal_obj);
+acpi_ut_copy_eobject_to_iobject(union acpi_object *obj,
+ union acpi_operand_object **internal_obj);
acpi_status
-acpi_ut_copy_isimple_to_isimple (
- union acpi_operand_object *source_obj,
- union acpi_operand_object *dest_obj);
+acpi_ut_copy_isimple_to_isimple(union acpi_operand_object *source_obj,
+ union acpi_operand_object *dest_obj);
acpi_status
-acpi_ut_copy_iobject_to_iobject (
- union acpi_operand_object *source_desc,
- union acpi_operand_object **dest_desc,
- struct acpi_walk_state *walk_state);
-
+acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
+ union acpi_operand_object **dest_desc,
+ struct acpi_walk_state *walk_state);
/*
* utcreate - Object creation
*/
acpi_status
-acpi_ut_update_object_reference (
- union acpi_operand_object *object,
- u16 action);
-
+acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action);
/*
* utdebug - Debug interfaces
*/
-void
-acpi_ut_init_stack_ptr_trace (
- void);
+void acpi_ut_init_stack_ptr_trace(void);
-void
-acpi_ut_track_stack_ptr (
- void);
+void acpi_ut_track_stack_ptr(void);
void
-acpi_ut_trace (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info);
+acpi_ut_trace(u32 line_number,
+ const char *function_name, char *module_name, u32 component_id);
void
-acpi_ut_trace_ptr (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- void *pointer);
+acpi_ut_trace_ptr(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, void *pointer);
void
-acpi_ut_trace_u32 (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- u32 integer);
+acpi_ut_trace_u32(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, u32 integer);
void
-acpi_ut_trace_str (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- char *string);
+acpi_ut_trace_str(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, char *string);
void
-acpi_ut_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info);
+acpi_ut_exit(u32 line_number,
+ const char *function_name, char *module_name, u32 component_id);
void
-acpi_ut_status_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- acpi_status status);
+acpi_ut_status_exit(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, acpi_status status);
void
-acpi_ut_value_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- acpi_integer value);
+acpi_ut_value_exit(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, acpi_integer value);
void
-acpi_ut_ptr_exit (
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- u8 *ptr);
+acpi_ut_ptr_exit(u32 line_number,
+ const char *function_name,
+ char *module_name, u32 component_id, u8 * ptr);
-void
-acpi_ut_report_info (
- char *module_name,
- u32 line_number,
- u32 component_id);
+void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id);
-void
-acpi_ut_report_error (
- char *module_name,
- u32 line_number,
- u32 component_id);
+void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id);
void
-acpi_ut_report_warning (
- char *module_name,
- u32 line_number,
- u32 component_id);
+acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id);
-void
-acpi_ut_dump_buffer (
- u8 *buffer,
- u32 count,
- u32 display,
- u32 component_id);
+void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id);
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_debug_print (
- u32 requested_debug_level,
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- char *format,
- ...) ACPI_PRINTF_LIKE_FUNC;
+acpi_ut_debug_print(u32 requested_debug_level,
+ u32 line_number,
+ const char *function_name,
+ char *module_name,
+ u32 component_id, char *format, ...) ACPI_PRINTF_LIKE_FUNC;
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_debug_print_raw (
- u32 requested_debug_level,
- u32 line_number,
- struct acpi_debug_print_info *dbg_info,
- char *format,
- ...) ACPI_PRINTF_LIKE_FUNC;
-
+acpi_ut_debug_print_raw(u32 requested_debug_level,
+ u32 line_number,
+ const char *function_name,
+ char *module_name,
+ u32 component_id,
+ char *format, ...) ACPI_PRINTF_LIKE_FUNC;
/*
* utdelete - Object deletion and reference counts
*/
-void
-acpi_ut_add_reference (
- union acpi_operand_object *object);
+void acpi_ut_add_reference(union acpi_operand_object *object);
-void
-acpi_ut_remove_reference (
- union acpi_operand_object *object);
+void acpi_ut_remove_reference(union acpi_operand_object *object);
-void
-acpi_ut_delete_internal_package_object (
- union acpi_operand_object *object);
+void acpi_ut_delete_internal_package_object(union acpi_operand_object *object);
-void
-acpi_ut_delete_internal_simple_object (
- union acpi_operand_object *object);
-
-void
-acpi_ut_delete_internal_object_list (
- union acpi_operand_object **obj_list);
+void acpi_ut_delete_internal_simple_object(union acpi_operand_object *object);
+void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list);
/*
* uteval - object evaluation
*/
-acpi_status
-acpi_ut_osi_implementation (
- struct acpi_walk_state *walk_state);
+acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
acpi_status
-acpi_ut_evaluate_object (
- struct acpi_namespace_node *prefix_node,
- char *path,
- u32 expected_return_btypes,
- union acpi_operand_object **return_desc);
+acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
+ char *path,
+ u32 expected_return_btypes,
+ union acpi_operand_object **return_desc);
acpi_status
-acpi_ut_evaluate_numeric_object (
- char *object_name,
- struct acpi_namespace_node *device_node,
- acpi_integer *address);
+acpi_ut_evaluate_numeric_object(char *object_name,
+ struct acpi_namespace_node *device_node,
+ acpi_integer * address);
acpi_status
-acpi_ut_execute_HID (
- struct acpi_namespace_node *device_node,
- struct acpi_device_id *hid);
+acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
+ struct acpi_device_id *hid);
acpi_status
-acpi_ut_execute_CID (
- struct acpi_namespace_node *device_node,
- struct acpi_compatible_id_list **return_cid_list);
+acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
+ struct acpi_compatible_id_list **return_cid_list);
acpi_status
-acpi_ut_execute_STA (
- struct acpi_namespace_node *device_node,
- u32 *status_flags);
+acpi_ut_execute_STA(struct acpi_namespace_node *device_node,
+ u32 * status_flags);
acpi_status
-acpi_ut_execute_UID (
- struct acpi_namespace_node *device_node,
- struct acpi_device_id *uid);
+acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
+ struct acpi_device_id *uid);
acpi_status
-acpi_ut_execute_sxds (
- struct acpi_namespace_node *device_node,
- u8 *highest);
-
+acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
/*
* utobject - internal object create/delete/cache routines
*/
-union acpi_operand_object *
-acpi_ut_create_internal_object_dbg (
- char *module_name,
- u32 line_number,
- u32 component_id,
- acpi_object_type type);
-
-void *
-acpi_ut_allocate_object_desc_dbg (
- char *module_name,
- u32 line_number,
- u32 component_id);
-
-#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_THIS_MODULE,__LINE__,_COMPONENT,t)
-#define acpi_ut_allocate_object_desc() acpi_ut_allocate_object_desc_dbg (_THIS_MODULE,__LINE__,_COMPONENT)
+union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
+ u32 line_number,
+ u32 component_id,
+ acpi_object_type
+ type);
-void
-acpi_ut_delete_object_desc (
- union acpi_operand_object *object);
+void *acpi_ut_allocate_object_desc_dbg(char *module_name,
+ u32 line_number, u32 component_id);
-u8
-acpi_ut_valid_internal_object (
- void *object);
+#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_acpi_module_name,__LINE__,_COMPONENT,t)
+#define acpi_ut_allocate_object_desc() acpi_ut_allocate_object_desc_dbg (_acpi_module_name,__LINE__,_COMPONENT)
-union acpi_operand_object *
-acpi_ut_create_buffer_object (
- acpi_size buffer_size);
+void acpi_ut_delete_object_desc(union acpi_operand_object *object);
-union acpi_operand_object *
-acpi_ut_create_string_object (
- acpi_size string_size);
+u8 acpi_ut_valid_internal_object(void *object);
-acpi_status
-acpi_ut_get_object_size(
- union acpi_operand_object *obj,
- acpi_size *obj_length);
+union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size);
+union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
+
+acpi_status
+acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length);
/*
* utstate - Generic state creation/cache routines
*/
void
-acpi_ut_push_generic_state (
- union acpi_generic_state **list_head,
- union acpi_generic_state *state);
+acpi_ut_push_generic_state(union acpi_generic_state **list_head,
+ union acpi_generic_state *state);
-union acpi_generic_state *
-acpi_ut_pop_generic_state (
- union acpi_generic_state **list_head);
+union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
+ **list_head);
+union acpi_generic_state *acpi_ut_create_generic_state(void);
-union acpi_generic_state *
-acpi_ut_create_generic_state (
- void);
+struct acpi_thread_state *acpi_ut_create_thread_state(void);
-struct acpi_thread_state *
-acpi_ut_create_thread_state (
- void);
+union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
+ *object, u16 action);
-union acpi_generic_state *
-acpi_ut_create_update_state (
- union acpi_operand_object *object,
- u16 action);
-
-union acpi_generic_state *
-acpi_ut_create_pkg_state (
- void *internal_object,
- void *external_object,
- u16 index);
+union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
+ void *external_object,
+ u16 index);
acpi_status
-acpi_ut_create_update_state_and_push (
- union acpi_operand_object *object,
- u16 action,
- union acpi_generic_state **state_list);
+acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
+ u16 action,
+ union acpi_generic_state **state_list);
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_ut_create_pkg_state_and_push (
- void *internal_object,
- void *external_object,
- u16 index,
- union acpi_generic_state **state_list);
-#endif /* ACPI_FUTURE_USAGE */
+acpi_ut_create_pkg_state_and_push(void *internal_object,
+ void *external_object,
+ u16 index,
+ union acpi_generic_state **state_list);
+#endif /* ACPI_FUTURE_USAGE */
-union acpi_generic_state *
-acpi_ut_create_control_state (
- void);
-
-void
-acpi_ut_delete_generic_state (
- union acpi_generic_state *state);
-
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-void
-acpi_ut_delete_generic_state_cache (
- void);
-
-void
-acpi_ut_delete_object_cache (
- void);
-#endif
+union acpi_generic_state *acpi_ut_create_control_state(void);
+void acpi_ut_delete_generic_state(union acpi_generic_state *state);
/*
* utmath
*/
acpi_status
-acpi_ut_divide (
- acpi_integer in_dividend,
- acpi_integer in_divisor,
- acpi_integer *out_quotient,
- acpi_integer *out_remainder);
+acpi_ut_divide(acpi_integer in_dividend,
+ acpi_integer in_divisor,
+ acpi_integer * out_quotient, acpi_integer * out_remainder);
acpi_status
-acpi_ut_short_divide (
- acpi_integer in_dividend,
- u32 divisor,
- acpi_integer *out_quotient,
- u32 *out_remainder);
+acpi_ut_short_divide(acpi_integer in_dividend,
+ u32 divisor,
+ acpi_integer * out_quotient, u32 * out_remainder);
/*
* utmisc
*/
+acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
+
+void acpi_ut_release_owner_id(acpi_owner_id * owner_id);
+
acpi_status
-acpi_ut_walk_package_tree (
- union acpi_operand_object *source_object,
- void *target_object,
- acpi_pkg_callback walk_callback,
- void *context);
+acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
+ void *target_object,
+ acpi_pkg_callback walk_callback, void *context);
-char *
-acpi_ut_strupr (
- char *src_string);
+void acpi_ut_strupr(char *src_string);
-void
-acpi_ut_print_string (
- char *string,
- u8 max_length);
+void acpi_ut_print_string(char *string, u8 max_length);
-u8
-acpi_ut_valid_acpi_name (
- u32 name);
+u8 acpi_ut_valid_acpi_name(u32 name);
-u8
-acpi_ut_valid_acpi_character (
- char character);
+u8 acpi_ut_valid_acpi_character(char character);
acpi_status
-acpi_ut_strtoul64 (
- char *string,
- u32 base,
- acpi_integer *ret_integer);
+acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer);
/* Values for Base above (16=Hex, 10=Decimal) */
#define ACPI_ANY_BASE 0
-acpi_status
-acpi_ut_mutex_initialize (
- void);
-
-void
-acpi_ut_mutex_terminate (
- void);
-
-acpi_status
-acpi_ut_acquire_mutex (
- acpi_mutex_handle mutex_id);
-
-acpi_status
-acpi_ut_release_mutex (
- acpi_mutex_handle mutex_id);
-
-u8 *
-acpi_ut_get_resource_end_tag (
- union acpi_operand_object *obj_desc);
+u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc);
-u8
-acpi_ut_generate_checksum (
- u8 *buffer,
- u32 length);
+u8 acpi_ut_generate_checksum(u8 * buffer, u32 length);
-u32
-acpi_ut_dword_byte_swap (
- u32 value);
+u32 acpi_ut_dword_byte_swap(u32 value);
-void
-acpi_ut_set_integer_width (
- u8 revision);
+void acpi_ut_set_integer_width(u8 revision);
#ifdef ACPI_DEBUG_OUTPUT
void
-acpi_ut_display_init_pathname (
- u8 type,
- struct acpi_namespace_node *obj_handle,
- char *path);
+acpi_ut_display_init_pathname(u8 type,
+ struct acpi_namespace_node *obj_handle,
+ char *path);
#endif
+/*
+ * utmutex - mutex support
+ */
+acpi_status acpi_ut_mutex_initialize(void);
+
+void acpi_ut_mutex_terminate(void);
+
+acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id);
+
+acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id);
/*
* utalloc - memory allocation and object caching
*/
-void *
-acpi_ut_acquire_from_cache (
- u32 list_id);
+acpi_status acpi_ut_create_caches(void);
-void
-acpi_ut_release_to_cache (
- u32 list_id,
- void *object);
+acpi_status acpi_ut_delete_caches(void);
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-void
-acpi_ut_delete_generic_cache (
- u32 list_id);
-#endif
+acpi_status acpi_ut_validate_buffer(struct acpi_buffer *buffer);
acpi_status
-acpi_ut_validate_buffer (
- struct acpi_buffer *buffer);
+acpi_ut_initialize_buffer(struct acpi_buffer *buffer,
+ acpi_size required_length);
-acpi_status
-acpi_ut_initialize_buffer (
- struct acpi_buffer *buffer,
- acpi_size required_length);
-
-void *
-acpi_ut_allocate (
- acpi_size size,
- u32 component,
- char *module,
- u32 line);
-
-void *
-acpi_ut_callocate (
- acpi_size size,
- u32 component,
- char *module,
- u32 line);
+void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line);
+
+void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line);
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-void *
-acpi_ut_allocate_and_track (
- acpi_size size,
- u32 component,
- char *module,
- u32 line);
-
-void *
-acpi_ut_callocate_and_track (
- acpi_size size,
- u32 component,
- char *module,
- u32 line);
+void *acpi_ut_allocate_and_track(acpi_size size,
+ u32 component, char *module, u32 line);
+
+void *acpi_ut_callocate_and_track(acpi_size size,
+ u32 component, char *module, u32 line);
void
-acpi_ut_free_and_track (
- void *address,
- u32 component,
- char *module,
- u32 line);
+acpi_ut_free_and_track(void *address, u32 component, char *module, u32 line);
#ifdef ACPI_FUTURE_USAGE
-void
-acpi_ut_dump_allocation_info (
- void);
-#endif /* ACPI_FUTURE_USAGE */
+void acpi_ut_dump_allocation_info(void);
+#endif /* ACPI_FUTURE_USAGE */
-void
-acpi_ut_dump_allocations (
- u32 component,
- char *module);
+void acpi_ut_dump_allocations(u32 component, char *module);
#endif
-#endif /* _ACUTILS_H */
+#endif /* _ACUTILS_H */
diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h
index 55e97ed29190..7fdf5299f501 100644
--- a/include/acpi/amlcode.h
+++ b/include/acpi/amlcode.h
@@ -59,17 +59,17 @@
#define AML_WORD_OP (u16) 0x0b
#define AML_DWORD_OP (u16) 0x0c
#define AML_STRING_OP (u16) 0x0d
-#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */
+#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */
#define AML_SCOPE_OP (u16) 0x10
#define AML_BUFFER_OP (u16) 0x11
#define AML_PACKAGE_OP (u16) 0x12
-#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */
+#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */
#define AML_METHOD_OP (u16) 0x14
#define AML_DUAL_NAME_PREFIX (u16) 0x2e
#define AML_MULTI_NAME_PREFIX_OP (u16) 0x2f
#define AML_NAME_CHAR_SUBSEQ (u16) 0x30
#define AML_NAME_CHAR_FIRST (u16) 0x41
-#define AML_OP_PREFIX (u16) 0x5b
+#define AML_EXTENDED_OP_PREFIX (u16) 0x5b
#define AML_ROOT_PREFIX (u16) 0x5c
#define AML_PARENT_PREFIX (u16) 0x5e
#define AML_LOCAL_OP (u16) 0x60
@@ -109,8 +109,8 @@
#define AML_FIND_SET_LEFT_BIT_OP (u16) 0x81
#define AML_FIND_SET_RIGHT_BIT_OP (u16) 0x82
#define AML_DEREF_OF_OP (u16) 0x83
-#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */
-#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */
+#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */
+#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */
#define AML_NOTIFY_OP (u16) 0x86
#define AML_SIZE_OF_OP (u16) 0x87
#define AML_INDEX_OP (u16) 0x88
@@ -120,21 +120,21 @@
#define AML_CREATE_BYTE_FIELD_OP (u16) 0x8c
#define AML_CREATE_BIT_FIELD_OP (u16) 0x8d
#define AML_TYPE_OP (u16) 0x8e
-#define AML_CREATE_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */
+#define AML_CREATE_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */
#define AML_LAND_OP (u16) 0x90
#define AML_LOR_OP (u16) 0x91
#define AML_LNOT_OP (u16) 0x92
#define AML_LEQUAL_OP (u16) 0x93
#define AML_LGREATER_OP (u16) 0x94
#define AML_LLESS_OP (u16) 0x95
-#define AML_TO_BUFFER_OP (u16) 0x96 /* ACPI 2.0 */
-#define AML_TO_DECSTRING_OP (u16) 0x97 /* ACPI 2.0 */
-#define AML_TO_HEXSTRING_OP (u16) 0x98 /* ACPI 2.0 */
-#define AML_TO_INTEGER_OP (u16) 0x99 /* ACPI 2.0 */
-#define AML_TO_STRING_OP (u16) 0x9c /* ACPI 2.0 */
-#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */
-#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */
-#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */
+#define AML_TO_BUFFER_OP (u16) 0x96 /* ACPI 2.0 */
+#define AML_TO_DECSTRING_OP (u16) 0x97 /* ACPI 2.0 */
+#define AML_TO_HEXSTRING_OP (u16) 0x98 /* ACPI 2.0 */
+#define AML_TO_INTEGER_OP (u16) 0x99 /* ACPI 2.0 */
+#define AML_TO_STRING_OP (u16) 0x9c /* ACPI 2.0 */
+#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */
+#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */
+#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */
#define AML_IF_OP (u16) 0xa0
#define AML_ELSE_OP (u16) 0xa1
#define AML_WHILE_OP (u16) 0xa2
@@ -146,7 +146,7 @@
/* prefixed opcodes */
-#define AML_EXTOP (u16) 0x005b /* prefix for 2-byte opcodes */
+#define AML_EXTENDED_OPCODE (u16) 0x5b00 /* prefix for 2-byte opcodes */
#define AML_MUTEX_OP (u16) 0x5b01
#define AML_EVENT_OP (u16) 0x5b02
@@ -154,7 +154,7 @@
#define AML_SHIFT_LEFT_BIT_OP (u16) 0x5b11
#define AML_COND_REF_OF_OP (u16) 0x5b12
#define AML_CREATE_FIELD_OP (u16) 0x5b13
-#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */
+#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */
#define AML_LOAD_OP (u16) 0x5b20
#define AML_STALL_OP (u16) 0x5b21
#define AML_SLEEP_OP (u16) 0x5b22
@@ -169,7 +169,7 @@
#define AML_REVISION_OP (u16) 0x5b30
#define AML_DEBUG_OP (u16) 0x5b31
#define AML_FATAL_OP (u16) 0x5b32
-#define AML_TIMER_OP (u16) 0x5b33 /* ACPI 3.0 */
+#define AML_TIMER_OP (u16) 0x5b33 /* ACPI 3.0 */
#define AML_REGION_OP (u16) 0x5b80
#define AML_FIELD_OP (u16) 0x5b81
#define AML_DEVICE_OP (u16) 0x5b82
@@ -178,8 +178,7 @@
#define AML_THERMAL_ZONE_OP (u16) 0x5b85
#define AML_INDEX_FIELD_OP (u16) 0x5b86
#define AML_BANK_FIELD_OP (u16) 0x5b87
-#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */
-
+#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */
/* Bogus opcodes (they are actually two separate opcodes) */
@@ -187,7 +186,6 @@
#define AML_LLESSEQUAL_OP (u16) 0x9294
#define AML_LNOTEQUAL_OP (u16) 0x9293
-
/*
* Internal opcodes
* Use only "Unknown" AML opcodes, don't attempt to use
@@ -203,7 +201,6 @@
#define AML_INT_RETURN_VALUE_OP (u16) 0x0036
#define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037
-
#define ARG_NONE 0x0
/*
@@ -245,7 +242,7 @@
/* Single, simple types */
-#define ARGI_ANYTYPE 0x01 /* Don't care */
+#define ARGI_ANYTYPE 0x01 /* Don't care */
#define ARGI_PACKAGE 0x02
#define ARGI_EVENT 0x03
#define ARGI_MUTEX 0x04
@@ -256,8 +253,8 @@
#define ARGI_INTEGER 0x06
#define ARGI_STRING 0x07
#define ARGI_BUFFER 0x08
-#define ARGI_BUFFER_OR_STRING 0x09 /* Used by MID op only */
-#define ARGI_COMPUTEDATA 0x0A /* Buffer, String, or Integer */
+#define ARGI_BUFFER_OR_STRING 0x09 /* Used by MID op only */
+#define ARGI_COMPUTEDATA 0x0A /* Buffer, String, or Integer */
/* Reference objects */
@@ -265,30 +262,28 @@
#define ARGI_OBJECT_REF 0x0C
#define ARGI_DEVICE_REF 0x0D
#define ARGI_REFERENCE 0x0E
-#define ARGI_TARGETREF 0x0F /* Target, subject to implicit conversion */
-#define ARGI_FIXED_TARGET 0x10 /* Target, no implicit conversion */
-#define ARGI_SIMPLE_TARGET 0x11 /* Name, Local, Arg -- no implicit conversion */
+#define ARGI_TARGETREF 0x0F /* Target, subject to implicit conversion */
+#define ARGI_FIXED_TARGET 0x10 /* Target, no implicit conversion */
+#define ARGI_SIMPLE_TARGET 0x11 /* Name, Local, Arg -- no implicit conversion */
/* Multiple/complex types */
-#define ARGI_DATAOBJECT 0x12 /* Buffer, String, package or reference to a Node - Used only by size_of operator*/
-#define ARGI_COMPLEXOBJ 0x13 /* Buffer, String, or package (Used by INDEX op only) */
-#define ARGI_REF_OR_STRING 0x14 /* Reference or String (Used by DEREFOF op only) */
-#define ARGI_REGION_OR_FIELD 0x15 /* Used by LOAD op only */
+#define ARGI_DATAOBJECT 0x12 /* Buffer, String, package or reference to a Node - Used only by size_of operator */
+#define ARGI_COMPLEXOBJ 0x13 /* Buffer, String, or package (Used by INDEX op only) */
+#define ARGI_REF_OR_STRING 0x14 /* Reference or String (Used by DEREFOF op only) */
+#define ARGI_REGION_OR_FIELD 0x15 /* Used by LOAD op only */
#define ARGI_DATAREFOBJ 0x16
/* Note: types above can expand to 0x1F maximum */
#define ARGI_INVALID_OPCODE 0xFFFFFFFF
-
/*
* hash offsets
*/
#define AML_EXTOP_HASH_OFFSET 22
#define AML_LNOT_HASH_OFFSET 19
-
/*
* opcode groups and types
*/
@@ -296,7 +291,6 @@
#define OPGRP_FIELD 0x02
#define OPGRP_BYTELIST 0x04
-
/*
* Opcode information
*/
@@ -322,31 +316,30 @@
/* Convenient flag groupings */
#define AML_FLAGS_EXEC_0A_0T_1R AML_HAS_RETVAL
-#define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */
-#define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */
+#define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */
+#define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */
#define AML_FLAGS_EXEC_1A_1T_0R AML_HAS_ARGS | AML_HAS_TARGET
-#define AML_FLAGS_EXEC_1A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* monadic2_r */
-#define AML_FLAGS_EXEC_2A_0T_0R AML_HAS_ARGS /* Dyadic1 */
-#define AML_FLAGS_EXEC_2A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Dyadic2 */
-#define AML_FLAGS_EXEC_2A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* dyadic2_r */
+#define AML_FLAGS_EXEC_1A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* monadic2_r */
+#define AML_FLAGS_EXEC_2A_0T_0R AML_HAS_ARGS /* Dyadic1 */
+#define AML_FLAGS_EXEC_2A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Dyadic2 */
+#define AML_FLAGS_EXEC_2A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* dyadic2_r */
#define AML_FLAGS_EXEC_2A_2T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
#define AML_FLAGS_EXEC_3A_0T_0R AML_HAS_ARGS
#define AML_FLAGS_EXEC_3A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
#define AML_FLAGS_EXEC_6A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL
-
/*
* The opcode Type is used in a dispatch table, do not change
* without updating the table.
*/
#define AML_TYPE_EXEC_0A_0T_1R 0x00
-#define AML_TYPE_EXEC_1A_0T_0R 0x01 /* Monadic1 */
-#define AML_TYPE_EXEC_1A_0T_1R 0x02 /* Monadic2 */
+#define AML_TYPE_EXEC_1A_0T_0R 0x01 /* Monadic1 */
+#define AML_TYPE_EXEC_1A_0T_1R 0x02 /* Monadic2 */
#define AML_TYPE_EXEC_1A_1T_0R 0x03
-#define AML_TYPE_EXEC_1A_1T_1R 0x04 /* monadic2_r */
-#define AML_TYPE_EXEC_2A_0T_0R 0x05 /* Dyadic1 */
-#define AML_TYPE_EXEC_2A_0T_1R 0x06 /* Dyadic2 */
-#define AML_TYPE_EXEC_2A_1T_1R 0x07 /* dyadic2_r */
+#define AML_TYPE_EXEC_1A_1T_1R 0x04 /* monadic2_r */
+#define AML_TYPE_EXEC_2A_0T_0R 0x05 /* Dyadic1 */
+#define AML_TYPE_EXEC_2A_0T_1R 0x06 /* Dyadic2 */
+#define AML_TYPE_EXEC_2A_1T_1R 0x07 /* dyadic2_r */
#define AML_TYPE_EXEC_2A_2T_1R 0x08
#define AML_TYPE_EXEC_3A_0T_0R 0x09
#define AML_TYPE_EXEC_3A_1T_1R 0x0A
@@ -399,40 +392,33 @@
#define AML_CLASS_METHOD_CALL 0x09
#define AML_CLASS_UNKNOWN 0x0A
-
/* Predefined Operation Region space_iDs */
-typedef enum
-{
- REGION_MEMORY = 0,
+typedef enum {
+ REGION_MEMORY = 0,
REGION_IO,
REGION_PCI_CONFIG,
REGION_EC,
REGION_SMBUS,
REGION_CMOS,
REGION_PCI_BAR,
- REGION_DATA_TABLE, /* Internal use only */
- REGION_FIXED_HW = 0x7F
-
+ REGION_DATA_TABLE, /* Internal use only */
+ REGION_FIXED_HW = 0x7F
} AML_REGION_TYPES;
-
/* Comparison operation codes for match_op operator */
-typedef enum
-{
- MATCH_MTR = 0,
- MATCH_MEQ = 1,
- MATCH_MLE = 2,
- MATCH_MLT = 3,
- MATCH_MGE = 4,
- MATCH_MGT = 5
-
+typedef enum {
+ MATCH_MTR = 0,
+ MATCH_MEQ = 1,
+ MATCH_MLE = 2,
+ MATCH_MLT = 3,
+ MATCH_MGE = 4,
+ MATCH_MGT = 5
} AML_MATCH_OPERATOR;
#define MAX_MATCH_OPERATOR 5
-
/*
* field_flags
*
@@ -450,60 +436,47 @@ typedef enum
#define AML_FIELD_LOCK_RULE_MASK 0x10
#define AML_FIELD_UPDATE_RULE_MASK 0x60
-
/* 1) Field Access Types */
-typedef enum
-{
- AML_FIELD_ACCESS_ANY = 0x00,
- AML_FIELD_ACCESS_BYTE = 0x01,
- AML_FIELD_ACCESS_WORD = 0x02,
- AML_FIELD_ACCESS_DWORD = 0x03,
- AML_FIELD_ACCESS_QWORD = 0x04, /* ACPI 2.0 */
- AML_FIELD_ACCESS_BUFFER = 0x05 /* ACPI 2.0 */
-
+typedef enum {
+ AML_FIELD_ACCESS_ANY = 0x00,
+ AML_FIELD_ACCESS_BYTE = 0x01,
+ AML_FIELD_ACCESS_WORD = 0x02,
+ AML_FIELD_ACCESS_DWORD = 0x03,
+ AML_FIELD_ACCESS_QWORD = 0x04, /* ACPI 2.0 */
+ AML_FIELD_ACCESS_BUFFER = 0x05 /* ACPI 2.0 */
} AML_ACCESS_TYPE;
-
/* 2) Field Lock Rules */
-typedef enum
-{
- AML_FIELD_LOCK_NEVER = 0x00,
- AML_FIELD_LOCK_ALWAYS = 0x10
-
+typedef enum {
+ AML_FIELD_LOCK_NEVER = 0x00,
+ AML_FIELD_LOCK_ALWAYS = 0x10
} AML_LOCK_RULE;
-
/* 3) Field Update Rules */
-typedef enum
-{
- AML_FIELD_UPDATE_PRESERVE = 0x00,
- AML_FIELD_UPDATE_WRITE_AS_ONES = 0x20,
+typedef enum {
+ AML_FIELD_UPDATE_PRESERVE = 0x00,
+ AML_FIELD_UPDATE_WRITE_AS_ONES = 0x20,
AML_FIELD_UPDATE_WRITE_AS_ZEROS = 0x40
-
} AML_UPDATE_RULE;
-
/*
* Field Access Attributes.
* This byte is extracted from the AML via the
* access_as keyword
*/
-typedef enum
-{
- AML_FIELD_ATTRIB_SMB_QUICK = 0x02,
- AML_FIELD_ATTRIB_SMB_SEND_RCV = 0x04,
- AML_FIELD_ATTRIB_SMB_BYTE = 0x06,
- AML_FIELD_ATTRIB_SMB_WORD = 0x08,
- AML_FIELD_ATTRIB_SMB_BLOCK = 0x0A,
- AML_FIELD_ATTRIB_SMB_WORD_CALL = 0x0C,
+typedef enum {
+ AML_FIELD_ATTRIB_SMB_QUICK = 0x02,
+ AML_FIELD_ATTRIB_SMB_SEND_RCV = 0x04,
+ AML_FIELD_ATTRIB_SMB_BYTE = 0x06,
+ AML_FIELD_ATTRIB_SMB_WORD = 0x08,
+ AML_FIELD_ATTRIB_SMB_BLOCK = 0x0A,
+ AML_FIELD_ATTRIB_SMB_WORD_CALL = 0x0C,
AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D
-
} AML_ACCESS_ATTRIBUTE;
-
/* Bit fields in method_flags byte */
#define AML_METHOD_ARG_COUNT 0x07
@@ -516,5 +489,4 @@ typedef enum
#define AML_METHOD_RESERVED1 0x02
#define AML_METHOD_RESERVED2 0x04
-
-#endif /* __AMLCODE_H__ */
+#endif /* __AMLCODE_H__ */
diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h
index b20ec303df07..051786e4b210 100644
--- a/include/acpi/amlresrc.h
+++ b/include/acpi/amlresrc.h
@@ -42,29 +42,27 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-
#ifndef __AMLRESRC_H
#define __AMLRESRC_H
-
#define ASL_RESNAME_ADDRESS "_ADR"
#define ASL_RESNAME_ALIGNMENT "_ALN"
#define ASL_RESNAME_ADDRESSSPACE "_ASI"
#define ASL_RESNAME_ACCESSSIZE "_ASZ"
#define ASL_RESNAME_TYPESPECIFICATTRIBUTES "_ATT"
#define ASL_RESNAME_BASEADDRESS "_BAS"
-#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */
+#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */
#define ASL_RESNAME_DECODE "_DEC"
#define ASL_RESNAME_DMA "_DMA"
-#define ASL_RESNAME_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */
+#define ASL_RESNAME_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */
#define ASL_RESNAME_GRANULARITY "_GRA"
#define ASL_RESNAME_INTERRUPT "_INT"
-#define ASL_RESNAME_INTERRUPTLEVEL "_LL_" /* active_lo(1), active_hi(0) */
-#define ASL_RESNAME_INTERRUPTSHARE "_SHR" /* Shareable(1), no_share(0) */
-#define ASL_RESNAME_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */
+#define ASL_RESNAME_INTERRUPTLEVEL "_LL_" /* active_lo(1), active_hi(0) */
+#define ASL_RESNAME_INTERRUPTSHARE "_SHR" /* Shareable(1), no_share(0) */
+#define ASL_RESNAME_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */
#define ASL_RESNAME_LENGTH "_LEN"
-#define ASL_RESNAME_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
-#define ASL_RESNAME_MEMTYPE "_MEM" /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
+#define ASL_RESNAME_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
+#define ASL_RESNAME_MEMTYPE "_MEM" /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
#define ASL_RESNAME_MAXADDR "_MAX"
#define ASL_RESNAME_MINADDR "_MIN"
#define ASL_RESNAME_MAXTYPE "_MAF"
@@ -72,12 +70,11 @@
#define ASL_RESNAME_REGISTERBITOFFSET "_RBO"
#define ASL_RESNAME_REGISTERBITWIDTH "_RBW"
#define ASL_RESNAME_RANGETYPE "_RNG"
-#define ASL_RESNAME_READWRITETYPE "_RW_" /* read_only(0), Writeable (1) */
+#define ASL_RESNAME_READWRITETYPE "_RW_" /* read_only(0), Writeable (1) */
#define ASL_RESNAME_TRANSLATION "_TRA"
-#define ASL_RESNAME_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */
-#define ASL_RESNAME_TYPE "_TTP" /* Translation(1), Static (0) */
-#define ASL_RESNAME_XFERTYPE "_SIz" /* 8(0), 8_and16(1), 16(2) */
-
+#define ASL_RESNAME_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */
+#define ASL_RESNAME_TYPE "_TTP" /* Translation(1), Static (0) */
+#define ASL_RESNAME_XFERTYPE "_SIz" /* 8(0), 8_and16(1), 16(2) */
/* Default sizes for "small" resource descriptors */
@@ -89,15 +86,12 @@
#define ASL_RDESC_FIXED_IO_SIZE 0x03
#define ASL_RDESC_END_TAG_SIZE 0x01
-
-struct asl_resource_node
-{
- u32 buffer_length;
- void *buffer;
- struct asl_resource_node *next;
+struct asl_resource_node {
+ u32 buffer_length;
+ void *buffer;
+ struct asl_resource_node *next;
};
-
/*
* Resource descriptors defined in the ACPI specification.
*
@@ -106,214 +100,175 @@ struct asl_resource_node
*/
#pragma pack(1)
-struct asl_irq_format_desc
-{
- u8 descriptor_type;
- u16 irq_mask;
- u8 flags;
+struct asl_irq_format_desc {
+ u8 descriptor_type;
+ u16 irq_mask;
+ u8 flags;
};
-
-struct asl_irq_noflags_desc
-{
- u8 descriptor_type;
- u16 irq_mask;
+struct asl_irq_noflags_desc {
+ u8 descriptor_type;
+ u16 irq_mask;
};
-
-struct asl_dma_format_desc
-{
- u8 descriptor_type;
- u8 dma_channel_mask;
- u8 flags;
+struct asl_dma_format_desc {
+ u8 descriptor_type;
+ u8 dma_channel_mask;
+ u8 flags;
};
-
-struct asl_start_dependent_desc
-{
- u8 descriptor_type;
- u8 flags;
+struct asl_start_dependent_desc {
+ u8 descriptor_type;
+ u8 flags;
};
-
-struct asl_start_dependent_noprio_desc
-{
- u8 descriptor_type;
+struct asl_start_dependent_noprio_desc {
+ u8 descriptor_type;
};
-
-struct asl_end_dependent_desc
-{
- u8 descriptor_type;
+struct asl_end_dependent_desc {
+ u8 descriptor_type;
};
-
-struct asl_io_port_desc
-{
- u8 descriptor_type;
- u8 information;
- u16 address_min;
- u16 address_max;
- u8 alignment;
- u8 length;
+struct asl_io_port_desc {
+ u8 descriptor_type;
+ u8 information;
+ u16 address_min;
+ u16 address_max;
+ u8 alignment;
+ u8 length;
};
-
-struct asl_fixed_io_port_desc
-{
- u8 descriptor_type;
- u16 base_address;
- u8 length;
+struct asl_fixed_io_port_desc {
+ u8 descriptor_type;
+ u16 base_address;
+ u8 length;
};
-
-struct asl_small_vendor_desc
-{
- u8 descriptor_type;
- u8 vendor_defined[7];
+struct asl_small_vendor_desc {
+ u8 descriptor_type;
+ u8 vendor_defined[7];
};
-
-struct asl_end_tag_desc
-{
- u8 descriptor_type;
- u8 checksum;
+struct asl_end_tag_desc {
+ u8 descriptor_type;
+ u8 checksum;
};
-
/* LARGE descriptors */
-struct asl_memory_24_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 information;
- u16 address_min;
- u16 address_max;
- u16 alignment;
- u16 range_length;
+struct asl_memory_24_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 information;
+ u16 address_min;
+ u16 address_max;
+ u16 alignment;
+ u16 range_length;
};
-
-struct asl_large_vendor_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 vendor_defined[1];
+struct asl_large_vendor_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 vendor_defined[1];
};
-
-struct asl_memory_32_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 information;
- u32 address_min;
- u32 address_max;
- u32 alignment;
- u32 range_length;
+struct asl_memory_32_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 information;
+ u32 address_min;
+ u32 address_max;
+ u32 alignment;
+ u32 range_length;
};
-
-struct asl_fixed_memory_32_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 information;
- u32 base_address;
- u32 range_length;
+struct asl_fixed_memory_32_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 information;
+ u32 base_address;
+ u32 range_length;
};
-
-struct asl_extended_address_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 resource_type;
- u8 flags;
- u8 specific_flags;
- u8 revision_iD;
- u8 reserved;
- u64 granularity;
- u64 address_min;
- u64 address_max;
- u64 translation_offset;
- u64 address_length;
- u64 type_specific_attributes;
- u8 optional_fields[2]; /* Used for length calculation only */
+struct asl_extended_address_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 resource_type;
+ u8 flags;
+ u8 specific_flags;
+ u8 revision_iD;
+ u8 reserved;
+ u64 granularity;
+ u64 address_min;
+ u64 address_max;
+ u64 translation_offset;
+ u64 address_length;
+ u64 type_specific_attributes;
+ u8 optional_fields[2]; /* Used for length calculation only */
};
-#define ASL_EXTENDED_ADDRESS_DESC_REVISION 1 /* ACPI 3.0 */
-
-
-struct asl_qword_address_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 resource_type;
- u8 flags;
- u8 specific_flags;
- u64 granularity;
- u64 address_min;
- u64 address_max;
- u64 translation_offset;
- u64 address_length;
- u8 optional_fields[2];
+#define ASL_EXTENDED_ADDRESS_DESC_REVISION 1 /* ACPI 3.0 */
+
+struct asl_qword_address_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 resource_type;
+ u8 flags;
+ u8 specific_flags;
+ u64 granularity;
+ u64 address_min;
+ u64 address_max;
+ u64 translation_offset;
+ u64 address_length;
+ u8 optional_fields[2];
};
-
-struct asl_dword_address_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 resource_type;
- u8 flags;
- u8 specific_flags;
- u32 granularity;
- u32 address_min;
- u32 address_max;
- u32 translation_offset;
- u32 address_length;
- u8 optional_fields[2];
+struct asl_dword_address_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 resource_type;
+ u8 flags;
+ u8 specific_flags;
+ u32 granularity;
+ u32 address_min;
+ u32 address_max;
+ u32 translation_offset;
+ u32 address_length;
+ u8 optional_fields[2];
};
-
-struct asl_word_address_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 resource_type;
- u8 flags;
- u8 specific_flags;
- u16 granularity;
- u16 address_min;
- u16 address_max;
- u16 translation_offset;
- u16 address_length;
- u8 optional_fields[2];
+struct asl_word_address_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 resource_type;
+ u8 flags;
+ u8 specific_flags;
+ u16 granularity;
+ u16 address_min;
+ u16 address_max;
+ u16 translation_offset;
+ u16 address_length;
+ u8 optional_fields[2];
};
-
-struct asl_extended_xrupt_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 flags;
- u8 table_length;
- u32 interrupt_number[1];
+struct asl_extended_xrupt_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 flags;
+ u8 table_length;
+ u32 interrupt_number[1];
/* res_source_index, res_source optional fields follow */
};
-
-struct asl_general_register_desc
-{
- u8 descriptor_type;
- u16 length;
- u8 address_space_id;
- u8 bit_width;
- u8 bit_offset;
- u8 access_size; /* ACPI 3.0, was Reserved */
- u64 address;
+struct asl_general_register_desc {
+ u8 descriptor_type;
+ u16 length;
+ u8 address_space_id;
+ u8 bit_width;
+ u8 bit_offset;
+ u8 access_size; /* ACPI 3.0, was Reserved */
+ u64 address;
};
/* restore default alignment */
@@ -322,32 +277,29 @@ struct asl_general_register_desc
/* Union of all resource descriptors, so we can allocate the worst case */
-union asl_resource_desc
-{
- struct asl_irq_format_desc irq;
- struct asl_dma_format_desc dma;
- struct asl_start_dependent_desc std;
- struct asl_end_dependent_desc end;
- struct asl_io_port_desc iop;
- struct asl_fixed_io_port_desc fio;
- struct asl_small_vendor_desc smv;
- struct asl_end_tag_desc et;
-
- struct asl_memory_24_desc M24;
- struct asl_large_vendor_desc lgv;
- struct asl_memory_32_desc M32;
- struct asl_fixed_memory_32_desc F32;
- struct asl_qword_address_desc qas;
- struct asl_dword_address_desc das;
- struct asl_word_address_desc was;
- struct asl_extended_address_desc eas;
- struct asl_extended_xrupt_desc exx;
- struct asl_general_register_desc grg;
- u32 u32_item;
- u16 u16_item;
- u8 U8item;
+union asl_resource_desc {
+ struct asl_irq_format_desc irq;
+ struct asl_dma_format_desc dma;
+ struct asl_start_dependent_desc std;
+ struct asl_end_dependent_desc end;
+ struct asl_io_port_desc iop;
+ struct asl_fixed_io_port_desc fio;
+ struct asl_small_vendor_desc smv;
+ struct asl_end_tag_desc et;
+
+ struct asl_memory_24_desc M24;
+ struct asl_large_vendor_desc lgv;
+ struct asl_memory_32_desc M32;
+ struct asl_fixed_memory_32_desc F32;
+ struct asl_qword_address_desc qas;
+ struct asl_dword_address_desc das;
+ struct asl_word_address_desc was;
+ struct asl_extended_address_desc eas;
+ struct asl_extended_xrupt_desc exx;
+ struct asl_general_register_desc grg;
+ u32 u32_item;
+ u16 u16_item;
+ u8 U8item;
};
-
#endif
-
diff --git a/include/acpi/container.h b/include/acpi/container.h
index d716df04d9dc..a703f14e049e 100644
--- a/include/acpi/container.h
+++ b/include/acpi/container.h
@@ -9,5 +9,4 @@ struct acpi_container {
int state;
};
-#endif /* __ACPI_CONTAINER_H */
-
+#endif /* __ACPI_CONTAINER_H */
diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h
index fd6730e4e567..91f4a12a99a1 100644
--- a/include/acpi/pdc_intel.h
+++ b/include/acpi/pdc_intel.h
@@ -14,7 +14,6 @@
#define ACPI_PDC_SMP_T_SWCOORD (0x0080)
#define ACPI_PDC_C_C1_FFH (0x0100)
-
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT)
@@ -25,5 +24,4 @@
ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT)
-#endif /* __PDC_INTEL_H__ */
-
+#endif /* __PDC_INTEL_H__ */
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index adf969efa510..16609c1ab2eb 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -44,40 +44,42 @@
#ifndef __ACENV_H__
#define __ACENV_H__
-
/*
* Configuration for ACPI tools and utilities
*/
-#ifdef _ACPI_DUMP_APP
+#ifdef ACPI_LIBRARY
+#define ACPI_USE_LOCAL_CACHE
+#endif
+
+#ifdef ACPI_DUMP_APP
#ifndef MSDOS
#define ACPI_DEBUG_OUTPUT
#endif
#define ACPI_APPLICATION
#define ACPI_DISASSEMBLER
#define ACPI_NO_METHOD_EXECUTION
-#define ACPI_USE_SYSTEM_CLIBRARY
-#define ACPI_ENABLE_OBJECT_CACHE
#endif
-#ifdef _ACPI_EXEC_APP
+#ifdef ACPI_EXEC_APP
#undef DEBUGGER_THREADING
#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED
#define ACPI_DEBUG_OUTPUT
#define ACPI_APPLICATION
#define ACPI_DEBUGGER
#define ACPI_DISASSEMBLER
-#define ACPI_USE_SYSTEM_CLIBRARY
-#define ACPI_ENABLE_OBJECT_CACHE
#endif
-#ifdef _ACPI_ASL_COMPILER
+#ifdef ACPI_ASL_COMPILER
#define ACPI_DEBUG_OUTPUT
#define ACPI_APPLICATION
#define ACPI_DISASSEMBLER
#define ACPI_CONSTANT_EVAL_ONLY
+#endif
+
+#ifdef ACPI_APPLICATION
#define ACPI_USE_SYSTEM_CLIBRARY
-#define ACPI_ENABLE_OBJECT_CACHE
+#define ACPI_USE_LOCAL_CACHE
#endif
/*
@@ -131,7 +133,7 @@
#elif defined(WIN64)
#include "acwin64.h"
-#elif defined(MSDOS) /* Must appear after WIN32 and WIN64 check */
+#elif defined(MSDOS) /* Must appear after WIN32 and WIN64 check */
#include "acdos16.h"
#elif defined(__FreeBSD__)
@@ -177,7 +179,6 @@
/*! [End] no source code translation !*/
-
/*
* Debugger threading model
* Use single threaded if the entire subsystem is contained in an application
@@ -196,8 +197,7 @@
#else
#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED
#endif
-#endif /* !DEBUGGER_THREADING */
-
+#endif /* !DEBUGGER_THREADING */
/******************************************************************************
*
@@ -219,7 +219,7 @@
#include <string.h>
#include <ctype.h>
-#endif /* ACPI_USE_STANDARD_HEADERS */
+#endif /* ACPI_USE_STANDARD_HEADERS */
/*
* We will be linking to the standard Clib functions
@@ -238,15 +238,15 @@
#define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (acpi_size)(n))
#define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (acpi_size)(n))
-#define ACPI_TOUPPER toupper
-#define ACPI_TOLOWER tolower
-#define ACPI_IS_XDIGIT isxdigit
-#define ACPI_IS_DIGIT isdigit
-#define ACPI_IS_SPACE isspace
-#define ACPI_IS_UPPER isupper
-#define ACPI_IS_PRINT isprint
-#define ACPI_IS_ALPHA isalpha
-#define ACPI_IS_ASCII isascii
+#define ACPI_TOUPPER(i) toupper((int) (i))
+#define ACPI_TOLOWER(i) tolower((int) (i))
+#define ACPI_IS_XDIGIT(i) isxdigit((int) (i))
+#define ACPI_IS_DIGIT(i) isdigit((int) (i))
+#define ACPI_IS_SPACE(i) isspace((int) (i))
+#define ACPI_IS_UPPER(i) isupper((int) (i))
+#define ACPI_IS_PRINT(i) isprint((int) (i))
+#define ACPI_IS_ALPHA(i) isalpha((int) (i))
+#define ACPI_IS_ASCII(i) isascii((int) (i))
#else
@@ -257,18 +257,18 @@
*****************************************************************************/
/*
- * Use local definitions of C library macros and functions
- * NOTE: The function implementations may not be as efficient
- * as an inline or assembly code implementation provided by a
- * native C library.
- */
+ * Use local definitions of C library macros and functions
+ * NOTE: The function implementations may not be as efficient
+ * as an inline or assembly code implementation provided by a
+ * native C library.
+ */
#ifndef va_arg
#ifndef _VALIST
#define _VALIST
typedef char *va_list;
-#endif /* _VALIST */
+#endif /* _VALIST */
/*
* Storage alignment properties
@@ -284,8 +284,7 @@ typedef char *va_list;
#define va_end(ap) (void) 0
#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
-#endif /* va_arg */
-
+#endif /* va_arg */
#define ACPI_STRSTR(s1,s2) acpi_ut_strstr ((s1), (s2))
#define ACPI_STRCHR(s1,c) acpi_ut_strchr ((s1), (c))
@@ -303,8 +302,7 @@ typedef char *va_list;
#define ACPI_TOUPPER acpi_ut_to_upper
#define ACPI_TOLOWER acpi_ut_to_lower
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
/******************************************************************************
*
@@ -345,8 +343,7 @@ typedef char *va_list;
#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
-#endif /* ACPI_ASM_MACROS */
-
+#endif /* ACPI_ASM_MACROS */
#ifdef ACPI_APPLICATION
@@ -356,11 +353,10 @@ typedef char *va_list;
#define BREAKPOINT3
#endif
-
/******************************************************************************
*
* Compiler-specific information is contained in the compiler-specific
* headers.
*
*****************************************************************************/
-#endif /* __ACENV_H__ */
+#endif /* __ACENV_H__ */
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
index 91fda36b042b..4c0e0ba09ba0 100644
--- a/include/acpi/platform/acgcc.h
+++ b/include/acpi/platform/acgcc.h
@@ -44,16 +44,20 @@
#ifndef __ACGCC_H__
#define __ACGCC_H__
+/* Function name is used for debug output. Non-ANSI, compiler-dependent */
+
+#define ACPI_GET_FUNCTION_NAME __FUNCTION__
+
/* This macro is used to tag functions as "printf-like" because
* some compilers (like GCC) can catch printf format string problems.
*/
-#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5)))
+#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 6, 7)))
/* Some compilers complain about unused variables. Sometimes we don't want to
- * use all the variables (most specifically for _THIS_MODULE). This allow us
+ * use all the variables (for example, _acpi_module_name). This allows us
* to to tell the compiler warning in a per-variable manner that a variable
* is unused.
*/
#define ACPI_UNUSED_VAR __attribute__ ((unused))
-#endif /* __ACGCC_H__ */
+#endif /* __ACGCC_H__ */
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index a3de0db85694..c93e6562f0e1 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -62,7 +62,16 @@
#define ACPI_MACHINE_WIDTH BITS_PER_LONG
-#else /* !__KERNEL__ */
+/* Type(s) for the OSL */
+
+#ifdef ACPI_USE_LOCAL_CACHE
+#define acpi_cache_t struct acpi_memory_list
+#else
+#include <linux/slab.h>
+#define acpi_cache_t kmem_cache_t
+#endif
+
+#else /* !__KERNEL__ */
#include <stdarg.h>
#include <string.h>
@@ -83,10 +92,10 @@
#define __cdecl
#define ACPI_FLUSH_CPU_CACHE()
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
/* Linux uses GCC */
#include "acgcc.h"
-#endif /* __ACLINUX_H__ */
+#endif /* __ACLINUX_H__ */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 50cfea4ff6ca..7a00d5089de9 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -23,45 +23,44 @@
struct acpi_processor_cx;
struct acpi_power_register {
- u8 descriptor;
- u16 length;
- u8 space_id;
- u8 bit_width;
- u8 bit_offset;
- u8 reserved;
- u64 address;
+ u8 descriptor;
+ u16 length;
+ u8 space_id;
+ u8 bit_width;
+ u8 bit_offset;
+ u8 reserved;
+ u64 address;
} __attribute__ ((packed));
-
struct acpi_processor_cx_policy {
- u32 count;
+ u32 count;
struct acpi_processor_cx *state;
struct {
- u32 time;
- u32 ticks;
- u32 count;
- u32 bm;
- } threshold;
+ u32 time;
+ u32 ticks;
+ u32 count;
+ u32 bm;
+ } threshold;
};
struct acpi_processor_cx {
- u8 valid;
- u8 type;
- u32 address;
- u32 latency;
- u32 latency_ticks;
- u32 power;
- u32 usage;
+ u8 valid;
+ u8 type;
+ u32 address;
+ u32 latency;
+ u32 latency_ticks;
+ u32 power;
+ u32 usage;
struct acpi_processor_cx_policy promotion;
struct acpi_processor_cx_policy demotion;
};
struct acpi_processor_power {
struct acpi_processor_cx *state;
- unsigned long bm_check_timestamp;
- u32 default_state;
- u32 bm_activity;
- int count;
+ unsigned long bm_check_timestamp;
+ u32 default_state;
+ u32 bm_activity;
+ int count;
struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
/* the _PDC objects passed by the driver, if any */
@@ -71,85 +70,82 @@ struct acpi_processor_power {
/* Performance Management */
struct acpi_pct_register {
- u8 descriptor;
- u16 length;
- u8 space_id;
- u8 bit_width;
- u8 bit_offset;
- u8 reserved;
- u64 address;
+ u8 descriptor;
+ u16 length;
+ u8 space_id;
+ u8 bit_width;
+ u8 bit_offset;
+ u8 reserved;
+ u64 address;
} __attribute__ ((packed));
struct acpi_processor_px {
- acpi_integer core_frequency; /* megahertz */
- acpi_integer power; /* milliWatts */
- acpi_integer transition_latency; /* microseconds */
- acpi_integer bus_master_latency; /* microseconds */
- acpi_integer control; /* control value */
- acpi_integer status; /* success indicator */
+ acpi_integer core_frequency; /* megahertz */
+ acpi_integer power; /* milliWatts */
+ acpi_integer transition_latency; /* microseconds */
+ acpi_integer bus_master_latency; /* microseconds */
+ acpi_integer control; /* control value */
+ acpi_integer status; /* success indicator */
};
struct acpi_processor_performance {
- unsigned int state;
- unsigned int platform_limit;
+ unsigned int state;
+ unsigned int platform_limit;
struct acpi_pct_register control_register;
struct acpi_pct_register status_register;
- unsigned int state_count;
+ unsigned int state_count;
struct acpi_processor_px *states;
/* the _PDC objects passed by the driver, if any */
struct acpi_object_list *pdc;
};
-
-
/* Throttling Control */
struct acpi_processor_tx {
- u16 power;
- u16 performance;
+ u16 power;
+ u16 performance;
};
struct acpi_processor_throttling {
- int state;
- u32 address;
- u8 duty_offset;
- u8 duty_width;
- int state_count;
+ int state;
+ u32 address;
+ u8 duty_offset;
+ u8 duty_width;
+ int state_count;
struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING];
};
/* Limit Interface */
struct acpi_processor_lx {
- int px; /* performace state */
- int tx; /* throttle level */
+ int px; /* performace state */
+ int tx; /* throttle level */
};
struct acpi_processor_limit {
- struct acpi_processor_lx state; /* current limit */
+ struct acpi_processor_lx state; /* current limit */
struct acpi_processor_lx thermal; /* thermal limit */
- struct acpi_processor_lx user; /* user limit */
+ struct acpi_processor_lx user; /* user limit */
};
-
struct acpi_processor_flags {
- u8 power:1;
- u8 performance:1;
- u8 throttling:1;
- u8 limit:1;
- u8 bm_control:1;
- u8 bm_check:1;
- u8 has_cst:1;
- u8 power_setup_done:1;
+ u8 power:1;
+ u8 performance:1;
+ u8 throttling:1;
+ u8 limit:1;
+ u8 bm_control:1;
+ u8 bm_check:1;
+ u8 has_cst:1;
+ u8 power_setup_done:1;
};
struct acpi_processor {
- acpi_handle handle;
- u32 acpi_id;
- u32 id;
- u32 pblk;
- int performance_platform_limit;
+ acpi_handle handle;
+ u32 acpi_id;
+ u32 id;
+ u32 pblk;
+ int performance_platform_limit;
struct acpi_processor_flags flags;
struct acpi_processor_power power;
struct acpi_processor_performance *performance;
@@ -158,50 +154,49 @@ struct acpi_processor {
};
struct acpi_processor_errata {
- u8 smp;
+ u8 smp;
struct {
- u8 throttle:1;
- u8 fdma:1;
- u8 reserved:6;
- u32 bmisx;
- } piix4;
+ u8 throttle:1;
+ u8 fdma:1;
+ u8 reserved:6;
+ u32 bmisx;
+ } piix4;
};
-extern int acpi_processor_register_performance (
- struct acpi_processor_performance * performance,
- unsigned int cpu);
-extern void acpi_processor_unregister_performance (
- struct acpi_processor_performance * performance,
- unsigned int cpu);
+extern int acpi_processor_register_performance(struct acpi_processor_performance
+ *performance, unsigned int cpu);
+extern void acpi_processor_unregister_performance(struct
+ acpi_processor_performance
+ *performance,
+ unsigned int cpu);
/* note: this locks both the calling module and the processor module
if a _PPC object exists, rmmod is disallowed then */
int acpi_processor_notify_smm(struct module *calling_module);
-
-
/* for communication between multiple parts of the processor kernel module */
-extern struct acpi_processor *processors[NR_CPUS];
+extern struct acpi_processor *processors[NR_CPUS];
extern struct acpi_processor_errata errata;
int acpi_processor_set_pdc(struct acpi_processor *pr,
- struct acpi_object_list *pdc_in);
+ struct acpi_object_list *pdc_in);
#ifdef ARCH_HAS_POWER_PDC_INIT
void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
- unsigned int cpu);
+ unsigned int cpu);
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
- unsigned int cpu);
+ unsigned int cpu);
#else
-static inline void acpi_processor_power_init_pdc(
- struct acpi_processor_power *pow, unsigned int cpu)
+static inline void acpi_processor_power_init_pdc(struct acpi_processor_power
+ *pow, unsigned int cpu)
{
pow->pdc = NULL;
return;
}
-static inline void acpi_processor_power_init_bm_check(
- struct acpi_processor_flags *flags, unsigned int cpu)
+static inline void acpi_processor_power_init_bm_check(struct
+ acpi_processor_flags
+ *flags, unsigned int cpu)
{
flags->bm_check = 1;
return;
@@ -215,51 +210,62 @@ void acpi_processor_ppc_init(void);
void acpi_processor_ppc_exit(void);
int acpi_processor_ppc_has_changed(struct acpi_processor *pr);
#else
-static inline void acpi_processor_ppc_init(void) { return; }
-static inline void acpi_processor_ppc_exit(void) { return; }
-static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) {
+static inline void acpi_processor_ppc_init(void)
+{
+ return;
+}
+static inline void acpi_processor_ppc_exit(void)
+{
+ return;
+}
+static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
+{
static unsigned int printout = 1;
if (printout) {
- printk(KERN_WARNING "Warning: Processor Platform Limit event detected, but not handled.\n");
- printk(KERN_WARNING "Consider compiling CPUfreq support into your kernel.\n");
+ printk(KERN_WARNING
+ "Warning: Processor Platform Limit event detected, but not handled.\n");
+ printk(KERN_WARNING
+ "Consider compiling CPUfreq support into your kernel.\n");
printout = 0;
}
return 0;
}
-#endif /* CONFIG_CPU_FREQ */
+#endif /* CONFIG_CPU_FREQ */
/* in processor_throttling.c */
-int acpi_processor_get_throttling_info (struct acpi_processor *pr);
-int acpi_processor_set_throttling (struct acpi_processor *pr, int state);
-ssize_t acpi_processor_write_throttling (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data);
+int acpi_processor_get_throttling_info(struct acpi_processor *pr);
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+ssize_t acpi_processor_write_throttling(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data);
extern struct file_operations acpi_processor_throttling_fops;
/* in processor_idle.c */
-int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device);
-int acpi_processor_cst_has_changed (struct acpi_processor *pr);
-int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device);
-
+int acpi_processor_power_init(struct acpi_processor *pr,
+ struct acpi_device *device);
+int acpi_processor_cst_has_changed(struct acpi_processor *pr);
+int acpi_processor_power_exit(struct acpi_processor *pr,
+ struct acpi_device *device);
/* in processor_thermal.c */
-int acpi_processor_get_limit_info (struct acpi_processor *pr);
-ssize_t acpi_processor_write_limit (
- struct file *file,
- const char __user *buffer,
- size_t count,
- loff_t *data);
+int acpi_processor_get_limit_info(struct acpi_processor *pr);
+ssize_t acpi_processor_write_limit(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data);
extern struct file_operations acpi_processor_limit_fops;
#ifdef CONFIG_CPU_FREQ
void acpi_thermal_cpufreq_init(void);
void acpi_thermal_cpufreq_exit(void);
#else
-static inline void acpi_thermal_cpufreq_init(void) { return; }
-static inline void acpi_thermal_cpufreq_exit(void) { return; }
+static inline void acpi_thermal_cpufreq_init(void)
+{
+ return;
+}
+static inline void acpi_thermal_cpufreq_exit(void)
+{
+ return;
+}
#endif
-
#endif
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index 1b383e3cb68c..20ac3d95ecd9 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -1,6 +1,8 @@
#ifndef _ALPHA_ATOMIC_H
#define _ALPHA_ATOMIC_H
+#include <asm/barrier.h>
+
/*
* Atomic operations that C can't guarantee us. Useful for
* resource counting etc...
@@ -100,18 +102,19 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
static __inline__ long atomic_add_return(int i, atomic_t * v)
{
long temp, result;
+ smp_mb();
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" addl %0,%3,%2\n"
" addl %0,%3,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
- " mb\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (v->counter), "=&r" (result)
:"Ir" (i), "m" (v->counter) : "memory");
+ smp_mb();
return result;
}
@@ -120,54 +123,57 @@ static __inline__ long atomic_add_return(int i, atomic_t * v)
static __inline__ long atomic64_add_return(long i, atomic64_t * v)
{
long temp, result;
+ smp_mb();
__asm__ __volatile__(
"1: ldq_l %0,%1\n"
" addq %0,%3,%2\n"
" addq %0,%3,%0\n"
" stq_c %0,%1\n"
" beq %0,2f\n"
- " mb\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (v->counter), "=&r" (result)
:"Ir" (i), "m" (v->counter) : "memory");
+ smp_mb();
return result;
}
static __inline__ long atomic_sub_return(int i, atomic_t * v)
{
long temp, result;
+ smp_mb();
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" subl %0,%3,%2\n"
" subl %0,%3,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
- " mb\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (v->counter), "=&r" (result)
:"Ir" (i), "m" (v->counter) : "memory");
+ smp_mb();
return result;
}
static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
{
long temp, result;
+ smp_mb();
__asm__ __volatile__(
"1: ldq_l %0,%1\n"
" subq %0,%3,%2\n"
" subq %0,%3,%0\n"
" stq_c %0,%1\n"
" beq %0,2f\n"
- " mb\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (v->counter), "=&r" (result)
:"Ir" (i), "m" (v->counter) : "memory");
+ smp_mb();
return result;
}
diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
new file mode 100644
index 000000000000..229c83fe77cb
--- /dev/null
+++ b/include/asm-alpha/barrier.h
@@ -0,0 +1,34 @@
+#ifndef __BARRIER_H
+#define __BARRIER_H
+
+#define mb() \
+__asm__ __volatile__("mb": : :"memory")
+
+#define rmb() \
+__asm__ __volatile__("mb": : :"memory")
+
+#define wmb() \
+__asm__ __volatile__("wmb": : :"memory")
+
+#define read_barrier_depends() \
+__asm__ __volatile__("mb": : :"memory")
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#define smp_read_barrier_depends() read_barrier_depends()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_read_barrier_depends() barrier()
+#endif
+
+#define set_mb(var, value) \
+do { var = value; mb(); } while (0)
+
+#define set_wmb(var, value) \
+do { var = value; wmb(); } while (0)
+
+#endif /* __BARRIER_H */
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h
index 399c33b7be51..0a4a8b40dfcd 100644
--- a/include/asm-alpha/compiler.h
+++ b/include/asm-alpha/compiler.h
@@ -98,6 +98,9 @@
#undef inline
#undef __inline__
#undef __inline
-
+#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3
+#undef __always_inline
+#define __always_inline inline __attribute__((always_inline))
+#endif
#endif /* __ALPHA_COMPILER_H */
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index c675f282d6ad..680f7ecbb28f 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -31,7 +31,7 @@
#else /* no PCI - no IOMMU. */
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp);
+ dma_addr_t *dma_handle, gfp_t gfp);
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction);
diff --git a/include/asm-alpha/futex.h b/include/asm-alpha/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-alpha/futex.h
+++ b/include/asm-alpha/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
index f681e675b823..4e115f368d5f 100644
--- a/include/asm-alpha/pci.h
+++ b/include/asm-alpha/pci.h
@@ -254,6 +254,19 @@ extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
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-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 22b53e369f59..8393bf374b2b 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -339,13 +339,6 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
#define kern_addr_valid(addr) (1)
#endif
-#define io_remap_page_range(vma, start, busaddr, size, prot) \
-({ \
- void *va = (void __force *)ioremap(busaddr, size); \
- unsigned long pfn = virt_to_phys(va) >> PAGE_SHIFT; \
- remap_pfn_range(vma, start, pfn, size, prot); \
-})
-
#define io_remap_pfn_range(vma, start, pfn, size, prot) \
remap_pfn_range(vma, start, pfn, size, prot)
diff --git a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h
index 80780dba9986..8197c69eff44 100644
--- a/include/asm-alpha/spinlock.h
+++ b/include/asm-alpha/spinlock.h
@@ -6,7 +6,6 @@
#include <linux/kernel.h>
#include <asm/current.h>
-
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
* on the local processor, one does not.
@@ -14,43 +13,18 @@
* We make no fairness assumptions. They have a cost.
*/
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- int on_cpu;
- int line_no;
- void *previous;
- struct task_struct * task;
- const char *base_file;
-#endif
-} spinlock_t;
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define SPIN_LOCK_UNLOCKED (spinlock_t){ 0, -1, 0, NULL, NULL, NULL }
-#else
-#define SPIN_LOCK_UNLOCKED (spinlock_t){ 0 }
-#endif
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock)
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-extern void _raw_spin_unlock(spinlock_t * lock);
-extern void debug_spin_lock(spinlock_t * lock, const char *, int);
-extern int debug_spin_trylock(spinlock_t * lock, const char *, int);
-#define _raw_spin_lock(LOCK) \
- debug_spin_lock(LOCK, __BASE_FILE__, __LINE__)
-#define _raw_spin_trylock(LOCK) \
- debug_spin_trylock(LOCK, __BASE_FILE__, __LINE__)
-#else
-static inline void _raw_spin_unlock(spinlock_t * lock)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_unlock_wait(x) \
+ do { cpu_relax(); } while ((x)->lock)
+
+static inline void __raw_spin_unlock(raw_spinlock_t * lock)
{
mb();
lock->lock = 0;
}
-static inline void _raw_spin_lock(spinlock_t * lock)
+static inline void __raw_spin_lock(raw_spinlock_t * lock)
{
long tmp;
@@ -70,80 +44,64 @@ static inline void _raw_spin_lock(spinlock_t * lock)
: "m"(lock->lock) : "memory");
}
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
return !test_and_set_bit(0, &lock->lock);
}
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
/***********************************************************/
-typedef struct {
- volatile unsigned int lock;
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t){ 0 }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-
-static inline int read_can_lock(rwlock_t *lock)
+static inline int __raw_read_can_lock(raw_rwlock_t *lock)
{
return (lock->lock & 1) == 0;
}
-static inline int write_can_lock(rwlock_t *lock)
+static inline int __raw_write_can_lock(raw_rwlock_t *lock)
{
return lock->lock == 0;
}
-#ifdef CONFIG_DEBUG_RWLOCK
-extern void _raw_write_lock(rwlock_t * lock);
-extern void _raw_read_lock(rwlock_t * lock);
-#else
-static inline void _raw_write_lock(rwlock_t * lock)
+static inline void __raw_read_lock(raw_rwlock_t *lock)
{
long regx;
__asm__ __volatile__(
"1: ldl_l %1,%0\n"
- " bne %1,6f\n"
- " lda %1,1\n"
+ " blbs %1,6f\n"
+ " subl %1,2,%1\n"
" stl_c %1,%0\n"
" beq %1,6f\n"
" mb\n"
".subsection 2\n"
"6: ldl %1,%0\n"
- " bne %1,6b\n"
+ " blbs %1,6b\n"
" br 1b\n"
".previous"
: "=m" (*lock), "=&r" (regx)
: "m" (*lock) : "memory");
}
-static inline void _raw_read_lock(rwlock_t * lock)
+static inline void __raw_write_lock(raw_rwlock_t *lock)
{
long regx;
__asm__ __volatile__(
"1: ldl_l %1,%0\n"
- " blbs %1,6f\n"
- " subl %1,2,%1\n"
+ " bne %1,6f\n"
+ " lda %1,1\n"
" stl_c %1,%0\n"
" beq %1,6f\n"
" mb\n"
".subsection 2\n"
"6: ldl %1,%0\n"
- " blbs %1,6b\n"
+ " bne %1,6b\n"
" br 1b\n"
".previous"
: "=m" (*lock), "=&r" (regx)
: "m" (*lock) : "memory");
}
-#endif /* CONFIG_DEBUG_RWLOCK */
-static inline int _raw_read_trylock(rwlock_t * lock)
+static inline int __raw_read_trylock(raw_rwlock_t * lock)
{
long regx;
int success;
@@ -165,7 +123,7 @@ static inline int _raw_read_trylock(rwlock_t * lock)
return success;
}
-static inline int _raw_write_trylock(rwlock_t * lock)
+static inline int __raw_write_trylock(raw_rwlock_t * lock)
{
long regx;
int success;
@@ -187,13 +145,7 @@ static inline int _raw_write_trylock(rwlock_t * lock)
return success;
}
-static inline void _raw_write_unlock(rwlock_t * lock)
-{
- mb();
- lock->lock = 0;
-}
-
-static inline void _raw_read_unlock(rwlock_t * lock)
+static inline void __raw_read_unlock(raw_rwlock_t * lock)
{
long regx;
__asm__ __volatile__(
@@ -209,4 +161,10 @@ static inline void _raw_read_unlock(rwlock_t * lock)
: "m" (*lock) : "memory");
}
+static inline void __raw_write_unlock(raw_rwlock_t * lock)
+{
+ mb();
+ lock->lock = 0;
+}
+
#endif /* _ALPHA_SPINLOCK_H */
diff --git a/include/asm-alpha/spinlock_types.h b/include/asm-alpha/spinlock_types.h
new file mode 100644
index 000000000000..8141eb5ebf0d
--- /dev/null
+++ b/include/asm-alpha/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef _ALPHA_SPINLOCK_TYPES_H
+#define _ALPHA_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index bdb4d66418f1..050e86d12891 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -4,6 +4,7 @@
#include <linux/config.h>
#include <asm/pal.h>
#include <asm/page.h>
+#include <asm/barrier.h>
/*
* System defines.. Note that this is included both from .c and .S
@@ -139,36 +140,6 @@ extern void halt(void) __attribute__((noreturn));
struct task_struct;
extern struct task_struct *alpha_switch_to(unsigned long, struct task_struct*);
-#define mb() \
-__asm__ __volatile__("mb": : :"memory")
-
-#define rmb() \
-__asm__ __volatile__("mb": : :"memory")
-
-#define wmb() \
-__asm__ __volatile__("wmb": : :"memory")
-
-#define read_barrier_depends() \
-__asm__ __volatile__("mb": : :"memory")
-
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_read_barrier_depends() read_barrier_depends()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_read_barrier_depends() barrier()
-#endif
-
-#define set_mb(var, value) \
-do { var = value; mb(); } while (0)
-
-#define set_wmb(var, value) \
-do { var = value; wmb(); } while (0)
-
#define imb() \
__asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory")
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
index 0e9b7e18af05..002227924b9f 100644
--- a/include/asm-arm/arch-aaec2000/aaec2000.h
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -17,6 +17,16 @@
#error You must include hardware.h not this file
#endif /* __ASM_ARCH_HARDWARE_H */
+/* Chip selects */
+#define AAEC_CS0 0x00000000
+#define AAEC_CS1 0x10000000
+#define AAEC_CS2 0x20000000
+#define AAEC_CS3 0x30000000
+
+/* Flash */
+#define AAEC_FLASH_BASE AAEC_CS0
+#define AAEC_FLASH_SIZE SZ_64M
+
/* Interrupt controller */
#define IRQ_BASE __REG(0x80000500)
#define IRQ_INTSR __REG(0x80000500) /* Int Status Register */
@@ -148,4 +158,50 @@
#define POWER_STFCLR __REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */
#define POWER_CLKSET __REG(0x80000420) /* Clock Speed Control */
+/* GPIO Registers */
+#define AAEC_GPIO_PHYS 0x80000e00
+
+#define AAEC_GPIO_PADR __REG(AAEC_GPIO_PHYS + 0x00)
+#define AAEC_GPIO_PBDR __REG(AAEC_GPIO_PHYS + 0x04)
+#define AAEC_GPIO_PCDR __REG(AAEC_GPIO_PHYS + 0x08)
+#define AAEC_GPIO_PDDR __REG(AAEC_GPIO_PHYS + 0x0c)
+#define AAEC_GPIO_PADDR __REG(AAEC_GPIO_PHYS + 0x10)
+#define AAEC_GPIO_PBDDR __REG(AAEC_GPIO_PHYS + 0x14)
+#define AAEC_GPIO_PCDDR __REG(AAEC_GPIO_PHYS + 0x18)
+#define AAEC_GPIO_PDDDR __REG(AAEC_GPIO_PHYS + 0x1c)
+#define AAEC_GPIO_PEDR __REG(AAEC_GPIO_PHYS + 0x20)
+#define AAEC_GPIO_PEDDR __REG(AAEC_GPIO_PHYS + 0x24)
+#define AAEC_GPIO_KSCAN __REG(AAEC_GPIO_PHYS + 0x28)
+#define AAEC_GPIO_PINMUX __REG(AAEC_GPIO_PHYS + 0x2c)
+#define AAEC_GPIO_PFDR __REG(AAEC_GPIO_PHYS + 0x30)
+#define AAEC_GPIO_PFDDR __REG(AAEC_GPIO_PHYS + 0x34)
+#define AAEC_GPIO_PGDR __REG(AAEC_GPIO_PHYS + 0x38)
+#define AAEC_GPIO_PGDDR __REG(AAEC_GPIO_PHYS + 0x3c)
+#define AAEC_GPIO_PHDR __REG(AAEC_GPIO_PHYS + 0x40)
+#define AAEC_GPIO_PHDDR __REG(AAEC_GPIO_PHYS + 0x44)
+#define AAEC_GPIO_RAZ __REG(AAEC_GPIO_PHYS + 0x48)
+#define AAEC_GPIO_INTTYPE1 __REG(AAEC_GPIO_PHYS + 0x4c)
+#define AAEC_GPIO_INTTYPE2 __REG(AAEC_GPIO_PHYS + 0x50)
+#define AAEC_GPIO_FEOI __REG(AAEC_GPIO_PHYS + 0x54)
+#define AAEC_GPIO_INTEN __REG(AAEC_GPIO_PHYS + 0x58)
+#define AAEC_GPIO_INTSTATUS __REG(AAEC_GPIO_PHYS + 0x5c)
+#define AAEC_GPIO_RAWINTSTATUS __REG(AAEC_GPIO_PHYS + 0x60)
+#define AAEC_GPIO_DB __REG(AAEC_GPIO_PHYS + 0x64)
+#define AAEC_GPIO_PAPINDR __REG(AAEC_GPIO_PHYS + 0x68)
+#define AAEC_GPIO_PBPINDR __REG(AAEC_GPIO_PHYS + 0x6c)
+#define AAEC_GPIO_PCPINDR __REG(AAEC_GPIO_PHYS + 0x70)
+#define AAEC_GPIO_PDPINDR __REG(AAEC_GPIO_PHYS + 0x74)
+#define AAEC_GPIO_PEPINDR __REG(AAEC_GPIO_PHYS + 0x78)
+#define AAEC_GPIO_PFPINDR __REG(AAEC_GPIO_PHYS + 0x7c)
+#define AAEC_GPIO_PGPINDR __REG(AAEC_GPIO_PHYS + 0x80)
+#define AAEC_GPIO_PHPINDR __REG(AAEC_GPIO_PHYS + 0x84)
+
+#define AAEC_GPIO_PINMUX_PE0CON (1 << 0)
+#define AAEC_GPIO_PINMUX_PD0CON (1 << 1)
+#define AAEC_GPIO_PINMUX_CODECON (1 << 2)
+#define AAEC_GPIO_PINMUX_UART3CON (1 << 3)
+
+/* LCD Controller */
+#define AAEC_CLCD_PHYS 0x80003000
+
#endif /* __ARM_ARCH_AAEC2000_H */
diff --git a/include/asm-arm/arch-aaec2000/aaed2000.h b/include/asm-arm/arch-aaec2000/aaed2000.h
new file mode 100644
index 000000000000..bc76d2badb91
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/aaed2000.h
@@ -0,0 +1,40 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/aaed2000.h
+ *
+ * AAED-2000 specific bits definition
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_AAED2000_H
+#define __ASM_ARCH_AAED2000_H
+
+/* External GPIOs. */
+
+#define EXT_GPIO_PBASE AAEC_CS3
+#define EXT_GPIO_VBASE 0xf8100000
+#define EXT_GPIO_LENGTH 0x00001000
+
+#define __ext_gpio_p2v(x) ((x) - EXT_GPIO_PBASE + EXT_GPIO_VBASE)
+#define __ext_gpio_v2p(x) ((x) + EXT_GPIO_PBASE - EXT_GPIO_VBASE)
+
+#define __EXT_GPIO_REG(x) (*((volatile u32 *)__ext_gpio_p2v(x)))
+#define __EXT_GPIO_PREG(x) (__ext_gpio_v2p((u32)&(x)))
+
+#define AAED_EXT_GPIO __EXT_GPIO_REG(EXT_GPIO_PBASE)
+
+#define AAED_EGPIO_KBD_SCAN 0x00003fff /* Keyboard scan data */
+#define AAED_EGPIO_PWR_INT 0x00008fff /* Smart battery charger interrupt */
+#define AAED_EGPIO_SWITCHED 0x000f0000 /* DIP Switches */
+#define AAED_EGPIO_USB_VBUS 0x00400000 /* USB Vbus sense */
+#define AAED_EGPIO_LCD_PWR_EN 0x02000000 /* LCD and backlight PWR enable */
+#define AAED_EGPIO_nLED0 0x20000000 /* LED 0 */
+#define AAED_EGPIO_nLED1 0x20000000 /* LED 1 */
+#define AAED_EGPIO_nLED2 0x20000000 /* LED 2 */
+
+
+#endif /* __ARM_ARCH_AAED2000_H */
diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h
index 4c37219e030e..153506fd06ed 100644
--- a/include/asm-arm/arch-aaec2000/hardware.h
+++ b/include/asm-arm/arch-aaec2000/hardware.h
@@ -11,7 +11,8 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
-#include <linux/config.h>
+#include <asm/sizes.h>
+#include <asm/arch/aaec2000.h>
/* The kernel is loaded at physical address 0xf8000000.
* We map the IO space a bit after
diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
index c58a8d10425a..8d67907fd4f0 100644
--- a/include/asm-arm/arch-aaec2000/io.h
+++ b/include/asm-arm/arch-aaec2000/io.h
@@ -6,6 +6,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
index 681b6a6171a1..79c90813bc3e 100644
--- a/include/asm-arm/arch-aaec2000/memory.h
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -64,10 +64,6 @@
#define NODE_MAX_MEM_SHIFT 26
#define NODE_MAX_MEM_SIZE (1 << NODE_MAX_MEM_SHIFT)
-#else
-
-#define PFN_TO_NID(addr) (0)
-
#endif /* CONFIG_DISCONTIGMEM */
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/include/asm-arm/arch-cl7500/io.h b/include/asm-arm/arch-cl7500/io.h
index f0113bc75630..89a33287f4fe 100644
--- a/include/asm-arm/arch-cl7500/io.h
+++ b/include/asm-arm/arch-cl7500/io.h
@@ -10,6 +10,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-clps711x/hardware.h b/include/asm-arm/arch-clps711x/hardware.h
index 1386871e1a5a..f864c367c934 100644
--- a/include/asm-arm/arch-clps711x/hardware.h
+++ b/include/asm-arm/arch-clps711x/hardware.h
@@ -235,4 +235,121 @@
#define CEIVA_PB0_BLK_BTN (1<<0)
#endif // #if defined (CONFIG_ARCH_CEIVA)
+#if defined (CONFIG_MACH_MP1000)
+/* NOR FLASH */
+#define MP1000_NIO_BASE 0xf9000000 /* virtual */
+#define MP1000_NIO_START CS0_PHYS_BASE /* physical */
+#define MP1000_NIO_SIZE 0x00400000
+
+/* DSP Interface */
+#define MP1000_DSP_BASE 0xfa000000 /* virtual */
+#define MP1000_DSP_START CS1_PHYS_BASE /* physical */
+#define MP1000_DSP_SIZE 0x00100000
+
+/* LCD, DAA/DSP, RTC, DAA RW Reg all in CS2 */
+#define MP1000_LIO_BASE 0xfb000000 /* virtual */
+#define MP1000_LIO_START CS2_PHYS_BASE /* physical */
+#define MP1000_LIO_SIZE 0x00100000
+
+/* NAND FLASH */
+#define MP1000_FIO_BASE 0xfc000000 /* virtual */
+#define MP1000_FIO_START CS3_PHYS_BASE /* physical */
+#define MP1000_FIO_SIZE 0x00800000
+
+/* Ethernet */
+#define MP1000_EIO_BASE 0xfd000000 /* virtual */
+#define MP1000_EIO_START CS4_PHYS_BASE /* physical */
+#define MP1000_EIO_SIZE 0x00100000
+
+#define MP1000_LCD_OFFSET 0x00000000 /* LCD offset in CS2 */
+#define MP1000_DDD_OFFSET 0x00001000 /* DAA/DAI/DSP sft reset offst*/
+#define MP1000_RTC_OFFSET 0x00002000 /* RTC offset in CS2 */
+#define MP1000_DAA_OFFSET 0x00003000 /* DAA RW reg offset in CS2 */
+
+/* IDE */
+#define MP1000_IDE_BASE 0xfe000000 /* virtual */
+#define MP1000_IDE_START CS5_PHYS_BASE /* physical */
+#define MP1000_IDE_SIZE 0x00100000 /* actually it's only 0x1000 */
+
+#define IRQ_HARDDISK IRQ_EINT2
+
+/*
+ * IDE registers definition
+ */
+
+#define IDE_CONTROL_BASE (MP1000_IDE_BASE + 0x1000)
+#define IDE_BASE_OFF (MP1000_IDE_BASE)
+
+#define IDE_WRITE_DEVICE_DATA (IDE_BASE_OFF + 0x0)
+#define IDE_FEATURES_REGISTER (IDE_BASE_OFF + 0x2)
+#define IDE_SECTOR_COUNT_REGISTER (IDE_BASE_OFF + 0x4)
+#define IDE_SECTOR_NUMBER_REGISTER (IDE_BASE_OFF + 0x6)
+#define IDE_CYLINDER_LOW_REGISTER (IDE_BASE_OFF + 0x8)
+#define IDE_CYLINDER_HIGH_REGISTER (IDE_BASE_OFF + 0xa)
+#define IDE_DEVICE_HEAD_REGISTER (IDE_BASE_OFF + 0xc)
+#define IDE_COMMAND_DATA_REGISTER (IDE_BASE_OFF + 0xe)
+#define IDE_DEVICE_CONTROL_REGISTER (IDE_CONTROL_BASE + 0xc)
+
+#define IDE_IRQ IRQ_EINT2
+
+
+#define RTC_PORT(x) (MP1000_LIO_BASE+0x2000 + (x*2))
+#define RTC_ALWAYS_BCD 0
+
+/*
+// Definitions of the bit fields in the HwPortA register for the
+// MP1000 board.
+*/
+#define HwPortAKeyboardRow1 0x00000001
+#define HwPortAKeyboardRow2 0x00000002
+#define HwPortAKeyboardRow3 0x00000004
+#define HwPortAKeyboardRow4 0x00000008
+#define HwPortAKeyboardRow5 0x00000010
+#define HwPortAKeyboardRow6 0x00000020
+#define HwPortALCDEnable 0x00000040
+#define HwPortAOffhook 0x00000080
+
+/*
+// Definitions of the bit fields in the HwPortB register for the
+// MP1000 board.
+*/
+#define HwPortBL3Mode 0x00000001
+#define HwPortBL3Clk 0x00000002
+#define HwPortBSClk 0x00000001
+#define HwPortBSData 0x00000002
+#define HwPortBL3Data 0x00000004
+#define HwPortBMute 0x00000008
+#define HwPortBQD0 0x00000010
+#define HwPortBQD1 0x00000020
+#define HwPortBQD2 0x00000040
+#define HwPortBQD3 0x00000080
+
+/*
+// Definitions of the bit fields in the HwPortD register for the
+// MP1000 board.
+*/
+#define HwPortDLED1 0x00000001
+#define HwPortDLED2 0x00000002
+#define HwPortDLED3 0x00000004
+#define HwPortDLED4 0x00000008
+#define HwPortDLED5 0x00000010
+#define HwPortDEECS 0x00000020
+#define HwPortBRTS 0x00000040
+#define HwPortBRI 0x00000080
+
+
+/*
+// Definitions of the bit fields in the HwPortE register for the
+// MP1000 board.
+*/
+
+#define HwPortECLE 0x00000001
+#define HwPortESepromDOut 0x00000001
+#define HwPortEALE 0x00000002
+#define HwPortESepromDIn 0x00000002
+#define HwPortENANDCS 0x00000004
+#define HwPortESepromCLK 0x00000004
+
+#endif // #if defined (CONFIG_MACH_MP1000)
+
#endif
diff --git a/include/asm-arm/arch-clps711x/io.h b/include/asm-arm/arch-clps711x/io.h
index 14d7e8da5453..62613b0e2d96 100644
--- a/include/asm-arm/arch-clps711x/io.h
+++ b/include/asm-arm/arch-clps711x/io.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(a))
diff --git a/include/asm-arm/arch-clps711x/mp1000-seprom.h b/include/asm-arm/arch-clps711x/mp1000-seprom.h
new file mode 100644
index 000000000000..3e5566cf9666
--- /dev/null
+++ b/include/asm-arm/arch-clps711x/mp1000-seprom.h
@@ -0,0 +1,77 @@
+#ifndef MP1000_SEPROM_H
+#define MP1000_SEPROM_H
+
+/*
+ * mp1000-seprom.h
+ *
+ *
+ * This file contains the Serial EEPROM definitions for the MP1000 board
+ *
+ * Copyright (C) 2005 Comdial Corporation
+ *
+ * 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 COMMAND_ERASE (0x1C0)
+#define COMMAND_ERASE_ALL (0x120)
+#define COMMAND_WRITE_DISABLE (0x100)
+#define COMMAND_WRITE_ENABLE (0x130)
+#define COMMAND_READ (0x180)
+#define COMMAND_WRITE (0x140)
+#define COMMAND_WRITE_ALL (0x110)
+
+//
+// Serial EEPROM data format
+//
+
+#define PACKED __attribute__ ((packed))
+
+typedef struct _EEPROM {
+ union {
+ unsigned char eprom_byte_data[128];
+ unsigned short eprom_short_data[64];
+ struct {
+ unsigned char version PACKED; // EEPROM Version "1" for now
+ unsigned char box_id PACKED; // Box ID (Standalone, SOHO, embedded, etc)
+ unsigned char major_hw_version PACKED; // Major Hardware version (Hex)
+ unsigned char minor_hw_version PACKED; // Minor Hardware Version (Hex)
+ unsigned char mfg_id[3] PACKED; // Manufacturer ID (3 character Alphabetic)
+ unsigned char mfg_serial_number[10] PACKED; // Manufacturer Serial number
+ unsigned char mfg_date[3] PACKED; // Date of Mfg (Formatted YY:MM:DD)
+ unsigned char country PACKED; // Country of deployment
+ unsigned char mac_Address[6] PACKED; // MAC Address
+ unsigned char oem_string[20] PACKED; // OEM ID string
+ unsigned short feature_bits1 PACKED; // Feature Bits 1
+ unsigned short feature_bits2 PACKED; // Feature Bits 2
+ unsigned char filler[75] PACKED; // Unused/Undefined “0” initialized
+ unsigned short checksum PACKED; // byte accumulated short checksum
+ } eprom_struct;
+ } variant;
+} eeprom_struct;
+
+/* These settings must be mutually exclusive */
+#define FEATURE_BITS1_DRAMSIZE_16MEG 0x0001 /* 0 signifies 4 MEG system */
+#define FEATURE_BITS1_DRAMSIZE_8MEG 0x0002 /* 1 in bit 1 = 8MEG system */
+#define FEATURE_BITS1_DRAMSIZE_64MEG 0x0004 /* 1 in bit 2 = 64MEG system */
+
+#define FEATURE_BITS1_CPUIS90MEG 0x0010
+
+extern void seprom_init(void);
+extern eeprom_struct* get_seprom_ptr(void);
+extern unsigned char* get_eeprom_mac_address(void);
+
+#endif /* MP1000_SEPROM_H */
+
diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h
index 70576b17f922..776f9d377057 100644
--- a/include/asm-arm/arch-ebsa285/io.h
+++ b/include/asm-arm/arch-ebsa285/io.h
@@ -14,6 +14,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffff
/*
diff --git a/include/asm-arm/arch-epxa10db/io.h b/include/asm-arm/arch-epxa10db/io.h
index 1f0afa257621..9fe100c9d6be 100644
--- a/include/asm-arm/arch-epxa10db/io.h
+++ b/include/asm-arm/arch-epxa10db/io.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffff
diff --git a/include/asm-arm/arch-h720x/io.h b/include/asm-arm/arch-h720x/io.h
index 68814828c9a7..d3ccfd8172b7 100644
--- a/include/asm-arm/arch-h720x/io.h
+++ b/include/asm-arm/arch-h720x/io.h
@@ -14,7 +14,7 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#include <asm/arch/hardware.h>
+#include <asm/hardware.h>
#define IO_SPACE_LIMIT 0xffffffff
diff --git a/include/asm-arm/arch-h720x/system.h b/include/asm-arm/arch-h720x/system.h
index 0b025e227ec2..09eda84592ff 100644
--- a/include/asm-arm/arch-h720x/system.h
+++ b/include/asm-arm/arch-h720x/system.h
@@ -17,9 +17,11 @@
static void arch_idle(void)
{
CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
- __asm__ __volatile__(
- "mov r0, r0\n\t"
- "mov r0, r0");
+ nop();
+ nop();
+ CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
+ nop();
+ nop();
}
diff --git a/include/asm-arm/arch-imx/imx-regs.h b/include/asm-arm/arch-imx/imx-regs.h
index 93b840e8fa60..a6912b3d8671 100644
--- a/include/asm-arm/arch-imx/imx-regs.h
+++ b/include/asm-arm/arch-imx/imx-regs.h
@@ -76,6 +76,7 @@
#define GPIO_PIN_MASK 0x1f
#define GPIO_PORT_MASK (0x3 << 5)
+#define GPIO_PORT_SHIFT 5
#define GPIO_PORTA (0<<5)
#define GPIO_PORTB (1<<5)
#define GPIO_PORTC (2<<5)
@@ -88,24 +89,37 @@
#define GPIO_PF (0<<9)
#define GPIO_AF (1<<9)
+#define GPIO_OCR_SHIFT 10
#define GPIO_OCR_MASK (3<<10)
#define GPIO_AIN (0<<10)
#define GPIO_BIN (1<<10)
#define GPIO_CIN (2<<10)
-#define GPIO_GPIO (3<<10)
+#define GPIO_DR (3<<10)
-#define GPIO_AOUT (1<<12)
-#define GPIO_BOUT (1<<13)
+#define GPIO_AOUT_SHIFT 12
+#define GPIO_AOUT_MASK (3<<12)
+#define GPIO_AOUT (0<<12)
+#define GPIO_AOUT_ISR (1<<12)
+#define GPIO_AOUT_0 (2<<12)
+#define GPIO_AOUT_1 (3<<12)
+
+#define GPIO_BOUT_SHIFT 14
+#define GPIO_BOUT_MASK (3<<14)
+#define GPIO_BOUT (0<<14)
+#define GPIO_BOUT_ISR (1<<14)
+#define GPIO_BOUT_0 (2<<14)
+#define GPIO_BOUT_1 (3<<14)
+
+#define GPIO_GIUS (1<<16)
/* assignements for GPIO alternate/primary functions */
/* FIXME: This list is not completed. The correct directions are
* missing on some (many) pins
*/
-#define PA0_PF_A24 ( GPIO_PORTA | GPIO_PF | 0 )
-#define PA0_AIN_SPI2_CLK ( GPIO_PORTA | GPIO_OUT | GPIO_AIN | 0 )
+#define PA0_AIN_SPI2_CLK ( GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 0 )
#define PA0_AF_ETMTRACESYNC ( GPIO_PORTA | GPIO_AF | 0 )
-#define PA1_AOUT_SPI2_RXD ( GPIO_PORTA | GPIO_IN | GPIO_AOUT | 1 )
+#define PA1_AOUT_SPI2_RXD ( GPIO_GIUS | GPIO_PORTA | GPIO_IN | 1 )
#define PA1_PF_TIN ( GPIO_PORTA | GPIO_PF | 1 )
#define PA2_PF_PWM0 ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 2 )
#define PA3_PF_CSI_MCLK ( GPIO_PORTA | GPIO_PF | 3 )
@@ -123,7 +137,7 @@
#define PA15_PF_I2C_SDA ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 15 )
#define PA16_PF_I2C_SCL ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 16 )
#define PA17_AF_ETMTRACEPKT4 ( GPIO_PORTA | GPIO_AF | 17 )
-#define PA17_AIN_SPI2_SS ( GPIO_PORTA | GPIO_AIN | 17 )
+#define PA17_AIN_SPI2_SS ( GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 17 )
#define PA18_AF_ETMTRACEPKT5 ( GPIO_PORTA | GPIO_AF | 18 )
#define PA19_AF_ETMTRACEPKT6 ( GPIO_PORTA | GPIO_AF | 19 )
#define PA20_AF_ETMTRACEPKT7 ( GPIO_PORTA | GPIO_AF | 20 )
@@ -191,19 +205,27 @@
#define PC15_PF_SPI1_SS ( GPIO_PORTC | GPIO_PF | 15 )
#define PC16_PF_SPI1_MISO ( GPIO_PORTC | GPIO_PF | 16 )
#define PC17_PF_SPI1_MOSI ( GPIO_PORTC | GPIO_PF | 17 )
+#define PC24_BIN_UART3_RI ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24 )
+#define PC25_BIN_UART3_DSR ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25 )
+#define PC26_AOUT_UART3_DTR ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 26 )
+#define PC27_BIN_UART3_DCD ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27 )
+#define PC28_BIN_UART3_CTS ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28 )
+#define PC29_AOUT_UART3_RTS ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 29 )
+#define PC30_BIN_UART3_TX ( GPIO_GIUS | GPIO_PORTC | GPIO_BIN | 30 )
+#define PC31_AOUT_UART3_RX ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 31)
#define PD6_PF_LSCLK ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 6 )
#define PD7_PF_REV ( GPIO_PORTD | GPIO_PF | 7 )
-#define PD7_AF_UART2_DTR ( GPIO_PORTD | GPIO_IN | GPIO_AF | 7 )
-#define PD7_AIN_SPI2_SCLK ( GPIO_PORTD | GPIO_AIN | 7 )
+#define PD7_AF_UART2_DTR ( GPIO_GIUS | GPIO_PORTD | GPIO_IN | GPIO_AF | 7 )
+#define PD7_AIN_SPI2_SCLK ( GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 7 )
#define PD8_PF_CLS ( GPIO_PORTD | GPIO_PF | 8 )
#define PD8_AF_UART2_DCD ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 8 )
-#define PD8_AIN_SPI2_SS ( GPIO_PORTD | GPIO_AIN | 8 )
+#define PD8_AIN_SPI2_SS ( GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 8 )
#define PD9_PF_PS ( GPIO_PORTD | GPIO_PF | 9 )
#define PD9_AF_UART2_RI ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 9 )
-#define PD9_AOUT_SPI2_RXD ( GPIO_PORTD | GPIO_IN | GPIO_AOUT | 9 )
+#define PD9_AOUT_SPI2_RXD ( GPIO_GIUS | GPIO_PORTD | GPIO_IN | 9 )
#define PD10_PF_SPL_SPR ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 10 )
#define PD10_AF_UART2_DSR ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 10 )
-#define PD10_AIN_SPI2_TXD ( GPIO_PORTD | GPIO_OUT | GPIO_AIN | 10 )
+#define PD10_AIN_SPI2_TXD ( GPIO_GIUS | GPIO_PORTD | GPIO_OUT | 10 )
#define PD11_PF_CONTRAST ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 11 )
#define PD12_PF_ACD_OE ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 12 )
#define PD13_PF_LP_HSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 13 )
@@ -225,7 +247,7 @@
#define PD29_PF_LD14 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 29 )
#define PD30_PF_LD15 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 30 )
#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 )
-#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 )
+#define PD31_BIN_SPI2_TXD ( GPIO_GIUS | GPIO_PORTD | GPIO_BIN | 31 )
/*
* PWM controller
diff --git a/include/asm-arm/arch-imx/io.h b/include/asm-arm/arch-imx/io.h
index 28a4cca6a4cb..b191cdd05576 100644
--- a/include/asm-arm/arch-imx/io.h
+++ b/include/asm-arm/arch-imx/io.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(a))
diff --git a/include/asm-arm/arch-integrator/hardware.h b/include/asm-arm/arch-integrator/hardware.h
index be2716eeaa02..6f0947bc500d 100644
--- a/include/asm-arm/arch-integrator/hardware.h
+++ b/include/asm-arm/arch-integrator/hardware.h
@@ -33,15 +33,6 @@
#define IO_SIZE 0x0B000000 // How much?
#define IO_START INTEGRATOR_HDR_BASE // PA of IO
-/*
- * Similar to above, but for PCI addresses (memory, IO, Config and the
- * V3 chip itself). WARNING: this has to mirror definitions in platform.h
- */
-#define PCI_MEMORY_VADDR 0xe8000000
-#define PCI_CONFIG_VADDR 0xec000000
-#define PCI_V3_VADDR 0xed000000
-#define PCI_IO_VADDR 0xee000000
-
#define PCIO_BASE PCI_IO_VADDR
#define PCIMEM_BASE PCI_MEMORY_VADDR
diff --git a/include/asm-arm/arch-integrator/io.h b/include/asm-arm/arch-integrator/io.h
index fbea8be67d26..31f2deab51b0 100644
--- a/include/asm-arm/arch-integrator/io.h
+++ b/include/asm-arm/arch-integrator/io.h
@@ -22,6 +22,14 @@
#define IO_SPACE_LIMIT 0xffff
+/*
+ * WARNING: this has to mirror definitions in platform.h
+ */
+#define PCI_MEMORY_VADDR 0xe8000000
+#define PCI_CONFIG_VADDR 0xec000000
+#define PCI_V3_VADDR 0xed000000
+#define PCI_IO_VADDR 0xee000000
+
#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
#define __mem_pci(a) (a)
#define __mem_isa(a) ((a) + PCI_MEMORY_VADDR)
diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop3xx/io.h
index 2761dfd8694d..f39046a6ab14 100644
--- a/include/asm-arm/arch-iop3xx/io.h
+++ b/include/asm-arm/arch-iop3xx/io.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem *)(p))
diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h
index dc4735cb0c10..45351f5cd904 100644
--- a/include/asm-arm/arch-iop3xx/memory.h
+++ b/include/asm-arm/arch-iop3xx/memory.h
@@ -36,6 +36,4 @@
#endif
-#define PFN_TO_NID(addr) (0)
-
#endif
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index 3241cd6f0778..7fbcdf9931ee 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -15,6 +15,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __mem_pci(a) (a)
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index 75623f81ef75..def089d693d2 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -370,8 +370,6 @@
#define GLOBAL_REG_BASE (IXP2000_GLOBAL_REG_VIRT_BASE + 0x0a00)
#define GLOBAL_REG(x) (volatile unsigned long*)(GLOBAL_REG_BASE | (x))
-#define IXP2000_PROD_ID GLOBAL_REG(0x00)
-
#define IXP2000_MAJ_PROD_TYPE_MASK 0x001F0000
#define IXP2000_MAJ_PROD_TYPE_IXP2000 0x00000000
#define IXP2000_MIN_PROD_TYPE_MASK 0x0000FF00
@@ -394,4 +392,47 @@
#define WDT_RESET_ENABLE 0x01000000
+/*
+ * MSF registers. The IXP2400 and IXP2800 have somewhat different MSF
+ * units, but the registers that differ between the two don't overlap,
+ * so we can have one register list for both.
+ */
+#define IXP2000_MSF_REG(x) ((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x)))
+#define IXP2000_MSF_RX_CONTROL IXP2000_MSF_REG(0x0000)
+#define IXP2000_MSF_TX_CONTROL IXP2000_MSF_REG(0x0004)
+#define IXP2000_MSF_INTERRUPT_STATUS IXP2000_MSF_REG(0x0008)
+#define IXP2000_MSF_INTERRUPT_ENABLE IXP2000_MSF_REG(0x000c)
+#define IXP2000_MSF_CSIX_TYPE_MAP IXP2000_MSF_REG(0x0010)
+#define IXP2000_MSF_FC_EGRESS_STATUS IXP2000_MSF_REG(0x0014)
+#define IXP2000_MSF_FC_INGRESS_STATUS IXP2000_MSF_REG(0x0018)
+#define IXP2000_MSF_HWM_CONTROL IXP2000_MSF_REG(0x0024)
+#define IXP2000_MSF_FC_STATUS_OVERRIDE IXP2000_MSF_REG(0x0028)
+#define IXP2000_MSF_CLOCK_CONTROL IXP2000_MSF_REG(0x002c)
+#define IXP2000_MSF_RX_PORT_MAP IXP2000_MSF_REG(0x0040)
+#define IXP2000_MSF_RBUF_ELEMENT_DONE IXP2000_MSF_REG(0x0044)
+#define IXP2000_MSF_RX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0048)
+#define IXP2000_MSF_RX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0048)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0 IXP2000_MSF_REG(0x0050)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1 IXP2000_MSF_REG(0x0054)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2 IXP2000_MSF_REG(0x0058)
+#define IXP2000_MSF_TX_SEQUENCE_0 IXP2000_MSF_REG(0x0060)
+#define IXP2000_MSF_TX_SEQUENCE_1 IXP2000_MSF_REG(0x0064)
+#define IXP2000_MSF_TX_SEQUENCE_2 IXP2000_MSF_REG(0x0068)
+#define IXP2000_MSF_TX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0070)
+#define IXP2000_MSF_TX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0070)
+#define IXP2000_MSF_RX_UP_CONTROL_0 IXP2000_MSF_REG(0x0080)
+#define IXP2000_MSF_RX_UP_CONTROL_1 IXP2000_MSF_REG(0x0084)
+#define IXP2000_MSF_RX_UP_CONTROL_2 IXP2000_MSF_REG(0x0088)
+#define IXP2000_MSF_RX_UP_CONTROL_3 IXP2000_MSF_REG(0x008c)
+#define IXP2000_MSF_TX_UP_CONTROL_0 IXP2000_MSF_REG(0x0090)
+#define IXP2000_MSF_TX_UP_CONTROL_1 IXP2000_MSF_REG(0x0094)
+#define IXP2000_MSF_TX_UP_CONTROL_2 IXP2000_MSF_REG(0x0098)
+#define IXP2000_MSF_TX_UP_CONTROL_3 IXP2000_MSF_REG(0x009c)
+#define IXP2000_MSF_TRAIN_DATA IXP2000_MSF_REG(0x00a0)
+#define IXP2000_MSF_TRAIN_CALENDAR IXP2000_MSF_REG(0x00a4)
+#define IXP2000_MSF_TRAIN_FLOW_CONTROL IXP2000_MSF_REG(0x00a8)
+#define IXP2000_MSF_TX_CALENDAR_0 IXP2000_MSF_REG(0x1000)
+#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS IXP2000_MSF_REG(0x1400)
+
+
#endif /* _IXP2000_H_ */
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h
index c0caf3e3e6fd..abdcf51bd283 100644
--- a/include/asm-arm/arch-ixp2000/platform.h
+++ b/include/asm-arm/arch-ixp2000/platform.h
@@ -31,20 +31,24 @@
#include <asm/system.h> /* Pickup local_irq_ functions */
-static inline void ixp2000_reg_write(volatile unsigned long *reg, unsigned long val)
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
{
- volatile unsigned long dummy;
+ unsigned long dummy;
unsigned long flags;
local_irq_save(flags);
- *reg = val;
+ *((volatile unsigned long *)reg) = val;
barrier();
- dummy = *reg;
+ dummy = *((volatile unsigned long *)reg);
local_irq_restore(flags);
}
#else
-#define ixp2000_reg_write(reg, val) (*reg = val)
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+{
+ *((volatile unsigned long *)reg) = val;
+}
#endif /* IXDP2400 || IXDP2401 */
+#define ixp2000_reg_read(reg) (*((volatile unsigned long *)reg))
/*
* Boards may multiplex different devices on the 2nd channel of
@@ -84,7 +88,7 @@ void ixp2000_release_slowport(struct slowport_cfg *);
*/
static inline unsigned ixp2000_has_broken_slowport(void)
{
- unsigned long id = *IXP2000_PROD_ID;
+ unsigned long id = *IXP2000_PRODUCT_ID;
unsigned long id_prod = id & (IXP2000_MAJ_PROD_TYPE_MASK |
IXP2000_MIN_PROD_TYPE_MASK);
return (((id_prod ==
diff --git a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S
index 455da64832de..323b0bc4a39c 100644
--- a/include/asm-arm/arch-ixp4xx/entry-macro.S
+++ b/include/asm-arm/arch-ixp4xx/entry-macro.S
@@ -15,25 +15,26 @@
ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
ldr \irqstat, [\irqstat] @ get interrupts
cmp \irqstat, #0
- beq 1001f
+ beq 1001f @ upper IRQ?
clz \irqnr, \irqstat
mov \base, #31
- subs \irqnr, \base, \irqnr
+ sub \irqnr, \base, \irqnr
+ b 1002f @ lower IRQ being
+ @ handled
1001:
/*
* IXP465 has an upper IRQ status register
*/
#if defined(CONFIG_CPU_IXP46X)
- bne 1002f
ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET)
ldr \irqstat, [\irqstat] @ get upper interrupts
mov \irqnr, #63
clz \irqstat, \irqstat
cmp \irqstat, #32
subne \irqnr, \irqnr, \irqstat
-1002:
#endif
+1002:
.endm
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 4ac964b9078a..55d85eea8c1a 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -27,7 +27,7 @@
#define pcibios_assign_all_busses() 1
-#if defined(CONFIG_CPU_IXP465) && !defined(__ASSEMBLY__)
+#if defined(CONFIG_CPU_IXP46X) && !defined(__ASSEMBLY__)
extern unsigned int processor_id;
#define cpu_is_ixp465() ((processor_id & 0xffffffc0) == 0x69054200)
#else
diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
index d13ee7f78c70..f14ed63590c3 100644
--- a/include/asm-arm/arch-ixp4xx/platform.h
+++ b/include/asm-arm/arch-ixp4xx/platform.h
@@ -93,7 +93,7 @@ extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
static inline void gpio_line_config(u8 line, u32 direction)
{
- if (direction == IXP4XX_GPIO_OUT)
+ if (direction == IXP4XX_GPIO_IN)
*IXP4XX_GPIO_GPOER |= (1 << line);
else
*IXP4XX_GPIO_GPOER &= ~(1 << line);
diff --git a/include/asm-arm/arch-l7200/io.h b/include/asm-arm/arch-l7200/io.h
index fc012a39e2cb..cab8ad0adf09 100644
--- a/include/asm-arm/arch-l7200/io.h
+++ b/include/asm-arm/arch-l7200/io.h
@@ -10,7 +10,7 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#include <asm/arch/hardware.h>
+#include <asm/hardware.h>
#define IO_SPACE_LIMIT 0xffffffff
diff --git a/include/asm-arm/arch-lh7a40x/io.h b/include/asm-arm/arch-lh7a40x/io.h
index c13bdd9add92..bbcd4335f441 100644
--- a/include/asm-arm/arch-lh7a40x/io.h
+++ b/include/asm-arm/arch-lh7a40x/io.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/* No ISA or PCI bus on this machine. */
diff --git a/include/asm-arm/arch-lh7a40x/memory.h b/include/asm-arm/arch-lh7a40x/memory.h
index 7e2fea372663..c650e6feb9d5 100644
--- a/include/asm-arm/arch-lh7a40x/memory.h
+++ b/include/asm-arm/arch-lh7a40x/memory.h
@@ -85,10 +85,6 @@
(((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT)
# endif
-#else
-
-# define PFN_TO_NID(addr) (0)
-
#endif
#endif
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index 11fbf629bf75..3d5bcd545082 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -34,6 +34,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h
index 84f81e315a25..ef32d61eec7a 100644
--- a/include/asm-arm/arch-omap/memory.h
+++ b/include/asm-arm/arch-omap/memory.h
@@ -86,6 +86,5 @@
#endif /* CONFIG_ARCH_OMAP1510 */
-#define PHYS_TO_NID(addr) (0)
#endif
diff --git a/include/asm-arm/arch-pxa/akita.h b/include/asm-arm/arch-pxa/akita.h
new file mode 100644
index 000000000000..4a1fbcfccc39
--- /dev/null
+++ b/include/asm-arm/arch-pxa/akita.h
@@ -0,0 +1,30 @@
+/*
+ * Hardware specific definitions for SL-C1000 (Akita)
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * 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.
+ *
+ */
+
+/* Akita IO Expander GPIOs */
+
+#define AKITA_IOEXP_RESERVED_7 (1 << 7)
+#define AKITA_IOEXP_IR_ON (1 << 6)
+#define AKITA_IOEXP_AKIN_PULLUP (1 << 5)
+#define AKITA_IOEXP_BACKLIGHT_CONT (1 << 4)
+#define AKITA_IOEXP_BACKLIGHT_ON (1 << 3)
+#define AKITA_IOEXP_MIC_BIAS (1 << 2)
+#define AKITA_IOEXP_RESERVED_1 (1 << 1)
+#define AKITA_IOEXP_RESERVED_0 (1 << 0)
+
+/* Direction Bitfield 0=output 1=input */
+#define AKITA_IOEXP_IO_DIR 0
+/* Default Values */
+#define AKITA_IOEXP_IO_OUT (AKITA_IOEXP_IR_ON | AKITA_IOEXP_AKIN_PULLUP)
+
+void akita_set_ioexp(struct device *dev, unsigned char bitmask);
+void akita_reset_ioexp(struct device *dev, unsigned char bitmask);
+
diff --git a/include/asm-arm/arch-pxa/corgi.h b/include/asm-arm/arch-pxa/corgi.h
index 4b7aa0b8391e..e554caa0d18b 100644
--- a/include/asm-arm/arch-pxa/corgi.h
+++ b/include/asm-arm/arch-pxa/corgi.h
@@ -106,17 +106,5 @@ extern struct platform_device corgiscoop_device;
extern struct platform_device corgissp_device;
extern struct platform_device corgifb_device;
-/*
- * External Functions
- */
-extern unsigned long corgi_ssp_ads7846_putget(unsigned long);
-extern unsigned long corgi_ssp_ads7846_get(void);
-extern void corgi_ssp_ads7846_put(unsigned long data);
-extern void corgi_ssp_ads7846_lock(void);
-extern void corgi_ssp_ads7846_unlock(void);
-extern void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data);
-extern void corgi_ssp_blduty_set(int duty);
-extern int corgi_ssp_max1111_get(unsigned long data);
-
#endif /* __ASM_ARCH_CORGI_H */
diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
index 72b04d846a23..3e70bd95472c 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
/* 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 u32 *)((u32)&__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 000000000000..46ec2243974a
--- /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/io.h b/include/asm-arm/arch-pxa/io.h
index c3bdbe44e21f..eb2dd58d397f 100644
--- a/include/asm-arm/arch-pxa/io.h
+++ b/include/asm-arm/arch-pxa/io.h
@@ -6,6 +6,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h
new file mode 100644
index 000000000000..748406f384c2
--- /dev/null
+++ b/include/asm-arm/arch-pxa/irda.h
@@ -0,0 +1,17 @@
+#ifndef ASMARM_ARCH_IRDA_H
+#define ASMARM_ARCH_IRDA_H
+
+/* board specific transceiver capabilities */
+
+#define IR_OFF 1
+#define IR_SIRMODE 2
+#define IR_FIRMODE 4
+
+struct pxaficp_platform_data {
+ int transceiver_cap;
+ void (*transceiver_mode)(struct device *dev, int mode);
+};
+
+extern void pxa_set_ficp_info(struct pxaficp_platform_data *info);
+
+#endif
diff --git a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
index 217a80b820ff..58bad9748b5c 100644
--- a/include/asm-arm/arch-pxa/memory.h
+++ b/include/asm-arm/arch-pxa/memory.h
@@ -67,10 +67,6 @@
#define LOCAL_MAP_NR(addr) \
(((unsigned long)(addr) & 0x03ffffff) >> PAGE_SHIFT)
-#else
-
-#define PFN_TO_NID(addr) (0)
-
#endif
#endif
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h
index 9718063a2119..88c17dd02ed2 100644
--- a/include/asm-arm/arch-pxa/mmc.h
+++ b/include/asm-arm/arch-pxa/mmc.h
@@ -9,6 +9,7 @@ struct mmc_host;
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/poodle.h b/include/asm-arm/arch-pxa/poodle.h
index 58bda9d571a5..6b5ac5144e70 100644
--- a/include/asm-arm/arch-pxa/poodle.h
+++ b/include/asm-arm/arch-pxa/poodle.h
@@ -37,24 +37,25 @@
#define POODLE_GPIO_nSD_DETECT (9)
#define POODLE_GPIO_MAIN_BAT_LOW (13)
#define POODLE_GPIO_BAT_COVER (13)
+#define POODLE_GPIO_USB_PULLUP (20)
#define POODLE_GPIO_ADC_TEMP_ON (21)
#define POODLE_GPIO_BYPASS_ON (36)
#define POODLE_GPIO_CHRG_ON (38)
#define POODLE_GPIO_CHRG_FULL (16)
/* PXA GPIOs */
-#define POODLE_IRQ_GPIO_ON_KEY IRQ_GPIO0
-#define POODLE_IRQ_GPIO_AC_IN IRQ_GPIO1
-#define POODLE_IRQ_GPIO_HP_IN IRQ_GPIO4
-#define POODLE_IRQ_GPIO_CO IRQ_GPIO16
-#define POODLE_IRQ_GPIO_TP_INT IRQ_GPIO5
-#define POODLE_IRQ_GPIO_WAKEUP IRQ_GPIO11
-#define POODLE_IRQ_GPIO_GA_INT IRQ_GPIO10
-#define POODLE_IRQ_GPIO_CF_IRQ IRQ_GPIO17
-#define POODLE_IRQ_GPIO_CF_CD IRQ_GPIO14
-#define POODLE_IRQ_GPIO_nSD_INT IRQ_GPIO8
-#define POODLE_IRQ_GPIO_nSD_DETECT IRQ_GPIO9
-#define POODLE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO13
+#define POODLE_IRQ_GPIO_ON_KEY IRQ_GPIO(0)
+#define POODLE_IRQ_GPIO_AC_IN IRQ_GPIO(1)
+#define POODLE_IRQ_GPIO_HP_IN IRQ_GPIO(4)
+#define POODLE_IRQ_GPIO_CO IRQ_GPIO(16)
+#define POODLE_IRQ_GPIO_TP_INT IRQ_GPIO(5)
+#define POODLE_IRQ_GPIO_WAKEUP IRQ_GPIO(11)
+#define POODLE_IRQ_GPIO_GA_INT IRQ_GPIO(10)
+#define POODLE_IRQ_GPIO_CF_IRQ IRQ_GPIO(17)
+#define POODLE_IRQ_GPIO_CF_CD IRQ_GPIO(14)
+#define POODLE_IRQ_GPIO_nSD_INT IRQ_GPIO(8)
+#define POODLE_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9)
+#define POODLE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(13)
/* SCOOP GPIOs */
#define POODLE_SCOOP_CHARGE_ON SCOOP_GPCR_PA11
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 939d9e5020a0..a75a2470f4f5 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -126,8 +126,8 @@
#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
-#define DRCMR15 __REG(0x4000013c) /* Reserved */
-#define DRCMR16 __REG(0x40000140) /* Reserved */
+#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for SSP2 receive Request */
+#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for SSP2 transmit Request */
#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
@@ -151,7 +151,8 @@
#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */
#define DRCMR39 __REG(0x4000019C) /* Reserved */
-
+#define DRCMR66 __REG(0x40001108) /* Request to Channel Map Register for SSP3 receive Request */
+#define DRCMR67 __REG(0x4000110C) /* Request to Channel Map Register for SSP3 transmit Request */
#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */
#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */
#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */
@@ -325,6 +326,25 @@
#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+/* Hardware UART (HWUART) */
+#define HWUART HWRBR
+#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */
+#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */
+#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */
+#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */
+#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */
+#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */
+#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */
+#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */
+#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */
+#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */
+#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */
+#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */
+#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */
+#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */
+#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
#define IER_DMAE (1 << 7) /* DMA Requests Enable */
#define IER_UUE (1 << 6) /* UART Unit Enable */
#define IER_NRZE (1 << 5) /* NRZ coding Enable */
@@ -652,7 +672,7 @@
#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
-#define UDCCS_IO_ROF (1 << 3) /* Receive overflow */
+#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */
#define UDCCS_IO_DME (1 << 3) /* DMA enable */
#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
@@ -1012,14 +1032,12 @@
#define ICCR0_LBM (1 << 1) /* Loopback mode */
#define ICCR0_ITR (1 << 0) /* IrDA transmission */
-#ifdef CONFIG_PXA27x
#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */
#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */
#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */
#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */
#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */
#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */
-#endif
#ifdef CONFIG_PXA27x
#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */
@@ -1249,9 +1267,13 @@
#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */
#define GPIO41_FFRTS 41 /* FFUART request to send */
#define GPIO42_BTRXD 42 /* BTUART receive data */
+#define GPIO42_HWRXD 42 /* HWUART receive data */
#define GPIO43_BTTXD 43 /* BTUART transmit data */
+#define GPIO43_HWTXD 43 /* HWUART transmit data */
#define GPIO44_BTCTS 44 /* BTUART clear to send */
+#define GPIO44_HWCTS 44 /* HWUART clear to send */
#define GPIO45_BTRTS 45 /* BTUART request to send */
+#define GPIO45_HWRTS 45 /* HWUART request to send */
#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */
#define GPIO46_ICPRXD 46 /* ICP receive data */
#define GPIO46_STRXD 46 /* STD_UART receive data */
@@ -1377,17 +1399,26 @@
#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT)
#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT)
#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN)
+#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN)
#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT)
+#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT)
#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN)
+#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN)
#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT)
+#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT)
#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT)
#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN)
#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN)
#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT)
#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT)
#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT)
+#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT)
+#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT)
+#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN)
#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT)
#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT)
+#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN)
+#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT)
#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT)
#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT)
#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT)
@@ -1762,6 +1793,7 @@
#define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
#define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
#define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
+#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */
#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */
#define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
#define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */
@@ -2281,4 +2313,11 @@
#endif
+/* PWRMODE register M field values */
+
+#define PWRMODE_IDLE 0x1
+#define PWRMODE_STANDBY 0x2
+#define PWRMODE_SLEEP 0x3
+#define PWRMODE_DEEPSLEEP 0x7
+
#endif
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index 27d71e9d413b..aba9b30f4249 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -66,3 +66,5 @@ struct pxafb_mach_info {
};
void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
+void set_pxa_fb_parent(struct device *parent_dev);
+unsigned long pxafb_get_hsync_time(struct device *dev);
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
new file mode 100644
index 000000000000..311f2bb5386a
--- /dev/null
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -0,0 +1,32 @@
+/*
+ * SharpSL SSP Driver
+ */
+
+unsigned long corgi_ssp_ads7846_putget(unsigned long);
+unsigned long corgi_ssp_ads7846_get(void);
+void corgi_ssp_ads7846_put(unsigned long data);
+void corgi_ssp_ads7846_lock(void);
+void corgi_ssp_ads7846_unlock(void);
+void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data);
+void corgi_ssp_blduty_set(int duty);
+int corgi_ssp_max1111_get(unsigned long data);
+
+/*
+ * SharpSL Touchscreen Driver
+ */
+
+struct corgits_machinfo {
+ unsigned long (*get_hsync_len)(void);
+ void (*put_hsync)(void);
+ void (*wait_hsync)(void);
+};
+
+/*
+ * SharpSL Backlight
+ */
+
+struct corgibl_machinfo {
+ int max_intensity;
+ void (*set_bl_intensity)(int intensity);
+};
+
diff --git a/include/asm-arm/arch-pxa/spitz.h b/include/asm-arm/arch-pxa/spitz.h
new file mode 100644
index 000000000000..62e1fe4d025f
--- /dev/null
+++ b/include/asm-arm/arch-pxa/spitz.h
@@ -0,0 +1,158 @@
+/*
+ * Hardware specific definitions for SL-Cx000 series of PDAs
+ *
+ * Copyright (c) 2005 Alexander Wykes
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * 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 __ASM_ARCH_SPITZ_H
+#define __ASM_ARCH_SPITZ_H 1
+#endif
+
+/* Spitz/Akita GPIOs */
+
+#define SPITZ_GPIO_KEY_INT (0) /* Key Interrupt */
+#define SPITZ_GPIO_RESET (1)
+#define SPITZ_GPIO_nSD_DETECT (9)
+#define SPITZ_GPIO_TP_INT (11) /* Touch Panel interrupt */
+#define SPITZ_GPIO_AK_INT (13) /* Remote Control */
+#define SPITZ_GPIO_ADS7846_CS (14)
+#define SPITZ_GPIO_SYNC (16)
+#define SPITZ_GPIO_MAX1111_CS (20)
+#define SPITZ_GPIO_FATAL_BAT (21)
+#define SPITZ_GPIO_HSYNC (22)
+#define SPITZ_GPIO_nSD_CLK (32)
+#define SPITZ_GPIO_USB_DEVICE (35)
+#define SPITZ_GPIO_USB_HOST (37)
+#define SPITZ_GPIO_USB_CONNECT (41)
+#define SPITZ_GPIO_LCDCON_CS (53)
+#define SPITZ_GPIO_nPCE (54)
+#define SPITZ_GPIO_nSD_WP (81)
+#define SPITZ_GPIO_ON_RESET (89)
+#define SPITZ_GPIO_BAT_COVER (90)
+#define SPITZ_GPIO_CF_CD (94)
+#define SPITZ_GPIO_ON_KEY (95)
+#define SPITZ_GPIO_SWA (97)
+#define SPITZ_GPIO_SWB (96)
+#define SPITZ_GPIO_CHRG_FULL (101)
+#define SPITZ_GPIO_CO (101)
+#define SPITZ_GPIO_CF_IRQ (105)
+#define SPITZ_GPIO_AC_IN (115)
+#define SPITZ_GPIO_HP_IN (116)
+
+/* Spitz Only GPIOs */
+
+#define SPITZ_GPIO_CF2_IRQ (106) /* CF slot1 Ready */
+#define SPITZ_GPIO_CF2_CD (93)
+
+
+/* Spitz/Akita Keyboard Definitions */
+
+#define SPITZ_KEY_STROBE_NUM (11)
+#define SPITZ_KEY_SENSE_NUM (7)
+#define SPITZ_GPIO_G0_STROBE_BIT 0x0f800000
+#define SPITZ_GPIO_G1_STROBE_BIT 0x00100000
+#define SPITZ_GPIO_G2_STROBE_BIT 0x01000000
+#define SPITZ_GPIO_G3_STROBE_BIT 0x00041880
+#define SPITZ_GPIO_G0_SENSE_BIT 0x00021000
+#define SPITZ_GPIO_G1_SENSE_BIT 0x000000d4
+#define SPITZ_GPIO_G2_SENSE_BIT 0x08000000
+#define SPITZ_GPIO_G3_SENSE_BIT 0x00000000
+
+#define SPITZ_GPIO_KEY_STROBE0 88
+#define SPITZ_GPIO_KEY_STROBE1 23
+#define SPITZ_GPIO_KEY_STROBE2 24
+#define SPITZ_GPIO_KEY_STROBE3 25
+#define SPITZ_GPIO_KEY_STROBE4 26
+#define SPITZ_GPIO_KEY_STROBE5 27
+#define SPITZ_GPIO_KEY_STROBE6 52
+#define SPITZ_GPIO_KEY_STROBE7 103
+#define SPITZ_GPIO_KEY_STROBE8 107
+#define SPITZ_GPIO_KEY_STROBE9 108
+#define SPITZ_GPIO_KEY_STROBE10 114
+
+#define SPITZ_GPIO_KEY_SENSE0 12
+#define SPITZ_GPIO_KEY_SENSE1 17
+#define SPITZ_GPIO_KEY_SENSE2 91
+#define SPITZ_GPIO_KEY_SENSE3 34
+#define SPITZ_GPIO_KEY_SENSE4 36
+#define SPITZ_GPIO_KEY_SENSE5 38
+#define SPITZ_GPIO_KEY_SENSE6 39
+
+
+/* Spitz Scoop Device (No. 1) GPIOs */
+/* Suspend States in comments */
+#define SPITZ_SCP_LED_GREEN SCOOP_GPCR_PA11 /* Keep */
+#define SPITZ_SCP_JK_B SCOOP_GPCR_PA12 /* Keep */
+#define SPITZ_SCP_CHRG_ON SCOOP_GPCR_PA13 /* Keep */
+#define SPITZ_SCP_MUTE_L SCOOP_GPCR_PA14 /* Low */
+#define SPITZ_SCP_MUTE_R SCOOP_GPCR_PA15 /* Low */
+#define SPITZ_SCP_CF_POWER SCOOP_GPCR_PA16 /* Keep */
+#define SPITZ_SCP_LED_ORANGE SCOOP_GPCR_PA17 /* Keep */
+#define SPITZ_SCP_JK_A SCOOP_GPCR_PA18 /* Low */
+#define SPITZ_SCP_ADC_TEMP_ON SCOOP_GPCR_PA19 /* Low */
+
+#define SPITZ_SCP_IO_DIR (SPITZ_SCP_LED_GREEN | SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \
+ SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_LED_ORANGE | \
+ SPITZ_SCP_CF_POWER | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
+#define SPITZ_SCP_IO_OUT (SPITZ_SCP_CHRG_ON | SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R)
+#define SPITZ_SCP_SUS_CLR (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
+#define SPITZ_SCP_SUS_SET 0
+
+/* Spitz Scoop Device (No. 2) GPIOs */
+/* Suspend States in comments */
+#define SPITZ_SCP2_IR_ON SCOOP_GPCR_PA11 /* High */
+#define SPITZ_SCP2_AKIN_PULLUP SCOOP_GPCR_PA12 /* Keep */
+#define SPITZ_SCP2_RESERVED_1 SCOOP_GPCR_PA13 /* High */
+#define SPITZ_SCP2_RESERVED_2 SCOOP_GPCR_PA14 /* Low */
+#define SPITZ_SCP2_RESERVED_3 SCOOP_GPCR_PA15 /* Low */
+#define SPITZ_SCP2_RESERVED_4 SCOOP_GPCR_PA16 /* Low */
+#define SPITZ_SCP2_BACKLIGHT_CONT SCOOP_GPCR_PA17 /* Low */
+#define SPITZ_SCP2_BACKLIGHT_ON SCOOP_GPCR_PA18 /* Low */
+#define SPITZ_SCP2_MIC_BIAS SCOOP_GPCR_PA19 /* Low */
+
+#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \
+ SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
+ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
+
+#define SPITZ_SCP2_IO_OUT (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1)
+#define SPITZ_SCP2_SUS_CLR (SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
+ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
+#define SPITZ_SCP2_SUS_SET (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1)
+
+
+/* Spitz IRQ Definitions */
+
+#define SPITZ_IRQ_GPIO_KEY_INT IRQ_GPIO(SPITZ_GPIO_KEY_INT)
+#define SPITZ_IRQ_GPIO_AC_IN IRQ_GPIO(SPITZ_GPIO_AC_IN)
+#define SPITZ_IRQ_GPIO_AK_INT IRQ_GPIO(SPITZ_GPIO_AK_INT)
+#define SPITZ_IRQ_GPIO_HP_IN IRQ_GPIO(SPITZ_GPIO_HP_IN)
+#define SPITZ_IRQ_GPIO_TP_INT IRQ_GPIO(SPITZ_GPIO_TP_INT)
+#define SPITZ_IRQ_GPIO_SYNC IRQ_GPIO(SPITZ_GPIO_SYNC)
+#define SPITZ_IRQ_GPIO_ON_KEY IRQ_GPIO(SPITZ_GPIO_ON_KEY)
+#define SPITZ_IRQ_GPIO_SWA IRQ_GPIO(SPITZ_GPIO_SWA)
+#define SPITZ_IRQ_GPIO_SWB IRQ_GPIO(SPITZ_GPIO_SWB)
+#define SPITZ_IRQ_GPIO_BAT_COVER IRQ_GPIO(SPITZ_GPIO_BAT_COVER)
+#define SPITZ_IRQ_GPIO_FATAL_BAT IRQ_GPIO(SPITZ_GPIO_FATAL_BAT)
+#define SPITZ_IRQ_GPIO_CO IRQ_GPIO(SPITZ_GPIO_CO)
+#define SPITZ_IRQ_GPIO_CF_IRQ IRQ_GPIO(SPITZ_GPIO_CF_IRQ)
+#define SPITZ_IRQ_GPIO_CF_CD IRQ_GPIO(SPITZ_GPIO_CF_CD)
+#define SPITZ_IRQ_GPIO_CF2_IRQ IRQ_GPIO(SPITZ_GPIO_CF2_IRQ)
+#define SPITZ_IRQ_GPIO_nSD_INT IRQ_GPIO(SPITZ_GPIO_nSD_INT)
+#define SPITZ_IRQ_GPIO_nSD_DETECT IRQ_GPIO(SPITZ_GPIO_nSD_DETECT)
+
+/*
+ * Shared data structures
+ */
+extern struct platform_device spitzscoop_device;
+extern struct platform_device spitzscoop2_device;
+extern struct platform_device spitzssp_device;
+extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
+
+extern void spitz_lcd_power(int on);
diff --git a/include/asm-arm/arch-pxa/uncompress.h b/include/asm-arm/arch-pxa/uncompress.h
index 4428d3eb7432..fe38090444e0 100644
--- a/include/asm-arm/arch-pxa/uncompress.h
+++ b/include/asm-arm/arch-pxa/uncompress.h
@@ -12,6 +12,7 @@
#define FFUART ((volatile unsigned long *)0x40100000)
#define BTUART ((volatile unsigned long *)0x40200000)
#define STUART ((volatile unsigned long *)0x40700000)
+#define HWUART ((volatile unsigned long *)0x41600000)
#define UART FFUART
diff --git a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h
index be9754a05c19..9d7f87375aa7 100644
--- a/include/asm-arm/arch-rpc/hardware.h
+++ b/include/asm-arm/arch-rpc/hardware.h
@@ -15,7 +15,7 @@
#include <asm/arch/memory.h>
#ifndef __ASSEMBLY__
-#define IOMEM(x) ((void __iomem *)(x))
+#define IOMEM(x) ((void __iomem *)(unsigned long)(x))
#else
#define IOMEM(x) x
#endif /* __ASSEMBLY__ */
@@ -52,7 +52,7 @@
/*
* IO Addresses
*/
-#define VIDC_BASE (void __iomem *)0xe0400000
+#define VIDC_BASE IOMEM(0xe0400000)
#define EXPMASK_BASE 0xe0360000
#define IOMD_BASE IOMEM(0xe0200000)
#define IOC_BASE IOMEM(0xe0200000)
diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h
index 24453c405a87..b4da08d7a336 100644
--- a/include/asm-arm/arch-rpc/io.h
+++ b/include/asm-arm/arch-rpc/io.h
@@ -13,6 +13,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-s3c2410/anubis-map.h b/include/asm-arm/arch-s3c2410/anubis-map.h
index 97741d6e506a..d529ffda8599 100644
--- a/include/asm-arm/arch-s3c2410/anubis-map.h
+++ b/include/asm-arm/arch-s3c2410/anubis-map.h
@@ -20,22 +20,22 @@
/* start peripherals off after the S3C2410 */
-#define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x02000000))
+#define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x01800000))
#define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26))
/* we put the CPLD registers next, to get them out of the way */
-#define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01300000 */
+#define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01800000 */
#define ANUBIS_PA_CTRL1 (ANUBIS_PA_CPLD)
-#define ANUBIS_VA_CTRL2 ANUBIS_IOADDR(0x00100000) /* 0x01400000 */
+#define ANUBIS_VA_CTRL2 ANUBIS_IOADDR(0x00100000) /* 0x01900000 */
#define ANUBIS_PA_CTRL2 (ANUBIS_PA_CPLD)
-#define ANUBIS_VA_CTRL3 ANUBIS_IOADDR(0x00200000) /* 0x01500000 */
+#define ANUBIS_VA_CTRL3 ANUBIS_IOADDR(0x00200000) /* 0x01A00000 */
#define ANUBIS_PA_CTRL3 (ANUBIS_PA_CPLD)
-#define ANUBIS_VA_CTRL4 ANUBIS_IOADDR(0x00300000) /* 0x01600000 */
+#define ANUBIS_VA_CTRL4 ANUBIS_IOADDR(0x00300000) /* 0x01B00000 */
#define ANUBIS_PA_CTRL4 (ANUBIS_PA_CPLD)
#define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000)
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
new file mode 100644
index 000000000000..4790491ba9d0
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -0,0 +1,70 @@
+/* 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
+ * 26-Oct-2005 BJD Changed name of platdata init
+*/
+
+#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;
+};
+
+extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
+
+#endif /* __ASM_ARM_FB_H */
diff --git a/include/asm-arm/arch-s3c2410/hardware.h b/include/asm-arm/arch-s3c2410/hardware.h
index 48a39918a760..1c9de29cafef 100644
--- a/include/asm-arm/arch-s3c2410/hardware.h
+++ b/include/asm-arm/arch-s3c2410/hardware.h
@@ -92,6 +92,13 @@ extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
+#ifdef CONFIG_CPU_S3C2440
+
+extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
+
+#endif /* CONFIG_CPU_S3C2440 */
+
+
#endif /* __ASSEMBLY__ */
#include <asm/sizes.h>
diff --git a/include/asm-arm/arch-s3c2410/io.h b/include/asm-arm/arch-s3c2410/io.h
index 418233a7ee6f..16fbc8afffd9 100644
--- a/include/asm-arm/arch-s3c2410/io.h
+++ b/include/asm-arm/arch-s3c2410/io.h
@@ -9,12 +9,14 @@
* 06-Dec-1997 RMK Created.
* 02-Sep-2003 BJD Modified for S3C2410
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
- *
+ * 13-Oct-2005 BJD Fixed problems with LDRH/STRH offset range
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
@@ -97,7 +99,7 @@ DECLARE_IO(int,l,"")
else \
__asm__ __volatile__( \
"strb %0, [%1, #0] @ outbc" \
- : : "r" (value), "r" ((port))); \
+ : : "r" (value), "r" ((port))); \
})
#define __inbc(port) \
@@ -110,35 +112,61 @@ DECLARE_IO(int,l,"")
else \
__asm__ __volatile__( \
"ldrb %0, [%1, #0] @ inbc" \
- : "=r" (result) : "r" ((port))); \
+ : "=r" (result) : "r" ((port))); \
result; \
})
#define __outwc(value,port) \
({ \
unsigned long v = value; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "strh %0, [%1, %2] @ outwc" \
- : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \
- else \
+ if (__PORT_PCIO((port))) { \
+ if ((port) < 256 && (port) > -256) \
+ __asm__ __volatile__( \
+ "strh %0, [%1, %2] @ outwc" \
+ : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \
+ else if ((port) > 0) \
+ __asm__ __volatile__( \
+ "strh %0, [%1, %2] @ outwc" \
+ : : "r" (v), \
+ "r" (PCIO_BASE + ((port) & ~0xff)), \
+ "Jr" (((port) & 0xff))); \
+ else \
+ __asm__ __volatile__( \
+ "strh %0, [%1, #0] @ outwc" \
+ : : "r" (v), \
+ "r" (PCIO_BASE + (port))); \
+ } else \
__asm__ __volatile__( \
"strh %0, [%1, #0] @ outwc" \
- : : "r" (v), "r" ((port))); \
+ : : "r" (v), "r" ((port))); \
})
#define __inwc(port) \
({ \
unsigned short result; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "ldrh %0, [%1, %2] @ inwc" \
- : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \
- else \
+ if (__PORT_PCIO((port))) { \
+ if ((port) < 256 && (port) > -256 ) \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, %2] @ inwc" \
+ : "=r" (result) \
+ : "r" (PCIO_BASE), \
+ "Jr" ((port))); \
+ else if ((port) > 0) \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, %2] @ inwc" \
+ : "=r" (result) \
+ : "r" (PCIO_BASE + ((port) & ~0xff)), \
+ "Jr" (((port) & 0xff))); \
+ else \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, #0] @ inwc" \
+ : "=r" (result) \
+ : "r" (PCIO_BASE + ((port)))); \
+ } else \
__asm__ __volatile__( \
"ldrh %0, [%1, #0] @ inwc" \
- : "=r" (result) : "r" ((port))); \
- result; \
+ : "=r" (result) : "r" ((port))); \
+ result; \
})
#define __outlc(value,port) \
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
index 16f4c3cc1388..34360706e016 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -18,7 +18,9 @@
* 10-Feb-2005 Ben Dooks Fixed CAMDIVN address (Guillaume Gourat)
* 10-Mar-2005 Lucas Villa Real Changed S3C2410_VA to S3C24XX_VA
* 27-Aug-2005 Ben Dooks Add clock-slow info
- */
+ * 20-Oct-2005 Ben Dooks Fixed overflow in PLL (Guillaume Gourat)
+ * 20-Oct-2005 Ben Dooks Add masks for DCLK (Guillaume Gourat)
+*/
#ifndef __ASM_ARM_REGS_CLOCK
#define __ASM_ARM_REGS_CLOCK "$Id: clock.h,v 1.4 2003/04/30 14:50:51 ben Exp $"
@@ -66,11 +68,16 @@
#define S3C2410_DCLKCON_DCLK0_UCLK (1<<1)
#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
+#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4)
+#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8)
#define S3C2410_DCLKCON_DCLK1EN (1<<16)
#define S3C2410_DCLKCON_DCLK1_PCLK (0<<17)
#define S3C2410_DCLKCON_DCLK1_UCLK (1<<17)
#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
+#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24)
+#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20)
+#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24)
#define S3C2410_CLKDIVN_PDIVN (1<<0)
#define S3C2410_CLKDIVN_HDIVN (1<<1)
@@ -83,10 +90,13 @@
#ifndef __ASSEMBLY__
+#include <asm/div64.h>
+
static inline unsigned int
-s3c2410_get_pll(int pllval, int baseclk)
+s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
{
- int mdiv, pdiv, sdiv;
+ unsigned int mdiv, pdiv, sdiv;
+ uint64_t fvco;
mdiv = pllval >> S3C2410_PLLCON_MDIVSHIFT;
pdiv = pllval >> S3C2410_PLLCON_PDIVSHIFT;
@@ -96,7 +106,10 @@ s3c2410_get_pll(int pllval, int baseclk)
pdiv &= S3C2410_PLLCON_PDIVMASK;
sdiv &= S3C2410_PLLCON_SDIVMASK;
- return (baseclk * (mdiv + 8)) / ((pdiv + 2) << sdiv);
+ fvco = (uint64_t)baseclk * (mdiv + 8);
+ do_div(fvco, (pdiv + 2) << sdiv);
+
+ return (unsigned int)fvco;
}
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index 2053cbacffc3..cb33d57c146c 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -20,6 +20,7 @@
* 18-11-2004 BJD Added S3C2440 AC97 controls
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 28-Mar-2005 LCVR Fixed definition of GPB10
+ * 26-Oct-2005 BJD Added generic configuration types
*/
@@ -43,6 +44,11 @@
/* general configuration options */
#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
+#define S3C2410_GPIO_INPUT (0xFFFFFFF0)
+#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1)
+#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */
+#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* not available on A */
+#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */
/* configure GPIO ports A..G */
diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h
index 7f882ea92b2a..b6b1b4e8bbeb 100644
--- a/include/asm-arm/arch-s3c2410/regs-lcd.h
+++ b/include/asm-arm/arch-s3c2410/regs-lcd.h
@@ -51,21 +51,32 @@
#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 10c62db34362..28711aaa4968 100644
--- a/include/asm-arm/arch-sa1100/hardware.h
+++ b/include/asm-arm/arch-sa1100/hardware.h
@@ -22,13 +22,6 @@
/*
- * We requires absolute addresses i.e. (PCMCIA_IO_0_BASE + 0x3f8) for
- * in*()/out*() macros to be usable for all cases.
- */
-#define PCIO_BASE 0
-
-
-/*
* SA1100 internal I/O mappings
*
* We have the following mapping:
@@ -49,23 +42,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/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h
index 7d969ffbd3bb..9d4fe6cf205b 100644
--- a/include/asm-arm/arch-sa1100/io.h
+++ b/include/asm-arm/arch-sa1100/io.h
@@ -10,13 +10,19 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
* We don't actually have real ISA nor PCI buses, but there is so many
* drivers out there that might just work if we fake them...
*/
-#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+#define __io(a) __io(a)
#define __mem_pci(a) (a)
#define __mem_isa(a) (a)
diff --git a/include/asm-arm/arch-sa1100/memory.h b/include/asm-arm/arch-sa1100/memory.h
index 32d3d5bde34d..8743ff5c1b23 100644
--- a/include/asm-arm/arch-sa1100/memory.h
+++ b/include/asm-arm/arch-sa1100/memory.h
@@ -99,10 +99,6 @@ __arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
#define LOCAL_MAP_NR(addr) \
(((unsigned long)(addr) & 0x07ffffff) >> PAGE_SHIFT)
-#else
-
-#define PFN_TO_NID(addr) (0)
-
#endif
#endif
diff --git a/include/asm-arm/arch-sa1100/system.h b/include/asm-arm/arch-sa1100/system.h
index 6f52118ba1a4..0f0612f79b2b 100644
--- a/include/asm-arm/arch-sa1100/system.h
+++ b/include/asm-arm/arch-sa1100/system.h
@@ -4,6 +4,7 @@
* Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
*/
#include <linux/config.h>
+#include <asm/hardware.h>
static inline void arch_idle(void)
{
diff --git a/include/asm-arm/arch-shark/io.h b/include/asm-arm/arch-shark/io.h
index 5e6ed0038b2b..87ffa27f2962 100644
--- a/include/asm-arm/arch-shark/io.h
+++ b/include/asm-arm/arch-shark/io.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h
index 9f895bf61494..47e904cf25c7 100644
--- a/include/asm-arm/arch-versatile/io.h
+++ b/include/asm-arm/arch-versatile/io.h
@@ -22,7 +22,11 @@
#define IO_SPACE_LIMIT 0xffffffff
-#define __io(a) ((void __iomem *)(a))
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+#define __io(a) __io(a)
#define __mem_pci(a) (a)
#define __mem_isa(a) (a)
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index aad7aad026b3..e007dd990da5 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -347,7 +347,6 @@ static inline unsigned long __ffs(unsigned long word)
* the clz instruction for much better code efficiency.
*/
-static __inline__ int generic_fls(int x);
#define fls(x) \
( __builtin_constant_p(x) ? generic_fls(x) : \
({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 035cdcff43d2..e81baff4f54b 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -256,7 +256,7 @@ extern void dmac_flush_range(unsigned long, unsigned long);
* 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/dma-mapping.h b/include/asm-arm/dma-mapping.h
index d62ade4e4cbb..e3e8541ee63b 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -70,7 +70,7 @@ static inline int dma_mapping_error(dma_addr_t dma_addr)
* device-viewed address.
*/
extern void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
/**
* dma_free_coherent - free memory allocated by dma_alloc_coherent
@@ -117,7 +117,7 @@ int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
* device-viewed address.
*/
extern void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
+dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
#define dma_free_writecombine(dev,size,cpu_addr,handle) \
dma_free_coherent(dev,size,cpu_addr,handle)
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index a1696ba238d3..7da97a937548 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -124,6 +124,8 @@ do { \
if (((ex).e_flags & EF_ARM_EABI_MASK) || \
((ex).e_flags & EF_ARM_SOFT_FLOAT)) \
set_thread_flag(TIF_USING_IWMMXT); \
+ else \
+ clear_thread_flag(TIF_USING_IWMMXT); \
} while (0)
#endif
diff --git a/include/asm-arm/futex.h b/include/asm-arm/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-arm/futex.h
+++ b/include/asm-arm/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-arm/hardware/arm_twd.h b/include/asm-arm/hardware/arm_twd.h
new file mode 100644
index 000000000000..131d5b40e072
--- /dev/null
+++ b/include/asm-arm/hardware/arm_twd.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_HARDWARE_TWD_H
+#define __ASM_HARDWARE_TWD_H
+
+#define TWD_TIMER_LOAD 0x00
+#define TWD_TIMER_COUNTER 0x04
+#define TWD_TIMER_CONTROL 0x08
+#define TWD_TIMER_INTSTAT 0x0C
+
+#define TWD_WDOG_LOAD 0x20
+#define TWD_WDOG_COUNTER 0x24
+#define TWD_WDOG_CONTROL 0x28
+#define TWD_WDOG_INTSTAT 0x2C
+#define TWD_WDOG_RESETSTAT 0x30
+#define TWD_WDOG_DISABLE 0x34
+
+#endif
diff --git a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h
index 527404b5a8df..a8f1013930e3 100644
--- a/include/asm-arm/hardware/scoop.h
+++ b/include/asm-arm/hardware/scoop.h
@@ -38,6 +38,8 @@
struct scoop_config {
unsigned short io_out;
unsigned short io_dir;
+ unsigned short suspend_clr;
+ unsigned short suspend_set;
};
/* Structure for linking scoop devices to PCMCIA sockets */
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index cfa71a0dffb6..2e6799632f12 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <asm/byteorder.h>
#include <asm/memory.h>
-#include <asm/arch/hardware.h>
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
@@ -136,9 +135,9 @@ extern void __readwrite_bug(const char *fn);
/*
* String version of IO memory access ops:
*/
-extern void _memcpy_fromio(void *, void __iomem *, size_t);
-extern void _memcpy_toio(void __iomem *, const void *, size_t);
-extern void _memset_io(void __iomem *, int, size_t);
+extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t);
+extern void _memcpy_toio(volatile void __iomem *, const void *, size_t);
+extern void _memset_io(volatile void __iomem *, int, size_t);
#define mmiowb()
diff --git a/include/asm-arm/locks.h b/include/asm-arm/locks.h
index f08dc8447913..852220eecdbc 100644
--- a/include/asm-arm/locks.h
+++ b/include/asm-arm/locks.h
@@ -103,7 +103,7 @@
({ \
smp_mb(); \
__asm__ __volatile__( \
- "@ up_op_read\n" \
+ "@ up_op_write\n" \
"1: ldrex lr, [%0]\n" \
" adds lr, lr, %1\n" \
" strex ip, lr, [%0]\n" \
@@ -231,7 +231,7 @@
#define __up_op_write(ptr,wake) \
({ \
__asm__ __volatile__( \
- "@ up_op_read\n" \
+ "@ up_op_write\n" \
" mrs ip, cpsr\n" \
" orr lr, ip, #128\n" \
" msr cpsr_c, lr\n" \
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index 56c6bf4ab0c3..7273c6fd95b5 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -48,10 +48,10 @@ struct machine_desc {
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
-#define MACHINE_START(_type,_name) \
-const struct machine_desc __mach_desc_##_type \
- __attribute__((__section__(".arch.info"))) = { \
- .nr = MACH_TYPE_##_type, \
+#define MACHINE_START(_type,_name) \
+static const struct machine_desc __mach_desc_##_type \
+ __attribute__((__section__(".arch.info.init"))) = { \
+ .nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
index 9ac47cf8d2e4..0619522bd926 100644
--- a/include/asm-arm/mach/map.h
+++ b/include/asm-arm/mach/map.h
@@ -11,7 +11,7 @@
*/
struct map_desc {
unsigned long virtual;
- unsigned long physical;
+ unsigned long pfn;
unsigned long length;
unsigned int type;
};
@@ -27,6 +27,9 @@ struct meminfo;
#define MT_ROM 6
#define MT_IXP2000_DEVICE 7
+#define __phys_to_pfn(paddr) (paddr >> PAGE_SHIFT)
+#define __pfn_to_phys(pfn) (pfn << PAGE_SHIFT)
+
extern void create_memmap_holes(struct meminfo *);
extern void memtable_init(struct meminfo *);
extern void iotable_init(struct map_desc *, int);
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index e47bea7d1723..a8a933a775db 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -160,12 +160,25 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
#define page_to_pfn(page) \
(( (page) - page_zone(page)->zone_mem_map) \
+ page_zone(page)->zone_start_pfn)
+
#define pfn_to_page(pfn) \
(PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
-#define pfn_valid(pfn) (PFN_TO_NID(pfn) < MAX_NUMNODES)
+
+#define pfn_valid(pfn) \
+ ({ \
+ unsigned int nid = PFN_TO_NID(pfn); \
+ int valid = nid < MAX_NUMNODES; \
+ if (valid) { \
+ pg_data_t *node = NODE_DATA(nid); \
+ valid = (pfn - node->node_start_pfn) < \
+ node->node_spanned_pages; \
+ } \
+ valid; \
+ })
#define virt_to_page(kaddr) \
(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+
#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
/*
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index 38ea5899a580..ead3ced38cb8 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -64,6 +64,19 @@ extern void
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-arm/pgtable.h b/include/asm-arm/pgtable.h
index 478c49b56e18..366bafbdfbb1 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -445,12 +445,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define HAVE_ARCH_UNMAPPED_AREA
/*
- * remap a physical address `phys' of size `size' with page protection `prot'
+ * remap a physical page `pfn' of size `size' with page protection `prot'
* into virtual address `from'
*/
-#define io_remap_page_range(vma,from,phys,size,prot) \
- remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h
index adcbd79762bf..ea3ed2465233 100644
--- a/include/asm-arm/setup.h
+++ b/include/asm-arm/setup.h
@@ -171,7 +171,7 @@ struct tagtable {
int (*parse)(const struct tag *);
};
-#define __tag __attribute_used__ __attribute__((__section__(".taglist")))
+#define __tag __attribute_used__ __attribute__((__section__(".taglist.init")))
#define __tagtable(tag, fn) \
static struct tagtable __tagtable_##fn __tag = { tag, fn }
@@ -213,6 +213,6 @@ struct early_params {
#define __early_param(name,fn) \
static struct early_params __early_##fn __attribute_used__ \
-__attribute__((__section__("__early_param"))) = { name, fn }
+__attribute__((__section__(".early_param.init"))) = { name, fn }
#endif
diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h
index 760f6e65af05..ced69161917b 100644
--- a/include/asm-arm/signal.h
+++ b/include/asm-arm/signal.h
@@ -115,7 +115,6 @@ typedef unsigned long sigset_t;
#ifdef __KERNEL__
#define SA_TIMER 0x40000000
-#define SA_IRQNOMASK 0x08000000
#endif
#include <asm-generic/signal.h>
diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
index 1f906d09b688..cb4906b45555 100644
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -16,21 +16,14 @@
* Unlocked value: 0
* Locked value: 1
*/
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while (0)
-#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_unlock_wait(x) do { barrier(); } while (spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned long tmp;
@@ -47,7 +40,7 @@ static inline void _raw_spin_lock(spinlock_t *lock)
smp_mb();
}
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
unsigned long tmp;
@@ -67,7 +60,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
}
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
smp_mb();
@@ -80,23 +73,14 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
/*
* RWLOCKS
- */
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while (0)
-#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0)
-
-/*
+ *
+ *
* Write locks are easy - we just set bit 31. When unlocking, we can
* just write zero since the lock is exclusively held.
*/
-static inline void _raw_write_lock(rwlock_t *rw)
+#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0)
+
+static inline void __raw_write_lock(rwlock_t *rw)
{
unsigned long tmp;
@@ -113,7 +97,7 @@ static inline void _raw_write_lock(rwlock_t *rw)
smp_mb();
}
-static inline int _raw_write_trylock(rwlock_t *rw)
+static inline int __raw_write_trylock(rwlock_t *rw)
{
unsigned long tmp;
@@ -133,7 +117,7 @@ static inline int _raw_write_trylock(rwlock_t *rw)
}
}
-static inline void _raw_write_unlock(rwlock_t *rw)
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
smp_mb();
@@ -156,7 +140,7 @@ static inline void _raw_write_unlock(rwlock_t *rw)
* currently active. However, we know we won't have any write
* locks.
*/
-static inline void _raw_read_lock(rwlock_t *rw)
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned long tmp, tmp2;
@@ -173,7 +157,7 @@ static inline void _raw_read_lock(rwlock_t *rw)
smp_mb();
}
-static inline void _raw_read_unlock(rwlock_t *rw)
+static inline void __raw_read_unlock(rwlock_t *rw)
{
unsigned long tmp, tmp2;
@@ -190,6 +174,6 @@ static inline void _raw_read_unlock(rwlock_t *rw)
: "cc");
}
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-arm/spinlock_types.h b/include/asm-arm/spinlock_types.h
new file mode 100644
index 000000000000..43e83f6d2ee5
--- /dev/null
+++ b/include/asm-arm/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 278de61224d1..c49df635a80f 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -355,6 +355,9 @@
#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
+#define __NR_mbind (__NR_SYSCALL_BASE+319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
/*
* The following SWIs are ARM private.
diff --git a/include/asm-arm26/futex.h b/include/asm-arm26/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-arm26/futex.h
+++ b/include/asm-arm26/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-arm26/hardirq.h b/include/asm-arm26/hardirq.h
index 791ee1da9bfa..dc28daab8aa8 100644
--- a/include/asm-arm26/hardirq.h
+++ b/include/asm-arm26/hardirq.h
@@ -22,8 +22,6 @@ typedef struct {
# error HARDIRQ_BITS is too low!
#endif
-#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
-
#ifndef CONFIG_SMP
extern asmlinkage void __do_softirq(void);
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index 4a0a00da425f..f602cf572411 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -294,12 +294,9 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
#include <asm-generic/pgtable.h>
/*
- * remap a physical address `phys' of size `size' with page protection `prot'
+ * remap a physical page `pfn' of size `size' with page protection `prot'
* into virtual address `from'
*/
-#define io_remap_page_range(vma,from,phys,size,prot) \
- remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index 0b5c3fdaefe1..8eff51349ae7 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -15,14 +15,14 @@
#ifdef CONFIG_PCI
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
#else
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-cris/futex.h b/include/asm-cris/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-cris/futex.h
+++ b/include/asm-cris/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index 0206ab35eae0..5003e017fd1e 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -13,7 +13,7 @@
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
-void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int gfp);
+void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
/*
diff --git a/include/asm-frv/futex.h b/include/asm-frv/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-frv/futex.h
+++ b/include/asm-frv/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
index b4efe5e3591a..1168451c275f 100644
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -32,7 +32,7 @@ extern void pcibios_set_master(struct pci_dev *dev);
extern void pcibios_penalize_isa_irq(int irq);
#ifdef CONFIG_MMU
-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
extern void consistent_free(void *vaddr);
extern void consistent_sync(void *vaddr, size_t size, int direction);
extern void consistent_sync_page(struct page *page, unsigned long offset,
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index d0a9c2f9c13e..473fb4bb6329 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -500,9 +500,6 @@ static inline int pte_file(pte_t pte)
#define PageSkip(page) (0)
#define kern_addr_valid(addr) (1)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
index fd9de9502dff..a7f1a55ce6b0 100644
--- a/include/asm-generic/dma-mapping-broken.h
+++ b/include/asm-generic/dma-mapping-broken.h
@@ -6,7 +6,7 @@
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 8cef663c5cd9..747d790295f3 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -35,7 +35,7 @@ dma_set_mask(struct device *dev, u64 dma_mask)
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- unsigned int __nocast flag)
+ gfp_t flag)
{
BUG_ON(dev->bus != &pci_bus_type);
@@ -168,7 +168,7 @@ dma_set_mask(struct device *dev, u64 dma_mask)
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- unsigned int __nocast flag)
+ gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index ee1d8b5d8168..c36a77d3bf44 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -30,6 +30,19 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
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-generic/pgtable.h b/include/asm-generic/pgtable.h
index f86c1e549466..ff28c8b31f58 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -158,6 +158,19 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
#define lazy_mmu_prot_update(pte) do { } while (0)
#endif
+#ifndef __HAVE_ARCH_MULTIPLE_ZERO_PAGE
+#define move_pte(pte, prot, old_addr, new_addr) (pte)
+#else
+#define move_pte(pte, prot, old_addr, new_addr) \
+({ \
+ pte_t newpte = (pte); \
+ if (pte_present(pte) && pfn_valid(pte_pfn(pte)) && \
+ pte_page(pte) == ZERO_PAGE(old_addr)) \
+ newpte = mk_pte(ZERO_PAGE(new_addr), (prot)); \
+ newpte; \
+})
+#endif
+
/*
* When walking page tables, get the address of the next boundary,
* or the end address of the range if that comes earlier. Although no
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index faff403e1061..7d0298347ee7 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -23,7 +23,11 @@
* and page free order so much..
*/
#ifdef CONFIG_SMP
- #define FREE_PTE_NR 506
+ #ifdef ARCH_FREE_PTR_NR
+ #define FREE_PTR_NR ARCH_FREE_PTR_NR
+ #else
+ #define FREE_PTE_NR 506
+ #endif
#define tlb_fast_mode(tlb) ((tlb)->nr == ~0U)
#else
#define FREE_PTE_NR 1
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6f857be2b644..a9c55490fb82 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -103,3 +103,41 @@
VMLINUX_SYMBOL(__kprobes_text_start) = .; \
*(.kprobes.text) \
VMLINUX_SYMBOL(__kprobes_text_end) = .;
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to
+ the beginning of the section so we begin them at 0. */
+#define DWARF_DEBUG \
+ /* DWARF 1 */ \
+ .debug 0 : { *(.debug) } \
+ .line 0 : { *(.line) } \
+ /* GNU DWARF 1 extensions */ \
+ .debug_srcinfo 0 : { *(.debug_srcinfo) } \
+ .debug_sfnames 0 : { *(.debug_sfnames) } \
+ /* DWARF 1.1 and DWARF 2 */ \
+ .debug_aranges 0 : { *(.debug_aranges) } \
+ .debug_pubnames 0 : { *(.debug_pubnames) } \
+ /* DWARF 2 */ \
+ .debug_info 0 : { *(.debug_info \
+ .gnu.linkonce.wi.*) } \
+ .debug_abbrev 0 : { *(.debug_abbrev) } \
+ .debug_line 0 : { *(.debug_line) } \
+ .debug_frame 0 : { *(.debug_frame) } \
+ .debug_str 0 : { *(.debug_str) } \
+ .debug_loc 0 : { *(.debug_loc) } \
+ .debug_macinfo 0 : { *(.debug_macinfo) } \
+ /* SGI/MIPS DWARF 2 extensions */ \
+ .debug_weaknames 0 : { *(.debug_weaknames) } \
+ .debug_funcnames 0 : { *(.debug_funcnames) } \
+ .debug_typenames 0 : { *(.debug_typenames) } \
+ .debug_varnames 0 : { *(.debug_varnames) } \
+
+ /* Stabs debugging sections. */
+#define STABS_DEBUG \
+ .stab 0 : { *(.stab) } \
+ .stabstr 0 : { *(.stabstr) } \
+ .stab.excl 0 : { *(.stab.excl) } \
+ .stab.exclstr 0 : { *(.stab.exclstr) } \
+ .stab.index 0 : { *(.stab.index) } \
+ .stab.indexstr 0 : { *(.stab.indexstr) } \
+ .comment 0 : { *(.comment) }
diff --git a/include/asm-h8300/futex.h b/include/asm-h8300/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-h8300/futex.h
+++ b/include/asm-h8300/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h
index 69076eb31476..f6e296fc1297 100644
--- a/include/asm-h8300/pgtable.h
+++ b/include/asm-h8300/pgtable.h
@@ -52,8 +52,6 @@ extern int is_in_rom(unsigned long);
* No page table caches to initialise
*/
#define pgtable_cache_init() do { } while (0)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index cf828ace13f9..df4ed323aa4d 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -103,7 +103,7 @@ __acpi_release_global_lock (unsigned int *lock)
:"=r"(n_hi), "=r"(n_lo) \
:"0"(n_hi), "1"(n_lo))
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern int acpi_lapic;
extern int acpi_ioapic;
extern int acpi_noirq;
@@ -146,13 +146,6 @@ static inline void check_acpi_pci(void) { }
#endif
-#else /* CONFIG_ACPI_BOOT */
-# define acpi_lapic 0
-# define acpi_ioapic 0
-
-#endif
-
-#ifdef CONFIG_ACPI_PCI
static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
static inline void acpi_disable_pci(void)
{
@@ -160,11 +153,16 @@ static inline void acpi_disable_pci(void)
acpi_noirq_set();
}
extern int acpi_irq_balance_set(char *str);
-#else
+
+#else /* !CONFIG_ACPI */
+
+#define acpi_lapic 0
+#define acpi_ioapic 0
static inline void acpi_noirq_set(void) { }
static inline void acpi_disable_pci(void) { }
-static inline int acpi_irq_balance_set(char *str) { return 0; }
-#endif
+
+#endif /* !CONFIG_ACPI */
+
#ifdef CONFIG_ACPI_SLEEP
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index 6a1b1882285c..8c454aa58ac6 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -130,6 +130,8 @@ extern unsigned int nmi_watchdog;
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
+extern int disable_timer_pin_1;
+
#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
diff --git a/include/asm-i386/div64.h b/include/asm-i386/div64.h
index 28ed8b296afc..75c67c785bb8 100644
--- a/include/asm-i386/div64.h
+++ b/include/asm-i386/div64.h
@@ -35,7 +35,7 @@
*/
#define div_long_long_rem(a,b,c) div_ll_X_l_rem(a,b,c)
-extern inline long
+static inline long
div_ll_X_l_rem(long long divs, long div, long *rem)
{
long dum2;
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index 563964b2995b..e56c335f8ef9 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -11,7 +11,7 @@
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
index c94cac958389..cfb1c61d3b9c 100644
--- a/include/asm-i386/fixmap.h
+++ b/include/asm-i386/fixmap.h
@@ -76,7 +76,7 @@ enum fixed_addresses {
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
FIX_ACPI_BEGIN,
FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
#endif
diff --git a/include/asm-i386/futex.h b/include/asm-i386/futex.h
index 44b9db806474..e7a271d39309 100644
--- a/include/asm-i386/futex.h
+++ b/include/asm-i386/futex.h
@@ -61,7 +61,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
if (op == FUTEX_OP_SET)
__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
else {
-#ifndef CONFIG_X86_BSWAP
+#if !defined(CONFIG_X86_BSWAP) && !defined(CONFIG_UML)
if (boot_cpu_data.x86 == 3)
ret = -ENOSYS;
else
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 4ac84cc6f01a..622815bf3243 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -18,6 +18,8 @@
#include <asm/irq.h>
#include <asm/sections.h>
+struct hw_interrupt_type;
+
/*
* Various low-level irq details needed by irq.c, process.c,
* time.c, io_apic.c and smp.c
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index 002c203ccd6a..51c4e5fe6062 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -195,12 +195,12 @@ extern int skip_ioapic_setup;
*/
#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern int io_apic_get_unique_id (int ioapic, int apic_id);
extern int io_apic_get_version (int ioapic);
extern int io_apic_get_redir_entries (int ioapic);
extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low);
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /* CONFIG_ACPI */
extern int (*ioapic_renumber_irq)(int ioapic, int irq);
diff --git a/include/asm-i386/mach-default/mach_reboot.h b/include/asm-i386/mach-default/mach_reboot.h
index 521e227db679..06ae4d81ba6a 100644
--- a/include/asm-i386/mach-default/mach_reboot.h
+++ b/include/asm-i386/mach-default/mach_reboot.h
@@ -22,7 +22,15 @@ static inline void mach_reboot(void)
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 516421300ea2..348fe3a4879d 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -29,7 +29,7 @@ static inline void get_memcfg_numa(void)
#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-i386/mpspec.h b/include/asm-i386/mpspec.h
index d84a9c326c22..64a0b8e6afeb 100644
--- a/include/asm-i386/mpspec.h
+++ b/include/asm-i386/mpspec.h
@@ -27,14 +27,14 @@ extern unsigned long mp_lapic_addr;
extern int pic_mode;
extern int using_apic_timer;
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern void mp_register_lapic (u8 id, u8 enabled);
extern void mp_register_lapic_address (u64 address);
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void);
extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /* CONFIG_ACPI */
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
diff --git a/include/asm-i386/numa.h b/include/asm-i386/numa.h
new file mode 100644
index 000000000000..96fcb157db1d
--- /dev/null
+++ b/include/asm-i386/numa.h
@@ -0,0 +1,3 @@
+
+int pxm_to_nid(int pxm);
+
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index 47bc1ffa3d4c..d101ac414f07 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -431,9 +431,6 @@ extern void noexec_setup(const char *str);
#define kern_addr_valid(addr) (1)
#endif /* CONFIG_FLATMEM */
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 37bef8ed7bed..0a4ec764377c 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -679,7 +679,7 @@ static inline void rep_nop(void)
However we don't do prefetches for pre XP Athlons currently
That should be fixed. */
#define ARCH_HAS_PREFETCH
-extern inline void prefetch(const void *x)
+static inline void prefetch(const void *x)
{
alternative_input(ASM_NOP4,
"prefetchnta (%1)",
@@ -693,7 +693,7 @@ extern inline void prefetch(const void *x)
/* 3dnow! prefetch to get an exclusive cache line. Useful for
spinlocks to avoid one state transition in the cache coherency protocol. */
-extern inline void prefetchw(const void *x)
+static inline void prefetchw(const void *x)
{
alternative_input(ASM_NOP4,
"prefetchw (%1)",
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index f9ff31f40036..23604350cdf4 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -7,46 +7,21 @@
#include <linux/config.h>
#include <linux/compiler.h>
-asmlinkage int printk(const char * fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
- */
-
-typedef struct {
- volatile unsigned int slock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned magic;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define SPINLOCK_MAGIC 0xdead4ead
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC
-#else
-#define SPINLOCK_MAGIC_INIT /* */
-#endif
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-/*
+ *
* Simple spin lock operations. There are two variants, one clears IRQ's
* on the local processor, one does not.
*
* We make no fairness assumptions. They have a cost.
+ *
+ * (the type definitions are in asm/spinlock_types.h)
*/
-#define spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0)
-#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
+#define __raw_spin_is_locked(x) \
+ (*(volatile signed char *)(&(x)->slock) <= 0)
-#define spin_lock_string \
+#define __raw_spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \
"jns 3f\n" \
@@ -57,7 +32,7 @@ typedef struct {
"jmp 1b\n" \
"3:\n\t"
-#define spin_lock_string_flags \
+#define __raw_spin_lock_string_flags \
"\n1:\t" \
"lock ; decb %0\n\t" \
"jns 4f\n\t" \
@@ -73,86 +48,71 @@ typedef struct {
"jmp 1b\n" \
"4:\n\t"
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+ __asm__ __volatile__(
+ __raw_spin_lock_string
+ :"=m" (lock->slock) : : "memory");
+}
+
+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+{
+ __asm__ __volatile__(
+ __raw_spin_lock_string_flags
+ :"=m" (lock->slock) : "r" (flags) : "memory");
+}
+
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+ char oldval;
+ __asm__ __volatile__(
+ "xchgb %b0,%1"
+ :"=q" (oldval), "=m" (lock->slock)
+ :"0" (0) : "memory");
+ return oldval > 0;
+}
+
/*
- * This works. Despite all the confusion.
- * (except on PPro SMP or if we are using OOSTORE)
+ * __raw_spin_unlock based on writing $1 to the low byte.
+ * This method works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there)
* (PPro errata 66, 92)
*/
#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
-#define spin_unlock_string \
+#define __raw_spin_unlock_string \
"movb $1,%0" \
:"=m" (lock->slock) : : "memory"
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(lock->magic != SPINLOCK_MAGIC);
- BUG_ON(!spin_is_locked(lock));
-#endif
__asm__ __volatile__(
- spin_unlock_string
+ __raw_spin_unlock_string
);
}
#else
-#define spin_unlock_string \
+#define __raw_spin_unlock_string \
"xchgb %b0, %1" \
:"=q" (oldval), "=m" (lock->slock) \
:"0" (oldval) : "memory"
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
char oldval = 1;
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(lock->magic != SPINLOCK_MAGIC);
- BUG_ON(!spin_is_locked(lock));
-#endif
- __asm__ __volatile__(
- spin_unlock_string
- );
-}
-#endif
-
-static inline int _raw_spin_trylock(spinlock_t *lock)
-{
- char oldval;
__asm__ __volatile__(
- "xchgb %b0,%1"
- :"=q" (oldval), "=m" (lock->slock)
- :"0" (0) : "memory");
- return oldval > 0;
+ __raw_spin_unlock_string
+ );
}
-static inline void _raw_spin_lock(spinlock_t *lock)
-{
-#ifdef CONFIG_DEBUG_SPINLOCK
- if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
- printk("eip: %p\n", __builtin_return_address(0));
- BUG();
- }
#endif
- __asm__ __volatile__(
- spin_lock_string
- :"=m" (lock->slock) : : "memory");
-}
-static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
-{
-#ifdef CONFIG_DEBUG_SPINLOCK
- if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
- printk("eip: %p\n", __builtin_return_address(0));
- BUG();
- }
-#endif
- __asm__ __volatile__(
- spin_lock_string_flags
- :"=m" (lock->slock) : "r" (flags) : "memory");
-}
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
/*
* Read-write spinlocks, allowing multiple readers
@@ -163,72 +123,41 @@ static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
* can "mix" irq-safe locks - any writer needs to get a
* irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
+ *
+ * On x86, we implement read-write locks as a 32-bit counter
+ * with the high bit (sign) being the "contended" bit.
+ *
+ * The inline assembly is non-obvious. Think about it.
+ *
+ * Changed to use the same technique as rw semaphores. See
+ * semaphore.h for details. -ben
+ *
+ * the helpers are in arch/i386/kernel/semaphore.c
*/
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned magic;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RWLOCK_MAGIC 0xdeaf1eed
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC
-#else
-#define RWLOCK_MAGIC_INIT /* */
-#endif
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
/**
* read_can_lock - would read_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define read_can_lock(x) ((int)(x)->lock > 0)
+#define __raw_read_can_lock(x) ((int)(x)->lock > 0)
/**
* write_can_lock - would write_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
+#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-/*
- * On x86, we implement read-write locks as a 32-bit counter
- * with the high bit (sign) being the "contended" bit.
- *
- * The inline assembly is non-obvious. Think about it.
- *
- * Changed to use the same technique as rw semaphores. See
- * semaphore.h for details. -ben
- */
-/* the spinlock helpers are in arch/i386/kernel/semaphore.c */
-
-static inline void _raw_read_lock(rwlock_t *rw)
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(rw->magic != RWLOCK_MAGIC);
-#endif
__build_read_lock(rw, "__read_lock_failed");
}
-static inline void _raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(rw->magic != RWLOCK_MAGIC);
-#endif
__build_write_lock(rw, "__write_lock_failed");
}
-#define _raw_read_unlock(rw) asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
-#define _raw_write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
-
-static inline int _raw_read_trylock(rwlock_t *lock)
+static inline int __raw_read_trylock(raw_rwlock_t *lock)
{
atomic_t *count = (atomic_t *)lock;
atomic_dec(count);
@@ -238,7 +167,7 @@ static inline int _raw_read_trylock(rwlock_t *lock)
return 0;
}
-static inline int _raw_write_trylock(rwlock_t *lock)
+static inline int __raw_write_trylock(raw_rwlock_t *lock)
{
atomic_t *count = (atomic_t *)lock;
if (atomic_sub_and_test(RW_LOCK_BIAS, count))
@@ -247,4 +176,15 @@ static inline int _raw_write_trylock(rwlock_t *lock)
return 0;
}
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
+{
+ asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
+}
+
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
+{
+ asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
+ : "=m" (rw->lock) : : "memory");
+}
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-i386/spinlock_types.h b/include/asm-i386/spinlock_types.h
new file mode 100644
index 000000000000..59efe849f351
--- /dev/null
+++ b/include/asm-i386/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int slock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
+
+#endif
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index e2cb9fa6f563..8fbf791651bf 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -48,7 +48,7 @@ struct thread_info {
#else /* !__ASSEMBLY__ */
-#include <asm/asm_offsets.h>
+#include <asm/asm-offsets.h>
#endif
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
index 2461b731781e..0ec27c9e8e45 100644
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -60,7 +60,7 @@ static inline int node_to_first_cpu(int node)
return first_cpu(mask);
}
-#define pcibus_to_node(bus) mp_bus_id_to_node[(bus)->number]
+#define pcibus_to_node(bus) ((long) (bus)->sysdata)
#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus))
/* sched_domains SD_NODE_INIT for NUMAQ machines */
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index a7cb377745bf..fbaf90a3968c 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -332,7 +332,7 @@ type name(type1 arg1) \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1))); \
+ : "0" (__NR_##name),"b" ((long)(arg1)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -342,7 +342,7 @@ type name(type1 arg1,type2 arg2) \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -353,7 +353,7 @@ long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
+ "d" ((long)(arg3)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -364,7 +364,7 @@ long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
+ "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -376,7 +376,7 @@ long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -389,7 +389,7 @@ __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; p
: "=a" (__res) \
: "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
- "0" ((long)(arg6))); \
+ "0" ((long)(arg6)) : "memory"); \
__syscall_return(type,__res); \
}
diff --git a/include/asm-ia64/acpi-ext.h b/include/asm-ia64/acpi-ext.h
index 9271d74c64cc..56d2ddc97b30 100644
--- a/include/asm-ia64/acpi-ext.h
+++ b/include/asm-ia64/acpi-ext.h
@@ -11,6 +11,7 @@
#define _ASM_IA64_ACPI_EXT_H
#include <linux/types.h>
+#include <acpi/actypes.h>
extern acpi_status hp_acpi_csr_space (acpi_handle, u64 *base, u64 *length);
diff --git a/include/asm-ia64/futex.h b/include/asm-ia64/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-ia64/futex.h
+++ b/include/asm-ia64/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
index a429fe225b07..20f98f1751a1 100644
--- a/include/asm-ia64/iosapic.h
+++ b/include/asm-ia64/iosapic.h
@@ -80,12 +80,9 @@ extern int iosapic_remove (unsigned int gsi_base);
#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 cd984d08fd15..dbe86c0bbce5 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -35,8 +35,4 @@ extern void disable_irq_nosync (unsigned int);
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/machvec.h b/include/asm-ia64/machvec.h
index 79e89a7db566..a2f6ac5aef7d 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -37,7 +37,7 @@ typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
/* DMA-mapping interface: */
typedef void ia64_mv_dma_init (void);
-typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, int);
+typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, gfp_t);
typedef void ia64_mv_dma_free_coherent (struct device *, size_t, void *, dma_addr_t);
typedef dma_addr_t ia64_mv_dma_map_single (struct device *, void *, size_t, int);
typedef void ia64_mv_dma_unmap_single (struct device *, dma_addr_t, size_t, int);
diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h
index 149ad0118455..c7d9c9ed38ba 100644
--- a/include/asm-ia64/mca.h
+++ b/include/asm-ia64/mca.h
@@ -11,8 +11,6 @@
#ifndef _ASM_IA64_MCA_H
#define _ASM_IA64_MCA_H
-#define IA64_MCA_STACK_SIZE 8192
-
#if !defined(__ASSEMBLY__)
#include <linux/interrupt.h>
@@ -48,7 +46,8 @@ typedef union cmcv_reg_u {
enum {
IA64_MCA_RENDEZ_CHECKIN_NOTDONE = 0x0,
- IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1
+ IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1,
+ IA64_MCA_RENDEZ_CHECKIN_INIT = 0x2,
};
/* Information maintained by the MC infrastructure */
@@ -63,18 +62,47 @@ typedef struct ia64_mc_info_s {
} ia64_mc_info_t;
-typedef struct ia64_mca_sal_to_os_state_s {
- u64 imsto_os_gp; /* GP of the os registered with the SAL */
- u64 imsto_pal_proc; /* PAL_PROC entry point - physical addr */
- u64 imsto_sal_proc; /* SAL_PROC entry point - physical addr */
- u64 imsto_sal_gp; /* GP of the SAL - physical */
- u64 imsto_rendez_state; /* Rendez state information */
- u64 imsto_sal_check_ra; /* Return address in SAL_CHECK while going
- * back to SAL from OS after MCA handling.
- */
- u64 pal_min_state; /* from PAL in r17 */
- u64 proc_state_param; /* from PAL in r18. See SDV 2:268 11.3.2.1 */
-} ia64_mca_sal_to_os_state_t;
+/* Handover state from SAL to OS and vice versa, for both MCA and INIT events.
+ * Besides the handover state, it also contains some saved registers from the
+ * time of the event.
+ * Note: mca_asm.S depends on the precise layout of this structure.
+ */
+
+struct ia64_sal_os_state {
+ /* SAL to OS, must be at offset 0 */
+ u64 os_gp; /* GP of the os registered with the SAL, physical */
+ u64 pal_proc; /* PAL_PROC entry point, physical */
+ u64 sal_proc; /* SAL_PROC entry point, physical */
+ u64 rv_rc; /* MCA - Rendezvous state, INIT - reason code */
+ u64 proc_state_param; /* from R18 */
+ u64 monarch; /* 1 for a monarch event, 0 for a slave */
+ /* common, must follow SAL to OS */
+ u64 sal_ra; /* Return address in SAL, physical */
+ u64 sal_gp; /* GP of the SAL - physical */
+ pal_min_state_area_t *pal_min_state; /* from R17. physical in asm, virtual in C */
+ /* Previous values of IA64_KR(CURRENT) and IA64_KR(CURRENT_STACK).
+ * Note: if the MCA/INIT recovery code wants to resume to a new context
+ * then it must change these values to reflect the new kernel stack.
+ */
+ u64 prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */
+ u64 prev_IA64_KR_CURRENT_STACK;
+ struct task_struct *prev_task; /* previous task, NULL if it is not useful */
+ /* Some interrupt registers are not saved in minstate, pt_regs or
+ * switch_stack. Because MCA/INIT can occur when interrupts are
+ * disabled, we need to save the additional interrupt registers over
+ * MCA/INIT and resume.
+ */
+ u64 isr;
+ u64 ifa;
+ u64 itir;
+ u64 iipa;
+ u64 iim;
+ u64 iha;
+ /* OS to SAL, must follow common */
+ u64 os_status; /* OS status to SAL, enum below */
+ u64 context; /* 0 if return to same context
+ 1 if return to new context */
+};
enum {
IA64_MCA_CORRECTED = 0x0, /* Error has been corrected by OS_MCA */
@@ -84,35 +112,21 @@ enum {
};
enum {
+ IA64_INIT_RESUME = 0x0, /* Resume after return from INIT */
+ IA64_INIT_WARM_BOOT = -1, /* Warm boot of the system need from SAL */
+};
+
+enum {
IA64_MCA_SAME_CONTEXT = 0x0, /* SAL to return to same context */
IA64_MCA_NEW_CONTEXT = -1 /* SAL to return to new context */
};
-typedef struct ia64_mca_os_to_sal_state_s {
- u64 imots_os_status; /* OS status to SAL as to what happened
- * with the MCA handling.
- */
- u64 imots_sal_gp; /* GP of the SAL - physical */
- u64 imots_context; /* 0 if return to same context
- 1 if return to new context */
- u64 *imots_new_min_state; /* Pointer to structure containing
- * new values of registers in the min state
- * save area.
- */
- u64 imots_sal_check_ra; /* Return address in SAL_CHECK while going
- * back to SAL from OS after MCA handling.
- */
-} ia64_mca_os_to_sal_state_t;
-
/* Per-CPU MCA state that is too big for normal per-CPU variables. */
struct ia64_mca_cpu {
- u64 stack[IA64_MCA_STACK_SIZE/8]; /* MCA memory-stack */
- u64 proc_state_dump[512];
- u64 stackframe[32];
- u64 rbstore[IA64_MCA_STACK_SIZE/8]; /* MCA reg.-backing store */
+ u64 mca_stack[KERNEL_STACK_SIZE/8];
u64 init_stack[KERNEL_STACK_SIZE/8];
-} __attribute__ ((aligned(16)));
+};
/* Array of physical addresses of each CPU's MCA area. */
extern unsigned long __per_cpu_mca[NR_CPUS];
@@ -121,12 +135,29 @@ extern void ia64_mca_init(void);
extern void ia64_mca_cpu_init(void *);
extern void ia64_os_mca_dispatch(void);
extern void ia64_os_mca_dispatch_end(void);
-extern void ia64_mca_ucmc_handler(void);
+extern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *);
+extern void ia64_init_handler(struct pt_regs *,
+ struct switch_stack *,
+ struct ia64_sal_os_state *);
extern void ia64_monarch_init_handler(void);
extern void ia64_slave_init_handler(void);
extern void ia64_mca_cmc_vector_setup(void);
-extern int ia64_reg_MCA_extension(void*);
+extern int ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *));
extern void ia64_unreg_MCA_extension(void);
+extern u64 ia64_get_rnat(u64 *);
+
+#else /* __ASSEMBLY__ */
+
+#define IA64_MCA_CORRECTED 0x0 /* Error has been corrected by OS_MCA */
+#define IA64_MCA_WARM_BOOT -1 /* Warm boot of the system need from SAL */
+#define IA64_MCA_COLD_BOOT -2 /* Cold boot of the system need from SAL */
+#define IA64_MCA_HALT -3 /* System to be halted by SAL */
+
+#define IA64_INIT_RESUME 0x0 /* Resume after return from INIT */
+#define IA64_INIT_WARM_BOOT -1 /* Warm boot of the system need from SAL */
+
+#define IA64_MCA_SAME_CONTEXT 0x0 /* SAL to return to same context */
+#define IA64_MCA_NEW_CONTEXT -1 /* SAL to return to new context */
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_MCA_H */
diff --git a/include/asm-ia64/mca_asm.h b/include/asm-ia64/mca_asm.h
index 836953e0f91f..27c9203d8ce3 100644
--- a/include/asm-ia64/mca_asm.h
+++ b/include/asm-ia64/mca_asm.h
@@ -8,6 +8,8 @@
* Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 2002 Intel Corp.
* Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
+ * Copyright (C) 2005 Silicon Graphics, Inc
+ * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
*/
#ifndef _ASM_IA64_MCA_ASM_H
#define _ASM_IA64_MCA_ASM_H
@@ -207,106 +209,33 @@
;;
/*
- * The following offsets capture the order in which the
- * RSE related registers from the old context are
- * saved onto the new stack frame.
+ * The MCA and INIT stacks in struct ia64_mca_cpu look like normal kernel
+ * stacks, except that the SAL/OS state and a switch_stack are stored near the
+ * top of the MCA/INIT stack. To support concurrent entry to MCA or INIT, as
+ * well as MCA over INIT, each event needs its own SAL/OS state. All entries
+ * are 16 byte aligned.
*
- * +-----------------------+
- * |NDIRTY [BSP - BSPSTORE]|
- * +-----------------------+
- * | RNAT |
- * +-----------------------+
- * | BSPSTORE |
- * +-----------------------+
- * | IFS |
- * +-----------------------+
- * | PFS |
- * +-----------------------+
- * | RSC |
- * +-----------------------+ <-------- Bottom of new stack frame
+ * +---------------------------+
+ * | pt_regs |
+ * +---------------------------+
+ * | switch_stack |
+ * +---------------------------+
+ * | SAL/OS state |
+ * +---------------------------+
+ * | 16 byte scratch area |
+ * +---------------------------+ <-------- SP at start of C MCA handler
+ * | ..... |
+ * +---------------------------+
+ * | RBS for MCA/INIT handler |
+ * +---------------------------+
+ * | struct task for MCA/INIT |
+ * +---------------------------+ <-------- Bottom of MCA/INIT stack
*/
-#define rse_rsc_offset 0
-#define rse_pfs_offset (rse_rsc_offset+0x08)
-#define rse_ifs_offset (rse_pfs_offset+0x08)
-#define rse_bspstore_offset (rse_ifs_offset+0x08)
-#define rse_rnat_offset (rse_bspstore_offset+0x08)
-#define rse_ndirty_offset (rse_rnat_offset+0x08)
-/*
- * rse_switch_context
- *
- * 1. Save old RSC onto the new stack frame
- * 2. Save PFS onto new stack frame
- * 3. Cover the old frame and start a new frame.
- * 4. Save IFS onto new stack frame
- * 5. Save the old BSPSTORE on the new stack frame
- * 6. Save the old RNAT on the new stack frame
- * 7. Write BSPSTORE with the new backing store pointer
- * 8. Read and save the new BSP to calculate the #dirty registers
- * NOTE: Look at pages 11-10, 11-11 in PRM Vol 2
- */
-#define rse_switch_context(temp,p_stackframe,p_bspstore) \
- ;; \
- mov temp=ar.rsc;; \
- st8 [p_stackframe]=temp,8;; \
- mov temp=ar.pfs;; \
- st8 [p_stackframe]=temp,8; \
- cover ;; \
- mov temp=cr.ifs;; \
- st8 [p_stackframe]=temp,8;; \
- mov temp=ar.bspstore;; \
- st8 [p_stackframe]=temp,8;; \
- mov temp=ar.rnat;; \
- st8 [p_stackframe]=temp,8; \
- mov ar.bspstore=p_bspstore;; \
- mov temp=ar.bsp;; \
- sub temp=temp,p_bspstore;; \
- st8 [p_stackframe]=temp,8;;
-
-/*
- * rse_return_context
- * 1. Allocate a zero-sized frame
- * 2. Store the number of dirty registers RSC.loadrs field
- * 3. Issue a loadrs to insure that any registers from the interrupted
- * context which were saved on the new stack frame have been loaded
- * back into the stacked registers
- * 4. Restore BSPSTORE
- * 5. Restore RNAT
- * 6. Restore PFS
- * 7. Restore IFS
- * 8. Restore RSC
- * 9. Issue an RFI
- */
-#define rse_return_context(psr_mask_reg,temp,p_stackframe) \
- ;; \
- alloc temp=ar.pfs,0,0,0,0; \
- add p_stackframe=rse_ndirty_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- shl temp=temp,16;; \
- mov ar.rsc=temp;; \
- loadrs;; \
- add p_stackframe=-rse_ndirty_offset+rse_bspstore_offset,p_stackframe;;\
- ld8 temp=[p_stackframe];; \
- mov ar.bspstore=temp;; \
- add p_stackframe=-rse_bspstore_offset+rse_rnat_offset,p_stackframe;;\
- ld8 temp=[p_stackframe];; \
- mov ar.rnat=temp;; \
- add p_stackframe=-rse_rnat_offset+rse_pfs_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- mov ar.pfs=temp;; \
- add p_stackframe=-rse_pfs_offset+rse_ifs_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- mov cr.ifs=temp;; \
- add p_stackframe=-rse_ifs_offset+rse_rsc_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- mov ar.rsc=temp ; \
- mov temp=psr;; \
- or temp=temp,psr_mask_reg;; \
- mov cr.ipsr=temp;; \
- mov temp=ip;; \
- add temp=0x30,temp;; \
- mov cr.iip=temp;; \
- srlz.i;; \
- rfi;;
+#define ALIGN16(x) ((x)&~15)
+#define MCA_PT_REGS_OFFSET ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)
+#define MCA_SWITCH_STACK_OFFSET ALIGN16(MCA_PT_REGS_OFFSET-IA64_SWITCH_STACK_SIZE)
+#define MCA_SOS_OFFSET ALIGN16(MCA_SWITCH_STACK_OFFSET-IA64_SAL_OS_STATE_SIZE)
+#define MCA_SP_OFFSET ALIGN16(MCA_SOS_OFFSET-16)
#endif /* _ASM_IA64_MCA_ASM_H */
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index dba9f220be71..ef616fd4cb1b 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -156,6 +156,19 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev,
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/pgtable.h b/include/asm-ia64/pgtable.h
index 2e34c06e6777..3339c7b55a6f 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -443,10 +443,6 @@ extern void paging_init (void);
#define pte_to_pgoff(pte) ((pte_val(pte) << 1) >> 3)
#define pgoff_to_pte(off) ((pte_t) { ((off) << 2) | _PAGE_FILE })
-/* XXX is this right? */
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 0bef19538406..a79d1a7ecc77 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -57,7 +57,9 @@
#include <linux/config.h>
#include <asm/fpu.h>
-#include <asm/offsets.h>
+#ifndef ASM_OFFSETS_C
+#include <asm/asm-offsets.h>
+#endif
/*
* Base-2 logarithm of number of pages to allocate per task structure
@@ -119,7 +121,7 @@ struct pt_regs {
unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
unsigned long ar_pfs; /* prev function state */
unsigned long ar_rsc; /* RSE configuration */
- /* The following two are valid only if cr_ipsr.cpl > 0: */
+ /* The following two are valid only if cr_ipsr.cpl > 0 || ti->flags & _TIF_MCA_INIT */
unsigned long ar_rnat; /* RSE NaT */
unsigned long ar_bspstore; /* RSE bspstore */
diff --git a/include/asm-ia64/sn/sn_feature_sets.h b/include/asm-ia64/sn/sn_feature_sets.h
new file mode 100644
index 000000000000..e68a80853d5d
--- /dev/null
+++ b/include/asm-ia64/sn/sn_feature_sets.h
@@ -0,0 +1,57 @@
+#ifndef _ASM_IA64_SN_FEATURE_SETS_H
+#define _ASM_IA64_SN_FEATURE_SETS_H
+
+/*
+ * SN PROM Features
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <asm/types.h>
+#include <asm/bitops.h>
+
+/* --------------------- PROM Features -----------------------------*/
+extern int sn_prom_feature_available(int id);
+
+#define MAX_PROM_FEATURE_SETS 2
+
+/*
+ * The following defines features that may or may not be supported by the
+ * current PROM. The OS uses sn_prom_feature_available(feature) to test for
+ * the presence of a PROM feature. Down rev (old) PROMs will always test
+ * "false" for new features.
+ *
+ * Use:
+ * if (sn_prom_feature_available(PRF_FEATURE_XXX))
+ * ...
+ */
+
+/*
+ * Example: feature XXX
+ */
+#define PRF_FEATURE_XXX 0
+
+
+
+/* --------------------- OS Features -------------------------------*/
+
+/*
+ * The following defines OS features that are optionally present in
+ * the operating system.
+ * During boot, PROM is notified of these features via a series of calls:
+ *
+ * ia64_sn_set_os_feature(feature1);
+ *
+ * Once enabled, a feature cannot be disabled.
+ *
+ * By default, features are disabled unless explicitly enabled.
+ */
+#define OSF_MCA_SLV_TO_OS_INIT_SLV 0
+#define OSF_FEAT_LOG_SBES 1
+
+#endif /* _ASM_IA64_SN_FEATURE_SETS_H */
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index e67825ad1930..fea35b33d4e4 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -80,6 +80,9 @@
#define SN_SAL_RESERVED_DO_NOT_USE 0x02000062
#define SN_SAL_IOIF_GET_PCI_TOPOLOGY 0x02000064
+#define SN_SAL_GET_PROM_FEATURE_SET 0x02000065
+#define SN_SAL_SET_OS_FEATURE_SET 0x02000066
+
/*
* Service-specific constants
*/
@@ -118,8 +121,8 @@
/*
* Error Handling Features
*/
-#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1
-#define SAL_ERR_FEAT_LOG_SBES 0x2
+#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1 // obsolete
+#define SAL_ERR_FEAT_LOG_SBES 0x2 // obsolete
#define SAL_ERR_FEAT_MFR_OVERRIDE 0x4
#define SAL_ERR_FEAT_SBE_THRESHOLD 0xffff0000
@@ -152,12 +155,6 @@ sn_sal_rev(void)
}
/*
- * Specify the minimum PROM revsion required for this kernel.
- * Note that they're stored in hex format...
- */
-#define SN_SAL_MIN_VERSION 0x0404
-
-/*
* Returns the master console nasid, if the call fails, return an illegal
* value.
*/
@@ -336,7 +333,7 @@ ia64_sn_plat_cpei_handler(void)
}
/*
- * Set Error Handling Features
+ * Set Error Handling Features (Obsolete)
*/
static inline u64
ia64_sn_plat_set_error_handling_features(void)
@@ -1052,4 +1049,25 @@ ia64_sn_is_fake_prom(void)
return (rv.status == 0);
}
+static inline int
+ia64_sn_get_prom_feature_set(int set, unsigned long *feature_set)
+{
+ struct ia64_sal_retval rv;
+
+ SAL_CALL_NOLOCK(rv, SN_SAL_GET_PROM_FEATURE_SET, set, 0, 0, 0, 0, 0, 0);
+ if (rv.status != 0)
+ return rv.status;
+ *feature_set = rv.v0;
+ return 0;
+}
+
+static inline int
+ia64_sn_set_os_feature(int feature)
+{
+ struct ia64_sal_retval rv;
+
+ SAL_CALL_NOLOCK(rv, SN_SAL_SET_OS_FEATURE_SET, feature, 0, 0, 0, 0, 0, 0);
+ return rv.status;
+}
+
#endif /* _ASM_IA64_SN_SN_SAL_H */
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index d2430aa0d49d..5b78611411c3 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -17,28 +17,20 @@
#include <asm/intrinsics.h>
#include <asm/system.h>
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-#define spin_lock_init(x) ((x)->lock = 0)
+#define __raw_spin_lock_init(x) ((x)->lock = 0)
#ifdef ASM_SUPPORTED
/*
* Try to get the lock. If we fail to get the lock, make a non-standard call to
* ia64_spinlock_contention(). We do not use a normal call because that would force all
- * callers of spin_lock() to be non-leaf routines. Instead, ia64_spinlock_contention() is
- * carefully coded to touch only those registers that spin_lock() marks "clobbered".
+ * callers of __raw_spin_lock() to be non-leaf routines. Instead, ia64_spinlock_contention() is
+ * carefully coded to touch only those registers that __raw_spin_lock() marks "clobbered".
*/
#define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "p15", "r27", "r28", "r29", "r30", "b6", "memory"
static inline void
-_raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
+__raw_spin_lock_flags (raw_spinlock_t *lock, unsigned long flags)
{
register volatile unsigned int *ptr asm ("r31") = &lock->lock;
@@ -94,17 +86,17 @@ _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
#endif
}
-#define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0)
+#define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0)
/* Unlock by doing an ordered store and releasing the cacheline with nta */
-static inline void _raw_spin_unlock(spinlock_t *x) {
+static inline void __raw_spin_unlock(raw_spinlock_t *x) {
barrier();
asm volatile ("st4.rel.nta [%0] = r0\n\t" :: "r"(x));
}
#else /* !ASM_SUPPORTED */
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
-# define _raw_spin_lock(x) \
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+# define __raw_spin_lock(x) \
do { \
__u32 *ia64_spinlock_ptr = (__u32 *) (x); \
__u64 ia64_spinlock_val; \
@@ -117,29 +109,20 @@ do { \
} while (ia64_spinlock_val); \
} \
} while (0)
-#define _raw_spin_unlock(x) do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0)
+#define __raw_spin_unlock(x) do { barrier(); ((raw_spinlock_t *) x)->lock = 0; } while (0)
#endif /* !ASM_SUPPORTED */
-#define spin_is_locked(x) ((x)->lock != 0)
-#define _raw_spin_trylock(x) (cmpxchg_acq(&(x)->lock, 0, 1) == 0)
-#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock)
-
-typedef struct {
- volatile unsigned int read_counter : 24;
- volatile unsigned int write_lock : 8;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_trylock(x) (cmpxchg_acq(&(x)->lock, 0, 1) == 0)
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#define read_can_lock(rw) (*(volatile int *)(rw) >= 0)
-#define write_can_lock(rw) (*(volatile int *)(rw) == 0)
+#define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0)
+#define __raw_write_can_lock(rw) (*(volatile int *)(rw) == 0)
-#define _raw_read_lock(rw) \
+#define __raw_read_lock(rw) \
do { \
- rwlock_t *__read_lock_ptr = (rw); \
+ raw_rwlock_t *__read_lock_ptr = (rw); \
\
while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) { \
ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
@@ -148,14 +131,14 @@ do { \
} \
} while (0)
-#define _raw_read_unlock(rw) \
+#define __raw_read_unlock(rw) \
do { \
- rwlock_t *__read_lock_ptr = (rw); \
+ raw_rwlock_t *__read_lock_ptr = (rw); \
ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
} while (0)
#ifdef ASM_SUPPORTED
-#define _raw_write_lock(rw) \
+#define __raw_write_lock(rw) \
do { \
__asm__ __volatile__ ( \
"mov ar.ccv = r0\n" \
@@ -170,7 +153,7 @@ do { \
:: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \
} while(0)
-#define _raw_write_trylock(rw) \
+#define __raw_write_trylock(rw) \
({ \
register long result; \
\
@@ -182,7 +165,7 @@ do { \
(result == 0); \
})
-static inline void _raw_write_unlock(rwlock_t *x)
+static inline void __raw_write_unlock(raw_rwlock_t *x)
{
u8 *y = (u8 *)x;
barrier();
@@ -191,7 +174,7 @@ static inline void _raw_write_unlock(rwlock_t *x)
#else /* !ASM_SUPPORTED */
-#define _raw_write_lock(l) \
+#define __raw_write_lock(l) \
({ \
__u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
__u32 *ia64_write_lock_ptr = (__u32 *) (l); \
@@ -202,7 +185,7 @@ static inline void _raw_write_unlock(rwlock_t *x)
} while (ia64_val); \
})
-#define _raw_write_trylock(rw) \
+#define __raw_write_trylock(rw) \
({ \
__u64 ia64_val; \
__u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1); \
@@ -210,7 +193,7 @@ static inline void _raw_write_unlock(rwlock_t *x)
(ia64_val == 0); \
})
-static inline void _raw_write_unlock(rwlock_t *x)
+static inline void __raw_write_unlock(raw_rwlock_t *x)
{
barrier();
x->write_lock = 0;
@@ -218,6 +201,6 @@ static inline void _raw_write_unlock(rwlock_t *x)
#endif /* !ASM_SUPPORTED */
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
#endif /* _ASM_IA64_SPINLOCK_H */
diff --git a/include/asm-ia64/spinlock_types.h b/include/asm-ia64/spinlock_types.h
new file mode 100644
index 000000000000..474e46f1ab4a
--- /dev/null
+++ b/include/asm-ia64/spinlock_types.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_IA64_SPINLOCK_TYPES_H
+#define _ASM_IA64_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int read_counter : 31;
+ volatile unsigned int write_lock : 1;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0, 0 }
+
+#endif
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 33256db4a7cf..635235fa1e32 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -275,6 +275,7 @@ extern void ia64_load_extra (struct task_struct *task);
*/
#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-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index 7dc8951708a3..171b2207bde4 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -5,7 +5,9 @@
#ifndef _ASM_IA64_THREAD_INFO_H
#define _ASM_IA64_THREAD_INFO_H
-#include <asm/offsets.h>
+#ifndef ASM_OFFSETS_C
+#include <asm/asm-offsets.h>
+#endif
#include <asm/processor.h>
#include <asm/ptrace.h>
@@ -51,9 +53,14 @@ struct thread_info {
}, \
}
+#ifndef ASM_OFFSETS_C
/* how to get the thread information struct from C */
#define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
#define alloc_thread_info(tsk) ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
+#else
+#define current_thread_info() ((struct thread_info *) 0)
+#define alloc_thread_info(tsk) ((struct thread_info *) 0)
+#endif
#define free_thread_info(ti) /* nothing */
#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
@@ -76,6 +83,7 @@ struct thread_info {
#define TIF_SIGDELAYED 5 /* signal delayed from MCA/INIT/NMI/PMI context */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17
+#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
@@ -85,6 +93,7 @@ struct thread_info {
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SIGDELAYED (1 << TIF_SIGDELAYED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
/* "work to do on user-return" bits */
#define TIF_ALLWORK_MASK (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SIGDELAYED)
diff --git a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
index 3a7829bb5954..9adb51211c22 100644
--- a/include/asm-ia64/uaccess.h
+++ b/include/asm-ia64/uaccess.h
@@ -187,8 +187,8 @@ extern void __get_user_unknown (void);
({ \
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
__typeof__ (size) __gu_size = (size); \
- long __gu_err = -EFAULT, __gu_val = 0; \
- \
+ long __gu_err = -EFAULT; \
+ unsigned long __gu_val = 0; \
if (!check || __access_ok(__gu_ptr, size, segment)) \
switch (__gu_size) { \
case 1: __get_user_size(__gu_val, __gu_ptr, 1, __gu_err); break; \
@@ -240,13 +240,13 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use
static inline unsigned long
__copy_to_user (void __user *to, const void *from, unsigned long count)
{
- return __copy_user(to, (void __user *) from, count);
+ return __copy_user(to, (__force void __user *) from, count);
}
static inline unsigned long
__copy_from_user (void *to, const void __user *from, unsigned long count)
{
- return __copy_user((void __user *) to, from, count);
+ return __copy_user((__force void __user *) to, from, count);
}
#define __copy_to_user_inatomic __copy_to_user
@@ -258,7 +258,7 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
long __cu_len = (n); \
\
if (__access_ok(__cu_to, __cu_len, get_fs())) \
- __cu_len = __copy_user(__cu_to, (void __user *) __cu_from, __cu_len); \
+ __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
__cu_len; \
})
@@ -270,7 +270,7 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
\
__chk_user_ptr(__cu_from); \
if (__access_ok(__cu_from, __cu_len, get_fs())) \
- __cu_len = __copy_user((void __user *) __cu_to, __cu_from, __cu_len); \
+ __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
__cu_len; \
})
diff --git a/include/asm-ia64/unwind.h b/include/asm-ia64/unwind.h
index 61426ad3ecdb..5df0276b0493 100644
--- a/include/asm-ia64/unwind.h
+++ b/include/asm-ia64/unwind.h
@@ -114,13 +114,6 @@ extern void unw_remove_unwind_table (void *handle);
*/
extern void unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t);
-/*
- * Prepare to unwind from interruption. The pt-regs and switch-stack structures must have
- * be "adjacent" (no state modifications between pt-regs and switch-stack).
- */
-extern void unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t,
- struct pt_regs *pt, struct switch_stack *sw);
-
extern void unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t,
struct switch_stack *sw);
diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index 3a2db28834b6..a7fa0302bda7 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -8,7 +8,7 @@
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
return (void *)NULL;
}
diff --git a/include/asm-m32r/futex.h b/include/asm-m32r/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-m32r/futex.h
+++ b/include/asm-m32r/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-m32r/io.h b/include/asm-m32r/io.h
index 8e9e481e6996..70ad1c949c2b 100644
--- a/include/asm-m32r/io.h
+++ b/include/asm-m32r/io.h
@@ -60,7 +60,7 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
* address.
*/
-static inline void * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index da805e970844..388e5ee9fa27 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -378,9 +378,6 @@ static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
#define kern_addr_valid(addr) (1)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-m32r/spinlock.h b/include/asm-m32r/spinlock.h
index 6608d8371c50..7de7def28da9 100644
--- a/include/asm-m32r/spinlock.h
+++ b/include/asm-m32r/spinlock.h
@@ -14,57 +14,30 @@
#include <asm/atomic.h>
#include <asm/page.h>
-extern int printk(const char * fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-#define RW_LOCK_BIAS 0x01000000
-#define RW_LOCK_BIAS_STR "0x01000000"
-
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
- */
-
-typedef struct {
- volatile int slock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned magic;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define SPINLOCK_MAGIC 0xdead4ead
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC
-#else
-#define SPINLOCK_MAGIC_INIT /* */
-#endif
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-/*
+ *
+ * (the type definitions are in asm/spinlock_types.h)
+ *
* Simple spin lock operations. There are two variants, one clears IRQ's
* on the local processor, one does not.
*
* We make no fairness assumptions. They have a cost.
*/
-#define spin_is_locked(x) (*(volatile int *)(&(x)->slock) <= 0)
-#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_is_locked(x) (*(volatile int *)(&(x)->slock) <= 0)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_unlock_wait(x) \
+ do { cpu_relax(); } while (__raw_spin_is_locked(x))
/**
- * _raw_spin_trylock - Try spin lock and return a result
+ * __raw_spin_trylock - Try spin lock and return a result
* @lock: Pointer to the lock variable
*
- * _raw_spin_trylock() tries to get the lock and returns a result.
+ * __raw_spin_trylock() tries to get the lock and returns a result.
* On the m32r, the result value is 1 (= Success) or 0 (= Failure).
*/
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
int oldval;
unsigned long tmp1, tmp2;
@@ -78,7 +51,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
* }
*/
__asm__ __volatile__ (
- "# spin_trylock \n\t"
+ "# __raw_spin_trylock \n\t"
"ldi %1, #0; \n\t"
"mvfc %2, psw; \n\t"
"clrpsw #0x40 -> nop; \n\t"
@@ -97,16 +70,10 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
return (oldval > 0);
}
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned long tmp0, tmp1;
-#ifdef CONFIG_DEBUG_SPINLOCK
- if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
- printk("pc: %p\n", __builtin_return_address(0));
- BUG();
- }
-#endif
/*
* lock->slock : =1 : unlock
* : <=0 : lock
@@ -118,7 +85,7 @@ static inline void _raw_spin_lock(spinlock_t *lock)
* }
*/
__asm__ __volatile__ (
- "# spin_lock \n\t"
+ "# __raw_spin_lock \n\t"
".fillinsn \n"
"1: \n\t"
"mvfc %1, psw; \n\t"
@@ -145,12 +112,8 @@ static inline void _raw_spin_lock(spinlock_t *lock)
);
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(lock->magic != SPINLOCK_MAGIC);
- BUG_ON(!spin_is_locked(lock));
-#endif
mb();
lock->slock = 1;
}
@@ -164,59 +127,32 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
* can "mix" irq-safe locks - any writer needs to get a
* irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
+ *
+ * On x86, we implement read-write locks as a 32-bit counter
+ * with the high bit (sign) being the "contended" bit.
+ *
+ * The inline assembly is non-obvious. Think about it.
+ *
+ * Changed to use the same technique as rw semaphores. See
+ * semaphore.h for details. -ben
*/
-typedef struct {
- volatile int lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned magic;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RWLOCK_MAGIC 0xdeaf1eed
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC
-#else
-#define RWLOCK_MAGIC_INIT /* */
-#endif
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
/**
* read_can_lock - would read_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define read_can_lock(x) ((int)(x)->lock > 0)
+#define __raw_read_can_lock(x) ((int)(x)->lock > 0)
/**
* write_can_lock - would write_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-
-/*
- * On x86, we implement read-write locks as a 32-bit counter
- * with the high bit (sign) being the "contended" bit.
- *
- * The inline assembly is non-obvious. Think about it.
- *
- * Changed to use the same technique as rw semaphores. See
- * semaphore.h for details. -ben
- */
-/* the spinlock helpers are in arch/i386/kernel/semaphore.c */
+#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-static inline void _raw_read_lock(rwlock_t *rw)
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned long tmp0, tmp1;
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(rw->magic != RWLOCK_MAGIC);
-#endif
/*
* rw->lock : >0 : unlock
* : <=0 : lock
@@ -264,13 +200,10 @@ static inline void _raw_read_lock(rwlock_t *rw)
);
}
-static inline void _raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
unsigned long tmp0, tmp1, tmp2;
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(rw->magic != RWLOCK_MAGIC);
-#endif
/*
* rw->lock : =RW_LOCK_BIAS_STR : unlock
* : !=RW_LOCK_BIAS_STR : lock
@@ -320,7 +253,7 @@ static inline void _raw_write_lock(rwlock_t *rw)
);
}
-static inline void _raw_read_unlock(rwlock_t *rw)
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned long tmp0, tmp1;
@@ -342,7 +275,7 @@ static inline void _raw_read_unlock(rwlock_t *rw)
);
}
-static inline void _raw_write_unlock(rwlock_t *rw)
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
unsigned long tmp0, tmp1, tmp2;
@@ -366,9 +299,9 @@ static inline void _raw_write_unlock(rwlock_t *rw)
);
}
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
-static inline int _raw_write_trylock(rwlock_t *lock)
+static inline int __raw_write_trylock(raw_rwlock_t *lock)
{
atomic_t *count = (atomic_t *)lock;
if (atomic_sub_and_test(RW_LOCK_BIAS, count))
diff --git a/include/asm-m32r/spinlock_types.h b/include/asm-m32r/spinlock_types.h
new file mode 100644
index 000000000000..7e9941c45f40
--- /dev/null
+++ b/include/asm-m32r/spinlock_types.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_M32R_SPINLOCK_TYPES_H
+#define _ASM_M32R_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile int slock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+
+typedef struct {
+ volatile int lock;
+} raw_rwlock_t;
+
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
+
+#endif
diff --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h
index 93d863c455a1..0da7c47d2f01 100644
--- a/include/asm-m32r/uaccess.h
+++ b/include/asm-m32r/uaccess.h
@@ -208,7 +208,8 @@ extern void __get_user_4(void);
* On error, the variable @x is set to zero.
*/
#define get_user(x,ptr) \
-({ int __ret_gu,__val_gu; \
+({ int __ret_gu; \
+ unsigned long __val_gu; \
__chk_user_ptr(ptr); \
switch(sizeof (*(ptr))) { \
case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
@@ -403,7 +404,8 @@ struct __large_struct { unsigned long buf[100]; };
#define __get_user_nocheck(x,ptr,size) \
({ \
- long __gu_err, __gu_val; \
+ long __gu_err; \
+ unsigned long __gu_val; \
__get_user_size(__gu_val,(ptr),(size),__gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
@@ -594,8 +596,8 @@ static inline unsigned long __generic_copy_to_user_nocheck(void __user *to,
return n;
}
-unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
-unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
+unsigned long __generic_copy_to_user(void __user *, const void *, unsigned long);
+unsigned long __generic_copy_from_user(void *, const void __user *, unsigned long);
/**
* __copy_to_user: - Copy a block of data into user space, with less checking.
diff --git a/include/asm-m68k/futex.h b/include/asm-m68k/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-m68k/futex.h
+++ b/include/asm-m68k/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index 0c87fc84f7a4..add129e93fd7 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -141,9 +141,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
#define kern_addr_valid(addr) (1)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index f95e32b40425..c42f88a9b9f9 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -259,7 +259,7 @@ static __inline__ int __test_bit(int nr, const volatile unsigned long * addr)
#define find_first_bit(addr, size) \
find_next_bit((addr), (size), 0)
-static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+static __inline__ int find_next_zero_bit (const void * addr, int size, int offset)
{
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
unsigned long result = offset & ~31UL;
diff --git a/include/asm-m68knommu/cacheflush.h b/include/asm-m68knommu/cacheflush.h
index aa7a2ffa41af..026bbc9565b4 100644
--- a/include/asm-m68knommu/cacheflush.h
+++ b/include/asm-m68knommu/cacheflush.h
@@ -2,23 +2,23 @@
#define _M68KNOMMU_CACHEFLUSH_H
/*
- * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
+ * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com>
*/
#include <linux/mm.h>
#define flush_cache_all() __flush_cache_all()
#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_dcache_range(start,len) do { } while (0)
+#define flush_cache_range(vma, start, end) __flush_cache_all()
+#define flush_cache_page(vma, vmaddr) do { } while (0)
+#define flush_dcache_range(start,len) __flush_cache_all()
#define flush_dcache_page(page) do { } while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
#define flush_icache_range(start,len) __flush_cache_all()
#define flush_icache_page(vma,pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
-#define flush_cache_vmap(start, end) flush_cache_all()
-#define flush_cache_vunmap(start, end) flush_cache_all()
+#define flush_cache_vmap(start, end) do { } while (0)
+#define flush_cache_vunmap(start, end) do { } while (0)
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
@@ -50,22 +50,23 @@ extern inline void __flush_cache_all(void)
"movec %%d0,%%CACR\n\t"
: : : "d0", "a0" );
#endif /* CONFIG_M5407 */
-#ifdef CONFIG_M5272
+#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
__asm__ __volatile__ (
- "movel #0x01000000, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
- "nop\n\t"
- "movel #0x80000100, %%d0\n\t"
+ "movel #0x81400100, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
: : : "d0" );
-#endif /* CONFIG_M5272 */
-#if 0 /* CONFIG_M5249 */
+#endif /* CONFIG_M527x || CONFIG_M528x */
+#ifdef CONFIG_M5272
__asm__ __volatile__ (
"movel #0x01000000, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- "movel #0xa0000200, %%d0\n\t"
+ : : : "d0" );
+#endif /* CONFIG_M5272 */
+#if CONFIG_M5249
+ __asm__ __volatile__ (
+ "movel #0xa1000200, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
: : : "d0" );
diff --git a/include/asm-m68knommu/checksum.h b/include/asm-m68knommu/checksum.h
index 92cf102c2534..294ec7583ac9 100644
--- a/include/asm-m68knommu/checksum.h
+++ b/include/asm-m68knommu/checksum.h
@@ -25,7 +25,8 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
* better 64-bit) boundary
*/
-unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
+ int len, int sum);
/*
@@ -35,8 +36,8 @@ unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
* better 64-bit) boundary
*/
-extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
- int len, int sum, int *csum_err);
+extern unsigned int csum_partial_copy_from_user(const unsigned char *src,
+ unsigned char *dst, int len, int sum, int *csum_err);
#define csum_partial_copy_nocheck(src, dst, len, sum) \
csum_partial_copy((src), (dst), (len), (sum))
diff --git a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
index 16f32cc80c40..1df3f666a28e 100644
--- a/include/asm-m68knommu/coldfire.h
+++ b/include/asm-m68knommu/coldfire.h
@@ -22,7 +22,7 @@
#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/futex.h b/include/asm-m68knommu/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-m68knommu/futex.h
+++ b/include/asm-m68knommu/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-m68knommu/m523xsim.h b/include/asm-m68knommu/m523xsim.h
new file mode 100644
index 000000000000..926cfb805df7
--- /dev/null
+++ b/include/asm-m68knommu/m523xsim.h
@@ -0,0 +1,46 @@
+/****************************************************************************/
+
+/*
+ * 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/m527xsim.h b/include/asm-m68knommu/m527xsim.h
index d280d013da03..e7878d0f7d7a 100644
--- a/include/asm-m68knommu/m527xsim.h
+++ b/include/asm-m68knommu/m527xsim.h
@@ -37,13 +37,14 @@
/*
* SDRAM configuration registers.
*/
-#ifdef CONFIG_M5271EVB
+#ifdef CONFIG_M5271
#define MCFSIM_DCR 0x40 /* 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 */
-#else
+#endif
+#ifdef CONFIG_M5275
#define MCFSIM_DMR 0x40 /* SDRAM mode */
#define MCFSIM_DCR 0x44 /* SDRAM control */
#define MCFSIM_DCFG1 0x48 /* SDRAM configuration 1 */
@@ -54,5 +55,21 @@
#define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */
#endif
+/*
+ * GPIO pins setups to enable the UARTs.
+ */
+#ifdef CONFIG_M5271
+#define MCF_GPIO_PAR_UART 0x100048 /* PAR UART address */
+#define UART0_ENABLE_MASK 0x000f
+#define UART1_ENABLE_MASK 0x0ff0
+#define UART2_ENABLE_MASK 0x3000
+#endif
+#ifdef CONFIG_M5275
+#define MCF_GPIO_PAR_UART 0x10007c /* PAR UART address */
+#define UART0_ENABLE_MASK 0x000f
+#define UART1_ENABLE_MASK 0x00f0
+#define UART2_ENABLE_MASK 0x3f00
+#endif
+
/****************************************************************************/
#endif /* m527xsim_h */
diff --git a/include/asm-m68knommu/m528xsim.h b/include/asm-m68knommu/m528xsim.h
index 371993a206ac..610774a17f70 100644
--- a/include/asm-m68knommu/m528xsim.h
+++ b/include/asm-m68knommu/m528xsim.h
@@ -41,5 +41,117 @@
#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */
#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
+/*
+ * Derek Cheung - 6 Feb 2005
+ * add I2C and QSPI register definition using Freescale's MCF5282
+ */
+/* set Port AS pin for I2C or UART */
+#define MCF5282_GPIO_PASPAR (volatile u16 *) (MCF_IPSBAR + 0x00100056)
+
+/* Interrupt Mask Register Register Low */
+#define MCF5282_INTC0_IMRL (volatile u32 *) (MCF_IPSBAR + 0x0C0C)
+/* Interrupt Control Register 7 */
+#define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51)
+
+
+
+/*********************************************************************
+*
+* Inter-IC (I2C) Module
+*
+*********************************************************************/
+/* Read/Write access macros for general use */
+#define MCF5282_I2C_I2ADR (volatile u8 *) (MCF_IPSBAR + 0x0300) // Address
+#define MCF5282_I2C_I2FDR (volatile u8 *) (MCF_IPSBAR + 0x0304) // Freq Divider
+#define MCF5282_I2C_I2CR (volatile u8 *) (MCF_IPSBAR + 0x0308) // Control
+#define MCF5282_I2C_I2SR (volatile u8 *) (MCF_IPSBAR + 0x030C) // Status
+#define MCF5282_I2C_I2DR (volatile u8 *) (MCF_IPSBAR + 0x0310) // Data I/O
+
+/* Bit level definitions and macros */
+#define MCF5282_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01)
+
+#define MCF5282_I2C_I2FDR_IC(x) (((x)&0x3F))
+
+#define MCF5282_I2C_I2CR_IEN (0x80) // I2C enable
+#define MCF5282_I2C_I2CR_IIEN (0x40) // interrupt enable
+#define MCF5282_I2C_I2CR_MSTA (0x20) // master/slave mode
+#define MCF5282_I2C_I2CR_MTX (0x10) // transmit/receive mode
+#define MCF5282_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable
+#define MCF5282_I2C_I2CR_RSTA (0x04) // repeat start
+
+#define MCF5282_I2C_I2SR_ICF (0x80) // data transfer bit
+#define MCF5282_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave
+#define MCF5282_I2C_I2SR_IBB (0x20) // I2C bus busy
+#define MCF5282_I2C_I2SR_IAL (0x10) // aribitration lost
+#define MCF5282_I2C_I2SR_SRW (0x04) // slave read/write
+#define MCF5282_I2C_I2SR_IIF (0x02) // I2C interrupt
+#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge
+
+
+
+/*********************************************************************
+*
+* Queued Serial Peripheral Interface (QSPI) Module
+*
+*********************************************************************/
+/* Derek - 21 Feb 2005 */
+/* change to the format used in I2C */
+/* Read/Write access macros for general use */
+#define MCF5282_QSPI_QMR MCF_IPSBAR + 0x0340
+#define MCF5282_QSPI_QDLYR MCF_IPSBAR + 0x0344
+#define MCF5282_QSPI_QWR MCF_IPSBAR + 0x0348
+#define MCF5282_QSPI_QIR MCF_IPSBAR + 0x034C
+#define MCF5282_QSPI_QAR MCF_IPSBAR + 0x0350
+#define MCF5282_QSPI_QDR MCF_IPSBAR + 0x0354
+#define MCF5282_QSPI_QCR MCF_IPSBAR + 0x0354
+
+/* Bit level definitions and macros */
+#define MCF5282_QSPI_QMR_MSTR (0x8000)
+#define MCF5282_QSPI_QMR_DOHIE (0x4000)
+#define MCF5282_QSPI_QMR_BITS_16 (0x0000)
+#define MCF5282_QSPI_QMR_BITS_8 (0x2000)
+#define MCF5282_QSPI_QMR_BITS_9 (0x2400)
+#define MCF5282_QSPI_QMR_BITS_10 (0x2800)
+#define MCF5282_QSPI_QMR_BITS_11 (0x2C00)
+#define MCF5282_QSPI_QMR_BITS_12 (0x3000)
+#define MCF5282_QSPI_QMR_BITS_13 (0x3400)
+#define MCF5282_QSPI_QMR_BITS_14 (0x3800)
+#define MCF5282_QSPI_QMR_BITS_15 (0x3C00)
+#define MCF5282_QSPI_QMR_CPOL (0x0200)
+#define MCF5282_QSPI_QMR_CPHA (0x0100)
+#define MCF5282_QSPI_QMR_BAUD(x) (((x)&0x00FF))
+
+#define MCF5282_QSPI_QDLYR_SPE (0x80)
+#define MCF5282_QSPI_QDLYR_QCD(x) (((x)&0x007F)<<8)
+#define MCF5282_QSPI_QDLYR_DTL(x) (((x)&0x00FF))
+
+#define MCF5282_QSPI_QWR_HALT (0x8000)
+#define MCF5282_QSPI_QWR_WREN (0x4000)
+#define MCF5282_QSPI_QWR_WRTO (0x2000)
+#define MCF5282_QSPI_QWR_CSIV (0x1000)
+#define MCF5282_QSPI_QWR_ENDQP(x) (((x)&0x000F)<<8)
+#define MCF5282_QSPI_QWR_CPTQP(x) (((x)&0x000F)<<4)
+#define MCF5282_QSPI_QWR_NEWQP(x) (((x)&0x000F))
+
+#define MCF5282_QSPI_QIR_WCEFB (0x8000)
+#define MCF5282_QSPI_QIR_ABRTB (0x4000)
+#define MCF5282_QSPI_QIR_ABRTL (0x1000)
+#define MCF5282_QSPI_QIR_WCEFE (0x0800)
+#define MCF5282_QSPI_QIR_ABRTE (0x0400)
+#define MCF5282_QSPI_QIR_SPIFE (0x0100)
+#define MCF5282_QSPI_QIR_WCEF (0x0008)
+#define MCF5282_QSPI_QIR_ABRT (0x0004)
+#define MCF5282_QSPI_QIR_SPIF (0x0001)
+
+#define MCF5282_QSPI_QAR_ADDR(x) (((x)&0x003F))
+
+#define MCF5282_QSPI_QDR_COMMAND(x) (((x)&0xFF00))
+#define MCF5282_QSPI_QCR_DATA(x) (((x)&0x00FF)<<8)
+#define MCF5282_QSPI_QCR_CONT (0x8000)
+#define MCF5282_QSPI_QCR_BITSE (0x4000)
+#define MCF5282_QSPI_QCR_DT (0x2000)
+#define MCF5282_QSPI_QCR_DSCK (0x1000)
+#define MCF5282_QSPI_QCR_CS (((x)&0x000F)<<8)
+
/****************************************************************************/
#endif /* m528xsim_h */
diff --git a/include/asm-m68knommu/mcfcache.h b/include/asm-m68knommu/mcfcache.h
index bdd8c53ef34c..b17cd920977f 100644
--- a/include/asm-m68knommu/mcfcache.h
+++ b/include/asm-m68knommu/mcfcache.h
@@ -33,7 +33,7 @@
.endm
#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */
-#if defined(CONFIG_M527x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x)
/*
* New version 2 cores have a configurable split cache arrangement.
* For now I am just enabling instruction cache - but ultimately I
@@ -51,23 +51,20 @@
movec %d0,%CACR /* enable cache */
nop
.endm
-#endif /* CONFIG_M527x */
+#endif /* CONFIG_M523x || CONFIG_M527x */
#if defined(CONFIG_M528x)
-/*
- * Cache is totally broken on early 5282 silicon. So far now we
- * disable its cache all together.
- */
.macro CACHE_ENABLE
- movel #0x01000000,%d0
- movec %d0,%CACR /* invalidate cache */
nop
- movel #0x0000c000,%d0 /* set SDRAM cached only */
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0x00000000,%d0 /* configure cache */
- movec %d0,%CACR /* enable cache */
+ movel #0x01000000, %d0
+ movec %d0, %CACR /* Invalidate cache */
+ nop
+ movel #0x0000c020, %d0 /* Set SDRAM cached only */
+ movec %d0, %ACR0
+ movel #0xff00c000, %d0 /* Cache Flash also */
+ movec %d0, %ACR1
+ movel #0x80000200, %d0 /* Setup cache mask */
+ movec %d0, %CACR /* Enable cache */
nop
.endm
#endif /* CONFIG_M528x */
diff --git a/include/asm-m68knommu/mcfdma.h b/include/asm-m68knommu/mcfdma.h
index 350c6090b5c1..b93f8ba8a248 100644
--- a/include/asm-m68knommu/mcfdma.h
+++ b/include/asm-m68knommu/mcfdma.h
@@ -21,7 +21,7 @@
#define MCFDMA_BASE1 0x240 /* Base address of DMA 1 */
#elif defined(CONFIG_M5272)
#define MCFDMA_BASE0 0x0e0 /* Base address of DMA 0 */
-#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
/* These are relative to the IPSBAR, not MBAR */
#define MCFDMA_BASE0 0x100 /* Base address of DMA 0 */
#define MCFDMA_BASE1 0x140 /* Base address of DMA 1 */
diff --git a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
index 522e513c2bc6..b0c7736f7a99 100644
--- a/include/asm-m68knommu/mcfsim.h
+++ b/include/asm-m68knommu/mcfsim.h
@@ -15,13 +15,15 @@
#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 54d4a85f4fdf..9c1210613bc7 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-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
index e2a69fffa370..00893055e6c2 100644
--- a/include/asm-m68knommu/pgtable.h
+++ b/include/asm-m68knommu/pgtable.h
@@ -56,8 +56,6 @@ extern int is_in_rom(unsigned long);
* No page table caches to initialise.
*/
#define pgtable_cache_init() do { } while (0)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 230b8d56d17f..12309b181d29 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -1,6 +1,8 @@
#ifndef _M68KNOMMU_SCATTERLIST_H
#define _M68KNOMMU_SCATTERLIST_H
+#include <linux/mm.h>
+
struct scatterlist {
struct page *page;
unsigned int offset;
@@ -8,6 +10,10 @@ struct scatterlist {
unsigned int length;
};
+#define sg_address(sg) (page_address((sg)->page) + (sg)->offset
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
#define ISA_DMA_THRESHOLD (0xffffffff)
#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index c341b66c147b..53cbbad0f130 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -57,9 +57,18 @@ asmlinkage void resume(void);
: "cc", "%d0", "memory")
#define local_irq_disable() __asm__ __volatile__ ( \
"move %/sr,%%d0\n\t" \
- "ori.l #0x0700,%%d0\n\t" \
+ "ori.l #0x0700,%%d0\n\t" \
"move %%d0,%/sr\n" \
- : /* no inputs */ \
+ : /* no outputs */ \
+ : \
+ : "cc", "%d0", "memory")
+/* For spinlocks etc */
+#define local_irq_save(x) __asm__ __volatile__ ( \
+ "movew %%sr,%0\n\t" \
+ "movew #0x0700,%%d0\n\t" \
+ "or.l %0,%%d0\n\t" \
+ "movew %%d0,%/sr" \
+ : "=d" (x) \
: \
: "cc", "%d0", "memory")
#else
@@ -75,7 +84,9 @@ asmlinkage void resume(void);
#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
/* For spinlocks etc */
+#ifndef local_irq_save
#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0)
+#endif
#define irqs_disabled() \
({ \
@@ -234,9 +245,9 @@ cmpxchg(volatile int *p, int old, int new)
#ifdef CONFIG_COLDFIRE
#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
/*
- * Need to account for broken early mask of 5272 silicon. So don't
- * jump through the original start address. Jump strait into the
- * known start of the FLASH code.
+ * Need to account for broken early mask of 5272 silicon. So don't
+ * jump through the original start address. Jump strait into the
+ * known start of the FLASH code.
*/
#define HARD_RESET_NOW() ({ \
asm(" \
@@ -244,7 +255,9 @@ cmpxchg(volatile int *p, int old, int new)
jmp 0xf0000400; \
"); \
})
-#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
+#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+ defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+ defined(CONFIG_CLEOPATRA)
#define HARD_RESET_NOW() ({ \
asm(" \
movew #0x2700, %sr; \
@@ -257,6 +270,26 @@ cmpxchg(volatile int *p, int old, int new)
jmp (%a0); \
"); \
})
+#elif defined(CONFIG_M5272)
+/*
+ * Retrieve the boot address in flash using CSBR0 and CSOR0
+ * find the reset vector at flash_address + 4 (e.g. 0x400)
+ * remap it in the flash's current location (e.g. 0xf0000400)
+ * and jump there.
+ */
+#define HARD_RESET_NOW() ({ \
+ asm(" \
+ movew #0x2700, %%sr; \
+ move.l %0+0x40,%%d0; \
+ and.l %0+0x44,%%d0; \
+ andi.l #0xfffff000,%%d0; \
+ mov.l %%d0,%%a0; \
+ or.l 4(%%a0),%%d0; \
+ mov.l %%d0,%%a0; \
+ jmp (%%a0);" \
+ : /* No output */ \
+ : "o" (*(char *)MCF_MBAR) ); \
+})
#elif defined(CONFIG_M528x)
/*
* The MCF528x has a bit (SOFTRST) in memory (Reset Control Register RCR),
@@ -270,6 +303,15 @@ cmpxchg(volatile int *p, int old, int new)
while(1) \
*reset |= (0x01 << 7);\
})
+#elif defined(CONFIG_M523x)
+#define HARD_RESET_NOW() ({ \
+ asm(" \
+ movew #0x2700, %sr; \
+ movel #0x01000000, %sp; \
+ moveal #0x40110000, %a0; \
+ moveb #0x80, (%a0); \
+ "); \
+})
#else
#define HARD_RESET_NOW() ({ \
asm(" \
diff --git a/include/asm-mips/asmmacro-32.h b/include/asm-mips/asmmacro-32.h
index ac8823df2554..11daf5ceb7b4 100644
--- a/include/asm-mips/asmmacro-32.h
+++ b/include/asm-mips/asmmacro-32.h
@@ -7,7 +7,7 @@
#ifndef _ASM_ASMMACRO_32_H
#define _ASM_ASMMACRO_32_H
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
diff --git a/include/asm-mips/asmmacro-64.h b/include/asm-mips/asmmacro-64.h
index bbed35511f5a..559c355b9b86 100644
--- a/include/asm-mips/asmmacro-64.h
+++ b/include/asm-mips/asmmacro-64.h
@@ -8,7 +8,7 @@
#ifndef _ASM_ASMMACRO_64_H
#define _ASM_ASMMACRO_64_H
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index af28dc88930b..43288634c38a 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -5,13 +5,13 @@
#include <asm/cache.h>
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_noncoherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index b90b11d0b886..3f2470e9e678 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -49,7 +49,4 @@ do { \
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/pgtable.h b/include/asm-mips/pgtable.h
index dbe13da0bdad..eaf5d9b3a0e1 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -68,6 +68,8 @@ extern unsigned long zero_page_mask;
#define ZERO_PAGE(vaddr) \
(virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
+#define __HAVE_ARCH_MULTIPLE_ZERO_PAGE
+
extern void paging_init(void);
/*
@@ -358,16 +360,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
-static inline int io_remap_page_range(struct vm_area_struct *vma,
- unsigned long vaddr,
- unsigned long paddr,
- unsigned long size,
- pgprot_t prot)
-{
- phys_t phys_addr_high = fixup_bigphys_addr(paddr, size);
- return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
-}
-
static inline int io_remap_pfn_range(struct vm_area_struct *vma,
unsigned long vaddr,
unsigned long pfn,
@@ -378,8 +370,6 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
return remap_pfn_range(vma, vaddr, pfn, size, prot);
}
#else
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif
diff --git a/include/asm-mips/sgi/hpc3.h b/include/asm-mips/sgi/hpc3.h
index ac3dfc7af5b0..fcec52bafb25 100644
--- a/include/asm-mips/sgi/hpc3.h
+++ b/include/asm-mips/sgi/hpc3.h
@@ -128,26 +128,26 @@ struct hpc3_ethregs {
volatile u32 rx_gfptr; /* current GIO fifo ptr */
volatile u32 rx_dfptr; /* current device fifo ptr */
u32 _unused1; /* padding */
- volatile u32 rx_reset; /* reset register */
-#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
-#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
-#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */
-
- volatile u32 rx_dconfig; /* DMA configuration register */
-#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */
-#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */
-#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */
-#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
-#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
-#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */
-#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */
-#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */
-
- volatile u32 rx_pconfig; /* PIO configuration register */
-#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */
-#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */
-#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */
-#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */
+ volatile u32 reset; /* reset register */
+#define HPC3_ERST_CRESET 0x1 /* Reset dma channel and external controller */
+#define HPC3_ERST_CLRIRQ 0x2 /* Clear channel interrupt */
+#define HPC3_ERST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+
+ volatile u32 dconfig; /* DMA configuration register */
+#define HPC3_EDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_EDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_EDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_EDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_EDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_EDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */
+#define HPC3_EDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */
+#define HPC3_EDCFG_PTO 0x30000 /* Programmed timeout value for above two */
+
+ volatile u32 pconfig; /* PIO configuration register */
+#define HPC3_EPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_EPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_EPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_EPCFG_TST 0x1000 /* Diagnistic ram test feature bit */
u32 _unused2[0x1000/4 - 8]; /* padding */
diff --git a/include/asm-mips/sim.h b/include/asm-mips/sim.h
index 3ccfe09fa744..9c2af1b00e19 100644
--- a/include/asm-mips/sim.h
+++ b/include/asm-mips/sim.h
@@ -11,7 +11,7 @@
#include <linux/config.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#define __str2(x) #x
#define __str(x) __str2(x)
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index 114d3eb98a6a..4d0135b11156 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -16,20 +16,10 @@
* Your basic SMP spinlocks, allowing only a single CPU anywhere
*/
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-
-#define spin_lock_init(x) do { (x)->lock = 0; } while(0)
-
-#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock)
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_unlock_wait(x) \
+ do { cpu_relax(); } while ((x)->lock)
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
@@ -38,13 +28,13 @@ typedef struct {
* We make no fairness assumptions. They have a cost.
*/
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned int tmp;
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
- " .set noreorder # _raw_spin_lock \n"
+ " .set noreorder # __raw_spin_lock \n"
"1: ll %1, %2 \n"
" bnez %1, 1b \n"
" li %1, 1 \n"
@@ -58,7 +48,7 @@ static inline void _raw_spin_lock(spinlock_t *lock)
: "memory");
} else {
__asm__ __volatile__(
- " .set noreorder # _raw_spin_lock \n"
+ " .set noreorder # __raw_spin_lock \n"
"1: ll %1, %2 \n"
" bnez %1, 1b \n"
" li %1, 1 \n"
@@ -72,10 +62,10 @@ static inline void _raw_spin_lock(spinlock_t *lock)
}
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__(
- " .set noreorder # _raw_spin_unlock \n"
+ " .set noreorder # __raw_spin_unlock \n"
" sync \n"
" sw $0, %0 \n"
" .set\treorder \n"
@@ -84,13 +74,13 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
: "memory");
}
-static inline unsigned int _raw_spin_trylock(spinlock_t *lock)
+static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
{
unsigned int temp, res;
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
- " .set noreorder # _raw_spin_trylock \n"
+ " .set noreorder # __raw_spin_trylock \n"
"1: ll %0, %3 \n"
" ori %2, %0, 1 \n"
" sc %2, %1 \n"
@@ -104,7 +94,7 @@ static inline unsigned int _raw_spin_trylock(spinlock_t *lock)
: "memory");
} else {
__asm__ __volatile__(
- " .set noreorder # _raw_spin_trylock \n"
+ " .set noreorder # __raw_spin_trylock \n"
"1: ll %0, %3 \n"
" ori %2, %0, 1 \n"
" sc %2, %1 \n"
@@ -129,24 +119,13 @@ static inline unsigned int _raw_spin_trylock(spinlock_t *lock)
* read-locks.
*/
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-
-static inline void _raw_read_lock(rwlock_t *rw)
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned int tmp;
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
- " .set noreorder # _raw_read_lock \n"
+ " .set noreorder # __raw_read_lock \n"
"1: ll %1, %2 \n"
" bltz %1, 1b \n"
" addu %1, 1 \n"
@@ -160,7 +139,7 @@ static inline void _raw_read_lock(rwlock_t *rw)
: "memory");
} else {
__asm__ __volatile__(
- " .set noreorder # _raw_read_lock \n"
+ " .set noreorder # __raw_read_lock \n"
"1: ll %1, %2 \n"
" bltz %1, 1b \n"
" addu %1, 1 \n"
@@ -177,13 +156,13 @@ static inline void _raw_read_lock(rwlock_t *rw)
/* Note the use of sub, not subu which will make the kernel die with an
overflow exception if we ever try to unlock an rwlock that is already
unlocked or is being held by a writer. */
-static inline void _raw_read_unlock(rwlock_t *rw)
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned int tmp;
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
- "1: ll %1, %2 # _raw_read_unlock \n"
+ "1: ll %1, %2 # __raw_read_unlock \n"
" sub %1, 1 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
@@ -193,7 +172,7 @@ static inline void _raw_read_unlock(rwlock_t *rw)
: "memory");
} else {
__asm__ __volatile__(
- " .set noreorder # _raw_read_unlock \n"
+ " .set noreorder # __raw_read_unlock \n"
"1: ll %1, %2 \n"
" sub %1, 1 \n"
" sc %1, %0 \n"
@@ -206,13 +185,13 @@ static inline void _raw_read_unlock(rwlock_t *rw)
}
}
-static inline void _raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
unsigned int tmp;
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
- " .set noreorder # _raw_write_lock \n"
+ " .set noreorder # __raw_write_lock \n"
"1: ll %1, %2 \n"
" bnez %1, 1b \n"
" lui %1, 0x8000 \n"
@@ -226,7 +205,7 @@ static inline void _raw_write_lock(rwlock_t *rw)
: "memory");
} else {
__asm__ __volatile__(
- " .set noreorder # _raw_write_lock \n"
+ " .set noreorder # __raw_write_lock \n"
"1: ll %1, %2 \n"
" bnez %1, 1b \n"
" lui %1, 0x8000 \n"
@@ -241,26 +220,26 @@ static inline void _raw_write_lock(rwlock_t *rw)
}
}
-static inline void _raw_write_unlock(rwlock_t *rw)
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
__asm__ __volatile__(
- " sync # _raw_write_unlock \n"
+ " sync # __raw_write_unlock \n"
" sw $0, %0 \n"
: "=m" (rw->lock)
: "m" (rw->lock)
: "memory");
}
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
-static inline int _raw_write_trylock(rwlock_t *rw)
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
{
unsigned int tmp;
int ret;
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
- " .set noreorder # _raw_write_trylock \n"
+ " .set noreorder # __raw_write_trylock \n"
" li %2, 0 \n"
"1: ll %1, %3 \n"
" bnez %1, 2f \n"
@@ -277,7 +256,7 @@ static inline int _raw_write_trylock(rwlock_t *rw)
: "memory");
} else {
__asm__ __volatile__(
- " .set noreorder # _raw_write_trylock \n"
+ " .set noreorder # __raw_write_trylock \n"
" li %2, 0 \n"
"1: ll %1, %3 \n"
" bnez %1, 2f \n"
diff --git a/include/asm-mips/spinlock_types.h b/include/asm-mips/spinlock_types.h
new file mode 100644
index 000000000000..ce26c5048b15
--- /dev/null
+++ b/include/asm-mips/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_SPINLOCK_TYPES_H
+#define _ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index fb42f99f8527..7b5e64600bc8 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -15,7 +15,7 @@
#include <asm/asm.h>
#include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
.macro SAVE_AT
.set push
diff --git a/include/asm-mips/vr41xx/tb0287.h b/include/asm-mips/vr41xx/tb0287.h
new file mode 100644
index 000000000000..dd9832313afe
--- /dev/null
+++ b/include/asm-mips/vr41xx/tb0287.h
@@ -0,0 +1,43 @@
+/*
+ * 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/assembly.h b/include/asm-parisc/assembly.h
index cbc286f49b36..30b023411fef 100644
--- a/include/asm-parisc/assembly.h
+++ b/include/asm-parisc/assembly.h
@@ -63,7 +63,7 @@
.level 2.0w
#endif
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/asmregs.h>
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index e24f7579adb0..048a2c7fd0c0 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -24,19 +24,19 @@
# define ATOMIC_HASH_SIZE 4
# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
-extern spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
+extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
-/* Can't use _raw_spin_lock_irq because of #include problems, so
+/* Can't use raw_spin_lock_irq because of #include problems, so
* this is the substitute */
#define _atomic_spin_lock_irqsave(l,f) do { \
- spinlock_t *s = ATOMIC_HASH(l); \
+ raw_spinlock_t *s = ATOMIC_HASH(l); \
local_irq_save(f); \
- _raw_spin_lock(s); \
+ __raw_spin_lock(s); \
} while(0)
#define _atomic_spin_unlock_irqrestore(l,f) do { \
- spinlock_t *s = ATOMIC_HASH(l); \
- _raw_spin_unlock(s); \
+ raw_spinlock_t *s = ATOMIC_HASH(l); \
+ __raw_spin_unlock(s); \
local_irq_restore(f); \
} while(0)
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index 928e5ef850bd..af7db694b22d 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -2,7 +2,7 @@
#define _PARISC_BITOPS_H
#include <linux/compiler.h>
-#include <asm/system.h>
+#include <asm/spinlock.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index 06732719d927..aa592d8c0e39 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -3,6 +3,7 @@
#include <linux/config.h>
#include <linux/mm.h>
+#include <asm/cache.h> /* for flush_user_dcache_range_asm() proto */
/* The usual comment is "Caches aren't brain-dead on the <architecture>".
* Unfortunately, that doesn't apply to PA-RISC. */
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 4db84f969e9e..74d4ac6f2151 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -9,8 +9,8 @@
/* See Documentation/DMA-mapping.txt */
struct hppa_dma_ops {
int (*dma_supported)(struct device *dev, u64 mask);
- void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
- void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
+ void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
+ void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
@@ -49,14 +49,14 @@ extern struct hppa_dma_ops *hppa_dma_ops;
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
}
static inline void *
dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
}
diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-parisc/futex.h
+++ b/include/asm-parisc/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 98d79a3d54fa..d0b761f690b5 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -257,6 +257,19 @@ extern void
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-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index f001bb01e38f..820c6e712cd7 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -498,9 +498,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
#endif /* !__ASSEMBLY__ */
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index 0b61f51d8467..a9dfadd05658 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -11,6 +11,7 @@
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <linux/threads.h>
+#include <linux/spinlock_types.h>
#include <asm/hardware.h>
#include <asm/page.h>
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index 679ea1c651ef..43eaa6e742e0 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -2,30 +2,25 @@
#define __ASM_SPINLOCK_H
#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/spinlock_types.h>
/* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
* since it only has load-and-zero. Moreover, at least on some PA processors,
* the semaphore address has to be 16-byte aligned.
*/
-#ifndef CONFIG_DEBUG_SPINLOCK
-
-#define __SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
-#undef SPIN_LOCK_UNLOCKED
-#define SPIN_LOCK_UNLOCKED (spinlock_t) __SPIN_LOCK_UNLOCKED
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-static inline int spin_is_locked(spinlock_t *x)
+static inline int __raw_spin_is_locked(raw_spinlock_t *x)
{
volatile unsigned int *a = __ldcw_align(x);
return *a == 0;
}
-#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_unlock_wait(x) \
+ do { cpu_relax(); } while (__raw_spin_is_locked(x))
-static inline void _raw_spin_lock(spinlock_t *x)
+static inline void __raw_spin_lock(raw_spinlock_t *x)
{
volatile unsigned int *a;
@@ -36,7 +31,7 @@ static inline void _raw_spin_lock(spinlock_t *x)
mb();
}
-static inline void _raw_spin_unlock(spinlock_t *x)
+static inline void __raw_spin_unlock(raw_spinlock_t *x)
{
volatile unsigned int *a;
mb();
@@ -45,7 +40,7 @@ static inline void _raw_spin_unlock(spinlock_t *x)
mb();
}
-static inline int _raw_spin_trylock(spinlock_t *x)
+static inline int __raw_spin_trylock(raw_spinlock_t *x)
{
volatile unsigned int *a;
int ret;
@@ -57,131 +52,38 @@ static inline int _raw_spin_trylock(spinlock_t *x)
return ret;
}
-
-#define spin_lock_own(LOCK, LOCATION) ((void)0)
-
-#else /* !(CONFIG_DEBUG_SPINLOCK) */
-
-#define SPINLOCK_MAGIC 0x1D244B3C
-
-#define __SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 }, SPINLOCK_MAGIC, 10, __FILE__ , NULL, 0, -1, NULL, NULL }
-#undef SPIN_LOCK_UNLOCKED
-#define SPIN_LOCK_UNLOCKED (spinlock_t) __SPIN_LOCK_UNLOCKED
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-#define CHECK_LOCK(x) \
- do { \
- if (unlikely((x)->magic != SPINLOCK_MAGIC)) { \
- printk(KERN_ERR "%s:%d: spin_is_locked" \
- " on uninitialized spinlock %p.\n", \
- __FILE__, __LINE__, (x)); \
- } \
- } while(0)
-
-#define spin_is_locked(x) \
- ({ \
- CHECK_LOCK(x); \
- volatile unsigned int *a = __ldcw_align(x); \
- if (unlikely((*a == 0) && (x)->babble)) { \
- (x)->babble--; \
- printk("KERN_WARNING \
- %s:%d: spin_is_locked(%s/%p) already" \
- " locked by %s:%d in %s at %p(%d)\n", \
- __FILE__,__LINE__, (x)->module, (x), \
- (x)->bfile, (x)->bline, (x)->task->comm,\
- (x)->previous, (x)->oncpu); \
- } \
- *a == 0; \
- })
-
-#define spin_unlock_wait(x) \
- do { \
- CHECK_LOCK(x); \
- volatile unsigned int *a = __ldcw_align(x); \
- if (unlikely((*a == 0) && (x)->babble)) { \
- (x)->babble--; \
- printk("KERN_WARNING \
- %s:%d: spin_unlock_wait(%s/%p)" \
- " owned by %s:%d in %s at %p(%d)\n", \
- __FILE__,__LINE__, (x)->module, (x), \
- (x)->bfile, (x)->bline, (x)->task->comm,\
- (x)->previous, (x)->oncpu); \
- } \
- barrier(); \
- } while (*((volatile unsigned char *)(__ldcw_align(x))) == 0)
-
-extern void _dbg_spin_lock(spinlock_t *lock, const char *base_file, int line_no);
-extern void _dbg_spin_unlock(spinlock_t *lock, const char *, int);
-extern int _dbg_spin_trylock(spinlock_t * lock, const char *, int);
-
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
-
-#define _raw_spin_unlock(lock) _dbg_spin_unlock(lock, __FILE__, __LINE__)
-#define _raw_spin_lock(lock) _dbg_spin_lock(lock, __FILE__, __LINE__)
-#define _raw_spin_trylock(lock) _dbg_spin_trylock(lock, __FILE__, __LINE__)
-
-/* just in case we need it */
-#define spin_lock_own(LOCK, LOCATION) \
-do { \
- volatile unsigned int *a = __ldcw_align(LOCK); \
- if (!((*a == 0) && ((LOCK)->oncpu == smp_processor_id()))) \
- printk("KERN_WARNING \
- %s: called on %d from %p but lock %s on %d\n", \
- LOCATION, smp_processor_id(), \
- __builtin_return_address(0), \
- (*a == 0) ? "taken" : "freed", (LOCK)->on_cpu); \
-} while (0)
-
-#endif /* !(CONFIG_DEBUG_SPINLOCK) */
/*
* Read-write spinlocks, allowing multiple readers
* but only one writer.
*/
-typedef struct {
- spinlock_t lock;
- volatile int counter;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { __SPIN_LOCK_UNLOCKED, 0 }
-
-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
/* read_lock, read_unlock are pretty straightforward. Of course it somehow
* sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
-#ifdef CONFIG_DEBUG_RWLOCK
-extern void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline);
-#define _raw_read_lock(rw) _dbg_read_lock(rw, __FILE__, __LINE__)
-#else
-static __inline__ void _raw_read_lock(rwlock_t *rw)
+static __inline__ void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned long flags;
local_irq_save(flags);
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
rw->counter++;
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
local_irq_restore(flags);
}
-#endif /* CONFIG_DEBUG_RWLOCK */
-static __inline__ void _raw_read_unlock(rwlock_t *rw)
+static __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned long flags;
local_irq_save(flags);
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
rw->counter--;
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
local_irq_restore(flags);
}
@@ -194,20 +96,17 @@ static __inline__ void _raw_read_unlock(rwlock_t *rw)
* writers) in interrupt handlers someone fucked up and we'd dead-lock
* sooner or later anyway. prumpf */
-#ifdef CONFIG_DEBUG_RWLOCK
-extern void _dbg_write_lock(rwlock_t * rw, const char *bfile, int bline);
-#define _raw_write_lock(rw) _dbg_write_lock(rw, __FILE__, __LINE__)
-#else
-static __inline__ void _raw_write_lock(rwlock_t *rw)
+static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
{
retry:
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
if(rw->counter != 0) {
/* this basically never happens */
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
- while(rw->counter != 0);
+ while (rw->counter != 0)
+ cpu_relax();
goto retry;
}
@@ -215,26 +114,21 @@ retry:
/* got it. now leave without unlocking */
rw->counter = -1; /* remember we are locked */
}
-#endif /* CONFIG_DEBUG_RWLOCK */
/* write_unlock is absolutely trivial - we don't have to wait for anything */
-static __inline__ void _raw_write_unlock(rwlock_t *rw)
+static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
{
rw->counter = 0;
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
}
-#ifdef CONFIG_DEBUG_RWLOCK
-extern int _dbg_write_trylock(rwlock_t * rw, const char *bfile, int bline);
-#define _raw_write_trylock(rw) _dbg_write_trylock(rw, __FILE__, __LINE__)
-#else
-static __inline__ int _raw_write_trylock(rwlock_t *rw)
+static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
{
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
if (rw->counter != 0) {
/* this basically never happens */
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
return 0;
}
@@ -243,14 +137,13 @@ static __inline__ int _raw_write_trylock(rwlock_t *rw)
rw->counter = -1; /* remember we are locked */
return 1;
}
-#endif /* CONFIG_DEBUG_RWLOCK */
-static __inline__ int is_read_locked(rwlock_t *rw)
+static __inline__ int __raw_is_read_locked(raw_rwlock_t *rw)
{
return rw->counter > 0;
}
-static __inline__ int is_write_locked(rwlock_t *rw)
+static __inline__ int __raw_is_write_locked(raw_rwlock_t *rw)
{
return rw->counter < 0;
}
diff --git a/include/asm-parisc/spinlock_types.h b/include/asm-parisc/spinlock_types.h
new file mode 100644
index 000000000000..785bba822fbf
--- /dev/null
+++ b/include/asm-parisc/spinlock_types.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock[4];
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
+
+typedef struct {
+ raw_spinlock_t lock;
+ volatile int counter;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { __RAW_SPIN_LOCK_UNLOCKED, 0 }
+
+#endif
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index 81c543339036..26ff844a21c1 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -160,29 +160,7 @@ static inline void set_eiem(unsigned long val)
})
#ifdef CONFIG_SMP
-/*
- * Your basic SMP spinlocks, allowing only a single CPU anywhere
- */
-
-typedef struct {
- volatile unsigned int lock[4];
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned long magic;
- volatile unsigned int babble;
- const char *module;
- char *bfile;
- int bline;
- int oncpu;
- void *previous;
- struct task_struct * task;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
-
+# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
#endif
#define KERNEL_START (0x10100000 - 0x1000)
diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h
index 862708a749b0..b70d6e53b303 100644
--- a/include/asm-powerpc/8253pit.h
+++ b/include/asm-powerpc/8253pit.h
@@ -1,10 +1,10 @@
+#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 ca9e423307f4..885b4631a6cf 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 310187d0e33a..42fdb73e3068 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 19f20bd41ae6..8c145fd17d86 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 93c6acfdd0fd..8eb99848c402 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 f5b7f2b055e7..5b94ff489b8b 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 291c2d01c44f..e1c4ac1cc4ba 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 a5619a2a1393..f2741c8b59a1 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 f2d55988d749..f5e5342fcac5 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 4438f4fd6524..7ecd05e03051 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 1053452a9376..dd76743c7537 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 29c9ec832133..657443474a6a 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 6198b1657a45..bdc724f70884 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 be5024913c62..edd2054da86b 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 c98fc18fe805..99a41938ae3d 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 000000000000..3d9740aae018
--- /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 29632db3b178..8efa39698b6c 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 d6250602ae64..5cda42a6d39e 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 ae70b8010b19..12f1bce037be 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,12 @@
#include <asm-generic/siginfo.h>
-#endif /* _POWERPC_SIGINFO_H */
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
+#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
+#undef NSIGTRAP
+#define NSIGTRAP 4
+
+#endif /* _ASM_POWERPC_SIGINFO_H */
diff --git a/include/asm-powerpc/socket.h b/include/asm-powerpc/socket.h
index 51a0cf5ee9f0..e4b8177d4acc 100644
--- a/include/asm-powerpc/socket.h
+++ b/include/asm-powerpc/socket.h
@@ -1,5 +1,5 @@
-#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 ef7ff664167e..590078d8ed28 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 225575997392..8606a696c088 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 2c5bf85a8c3c..ebf6055481dc 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 237533bb0e9f..c5b8e5358f83 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-powerpc/timex.h b/include/asm-powerpc/timex.h
new file mode 100644
index 000000000000..c02d15aced91
--- /dev/null
+++ b/include/asm-powerpc/timex.h
@@ -0,0 +1,49 @@
+#ifndef _ASM_POWERPC_TIMEX_H
+#define _ASM_POWERPC_TIMEX_H
+
+#ifdef __KERNEL__
+
+/*
+ * PowerPC architecture timex specifications
+ */
+
+#include <linux/config.h>
+#include <asm/cputable.h>
+
+#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+ 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"
+ "99:\n"
+ ".section __ftr_fixup,\"a\"\n"
+ " .long %1\n"
+ " .long 0\n"
+ " .long 98b\n"
+ " .long 99b\n"
+ ".previous"
+ : "=r" (ret) : "i" (CPU_FTR_601));
+#endif
+
+ return ret;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_TIMEX_H */
diff --git a/include/asm-ppc64/topology.h b/include/asm-powerpc/topology.h
index 1e9b19073230..2512e3836bf4 100644
--- a/include/asm-ppc64/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -1,11 +1,12 @@
-#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 45520d9b85d1..6c95dfa2652f 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 d662b2151370..e59ade4b3dfb 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/cputable.h b/include/asm-ppc/cputable.h
index 41d8f8425c04..e17c492c870b 100644
--- a/include/asm-ppc/cputable.h
+++ b/include/asm-ppc/cputable.h
@@ -24,6 +24,7 @@
#define PPC_FEATURE_HAS_SPE 0x00800000
#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
+#define PPC_FEATURE_NO_TB 0x00100000
#ifdef __KERNEL__
diff --git a/include/asm-ppc/dma-mapping.h b/include/asm-ppc/dma-mapping.h
index 92b8ee78dcc2..6e9635114433 100644
--- a/include/asm-ppc/dma-mapping.h
+++ b/include/asm-ppc/dma-mapping.h
@@ -19,7 +19,7 @@
* allocate the space "normally" and use the cache management functions
* to ensure it is consistent.
*/
-extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, int gfp);
+extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp);
extern void __dma_free_coherent(size_t size, void *vaddr);
extern void __dma_sync(void *vaddr, size_t size, int direction);
extern void __dma_sync_page(struct page *page, unsigned long offset,
@@ -61,7 +61,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t * dma_handle,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
#ifdef CONFIG_NOT_COHERENT_CACHE
return __dma_alloc_coherent(size, dma_handle, gfp);
diff --git a/include/asm-ppc/futex.h b/include/asm-ppc/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-ppc/futex.h
+++ b/include/asm-ppc/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 7eb7cf6360bd..94d83998a759 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -56,7 +56,7 @@ extern unsigned long pci_dram_offset;
* is actually performed (i.e. the data has come back) before we start
* executing any following instructions.
*/
-extern inline int in_8(volatile unsigned char __iomem *addr)
+extern inline int in_8(const volatile unsigned char __iomem *addr)
{
int ret;
@@ -72,7 +72,7 @@ extern inline void out_8(volatile unsigned char __iomem *addr, int val)
__asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
-extern inline int in_le16(volatile unsigned short __iomem *addr)
+extern inline int in_le16(const volatile unsigned short __iomem *addr)
{
int ret;
@@ -83,7 +83,7 @@ extern inline int in_le16(volatile unsigned short __iomem *addr)
return ret;
}
-extern inline int in_be16(volatile unsigned short __iomem *addr)
+extern inline int in_be16(const volatile unsigned short __iomem *addr)
{
int ret;
@@ -104,7 +104,7 @@ extern inline void out_be16(volatile unsigned short __iomem *addr, int val)
__asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
-extern inline unsigned in_le32(volatile unsigned __iomem *addr)
+extern inline unsigned in_le32(const volatile unsigned __iomem *addr)
{
unsigned ret;
@@ -115,7 +115,7 @@ extern inline unsigned in_le32(volatile unsigned __iomem *addr)
return ret;
}
-extern inline unsigned in_be32(volatile unsigned __iomem *addr)
+extern inline unsigned in_be32(const volatile unsigned __iomem *addr)
{
unsigned ret;
@@ -139,7 +139,7 @@ extern inline void out_be32(volatile unsigned __iomem *addr, int val)
#define readb(addr) in_8((volatile u8 *)(addr))
#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))
#else
-static inline __u8 readb(volatile void __iomem *addr)
+static inline __u8 readb(const volatile void __iomem *addr)
{
return in_8(addr);
}
@@ -150,11 +150,11 @@ static inline void writeb(__u8 b, volatile void __iomem *addr)
#endif
#if defined(CONFIG_APUS)
-static inline __u16 readw(volatile void __iomem *addr)
+static inline __u16 readw(const volatile void __iomem *addr)
{
return *(__force volatile __u16 *)(addr);
}
-static inline __u32 readl(volatile void __iomem *addr)
+static inline __u32 readl(const volatile void __iomem *addr)
{
return *(__force volatile __u32 *)(addr);
}
@@ -173,11 +173,11 @@ static inline void writel(__u32 b, volatile void __iomem *addr)
#define writew(b,addr) out_le16((volatile u16 *)(addr),(b))
#define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
#else
-static inline __u16 readw(volatile void __iomem *addr)
+static inline __u16 readw(const volatile void __iomem *addr)
{
return in_le16(addr);
}
-static inline __u32 readl(volatile void __iomem *addr)
+static inline __u32 readl(const volatile void __iomem *addr)
{
return in_le32(addr);
}
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
index b4b270457edd..bd9674807f05 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-ppc/irq.h
@@ -138,6 +138,16 @@ irq_canonicalize(int irq)
#define SIU_IRQ7 (14)
#define SIU_LEVEL7 (15)
+#define MPC8xx_INT_FEC1 SIU_LEVEL1
+#define MPC8xx_INT_FEC2 SIU_LEVEL3
+
+#define MPC8xx_INT_SCC1 (CPM_IRQ_OFFSET + CPMVEC_SCC1)
+#define MPC8xx_INT_SCC2 (CPM_IRQ_OFFSET + CPMVEC_SCC2)
+#define MPC8xx_INT_SCC3 (CPM_IRQ_OFFSET + CPMVEC_SCC3)
+#define MPC8xx_INT_SCC4 (CPM_IRQ_OFFSET + CPMVEC_SCC4)
+#define MPC8xx_INT_SMC1 (CPM_IRQ_OFFSET + CPMVEC_SMC1)
+#define MPC8xx_INT_SMC2 (CPM_IRQ_OFFSET + CPMVEC_SMC2)
+
/* The internal interrupts we can configure as we see fit.
* My personal preference is CPM at level 2, which puts it above the
* MBX PCI/ISA/IDE interrupts.
@@ -404,9 +414,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/macio.h b/include/asm-ppc/macio.h
index a481b772d154..b553dd4b139e 100644
--- a/include/asm-ppc/macio.h
+++ b/include/asm-ppc/macio.h
@@ -1,7 +1,6 @@
#ifndef __MACIO_ASIC_H__
#define __MACIO_ASIC_H__
-#include <linux/mod_devicetable.h>
#include <asm/of_device.h>
extern struct bus_type macio_bus_type;
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index dc8e59896050..208a2e11daee 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -97,6 +97,22 @@ extern unsigned char __res[];
struct pt_regs;
+enum ppc_sys_devices {
+ MPC8xx_CPM_FEC1,
+ MPC8xx_CPM_FEC2,
+ MPC8xx_CPM_I2C,
+ MPC8xx_CPM_SCC1,
+ MPC8xx_CPM_SCC2,
+ MPC8xx_CPM_SCC3,
+ MPC8xx_CPM_SCC4,
+ MPC8xx_CPM_SPI,
+ MPC8xx_CPM_MCC1,
+ MPC8xx_CPM_MCC2,
+ MPC8xx_CPM_SMC1,
+ MPC8xx_CPM_SMC2,
+ MPC8xx_CPM_USB,
+};
+
#endif /* !__ASSEMBLY__ */
#endif /* CONFIG_8xx */
#endif /* __CONFIG_8xx_DEFS */
diff --git a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
index 835930d6faa1..ee2f9188cc64 100644
--- a/include/asm-ppc/mv64x60.h
+++ b/include/asm-ppc/mv64x60.h
@@ -119,6 +119,14 @@ extern spinlock_t mv64x60_lock;
#define MV64x60_64BIT_WIN_COUNT 24
+/* Watchdog Platform Device, Driver Data */
+#define MV64x60_WDT_NAME "wdt"
+
+struct mv64x60_wdt_pdata {
+ int timeout; /* watchdog expiry in seconds, default 10 */
+ int bus_clk; /* bus clock in MHz, default 133 */
+};
+
/*
* Define a structure that's used to pass in config information to the
* core routines.
@@ -225,7 +233,7 @@ struct mv64x60_chip_info {
struct mv64x60_handle {
u32 type; /* type of bridge */
u32 rev; /* revision of bridge */
- void *v_base; /* virtual base addr of bridge regs */
+ void __iomem *v_base;/* virtual base addr of bridge regs */
phys_addr_t p_base; /* physical base addr of bridge regs */
u32 pci_mode_a; /* pci 0 mode: conventional pci, pci-x*/
@@ -295,7 +303,7 @@ void mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr,
u32 cfg_data, struct pci_controller **hose);
int mv64x60_get_type(struct mv64x60_handle *bh);
int mv64x60_setup_for_chip(struct mv64x60_handle *bh);
-void *mv64x60_get_bridge_vbase(void);
+void __iomem *mv64x60_get_bridge_vbase(void);
u32 mv64x60_get_bridge_type(void);
u32 mv64x60_get_bridge_rev(void);
void mv64x60_get_mem_windows(struct mv64x60_handle *bh,
diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h
index 4b264cfd3998..575bce418f80 100644
--- a/include/asm-ppc/of_device.h
+++ b/include/asm-ppc/of_device.h
@@ -2,6 +2,7 @@
#define __OF_DEVICE_H__
#include <linux/device.h>
+#include <linux/mod_devicetable.h>
#include <asm/prom.h>
/*
@@ -55,7 +56,9 @@ extern int of_register_driver(struct of_platform_driver *drv);
extern void of_unregister_driver(struct of_platform_driver *drv);
extern int of_device_register(struct of_device *ofdev);
extern void of_device_unregister(struct of_device *ofdev);
-extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id);
+extern struct of_device *of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent);
extern void of_release_dev(struct device *dev);
#endif /* __OF_DEVICE_H__ */
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index a811e440c978..9dd06cd40096 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -109,6 +109,19 @@ extern void
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/pgtable.h b/include/asm-ppc/pgtable.h
index 92f30b28b252..eee601bb9ada 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -812,15 +812,6 @@ extern void kernel_set_cachemode (unsigned long address, unsigned long size,
#ifdef CONFIG_PHYS_64BIT
extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long paddr, unsigned long size, pgprot_t prot);
-static inline int io_remap_page_range(struct vm_area_struct *vma,
- unsigned long vaddr,
- unsigned long paddr,
- unsigned long size,
- pgprot_t prot)
-{
- phys_addr_t paddr64 = fixup_bigphys_addr(paddr, size);
- return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
-}
static inline int io_remap_pfn_range(struct vm_area_struct *vma,
unsigned long vaddr,
@@ -832,8 +823,6 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
}
#else
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 048f7c8596ee..549f44843c5e 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -27,6 +27,8 @@
#include <asm/mpc83xx.h>
#elif defined(CONFIG_85xx)
#include <asm/mpc85xx.h>
+#elif defined(CONFIG_8xx)
+#include <asm/mpc8xx.h>
#elif defined(CONFIG_PPC_MPC52xx)
#include <asm/mpc52xx.h>
#elif defined(CONFIG_MPC10X_BRIDGE)
diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h
index 9d4e4ea530c3..7043c164b537 100644
--- a/include/asm-ppc/ptrace.h
+++ b/include/asm-ppc/ptrace.h
@@ -142,4 +142,11 @@ do { \
#define PTRACE_GETEVRREGS 20
#define PTRACE_SETEVRREGS 21
+/*
+ * Get or set a debug register. The first 16 are DABR registers and the
+ * second 16 are IABR registers.
+ */
+#define PTRACE_GET_DEBUGREG 25
+#define PTRACE_SET_DEBUGREG 26
+
#endif
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
index 88b4222154d4..73c33e3ef9c6 100644
--- a/include/asm-ppc/reg.h
+++ b/include/asm-ppc/reg.h
@@ -366,12 +366,6 @@
#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/segment.h b/include/asm-ppc/segment.h
deleted file mode 100644
index 0f2f7428d437..000000000000
--- a/include/asm-ppc/segment.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm/uaccess.h>
diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h
deleted file mode 100644
index d2d19ee103df..000000000000
--- a/include/asm-ppc/setup.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#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/smp.h b/include/asm-ppc/smp.h
index 17530c232c76..829481c0a9dc 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -41,6 +41,10 @@ extern void smp_send_xmon_break(int cpu);
struct pt_regs;
extern void smp_message_recv(int, struct pt_regs *);
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
+extern void cpu_die(void) __attribute__((noreturn));
+
#define NO_PROC_ID 0xFF /* No processor magic marker */
#define PROC_CHANGE_PENALTY 20
@@ -64,6 +68,8 @@ extern struct klock_info_struct klock_info;
#else /* !(CONFIG_SMP) */
+static inline void cpu_die(void) { }
+
#endif /* !(CONFIG_SMP) */
#endif /* !(_PPC_SMP_H) */
diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
index 909199aae104..20edcf2a6e0c 100644
--- a/include/asm-ppc/spinlock.h
+++ b/include/asm-ppc/spinlock.h
@@ -5,41 +5,21 @@
/*
* Simple spin lock operations.
+ *
+ * (the type definitions are in asm/raw_spinlock_types.h)
*/
-typedef struct {
- volatile unsigned long lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- volatile unsigned long owner_pc;
- volatile unsigned long owner_cpu;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#ifdef __KERNEL__
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define SPINLOCK_DEBUG_INIT , 0, 0
-#else
-#define SPINLOCK_DEBUG_INIT /* */
-#endif
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 SPINLOCK_DEBUG_INIT }
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
-
-#ifndef CONFIG_DEBUG_SPINLOCK
-
-static inline void _raw_spin_lock(spinlock_t *lock)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned long tmp;
__asm__ __volatile__(
- "b 1f # spin_lock\n\
+ "b 1f # __raw_spin_lock\n\
2: lwzx %0,0,%1\n\
cmpwi 0,%0,0\n\
bne+ 2b\n\
@@ -55,21 +35,13 @@ static inline void _raw_spin_lock(spinlock_t *lock)
: "cr0", "memory");
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
- __asm__ __volatile__("eieio # spin_unlock": : :"memory");
+ __asm__ __volatile__("eieio # __raw_spin_unlock": : :"memory");
lock->lock = 0;
}
-#define _raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock))
-
-#else
-
-extern void _raw_spin_lock(spinlock_t *lock);
-extern void _raw_spin_unlock(spinlock_t *lock);
-extern int _raw_spin_trylock(spinlock_t *lock);
-
-#endif
+#define __raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock))
/*
* Read-write spinlocks, allowing multiple readers
@@ -81,22 +53,11 @@ extern int _raw_spin_trylock(spinlock_t *lock);
* irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
*/
-typedef struct {
- volatile signed int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
+#define __raw_read_can_lock(rw) ((rw)->lock >= 0)
+#define __raw_write_can_lock(rw) (!(rw)->lock)
-#define read_can_lock(rw) ((rw)->lock >= 0)
-#define write_can_lock(rw) (!(rw)->lock)
-
-#ifndef CONFIG_DEBUG_SPINLOCK
-
-static __inline__ int _raw_read_trylock(rwlock_t *rw)
+static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
{
signed int tmp;
@@ -116,7 +77,7 @@ static __inline__ int _raw_read_trylock(rwlock_t *rw)
return tmp > 0;
}
-static __inline__ void _raw_read_lock(rwlock_t *rw)
+static __inline__ void __raw_read_lock(raw_rwlock_t *rw)
{
signed int tmp;
@@ -137,7 +98,7 @@ static __inline__ void _raw_read_lock(rwlock_t *rw)
: "cr0", "memory");
}
-static __inline__ void _raw_read_unlock(rwlock_t *rw)
+static __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
{
signed int tmp;
@@ -153,7 +114,7 @@ static __inline__ void _raw_read_unlock(rwlock_t *rw)
: "cr0", "memory");
}
-static __inline__ int _raw_write_trylock(rwlock_t *rw)
+static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
{
signed int tmp;
@@ -173,7 +134,7 @@ static __inline__ int _raw_write_trylock(rwlock_t *rw)
return tmp == 0;
}
-static __inline__ void _raw_write_lock(rwlock_t *rw)
+static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
{
signed int tmp;
@@ -194,22 +155,10 @@ static __inline__ void _raw_write_lock(rwlock_t *rw)
: "cr0", "memory");
}
-static __inline__ void _raw_write_unlock(rwlock_t *rw)
+static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
{
__asm__ __volatile__("eieio # write_unlock": : :"memory");
rw->lock = 0;
}
-#else
-
-extern void _raw_read_lock(rwlock_t *rw);
-extern void _raw_read_unlock(rwlock_t *rw);
-extern void _raw_write_lock(rwlock_t *rw);
-extern void _raw_write_unlock(rwlock_t *rw);
-extern int _raw_read_trylock(rwlock_t *rw);
-extern int _raw_write_trylock(rwlock_t *rw);
-
-#endif
-
#endif /* __ASM_SPINLOCK_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/spinlock_types.h b/include/asm-ppc/spinlock_types.h
new file mode 100644
index 000000000000..7919ccc75b8a
--- /dev/null
+++ b/include/asm-ppc/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned long lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile signed int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index 513a334c5810..d754ab570fe0 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -88,6 +88,7 @@ extern void *cacheable_memcpy(void *, const void *, unsigned int);
extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
extern void die(const char *, struct pt_regs *, long);
+extern void _exception(int, struct pt_regs *, int, unsigned long);
#ifdef CONFIG_BOOKE_WDT
extern u32 booke_wdt_enabled;
extern u32 booke_wdt_period;
diff --git a/include/asm-ppc/timex.h b/include/asm-ppc/timex.h
deleted file mode 100644
index cffc8712077c..000000000000
--- a/include/asm-ppc/timex.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * include/asm-ppc/timex.h
- *
- * ppc architecture timex specifications
- */
-#ifdef __KERNEL__
-#ifndef _ASMppc_TIMEX_H
-#define _ASMppc_TIMEX_H
-
-#include <linux/config.h>
-#include <asm/cputable.h>
-
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
-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;
-
- __asm__ __volatile__(
- "98: mftb %0\n"
- "99:\n"
- ".section __ftr_fixup,\"a\"\n"
- " .long %1\n"
- " .long 0\n"
- " .long 98b\n"
- " .long 99b\n"
- ".previous"
- : "=r" (ret) : "i" (CPU_FTR_601));
- return ret;
-}
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h
index 9850f53f54b0..9afee4ffc835 100644
--- a/include/asm-ppc/tlbflush.h
+++ b/include/asm-ppc/tlbflush.h
@@ -72,7 +72,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
-static inline void flush_tlb_range(struct mm_struct *mm,
+static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ __tlbia(); }
static inline void flush_tlb_kernel_range(unsigned long start,
diff --git a/include/asm-ppc/topology.h b/include/asm-ppc/topology.h
deleted file mode 100644
index 6a029bbba6e1..000000000000
--- a/include/asm-ppc/topology.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#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/dma-mapping.h b/include/asm-ppc64/dma-mapping.h
index 9ad8adee0067..fb68fa23bea8 100644
--- a/include/asm-ppc64/dma-mapping.h
+++ b/include/asm-ppc64/dma-mapping.h
@@ -19,7 +19,7 @@
extern int dma_supported(struct device *dev, u64 mask);
extern int dma_set_mask(struct device *dev, u64 dma_mask);
extern void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag);
+ dma_addr_t *dma_handle, gfp_t flag);
extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle);
extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
@@ -118,7 +118,7 @@ dma_cache_sync(void *vaddr, size_t size,
*/
struct dma_mapping_ops {
void * (*alloc_coherent)(struct device *dev, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void (*free_coherent)(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
dma_addr_t (*map_single)(struct device *dev, void *ptr,
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
index 94298b106a4b..40c8eb57493e 100644
--- a/include/asm-ppc64/eeh.h
+++ b/include/asm-ppc64/eeh.h
@@ -219,23 +219,24 @@ static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
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/hvcall.h b/include/asm-ppc64/hvcall.h
index 4f668a4baff0..ab7c3cf24888 100644
--- a/include/asm-ppc64/hvcall.h
+++ b/include/asm-ppc64/hvcall.h
@@ -56,6 +56,11 @@
#define H_PP1 (1UL<<(63-62))
#define H_PP2 (1UL<<(63-63))
+/* DABRX flags */
+#define H_DABRX_HYPERVISOR (1UL<<(63-61))
+#define H_DABRX_KERNEL (1UL<<(63-62))
+#define H_DABRX_USER (1UL<<(63-63))
+
/* pSeries hypervisor opcodes */
#define H_REMOVE 0x04
#define H_ENTER 0x08
@@ -101,6 +106,7 @@
#define H_VIO_SIGNAL 0x104
#define H_SEND_CRQ 0x108
#define H_COPY_RDMA 0x110
+#define H_SET_XDABR 0x134
#define H_STUFF_TCE 0x138
#define H_PUT_TCE_INDIRECT 0x13C
#define H_VTERM_PARTNER_INFO 0x150
diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
index aba1dfa388ba..59c958aea4db 100644
--- a/include/asm-ppc64/io.h
+++ b/include/asm-ppc64/io.h
@@ -20,10 +20,10 @@
#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/iommu.h b/include/asm-ppc64/iommu.h
index 72dcf8116b04..c2f3b6e8a42f 100644
--- a/include/asm-ppc64/iommu.h
+++ b/include/asm-ppc64/iommu.h
@@ -122,7 +122,7 @@ extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction);
extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
- dma_addr_t *dma_handle, unsigned int __nocast flag);
+ dma_addr_t *dma_handle, gfp_t flag);
extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
void *vaddr, dma_addr_t dma_handle);
extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
index 9a1ef4427ed2..8027160ec96d 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-ppc64/machdep.h
@@ -88,6 +88,7 @@ struct machdep_calls {
/* PCI stuff */
void (*pcibios_fixup)(void);
+ int (*pci_probe_mode)(struct pci_bus *);
void (*restart)(char *cmd);
void (*power_off)(void);
@@ -173,10 +174,6 @@ extern sys_ctrler_t sys_ctrler;
void ppc64_boot_msg(unsigned int src, const char *msg);
/* Print a termination message (print only -- does not stop the kernel) */
void ppc64_terminate_msg(unsigned int src, const char *msg);
-/* Print something that needs attention (device error, etc) */
-void ppc64_attention_msg(unsigned int src, const char *msg);
-/* Print a dump progress message. */
-void ppc64_dump_msg(unsigned int src, const char *msg);
static inline void log_error(char *buf, unsigned int err_type, int fatal)
{
diff --git a/include/asm-ppc64/msgbuf.h b/include/asm-ppc64/msgbuf.h
deleted file mode 100644
index 31c1cbf133cc..000000000000
--- a/include/asm-ppc64/msgbuf.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#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 76c212d475b3..000000000000
--- 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 c4f9023ea5ed..d8991389ab39 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,8 +116,13 @@ 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;
}
+/* Return values for ppc_md.pci_probe_mode function */
+#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
+#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
+#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */
+
#endif
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index 4d057452f59b..a88bbfc26967 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -138,6 +138,19 @@ extern void
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/plpar_wrappers.h b/include/asm-ppc64/plpar_wrappers.h
index f4a5fb7d67c7..72dd2449ee76 100644
--- a/include/asm-ppc64/plpar_wrappers.h
+++ b/include/asm-ppc64/plpar_wrappers.h
@@ -107,5 +107,14 @@ static inline long plpar_put_term_char(unsigned long termno,
lbuf[1]);
}
+static inline long plpar_set_xdabr(unsigned long address, unsigned long flags)
+{
+ return plpar_hcall_norets(H_SET_XDABR, address, flags);
+}
+
+static inline long plpar_set_dabr(unsigned long val)
+{
+ return plpar_hcall_norets(H_SET_DABR, val);
+}
#endif /* _PPC64_PLPAR_WRAPPERS_H */
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index 8bd7aa959385..4146189006e3 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -433,6 +433,7 @@ struct thread_struct {
unsigned long start_tb; /* Start purr when proc switched in */
unsigned long accum_tb; /* Total accumilated purr for process */
unsigned long vdso_base; /* base of the vDSO library */
+ unsigned long dabr; /* Data address breakpoint register */
#ifdef CONFIG_ALTIVEC
/* Complete AltiVec register set */
vector128 vr[32] __attribute((aligned(16)));
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index dc5330b39509..c02ec1d6b909 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -116,14 +116,6 @@ struct property {
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/ptrace-common.h b/include/asm-ppc64/ptrace-common.h
index af03547f9c7e..b1babb729673 100644
--- a/include/asm-ppc64/ptrace-common.h
+++ b/include/asm-ppc64/ptrace-common.h
@@ -11,6 +11,10 @@
#ifndef _PPC64_PTRACE_COMMON_H
#define _PPC64_PTRACE_COMMON_H
+
+#include <linux/config.h>
+#include <asm/system.h>
+
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
@@ -69,4 +73,92 @@ static inline void clear_single_step(struct task_struct *task)
clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
+#ifdef CONFIG_ALTIVEC
+/*
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
+ * corresponding vector registers. Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword. Quadword 33 contains the
+ * vrsave as the first word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the
+ * same structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ */
+
+/*
+ * Get contents of AltiVec register state in task TASK
+ */
+static inline int get_vrregs(unsigned long __user *data,
+ struct task_struct *task)
+{
+ unsigned long regsize;
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ regsize = 32 * sizeof(vector128);
+ if (copy_to_user(data, task->thread.vr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_to_user(data, &task->thread.vscr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (put_user(task->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * Write contents of AltiVec register state into task TASK.
+ */
+static inline int set_vrregs(struct task_struct *task,
+ unsigned long __user *data)
+{
+ unsigned long regsize;
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ regsize = 32 * sizeof(vector128);
+ if (copy_from_user(task->thread.vr, data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_from_user(&task->thread.vscr, data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (get_user(task->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+
+ return 0;
+}
+#endif
+
+static inline int ptrace_set_debugreg(struct task_struct *task,
+ unsigned long addr, unsigned long data)
+{
+ /* We only support one DABR and no IABRS at the moment */
+ if (addr > 0)
+ return -EINVAL;
+
+ /* The bottom 3 bits are flags */
+ if ((data & ~0x7UL) >= TASK_SIZE)
+ return -EIO;
+
+ /* Ensure translation is on */
+ if (data && !(data & DABR_TRANSLATION))
+ return -EIO;
+
+ task->thread.dabr = data;
+ return 0;
+}
+
#endif /* _PPC64_PTRACE_COMMON_H */
diff --git a/include/asm-ppc64/ptrace.h b/include/asm-ppc64/ptrace.h
index c96aad28fc08..3a55377f1fd3 100644
--- a/include/asm-ppc64/ptrace.h
+++ b/include/asm-ppc64/ptrace.h
@@ -25,56 +25,49 @@
*/
#ifndef __ASSEMBLY__
-#define PPC_REG unsigned long
+
struct pt_regs {
- PPC_REG gpr[32];
- PPC_REG nip;
- PPC_REG msr;
- PPC_REG orig_gpr3; /* Used for restarting system calls */
- PPC_REG ctr;
- PPC_REG link;
- PPC_REG xer;
- PPC_REG ccr;
- PPC_REG softe; /* Soft enabled/disabled */
- PPC_REG trap; /* Reason for being here */
- PPC_REG dar; /* Fault registers */
- PPC_REG dsisr;
- PPC_REG result; /* Result of a system call */
+ unsigned long gpr[32];
+ unsigned long nip;
+ unsigned long msr;
+ unsigned long orig_gpr3; /* Used for restarting system calls */
+ unsigned long ctr;
+ unsigned long link;
+ unsigned long xer;
+ unsigned long ccr;
+ unsigned long softe; /* Soft enabled/disabled */
+ unsigned long trap; /* Reason for being here */
+ unsigned long dar; /* Fault registers */
+ unsigned long dsisr;
+ unsigned long result; /* Result of a system call */
};
-#define PPC_REG_32 unsigned int
struct pt_regs32 {
- PPC_REG_32 gpr[32];
- PPC_REG_32 nip;
- PPC_REG_32 msr;
- PPC_REG_32 orig_gpr3; /* Used for restarting system calls */
- PPC_REG_32 ctr;
- PPC_REG_32 link;
- PPC_REG_32 xer;
- PPC_REG_32 ccr;
- PPC_REG_32 mq; /* 601 only (not used at present) */
- /* Used on APUS to hold IPL value. */
- PPC_REG_32 trap; /* Reason for being here */
- PPC_REG_32 dar; /* Fault registers */
- PPC_REG_32 dsisr;
- PPC_REG_32 result; /* Result of a system call */
+ unsigned int gpr[32];
+ unsigned int nip;
+ unsigned int msr;
+ unsigned int orig_gpr3; /* Used for restarting system calls */
+ unsigned int ctr;
+ unsigned int link;
+ unsigned int xer;
+ unsigned int ccr;
+ unsigned int mq; /* 601 only (not used at present) */
+ unsigned int trap; /* Reason for being here */
+ unsigned int dar; /* Fault registers */
+ unsigned int dsisr;
+ unsigned int result; /* Result of a system call */
};
+#ifdef __KERNEL__
+
#define instruction_pointer(regs) ((regs)->nip)
+
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
-#endif /* __ASSEMBLY__ */
-
-#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
-
-/* Size of dummy stack frame allocated when calling signal handler. */
-#define __SIGNAL_FRAMESIZE 128
-#define __SIGNAL_FRAMESIZE32 64
-
#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
#define force_successful_syscall_return() \
@@ -89,6 +82,16 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define TRAP(regs) ((regs)->trap & ~0xF)
#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
+
+/* Size of dummy stack frame allocated when calling signal handler. */
+#define __SIGNAL_FRAMESIZE 128
+#define __SIGNAL_FRAMESIZE32 64
+
/*
* Offsets used by 'ptrace' system call interface.
*/
@@ -135,17 +138,21 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PT_XER 37
#define PT_CCR 38
#define PT_SOFTE 39
+#define PT_TRAP 40
+#define PT_DAR 41
+#define PT_DSISR 42
#define PT_RESULT 43
#define PT_FPR0 48
-/* Kernel and userspace will both use this PT_FPSCR value. 32-bit apps will have
- * visibility to the asm-ppc/ptrace.h header instead of this one.
+/*
+ * Kernel and userspace will both use this PT_FPSCR value. 32-bit apps will
+ * have visibility to the asm-ppc/ptrace.h header instead of this one.
*/
-#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
+#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
#ifdef __KERNEL__
-#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */
+#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */
#endif
#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */
@@ -173,17 +180,34 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PTRACE_GETVRREGS 18
#define PTRACE_SETVRREGS 19
-/* Additional PTRACE requests implemented on PowerPC. */
-#define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */
-#define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */
-#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */
-#define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */
-#define PPC_PTRACE_PEEKTEXT_3264 0x95 /* Read word at location ADDR on a 64-bit process from a 32-bit process. */
-#define PPC_PTRACE_PEEKDATA_3264 0x94 /* Read word at location ADDR on a 64-bit process from a 32-bit process. */
-#define PPC_PTRACE_POKETEXT_3264 0x93 /* Write word at location ADDR on a 64-bit process from a 32-bit process. */
-#define PPC_PTRACE_POKEDATA_3264 0x92 /* Write word at location ADDR on a 64-bit process from a 32-bit process. */
-#define PPC_PTRACE_PEEKUSR_3264 0x91 /* Read a register (specified by ADDR) out of the "user area" on a 64-bit process from a 32-bit process. */
-#define PPC_PTRACE_POKEUSR_3264 0x90 /* Write DATA into location ADDR within the "user area" on a 64-bit process from a 32-bit process. */
+/*
+ * While we dont have 64bit book E processors, we need to reserve the
+ * relevant ptrace calls for 32bit compatibility.
+ */
+#if 0
+#define PTRACE_GETEVRREGS 20
+#define PTRACE_SETEVRREGS 21
+#endif
+/*
+ * Get or set a debug register. The first 16 are DABR registers and the
+ * second 16 are IABR registers.
+ */
+#define PTRACE_GET_DEBUGREG 25
+#define PTRACE_SET_DEBUGREG 26
+
+/* Additional PTRACE requests implemented on PowerPC. */
+#define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */
+#define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */
+#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */
+#define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */
+
+/* Calls to trace a 64bit program from a 32bit program */
+#define PPC_PTRACE_PEEKTEXT_3264 0x95
+#define PPC_PTRACE_PEEKDATA_3264 0x94
+#define PPC_PTRACE_POKETEXT_3264 0x93
+#define PPC_PTRACE_POKEDATA_3264 0x92
+#define PPC_PTRACE_PEEKUSR_3264 0x91
+#define PPC_PTRACE_POKEUSR_3264 0x90
#endif /* _PPC64_PTRACE_H */
diff --git a/include/asm-ppc64/segment.h b/include/asm-ppc64/segment.h
deleted file mode 100644
index d80fb68cc79e..000000000000
--- a/include/asm-ppc64/segment.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#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 b257b8348c73..000000000000
--- 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/smu.h b/include/asm-ppc64/smu.h
index 10b4397af9aa..dee8eefe47bc 100644
--- a/include/asm-ppc64/smu.h
+++ b/include/asm-ppc64/smu.h
@@ -1,22 +1,379 @@
+#ifndef _SMU_H
+#define _SMU_H
+
/*
* Definitions for talking to the SMU chip in newer G5 PowerMacs
*/
#include <linux/config.h>
+#include <linux/list.h>
+
+/*
+ * Known SMU commands
+ *
+ * Most of what is below comes from looking at the Open Firmware driver,
+ * though this is still incomplete and could use better documentation here
+ * or there...
+ */
+
+
+/*
+ * Partition info commands
+ *
+ * I do not know what those are for at this point
+ */
+#define SMU_CMD_PARTITION_COMMAND 0x3e
+
+
+/*
+ * Fan control
+ *
+ * This is a "mux" for fan control commands, first byte is the
+ * "sub" command.
+ */
+#define SMU_CMD_FAN_COMMAND 0x4a
+
+
+/*
+ * Battery access
+ *
+ * Same command number as the PMU, could it be same syntax ?
+ */
+#define SMU_CMD_BATTERY_COMMAND 0x6f
+#define SMU_CMD_GET_BATTERY_INFO 0x00
+
+/*
+ * Real time clock control
+ *
+ * This is a "mux", first data byte contains the "sub" command.
+ * The "RTC" part of the SMU controls the date, time, powerup
+ * timer, but also a PRAM
+ *
+ * Dates are in BCD format on 7 bytes:
+ * [sec] [min] [hour] [weekday] [month day] [month] [year]
+ * with month being 1 based and year minus 100
+ */
+#define SMU_CMD_RTC_COMMAND 0x8e
+#define SMU_CMD_RTC_SET_PWRUP_TIMER 0x00 /* i: 7 bytes date */
+#define SMU_CMD_RTC_GET_PWRUP_TIMER 0x01 /* o: 7 bytes date */
+#define SMU_CMD_RTC_STOP_PWRUP_TIMER 0x02
+#define SMU_CMD_RTC_SET_PRAM_BYTE_ACC 0x20 /* i: 1 byte (address?) */
+#define SMU_CMD_RTC_SET_PRAM_AUTOINC 0x21 /* i: 1 byte (data?) */
+#define SMU_CMD_RTC_SET_PRAM_LO_BYTES 0x22 /* i: 10 bytes */
+#define SMU_CMD_RTC_SET_PRAM_HI_BYTES 0x23 /* i: 10 bytes */
+#define SMU_CMD_RTC_GET_PRAM_BYTE 0x28 /* i: 1 bytes (address?) */
+#define SMU_CMD_RTC_GET_PRAM_LO_BYTES 0x29 /* o: 10 bytes */
+#define SMU_CMD_RTC_GET_PRAM_HI_BYTES 0x2a /* o: 10 bytes */
+#define SMU_CMD_RTC_SET_DATETIME 0x80 /* i: 7 bytes date */
+#define SMU_CMD_RTC_GET_DATETIME 0x81 /* o: 7 bytes date */
+
+ /*
+ * i2c commands
+ *
+ * To issue an i2c command, first is to send a parameter block to the
+ * the SMU. This is a command of type 0x9a with 9 bytes of header
+ * eventually followed by data for a write:
+ *
+ * 0: bus number (from device-tree usually, SMU has lots of busses !)
+ * 1: transfer type/format (see below)
+ * 2: device address. For combined and combined4 type transfers, this
+ * is the "write" version of the address (bit 0x01 cleared)
+ * 3: subaddress length (0..3)
+ * 4: subaddress byte 0 (or only byte for subaddress length 1)
+ * 5: subaddress byte 1
+ * 6: subaddress byte 2
+ * 7: combined address (device address for combined mode data phase)
+ * 8: data length
+ *
+ * The transfer types are the same good old Apple ones it seems,
+ * that is:
+ * - 0x00: Simple transfer
+ * - 0x01: Subaddress transfer (addr write + data tx, no restart)
+ * - 0x02: Combined transfer (addr write + restart + data tx)
+ *
+ * This is then followed by actual data for a write.
+ *
+ * At this point, the OF driver seems to have a limitation on transfer
+ * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know
+ * wether this is just an OF limit due to some temporary buffer size
+ * or if this is an SMU imposed limit. This driver has the same limitation
+ * for now as I use a 0x10 bytes temporary buffer as well
+ *
+ * Once that is completed, a response is expected from the SMU. This is
+ * obtained via a command of type 0x9a with a length of 1 byte containing
+ * 0 as the data byte. OF also fills the rest of the data buffer with 0xff's
+ * though I can't tell yet if this is actually necessary. Once this command
+ * is complete, at this point, all I can tell is what OF does. OF tests
+ * byte 0 of the reply:
+ * - on read, 0xfe or 0xfc : bus is busy, wait (see below) or nak ?
+ * - on read, 0x00 or 0x01 : reply is in buffer (after the byte 0)
+ * - on write, < 0 -> failure (immediate exit)
+ * - else, OF just exists (without error, weird)
+ *
+ * So on read, there is this wait-for-busy thing when getting a 0xfc or
+ * 0xfe result. OF does a loop of up to 64 retries, waiting 20ms and
+ * doing the above again until either the retries expire or the result
+ * is no longer 0xfe or 0xfc
+ *
+ * The Darwin I2C driver is less subtle though. On any non-success status
+ * from the response command, it waits 5ms and tries again up to 20 times,
+ * it doesn't differenciate between fatal errors or "busy" status.
+ *
+ * This driver provides an asynchronous paramblock based i2c command
+ * interface to be used either directly by low level code or by a higher
+ * level driver interfacing to the linux i2c layer. The current
+ * implementation of this relies on working timers & timer interrupts
+ * though, so be careful of calling context for now. This may be "fixed"
+ * in the future by adding a polling facility.
+ */
+#define SMU_CMD_I2C_COMMAND 0x9a
+ /* transfer types */
+#define SMU_I2C_TRANSFER_SIMPLE 0x00
+#define SMU_I2C_TRANSFER_STDSUB 0x01
+#define SMU_I2C_TRANSFER_COMBINED 0x02
+
+/*
+ * Power supply control
+ *
+ * The "sub" command is an ASCII string in the data, the
+ * data lenght is that of the string.
+ *
+ * The VSLEW command can be used to get or set the voltage slewing.
+ * - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
+ * reply at data offset 6, 7 and 8.
+ * - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is
+ * used to set the voltage slewing point. The SMU replies with "DONE"
+ * I yet have to figure out their exact meaning of those 3 bytes in
+ * both cases.
+ *
+ */
+#define SMU_CMD_POWER_COMMAND 0xaa
+#define SMU_CMD_POWER_RESTART "RESTART"
+#define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN"
+#define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW"
+
+/* Misc commands
+ *
+ * This command seem to be a grab bag of various things
+ */
+#define SMU_CMD_MISC_df_COMMAND 0xdf
+#define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02 /* i: 1 byte */
+#define SMU_CMD_MISC_df_NMI_OPTION 0x04
+
+/*
+ * Version info commands
+ *
+ * I haven't quite tried to figure out how these work
+ */
+#define SMU_CMD_VERSION_COMMAND 0xea
+
+
+/*
+ * Misc commands
+ *
+ * This command seem to be a grab bag of various things
+ */
+#define SMU_CMD_MISC_ee_COMMAND 0xee
+#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02
+#define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */
+#define SMU_CMD_MISC_ee_GET_DATA 0x05 /* i: 00 , o: ?? */
+
+
+
+/*
+ * - Kernel side interface -
+ */
+
+#ifdef __KERNEL__
+
+/*
+ * Asynchronous SMU commands
+ *
+ * Fill up this structure and submit it via smu_queue_command(),
+ * and get notified by the optional done() callback, or because
+ * status becomes != 1
+ */
+
+struct smu_cmd;
+
+struct smu_cmd
+{
+ /* public */
+ u8 cmd; /* command */
+ int data_len; /* data len */
+ int reply_len; /* reply len */
+ void *data_buf; /* data buffer */
+ void *reply_buf; /* reply buffer */
+ int status; /* command status */
+ void (*done)(struct smu_cmd *cmd, void *misc);
+ void *misc;
+
+ /* private */
+ struct list_head link;
+};
+
+/*
+ * Queues an SMU command, all fields have to be initialized
+ */
+extern int smu_queue_cmd(struct smu_cmd *cmd);
+
+/*
+ * Simple command wrapper. This structure embeds a small buffer
+ * to ease sending simple SMU commands from the stack
+ */
+struct smu_simple_cmd
+{
+ struct smu_cmd cmd;
+ u8 buffer[16];
+};
+
+/*
+ * Queues a simple command. All fields will be initialized by that
+ * function
+ */
+extern int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command,
+ unsigned int data_len,
+ void (*done)(struct smu_cmd *cmd, void *misc),
+ void *misc,
+ ...);
+
+/*
+ * Completion helper. Pass it to smu_queue_simple or as 'done'
+ * member to smu_queue_cmd, it will call complete() on the struct
+ * completion passed in the "misc" argument
+ */
+extern void smu_done_complete(struct smu_cmd *cmd, void *misc);
/*
- * Basic routines for use by architecture. To be extended as
- * we understand more of the chip
+ * Synchronous helpers. Will spin-wait for completion of a command
+ */
+extern void smu_spinwait_cmd(struct smu_cmd *cmd);
+
+static inline void smu_spinwait_simple(struct smu_simple_cmd *scmd)
+{
+ smu_spinwait_cmd(&scmd->cmd);
+}
+
+/*
+ * Poll routine to call if blocked with irqs off
+ */
+extern void smu_poll(void);
+
+
+/*
+ * Init routine, presence check....
*/
extern int smu_init(void);
extern int smu_present(void);
+struct of_device;
+extern struct of_device *smu_get_ofdev(void);
+
+
+/*
+ * Common command wrappers
+ */
extern void smu_shutdown(void);
extern void smu_restart(void);
-extern int smu_get_rtc_time(struct rtc_time *time);
-extern int smu_set_rtc_time(struct rtc_time *time);
+struct rtc_time;
+extern int smu_get_rtc_time(struct rtc_time *time, int spinwait);
+extern int smu_set_rtc_time(struct rtc_time *time, int spinwait);
/*
* SMU command buffer absolute address, exported by pmac_setup,
* this is allocated very early during boot.
*/
extern unsigned long smu_cmdbuf_abs;
+
+
+/*
+ * Kenrel asynchronous i2c interface
+ */
+
+/* SMU i2c header, exactly matches i2c header on wire */
+struct smu_i2c_param
+{
+ u8 bus; /* SMU bus ID (from device tree) */
+ u8 type; /* i2c transfer type */
+ u8 devaddr; /* device address (includes direction) */
+ u8 sublen; /* subaddress length */
+ u8 subaddr[3]; /* subaddress */
+ u8 caddr; /* combined address, filled by SMU driver */
+ u8 datalen; /* length of transfer */
+ u8 data[7]; /* data */
+};
+
+#define SMU_I2C_READ_MAX 0x0d
+#define SMU_I2C_WRITE_MAX 0x05
+
+struct smu_i2c_cmd
+{
+ /* public */
+ struct smu_i2c_param info;
+ void (*done)(struct smu_i2c_cmd *cmd, void *misc);
+ void *misc;
+ int status; /* 1 = pending, 0 = ok, <0 = fail */
+
+ /* private */
+ struct smu_cmd scmd;
+ int read;
+ int stage;
+ int retries;
+ u8 pdata[0x10];
+ struct list_head link;
+};
+
+/*
+ * Call this to queue an i2c command to the SMU. You must fill info,
+ * including info.data for a write, done and misc.
+ * For now, no polling interface is provided so you have to use completion
+ * callback.
+ */
+extern int smu_queue_i2c(struct smu_i2c_cmd *cmd);
+
+
+#endif /* __KERNEL__ */
+
+/*
+ * - Userland interface -
+ */
+
+/*
+ * A given instance of the device can be configured for 2 different
+ * things at the moment:
+ *
+ * - sending SMU commands (default at open() time)
+ * - receiving SMU events (not yet implemented)
+ *
+ * Commands are written with write() of a command block. They can be
+ * "driver" commands (for example to switch to event reception mode)
+ * or real SMU commands. They are made of a header followed by command
+ * data if any.
+ *
+ * For SMU commands (not for driver commands), you can then read() back
+ * a reply. The reader will be blocked or not depending on how the device
+ * file is opened. poll() isn't implemented yet. The reply will consist
+ * of a header as well, followed by the reply data if any. You should
+ * always provide a buffer large enough for the maximum reply data, I
+ * recommand one page.
+ *
+ * It is illegal to send SMU commands through a file descriptor configured
+ * for events reception
+ *
+ */
+struct smu_user_cmd_hdr
+{
+ __u32 cmdtype;
+#define SMU_CMDTYPE_SMU 0 /* SMU command */
+#define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */
+
+ __u8 cmd; /* SMU command byte */
+ __u32 data_len; /* Lenght of data following */
+};
+
+struct smu_user_reply_hdr
+{
+ __u32 status; /* Command status */
+ __u32 reply_len; /* Lenght of data follwing */
+};
+
+#endif /* _SMU_H */
diff --git a/include/asm-ppc64/spinlock.h b/include/asm-ppc64/spinlock.h
index acd11564dd75..14cb895bb607 100644
--- a/include/asm-ppc64/spinlock.h
+++ b/include/asm-ppc64/spinlock.h
@@ -15,36 +15,42 @@
* 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.
+ *
+ * (the type definitions are in asm/spinlock_types.h)
*/
#include <linux/config.h>
#include <asm/paca.h>
#include <asm/hvcall.h>
#include <asm/iSeries/HvCall.h>
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
+#define __raw_spin_is_locked(x) ((x)->slock != 0)
-typedef struct {
- volatile signed int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
+/*
+ * This returns the old value in the lock, so we succeeded
+ * in getting the lock if the return value is 0.
+ */
+static __inline__ unsigned long __spin_trylock(raw_spinlock_t *lock)
+{
+ unsigned long tmp, tmp2;
-#ifdef __KERNEL__
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+ __asm__ __volatile__(
+" lwz %1,%3(13) # __spin_trylock\n\
+1: lwarx %0,0,%2\n\
+ cmpwi 0,%0,0\n\
+ bne- 2f\n\
+ stwcx. %1,0,%2\n\
+ bne- 1b\n\
+ isync\n\
+2:" : "=&r" (tmp), "=&r" (tmp2)
+ : "r" (&lock->slock), "i" (offsetof(struct paca_struct, lock_token))
+ : "cr0", "memory");
-#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
+ return tmp;
+}
-static __inline__ void _raw_spin_unlock(spinlock_t *lock)
+static int __inline__ __raw_spin_trylock(raw_spinlock_t *lock)
{
- __asm__ __volatile__("lwsync # spin_unlock": : :"memory");
- lock->lock = 0;
+ return __spin_trylock(lock) == 0;
}
/*
@@ -64,44 +70,15 @@ static __inline__ void _raw_spin_unlock(spinlock_t *lock)
#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
/* We only yield to the hypervisor if we are in shared processor mode */
#define SHARED_PROCESSOR (get_paca()->lppaca.shared_proc)
-extern void __spin_yield(spinlock_t *lock);
-extern void __rw_yield(rwlock_t *lock);
+extern void __spin_yield(raw_spinlock_t *lock);
+extern void __rw_yield(raw_rwlock_t *lock);
#else /* SPLPAR || ISERIES */
#define __spin_yield(x) barrier()
#define __rw_yield(x) barrier()
#define SHARED_PROCESSOR 0
#endif
-extern void spin_unlock_wait(spinlock_t *lock);
-
-/*
- * This returns the old value in the lock, so we succeeded
- * in getting the lock if the return value is 0.
- */
-static __inline__ unsigned long __spin_trylock(spinlock_t *lock)
-{
- unsigned long tmp, tmp2;
-
- __asm__ __volatile__(
-" lwz %1,%3(13) # __spin_trylock\n\
-1: lwarx %0,0,%2\n\
- cmpwi 0,%0,0\n\
- bne- 2f\n\
- stwcx. %1,0,%2\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp), "=&r" (tmp2)
- : "r" (&lock->lock), "i" (offsetof(struct paca_struct, lock_token))
- : "cr0", "memory");
-
- return tmp;
-}
-
-static int __inline__ _raw_spin_trylock(spinlock_t *lock)
-{
- return __spin_trylock(lock) == 0;
-}
-static void __inline__ _raw_spin_lock(spinlock_t *lock)
+static void __inline__ __raw_spin_lock(raw_spinlock_t *lock)
{
while (1) {
if (likely(__spin_trylock(lock) == 0))
@@ -110,12 +87,12 @@ static void __inline__ _raw_spin_lock(spinlock_t *lock)
HMT_low();
if (SHARED_PROCESSOR)
__spin_yield(lock);
- } while (unlikely(lock->lock != 0));
+ } while (unlikely(lock->slock != 0));
HMT_medium();
}
}
-static void __inline__ _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags)
+static void __inline__ __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
{
unsigned long flags_dis;
@@ -128,12 +105,20 @@ static void __inline__ _raw_spin_lock_flags(spinlock_t *lock, unsigned long flag
HMT_low();
if (SHARED_PROCESSOR)
__spin_yield(lock);
- } while (unlikely(lock->lock != 0));
+ } while (unlikely(lock->slock != 0));
HMT_medium();
local_irq_restore(flags_dis);
}
}
+static __inline__ void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+ __asm__ __volatile__("lwsync # __raw_spin_unlock": : :"memory");
+ lock->slock = 0;
+}
+
+extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
+
/*
* Read-write spinlocks, allowing multiple readers
* but only one writer.
@@ -144,24 +129,15 @@ static void __inline__ _raw_spin_lock_flags(spinlock_t *lock, unsigned long flag
* irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
*/
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-
-#define read_can_lock(rw) ((rw)->lock >= 0)
-#define write_can_lock(rw) (!(rw)->lock)
-
-static __inline__ void _raw_write_unlock(rwlock_t *rw)
-{
- __asm__ __volatile__("lwsync # write_unlock": : :"memory");
- rw->lock = 0;
-}
+#define __raw_read_can_lock(rw) ((rw)->lock >= 0)
+#define __raw_write_can_lock(rw) (!(rw)->lock)
/*
* This returns the old value in the lock + 1,
* so we got a read lock if the return value is > 0.
*/
-static long __inline__ __read_trylock(rwlock_t *rw)
+static long __inline__ __read_trylock(raw_rwlock_t *rw)
{
long tmp;
@@ -180,45 +156,11 @@ static long __inline__ __read_trylock(rwlock_t *rw)
return tmp;
}
-static int __inline__ _raw_read_trylock(rwlock_t *rw)
-{
- return __read_trylock(rw) > 0;
-}
-
-static void __inline__ _raw_read_lock(rwlock_t *rw)
-{
- while (1) {
- if (likely(__read_trylock(rw) > 0))
- break;
- do {
- HMT_low();
- if (SHARED_PROCESSOR)
- __rw_yield(rw);
- } while (unlikely(rw->lock < 0));
- HMT_medium();
- }
-}
-
-static void __inline__ _raw_read_unlock(rwlock_t *rw)
-{
- long tmp;
-
- __asm__ __volatile__(
- "eieio # read_unlock\n\
-1: lwarx %0,0,%1\n\
- addic %0,%0,-1\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- : "=&r"(tmp)
- : "r"(&rw->lock)
- : "cr0", "memory");
-}
-
/*
* This returns the old value in the lock,
* so we got the write lock if the return value is 0.
*/
-static __inline__ long __write_trylock(rwlock_t *rw)
+static __inline__ long __write_trylock(raw_rwlock_t *rw)
{
long tmp, tmp2;
@@ -237,12 +179,21 @@ static __inline__ long __write_trylock(rwlock_t *rw)
return tmp;
}
-static int __inline__ _raw_write_trylock(rwlock_t *rw)
+static void __inline__ __raw_read_lock(raw_rwlock_t *rw)
{
- return __write_trylock(rw) == 0;
+ while (1) {
+ if (likely(__read_trylock(rw) > 0))
+ break;
+ do {
+ HMT_low();
+ if (SHARED_PROCESSOR)
+ __rw_yield(rw);
+ } while (unlikely(rw->lock < 0));
+ HMT_medium();
+ }
}
-static void __inline__ _raw_write_lock(rwlock_t *rw)
+static void __inline__ __raw_write_lock(raw_rwlock_t *rw)
{
while (1) {
if (likely(__write_trylock(rw) == 0))
@@ -256,5 +207,35 @@ static void __inline__ _raw_write_lock(rwlock_t *rw)
}
}
-#endif /* __KERNEL__ */
+static int __inline__ __raw_read_trylock(raw_rwlock_t *rw)
+{
+ return __read_trylock(rw) > 0;
+}
+
+static int __inline__ __raw_write_trylock(raw_rwlock_t *rw)
+{
+ return __write_trylock(rw) == 0;
+}
+
+static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
+{
+ long tmp;
+
+ __asm__ __volatile__(
+ "eieio # read_unlock\n\
+1: lwarx %0,0,%1\n\
+ addic %0,%0,-1\n\
+ stwcx. %0,0,%1\n\
+ bne- 1b"
+ : "=&r"(tmp)
+ : "r"(&rw->lock)
+ : "cr0", "memory");
+}
+
+static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
+{
+ __asm__ __volatile__("lwsync # write_unlock": : :"memory");
+ rw->lock = 0;
+}
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-ppc64/spinlock_types.h b/include/asm-ppc64/spinlock_types.h
new file mode 100644
index 000000000000..a37c8eabb9f2
--- /dev/null
+++ b/include/asm-ppc64/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int slock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile signed int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
index c0396428cc3c..375015c62f20 100644
--- a/include/asm-ppc64/system.h
+++ b/include/asm-ppc64/system.h
@@ -101,6 +101,9 @@ static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif
+extern int set_dabr(unsigned long dabr);
+extern void _exception(int signr, struct pt_regs *regs, int code,
+ unsigned long addr);
extern int fix_alignment(struct pt_regs *regs);
extern void bad_page_fault(struct pt_regs *regs, unsigned long address,
int sig);
diff --git a/include/asm-ppc64/timex.h b/include/asm-ppc64/timex.h
deleted file mode 100644
index 8db4da4064cd..000000000000
--- a/include/asm-ppc64/timex.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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/tlbflush.h b/include/asm-ppc64/tlbflush.h
index 45411a67e082..74271d7c1d16 100644
--- a/include/asm-ppc64/tlbflush.h
+++ b/include/asm-ppc64/tlbflush.h
@@ -25,6 +25,7 @@ struct ppc64_tlb_batch {
pte_t pte[PPC64_TLB_BATCH_NR];
unsigned long addr[PPC64_TLB_BATCH_NR];
unsigned long vaddr[PPC64_TLB_BATCH_NR];
+ unsigned int large;
};
DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
diff --git a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
index c181a60d868c..132c1276547b 100644
--- a/include/asm-ppc64/uaccess.h
+++ b/include/asm-ppc64/uaccess.h
@@ -164,7 +164,8 @@ do { \
#define __get_user_nocheck(x,ptr,size) \
({ \
- long __gu_err, __gu_val; \
+ long __gu_err; \
+ unsigned long __gu_val; \
might_sleep(); \
__get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
(x) = (__typeof__(*(ptr)))__gu_val; \
@@ -173,7 +174,8 @@ do { \
#define __get_user_check(x,ptr,size) \
({ \
- long __gu_err = -EFAULT, __gu_val = 0; \
+ long __gu_err = -EFAULT; \
+ unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
might_sleep(); \
if (access_ok(VERIFY_READ,__gu_addr,size)) \
diff --git a/include/asm-ppc64/user.h b/include/asm-ppc64/user.h
deleted file mode 100644
index d7d6554a421f..000000000000
--- a/include/asm-ppc64/user.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#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-s390/futex.h b/include/asm-s390/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-s390/futex.h
+++ b/include/asm-s390/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-s390/sigcontext.h b/include/asm-s390/sigcontext.h
index d57bc0cebdce..803545351dd8 100644
--- a/include/asm-s390/sigcontext.h
+++ b/include/asm-s390/sigcontext.h
@@ -61,7 +61,7 @@ typedef struct
struct sigcontext
{
unsigned long oldmask[_SIGCONTEXT_NSIG_WORDS];
- _sigregs *sregs;
+ _sigregs __user *sregs;
};
diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h
index 3d6e11c6c1fd..7084626de215 100644
--- a/include/asm-s390/signal.h
+++ b/include/asm-s390/signal.h
@@ -165,7 +165,7 @@ struct sigaction {
#endif /* __KERNEL__ */
typedef struct sigaltstack {
- void *ss_sp;
+ void __user *ss_sp;
int ss_flags;
size_t ss_size;
} stack_t;
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h
index 321b23bba1ec..273dbecf8ace 100644
--- a/include/asm-s390/spinlock.h
+++ b/include/asm-s390/spinlock.h
@@ -27,25 +27,19 @@ _raw_compare_and_swap(volatile unsigned int *lock,
* on the local processor, one does not.
*
* We make no fairness assumptions. They have a cost.
+ *
+ * (the type definitions are in asm/spinlock_types.h)
*/
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} __attribute__ ((aligned (4))) spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-#define spin_lock_init(lp) do { (lp)->lock = 0; } while(0)
-#define spin_unlock_wait(lp) do { barrier(); } while(((volatile spinlock_t *)(lp))->lock)
-#define spin_is_locked(x) ((x)->lock != 0)
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
-extern void _raw_spin_lock_wait(spinlock_t *lp, unsigned int pc);
-extern int _raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc);
+extern void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc);
+extern int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc);
-static inline void _raw_spin_lock(spinlock_t *lp)
+static inline void __raw_spin_lock(raw_spinlock_t *lp)
{
unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
@@ -53,7 +47,7 @@ static inline void _raw_spin_lock(spinlock_t *lp)
_raw_spin_lock_wait(lp, pc);
}
-static inline int _raw_spin_trylock(spinlock_t *lp)
+static inline int __raw_spin_trylock(raw_spinlock_t *lp)
{
unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
@@ -62,7 +56,7 @@ static inline int _raw_spin_trylock(spinlock_t *lp)
return _raw_spin_trylock_retry(lp, pc);
}
-static inline void _raw_spin_unlock(spinlock_t *lp)
+static inline void __raw_spin_unlock(raw_spinlock_t *lp)
{
_raw_compare_and_swap(&lp->lock, lp->lock, 0);
}
@@ -77,36 +71,25 @@ static inline void _raw_spin_unlock(spinlock_t *lp)
* irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
*/
-typedef struct {
- volatile unsigned int lock;
- volatile unsigned long owner_pc;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
/**
* read_can_lock - would read_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define read_can_lock(x) ((int)(x)->lock >= 0)
+#define __raw_read_can_lock(x) ((int)(x)->lock >= 0)
/**
* write_can_lock - would write_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define write_can_lock(x) ((x)->lock == 0)
+#define __raw_write_can_lock(x) ((x)->lock == 0)
-extern void _raw_read_lock_wait(rwlock_t *lp);
-extern int _raw_read_trylock_retry(rwlock_t *lp);
-extern void _raw_write_lock_wait(rwlock_t *lp);
-extern int _raw_write_trylock_retry(rwlock_t *lp);
+extern void _raw_read_lock_wait(raw_rwlock_t *lp);
+extern int _raw_read_trylock_retry(raw_rwlock_t *lp);
+extern void _raw_write_lock_wait(raw_rwlock_t *lp);
+extern int _raw_write_trylock_retry(raw_rwlock_t *lp);
-static inline void _raw_read_lock(rwlock_t *rw)
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned int old;
old = rw->lock & 0x7fffffffU;
@@ -114,7 +97,7 @@ static inline void _raw_read_lock(rwlock_t *rw)
_raw_read_lock_wait(rw);
}
-static inline void _raw_read_unlock(rwlock_t *rw)
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned int old, cmp;
@@ -125,18 +108,18 @@ static inline void _raw_read_unlock(rwlock_t *rw)
} while (cmp != old);
}
-static inline void _raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0))
_raw_write_lock_wait(rw);
}
-static inline void _raw_write_unlock(rwlock_t *rw)
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
_raw_compare_and_swap(&rw->lock, 0x80000000, 0);
}
-static inline int _raw_read_trylock(rwlock_t *rw)
+static inline int __raw_read_trylock(raw_rwlock_t *rw)
{
unsigned int old;
old = rw->lock & 0x7fffffffU;
@@ -145,7 +128,7 @@ static inline int _raw_read_trylock(rwlock_t *rw)
return _raw_read_trylock_retry(rw);
}
-static inline int _raw_write_trylock(rwlock_t *rw)
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
{
if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0))
return 1;
diff --git a/include/asm-s390/spinlock_types.h b/include/asm-s390/spinlock_types.h
new file mode 100644
index 000000000000..f79a2216204f
--- /dev/null
+++ b/include/asm-s390/spinlock_types.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} __attribute__ ((aligned (4))) raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+ volatile unsigned int owner_pc;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0, 0 }
+
+#endif
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 80d164c1529e..d3fa5c2b889d 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -9,7 +9,7 @@
extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
+extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
@@ -26,7 +26,7 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
}
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
if (sh_mv.mv_consistent_alloc) {
void *ret;
diff --git a/include/asm-sh/futex.h b/include/asm-sh/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-sh/futex.h
+++ b/include/asm-sh/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 831e52ee45b5..614a8c13b721 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -587,10 +587,6 @@ static inline int generic_irq_demux(int irq)
#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-sh/machvec.h b/include/asm-sh/machvec.h
index 5771f4baa478..3f18aa180516 100644
--- a/include/asm-sh/machvec.h
+++ b/include/asm-sh/machvec.h
@@ -64,7 +64,7 @@ struct sh_machine_vector
void (*mv_heartbeat)(void);
- void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, int);
+ void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, gfp_t);
int (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t);
};
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index ecb909572d3f..0f4bcaae61bd 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -277,9 +277,6 @@ typedef pte_t *pte_addr_t;
#define kern_addr_valid(addr) (1)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h
index e770b55649eb..846322d4c35d 100644
--- a/include/asm-sh/spinlock.h
+++ b/include/asm-sh/spinlock.h
@@ -15,20 +15,11 @@
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
*/
-typedef struct {
- volatile unsigned long lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_unlock_wait(x) do { barrier(); } while (spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_unlock_wait(x) \
+ do { cpu_relax(); } while (__raw_spin_is_locked(x))
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
@@ -36,7 +27,7 @@ typedef struct {
*
* We make no fairness assumptions. They have a cost.
*/
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
__asm__ __volatile__ (
"1:\n\t"
@@ -49,14 +40,14 @@ static inline void _raw_spin_lock(spinlock_t *lock)
);
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
assert_spin_locked(lock);
lock->lock = 0;
}
-#define _raw_spin_trylock(x) (!test_and_set_bit(0, &(x)->lock))
+#define __raw_spin_trylock(x) (!test_and_set_bit(0, &(x)->lock))
/*
* Read-write spinlocks, allowing multiple readers but only one writer.
@@ -66,51 +57,40 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
* needs to get a irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
*/
-typedef struct {
- spinlock_t lock;
- atomic_t counter;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RW_LOCK_BIAS 0x01000000
-#define RW_LOCK_UNLOCKED (rwlock_t) { { 0 }, { RW_LOCK_BIAS } }
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while (0)
-
-static inline void _raw_read_lock(rwlock_t *rw)
+
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
atomic_inc(&rw->counter);
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
}
-static inline void _raw_read_unlock(rwlock_t *rw)
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
atomic_dec(&rw->counter);
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
}
-static inline void _raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
- _raw_spin_lock(&rw->lock);
+ __raw_spin_lock(&rw->lock);
atomic_set(&rw->counter, -1);
}
-static inline void _raw_write_unlock(rwlock_t *rw)
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
atomic_set(&rw->counter, 0);
- _raw_spin_unlock(&rw->lock);
+ __raw_spin_unlock(&rw->lock);
}
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
-static inline int _raw_write_trylock(rwlock_t *rw)
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
{
if (atomic_sub_and_test(RW_LOCK_BIAS, &rw->counter))
return 1;
@@ -121,4 +101,3 @@ static inline int _raw_write_trylock(rwlock_t *rw)
}
#endif /* __ASM_SH_SPINLOCK_H */
-
diff --git a/include/asm-sh/spinlock_types.h b/include/asm-sh/spinlock_types.h
new file mode 100644
index 000000000000..8c41b6c3aac8
--- /dev/null
+++ b/include/asm-sh/spinlock_types.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_SH_SPINLOCK_TYPES_H
+#define __ASM_SH_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned long lock;
+} raw_spinlock_t;
+
+#define __SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ raw_spinlock_t lock;
+ atomic_t counter;
+} raw_rwlock_t;
+
+#define RW_LOCK_BIAS 0x01000000
+#define __RAW_RW_LOCK_UNLOCKED { { 0 }, { RW_LOCK_BIAS } }
+
+#endif
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index b8d26fe677f4..cc9a2e86f5b4 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -25,7 +25,7 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
}
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
return consistent_alloc(NULL, size, dma_handle);
}
diff --git a/include/asm-sh64/futex.h b/include/asm-sh64/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-sh64/futex.h
+++ b/include/asm-sh64/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 78ac6be2d9ef..51db4307bfaf 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -482,9 +482,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
#define PageSkip(page) (0)
#define kern_addr_valid(addr) (1)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-sparc/btfixup.h b/include/asm-sparc/btfixup.h
index b84c96c89581..c2868d0f60b6 100644
--- a/include/asm-sparc/btfixup.h
+++ b/include/asm-sparc/btfixup.h
@@ -49,17 +49,17 @@ extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
/* Put bottom 13bits into some register variable */
#define BTFIXUPDEF_SIMM13(__name) \
- extern unsigned int ___sf_##__name(void) __attribute_const__; \
+ static inline unsigned int ___sf_##__name(void) __attribute_const__; \
extern unsigned ___ss_##__name[2]; \
- extern __inline__ unsigned int ___sf_##__name(void) { \
+ static inline unsigned int ___sf_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret)); \
return ret; \
}
#define BTFIXUPDEF_SIMM13_INIT(__name,__val) \
- extern unsigned int ___sf_##__name(void) __attribute_const__; \
+ static inline unsigned int ___sf_##__name(void) __attribute_const__; \
extern unsigned ___ss_##__name[2]; \
- extern __inline__ unsigned int ___sf_##__name(void) { \
+ static inline unsigned int ___sf_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
return ret; \
@@ -71,17 +71,17 @@ extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
*/
#define BTFIXUPDEF_HALF(__name) \
- extern unsigned int ___af_##__name(void) __attribute_const__; \
+ static inline unsigned int ___af_##__name(void) __attribute_const__; \
extern unsigned ___as_##__name[2]; \
- extern __inline__ unsigned int ___af_##__name(void) { \
+ static inline unsigned int ___af_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret)); \
return ret; \
}
#define BTFIXUPDEF_HALF_INIT(__name,__val) \
- extern unsigned int ___af_##__name(void) __attribute_const__; \
+ static inline unsigned int ___af_##__name(void) __attribute_const__; \
extern unsigned ___as_##__name[2]; \
- extern __inline__ unsigned int ___af_##__name(void) { \
+ static inline unsigned int ___af_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
return ret; \
@@ -90,17 +90,17 @@ extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
/* Put upper 22 bits into some register variable */
#define BTFIXUPDEF_SETHI(__name) \
- extern unsigned int ___hf_##__name(void) __attribute_const__; \
+ static inline unsigned int ___hf_##__name(void) __attribute_const__; \
extern unsigned ___hs_##__name[2]; \
- extern __inline__ unsigned int ___hf_##__name(void) { \
+ static inline unsigned int ___hf_##__name(void) { \
unsigned int ret; \
__asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret)); \
return ret; \
}
#define BTFIXUPDEF_SETHI_INIT(__name,__val) \
- extern unsigned int ___hf_##__name(void) __attribute_const__; \
+ static inline unsigned int ___hf_##__name(void) __attribute_const__; \
extern unsigned ___hs_##__name[2]; \
- extern __inline__ unsigned int ___hf_##__name(void) { \
+ static inline unsigned int ___hf_##__name(void) { \
unsigned int ret; \
__asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : \
"=r"(ret)); \
diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h
index e6316fd7e1a4..a10522cb21b7 100644
--- a/include/asm-sparc/cache.h
+++ b/include/asm-sparc/cache.h
@@ -27,7 +27,7 @@
*/
/* First, cache-tag access. */
-extern __inline__ unsigned int get_icache_tag(int setnum, int tagnum)
+static inline unsigned int get_icache_tag(int setnum, int tagnum)
{
unsigned int vaddr, retval;
@@ -38,7 +38,7 @@ extern __inline__ unsigned int get_icache_tag(int setnum, int tagnum)
return retval;
}
-extern __inline__ void put_icache_tag(int setnum, int tagnum, unsigned int entry)
+static inline void put_icache_tag(int setnum, int tagnum, unsigned int entry)
{
unsigned int vaddr;
@@ -51,7 +51,7 @@ extern __inline__ void put_icache_tag(int setnum, int tagnum, unsigned int entry
/* Second cache-data access. The data is returned two-32bit quantities
* at a time.
*/
-extern __inline__ void get_icache_data(int setnum, int tagnum, int subblock,
+static inline void get_icache_data(int setnum, int tagnum, int subblock,
unsigned int *data)
{
unsigned int value1, value2, vaddr;
@@ -67,7 +67,7 @@ extern __inline__ void get_icache_data(int setnum, int tagnum, int subblock,
data[0] = value1; data[1] = value2;
}
-extern __inline__ void put_icache_data(int setnum, int tagnum, int subblock,
+static inline void put_icache_data(int setnum, int tagnum, int subblock,
unsigned int *data)
{
unsigned int value1, value2, vaddr;
@@ -92,35 +92,35 @@ extern __inline__ void put_icache_data(int setnum, int tagnum, int subblock,
*/
/* Flushes which clear out both the on-chip and external caches */
-extern __inline__ void flush_ei_page(unsigned int addr)
+static inline void flush_ei_page(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_PAGE) :
"memory");
}
-extern __inline__ void flush_ei_seg(unsigned int addr)
+static inline void flush_ei_seg(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_SEG) :
"memory");
}
-extern __inline__ void flush_ei_region(unsigned int addr)
+static inline void flush_ei_region(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_REGION) :
"memory");
}
-extern __inline__ void flush_ei_ctx(unsigned int addr)
+static inline void flush_ei_ctx(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_CTX) :
"memory");
}
-extern __inline__ void flush_ei_user(unsigned int addr)
+static inline void flush_ei_user(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_USER) :
diff --git a/include/asm-sparc/cypress.h b/include/asm-sparc/cypress.h
index fc92fc839c3f..99599533efbc 100644
--- a/include/asm-sparc/cypress.h
+++ b/include/asm-sparc/cypress.h
@@ -48,25 +48,25 @@
#define CYPRESS_NFAULT 0x00000002
#define CYPRESS_MENABLE 0x00000001
-extern __inline__ void cypress_flush_page(unsigned long page)
+static inline void cypress_flush_page(unsigned long page)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (page), "i" (ASI_M_FLUSH_PAGE));
}
-extern __inline__ void cypress_flush_segment(unsigned long addr)
+static inline void cypress_flush_segment(unsigned long addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_SEG));
}
-extern __inline__ void cypress_flush_region(unsigned long addr)
+static inline void cypress_flush_region(unsigned long addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_REGION));
}
-extern __inline__ void cypress_flush_context(void)
+static inline void cypress_flush_context(void)
{
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
"i" (ASI_M_FLUSH_CTX));
diff --git a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h
index 6edf2cbb246b..7ec8e9f7ad4f 100644
--- a/include/asm-sparc/delay.h
+++ b/include/asm-sparc/delay.h
@@ -10,7 +10,7 @@
#include <linux/config.h>
#include <asm/cpudata.h>
-extern __inline__ void __delay(unsigned long loops)
+static inline void __delay(unsigned long loops)
{
__asm__ __volatile__("cmp %0, 0\n\t"
"1: bne 1b\n\t"
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index 2dc5bb8effa6..d7c3b0f0a901 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -8,7 +8,7 @@
#else
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-sparc/dma.h b/include/asm-sparc/dma.h
index 07e6368a2521..8ec206aa5f2e 100644
--- a/include/asm-sparc/dma.h
+++ b/include/asm-sparc/dma.h
@@ -198,7 +198,7 @@ extern void dvma_init(struct sbus_bus *);
/* Pause until counter runs out or BIT isn't set in the DMA condition
* register.
*/
-extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs,
+static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
unsigned long bit)
{
int ctr = 50000; /* Let's find some bugs ;) */
diff --git a/include/asm-sparc/futex.h b/include/asm-sparc/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-sparc/futex.h
+++ b/include/asm-sparc/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-sparc/iommu.h b/include/asm-sparc/iommu.h
index 8171362d56b9..70c589c05a10 100644
--- a/include/asm-sparc/iommu.h
+++ b/include/asm-sparc/iommu.h
@@ -108,12 +108,12 @@ struct iommu_struct {
struct bit_map usemap;
};
-extern __inline__ void iommu_invalidate(struct iommu_regs *regs)
+static inline void iommu_invalidate(struct iommu_regs *regs)
{
regs->tlbflush = 0;
}
-extern __inline__ void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
+static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
{
regs->pageflush = (ba & PAGE_MASK);
}
diff --git a/include/asm-sparc/kdebug.h b/include/asm-sparc/kdebug.h
index 3ea4916635ee..fba92485fdba 100644
--- a/include/asm-sparc/kdebug.h
+++ b/include/asm-sparc/kdebug.h
@@ -46,7 +46,7 @@ struct kernel_debug {
extern struct kernel_debug *linux_dbvec;
/* Use this macro in C-code to enter the debugger. */
-extern __inline__ void sp_enter_debugger(void)
+static inline void sp_enter_debugger(void)
{
__asm__ __volatile__("jmpl %0, %%o7\n\t"
"nop\n\t" : :
diff --git a/include/asm-sparc/mbus.h b/include/asm-sparc/mbus.h
index 5f2749015342..ecacdf4075d7 100644
--- a/include/asm-sparc/mbus.h
+++ b/include/asm-sparc/mbus.h
@@ -83,7 +83,7 @@ extern unsigned int hwbug_bitmask;
*/
#define TBR_ID_SHIFT 20
-extern __inline__ int get_cpuid(void)
+static inline int get_cpuid(void)
{
register int retval;
__asm__ __volatile__("rd %%tbr, %0\n\t"
@@ -93,7 +93,7 @@ extern __inline__ int get_cpuid(void)
return (retval & 3);
}
-extern __inline__ int get_modid(void)
+static inline int get_modid(void)
{
return (get_cpuid() | 0x8);
}
diff --git a/include/asm-sparc/msi.h b/include/asm-sparc/msi.h
index b69543dd3b46..ff72cbd946a4 100644
--- a/include/asm-sparc/msi.h
+++ b/include/asm-sparc/msi.h
@@ -19,7 +19,7 @@
#define MSI_ASYNC_MODE 0x80000000 /* Operate the MSI asynchronously */
-extern __inline__ void msi_set_sync(void)
+static inline void msi_set_sync(void)
{
__asm__ __volatile__ ("lda [%0] %1, %%g3\n\t"
"andn %%g3, %2, %%g3\n\t"
diff --git a/include/asm-sparc/mxcc.h b/include/asm-sparc/mxcc.h
index 60ef9d6fe7bc..128fe9708135 100644
--- a/include/asm-sparc/mxcc.h
+++ b/include/asm-sparc/mxcc.h
@@ -85,7 +85,7 @@
#ifndef __ASSEMBLY__
-extern __inline__ void mxcc_set_stream_src(unsigned long *paddr)
+static inline void mxcc_set_stream_src(unsigned long *paddr)
{
unsigned long data0 = paddr[0];
unsigned long data1 = paddr[1];
@@ -98,7 +98,7 @@ extern __inline__ void mxcc_set_stream_src(unsigned long *paddr)
"i" (ASI_M_MXCC) : "g2", "g3");
}
-extern __inline__ void mxcc_set_stream_dst(unsigned long *paddr)
+static inline void mxcc_set_stream_dst(unsigned long *paddr)
{
unsigned long data0 = paddr[0];
unsigned long data1 = paddr[1];
@@ -111,7 +111,7 @@ extern __inline__ void mxcc_set_stream_dst(unsigned long *paddr)
"i" (ASI_M_MXCC) : "g2", "g3");
}
-extern __inline__ unsigned long mxcc_get_creg(void)
+static inline unsigned long mxcc_get_creg(void)
{
unsigned long mxcc_control;
@@ -125,7 +125,7 @@ extern __inline__ unsigned long mxcc_get_creg(void)
return mxcc_control;
}
-extern __inline__ void mxcc_set_creg(unsigned long mxcc_control)
+static inline void mxcc_set_creg(unsigned long mxcc_control)
{
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
"r" (mxcc_control), "r" (MXCC_CREG),
diff --git a/include/asm-sparc/obio.h b/include/asm-sparc/obio.h
index 62e1d77965f3..47854a2a12cf 100644
--- a/include/asm-sparc/obio.h
+++ b/include/asm-sparc/obio.h
@@ -98,7 +98,7 @@
#ifndef __ASSEMBLY__
-extern __inline__ int bw_get_intr_mask(int sbus_level)
+static inline int bw_get_intr_mask(int sbus_level)
{
int mask;
@@ -109,7 +109,7 @@ extern __inline__ int bw_get_intr_mask(int sbus_level)
return mask;
}
-extern __inline__ void bw_clear_intr_mask(int sbus_level, int mask)
+static inline void bw_clear_intr_mask(int sbus_level, int mask)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (mask),
@@ -117,7 +117,7 @@ extern __inline__ void bw_clear_intr_mask(int sbus_level, int mask)
"i" (ASI_M_CTL));
}
-extern __inline__ unsigned bw_get_prof_limit(int cpu)
+static inline unsigned bw_get_prof_limit(int cpu)
{
unsigned limit;
@@ -128,7 +128,7 @@ extern __inline__ unsigned bw_get_prof_limit(int cpu)
return limit;
}
-extern __inline__ void bw_set_prof_limit(int cpu, unsigned limit)
+static inline void bw_set_prof_limit(int cpu, unsigned limit)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (limit),
@@ -136,7 +136,7 @@ extern __inline__ void bw_set_prof_limit(int cpu, unsigned limit)
"i" (ASI_M_CTL));
}
-extern __inline__ unsigned bw_get_ctrl(int cpu)
+static inline unsigned bw_get_ctrl(int cpu)
{
unsigned ctrl;
@@ -147,7 +147,7 @@ extern __inline__ unsigned bw_get_ctrl(int cpu)
return ctrl;
}
-extern __inline__ void bw_set_ctrl(int cpu, unsigned ctrl)
+static inline void bw_set_ctrl(int cpu, unsigned ctrl)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (ctrl),
@@ -157,7 +157,7 @@ extern __inline__ void bw_set_ctrl(int cpu, unsigned ctrl)
extern unsigned char cpu_leds[32];
-extern __inline__ void show_leds(int cpuid)
+static inline void show_leds(int cpuid)
{
cpuid &= 0x1e;
__asm__ __volatile__ ("stba %0, [%1] %2" : :
@@ -166,7 +166,7 @@ extern __inline__ void show_leds(int cpuid)
"i" (ASI_M_CTL));
}
-extern __inline__ unsigned cc_get_ipen(void)
+static inline unsigned cc_get_ipen(void)
{
unsigned pending;
@@ -177,7 +177,7 @@ extern __inline__ unsigned cc_get_ipen(void)
return pending;
}
-extern __inline__ void cc_set_iclr(unsigned clear)
+static inline void cc_set_iclr(unsigned clear)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (clear),
@@ -185,7 +185,7 @@ extern __inline__ void cc_set_iclr(unsigned clear)
"i" (ASI_M_MXCC));
}
-extern __inline__ unsigned cc_get_imsk(void)
+static inline unsigned cc_get_imsk(void)
{
unsigned mask;
@@ -196,7 +196,7 @@ extern __inline__ unsigned cc_get_imsk(void)
return mask;
}
-extern __inline__ void cc_set_imsk(unsigned mask)
+static inline void cc_set_imsk(unsigned mask)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (mask),
@@ -204,7 +204,7 @@ extern __inline__ void cc_set_imsk(unsigned mask)
"i" (ASI_M_MXCC));
}
-extern __inline__ unsigned cc_get_imsk_other(int cpuid)
+static inline unsigned cc_get_imsk_other(int cpuid)
{
unsigned mask;
@@ -215,7 +215,7 @@ extern __inline__ unsigned cc_get_imsk_other(int cpuid)
return mask;
}
-extern __inline__ void cc_set_imsk_other(int cpuid, unsigned mask)
+static inline void cc_set_imsk_other(int cpuid, unsigned mask)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (mask),
@@ -223,7 +223,7 @@ extern __inline__ void cc_set_imsk_other(int cpuid, unsigned mask)
"i" (ASI_M_CTL));
}
-extern __inline__ void cc_set_igen(unsigned gen)
+static inline void cc_set_igen(unsigned gen)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (gen),
@@ -239,7 +239,7 @@ extern __inline__ void cc_set_igen(unsigned gen)
#define IGEN_MESSAGE(bcast, devid, sid, levels) \
(((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
-extern __inline__ void sun4d_send_ipi(int cpu, int level)
+static inline void sun4d_send_ipi(int cpu, int level)
{
cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
}
diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h
index 97052baf90c1..38644742f011 100644
--- a/include/asm-sparc/pci.h
+++ b/include/asm-sparc/pci.h
@@ -15,12 +15,12 @@
#define PCI_IRQ_NONE 0xffffffff
-extern inline void pcibios_set_master(struct pci_dev *dev)
+static inline void pcibios_set_master(struct pci_dev *dev)
{
/* No special bus mastering setup handling */
}
-extern inline void pcibios_penalize_isa_irq(int irq, int active)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
}
@@ -137,7 +137,7 @@ extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist
* only drive the low 24-bits during PCI bus mastering, then
* you would pass 0x00ffffff as the mask to this function.
*/
-extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
{
return 1;
}
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
index 8f4f6a959651..a14e98677500 100644
--- a/include/asm-sparc/pgtable.h
+++ b/include/asm-sparc/pgtable.h
@@ -82,6 +82,8 @@ extern unsigned long page_kernel;
/* Top-level page directory */
extern pgd_t swapper_pg_dir[1024];
+extern void paging_init(void);
+
/* Page table for 0-4MB for everybody, on the Sparc this
* holds the same as on the i386.
*/
@@ -152,7 +154,7 @@ BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
BTFIXUPDEF_CALL(int, pte_read, pte_t)
-extern __inline__ int pte_none(pte_t pte)
+static inline int pte_none(pte_t pte)
{
return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
}
@@ -165,7 +167,7 @@ BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
-extern __inline__ int pmd_none(pmd_t pmd)
+static inline int pmd_none(pmd_t pmd)
{
return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
}
@@ -192,20 +194,20 @@ BTFIXUPDEF_HALF(pte_writei)
BTFIXUPDEF_HALF(pte_dirtyi)
BTFIXUPDEF_HALF(pte_youngi)
-extern int pte_write(pte_t pte) __attribute_const__;
-extern __inline__ int pte_write(pte_t pte)
+static int pte_write(pte_t pte) __attribute_const__;
+static inline int pte_write(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_writei);
}
-extern int pte_dirty(pte_t pte) __attribute_const__;
-extern __inline__ int pte_dirty(pte_t pte)
+static int pte_dirty(pte_t pte) __attribute_const__;
+static inline int pte_dirty(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
}
-extern int pte_young(pte_t pte) __attribute_const__;
-extern __inline__ int pte_young(pte_t pte)
+static int pte_young(pte_t pte) __attribute_const__;
+static inline int pte_young(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
}
@@ -215,8 +217,8 @@ extern __inline__ int pte_young(pte_t pte)
*/
BTFIXUPDEF_HALF(pte_filei)
-extern int pte_file(pte_t pte) __attribute_const__;
-extern __inline__ int pte_file(pte_t pte)
+static int pte_file(pte_t pte) __attribute_const__;
+static inline int pte_file(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_filei);
}
@@ -227,20 +229,20 @@ BTFIXUPDEF_HALF(pte_wrprotecti)
BTFIXUPDEF_HALF(pte_mkcleani)
BTFIXUPDEF_HALF(pte_mkoldi)
-extern pte_t pte_wrprotect(pte_t pte) __attribute_const__;
-extern __inline__ pte_t pte_wrprotect(pte_t pte)
+static pte_t pte_wrprotect(pte_t pte) __attribute_const__;
+static inline pte_t pte_wrprotect(pte_t pte)
{
return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
}
-extern pte_t pte_mkclean(pte_t pte) __attribute_const__;
-extern __inline__ pte_t pte_mkclean(pte_t pte)
+static pte_t pte_mkclean(pte_t pte) __attribute_const__;
+static inline pte_t pte_mkclean(pte_t pte)
{
return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
}
-extern pte_t pte_mkold(pte_t pte) __attribute_const__;
-extern __inline__ pte_t pte_mkold(pte_t pte)
+static pte_t pte_mkold(pte_t pte) __attribute_const__;
+static inline pte_t pte_mkold(pte_t pte)
{
return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
}
@@ -276,8 +278,8 @@ BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
BTFIXUPDEF_INT(pte_modify_mask)
-extern pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
-extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
pgprot_val(newprot));
@@ -384,13 +386,13 @@ extern struct ctx_list ctx_used; /* Head of used contexts list */
#define NO_CONTEXT -1
-extern __inline__ void remove_from_ctx_list(struct ctx_list *entry)
+static inline void remove_from_ctx_list(struct ctx_list *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
}
-extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
+static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
{
entry->next = head;
(entry->prev = head->prev)->next = entry;
@@ -399,7 +401,7 @@ extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *e
#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
-extern __inline__ unsigned long
+static inline unsigned long
__get_phys (unsigned long addr)
{
switch (sparc_cpu_model){
@@ -414,7 +416,7 @@ __get_phys (unsigned long addr)
}
}
-extern __inline__ int
+static inline int
__get_iospace (unsigned long addr)
{
switch (sparc_cpu_model){
diff --git a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
index ee3b9d93187c..edeb9811e728 100644
--- a/include/asm-sparc/pgtsrmmu.h
+++ b/include/asm-sparc/pgtsrmmu.h
@@ -148,7 +148,7 @@ extern void *srmmu_nocache_pool;
#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
/* Accessing the MMU control register. */
-extern __inline__ unsigned int srmmu_get_mmureg(void)
+static inline unsigned int srmmu_get_mmureg(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
@@ -157,14 +157,14 @@ extern __inline__ unsigned int srmmu_get_mmureg(void)
return retval;
}
-extern __inline__ void srmmu_set_mmureg(unsigned long regval)
+static inline void srmmu_set_mmureg(unsigned long regval)
{
__asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
"r" (regval), "i" (ASI_M_MMUREGS) : "memory");
}
-extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr)
+static inline void srmmu_set_ctable_ptr(unsigned long paddr)
{
paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
@@ -173,7 +173,7 @@ extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr)
"memory");
}
-extern __inline__ unsigned long srmmu_get_ctable_ptr(void)
+static inline unsigned long srmmu_get_ctable_ptr(void)
{
unsigned int retval;
@@ -184,14 +184,14 @@ extern __inline__ unsigned long srmmu_get_ctable_ptr(void)
return (retval & SRMMU_CTX_PMASK) << 4;
}
-extern __inline__ void srmmu_set_context(int context)
+static inline void srmmu_set_context(int context)
{
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
"r" (context), "r" (SRMMU_CTX_REG),
"i" (ASI_M_MMUREGS) : "memory");
}
-extern __inline__ int srmmu_get_context(void)
+static inline int srmmu_get_context(void)
{
register int retval;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
@@ -201,7 +201,7 @@ extern __inline__ int srmmu_get_context(void)
return retval;
}
-extern __inline__ unsigned int srmmu_get_fstatus(void)
+static inline unsigned int srmmu_get_fstatus(void)
{
unsigned int retval;
@@ -211,7 +211,7 @@ extern __inline__ unsigned int srmmu_get_fstatus(void)
return retval;
}
-extern __inline__ unsigned int srmmu_get_faddr(void)
+static inline unsigned int srmmu_get_faddr(void)
{
unsigned int retval;
@@ -222,7 +222,7 @@ extern __inline__ unsigned int srmmu_get_faddr(void)
}
/* This is guaranteed on all SRMMU's. */
-extern __inline__ void srmmu_flush_whole_tlb(void)
+static inline void srmmu_flush_whole_tlb(void)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
"r" (0x400), /* Flush entire TLB!! */
@@ -231,7 +231,7 @@ extern __inline__ void srmmu_flush_whole_tlb(void)
}
/* These flush types are not available on all chips... */
-extern __inline__ void srmmu_flush_tlb_ctx(void)
+static inline void srmmu_flush_tlb_ctx(void)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
"r" (0x300), /* Flush TLB ctx.. */
@@ -239,7 +239,7 @@ extern __inline__ void srmmu_flush_tlb_ctx(void)
}
-extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
+static inline void srmmu_flush_tlb_region(unsigned long addr)
{
addr &= SRMMU_PGDIR_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
@@ -249,7 +249,7 @@ extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
}
-extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
+static inline void srmmu_flush_tlb_segment(unsigned long addr)
{
addr &= SRMMU_REAL_PMD_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
@@ -258,7 +258,7 @@ extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
}
-extern __inline__ void srmmu_flush_tlb_page(unsigned long page)
+static inline void srmmu_flush_tlb_page(unsigned long page)
{
page &= PAGE_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
@@ -267,7 +267,7 @@ extern __inline__ void srmmu_flush_tlb_page(unsigned long page)
}
-extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr)
+static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
{
unsigned long retval;
@@ -279,7 +279,7 @@ extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr)
return retval;
}
-extern __inline__ int
+static inline int
srmmu_get_pte (unsigned long addr)
{
register unsigned long entry;
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index 5a7a1a8d29ac..6fbb3f0af8d8 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -79,7 +79,7 @@ struct thread_struct {
extern unsigned long thread_saved_pc(struct task_struct *t);
/* Do necessary setup to start up a newly executed thread. */
-extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
+static inline void start_thread(struct pt_regs * regs, unsigned long pc,
unsigned long sp)
{
register unsigned long zero asm("g1");
diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h
index 9778b8c8b15b..19c978051118 100644
--- a/include/asm-sparc/psr.h
+++ b/include/asm-sparc/psr.h
@@ -38,7 +38,7 @@
#ifndef __ASSEMBLY__
/* Get the %psr register. */
-extern __inline__ unsigned int get_psr(void)
+static inline unsigned int get_psr(void)
{
unsigned int psr;
__asm__ __volatile__(
@@ -53,7 +53,7 @@ extern __inline__ unsigned int get_psr(void)
return psr;
}
-extern __inline__ void put_psr(unsigned int new_psr)
+static inline void put_psr(unsigned int new_psr)
{
__asm__ __volatile__(
"wr %0, 0x0, %%psr\n\t"
@@ -72,7 +72,7 @@ extern __inline__ void put_psr(unsigned int new_psr)
extern unsigned int fsr_storage;
-extern __inline__ unsigned int get_fsr(void)
+static inline unsigned int get_fsr(void)
{
unsigned int fsr = 0;
diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
index dd9d94d7e0ae..a8ecb2d6977a 100644
--- a/include/asm-sparc/ptrace.h
+++ b/include/asm-sparc/ptrace.h
@@ -73,11 +73,11 @@ extern void show_regs(struct pt_regs *);
#endif
/*
- * The asm_offsets.h is a generated file, so we cannot include it.
+ * The asm-offsets.h is a generated file, so we cannot include it.
* It may be OK for glibc headers, but it's utterly pointless for C code.
* The assembly code using those offsets has to include it explicitly.
*/
-/* #include <asm/asm_offsets.h> */
+/* #include <asm/asm-offsets.h> */
/* These are for pt_regs. */
#define PT_PSR 0x0
diff --git a/include/asm-sparc/sbi.h b/include/asm-sparc/sbi.h
index 739ccac5dcf2..86a603ac7b20 100644
--- a/include/asm-sparc/sbi.h
+++ b/include/asm-sparc/sbi.h
@@ -65,7 +65,7 @@ struct sbi_regs {
#ifndef __ASSEMBLY__
-extern __inline__ int acquire_sbi(int devid, int mask)
+static inline int acquire_sbi(int devid, int mask)
{
__asm__ __volatile__ ("swapa [%2] %3, %0" :
"=r" (mask) :
@@ -75,7 +75,7 @@ extern __inline__ int acquire_sbi(int devid, int mask)
return mask;
}
-extern __inline__ void release_sbi(int devid, int mask)
+static inline void release_sbi(int devid, int mask)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (mask),
@@ -83,7 +83,7 @@ extern __inline__ void release_sbi(int devid, int mask)
"i" (ASI_M_CTL));
}
-extern __inline__ void set_sbi_tid(int devid, int targetid)
+static inline void set_sbi_tid(int devid, int targetid)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (targetid),
@@ -91,7 +91,7 @@ extern __inline__ void set_sbi_tid(int devid, int targetid)
"i" (ASI_M_CTL));
}
-extern __inline__ int get_sbi_ctl(int devid, int cfgno)
+static inline int get_sbi_ctl(int devid, int cfgno)
{
int cfg;
@@ -102,7 +102,7 @@ extern __inline__ int get_sbi_ctl(int devid, int cfgno)
return cfg;
}
-extern __inline__ void set_sbi_ctl(int devid, int cfgno, int cfg)
+static inline void set_sbi_ctl(int devid, int cfgno, int cfg)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (cfg),
diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h
index 3a8b3908728a..a13cddcecec5 100644
--- a/include/asm-sparc/sbus.h
+++ b/include/asm-sparc/sbus.h
@@ -28,12 +28,12 @@
* numbers + offsets, and vice versa.
*/
-extern __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
{
return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
}
-extern __inline__ int sbus_dev_slot(unsigned long dev_addr)
+static inline int sbus_dev_slot(unsigned long dev_addr)
{
return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
}
@@ -80,7 +80,7 @@ struct sbus_bus {
extern struct sbus_bus *sbus_root;
-extern __inline__ int
+static inline int
sbus_is_slave(struct sbus_dev *dev)
{
/* XXX Have to write this for sun4c's */
diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
index 4f96d8333a12..580c51d011df 100644
--- a/include/asm-sparc/smp.h
+++ b/include/asm-sparc/smp.h
@@ -60,22 +60,22 @@ BTFIXUPDEF_BLACKBOX(load_current)
#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5)
#define smp_message_pass(target,msg,data,wait) BTFIXUP_CALL(smp_message_pass)(target,msg,data,wait)
-extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
-extern __inline__ void xc1(smpfunc_t func, unsigned long arg1)
+static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
+static inline void xc1(smpfunc_t func, unsigned long arg1)
{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
-extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
+static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
-extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3)
{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
-extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4)
{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
-extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5)
{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
-extern __inline__ int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait)
+static inline int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait)
{
xc1((smpfunc_t)func, (unsigned long)info);
return 0;
@@ -84,16 +84,16 @@ extern __inline__ int smp_call_function(void (*func)(void *info), void *info, in
extern __volatile__ int __cpu_number_map[NR_CPUS];
extern __volatile__ int __cpu_logical_map[NR_CPUS];
-extern __inline__ int cpu_logical_map(int cpu)
+static inline int cpu_logical_map(int cpu)
{
return __cpu_logical_map[cpu];
}
-extern __inline__ int cpu_number_map(int cpu)
+static inline int cpu_number_map(int cpu)
{
return __cpu_number_map[cpu];
}
-extern __inline__ int hard_smp4m_processor_id(void)
+static inline int hard_smp4m_processor_id(void)
{
int cpuid;
@@ -104,7 +104,7 @@ extern __inline__ int hard_smp4m_processor_id(void)
return cpuid;
}
-extern __inline__ int hard_smp4d_processor_id(void)
+static inline int hard_smp4d_processor_id(void)
{
int cpuid;
@@ -114,7 +114,7 @@ extern __inline__ int hard_smp4d_processor_id(void)
}
#ifndef MODULE
-extern __inline__ int hard_smp_processor_id(void)
+static inline int hard_smp_processor_id(void)
{
int cpuid;
@@ -136,7 +136,7 @@ extern __inline__ int hard_smp_processor_id(void)
return cpuid;
}
#else
-extern __inline__ int hard_smp_processor_id(void)
+static inline int hard_smp_processor_id(void)
{
int cpuid;
diff --git a/include/asm-sparc/smpprim.h b/include/asm-sparc/smpprim.h
index 9b9c28ed748e..e7b6d346ae10 100644
--- a/include/asm-sparc/smpprim.h
+++ b/include/asm-sparc/smpprim.h
@@ -15,7 +15,7 @@
* atomic.
*/
-extern __inline__ __volatile__ char test_and_set(void *addr)
+static inline __volatile__ char test_and_set(void *addr)
{
char state = 0;
@@ -27,7 +27,7 @@ extern __inline__ __volatile__ char test_and_set(void *addr)
}
/* Initialize a spin-lock. */
-extern __inline__ __volatile__ smp_initlock(void *spinlock)
+static inline __volatile__ smp_initlock(void *spinlock)
{
/* Unset the lock. */
*((unsigned char *) spinlock) = 0;
@@ -36,7 +36,7 @@ extern __inline__ __volatile__ smp_initlock(void *spinlock)
}
/* This routine spins until it acquires the lock at ADDR. */
-extern __inline__ __volatile__ smp_lock(void *addr)
+static inline __volatile__ smp_lock(void *addr)
{
while(test_and_set(addr) == 0xff)
;
@@ -46,7 +46,7 @@ extern __inline__ __volatile__ smp_lock(void *addr)
}
/* This routine releases the lock at ADDR. */
-extern __inline__ __volatile__ smp_unlock(void *addr)
+static inline __volatile__ smp_unlock(void *addr)
{
*((unsigned char *) addr) = 0;
}
diff --git a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h
index 0cbd87ad4912..e344c98a6f5f 100644
--- a/include/asm-sparc/spinlock.h
+++ b/include/asm-sparc/spinlock.h
@@ -12,96 +12,12 @@
#include <asm/psr.h>
-#ifdef CONFIG_DEBUG_SPINLOCK
-struct _spinlock_debug {
- unsigned char lock;
- unsigned long owner_pc;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-};
-typedef struct _spinlock_debug spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0 }
-#define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(lp) (*((volatile unsigned char *)(&((lp)->lock))) != 0)
-#define spin_unlock_wait(lp) do { barrier(); } while(*(volatile unsigned char *)(&(lp)->lock))
-
-extern void _do_spin_lock(spinlock_t *lock, char *str);
-extern int _spin_trylock(spinlock_t *lock);
-extern void _do_spin_unlock(spinlock_t *lock);
-
-#define _raw_spin_trylock(lp) _spin_trylock(lp)
-#define _raw_spin_lock(lock) _do_spin_lock(lock, "spin_lock")
-#define _raw_spin_unlock(lock) _do_spin_unlock(lock)
-
-struct _rwlock_debug {
- volatile unsigned int lock;
- unsigned long owner_pc;
- unsigned long reader_pc[NR_CPUS];
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-};
-typedef struct _rwlock_debug rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} }
-
-#define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0)
-
-extern void _do_read_lock(rwlock_t *rw, char *str);
-extern void _do_read_unlock(rwlock_t *rw, char *str);
-extern void _do_write_lock(rwlock_t *rw, char *str);
-extern void _do_write_unlock(rwlock_t *rw);
-
-#define _raw_read_lock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_read_lock(lock, "read_lock"); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_read_unlock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_read_unlock(lock, "read_unlock"); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_lock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_write_lock(lock, "write_lock"); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_unlock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_write_unlock(lock); \
- local_irq_restore(flags); \
-} while(0)
-
-#else /* !CONFIG_DEBUG_SPINLOCK */
-
-typedef struct {
- unsigned char lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-
-#define spin_lock_init(lock) (*((unsigned char *)(lock)) = 0)
-#define spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
+#define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
-#define spin_unlock_wait(lock) \
-do { \
- barrier(); \
-} while(*((volatile unsigned char *)lock))
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
-extern __inline__ void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
__asm__ __volatile__(
"\n1:\n\t"
@@ -121,7 +37,7 @@ extern __inline__ void _raw_spin_lock(spinlock_t *lock)
: "g2", "memory", "cc");
}
-extern __inline__ int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
unsigned int result;
__asm__ __volatile__("ldstub [%1], %0"
@@ -131,7 +47,7 @@ extern __inline__ int _raw_spin_trylock(spinlock_t *lock)
return (result == 0);
}
-extern __inline__ void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
}
@@ -147,23 +63,11 @@ extern __inline__ void _raw_spin_unlock(spinlock_t *lock)
*
* XXX This might create some problems with my dual spinlock
* XXX scheme, deadlocks etc. -DaveM
- */
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-
-#define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0)
-
-
-/* Sort of like atomic_t's on Sparc, but even more clever.
+ *
+ * Sort of like atomic_t's on Sparc, but even more clever.
*
* ------------------------------------
- * | 24-bit counter | wlock | rwlock_t
+ * | 24-bit counter | wlock | raw_rwlock_t
* ------------------------------------
* 31 8 7 0
*
@@ -174,9 +78,9 @@ typedef struct {
*
* Unfortunately this scheme limits us to ~16,000,000 cpus.
*/
-extern __inline__ void _read_lock(rwlock_t *rw)
+static inline void __read_lock(raw_rwlock_t *rw)
{
- register rwlock_t *lp asm("g1");
+ register raw_rwlock_t *lp asm("g1");
lp = rw;
__asm__ __volatile__(
"mov %%o7, %%g4\n\t"
@@ -187,16 +91,16 @@ extern __inline__ void _read_lock(rwlock_t *rw)
: "g2", "g4", "memory", "cc");
}
-#define _raw_read_lock(lock) \
+#define __raw_read_lock(lock) \
do { unsigned long flags; \
local_irq_save(flags); \
- _read_lock(lock); \
+ __raw_read_lock(lock); \
local_irq_restore(flags); \
} while(0)
-extern __inline__ void _read_unlock(rwlock_t *rw)
+static inline void __read_unlock(raw_rwlock_t *rw)
{
- register rwlock_t *lp asm("g1");
+ register raw_rwlock_t *lp asm("g1");
lp = rw;
__asm__ __volatile__(
"mov %%o7, %%g4\n\t"
@@ -207,16 +111,16 @@ extern __inline__ void _read_unlock(rwlock_t *rw)
: "g2", "g4", "memory", "cc");
}
-#define _raw_read_unlock(lock) \
+#define __raw_read_unlock(lock) \
do { unsigned long flags; \
local_irq_save(flags); \
- _read_unlock(lock); \
+ __raw_read_unlock(lock); \
local_irq_restore(flags); \
} while(0)
-extern __inline__ void _raw_write_lock(rwlock_t *rw)
+extern __inline__ void __raw_write_lock(raw_rwlock_t *rw)
{
- register rwlock_t *lp asm("g1");
+ register raw_rwlock_t *lp asm("g1");
lp = rw;
__asm__ __volatile__(
"mov %%o7, %%g4\n\t"
@@ -227,11 +131,9 @@ extern __inline__ void _raw_write_lock(rwlock_t *rw)
: "g2", "g4", "memory", "cc");
}
-#define _raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
-
-#endif /* CONFIG_DEBUG_SPINLOCK */
+#define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
#endif /* !(__ASSEMBLY__) */
diff --git a/include/asm-sparc/spinlock_types.h b/include/asm-sparc/spinlock_types.h
new file mode 100644
index 000000000000..0a0fb116c4ec
--- /dev/null
+++ b/include/asm-sparc/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __SPARC_SPINLOCK_TYPES_H
+#define __SPARC_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ unsigned char lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 3557781a4bfd..1f6b71f9e1b6 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -204,7 +204,7 @@ static inline unsigned long getipl(void)
BTFIXUPDEF_CALL(void, ___xchg32, void)
#endif
-extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
+static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
{
#ifdef CONFIG_SMP
__asm__ __volatile__("swap [%2], %0"
diff --git a/include/asm-sparc/traps.h b/include/asm-sparc/traps.h
index 6690ab956ea6..f62c7f878ee1 100644
--- a/include/asm-sparc/traps.h
+++ b/include/asm-sparc/traps.h
@@ -22,7 +22,7 @@ struct tt_entry {
/* We set this to _start in system setup. */
extern struct tt_entry *sparc_ttable;
-extern __inline__ unsigned long get_tbr(void)
+static inline unsigned long get_tbr(void)
{
unsigned long tbr;
diff --git a/include/asm-sparc64/cacheflush.h b/include/asm-sparc64/cacheflush.h
index 51b26e81d828..b3f61659ba81 100644
--- a/include/asm-sparc64/cacheflush.h
+++ b/include/asm-sparc64/cacheflush.h
@@ -4,13 +4,6 @@
#include <linux/config.h>
#include <asm/page.h>
-/* Flushing for D-cache alias handling is only needed if
- * the page size is smaller than 16K.
- */
-#if PAGE_SHIFT < 14
-#define DCACHE_ALIASING_POSSIBLE
-#endif
-
#ifndef __ASSEMBLY__
#include <linux/mm.h>
@@ -73,6 +66,11 @@ extern void flush_ptrace_access(struct vm_area_struct *, struct page *,
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
+#ifdef CONFIG_DEBUG_PAGEALLOC
+/* internal debugging function */
+void kernel_map_pages(struct page *page, int numpages, int enable);
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* _SPARC64_CACHEFLUSH_H */
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h
index 9a3a81f1cc58..74de79dca915 100644
--- a/include/asm-sparc64/cpudata.h
+++ b/include/asm-sparc64/cpudata.h
@@ -22,6 +22,16 @@ typedef struct {
unsigned int __pad1;
unsigned long *pte_cache[2];
unsigned long *pgd_cache;
+
+ /* Dcache line 3, rarely used */
+ unsigned int dcache_size;
+ unsigned int dcache_line_size;
+ unsigned int icache_size;
+ unsigned int icache_line_size;
+ unsigned int ecache_size;
+ unsigned int ecache_line_size;
+ unsigned int __pad2;
+ unsigned int __pad3;
} cpuinfo_sparc;
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index 1c5da41653a4..c7d5804ba76d 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -10,7 +10,7 @@
struct device;
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-sparc64/futex.h
+++ b/include/asm-sparc64/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h
index b63a33cf4971..0abd3a674e8f 100644
--- a/include/asm-sparc64/head.h
+++ b/include/asm-sparc64/head.h
@@ -12,9 +12,12 @@
#define __JALAPENO_ID 0x003e0016
#define CHEETAH_MANUF 0x003e
-#define CHEETAH_IMPL 0x0014
-#define CHEETAH_PLUS_IMPL 0x0015
-#define JALAPENO_IMPL 0x0016
+#define CHEETAH_IMPL 0x0014 /* Ultra-III */
+#define CHEETAH_PLUS_IMPL 0x0015 /* Ultra-III+ */
+#define JALAPENO_IMPL 0x0016 /* Ultra-IIIi */
+#define JAGUAR_IMPL 0x0018 /* Ultra-IV */
+#define PANTHER_IMPL 0x0019 /* Ultra-IV+ */
+#define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */
#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \
rdpr %ver, %tmp1; \
diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
index 4c1098474c73..c393f815b0be 100644
--- a/include/asm-sparc64/ide.h
+++ b/include/asm-sparc64/ide.h
@@ -15,6 +15,7 @@
#include <asm/io.h>
#include <asm/spitfire.h>
#include <asm/cacheflush.h>
+#include <asm/page.h>
#ifndef MAX_HWIFS
# ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h
index 0a336901d585..b4959d2b0d99 100644
--- a/include/asm-sparc64/openprom.h
+++ b/include/asm-sparc64/openprom.h
@@ -186,8 +186,8 @@ struct linux_prom_registers {
};
struct linux_prom64_registers {
- long phys_addr;
- long reg_size;
+ unsigned long phys_addr;
+ unsigned long reg_size;
};
struct linux_prom_irqs {
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index a432d9e7daaa..d02f1e8ae1a6 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -38,6 +38,20 @@ extern int prom_stdin, prom_stdout;
*/
extern int prom_chosen_node;
+/* Helper values and strings in arch/sparc64/kernel/head.S */
+extern const char prom_finddev_name[];
+extern const char prom_chosen_path[];
+extern const char prom_getprop_name[];
+extern const char prom_mmu_name[];
+extern const char prom_callmethod_name[];
+extern const char prom_translate_name[];
+extern const char prom_map_name[];
+extern const char prom_unmap_name[];
+extern int prom_mmu_ihandle_cache;
+extern unsigned int prom_boot_mapped_pc;
+extern unsigned int prom_boot_mapping_mode;
+extern unsigned long prom_boot_mapping_phys_high, prom_boot_mapping_phys_low;
+
struct linux_mlist_p1275 {
struct linux_mlist_p1275 *theres_more;
unsigned long start_adr;
@@ -68,7 +82,7 @@ extern char *prom_getbootargs(void);
* of the string is different on V0 vs. V2->higher proms. The caller must
* know what he/she is doing! Returns the device descriptor, an int.
*/
-extern int prom_devopen(char *device_string);
+extern int prom_devopen(const char *device_string);
/* Close a previously opened device described by the passed integer
* descriptor.
@@ -81,27 +95,13 @@ extern int prom_devclose(int device_handle);
extern void prom_seek(int device_handle, unsigned int seek_hival,
unsigned int seek_lowval);
-/* Machine memory configuration routine. */
-
-/* This function returns a V0 format memory descriptor table, it has three
- * entries. One for the total amount of physical ram on the machine, one
- * for the amount of physical ram available, and one describing the virtual
- * areas which are allocated by the prom. So, in a sense the physical
- * available is a calculation of the total physical minus the physical mapped
- * by the prom with virtual mappings.
- *
- * These lists are returned pre-sorted, this should make your life easier
- * since the prom itself is way too lazy to do such nice things.
- */
-extern struct linux_mem_p1275 *prom_meminfo(void);
-
/* Miscellaneous routines, don't really fit in any category per se. */
/* Reboot the machine with the command line passed. */
-extern void prom_reboot(char *boot_command);
+extern void prom_reboot(const char *boot_command);
/* Evaluate the forth string passed. */
-extern void prom_feval(char *forth_string);
+extern void prom_feval(const char *forth_string);
/* Enter the prom, with possibility of continuation with the 'go'
* command in newer proms.
@@ -154,7 +154,7 @@ extern char prom_getchar(void);
extern void prom_putchar(char character);
/* Prom's internal routines, don't use in kernel/boot code. */
-extern void prom_printf(char *fmt, ...);
+extern void prom_printf(const char *fmt, ...);
extern void prom_write(const char *buf, unsigned int len);
/* Query for input device type */
@@ -215,7 +215,7 @@ extern int prom_getunumber(int syndrome_code,
char *buf, int buflen);
/* Retain physical memory to the caller across soft resets. */
-extern unsigned long prom_retain(char *name,
+extern unsigned long prom_retain(const char *name,
unsigned long pa_low, unsigned long pa_high,
long size, long align);
@@ -269,28 +269,28 @@ extern int prom_getsibling(int node);
/* Get the length, at the passed node, of the given property type.
* Returns -1 on error (ie. no such property at this node).
*/
-extern int prom_getproplen(int thisnode, char *property);
+extern int prom_getproplen(int thisnode, const char *property);
/* Fetch the requested property using the given buffer. Returns
* the number of bytes the prom put into your buffer or -1 on error.
*/
-extern int prom_getproperty(int thisnode, char *property,
+extern int prom_getproperty(int thisnode, const char *property,
char *prop_buffer, int propbuf_size);
/* Acquire an integer property. */
-extern int prom_getint(int node, char *property);
+extern int prom_getint(int node, const char *property);
/* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(int node, char *property, int defval);
+extern int prom_getintdefault(int node, const char *property, int defval);
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(int node, char *prop);
+extern int prom_getbool(int node, const char *prop);
/* Acquire a string property, null string on error. */
-extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
/* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(int thisnode, char *name);
+extern int prom_nodematch(int thisnode, const char *name);
/* Puts in buffer a prom name in the form name@x,y or name (x for which_io
* and y for first regs phys address
@@ -300,7 +300,7 @@ extern int prom_getname(int node, char *buf, int buflen);
/* Search all siblings starting at the passed node for "name" matching
* the given string. Returns the node on success, zero on failure.
*/
-extern int prom_searchsiblings(int node_start, char *name);
+extern int prom_searchsiblings(int node_start, const char *name);
/* Return the first property type, as a string, for the given node.
* Returns a null string on error. Buffer should be at least 32B long.
@@ -310,21 +310,21 @@ extern char *prom_firstprop(int node, char *buffer);
/* Returns the next property after the passed property for the given
* node. Returns null string on failure. Buffer should be at least 32B long.
*/
-extern char *prom_nextprop(int node, char *prev_property, char *buffer);
+extern char *prom_nextprop(int node, const char *prev_property, char *buffer);
/* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(int node, char *property);
+extern int prom_node_has_property(int node, const char *property);
/* Returns phandle of the path specified */
-extern int prom_finddevice(char *name);
+extern int prom_finddevice(const char *name);
/* Set the indicated property at the given node with the passed value.
* Returns the number of bytes of your value that the prom took.
*/
-extern int prom_setprop(int node, char *prop_name, char *prop_value,
+extern int prom_setprop(int node, const char *prop_name, char *prop_value,
int value_size);
-extern int prom_pathtoinode(char *path);
+extern int prom_pathtoinode(const char *path);
extern int prom_inst2pkg(int);
/* CPU probing helpers. */
@@ -334,7 +334,7 @@ int cpu_find_by_mid(int mid, int *prom_node);
/* Client interface level routines. */
extern void prom_set_trap_table(unsigned long tba);
-extern long p1275_cmd (char *, long, ...);
+extern long p1275_cmd(const char *, long, ...);
#if 0
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
index c9f8ef208ea5..5426bb28a993 100644
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -21,6 +21,13 @@
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
+/* Flushing for D-cache alias handling is only needed if
+ * the page size is smaller than 16K.
+ */
+#if PAGE_SHIFT < 14
+#define DCACHE_ALIASING_POSSIBLE
+#endif
+
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -133,23 +140,6 @@ extern unsigned long page_to_pfn(struct page *);
#define virt_to_phys __pa
#define phys_to_virt __va
-/* The following structure is used to hold the physical
- * memory configuration of the machine. This is filled in
- * probe_memory() and is later used by mem_init() to set up
- * mem_map[]. We statically allocate SPARC_PHYS_BANKS of
- * these structs, this is arbitrary. The entry after the
- * last valid one has num_bytes==0.
- */
-
-struct sparc_phys_banks {
- unsigned long base_addr;
- unsigned long num_bytes;
-};
-
-#define SPARC_PHYS_BANKS 32
-
-extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
-
#endif /* !(__ASSEMBLY__) */
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 38bbbccb4068..dd35a2c7798a 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -27,23 +27,27 @@
* PCI bus.
*/
-#define PBM_LOGCLUSTERS 3
-#define PBM_NCLUSTERS (1 << PBM_LOGCLUSTERS)
-
struct pci_controller_info;
/* This contains the software state necessary to drive a PCI
* controller's IOMMU.
*/
+struct pci_iommu_arena {
+ unsigned long *map;
+ unsigned int hint;
+ unsigned int limit;
+};
+
struct pci_iommu {
/* This protects the controller's IOMMU and all
* streaming buffers underneath.
*/
spinlock_t lock;
+ struct pci_iommu_arena arena;
+
/* IOMMU page table, a linear array of ioptes. */
iopte_t *page_table; /* The page table itself. */
- int page_table_sz_bits; /* log2 of ow many pages does it map? */
/* Base PCI memory space address where IOMMU mappings
* begin.
@@ -62,12 +66,6 @@ struct pci_iommu {
*/
unsigned long write_complete_reg;
- /* The lowest used consistent mapping entry. Since
- * we allocate consistent maps out of cluster 0 this
- * is relative to the beginning of closter 0.
- */
- u32 lowest_consistent_map;
-
/* In order to deal with some buggy third-party PCI bridges that
* do wrong prefetching, we never mark valid mappings as invalid.
* Instead we point them at this dummy page.
@@ -75,16 +73,6 @@ struct pci_iommu {
unsigned long dummy_page;
unsigned long dummy_page_pa;
- /* If PBM_NCLUSTERS is ever decreased to 4 or lower,
- * or if largest supported page_table_sz * 8K goes above
- * 2GB, you must increase the size of the type of
- * these counters. You have been duly warned. -DaveM
- */
- struct {
- u16 next;
- u16 flush;
- } alloc_info[PBM_NCLUSTERS];
-
/* CTX allocation. */
unsigned long ctx_lowest_free;
unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)];
@@ -102,7 +90,7 @@ struct pci_iommu {
u32 dma_addr_mask;
};
-extern void pci_iommu_table_init(struct pci_iommu *, int);
+extern void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask);
/* This describes a PCI bus module's streaming buffer. */
struct pci_strbuf {
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index a4ab0ec7143a..89bd71b1c0d8 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -269,6 +269,8 @@ extern void
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/pgalloc.h b/include/asm-sparc64/pgalloc.h
index b9b1914aae63..a96067cca963 100644
--- a/include/asm-sparc64/pgalloc.h
+++ b/include/asm-sparc64/pgalloc.h
@@ -10,6 +10,7 @@
#include <asm/spitfire.h>
#include <asm/cpudata.h>
#include <asm/cacheflush.h>
+#include <asm/page.h>
/* Page table allocation/freeing. */
#ifdef CONFIG_SMP
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index a2b4f5ed4625..8c6dfc6c7af6 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -24,21 +24,23 @@
#include <asm/processor.h>
#include <asm/const.h>
-/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 16MB).
- * The page copy blockops use 0x1000000 to 0x18000000 (16MB --> 24MB).
+/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).
+ * The page copy blockops can use 0x2000000 to 0x10000000.
* The PROM resides in an area spanning 0xf0000000 to 0x100000000.
- * The vmalloc area spans 0x140000000 to 0x200000000.
+ * The vmalloc area spans 0x100000000 to 0x200000000.
+ * Since modules need to be in the lowest 32-bits of the address space,
+ * we place them right before the OBP area from 0x10000000 to 0xf0000000.
* There is a single static kernel PMD which maps from 0x0 to address
* 0x400000000.
*/
-#define TLBTEMP_BASE _AC(0x0000000001000000,UL)
-#define MODULES_VADDR _AC(0x0000000002000000,UL)
-#define MODULES_LEN _AC(0x000000007e000000,UL)
-#define MODULES_END _AC(0x0000000080000000,UL)
-#define VMALLOC_START _AC(0x0000000140000000,UL)
-#define VMALLOC_END _AC(0x0000000200000000,UL)
+#define TLBTEMP_BASE _AC(0x0000000002000000,UL)
+#define MODULES_VADDR _AC(0x0000000010000000,UL)
+#define MODULES_LEN _AC(0x00000000e0000000,UL)
+#define MODULES_END _AC(0x00000000f0000000,UL)
#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL)
#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
+#define VMALLOC_START _AC(0x0000000100000000,UL)
+#define VMALLOC_END _AC(0x0000000200000000,UL)
/* XXX All of this needs to be rethought so we can take advantage
* XXX cheetah's full 64-bit virtual address space, ie. no more hole
@@ -58,13 +60,13 @@
* table can map
*/
#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3))
-#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_SIZE (_AC(1,UL) << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PMD_BITS (PAGE_SHIFT - 2)
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PGDIR_BITS (PAGE_SHIFT - 2)
@@ -96,7 +98,9 @@
#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */
#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */
#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */
-#define _PAGE_RES1 _AC(0x0003000000000000,UL) /* Reserved */
+#define _PAGE_RES1 _AC(0x0002000000000000,UL) /* Reserved */
+#define _PAGE_SZ32MB _AC(0x0001000000000000,UL) /* (Panther) 32MB page */
+#define _PAGE_SZ256MB _AC(0x2001000000000000,UL) /* (Panther) 256MB page */
#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */
#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */
#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/
@@ -334,7 +338,11 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p
#define pte_clear(mm,addr,ptep) \
set_pte_at((mm), (addr), (ptep), __pte(0UL))
-extern pgd_t swapper_pg_dir[1];
+extern pgd_t swapper_pg_dir[2048];
+extern pmd_t swapper_low_pmd_dir[2048];
+
+extern void paging_init(void);
+extern unsigned long find_ecache_flush_span(unsigned long size);
/* These do nothing with the way I have things setup. */
#define mmu_lockarea(vaddr, len) (vaddr)
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index a02c4370eb42..ec85d12d73b9 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -29,24 +29,13 @@
* must be pre-V9 branches.
*/
-#ifndef CONFIG_DEBUG_SPINLOCK
+#define __raw_spin_is_locked(lp) ((lp)->lock != 0)
-typedef struct {
- volatile unsigned char lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) {0,}
+#define __raw_spin_unlock_wait(lp) \
+ do { rmb(); \
+ } while((lp)->lock)
-#define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(lp) ((lp)->lock != 0)
-
-#define spin_unlock_wait(lp) \
-do { rmb(); \
-} while((lp)->lock)
-
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned long tmp;
@@ -67,7 +56,7 @@ static inline void _raw_spin_lock(spinlock_t *lock)
: "memory");
}
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
unsigned long result;
@@ -81,7 +70,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
return (result == 0UL);
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__(
" membar #StoreStore | #LoadStore\n"
@@ -91,7 +80,7 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
: "memory");
}
-static inline void _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags)
+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
{
unsigned long tmp1, tmp2;
@@ -115,51 +104,9 @@ static inline void _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags)
: "memory");
}
-#else /* !(CONFIG_DEBUG_SPINLOCK) */
-
-typedef struct {
- volatile unsigned char lock;
- unsigned int owner_pc, owner_cpu;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0, 0xff }
-#define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(__lock) ((__lock)->lock != 0)
-#define spin_unlock_wait(__lock) \
-do { \
- rmb(); \
-} while((__lock)->lock)
-
-extern void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller);
-extern void _do_spin_unlock(spinlock_t *lock);
-extern int _do_spin_trylock(spinlock_t *lock, unsigned long caller);
-
-#define _raw_spin_trylock(lp) \
- _do_spin_trylock(lp, (unsigned long) __builtin_return_address(0))
-#define _raw_spin_lock(lock) \
- _do_spin_lock(lock, "spin_lock", \
- (unsigned long) __builtin_return_address(0))
-#define _raw_spin_unlock(lock) _do_spin_unlock(lock)
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
-
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
-#ifndef CONFIG_DEBUG_SPINLOCK
-
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) {0,}
-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
-
-static void inline __read_lock(rwlock_t *lock)
+static void inline __read_lock(raw_rwlock_t *lock)
{
unsigned long tmp1, tmp2;
@@ -184,7 +131,7 @@ static void inline __read_lock(rwlock_t *lock)
: "memory");
}
-static void inline __read_unlock(rwlock_t *lock)
+static void inline __read_unlock(raw_rwlock_t *lock)
{
unsigned long tmp1, tmp2;
@@ -201,7 +148,7 @@ static void inline __read_unlock(rwlock_t *lock)
: "memory");
}
-static void inline __write_lock(rwlock_t *lock)
+static void inline __write_lock(raw_rwlock_t *lock)
{
unsigned long mask, tmp1, tmp2;
@@ -228,7 +175,7 @@ static void inline __write_lock(rwlock_t *lock)
: "memory");
}
-static void inline __write_unlock(rwlock_t *lock)
+static void inline __write_unlock(raw_rwlock_t *lock)
{
__asm__ __volatile__(
" membar #LoadStore | #StoreStore\n"
@@ -238,7 +185,7 @@ static void inline __write_unlock(rwlock_t *lock)
: "memory");
}
-static int inline __write_trylock(rwlock_t *lock)
+static int inline __write_trylock(raw_rwlock_t *lock)
{
unsigned long mask, tmp1, tmp2, result;
@@ -263,78 +210,15 @@ static int inline __write_trylock(rwlock_t *lock)
return result;
}
-#define _raw_read_lock(p) __read_lock(p)
-#define _raw_read_unlock(p) __read_unlock(p)
-#define _raw_write_lock(p) __write_lock(p)
-#define _raw_write_unlock(p) __write_unlock(p)
-#define _raw_write_trylock(p) __write_trylock(p)
-
-#else /* !(CONFIG_DEBUG_SPINLOCK) */
-
-typedef struct {
- volatile unsigned long lock;
- unsigned int writer_pc, writer_cpu;
- unsigned int reader_pc[NR_CPUS];
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { } }
-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
-
-extern void _do_read_lock(rwlock_t *rw, char *str, unsigned long caller);
-extern void _do_read_unlock(rwlock_t *rw, char *str, unsigned long caller);
-extern void _do_write_lock(rwlock_t *rw, char *str, unsigned long caller);
-extern void _do_write_unlock(rwlock_t *rw, unsigned long caller);
-extern int _do_write_trylock(rwlock_t *rw, char *str, unsigned long caller);
-
-#define _raw_read_lock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_read_lock(lock, "read_lock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_read_unlock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_read_unlock(lock, "read_unlock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_lock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_write_lock(lock, "write_lock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_unlock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_write_unlock(lock, \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_trylock(lock) \
-({ unsigned long flags; \
- int val; \
- local_irq_save(flags); \
- val = _do_write_trylock(lock, "write_trylock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
- val; \
-})
-
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
-#define read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
-#define write_can_lock(rw) (!(rw)->lock)
+#define __raw_read_lock(p) __read_lock(p)
+#define __raw_read_unlock(p) __read_unlock(p)
+#define __raw_write_lock(p) __write_lock(p)
+#define __raw_write_unlock(p) __write_unlock(p)
+#define __raw_write_trylock(p) __write_trylock(p)
+
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
+#define __raw_write_can_lock(rw) (!(rw)->lock)
#endif /* !(__ASSEMBLY__) */
diff --git a/include/asm-sparc64/spinlock_types.h b/include/asm-sparc64/spinlock_types.h
new file mode 100644
index 000000000000..e128112a0d7c
--- /dev/null
+++ b/include/asm-sparc64/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __SPARC64_SPINLOCK_TYPES_H
+#define __SPARC64_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned char lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 5e94c05dc2fc..b5417529f6f1 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -28,13 +28,48 @@ enum sparc_cpu {
#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-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h
index 80a65d7e3dbf..203e8eee6351 100644
--- a/include/asm-sparc64/uaccess.h
+++ b/include/asm-sparc64/uaccess.h
@@ -70,26 +70,14 @@ static inline int access_ok(int type, const void __user * addr, unsigned long si
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
- *
- * There is a special way how to put a range of potentially faulting
- * insns (like twenty ldd/std's with now intervening other instructions)
- * You specify address of first in insn and 0 in fixup and in the next
- * exception_table_entry you specify last potentially faulting insn + 1
- * and in fixup the routine which should handle the fault.
- * That fixup code will get
- * (faulting_insn_address - first_insn_in_the_range_address)/4
- * in %g2 (ie. index of the faulting instruction in the range).
*/
-struct exception_table_entry
-{
- unsigned insn, fixup;
+struct exception_table_entry {
+ unsigned int insn, fixup;
};
-/* Special exable search, which handles ranges. Returns fixup */
-unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
-
extern void __ret_efault(void);
+extern void __retl_efault(void);
/* Uh, these should become the main single-value transfer routines..
* They automatically use the right size if we just have the right
@@ -263,7 +251,7 @@ copy_from_user(void *to, const void __user *from, unsigned long size)
{
unsigned long ret = ___copy_from_user(to, from, size);
- if (ret)
+ if (unlikely(ret))
ret = copy_from_user_fixup(to, from, size);
return ret;
}
@@ -279,7 +267,7 @@ copy_to_user(void __user *to, const void *from, unsigned long size)
{
unsigned long ret = ___copy_to_user(to, from, size);
- if (ret)
+ if (unlikely(ret))
ret = copy_to_user_fixup(to, from, size);
return ret;
}
@@ -295,7 +283,7 @@ copy_in_user(void __user *to, void __user *from, unsigned long size)
{
unsigned long ret = ___copy_in_user(to, from, size);
- if (ret)
+ if (unlikely(ret))
ret = copy_in_user_fixup(to, from, size);
return ret;
}
diff --git a/include/asm-um/dma-mapping.h b/include/asm-um/dma-mapping.h
index 13e6291f7151..babd29895114 100644
--- a/include/asm-um/dma-mapping.h
+++ b/include/asm-um/dma-mapping.h
@@ -19,7 +19,7 @@ dma_set_mask(struct device *dev, u64 dma_mask)
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
BUG();
return((void *) 0);
diff --git a/include/asm-um/futex.h b/include/asm-um/futex.h
index 2cac5ecd9d00..142ee2d8e0fd 100644
--- a/include/asm-um/futex.h
+++ b/include/asm-um/futex.h
@@ -1,53 +1,12 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#ifdef __KERNEL__
+#ifndef __UM_FUTEX_H
+#define __UM_FUTEX_H
#include <linux/futex.h>
#include <asm/errno.h>
+#include <asm/system.h>
+#include <asm/processor.h>
#include <asm/uaccess.h>
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
- int op = (encoded_op >> 28) & 7;
- int cmp = (encoded_op >> 24) & 15;
- int oparg = (encoded_op << 8) >> 20;
- int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
- oparg = 1 << oparg;
-
- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
- return -EFAULT;
-
- inc_preempt_count();
-
- switch (op) {
- case FUTEX_OP_SET:
- case FUTEX_OP_ADD:
- case FUTEX_OP_OR:
- case FUTEX_OP_ANDN:
- case FUTEX_OP_XOR:
- default:
- ret = -ENOSYS;
- }
+#include "asm/arch/futex.h"
- dec_preempt_count();
-
- if (!ret) {
- switch (cmp) {
- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
- default: ret = -ENOSYS;
- }
- }
- return ret;
-}
-
-#endif
#endif
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index bd850a249183..0229814af31e 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -96,8 +96,7 @@ extern unsigned long uml_physmem;
#define __va_space (8*1024*1024)
-extern unsigned long to_phys(void *virt);
-extern void *to_virt(unsigned long phys);
+#include "mem.h"
/* Cast to unsigned long before casting to void * to avoid a warning from
* mmap_kmem about cutting a long long down to a void *. Not sure that
@@ -116,7 +115,7 @@ extern void *to_virt(unsigned long phys);
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
-extern struct page *arch_validate(struct page *page, int mask, int order);
+extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
#define HAVE_ARCH_VALIDATE
extern void arch_free_page(struct page *page, int order);
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
index b48e0966ecd7..616d02b57ea9 100644
--- a/include/asm-um/pgtable.h
+++ b/include/asm-um/pgtable.h
@@ -326,19 +326,26 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
}
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-extern phys_t page_to_phys(struct page *page);
-
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
+#define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys))
+#define __virt_to_page(virt) phys_to_page(__pa(virt))
+#define page_to_phys(page) pfn_to_phys(page_to_pfn(page))
+
+#define mk_pte(page, pgprot) \
+ ({ pte_t pte; \
+ \
+ pte_set_val(pte, page_to_phys(page), (pgprot)); \
+ if (pte_present(pte)) \
+ pte_mknewprot(pte_mknewpage(pte)); \
+ pte;})
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot);
- if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
return pte;
}
@@ -410,8 +417,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#endif
#endif
-extern struct page *phys_to_page(const unsigned long phys);
-extern struct page *__virt_to_page(const unsigned long virt);
#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
/*
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index b2fc94fbc2d9..075771c371f6 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -13,6 +13,7 @@ struct task_struct;
#include "linux/config.h"
#include "asm/ptrace.h"
#include "choose-mode.h"
+#include "registers.h"
struct mm_struct;
@@ -21,6 +22,7 @@ struct thread_struct {
* copy_thread) to mark that we are begin called from userspace (fork /
* vfork / clone), and reset to 0 after. It is left to 0 when called
* from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */
+ struct task_struct *saved_task;
int forking;
int nsyscalls;
struct pt_regs regs;
@@ -135,19 +137,15 @@ extern struct cpuinfo_um cpu_data[];
#define current_cpu_data boot_cpu_data
#endif
-#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
-#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
-#define get_wchan(p) (0)
+#ifdef CONFIG_MODE_SKAS
+#define KSTK_REG(tsk, reg) \
+ ({ union uml_pt_regs regs; \
+ get_thread_regs(&regs, tsk->thread.mode.skas.switch_buf); \
+ UPT_REG(&regs, reg); })
+#else
+#define KSTK_REG(tsk, reg) (0xbadbabe)
#endif
+#define get_wchan(p) (0)
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
index 431bad3ae9d7..4108a579eb92 100644
--- a/include/asm-um/processor-i386.h
+++ b/include/asm-um/processor-i386.h
@@ -43,17 +43,10 @@ static inline void rep_nop(void)
#define ARCH_IS_STACKGROW(address) \
(address + 32 >= UPT_SP(&current->thread.regs.regs))
+#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP)
+#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP)
+#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP)
+
#include "asm/processor-generic.h"
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index 0beb9a42ae05..e1e1255a1d36 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -36,17 +36,9 @@ extern inline void rep_nop(void)
#define ARCH_IS_STACKGROW(address) \
(address + 128 >= UPT_SP(&current->thread.regs.regs))
+#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP)
+#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP)
+
#include "asm/processor-generic.h"
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/spinlock_types.h b/include/asm-um/spinlock_types.h
new file mode 100644
index 000000000000..e5a94294bf82
--- /dev/null
+++ b/include/asm-um/spinlock_types.h
@@ -0,0 +1,6 @@
+#ifndef __UM_SPINLOCK_TYPES_H
+#define __UM_SPINLOCK_TYPES_H
+
+#include "asm/arch/spinlock_types.h"
+
+#endif
diff --git a/include/asm-um/system-i386.h b/include/asm-um/system-i386.h
index ea8381de3cc9..c436263e67ba 100644
--- a/include/asm-um/system-i386.h
+++ b/include/asm-um/system-i386.h
@@ -3,6 +3,4 @@
#include "asm/system-generic.h"
-#define __HAVE_ARCH_CMPXCHG 1
-
#endif
diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
index 801710d00a40..2ee028b8de9d 100644
--- a/include/asm-um/uaccess.h
+++ b/include/asm-um/uaccess.h
@@ -44,7 +44,7 @@
const __typeof__(ptr) __private_ptr = ptr; \
__typeof__(*(__private_ptr)) __private_val; \
int __private_ret = -EFAULT; \
- (x) = 0; \
+ (x) = (__typeof__(*(__private_ptr)))0; \
if (__copy_from_user(&__private_val, (__private_ptr), \
sizeof(*(__private_ptr))) == 0) {\
(x) = (__typeof__(*(__private_ptr))) __private_val; \
diff --git a/include/asm-v850/futex.h b/include/asm-v850/futex.h
index 2cac5ecd9d00..9feff4ce1424 100644
--- a/include/asm-v850/futex.h
+++ b/include/asm-v850/futex.h
@@ -14,7 +14,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret, tem;
+ int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
index dc8c981af27f..aa1c7b2e438c 100644
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -101,7 +101,7 @@ __acpi_release_global_lock (unsigned int *lock)
:"=r"(n_hi), "=r"(n_lo) \
:"0"(n_hi), "1"(n_lo))
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern int acpi_lapic;
extern int acpi_ioapic;
extern int acpi_noirq;
@@ -121,17 +121,6 @@ static inline void disable_acpi(void)
#define FIX_ACPI_PAGES 4
extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
-
-#else /* !CONFIG_ACPI_BOOT */
-#define acpi_lapic 0
-#define acpi_ioapic 0
-#endif /* !CONFIG_ACPI_BOOT */
-
-extern int acpi_numa;
-extern int acpi_scan_nodes(unsigned long start, unsigned long end);
-#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
-
-#ifdef CONFIG_ACPI_PCI
static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
static inline void acpi_disable_pci(void)
{
@@ -139,11 +128,19 @@ static inline void acpi_disable_pci(void)
acpi_noirq_set();
}
extern int acpi_irq_balance_set(char *str);
-#else
+
+#else /* !CONFIG_ACPI */
+
+#define acpi_lapic 0
+#define acpi_ioapic 0
static inline void acpi_noirq_set(void) { }
static inline void acpi_disable_pci(void) { }
-static inline int acpi_irq_balance_set(char *str) { return 0; }
-#endif
+
+#endif /* !CONFIG_ACPI */
+
+extern int acpi_numa;
+extern int acpi_scan_nodes(unsigned long start, unsigned long end);
+#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
#ifdef CONFIG_ACPI_SLEEP
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
index 16ec82e16b21..6c5d5ca8383a 100644
--- a/include/asm-x86_64/apic.h
+++ b/include/asm-x86_64/apic.h
@@ -109,9 +109,10 @@ extern unsigned int nmi_watchdog;
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
+extern int disable_timer_pin_1;
+
#endif /* CONFIG_X86_LOCAL_APIC */
-#define esr_disable 0
extern unsigned boot_cpu_id;
#endif /* __ASM_APIC_H */
diff --git a/include/asm-x86_64/apicdef.h b/include/asm-x86_64/apicdef.h
index 9388062c4f6e..fb1c99ac669f 100644
--- a/include/asm-x86_64/apicdef.h
+++ b/include/asm-x86_64/apicdef.h
@@ -113,6 +113,7 @@
#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
#define MAX_IO_APICS 128
+#define MAX_LOCAL_APIC 256
/*
* All x86-64 systems are xAPIC compatible.
diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h
index eed785667289..80ac1fe966ac 100644
--- a/include/asm-x86_64/bug.h
+++ b/include/asm-x86_64/bug.h
@@ -9,10 +9,8 @@
*/
struct bug_frame {
unsigned char ud2[2];
- unsigned char mov;
- /* should use 32bit offset instead, but the assembler doesn't
- like it */
- char *filename;
+ unsigned char push;
+ signed int filename;
unsigned char ret;
unsigned short line;
} __attribute__((packed));
@@ -25,8 +23,8 @@ struct bug_frame {
The magic numbers generate mov $64bitimm,%eax ; ret $offset. */
#define BUG() \
asm volatile( \
- "ud2 ; .byte 0xa3 ; .quad %c1 ; .byte 0xc2 ; .short %c0" :: \
- "i"(__LINE__), "i" (__stringify(__FILE__)))
+ "ud2 ; pushq $%c1 ; ret $%c0" :: \
+ "i"(__LINE__), "i" (__FILE__))
void out_of_line_bug(void);
#else
static inline void out_of_line_bug(void) { }
diff --git a/include/asm-x86_64/calling.h b/include/asm-x86_64/calling.h
index 0bc12655fa5b..fc2c5a6c262a 100644
--- a/include/asm-x86_64/calling.h
+++ b/include/asm-x86_64/calling.h
@@ -65,27 +65,36 @@
.if \skipr11
.else
movq (%rsp),%r11
+ CFI_RESTORE r11
.endif
.if \skipr8910
.else
movq 1*8(%rsp),%r10
+ CFI_RESTORE r10
movq 2*8(%rsp),%r9
+ CFI_RESTORE r9
movq 3*8(%rsp),%r8
+ CFI_RESTORE r8
.endif
.if \skiprax
.else
movq 4*8(%rsp),%rax
+ CFI_RESTORE rax
.endif
.if \skiprcx
.else
movq 5*8(%rsp),%rcx
+ CFI_RESTORE rcx
.endif
.if \skiprdx
.else
movq 6*8(%rsp),%rdx
+ CFI_RESTORE rdx
.endif
movq 7*8(%rsp),%rsi
+ CFI_RESTORE rsi
movq 8*8(%rsp),%rdi
+ CFI_RESTORE rdi
.if ARG_SKIP+\addskip > 0
addq $ARG_SKIP+\addskip,%rsp
CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
@@ -124,11 +133,17 @@
.macro RESTORE_REST
movq (%rsp),%r15
+ CFI_RESTORE r15
movq 1*8(%rsp),%r14
+ CFI_RESTORE r14
movq 2*8(%rsp),%r13
+ CFI_RESTORE r13
movq 3*8(%rsp),%r12
+ CFI_RESTORE r12
movq 4*8(%rsp),%rbp
+ CFI_RESTORE rbp
movq 5*8(%rsp),%rbx
+ CFI_RESTORE rbx
addq $REST_SKIP,%rsp
CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
.endm
@@ -146,11 +161,3 @@
.macro icebp
.byte 0xf1
.endm
-
-#ifdef CONFIG_FRAME_POINTER
-#define ENTER enter
-#define LEAVE leave
-#else
-#define ENTER
-#define LEAVE
-#endif
diff --git a/include/asm-x86_64/current.h b/include/asm-x86_64/current.h
index 7db560ee6f70..bc8adecee66d 100644
--- a/include/asm-x86_64/current.h
+++ b/include/asm-x86_64/current.h
@@ -17,7 +17,7 @@ static inline struct task_struct *get_current(void)
#else
#ifndef ASM_OFFSET_H
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
#endif
#define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
index c89b58bebee2..68ac3c62fe3d 100644
--- a/include/asm-x86_64/desc.h
+++ b/include/asm-x86_64/desc.h
@@ -8,6 +8,8 @@
#ifndef __ASSEMBLY__
#include <linux/string.h>
+#include <linux/smp.h>
+
#include <asm/segment.h>
#include <asm/mmu.h>
@@ -191,7 +193,7 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
/*
* load one particular LDT into the current CPU
*/
-extern inline void load_LDT_nolock (mm_context_t *pc, int cpu)
+static inline void load_LDT_nolock (mm_context_t *pc, int cpu)
{
int count = pc->size;
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index a416dc31634a..54a380efed41 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -17,7 +17,7 @@ extern dma_addr_t bad_dma_address;
(swiotlb ? swiotlb_dma_mapping_error(x) : ((x) == bad_dma_address))
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- unsigned gfp);
+ gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle);
@@ -85,6 +85,11 @@ static inline void dma_sync_single_for_device(struct device *hwdev,
flush_write_buffers();
}
+#define dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, dir) \
+ dma_sync_single_for_cpu(dev, dma_handle, size, dir)
+#define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \
+ dma_sync_single_for_device(dev, dma_handle, size, dir)
+
static inline void dma_sync_sg_for_cpu(struct device *hwdev,
struct scatterlist *sg,
int nelems, int direction)
diff --git a/include/asm-x86_64/dwarf2.h b/include/asm-x86_64/dwarf2.h
index afd4212e860b..582757fc0365 100644
--- a/include/asm-x86_64/dwarf2.h
+++ b/include/asm-x86_64/dwarf2.h
@@ -24,6 +24,10 @@
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
#define CFI_OFFSET .cfi_offset
#define CFI_REL_OFFSET .cfi_rel_offset
+#define CFI_REGISTER .cfi_register
+#define CFI_RESTORE .cfi_restore
+#define CFI_REMEMBER_STATE .cfi_remember_state
+#define CFI_RESTORE_STATE .cfi_restore_state
#else
@@ -36,6 +40,10 @@
#define CFI_ADJUST_CFA_OFFSET #
#define CFI_OFFSET #
#define CFI_REL_OFFSET #
+#define CFI_REGISTER #
+#define CFI_RESTORE #
+#define CFI_REMEMBER_STATE #
+#define CFI_RESTORE_STATE #
#endif
diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h
index cf8b16cbe8db..a582cfcf2231 100644
--- a/include/asm-x86_64/fixmap.h
+++ b/include/asm-x86_64/fixmap.h
@@ -76,7 +76,7 @@ extern void __this_fixmap_does_not_exist(void);
* directly without translation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
-extern inline unsigned long fix_to_virt(const unsigned int idx)
+static inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
index 27c381fa1c9d..8661b476fb40 100644
--- a/include/asm-x86_64/hardirq.h
+++ b/include/asm-x86_64/hardirq.h
@@ -9,11 +9,12 @@
#define __ARCH_IRQ_STAT 1
-/* Generate a lvalue for a pda member. Should fix softirq.c instead to use
- special access macros. This would generate better code. */
-#define __IRQ_STAT(cpu,member) (read_pda(me)->member)
+#define local_softirq_pending() read_pda(__softirq_pending)
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+#define __ARCH_SET_SOFTIRQ_PENDING 1
+
+#define set_softirq_pending(x) write_pda(__softirq_pending, (x))
+#define or_softirq_pending(x) or_pda(__softirq_pending, (x))
/*
* 'what should we do if we get a hw irq event on an illegal vector'.
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 2b5cb2865d21..dc97668ea0f9 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -26,6 +26,7 @@
struct hw_interrupt_type;
#endif
+#define NMI_VECTOR 0x02
/*
* IDT vectors usable for external interrupt sources start
* at 0x20:
@@ -50,14 +51,15 @@ struct hw_interrupt_type;
*/
#define SPURIOUS_APIC_VECTOR 0xff
#define ERROR_APIC_VECTOR 0xfe
-#define INVALIDATE_TLB_VECTOR 0xfd
-#define RESCHEDULE_VECTOR 0xfc
-#define TASK_MIGRATION_VECTOR 0xfb
-#define CALL_FUNCTION_VECTOR 0xfa
-#define KDB_VECTOR 0xf9
-
-#define THERMAL_APIC_VECTOR 0xf0
-
+#define RESCHEDULE_VECTOR 0xfd
+#define CALL_FUNCTION_VECTOR 0xfc
+#define KDB_VECTOR 0xfb /* reserved for KDB */
+#define THERMAL_APIC_VECTOR 0xfa
+/* 0xf9 free */
+#define INVALIDATE_TLB_VECTOR_END 0xf8
+#define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f8 used for TLB flush */
+
+#define NUM_INVALIDATE_TLB_VECTORS 8
/*
* Local APIC timer IRQ vector is on a different priority level,
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index 37fc3f149a5a..52ff269fe054 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -48,7 +48,7 @@
* Talk about misusing macros..
*/
#define __OUT1(s,x) \
-extern inline void out##s(unsigned x value, unsigned short port) {
+static inline void out##s(unsigned x value, unsigned short port) {
#define __OUT2(s,s1,s2) \
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
@@ -58,7 +58,7 @@ __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
#define __IN1(s) \
-extern inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
+static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
@@ -68,12 +68,12 @@ __IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
#define __INS(s) \
-extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
{ __asm__ __volatile__ ("rep ; ins" #s \
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
-extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
@@ -110,12 +110,12 @@ __OUTS(l)
* Change virtual addresses to physical addresses and vv.
* These are pretty trivial
*/
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
{
return __pa(address);
}
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
{
return __va(address);
}
@@ -130,7 +130,7 @@ extern inline void * phys_to_virt(unsigned long address)
extern void __iomem *__ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-extern inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index a8babd2bbe84..ee1bc69aec9c 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -201,7 +201,7 @@ extern int skip_ioapic_setup;
*/
#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern int io_apic_get_version (int ioapic);
extern int io_apic_get_redir_entries (int ioapic);
extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int);
diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h
index 5e166b9d3bde..022e9d340ad7 100644
--- a/include/asm-x86_64/ipi.h
+++ b/include/asm-x86_64/ipi.h
@@ -31,9 +31,20 @@
static inline unsigned int __prepare_ICR (unsigned int shortcut, int vector, unsigned int dest)
{
- unsigned int icr = APIC_DM_FIXED | shortcut | vector | dest;
- if (vector == KDB_VECTOR)
- icr = (icr & (~APIC_VECTOR_MASK)) | APIC_DM_NMI;
+ unsigned int icr = shortcut | dest;
+
+ switch (vector) {
+ default:
+ icr |= APIC_DM_FIXED | vector;
+ break;
+ case NMI_VECTOR:
+ /*
+ * Setup KDB IPI to be delivered as an NMI
+ */
+ case KDB_VECTOR:
+ icr |= APIC_DM_NMI;
+ break;
+ }
return icr;
}
@@ -66,7 +77,7 @@ static inline void __send_IPI_shortcut(unsigned int shortcut, int vector, unsign
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write_around(APIC_ICR, cfg);
+ apic_write(APIC_ICR, cfg);
}
@@ -92,7 +103,7 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
* prepare target chip field
*/
cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]);
- apic_write_around(APIC_ICR2, cfg);
+ apic_write(APIC_ICR2, cfg);
/*
* program the ICR
@@ -102,7 +113,7 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write_around(APIC_ICR, cfg);
+ apic_write(APIC_ICR, cfg);
}
local_irq_restore(flags);
}
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
index 4482657777bb..fb724ba37ae6 100644
--- a/include/asm-x86_64/irq.h
+++ b/include/asm-x86_64/irq.h
@@ -48,10 +48,6 @@ static __inline__ int irq_canonicalize(int irq)
#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/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
index b90341994d80..f604e84c5303 100644
--- a/include/asm-x86_64/kdebug.h
+++ b/include/asm-x86_64/kdebug.h
@@ -46,7 +46,7 @@ extern void die(const char *,struct pt_regs *,long);
extern void __die(const char *,struct pt_regs *,long);
extern void show_registers(struct pt_regs *regs);
extern void dump_pagetable(unsigned long);
-extern void oops_begin(void);
-extern void oops_end(void);
+extern unsigned long oops_begin(void);
+extern void oops_end(unsigned long);
#endif
diff --git a/include/asm-x86_64/local.h b/include/asm-x86_64/local.h
index c954f15c1a75..3e72c41727c5 100644
--- a/include/asm-x86_64/local.h
+++ b/include/asm-x86_64/local.h
@@ -29,7 +29,7 @@ static __inline__ void local_dec(local_t *v)
:"m" (v->counter));
}
-static __inline__ void local_add(unsigned long i, local_t *v)
+static __inline__ void local_add(unsigned int i, local_t *v)
{
__asm__ __volatile__(
"addl %1,%0"
@@ -37,7 +37,7 @@ static __inline__ void local_add(unsigned long i, local_t *v)
:"ir" (i), "m" (v->counter));
}
-static __inline__ void local_sub(unsigned long i, local_t *v)
+static __inline__ void local_sub(unsigned int i, local_t *v)
{
__asm__ __volatile__(
"subl %1,%0"
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index 768413751b34..b40c661f111e 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -12,7 +12,7 @@
#include <asm/smp.h>
-#define NODEMAPSIZE 0xff
+#define NODEMAPSIZE 0xfff
/* Simple perfect hash to map physical addresses to node numbers */
extern int memnode_shift;
@@ -54,7 +54,7 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
#define pfn_valid(pfn) ((pfn) >= num_physpages ? 0 : \
({ u8 nid__ = pfn_to_nid(pfn); \
- nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) <= node_end_pfn(nid__); }))
+ nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) < node_end_pfn(nid__); }))
#endif
#define local_mapnr(kvaddr) \
diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h
index 331f6a3c72a2..f267e10c023d 100644
--- a/include/asm-x86_64/mpspec.h
+++ b/include/asm-x86_64/mpspec.h
@@ -179,7 +179,7 @@ extern int mpc_default_type;
extern unsigned long mp_lapic_addr;
extern int pic_mode;
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
extern void mp_register_lapic (u8 id, u8 enabled);
extern void mp_register_lapic_address (u64 address);
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index ba15279a79d0..5a7fe3c6c3d8 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -29,22 +29,37 @@
#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32)
/* wrmsr with exception handling */
-#define wrmsr_safe(msr,a,b) ({ int ret__; \
- asm volatile("2: wrmsr ; xorl %0,%0\n" \
- "1:\n\t" \
- ".section .fixup,\"ax\"\n\t" \
- "3: movl %4,%0 ; jmp 1b\n\t" \
- ".previous\n\t" \
- ".section __ex_table,\"a\"\n" \
- " .align 8\n\t" \
- " .quad 2b,3b\n\t" \
- ".previous" \
- : "=a" (ret__) \
- : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT));\
+#define wrmsr_safe(msr,a,b) ({ int ret__; \
+ asm volatile("2: wrmsr ; xorl %0,%0\n" \
+ "1:\n\t" \
+ ".section .fixup,\"ax\"\n\t" \
+ "3: movl %4,%0 ; jmp 1b\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 8\n\t" \
+ " .quad 2b,3b\n\t" \
+ ".previous" \
+ : "=a" (ret__) \
+ : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \
ret__; })
#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32))
+#define rdmsr_safe(msr,a,b) \
+ ({ int ret__; \
+ asm volatile ("1: rdmsr\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: movl %4,%0\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 8\n" \
+ " .quad 1b,3b\n" \
+ ".previous":"=&bDS" (ret__), "=a"(a), "=d"(b)\
+ :"c"(msr), "i"(-EIO), "0"(0)); \
+ ret__; })
+
#define rdtsc(low,high) \
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
@@ -64,7 +79,7 @@
: "=a" (low), "=d" (high) \
: "c" (counter))
-extern inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
+static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
__asm__("cpuid"
@@ -90,7 +105,7 @@ static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
/*
* CPUID functions returning a single datum
*/
-extern inline unsigned int cpuid_eax(unsigned int op)
+static inline unsigned int cpuid_eax(unsigned int op)
{
unsigned int eax;
@@ -100,7 +115,7 @@ extern inline unsigned int cpuid_eax(unsigned int op)
: "bx", "cx", "dx");
return eax;
}
-extern inline unsigned int cpuid_ebx(unsigned int op)
+static inline unsigned int cpuid_ebx(unsigned int op)
{
unsigned int eax, ebx;
@@ -110,7 +125,7 @@ extern inline unsigned int cpuid_ebx(unsigned int op)
: "cx", "dx" );
return ebx;
}
-extern inline unsigned int cpuid_ecx(unsigned int op)
+static inline unsigned int cpuid_ecx(unsigned int op)
{
unsigned int eax, ecx;
@@ -120,7 +135,7 @@ extern inline unsigned int cpuid_ecx(unsigned int op)
: "bx", "dx" );
return ecx;
}
-extern inline unsigned int cpuid_edx(unsigned int op)
+static inline unsigned int cpuid_edx(unsigned int op)
{
unsigned int eax, edx;
@@ -219,6 +234,7 @@ extern inline unsigned int cpuid_edx(unsigned int op)
#define MSR_K8_TOP_MEM1 0xC001001A
#define MSR_K8_TOP_MEM2 0xC001001D
#define MSR_K8_SYSCFG 0xC0010010
+#define MSR_K8_HWCR 0xC0010015
/* K6 MSRs */
#define MSR_K6_EFER 0xC0000080
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
index 5c363a1482e4..bcf55c3f7f7f 100644
--- a/include/asm-x86_64/numa.h
+++ b/include/asm-x86_64/numa.h
@@ -9,6 +9,7 @@ struct node {
};
extern int compute_hash_shift(struct node *nodes, int numnodes);
+extern int pxm_to_node(int nid);
#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
@@ -16,6 +17,8 @@ extern void numa_add_cpu(int cpu);
extern void numa_init_array(void);
extern int numa_off;
+extern unsigned char apicid_to_node[256];
+
#define NUMA_NO_NODE 0xff
#endif
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index 135ffaa0393b..e5ab4d231f2c 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -32,6 +32,8 @@
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
+extern unsigned long end_pfn;
+
void clear_page(void *);
void copy_page(void *, void *);
@@ -111,7 +113,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#ifdef CONFIG_FLATMEM
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
-#define pfn_valid(pfn) ((pfn) < max_mapnr)
+#define pfn_valid(pfn) ((pfn) < end_pfn)
#endif
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index 36b766cfc4d5..bbf89aa8a1af 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -10,10 +10,8 @@
struct x8664_pda {
struct task_struct *pcurrent; /* Current process */
unsigned long data_offset; /* Per cpu data offset from linker address */
- struct x8664_pda *me; /* Pointer to itself */
unsigned long kernelstack; /* top of kernel stack for current */
unsigned long oldrsp; /* user rsp for system call */
- unsigned long irqrsp; /* Old rsp for interrupts. */
int irqcount; /* Irq nesting counter. Starts with -1 */
int cpunumber; /* Logical CPU number */
char *irqstackptr; /* top of irqstack */
@@ -22,7 +20,7 @@ struct x8664_pda {
struct mm_struct *active_mm;
int mmu_state;
unsigned apic_timer_irqs;
-} ____cacheline_aligned;
+} ____cacheline_aligned_in_smp;
#define IRQSTACK_ORDER 2
@@ -42,13 +40,14 @@ extern void __bad_pda_field(void);
#define pda_offset(field) offsetof(struct x8664_pda, field)
#define pda_to_op(op,field,val) do { \
+ typedef typeof_field(struct x8664_pda, field) T__; \
switch (sizeof_field(struct x8664_pda, field)) { \
case 2: \
-asm volatile(op "w %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+asm volatile(op "w %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
case 4: \
-asm volatile(op "l %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+asm volatile(op "l %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
case 8: \
-asm volatile(op "q %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+asm volatile(op "q %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
default: __bad_pda_field(); \
} \
} while (0)
@@ -58,7 +57,7 @@ asm volatile(op "q %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); bre
* Unfortunately removing them causes all hell to break lose currently.
*/
#define pda_from_op(op,field) ({ \
- typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
+ typeof_field(struct x8664_pda, field) ret__; \
switch (sizeof_field(struct x8664_pda, field)) { \
case 2: \
asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
@@ -75,6 +74,7 @@ asm volatile(op "q %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); b
#define write_pda(field,val) pda_to_op("mov",field,val)
#define add_pda(field,val) pda_to_op("add",field,val)
#define sub_pda(field,val) pda_to_op("sub",field,val)
+#define or_pda(field,val) pda_to_op("or",field,val)
#endif
diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h
index deadd146978b..08cad2482bcb 100644
--- a/include/asm-x86_64/pgalloc.h
+++ b/include/asm-x86_64/pgalloc.h
@@ -18,12 +18,12 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *p
set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
}
-extern __inline__ pmd_t *get_pmd(void)
+static inline pmd_t *get_pmd(void)
{
return (pmd_t *)get_zeroed_page(GFP_KERNEL);
}
-extern __inline__ void pmd_free(pmd_t *pmd)
+static inline void pmd_free(pmd_t *pmd)
{
BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
free_page((unsigned long)pmd);
@@ -86,13 +86,13 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long add
/* Should really implement gc for free page table pages. This could be
done with a reference count in struct page. */
-extern __inline__ void pte_free_kernel(pte_t *pte)
+static inline void pte_free_kernel(pte_t *pte)
{
BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
free_page((unsigned long)pte);
}
-extern inline void pte_free(struct page *pte)
+static inline void pte_free(struct page *pte)
{
__free_page(pte);
}
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 5e0f2fdab0d3..dd8711ecaf2f 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -85,7 +85,7 @@ static inline void set_pud(pud_t *dst, pud_t val)
pud_val(*dst) = pud_val(val);
}
-extern inline void pud_clear (pud_t *pud)
+static inline void pud_clear (pud_t *pud)
{
set_pud(pud, __pud(0));
}
@@ -95,7 +95,7 @@ static inline void set_pgd(pgd_t *dst, pgd_t val)
pgd_val(*dst) = pgd_val(val);
}
-extern inline void pgd_clear (pgd_t * pgd)
+static inline void pgd_clear (pgd_t * pgd)
{
set_pgd(pgd, __pgd(0));
}
@@ -375,7 +375,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
}
/* Change flags of a PTE */
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte_val(pte) &= _PAGE_CHG_MASK;
pte_val(pte) |= pgprot_val(newprot);
@@ -384,7 +384,7 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
}
#define pte_index(address) \
- ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset_kernel(dir, address) ((pte_t *) pmd_page_kernel(*(dir)) + \
pte_index(address))
@@ -421,9 +421,6 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
extern int kern_addr_valid(unsigned long addr);
-#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index a8321999448f..03837d34fba0 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -254,7 +254,13 @@ struct thread_struct {
u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
} __attribute__((aligned(16)));
-#define INIT_THREAD {}
+#define INIT_THREAD { \
+ .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
+}
+
+#define INIT_TSS { \
+ .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
+}
#define INIT_MMAP \
{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
@@ -375,13 +381,13 @@ struct extended_sigtable {
#define ASM_NOP_MAX 8
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-extern inline void rep_nop(void)
+static inline void rep_nop(void)
{
__asm__ __volatile__("rep;nop": : :"memory");
}
/* Stop speculative execution */
-extern inline void sync_core(void)
+static inline void sync_core(void)
{
int tmp;
asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 6c813eb521f3..dbb37b0adb43 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -8,7 +8,6 @@
struct cpuinfo_x86;
struct pt_regs;
-extern void get_cpu_vendor(struct cpuinfo_x86*);
extern void start_kernel(void);
extern void pda_init(int);
@@ -75,9 +74,6 @@ extern void acpi_reserve_bootmem(void);
extern void swap_low_mappings(void);
-extern void oops_begin(void);
-extern void die(const char *,struct pt_regs *,long);
-extern void __die(const char * str, struct pt_regs * regs, long err);
extern void __show_regs(struct pt_regs * regs);
extern void show_regs(struct pt_regs * regs);
@@ -94,8 +90,6 @@ extern int unhandled_signal(struct task_struct *tsk, int sig);
extern void select_idle_routine(const struct cpuinfo_x86 *c);
extern void swiotlb_init(void);
-extern unsigned long max_mapnr;
-extern unsigned long end_pfn;
extern unsigned long table_start, table_end;
extern int exception_trace;
diff --git a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h
index fe9b96d94815..f8d55798535a 100644
--- a/include/asm-x86_64/signal.h
+++ b/include/asm-x86_64/signal.h
@@ -143,23 +143,23 @@ typedef struct sigaltstack {
#undef __HAVE_ARCH_SIG_BITOPS
#if 0
-extern __inline__ void sigaddset(sigset_t *set, int _sig)
+static inline void sigaddset(sigset_t *set, int _sig)
{
__asm__("btsq %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
}
-extern __inline__ void sigdelset(sigset_t *set, int _sig)
+static inline void sigdelset(sigset_t *set, int _sig)
{
__asm__("btrq %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
}
-extern __inline__ int __const_sigismember(sigset_t *set, int _sig)
+static inline int __const_sigismember(sigset_t *set, int _sig)
{
unsigned long sig = _sig - 1;
return 1 & (set->sig[sig / _NSIG_BPW] >> (sig & ~(_NSIG_BPW-1)));
}
-extern __inline__ int __gen_sigismember(sigset_t *set, int _sig)
+static inline int __gen_sigismember(sigset_t *set, int _sig)
{
int ret;
__asm__("btq %2,%1\n\tsbbq %0,%0"
@@ -172,7 +172,7 @@ extern __inline__ int __gen_sigismember(sigset_t *set, int _sig)
__const_sigismember((set),(sig)) : \
__gen_sigismember((set),(sig)))
-extern __inline__ int sigfindinword(unsigned long word)
+static inline int sigfindinword(unsigned long word)
{
__asm__("bsfq %1,%0" : "=r"(word) : "rm"(word) : "cc");
return word;
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index de8b57b2b62b..c57ce4071342 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -72,7 +72,7 @@ static inline int num_booting_cpus(void)
#define raw_smp_processor_id() read_pda(cpunumber)
-extern __inline int hard_smp_processor_id(void)
+static inline int hard_smp_processor_id(void)
{
/* we don't want to mark this access volatile - bad code generation */
return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID));
@@ -81,6 +81,7 @@ extern __inline int hard_smp_processor_id(void)
extern int safe_smp_processor_id(void);
extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
+extern void prefill_possible_map(void);
#endif /* !ASSEMBLY */
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
index 5aeb57a3baad..69636831ad2f 100644
--- a/include/asm-x86_64/spinlock.h
+++ b/include/asm-x86_64/spinlock.h
@@ -6,47 +6,21 @@
#include <asm/page.h>
#include <linux/config.h>
-extern int printk(const char * fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
- */
-
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned magic;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-
-#define SPINLOCK_MAGIC 0xdead4ead
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC
-#else
-#define SPINLOCK_MAGIC_INIT /* */
-#endif
-
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-/*
+ *
* Simple spin lock operations. There are two variants, one clears IRQ's
* on the local processor, one does not.
*
* We make no fairness assumptions. They have a cost.
+ *
+ * (the type definitions are in asm/spinlock_types.h)
*/
-#define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0)
-#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+#define __raw_spin_is_locked(x) \
+ (*(volatile signed char *)(&(x)->slock) <= 0)
-#define spin_lock_string \
+#define __raw_spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \
"js 2f\n" \
@@ -58,74 +32,40 @@ typedef struct {
"jmp 1b\n" \
LOCK_SECTION_END
-/*
- * This works. Despite all the confusion.
- * (except on PPro SMP or if we are using OOSTORE)
- * (PPro errata 66, 92)
- */
-
-#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
-
-#define spin_unlock_string \
+#define __raw_spin_unlock_string \
"movb $1,%0" \
- :"=m" (lock->lock) : : "memory"
-
-
-static inline void _raw_spin_unlock(spinlock_t *lock)
-{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(lock->magic != SPINLOCK_MAGIC);
- assert_spin_locked(lock);
-#endif
- __asm__ __volatile__(
- spin_unlock_string
- );
-}
-
-#else
-
-#define spin_unlock_string \
- "xchgb %b0, %1" \
- :"=q" (oldval), "=m" (lock->lock) \
- :"0" (oldval) : "memory"
+ :"=m" (lock->slock) : : "memory"
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
- char oldval = 1;
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(lock->magic != SPINLOCK_MAGIC);
- assert_spin_locked(lock);
-#endif
__asm__ __volatile__(
- spin_unlock_string
- );
+ __raw_spin_lock_string
+ :"=m" (lock->slock) : : "memory");
}
-#endif
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
char oldval;
+
__asm__ __volatile__(
"xchgb %b0,%1"
- :"=q" (oldval), "=m" (lock->lock)
+ :"=q" (oldval), "=m" (lock->slock)
:"0" (0) : "memory");
+
return oldval > 0;
}
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- if (lock->magic != SPINLOCK_MAGIC) {
- printk("eip: %p\n", __builtin_return_address(0));
- BUG();
- }
-#endif
__asm__ __volatile__(
- spin_lock_string
- :"=m" (lock->lock) : : "memory");
+ __raw_spin_unlock_string
+ );
}
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
/*
* Read-write spinlocks, allowing multiple readers
@@ -136,33 +76,7 @@ static inline void _raw_spin_lock(spinlock_t *lock)
* can "mix" irq-safe locks - any writer needs to get a
* irq-safe write-lock, but readers can get non-irqsafe
* read-locks.
- */
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
- unsigned magic;
-#endif
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-
-#define RWLOCK_MAGIC 0xdeaf1eed
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC
-#else
-#define RWLOCK_MAGIC_INIT /* */
-#endif
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-
-#define read_can_lock(x) ((int)(x)->lock > 0)
-#define write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-
-/*
+ *
* On x86, we implement read-write locks as a 32-bit counter
* with the high bit (sign) being the "contended" bit.
*
@@ -170,29 +84,24 @@ typedef struct {
*
* Changed to use the same technique as rw semaphores. See
* semaphore.h for details. -ben
+ *
+ * the helpers are in arch/i386/kernel/semaphore.c
*/
-/* the spinlock helpers are in arch/i386/kernel/semaphore.c */
-static inline void _raw_read_lock(rwlock_t *rw)
+#define __raw_read_can_lock(x) ((int)(x)->lock > 0)
+#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
+
+static inline void __raw_read_lock(raw_rwlock_t *rw)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(rw->magic != RWLOCK_MAGIC);
-#endif
__build_read_lock(rw, "__read_lock_failed");
}
-static inline void _raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
-#ifdef CONFIG_DEBUG_SPINLOCK
- BUG_ON(rw->magic != RWLOCK_MAGIC);
-#endif
__build_write_lock(rw, "__write_lock_failed");
}
-#define _raw_read_unlock(rw) asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
-#define _raw_write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
-
-static inline int _raw_read_trylock(rwlock_t *lock)
+static inline int __raw_read_trylock(raw_rwlock_t *lock)
{
atomic_t *count = (atomic_t *)lock;
atomic_dec(count);
@@ -202,7 +111,7 @@ static inline int _raw_read_trylock(rwlock_t *lock)
return 0;
}
-static inline int _raw_write_trylock(rwlock_t *lock)
+static inline int __raw_write_trylock(raw_rwlock_t *lock)
{
atomic_t *count = (atomic_t *)lock;
if (atomic_sub_and_test(RW_LOCK_BIAS, count))
@@ -211,4 +120,15 @@ static inline int _raw_write_trylock(rwlock_t *lock)
return 0;
}
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
+{
+ asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
+}
+
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
+{
+ asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0"
+ : "=m" (rw->lock) : : "memory");
+}
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-x86_64/spinlock_types.h b/include/asm-x86_64/spinlock_types.h
new file mode 100644
index 000000000000..59efe849f351
--- /dev/null
+++ b/include/asm-x86_64/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int slock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
+
+#endif
diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h
index 36293061f4ed..7cbfd10ecc3c 100644
--- a/include/asm-x86_64/swiotlb.h
+++ b/include/asm-x86_64/swiotlb.h
@@ -27,7 +27,7 @@ extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
int nents, int direction);
extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
extern void *swiotlb_alloc_coherent (struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, int flags);
+ dma_addr_t *dma_handle, gfp_t flags);
extern void swiotlb_free_coherent (struct device *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 8606e170a7dc..85348e02ad2e 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -188,7 +188,7 @@ static inline void write_cr4(unsigned long val)
#define __xg(x) ((volatile long *)(x))
-extern inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
+static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
{
*ptr = val;
}
@@ -253,19 +253,19 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
case 2:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 4:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 8:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
}
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
index 24ecf6a637cb..f971f45d6d78 100644
--- a/include/asm-x86_64/timex.h
+++ b/include/asm-x86_64/timex.h
@@ -6,7 +6,6 @@
#ifndef _ASMx8664_TIMEX_H
#define _ASMx8664_TIMEX_H
-#include <linux/config.h>
#include <asm/8253pit.h>
#include <asm/msr.h>
#include <asm/vsyscall.h>
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86_64/tlbflush.h
index 505b0cf906de..4a9c20ea9b10 100644
--- a/include/asm-x86_64/tlbflush.h
+++ b/include/asm-x86_64/tlbflush.h
@@ -109,6 +109,10 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
#define TLBSTATE_OK 1
#define TLBSTATE_LAZY 2
+/* Roughly an IPI every 20MB with 4k pages for freeing page table
+ ranges. Cost is about 42k of memory for each CPU. */
+#define ARCH_FREE_PTE_NR 5350
+
#endif
#define flush_tlb_kernel_range(start, end) flush_tlb_all()
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index c1bc3fad482e..1c603cd7e4d0 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -13,7 +13,6 @@
extern cpumask_t cpu_online_map;
extern unsigned char cpu_to_node[];
-extern unsigned char pci_bus_to_node[];
extern cpumask_t node_to_cpumask[];
#ifdef CONFIG_ACPI_NUMA
@@ -26,7 +25,7 @@ extern int __node_distance(int, int);
#define parent_node(node) (node)
#define node_to_first_cpu(node) (__ffs(node_to_cpumask[node]))
#define node_to_cpumask(node) (node_to_cpumask[node])
-#define pcibus_to_node(bus) pci_bus_to_node[(bus)->number]
+#define pcibus_to_node(bus) ((long)(bus->sysdata))
#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus));
/* sched_domains SD_NODE_INIT for x86_64 machines */
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h
index 2872da23fc7e..438a3f52f839 100644
--- a/include/asm-x86_64/vsyscall.h
+++ b/include/asm-x86_64/vsyscall.h
@@ -29,7 +29,6 @@ enum vsyscall_num {
struct vxtime_data {
long hpet_address; /* HPET base address */
- unsigned long hz; /* HPET clocks / sec */
int last;
unsigned long last_tsc;
long quot;
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index 24f86f0e43cf..12b5732dc6e5 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -22,7 +22,7 @@ typedef struct { volatile int counter; } atomic_t;
#include <asm/processor.h>
#include <asm/system.h>
-#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
+#define ATOMIC_INIT(i) { (i) }
/*
* This Xtensa implementation assumes that the right mechanism
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index d395ef226c32..e76ee889e21d 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -174,7 +174,7 @@ static __inline__ int test_bit(int nr, const volatile void *addr)
return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31));
}
-#if XCHAL_HAVE_NSAU
+#if XCHAL_HAVE_NSA
static __inline__ int __cntlz (unsigned long x)
{
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index e86a206f1209..c425f10d086a 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -28,7 +28,7 @@ extern void consistent_sync(void*, size_t, int);
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-xtensa/hardirq.h b/include/asm-xtensa/hardirq.h
index e07c76c36b95..aa9c1adf68d7 100644
--- a/include/asm-xtensa/hardirq.h
+++ b/include/asm-xtensa/hardirq.h
@@ -23,6 +23,7 @@ typedef struct {
unsigned int __nmi_count; /* arch dependent */
} ____cacheline_aligned irq_cpustat_t;
+void ack_bad_irq(unsigned int irq);
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
#endif /* _XTENSA_HARDIRQ_H */
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index 883ebc2d75d6..987e3b802313 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -441,11 +441,11 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t pte);
/*
- * remap a physical address `phys' of size `size' with page protection `prot'
+ * remap a physical page `pfn' of size `size' with page protection `prot'
* into virtual address `from'
*/
-#define io_remap_page_range(vma,from,phys,size,prot) \
- remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
+#define io_remap_pfn_range(vma,from,pfn,size,prot) \
+ remap_pfn_range(vma, from, pfn, size, prot)
/* No page table caches to init */
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
index 2848a5ff8349..aa4fd7fb3ce7 100644
--- a/include/asm-xtensa/ptrace.h
+++ b/include/asm-xtensa/ptrace.h
@@ -127,7 +127,7 @@ extern void show_regs(struct pt_regs *);
#else /* __ASSEMBLY__ */
#ifdef __KERNEL__
-# include <asm/offsets.h>
+# include <asm/asm-offsets.h>
#define PT_REGS_OFFSET (KERNEL_STACK_SIZE - PT_USER_SIZE)
#endif
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
index db740b8bc6f0..09e89ab3eb61 100644
--- a/include/asm-xtensa/semaphore.h
+++ b/include/asm-xtensa/semaphore.h
@@ -20,28 +20,19 @@ struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
-#if WAITQUEUE_DEBUG
- long __magic;
-#endif
};
-#if WAITQUEUE_DEBUG
-# define __SEM_DEBUG_INIT(name) \
- , (int)&(name).__magic
-#else
-# define __SEM_DEBUG_INIT(name)
-#endif
-
-#define __SEMAPHORE_INITIALIZER(name,count) \
- { ATOMIC_INIT(count), \
- 0, \
- __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
- __SEM_DEBUG_INIT(name) }
+#define __SEMAPHORE_INITIALIZER(name,n) \
+{ \
+ .count = ATOMIC_INIT(n), \
+ .sleepers = 0, \
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+}
-#define __MUTEX_INITIALIZER(name) \
+#define __MUTEX_INITIALIZER(name) \
__SEMAPHORE_INITIALIZER(name, 1)
-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
@@ -49,17 +40,8 @@ struct semaphore {
static inline void sema_init (struct semaphore *sem, int val)
{
-/*
- * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
- *
- * i'd rather use the more flexible initialization above, but sadly
- * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
- */
atomic_set(&sem->count, val);
init_waitqueue_head(&sem->wait);
-#if WAITQUEUE_DEBUG
- sem->__magic = (int)&sem->__magic;
-#endif
}
static inline void init_MUTEX (struct semaphore *sem)
@@ -81,9 +63,7 @@ extern spinlock_t semaphore_wake_lock;
static inline void down(struct semaphore * sem)
{
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
+ might_sleep();
if (atomic_sub_return(1, &sem->count) < 0)
__down(sem);
@@ -92,9 +72,8 @@ static inline void down(struct semaphore * sem)
static inline int down_interruptible(struct semaphore * sem)
{
int ret = 0;
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
+
+ might_sleep();
if (atomic_sub_return(1, &sem->count) < 0)
ret = __down_interruptible(sem);
@@ -104,9 +83,6 @@ static inline int down_interruptible(struct semaphore * sem)
static inline int down_trylock(struct semaphore * sem)
{
int ret = 0;
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
if (atomic_sub_return(1, &sem->count) < 0)
ret = __down_trylock(sem);
@@ -119,9 +95,6 @@ static inline int down_trylock(struct semaphore * sem)
*/
static inline void up(struct semaphore * sem)
{
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
if (atomic_add_return(1, &sem->count) <= 0)
__up(sem);
}
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index f09393232e5e..9284867f1cb9 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -189,20 +189,6 @@ static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
#define tas(ptr) (xchg((ptr),1))
-#if ( __XCC__ == 1 )
-
-/* xt-xcc processes __inline__ differently than xt-gcc and decides to
- * insert an out-of-line copy of function __xchg. This presents the
- * unresolved symbol at link time of __xchg_called_with_bad_pointer,
- * even though such a function would never be called at run-time.
- * xt-gcc always inlines __xchg, and optimizes away the undefined
- * bad_pointer function.
- */
-
-#define xchg(ptr,x) xchg_u32(ptr,x)
-
-#else /* assume xt-gcc */
-
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
/*
@@ -224,8 +210,6 @@ __xchg(unsigned long x, volatile void * ptr, int size)
return x;
}
-#endif
-
extern void set_except_vector(int n, void *addr);
static inline void spill_registers(void)
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
index fc268ac923c0..06a22b83ba17 100644
--- a/include/asm-xtensa/uaccess.h
+++ b/include/asm-xtensa/uaccess.h
@@ -25,7 +25,7 @@
#define _ASMLANGUAGE
#include <asm/current.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/processor.h>
/*
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 1993a3691768..19f70462b3be 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -162,13 +162,13 @@ typedef struct acct acct_t;
#ifdef __KERNEL__
/*
* Yet another set of HZ to *HZ helper functions.
- * See <linux/times.h> for the original.
+ * See <linux/jiffies.h> for the original.
*/
static inline u32 jiffies_to_AHZ(unsigned long x)
{
#if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0
- return x / (HZ / USER_HZ);
+ return x / (HZ / AHZ);
#else
u64 tmp = (u64)x * TICK_NSEC;
do_div(tmp, (NSEC_PER_SEC / AHZ));
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b46a5205ee7b..026c3c011dc0 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -41,7 +41,7 @@
#include <asm/acpi.h>
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
enum acpi_irq_model_id {
ACPI_IRQ_MODEL_PIC = 0,
@@ -429,23 +429,13 @@ extern int pci_mmcfg_config_num;
extern int sbf_port ;
-#else /*!CONFIG_ACPI_BOOT*/
+#else /* !CONFIG_ACPI */
#define acpi_mp_config 0
-static inline int acpi_boot_init(void)
-{
- return 0;
-}
-
-static inline int acpi_boot_table_init(void)
-{
- return 0;
-}
+#endif /* !CONFIG_ACPI */
-#endif /*!CONFIG_ACPI_BOOT*/
-
-unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
+int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
/*
@@ -455,7 +445,7 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
*/
void acpi_unregister_gsi (u32 gsi);
-#ifdef CONFIG_ACPI_PCI
+#ifdef CONFIG_ACPI
struct acpi_prt_entry {
struct list_head node;
@@ -489,7 +479,7 @@ struct acpi_pci_driver {
int acpi_pci_register_driver(struct acpi_pci_driver *driver);
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
-#endif /*CONFIG_ACPI_PCI*/
+#endif /* CONFIG_ACPI */
#ifdef CONFIG_ACPI_EC
@@ -498,20 +488,9 @@ extern int ec_write(u8 addr, u8 val);
#endif /*CONFIG_ACPI_EC*/
-#ifdef CONFIG_ACPI_INTERPRETER
-
extern int acpi_blacklisted(void);
extern void acpi_bios_year(char *s);
-#else /*!CONFIG_ACPI_INTERPRETER*/
-
-static inline int acpi_blacklisted(void)
-{
- return 0;
-}
-
-#endif /*!CONFIG_ACPI_INTERPRETER*/
-
#define ACPI_CSTATE_LIMIT_DEFINED /* for driver builds */
#ifdef CONFIG_ACPI
@@ -549,5 +528,17 @@ static inline int acpi_get_pxm(acpi_handle handle)
extern int pnpacpi_disabled;
+#else /* CONFIG_ACPI */
+
+static inline int acpi_boot_init(void)
+{
+ return 0;
+}
+
+static inline int acpi_boot_table_init(void)
+{
+ return 0;
+}
+
#endif /* CONFIG_ACPI */
#endif /*_LINUX_ACPI_H*/
diff --git a/include/linux/aio.h b/include/linux/aio.h
index a4d5af907f90..0decf66117c1 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -24,7 +24,12 @@ struct kioctx;
#define KIOCB_SYNC_KEY (~0U)
/* ki_flags bits */
-#define KIF_LOCKED 0
+/*
+ * This may be used for cancel/retry serialization in the future, but
+ * for now it's unused and we probably don't want modules to even
+ * think they can use it.
+ */
+/* #define KIF_LOCKED 0 */
#define KIF_KICKED 1
#define KIF_CANCELLED 2
@@ -43,6 +48,40 @@ struct kioctx;
#define kiocbIsKicked(iocb) test_bit(KIF_KICKED, &(iocb)->ki_flags)
#define kiocbIsCancelled(iocb) test_bit(KIF_CANCELLED, &(iocb)->ki_flags)
+/* is there a better place to document function pointer methods? */
+/**
+ * ki_retry - iocb forward progress callback
+ * @kiocb: The kiocb struct to advance by performing an operation.
+ *
+ * This callback is called when the AIO core wants a given AIO operation
+ * to make forward progress. The kiocb argument describes the operation
+ * that is to be performed. As the operation proceeds, perhaps partially,
+ * ki_retry is expected to update the kiocb with progress made. Typically
+ * ki_retry is set in the AIO core and it itself calls file_operations
+ * helpers.
+ *
+ * ki_retry's return value determines when the AIO operation is completed
+ * and an event is generated in the AIO event ring. Except the special
+ * return values described below, the value that is returned from ki_retry
+ * is transferred directly into the completion ring as the operation's
+ * resulting status. Once this has happened ki_retry *MUST NOT* reference
+ * the kiocb pointer again.
+ *
+ * If ki_retry returns -EIOCBQUEUED it has made a promise that aio_complete()
+ * will be called on the kiocb pointer in the future. The AIO core will
+ * not ask the method again -- ki_retry must ensure forward progress.
+ * aio_complete() must be called once and only once in the future, multiple
+ * calls may result in undefined behaviour.
+ *
+ * If ki_retry returns -EIOCBRETRY it has made a promise that kick_iocb()
+ * will be called on the kiocb pointer in the future. This may happen
+ * through generic helpers that associate kiocb->ki_wait with a wait
+ * queue head that ki_retry uses via current->io_wait. It can also happen
+ * with custom tracking and manual calls to kick_iocb(), though that is
+ * discouraged. In either case, kick_iocb() must be called once and only
+ * once. ki_retry must ensure forward progress, the AIO core will wait
+ * indefinitely for kick_iocb() to be called.
+ */
struct kiocb {
struct list_head ki_run_list;
long ki_flags;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index a5b74efab067..d2873b732bb1 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -42,13 +42,18 @@ enum {
ATA_SECT_SIZE = 512,
ATA_ID_WORDS = 256,
- ATA_ID_PROD_OFS = 27,
- ATA_ID_FW_REV_OFS = 23,
ATA_ID_SERNO_OFS = 10,
- ATA_ID_MAJOR_VER = 80,
- ATA_ID_PIO_MODES = 64,
+ ATA_ID_FW_REV_OFS = 23,
+ ATA_ID_PROD_OFS = 27,
+ ATA_ID_OLD_PIO_MODES = 51,
+ ATA_ID_FIELD_VALID = 53,
ATA_ID_MWDMA_MODES = 63,
+ ATA_ID_PIO_MODES = 64,
+ ATA_ID_EIDE_DMA_MIN = 65,
+ ATA_ID_EIDE_PIO = 67,
+ ATA_ID_EIDE_PIO_IORDY = 68,
ATA_ID_UDMA_MODES = 88,
+ ATA_ID_MAJOR_VER = 80,
ATA_ID_PIO4 = (1 << 1),
ATA_PCI_CTL_OFS = 2,
@@ -128,10 +133,15 @@ enum {
ATA_CMD_PIO_READ_EXT = 0x24,
ATA_CMD_PIO_WRITE = 0x30,
ATA_CMD_PIO_WRITE_EXT = 0x34,
+ ATA_CMD_READ_MULTI = 0xC4,
+ ATA_CMD_READ_MULTI_EXT = 0x29,
+ ATA_CMD_WRITE_MULTI = 0xC5,
+ ATA_CMD_WRITE_MULTI_EXT = 0x39,
ATA_CMD_SET_FEATURES = 0xEF,
ATA_CMD_PACKET = 0xA0,
ATA_CMD_VERIFY = 0x40,
ATA_CMD_VERIFY_EXT = 0x42,
+ ATA_CMD_INIT_DEV_PARAMS = 0x91,
/* SETFEATURES stuff */
SETFEATURES_XFER = 0x03,
@@ -146,14 +156,14 @@ enum {
XFER_MW_DMA_2 = 0x22,
XFER_MW_DMA_1 = 0x21,
XFER_MW_DMA_0 = 0x20,
+ XFER_SW_DMA_2 = 0x12,
+ XFER_SW_DMA_1 = 0x11,
+ XFER_SW_DMA_0 = 0x10,
XFER_PIO_4 = 0x0C,
XFER_PIO_3 = 0x0B,
XFER_PIO_2 = 0x0A,
XFER_PIO_1 = 0x09,
XFER_PIO_0 = 0x08,
- XFER_SW_DMA_2 = 0x12,
- XFER_SW_DMA_1 = 0x11,
- XFER_SW_DMA_0 = 0x10,
XFER_PIO_SLOW = 0x00,
/* ATAPI stuff */
@@ -181,6 +191,7 @@ enum {
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */
+ ATA_TFLAG_LBA = (1 << 4), /* enable LBA */
};
enum ata_tf_protocols {
@@ -250,7 +261,19 @@ struct ata_taskfile {
((u64) (id)[(n) + 1] << 16) | \
((u64) (id)[(n) + 0]) )
-static inline int atapi_cdb_len(u16 *dev_id)
+static inline int ata_id_current_chs_valid(const u16 *id)
+{
+ /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
+ has not been issued to the device then the values of
+ id[54] to id[56] are vendor specific. */
+ return (id[53] & 0x01) && /* Current translation valid */
+ id[54] && /* cylinders in current translation */
+ id[55] && /* heads in current translation */
+ id[55] <= 16 &&
+ id[56]; /* sectors in current translation */
+}
+
+static inline int atapi_cdb_len(const u16 *dev_id)
{
u16 tmp = dev_id[0] & 0x3;
switch (tmp) {
@@ -260,7 +283,7 @@ static inline int atapi_cdb_len(u16 *dev_id)
}
}
-static inline int is_atapi_taskfile(struct ata_taskfile *tf)
+static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
{
return (tf->protocol == ATA_PROT_ATAPI) ||
(tf->protocol == ATA_PROT_ATAPI_NODATA) ||
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 9f374cfa1b05..e7d0593bb576 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -76,6 +76,13 @@ struct atm_dev_stats {
/* set interface ESI */
#define ATM_SETESIF _IOW('a',ATMIOC_ITF+13,struct atmif_sioc)
/* force interface ESI */
+#define ATM_ADDLECSADDR _IOW('a', ATMIOC_ITF+14, struct atmif_sioc)
+ /* register a LECS address */
+#define ATM_DELLECSADDR _IOW('a', ATMIOC_ITF+15, struct atmif_sioc)
+ /* unregister a LECS address */
+#define ATM_GETLECSADDR _IOW('a', ATMIOC_ITF+16, struct atmif_sioc)
+ /* retrieve LECS address(es) */
+
#define ATM_GETSTAT _IOW('a',ATMIOC_SARCOM+0,struct atmif_sioc)
/* get AAL layer statistics */
#define ATM_GETSTATZ _IOW('a',ATMIOC_SARCOM+1,struct atmif_sioc)
@@ -328,6 +335,8 @@ struct atm_dev_addr {
struct list_head entry; /* next address */
};
+enum atm_addr_type_t { ATM_ADDR_LOCAL, ATM_ADDR_LECS };
+
struct atm_dev {
const struct atmdev_ops *ops; /* device operations; NULL if unused */
const struct atmphy_ops *phy; /* PHY operations, may be undefined */
@@ -338,6 +347,7 @@ struct atm_dev {
void *phy_data; /* private PHY date */
unsigned long flags; /* device flags (ATM_DF_*) */
struct list_head local; /* local ATM addresses */
+ struct list_head lecs; /* LECS ATM addresses learned via ILMI */
unsigned char esi[ESI_LEN]; /* ESI ("MAC" addr) */
struct atm_cirange ci_range; /* VPI/VCI range */
struct k_atm_dev_stats stats; /* statistics */
@@ -457,7 +467,7 @@ static inline void atm_dev_put(struct atm_dev *dev)
int atm_charge(struct atm_vcc *vcc,int truesize);
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
- int gfp_flags);
+ gfp_t gfp_flags);
int atm_pcr_goal(struct atm_trafprm *tp);
void vcc_release_async(struct atm_vcc *vcc, int reply);
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 68aba0c02e49..da3c01955f3d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -51,7 +51,8 @@
#define AUDIT_WATCH_LIST 1009 /* List all file/dir watches */
#define AUDIT_SIGNAL_INFO 1010 /* Get info about sender of signal to auditd */
-#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages uninteresting to kernel */
+#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */
+#define AUDIT_USER_AVC 1107 /* We filter this differently */
#define AUDIT_LAST_USER_MSG 1199
#define AUDIT_DAEMON_START 1200 /* Daemon startup record */
@@ -75,10 +76,15 @@
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
/* Rule flags */
-#define AUDIT_PER_TASK 0x01 /* Apply rule at task creation (not syscall) */
-#define AUDIT_AT_ENTRY 0x02 /* Apply rule at syscall entry */
-#define AUDIT_AT_EXIT 0x04 /* Apply rule at syscall exit */
-#define AUDIT_PREPEND 0x10 /* Prepend to front of list */
+#define AUDIT_FILTER_USER 0x00 /* Apply rule to user-generated messages */
+#define AUDIT_FILTER_TASK 0x01 /* Apply rule at task creation (not syscall) */
+#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */
+#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
+#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
+
+#define AUDIT_NR_FILTERS 5
+
+#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
/* Rule actions */
#define AUDIT_NEVER 0 /* Do not build context if rule matches */
@@ -199,6 +205,7 @@ struct audit_sig_info {
struct audit_buffer;
struct audit_context;
struct inode;
+struct netlink_skb_parms;
#define AUDITSC_INVALID 0
#define AUDITSC_SUCCESS 1
@@ -215,7 +222,7 @@ extern void audit_syscall_entry(struct task_struct *task, int arch,
extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
extern void audit_getname(const char *name);
extern void audit_putname(const char *name);
-extern void audit_inode(const char *name, const struct inode *inode);
+extern void audit_inode(const char *name, const struct inode *inode, unsigned flags);
/* Private API (for audit.c only) */
extern int audit_receive_filter(int type, int pid, int uid, int seq,
@@ -230,6 +237,7 @@ extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
extern void audit_signal_info(int sig, struct task_struct *t);
+extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
@@ -237,7 +245,7 @@ extern void audit_signal_info(int sig, struct task_struct *t);
#define audit_syscall_exit(t,f,r) do { ; } while (0)
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
-#define audit_inode(n,i) do { ; } while (0)
+#define audit_inode(n,i,f) do { ; } while (0)
#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
@@ -246,16 +254,17 @@ extern void audit_signal_info(int sig, struct task_struct *t);
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_avc_path(dentry, mnt) ({ 0; })
#define audit_signal_info(s,t) do { ; } while (0)
+#define audit_filter_user(cb,t) ({ 1; })
#endif
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
-extern void audit_log(struct audit_context *ctx, int type,
- const char *fmt, ...)
- __attribute__((format(printf,3,4)));
+extern void audit_log(struct audit_context *ctx, gfp_t gfp_mask,
+ int type, const char *fmt, ...)
+ __attribute__((format(printf,4,5)));
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
@@ -274,9 +283,10 @@ extern void audit_send_reply(int pid, int seq, int type,
int done, int multi,
void *payload, int size);
extern void audit_log_lost(const char *message);
+extern struct semaphore audit_netlink_sem;
#else
-#define audit_log(c,t,f,...) do { ; } while (0)
-#define audit_log_start(c,t) ({ NULL; })
+#define audit_log(c,g,t,f,...) do { ; } while (0)
+#define audit_log_start(c,g,t) ({ NULL; })
#define audit_log_vformat(b,f,a) do { ; } while (0)
#define audit_log_format(b,f,...) do { ; } while (0)
#define audit_log_end(b) do { ; } while (0)
diff --git a/include/linux/bfs_fs.h b/include/linux/bfs_fs.h
index f7f0913cd110..8ed6dfdcd783 100644
--- a/include/linux/bfs_fs.h
+++ b/include/linux/bfs_fs.h
@@ -14,24 +14,25 @@
#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 {
- __u16 i_ino;
+ __le16 i_ino;
__u16 i_unused;
- __u32 i_sblock;
- __u32 i_eblock;
- __u32 i_eoffset;
- __u32 i_vtype;
- __u32 i_mode;
- __s32 i_uid;
- __s32 i_gid;
- __u32 i_nlink;
- __u32 i_atime;
- __u32 i_mtime;
- __u32 i_ctime;
+ __le32 i_sblock;
+ __le32 i_eblock;
+ __le32 i_eoffset;
+ __le32 i_vtype;
+ __le32 i_mode;
+ __le32 i_uid;
+ __le32 i_gid;
+ __le32 i_nlink;
+ __le32 i_atime;
+ __le32 i_mtime;
+ __le32 i_ctime;
__u32 i_padding[4];
};
@@ -40,17 +41,17 @@ struct bfs_inode {
#define BFS_DIRS_PER_BLOCK 32
struct bfs_dirent {
- __u16 ino;
+ __le16 ino;
char name[BFS_NAMELEN];
};
/* BFS superblock layout on disk */
struct bfs_super_block {
- __u32 s_magic;
- __u32 s_start;
- __u32 s_end;
- __s32 s_from;
- __s32 s_to;
+ __le32 s_magic;
+ __le32 s_start;
+ __le32 s_end;
+ __le32 s_from;
+ __le32 s_to;
__s32 s_bfrom;
__s32 s_bto;
char s_fsname[6];
@@ -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) \
+ ((le32_to_cpu((ip)->i_eoffset) + 1) - le32_to_cpu((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 : (le32_to_cpu((ip)->i_eblock) + 1) - le32_to_cpu((ip)->i_sblock))
#define BFS_UNCLEAN(bfs_sb, sb) \
- ((bfs_sb->s_from != -1) && (bfs_sb->s_to != -1) && !(sb->s_flags & MS_RDONLY))
+ ((le32_to_cpu(bfs_sb->s_from) != -1) && (le32_to_cpu(bfs_sb->s_to) != -1) && !(sb->s_flags & MS_RDONLY))
+
#endif /* _LINUX_BFS_FS_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index cdaf03a14a51..685fd3720df5 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -276,8 +276,8 @@ extern void bio_pair_release(struct bio_pair *dbio);
extern struct bio_set *bioset_create(int, int, int);
extern void bioset_free(struct bio_set *);
-extern struct bio *bio_alloc(unsigned int __nocast, int);
-extern struct bio *bio_alloc_bioset(unsigned int __nocast, int, struct bio_set *);
+extern struct bio *bio_alloc(gfp_t, int);
+extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
extern void bio_put(struct bio *);
extern void bio_free(struct bio *, struct bio_set *);
@@ -287,7 +287,7 @@ extern int bio_phys_segments(struct request_queue *, struct bio *);
extern int bio_hw_segments(struct request_queue *, struct bio *);
extern void __bio_clone(struct bio *, struct bio *);
-extern struct bio *bio_clone(struct bio *, unsigned int __nocast);
+extern struct bio *bio_clone(struct bio *, gfp_t);
extern void bio_init(struct bio *);
@@ -301,7 +301,7 @@ extern struct bio *bio_map_user_iov(struct request_queue *,
struct sg_iovec *, int, int);
extern void bio_unmap_user(struct bio *);
extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
- unsigned int);
+ gfp_t);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
@@ -314,9 +314,8 @@ void zero_fill_bio(struct bio *bio);
* bvec_kmap_irq and bvec_kunmap_irq!!
*
* This function MUST be inlined - it plays with the CPU interrupt flags.
- * Hence the `extern inline'.
*/
-extern inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
+static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
{
unsigned long addr;
@@ -332,7 +331,7 @@ extern inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
return (char *) addr + bvec->bv_offset;
}
-extern inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
+static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
{
unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
@@ -345,7 +344,7 @@ extern inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
#define bvec_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
#endif
-extern inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
+static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
unsigned long *flags)
{
return bvec_kmap_irq(bio_iovec_idx(bio, idx), flags);
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
new file mode 100644
index 000000000000..6b20af0bbb79
--- /dev/null
+++ b/include/linux/bit_spinlock.h
@@ -0,0 +1,77 @@
+#ifndef __LINUX_BIT_SPINLOCK_H
+#define __LINUX_BIT_SPINLOCK_H
+
+/*
+ * bit-based spin_lock()
+ *
+ * Don't use this unless you really need to: spin_lock() and spin_unlock()
+ * are significantly faster.
+ */
+static inline void bit_spin_lock(int bitnum, unsigned long *addr)
+{
+ /*
+ * Assuming the lock is uncontended, this never enters
+ * the body of the outer loop. If it is contended, then
+ * within the inner loop a non-atomic test is used to
+ * busywait with less bus contention for a good time to
+ * attempt to acquire the lock bit.
+ */
+ preempt_disable();
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+ while (test_and_set_bit(bitnum, addr)) {
+ while (test_bit(bitnum, addr)) {
+ preempt_enable();
+ cpu_relax();
+ preempt_disable();
+ }
+ }
+#endif
+ __acquire(bitlock);
+}
+
+/*
+ * Return true if it was acquired
+ */
+static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
+{
+ preempt_disable();
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+ if (test_and_set_bit(bitnum, addr)) {
+ preempt_enable();
+ return 0;
+ }
+#endif
+ __acquire(bitlock);
+ return 1;
+}
+
+/*
+ * bit-based spin_unlock()
+ */
+static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+ BUG_ON(!test_bit(bitnum, addr));
+ smp_mb__before_clear_bit();
+ clear_bit(bitnum, addr);
+#endif
+ preempt_enable();
+ __release(bitlock);
+}
+
+/*
+ * Return true if the lock is held.
+ */
+static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+ return test_bit(bitnum, addr);
+#elif defined CONFIG_PREEMPT
+ return preempt_count();
+#else
+ return 1;
+#endif
+}
+
+#endif /* __LINUX_BIT_SPINLOCK_H */
+
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index aefa26fbae8a..025a7f084dbd 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -96,8 +96,8 @@ struct io_context {
void put_io_context(struct io_context *ioc);
void exit_io_context(void);
-struct io_context *current_io_context(int gfp_flags);
-struct io_context *get_io_context(int gfp_flags);
+struct io_context *current_io_context(gfp_t gfp_flags);
+struct io_context *get_io_context(gfp_t gfp_flags);
void copy_io_context(struct io_context **pdst, struct io_context **psrc);
void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
@@ -107,9 +107,9 @@ typedef void (rq_end_io_fn)(struct request *);
struct request_list {
int count[2];
int starved[2];
+ int elvpriv;
mempool_t *rq_pool;
wait_queue_head_t wait[2];
- wait_queue_head_t drain;
};
#define BLK_MAX_CDB 16
@@ -203,6 +203,7 @@ struct request {
enum rq_flag_bits {
__REQ_RW, /* not set, read. set, write */
__REQ_FAILFAST, /* no low level driver retries */
+ __REQ_SORTED, /* elevator knows about this request */
__REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
__REQ_HARDBARRIER, /* may not be passed by drive either */
__REQ_CMD, /* is a regular fs rw request */
@@ -210,6 +211,7 @@ enum rq_flag_bits {
__REQ_STARTED, /* drive already may have started this one */
__REQ_DONTPREP, /* don't call prep for this one */
__REQ_QUEUED, /* uses queueing */
+ __REQ_ELVPRIV, /* elevator private data attached */
/*
* for ATA/ATAPI devices
*/
@@ -235,6 +237,7 @@ enum rq_flag_bits {
#define REQ_RW (1 << __REQ_RW)
#define REQ_FAILFAST (1 << __REQ_FAILFAST)
+#define REQ_SORTED (1 << __REQ_SORTED)
#define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER)
#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER)
#define REQ_CMD (1 << __REQ_CMD)
@@ -242,6 +245,7 @@ enum rq_flag_bits {
#define REQ_STARTED (1 << __REQ_STARTED)
#define REQ_DONTPREP (1 << __REQ_DONTPREP)
#define REQ_QUEUED (1 << __REQ_QUEUED)
+#define REQ_ELVPRIV (1 << __REQ_ELVPRIV)
#define REQ_PC (1 << __REQ_PC)
#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
#define REQ_SENSE (1 << __REQ_SENSE)
@@ -333,6 +337,12 @@ struct request_queue
end_flush_fn *end_flush_fn;
/*
+ * Dispatch queue sorting
+ */
+ sector_t end_sector;
+ struct request *boundary_rq;
+
+ /*
* Auto-unplugging state
*/
struct timer_list unplug_timer;
@@ -354,7 +364,7 @@ struct request_queue
* queue needs bounce pages for pages above this limit
*/
unsigned long bounce_pfn;
- unsigned int bounce_gfp;
+ gfp_t bounce_gfp;
/*
* various queue flags, see QUEUE_* below
@@ -405,8 +415,6 @@ struct request_queue
unsigned int sg_reserved_size;
int node;
- struct list_head drain_list;
-
/*
* reserved for flush operations
*/
@@ -434,7 +442,7 @@ enum {
#define QUEUE_FLAG_DEAD 5 /* queue being torn down */
#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */
#define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */
-#define QUEUE_FLAG_DRAIN 8 /* draining queue for sched switch */
+#define QUEUE_FLAG_ELVSWITCH 8 /* don't use elevator, just do FIFO */
#define QUEUE_FLAG_FLUSH 9 /* doing barrier flush sequence */
#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
@@ -454,6 +462,7 @@ enum {
#define blk_pm_request(rq) \
((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+#define blk_sorted_rq(rq) ((rq)->flags & REQ_SORTED)
#define blk_barrier_rq(rq) ((rq)->flags & REQ_HARDBARRIER)
#define blk_barrier_preflush(rq) ((rq)->flags & REQ_BAR_PREFLUSH)
#define blk_barrier_postflush(rq) ((rq)->flags & REQ_BAR_POSTFLUSH)
@@ -550,7 +559,7 @@ extern void generic_make_request(struct bio *bio);
extern void blk_put_request(struct request *);
extern void blk_end_sync_rq(struct request *rq);
extern void blk_attempt_remerge(request_queue_t *, struct request *);
-extern struct request *blk_get_request(request_queue_t *, int, int);
+extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
extern void blk_requeue_request(request_queue_t *, struct request *);
extern void blk_plug_device(request_queue_t *);
@@ -565,7 +574,7 @@ extern void blk_run_queue(request_queue_t *);
extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
extern int blk_rq_unmap_user(struct bio *, unsigned int);
-extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, unsigned int);
+extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
extern int blk_execute_rq(request_queue_t *, struct gendisk *,
struct request *, int);
@@ -611,12 +620,21 @@ extern void end_request(struct request *req, int uptodate);
static inline void blkdev_dequeue_request(struct request *req)
{
- BUG_ON(list_empty(&req->queuelist));
+ elv_dequeue_request(req->q, req);
+}
- list_del_init(&req->queuelist);
+/*
+ * This should be in elevator.h, but that requires pulling in rq and q
+ */
+static inline void elv_dispatch_add_tail(struct request_queue *q,
+ struct request *rq)
+{
+ if (q->last_merge == rq)
+ q->last_merge = NULL;
- if (req->rl)
- elv_remove_request(req->q, req);
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = rq;
+ list_add_tail(&rq->queuelist, &q->queue_head);
}
/*
@@ -650,12 +668,10 @@ extern void blk_dump_rq_flags(struct request *, char *);
extern void generic_unplug_device(request_queue_t *);
extern void __generic_unplug_device(request_queue_t *);
extern long nr_blockdev_pages(void);
-extern void blk_wait_queue_drained(request_queue_t *, int);
-extern void blk_finish_queue_drain(request_queue_t *);
int blk_get_queue(request_queue_t *);
-request_queue_t *blk_alloc_queue(int gfp_mask);
-request_queue_t *blk_alloc_queue_node(int,int);
+request_queue_t *blk_alloc_queue(gfp_t);
+request_queue_t *blk_alloc_queue_node(gfp_t, int);
#define blk_put_queue(q) blk_cleanup_queue((q))
/*
@@ -728,7 +744,7 @@ static inline unsigned int blksize_bits(unsigned int size)
return bits;
}
-extern inline unsigned int block_size(struct block_device *bdev)
+static inline unsigned int block_size(struct block_device *bdev)
{
return bdev->bd_block_size;
}
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 82bd8842d11c..3b03b0b868dd 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -43,7 +43,7 @@ typedef struct bootmem_data {
extern unsigned long __init bootmem_bootmap_pages (unsigned long);
extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend);
extern void __init free_bootmem (unsigned long addr, unsigned long size);
-extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal);
+extern void * __init __alloc_bootmem_limit (unsigned long size, unsigned long align, unsigned long goal, unsigned long limit);
#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
#define alloc_bootmem(x) \
@@ -54,6 +54,16 @@ extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_low_pages(x) \
__alloc_bootmem((x), PAGE_SIZE, 0)
+
+#define alloc_bootmem_limit(x, limit) \
+ __alloc_bootmem_limit((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS), (limit))
+#define alloc_bootmem_low_limit(x, limit) \
+ __alloc_bootmem_limit((x), SMP_CACHE_BYTES, 0, (limit))
+#define alloc_bootmem_pages_limit(x, limit) \
+ __alloc_bootmem_limit((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS), (limit))
+#define alloc_bootmem_low_pages_limit(x, limit) \
+ __alloc_bootmem_limit((x), PAGE_SIZE, 0, (limit))
+
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
extern unsigned long __init free_all_bootmem (void);
@@ -61,7 +71,7 @@ extern unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long f
extern void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size);
extern void __init free_bootmem_node (pg_data_t *pgdat, unsigned long addr, unsigned long size);
extern unsigned long __init free_all_bootmem_node (pg_data_t *pgdat);
-extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal);
+extern void * __init __alloc_bootmem_node_limit (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal, unsigned long limit);
#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
#define alloc_bootmem_node(pgdat, x) \
__alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
@@ -69,6 +79,14 @@ extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size,
__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_low_pages_node(pgdat, x) \
__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)
+
+#define alloc_bootmem_node_limit(pgdat, x, limit) \
+ __alloc_bootmem_node_limit((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS), (limit))
+#define alloc_bootmem_pages_node_limit(pgdat, x, limit) \
+ __alloc_bootmem_node_limit((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS), (limit))
+#define alloc_bootmem_low_pages_node_limit(pgdat, x, limit) \
+ __alloc_bootmem_node_limit((pgdat), (x), PAGE_SIZE, 0, (limit))
+
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
#ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
@@ -105,5 +123,15 @@ extern void *__init alloc_large_system_hash(const char *tablename,
#endif
extern int __initdata hashdist; /* Distribute hashes across NUMA nodes? */
+static inline void *__alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
+{
+ return __alloc_bootmem_limit(size, align, goal, 0);
+}
+
+static inline void *__alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align,
+ unsigned long goal)
+{
+ return __alloc_bootmem_node_limit(pgdat, size, align, goal, 0);
+}
#endif /* _LINUX_BOOTMEM_H */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 90828493791f..88af42f5e04a 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -172,7 +172,7 @@ void __brelse(struct buffer_head *);
void __bforget(struct buffer_head *);
void __breadahead(struct block_device *, sector_t block, int size);
struct buffer_head *__bread(struct block_device *, sector_t block, int size);
-struct buffer_head *alloc_buffer_head(unsigned int __nocast gfp_flags);
+struct buffer_head *alloc_buffer_head(gfp_t gfp_flags);
void free_buffer_head(struct buffer_head * bh);
void FASTCALL(unlock_buffer(struct buffer_head *bh));
void FASTCALL(__lock_buffer(struct buffer_head *bh));
@@ -188,7 +188,7 @@ extern int buffer_heads_over_limit;
* Generic address_space_operations implementations for buffer_head-backed
* address_spaces.
*/
-int try_to_release_page(struct page * page, int gfp_mask);
+int try_to_release_page(struct page * page, gfp_t gfp_mask);
int block_invalidatepage(struct page *page, unsigned long offset);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index 5fde6f4d6c1e..04bd756efc67 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -5,6 +5,10 @@
* linux/byteorder_generic.h
* Generic Byte-reordering support
*
+ * The "... p" macros, like le64_to_cpup, can be used with pointers
+ * to unaligned data, but there will be a performance penalty on
+ * some architectures. Use get_unaligned for unaligned data.
+ *
* Francois-Rene Rideau <fare@tunes.org> 19970707
* gathered all the good ideas from all asm-foo/byteorder.h into one file,
* cleaned them up.
diff --git a/include/linux/chio.h b/include/linux/chio.h
index 63035ae67e63..a404c111c937 100644
--- a/include/linux/chio.h
+++ b/include/linux/chio.h
@@ -96,7 +96,7 @@ struct changer_position {
*/
struct changer_element_status {
int ces_type;
- unsigned char *ces_data;
+ unsigned char __user *ces_data;
};
#define CESTATUS_FULL 0x01 /* full */
#define CESTATUS_IMPEXP 0x02 /* media was imported (inserted by sysop) */
diff --git a/include/linux/connector.h b/include/linux/connector.h
new file mode 100644
index 000000000000..95952cc1f525
--- /dev/null
+++ b/include/linux/connector.h
@@ -0,0 +1,167 @@
+/*
+ * connector.h
+ *
+ * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ * 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. 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 __CONNECTOR_H
+#define __CONNECTOR_H
+
+#include <asm/types.h>
+
+#define CN_IDX_CONNECTOR 0xffffffff
+#define CN_VAL_CONNECTOR 0xffffffff
+
+#define CN_NETLINK_USERS 1
+
+/*
+ * Maximum connector's message size.
+ */
+#define CONNECTOR_MAX_MSG_SIZE 1024
+
+/*
+ * idx and val are unique identifiers which
+ * are used for message routing and
+ * must be registered in connector.h for in-kernel usage.
+ */
+
+struct cb_id {
+ __u32 idx;
+ __u32 val;
+};
+
+struct cn_msg {
+ struct cb_id id;
+
+ __u32 seq;
+ __u32 ack;
+
+ __u16 len; /* Length of the following data */
+ __u16 flags;
+ __u8 data[0];
+};
+
+/*
+ * Notify structure - requests notification about
+ * registering/unregistering idx/val in range [first, first+range].
+ */
+struct cn_notify_req {
+ __u32 first;
+ __u32 range;
+};
+
+/*
+ * Main notification control message
+ * *_notify_num - number of appropriate cn_notify_req structures after
+ * this struct.
+ * group - notification receiver's idx.
+ * len - total length of the attached data.
+ */
+struct cn_ctl_msg {
+ __u32 idx_notify_num;
+ __u32 val_notify_num;
+ __u32 group;
+ __u32 len;
+ __u8 data[0];
+};
+
+#ifdef __KERNEL__
+
+#include <asm/atomic.h>
+
+#include <linux/list.h>
+#include <linux/workqueue.h>
+
+#include <net/sock.h>
+
+#define CN_CBQ_NAMELEN 32
+
+struct cn_queue_dev {
+ atomic_t refcnt;
+ unsigned char name[CN_CBQ_NAMELEN];
+
+ struct workqueue_struct *cn_queue;
+
+ struct list_head queue_list;
+ spinlock_t queue_lock;
+
+ int netlink_groups;
+ struct sock *nls;
+};
+
+struct cn_callback_id {
+ unsigned char name[CN_CBQ_NAMELEN];
+ struct cb_id id;
+};
+
+struct cn_callback_data {
+ void (*destruct_data) (void *);
+ void *ddata;
+
+ void *callback_priv;
+ void (*callback) (void *);
+
+ void *free;
+};
+
+struct cn_callback_entry {
+ struct list_head callback_entry;
+ struct cn_callback *cb;
+ struct work_struct work;
+ struct cn_queue_dev *pdev;
+
+ struct cn_callback_id id;
+ struct cn_callback_data data;
+
+ int seq, group;
+ struct sock *nls;
+};
+
+struct cn_ctl_entry {
+ struct list_head notify_entry;
+ struct cn_ctl_msg *msg;
+};
+
+struct cn_dev {
+ struct cb_id id;
+
+ u32 seq, groups;
+ struct sock *nls;
+ void (*input) (struct sock * sk, int len);
+
+ struct cn_queue_dev *cbdev;
+};
+
+int cn_add_callback(struct cb_id *, char *, void (*callback) (void *));
+void cn_del_callback(struct cb_id *);
+int cn_netlink_send(struct cn_msg *, u32, gfp_t);
+
+int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *));
+void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
+
+struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *);
+void cn_queue_free_dev(struct cn_queue_dev *dev);
+
+int cn_cb_equal(struct cb_id *, struct cb_id *);
+
+void cn_queue_wrapper(void *data);
+
+extern int cn_already_initialized;
+
+#endif /* __KERNEL__ */
+#endif /* __CONNECTOR_H */
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index b15826f6e3a2..9bdba8169b41 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -392,4 +392,14 @@ extern cpumask_t cpu_present_map;
#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
+/* Find the highest possible smp_processor_id() */
+#define highest_possible_processor_id() \
+({ \
+ unsigned int cpu, highest = 0; \
+ for_each_cpu_mask(cpu, cpu_possible_map) \
+ highest = cpu; \
+ highest; \
+})
+
+
#endif /* __LINUX_CPUMASK_H */
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 24062a1dbf61..6e2deef96b34 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -23,7 +23,7 @@ void cpuset_init_current_mems_allowed(void);
void cpuset_update_current_mems_allowed(void);
void cpuset_restrict_to_mems_allowed(unsigned long *nodes);
int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl);
-extern int cpuset_zone_allowed(struct zone *z, unsigned int __nocast gfp_mask);
+extern int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask);
extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
extern struct file_operations proc_cpuset_operations;
extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer);
@@ -49,8 +49,7 @@ static inline int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
return 1;
}
-static inline int cpuset_zone_allowed(struct zone *z,
- unsigned int __nocast gfp_mask)
+static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
{
return 1;
}
diff --git a/include/linux/crc16.h b/include/linux/crc16.h
new file mode 100644
index 000000000000..9443c084f881
--- /dev/null
+++ b/include/linux/crc16.h
@@ -0,0 +1,30 @@
+/*
+ * crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16:
+ * Width 16
+ * Poly 0x8005 (x^16 + x^15 + x^2 + 1)
+ * Init 0
+ *
+ * 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>
+
+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/cyclomx.h b/include/linux/cyclomx.h
index 04fa7dff079c..300d704bdb9a 100644
--- a/include/linux/cyclomx.h
+++ b/include/linux/cyclomx.h
@@ -37,8 +37,6 @@
#include <linux/cycx_x25.h>
#endif
-#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-
/* Adapter Data Space.
* This structure is needed because we handle multiple cards, otherwise
* static data would do it.
diff --git a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h
index 6621df86a748..12fe6b0bfcff 100644
--- a/include/linux/cycx_drv.h
+++ b/include/linux/cycx_drv.h
@@ -60,6 +60,5 @@ extern int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
extern int cycx_exec(void __iomem *addr);
-extern void cycx_inten(struct cycx_hw *hw);
extern void cycx_intr(struct cycx_hw *hw);
#endif /* _CYCX_DRV_H */
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 007c290f74d4..71fab4311e92 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -4,16 +4,6 @@
#include <linux/types.h>
#include <asm/byteorder.h>
-/* Structure describing an Internet (DCCP) socket address. */
-struct sockaddr_dccp {
- __u16 sdccp_family; /* Address family */
- __u16 sdccp_port; /* Port number */
- __u32 sdccp_addr; /* Internet address */
- __u32 sdccp_service; /* Service */
- /* Pad to size of `struct sockaddr': 16 bytes . */
- __u32 sdccp_pad;
-};
-
/**
* struct dccp_hdr - generic part of DCCP packet header
*
@@ -188,6 +178,11 @@ enum {
/* DCCP socket options */
#define DCCP_SOCKOPT_PACKET_SIZE 1
+#define DCCP_SOCKOPT_SERVICE 2
+#define DCCP_SOCKOPT_CCID_RX_INFO 128
+#define DCCP_SOCKOPT_CCID_TX_INFO 192
+
+#define DCCP_SERVICE_LIST_MAX_LEN 32
#ifdef __KERNEL__
@@ -337,7 +332,8 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
*/
struct dccp_options {
__u64 dccpo_sequence_window;
- __u8 dccpo_ccid;
+ __u8 dccpo_rx_ccid;
+ __u8 dccpo_tx_ccid;
__u8 dccpo_send_ack_vector;
__u8 dccpo_send_ndp_count;
};
@@ -360,14 +356,8 @@ static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
extern struct inet_timewait_death_row dccp_death_row;
-/* Read about the ECN nonce to see why it is 253 */
-#define DCCP_MAX_ACK_VECTOR_LEN 253
-
struct dccp_options_received {
- u32 dccpor_ndp:24,
- dccpor_ack_vector_len:8;
- u32 dccpor_ack_vector_idx:10;
- /* 22 bits hole, try to pack */
+ u32 dccpor_ndp; /* only 24 bits */
u32 dccpor_timestamp;
u32 dccpor_timestamp_echo;
u32 dccpor_elapsed_time;
@@ -382,6 +372,27 @@ enum dccp_role {
DCCP_ROLE_SERVER,
};
+struct dccp_service_list {
+ __u32 dccpsl_nr;
+ __u32 dccpsl_list[0];
+};
+
+#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
+
+static inline int dccp_list_has_service(const struct dccp_service_list *sl,
+ const u32 service)
+{
+ if (likely(sl != NULL)) {
+ u32 i = sl->dccpsl_nr;
+ while (i--)
+ if (sl->dccpsl_list[i] == service)
+ return 1;
+ }
+ return 0;
+}
+
+struct dccp_ackvec;
+
/**
* struct dccp_sock - DCCP socket state
*
@@ -402,7 +413,7 @@ enum dccp_role {
* @dccps_packet_size - Set thru setsockopt
* @dccps_role - Role of this sock, one of %dccp_role
* @dccps_ndp_count - number of Non Data Packets since last data packet
- * @dccps_hc_rx_ackpkts - receiver half connection acked packets
+ * @dccps_hc_rx_ackvec - rx half connection ack vector
*/
struct dccp_sock {
/* inet_connection_sock has to be the first member of dccp_sock */
@@ -417,7 +428,8 @@ struct dccp_sock {
__u64 dccps_gss;
__u64 dccps_gsr;
__u64 dccps_gar;
- unsigned long dccps_service;
+ __u32 dccps_service;
+ struct dccp_service_list *dccps_service_list;
struct timeval dccps_timestamp_time;
__u32 dccps_timestamp_echo;
__u32 dccps_packet_size;
@@ -426,13 +438,16 @@ struct dccp_sock {
__u32 dccps_pmtu_cookie;
__u32 dccps_mss_cache;
struct dccp_options dccps_options;
- struct dccp_ackpkts *dccps_hc_rx_ackpkts;
+ struct dccp_ackvec *dccps_hc_rx_ackvec;
void *dccps_hc_rx_ccid_private;
void *dccps_hc_tx_ccid_private;
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)
@@ -440,6 +455,11 @@ static inline struct dccp_sock *dccp_sk(const struct sock *sk)
return (struct dccp_sock *)sk;
}
+static inline int dccp_service_not_initialized(const struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_service == DCCP_SERVICE_INVALID_VALUE;
+}
+
static inline const char *dccp_role(const struct sock *sk)
{
switch (dccp_sk(sk)->dccps_role) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 06e5d42f2c7b..95d607a48f06 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -317,6 +317,11 @@ dev_set_drvdata (struct device *dev, void *data)
dev->driver_data = data;
}
+static inline int device_is_registered(struct device *dev)
+{
+ return klist_node_attached(&dev->knode_bus);
+}
+
/*
* High level routines for use by the bus drivers
*/
diff --git a/include/linux/dmapool.h b/include/linux/dmapool.h
index e60bfdac348d..76f12f46db7f 100644
--- a/include/linux/dmapool.h
+++ b/include/linux/dmapool.h
@@ -19,7 +19,8 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev,
void dma_pool_destroy(struct dma_pool *pool);
-void *dma_pool_alloc(struct dma_pool *pool, int mem_flags, dma_addr_t *handle);
+void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
+ dma_addr_t *handle);
void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr);
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index c30175e8dec6..a415f1d93e9a 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -70,7 +70,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name,
static inline int dmi_check_system(struct dmi_system_id *list) { return 0; }
static inline char * dmi_get_system_info(int field) { return NULL; }
-static struct dmi_device * dmi_find_device(int type, const char *name,
+static inline struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from) { return NULL; }
#endif
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index ea6bbc2d7407..a74c27e460ba 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -8,18 +8,17 @@ typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struc
typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
-typedef struct request *(elevator_next_req_fn) (request_queue_t *);
+typedef int (elevator_dispatch_fn) (request_queue_t *, int);
-typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, int);
+typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_queue_empty_fn) (request_queue_t *);
-typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
-typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_may_queue_fn) (request_queue_t *, int, struct bio *);
-typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, int);
+typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, gfp_t);
typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
+typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_init_fn) (request_queue_t *, elevator_t *);
@@ -31,10 +30,9 @@ struct elevator_ops
elevator_merged_fn *elevator_merged_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
- elevator_next_req_fn *elevator_next_req_fn;
+ elevator_dispatch_fn *elevator_dispatch_fn;
elevator_add_req_fn *elevator_add_req_fn;
- elevator_remove_req_fn *elevator_remove_req_fn;
- elevator_requeue_req_fn *elevator_requeue_req_fn;
+ elevator_activate_req_fn *elevator_activate_req_fn;
elevator_deactivate_req_fn *elevator_deactivate_req_fn;
elevator_queue_empty_fn *elevator_queue_empty_fn;
@@ -81,15 +79,15 @@ struct elevator_queue
/*
* block elevator interface
*/
+extern void elv_dispatch_sort(request_queue_t *, struct request *);
extern void elv_add_request(request_queue_t *, struct request *, int, int);
extern void __elv_add_request(request_queue_t *, struct request *, int, int);
extern int elv_merge(request_queue_t *, struct request **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
extern void elv_merged_request(request_queue_t *, struct request *);
-extern void elv_remove_request(request_queue_t *, struct request *);
+extern void elv_dequeue_request(request_queue_t *, struct request *);
extern void elv_requeue_request(request_queue_t *, struct request *);
-extern void elv_deactivate_request(request_queue_t *, struct request *);
extern int elv_queue_empty(request_queue_t *);
extern struct request *elv_next_request(struct request_queue *q);
extern struct request *elv_former_request(request_queue_t *, struct request *);
@@ -98,7 +96,7 @@ extern int elv_register_queue(request_queue_t *q);
extern void elv_unregister_queue(request_queue_t *q);
extern int elv_may_queue(request_queue_t *, int, struct bio *);
extern void elv_completed_request(request_queue_t *, struct request *);
-extern int elv_set_request(request_queue_t *, struct request *, struct bio *, int);
+extern int elv_set_request(request_queue_t *, struct request *, struct bio *, gfp_t);
extern void elv_put_request(request_queue_t *, struct request *);
/*
@@ -142,4 +140,6 @@ enum {
ELV_MQUEUE_MUST,
};
+#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
+
#endif
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24beeed971..c698055266d0 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;
@@ -614,7 +619,7 @@ struct fb_tilemap {
__u32 height; /* height of each tile in scanlines */
__u32 depth; /* color depth of each tile */
__u32 length; /* number of tiles in the map */
- __u8 *data; /* actual tile map: a bitmap array, packed
+ const __u8 *data; /* actual tile map: a bitmap array, packed
to the nearest byte */
};
@@ -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 5206beb9a80e..f5bbd4c508b3 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/font.h b/include/linux/font.h
index 8fc80a7d78ac..53b129f07f6f 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -15,9 +15,9 @@
struct font_desc {
int idx;
- char *name;
+ const char *name;
int width, height;
- void *data;
+ const void *data;
int pref;
};
@@ -32,7 +32,7 @@ struct font_desc {
#define ACORN8x8_IDX 8
#define MINI4x6_IDX 9
-extern struct font_desc font_vga_8x8,
+extern const struct font_desc font_vga_8x8,
font_vga_8x16,
font_pearl_8x8,
font_vga_6x11,
@@ -45,11 +45,11 @@ extern struct font_desc font_vga_8x8,
/* Find a font with a specific name */
-extern struct font_desc *find_font(char *name);
+extern const struct font_desc *find_font(const char *name);
/* Get the default font for a specific screen size */
-extern struct font_desc *get_default_font(int xres, int yres);
+extern const struct font_desc *get_default_font(int xres, int yres);
/* Max. length for the name of a predefined font */
#define MAX_FONT_NAME 32
diff --git a/include/linux/fs.h b/include/linux/fs.h
index fd93ab7da905..f83d997c5582 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
@@ -319,7 +320,7 @@ struct address_space_operations {
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
- int (*releasepage) (struct page *, int);
+ int (*releasepage) (struct page *, gfp_t);
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,
@@ -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)
@@ -1507,8 +1509,6 @@ extern void do_generic_mapping_read(struct address_space *mapping,
loff_t *, read_descriptor_t *, read_actor_t);
extern void
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
-extern ssize_t generic_file_direct_IO(int rw, struct kiocb *iocb,
- const struct iovec *iov, loff_t offset, unsigned long nr_segs);
extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos);
ssize_t generic_file_writev(struct file *filp, const struct iovec *iov,
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
new file mode 100644
index 000000000000..acbeb96a3353
--- /dev/null
+++ b/include/linux/fuse.h
@@ -0,0 +1,259 @@
+/*
+ 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/genhd.h b/include/linux/genhd.h
index 01796c41c951..142e1c1e0689 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -119,7 +119,7 @@ struct gendisk {
int policy;
atomic_t sync_io; /* RAID */
- unsigned long stamp, stamp_idle;
+ unsigned long stamp;
int in_flight;
#ifdef CONFIG_SMP
struct disk_stats *dkstats;
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 4dc990f3b5cc..c3779432a723 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -12,8 +12,8 @@ struct vm_area_struct;
* GFP bitmasks..
*/
/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
-#define __GFP_DMA 0x01u
-#define __GFP_HIGHMEM 0x02u
+#define __GFP_DMA ((__force gfp_t)0x01u)
+#define __GFP_HIGHMEM ((__force gfp_t)0x02u)
/*
* Action modifiers - doesn't change the zoning
@@ -26,24 +26,24 @@ struct vm_area_struct;
*
* __GFP_NORETRY: The VM implementation must not retry indefinitely.
*/
-#define __GFP_WAIT 0x10u /* Can wait and reschedule? */
-#define __GFP_HIGH 0x20u /* Should access emergency pools? */
-#define __GFP_IO 0x40u /* Can start physical IO? */
-#define __GFP_FS 0x80u /* Can call down to low-level FS? */
-#define __GFP_COLD 0x100u /* Cache-cold page required */
-#define __GFP_NOWARN 0x200u /* Suppress page allocation failure warning */
-#define __GFP_REPEAT 0x400u /* Retry the allocation. Might fail */
-#define __GFP_NOFAIL 0x800u /* Retry for ever. Cannot fail */
-#define __GFP_NORETRY 0x1000u /* Do not retry. Might fail */
-#define __GFP_NO_GROW 0x2000u /* Slab internal usage */
-#define __GFP_COMP 0x4000u /* Add compound page metadata */
-#define __GFP_ZERO 0x8000u /* Return zeroed page on success */
-#define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
-#define __GFP_NORECLAIM 0x20000u /* No realy zone reclaim during allocation */
-#define __GFP_HARDWALL 0x40000u /* Enforce hardwall cpuset memory allocs */
+#define __GFP_WAIT ((__force gfp_t)0x10u) /* Can wait and reschedule? */
+#define __GFP_HIGH ((__force gfp_t)0x20u) /* Should access emergency pools? */
+#define __GFP_IO ((__force gfp_t)0x40u) /* Can start physical IO? */
+#define __GFP_FS ((__force gfp_t)0x80u) /* Can call down to low-level FS? */
+#define __GFP_COLD ((__force gfp_t)0x100u) /* Cache-cold page required */
+#define __GFP_NOWARN ((__force gfp_t)0x200u) /* Suppress page allocation failure warning */
+#define __GFP_REPEAT ((__force gfp_t)0x400u) /* Retry the allocation. Might fail */
+#define __GFP_NOFAIL ((__force gfp_t)0x800u) /* Retry for ever. Cannot fail */
+#define __GFP_NORETRY ((__force gfp_t)0x1000u)/* Do not retry. Might fail */
+#define __GFP_NO_GROW ((__force gfp_t)0x2000u)/* Slab internal usage */
+#define __GFP_COMP ((__force gfp_t)0x4000u)/* Add compound page metadata */
+#define __GFP_ZERO ((__force gfp_t)0x8000u)/* Return zeroed page on success */
+#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
+#define __GFP_NORECLAIM ((__force gfp_t)0x20000u) /* No realy zone reclaim during allocation */
+#define __GFP_HARDWALL ((__force gfp_t)0x40000u) /* Enforce hardwall cpuset memory allocs */
#define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */
-#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
+#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
/* if you forget to add the bitmask here kernel will crash, period */
#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
@@ -64,6 +64,7 @@ struct vm_area_struct;
#define GFP_DMA __GFP_DMA
+#define gfp_zone(mask) ((__force int)((mask) & (__force gfp_t)GFP_ZONEMASK))
/*
* There is only one page-allocator function, and two main namespaces to
@@ -85,30 +86,30 @@ static inline void arch_free_page(struct page *page, int order) { }
#endif
extern struct page *
-FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
+FASTCALL(__alloc_pages(gfp_t, unsigned int, struct zonelist *));
-static inline struct page *alloc_pages_node(int nid, unsigned int __nocast gfp_mask,
+static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
unsigned int order)
{
if (unlikely(order >= MAX_ORDER))
return NULL;
return __alloc_pages(gfp_mask, order,
- NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
+ NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask));
}
#ifdef CONFIG_NUMA
-extern struct page *alloc_pages_current(unsigned int __nocast gfp_mask, unsigned order);
+extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order);
static inline struct page *
-alloc_pages(unsigned int __nocast gfp_mask, unsigned int order)
+alloc_pages(gfp_t gfp_mask, unsigned int order)
{
if (unlikely(order >= MAX_ORDER))
return NULL;
return alloc_pages_current(gfp_mask, order);
}
-extern struct page *alloc_page_vma(unsigned __nocast gfp_mask,
+extern struct page *alloc_page_vma(gfp_t gfp_mask,
struct vm_area_struct *vma, unsigned long addr);
#else
#define alloc_pages(gfp_mask, order) \
@@ -117,8 +118,8 @@ extern struct page *alloc_page_vma(unsigned __nocast gfp_mask,
#endif
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
-extern unsigned long FASTCALL(__get_free_pages(unsigned int __nocast gfp_mask, unsigned int order));
-extern unsigned long FASTCALL(get_zeroed_page(unsigned int __nocast gfp_mask));
+extern unsigned long FASTCALL(__get_free_pages(gfp_t gfp_mask, unsigned int order));
+extern unsigned long FASTCALL(get_zeroed_page(gfp_t gfp_mask));
#define __get_free_page(gfp_mask) \
__get_free_pages((gfp_mask),0)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index e670b0d13fe0..d664330d900e 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -25,6 +25,8 @@ int is_hugepage_mem_enough(size_t);
unsigned long hugetlb_total_pages(void);
struct page *alloc_huge_page(void);
void free_huge_page(struct page *);
+int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, int write_access);
extern unsigned long max_huge_pages;
extern const unsigned long hugetlb_zero, hugetlb_infinity;
@@ -99,6 +101,7 @@ static inline unsigned long hugetlb_total_pages(void)
do { } while (0)
#define alloc_huge_page() ({ NULL; })
#define free_huge_page(p) ({ (void)(p); BUG(); })
+#define hugetlb_fault(mm, vma, addr, write) ({ BUG(); 0; })
#ifndef HPAGE_MASK
#define HPAGE_MASK 0 /* Keep the compiler happy */
diff --git a/include/linux/i2c-pxa.h b/include/linux/i2c-pxa.h
new file mode 100644
index 000000000000..5f3eaf802223
--- /dev/null
+++ b/include/linux/i2c-pxa.h
@@ -0,0 +1,48 @@
+#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/i2c.h b/include/linux/i2c.h
index be35332b67e6..3d49a305bf88 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -230,11 +230,6 @@ struct i2c_adapter {
struct device dev; /* the adapter device */
struct class_device class_dev; /* the class device */
-#ifdef CONFIG_PROC_FS
- /* No need to set this when you initialize the adapter */
- int inode;
-#endif /* def CONFIG_PROC_FS */
-
int nr;
struct list_head clients;
struct list_head list;
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index bdc286ec947c..b4af45aad25d 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -492,7 +492,7 @@ static inline int i2o_dma_map_sg(struct i2o_controller *c,
* Returns 0 on success or -ENOMEM on failure.
*/
static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
- size_t len, unsigned int gfp_mask)
+ size_t len, gfp_t gfp_mask)
{
struct pci_dev *pdev = to_pci_dev(dev);
int dma_64 = 0;
@@ -551,7 +551,7 @@ static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
* Returns the 0 on success or negative error code on failure.
*/
static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
- size_t len, unsigned int gfp_mask)
+ size_t len, gfp_t gfp_mask)
{
i2o_dma_free(dev, addr);
diff --git a/include/linux/ibmtr.h b/include/linux/ibmtr.h
index 2ef0b21517fb..1c7a0dd5536a 100644
--- a/include/linux/ibmtr.h
+++ b/include/linux/ibmtr.h
@@ -7,8 +7,8 @@
/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
#define TR_RETRY_INTERVAL (30*HZ) /* 500 on PC = 5 s */
-#define TR_RST_TIME (HZ/20) /* 5 on PC = 50 ms */
-#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */
+#define TR_RST_TIME (msecs_to_jiffies(50)) /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL (msecs_to_jiffies(200)) /* 5 on PC = 200 ms */
#define TR_SPIN_INTERVAL (3*HZ) /* 3 seconds before init timeout */
#define TR_ISA 1
diff --git a/include/linux/idr.h b/include/linux/idr.h
index ca3b7e462576..7fb3ff9c7b0e 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -71,8 +71,9 @@ struct idr {
*/
void *idr_find(struct idr *idp, int id);
-int idr_pre_get(struct idr *idp, unsigned gfp_mask);
+int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
int idr_get_new(struct idr *idp, void *ptr, int *id);
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
void idr_remove(struct idr *idp, int id);
+void idr_destroy(struct idr *idp);
void idr_init(struct idr *idp);
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index 0856548a2a08..a8b1a2071838 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -84,6 +84,7 @@
#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */
#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
+#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
#define ARPHRD_NONE 0xFFFE /* zero header length */
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index fc2d4c8225aa..d21c305c6c64 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -111,7 +111,9 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
return (struct ethhdr *)skb->mac.raw;
}
+#ifdef CONFIG_SYSCTL
extern struct ctl_table ether_table[];
#endif
+#endif
#endif /* _LINUX_IF_ETHER_H */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 17d0c0d40b0e..eef0876d8307 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -42,8 +42,8 @@ struct hlist_node;
struct vlan_ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_vlan_proto; /* Should always be 0x8100 */
- unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID */
+ __be16 h_vlan_proto; /* Should always be 0x8100 */
+ __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */
unsigned short h_vlan_encapsulated_proto; /* packet type ID field (or len) */
};
@@ -55,8 +55,8 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
}
struct vlan_hdr {
- unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID */
- unsigned short h_vlan_encapsulated_proto; /* packet type ID field (or len) */
+ __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */
+ __be16 h_vlan_encapsulated_proto; /* packet type ID field (or len) */
};
#define VLAN_VID_MASK 0xfff
diff --git a/include/linux/in6.h b/include/linux/in6.h
index dcf5720ffcbb..304aaedea305 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,44 @@ struct in6_flowlabel_req
* MCAST_MSFILTER 48
*/
+/*
+ * Advanced API (RFC3542) (1)
+ *
+ * Note: IPV6_RECVRTHDRDSTOPTS does not exist. see net/ipv6/datagram.c.
+ */
+
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+#if 0 /* not yet */
+#define IPV6_RECVPATHMTU 60
+#define IPV6_PATHMTU 61
+#define IPV6_DONTFRAG 62
+#define IPV6_USE_MIN_MTU 63
+#endif
+
+/*
+ * Netfilter
+ *
+ * Following socket options are used in ip6_tables;
+ * see include/linux/netfilter_ipv6/ip6_tables.h.
+ *
+ * IP6T_SO_SET_REPLACE / IP6T_SO_GET_INFO 64
+ * IP6T_SO_SET_ADD_COUNTERS / IP6T_SO_GET_ENTRIES 65
+ */
+
+/*
+ * Advanced API (RFC3542) (2)
+ */
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+
#endif
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 7e1e15f934f3..fd7af86151b1 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -142,13 +142,21 @@ static __inline__ int bad_mask(u32 mask, u32 addr)
#define endfor_ifa(in_dev) }
+static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev)
+{
+ struct in_device *in_dev = dev->ip_ptr;
+ if (in_dev)
+ in_dev = rcu_dereference(in_dev);
+ return in_dev;
+}
+
static __inline__ struct in_device *
in_dev_get(const struct net_device *dev)
{
struct in_device *in_dev;
rcu_read_lock();
- in_dev = dev->ip_ptr;
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev)
atomic_inc(&in_dev->refcnt);
rcu_read_unlock();
@@ -156,7 +164,7 @@ in_dev_get(const struct net_device *dev)
}
static __inline__ struct in_device *
-__in_dev_get(const struct net_device *dev)
+__in_dev_get_rtnl(const struct net_device *dev)
{
return (struct in_device*)dev->ip_ptr;
}
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index c727c195a91a..68ab5f2ab9cd 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -2,17 +2,27 @@
#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/input.h b/include/linux/input.h
index 4767e5429534..e8c296ff6257 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -289,6 +289,8 @@ struct input_absinfo {
#define KEY_SCROLLDOWN 178
#define KEY_KPLEFTPAREN 179
#define KEY_KPRIGHTPAREN 180
+#define KEY_NEW 181
+#define KEY_REDO 182
#define KEY_F13 183
#define KEY_F14 184
@@ -335,6 +337,12 @@ struct input_absinfo {
#define KEY_KBDILLUMDOWN 229
#define KEY_KBDILLUMUP 230
+#define KEY_SEND 231
+#define KEY_REPLY 232
+#define KEY_FORWARDMAIL 233
+#define KEY_SAVE 234
+#define KEY_DOCUMENTS 235
+
#define KEY_UNKNOWN 240
#define BTN_MISC 0x100
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index d99e7aeb7d33..0a90205184b0 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -57,6 +57,11 @@ extern void disable_irq(unsigned int irq);
extern void enable_irq(unsigned int irq);
#endif
+#ifndef __ARCH_SET_SOFTIRQ_PENDING
+#define set_softirq_pending(x) (local_softirq_pending() = (x))
+#define or_softirq_pending(x) (local_softirq_pending() |= (x))
+#endif
+
/*
* Temporary defines for UP kernels, until all code gets fixed.
*/
@@ -123,7 +128,7 @@ struct softirq_action
asmlinkage void do_softirq(void);
extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
extern void softirq_init(void);
-#define __raise_softirq_irqoff(nr) do { local_softirq_pending() |= 1UL << (nr); } while (0)
+#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
extern void FASTCALL(raise_softirq_irqoff(unsigned int nr));
extern void FASTCALL(raise_softirq(unsigned int nr));
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 3c7dbc6a0a70..e0b922785d98 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -68,7 +68,7 @@ struct ipv6_opt_hdr {
struct rt0_hdr {
struct ipv6_rt_hdr rt_hdr;
- __u32 bitmap; /* strict/loose bit map */
+ __u32 reserved;
struct in6_addr addr[0];
#define rt0_type rt_hdr.type
@@ -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;
};
@@ -363,8 +372,9 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
#define inet_v6_ipv6only(__sk) 0
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-#define INET6_MATCH(__sk, __saddr, __daddr, __ports, __dif) \
- (((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
+#define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && \
+ ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
((__sk)->sk_family == AF_INET6) && \
ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \
ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 84321a4cac93..be197eb90077 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -28,6 +28,7 @@
#include <linux/buffer_head.h>
#include <linux/journal-head.h>
#include <linux/stddef.h>
+#include <linux/bit_spinlock.h>
#include <asm/semaphore.h>
#endif
@@ -68,7 +69,7 @@ extern int journal_enable_debug;
#define jbd_debug(f, a...) /**/
#endif
-extern void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry);
+extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
#define jbd_kmalloc(size, flags) \
__jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
#define jbd_rep_kmalloc(size, flags) \
@@ -889,7 +890,7 @@ extern int journal_forget (handle_t *, struct buffer_head *);
extern void journal_sync_buffer (struct buffer_head *);
extern int journal_invalidatepage(journal_t *,
struct page *, unsigned long);
-extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
+extern int journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
extern int journal_stop(handle_t *);
extern int journal_flush (journal_t *);
extern void journal_lock_updates (journal_t *);
@@ -934,7 +935,7 @@ void journal_put_journal_head(struct journal_head *jh);
*/
extern kmem_cache_t *jbd_handle_cache;
-static inline handle_t *jbd_alloc_handle(unsigned int __nocast gfp_flags)
+static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags)
{
return kmem_cache_alloc(jbd_handle_cache, gfp_flags);
}
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index d7a2555a886c..6acfdbba734b 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -254,23 +254,23 @@ static inline u64 get_jiffies_64(void)
*/
static inline unsigned int jiffies_to_msecs(const unsigned long j)
{
-#if HZ <= 1000 && !(1000 % HZ)
- return (1000 / HZ) * j;
-#elif HZ > 1000 && !(HZ % 1000)
- return (j + (HZ / 1000) - 1)/(HZ / 1000);
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+ return (MSEC_PER_SEC / HZ) * j;
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+ return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
#else
- return (j * 1000) / HZ;
+ return (j * MSEC_PER_SEC) / HZ;
#endif
}
static inline unsigned int jiffies_to_usecs(const unsigned long j)
{
-#if HZ <= 1000000 && !(1000000 % HZ)
- return (1000000 / HZ) * j;
-#elif HZ > 1000000 && !(HZ % 1000000)
- return (j + (HZ / 1000000) - 1)/(HZ / 1000000);
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ return (USEC_PER_SEC / HZ) * j;
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+ return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
#else
- return (j * 1000000) / HZ;
+ return (j * USEC_PER_SEC) / HZ;
#endif
}
@@ -278,12 +278,12 @@ static inline unsigned long msecs_to_jiffies(const unsigned int m)
{
if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
return MAX_JIFFY_OFFSET;
-#if HZ <= 1000 && !(1000 % HZ)
- return (m + (1000 / HZ) - 1) / (1000 / HZ);
-#elif HZ > 1000 && !(HZ % 1000)
- return m * (HZ / 1000);
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+ return m * (HZ / MSEC_PER_SEC);
#else
- return (m * HZ + 999) / 1000;
+ return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
#endif
}
@@ -291,12 +291,12 @@ static inline unsigned long usecs_to_jiffies(const unsigned int u)
{
if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
return MAX_JIFFY_OFFSET;
-#if HZ <= 1000000 && !(1000000 % HZ)
- return (u + (1000000 / HZ) - 1) / (1000000 / HZ);
-#elif HZ > 1000000 && !(HZ % 1000000)
- return u * (HZ / 1000000);
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+ return u * (HZ / USEC_PER_SEC);
#else
- return (u * HZ + 999999) / 1000000;
+ return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC;
#endif
}
diff --git a/include/linux/joystick.h b/include/linux/joystick.h
index 06b9af77eb7f..5fd20ddd7ae3 100644
--- a/include/linux/joystick.h
+++ b/include/linux/joystick.h
@@ -111,29 +111,30 @@ struct js_corr {
#define JS_SET_ALL 8
struct JS_DATA_TYPE {
- __s32 buttons;
- __s32 x;
- __s32 y;
+ int32_t buttons;
+ int32_t x;
+ int32_t y;
};
struct JS_DATA_SAVE_TYPE_32 {
- __s32 JS_TIMEOUT;
- __s32 BUSY;
- __s32 JS_EXPIRETIME;
- __s32 JS_TIMELIMIT;
+ int32_t JS_TIMEOUT;
+ int32_t BUSY;
+ int32_t JS_EXPIRETIME;
+ int32_t JS_TIMELIMIT;
struct JS_DATA_TYPE JS_SAVE;
struct JS_DATA_TYPE JS_CORR;
};
struct JS_DATA_SAVE_TYPE_64 {
- __s32 JS_TIMEOUT;
- __s32 BUSY;
- __s64 JS_EXPIRETIME;
- __s64 JS_TIMELIMIT;
+ int32_t JS_TIMEOUT;
+ int32_t BUSY;
+ int64_t JS_EXPIRETIME;
+ int64_t JS_TIMELIMIT;
struct JS_DATA_TYPE JS_SAVE;
struct JS_DATA_TYPE JS_CORR;
};
+#ifdef __KERNEL__
#if BITS_PER_LONG == 64
#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_64
#elif BITS_PER_LONG == 32
@@ -141,5 +142,6 @@ struct JS_DATA_SAVE_TYPE_64 {
#else
#error Unexpected BITS_PER_LONG
#endif
+#endif
#endif /* _LINUX_JOYSTICK_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 687ba8c9973d..4367ce4db52a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -307,8 +307,8 @@ struct sysinfo {
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
};
-extern void BUILD_BUG(void);
-#define BUILD_BUG_ON(condition) do { if (condition) BUILD_BUG(); } while(0)
+/* Force a compilation error if condition is false */
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
#ifdef CONFIG_SYSCTL
extern int randomize_va_space;
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index cc326174a808..7a2e332067c3 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -38,92 +38,21 @@ struct keyring_list {
struct key *keys[0];
};
-
/*
* check to see whether permission is granted to use a key in the desired way
*/
-static inline int key_permission(const struct key *key, key_perm_t perm)
-{
- key_perm_t kperm;
-
- if (key->uid == current->fsuid)
- kperm = key->perm >> 16;
- else if (key->gid != -1 &&
- key->perm & KEY_GRP_ALL &&
- in_group_p(key->gid)
- )
- kperm = key->perm >> 8;
- else
- kperm = key->perm;
-
- kperm = kperm & perm & KEY_ALL;
-
- return kperm == perm;
-}
-
-/*
- * check to see whether permission is granted to use a key in at least one of
- * the desired ways
- */
-static inline int key_any_permission(const struct key *key, key_perm_t perm)
-{
- key_perm_t kperm;
-
- if (key->uid == current->fsuid)
- kperm = key->perm >> 16;
- else if (key->gid != -1 &&
- key->perm & KEY_GRP_ALL &&
- in_group_p(key->gid)
- )
- kperm = key->perm >> 8;
- else
- kperm = key->perm;
+extern int key_task_permission(const key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm);
- kperm = kperm & perm & KEY_ALL;
-
- return kperm != 0;
-}
-
-static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid)
+static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
{
- int ret;
-
- task_lock(tsk);
- ret = groups_search(tsk->group_info, gid);
- task_unlock(tsk);
- return ret;
-}
-
-static inline int key_task_permission(const struct key *key,
- struct task_struct *context,
- key_perm_t perm)
-{
- key_perm_t kperm;
-
- if (key->uid == context->fsuid) {
- kperm = key->perm >> 16;
- }
- else if (key->gid != -1 &&
- key->perm & KEY_GRP_ALL && (
- key->gid == context->fsgid ||
- key_task_groups_search(context, key->gid)
- )
- ) {
- kperm = key->perm >> 8;
- }
- else {
- kperm = key->perm;
- }
-
- kperm = kperm & perm & KEY_ALL;
-
- return kperm == perm;
-
+ return key_task_permission(key_ref, current, perm);
}
-extern struct key *lookup_user_key(struct task_struct *context,
- key_serial_t id, int create, int partial,
- key_perm_t perm);
+extern key_ref_t lookup_user_key(struct task_struct *context,
+ key_serial_t id, int create, int partial,
+ key_perm_t perm);
extern long join_session_keyring(const char *name);
diff --git a/include/linux/key.h b/include/linux/key.h
index 970bbd916cf4..f1efa016dbf3 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -35,11 +35,18 @@ struct key;
#undef KEY_DEBUGGING
-#define KEY_USR_VIEW 0x00010000 /* user can view a key's attributes */
-#define KEY_USR_READ 0x00020000 /* user can read key payload / view keyring */
-#define KEY_USR_WRITE 0x00040000 /* user can update key payload / add link to keyring */
-#define KEY_USR_SEARCH 0x00080000 /* user can find a key in search / search a keyring */
-#define KEY_USR_LINK 0x00100000 /* user can create a link to a key/keyring */
+#define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */
+#define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */
+#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
+#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
+#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
+#define KEY_POS_ALL 0x1f000000
+
+#define KEY_USR_VIEW 0x00010000 /* user permissions... */
+#define KEY_USR_READ 0x00020000
+#define KEY_USR_WRITE 0x00040000
+#define KEY_USR_SEARCH 0x00080000
+#define KEY_USR_LINK 0x00100000
#define KEY_USR_ALL 0x001f0000
#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
@@ -67,6 +74,38 @@ struct keyring_name;
/*****************************************************************************/
/*
+ * key reference with possession attribute handling
+ *
+ * NOTE! key_ref_t is a typedef'd pointer to a type that is not actually
+ * defined. This is because we abuse the bottom bit of the reference to carry a
+ * flag to indicate whether the calling process possesses that key in one of
+ * its keyrings.
+ *
+ * the key_ref_t has been made a separate type so that the compiler can reject
+ * attempts to dereference it without proper conversion.
+ *
+ * the three functions are used to assemble and disassemble references
+ */
+typedef struct __key_reference_with_attributes *key_ref_t;
+
+static inline key_ref_t make_key_ref(const struct key *key,
+ unsigned long possession)
+{
+ return (key_ref_t) ((unsigned long) key | possession);
+}
+
+static inline struct key *key_ref_to_ptr(const key_ref_t key_ref)
+{
+ return (struct key *) ((unsigned long) key_ref & ~1UL);
+}
+
+static inline unsigned long is_key_possessed(const key_ref_t key_ref)
+{
+ return (unsigned long) key_ref & 1UL;
+}
+
+/*****************************************************************************/
+/*
* authentication token / access credential / keyring
* - types of key include:
* - keyrings
@@ -215,20 +254,25 @@ static inline struct key *key_get(struct key *key)
return key;
}
+static inline void key_ref_put(key_ref_t key_ref)
+{
+ key_put(key_ref_to_ptr(key_ref));
+}
+
extern struct key *request_key(struct key_type *type,
const char *description,
const char *callout_info);
extern int key_validate(struct key *key);
-extern struct key *key_create_or_update(struct key *keyring,
- const char *type,
- const char *description,
- const void *payload,
- size_t plen,
- int not_in_quota);
+extern key_ref_t key_create_or_update(key_ref_t keyring,
+ const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ int not_in_quota);
-extern int key_update(struct key *key,
+extern int key_update(key_ref_t key,
const void *payload,
size_t plen);
@@ -243,9 +287,9 @@ extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
extern int keyring_clear(struct key *keyring);
-extern struct key *keyring_search(struct key *keyring,
- struct key_type *type,
- const char *description);
+extern key_ref_t keyring_search(key_ref_t keyring,
+ struct key_type *type,
+ const char *description);
extern int keyring_add_key(struct key *keyring,
struct key *key);
@@ -285,6 +329,10 @@ extern void key_init(void);
#define key_serial(k) 0
#define key_get(k) ({ NULL; })
#define key_put(k) do { } while(0)
+#define key_ref_put(k) do { } while(0)
+#define make_key_ref(k) ({ NULL; })
+#define key_ref_to_ptr(k) ({ NULL; })
+#define is_key_possessed(k) 0
#define alloc_uid_keyring(u) 0
#define switch_uid_keyring(u) do { } while(0)
#define __install_session_keyring(t, k) ({ NULL; })
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index c27cd428d269..48eccd865bd8 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -35,8 +35,8 @@ struct kfifo {
};
extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
- unsigned int __nocast gfp_mask, spinlock_t *lock);
-extern struct kfifo *kfifo_alloc(unsigned int size, unsigned int __nocast gfp_mask,
+ gfp_t gfp_mask, spinlock_t *lock);
+extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask,
spinlock_t *lock);
extern void kfifo_free(struct kfifo *fifo);
extern unsigned int __kfifo_put(struct kfifo *fifo,
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 3b22304f12fd..7f7403aa4a41 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -65,7 +65,7 @@ extern void kobject_unregister(struct kobject *);
extern struct kobject * kobject_get(struct kobject *);
extern void kobject_put(struct kobject *);
-extern char * kobject_get_path(struct kobject *, int);
+extern char * kobject_get_path(struct kobject *, gfp_t);
struct kobj_type {
void (*release)(struct kobject *);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 022105c745fc..00a8a5738858 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -91,12 +91,13 @@ enum {
ATA_SHT_EMULATED = 1,
ATA_SHT_CMD_PER_LUN = 1,
ATA_SHT_THIS_ID = -1,
- ATA_SHT_USE_CLUSTERING = 0,
+ ATA_SHT_USE_CLUSTERING = 1,
/* struct ata_device stuff */
ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */
ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */
ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */
+ ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */
ATA_DEV_UNKNOWN = 0, /* unknown device */
ATA_DEV_ATA = 1, /* ATA device */
@@ -154,17 +155,21 @@ enum {
ATA_SHIFT_UDMA = 0,
ATA_SHIFT_MWDMA = 8,
ATA_SHIFT_PIO = 11,
+
+ /* Masks for port functions */
+ ATA_PORT_PRIMARY = (1 << 0),
+ ATA_PORT_SECONDARY = (1 << 1),
};
-enum pio_task_states {
- PIO_ST_UNKNOWN,
- PIO_ST_IDLE,
- PIO_ST_POLL,
- PIO_ST_TMOUT,
- PIO_ST,
- PIO_ST_LAST,
- PIO_ST_LAST_POLL,
- PIO_ST_ERR,
+enum hsm_task_states {
+ HSM_ST_UNKNOWN,
+ HSM_ST_IDLE,
+ HSM_ST_POLL,
+ HSM_ST_TMOUT,
+ HSM_ST,
+ HSM_ST_LAST,
+ HSM_ST_LAST_POLL,
+ HSM_ST_ERR,
};
/* forward declarations */
@@ -197,7 +202,7 @@ struct ata_ioports {
struct ata_probe_ent {
struct list_head node;
struct device *dev;
- struct ata_port_operations *port_ops;
+ const struct ata_port_operations *port_ops;
Scsi_Host_Template *sht;
struct ata_ioports port[ATA_MAX_PORTS];
unsigned int n_ports;
@@ -220,7 +225,7 @@ struct ata_host_set {
void __iomem *mmio_base;
unsigned int n_ports;
void *private_data;
- struct ata_port_operations *ops;
+ const struct ata_port_operations *ops;
struct ata_port * ports[0];
};
@@ -278,15 +283,18 @@ struct ata_device {
u8 xfer_mode;
unsigned int xfer_shift; /* ATA_SHIFT_xxx */
- /* cache info about current transfer mode */
- u8 xfer_protocol; /* taskfile xfer protocol */
- u8 read_cmd; /* opcode to use on read */
- u8 write_cmd; /* opcode to use on write */
+ unsigned int multi_count; /* sectors count for
+ READ/WRITE MULTIPLE */
+
+ /* for CHS addressing */
+ u16 cylinders; /* Number of cylinders */
+ u16 heads; /* Number of heads */
+ u16 sectors; /* Number of sectors per track */
};
struct ata_port {
struct Scsi_Host *host; /* our co-allocated scsi host */
- struct ata_port_operations *ops;
+ const struct ata_port_operations *ops;
unsigned long flags; /* ATA_FLAG_xxx */
unsigned int id; /* unique id req'd by scsi midlyr */
unsigned int port_no; /* unique port #; from zero */
@@ -319,7 +327,7 @@ struct ata_port {
struct work_struct packet_task;
struct work_struct pio_task;
- unsigned int pio_task_state;
+ unsigned int hsm_task_state;
unsigned long pio_task_timeout;
void *private_data;
@@ -333,10 +341,10 @@ struct ata_port_operations {
void (*set_piomode) (struct ata_port *, struct ata_device *);
void (*set_dmamode) (struct ata_port *, struct ata_device *);
- void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+ void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
- void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+ void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
u8 (*check_status)(struct ata_port *ap);
u8 (*check_altstatus)(struct ata_port *ap);
u8 (*check_err)(struct ata_port *ap);
@@ -377,9 +385,22 @@ struct ata_port_info {
unsigned long pio_mask;
unsigned long mwdma_mask;
unsigned long udma_mask;
- struct ata_port_operations *port_ops;
+ const struct ata_port_operations *port_ops;
+};
+
+struct ata_timing {
+ unsigned short mode; /* ATA mode */
+ unsigned short setup; /* t1 */
+ unsigned short act8b; /* t2 for 8-bit I/O */
+ unsigned short rec8b; /* t2i for 8-bit I/O */
+ unsigned short cyc8b; /* t0 for 8-bit I/O */
+ unsigned short active; /* t2 or tD */
+ unsigned short recover; /* t2i or tK */
+ unsigned short cycle; /* t0 */
+ unsigned short udma; /* t2CYCTYP/2 */
};
+#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin)
extern void ata_port_probe(struct ata_port *);
extern void __sata_phy_reset(struct ata_port *ap);
@@ -392,26 +413,29 @@ extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_i
unsigned int n_ports);
extern void ata_pci_remove_one (struct pci_dev *pdev);
#endif /* CONFIG_PCI */
-extern int ata_device_add(struct ata_probe_ent *ent);
+extern int ata_device_add(const struct ata_probe_ent *ent);
+extern void ata_host_set_remove(struct ata_host_set *host_set);
extern int ata_scsi_detect(Scsi_Host_Template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_scsi_error(struct Scsi_Host *host);
extern int ata_scsi_release(struct Scsi_Host *host);
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+extern int ata_ratelimit(void);
+
/*
* Default driver ops implementations
*/
-extern void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-extern void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp);
-extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf);
+extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp);
+extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf);
extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
extern u8 ata_check_status(struct ata_port *ap);
extern u8 ata_altstatus(struct ata_port *ap);
extern u8 ata_chk_err(struct ata_port *ap);
-extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
extern void ata_host_stop (struct ata_host_set *host_set);
@@ -422,8 +446,8 @@ extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf,
unsigned int buflen);
extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem);
-extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
-extern void ata_dev_id_string(u16 *id, unsigned char *s,
+extern unsigned int ata_dev_classify(const struct ata_taskfile *tf);
+extern void ata_dev_id_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_dev_config(struct ata_port *ap, unsigned int i);
extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
@@ -440,6 +464,32 @@ extern int ata_std_bios_param(struct scsi_device *sdev,
sector_t capacity, int geom[]);
extern int ata_scsi_slave_config(struct scsi_device *sdev);
+/*
+ * Timing helpers
+ */
+extern int ata_timing_compute(struct ata_device *, unsigned short,
+ struct ata_timing *, int, int);
+extern void ata_timing_merge(const struct ata_timing *,
+ const struct ata_timing *, struct ata_timing *,
+ unsigned int);
+
+enum {
+ ATA_TIMING_SETUP = (1 << 0),
+ ATA_TIMING_ACT8B = (1 << 1),
+ ATA_TIMING_REC8B = (1 << 2),
+ ATA_TIMING_CYC8B = (1 << 3),
+ ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B |
+ ATA_TIMING_CYC8B,
+ ATA_TIMING_ACTIVE = (1 << 4),
+ ATA_TIMING_RECOVER = (1 << 5),
+ ATA_TIMING_CYCLE = (1 << 6),
+ ATA_TIMING_UDMA = (1 << 7),
+ ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B |
+ ATA_TIMING_REC8B | ATA_TIMING_CYC8B |
+ ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
+ ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
+};
+
#ifdef CONFIG_PCI
struct pci_bits {
@@ -451,8 +501,8 @@ struct pci_bits {
extern void ata_pci_host_stop (struct ata_host_set *host_set);
extern struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
-extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
+extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
#endif /* CONFIG_PCI */
@@ -462,7 +512,7 @@ static inline unsigned int ata_tag_valid(unsigned int tag)
return (tag < ATA_MAX_QUEUE) ? 1 : 0;
}
-static inline unsigned int ata_dev_present(struct ata_device *dev)
+static inline unsigned int ata_dev_present(const struct ata_device *dev)
{
return ((dev->class == ATA_DEV_ATA) ||
(dev->class == ATA_DEV_ATAPI));
@@ -661,7 +711,7 @@ static inline unsigned int sata_dev_present(struct ata_port *ap)
return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
}
-static inline int ata_try_flush_cache(struct ata_device *dev)
+static inline int ata_try_flush_cache(const struct ata_device *dev)
{
return ata_id_wcache_enabled(dev->id) ||
ata_id_has_flush(dev->id) ||
diff --git a/include/linux/list.h b/include/linux/list.h
index e6ec59682274..084971f333fe 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -442,12 +442,14 @@ static inline void list_splice_init(struct list_head *list,
* as long as the traversal is guarded by rcu_read_lock().
*/
#define list_for_each_rcu(pos, head) \
- for (pos = (head)->next; prefetch(pos->next), pos != (head); \
- pos = rcu_dereference(pos->next))
+ for (pos = (head)->next; \
+ prefetch(rcu_dereference(pos)->next), pos != (head); \
+ pos = pos->next)
#define __list_for_each_rcu(pos, head) \
- for (pos = (head)->next; pos != (head); \
- pos = rcu_dereference(pos->next))
+ for (pos = (head)->next; \
+ rcu_dereference(pos) != (head); \
+ pos = pos->next)
/**
* list_for_each_safe_rcu - iterate over an rcu-protected list safe
@@ -461,8 +463,9 @@ static inline void list_splice_init(struct list_head *list,
* as long as the traversal is guarded by rcu_read_lock().
*/
#define list_for_each_safe_rcu(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = rcu_dereference(n), n = pos->next)
+ for (pos = (head)->next; \
+ n = rcu_dereference(pos)->next, pos != (head); \
+ pos = n)
/**
* list_for_each_entry_rcu - iterate over rcu list of given type
@@ -474,11 +477,11 @@ static inline void list_splice_init(struct list_head *list,
* the _rcu list-mutation primitives such as list_add_rcu()
* as long as the traversal is guarded by rcu_read_lock().
*/
-#define list_for_each_entry_rcu(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- prefetch(pos->member.next), &pos->member != (head); \
- pos = rcu_dereference(list_entry(pos->member.next, \
- typeof(*pos), member)))
+#define list_for_each_entry_rcu(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ prefetch(rcu_dereference(pos)->member.next), \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
/**
@@ -492,8 +495,9 @@ static inline void list_splice_init(struct list_head *list,
* as long as the traversal is guarded by rcu_read_lock().
*/
#define list_for_each_continue_rcu(pos, head) \
- for ((pos) = (pos)->next; prefetch((pos)->next), (pos) != (head); \
- (pos) = rcu_dereference((pos)->next))
+ for ((pos) = (pos)->next; \
+ prefetch(rcu_dereference((pos))->next), (pos) != (head); \
+ (pos) = (pos)->next)
/*
* Double linked lists with a single pointer list head.
@@ -696,8 +700,9 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
pos = n)
#define hlist_for_each_rcu(pos, head) \
- for ((pos) = (head)->first; pos && ({ prefetch((pos)->next); 1; }); \
- (pos) = rcu_dereference((pos)->next))
+ for ((pos) = (head)->first; \
+ rcu_dereference((pos)) && ({ prefetch((pos)->next); 1; }); \
+ (pos) = (pos)->next)
/**
* hlist_for_each_entry - iterate over list of given type
@@ -762,9 +767,9 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
*/
#define hlist_for_each_entry_rcu(tpos, pos, head, member) \
for (pos = (head)->first; \
- pos && ({ prefetch(pos->next); 1;}) && \
+ rcu_dereference(pos) && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = rcu_dereference(pos->next))
+ pos = pos->next)
#else
#warning "don't include kernel headers in userspace"
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 53fa51595443..40f63c9879d2 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -52,7 +52,7 @@ struct loop_device {
unsigned lo_blocksize;
void *key_data;
- int old_gfp_mask;
+ gfp_t old_gfp_mask;
spinlock_t lo_lock;
struct bio *lo_bio;
diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
index 9263d2db2d67..99e044b4efc6 100644
--- a/include/linux/mbcache.h
+++ b/include/linux/mbcache.h
@@ -22,7 +22,7 @@ struct mb_cache_entry {
};
struct mb_cache_op {
- int (*free)(struct mb_cache_entry *, int);
+ int (*free)(struct mb_cache_entry *, gfp_t);
};
/* Functions on caches */
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 94a46f38c532..58385ee1c0ac 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -155,6 +155,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
extern void numa_default_policy(void);
extern void numa_policy_init(void);
+extern struct mempolicy default_policy;
#else
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
index 796220ce47cc..f2427d7394b0 100644
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -6,7 +6,7 @@
#include <linux/wait.h>
-typedef void * (mempool_alloc_t)(unsigned int __nocast gfp_mask, void *pool_data);
+typedef void * (mempool_alloc_t)(gfp_t gfp_mask, void *pool_data);
typedef void (mempool_free_t)(void *element, void *pool_data);
typedef struct mempool_s {
@@ -26,17 +26,16 @@ extern mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
mempool_free_t *free_fn, void *pool_data, int nid);
-extern int mempool_resize(mempool_t *pool, int new_min_nr,
- unsigned int __nocast gfp_mask);
+extern int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask);
extern void mempool_destroy(mempool_t *pool);
-extern void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask);
+extern void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask);
extern void mempool_free(void *element, mempool_t *pool);
/*
* A mempool_alloc_t and mempool_free_t that get the memory from
* a slab that is passed in through pool_data.
*/
-void *mempool_alloc_slab(unsigned int __nocast gfp_mask, void *pool_data);
+void *mempool_alloc_slab(gfp_t gfp_mask, void *pool_data);
void mempool_free_slab(void *element, void *pool_data);
#endif /* _LINUX_MEMPOOL_H */
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 9b8d0476988a..68f5a0f392dd 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -158,6 +158,7 @@ extern int mii_link_ok (struct mii_if_info *mii);
extern int mii_nway_restart (struct mii_if_info *mii);
extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
+extern int mii_check_gmii_support(struct mii_if_info *mii);
extern void mii_check_link (struct mii_if_info *mii);
extern unsigned int mii_check_media (struct mii_if_info *mii,
unsigned int ok_to_print,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 82d7024f0765..e1649578fb0c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -136,6 +136,7 @@ extern unsigned int kobjsize(const void *objp);
#define VM_EXEC 0x00000004
#define VM_SHARED 0x00000008
+/* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */
#define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */
#define VM_MAYWRITE 0x00000020
#define VM_MAYEXEC 0x00000040
@@ -350,7 +351,8 @@ static inline void put_page(struct page *page)
* only one copy in memory, at most, normally.
*
* For the non-reserved pages, page_count(page) denotes a reference count.
- * page_count() == 0 means the page is free.
+ * page_count() == 0 means the page is free. page->lru is then used for
+ * freelist management in the buddy allocator.
* page_count() == 1 means the page is used for exactly one purpose
* (e.g. a private data page of one process).
*
@@ -376,10 +378,8 @@ static inline void put_page(struct page *page)
* attaches, plus 1 if `private' contains something, plus one for
* the page cache itself.
*
- * All pages belonging to an inode are in these doubly linked lists:
- * mapping->clean_pages, mapping->dirty_pages and mapping->locked_pages;
- * using the page->list list_head. These fields are also used for
- * freelist managemet (when page_count()==0).
+ * Instead of keeping dirty/clean pages in per address-space lists, we instead
+ * now tag pages as dirty/under writeback in the radix tree.
*
* There is also a per-mapping radix tree mapping index to the page
* in memory if present. The tree is rooted at mapping->root.
@@ -747,7 +747,7 @@ extern unsigned long do_mremap(unsigned long addr,
* The callback will be passed nr_to_scan == 0 when the VM is querying the
* cache size, so a fastpath for that case is appropriate.
*/
-typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask);
+typedef int (*shrinker_t)(int nr_to_scan, gfp_t gfp_mask);
/*
* Add an aging callback. The int is the number of 'seeks' it takes
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6014160d9c06..c1f021eddffa 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -109,6 +109,8 @@ struct mmc_host {
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/mmc/mmc.h b/include/linux/mmc/mmc.h
index 1ab78e8d6c53..aef6042f8f0b 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -50,7 +50,7 @@ struct mmc_command {
#define MMC_ERR_INVALID 5
struct mmc_data *data; /* data segment associated with cmd */
- struct mmc_request *mrq; /* assoicated request */
+ struct mmc_request *mrq; /* associated request */
};
struct mmc_data {
@@ -68,7 +68,7 @@ struct mmc_data {
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */
- struct mmc_request *mrq; /* assoicated request */
+ struct mmc_request *mrq; /* associated request */
unsigned int sg_len; /* size of scatter list */
struct scatterlist *sg; /* I/O scatter list */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 5ed471b58f4f..7519eb4191e7 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -302,7 +302,7 @@ void get_zone_counts(unsigned long *active, unsigned long *inactive,
void build_all_zonelists(void);
void wakeup_kswapd(struct zone *zone, int order);
int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
- int alloc_type, int can_try_harder, int gfp_high);
+ int alloc_type, int can_try_harder, gfp_t gfp_high);
#ifdef CONFIG_HAVE_MEMORY_PRESENT
void memory_present(int nid, unsigned long start, unsigned long end);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 47da39ba3f03..2f0299a448f6 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -183,7 +183,7 @@ struct of_device_id
char name[32];
char type[32];
char compatible[128];
-#if __KERNEL__
+#ifdef __KERNEL__
void *data;
#else
kernel_ulong_t data;
@@ -209,10 +209,11 @@ struct pcmcia_device_id {
/* for real multi-function devices */
__u8 function;
- /* for pseude multi-function devices */
+ /* for pseudo multi-function devices */
__u8 device_no;
- __u32 prod_id_hash[4];
+ __u32 prod_id_hash[4]
+ __attribute__((aligned(sizeof(__u32))));
/* not matched against in kernelspace*/
#ifdef __KERNEL__
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 7db67b008cac..1c975d0d9e94 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -8,6 +8,7 @@ struct vfsmount;
struct open_intent {
int flags;
int create_mode;
+ struct file *file;
};
enum { MAX_NESTED_LINKS = 5 };
@@ -65,6 +66,13 @@ extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
extern void path_release(struct nameidata *);
extern void path_release_on_umount(struct nameidata *);
+extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
+extern int path_lookup_open(const char *, unsigned lookup_flags, struct nameidata *, int open_flags);
+extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
+ int (*open)(struct inode *, struct file *));
+extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
+extern void release_open_intent(struct nameidata *);
+
extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7c717907896d..a9281b24c40b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -265,6 +265,8 @@ struct net_device
* the interface.
*/
char name[IFNAMSIZ];
+ /* device name hash chain */
+ struct hlist_node name_hlist;
/*
* I/O specific fields
@@ -292,6 +294,21 @@ struct net_device
/* ------- Fields preinitialized in Space.c finish here ------- */
+ /* Net device features */
+ unsigned long features;
+#define NETIF_F_SG 1 /* Scatter/gather IO. */
+#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
+#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
+#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
+#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
+#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
+#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */
+#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
+#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
+#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
+#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
+#define NETIF_F_LLTX 4096 /* LockLess TX */
+
struct net_device *next_sched;
/* Interface index. Unique device identifier */
@@ -316,9 +333,6 @@ struct net_device
* will (read: may be cleaned up at will).
*/
- /* These may be needed for future network-power-down code. */
- unsigned long trans_start; /* Time (in jiffies) of last Tx */
- unsigned long last_rx; /* Time of last Rx */
unsigned short flags; /* interface flags (a la BSD) */
unsigned short gflags;
@@ -328,15 +342,12 @@ struct net_device
unsigned mtu; /* interface MTU value */
unsigned short type; /* interface hardware type */
unsigned short hard_header_len; /* hardware hdr length */
- void *priv; /* pointer to private data */
struct net_device *master; /* Pointer to master device of a group,
* which this device is member of.
*/
/* Interface address info. */
- unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
- unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
unsigned char addr_len; /* hardware address length */
unsigned short dev_id; /* for shared network cards */
@@ -346,8 +357,6 @@ struct net_device
int promiscuity;
int allmulti;
- int watchdog_timeo;
- struct timer_list watchdog_timer;
/* Protocol specific pointers */
@@ -358,32 +367,62 @@ struct net_device
void *ec_ptr; /* Econet specific data */
void *ax25_ptr; /* AX.25 specific data */
- struct list_head poll_list; /* Link to poll list */
+/*
+ * Cache line mostly used on receive path (including eth_type_trans())
+ */
+ struct list_head poll_list ____cacheline_aligned_in_smp;
+ /* Link to poll list */
+
+ int (*poll) (struct net_device *dev, int *quota);
int quota;
int weight;
+ unsigned long last_rx; /* Time of last Rx */
+ /* Interface address info used in eth_type_trans() */
+ unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
+ because most packets are unicast) */
+
+ unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
+/*
+ * Cache line mostly used on queue transmit path (qdisc)
+ */
+ /* device queue lock */
+ spinlock_t queue_lock ____cacheline_aligned_in_smp;
struct Qdisc *qdisc;
struct Qdisc *qdisc_sleeping;
- struct Qdisc *qdisc_ingress;
struct list_head qdisc_list;
unsigned long tx_queue_len; /* Max frames per queue allowed */
/* ingress path synchronizer */
spinlock_t ingress_lock;
+ struct Qdisc *qdisc_ingress;
+
+/*
+ * One part is mostly used on xmit path (device)
+ */
/* hard_start_xmit synchronizer */
- spinlock_t xmit_lock;
+ spinlock_t xmit_lock ____cacheline_aligned_in_smp;
/* cpu id of processor entered to hard_start_xmit or -1,
if nobody entered there.
*/
int xmit_lock_owner;
- /* device queue lock */
- spinlock_t queue_lock;
+ void *priv; /* pointer to private data */
+ int (*hard_start_xmit) (struct sk_buff *skb,
+ struct net_device *dev);
+ /* These may be needed for future network-power-down code. */
+ unsigned long trans_start; /* Time (in jiffies) of last Tx */
+
+ int watchdog_timeo; /* used by dev_watchdog() */
+ struct timer_list watchdog_timer;
+
+/*
+ * refcnt is a very hot point, so align it on SMP
+ */
/* Number of references to this device */
- atomic_t refcnt;
+ atomic_t refcnt ____cacheline_aligned_in_smp;
+
/* delayed register/unregister */
struct list_head todo_list;
- /* device name hash chain */
- struct hlist_node name_hlist;
/* device index hash chain */
struct hlist_node index_hlist;
@@ -396,21 +435,6 @@ struct net_device
NETREG_RELEASED, /* called free_netdev */
} reg_state;
- /* Net device features */
- unsigned long features;
-#define NETIF_F_SG 1 /* Scatter/gather IO. */
-#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
-#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
-#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
-#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
-#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
-#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */
-#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
-#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
-#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
-#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
-#define NETIF_F_LLTX 4096 /* LockLess TX */
-
/* Called after device is detached from network. */
void (*uninit)(struct net_device *dev);
/* Called after last user reference disappears. */
@@ -419,10 +443,7 @@ struct net_device
/* Pointers to interface service routines. */
int (*open)(struct net_device *dev);
int (*stop)(struct net_device *dev);
- int (*hard_start_xmit) (struct sk_buff *skb,
- struct net_device *dev);
#define HAVE_NETDEV_POLL
- int (*poll) (struct net_device *dev, int *quota);
int (*hard_header) (struct sk_buff *skb,
struct net_device *dev,
unsigned short type,
@@ -852,11 +873,9 @@ static inline void netif_rx_complete(struct net_device *dev)
static inline void netif_poll_disable(struct net_device *dev)
{
- while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+ while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state))
/* No hurry. */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
+ schedule_timeout_interruptible(1);
}
static inline void netif_poll_enable(struct net_device *dev)
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 1d5b10ae2399..f08e870100f4 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -41,11 +41,15 @@ enum nfnetlink_groups {
struct nfattr
{
u_int16_t nfa_len;
- u_int16_t nfa_type;
+ u_int16_t nfa_type; /* we use 15 bits for the type, and the highest
+ * bit to indicate whether the payload is nested */
} __attribute__ ((packed));
-/* FIXME: Shamelessly copy and pasted from rtnetlink.h, it's time
- * to put this in a generic file */
+/* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from
+ * rtnetlink.h, it's time to put this in a generic file */
+
+#define NFNL_NFA_NEST 0x8000
+#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff)
#define NFA_ALIGNTO 4
#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
@@ -59,7 +63,7 @@ struct nfattr
#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
#define NFA_NEST(skb, type) \
({ struct nfattr *__start = (struct nfattr *) (skb)->tail; \
- NFA_PUT(skb, type, 0, NULL); \
+ NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \
__start; })
#define NFA_NEST_END(skb, start) \
({ (start)->nfa_len = ((skb)->tail - (unsigned char *) (start)); \
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 5c55751c78e4..116fcaced909 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -70,15 +70,24 @@ enum ctattr_l4proto {
enum ctattr_protoinfo {
CTA_PROTOINFO_UNSPEC,
- CTA_PROTOINFO_TCP_STATE,
+ CTA_PROTOINFO_TCP,
__CTA_PROTOINFO_MAX
};
#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
+enum ctattr_protoinfo_tcp {
+ CTA_PROTOINFO_TCP_UNSPEC,
+ CTA_PROTOINFO_TCP_STATE,
+ __CTA_PROTOINFO_TCP_MAX
+};
+#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
+
enum ctattr_counters {
CTA_COUNTERS_UNSPEC,
- CTA_COUNTERS_PACKETS,
- CTA_COUNTERS_BYTES,
+ CTA_COUNTERS_PACKETS, /* old 64bit counters */
+ CTA_COUNTERS_BYTES, /* old 64bit counters */
+ CTA_COUNTERS32_PACKETS,
+ CTA_COUNTERS32_BYTES,
__CTA_COUNTERS_MAX
};
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 7e033e9271a8..d078bb91d9e5 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -117,6 +117,10 @@ enum ip_conntrack_events
/* NAT info */
IPCT_NATINFO_BIT = 10,
IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
+
+ /* Counter highest bit has been set */
+ IPCT_COUNTER_FILLING_BIT = 11,
+ IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
};
enum ip_conntrack_expect_events {
@@ -133,11 +137,13 @@ enum ip_conntrack_expect_events {
#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
#include <linux/netfilter_ipv4/ip_conntrack_sctp.h>
/* per conntrack: protocol private data */
union ip_conntrack_proto {
/* insert conntrack proto private data here */
+ struct ip_ct_gre gre;
struct ip_ct_sctp sctp;
struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
@@ -148,6 +154,7 @@ union ip_conntrack_expect_proto {
};
/* Add protocol helper include file here */
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
@@ -155,12 +162,20 @@ union ip_conntrack_expect_proto {
/* per conntrack: application helper private data */
union ip_conntrack_help {
/* insert conntrack helper private data (master) here */
+ struct ip_ct_pptp_master ct_pptp_info;
struct ip_ct_ftp_master ct_ftp_info;
struct ip_ct_irc_master ct_irc_info;
};
#ifdef CONFIG_IP_NF_NAT_NEEDED
#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_pptp.h>
+
+/* per conntrack: nat application helper private data */
+union ip_conntrack_nat_help {
+ /* insert nat helper private data here */
+ struct ip_nat_pptp nat_pptp_info;
+};
#endif
#include <linux/types.h>
@@ -181,8 +196,8 @@ do { \
struct ip_conntrack_counter
{
- u_int64_t packets;
- u_int64_t bytes;
+ u_int32_t packets;
+ u_int32_t bytes;
};
struct ip_conntrack_helper;
@@ -223,6 +238,7 @@ struct ip_conntrack
#ifdef CONFIG_IP_NF_NAT_NEEDED
struct {
struct ip_nat_info info;
+ union ip_conntrack_nat_help help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
int masq_index;
@@ -320,11 +336,28 @@ extern void need_ip_conntrack(void);
extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig);
+extern void __ip_ct_refresh_acct(struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies,
+ int do_acct);
+
+/* Refresh conntrack for this many jiffies and do accounting */
+static inline void ip_ct_refresh_acct(struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies)
+{
+ __ip_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
+}
+
/* Refresh conntrack for this many jiffies */
-extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const struct sk_buff *skb,
- unsigned long extra_jiffies);
+static inline void ip_ct_refresh(struct ip_conntrack *ct,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies)
+{
+ __ip_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
+}
/* These are for NAT. Icky. */
/* Update TCP window tracking data when NAT mangles the packet */
@@ -372,7 +405,7 @@ extern struct ip_conntrack_expect *
__ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);
extern struct ip_conntrack_expect *
-ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);
+ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);
extern struct ip_conntrack_tuple_hash *
__ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_pptp.h b/include/linux/netfilter_ipv4/ip_conntrack_pptp.h
new file mode 100644
index 000000000000..816144c75de0
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_conntrack_pptp.h
@@ -0,0 +1,325 @@
+/* PPTP constants and structs */
+#ifndef _CONNTRACK_PPTP_H
+#define _CONNTRACK_PPTP_H
+
+/* state of the control session */
+enum pptp_ctrlsess_state {
+ PPTP_SESSION_NONE, /* no session present */
+ PPTP_SESSION_ERROR, /* some session error */
+ PPTP_SESSION_STOPREQ, /* stop_sess request seen */
+ PPTP_SESSION_REQUESTED, /* start_sess request seen */
+ PPTP_SESSION_CONFIRMED, /* session established */
+};
+
+/* state of the call inside the control session */
+enum pptp_ctrlcall_state {
+ PPTP_CALL_NONE,
+ PPTP_CALL_ERROR,
+ PPTP_CALL_OUT_REQ,
+ PPTP_CALL_OUT_CONF,
+ PPTP_CALL_IN_REQ,
+ PPTP_CALL_IN_REP,
+ PPTP_CALL_IN_CONF,
+ PPTP_CALL_CLEAR_REQ,
+};
+
+
+/* conntrack private data */
+struct ip_ct_pptp_master {
+ enum pptp_ctrlsess_state sstate; /* session state */
+
+ /* everything below is going to be per-expectation in newnat,
+ * since there could be more than one call within one session */
+ enum pptp_ctrlcall_state cstate; /* call state */
+ u_int16_t pac_call_id; /* call id of PAC, host byte order */
+ u_int16_t pns_call_id; /* call id of PNS, host byte order */
+
+ /* in pre-2.6.11 this used to be per-expect. Now it is per-conntrack
+ * and therefore imposes a fixed limit on the number of maps */
+ struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
+};
+
+/* conntrack_expect private member */
+struct ip_ct_pptp_expect {
+ enum pptp_ctrlcall_state cstate; /* call state */
+ u_int16_t pac_call_id; /* call id of PAC */
+ u_int16_t pns_call_id; /* call id of PNS */
+};
+
+
+#ifdef __KERNEL__
+
+#define IP_CONNTR_PPTP PPTP_CONTROL_PORT
+
+#define PPTP_CONTROL_PORT 1723
+
+#define PPTP_PACKET_CONTROL 1
+#define PPTP_PACKET_MGMT 2
+
+#define PPTP_MAGIC_COOKIE 0x1a2b3c4d
+
+struct pptp_pkt_hdr {
+ __u16 packetLength;
+ __be16 packetType;
+ __be32 magicCookie;
+};
+
+/* PptpControlMessageType values */
+#define PPTP_START_SESSION_REQUEST 1
+#define PPTP_START_SESSION_REPLY 2
+#define PPTP_STOP_SESSION_REQUEST 3
+#define PPTP_STOP_SESSION_REPLY 4
+#define PPTP_ECHO_REQUEST 5
+#define PPTP_ECHO_REPLY 6
+#define PPTP_OUT_CALL_REQUEST 7
+#define PPTP_OUT_CALL_REPLY 8
+#define PPTP_IN_CALL_REQUEST 9
+#define PPTP_IN_CALL_REPLY 10
+#define PPTP_IN_CALL_CONNECT 11
+#define PPTP_CALL_CLEAR_REQUEST 12
+#define PPTP_CALL_DISCONNECT_NOTIFY 13
+#define PPTP_WAN_ERROR_NOTIFY 14
+#define PPTP_SET_LINK_INFO 15
+
+#define PPTP_MSG_MAX 15
+
+/* PptpGeneralError values */
+#define PPTP_ERROR_CODE_NONE 0
+#define PPTP_NOT_CONNECTED 1
+#define PPTP_BAD_FORMAT 2
+#define PPTP_BAD_VALUE 3
+#define PPTP_NO_RESOURCE 4
+#define PPTP_BAD_CALLID 5
+#define PPTP_REMOVE_DEVICE_ERROR 6
+
+struct PptpControlHeader {
+ __be16 messageType;
+ __u16 reserved;
+};
+
+/* FramingCapability Bitmap Values */
+#define PPTP_FRAME_CAP_ASYNC 0x1
+#define PPTP_FRAME_CAP_SYNC 0x2
+
+/* BearerCapability Bitmap Values */
+#define PPTP_BEARER_CAP_ANALOG 0x1
+#define PPTP_BEARER_CAP_DIGITAL 0x2
+
+struct PptpStartSessionRequest {
+ __be16 protocolVersion;
+ __u8 reserved1;
+ __u8 reserved2;
+ __be32 framingCapability;
+ __be32 bearerCapability;
+ __be16 maxChannels;
+ __be16 firmwareRevision;
+ __u8 hostName[64];
+ __u8 vendorString[64];
+};
+
+/* PptpStartSessionResultCode Values */
+#define PPTP_START_OK 1
+#define PPTP_START_GENERAL_ERROR 2
+#define PPTP_START_ALREADY_CONNECTED 3
+#define PPTP_START_NOT_AUTHORIZED 4
+#define PPTP_START_UNKNOWN_PROTOCOL 5
+
+struct PptpStartSessionReply {
+ __be16 protocolVersion;
+ __u8 resultCode;
+ __u8 generalErrorCode;
+ __be32 framingCapability;
+ __be32 bearerCapability;
+ __be16 maxChannels;
+ __be16 firmwareRevision;
+ __u8 hostName[64];
+ __u8 vendorString[64];
+};
+
+/* PptpStopReasons */
+#define PPTP_STOP_NONE 1
+#define PPTP_STOP_PROTOCOL 2
+#define PPTP_STOP_LOCAL_SHUTDOWN 3
+
+struct PptpStopSessionRequest {
+ __u8 reason;
+};
+
+/* PptpStopSessionResultCode */
+#define PPTP_STOP_OK 1
+#define PPTP_STOP_GENERAL_ERROR 2
+
+struct PptpStopSessionReply {
+ __u8 resultCode;
+ __u8 generalErrorCode;
+};
+
+struct PptpEchoRequest {
+ __be32 identNumber;
+};
+
+/* PptpEchoReplyResultCode */
+#define PPTP_ECHO_OK 1
+#define PPTP_ECHO_GENERAL_ERROR 2
+
+struct PptpEchoReply {
+ __be32 identNumber;
+ __u8 resultCode;
+ __u8 generalErrorCode;
+ __u16 reserved;
+};
+
+/* PptpFramingType */
+#define PPTP_ASYNC_FRAMING 1
+#define PPTP_SYNC_FRAMING 2
+#define PPTP_DONT_CARE_FRAMING 3
+
+/* PptpCallBearerType */
+#define PPTP_ANALOG_TYPE 1
+#define PPTP_DIGITAL_TYPE 2
+#define PPTP_DONT_CARE_BEARER_TYPE 3
+
+struct PptpOutCallRequest {
+ __be16 callID;
+ __be16 callSerialNumber;
+ __be32 minBPS;
+ __be32 maxBPS;
+ __be32 bearerType;
+ __be32 framingType;
+ __be16 packetWindow;
+ __be16 packetProcDelay;
+ __u16 reserved1;
+ __be16 phoneNumberLength;
+ __u16 reserved2;
+ __u8 phoneNumber[64];
+ __u8 subAddress[64];
+};
+
+/* PptpCallResultCode */
+#define PPTP_OUTCALL_CONNECT 1
+#define PPTP_OUTCALL_GENERAL_ERROR 2
+#define PPTP_OUTCALL_NO_CARRIER 3
+#define PPTP_OUTCALL_BUSY 4
+#define PPTP_OUTCALL_NO_DIAL_TONE 5
+#define PPTP_OUTCALL_TIMEOUT 6
+#define PPTP_OUTCALL_DONT_ACCEPT 7
+
+struct PptpOutCallReply {
+ __be16 callID;
+ __be16 peersCallID;
+ __u8 resultCode;
+ __u8 generalErrorCode;
+ __be16 causeCode;
+ __be32 connectSpeed;
+ __be16 packetWindow;
+ __be16 packetProcDelay;
+ __be32 physChannelID;
+};
+
+struct PptpInCallRequest {
+ __be16 callID;
+ __be16 callSerialNumber;
+ __be32 callBearerType;
+ __be32 physChannelID;
+ __be16 dialedNumberLength;
+ __be16 dialingNumberLength;
+ __u8 dialedNumber[64];
+ __u8 dialingNumber[64];
+ __u8 subAddress[64];
+};
+
+/* PptpInCallResultCode */
+#define PPTP_INCALL_ACCEPT 1
+#define PPTP_INCALL_GENERAL_ERROR 2
+#define PPTP_INCALL_DONT_ACCEPT 3
+
+struct PptpInCallReply {
+ __be16 callID;
+ __be16 peersCallID;
+ __u8 resultCode;
+ __u8 generalErrorCode;
+ __be16 packetWindow;
+ __be16 packetProcDelay;
+ __u16 reserved;
+};
+
+struct PptpInCallConnected {
+ __be16 peersCallID;
+ __u16 reserved;
+ __be32 connectSpeed;
+ __be16 packetWindow;
+ __be16 packetProcDelay;
+ __be32 callFramingType;
+};
+
+struct PptpClearCallRequest {
+ __be16 callID;
+ __u16 reserved;
+};
+
+struct PptpCallDisconnectNotify {
+ __be16 callID;
+ __u8 resultCode;
+ __u8 generalErrorCode;
+ __be16 causeCode;
+ __u16 reserved;
+ __u8 callStatistics[128];
+};
+
+struct PptpWanErrorNotify {
+ __be16 peersCallID;
+ __u16 reserved;
+ __be32 crcErrors;
+ __be32 framingErrors;
+ __be32 hardwareOverRuns;
+ __be32 bufferOverRuns;
+ __be32 timeoutErrors;
+ __be32 alignmentErrors;
+};
+
+struct PptpSetLinkInfo {
+ __be16 peersCallID;
+ __u16 reserved;
+ __be32 sendAccm;
+ __be32 recvAccm;
+};
+
+union pptp_ctrl_union {
+ struct PptpStartSessionRequest sreq;
+ struct PptpStartSessionReply srep;
+ struct PptpStopSessionRequest streq;
+ struct PptpStopSessionReply strep;
+ struct PptpOutCallRequest ocreq;
+ struct PptpOutCallReply ocack;
+ struct PptpInCallRequest icreq;
+ struct PptpInCallReply icack;
+ struct PptpInCallConnected iccon;
+ struct PptpClearCallRequest clrreq;
+ struct PptpCallDisconnectNotify disc;
+ struct PptpWanErrorNotify wanerr;
+ struct PptpSetLinkInfo setlink;
+};
+
+extern int
+(*ip_nat_pptp_hook_outbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+extern int
+(*ip_nat_pptp_hook_inbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+extern int
+(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *exp_orig,
+ struct ip_conntrack_expect *exp_reply);
+
+extern void
+(*ip_nat_pptp_hook_expectfn)(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp);
+#endif /* __KERNEL__ */
+#endif /* _CONNTRACK_PPTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
new file mode 100644
index 000000000000..8d090ef82f5f
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
@@ -0,0 +1,114 @@
+#ifndef _CONNTRACK_PROTO_GRE_H
+#define _CONNTRACK_PROTO_GRE_H
+#include <asm/byteorder.h>
+
+/* GRE PROTOCOL HEADER */
+
+/* GRE Version field */
+#define GRE_VERSION_1701 0x0
+#define GRE_VERSION_PPTP 0x1
+
+/* GRE Protocol field */
+#define GRE_PROTOCOL_PPTP 0x880B
+
+/* GRE Flags */
+#define GRE_FLAG_C 0x80
+#define GRE_FLAG_R 0x40
+#define GRE_FLAG_K 0x20
+#define GRE_FLAG_S 0x10
+#define GRE_FLAG_A 0x80
+
+#define GRE_IS_C(f) ((f)&GRE_FLAG_C)
+#define GRE_IS_R(f) ((f)&GRE_FLAG_R)
+#define GRE_IS_K(f) ((f)&GRE_FLAG_K)
+#define GRE_IS_S(f) ((f)&GRE_FLAG_S)
+#define GRE_IS_A(f) ((f)&GRE_FLAG_A)
+
+/* GRE is a mess: Four different standards */
+struct gre_hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u16 rec:3,
+ srr:1,
+ seq:1,
+ key:1,
+ routing:1,
+ csum:1,
+ version:3,
+ reserved:4,
+ ack:1;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u16 csum:1,
+ routing:1,
+ key:1,
+ seq:1,
+ srr:1,
+ rec:3,
+ ack:1,
+ reserved:4,
+ version:3;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __u16 protocol;
+};
+
+/* modified GRE header for PPTP */
+struct gre_hdr_pptp {
+ __u8 flags; /* bitfield */
+ __u8 version; /* should be GRE_VERSION_PPTP */
+ __u16 protocol; /* should be GRE_PROTOCOL_PPTP */
+ __u16 payload_len; /* size of ppp payload, not inc. gre header */
+ __u16 call_id; /* peer's call_id for this session */
+ __u32 seq; /* sequence number. Present if S==1 */
+ __u32 ack; /* seq number of highest packet recieved by */
+ /* sender in this session */
+};
+
+
+/* this is part of ip_conntrack */
+struct ip_ct_gre {
+ unsigned int stream_timeout;
+ unsigned int timeout;
+};
+
+#ifdef __KERNEL__
+struct ip_conntrack_expect;
+struct ip_conntrack;
+
+/* structure for original <-> reply keymap */
+struct ip_ct_gre_keymap {
+ struct list_head list;
+
+ struct ip_conntrack_tuple tuple;
+};
+
+/* add new tuple->key_reply pair to keymap */
+int ip_ct_gre_keymap_add(struct ip_conntrack *ct,
+ struct ip_conntrack_tuple *t,
+ int reply);
+
+/* delete keymap entries */
+void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct);
+
+
+/* get pointer to gre key, if present */
+static inline u_int32_t *gre_key(struct gre_hdr *greh)
+{
+ if (!greh->key)
+ return NULL;
+ if (greh->csum || greh->routing)
+ return (u_int32_t *) (greh+sizeof(*greh)+4);
+ return (u_int32_t *) (greh+sizeof(*greh));
+}
+
+/* get pointer ot gre csum, if present */
+static inline u_int16_t *gre_csum(struct gre_hdr *greh)
+{
+ if (!greh->csum)
+ return NULL;
+ return (u_int16_t *) (greh+sizeof(*greh));
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _CONNTRACK_PROTO_GRE_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
index b6b99be8632a..2c76b879e3dc 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
@@ -52,6 +52,9 @@ struct ip_conntrack_protocol
int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa,
const struct ip_conntrack *ct);
+ /* convert nfnetlink attributes to protoinfo */
+ int (*from_nfattr)(struct nfattr *tb[], struct ip_conntrack *ct);
+
int (*tuple_to_nfattr)(struct sk_buff *skb,
const struct ip_conntrack_tuple *t);
int (*nfattr_to_tuple)(struct nfattr *tb[],
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
index c33f0b5e0d0a..3232db11a4e5 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -1,6 +1,8 @@
#ifndef _IP_CONNTRACK_TUPLE_H
#define _IP_CONNTRACK_TUPLE_H
+#include <linux/types.h>
+
/* A `tuple' is a structure containing the information to uniquely
identify a connection. ie. if two packets have the same tuple, they
are in the same connection; if not, they are not.
@@ -17,7 +19,7 @@ union ip_conntrack_manip_proto
u_int16_t all;
struct {
- u_int16_t port;
+ __be16 port;
} tcp;
struct {
u_int16_t port;
@@ -28,6 +30,9 @@ union ip_conntrack_manip_proto
struct {
u_int16_t port;
} sctp;
+ struct {
+ __be16 key; /* key is 32bit, pptp only uses 16 */
+ } gre;
};
/* The manipulable part of the tuple. */
@@ -61,6 +66,10 @@ struct ip_conntrack_tuple
struct {
u_int16_t port;
} sctp;
+ struct {
+ __be16 key; /* key is 32bit,
+ * pptp only uses 16 */
+ } gre;
} u;
/* The protocol. */
diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index e201ec6e9905..41a107de17cf 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -58,10 +58,6 @@ extern rwlock_t ip_nat_lock;
struct ip_nat_info
{
struct list_head bysource;
-
- /* Helper (NULL if none). */
- struct ip_nat_helper *helper;
-
struct ip_nat_seq seq[IP_CT_DIR_MAX];
};
diff --git a/include/linux/netfilter_ipv4/ip_nat_core.h b/include/linux/netfilter_ipv4/ip_nat_core.h
index 3b50eb91f007..30db23f06b03 100644
--- a/include/linux/netfilter_ipv4/ip_nat_core.h
+++ b/include/linux/netfilter_ipv4/ip_nat_core.h
@@ -5,16 +5,14 @@
/* This header used to share core functionality between the standalone
NAT module, and the compatibility layer's use of NAT for masquerading. */
-extern int ip_nat_init(void);
-extern void ip_nat_cleanup(void);
-extern unsigned int nat_packet(struct ip_conntrack *ct,
+extern unsigned int ip_nat_packet(struct ip_conntrack *ct,
enum ip_conntrack_info conntrackinfo,
unsigned int hooknum,
struct sk_buff **pskb);
-extern int icmp_reply_translation(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_nat_manip_type manip,
- enum ip_conntrack_dir dir);
+extern int ip_nat_icmp_reply_translation(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_nat_manip_type manip,
+ enum ip_conntrack_dir dir);
#endif /* _IP_NAT_CORE_H */
diff --git a/include/linux/netfilter_ipv4/ip_nat_pptp.h b/include/linux/netfilter_ipv4/ip_nat_pptp.h
new file mode 100644
index 000000000000..eaf66c2e8f93
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_nat_pptp.h
@@ -0,0 +1,11 @@
+/* PPTP constants and structs */
+#ifndef _NAT_PPTP_H
+#define _NAT_PPTP_H
+
+/* conntrack private data */
+struct ip_nat_pptp {
+ u_int16_t pns_call_id; /* NAT'ed PNS call id */
+ u_int16_t pac_call_id; /* NAT'ed PAC call id */
+};
+
+#endif /* _NAT_PPTP_H */
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 58c72a52dc65..59f70b34e029 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -455,6 +455,9 @@ extern unsigned int ip6t_do_table(struct sk_buff **pskb,
/* Check for an extension */
extern int ip6t_ext_hdr(u8 nexthdr);
+/* find specified header and get offset to it */
+extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+ u8 target);
#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 167518668936..ba25ca874c20 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -15,10 +15,12 @@
#define NETLINK_ISCSI 8 /* Open-iSCSI */
#define NETLINK_AUDIT 9 /* auditing */
#define NETLINK_FIB_LOOKUP 10
+#define NETLINK_CONNECTOR 11
#define NETLINK_NETFILTER 12 /* netfilter subsystem */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
+#define NETLINK_GENERIC 16
#define MAX_LINKS 32
@@ -129,7 +131,7 @@ extern struct sock *netlink_kernel_create(int unit, unsigned int groups, void (*
extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
- __u32 group, unsigned int __nocast allocation);
+ __u32 group, gfp_t allocation);
extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
extern int netlink_register_notifier(struct notifier_block *nb);
extern int netlink_unregister_notifier(struct notifier_block *nb);
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 5ade54a78dbb..ca5a8733000f 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -86,7 +86,7 @@ static inline void netpoll_poll_unlock(void *have)
#else
#define netpoll_rx(a) 0
-#define netpoll_poll_lock(a) 0
+#define netpoll_poll_lock(a) NULL
#define netpoll_poll_unlock(a)
#endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 9a6047ff1b25..325fe7ae49bb 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -41,6 +41,10 @@
#define NFS_MAX_FILE_IO_BUFFER_SIZE 32768
#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096
+/* Default timeout values */
+#define NFS_MAX_UDP_TIMEOUT (60*HZ)
+#define NFS_MAX_TCP_TIMEOUT (600*HZ)
+
/*
* superblock magic number for NFS
*/
@@ -137,6 +141,7 @@ struct nfs_inode {
unsigned long attrtimeo_timestamp;
__u64 change_attr; /* v4 only */
+ unsigned long last_updated;
/* "Generation counter" for the attribute cache. This is
* bumped whenever we update the metadata on the
* server.
@@ -236,13 +241,17 @@ static inline int nfs_caches_unstable(struct inode *inode)
return atomic_read(&NFS_I(inode)->data_updates) != 0;
}
+static inline void nfs_mark_for_revalidate(struct inode *inode)
+{
+ spin_lock(&inode->i_lock);
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+ spin_unlock(&inode->i_lock);
+}
+
static inline void NFS_CACHEINV(struct inode *inode)
{
- if (!nfs_caches_unstable(inode)) {
- spin_lock(&inode->i_lock);
- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
- spin_unlock(&inode->i_lock);
- }
+ if (!nfs_caches_unstable(inode))
+ nfs_mark_for_revalidate(inode);
}
static inline int nfs_server_capable(struct inode *inode, int cap)
@@ -276,7 +285,7 @@ static inline long nfs_save_change_attribute(struct inode *inode)
static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long chattr)
{
return !nfs_caches_unstable(inode)
- && chattr == NFS_I(inode)->cache_change_attribute;
+ && time_after_eq(chattr, NFS_I(inode)->cache_change_attribute);
}
/*
@@ -286,6 +295,7 @@ extern void nfs_zap_caches(struct inode *);
extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
struct nfs_fattr *);
extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
+extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int nfs_permission(struct inode *, int, struct nameidata *);
extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *);
@@ -312,6 +322,12 @@ extern void nfs_file_clear_open_context(struct file *filp);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/
+static inline void nfs_fattr_init(struct nfs_fattr *fattr)
+{
+ fattr->valid = 0;
+ fattr->time_start = jiffies;
+}
+
/*
* linux/fs/nfs/file.c
*/
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a2bf6914ff1b..40718669b9c8 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -41,7 +41,7 @@ struct nfs_fattr {
__u32 bitmap[2]; /* NFSv4 returned attribute bitmap */
__u64 change_attr; /* NFSv4 change attribute */
__u64 pre_change_attr;/* pre-op NFSv4 change attribute */
- unsigned long timestamp;
+ unsigned long time_start;
};
#define NFS_ATTR_WCC 0x0001 /* pre-op WCC data */
@@ -96,12 +96,13 @@ struct nfs4_change_info {
u64 after;
};
+struct nfs_seqid;
/*
* Arguments to the open call.
*/
struct nfs_openargs {
const struct nfs_fh * fh;
- __u32 seqid;
+ struct nfs_seqid * seqid;
int open_flags;
__u64 clientid;
__u32 id;
@@ -123,6 +124,7 @@ struct nfs_openres {
struct nfs4_change_info cinfo;
__u32 rflags;
struct nfs_fattr * f_attr;
+ struct nfs_fattr * dir_attr;
const struct nfs_server *server;
int delegation_type;
nfs4_stateid delegation;
@@ -136,7 +138,7 @@ struct nfs_openres {
struct nfs_open_confirmargs {
const struct nfs_fh * fh;
nfs4_stateid stateid;
- __u32 seqid;
+ struct nfs_seqid * seqid;
};
struct nfs_open_confirmres {
@@ -148,13 +150,16 @@ struct nfs_open_confirmres {
*/
struct nfs_closeargs {
struct nfs_fh * fh;
- nfs4_stateid stateid;
- __u32 seqid;
+ nfs4_stateid * stateid;
+ struct nfs_seqid * seqid;
int open_flags;
+ const u32 * bitmask;
};
struct nfs_closeres {
nfs4_stateid stateid;
+ struct nfs_fattr * fattr;
+ const struct nfs_server *server;
};
/*
* * Arguments to the lock,lockt, and locku call.
@@ -164,30 +169,19 @@ struct nfs_lowner {
u32 id;
};
-struct nfs_open_to_lock {
- __u32 open_seqid;
- nfs4_stateid open_stateid;
- __u32 lock_seqid;
- struct nfs_lowner lock_owner;
-};
-
-struct nfs_exist_lock {
- nfs4_stateid stateid;
- __u32 seqid;
-};
-
struct nfs_lock_opargs {
+ struct nfs_seqid * lock_seqid;
+ nfs4_stateid * lock_stateid;
+ struct nfs_seqid * open_seqid;
+ nfs4_stateid * open_stateid;
+ struct nfs_lowner lock_owner;
__u32 reclaim;
__u32 new_lock_owner;
- union {
- struct nfs_open_to_lock *open_lock;
- struct nfs_exist_lock *exist_lock;
- } u;
};
struct nfs_locku_opargs {
- __u32 seqid;
- nfs4_stateid stateid;
+ struct nfs_seqid * seqid;
+ nfs4_stateid * stateid;
};
struct nfs_lockargs {
@@ -262,6 +256,7 @@ struct nfs_writeargs {
enum nfs3_stable_how stable;
unsigned int pgbase;
struct page ** pages;
+ const u32 * bitmask;
};
struct nfs_writeverf {
@@ -273,6 +268,7 @@ struct nfs_writeres {
struct nfs_fattr * fattr;
struct nfs_writeverf * verf;
__u32 count;
+ const struct nfs_server *server;
};
/*
@@ -550,6 +546,7 @@ struct nfs4_create_res {
struct nfs_fh * fh;
struct nfs_fattr * fattr;
struct nfs4_change_info dir_cinfo;
+ struct nfs_fattr * dir_fattr;
};
struct nfs4_fsinfo_arg {
@@ -571,8 +568,17 @@ struct nfs4_link_arg {
const struct nfs_fh * fh;
const struct nfs_fh * dir_fh;
const struct qstr * name;
+ const u32 * bitmask;
+};
+
+struct nfs4_link_res {
+ const struct nfs_server * server;
+ struct nfs_fattr * fattr;
+ struct nfs4_change_info cinfo;
+ struct nfs_fattr * dir_attr;
};
+
struct nfs4_lookup_arg {
const struct nfs_fh * dir_fh;
const struct qstr * name;
@@ -619,6 +625,13 @@ struct nfs4_readlink {
struct nfs4_remove_arg {
const struct nfs_fh * fh;
const struct qstr * name;
+ const u32 * bitmask;
+};
+
+struct nfs4_remove_res {
+ const struct nfs_server * server;
+ struct nfs4_change_info cinfo;
+ struct nfs_fattr * dir_attr;
};
struct nfs4_rename_arg {
@@ -626,11 +639,15 @@ struct nfs4_rename_arg {
const struct nfs_fh * new_dir;
const struct qstr * old_name;
const struct qstr * new_name;
+ const u32 * bitmask;
};
struct nfs4_rename_res {
+ const struct nfs_server * server;
struct nfs4_change_info old_cinfo;
+ struct nfs_fattr * old_fattr;
struct nfs4_change_info new_cinfo;
+ struct nfs_fattr * new_fattr;
};
struct nfs4_setclientid {
@@ -722,7 +739,7 @@ struct nfs_rpc_ops {
int (*write) (struct nfs_write_data *);
int (*commit) (struct nfs_write_data *);
int (*create) (struct inode *, struct dentry *,
- struct iattr *, int);
+ struct iattr *, int, struct nameidata *);
int (*remove) (struct inode *, struct qstr *);
int (*unlink_setup) (struct rpc_message *,
struct dentry *, struct qstr *);
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 4d24d65c0e88..8903688890ce 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -438,17 +438,22 @@ extern int nfsd4_process_open1(struct nfsd4_open *open);
extern int nfsd4_process_open2(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open *open);
extern int nfsd4_open_confirm(struct svc_rqst *rqstp,
- struct svc_fh *current_fh, struct nfsd4_open_confirm *oc);
+ struct svc_fh *current_fh, struct nfsd4_open_confirm *oc,
+ struct nfs4_stateowner **);
extern int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct nfsd4_close *close);
+ struct nfsd4_close *close,
+ struct nfs4_stateowner **replay_owner);
extern int nfsd4_open_downgrade(struct svc_rqst *rqstp,
- struct svc_fh *current_fh, struct nfsd4_open_downgrade *od);
+ struct svc_fh *current_fh, struct nfsd4_open_downgrade *od,
+ struct nfs4_stateowner **replay_owner);
extern int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct nfsd4_lock *lock);
+ struct nfsd4_lock *lock,
+ struct nfs4_stateowner **replay_owner);
extern int nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh,
struct nfsd4_lockt *lockt);
extern int nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct nfsd4_locku *locku);
+ struct nfsd4_locku *locku,
+ struct nfs4_stateowner **replay_owner);
extern int
nfsd4_release_lockowner(struct svc_rqst *rqstp,
struct nfsd4_release_lockowner *rlockowner);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index d9a25647a295..ba6c310a055f 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -19,18 +19,19 @@
#define AS_EIO (__GFP_BITS_SHIFT + 0) /* IO error on async write */
#define AS_ENOSPC (__GFP_BITS_SHIFT + 1) /* ENOSPC on async write */
-static inline unsigned int __nocast mapping_gfp_mask(struct address_space * mapping)
+static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
- return mapping->flags & __GFP_BITS_MASK;
+ return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
}
/*
* This is non-atomic. Only to be used before the mapping is activated.
* Probably needs a barrier...
*/
-static inline void mapping_set_gfp_mask(struct address_space *m, int mask)
+static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
{
- m->flags = (m->flags & ~__GFP_BITS_MASK) | mask;
+ m->flags = (m->flags & ~(__force unsigned long)__GFP_BITS_MASK) |
+ (__force unsigned long)mask;
}
/*
@@ -69,7 +70,7 @@ extern struct page * find_lock_page(struct address_space *mapping,
extern struct page * find_trylock_page(struct address_space *mapping,
unsigned long index);
extern struct page * find_or_create_page(struct address_space *mapping,
- unsigned long index, unsigned int gfp_mask);
+ unsigned long index, gfp_t gfp_mask);
unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
unsigned int nr_pages, struct page **pages);
unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
@@ -92,9 +93,9 @@ extern int read_cache_pages(struct address_space *mapping,
struct list_head *pages, filler_t *filler, void *data);
int add_to_page_cache(struct page *page, struct address_space *mapping,
- unsigned long index, int gfp_mask);
+ unsigned long index, gfp_t gfp_mask);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
- unsigned long index, int gfp_mask);
+ unsigned long index, gfp_t gfp_mask);
extern void remove_from_page_cache(struct page *page);
extern void __remove_from_page_cache(struct page *page);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index bc4c40000c0d..7349058ed778 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -19,436 +19,10 @@
#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_ids.h b/include/linux/pci_ids.h
index ee0ab7a5f91b..71834f05504f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -185,6 +185,7 @@
#define PCI_DEVICE_ID_LSI_61C102 0x0901
#define PCI_DEVICE_ID_LSI_63C815 0x1000
#define PCI_DEVICE_ID_LSI_SAS1064 0x0050
+#define PCI_DEVICE_ID_LSI_SAS1064R 0x0411
#define PCI_DEVICE_ID_LSI_SAS1066 0x005E
#define PCI_DEVICE_ID_LSI_SAS1068 0x0054
#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C
@@ -392,6 +393,7 @@
#define PCI_DEVICE_ID_NS_87560_USB 0x0012
#define PCI_DEVICE_ID_NS_83815 0x0020
#define PCI_DEVICE_ID_NS_83820 0x0022
+#define PCI_DEVICE_ID_NS_SATURN 0x0035
#define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500
#define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501
#define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502
@@ -447,6 +449,10 @@
#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
#define PCI_DEVICE_ID_CIRRUS_7541 0x1204
+#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
+#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
+#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
+#define PCI_DEVICE_ID_CIRRUS_4281 0x6005
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a
@@ -487,6 +493,7 @@
#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060
#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_K8_NB 0x1100
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
#define PCI_DEVICE_ID_AMD_SCSI 0x2020
@@ -554,6 +561,7 @@
#define PCI_VENDOR_ID_DELL 0x1028
#define PCI_DEVICE_ID_DELL_RACIII 0x0008
#define PCI_DEVICE_ID_DELL_RAC4 0x0012
+#define PCI_DEVICE_ID_DELL_PERC5 0x0015
#define PCI_VENDOR_ID_MATROX 0x102B
#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
@@ -682,7 +690,9 @@
#define PCI_DEVICE_ID_SI_6326 0x6326
#define PCI_DEVICE_ID_SI_7001 0x7001
#define PCI_DEVICE_ID_SI_7012 0x7012
+#define PCI_DEVICE_ID_SI_7013 0x7013
#define PCI_DEVICE_ID_SI_7016 0x7016
+#define PCI_DEVICE_ID_SI_7018 0x7018
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005
@@ -713,10 +723,13 @@
#define PCI_DEVICE_ID_HP_DIVA_EVEREST 0x1282
#define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290
#define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301
+#define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a
+#define PCI_DEVICE_ID_HP_CISS 0x3210
#define PCI_DEVICE_ID_HP_CISSA 0x3220
#define PCI_DEVICE_ID_HP_CISSB 0x3222
-#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
#define PCI_DEVICE_ID_HP_CISSC 0x3230
+#define PCI_DEVICE_ID_HP_CISSD 0x3238
+#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
#define PCI_VENDOR_ID_PCTECH 0x1042
#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
@@ -760,6 +773,8 @@
#define PCI_DEVICE_ID_TI_TVP4010 0x3d04
#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
#define PCI_DEVICE_ID_TI_4450 0x8011
+#define PCI_DEVICE_ID_TI_XX21_XX11 0x8031
+#define PCI_DEVICE_ID_TI_X515 0x8036
#define PCI_DEVICE_ID_TI_1130 0xac12
#define PCI_DEVICE_ID_TI_1031 0xac13
#define PCI_DEVICE_ID_TI_1131 0xac15
@@ -776,12 +791,17 @@
#define PCI_DEVICE_ID_TI_4451 0xac42
#define PCI_DEVICE_ID_TI_4510 0xac44
#define PCI_DEVICE_ID_TI_4520 0xac46
+#define PCI_DEVICE_ID_TI_7510 0xac47
+#define PCI_DEVICE_ID_TI_7610 0xac48
+#define PCI_DEVICE_ID_TI_7410 0xac49
#define PCI_DEVICE_ID_TI_1410 0xac50
#define PCI_DEVICE_ID_TI_1420 0xac51
#define PCI_DEVICE_ID_TI_1451A 0xac52
#define PCI_DEVICE_ID_TI_1620 0xac54
#define PCI_DEVICE_ID_TI_1520 0xac55
#define PCI_DEVICE_ID_TI_1510 0xac56
+#define PCI_DEVICE_ID_TI_X620 0xac8d
+#define PCI_DEVICE_ID_TI_X420 0xac8e
#define PCI_VENDOR_ID_SONY 0x104d
#define PCI_DEVICE_ID_SONY_CXD3222 0x8039
@@ -967,6 +987,7 @@
#define PCI_DEVICE_ID_SUN_SABRE 0xa000
#define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001
#define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801
+#define PCI_DEVICE_ID_SUN_CASSINI 0xabba
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_640 0x0640
@@ -991,6 +1012,7 @@
#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351
#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e
#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
+#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474
#define PCI_VENDOR_ID_SIERRA 0x10a8
@@ -1109,6 +1131,9 @@
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083
+#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
+#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
+#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
#define PCI_VENDOR_ID_ASP 0x10cd
#define PCI_DEVICE_ID_ASP_ABP940 0x1200
@@ -1155,10 +1180,13 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064
#define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065
#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066
+#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069
#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a
#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS 0x0084
#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085
#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086
+#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089
+#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a
#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c
#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e
#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
@@ -1173,6 +1201,7 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4
#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5
#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6
+#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9
#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df
#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1
@@ -1180,6 +1209,7 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS 0x00e4
#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5
#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6
+#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea
#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
@@ -1230,6 +1260,7 @@
#define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1
#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4
#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc
+#define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM 0x01c1
#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3
#define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200
@@ -1249,7 +1280,8 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E
-#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x036F
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F
#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268
#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269
#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B
@@ -1334,6 +1366,13 @@
#define PCI_DEVICE_ID_REALTEK_8169 0x8169
#define PCI_VENDOR_ID_XILINX 0x10ee
+#define PCI_DEVICE_ID_RME_DIGI96 0x3fc0
+#define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1
+#define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2
+#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
#define PCI_DEVICE_ID_TURBOPAM 0x4020
#define PCI_VENDOR_ID_TRUEVISION 0x10fa
@@ -1809,6 +1848,14 @@
#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969
#define PCI_DEVICE_ID_ESS_ESS1978 0x1978
+#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988
+#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989
+#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990
+#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992
+#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998
+#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999
+#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a
+#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b
#define PCI_VENDOR_ID_SATSAGEM 0x1267
#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016
@@ -1968,6 +2015,9 @@
#define PCI_DEVICE_ID_LMC_SSI 0x0005
#define PCI_DEVICE_ID_LMC_T1 0x0006
+#define PCI_VENDOR_ID_MARIAN 0x1382
+#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048
+
#define PCI_VENDOR_ID_NETGEAR 0x1385
#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
#define PCI_DEVICE_ID_NETGEAR_GA622 0x622a
@@ -2056,6 +2106,10 @@
#define PCI_VENDOR_ID_TIMEDIA 0x1409
#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
+#define PCI_VENDOR_ID_ICE 0x1412
+#define PCI_DEVICE_ID_ICE_1712 0x1712
+#define PCI_DEVICE_ID_VT1724 0x1724
+
#define PCI_VENDOR_ID_OXSEMI 0x1415
#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403
#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
@@ -2145,7 +2199,12 @@
#define PCI_DEVICE_ID_ENE_1211 0x1211
#define PCI_DEVICE_ID_ENE_1225 0x1225
#define PCI_DEVICE_ID_ENE_1410 0x1410
+#define PCI_DEVICE_ID_ENE_710 0x1411
+#define PCI_DEVICE_ID_ENE_712 0x1412
#define PCI_DEVICE_ID_ENE_1420 0x1420
+#define PCI_DEVICE_ID_ENE_720 0x1421
+#define PCI_DEVICE_ID_ENE_722 0x1422
+
#define PCI_VENDOR_ID_CHELSIO 0x1425
#define PCI_VENDOR_ID_MIPS 0x153f
@@ -2212,6 +2271,9 @@
#define PCI_VENDOR_ID_INFINICON 0x1820
+#define PCI_VENDOR_ID_SITECOM 0x182d
+#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069
+
#define PCI_VENDOR_ID_TOPSPIN 0x1867
#define PCI_VENDOR_ID_TDI 0x192E
@@ -2536,6 +2598,7 @@
#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192
#define PCI_DEVICE_ID_INTEL_440MX 0x7195
+#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196
#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198
#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199
#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a
@@ -2634,6 +2697,7 @@
#define PCI_SUBVENDOR_ID_EXSYS 0xd84d
#define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014
+#define PCI_SUBDEVICE_ID_EXSYS_4055 0x4055
#define PCI_VENDOR_ID_TIGERJET 0xe159
#define PCI_DEVICE_ID_TIGERJET_300 0x0001
@@ -2642,6 +2706,11 @@
#define PCI_VENDOR_ID_TTTECH 0x0357
#define PCI_DEVICE_ID_TTTECH_MC322 0x000A
+#define PCI_VENDOR_ID_XILINX_RME 0xea60
+#define PCI_DEVICE_ID_RME_DIGI32 0x9896
+#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
+#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
+
#define PCI_VENDOR_ID_ARK 0xedd8
#define PCI_DEVICE_ID_ARK_STING 0xa091
#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
new file mode 100644
index 000000000000..e2a089b051ed
--- /dev/null
+++ b/include/linux/pci_regs.h
@@ -0,0 +1,448 @@
+/*
+ * 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/pktcdvd.h b/include/linux/pktcdvd.h
index 4b32bce9a289..2c177e4c8f22 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -166,6 +166,9 @@ struct packet_iosched
/*
* 32 buffers of 2048 bytes
*/
+#if (PAGE_SIZE % CD_FRAMESIZE) != 0
+#error "PAGE_SIZE must be a multiple of CD_FRAMESIZE"
+#endif
#define PACKET_MAX_SIZE 32
#define PAGES_PER_PACKET (PACKET_MAX_SIZE * CD_FRAMESIZE / PAGE_SIZE)
#define PACKET_MAX_SECTORS (PACKET_MAX_SIZE * CD_FRAMESIZE >> 9)
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 4caedddaa033..4bc241290c24 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -71,11 +71,11 @@ posix_acl_release(struct posix_acl *acl)
/* posix_acl.c */
-extern struct posix_acl *posix_acl_alloc(int, unsigned int __nocast);
-extern struct posix_acl *posix_acl_clone(const struct posix_acl *, unsigned int __nocast);
+extern struct posix_acl *posix_acl_alloc(int, gfp_t);
+extern struct posix_acl *posix_acl_clone(const struct posix_acl *, gfp_t);
extern int posix_acl_valid(const struct posix_acl *);
extern int posix_acl_permission(struct inode *, const struct posix_acl *, int);
-extern struct posix_acl *posix_acl_from_mode(mode_t, unsigned int __nocast);
+extern struct posix_acl *posix_acl_from_mode(mode_t, gfp_t);
extern int posix_acl_equiv_mode(const struct posix_acl *, mode_t *);
extern int posix_acl_create_masq(struct posix_acl *, mode_t *);
extern int posix_acl_chmod_masq(struct posix_acl *, mode_t);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 8081a281fa5e..9f0f9281f42a 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -24,7 +24,7 @@
struct radix_tree_root {
unsigned int height;
- int gfp_mask;
+ gfp_t gfp_mask;
struct radix_tree_node *rnode;
};
@@ -50,7 +50,7 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long);
unsigned int
radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
unsigned long first_index, unsigned int max_items);
-int radix_tree_preload(int gfp_mask);
+int radix_tree_preload(gfp_t gfp_mask);
void radix_tree_init(void);
void *radix_tree_tag_set(struct radix_tree_root *root,
unsigned long index, int tag);
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 4bf1659f8aa8..9de99198caf1 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -7,7 +7,7 @@
#define BITMAP_H 1
#define BITMAP_MAJOR 3
-#define BITMAP_MINOR 38
+#define BITMAP_MINOR 39
/*
* in-memory bitmap:
@@ -147,8 +147,9 @@ typedef struct bitmap_super_s {
__u32 state; /* 48 bitmap state information */
__u32 chunksize; /* 52 the bitmap chunk size in bytes */
__u32 daemon_sleep; /* 56 seconds between disk flushes */
+ __u32 write_behind; /* 60 number of outstanding write-behind writes */
- __u8 pad[256 - 60]; /* set to zero */
+ __u8 pad[256 - 64]; /* set to zero */
} bitmap_super_t;
/* notes:
@@ -226,6 +227,9 @@ struct bitmap {
unsigned long flags;
+ unsigned long max_write_behind; /* write-behind mode */
+ atomic_t behind_writes;
+
/*
* the bitmap daemon - periodically wakes up and sweeps the bitmap
* file, cleaning up bits and flushing out pages to disk as necessary
@@ -260,9 +264,10 @@ int bitmap_setallbits(struct bitmap *bitmap);
void bitmap_write_all(struct bitmap *bitmap);
/* these are exported */
-int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
-void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
- int success);
+int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
+ unsigned long sectors, int behind);
+void bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
+ unsigned long sectors, int success, int behind);
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
void bitmap_close_sync(struct bitmap *bitmap);
diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h
index e04c4fe45b53..7eaf290e10e7 100644
--- a/include/linux/raid/linear.h
+++ b/include/linux/raid/linear.h
@@ -14,8 +14,8 @@ typedef struct dev_info dev_info_t;
struct linear_private_data
{
dev_info_t **hash_table;
- dev_info_t *smallest;
- int nr_zones;
+ sector_t hash_spacing;
+ int preshift; /* shift before dividing by hash_spacing */
dev_info_t disks[0];
};
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 8c14ba565a45..ebce949b1443 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -86,70 +86,6 @@ typedef struct mdk_rdev_s mdk_rdev_t;
#define MAX_CHUNK_SIZE (4096*1024)
/*
- * default readahead
- */
-
-static inline int disk_faulty(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_FAULTY);
-}
-
-static inline int disk_active(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_ACTIVE);
-}
-
-static inline int disk_sync(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_SYNC);
-}
-
-static inline int disk_spare(mdp_disk_t * d)
-{
- return !disk_sync(d) && !disk_active(d) && !disk_faulty(d);
-}
-
-static inline int disk_removed(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_REMOVED);
-}
-
-static inline void mark_disk_faulty(mdp_disk_t * d)
-{
- d->state |= (1 << MD_DISK_FAULTY);
-}
-
-static inline void mark_disk_active(mdp_disk_t * d)
-{
- d->state |= (1 << MD_DISK_ACTIVE);
-}
-
-static inline void mark_disk_sync(mdp_disk_t * d)
-{
- d->state |= (1 << MD_DISK_SYNC);
-}
-
-static inline void mark_disk_spare(mdp_disk_t * d)
-{
- d->state = 0;
-}
-
-static inline void mark_disk_removed(mdp_disk_t * d)
-{
- d->state = (1 << MD_DISK_FAULTY) | (1 << MD_DISK_REMOVED);
-}
-
-static inline void mark_disk_inactive(mdp_disk_t * d)
-{
- d->state &= ~(1 << MD_DISK_ACTIVE);
-}
-
-static inline void mark_disk_nonsync(mdp_disk_t * d)
-{
- d->state &= ~(1 << MD_DISK_SYNC);
-}
-
-/*
* MD's 'extended' device
*/
struct mdk_rdev_s
@@ -166,6 +102,7 @@ struct mdk_rdev_s
int sb_loaded;
sector_t data_offset; /* start of data in array */
sector_t sb_offset;
+ int sb_size; /* bytes in the superblock */
int preferred_minor; /* autorun support */
/* A device can be in one of three states based on two flags:
@@ -181,6 +118,9 @@ struct mdk_rdev_s
int faulty; /* if faulty do not issue IO requests */
int in_sync; /* device is a full member of the array */
+ unsigned long flags; /* Should include faulty and in_sync here. */
+#define WriteMostly 4 /* Avoid reading if at all possible */
+
int desc_nr; /* descriptor index in the superblock */
int raid_disk; /* role of device in array */
int saved_raid_disk; /* role that device used to have in the
@@ -272,12 +212,19 @@ struct mddev_s
atomic_t writes_pending;
request_queue_t *queue; /* for plugging ... */
+ atomic_t write_behind; /* outstanding async IO */
+ unsigned int max_write_behind; /* 0 = sync */
+
struct bitmap *bitmap; /* the bitmap for the device */
struct file *bitmap_file; /* the bitmap file */
long bitmap_offset; /* offset from superblock of
* start of bitmap. May be
* negative, but not '0'
*/
+ long default_bitmap_offset; /* this is the offset to use when
+ * hot-adding a bitmap. It should
+ * eventually be settable by sysfs.
+ */
struct list_head all_mddevs;
};
@@ -314,6 +261,12 @@ struct mdk_personality_s
int (*resize) (mddev_t *mddev, sector_t sectors);
int (*reshape) (mddev_t *mddev, int raid_disks);
int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
+ /* quiesce moves between quiescence states
+ * 0 - fully active
+ * 1 - no new requests allowed
+ * others - reserved
+ */
+ void (*quiesce) (mddev_t *mddev, int state);
};
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h
index dc65cd435494..c100fa5d4bfa 100644
--- a/include/linux/raid/md_p.h
+++ b/include/linux/raid/md_p.h
@@ -79,6 +79,11 @@
#define MD_DISK_SYNC 2 /* disk is in sync with the raid set */
#define MD_DISK_REMOVED 3 /* disk is in sync with the raid set */
+#define MD_DISK_WRITEMOSTLY 9 /* disk is "write-mostly" is RAID1 config.
+ * read requests will only be sent here in
+ * dire need
+ */
+
typedef struct mdp_device_descriptor_s {
__u32 number; /* 0 Device number in the entire set */
__u32 major; /* 1 Device major number */
@@ -193,7 +198,7 @@ struct mdp_superblock_1 {
__u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
__u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */
- __u32 layout; /* only for raid5 currently */
+ __u32 layout; /* only for raid5 and raid10 currently */
__u64 size; /* used size of component devices, in 512byte sectors */
__u32 chunksize; /* in 512byte sectors */
@@ -212,7 +217,9 @@ struct mdp_superblock_1 {
__u32 dev_number; /* permanent identifier of this device - not role in raid */
__u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */
__u8 device_uuid[16]; /* user-space setable, ignored by kernel */
- __u8 pad2[64-56]; /* set to 0 when writing */
+ __u8 devflags; /* per-device flags. Only one defined...*/
+#define WriteMostly1 1 /* mask for writemostly flag in above */
+ __u8 pad2[64-57]; /* set to 0 when writing */
/* array state information - 64 bytes */
__u64 utime; /* 40 bits second, 24 btes microseconds */
@@ -231,5 +238,10 @@ struct mdp_superblock_1 {
__u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
};
+/* feature_map bits */
+#define MD_FEATURE_BITMAP_OFFSET 1
+
+#define MD_FEATURE_ALL 1
+
#endif
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 9d93cf12e890..60e19b667548 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -80,6 +80,9 @@ struct r1bio_s {
atomic_t remaining; /* 'have we finished' count,
* used from IRQ handlers
*/
+ atomic_t behind_remaining; /* number of write-behind ios remaining
+ * in this BehindIO request
+ */
sector_t sector;
int sectors;
unsigned long state;
@@ -107,4 +110,14 @@ struct r1bio_s {
#define R1BIO_Uptodate 0
#define R1BIO_IsSync 1
#define R1BIO_Degraded 2
+#define R1BIO_BehindIO 3
+/* For write-behind requests, we call bi_end_io when
+ * the last non-write-behind device completes, providing
+ * any write was successful. Otherwise we call when
+ * any write-behind write succeeds, otherwise we call
+ * with failure when last write completes (and all failed).
+ * Record that bi_end_io was called with this flag...
+ */
+#define R1BIO_Returned 4
+
#endif
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index d63ddcb4afad..176fc653c284 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -134,6 +134,7 @@ struct stripe_head {
unsigned long state; /* state flags */
atomic_t count; /* nr of active thread/requests */
spinlock_t lock;
+ int bm_seq; /* sequence number for bitmap flushes */
struct r5dev {
struct bio req;
struct bio_vec vec;
@@ -165,12 +166,13 @@ struct stripe_head {
/*
* Stripe state
*/
-#define STRIPE_ERROR 1
#define STRIPE_HANDLE 2
#define STRIPE_SYNCING 3
#define STRIPE_INSYNC 4
#define STRIPE_PREREAD_ACTIVE 5
#define STRIPE_DELAYED 6
+#define STRIPE_DEGRADED 7
+#define STRIPE_BIT_DELAY 8
/*
* Plugging:
@@ -210,10 +212,20 @@ struct raid5_private_data {
struct list_head handle_list; /* stripes needing handling */
struct list_head delayed_list; /* stripes that have plugged requests */
+ struct list_head bitmap_list; /* stripes delaying awaiting bitmap update */
atomic_t preread_active_stripes; /* stripes with scheduled io */
char cache_name[20];
kmem_cache_t *slab_cache; /* for allocating stripes */
+
+ int seq_flush, seq_write;
+ int quiesce;
+
+ int fullsync; /* set to 1 if a full sync is needed,
+ * (fresh device added).
+ * Cleared when a sync completes.
+ */
+
/*
* Free stripes pool
*/
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index fd276adf0fd5..70191a5a148f 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)
@@ -94,6 +94,7 @@ struct rcu_data {
long batch; /* Batch # for current RCU batch */
struct rcu_head *nxtlist;
struct rcu_head **nxttail;
+ long count; /* # of queued items */
struct rcu_head *curlist;
struct rcu_head **curtail;
struct rcu_head *donelist;
diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h
new file mode 100644
index 000000000000..e1adbba14b67
--- /dev/null
+++ b/include/linux/rcuref.h
@@ -0,0 +1,220 @@
+/*
+ * 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/reboot.h b/include/linux/reboot.h
index 3b3266ff1a95..7ab2cdb83ef0 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -59,6 +59,10 @@ extern void machine_crash_shutdown(struct pt_regs *);
* Architecture independent implemenations of sys_reboot commands.
*/
+extern void kernel_restart_prepare(char *cmd);
+extern void kernel_halt_prepare(void);
+extern void kernel_power_off_prepare(void);
+
extern void kernel_restart(char *cmd);
extern void kernel_halt(void);
extern void kernel_power_off(void);
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 17e458e17e2b..001ab82df051 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1972,7 +1972,7 @@ extern struct address_space_operations reiserfs_address_space_operations;
/* fix_nodes.c */
#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s);
+void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s);
void reiserfs_kfree(const void *vp, size_t size, struct super_block *s);
#else
static inline void *reiserfs_kmalloc(size_t size, int flags,
@@ -2097,7 +2097,7 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *,
b_blocknr_t, int for_unformatted);
int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t *, int,
int);
-extern inline int reiserfs_new_form_blocknrs(struct tree_balance *tb,
+static inline int reiserfs_new_form_blocknrs(struct tree_balance *tb,
b_blocknr_t * new_blocknrs,
int amount_needed)
{
@@ -2113,7 +2113,7 @@ extern inline int reiserfs_new_form_blocknrs(struct tree_balance *tb,
0);
}
-extern inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
+static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
*th, struct inode *inode,
b_blocknr_t * new_blocknrs,
struct path *path, long block)
@@ -2130,7 +2130,7 @@ extern inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
}
#ifdef REISERFS_PREALLOCATE
-extern inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle
+static inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle
*th, struct inode *inode,
b_blocknr_t * new_blocknrs,
struct path *path, long block)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index ea1b5f32ec5c..27519df0f987 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -107,19 +107,43 @@ extern unsigned long nr_iowait(void);
#include <asm/processor.h>
+/*
+ * Task state bitmask. NOTE! These bits are also
+ * encoded in fs/proc/array.c: get_task_state().
+ *
+ * We have two separate sets of flags: task->state
+ * is about runnability, while task->exit_state are
+ * about the task exiting. Confusing, but this way
+ * modifying one set can't modify the other one by
+ * mistake.
+ */
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_STOPPED 4
#define TASK_TRACED 8
+/* in tsk->exit_state */
#define EXIT_ZOMBIE 16
#define EXIT_DEAD 32
+/* in tsk->state again */
+#define TASK_NONINTERACTIVE 64
#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
#define set_task_state(tsk, state_value) \
set_mb((tsk)->state, (state_value))
+/*
+ * set_current_state() includes a barrier so that the write of current->state
+ * is correctly serialised wrt the caller's subsequent test of whether to
+ * actually sleep:
+ *
+ * set_current_state(TASK_UNINTERRUPTIBLE);
+ * if (do_i_need_to_sleep())
+ * schedule();
+ *
+ * If the caller does not need such serialisation then use __set_current_state()
+ */
#define __set_current_state(state_value) \
do { current->state = (state_value); } while (0)
#define set_current_state(state_value) \
@@ -202,6 +226,8 @@ extern int in_sched_functions(unsigned long addr);
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
extern signed long FASTCALL(schedule_timeout(signed long timeout));
+extern signed long schedule_timeout_interruptible(signed long timeout);
+extern signed long schedule_timeout_uninterruptible(signed long timeout);
asmlinkage void schedule(void);
struct namespace;
@@ -604,6 +630,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;
@@ -895,6 +926,8 @@ extern int task_curr(const task_t *p);
extern int idle_cpu(int cpu);
extern int sched_setscheduler(struct task_struct *, int, struct sched_param *);
extern task_t *idle_task(int cpu);
+extern task_t *curr_task(int cpu);
+extern void set_curr_task(int cpu, task_t *p);
void yield(void);
@@ -985,6 +1018,7 @@ extern int force_sig_info(int, struct siginfo *, struct task_struct *);
extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
extern int kill_pg_info(int, struct siginfo *, pid_t);
extern int kill_proc_info(int, struct siginfo *, pid_t);
+extern int kill_proc_info_as_uid(int, struct siginfo *, pid_t, uid_t, uid_t);
extern void do_notify_parent(struct task_struct *, int);
extern void force_sig(int, struct task_struct *);
extern void force_sig_specific(int, struct task_struct *);
diff --git a/include/linux/sdladrv.h b/include/linux/sdladrv.h
index 78f634007fc6..c85e103d5e7b 100644
--- a/include/linux/sdladrv.h
+++ b/include/linux/sdladrv.h
@@ -52,12 +52,8 @@ typedef struct sdlahw
extern int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len);
extern int sdla_down (sdlahw_t* hw);
-extern int sdla_inten (sdlahw_t* hw);
-extern int sdla_intde (sdlahw_t* hw);
-extern int sdla_intack (sdlahw_t* hw);
extern void S514_intack (sdlahw_t* hw, u32 int_status);
extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
-extern int sdla_intr (sdlahw_t* hw);
extern int sdla_mapmem (sdlahw_t* hw, unsigned long addr);
extern int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf,
unsigned len);
diff --git a/include/linux/security.h b/include/linux/security.h
index 7aab6ab7c57f..dac956ed98f0 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);
@@ -1240,7 +1210,7 @@ struct security_operations {
int (*socket_shutdown) (struct socket * sock, int how);
int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
- int (*sk_alloc_security) (struct sock *sk, int family, int priority);
+ int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
void (*sk_free_security) (struct sock *sk);
#endif /* CONFIG_SECURITY_NETWORK */
};
@@ -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)))
@@ -1983,6 +1907,11 @@ extern int register_security (struct security_operations *ops);
extern int unregister_security (struct security_operations *ops);
extern int mod_reg_security (const char *name, struct security_operations *ops);
extern int mod_unreg_security (const char *name, struct security_operations *ops);
+extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent, void *data,
+ struct file_operations *fops);
+extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent);
+extern void securityfs_remove(struct dentry *dentry);
#else /* CONFIG_SECURITY */
@@ -2171,6 +2100,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 +2117,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 +2124,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 +2137,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 +2144,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 +2157,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 +2165,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;
@@ -2727,8 +2634,7 @@ static inline int security_socket_getpeersec(struct socket *sock, char __user *o
return security_ops->socket_getpeersec(sock, optval, optlen, len);
}
-static inline int security_sk_alloc(struct sock *sk, int family,
- unsigned int __nocast priority)
+static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
{
return security_ops->sk_alloc_security(sk, family, priority);
}
@@ -2845,8 +2751,7 @@ static inline int security_socket_getpeersec(struct socket *sock, char __user *o
return -ENOPROTOOPT;
}
-static inline int security_sk_alloc(struct sock *sk, int family,
- unsigned int __nocast priority)
+static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
{
return 0;
}
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index d8a023d804d4..317a979b24de 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -30,6 +30,21 @@ struct plat_serial8250_port {
};
/*
+ * 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 9b12fe731612..27db8da43aa4 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -401,6 +401,9 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
#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 da7da9c0ed1b..b756935da9c8 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -155,8 +155,6 @@ struct skb_shared_info {
#define SKB_DATAREF_SHIFT 16
#define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
-extern struct timeval skb_tv_base;
-
struct skb_timeval {
u32 off_sec;
u32 off_usec;
@@ -173,9 +171,8 @@ enum {
* struct sk_buff - socket buffer
* @next: Next buffer in list
* @prev: Previous buffer in list
- * @list: List we are on
* @sk: Socket we are owned by
- * @tstamp: Time we arrived stored as offset to skb_tv_base
+ * @tstamp: Time we arrived
* @dev: Device we arrived on/are leaving by
* @input_dev: Device we arrived on
* @h: Transport layer header
@@ -192,6 +189,7 @@ enum {
* @cloned: Head may be cloned (check refcnt to be sure)
* @nohdr: Payload reference only, must not modify header
* @pkt_type: Packet class
+ * @fclone: skbuff clone status
* @ip_summed: Driver fed us an IP checksum
* @priority: Packet queueing priority
* @users: User count - see {datagram,tcp}.c
@@ -204,6 +202,7 @@ enum {
* @destructor: Destruct function
* @nfmark: Can be used for communication between hooks
* @nfct: Associated connection, if any
+ * @ipvs_property: skbuff is owned by ipvs
* @nfctinfo: Relationship of this skb to the connection
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
* @tc_index: Traffic control index
@@ -304,37 +303,37 @@ struct sk_buff {
extern void __kfree_skb(struct sk_buff *skb);
extern struct sk_buff *__alloc_skb(unsigned int size,
- unsigned int __nocast priority, int fclone);
+ gfp_t priority, int fclone);
static inline struct sk_buff *alloc_skb(unsigned int size,
- unsigned int __nocast priority)
+ gfp_t priority)
{
return __alloc_skb(size, priority, 0);
}
static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
- unsigned int __nocast priority)
+ gfp_t priority)
{
return __alloc_skb(size, priority, 1);
}
extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
unsigned int size,
- unsigned int __nocast priority);
+ gfp_t priority);
extern void kfree_skbmem(struct sk_buff *skb);
extern struct sk_buff *skb_clone(struct sk_buff *skb,
- unsigned int __nocast priority);
+ gfp_t priority);
extern struct sk_buff *skb_copy(const struct sk_buff *skb,
- unsigned int __nocast priority);
+ gfp_t priority);
extern struct sk_buff *pskb_copy(struct sk_buff *skb,
- unsigned int __nocast gfp_mask);
+ gfp_t gfp_mask);
extern int pskb_expand_head(struct sk_buff *skb,
int nhead, int ntail,
- unsigned int __nocast gfp_mask);
+ gfp_t gfp_mask);
extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
unsigned int headroom);
extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
int newheadroom, int newtailroom,
- unsigned int __nocast priority);
+ gfp_t priority);
extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad);
#define dev_kfree_skb(a) kfree_skb(a)
extern void skb_over_panic(struct sk_buff *skb, int len,
@@ -486,7 +485,7 @@ static inline int skb_shared(const struct sk_buff *skb)
* NULL is returned on a memory allocation failure.
*/
static inline struct sk_buff *skb_share_check(struct sk_buff *skb,
- unsigned int __nocast pri)
+ gfp_t pri)
{
might_sleep_if(pri & __GFP_WAIT);
if (skb_shared(skb)) {
@@ -518,7 +517,7 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb,
* %NULL is returned on a memory allocation failure.
*/
static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
- unsigned int __nocast pri)
+ gfp_t pri)
{
might_sleep_if(pri & __GFP_WAIT);
if (skb_cloned(skb)) {
@@ -1019,7 +1018,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
* %NULL is returned in there is no free memory.
*/
static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
if (likely(skb))
@@ -1132,8 +1131,8 @@ static inline int skb_can_coalesce(struct sk_buff *skb, int i,
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
*/
-extern int __skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp);
-static inline int skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp)
+extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
+static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
{
return __skb_linearize(skb, gfp);
}
@@ -1167,7 +1166,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;
@@ -1255,10 +1254,6 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *
{
stamp->tv_sec = skb->tstamp.off_sec;
stamp->tv_usec = skb->tstamp.off_usec;
- if (skb->tstamp.off_sec) {
- stamp->tv_sec += skb_tv_base.tv_sec;
- stamp->tv_usec += skb_tv_base.tv_usec;
- }
}
/**
@@ -1272,8 +1267,8 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *
*/
static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
{
- skb->tstamp.off_sec = stamp->tv_sec - skb_tv_base.tv_sec;
- skb->tstamp.off_usec = stamp->tv_usec - skb_tv_base.tv_usec;
+ skb->tstamp.off_sec = stamp->tv_sec;
+ skb->tstamp.off_usec = stamp->tv_usec;
}
extern void __net_timestamp(struct sk_buff *skb);
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 42a6bea58af3..09b9aa60063d 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -61,11 +61,11 @@ extern kmem_cache_t *kmem_cache_create(const char *, size_t, size_t, unsigned lo
void (*)(void *, kmem_cache_t *, unsigned long));
extern int kmem_cache_destroy(kmem_cache_t *);
extern int kmem_cache_shrink(kmem_cache_t *);
-extern void *kmem_cache_alloc(kmem_cache_t *, unsigned int __nocast);
+extern void *kmem_cache_alloc(kmem_cache_t *, gfp_t);
extern void kmem_cache_free(kmem_cache_t *, void *);
extern unsigned int kmem_cache_size(kmem_cache_t *);
extern const char *kmem_cache_name(kmem_cache_t *);
-extern kmem_cache_t *kmem_find_general_cachep(size_t size, unsigned int __nocast gfpflags);
+extern kmem_cache_t *kmem_find_general_cachep(size_t size, gfp_t gfpflags);
/* Size description struct for general caches. */
struct cache_sizes {
@@ -74,9 +74,9 @@ struct cache_sizes {
kmem_cache_t *cs_dmacachep;
};
extern struct cache_sizes malloc_sizes[];
-extern void *__kmalloc(size_t, unsigned int __nocast);
+extern void *__kmalloc(size_t, gfp_t);
-static inline void *kmalloc(size_t size, unsigned int __nocast flags)
+static inline void *kmalloc(size_t size, gfp_t flags)
{
if (__builtin_constant_p(size)) {
int i = 0;
@@ -99,7 +99,7 @@ found:
return __kmalloc(size, flags);
}
-extern void *kzalloc(size_t, unsigned int __nocast);
+extern void *kzalloc(size_t, gfp_t);
/**
* kcalloc - allocate memory for an array. The memory is set to zero.
@@ -107,7 +107,7 @@ extern void *kzalloc(size_t, unsigned int __nocast);
* @size: element size.
* @flags: the type of memory to allocate.
*/
-static inline void *kcalloc(size_t n, size_t size, unsigned int __nocast flags)
+static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
{
if (n != 0 && size > INT_MAX / n)
return NULL;
@@ -118,14 +118,14 @@ extern void kfree(const void *);
extern unsigned int ksize(const void *);
#ifdef CONFIG_NUMA
-extern void *kmem_cache_alloc_node(kmem_cache_t *, int flags, int node);
-extern void *kmalloc_node(size_t size, unsigned int __nocast flags, int node);
+extern void *kmem_cache_alloc_node(kmem_cache_t *, gfp_t flags, int node);
+extern void *kmalloc_node(size_t size, gfp_t flags, int node);
#else
-static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node)
+static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int node)
{
return kmem_cache_alloc(cachep, flags);
}
-static inline void *kmalloc_node(size_t size, unsigned int __nocast flags, int node)
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
return kmalloc(size, flags);
}
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index d6ba068719b6..cdc99a27840d 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -2,7 +2,48 @@
#define __LINUX_SPINLOCK_H
/*
- * include/linux/spinlock.h - generic locking declarations
+ * include/linux/spinlock.h - generic spinlock/rwlock declarations
+ *
+ * here's the role of the various spinlock/rwlock related include files:
+ *
+ * on SMP builds:
+ *
+ * asm/spinlock_types.h: contains the raw_spinlock_t/raw_rwlock_t and the
+ * initializers
+ *
+ * linux/spinlock_types.h:
+ * defines the generic type and initializers
+ *
+ * asm/spinlock.h: contains the __raw_spin_*()/etc. lowlevel
+ * implementations, mostly inline assembly code
+ *
+ * (also included on UP-debug builds:)
+ *
+ * linux/spinlock_api_smp.h:
+ * contains the prototypes for the _spin_*() APIs.
+ *
+ * linux/spinlock.h: builds the final spin_*() APIs.
+ *
+ * on UP builds:
+ *
+ * linux/spinlock_type_up.h:
+ * contains the generic, simplified UP spinlock type.
+ * (which is an empty structure on non-debug builds)
+ *
+ * linux/spinlock_types.h:
+ * defines the generic type and initializers
+ *
+ * linux/spinlock_up.h:
+ * contains the __raw_spin_*()/etc. version of UP
+ * builds. (which are NOPs on non-debug, non-preempt
+ * builds)
+ *
+ * (included on UP-non-debug builds:)
+ *
+ * linux/spinlock_api_up.h:
+ * builds the _spin_*() APIs.
+ *
+ * linux/spinlock.h: builds the final spin_*() APIs.
*/
#include <linux/config.h>
@@ -13,7 +54,6 @@
#include <linux/kernel.h>
#include <linux/stringify.h>
-#include <asm/processor.h> /* for cpu relax */
#include <asm/system.h>
/*
@@ -35,423 +75,84 @@
#define __lockfunc fastcall __attribute__((section(".spinlock.text")))
/*
- * If CONFIG_SMP is set, pull in the _raw_* definitions
+ * Pull the raw_spinlock_t and raw_rwlock_t definitions:
*/
-#ifdef CONFIG_SMP
-
-#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x))
-#include <asm/spinlock.h>
-
-int __lockfunc _spin_trylock(spinlock_t *lock);
-int __lockfunc _read_trylock(rwlock_t *lock);
-int __lockfunc _write_trylock(rwlock_t *lock);
-
-void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t);
-void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t);
-
-void __lockfunc _spin_unlock(spinlock_t *lock) __releases(spinlock_t);
-void __lockfunc _read_unlock(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _write_unlock(rwlock_t *lock) __releases(rwlock_t);
-
-unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) __acquires(spinlock_t);
-unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) __acquires(rwlock_t);
-unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) __acquires(rwlock_t);
-
-void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(spinlock_t);
-void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t);
-void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(rwlock_t);
-
-void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) __releases(spinlock_t);
-void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(spinlock_t);
-void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(spinlock_t);
-void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) __releases(rwlock_t);
-void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) __releases(rwlock_t);
-void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(rwlock_t);
-
-int __lockfunc _spin_trylock_bh(spinlock_t *lock);
-int __lockfunc generic_raw_read_trylock(rwlock_t *lock);
-int in_lock_functions(unsigned long addr);
-
-#else
+#include <linux/spinlock_types.h>
-#define in_lock_functions(ADDR) 0
+extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
-#if !defined(CONFIG_PREEMPT) && !defined(CONFIG_DEBUG_SPINLOCK)
-# define _atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
-# define ATOMIC_DEC_AND_LOCK
-#endif
-
-#ifdef CONFIG_DEBUG_SPINLOCK
-
-#define SPINLOCK_MAGIC 0x1D244B3C
-typedef struct {
- unsigned long magic;
- volatile unsigned long lock;
- volatile unsigned int babble;
- const char *module;
- char *owner;
- int oline;
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0}
-
-#define spin_lock_init(x) \
- do { \
- (x)->magic = SPINLOCK_MAGIC; \
- (x)->lock = 0; \
- (x)->babble = 5; \
- (x)->module = __FILE__; \
- (x)->owner = NULL; \
- (x)->oline = 0; \
- } while (0)
-
-#define CHECK_LOCK(x) \
- do { \
- if ((x)->magic != SPINLOCK_MAGIC) { \
- printk(KERN_ERR "%s:%d: spin_is_locked on uninitialized spinlock %p.\n", \
- __FILE__, __LINE__, (x)); \
- } \
- } while(0)
-
-#define _raw_spin_lock(x) \
- do { \
- CHECK_LOCK(x); \
- if ((x)->lock&&(x)->babble) { \
- (x)->babble--; \
- printk("%s:%d: spin_lock(%s:%p) already locked by %s/%d\n", \
- __FILE__,__LINE__, (x)->module, \
- (x), (x)->owner, (x)->oline); \
- } \
- (x)->lock = 1; \
- (x)->owner = __FILE__; \
- (x)->oline = __LINE__; \
- } while (0)
-
-/* without debugging, spin_is_locked on UP always says
- * FALSE. --> printk if already locked. */
-#define spin_is_locked(x) \
- ({ \
- CHECK_LOCK(x); \
- if ((x)->lock&&(x)->babble) { \
- (x)->babble--; \
- printk("%s:%d: spin_is_locked(%s:%p) already locked by %s/%d\n", \
- __FILE__,__LINE__, (x)->module, \
- (x), (x)->owner, (x)->oline); \
- } \
- 0; \
- })
-
-/* with debugging, assert_spin_locked() on UP does check
- * the lock value properly */
-#define assert_spin_locked(x) \
- ({ \
- CHECK_LOCK(x); \
- BUG_ON(!(x)->lock); \
- })
-
-/* without debugging, spin_trylock on UP always says
- * TRUE. --> printk if already locked. */
-#define _raw_spin_trylock(x) \
- ({ \
- CHECK_LOCK(x); \
- if ((x)->lock&&(x)->babble) { \
- (x)->babble--; \
- printk("%s:%d: spin_trylock(%s:%p) already locked by %s/%d\n", \
- __FILE__,__LINE__, (x)->module, \
- (x), (x)->owner, (x)->oline); \
- } \
- (x)->lock = 1; \
- (x)->owner = __FILE__; \
- (x)->oline = __LINE__; \
- 1; \
- })
-
-#define spin_unlock_wait(x) \
- do { \
- CHECK_LOCK(x); \
- if ((x)->lock&&(x)->babble) { \
- (x)->babble--; \
- printk("%s:%d: spin_unlock_wait(%s:%p) owned by %s/%d\n", \
- __FILE__,__LINE__, (x)->module, (x), \
- (x)->owner, (x)->oline); \
- }\
- } while (0)
-
-#define _raw_spin_unlock(x) \
- do { \
- CHECK_LOCK(x); \
- if (!(x)->lock&&(x)->babble) { \
- (x)->babble--; \
- printk("%s:%d: spin_unlock(%s:%p) not locked\n", \
- __FILE__,__LINE__, (x)->module, (x));\
- } \
- (x)->lock = 0; \
- } while (0)
-#else
/*
- * gcc versions before ~2.95 have a nasty bug with empty initializers.
+ * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them):
*/
-#if (__GNUC__ > 2)
- typedef struct { } spinlock_t;
- #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
+#if defined(CONFIG_SMP)
+# include <asm/spinlock.h>
#else
- typedef struct { int gcc_is_buggy; } spinlock_t;
- #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+# include <linux/spinlock_up.h>
#endif
+#define spin_lock_init(lock) do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
+#define rwlock_init(lock) do { *(lock) = RW_LOCK_UNLOCKED; } while (0)
+
+#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock)
+
+/**
+ * spin_unlock_wait - wait until the spinlock gets unlocked
+ * @lock: the spinlock in question.
+ */
+#define spin_unlock_wait(lock) __raw_spin_unlock_wait(&(lock)->raw_lock)
+
/*
- * If CONFIG_SMP is unset, declare the _raw_* definitions as nops
+ * Pull the _spin_*()/_read_*()/_write_*() functions/declarations:
*/
-#define spin_lock_init(lock) do { (void)(lock); } while(0)
-#define _raw_spin_lock(lock) do { (void)(lock); } while(0)
-#define spin_is_locked(lock) ((void)(lock), 0)
-#define assert_spin_locked(lock) do { (void)(lock); } while(0)
-#define _raw_spin_trylock(lock) (((void)(lock), 1))
-#define spin_unlock_wait(lock) (void)(lock)
-#define _raw_spin_unlock(lock) do { (void)(lock); } while(0)
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
-/* RW spinlocks: No debug version */
-
-#if (__GNUC__ > 2)
- typedef struct { } rwlock_t;
- #define RW_LOCK_UNLOCKED (rwlock_t) { }
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+# include <linux/spinlock_api_smp.h>
#else
- typedef struct { int gcc_is_buggy; } rwlock_t;
- #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
+# include <linux/spinlock_api_up.h>
#endif
-#define rwlock_init(lock) do { (void)(lock); } while(0)
-#define _raw_read_lock(lock) do { (void)(lock); } while(0)
-#define _raw_read_unlock(lock) do { (void)(lock); } while(0)
-#define _raw_write_lock(lock) do { (void)(lock); } while(0)
-#define _raw_write_unlock(lock) do { (void)(lock); } while(0)
-#define read_can_lock(lock) (((void)(lock), 1))
-#define write_can_lock(lock) (((void)(lock), 1))
-#define _raw_read_trylock(lock) ({ (void)(lock); (1); })
-#define _raw_write_trylock(lock) ({ (void)(lock); (1); })
-
-#define _spin_trylock(lock) ({preempt_disable(); _raw_spin_trylock(lock) ? \
- 1 : ({preempt_enable(); 0;});})
-
-#define _read_trylock(lock) ({preempt_disable();_raw_read_trylock(lock) ? \
- 1 : ({preempt_enable(); 0;});})
-
-#define _write_trylock(lock) ({preempt_disable(); _raw_write_trylock(lock) ? \
- 1 : ({preempt_enable(); 0;});})
-
-#define _spin_trylock_bh(lock) ({preempt_disable(); local_bh_disable(); \
- _raw_spin_trylock(lock) ? \
- 1 : ({preempt_enable_no_resched(); local_bh_enable(); 0;});})
-
-#define _spin_lock(lock) \
-do { \
- preempt_disable(); \
- _raw_spin_lock(lock); \
- __acquire(lock); \
-} while(0)
-
-#define _write_lock(lock) \
-do { \
- preempt_disable(); \
- _raw_write_lock(lock); \
- __acquire(lock); \
-} while(0)
-
-#define _read_lock(lock) \
-do { \
- preempt_disable(); \
- _raw_read_lock(lock); \
- __acquire(lock); \
-} while(0)
-
-#define _spin_unlock(lock) \
-do { \
- _raw_spin_unlock(lock); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#define _write_unlock(lock) \
-do { \
- _raw_write_unlock(lock); \
- preempt_enable(); \
- __release(lock); \
-} while(0)
-
-#define _read_unlock(lock) \
-do { \
- _raw_read_unlock(lock); \
- preempt_enable(); \
- __release(lock); \
-} while(0)
-
-#define _spin_lock_irqsave(lock, flags) \
-do { \
- local_irq_save(flags); \
- preempt_disable(); \
- _raw_spin_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _spin_lock_irq(lock) \
-do { \
- local_irq_disable(); \
- preempt_disable(); \
- _raw_spin_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _spin_lock_bh(lock) \
-do { \
- local_bh_disable(); \
- preempt_disable(); \
- _raw_spin_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _read_lock_irqsave(lock, flags) \
-do { \
- local_irq_save(flags); \
- preempt_disable(); \
- _raw_read_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _read_lock_irq(lock) \
-do { \
- local_irq_disable(); \
- preempt_disable(); \
- _raw_read_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _read_lock_bh(lock) \
-do { \
- local_bh_disable(); \
- preempt_disable(); \
- _raw_read_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _write_lock_irqsave(lock, flags) \
-do { \
- local_irq_save(flags); \
- preempt_disable(); \
- _raw_write_lock(lock); \
- __acquire(lock); \
-} while (0)
+#ifdef CONFIG_DEBUG_SPINLOCK
+ extern void _raw_spin_lock(spinlock_t *lock);
+#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+ extern int _raw_spin_trylock(spinlock_t *lock);
+ extern void _raw_spin_unlock(spinlock_t *lock);
+
+ extern void _raw_read_lock(rwlock_t *lock);
+ extern int _raw_read_trylock(rwlock_t *lock);
+ extern void _raw_read_unlock(rwlock_t *lock);
+ extern void _raw_write_lock(rwlock_t *lock);
+ extern int _raw_write_trylock(rwlock_t *lock);
+ extern void _raw_write_unlock(rwlock_t *lock);
+#else
+# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
+# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock)
+# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock)
+# define _raw_spin_lock_flags(lock, flags) \
+ __raw_spin_lock_flags(&(lock)->raw_lock, *(flags))
+# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock)
+# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock)
+# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock)
+# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock)
+# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock)
+# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock)
+#endif
-#define _write_lock_irq(lock) \
-do { \
- local_irq_disable(); \
- preempt_disable(); \
- _raw_write_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _write_lock_bh(lock) \
-do { \
- local_bh_disable(); \
- preempt_disable(); \
- _raw_write_lock(lock); \
- __acquire(lock); \
-} while (0)
-
-#define _spin_unlock_irqrestore(lock, flags) \
-do { \
- _raw_spin_unlock(lock); \
- local_irq_restore(flags); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#define _spin_unlock_irq(lock) \
-do { \
- _raw_spin_unlock(lock); \
- local_irq_enable(); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#define _spin_unlock_bh(lock) \
-do { \
- _raw_spin_unlock(lock); \
- preempt_enable_no_resched(); \
- local_bh_enable(); \
- __release(lock); \
-} while (0)
-
-#define _write_unlock_bh(lock) \
-do { \
- _raw_write_unlock(lock); \
- preempt_enable_no_resched(); \
- local_bh_enable(); \
- __release(lock); \
-} while (0)
-
-#define _read_unlock_irqrestore(lock, flags) \
-do { \
- _raw_read_unlock(lock); \
- local_irq_restore(flags); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#define _write_unlock_irqrestore(lock, flags) \
-do { \
- _raw_write_unlock(lock); \
- local_irq_restore(flags); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#define _read_unlock_irq(lock) \
-do { \
- _raw_read_unlock(lock); \
- local_irq_enable(); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#define _read_unlock_bh(lock) \
-do { \
- _raw_read_unlock(lock); \
- preempt_enable_no_resched(); \
- local_bh_enable(); \
- __release(lock); \
-} while (0)
-
-#define _write_unlock_irq(lock) \
-do { \
- _raw_write_unlock(lock); \
- local_irq_enable(); \
- preempt_enable(); \
- __release(lock); \
-} while (0)
-
-#endif /* !SMP */
+#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock)
+#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock)
/*
* Define the various spin_lock and rw_lock methods. Note we define these
* regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
* methods are defined as nops in the case they are not required.
*/
-#define spin_trylock(lock) __cond_lock(_spin_trylock(lock))
-#define read_trylock(lock) __cond_lock(_read_trylock(lock))
-#define write_trylock(lock) __cond_lock(_write_trylock(lock))
+#define spin_trylock(lock) __cond_lock(_spin_trylock(lock))
+#define read_trylock(lock) __cond_lock(_read_trylock(lock))
+#define write_trylock(lock) __cond_lock(_write_trylock(lock))
-#define spin_lock(lock) _spin_lock(lock)
-#define write_lock(lock) _write_lock(lock)
-#define read_lock(lock) _read_lock(lock)
+#define spin_lock(lock) _spin_lock(lock)
+#define write_lock(lock) _write_lock(lock)
+#define read_lock(lock) _read_lock(lock)
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock)
#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock)
#define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock)
@@ -470,137 +171,59 @@ do { \
#define write_lock_irq(lock) _write_lock_irq(lock)
#define write_lock_bh(lock) _write_lock_bh(lock)
-#define spin_unlock(lock) _spin_unlock(lock)
-#define write_unlock(lock) _write_unlock(lock)
-#define read_unlock(lock) _read_unlock(lock)
+#define spin_unlock(lock) _spin_unlock(lock)
+#define write_unlock(lock) _write_unlock(lock)
+#define read_unlock(lock) _read_unlock(lock)
-#define spin_unlock_irqrestore(lock, flags) _spin_unlock_irqrestore(lock, flags)
+#define spin_unlock_irqrestore(lock, flags) \
+ _spin_unlock_irqrestore(lock, flags)
#define spin_unlock_irq(lock) _spin_unlock_irq(lock)
#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
-#define read_unlock_irqrestore(lock, flags) _read_unlock_irqrestore(lock, flags)
-#define read_unlock_irq(lock) _read_unlock_irq(lock)
-#define read_unlock_bh(lock) _read_unlock_bh(lock)
+#define read_unlock_irqrestore(lock, flags) \
+ _read_unlock_irqrestore(lock, flags)
+#define read_unlock_irq(lock) _read_unlock_irq(lock)
+#define read_unlock_bh(lock) _read_unlock_bh(lock)
-#define write_unlock_irqrestore(lock, flags) _write_unlock_irqrestore(lock, flags)
-#define write_unlock_irq(lock) _write_unlock_irq(lock)
-#define write_unlock_bh(lock) _write_unlock_bh(lock)
+#define write_unlock_irqrestore(lock, flags) \
+ _write_unlock_irqrestore(lock, flags)
+#define write_unlock_irq(lock) _write_unlock_irq(lock)
+#define write_unlock_bh(lock) _write_unlock_bh(lock)
-#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
+#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
#define spin_trylock_irq(lock) \
({ \
local_irq_disable(); \
_spin_trylock(lock) ? \
- 1 : ({local_irq_enable(); 0; }); \
+ 1 : ({ local_irq_enable(); 0; }); \
})
#define spin_trylock_irqsave(lock, flags) \
({ \
local_irq_save(flags); \
_spin_trylock(lock) ? \
- 1 : ({local_irq_restore(flags); 0;}); \
+ 1 : ({ local_irq_restore(flags); 0; }); \
})
-#ifdef CONFIG_LOCKMETER
-extern void _metered_spin_lock (spinlock_t *lock);
-extern void _metered_spin_unlock (spinlock_t *lock);
-extern int _metered_spin_trylock(spinlock_t *lock);
-extern void _metered_read_lock (rwlock_t *lock);
-extern void _metered_read_unlock (rwlock_t *lock);
-extern void _metered_write_lock (rwlock_t *lock);
-extern void _metered_write_unlock (rwlock_t *lock);
-extern int _metered_read_trylock (rwlock_t *lock);
-extern int _metered_write_trylock(rwlock_t *lock);
-#endif
-
-/* "lock on reference count zero" */
-#ifndef ATOMIC_DEC_AND_LOCK
-#include <asm/atomic.h>
-extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
-#endif
-
-#define atomic_dec_and_lock(atomic,lock) __cond_lock(_atomic_dec_and_lock(atomic,lock))
-
-/*
- * bit-based spin_lock()
- *
- * Don't use this unless you really need to: spin_lock() and spin_unlock()
- * are significantly faster.
- */
-static inline void bit_spin_lock(int bitnum, unsigned long *addr)
-{
- /*
- * Assuming the lock is uncontended, this never enters
- * the body of the outer loop. If it is contended, then
- * within the inner loop a non-atomic test is used to
- * busywait with less bus contention for a good time to
- * attempt to acquire the lock bit.
- */
- preempt_disable();
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
- while (test_and_set_bit(bitnum, addr)) {
- while (test_bit(bitnum, addr)) {
- preempt_enable();
- cpu_relax();
- preempt_disable();
- }
- }
-#endif
- __acquire(bitlock);
-}
-
/*
- * Return true if it was acquired
+ * Pull the atomic_t declaration:
+ * (asm-mips/atomic.h needs above definitions)
*/
-static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
-{
- preempt_disable();
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
- if (test_and_set_bit(bitnum, addr)) {
- preempt_enable();
- return 0;
- }
-#endif
- __acquire(bitlock);
- return 1;
-}
-
-/*
- * bit-based spin_unlock()
- */
-static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
- BUG_ON(!test_bit(bitnum, addr));
- smp_mb__before_clear_bit();
- clear_bit(bitnum, addr);
-#endif
- preempt_enable();
- __release(bitlock);
-}
-
-/*
- * Return true if the lock is held.
+#include <asm/atomic.h>
+/**
+ * atomic_dec_and_lock - lock on reaching reference count zero
+ * @atomic: the atomic counter
+ * @lock: the spinlock in question
*/
-static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
- return test_bit(bitnum, addr);
-#elif defined CONFIG_PREEMPT
- return preempt_count();
-#else
- return 1;
-#endif
-}
-
-#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
-#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
+extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
+#define atomic_dec_and_lock(atomic, lock) \
+ __cond_lock(_atomic_dec_and_lock(atomic, lock))
/**
* spin_can_lock - would spin_trylock() succeed?
* @lock: the spinlock in question.
*/
-#define spin_can_lock(lock) (!spin_is_locked(lock))
+#define spin_can_lock(lock) (!spin_is_locked(lock))
#endif /* __LINUX_SPINLOCK_H */
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h
new file mode 100644
index 000000000000..78e6989ffb54
--- /dev/null
+++ b/include/linux/spinlock_api_smp.h
@@ -0,0 +1,57 @@
+#ifndef __LINUX_SPINLOCK_API_SMP_H
+#define __LINUX_SPINLOCK_API_SMP_H
+
+#ifndef __LINUX_SPINLOCK_H
+# error "please don't include this file directly"
+#endif
+
+/*
+ * include/linux/spinlock_api_smp.h
+ *
+ * spinlock API declarations on SMP (and debug)
+ * (implemented in kernel/spinlock.c)
+ *
+ * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
+ * Released under the General Public License (GPL).
+ */
+
+int in_lock_functions(unsigned long addr);
+
+#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x))
+
+void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t);
+void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t);
+void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t);
+void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t);
+void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(rwlock_t);
+void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(rwlock_t);
+void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(spinlock_t);
+void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(rwlock_t);
+void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(rwlock_t);
+unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
+ __acquires(spinlock_t);
+unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
+ __acquires(rwlock_t);
+unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
+ __acquires(rwlock_t);
+int __lockfunc _spin_trylock(spinlock_t *lock);
+int __lockfunc _read_trylock(rwlock_t *lock);
+int __lockfunc _write_trylock(rwlock_t *lock);
+int __lockfunc _spin_trylock_bh(spinlock_t *lock);
+void __lockfunc _spin_unlock(spinlock_t *lock) __releases(spinlock_t);
+void __lockfunc _read_unlock(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _write_unlock(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(spinlock_t);
+void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(spinlock_t);
+void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
+ __releases(spinlock_t);
+void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
+ __releases(rwlock_t);
+void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
+ __releases(rwlock_t);
+
+#endif /* __LINUX_SPINLOCK_API_SMP_H */
diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h
new file mode 100644
index 000000000000..cd81cee566f4
--- /dev/null
+++ b/include/linux/spinlock_api_up.h
@@ -0,0 +1,80 @@
+#ifndef __LINUX_SPINLOCK_API_UP_H
+#define __LINUX_SPINLOCK_API_UP_H
+
+#ifndef __LINUX_SPINLOCK_H
+# error "please don't include this file directly"
+#endif
+
+/*
+ * include/linux/spinlock_api_up.h
+ *
+ * spinlock API implementation on UP-nondebug (inlined implementation)
+ *
+ * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
+ * Released under the General Public License (GPL).
+ */
+
+#define in_lock_functions(ADDR) 0
+
+#define assert_spin_locked(lock) do { (void)(lock); } while (0)
+
+/*
+ * In the UP-nondebug case there's no real locking going on, so the
+ * only thing we have to do is to keep the preempt counts and irq
+ * flags straight, to supress compiler warnings of unused lock
+ * variables, and to add the proper checker annotations:
+ */
+#define __LOCK(lock) \
+ do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)
+
+#define __LOCK_BH(lock) \
+ do { local_bh_disable(); __LOCK(lock); } while (0)
+
+#define __LOCK_IRQ(lock) \
+ do { local_irq_disable(); __LOCK(lock); } while (0)
+
+#define __LOCK_IRQSAVE(lock, flags) \
+ do { local_irq_save(flags); __LOCK(lock); } while (0)
+
+#define __UNLOCK(lock) \
+ do { preempt_enable(); __release(lock); (void)(lock); } while (0)
+
+#define __UNLOCK_BH(lock) \
+ do { preempt_enable_no_resched(); local_bh_enable(); __release(lock); (void)(lock); } while (0)
+
+#define __UNLOCK_IRQ(lock) \
+ do { local_irq_enable(); __UNLOCK(lock); } while (0)
+
+#define __UNLOCK_IRQRESTORE(lock, flags) \
+ do { local_irq_restore(flags); __UNLOCK(lock); } while (0)
+
+#define _spin_lock(lock) __LOCK(lock)
+#define _read_lock(lock) __LOCK(lock)
+#define _write_lock(lock) __LOCK(lock)
+#define _spin_lock_bh(lock) __LOCK_BH(lock)
+#define _read_lock_bh(lock) __LOCK_BH(lock)
+#define _write_lock_bh(lock) __LOCK_BH(lock)
+#define _spin_lock_irq(lock) __LOCK_IRQ(lock)
+#define _read_lock_irq(lock) __LOCK_IRQ(lock)
+#define _write_lock_irq(lock) __LOCK_IRQ(lock)
+#define _spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)
+#define _read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)
+#define _write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)
+#define _spin_trylock(lock) ({ __LOCK(lock); 1; })
+#define _read_trylock(lock) ({ __LOCK(lock); 1; })
+#define _write_trylock(lock) ({ __LOCK(lock); 1; })
+#define _spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; })
+#define _spin_unlock(lock) __UNLOCK(lock)
+#define _read_unlock(lock) __UNLOCK(lock)
+#define _write_unlock(lock) __UNLOCK(lock)
+#define _spin_unlock_bh(lock) __UNLOCK_BH(lock)
+#define _write_unlock_bh(lock) __UNLOCK_BH(lock)
+#define _read_unlock_bh(lock) __UNLOCK_BH(lock)
+#define _spin_unlock_irq(lock) __UNLOCK_IRQ(lock)
+#define _read_unlock_irq(lock) __UNLOCK_IRQ(lock)
+#define _write_unlock_irq(lock) __UNLOCK_IRQ(lock)
+#define _spin_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)
+#define _read_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)
+#define _write_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)
+
+#endif /* __LINUX_SPINLOCK_API_UP_H */
diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h
new file mode 100644
index 000000000000..9cb51e070390
--- /dev/null
+++ b/include/linux/spinlock_types.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_SPINLOCK_TYPES_H
+#define __LINUX_SPINLOCK_TYPES_H
+
+/*
+ * include/linux/spinlock_types.h - generic spinlock type definitions
+ * and initializers
+ *
+ * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
+ * Released under the General Public License (GPL).
+ */
+
+#if defined(CONFIG_SMP)
+# include <asm/spinlock_types.h>
+#else
+# include <linux/spinlock_types_up.h>
+#endif
+
+typedef struct {
+ raw_spinlock_t raw_lock;
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
+ unsigned int break_lock;
+#endif
+#ifdef CONFIG_DEBUG_SPINLOCK
+ unsigned int magic, owner_cpu;
+ void *owner;
+#endif
+} spinlock_t;
+
+#define SPINLOCK_MAGIC 0xdead4ead
+
+typedef struct {
+ raw_rwlock_t raw_lock;
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
+ unsigned int break_lock;
+#endif
+#ifdef CONFIG_DEBUG_SPINLOCK
+ unsigned int magic, owner_cpu;
+ void *owner;
+#endif
+} rwlock_t;
+
+#define RWLOCK_MAGIC 0xdeaf1eed
+
+#define SPINLOCK_OWNER_INIT ((void *)-1L)
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+# define SPIN_LOCK_UNLOCKED \
+ (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \
+ .magic = SPINLOCK_MAGIC, \
+ .owner = SPINLOCK_OWNER_INIT, \
+ .owner_cpu = -1 }
+#define RW_LOCK_UNLOCKED \
+ (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \
+ .magic = RWLOCK_MAGIC, \
+ .owner = SPINLOCK_OWNER_INIT, \
+ .owner_cpu = -1 }
+#else
+# define SPIN_LOCK_UNLOCKED \
+ (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED }
+#define RW_LOCK_UNLOCKED \
+ (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED }
+#endif
+
+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
+#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
+
+#endif /* __LINUX_SPINLOCK_TYPES_H */
diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h
new file mode 100644
index 000000000000..def2d173a8db
--- /dev/null
+++ b/include/linux/spinlock_types_up.h
@@ -0,0 +1,51 @@
+#ifndef __LINUX_SPINLOCK_TYPES_UP_H
+#define __LINUX_SPINLOCK_TYPES_UP_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+/*
+ * include/linux/spinlock_types_up.h - spinlock type definitions for UP
+ *
+ * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
+ * Released under the General Public License (GPL).
+ */
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+
+typedef struct {
+ volatile unsigned int slock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+
+#else
+
+/*
+ * All gcc 2.95 versions and early versions of 2.96 have a nasty bug
+ * with empty initializers.
+ */
+#if (__GNUC__ > 2)
+typedef struct { } raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { }
+#else
+typedef struct { int gcc_is_buggy; } raw_spinlock_t;
+#define __RAW_SPIN_LOCK_UNLOCKED (raw_spinlock_t) { 0 }
+#endif
+
+#endif
+
+#if (__GNUC__ > 2)
+typedef struct {
+ /* no debug version on UP */
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { }
+#else
+typedef struct { int gcc_is_buggy; } raw_rwlock_t;
+#define __RAW_RW_LOCK_UNLOCKED (raw_rwlock_t) { 0 }
+#endif
+
+#endif /* __LINUX_SPINLOCK_TYPES_UP_H */
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
new file mode 100644
index 000000000000..31accf2f0b13
--- /dev/null
+++ b/include/linux/spinlock_up.h
@@ -0,0 +1,74 @@
+#ifndef __LINUX_SPINLOCK_UP_H
+#define __LINUX_SPINLOCK_UP_H
+
+#ifndef __LINUX_SPINLOCK_H
+# error "please don't include this file directly"
+#endif
+
+/*
+ * include/linux/spinlock_up.h - UP-debug version of spinlocks.
+ *
+ * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
+ * Released under the General Public License (GPL).
+ *
+ * In the debug case, 1 means unlocked, 0 means locked. (the values
+ * are inverted, to catch initialization bugs)
+ *
+ * No atomicity anywhere, we are on UP.
+ */
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+
+#define __raw_spin_is_locked(x) ((x)->slock == 0)
+
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+ lock->slock = 0;
+}
+
+static inline void
+__raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+{
+ local_irq_save(flags);
+ lock->slock = 0;
+}
+
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+ char oldval = lock->slock;
+
+ lock->slock = 0;
+
+ return oldval > 0;
+}
+
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+ lock->slock = 1;
+}
+
+/*
+ * Read-write spinlocks. No debug version.
+ */
+#define __raw_read_lock(lock) do { (void)(lock); } while (0)
+#define __raw_write_lock(lock) do { (void)(lock); } while (0)
+#define __raw_read_trylock(lock) ({ (void)(lock); 1; })
+#define __raw_write_trylock(lock) ({ (void)(lock); 1; })
+#define __raw_read_unlock(lock) do { (void)(lock); } while (0)
+#define __raw_write_unlock(lock) do { (void)(lock); } while (0)
+
+#else /* DEBUG_SPINLOCK */
+#define __raw_spin_is_locked(lock) ((void)(lock), 0)
+/* for sched.c and kernel_lock.c: */
+# define __raw_spin_lock(lock) do { (void)(lock); } while (0)
+# define __raw_spin_unlock(lock) do { (void)(lock); } while (0)
+# define __raw_spin_trylock(lock) ({ (void)(lock); 1; })
+#endif /* DEBUG_SPINLOCK */
+
+#define __raw_read_can_lock(lock) (((void)(lock), 1))
+#define __raw_write_can_lock(lock) (((void)(lock), 1))
+
+#define __raw_spin_unlock_wait(lock) \
+ do { cpu_relax(); } while (__raw_spin_is_locked(lock))
+
+#endif /* __LINUX_SPINLOCK_UP_H */
diff --git a/include/linux/string.h b/include/linux/string.h
index dab2652acbd8..369be3264a55 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -88,7 +88,7 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
extern void * memchr(const void *,int,__kernel_size_t);
#endif
-extern char *kstrdup(const char *s, unsigned int __nocast gfp);
+extern char *kstrdup(const char *s, gfp_t gfp);
#ifdef __cplusplus
}
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 04ebc24db348..b68c11a2d6dd 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -66,7 +66,12 @@ struct rpc_cred_cache {
struct rpc_auth {
unsigned int au_cslack; /* call cred size estimate */
- unsigned int au_rslack; /* reply verf size guess */
+ /* guess at number of u32's auth adds before
+ * reply data; normally the verifier size: */
+ unsigned int au_rslack;
+ /* for gss, used to calculate au_rslack: */
+ unsigned int au_verfsize;
+
unsigned int au_flags; /* various flags */
struct rpc_authops * au_ops; /* operations */
rpc_authflavor_t au_flavor; /* pseudoflavor (note may
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index eadb31e3c198..1a42d902bc11 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -32,6 +32,7 @@
#define RPCDBG_AUTH 0x0010
#define RPCDBG_PMAP 0x0020
#define RPCDBG_SCHED 0x0040
+#define RPCDBG_TRANS 0x0080
#define RPCDBG_SVCSOCK 0x0100
#define RPCDBG_SVCDSP 0x0200
#define RPCDBG_MISC 0x0400
@@ -94,6 +95,8 @@ enum {
CTL_NLMDEBUG,
CTL_SLOTTABLE_UDP,
CTL_SLOTTABLE_TCP,
+ CTL_MIN_RESVPORT,
+ CTL_MAX_RESVPORT,
};
#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index 689262f63059..9b8bcf125c18 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -40,14 +40,21 @@ int gss_import_sec_context(
struct gss_ctx **ctx_id);
u32 gss_get_mic(
struct gss_ctx *ctx_id,
- u32 qop,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 gss_verify_mic(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate);
+ struct xdr_netobj *mic_token);
+u32 gss_wrap(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *outbuf,
+ struct page **inpages);
+u32 gss_unwrap(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *inbuf);
u32 gss_delete_sec_context(
struct gss_ctx **ctx_id);
@@ -56,7 +63,6 @@ char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
struct pf_desc {
u32 pseudoflavor;
- u32 qop;
u32 service;
char *name;
char *auth_domain_name;
@@ -85,14 +91,21 @@ struct gss_api_ops {
struct gss_ctx *ctx_id);
u32 (*gss_get_mic)(
struct gss_ctx *ctx_id,
- u32 qop,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 (*gss_verify_mic)(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate);
+ struct xdr_netobj *mic_token);
+ u32 (*gss_wrap)(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *outbuf,
+ struct page **inpages);
+ u32 (*gss_unwrap)(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *buf);
void (*gss_delete_sec_context)(
void *internal_ctx_id);
};
diff --git a/include/linux/sunrpc/gss_err.h b/include/linux/sunrpc/gss_err.h
index 92608a2e574c..a6807867bd21 100644
--- a/include/linux/sunrpc/gss_err.h
+++ b/include/linux/sunrpc/gss_err.h
@@ -66,16 +66,6 @@ typedef unsigned int OM_uint32;
/*
- * Define the default Quality of Protection for per-message services. Note
- * that an implementation that offers multiple levels of QOP may either reserve
- * a value (for example zero, as assumed here) to mean "default protection", or
- * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
- * QOP value. However a value of 0 should always be interpreted by a GSSAPI
- * implementation as a request for the default protection level.
- */
-#define GSS_C_QOP_DEFAULT 0
-
-/*
* Expiration time of 2^32-1 seconds means infinite lifetime for a
* credential or security context
*/
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index ffe31d2eb9ec..2c3601d31045 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -116,18 +116,22 @@ enum seal_alg {
s32
make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
- struct xdr_netobj *cksum);
+ int body_offset, struct xdr_netobj *cksum);
+
+u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
+ struct xdr_netobj *);
+
+u32 gss_verify_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
+ struct xdr_netobj *);
u32
-krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
- struct xdr_buf *input_message_buffer,
- struct xdr_netobj *output_message_buffer, int toktype);
+gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset,
+ struct xdr_buf *outbuf, struct page **pages);
u32
-krb5_read_token(struct krb5_ctx *context_handle,
- struct xdr_netobj *input_token_buffer,
- struct xdr_buf *message_buffer,
- int *qop_state, int toktype);
+gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset,
+ struct xdr_buf *buf);
+
u32
krb5_encrypt(struct crypto_tfm * key,
@@ -137,6 +141,13 @@ u32
krb5_decrypt(struct crypto_tfm * key,
void *iv, void *in, void *out, int length);
+int
+gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *outbuf, int offset,
+ struct page **pages);
+
+int
+gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *inbuf, int offset);
+
s32
krb5_make_seq_num(struct crypto_tfm * key,
int direction,
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
index b5c9968c3c17..0beb2cf00a84 100644
--- a/include/linux/sunrpc/gss_spkm3.h
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -41,9 +41,9 @@ struct spkm3_ctx {
#define SPKM_WRAP_TOK 5
#define SPKM_DEL_TOK 6
-u32 spkm3_make_token(struct spkm3_ctx *ctx, int qop_req, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
+u32 spkm3_make_token(struct spkm3_ctx *ctx, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
-u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int *qop_state, int toktype);
+u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int toktype);
#define CKSUMTYPE_RSA_MD5 0x0007
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 15f115332389..f43f237360ae 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -76,5 +76,30 @@ enum rpc_auth_stat {
#define RPC_MAXNETNAMELEN 256
+/*
+ * From RFC 1831:
+ *
+ * "A record is composed of one or more record fragments. A record
+ * fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of
+ * fragment data. The bytes encode an unsigned binary number; as with
+ * XDR integers, the byte order is from highest to lowest. The number
+ * encodes two values -- a boolean which indicates whether the fragment
+ * is the last fragment of the record (bit value 1 implies the fragment
+ * is the last fragment) and a 31-bit unsigned binary value which is the
+ * length in bytes of the fragment's data. The boolean value is the
+ * highest-order bit of the header; the length is the 31 low-order bits.
+ * (Note that this record specification is NOT in XDR standard form!)"
+ *
+ * The Linux RPC client always sends its requests in a single record
+ * fragment, limiting the maximum payload size for stream transports to
+ * 2GB.
+ */
+
+typedef u32 rpc_fraghdr;
+
+#define RPC_LAST_STREAM_FRAGMENT (1U << 31)
+#define RPC_FRAGMENT_SIZE_MASK (~RPC_LAST_STREAM_FRAGMENT)
+#define RPC_MAX_FRAGMENT_SIZE ((1U << 31) - 1)
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 23448d0fb5bc..5da968729cf8 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -161,14 +161,10 @@ typedef struct {
typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
+extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *);
extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
skb_reader_t *, skb_read_actor_t);
-struct socket;
-struct sockaddr;
-extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
- struct xdr_buf *, unsigned int, int);
-
extern int xdr_encode_word(struct xdr_buf *, int, u32);
extern int xdr_decode_word(struct xdr_buf *, int, u32 *);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index e618c1649814..3b8b6e823c70 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -1,5 +1,5 @@
/*
- * linux/include/linux/sunrpc/clnt_xprt.h
+ * linux/include/linux/sunrpc/xprt.h
*
* Declarations for the RPC transport interface.
*
@@ -15,20 +15,6 @@
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xdr.h>
-/*
- * The transport code maintains an estimate on the maximum number of out-
- * standing RPC requests, using a smoothed version of the congestion
- * avoidance implemented in 44BSD. This is basically the Van Jacobson
- * congestion algorithm: If a retransmit occurs, the congestion window is
- * halved; otherwise, it is incremented by 1/cwnd when
- *
- * - a reply is received and
- * - a full number of requests are outstanding and
- * - the congestion window hasn't been updated recently.
- *
- * Upper procedures may check whether a request would block waiting for
- * a free RPC slot by using the RPC_CONGESTED() macro.
- */
extern unsigned int xprt_udp_slot_table_entries;
extern unsigned int xprt_tcp_slot_table_entries;
@@ -36,34 +22,23 @@ extern unsigned int xprt_tcp_slot_table_entries;
#define RPC_DEF_SLOT_TABLE (16U)
#define RPC_MAX_SLOT_TABLE (128U)
-#define RPC_CWNDSHIFT (8U)
-#define RPC_CWNDSCALE (1U << RPC_CWNDSHIFT)
-#define RPC_INITCWND RPC_CWNDSCALE
-#define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT)
-#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
-
-/* Default timeout values */
-#define RPC_MAX_UDP_TIMEOUT (60*HZ)
-#define RPC_MAX_TCP_TIMEOUT (600*HZ)
-
/*
- * Wait duration for an RPC TCP connection to be established. Solaris
- * NFS over TCP uses 60 seconds, for example, which is in line with how
- * long a server takes to reboot.
+ * RPC call and reply header size as number of 32bit words (verifier
+ * size computed separately)
*/
-#define RPC_CONNECT_TIMEOUT (60*HZ)
+#define RPC_CALLHDRSIZE 6
+#define RPC_REPHDRSIZE 4
/*
- * Delay an arbitrary number of seconds before attempting to reconnect
- * after an error.
+ * Parameters for choosing a free port
*/
-#define RPC_REESTABLISH_TIMEOUT (15*HZ)
+extern unsigned int xprt_min_resvport;
+extern unsigned int xprt_max_resvport;
-/* RPC call and reply header size as number of 32bit words (verifier
- * size computed separately)
- */
-#define RPC_CALLHDRSIZE 6
-#define RPC_REPHDRSIZE 4
+#define RPC_MIN_RESVPORT (1U)
+#define RPC_MAX_RESVPORT (65535U)
+#define RPC_DEF_MIN_RESVPORT (650U)
+#define RPC_DEF_MAX_RESVPORT (1023U)
/*
* This describes a timeout strategy
@@ -76,6 +51,9 @@ struct rpc_timeout {
unsigned char to_exponential;
};
+struct rpc_task;
+struct rpc_xprt;
+
/*
* This describes a complete RPC request
*/
@@ -95,7 +73,10 @@ struct rpc_rqst {
int rq_cong; /* has incremented xprt->cong */
int rq_received; /* receive completed */
u32 rq_seqno; /* gss seq no. used on req. */
-
+ int rq_enc_pages_num;
+ struct page **rq_enc_pages; /* scratch pages for use by
+ gss privacy code */
+ void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */
struct list_head rq_list;
struct xdr_buf rq_private_buf; /* The receive buffer
@@ -121,12 +102,21 @@ struct rpc_rqst {
#define rq_svec rq_snd_buf.head
#define rq_slen rq_snd_buf.len
-#define XPRT_LAST_FRAG (1 << 0)
-#define XPRT_COPY_RECM (1 << 1)
-#define XPRT_COPY_XID (1 << 2)
-#define XPRT_COPY_DATA (1 << 3)
+struct rpc_xprt_ops {
+ void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
+ int (*reserve_xprt)(struct rpc_task *task);
+ void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
+ void (*connect)(struct rpc_task *task);
+ int (*send_request)(struct rpc_task *task);
+ void (*set_retrans_timeout)(struct rpc_task *task);
+ void (*timer)(struct rpc_task *task);
+ void (*release_request)(struct rpc_task *task);
+ void (*close)(struct rpc_xprt *xprt);
+ void (*destroy)(struct rpc_xprt *xprt);
+};
struct rpc_xprt {
+ struct rpc_xprt_ops * ops; /* transport methods */
struct socket * sock; /* BSD socket layer */
struct sock * inet; /* INET layer */
@@ -137,11 +127,13 @@ struct rpc_xprt {
unsigned long cong; /* current congestion */
unsigned long cwnd; /* congestion window */
- unsigned int rcvsize, /* socket receive buffer size */
- sndsize; /* socket send buffer size */
+ size_t rcvsize, /* transport rcv buffer size */
+ sndsize; /* transport send buffer size */
size_t max_payload; /* largest RPC payload size,
in bytes */
+ unsigned int tsh_size; /* size of transport specific
+ header */
struct rpc_wait_queue sending; /* requests waiting to send */
struct rpc_wait_queue resend; /* requests waiting to resend */
@@ -150,11 +142,9 @@ struct rpc_xprt {
struct list_head free; /* free slots */
struct rpc_rqst * slot; /* slot table storage */
unsigned int max_reqs; /* total slots */
- unsigned long sockstate; /* Socket state */
+ unsigned long state; /* transport state */
unsigned char shutdown : 1, /* being shut down */
- nocong : 1, /* no congestion control */
- resvport : 1, /* use a reserved port */
- stream : 1; /* TCP */
+ resvport : 1; /* use a reserved port */
/*
* XID
@@ -171,22 +161,27 @@ struct rpc_xprt {
unsigned long tcp_copied, /* copied to request */
tcp_flags;
/*
- * Connection of sockets
+ * Connection of transports
*/
- struct work_struct sock_connect;
+ unsigned long connect_timeout,
+ bind_timeout,
+ reestablish_timeout;
+ struct work_struct connect_worker;
unsigned short port;
+
/*
- * Disconnection of idle sockets
+ * Disconnection of idle transports
*/
struct work_struct task_cleanup;
struct timer_list timer;
- unsigned long last_used;
+ unsigned long last_used,
+ idle_timeout;
/*
* Send stuff
*/
- spinlock_t sock_lock; /* lock socket info */
- spinlock_t xprt_lock; /* lock xprt info */
+ spinlock_t transport_lock; /* lock transport info */
+ spinlock_t reserve_lock; /* lock slot table */
struct rpc_task * snd_task; /* Task blocked in send */
struct list_head recv;
@@ -195,37 +190,111 @@ struct rpc_xprt {
void (*old_data_ready)(struct sock *, int);
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);
-
- wait_queue_head_t cong_wait;
};
+#define XPRT_LAST_FRAG (1 << 0)
+#define XPRT_COPY_RECM (1 << 1)
+#define XPRT_COPY_XID (1 << 2)
+#define XPRT_COPY_DATA (1 << 3)
+
#ifdef __KERNEL__
-struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr,
- struct rpc_timeout *toparms);
-int xprt_destroy(struct rpc_xprt *);
-void xprt_set_timeout(struct rpc_timeout *, unsigned int,
- unsigned long);
+/*
+ * Transport operations used by ULPs
+ */
+struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, struct rpc_timeout *to);
+void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr);
-void xprt_reserve(struct rpc_task *);
-int xprt_prepare_transmit(struct rpc_task *);
-void xprt_transmit(struct rpc_task *);
-void xprt_receive(struct rpc_task *);
+/*
+ * Generic internal transport functions
+ */
+void xprt_connect(struct rpc_task *task);
+void xprt_reserve(struct rpc_task *task);
+int xprt_reserve_xprt(struct rpc_task *task);
+int xprt_reserve_xprt_cong(struct rpc_task *task);
+int xprt_prepare_transmit(struct rpc_task *task);
+void xprt_transmit(struct rpc_task *task);
+void xprt_abort_transmit(struct rpc_task *task);
int xprt_adjust_timeout(struct rpc_rqst *req);
-void xprt_release(struct rpc_task *);
-void xprt_connect(struct rpc_task *);
-void xprt_sock_setbufsize(struct rpc_xprt *);
-
-#define XPRT_LOCKED 0
-#define XPRT_CONNECT 1
-#define XPRT_CONNECTING 2
-
-#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_test_and_clear_connected(xp) \
- (test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
+void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
+void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
+void xprt_release(struct rpc_task *task);
+int xprt_destroy(struct rpc_xprt *xprt);
+
+static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p)
+{
+ return p + xprt->tsh_size;
+}
+
+/*
+ * Transport switch helper functions
+ */
+void xprt_set_retrans_timeout_def(struct rpc_task *task);
+void xprt_set_retrans_timeout_rtt(struct rpc_task *task);
+void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
+void xprt_wait_for_buffer_space(struct rpc_task *task);
+void xprt_write_space(struct rpc_xprt *xprt);
+void xprt_update_rtt(struct rpc_task *task);
+void xprt_adjust_cwnd(struct rpc_task *task, int result);
+struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
+void xprt_complete_rqst(struct rpc_task *task, int copied);
+void xprt_release_rqst_cong(struct rpc_task *task);
+void xprt_disconnect(struct rpc_xprt *xprt);
+
+/*
+ * Socket transport setup operations
+ */
+int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to);
+int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to);
+
+/*
+ * Reserved bit positions in xprt->state
+ */
+#define XPRT_LOCKED (0)
+#define XPRT_CONNECTED (1)
+#define XPRT_CONNECTING (2)
+
+static inline void xprt_set_connected(struct rpc_xprt *xprt)
+{
+ set_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline void xprt_clear_connected(struct rpc_xprt *xprt)
+{
+ clear_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline int xprt_connected(struct rpc_xprt *xprt)
+{
+ return test_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline int xprt_test_and_set_connected(struct rpc_xprt *xprt)
+{
+ return test_and_set_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline int xprt_test_and_clear_connected(struct rpc_xprt *xprt)
+{
+ return test_and_clear_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline void xprt_clear_connecting(struct rpc_xprt *xprt)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(XPRT_CONNECTING, &xprt->state);
+ smp_mb__after_clear_bit();
+}
+
+static inline int xprt_connecting(struct rpc_xprt *xprt)
+{
+ return test_bit(XPRT_CONNECTING, &xprt->state);
+}
+
+static inline int xprt_test_and_set_connecting(struct rpc_xprt *xprt)
+{
+ return test_and_set_bit(XPRT_CONNECTING, &xprt->state);
+}
#endif /* __KERNEL__*/
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index f2e96fdfaae0..ba448c760168 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -71,5 +71,7 @@ void restore_processor_state(void);
struct saved_context;
void __save_processor_state(struct saved_context *ctxt);
void __restore_processor_state(struct saved_context *ctxt);
+extern unsigned long get_usable_page(gfp_t gfp_mask);
+extern void free_eaten_memory(void);
#endif /* _LINUX_SWSUSP_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 3c9ff0048153..20c975642cab 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -147,7 +147,7 @@ struct swap_list_t {
#define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
/* linux/mm/oom_kill.c */
-extern void out_of_memory(unsigned int __nocast gfp_mask, int order);
+extern void out_of_memory(gfp_t gfp_mask, int order);
/* linux/mm/memory.c */
extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct *);
@@ -171,8 +171,8 @@ extern int rotate_reclaimable_page(struct page *page);
extern void swap_setup(void);
/* linux/mm/vmscan.c */
-extern int try_to_free_pages(struct zone **, unsigned int);
-extern int zone_reclaim(struct zone *, unsigned int, unsigned int);
+extern int try_to_free_pages(struct zone **, gfp_t);
+extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
extern int shrink_all_memory(int);
extern int vm_swappiness;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 425f58c8ea4a..a6f03e473737 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -508,5 +508,7 @@ asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
asmlinkage long sys_ioprio_get(int which, int who);
+asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
+ unsigned long maxnode);
#endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 532a6c5c24e9..fc8e367f671e 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -202,7 +202,8 @@ enum
NET_TR=14,
NET_DECNET=15,
NET_ECONET=16,
- NET_SCTP=17,
+ NET_SCTP=17,
+ NET_LLC=18,
};
/* /proc/sys/kernel/random */
@@ -522,6 +523,29 @@ enum {
NET_IPX_FORWARDING=2
};
+/* /proc/sys/net/llc */
+enum {
+ NET_LLC2=1,
+ NET_LLC_STATION=2,
+};
+
+/* /proc/sys/net/llc/llc2 */
+enum {
+ NET_LLC2_TIMEOUT=1,
+};
+
+/* /proc/sys/net/llc/station */
+enum {
+ NET_LLC_STATION_ACK_TIMEOUT=1,
+};
+
+/* /proc/sys/net/llc/llc2/timeout */
+enum {
+ NET_LLC2_ACK_TIMEOUT=1,
+ NET_LLC2_P_TIMEOUT=2,
+ NET_LLC2_REJ_TIMEOUT=3,
+ NET_LLC2_BUSY_TIMEOUT=4,
+};
/* /proc/sys/net/appletalk */
enum {
@@ -544,7 +568,8 @@ enum {
NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8,
NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9,
NET_NETROM_ROUTING_CONTROL=10,
- NET_NETROM_LINK_FAILS_COUNT=11
+ NET_NETROM_LINK_FAILS_COUNT=11,
+ NET_NETROM_RESET=12
};
/* /proc/sys/net/ax25 */
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index 081b1ee8516e..e21937cf91d0 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -71,7 +71,7 @@ enum
TCF_META_ID_SK_SNDBUF,
TCF_META_ID_SK_ALLOCS,
TCF_META_ID_SK_ROUTE_CAPS,
- TCF_META_ID_SK_HASHENT,
+ TCF_META_ID_SK_HASH,
TCF_META_ID_SK_LINGERTIME,
TCF_META_ID_SK_ACK_BACKLOG,
TCF_META_ID_SK_MAX_ACK_BACKLOG,
diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
index 941f45ac117a..fc5bb4e91a58 100644
--- a/include/linux/textsearch.h
+++ b/include/linux/textsearch.h
@@ -40,7 +40,7 @@ struct ts_state
struct ts_ops
{
const char *name;
- struct ts_config * (*init)(const void *, unsigned int, int);
+ struct ts_config * (*init)(const void *, unsigned int, gfp_t);
unsigned int (*find)(struct ts_config *,
struct ts_state *);
void (*destroy)(struct ts_config *);
@@ -148,7 +148,7 @@ static inline unsigned int textsearch_get_pattern_len(struct ts_config *conf)
extern int textsearch_register(struct ts_ops *);
extern int textsearch_unregister(struct ts_ops *);
extern struct ts_config *textsearch_prepare(const char *, const void *,
- unsigned int, int, int);
+ unsigned int, gfp_t, int);
extern void textsearch_destroy(struct ts_config *conf);
extern unsigned int textsearch_find_continuous(struct ts_config *,
struct ts_state *,
@@ -158,7 +158,8 @@ extern unsigned int textsearch_find_continuous(struct ts_config *,
#define TS_PRIV_ALIGNTO 8
#define TS_PRIV_ALIGN(len) (((len) + TS_PRIV_ALIGNTO-1) & ~(TS_PRIV_ALIGNTO-1))
-static inline struct ts_config *alloc_ts_config(size_t payload, int gfp_mask)
+static inline struct ts_config *alloc_ts_config(size_t payload,
+ gfp_t gfp_mask)
{
struct ts_config *conf;
diff --git a/include/linux/tfrc.h b/include/linux/tfrc.h
new file mode 100644
index 000000000000..7dab7831c3cb
--- /dev/null
+++ b/include/linux/tfrc.h
@@ -0,0 +1,35 @@
+#ifndef _LINUX_TFRC_H_
+#define _LINUX_TFRC_H_
+/*
+ * include/linux/tfrc.h
+ *
+ * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
+ * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
+ * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
+ *
+ * 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/types.h>
+
+struct tfrc_rx_info {
+ __u32 tfrcrx_x_recv;
+ __u32 tfrcrx_rtt;
+ __u32 tfrcrx_p;
+};
+
+struct tfrc_tx_info {
+ __u32 tfrctx_x;
+ __u32 tfrctx_x_recv;
+ __u32 tfrctx_x_calc;
+ __u32 tfrctx_rtt;
+ __u32 tfrctx_p;
+ __u32 tfrctx_rto;
+ __u32 tfrctx_ipi;
+};
+
+#endif /* _LINUX_TFRC_H_ */
diff --git a/include/linux/time.h b/include/linux/time.h
index c10d4c21c183..8e83f4e778bb 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -28,17 +28,10 @@ struct timezone {
#ifdef __KERNEL__
/* Parameters used to convert the timespec values */
-#ifndef USEC_PER_SEC
+#define MSEC_PER_SEC (1000L)
#define USEC_PER_SEC (1000000L)
-#endif
-
-#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC (1000000000L)
-#endif
-
-#ifndef NSEC_PER_USEC
#define NSEC_PER_USEC (1000L)
-#endif
static __inline__ int timespec_equal(struct timespec *a, struct timespec *b)
{
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 221f81ac2002..3340f3bd135d 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -32,6 +32,10 @@ extern struct timer_base_s __init_timer_base;
.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 59ff42c629ec..1267f88ece6e 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/types.h b/include/linux/types.h
index 2b678c22ca4a..21b9ce803644 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -151,7 +151,12 @@ typedef unsigned long sector_t;
*/
#ifdef __CHECKER__
-#define __bitwise __attribute__((bitwise))
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
#else
#define __bitwise
#endif
@@ -165,6 +170,10 @@ typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
#endif
+#ifdef __KERNEL__
+typedef unsigned __bitwise__ gfp_t;
+#endif
+
struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 724637792996..8f731e8f2821 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.
@@ -938,17 +933,17 @@ static inline void usb_fill_int_urb (struct urb *urb,
}
extern void usb_init_urb(struct urb *urb);
-extern struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags);
+extern struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags);
extern void usb_free_urb(struct urb *urb);
#define usb_put_urb usb_free_urb
extern struct urb *usb_get_urb(struct urb *urb);
-extern int usb_submit_urb(struct urb *urb, unsigned mem_flags);
+extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
extern int usb_unlink_urb(struct urb *urb);
extern void usb_kill_urb(struct urb *urb);
#define HAVE_USB_BUFFERS
void *usb_buffer_alloc (struct usb_device *dev, size_t size,
- unsigned mem_flags, dma_addr_t *dma);
+ gfp_t mem_flags, dma_addr_t *dma);
void usb_buffer_free (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);
@@ -1055,7 +1050,7 @@ int usb_sg_init (
struct scatterlist *sg,
int nents,
size_t length,
- unsigned mem_flags
+ gfp_t mem_flags
);
void usb_sg_cancel (struct usb_sg_request *io);
void usb_sg_wait (struct usb_sg_request *io);
diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h
index 71e608607324..ff81117eb733 100644
--- a/include/linux/usb_gadget.h
+++ b/include/linux/usb_gadget.h
@@ -107,18 +107,18 @@ struct usb_ep_ops {
int (*disable) (struct usb_ep *ep);
struct usb_request *(*alloc_request) (struct usb_ep *ep,
- unsigned gfp_flags);
+ gfp_t gfp_flags);
void (*free_request) (struct usb_ep *ep, struct usb_request *req);
void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
- dma_addr_t *dma, unsigned gfp_flags);
+ dma_addr_t *dma, gfp_t gfp_flags);
void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
unsigned bytes);
// NOTE: on 2.6, drivers may also use dma_map() and
// dma_sync_single_*() to directly manage dma overhead.
int (*queue) (struct usb_ep *ep, struct usb_request *req,
- unsigned gfp_flags);
+ gfp_t gfp_flags);
int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
int (*set_halt) (struct usb_ep *ep, int value);
@@ -214,7 +214,7 @@ usb_ep_disable (struct usb_ep *ep)
* Returns the request, or null if one could not be allocated.
*/
static inline struct usb_request *
-usb_ep_alloc_request (struct usb_ep *ep, unsigned gfp_flags)
+usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags)
{
return ep->ops->alloc_request (ep, gfp_flags);
}
@@ -254,7 +254,7 @@ usb_ep_free_request (struct usb_ep *ep, struct usb_request *req)
*/
static inline void *
usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
- unsigned gfp_flags)
+ gfp_t gfp_flags)
{
return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
}
@@ -330,7 +330,7 @@ usb_ep_free_buffer (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned len)
* reported when the usb peripheral is disconnected.
*/
static inline int
-usb_ep_queue (struct usb_ep *ep, struct usb_request *req, unsigned gfp_flags)
+usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags)
{
return ep->ops->queue (ep, req, gfp_flags);
}
diff --git a/include/linux/usb_isp116x.h b/include/linux/usb_isp116x.h
index 5f5a9d9bd6c2..436dd8a2b64a 100644
--- a/include/linux/usb_isp116x.h
+++ b/include/linux/usb_isp116x.h
@@ -7,36 +7,18 @@
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/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index fb57c2217468..9facf733800c 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -32,7 +32,6 @@
#define _LINUX_USBDEVICE_FS_H
#include <linux/types.h>
-#include <linux/compat.h>
/* --------------------------------------------------------------------- */
@@ -125,6 +124,7 @@ struct usbdevfs_hub_portinfo {
};
#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
struct usbdevfs_urb32 {
unsigned char type;
unsigned char endpoint;
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 9d6fbde3d29c..1cc8c31b7988 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -3,7 +3,6 @@
#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 acbfc525576d..89a055761bed 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -60,12 +60,17 @@ enum v4l2_field {
(field) == V4L2_FIELD_SEQ_BT)
enum v4l2_buf_type {
- V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
- V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
- V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
- V4L2_BUF_TYPE_VBI_CAPTURE = 4,
- V4L2_BUF_TYPE_VBI_OUTPUT = 5,
- V4L2_BUF_TYPE_PRIVATE = 0x80,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
+ V4L2_BUF_TYPE_VBI_CAPTURE = 4,
+ V4L2_BUF_TYPE_VBI_OUTPUT = 5,
+#if 1
+ /* Experimental Sliced VBI */
+ V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
+ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
+#endif
+ V4L2_BUF_TYPE_PRIVATE = 0x80,
};
enum v4l2_ctrl_type {
@@ -149,20 +154,24 @@ struct v4l2_capability
};
/* Values for 'capabilities' field */
-#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
-#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
-#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
-#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */
-#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */
-#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
+#if 1
+#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
+#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
+#endif
+#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
-#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
-#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
-#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
+#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
+#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
+#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
-#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
-#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
-#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
+#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
+#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
+#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
/*
* V I D E O I M A G E F O R M A T
@@ -270,7 +279,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 +365,6 @@ struct v4l2_mpeg_compression {
/* I don't expect the above being perfect yet ;) */
__u32 reserved_5[8];
};
-#endif
struct v4l2_jpegcompression
{
@@ -811,6 +818,8 @@ struct v4l2_audioout
* Data services API by Michael Schimek
*/
+/* Raw VBI */
+
struct v4l2_vbi_format
{
__u32 sampling_rate; /* in 1 Hz */
@@ -827,6 +836,54 @@ struct v4l2_vbi_format
#define V4L2_VBI_UNSYNC (1<< 0)
#define V4L2_VBI_INTERLACED (1<< 1)
+#if 1
+/* Sliced VBI
+ *
+ * This implements is a proposal V4L2 API to allow SLICED VBI
+ * required for some hardware encoders. It should change without
+ * notice in the definitive implementation.
+ */
+
+struct v4l2_sliced_vbi_format
+{
+ __u16 service_set;
+ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+ (equals frame lines 313-336 for 625 line video
+ standards, 263-286 for 525 line standards) */
+ __u16 service_lines[2][24];
+ __u32 io_size;
+ __u32 reserved[2]; /* must be zero */
+};
+
+#define V4L2_SLICED_TELETEXT_B (0x0001)
+#define V4L2_SLICED_VPS (0x0400)
+#define V4L2_SLICED_CAPTION_525 (0x1000)
+#define V4L2_SLICED_WSS_625 (0x4000)
+
+#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+struct v4l2_sliced_vbi_cap
+{
+ __u16 service_set;
+ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+ (equals frame lines 313-336 for 625 line video
+ standards, 263-286 for 525 line standards) */
+ __u16 service_lines[2][24];
+ __u32 reserved[4]; /* must be 0 */
+};
+
+struct v4l2_sliced_vbi_data
+{
+ __u32 id;
+ __u32 field; /* 0: first field, 1: second field */
+ __u32 line; /* 1-23 */
+ __u32 reserved; /* must be 0 */
+ __u8 data[48];
+};
+#endif
/*
* A G G R E G A T E S T R U C T U R E S
@@ -839,10 +896,13 @@ struct v4l2_format
enum v4l2_buf_type type;
union
{
- struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
- struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
- struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
- __u8 raw_data[200]; // user-defined
+ struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
+ struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
+ struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
+#if 1
+ struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
+#endif
+ __u8 raw_data[200]; // user-defined
} fmt;
};
@@ -871,10 +931,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)
@@ -920,6 +978,9 @@ struct v4l2_streamparm
#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
+#if 1
+#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
+#endif
/* for compatibility, will go away some day */
#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index b244f69ef682..3701a0673d2c 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -34,8 +34,8 @@ struct vm_struct {
extern void *vmalloc(unsigned long size);
extern void *vmalloc_exec(unsigned long size);
extern void *vmalloc_32(unsigned long size);
-extern void *__vmalloc(unsigned long size, unsigned int __nocast gfp_mask, pgprot_t prot);
-extern void *__vmalloc_area(struct vm_struct *area, unsigned int __nocast gfp_mask, pgprot_t prot);
+extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
+extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot);
extern void vfree(void *addr);
extern void *vmap(struct page **pages, unsigned int count,
diff --git a/include/linux/wanpipe.h b/include/linux/wanpipe.h
index 167d956c492b..dae9860091dd 100644
--- a/include/linux/wanpipe.h
+++ b/include/linux/wanpipe.h
@@ -265,15 +265,6 @@ typedef struct {
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
-
-#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-#define is_alpha(ch) ((((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'z')||\
- ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'Z'))?1:0)
-#define is_hex_digit(ch) ((((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')||\
- ((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'f')||\
- ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'F'))?1:0)
-
-
/****** Data Structures *****************************************************/
/* Adapter Data Space.
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 542dbaee6512..343d883d69c5 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -109,8 +109,6 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
int sync_page_range(struct inode *inode, struct address_space *mapping,
loff_t pos, size_t count);
-int sync_page_range_nolock(struct inode *inode, struct address_space
- *mapping, loff_t pos, size_t count);
/* pdflush.c */
extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index cd831168fdc1..a7ceee9fc5e9 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -1,5 +1,4 @@
/*
- * $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 801ddef301aa..6d02c94cdc0d 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 698670547f16..01b56822df4d 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 3dfb8d670eb7..2a897c3a6a9a 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 eeaa15ddee85..4ad08e24a1aa 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 854a2c2f105b..e2035c7da094 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 ae6da6de98de..ae8d7a000440 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 364b046e9f47..30bb4a893237 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -26,11 +26,20 @@
/* AX.25 Protocol IDs */
#define AX25_P_ROSE 0x01
-#define AX25_P_IP 0xCC
-#define AX25_P_ARP 0xCD
-#define AX25_P_TEXT 0xF0
-#define AX25_P_NETROM 0xCF
-#define AX25_P_SEGMENT 0x08
+#define AX25_P_VJCOMP 0x06 /* Compressed TCP/IP packet */
+ /* Van Jacobsen (RFC 1144) */
+#define AX25_P_VJUNCOMP 0x07 /* Uncompressed TCP/IP packet */
+ /* Van Jacobsen (RFC 1144) */
+#define AX25_P_SEGMENT 0x08 /* Segmentation fragment */
+#define AX25_P_TEXNET 0xc3 /* TEXTNET datagram protocol */
+#define AX25_P_LQ 0xc4 /* Link Quality Protocol */
+#define AX25_P_ATALK 0xca /* Appletalk */
+#define AX25_P_ATALK_ARP 0xcb /* Appletalk ARP */
+#define AX25_P_IP 0xcc /* ARPA Internet Protocol */
+#define AX25_P_ARP 0xcd /* ARPA Adress Resolution */
+#define AX25_P_FLEXNET 0xce /* FlexNet */
+#define AX25_P_NETROM 0xcf /* NET/ROM */
+#define AX25_P_TEXT 0xF0 /* No layer 3 protocol impl. */
/* AX.25 Segment control values */
#define AX25_SEG_REM 0x7F
@@ -88,11 +97,11 @@
/* Define Link State constants. */
enum {
- AX25_STATE_0,
- AX25_STATE_1,
- AX25_STATE_2,
- AX25_STATE_3,
- AX25_STATE_4
+ AX25_STATE_0, /* Listening */
+ AX25_STATE_1, /* SABM sent */
+ AX25_STATE_2, /* DISC sent */
+ AX25_STATE_3, /* Established */
+ AX25_STATE_4 /* Recovery */
};
#define AX25_MODULUS 8 /* Standard AX.25 modulus */
@@ -162,7 +171,7 @@ typedef struct {
ax25_address calls[AX25_MAX_DIGIS];
unsigned char repeated[AX25_MAX_DIGIS];
unsigned char ndigi;
- char lastrepeat;
+ signed char lastrepeat;
} ax25_digi;
typedef struct ax25_route {
@@ -258,7 +267,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 *);
@@ -319,7 +328,7 @@ extern int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
extern int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
/* ax25_ip.c */
-extern int ax25_encapsulate(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int);
+extern int ax25_hard_header(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int);
extern int ax25_rebuild_header(struct sk_buff *);
/* ax25_out.c */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 6dfa4a61ffd0..210458624840 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -136,7 +136,7 @@ struct bt_skb_cb {
};
#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb))
-static inline struct sk_buff *bt_skb_alloc(unsigned int len, unsigned int __nocast how)
+static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
{
struct sk_buff *skb;
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 371e7d3f2e6f..fa2d12b0579b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -463,6 +463,17 @@ struct inquiry_info_with_rssi_and_pscan_mode {
__s8 rssi;
} __attribute__ ((packed));
+#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2F
+struct extended_inquiry_info {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+ __u8 pscan_period_mode;
+ __u8 dev_class[3];
+ __u16 clock_offset;
+ __s8 rssi;
+ __u8 data[240];
+} __attribute__ ((packed));
+
#define HCI_EV_CONN_COMPLETE 0x03
struct hci_ev_conn_complete {
__u8 status;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index ffea9d54071f..fbe557f7ea1d 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -230,7 +230,7 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
u8 xon_char, u8 xoff_char, u16 param_mask);
/* ---- RFCOMM DLCs (channels) ---- */
-struct rfcomm_dlc *rfcomm_dlc_alloc(unsigned int __nocast prio);
+struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio);
void rfcomm_dlc_free(struct rfcomm_dlc *d);
int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
diff --git a/include/net/compat.h b/include/net/compat.h
index 9983fd857804..290bab46d457 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -33,7 +33,8 @@ extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsi
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 *, 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/dn_nsp.h b/include/net/dn_nsp.h
index 6bbeafa73e8b..1ba03be0af3a 100644
--- a/include/net/dn_nsp.h
+++ b/include/net/dn_nsp.h
@@ -19,9 +19,9 @@ extern void dn_nsp_send_data_ack(struct sock *sk);
extern void dn_nsp_send_oth_ack(struct sock *sk);
extern void dn_nsp_delayed_ack(struct sock *sk);
extern void dn_send_conn_ack(struct sock *sk);
-extern void dn_send_conn_conf(struct sock *sk, int gfp);
+extern void dn_send_conn_conf(struct sock *sk, gfp_t gfp);
extern void dn_nsp_send_disc(struct sock *sk, unsigned char type,
- unsigned short reason, int gfp);
+ unsigned short reason, gfp_t gfp);
extern void dn_nsp_return_disc(struct sk_buff *skb, unsigned char type,
unsigned short reason);
extern void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval);
@@ -29,14 +29,14 @@ extern void dn_nsp_send_conninit(struct sock *sk, unsigned char flags);
extern void dn_nsp_output(struct sock *sk);
extern int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum);
-extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oob);
+extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, gfp_t gfp, int oob);
extern unsigned long dn_nsp_persist(struct sock *sk);
extern int dn_nsp_xmit_timeout(struct sock *sk);
extern int dn_nsp_rx(struct sk_buff *);
extern int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
-extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri);
+extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err);
#define NSP_REASON_OK 0 /* No error */
diff --git a/include/net/dn_route.h b/include/net/dn_route.h
index d084721db198..5122da3f2eb3 100644
--- a/include/net/dn_route.h
+++ b/include/net/dn_route.h
@@ -15,7 +15,7 @@
GNU General Public License for more details.
*******************************************************************************/
-extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri);
+extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
extern int dn_route_output_sock(struct dst_entry **pprt, struct flowi *, struct sock *sk, int flags);
extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
extern int dn_cache_getroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
diff --git a/include/net/dst.h b/include/net/dst.h
index 4a056a682435..6c196a5baf24 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -94,7 +94,6 @@ struct dst_ops
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
- int (*get_mss)(struct dst_entry *dst, u32 mtu);
int entry_size;
atomic_t entries;
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index dc36b1be6745..5e38dca1d082 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -11,19 +11,26 @@
*
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
* <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
+ * Copyright (c) 2004-2005, Intel Corporation
*
* 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. See README and COPYING for
* more details.
+ *
+ * API Version History
+ * 1.0.x -- Initial version
+ * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
+ * various structure changes, and crypto API init method
*/
#ifndef IEEE80211_H
#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h> /* ARRAY_SIZE */
+#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/kernel.h> /* ARRAY_SIZE */
#include <linux/wireless.h>
+#define IEEE80211_VERSION "git-1.1.6"
+
#define IEEE80211_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6.2.1.1.2.
@@ -33,34 +40,13 @@
represents the 2304 bytes of real data, plus a possible 8 bytes of
WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-
-#define IEEE80211_HLEN 30
-#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-struct ieee80211_hdr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
- u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
-} __attribute__ ((packed));
-
#define IEEE80211_1ADDR_LEN 10
#define IEEE80211_2ADDR_LEN 16
#define IEEE80211_3ADDR_LEN 24
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_FCS_LEN 4
+#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
#define MIN_FRAG_THRESHOLD 256U
#define MAX_FRAG_THRESHOLD 2346U
@@ -113,11 +99,11 @@ struct ieee80211_hdr_3addr {
#define IEEE80211_STYPE_CFACK 0x0050
#define IEEE80211_STYPE_CFPOLL 0x0060
#define IEEE80211_STYPE_CFACKPOLL 0x0070
+#define IEEE80211_STYPE_QOS_DATA 0x0080
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
-
/* debug macros */
#ifdef CONFIG_IEEE80211_DEBUG
@@ -128,8 +114,7 @@ do { if (ieee80211_debug_level & (level)) \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
#else
#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif /* CONFIG_IEEE80211_DEBUG */
-
+#endif /* CONFIG_IEEE80211_DEBUG */
/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
@@ -140,7 +125,6 @@ do { if (ieee80211_debug_level & (level)) \
* messages. It should never be used for passing essid to user space. */
const char *escape_essid(const char *essid, u8 essid_len);
-
/*
* To use the debug system:
*
@@ -177,6 +161,7 @@ const char *escape_essid(const char *essid, u8 essid_len);
#define IEEE80211_DL_TX (1<<8)
#define IEEE80211_DL_RX (1<<9)
+#define IEEE80211_DL_QOS (1<<31)
#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
@@ -190,9 +175,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
#include <linux/netdevice.h>
#include <linux/wireless.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
#ifndef WIRELESS_SPY
#define WIRELESS_SPY /* enable iwspy support */
@@ -200,10 +186,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
#include <net/iw_handler.h> /* new driver API */
#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
#ifndef ETH_P_80211_RAW
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
@@ -215,10 +201,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
struct ieee80211_snap_hdr {
- u8 dsap; /* always 0xAA */
- u8 ssap; /* always 0xAA */
- u8 ctrl; /* always 0x03 */
- u8 oui[P80211_OUI_LEN]; /* organizational universal id */
+ u8 dsap; /* always 0xAA */
+ u8 ssap; /* always 0xAA */
+ u8 ctrl; /* always 0x03 */
+ u8 oui[P80211_OUI_LEN]; /* organizational universal id */
} __attribute__ ((packed));
@@ -246,8 +232,9 @@ struct ieee80211_snap_hdr {
#define WLAN_CAPABILITY_PBCC (1<<6)
#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
-#define WLAN_CAPABILITY_OSSS_OFDM (1<<13)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
/* Status codes */
enum ieee80211_statuscode {
@@ -312,14 +299,12 @@ enum ieee80211_reasoncode {
WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
};
-
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
#define IEEE80211_STATMASK_RATE (1<<3)
#define IEEE80211_STATMASK_WEMASK 0x7
-
#define IEEE80211_CCK_MODULATION (1<<0)
#define IEEE80211_OFDM_MODULATION (1<<1)
@@ -377,9 +362,6 @@ enum ieee80211_reasoncode {
#define IEEE80211_NUM_CCK_RATES 4
#define IEEE80211_OFDM_SHIFT_MASK_A 4
-
-
-
/* NOTE: This data is for statistical purposes; not all hardware provides this
* information for frames received. Not setting these will not cause
* any adverse affects. */
@@ -388,7 +370,7 @@ struct ieee80211_rx_stats {
s8 rssi;
u8 signal;
u8 noise;
- u16 rate; /* in 100 kbps */
+ u16 rate; /* in 100 kbps */
u8 received_channel;
u8 control;
u8 mask;
@@ -439,38 +421,44 @@ struct ieee80211_device;
#include "ieee80211_crypt.h"
-#define SEC_KEY_1 (1<<0)
-#define SEC_KEY_2 (1<<1)
-#define SEC_KEY_3 (1<<2)
-#define SEC_KEY_4 (1<<3)
-#define SEC_ACTIVE_KEY (1<<4)
-#define SEC_AUTH_MODE (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL (1<<7)
-#define SEC_ENABLED (1<<8)
-
-#define SEC_LEVEL_0 0 /* None */
-#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
+#define SEC_KEY_1 (1<<0)
+#define SEC_KEY_2 (1<<1)
+#define SEC_KEY_3 (1<<2)
+#define SEC_KEY_4 (1<<3)
+#define SEC_ACTIVE_KEY (1<<4)
+#define SEC_AUTH_MODE (1<<5)
+#define SEC_UNICAST_GROUP (1<<6)
+#define SEC_LEVEL (1<<7)
+#define SEC_ENABLED (1<<8)
+#define SEC_ENCRYPT (1<<9)
+
+#define SEC_LEVEL_0 0 /* None */
+#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
+
+#define SEC_ALG_NONE 0
+#define SEC_ALG_WEP 1
+#define SEC_ALG_TKIP 2
+#define SEC_ALG_CCMP 3
+
+#define WEP_KEYS 4
+#define WEP_KEY_LEN 13
+#define SCM_KEY_LEN 32
+#define SCM_TEMPORAL_KEY_LENGTH 16
struct ieee80211_security {
u16 active_key:2,
- enabled:1,
- auth_mode:2,
- auth_algo:4,
- unicast_uses_group:1;
+ enabled:1,
+ auth_mode:2, auth_algo:4, unicast_uses_group:1, encrypt:1;
+ u8 encode_alg[WEP_KEYS];
u8 key_sizes[WEP_KEYS];
- u8 keys[WEP_KEYS][WEP_KEY_LEN];
+ u8 keys[WEP_KEYS][SCM_KEY_LEN];
u8 level;
u16 flags;
} __attribute__ ((packed));
-
/*
802.11 data frame from AP
@@ -494,7 +482,7 @@ enum ieee80211_mfie {
MFIE_TYPE_RATES = 1,
MFIE_TYPE_FH_SET = 2,
MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
+ MFIE_TYPE_CF_SET = 4,
MFIE_TYPE_TIM = 5,
MFIE_TYPE_IBSS_SET = 6,
MFIE_TYPE_COUNTRY = 7,
@@ -516,11 +504,75 @@ enum ieee80211_mfie {
MFIE_TYPE_RSN = 48,
MFIE_TYPE_RATES_EX = 50,
MFIE_TYPE_GENERIC = 221,
+ MFIE_TYPE_QOS_PARAMETER = 222,
};
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+ __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+ u8 payload[0];
+ __le16 qos_ctl;
} __attribute__ ((packed));
struct ieee80211_info_element {
@@ -546,49 +598,77 @@ struct ieee80211_info_element {
u16 status;
*/
-struct ieee80211_authentication {
+struct ieee80211_auth {
struct ieee80211_hdr_3addr header;
__le16 algorithm;
__le16 transaction;
__le16 status;
- struct ieee80211_info_element info_element;
+ /* challenge */
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
+struct ieee80211_disassoc {
+ struct ieee80211_hdr_3addr header;
+ __le16 reason;
+} __attribute__ ((packed));
+
+/* Alias deauth for disassoc */
+#define ieee80211_deauth ieee80211_disassoc
+
+struct ieee80211_probe_request {
+ struct ieee80211_hdr_3addr header;
+ /* SSID, supported rates */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
struct ieee80211_probe_response {
struct ieee80211_hdr_3addr header;
u32 time_stamp[2];
__le16 beacon_interval;
__le16 capability;
- struct ieee80211_info_element info_element;
+ /* SSID, supported rates, FH params, DS params,
+ * CF params, IBSS params, TIM (if beacon), RSN */
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
-struct ieee80211_assoc_request_frame {
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 listen_interval;
+ /* SSID, supported rates, RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request {
+ struct ieee80211_hdr_3addr header;
__le16 capability;
__le16 listen_interval;
u8 current_ap[ETH_ALEN];
- struct ieee80211_info_element info_element;
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
-struct ieee80211_assoc_response_frame {
+struct ieee80211_assoc_response {
struct ieee80211_hdr_3addr header;
__le16 capability;
__le16 status;
__le16 aid;
- struct ieee80211_info_element info_element; /* supported rates */
+ /* supported rates */
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
-
struct ieee80211_txb {
u8 nr_frags;
u8 encrypted;
- u16 reserved;
- u16 frag_size;
- u16 payload_size;
+ u8 rts_included;
+ u8 reserved;
+ __le16 frag_size;
+ __le16 payload_size;
struct sk_buff *fragments[0];
};
-
/* SWEEP TABLE ENTRIES NUMBER */
#define MAX_SWEEP_TAB_ENTRIES 42
#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
@@ -604,9 +684,68 @@ struct ieee80211_txb {
#define MAX_WPA_IE_LEN 64
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM (1<<1)
-#define NETWORK_HAS_CCK (1<<2)
+#define NETWORK_EMPTY_ESSID (1<<0)
+#define NETWORK_HAS_OFDM (1<<1)
+#define NETWORK_HAS_CCK (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION (1<<4)
+#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION)
+
+#define QOS_QUEUE_NUM 4
+#define QOS_OUI_LEN 3
+#define QOS_OUI_TYPE 2
+#define QOS_ELEMENT_ID 221
+#define QOS_OUI_INFO_SUB_TYPE 0
+#define QOS_OUI_PARAM_SUB_TYPE 1
+#define QOS_VERSION_1 1
+#define QOS_AIFSN_MIN_VALUE 2
+
+struct ieee80211_qos_information_element {
+ u8 elementID;
+ u8 length;
+ u8 qui[QOS_OUI_LEN];
+ u8 qui_type;
+ u8 qui_subtype;
+ u8 version;
+ u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+ u8 aci_aifsn;
+ u8 ecw_min_max;
+ __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+ struct ieee80211_qos_information_element info_element;
+ u8 reserved;
+ struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+ __le16 cw_min[QOS_QUEUE_NUM];
+ __le16 cw_max[QOS_QUEUE_NUM];
+ u8 aifs[QOS_QUEUE_NUM];
+ u8 flag[QOS_QUEUE_NUM];
+ __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+ struct ieee80211_qos_parameters parameters;
+ int active;
+ int supported;
+ u8 param_count;
+ u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+ u8 tim_count;
+ u8 tim_period;
+} __attribute__ ((packed));
+
+/*******************************************************/
struct ieee80211_network {
/* These entries are used to identify a unique network */
@@ -616,6 +755,8 @@ struct ieee80211_network {
u8 ssid[IW_ESSID_MAX_SIZE + 1];
u8 ssid_len;
+ struct ieee80211_qos_data qos_data;
+
/* These are network statistics */
struct ieee80211_rx_stats stats;
u16 capability;
@@ -631,10 +772,12 @@ struct ieee80211_network {
u16 beacon_interval;
u16 listen_interval;
u16 atim_window;
+ u8 erp_value;
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
u8 rsn_ie[MAX_WPA_IE_LEN];
size_t rsn_ie_len;
+ struct ieee80211_tim_parameters tim;
struct list_head list;
};
@@ -651,17 +794,52 @@ enum ieee80211_state {
#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
#define DEFAULT_FTS 2346
-
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS 14
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 36
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS 32
+
+enum {
+ IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+ IEEE80211_CH_B_ONLY = (1 << 2),
+ IEEE80211_CH_NO_IBSS = (1 << 3),
+ IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
+ IEEE80211_CH_RADAR_DETECT = (1 << 5),
+ IEEE80211_CH_INVALID = (1 << 6),
+};
+
+struct ieee80211_channel {
+ u32 freq;
+ u8 channel;
+ u8 flags;
+ u8 max_power;
+};
+
+struct ieee80211_geo {
+ u8 name[4];
+ u8 bg_channels;
+ u8 a_channels;
+ struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
+ struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
+};
struct ieee80211_device {
struct net_device *dev;
+ struct ieee80211_security sec;
/* Bookkeeping structures */
struct net_device_stats stats;
struct ieee80211_stats ieee_stats;
+ struct ieee80211_geo geo;
+
/* Probe / Beacon management */
struct list_head network_free_list;
struct list_head network_list;
@@ -669,62 +847,102 @@ struct ieee80211_device {
int scans;
int scan_age;
- int iw_mode; /* operating mode (IW_MODE_*) */
+ int iw_mode; /* operating mode (IW_MODE_*) */
+ struct iw_spy_data spy_data; /* iwspy support */
spinlock_t lock;
- int tx_headroom; /* Set to size of any additional room needed at front
- * of allocated Tx SKBs */
+ int tx_headroom; /* Set to size of any additional room needed at front
+ * of allocated Tx SKBs */
u32 config;
/* WEP and other encryption related settings at the device level */
- int open_wep; /* Set to 1 to allow unencrypted frames */
+ int open_wep; /* Set to 1 to allow unencrypted frames */
- int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+ int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
* WEP key changes */
/* If the host performs {en,de}cryption, then set to 1 */
int host_encrypt;
+ int host_encrypt_msdu;
int host_decrypt;
- int ieee802_1x; /* is IEEE 802.1X used */
+ /* host performs multicast decryption */
+ int host_mc_decrypt;
+
+ int host_open_frag;
+ int host_build_iv;
+ int ieee802_1x; /* is IEEE 802.1X used */
/* WPA data */
int wpa_enabled;
int drop_unencrypted;
- int tkip_countermeasures;
int privacy_invoked;
size_t wpa_ie_len;
u8 *wpa_ie;
struct list_head crypt_deinit_list;
struct ieee80211_crypt_data *crypt[WEP_KEYS];
- int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+ int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
struct timer_list crypt_deinit_timer;
+ int crypt_quiesced;
- int bcrx_sta_key; /* use individual keys to override default keys even
- * with RX of broad/multicast frames */
+ int bcrx_sta_key; /* use individual keys to override default keys even
+ * with RX of broad/multicast frames */
/* Fragmentation structures */
struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
unsigned int frag_next_idx;
- u16 fts; /* Fragmentation Threshold */
+ u16 fts; /* Fragmentation Threshold */
+ u16 rts; /* RTS threshold */
/* Association info */
u8 bssid[ETH_ALEN];
enum ieee80211_state state;
- int mode; /* A, B, G */
- int modulation; /* CCK, OFDM */
- int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
- int abg_ture; /* ABG flag */
+ int mode; /* A, B, G */
+ int modulation; /* CCK, OFDM */
+ int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
+ int abg_true; /* ABG flag */
+
+ int perfect_rssi;
+ int worst_rssi;
/* Callback functions */
- void (*set_security)(struct net_device *dev,
- struct ieee80211_security *sec);
- int (*hard_start_xmit)(struct ieee80211_txb *txb,
- struct net_device *dev);
- int (*reset_port)(struct net_device *dev);
+ void (*set_security) (struct net_device * dev,
+ struct ieee80211_security * sec);
+ int (*hard_start_xmit) (struct ieee80211_txb * txb,
+ struct net_device * dev, int pri);
+ int (*reset_port) (struct net_device * dev);
+ int (*is_queue_full) (struct net_device * dev, int pri);
+
+ int (*handle_management) (struct net_device * dev,
+ struct ieee80211_network * network, u16 type);
+
+ /* Typical STA methods */
+ int (*handle_auth) (struct net_device * dev,
+ struct ieee80211_auth * auth);
+ int (*handle_deauth) (struct net_device * dev,
+ struct ieee80211_auth * auth);
+ int (*handle_disassoc) (struct net_device * dev,
+ struct ieee80211_disassoc * assoc);
+ int (*handle_beacon) (struct net_device * dev,
+ struct ieee80211_beacon * beacon,
+ struct ieee80211_network * network);
+ int (*handle_probe_response) (struct net_device * dev,
+ struct ieee80211_probe_response * resp,
+ struct ieee80211_network * network);
+ int (*handle_probe_request) (struct net_device * dev,
+ struct ieee80211_probe_request * req,
+ struct ieee80211_rx_stats * stats);
+ int (*handle_assoc_response) (struct net_device * dev,
+ struct ieee80211_assoc_response * resp,
+ struct ieee80211_network * network);
+
+ /* Typical AP methods */
+ int (*handle_assoc_request) (struct net_device * dev);
+ int (*handle_reassoc_request) (struct net_device * dev,
+ struct ieee80211_reassoc_request * req);
/* This must be the last item so that it points to the data
* allocated beyond this structure by alloc_ieee80211 */
@@ -736,12 +954,12 @@ struct ieee80211_device {
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-extern inline void *ieee80211_priv(struct net_device *dev)
+static inline void *ieee80211_priv(struct net_device *dev)
{
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -757,7 +975,8 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
return 1;
}
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
+ int mode)
{
/*
* It is possible for both access points and our device to support
@@ -783,14 +1002,17 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
return 0;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+static inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = IEEE80211_3ADDR_LEN;
+ u16 stype = WLAN_FC_GET_STYPE(fc);
switch (WLAN_FC_GET_TYPE(fc)) {
case IEEE80211_FTYPE_DATA:
if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
hdrlen = IEEE80211_4ADDR_LEN;
+ if (stype & IEEE80211_STYPE_QOS_DATA)
+ hdrlen += 2;
break;
case IEEE80211_FTYPE_CTL:
switch (WLAN_FC_GET_STYPE(fc)) {
@@ -808,7 +1030,48 @@ extern inline int ieee80211_get_hdrlen(u16 fc)
return hdrlen;
}
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+ switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+ case IEEE80211_1ADDR_LEN:
+ return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+ case IEEE80211_2ADDR_LEN:
+ return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+ case IEEE80211_3ADDR_LEN:
+ return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+ case IEEE80211_4ADDR_LEN:
+ return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+ }
+
+}
+
+static inline int ieee80211_is_ofdm_rate(u8 rate)
+{
+ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+ case IEEE80211_OFDM_RATE_6MB:
+ case IEEE80211_OFDM_RATE_9MB:
+ case IEEE80211_OFDM_RATE_12MB:
+ case IEEE80211_OFDM_RATE_18MB:
+ case IEEE80211_OFDM_RATE_24MB:
+ case IEEE80211_OFDM_RATE_36MB:
+ case IEEE80211_OFDM_RATE_48MB:
+ case IEEE80211_OFDM_RATE_54MB:
+ return 1;
+ }
+ return 0;
+}
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+ case IEEE80211_CCK_RATE_1MB:
+ case IEEE80211_CCK_RATE_2MB:
+ case IEEE80211_CCK_RATE_5MB:
+ case IEEE80211_CCK_RATE_11MB:
+ return 1;
+ }
+ return 0;
+}
/* ieee80211.c */
extern void free_ieee80211(struct net_device *dev);
@@ -817,18 +1080,30 @@ extern struct net_device *alloc_ieee80211(int sizeof_priv);
extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
/* ieee80211_tx.c */
-extern int ieee80211_xmit(struct sk_buff *skb,
- struct net_device *dev);
+extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
extern void ieee80211_txb_free(struct ieee80211_txb *);
-
+extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
+ struct ieee80211_hdr *frame, int len);
/* ieee80211_rx.c */
extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats);
extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr *header,
+ struct ieee80211_hdr_4addr *header,
struct ieee80211_rx_stats *stats);
+/* ieee80211_geo.c */
+extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
+ *ieee);
+extern int ieee80211_set_geo(struct ieee80211_device *ieee,
+ const struct ieee80211_geo *geo);
+
+extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
+ u8 channel);
+extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
+ u8 channel);
+extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
+
/* ieee80211_wx.c */
extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
struct iw_request_info *info,
@@ -839,17 +1114,21 @@ extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key);
-
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
{
ieee->scans++;
}
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
{
return ieee->scans;
}
-
-#endif /* IEEE80211_H */
+#endif /* IEEE80211_H */
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index b58a3bcc0dc0..0a1c2d82ca4b 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -25,16 +25,22 @@
#include <linux/skbuff.h>
+enum {
+ IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
+};
+
struct ieee80211_crypto_ops {
const char *name;
/* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated
* private data on success */
- void * (*init)(int keyidx);
+ void *(*init) (int keyidx);
/* deinitialize crypto context and free allocated private data */
- void (*deinit)(void *priv);
+ void (*deinit) (void *priv);
+
+ int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv);
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
* value from decrypt_mpdu is passed as the keyidx value for
@@ -42,34 +48,39 @@ struct ieee80211_crypto_ops {
* encryption; if not, error will be returned; these functions are
* called for all MPDUs (i.e., fragments).
*/
- int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+ int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
/* These functions are called for full MSDUs, i.e. full frames.
* These can be NULL if full MSDU operations are not needed. */
- int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
- void *priv);
+ int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
+ void *priv);
- int (*set_key)(void *key, int len, u8 *seq, void *priv);
- int (*get_key)(void *key, int len, u8 *seq, void *priv);
+ int (*set_key) (void *key, int len, u8 * seq, void *priv);
+ int (*get_key) (void *key, int len, u8 * seq, void *priv);
/* procfs handler for printing out key information and possible
* statistics */
- char * (*print_stats)(char *p, void *priv);
+ char *(*print_stats) (char *p, void *priv);
+
+ /* Crypto specific flag get/set for configuration settings */
+ unsigned long (*get_flags) (void *priv);
+ unsigned long (*set_flags) (unsigned long flags, void *priv);
/* maximum number of bytes added by encryption; encrypt buf is
* allocated with extra_prefix_len bytes, copy of in_buf, and
* extra_postfix_len; encrypt need not use all this space, but
* the result must start at the beginning of the buffer and correct
* length must be returned */
- int extra_prefix_len, extra_postfix_len;
+ int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
+ int extra_msdu_prefix_len, extra_msdu_postfix_len;
struct module *owner;
};
struct ieee80211_crypt_data {
- struct list_head list; /* delayed deletion list */
+ struct list_head list; /* delayed deletion list */
struct ieee80211_crypto_ops *ops;
void *priv;
atomic_t refcnt;
@@ -77,10 +88,11 @@ struct ieee80211_crypt_data {
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
+struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
void ieee80211_crypt_deinit_handler(unsigned long);
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt);
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee);
#endif
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
new file mode 100644
index 000000000000..429b73892a5f
--- /dev/null
+++ b/include/net/ieee80211_radiotap.h
@@ -0,0 +1,231 @@
+/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
+/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2004 David Young. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``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 DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * Modifications to fit into the linux IEEE 802.11 stack,
+ * Mike Kershaw (dragorn@kismetwireless.net)
+ */
+
+#ifndef IEEE80211RADIOTAP_H
+#define IEEE80211RADIOTAP_H
+
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+
+/* Radiotap header version (from official NetBSD feed) */
+#define IEEE80211RADIOTAP_VERSION "1.5"
+/* Base version of the radiotap packet header data */
+#define PKTHDR_RADIOTAP_VERSION 0
+
+/* A generic radio capture format is desirable. There is one for
+ * Linux, but it is neither rigidly defined (there were not even
+ * units given for some fields) nor easily extensible.
+ *
+ * I suggest the following extensible radio capture format. It is
+ * based on a bitmap indicating which fields are present.
+ *
+ * I am trying to describe precisely what the application programmer
+ * should expect in the following, and for that reason I tell the
+ * units and origin of each measurement (where it applies), or else I
+ * use sufficiently weaselly language ("is a monotonically nondecreasing
+ * function of...") that I cannot set false expectations for lawyerly
+ * readers.
+ */
+
+/* XXX tcpdump/libpcap do not tolerate variable-length headers,
+ * yet, so we pad every radiotap header to 64 bytes. Ugh.
+ */
+#define IEEE80211_RADIOTAP_HDRLEN 64
+
+/* The radio capture header precedes the 802.11 header. */
+struct ieee80211_radiotap_header {
+ u8 it_version; /* Version 0. Only increases
+ * for drastic changes,
+ * introduction of compatible
+ * new fields does not count.
+ */
+ u8 it_pad;
+ u16 it_len; /* length of the whole
+ * header in bytes, including
+ * it_version, it_pad,
+ * it_len, and data fields.
+ */
+ u32 it_present; /* A bitmap telling which
+ * fields are present. Set bit 31
+ * (0x80000000) to extend the
+ * bitmap by another 32 bits.
+ * Additional extensions are made
+ * by setting bit 31.
+ */
+};
+
+/* Name Data type Units
+ * ---- --------- -----
+ *
+ * IEEE80211_RADIOTAP_TSFT u64 microseconds
+ *
+ * Value in microseconds of the MAC's 64-bit 802.11 Time
+ * Synchronization Function timer when the first bit of the
+ * MPDU arrived at the MAC. For received frames, only.
+ *
+ * IEEE80211_RADIOTAP_CHANNEL 2 x u16 MHz, bitmap
+ *
+ * Tx/Rx frequency in MHz, followed by flags (see below).
+ *
+ * IEEE80211_RADIOTAP_FHSS u16 see below
+ *
+ * For frequency-hopping radios, the hop set (first byte)
+ * and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE u8 500kb/s
+ *
+ * Tx/Rx data rate
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * RF signal power at the antenna, decibel difference from
+ * one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * RF noise power at the antenna, decibel difference from one
+ * milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
+ *
+ * RF signal power at the antenna, decibel difference from an
+ * arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
+ *
+ * RF noise power at the antenna, decibel difference from an
+ * arbitrary, fixed reference point.
+ *
+ * IEEE80211_RADIOTAP_LOCK_QUALITY u16 unitless
+ *
+ * Quality of Barker code lock. Unitless. Monotonically
+ * nondecreasing with "better" lock strength. Called "Signal
+ * Quality" in datasheets. (Is there a standard way to measure
+ * this?)
+ *
+ * IEEE80211_RADIOTAP_TX_ATTENUATION u16 unitless
+ *
+ * Transmit power expressed as unitless distance from max
+ * power set at factory calibration. 0 is max power.
+ * Monotonically nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u16 decibels (dB)
+ *
+ * Transmit power expressed as decibel distance from max power
+ * set at factory calibration. 0 is max power. Monotonically
+ * nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * Transmit power expressed as dBm (decibels from a 1 milliwatt
+ * reference). This is the absolute power level measured at
+ * the antenna port.
+ *
+ * IEEE80211_RADIOTAP_FLAGS u8 bitmap
+ *
+ * Properties of transmitted and received frames. See flags
+ * defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA u8 antenna index
+ *
+ * Unitless indication of the Rx/Tx antenna for this packet.
+ * The first antenna is antenna 0.
+ *
+ * IEEE80211_RADIOTAP_FCS u32 data
+ *
+ * FCS from frame in network byte order.
+ */
+enum ieee80211_radiotap_type {
+ IEEE80211_RADIOTAP_TSFT = 0,
+ IEEE80211_RADIOTAP_FLAGS = 1,
+ IEEE80211_RADIOTAP_RATE = 2,
+ IEEE80211_RADIOTAP_CHANNEL = 3,
+ IEEE80211_RADIOTAP_FHSS = 4,
+ IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+ IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+ IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+ IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+ IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+ IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+ IEEE80211_RADIOTAP_ANTENNA = 11,
+ IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+ IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+ IEEE80211_RADIOTAP_EXT = 31,
+};
+
+/* Channel flags. */
+#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
+#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
+#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
+#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
+#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
+#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
+#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
+#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
+
+/* For IEEE80211_RADIOTAP_FLAGS */
+#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
+ * during CFP
+ */
+#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
+ * with short
+ * preamble
+ */
+#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
+ * with WEP encryption
+ */
+#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
+ * with fragmentation
+ */
+#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
+#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
+ * 802.11 header and payload
+ * (to 32-bit boundary)
+ */
+
+/* Ugly macro to convert literal channel numbers into their mhz equivalents
+ * There are certianly some conditions that will break this (like feeding it '30')
+ * but they shouldn't arise since nothing talks on channel 30. */
+#define ieee80211chan2mhz(x) \
+ (((x) <= 14) ? \
+ (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
+ ((x) + 1000) * 5)
+
+#endif /* IEEE80211_RADIOTAP_H */
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 03df3b157960..5a2beed5a770 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -26,19 +26,18 @@
struct inet_hashinfo;
/* I have no idea if this is a good hash for v6 or not. -DaveM */
-static inline int inet6_ehashfn(const struct in6_addr *laddr, const u16 lport,
- const struct in6_addr *faddr, const u16 fport,
- const int ehash_size)
+static inline unsigned int inet6_ehashfn(const struct in6_addr *laddr, const u16 lport,
+ const struct in6_addr *faddr, const u16 fport)
{
- int hashent = (lport ^ fport);
+ unsigned int hashent = (lport ^ fport);
hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]);
hashent ^= hashent >> 16;
hashent ^= hashent >> 8;
- return (hashent & (ehash_size - 1));
+ return hashent;
}
-static inline int inet6_sk_ehashfn(const struct sock *sk, const int ehash_size)
+static inline int inet6_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct ipv6_pinfo *np = inet6_sk(sk);
@@ -46,7 +45,7 @@ static inline int inet6_sk_ehashfn(const struct sock *sk, const int ehash_size)
const struct in6_addr *faddr = &np->daddr;
const __u16 lport = inet->num;
const __u16 fport = inet->dport;
- return inet6_ehashfn(laddr, lport, faddr, fport, ehash_size);
+ return inet6_ehashfn(laddr, lport, faddr, fport);
}
/*
@@ -69,14 +68,14 @@ static inline struct sock *
/* Optimize here for direct hit, only listening connections can
* have wildcards anyways.
*/
- const int hash = inet6_ehashfn(daddr, hnum, saddr, sport,
- hashinfo->ehash_size);
- struct inet_ehash_bucket *head = &hashinfo->ehash[hash];
+ unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+ prefetch(head->chain.first);
read_lock(&head->lock);
sk_for_each(sk, node, &head->chain) {
/* For IPV6 do the cheaper port and family tests first. */
- if (INET6_MATCH(sk, saddr, daddr, ports, dif))
+ if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
goto hit; /* You sunk my battleship! */
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 651f824c1008..b0c99060b78d 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -94,7 +94,7 @@ static inline void *inet_csk_ca(const struct sock *sk)
extern struct sock *inet_csk_clone(struct sock *sk,
const struct request_sock *req,
- const unsigned int __nocast priority);
+ const gfp_t priority);
enum inet_csk_ack_state_t {
ICSK_ACK_SCHED = 1,
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 646b6ea7fe26..f50f95968340 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -40,7 +40,7 @@
struct inet_ehash_bucket {
rwlock_t lock;
struct hlist_head chain;
-} __attribute__((__aligned__(8)));
+};
/* There are a few simple rules, which allow for local port reuse by
* an application. In essence:
@@ -108,7 +108,7 @@ struct inet_hashinfo {
struct inet_bind_hashbucket *bhash;
int bhash_size;
- int ehash_size;
+ unsigned int ehash_size;
/* All sockets in TCP_LISTEN state will be in here. This is the only
* table where wildcard'd TCP sockets can exist. Hash function here
@@ -130,17 +130,16 @@ struct inet_hashinfo {
int port_rover;
};
-static inline int inet_ehashfn(const __u32 laddr, const __u16 lport,
- const __u32 faddr, const __u16 fport,
- const int ehash_size)
+static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
+ const __u32 faddr, const __u16 fport)
{
- int h = (laddr ^ lport) ^ (faddr ^ fport);
+ unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
h ^= h >> 16;
h ^= h >> 8;
- return h & (ehash_size - 1);
+ return h;
}
-static inline int inet_sk_ehashfn(const struct sock *sk, const int ehash_size)
+static inline int inet_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const __u32 laddr = inet->rcv_saddr;
@@ -148,7 +147,14 @@ static inline int inet_sk_ehashfn(const struct sock *sk, const int ehash_size)
const __u32 faddr = inet->daddr;
const __u16 fport = inet->dport;
- return inet_ehashfn(laddr, lport, faddr, fport, ehash_size);
+ return inet_ehashfn(laddr, lport, faddr, fport);
+}
+
+static inline struct inet_ehash_bucket *inet_ehash_bucket(
+ struct inet_hashinfo *hashinfo,
+ unsigned int hash)
+{
+ return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)];
}
extern struct inet_bind_bucket *
@@ -235,9 +241,11 @@ static inline void __inet_hash(struct inet_hashinfo *hashinfo,
lock = &hashinfo->lhash_lock;
inet_listen_wlock(hashinfo);
} else {
- sk->sk_hashent = inet_sk_ehashfn(sk, hashinfo->ehash_size);
- list = &hashinfo->ehash[sk->sk_hashent].chain;
- lock = &hashinfo->ehash[sk->sk_hashent].lock;
+ struct inet_ehash_bucket *head;
+ sk->sk_hash = inet_sk_ehashfn(sk);
+ head = inet_ehash_bucket(hashinfo, sk->sk_hash);
+ list = &head->chain;
+ lock = &head->lock;
write_lock(lock);
}
__sk_add_node(sk, list);
@@ -268,9 +276,8 @@ static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk)
inet_listen_wlock(hashinfo);
lock = &hashinfo->lhash_lock;
} else {
- struct inet_ehash_bucket *head = &hashinfo->ehash[sk->sk_hashent];
- lock = &head->lock;
- write_lock_bh(&head->lock);
+ lock = &inet_ehash_bucket(hashinfo, sk->sk_hash)->lock;
+ write_lock_bh(lock);
}
if (__sk_del_node_init(sk))
@@ -337,23 +344,27 @@ sherry_cache:
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
const __u64 __name = (((__u64)(__daddr)) << 32) | ((__u64)(__saddr));
#endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\
- (((*((__u64 *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
+#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && \
+ ((*((__u64 *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\
- (((*((__u64 *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
+#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && \
+ ((*((__u64 *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr)
-#define INET_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif) \
- ((inet_sk(__sk)->daddr == (__saddr)) && \
+#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && \
+ (inet_sk(__sk)->daddr == (__saddr)) && \
(inet_sk(__sk)->rcv_saddr == (__daddr)) && \
((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif) \
- ((inet_twsk(__sk)->tw_daddr == (__saddr)) && \
+#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && \
+ (inet_twsk(__sk)->tw_daddr == (__saddr)) && \
(inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \
((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
@@ -378,18 +389,19 @@ static inline struct sock *
/* Optimize here for direct hit, only listening connections can
* have wildcards anyways.
*/
- const int hash = inet_ehashfn(daddr, hnum, saddr, sport, hashinfo->ehash_size);
- struct inet_ehash_bucket *head = &hashinfo->ehash[hash];
+ unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+ prefetch(head->chain.first);
read_lock(&head->lock);
sk_for_each(sk, node, &head->chain) {
- if (INET_MATCH(sk, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
goto hit; /* You sunk my battleship! */
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
- if (INET_TW_MATCH(sk, acookie, saddr, daddr, ports, dif))
+ if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
goto hit;
}
sk = NULL;
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 3b070352e869..28f7b2103505 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -19,6 +19,7 @@
#include <linux/ip.h>
#include <linux/list.h>
+#include <linux/module.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/workqueue.h>
@@ -112,6 +113,7 @@ struct inet_timewait_sock {
#define tw_node __tw_common.skc_node
#define tw_bind_node __tw_common.skc_bind_node
#define tw_refcnt __tw_common.skc_refcnt
+#define tw_hash __tw_common.skc_hash
#define tw_prot __tw_common.skc_prot
volatile unsigned char tw_substate;
/* 3 bits hole, try to pack */
@@ -126,7 +128,6 @@ struct inet_timewait_sock {
/* And these are ours. */
__u8 tw_ipv6only:1;
/* 31 bits hole, try to pack */
- int tw_hashent;
int tw_timeout;
unsigned long tw_ttd;
struct inet_bind_bucket *tw_tb;
@@ -193,11 +194,13 @@ static inline u32 inet_rcv_saddr(const struct sock *sk)
static inline void inet_twsk_put(struct inet_timewait_sock *tw)
{
if (atomic_dec_and_test(&tw->tw_refcnt)) {
+ struct module *owner = tw->tw_prot->owner;
#ifdef SOCK_REFCNT_DEBUG
printk(KERN_DEBUG "%s timewait_sock %p released\n",
tw->tw_prot->name, tw);
#endif
kmem_cache_free(tw->tw_prot->twsk_slab, tw);
+ module_put(owner);
}
}
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index e426641c519f..3b5559a023a4 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -84,6 +84,7 @@
#define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */
#define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */
#define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */
+#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
/* Move it to better place one day, for now keep it unique */
#define NFC_IPVS_PROPERTY 0x10000
@@ -739,6 +740,8 @@ enum {
extern struct ip_vs_conn *ip_vs_conn_in_get
(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+extern struct ip_vs_conn *ip_vs_ct_in_get
+(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
extern struct ip_vs_conn *ip_vs_conn_out_get
(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
@@ -829,7 +832,7 @@ extern void ip_vs_app_inc_put(struct ip_vs_app *inc);
extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff **pskb);
extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff **pskb);
-extern int ip_vs_skb_replace(struct sk_buff *skb, int pri,
+extern int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri,
char *o_buf, int o_len, char *n_buf, int n_len);
extern int ip_vs_app_init(void);
extern void ip_vs_app_cleanup(void);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 3203eaff4bd4..65ec86678a08 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -233,6 +233,10 @@ extern int ip6_ra_control(struct sock *sk, int sel,
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/llc.h b/include/net/llc.h
index 71769a5aeef3..1adb2ef3f6f7 100644
--- a/include/net/llc.h
+++ b/include/net/llc.h
@@ -17,6 +17,8 @@
#include <linux/list.h>
#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
struct net_device;
struct packet_type;
struct sk_buff;
@@ -44,6 +46,7 @@ struct llc_sap {
unsigned char state;
unsigned char p_bit;
unsigned char f_bit;
+ atomic_t refcnt;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
@@ -81,13 +84,27 @@ extern struct llc_sap *llc_sap_open(unsigned char lsap,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev));
+static inline void llc_sap_hold(struct llc_sap *sap)
+{
+ atomic_inc(&sap->refcnt);
+}
+
extern void llc_sap_close(struct llc_sap *sap);
+static inline void llc_sap_put(struct llc_sap *sap)
+{
+ if (atomic_dec_and_test(&sap->refcnt))
+ llc_sap_close(sap);
+}
+
extern struct llc_sap *llc_sap_find(unsigned char sap_value);
extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
unsigned char *dmac, unsigned char dsap);
+extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
+extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
+
extern int llc_station_init(void);
extern void llc_station_exit(void);
@@ -98,4 +115,17 @@ extern void llc_proc_exit(void);
#define llc_proc_init() (0)
#define llc_proc_exit() do { } while(0)
#endif /* CONFIG_PROC_FS */
+#ifdef CONFIG_SYSCTL
+extern int llc_sysctl_init(void);
+extern void llc_sysctl_exit(void);
+
+extern int sysctl_llc2_ack_timeout;
+extern int sysctl_llc2_busy_timeout;
+extern int sysctl_llc2_p_timeout;
+extern int sysctl_llc2_rej_timeout;
+extern int sysctl_llc_station_ack_timeout;
+#else
+#define llc_sysctl_init() (0)
+#define llc_sysctl_exit() do { } while(0)
+#endif /* CONFIG_SYSCTL */
#endif /* LLC_H */
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
index 8ad3bc2c23d7..00730d21b522 100644
--- a/include/net/llc_conn.h
+++ b/include/net/llc_conn.h
@@ -19,14 +19,14 @@
#define LLC_EVENT 1
#define LLC_PACKET 2
-#define LLC_P_TIME 2
-#define LLC_ACK_TIME 1
-#define LLC_REJ_TIME 3
-#define LLC_BUSY_TIME 3
+#define LLC2_P_TIME 2
+#define LLC2_ACK_TIME 1
+#define LLC2_REJ_TIME 3
+#define LLC2_BUSY_TIME 3
struct llc_timer {
struct timer_list timer;
- u16 expire; /* timer expire time */
+ unsigned long expire; /* timer expire time */
};
struct llc_sock {
@@ -38,6 +38,7 @@ struct llc_sock {
struct llc_addr laddr; /* lsap/mac pair */
struct llc_addr daddr; /* dsap/mac pair */
struct net_device *dev; /* device to send to remote */
+ u32 copied_seq; /* head of yet unread data */
u8 retry_count; /* number of retries */
u8 ack_must_be_send;
u8 first_pdu_Ns;
@@ -92,7 +93,8 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
return skb->cb[sizeof(skb->cb) - 1];
}
-extern struct sock *llc_sk_alloc(int family, int priority, struct proto *prot);
+extern struct sock *llc_sk_alloc(int family, gfp_t priority,
+ struct proto *prot);
extern void llc_sk_free(struct sock *sk);
extern void llc_sk_reset(struct sock *sk);
@@ -115,5 +117,4 @@ extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
extern u8 llc_data_accept_state(u8 state);
extern void llc_build_offset_table(void);
-extern int llc_release_sockets(struct llc_sap *sap);
#endif /* LLC_CONN_H */
diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h
index f45c37d89cf7..c7a959428b4f 100644
--- a/include/net/llc_pdu.h
+++ b/include/net/llc_pdu.h
@@ -254,8 +254,10 @@ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
{
if (skb->protocol == ntohs(ETH_P_802_2))
memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN);
- else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+ else if (skb->protocol == ntohs(ETH_P_TR_802_2)) {
memcpy(sa, tr_hdr(skb)->saddr, ETH_ALEN);
+ *sa &= 0x7F;
+ }
}
/**
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
index 353baaa627f3..2c56dbece729 100644
--- a/include/net/llc_sap.h
+++ b/include/net/llc_sap.h
@@ -12,11 +12,15 @@
* See the GNU General Public License for more details.
*/
struct llc_sap;
+struct net_device;
struct sk_buff;
+struct sock;
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
-extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
-extern struct sk_buff *llc_alloc_frame(void);
+extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
+ unsigned char prim);
+extern struct sk_buff *llc_alloc_frame(struct sock *sk,
+ struct net_device *dev);
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
struct sk_buff *skb,
diff --git a/include/net/netrom.h b/include/net/netrom.h
index 45f2c7616d8b..a6bf6e0f606a 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -6,6 +6,7 @@
#ifndef _NETROM_H
#define _NETROM_H
+
#include <linux/netrom.h>
#include <linux/list.h>
#include <net/sock.h>
@@ -22,6 +23,7 @@
#define NR_DISCACK 0x04
#define NR_INFO 0x05
#define NR_INFOACK 0x06
+#define NR_RESET 0x07
#define NR_CHOKE_FLAG 0x80
#define NR_NAK_FLAG 0x40
@@ -51,11 +53,16 @@ enum {
#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */
#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */
#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */
+#define NR_DEFAULT_RESET 0 /* Sent / accept reset cmds? */
#define NR_MODULUS 256
#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */
#define NR_MAX_PACKET_SIZE 236 /* Maximum Packet Length - 236 */
+struct nr_private {
+ struct net_device_stats stats;
+};
+
struct nr_sock {
struct sock sock;
ax25_address user_addr, source_addr, dest_addr;
@@ -176,6 +183,8 @@ extern int sysctl_netrom_transport_requested_window_size;
extern int sysctl_netrom_transport_no_activity_timeout;
extern int sysctl_netrom_routing_control;
extern int sysctl_netrom_link_fails_count;
+extern int sysctl_netrom_reset_circuit;
+
extern int nr_rx_frame(struct sk_buff *, struct net_device *);
extern void nr_destroy_socket(struct sock *);
@@ -218,7 +227,28 @@ extern void nr_requeue_frames(struct sock *);
extern int nr_validate_nr(struct sock *, unsigned short);
extern int nr_in_rx_window(struct sock *, unsigned short);
extern void nr_write_internal(struct sock *, int);
-extern void nr_transmit_refusal(struct sk_buff *, int);
+
+extern void __nr_transmit_reply(struct sk_buff *skb, int mine,
+ unsigned char cmdflags);
+
+/*
+ * This routine is called when a Connect Acknowledge with the Choke Flag
+ * set is needed to refuse a connection.
+ */
+#define nr_transmit_refusal(skb, mine) \
+do { \
+ __nr_transmit_reply((skb), (mine), NR_CONNACK | NR_CHOKE_FLAG); \
+} while (0)
+
+/*
+ * This routine is called when we don't have a circuit matching an incoming
+ * NET/ROM packet. This is an G8PZT Xrouter extension.
+ */
+#define nr_transmit_reset(skb, mine) \
+do { \
+ __nr_transmit_reply((skb), (mine), NR_RESET); \
+} while (0)
+
extern void nr_disconnect(struct sock *, int);
/* nr_timer.c */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index e1d5ec1c23c0..8f241216f46b 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -125,7 +125,7 @@
*/
extern struct sock *sctp_get_ctl_sock(void);
extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
- sctp_scope_t, unsigned int __nocast gfp,
+ sctp_scope_t, gfp_t gfp,
int flags);
extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 58462164d960..1eac3d0eb7a9 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -181,17 +181,17 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t,
int sctp_chunk_iif(const struct sctp_chunk *);
struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *,
struct sctp_chunk *,
- unsigned int __nocast gfp);
+ gfp_t gfp);
__u32 sctp_generate_verification_tag(void);
void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
/* Prototypes for chunk-building functions. */
struct sctp_chunk *sctp_make_init(const struct sctp_association *,
const struct sctp_bind_addr *,
- unsigned int __nocast gfp, int vparam_len);
+ gfp_t gfp, int vparam_len);
struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *,
const struct sctp_chunk *,
- const unsigned int __nocast gfp,
+ const gfp_t gfp,
const int unkparam_len);
struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *,
const struct sctp_chunk *);
@@ -265,7 +265,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
struct sctp_endpoint *,
struct sctp_association *asoc,
void *event_arg,
- unsigned int __nocast gfp);
+ gfp_t gfp);
/* 2nd level prototypes */
void sctp_generate_t3_rtx_event(unsigned long peer);
@@ -276,7 +276,7 @@ void sctp_ootb_pkt_free(struct sctp_packet *);
struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
const struct sctp_association *,
struct sctp_chunk *,
- unsigned int __nocast gfp, int *err,
+ gfp_t gfp, int *err,
struct sctp_chunk **err_chk_p);
int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
struct sockaddr_storage*, int);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 994009bbe3b4..9c385b6417c7 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -446,7 +446,7 @@ struct sctp_ssnmap {
};
struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
- unsigned int __nocast gfp);
+ gfp_t gfp);
void sctp_ssnmap_free(struct sctp_ssnmap *map);
void sctp_ssnmap_clear(struct sctp_ssnmap *map);
@@ -947,7 +947,7 @@ struct sctp_transport {
};
struct sctp_transport *sctp_transport_new(const union sctp_addr *,
- unsigned int __nocast);
+ gfp_t);
void sctp_transport_set_owner(struct sctp_transport *,
struct sctp_association *);
void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
@@ -1095,10 +1095,10 @@ void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port);
void sctp_bind_addr_free(struct sctp_bind_addr *);
int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src,
- sctp_scope_t scope, unsigned int __nocast gfp,
+ sctp_scope_t scope, gfp_t gfp,
int flags);
int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
- unsigned int __nocast gfp);
+ gfp_t gfp);
int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
struct sctp_sock *);
@@ -1108,9 +1108,9 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
struct sctp_sock *opt);
union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
int *addrs_len,
- unsigned int __nocast gfp);
+ gfp_t gfp);
int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
- __u16 port, unsigned int __nocast gfp);
+ __u16 port, gfp_t gfp);
sctp_scope_t sctp_scope(const union sctp_addr *);
int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
@@ -1239,7 +1239,7 @@ static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base)
}
/* These are function signatures for manipulating endpoints. */
-struct sctp_endpoint *sctp_endpoint_new(struct sock *, unsigned int __nocast);
+struct sctp_endpoint *sctp_endpoint_new(struct sock *, gfp_t);
void sctp_endpoint_free(struct sctp_endpoint *);
void sctp_endpoint_put(struct sctp_endpoint *);
void sctp_endpoint_hold(struct sctp_endpoint *);
@@ -1260,7 +1260,7 @@ int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t,
struct sctp_chunk **err_chunk);
int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
const union sctp_addr *peer,
- sctp_init_chunk_t *init, unsigned int __nocast gfp);
+ sctp_init_chunk_t *init, gfp_t gfp);
__u32 sctp_generate_tag(const struct sctp_endpoint *);
__u32 sctp_generate_tsn(const struct sctp_endpoint *);
@@ -1723,7 +1723,7 @@ static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base)
struct sctp_association *
sctp_association_new(const struct sctp_endpoint *, const struct sock *,
- sctp_scope_t scope, unsigned int __nocast gfp);
+ sctp_scope_t scope, gfp_t gfp);
void sctp_association_free(struct sctp_association *);
void sctp_association_put(struct sctp_association *);
void sctp_association_hold(struct sctp_association *);
@@ -1739,7 +1739,7 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
const union sctp_addr *laddr);
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
const union sctp_addr *address,
- const unsigned int __nocast gfp,
+ const gfp_t gfp,
const int peer_state);
void sctp_assoc_del_peer(struct sctp_association *asoc,
const union sctp_addr *addr);
@@ -1764,10 +1764,10 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
void sctp_assoc_set_primary(struct sctp_association *,
struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
- unsigned int __nocast);
+ gfp_t);
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
struct sctp_cookie*,
- unsigned int __nocast gfp);
+ gfp_t gfp);
int sctp_cmp_addr_exact(const union sctp_addr *ss1,
const union sctp_addr *ss2);
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 90fe4bf6754f..6c40cfc4832d 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -88,7 +88,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
__u16 error,
__u16 outbound,
__u16 inbound,
- unsigned int __nocast gfp);
+ gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
const struct sctp_association *asoc,
@@ -96,35 +96,35 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
int flags,
int state,
int error,
- unsigned int __nocast gfp);
+ gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
__u16 flags,
- unsigned int __nocast gfp);
+ gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
__u16 flags,
__u32 error,
- unsigned int __nocast gfp);
+ gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
const struct sctp_association *asoc,
__u16 flags,
- unsigned int __nocast gfp);
+ gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
const struct sctp_association *asoc,
- __u32 indication, unsigned int __nocast gfp);
+ __u32 indication, gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
- const struct sctp_association *asoc, unsigned int __nocast gfp);
+ const struct sctp_association *asoc, gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
struct sctp_chunk *chunk,
- unsigned int __nocast gfp);
+ gfp_t gfp);
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
index 1a60c6d943c1..a43c8788b650 100644
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -62,22 +62,19 @@ struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *,
void sctp_ulpq_free(struct sctp_ulpq *);
/* Add a new DATA chunk for processing. */
-int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *,
- unsigned int __nocast);
+int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
/* Add a new event for propagation to the ULP. */
int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
/* Renege previously received chunks. */
-void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *,
- unsigned int __nocast);
+void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
/* Perform partial delivery. */
-void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *,
- unsigned int __nocast);
+void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
/* Abort the partial delivery. */
-void sctp_ulpq_abort_pd(struct sctp_ulpq *, unsigned int __nocast);
+void sctp_ulpq_abort_pd(struct sctp_ulpq *, gfp_t);
/* Clear the partial data delivery condition on this socket. */
int sctp_clear_pd(struct sock *sk);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index f6328aeddcce..1c5f19f995ad 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -103,16 +103,20 @@ enum sctp_optname {
#define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM
SCTP_SOCKOPT_PEELOFF, /* peel off association. */
#define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF
- SCTP_GET_PEER_ADDRS_NUM, /* Get number of peer addresss. */
-#define SCTP_GET_PEER_ADDRS_NUM SCTP_GET_PEER_ADDRS_NUM
+ SCTP_GET_PEER_ADDRS_NUM_OLD, /* Get number of peer addresss. */
+#define SCTP_GET_PEER_ADDRS_NUM_OLD SCTP_GET_PEER_ADDRS_NUM_OLD
+ SCTP_GET_PEER_ADDRS_OLD, /* Get all peer addresss. */
+#define SCTP_GET_PEER_ADDRS_OLD SCTP_GET_PEER_ADDRS_OLD
+ SCTP_GET_LOCAL_ADDRS_NUM_OLD, /* Get number of local addresss. */
+#define SCTP_GET_LOCAL_ADDRS_NUM_OLD SCTP_GET_LOCAL_ADDRS_NUM_OLD
+ SCTP_GET_LOCAL_ADDRS_OLD, /* Get all local addresss. */
+#define SCTP_GET_LOCAL_ADDRS_OLD SCTP_GET_LOCAL_ADDRS_OLD
+ SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
+#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX
SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */
#define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS
- SCTP_GET_LOCAL_ADDRS_NUM, /* Get number of local addresss. */
-#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM
SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */
#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
- SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
-#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX
};
/*
@@ -239,7 +243,7 @@ struct sctp_paddr_change {
int spc_state;
int spc_error;
sctp_assoc_t spc_assoc_id;
-};
+} __attribute__((packed, aligned(4)));
/*
* spc_state: 32 bits (signed integer)
@@ -464,7 +468,7 @@ struct sctp_assocparams {
struct sctp_setpeerprim {
sctp_assoc_t sspp_assoc_id;
struct sockaddr_storage sspp_addr;
-};
+} __attribute__((packed, aligned(4)));
/*
* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
@@ -477,7 +481,7 @@ struct sctp_setpeerprim {
struct sctp_prim {
sctp_assoc_t ssp_assoc_id;
struct sockaddr_storage ssp_addr;
-};
+} __attribute__((packed, aligned(4)));
/*
* 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
@@ -504,7 +508,7 @@ struct sctp_paddrparams {
struct sockaddr_storage spp_address;
__u32 spp_hbinterval;
__u16 spp_pathmaxrxt;
-};
+} __attribute__((packed, aligned(4)));
/*
* 7.2.2 Peer Address Information
@@ -523,7 +527,7 @@ struct sctp_paddrinfo {
__u32 spinfo_srtt;
__u32 spinfo_rto;
__u32 spinfo_mtu;
-};
+} __attribute__((packed, aligned(4)));
/* Peer addresses's state. */
enum sctp_spinfo_state {
@@ -559,11 +563,16 @@ struct sctp_status {
* SCTP_GET_LOCAL_ADDRS socket options used internally to implement
* sctp_getpaddrs() and sctp_getladdrs() API.
*/
-struct sctp_getaddrs {
+struct sctp_getaddrs_old {
sctp_assoc_t assoc_id;
int addr_num;
struct sockaddr __user *addrs;
};
+struct sctp_getaddrs {
+ sctp_assoc_t assoc_id; /*input*/
+ __u32 addr_num; /*output*/
+ __u8 addrs[0]; /*output, variable size*/
+};
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
/* On user space Linux, these live in <bits/socket.h> as an enum. */
diff --git a/include/net/sock.h b/include/net/sock.h
index 8c48fbecb7cf..e0498bd36004 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -99,6 +99,7 @@ struct proto;
* @skc_node: main hash linkage for various protocol lookup tables
* @skc_bind_node: bind hash linkage for various protocol lookup tables
* @skc_refcnt: reference count
+ * @skc_hash: hash value used with various protocol lookup tables
* @skc_prot: protocol handlers inside a network family
*
* This is the minimal network layer representation of sockets, the header
@@ -112,6 +113,7 @@ struct sock_common {
struct hlist_node skc_node;
struct hlist_node skc_bind_node;
atomic_t skc_refcnt;
+ unsigned int skc_hash;
struct proto *skc_prot;
};
@@ -139,7 +141,6 @@ struct sock_common {
* @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
* @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
* @sk_lingertime: %SO_LINGER l_linger setting
- * @sk_hashent: hash entry in several tables (e.g. inet_hashinfo.ehash)
* @sk_backlog: always used with the per-socket spinlock held
* @sk_callback_lock: used with the callbacks in the end of this struct
* @sk_error_queue: rarely used
@@ -186,6 +187,7 @@ struct sock {
#define sk_node __sk_common.skc_node
#define sk_bind_node __sk_common.skc_bind_node
#define sk_refcnt __sk_common.skc_refcnt
+#define sk_hash __sk_common.skc_hash
#define sk_prot __sk_common.skc_prot
unsigned char sk_shutdown : 2,
sk_no_check : 2,
@@ -205,10 +207,9 @@ struct sock {
struct sk_buff_head sk_write_queue;
int sk_wmem_queued;
int sk_forward_alloc;
- unsigned int sk_allocation;
+ gfp_t sk_allocation;
int sk_sndbuf;
int sk_route_caps;
- int sk_hashent;
unsigned long sk_flags;
unsigned long sk_lingertime;
/*
@@ -738,18 +739,18 @@ extern void FASTCALL(release_sock(struct sock *sk));
#define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock))
extern struct sock *sk_alloc(int family,
- unsigned int __nocast priority,
+ gfp_t priority,
struct proto *prot, int zero_it);
extern void sk_free(struct sock *sk);
extern struct sock *sk_clone(const struct sock *sk,
- const unsigned int __nocast priority);
+ const gfp_t priority);
extern struct sk_buff *sock_wmalloc(struct sock *sk,
unsigned long size, int force,
- unsigned int __nocast priority);
+ gfp_t priority);
extern struct sk_buff *sock_rmalloc(struct sock *sk,
unsigned long size, int force,
- unsigned int __nocast priority);
+ gfp_t priority);
extern void sock_wfree(struct sk_buff *skb);
extern void sock_rfree(struct sk_buff *skb);
@@ -765,7 +766,7 @@ extern struct sk_buff *sock_alloc_send_skb(struct sock *sk,
int noblock,
int *errcode);
extern void *sock_kmalloc(struct sock *sk, int size,
- unsigned int __nocast priority);
+ gfp_t priority);
extern void sock_kfree_s(struct sock *sk, void *mem, int size);
extern void sk_send_sigurg(struct sock *sk);
@@ -1200,7 +1201,7 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk)
static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
int size, int mem,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sk_buff *skb;
int hdr_len;
@@ -1223,7 +1224,7 @@ static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk,
int size,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
return sk_stream_alloc_pskb(sk, size, 0, gfp);
}
@@ -1254,7 +1255,7 @@ static inline int sock_writeable(const struct sock *sk)
return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf / 2);
}
-static inline unsigned int __nocast gfp_any(void)
+static inline gfp_t gfp_any(void)
{
return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
}
diff --git a/include/net/syncppp.h b/include/net/syncppp.h
index 614cb6ba564e..877efa434700 100644
--- a/include/net/syncppp.h
+++ b/include/net/syncppp.h
@@ -86,7 +86,6 @@ static inline struct sppp *sppp_of(struct net_device *dev)
void sppp_attach (struct ppp_device *pd);
void sppp_detach (struct net_device *dev);
-void sppp_input (struct net_device *dev, struct sk_buff *m);
int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
struct sk_buff *sppp_dequeue (struct net_device *dev);
int sppp_isempty (struct net_device *dev);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 97af77c4d096..c24339c4e310 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -460,8 +460,7 @@ extern void tcp_send_probe0(struct sock *);
extern void tcp_send_partial(struct sock *);
extern int tcp_write_wakeup(struct sock *);
extern void tcp_send_fin(struct sock *sk);
-extern void tcp_send_active_reset(struct sock *sk,
- unsigned int __nocast priority);
+extern void tcp_send_active_reset(struct sock *sk, gfp_t priority);
extern int tcp_send_synack(struct sock *);
extern void tcp_push_one(struct sock *, unsigned int mss_now);
extern void tcp_send_ack(struct sock *sk);
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 8b075ab7a26c..4e86f2de6638 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -37,7 +37,7 @@ extern int datagram_recv_ctl(struct sock *sk,
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/net/xfrm.h b/include/net/xfrm.h
index a9d0d8c5dfbf..5beae1ccd574 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -875,7 +875,7 @@ static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsig
}
#endif
-struct xfrm_policy *xfrm_policy_alloc(int gfp);
+struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
@@ -931,4 +931,9 @@ static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b,
}
}
+static inline int xfrm_policy_id2dir(u32 index)
+{
+ return index & 7;
+}
+
#endif /* _NET_XFRM_H */
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index b707a603351b..cb8b6e6ce66c 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -151,6 +151,8 @@ struct pcmcia_device {
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/pcmcia/ss.h b/include/pcmcia/ss.h
index 0f7aacc33fe9..c8592c7e8eaa 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -21,6 +21,9 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
+#ifdef CONFIG_CARDBUS
+#include <linux/pci.h>
+#endif
/* Definitions for card status flags for GetStatus */
#define SS_WRPROT 0x0001
@@ -233,7 +236,11 @@ struct pcmcia_socket {
/* so is power hook */
int (*power_hook)(struct pcmcia_socket *sock, int operation);
-
+#ifdef CONFIG_CARDBUS
+ /* allows tuning the CB bridge before loading driver for the CB card */
+ void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus);
+#endif
+
/* state thread */
struct semaphore skt_sem; /* protects socket h/w state */
diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
index 77fe9039209b..5308683c8c41 100644
--- a/include/rdma/ib_cm.h
+++ b/include/rdma/ib_cm.h
@@ -290,6 +290,7 @@ struct ib_cm_id {
enum ib_cm_lap_state lap_state; /* internal CM/debug use */
__be32 local_id;
__be32 remote_id;
+ u32 remote_cm_qpn; /* 1 unless redirected */
};
/**
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index fc6b1c18ffc6..4172e6841e3d 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -108,6 +108,13 @@
#define IB_QP1_QKEY 0x80010000
#define IB_QP_SET_QKEY 0x80000000
+enum {
+ IB_MGMT_MAD_DATA = 232,
+ IB_MGMT_RMPP_DATA = 220,
+ IB_MGMT_VENDOR_DATA = 216,
+ IB_MGMT_SA_DATA = 200
+};
+
struct ib_mad_hdr {
u8 base_version;
u8 mgmt_class;
@@ -149,20 +156,20 @@ struct ib_sa_hdr {
struct ib_mad {
struct ib_mad_hdr mad_hdr;
- u8 data[232];
+ u8 data[IB_MGMT_MAD_DATA];
};
struct ib_rmpp_mad {
struct ib_mad_hdr mad_hdr;
struct ib_rmpp_hdr rmpp_hdr;
- u8 data[220];
+ u8 data[IB_MGMT_RMPP_DATA];
};
struct ib_sa_mad {
struct ib_mad_hdr mad_hdr;
struct ib_rmpp_hdr rmpp_hdr;
struct ib_sa_hdr sa_hdr;
- u8 data[200];
+ u8 data[IB_MGMT_SA_DATA];
} __attribute__ ((packed));
struct ib_vendor_mad {
@@ -170,7 +177,28 @@ struct ib_vendor_mad {
struct ib_rmpp_hdr rmpp_hdr;
u8 reserved;
u8 oui[3];
- u8 data[216];
+ u8 data[IB_MGMT_VENDOR_DATA];
+};
+
+struct ib_class_port_info
+{
+ u8 base_version;
+ u8 class_version;
+ __be16 capability_mask;
+ u8 reserved[3];
+ u8 resp_time_value;
+ u8 redirect_gid[16];
+ __be32 redirect_tcslfl;
+ __be16 redirect_lid;
+ __be16 redirect_pkey;
+ __be32 redirect_qp;
+ __be32 redirect_qkey;
+ u8 trap_gid[16];
+ __be32 trap_tcslfl;
+ __be16 trap_lid;
+ __be16 trap_pkey;
+ __be32 trap_hlqp;
+ __be32 trap_qkey;
};
/**
@@ -568,7 +596,7 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
u32 remote_qpn, u16 pkey_index,
struct ib_ah *ah, int rmpp_active,
int hdr_len, int data_len,
- unsigned int __nocast gfp_mask);
+ gfp_t gfp_mask);
/**
* ib_free_send_mad - Returns data buffers used to send a MAD.
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index c022edfc49da..f404fe21cc21 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -46,7 +46,36 @@ enum {
IB_SA_METHOD_GET_TABLE = 0x12,
IB_SA_METHOD_GET_TABLE_RESP = 0x92,
- IB_SA_METHOD_DELETE = 0x15
+ IB_SA_METHOD_DELETE = 0x15,
+ IB_SA_METHOD_DELETE_RESP = 0x95,
+ IB_SA_METHOD_GET_MULTI = 0x14,
+ IB_SA_METHOD_GET_MULTI_RESP = 0x94,
+ IB_SA_METHOD_GET_TRACE_TBL = 0x13
+};
+
+enum {
+ IB_SA_ATTR_CLASS_PORTINFO = 0x01,
+ IB_SA_ATTR_NOTICE = 0x02,
+ IB_SA_ATTR_INFORM_INFO = 0x03,
+ IB_SA_ATTR_NODE_REC = 0x11,
+ IB_SA_ATTR_PORT_INFO_REC = 0x12,
+ IB_SA_ATTR_SL2VL_REC = 0x13,
+ IB_SA_ATTR_SWITCH_REC = 0x14,
+ IB_SA_ATTR_LINEAR_FDB_REC = 0x15,
+ IB_SA_ATTR_RANDOM_FDB_REC = 0x16,
+ IB_SA_ATTR_MCAST_FDB_REC = 0x17,
+ IB_SA_ATTR_SM_INFO_REC = 0x18,
+ IB_SA_ATTR_LINK_REC = 0x20,
+ IB_SA_ATTR_GUID_INFO_REC = 0x30,
+ IB_SA_ATTR_SERVICE_REC = 0x31,
+ IB_SA_ATTR_PARTITION_REC = 0x33,
+ IB_SA_ATTR_PATH_REC = 0x35,
+ IB_SA_ATTR_VL_ARB_REC = 0x36,
+ IB_SA_ATTR_MC_MEMBER_REC = 0x38,
+ IB_SA_ATTR_TRACE_REC = 0x39,
+ IB_SA_ATTR_MULTI_PATH_REC = 0x3a,
+ IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b,
+ IB_SA_ATTR_INFORM_INFO_REC = 0xf3
};
enum ib_sa_selector {
@@ -256,7 +285,7 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query);
int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
struct ib_sa_path_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_path_rec *resp,
void *context),
@@ -267,7 +296,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
u8 method,
struct ib_sa_mcmember_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_mcmember_rec *resp,
void *context),
@@ -278,7 +307,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
u8 method,
struct ib_sa_service_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_service_rec *resp,
void *context),
@@ -313,7 +342,7 @@ static inline int
ib_sa_mcmember_rec_set(struct ib_device *device, u8 port_num,
struct ib_sa_mcmember_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_mcmember_rec *resp,
void *context),
@@ -355,7 +384,7 @@ static inline int
ib_sa_mcmember_rec_delete(struct ib_device *device, u8 port_num,
struct ib_sa_mcmember_rec *rec,
ib_sa_comp_mask comp_mask,
- int timeout_ms, unsigned int __nocast gfp_mask,
+ int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
struct ib_sa_mcmember_rec *resp,
void *context),
diff --git a/include/rdma/ib_user_cm.h b/include/rdma/ib_user_cm.h
index 72182d16778b..e4d1654276ad 100644
--- a/include/rdma/ib_user_cm.h
+++ b/include/rdma/ib_user_cm.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -37,7 +38,7 @@
#include <linux/types.h>
-#define IB_USER_CM_ABI_VERSION 1
+#define IB_USER_CM_ABI_VERSION 2
enum {
IB_USER_CM_CMD_CREATE_ID,
@@ -60,6 +61,7 @@ enum {
IB_USER_CM_CMD_SEND_SIDR_REP,
IB_USER_CM_CMD_EVENT,
+ IB_USER_CM_CMD_INIT_QP_ATTR,
};
/*
* command ABI structures.
@@ -71,6 +73,7 @@ struct ib_ucm_cmd_hdr {
};
struct ib_ucm_create_id {
+ __u64 uid;
__u64 response;
};
@@ -79,9 +82,14 @@ struct ib_ucm_create_id_resp {
};
struct ib_ucm_destroy_id {
+ __u64 response;
__u32 id;
};
+struct ib_ucm_destroy_id_resp {
+ __u32 events_reported;
+};
+
struct ib_ucm_attr_id {
__u64 response;
__u32 id;
@@ -94,6 +102,64 @@ struct ib_ucm_attr_id_resp {
__be32 remote_id;
};
+struct ib_ucm_init_qp_attr {
+ __u64 response;
+ __u32 id;
+ __u32 qp_state;
+};
+
+struct ib_ucm_ah_attr {
+ __u8 grh_dgid[16];
+ __u32 grh_flow_label;
+ __u16 dlid;
+ __u16 reserved;
+ __u8 grh_sgid_index;
+ __u8 grh_hop_limit;
+ __u8 grh_traffic_class;
+ __u8 sl;
+ __u8 src_path_bits;
+ __u8 static_rate;
+ __u8 is_global;
+ __u8 port_num;
+};
+
+struct ib_ucm_init_qp_attr_resp {
+ __u32 qp_attr_mask;
+ __u32 qp_state;
+ __u32 cur_qp_state;
+ __u32 path_mtu;
+ __u32 path_mig_state;
+ __u32 qkey;
+ __u32 rq_psn;
+ __u32 sq_psn;
+ __u32 dest_qp_num;
+ __u32 qp_access_flags;
+
+ struct ib_ucm_ah_attr ah_attr;
+ struct ib_ucm_ah_attr alt_ah_attr;
+
+ /* ib_qp_cap */
+ __u32 max_send_wr;
+ __u32 max_recv_wr;
+ __u32 max_send_sge;
+ __u32 max_recv_sge;
+ __u32 max_inline_data;
+
+ __u16 pkey_index;
+ __u16 alt_pkey_index;
+ __u8 en_sqd_async_notify;
+ __u8 sq_draining;
+ __u8 max_rd_atomic;
+ __u8 max_dest_rd_atomic;
+ __u8 min_rnr_timer;
+ __u8 port_num;
+ __u8 timeout;
+ __u8 retry_cnt;
+ __u8 rnr_retry;
+ __u8 alt_port_num;
+ __u8 alt_timeout;
+};
+
struct ib_ucm_listen {
__be64 service_id;
__be64 service_mask;
@@ -157,6 +223,7 @@ struct ib_ucm_req {
};
struct ib_ucm_rep {
+ __u64 uid;
__u64 data;
__u32 id;
__u32 qpn;
@@ -232,7 +299,6 @@ struct ib_ucm_event_get {
};
struct ib_ucm_req_event_resp {
- __u32 listen_id;
/* device */
/* port */
struct ib_ucm_path_rec primary_path;
@@ -287,7 +353,6 @@ struct ib_ucm_apr_event_resp {
};
struct ib_ucm_sidr_req_event_resp {
- __u32 listen_id;
/* device */
/* port */
__u16 pkey;
@@ -307,6 +372,7 @@ struct ib_ucm_sidr_rep_event_resp {
#define IB_UCM_PRES_ALTERNATE 0x08
struct ib_ucm_event_resp {
+ __u64 uid;
__u32 id;
__u32 event;
__u32 present;
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index 7ebb01c8f996..fd85725391a4 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -42,7 +42,7 @@
* Increment this value if any changes that break userspace ABI
* compatibility are made.
*/
-#define IB_USER_VERBS_ABI_VERSION 1
+#define IB_USER_VERBS_ABI_VERSION 2
enum {
IB_USER_VERBS_CMD_QUERY_PARAMS,
@@ -292,7 +292,14 @@ struct ib_uverbs_create_cq_resp {
};
struct ib_uverbs_destroy_cq {
+ __u64 response;
__u32 cq_handle;
+ __u32 reserved;
+};
+
+struct ib_uverbs_destroy_cq_resp {
+ __u32 comp_events_reported;
+ __u32 async_events_reported;
};
struct ib_uverbs_create_qp {
@@ -372,7 +379,13 @@ struct ib_uverbs_modify_qp_resp {
};
struct ib_uverbs_destroy_qp {
+ __u64 response;
__u32 qp_handle;
+ __u32 reserved;
+};
+
+struct ib_uverbs_destroy_qp_resp {
+ __u32 events_reported;
};
struct ib_uverbs_attach_mcast {
@@ -416,7 +429,13 @@ struct ib_uverbs_modify_srq {
};
struct ib_uverbs_destroy_srq {
+ __u64 response;
__u32 srq_handle;
+ __u32 reserved;
+};
+
+struct ib_uverbs_destroy_srq_resp {
+ __u32 events_reported;
};
#endif /* IB_USER_VERBS_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index e16cf94870f2..e6f4c9e55df7 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -665,7 +665,6 @@ struct ib_ucontext {
struct list_head qp_list;
struct list_head srq_list;
struct list_head ah_list;
- spinlock_t lock;
};
struct ib_uobject {
diff --git a/include/rxrpc/call.h b/include/rxrpc/call.h
index f48f27e9e0ab..b86f83743510 100644
--- a/include/rxrpc/call.h
+++ b/include/rxrpc/call.h
@@ -203,7 +203,7 @@ extern int rxrpc_call_write_data(struct rxrpc_call *call,
size_t sioc,
struct kvec *siov,
uint8_t rxhdr_flags,
- int alloc_flags,
+ gfp_t alloc_flags,
int dup_data,
size_t *size_sent);
diff --git a/include/rxrpc/message.h b/include/rxrpc/message.h
index 3a59df6870b2..b318f273d4f2 100644
--- a/include/rxrpc/message.h
+++ b/include/rxrpc/message.h
@@ -63,7 +63,7 @@ extern int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
uint8_t type,
int count,
struct kvec *diov,
- int alloc_flags,
+ gfp_t alloc_flags,
struct rxrpc_message **_msg);
extern int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg);
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index bed4b7c9be99..e6b61fab66dd 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -146,7 +146,7 @@ struct scsi_cmnd {
#define SCSI_STATE_MLQUEUE 0x100b
-extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
+extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
extern void scsi_put_command(struct scsi_cmnd *);
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index da63722c0123..7ece05666feb 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -163,6 +163,7 @@ struct scsi_target {
unsigned int id; /* target id ... replace
* scsi_device.id eventually */
unsigned long create:1; /* signal that it needs to be added */
+ char scsi_level;
void *hostdata; /* available to low-level driver */
unsigned long starget_data[0]; /* for the transport */
/* starget_data must be the last element!!!! */
@@ -178,8 +179,8 @@ static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
uint, uint, uint, void *hostdata);
-#define scsi_add_device(host, channel, target, lun) \
- __scsi_add_device(host, channel, target, lun, NULL)
+extern int scsi_add_device(struct Scsi_Host *host, uint channel,
+ uint target, uint lun);
extern void scsi_remove_device(struct scsi_device *);
extern int scsi_device_cancel(struct scsi_device *, int);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 916144be208b..69313ba7505b 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -439,6 +439,8 @@ enum scsi_host_state {
SHOST_CANCEL,
SHOST_DEL,
SHOST_RECOVERY,
+ SHOST_CANCEL_RECOVERY,
+ SHOST_DEL_RECOVERY,
};
struct Scsi_Host {
@@ -465,8 +467,6 @@ struct Scsi_Host {
struct list_head eh_cmd_q;
struct task_struct * ehandler; /* Error recovery thread. */
- struct semaphore * eh_wait; /* The error recovery thread waits
- on this. */
struct semaphore * eh_action; /* Wait for specific actions on the
host. */
unsigned int eh_active:1; /* Indicates the eh thread is awake and active if
@@ -621,6 +621,13 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
return container_of(dev, struct Scsi_Host, shost_gendev);
}
+static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
+{
+ return shost->shost_state == SHOST_RECOVERY ||
+ shost->shost_state == SHOST_CANCEL_RECOVERY ||
+ shost->shost_state == SHOST_DEL_RECOVERY;
+}
+
extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
extern void scsi_flush_work(struct Scsi_Host *);
diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
index 6a140020d7cb..2539debb7993 100644
--- a/include/scsi/scsi_request.h
+++ b/include/scsi/scsi_request.h
@@ -45,7 +45,7 @@ struct scsi_request {
level driver) of this request */
};
-extern struct scsi_request *scsi_allocate_request(struct scsi_device *, int);
+extern struct scsi_request *scsi_allocate_request(struct scsi_device *, gfp_t);
extern void scsi_release_request(struct scsi_request *);
extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
void *buffer, unsigned bufflen,
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 70ad16315a16..b0d445437372 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -103,8 +103,8 @@ enum fc_port_state {
incapable of reporting */
#define FC_PORTSPEED_1GBIT 1
#define FC_PORTSPEED_2GBIT 2
-#define FC_PORTSPEED_10GBIT 4
-#define FC_PORTSPEED_4GBIT 8
+#define FC_PORTSPEED_4GBIT 4
+#define FC_PORTSPEED_10GBIT 8
#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */
/*
@@ -439,4 +439,12 @@ int fc_remote_port_block(struct fc_rport *rport);
void fc_remote_port_unblock(struct fc_rport *rport);
int scsi_is_fc_rport(const struct device *);
+static inline u64 wwn_to_u64(u8 *wwn)
+{
+ return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
+ (u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
+ (u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
+ (u64)wwn[6] << 8 | (u64)wwn[7];
+}
+
#endif /* SCSI_TRANSPORT_FC_H */
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h
new file mode 100644
index 000000000000..bc4aeb660dd3
--- /dev/null
+++ b/include/scsi/scsi_transport_sas.h
@@ -0,0 +1,100 @@
+#ifndef SCSI_TRANSPORT_SAS_H
+#define SCSI_TRANSPORT_SAS_H
+
+#include <linux/transport_class.h>
+#include <linux/types.h>
+
+struct scsi_transport_template;
+struct sas_rphy;
+
+
+enum sas_device_type {
+ SAS_PHY_UNUSED,
+ SAS_END_DEVICE,
+ SAS_EDGE_EXPANDER_DEVICE,
+ SAS_FANOUT_EXPANDER_DEVICE,
+};
+
+enum sas_protocol {
+ SAS_PROTOCOL_SATA = 0x01,
+ SAS_PROTOCOL_SMP = 0x02,
+ SAS_PROTOCOL_STP = 0x04,
+ SAS_PROTOCOL_SSP = 0x08,
+};
+
+enum sas_linkrate {
+ SAS_LINK_RATE_UNKNOWN,
+ SAS_PHY_DISABLED,
+ SAS_LINK_RATE_FAILED,
+ SAS_SATA_SPINUP_HOLD,
+ SAS_SATA_PORT_SELECTOR,
+ SAS_LINK_RATE_1_5_GBPS,
+ SAS_LINK_RATE_3_0_GBPS,
+ SAS_LINK_VIRTUAL,
+};
+
+struct sas_identify {
+ enum sas_device_type device_type;
+ enum sas_protocol initiator_port_protocols;
+ enum sas_protocol target_port_protocols;
+ u64 sas_address;
+ u8 phy_identifier;
+};
+
+/* The functions by which the transport class and the driver communicate */
+struct sas_function_template {
+};
+
+struct sas_phy {
+ struct device dev;
+ int number;
+ struct sas_identify identify;
+ enum sas_linkrate negotiated_linkrate;
+ enum sas_linkrate minimum_linkrate_hw;
+ enum sas_linkrate minimum_linkrate;
+ enum sas_linkrate maximum_linkrate_hw;
+ enum sas_linkrate maximum_linkrate;
+ u8 port_identifier;
+ struct sas_rphy *rphy;
+};
+
+#define dev_to_phy(d) \
+ container_of((d), struct sas_phy, dev)
+#define transport_class_to_phy(cdev) \
+ dev_to_phy((cdev)->dev)
+#define phy_to_shost(phy) \
+ dev_to_shost((phy)->dev.parent)
+
+struct sas_rphy {
+ struct device dev;
+ struct sas_identify identify;
+ struct list_head list;
+ u32 scsi_target_id;
+};
+
+#define dev_to_rphy(d) \
+ container_of((d), struct sas_rphy, dev)
+#define transport_class_to_rphy(cdev) \
+ dev_to_rphy((cdev)->dev)
+#define rphy_to_shost(rphy) \
+ dev_to_shost((rphy)->dev.parent)
+
+extern void sas_remove_host(struct Scsi_Host *);
+
+extern struct sas_phy *sas_phy_alloc(struct device *, int);
+extern void sas_phy_free(struct sas_phy *);
+extern int sas_phy_add(struct sas_phy *);
+extern void sas_phy_delete(struct sas_phy *);
+extern int scsi_is_sas_phy(const struct device *);
+
+extern struct sas_rphy *sas_rphy_alloc(struct sas_phy *);
+void sas_rphy_free(struct sas_rphy *);
+extern int sas_rphy_add(struct sas_rphy *);
+extern void sas_rphy_delete(struct sas_rphy *);
+extern int scsi_is_sas_rphy(const struct device *);
+
+extern struct scsi_transport_template *
+sas_attach_transport(struct sas_function_template *);
+extern void sas_release_transport(struct scsi_transport_template *);
+
+#endif /* SCSI_TRANSPORT_SAS_H */
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 2857cf0472df..d11f34832a97 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -527,6 +527,8 @@ struct _snd_ac97 {
struct device dev;
};
+#define to_ac97_t(d) container_of(d, struct _snd_ac97, dev)
+
/* conditions */
static inline int ac97_is_audio(ac97_t * ac97)
{
diff --git a/include/sound/core.h b/include/sound/core.h
index 3dc41fd5c54d..6d971a4c4ca0 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -168,6 +168,9 @@ struct _snd_card {
wait_queue_head_t shutdown_sleep;
struct work_struct free_workq; /* for free in workqueue */
struct device *dev;
+#ifdef CONFIG_SND_GENERIC_DRIVER
+ struct snd_generic_device *generic_dev;
+#endif
#ifdef CONFIG_PM
int (*pm_suspend)(snd_card_t *card, pm_message_t state);
@@ -176,9 +179,6 @@ struct _snd_card {
unsigned int power_state; /* power state */
struct semaphore power_lock; /* power lock */
wait_queue_head_t power_sleep;
-#ifdef CONFIG_SND_GENERIC_PM
- struct snd_generic_device *pm_dev; /* for ISA */
-#endif
#endif
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
@@ -290,13 +290,13 @@ void snd_memory_init(void);
void snd_memory_done(void);
int snd_memory_info_init(void);
int snd_memory_info_done(void);
-void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags);
-void *snd_hidden_kzalloc(size_t size, unsigned int __nocast flags);
-void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags);
+void *snd_hidden_kmalloc(size_t size, gfp_t flags);
+void *snd_hidden_kzalloc(size_t size, gfp_t flags);
+void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
void snd_hidden_kfree(const void *obj);
void *snd_hidden_vmalloc(unsigned long size);
void snd_hidden_vfree(void *obj);
-char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags);
+char *snd_hidden_kstrdup(const char *s, gfp_t flags);
#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
#define kzalloc(size, flags) snd_hidden_kzalloc(size, flags)
#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
@@ -348,6 +348,8 @@ int snd_card_file_remove(snd_card_t *card, struct file *file);
#ifndef snd_card_set_dev
#define snd_card_set_dev(card,devptr) ((card)->dev = (devptr))
#endif
+/* register a generic device (for ISA, etc) */
+int snd_card_set_generic_dev(snd_card_t *card);
/* device.c */
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h
index 9b94510eda60..b0c0e192eb56 100644
--- a/include/sound/cs46xx.h
+++ b/include/sound/cs46xx.h
@@ -29,19 +29,6 @@
#include "ac97_codec.h"
#include "cs46xx_dsp_spos.h"
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS 0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4610
-#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4612
-#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4615
-#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
-#endif
-
/*
* Direct registers
*/
@@ -1715,7 +1702,6 @@ struct _snd_cs46xx {
void (*active_ctrl)(cs46xx_t *, int);
void (*mixer_init)(cs46xx_t *);
- struct pci_dev *acpi_dev;
int acpi_port;
snd_kcontrol_t *eapd_switch; /* for amplifier hack */
int accept_valid; /* accept mmap valid (for OSS) */
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 0d12456ec3ae..1ec2fae050a6 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -51,7 +51,7 @@
#ifdef CONFIG_SND_DEBUG_MEMORY
#include <linux/slab.h>
#include <linux/vmalloc.h>
-void *snd_wrapper_kmalloc(size_t, unsigned int __nocast);
+void *snd_wrapper_kmalloc(size_t, gfp_t);
#undef kmalloc
void snd_wrapper_kfree(const void *);
#undef kfree
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 4e3993dfcefe..14cb2718cb77 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -35,13 +35,6 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#ifndef PCI_VENDOR_ID_CREATIVE
-#define PCI_VENDOR_ID_CREATIVE 0x1102
-#endif
-#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
-#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
-#endif
-
/* ------------------- DEFINES -------------------- */
#define EMUPAGESIZE 4096
@@ -1066,7 +1059,7 @@ typedef struct {
unsigned char spk71; /* Has 7.1 speakers */
unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
unsigned char spdif_bug; /* Has Spdif phasing bug */
- unsigned char ac97_chip; /* Has an AC97 chip */
+ unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */
unsigned char ecard; /* APS EEPROM */
const char *driver;
const char *name;
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index 3a2fd2cc9f19..83489c3abbaf 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -111,7 +111,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id);
int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id);
/* basic memory allocation functions */
-void *snd_malloc_pages(size_t size, unsigned int gfp_flags);
+void *snd_malloc_pages(size_t size, gfp_t gfp_flags);
void snd_free_pages(void *ptr, size_t size);
#endif /* __SOUND_MEMALLOC_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 389e8ebe9c19..2b23a5967071 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -903,18 +903,20 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format);
int snd_pcm_format_linear(snd_pcm_format_t format);
int snd_pcm_format_little_endian(snd_pcm_format_t format);
int snd_pcm_format_big_endian(snd_pcm_format_t format);
-/*
+#if 0 /* just for DocBook */
+/**
* snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
* @format: the format to check
*
* 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); */
+int snd_pcm_format_cpu_endian(snd_pcm_format_t format);
+#endif /* DocBook */
#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/pcm_oss.h b/include/sound/pcm_oss.h
index 518728536bc6..0b67c9d105af 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -32,7 +32,8 @@ struct _snd_pcm_oss_setup {
block:1,
nonblock:1,
partialfrag:1,
- nosilence:1;
+ nosilence:1,
+ buggyptr:1;
unsigned int periods;
unsigned int period_size;
snd_pcm_oss_setup_t *next;
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
index ad3c3be33c03..b82e408e758f 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -34,9 +34,7 @@ struct snd_tea575x_ops {
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/sound/trident.h b/include/sound/trident.h
index f5254ec36e6a..a408d3925050 100644
--- a/include/sound/trident.h
+++ b/include/sound/trident.h
@@ -33,23 +33,6 @@
//#include "ainstr_gf1.h"
#include "ainstr_simple.h"
-#ifndef PCI_VENDOR_ID_TRIDENT
-#define PCI_VENDOR_ID_TRIDENT 0x1023
-#endif
-#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_DX
-#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
-#endif
-#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_NX
-#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
-#endif
-
-#ifndef PCI_VENDOR_ID_SI
-#define PCI_VENDOR_ID_SI 0x1039
-#endif
-#ifndef PCI_DEVICE_ID_SI_7018
-#define PCI_DEVICE_ID_SI_7018 0x7018
-#endif
-
#define TRIDENT_DEVICE_ID_DX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_DX)
#define TRIDENT_DEVICE_ID_NX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_NX)
#define TRIDENT_DEVICE_ID_SI7018 ((PCI_VENDOR_ID_SI<<16)|PCI_DEVICE_ID_SI_7018)
diff --git a/include/sound/version.h b/include/sound/version.h
index 8d19bfabb7e0..ee32af20dba9 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "1.0.10rc1"
-#define CONFIG_SND_DATE " (Tue Aug 30 05:31:08 2005 UTC)"
+#define CONFIG_SND_DATE " (Mon Sep 12 08:13:09 2005 UTC)"
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
index 9a3c1e6c820a..c3bccbfd8d4c 100644
--- a/include/sound/ymfpci.h
+++ b/include/sound/ymfpci.h
@@ -28,28 +28,6 @@
#include "timer.h"
#include <linux/gameport.h>
-#ifndef PCI_VENDOR_ID_YAMAHA
-#define PCI_VENDOR_ID_YAMAHA 0x1073
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_724
-#define PCI_DEVICE_ID_YAMAHA_724 0x0004
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_724F
-#define PCI_DEVICE_ID_YAMAHA_724F 0x000d
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_740
-#define PCI_DEVICE_ID_YAMAHA_740 0x000a
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_740C
-#define PCI_DEVICE_ID_YAMAHA_740C 0x000c
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_744
-#define PCI_DEVICE_ID_YAMAHA_744 0x0010
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_754
-#define PCI_DEVICE_ID_YAMAHA_754 0x0012
-#endif
-
/*
* Direct registers
*/
diff --git a/include/video/cyblafb.h b/include/video/cyblafb.h
new file mode 100644
index 000000000000..a9948232b131
--- /dev/null
+++ b/include/video/cyblafb.h
@@ -0,0 +1,171 @@
+
+#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/pm3fb.h b/include/video/pm3fb.h
index 8d3cef5d87a2..6f4ea808cf74 100644
--- a/include/video/pm3fb.h
+++ b/include/video/pm3fb.h
@@ -1142,9 +1142,6 @@
/* do we want accelerated console */
#define PM3FB_USE_ACCEL 1
-/* useful ? */
-#define CHAR_IS_NUM(a) ((((a) >= '0') && ((a) <= '9')) ? 1 : 0)
-
/* for driver debugging ONLY */
/* 0 = assert only, 1 = error, 2 = info, 3+ = verbose */
/* define PM3FB_MASTER_DEBUG 1 */
diff --git a/include/video/sisfb.h b/include/video/sisfb.h
index 136bf791643d..e402eb5b3c7a 100644
--- a/include/video/sisfb.h
+++ b/include/video/sisfb.h
@@ -1,5 +1,7 @@
/*
- * 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/include/video/w100fb.h b/include/video/w100fb.h
index e6da2d7ded8c..677d40326796 100644
--- a/include/video/w100fb.h
+++ b/include/video/w100fb.h
@@ -19,6 +19,7 @@ struct w100fb_par;
unsigned long w100fb_gpio_read(int port);
void w100fb_gpio_write(int port, unsigned long value);
+unsigned long w100fb_get_hsynclen(struct device *dev);
/* LCD Specific Routines and Config */
struct w100_tg_info {
diff --git a/init/initramfs.c b/init/initramfs.c
index 02c5ce64990d..0c5d9a3f951b 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -466,6 +466,14 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
extern char __initramfs_start[], __initramfs_end[];
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/initrd.h>
+
+static void __init free_initrd(void)
+{
+ free_initrd_mem(initrd_start, initrd_end);
+ initrd_start = 0;
+ initrd_end = 0;
+}
+
#endif
void __init populate_rootfs(void)
@@ -484,7 +492,7 @@ void __init populate_rootfs(void)
printk(" it is\n");
unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start, 0);
- free_initrd_mem(initrd_start, initrd_end);
+ free_initrd();
return;
}
printk("it isn't (%s); looks like an initrd\n", err);
@@ -493,7 +501,7 @@ void __init populate_rootfs(void)
sys_write(fd, (char *)initrd_start,
initrd_end - initrd_start);
sys_close(fd);
- free_initrd_mem(initrd_start, initrd_end);
+ free_initrd();
}
}
#endif
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 0acf245f441d..a0f18c9cc89d 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -69,7 +69,7 @@ struct mqueue_inode_info {
struct sigevent notify;
pid_t notify_owner;
- struct user_struct *user; /* user who created, for accouting */
+ struct user_struct *user; /* user who created, for accounting */
struct sock *notify_sock;
struct sk_buff *notify_cookie;
@@ -611,6 +611,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
dentry->d_fsdata = &attr;
}
+ mode &= ~current->fs->umask;
ret = vfs_create(dir->d_inode, dentry, mode, NULL);
dentry->d_fsdata = NULL;
if (ret)
diff --git a/kernel/Makefile b/kernel/Makefile
index 8d57a2f1226b..ff4dc02ce170 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -12,6 +12,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
obj-$(CONFIG_FUTEX) += futex.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
obj-$(CONFIG_SMP) += cpu.o spinlock.o
+obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
diff --git a/kernel/acct.c b/kernel/acct.c
index f70e6027cca9..b756f527497e 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -165,7 +165,7 @@ out:
}
/*
- * Close the old accouting file (if currently open) and then replace
+ * Close the old accounting file (if currently open) and then replace
* it with file (if non-NULL).
*
* NOTE: acct_globals.lock MUST be held on entry and exit.
@@ -199,11 +199,16 @@ static void acct_file_reopen(struct file *file)
}
}
-/*
- * sys_acct() is the only system call needed to implement process
- * accounting. It takes the name of the file where accounting records
- * should be written. If the filename is NULL, accounting will be
- * shutdown.
+/**
+ * sys_acct - enable/disable process accounting
+ * @name: file name for accounting records or NULL to shutdown accounting
+ *
+ * Returns 0 for success or negative errno values for failure.
+ *
+ * sys_acct() is the only system call needed to implement process
+ * accounting. It takes the name of the file where accounting records
+ * should be written. If the filename is NULL, accounting will be
+ * shutdown.
*/
asmlinkage long sys_acct(const char __user *name)
{
@@ -250,9 +255,12 @@ asmlinkage long sys_acct(const char __user *name)
return (0);
}
-/*
- * If the accouting is turned on for a file in the filesystem pointed
- * to by sb, turn accouting off.
+/**
+ * acct_auto_close - turn off a filesystem's accounting if it is on
+ * @sb: super block for the filesystem
+ *
+ * If the accounting is turned on for a file in the filesystem pointed
+ * to by sb, turn accounting off.
*/
void acct_auto_close(struct super_block *sb)
{
@@ -503,8 +511,11 @@ static void do_acct_process(long exitcode, struct file *file)
set_fs(fs);
}
-/*
+/**
* acct_process - now just a wrapper around do_acct_process
+ * @exitcode: task exit code
+ *
+ * handles process accounting for an exiting task
*/
void acct_process(long exitcode)
{
@@ -530,9 +541,9 @@ void acct_process(long exitcode)
}
-/*
- * acct_update_integrals
- * - update mm integral fields in task_struct
+/**
+ * acct_update_integrals - update mm integral fields in task_struct
+ * @tsk: task_struct for accounting
*/
void acct_update_integrals(struct task_struct *tsk)
{
@@ -547,9 +558,9 @@ void acct_update_integrals(struct task_struct *tsk)
}
}
-/*
- * acct_clear_integrals
- * - clear the mm integral fields in task_struct
+/**
+ * acct_clear_integrals - clear the mm integral fields in task_struct
+ * @tsk: task_struct whose accounting fields are cleared
*/
void acct_clear_integrals(struct task_struct *tsk)
{
diff --git a/kernel/audit.c b/kernel/audit.c
index 7f0699790d46..0c56320d38dc 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -79,6 +79,8 @@ static int audit_rate_limit;
/* Number of outstanding audit_buffers allowed. */
static int audit_backlog_limit = 64;
+static int audit_backlog_wait_time = 60 * HZ;
+static int audit_backlog_wait_overflow = 0;
/* The identity of the user shutting down the audit system. */
uid_t audit_sig_uid = -1;
@@ -106,18 +108,12 @@ static LIST_HEAD(audit_freelist);
static struct sk_buff_head audit_skb_queue;
static struct task_struct *kauditd_task;
static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
-
-/* There are three lists of rules -- one to search at task creation
- * time, one to search at syscall entry time, and another to search at
- * syscall exit time. */
-static LIST_HEAD(audit_tsklist);
-static LIST_HEAD(audit_entlist);
-static LIST_HEAD(audit_extlist);
+static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
/* The netlink socket is only to be read by 1 CPU, which lets us assume
* that list additions and deletions never happen simultaneously in
* auditsc.c */
-static DECLARE_MUTEX(audit_netlink_sem);
+DECLARE_MUTEX(audit_netlink_sem);
/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
* audit records. Since printk uses a 1024 byte buffer, this buffer
@@ -137,6 +133,7 @@ struct audit_buffer {
struct list_head list;
struct sk_buff *skb; /* formatted skb ready to send */
struct audit_context *ctx; /* NULL or associated context */
+ gfp_t gfp_mask;
};
static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
@@ -145,11 +142,6 @@ static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
nlh->nlmsg_pid = pid;
}
-struct audit_entry {
- struct list_head list;
- struct audit_rule rule;
-};
-
static void audit_panic(const char *message)
{
switch (audit_failure)
@@ -233,7 +225,7 @@ static int audit_set_rate_limit(int limit, uid_t loginuid)
{
int old = audit_rate_limit;
audit_rate_limit = limit;
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
"audit_rate_limit=%d old=%d by auid=%u",
audit_rate_limit, old, loginuid);
return old;
@@ -243,7 +235,7 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid)
{
int old = audit_backlog_limit;
audit_backlog_limit = limit;
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
"audit_backlog_limit=%d old=%d by auid=%u",
audit_backlog_limit, old, loginuid);
return old;
@@ -255,7 +247,7 @@ static int audit_set_enabled(int state, uid_t loginuid)
if (state != 0 && state != 1)
return -EINVAL;
audit_enabled = state;
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
"audit_enabled=%d old=%d by auid=%u",
audit_enabled, old, loginuid);
return old;
@@ -269,7 +261,7 @@ static int audit_set_failure(int state, uid_t loginuid)
&& state != AUDIT_FAIL_PANIC)
return -EINVAL;
audit_failure = state;
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
"audit_failure=%d old=%d by auid=%u",
audit_failure, old, loginuid);
return old;
@@ -281,6 +273,7 @@ int kauditd_thread(void *dummy)
while (1) {
skb = skb_dequeue(&audit_skb_queue);
+ wake_up(&audit_backlog_wait);
if (skb) {
if (audit_pid) {
int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
@@ -290,7 +283,7 @@ int kauditd_thread(void *dummy)
audit_pid = 0;
}
} else {
- printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+ printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
kfree_skb(skb);
}
} else {
@@ -423,7 +416,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (status_get->mask & AUDIT_STATUS_PID) {
int old = audit_pid;
audit_pid = status_get->pid;
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
"audit_pid=%d old=%d by auid=%u",
audit_pid, old, loginuid);
}
@@ -435,15 +428,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
break;
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
- ab = audit_log_start(NULL, msg_type);
- if (!ab)
- break; /* audit_panic has been called */
- audit_log_format(ab,
- "user pid=%d uid=%u auid=%u"
- " msg='%.1024s'",
- pid, uid, loginuid, (char *)data);
- audit_set_pid(ab, pid);
- audit_log_end(ab);
+ if (!audit_enabled && msg_type != AUDIT_USER_AVC)
+ return 0;
+
+ err = audit_filter_user(&NETLINK_CB(skb), msg_type);
+ if (err == 1) {
+ err = 0;
+ ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+ if (ab) {
+ audit_log_format(ab,
+ "user pid=%d uid=%u auid=%u msg='%.1024s'",
+ pid, uid, loginuid, (char *)data);
+ audit_set_pid(ab, pid);
+ audit_log_end(ab);
+ }
+ }
break;
case AUDIT_ADD:
case AUDIT_DEL:
@@ -523,7 +522,7 @@ static int __init audit_init(void)
skb_queue_head_init(&audit_skb_queue);
audit_initialized = 1;
audit_enabled = audit_default;
- audit_log(NULL, AUDIT_KERNEL, "initialized");
+ audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
return 0;
}
__initcall(audit_init);
@@ -561,7 +560,7 @@ static void audit_buffer_free(struct audit_buffer *ab)
}
static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
- int gfp_mask, int type)
+ gfp_t gfp_mask, int type)
{
unsigned long flags;
struct audit_buffer *ab = NULL;
@@ -587,6 +586,7 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
goto err;
ab->ctx = ctx;
+ ab->gfp_mask = gfp_mask;
nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
nlh->nlmsg_type = type;
nlh->nlmsg_flags = 0;
@@ -606,26 +606,27 @@ err:
* (timestamp,serial) tuple is unique for each syscall and is live from
* syscall entry to syscall exit.
*
- * Atomic values are only guaranteed to be 24-bit, so we count down.
- *
* NOTE: Another possibility is to store the formatted records off the
* audit context (for those records that have a context), and emit them
* all at syscall exit. However, this could delay the reporting of
* significant errors until syscall exit (or never, if the system
* halts). */
+
unsigned int audit_serial(void)
{
- static atomic_t serial = ATOMIC_INIT(0xffffff);
- unsigned int a, b;
+ static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
+ static unsigned int serial = 0;
+
+ unsigned long flags;
+ unsigned int ret;
+ spin_lock_irqsave(&serial_lock, flags);
do {
- a = atomic_read(&serial);
- if (atomic_dec_and_test(&serial))
- atomic_set(&serial, 0xffffff);
- b = atomic_read(&serial);
- } while (b != a - 1);
+ ret = ++serial;
+ } while (unlikely(!ret));
+ spin_unlock_irqrestore(&serial_lock, flags);
- return 0xffffff - b;
+ return ret;
}
static inline void audit_get_stamp(struct audit_context *ctx,
@@ -645,17 +646,43 @@ static inline void audit_get_stamp(struct audit_context *ctx,
* syscall, then the syscall is marked as auditable and an audit record
* will be written at syscall exit. If there is no associated task, tsk
* should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
+
+struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
+ int type)
{
struct audit_buffer *ab = NULL;
struct timespec t;
unsigned int serial;
+ int reserve;
+ unsigned long timeout_start = jiffies;
if (!audit_initialized)
return NULL;
- if (audit_backlog_limit
- && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
+ if (gfp_mask & __GFP_WAIT)
+ reserve = 0;
+ else
+ reserve = 5; /* Allow atomic callers to go up to five
+ entries over the normal backlog limit */
+
+ while (audit_backlog_limit
+ && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
+ if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time
+ && time_before(jiffies, timeout_start + audit_backlog_wait_time)) {
+
+ /* Wait for auditd to drain the queue a little */
+ DECLARE_WAITQUEUE(wait, current);
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&audit_backlog_wait, &wait);
+
+ if (audit_backlog_limit &&
+ skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
+ schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies);
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&audit_backlog_wait, &wait);
+ continue;
+ }
if (audit_rate_check())
printk(KERN_WARNING
"audit: audit_backlog=%d > "
@@ -663,10 +690,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
skb_queue_len(&audit_skb_queue),
audit_backlog_limit);
audit_log_lost("backlog limit exceeded");
+ audit_backlog_wait_time = audit_backlog_wait_overflow;
+ wake_up(&audit_backlog_wait);
return NULL;
}
- ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
+ ab = audit_buffer_alloc(ctx, gfp_mask, type);
if (!ab) {
audit_log_lost("out of memory in audit_log_start");
return NULL;
@@ -690,7 +719,7 @@ static inline int audit_expand(struct audit_buffer *ab, int extra)
{
struct sk_buff *skb = ab->skb;
int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
- GFP_ATOMIC);
+ ab->gfp_mask);
if (ret < 0) {
audit_log_lost("out of memory in audit_expand");
return 0;
@@ -809,7 +838,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
audit_log_format(ab, " %s", prefix);
/* We will allow 11 spaces for ' (deleted)' to be appended */
- path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+ path = kmalloc(PATH_MAX+11, ab->gfp_mask);
if (!path) {
audit_log_format(ab, "<no memory>");
return;
@@ -841,7 +870,7 @@ void audit_log_end(struct audit_buffer *ab)
ab->skb = NULL;
wake_up_interruptible(&kauditd_wait);
} else {
- printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+ printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));
}
}
audit_buffer_free(ab);
@@ -850,12 +879,13 @@ void audit_log_end(struct audit_buffer *ab)
/* Log an audit record. This is a convenience function that calls
* audit_log_start, audit_log_vformat, and audit_log_end. It may be
* called in any context. */
-void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
+ const char *fmt, ...)
{
struct audit_buffer *ab;
va_list args;
- ab = audit_log_start(ctx, type);
+ ab = audit_log_start(ctx, gfp_mask, type);
if (ab) {
va_start(args, fmt);
audit_log_vformat(ab, fmt, args);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index e75f84e1a1a0..d8a68509e729 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -39,6 +39,9 @@
#include <linux/audit.h>
#include <linux/personality.h>
#include <linux/time.h>
+#include <linux/kthread.h>
+#include <linux/netlink.h>
+#include <linux/compiler.h>
#include <asm/unistd.h>
/* 0 = no checking
@@ -95,6 +98,7 @@ struct audit_names {
uid_t uid;
gid_t gid;
dev_t rdev;
+ unsigned flags;
};
struct audit_aux_data {
@@ -167,9 +171,16 @@ struct audit_context {
/* There are three lists of rules -- one to search at task creation
* time, one to search at syscall entry time, and another to search at
* syscall exit time. */
-static LIST_HEAD(audit_tsklist);
-static LIST_HEAD(audit_entlist);
-static LIST_HEAD(audit_extlist);
+static struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
+ LIST_HEAD_INIT(audit_filter_list[0]),
+ LIST_HEAD_INIT(audit_filter_list[1]),
+ LIST_HEAD_INIT(audit_filter_list[2]),
+ LIST_HEAD_INIT(audit_filter_list[3]),
+ LIST_HEAD_INIT(audit_filter_list[4]),
+#if AUDIT_NR_FILTERS != 5
+#error Fix audit_filter_list initialiser
+#endif
+};
struct audit_entry {
struct list_head list;
@@ -179,9 +190,36 @@ struct audit_entry {
extern int audit_pid;
+/* Copy rule from user-space to kernel-space. Called from
+ * audit_add_rule during AUDIT_ADD. */
+static inline int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
+{
+ int i;
+
+ if (s->action != AUDIT_NEVER
+ && s->action != AUDIT_POSSIBLE
+ && s->action != AUDIT_ALWAYS)
+ return -1;
+ if (s->field_count < 0 || s->field_count > AUDIT_MAX_FIELDS)
+ return -1;
+ if ((s->flags & ~AUDIT_FILTER_PREPEND) >= AUDIT_NR_FILTERS)
+ return -1;
+
+ d->flags = s->flags;
+ d->action = s->action;
+ d->field_count = s->field_count;
+ for (i = 0; i < d->field_count; i++) {
+ d->fields[i] = s->fields[i];
+ d->values[i] = s->values[i];
+ }
+ for (i = 0; i < AUDIT_BITMASK_SIZE; i++) d->mask[i] = s->mask[i];
+ return 0;
+}
+
/* Check to see if two rules are identical. It is called from
+ * audit_add_rule during AUDIT_ADD and
* audit_del_rule during AUDIT_DEL. */
-static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
+static inline int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
{
int i;
@@ -210,19 +248,37 @@ static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
/* Note that audit_add_rule and audit_del_rule are called via
* audit_receive() in audit.c, and are protected by
* audit_netlink_sem. */
-static inline int audit_add_rule(struct audit_entry *entry,
- struct list_head *list)
+static inline int audit_add_rule(struct audit_rule *rule,
+ struct list_head *list)
{
- if (entry->rule.flags & AUDIT_PREPEND) {
- entry->rule.flags &= ~AUDIT_PREPEND;
+ struct audit_entry *entry;
+
+ /* Do not use the _rcu iterator here, since this is the only
+ * addition routine. */
+ list_for_each_entry(entry, list, list) {
+ if (!audit_compare_rule(rule, &entry->rule)) {
+ return -EEXIST;
+ }
+ }
+
+ if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
+ return -ENOMEM;
+ if (audit_copy_rule(&entry->rule, rule)) {
+ kfree(entry);
+ return -EINVAL;
+ }
+
+ if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
+ entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
list_add_rcu(&entry->list, list);
} else {
list_add_tail_rcu(&entry->list, list);
}
+
return 0;
}
-static void audit_free_rule(struct rcu_head *head)
+static inline void audit_free_rule(struct rcu_head *head)
{
struct audit_entry *e = container_of(head, struct audit_entry, rcu);
kfree(e);
@@ -245,82 +301,82 @@ static inline int audit_del_rule(struct audit_rule *rule,
return 0;
}
}
- return -EFAULT; /* No matching rule */
+ return -ENOENT; /* No matching rule */
}
-/* Copy rule from user-space to kernel-space. Called during
- * AUDIT_ADD. */
-static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
+static int audit_list_rules(void *_dest)
{
+ int pid, seq;
+ int *dest = _dest;
+ struct audit_entry *entry;
int i;
- if (s->action != AUDIT_NEVER
- && s->action != AUDIT_POSSIBLE
- && s->action != AUDIT_ALWAYS)
- return -1;
- if (s->field_count < 0 || s->field_count > AUDIT_MAX_FIELDS)
- return -1;
+ pid = dest[0];
+ seq = dest[1];
+ kfree(dest);
- d->flags = s->flags;
- d->action = s->action;
- d->field_count = s->field_count;
- for (i = 0; i < d->field_count; i++) {
- d->fields[i] = s->fields[i];
- d->values[i] = s->values[i];
+ down(&audit_netlink_sem);
+
+ /* The *_rcu iterators not needed here because we are
+ always called with audit_netlink_sem held. */
+ for (i=0; i<AUDIT_NR_FILTERS; i++) {
+ list_for_each_entry(entry, &audit_filter_list[i], list)
+ audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
+ &entry->rule, sizeof(entry->rule));
}
- for (i = 0; i < AUDIT_BITMASK_SIZE; i++) d->mask[i] = s->mask[i];
+ audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
+
+ up(&audit_netlink_sem);
return 0;
}
int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
uid_t loginuid)
{
- u32 flags;
- struct audit_entry *entry;
+ struct task_struct *tsk;
+ int *dest;
int err = 0;
+ unsigned listnr;
switch (type) {
case AUDIT_LIST:
- /* The *_rcu iterators not needed here because we are
- always called with audit_netlink_sem held. */
- list_for_each_entry(entry, &audit_tsklist, list)
- audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
- &entry->rule, sizeof(entry->rule));
- list_for_each_entry(entry, &audit_entlist, list)
- audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
- &entry->rule, sizeof(entry->rule));
- list_for_each_entry(entry, &audit_extlist, list)
- audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
- &entry->rule, sizeof(entry->rule));
- audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
+ /* We can't just spew out the rules here because we might fill
+ * the available socket buffer space and deadlock waiting for
+ * auditctl to read from it... which isn't ever going to
+ * happen if we're actually running in the context of auditctl
+ * trying to _send_ the stuff */
+
+ dest = kmalloc(2 * sizeof(int), GFP_KERNEL);
+ if (!dest)
+ return -ENOMEM;
+ dest[0] = pid;
+ dest[1] = seq;
+
+ tsk = kthread_run(audit_list_rules, dest, "audit_list_rules");
+ if (IS_ERR(tsk)) {
+ kfree(dest);
+ err = PTR_ERR(tsk);
+ }
break;
case AUDIT_ADD:
- if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
- return -ENOMEM;
- if (audit_copy_rule(&entry->rule, data)) {
- kfree(entry);
+ listnr =((struct audit_rule *)data)->flags & ~AUDIT_FILTER_PREPEND;
+ if (listnr >= AUDIT_NR_FILTERS)
return -EINVAL;
- }
- flags = entry->rule.flags;
- if (!err && (flags & AUDIT_PER_TASK))
- err = audit_add_rule(entry, &audit_tsklist);
- if (!err && (flags & AUDIT_AT_ENTRY))
- err = audit_add_rule(entry, &audit_entlist);
- if (!err && (flags & AUDIT_AT_EXIT))
- err = audit_add_rule(entry, &audit_extlist);
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
- "auid=%u added an audit rule\n", loginuid);
+
+ err = audit_add_rule(data, &audit_filter_list[listnr]);
+ if (!err)
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+ "auid=%u added an audit rule\n", loginuid);
break;
case AUDIT_DEL:
- flags =((struct audit_rule *)data)->flags;
- if (!err && (flags & AUDIT_PER_TASK))
- err = audit_del_rule(data, &audit_tsklist);
- if (!err && (flags & AUDIT_AT_ENTRY))
- err = audit_del_rule(data, &audit_entlist);
- if (!err && (flags & AUDIT_AT_EXIT))
- err = audit_del_rule(data, &audit_extlist);
- audit_log(NULL, AUDIT_CONFIG_CHANGE,
- "auid=%u removed an audit rule\n", loginuid);
+ listnr =((struct audit_rule *)data)->flags & ~AUDIT_FILTER_PREPEND;
+ if (listnr >= AUDIT_NR_FILTERS)
+ return -EINVAL;
+
+ err = audit_del_rule(data, &audit_filter_list[listnr]);
+ if (!err)
+ audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+ "auid=%u removed an audit rule\n", loginuid);
break;
default:
return -EINVAL;
@@ -384,8 +440,12 @@ static int audit_filter_rules(struct task_struct *tsk,
result = (ctx->return_code == value);
break;
case AUDIT_SUCCESS:
- if (ctx && ctx->return_valid)
- result = (ctx->return_valid == AUDITSC_SUCCESS);
+ if (ctx && ctx->return_valid) {
+ if (value)
+ result = (ctx->return_valid == AUDITSC_SUCCESS);
+ else
+ result = (ctx->return_valid == AUDITSC_FAILURE);
+ }
break;
case AUDIT_DEVMAJOR:
if (ctx) {
@@ -454,7 +514,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
enum audit_state state;
rcu_read_lock();
- list_for_each_entry_rcu(e, &audit_tsklist, list) {
+ list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
rcu_read_unlock();
return state;
@@ -474,20 +534,84 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
struct list_head *list)
{
struct audit_entry *e;
+ enum audit_state state;
+
+ if (audit_pid && tsk->tgid == audit_pid)
+ return AUDIT_DISABLED;
+
+ rcu_read_lock();
+ if (!list_empty(list)) {
+ int word = AUDIT_WORD(ctx->major);
+ int bit = AUDIT_BIT(ctx->major);
+
+ list_for_each_entry_rcu(e, list, list) {
+ if ((e->rule.mask[word] & bit) == bit
+ && audit_filter_rules(tsk, &e->rule, ctx, &state)) {
+ rcu_read_unlock();
+ return state;
+ }
+ }
+ }
+ rcu_read_unlock();
+ return AUDIT_BUILD_CONTEXT;
+}
+
+static int audit_filter_user_rules(struct netlink_skb_parms *cb,
+ struct audit_rule *rule,
+ enum audit_state *state)
+{
+ int i;
+
+ for (i = 0; i < rule->field_count; i++) {
+ u32 field = rule->fields[i] & ~AUDIT_NEGATE;
+ u32 value = rule->values[i];
+ int result = 0;
+
+ switch (field) {
+ case AUDIT_PID:
+ result = (cb->creds.pid == value);
+ break;
+ case AUDIT_UID:
+ result = (cb->creds.uid == value);
+ break;
+ case AUDIT_GID:
+ result = (cb->creds.gid == value);
+ break;
+ case AUDIT_LOGINUID:
+ result = (cb->loginuid == value);
+ break;
+ }
+
+ if (rule->fields[i] & AUDIT_NEGATE)
+ result = !result;
+ if (!result)
+ return 0;
+ }
+ switch (rule->action) {
+ case AUDIT_NEVER: *state = AUDIT_DISABLED; break;
+ case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT; break;
+ case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break;
+ }
+ return 1;
+}
+
+int audit_filter_user(struct netlink_skb_parms *cb, int type)
+{
+ struct audit_entry *e;
enum audit_state state;
- int word = AUDIT_WORD(ctx->major);
- int bit = AUDIT_BIT(ctx->major);
+ int ret = 1;
rcu_read_lock();
- list_for_each_entry_rcu(e, list, list) {
- if ((e->rule.mask[word] & bit) == bit
- && audit_filter_rules(tsk, &e->rule, ctx, &state)) {
- rcu_read_unlock();
- return state;
+ list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
+ if (audit_filter_user_rules(cb, &e->rule, &state)) {
+ if (state == AUDIT_DISABLED)
+ ret = 0;
+ break;
}
}
rcu_read_unlock();
- return AUDIT_BUILD_CONTEXT;
+
+ return ret; /* Audit by default */
}
/* This should be called with task_lock() held. */
@@ -504,7 +628,7 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
if (context->in_syscall && !context->auditable) {
enum audit_state state;
- state = audit_filter_syscall(tsk, context, &audit_extlist);
+ state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
if (state == AUDIT_RECORD_CONTEXT)
context->auditable = 1;
}
@@ -679,13 +803,13 @@ static void audit_log_task_info(struct audit_buffer *ab)
up_read(&mm->mmap_sem);
}
-static void audit_log_exit(struct audit_context *context)
+static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
{
int i;
struct audit_buffer *ab;
struct audit_aux_data *aux;
- ab = audit_log_start(context, AUDIT_SYSCALL);
+ ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "arch=%x syscall=%d",
@@ -717,7 +841,7 @@ static void audit_log_exit(struct audit_context *context)
for (aux = context->aux; aux; aux = aux->next) {
- ab = audit_log_start(context, aux->type);
+ ab = audit_log_start(context, GFP_KERNEL, aux->type);
if (!ab)
continue; /* audit_panic has been called */
@@ -754,14 +878,14 @@ static void audit_log_exit(struct audit_context *context)
}
if (context->pwd && context->pwdmnt) {
- ab = audit_log_start(context, AUDIT_CWD);
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
if (ab) {
audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
audit_log_end(ab);
}
}
for (i = 0; i < context->name_count; i++) {
- ab = audit_log_start(context, AUDIT_PATH);
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
if (!ab)
continue; /* audit_panic has been called */
@@ -770,6 +894,8 @@ static void audit_log_exit(struct audit_context *context)
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, context->names[i].name);
}
+ audit_log_format(ab, " flags=%x\n", context->names[i].flags);
+
if (context->names[i].ino != (unsigned long)-1)
audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
" ouid=%u ogid=%u rdev=%02x:%02x",
@@ -799,9 +925,11 @@ void audit_free(struct task_struct *tsk)
return;
/* Check for system calls that do not go through the exit
- * function (e.g., exit_group), then free context block. */
- if (context->in_syscall && context->auditable && context->pid != audit_pid)
- audit_log_exit(context);
+ * function (e.g., exit_group), then free context block.
+ * We use GFP_ATOMIC here because we might be doing this
+ * in the context of the idle thread */
+ if (context->in_syscall && context->auditable)
+ audit_log_exit(context, GFP_ATOMIC);
audit_free_context(context);
}
@@ -876,11 +1004,11 @@ void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
state = context->state;
if (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)
- state = audit_filter_syscall(tsk, context, &audit_entlist);
+ state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
if (likely(state == AUDIT_DISABLED))
return;
- context->serial = audit_serial();
+ context->serial = 0;
context->ctime = CURRENT_TIME;
context->in_syscall = 1;
context->auditable = !!(state == AUDIT_RECORD_CONTEXT);
@@ -903,10 +1031,10 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
/* Not having a context here is ok, since the parent may have
* called __put_task_struct. */
if (likely(!context))
- return;
+ goto out;
- if (context->in_syscall && context->auditable && context->pid != audit_pid)
- audit_log_exit(context);
+ if (context->in_syscall && context->auditable)
+ audit_log_exit(context, GFP_KERNEL);
context->in_syscall = 0;
context->auditable = 0;
@@ -919,9 +1047,9 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
} else {
audit_free_names(context);
audit_free_aux(context);
- audit_zero_context(context, context->state);
tsk->audit_context = context;
}
+ out:
put_task_struct(tsk);
}
@@ -996,7 +1124,7 @@ void audit_putname(const char *name)
/* Store the inode and device from a lookup. Called from
* fs/namei.c:path_lookup(). */
-void audit_inode(const char *name, const struct inode *inode)
+void audit_inode(const char *name, const struct inode *inode, unsigned flags)
{
int idx;
struct audit_context *context = current->audit_context;
@@ -1022,17 +1150,20 @@ void audit_inode(const char *name, const struct inode *inode)
++context->ino_count;
#endif
}
- context->names[idx].ino = inode->i_ino;
- context->names[idx].dev = inode->i_sb->s_dev;
- context->names[idx].mode = inode->i_mode;
- context->names[idx].uid = inode->i_uid;
- context->names[idx].gid = inode->i_gid;
- context->names[idx].rdev = inode->i_rdev;
+ context->names[idx].flags = flags;
+ context->names[idx].ino = inode->i_ino;
+ context->names[idx].dev = inode->i_sb->s_dev;
+ context->names[idx].mode = inode->i_mode;
+ context->names[idx].uid = inode->i_uid;
+ context->names[idx].gid = inode->i_gid;
+ context->names[idx].rdev = inode->i_rdev;
}
void auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial)
{
+ if (!ctx->serial)
+ ctx->serial = audit_serial();
t->tv_sec = ctx->ctime.tv_sec;
t->tv_nsec = ctx->ctime.tv_nsec;
*serial = ctx->serial;
@@ -1044,7 +1175,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
if (task->audit_context) {
struct audit_buffer *ab;
- ab = audit_log_start(NULL, AUDIT_LOGIN);
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
if (ab) {
audit_log_format(ab, "login pid=%d uid=%u "
"old auid=%u new auid=%u",
@@ -1153,7 +1284,7 @@ void audit_signal_info(int sig, struct task_struct *t)
extern pid_t audit_sig_pid;
extern uid_t audit_sig_uid;
- if (unlikely(audit_pid && t->pid == audit_pid)) {
+ if (unlikely(audit_pid && t->tgid == audit_pid)) {
if (sig == SIGTERM || sig == SIGHUP) {
struct audit_context *ctx = current->audit_context;
audit_sig_pid = current->pid;
diff --git a/kernel/compat.c b/kernel/compat.c
index ddfcaaa86623..102296e21ea8 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -48,8 +48,7 @@ static long compat_nanosleep_restart(struct restart_block *restart)
if (!time_after(expire, now))
return 0;
- current->state = TASK_INTERRUPTIBLE;
- expire = schedule_timeout(expire - now);
+ expire = schedule_timeout_interruptible(expire - now);
if (expire == 0)
return 0;
@@ -82,8 +81,7 @@ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
return -EINVAL;
expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
- current->state = TASK_INTERRUPTIBLE;
- expire = schedule_timeout(expire);
+ expire = schedule_timeout_interruptible(expire);
if (expire == 0)
return 0;
@@ -795,8 +793,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- current->state = TASK_INTERRUPTIBLE;
- timeout = schedule_timeout(timeout);
+ timeout = schedule_timeout_interruptible(timeout);
spin_lock_irq(&current->sighand->siglock);
sig = dequeue_signal(current, &s, &info);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 1f06e7690106..28176d083f7b 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -180,6 +180,42 @@ static struct super_block *cpuset_sb = NULL;
*/
static DECLARE_MUTEX(cpuset_sem);
+static struct task_struct *cpuset_sem_owner;
+static int cpuset_sem_depth;
+
+/*
+ * The global cpuset semaphore cpuset_sem can be needed by the
+ * memory allocator to update a tasks mems_allowed (see the calls
+ * to cpuset_update_current_mems_allowed()) or to walk up the
+ * cpuset hierarchy to find a mem_exclusive cpuset see the calls
+ * to cpuset_excl_nodes_overlap()).
+ *
+ * But if the memory allocation is being done by cpuset.c code, it
+ * usually already holds cpuset_sem. Double tripping on a kernel
+ * semaphore deadlocks the current task, and any other task that
+ * subsequently tries to obtain the lock.
+ *
+ * Run all up's and down's on cpuset_sem through the following
+ * wrappers, which will detect this nested locking, and avoid
+ * deadlocking.
+ */
+
+static inline void cpuset_down(struct semaphore *psem)
+{
+ if (cpuset_sem_owner != current) {
+ down(psem);
+ cpuset_sem_owner = current;
+ }
+ cpuset_sem_depth++;
+}
+
+static inline void cpuset_up(struct semaphore *psem)
+{
+ if (--cpuset_sem_depth == 0) {
+ cpuset_sem_owner = NULL;
+ up(psem);
+ }
+}
/*
* A couple of forward declarations required, due to cyclic reference loop:
@@ -522,19 +558,10 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
* Refresh current tasks mems_allowed and mems_generation from
* current tasks cpuset. Call with cpuset_sem held.
*
- * Be sure to call refresh_mems() on any cpuset operation which
- * (1) holds cpuset_sem, and (2) might possibly alloc memory.
- * Call after obtaining cpuset_sem lock, before any possible
- * allocation. Otherwise one risks trying to allocate memory
- * while the task cpuset_mems_generation is not the same as
- * the mems_generation in its cpuset, which would deadlock on
- * cpuset_sem in cpuset_update_current_mems_allowed().
- *
- * Since we hold cpuset_sem, once refresh_mems() is called, the
- * test (current->cpuset_mems_generation != cs->mems_generation)
- * in cpuset_update_current_mems_allowed() will remain false,
- * until we drop cpuset_sem. Anyone else who would change our
- * cpusets mems_generation needs to lock cpuset_sem first.
+ * This routine is needed to update the per-task mems_allowed
+ * data, within the tasks context, when it is trying to allocate
+ * memory (in various mm/mempolicy.c routines) and notices
+ * that some other task has been modifying its cpuset.
*/
static void refresh_mems(void)
@@ -840,7 +867,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
}
buffer[nbytes] = 0; /* nul-terminate */
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
if (is_removed(cs)) {
retval = -ENODEV;
@@ -874,7 +901,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
if (retval == 0)
retval = nbytes;
out2:
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
cpuset_release_agent(pathbuf);
out1:
kfree(buffer);
@@ -914,9 +941,9 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
{
cpumask_t mask;
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
mask = cs->cpus_allowed;
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return cpulist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -925,9 +952,9 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
{
nodemask_t mask;
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
mask = cs->mems_allowed;
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return nodelist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -941,8 +968,6 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
char *page;
ssize_t retval = 0;
char *s;
- char *start;
- size_t n;
if (!(page = (char *)__get_free_page(GFP_KERNEL)))
return -ENOMEM;
@@ -972,10 +997,7 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
*s++ = '\n';
*s = '\0';
- start = page + *ppos;
- n = s - start;
- retval = n - copy_to_user(buf, start, min(n, nbytes));
- *ppos += retval;
+ retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
out:
free_page((unsigned long)page);
return retval;
@@ -1330,8 +1352,7 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
if (!cs)
return -ENOMEM;
- down(&cpuset_sem);
- refresh_mems();
+ cpuset_down(&cpuset_sem);
cs->flags = 0;
if (notify_on_release(parent))
set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
@@ -1356,14 +1377,14 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
* will down() this new directory's i_sem and if we race with
* another mkdir, we might deadlock.
*/
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
err = cpuset_populate_dir(cs->dentry);
/* If err < 0, we have a half-filled directory - oh well ;) */
return 0;
err:
list_del(&cs->sibling);
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
kfree(cs);
return err;
}
@@ -1385,14 +1406,13 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
/* the vfs holds both inode->i_sem already */
- down(&cpuset_sem);
- refresh_mems();
+ cpuset_down(&cpuset_sem);
if (atomic_read(&cs->count) > 0) {
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return -EBUSY;
}
if (!list_empty(&cs->children)) {
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return -EBUSY;
}
parent = cs->parent;
@@ -1408,7 +1428,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
spin_unlock(&d->d_lock);
cpuset_d_remove_dir(d);
dput(d);
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
cpuset_release_agent(pathbuf);
return 0;
}
@@ -1511,10 +1531,10 @@ void cpuset_exit(struct task_struct *tsk)
if (notify_on_release(cs)) {
char *pathbuf = NULL;
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
if (atomic_dec_and_test(&cs->count))
check_for_release(cs, &pathbuf);
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
cpuset_release_agent(pathbuf);
} else {
atomic_dec(&cs->count);
@@ -1535,11 +1555,11 @@ cpumask_t cpuset_cpus_allowed(const struct task_struct *tsk)
{
cpumask_t mask;
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
task_lock((struct task_struct *)tsk);
guarantee_online_cpus(tsk->cpuset, &mask);
task_unlock((struct task_struct *)tsk);
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return mask;
}
@@ -1564,9 +1584,9 @@ void cpuset_update_current_mems_allowed(void)
if (!cs)
return; /* task is exiting */
if (current->cpuset_mems_generation != cs->mems_generation) {
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
refresh_mems();
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
}
}
@@ -1650,7 +1670,7 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* GFP_USER - only nodes in current tasks mems allowed ok.
**/
-int cpuset_zone_allowed(struct zone *z, unsigned int __nocast gfp_mask)
+int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
{
int node; /* node that zone z is on */
const struct cpuset *cs; /* current cpuset ancestors */
@@ -1665,14 +1685,14 @@ int cpuset_zone_allowed(struct zone *z, unsigned int __nocast gfp_mask)
return 0;
/* Not hardwall and node outside mems_allowed: scan up cpusets */
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
cs = current->cpuset;
if (!cs)
goto done; /* current task exiting */
cs = nearest_exclusive_ancestor(cs);
allowed = node_isset(node, cs->mems_allowed);
done:
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return allowed;
}
@@ -1693,7 +1713,7 @@ int cpuset_excl_nodes_overlap(const struct task_struct *p)
const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
int overlap = 0; /* do cpusets overlap? */
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
cs1 = current->cpuset;
if (!cs1)
goto done; /* current task exiting */
@@ -1704,7 +1724,7 @@ int cpuset_excl_nodes_overlap(const struct task_struct *p)
cs2 = nearest_exclusive_ancestor(cs2);
overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
done:
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
return overlap;
}
@@ -1727,7 +1747,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
return -ENOMEM;
tsk = m->private;
- down(&cpuset_sem);
+ cpuset_down(&cpuset_sem);
task_lock(tsk);
cs = tsk->cpuset;
task_unlock(tsk);
@@ -1742,7 +1762,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
seq_puts(m, buf);
seq_putc(m, '\n');
out:
- up(&cpuset_sem);
+ cpuset_up(&cpuset_sem);
kfree(buf);
return retval;
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 5b0fb9f09f21..3b25b182d2be 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -368,17 +368,25 @@ EXPORT_SYMBOL(daemonize);
static inline void close_files(struct files_struct * files)
{
int i, j;
+ struct fdtable *fdt;
j = 0;
+
+ /*
+ * It is safe to dereference the fd table without RCU or
+ * ->file_lock because this is the last reference to the
+ * files structure.
+ */
+ 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 +411,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);
}
}
@@ -831,6 +843,7 @@ fastcall NORET_TYPE void do_exit(long code)
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
del_timer_sync(&tsk->signal->real_timer);
+ exit_itimers(tsk->signal);
acct_process(code);
}
exit_mm(tsk);
@@ -1191,7 +1204,7 @@ static int wait_task_stopped(task_t *p, int delayed_group_leader, int noreap,
exit_code = p->exit_code;
if (unlikely(!exit_code) ||
- unlikely(p->state > TASK_STOPPED))
+ unlikely(p->state & TASK_TRACED))
goto bail_ref;
return wait_noreap_copyout(p, pid, uid,
why, (exit_code << 8) | 0x7f,
diff --git a/kernel/fork.c b/kernel/fork.c
index 7e1ead9a6ba4..280bd44ac441 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;
}
@@ -818,7 +848,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
{
unsigned long new_flags = p->flags;
- new_flags &= ~PF_SUPERPRIV;
+ new_flags &= ~(PF_SUPERPRIV | PF_NOFREEZE);
new_flags |= PF_FORKNOEXEC;
if (!(clone_flags & CLONE_PTRACE))
p->ptrace = 0;
@@ -1032,7 +1062,8 @@ static task_t *copy_process(unsigned long clone_flags,
* parent's CPU). This avoids alot of nasty races.
*/
p->cpus_allowed = current->cpus_allowed;
- if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed)))
+ if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) ||
+ !cpu_online(task_cpu(p))))
set_task_cpu(p, smp_processor_id());
/*
@@ -1115,6 +1146,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/kexec.c b/kernel/kexec.c
index cdd4dcd8fb63..36c5d9cd4cc1 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -90,7 +90,7 @@ int kexec_should_crash(struct task_struct *p)
static int kimage_is_destination_range(struct kimage *image,
unsigned long start, unsigned long end);
static struct page *kimage_alloc_page(struct kimage *image,
- unsigned int gfp_mask,
+ gfp_t gfp_mask,
unsigned long dest);
static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
@@ -326,8 +326,7 @@ static int kimage_is_destination_range(struct kimage *image,
return 0;
}
-static struct page *kimage_alloc_pages(unsigned int gfp_mask,
- unsigned int order)
+static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
{
struct page *pages;
@@ -654,7 +653,7 @@ static kimage_entry_t *kimage_dst_used(struct kimage *image,
}
static struct page *kimage_alloc_page(struct kimage *image,
- unsigned int gfp_mask,
+ gfp_t gfp_mask,
unsigned long destination)
{
/*
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index 179baafcdd96..64ab045c3d9d 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -36,7 +36,7 @@
* struct kfifo with kfree().
*/
struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
- unsigned int __nocast gfp_mask, spinlock_t *lock)
+ gfp_t gfp_mask, spinlock_t *lock)
{
struct kfifo *fifo;
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(kfifo_init);
*
* The size will be rounded-up to a power of 2.
*/
-struct kfifo *kfifo_alloc(unsigned int size, unsigned int __nocast gfp_mask, spinlock_t *lock)
+struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
{
unsigned char *buffer;
struct kfifo *ret;
diff --git a/kernel/module.c b/kernel/module.c
index 4b39d3793c72..ff5c500ab625 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/elf.h>
@@ -498,7 +499,7 @@ static inline int try_force(unsigned int flags)
{
int ret = (flags & O_TRUNC);
if (ret)
- tainted |= TAINT_FORCED_MODULE;
+ add_taint(TAINT_FORCED_MODULE);
return ret;
}
#else
@@ -897,7 +898,7 @@ static int check_version(Elf_Shdr *sechdrs,
if (!(tainted & TAINT_FORCED_MODULE)) {
printk("%s: no version for \"%s\" found: kernel tainted.\n",
mod->name, symname);
- tainted |= TAINT_FORCED_MODULE;
+ add_taint(TAINT_FORCED_MODULE);
}
return 1;
}
@@ -1352,7 +1353,7 @@ static void set_license(struct module *mod, const char *license)
if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) {
printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
mod->name, license);
- tainted |= TAINT_PROPRIETARY_MODULE;
+ add_taint(TAINT_PROPRIETARY_MODULE);
}
}
@@ -1610,7 +1611,7 @@ static struct module *load_module(void __user *umod,
modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
- tainted |= TAINT_FORCED_MODULE;
+ add_taint(TAINT_FORCED_MODULE);
printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
mod->name);
} else if (!same_magic(modmagic, vermagic)) {
@@ -1739,7 +1740,7 @@ static struct module *load_module(void __user *umod,
(mod->num_gpl_syms && !gplcrcindex)) {
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
- tainted |= TAINT_FORCED_MODULE;
+ add_taint(TAINT_FORCED_MODULE);
}
#endif
diff --git a/kernel/params.c b/kernel/params.c
index fbf173215fd2..1a8614bac5d5 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -80,8 +80,6 @@ static char *next_arg(char *args, char **param, char **val)
int in_quote = 0, quoted = 0;
char *next;
- /* Chew any extra spaces */
- while (*args == ' ') args++;
if (*args == '"') {
args++;
in_quote = 1;
@@ -121,6 +119,10 @@ static char *next_arg(char *args, char **param, char **val)
next = args + i + 1;
} else
next = args + i;
+
+ /* Chew up trailing spaces. */
+ while (*next == ' ')
+ next++;
return next;
}
@@ -135,6 +137,10 @@ int parse_args(const char *name,
DEBUGP("Parsing ARGS: %s\n", args);
+ /* Chew leading spaces */
+ while (*args == ' ')
+ args++;
+
while (*args) {
int ret;
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index ad85d3f0dcc4..bf374fceb39c 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -91,7 +91,7 @@ static inline union cpu_time_count cpu_time_sub(clockid_t which_clock,
* Update expiry time from increment, and increase overrun count,
* given the current clock sample.
*/
-static inline void bump_cpu_timer(struct k_itimer *timer,
+static void bump_cpu_timer(struct k_itimer *timer,
union cpu_time_count now)
{
int i;
@@ -110,7 +110,7 @@ static inline void bump_cpu_timer(struct k_itimer *timer,
for (i = 0; incr < delta - incr; i++)
incr = incr << 1;
for (; i >= 0; incr >>= 1, i--) {
- if (delta <= incr)
+ if (delta < incr)
continue;
timer->it.cpu.expires.sched += incr;
timer->it_overrun += 1 << i;
@@ -128,7 +128,7 @@ static inline void bump_cpu_timer(struct k_itimer *timer,
for (i = 0; cputime_lt(incr, cputime_sub(delta, incr)); i++)
incr = cputime_add(incr, incr);
for (; i >= 0; incr = cputime_halve(incr), i--) {
- if (cputime_le(delta, incr))
+ if (cputime_lt(delta, incr))
continue;
timer->it.cpu.expires.cpu =
cputime_add(timer->it.cpu.expires.cpu, incr);
@@ -380,14 +380,9 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
int posix_cpu_timer_del(struct k_itimer *timer)
{
struct task_struct *p = timer->it.cpu.task;
+ int ret = 0;
- if (timer->it.cpu.firing)
- return TIMER_RETRY;
-
- if (unlikely(p == NULL))
- return 0;
-
- if (!list_empty(&timer->it.cpu.entry)) {
+ if (likely(p != NULL)) {
read_lock(&tasklist_lock);
if (unlikely(p->signal == NULL)) {
/*
@@ -396,18 +391,20 @@ int posix_cpu_timer_del(struct k_itimer *timer)
*/
BUG_ON(!list_empty(&timer->it.cpu.entry));
} else {
- /*
- * Take us off the task's timer list.
- */
spin_lock(&p->sighand->siglock);
- list_del(&timer->it.cpu.entry);
+ if (timer->it.cpu.firing)
+ ret = TIMER_RETRY;
+ else
+ list_del(&timer->it.cpu.entry);
spin_unlock(&p->sighand->siglock);
}
read_unlock(&tasklist_lock);
+
+ if (!ret)
+ put_task_struct(p);
}
- put_task_struct(p);
- return 0;
+ return ret;
}
/*
@@ -424,7 +421,6 @@ static void cleanup_timers(struct list_head *head,
cputime_t ptime = cputime_add(utime, stime);
list_for_each_entry_safe(timer, next, head, entry) {
- timer->task = NULL;
list_del_init(&timer->entry);
if (cputime_lt(timer->expires.cpu, ptime)) {
timer->expires.cpu = cputime_zero;
@@ -436,7 +432,6 @@ static void cleanup_timers(struct list_head *head,
++head;
list_for_each_entry_safe(timer, next, head, entry) {
- timer->task = NULL;
list_del_init(&timer->entry);
if (cputime_lt(timer->expires.cpu, utime)) {
timer->expires.cpu = cputime_zero;
@@ -448,7 +443,6 @@ static void cleanup_timers(struct list_head *head,
++head;
list_for_each_entry_safe(timer, next, head, entry) {
- timer->task = NULL;
list_del_init(&timer->entry);
if (timer->expires.sched < sched_time) {
timer->expires.sched = 0;
@@ -492,6 +486,9 @@ static void process_timer_rebalance(struct task_struct *p,
struct task_struct *t = p;
unsigned int nthreads = atomic_read(&p->signal->live);
+ if (!nthreads)
+ return;
+
switch (clock_idx) {
default:
BUG();
@@ -500,7 +497,7 @@ static void process_timer_rebalance(struct task_struct *p,
left = cputime_div(cputime_sub(expires.cpu, val.cpu),
nthreads);
do {
- if (!unlikely(t->exit_state)) {
+ if (!unlikely(t->flags & PF_EXITING)) {
ticks = cputime_add(prof_ticks(t), left);
if (cputime_eq(t->it_prof_expires,
cputime_zero) ||
@@ -515,7 +512,7 @@ static void process_timer_rebalance(struct task_struct *p,
left = cputime_div(cputime_sub(expires.cpu, val.cpu),
nthreads);
do {
- if (!unlikely(t->exit_state)) {
+ if (!unlikely(t->flags & PF_EXITING)) {
ticks = cputime_add(virt_ticks(t), left);
if (cputime_eq(t->it_virt_expires,
cputime_zero) ||
@@ -530,7 +527,7 @@ static void process_timer_rebalance(struct task_struct *p,
nsleft = expires.sched - val.sched;
do_div(nsleft, nthreads);
do {
- if (!unlikely(t->exit_state)) {
+ if (!unlikely(t->flags & PF_EXITING)) {
ns = t->sched_time + nsleft;
if (t->it_sched_expires == 0 ||
t->it_sched_expires > ns) {
@@ -569,6 +566,9 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
struct cpu_timer_list *next;
unsigned long i;
+ if (CPUCLOCK_PERTHREAD(timer->it_clock) && (p->flags & PF_EXITING))
+ return;
+
head = (CPUCLOCK_PERTHREAD(timer->it_clock) ?
p->cpu_timers : p->signal->cpu_timers);
head += CPUCLOCK_WHICH(timer->it_clock);
@@ -579,17 +579,15 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
listpos = head;
if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) {
list_for_each_entry(next, head, entry) {
- if (next->expires.sched > nt->expires.sched) {
- listpos = &next->entry;
+ if (next->expires.sched > nt->expires.sched)
break;
- }
+ listpos = &next->entry;
}
} else {
list_for_each_entry(next, head, entry) {
- if (cputime_gt(next->expires.cpu, nt->expires.cpu)) {
- listpos = &next->entry;
+ if (cputime_gt(next->expires.cpu, nt->expires.cpu))
break;
- }
+ listpos = &next->entry;
}
}
list_add(&nt->entry, listpos);
@@ -733,9 +731,15 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
* Disarm any old timer after extracting its expiry time.
*/
BUG_ON(!irqs_disabled());
+
+ ret = 0;
spin_lock(&p->sighand->siglock);
old_expires = timer->it.cpu.expires;
- list_del_init(&timer->it.cpu.entry);
+ if (unlikely(timer->it.cpu.firing)) {
+ timer->it.cpu.firing = -1;
+ ret = TIMER_RETRY;
+ } else
+ list_del_init(&timer->it.cpu.entry);
spin_unlock(&p->sighand->siglock);
/*
@@ -783,7 +787,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
}
}
- if (unlikely(timer->it.cpu.firing)) {
+ if (unlikely(ret)) {
/*
* We are colliding with the timer actually firing.
* Punt after filling in the timer's old value, and
@@ -791,8 +795,6 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
* it as an overrun (thanks to bump_cpu_timer above).
*/
read_unlock(&tasklist_lock);
- timer->it.cpu.firing = -1;
- ret = TIMER_RETRY;
goto out;
}
@@ -958,14 +960,16 @@ void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
static void check_thread_timers(struct task_struct *tsk,
struct list_head *firing)
{
+ int maxfire;
struct list_head *timers = tsk->cpu_timers;
+ maxfire = 20;
tsk->it_prof_expires = cputime_zero;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_entry(timers->next,
struct cpu_timer_list,
entry);
- if (cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
+ if (!--maxfire || cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
tsk->it_prof_expires = t->expires.cpu;
break;
}
@@ -974,12 +978,13 @@ static void check_thread_timers(struct task_struct *tsk,
}
++timers;
+ maxfire = 20;
tsk->it_virt_expires = cputime_zero;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_entry(timers->next,
struct cpu_timer_list,
entry);
- if (cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
+ if (!--maxfire || cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
tsk->it_virt_expires = t->expires.cpu;
break;
}
@@ -988,12 +993,13 @@ static void check_thread_timers(struct task_struct *tsk,
}
++timers;
+ maxfire = 20;
tsk->it_sched_expires = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_entry(timers->next,
struct cpu_timer_list,
entry);
- if (tsk->sched_time < t->expires.sched) {
+ if (!--maxfire || tsk->sched_time < t->expires.sched) {
tsk->it_sched_expires = t->expires.sched;
break;
}
@@ -1010,6 +1016,7 @@ static void check_thread_timers(struct task_struct *tsk,
static void check_process_timers(struct task_struct *tsk,
struct list_head *firing)
{
+ int maxfire;
struct signal_struct *const sig = tsk->signal;
cputime_t utime, stime, ptime, virt_expires, prof_expires;
unsigned long long sched_time, sched_expires;
@@ -1042,12 +1049,13 @@ static void check_process_timers(struct task_struct *tsk,
} while (t != tsk);
ptime = cputime_add(utime, stime);
+ maxfire = 20;
prof_expires = cputime_zero;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_entry(timers->next,
struct cpu_timer_list,
entry);
- if (cputime_lt(ptime, t->expires.cpu)) {
+ if (!--maxfire || cputime_lt(ptime, t->expires.cpu)) {
prof_expires = t->expires.cpu;
break;
}
@@ -1056,12 +1064,13 @@ static void check_process_timers(struct task_struct *tsk,
}
++timers;
+ maxfire = 20;
virt_expires = cputime_zero;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_entry(timers->next,
struct cpu_timer_list,
entry);
- if (cputime_lt(utime, t->expires.cpu)) {
+ if (!--maxfire || cputime_lt(utime, t->expires.cpu)) {
virt_expires = t->expires.cpu;
break;
}
@@ -1070,12 +1079,13 @@ static void check_process_timers(struct task_struct *tsk,
}
++timers;
+ maxfire = 20;
sched_expires = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_entry(timers->next,
struct cpu_timer_list,
entry);
- if (sched_time < t->expires.sched) {
+ if (!--maxfire || sched_time < t->expires.sched) {
sched_expires = t->expires.sched;
break;
}
@@ -1158,6 +1168,9 @@ static void check_process_timers(struct task_struct *tsk,
unsigned long long sched_left, sched;
const unsigned int nthreads = atomic_read(&sig->live);
+ if (!nthreads)
+ return;
+
prof_left = cputime_sub(prof_expires, utime);
prof_left = cputime_sub(prof_left, stime);
prof_left = cputime_div(prof_left, nthreads);
@@ -1194,7 +1207,7 @@ static void check_process_timers(struct task_struct *tsk,
do {
t = next_thread(t);
- } while (unlikely(t->exit_state));
+ } while (unlikely(t->flags & PF_EXITING));
} while (t != tsk);
}
}
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index b7b532acd9fc..dda3cda73c77 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1157,7 +1157,7 @@ retry_delete:
}
/*
- * This is called by __exit_signal, only when there are no more
+ * This is called by do_exit or de_thread, only when there are no more
* references to the shared signal_struct.
*/
void exit_itimers(struct signal_struct *sig)
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index c14cd9991181..46a5e5acff97 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -1,5 +1,6 @@
config PM
bool "Power Management support"
+ depends on !IA64_HP_SIM
---help---
"Power Management" means that parts of your computer are shut
off or put into a power conserving "sleep" mode if they are not
@@ -28,7 +29,7 @@ config PM_DEBUG
config SOFTWARE_SUSPEND
bool "Software Suspend"
- depends on PM && SWAP && (X86 || ((FVR || PPC32) && !SMP))
+ depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FVR || PPC32) && !SMP)
---help---
Enable the possibility of suspending the machine.
It doesn't need APM.
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 2d8bf054d036..761956e813f5 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -17,12 +17,12 @@
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/mount.h>
+#include <linux/pm.h>
#include "power.h"
extern suspend_disk_method_t pm_disk_mode;
-extern struct pm_ops * pm_ops;
extern int swsusp_suspend(void);
extern int swsusp_write(void);
@@ -49,13 +49,11 @@ dev_t swsusp_resume_device;
static void power_down(suspend_disk_method_t mode)
{
- unsigned long flags;
int error = 0;
- local_irq_save(flags);
switch(mode) {
case PM_DISK_PLATFORM:
- device_shutdown();
+ kernel_power_off_prepare();
error = pm_ops->enter(PM_SUSPEND_DISK);
break;
case PM_DISK_SHUTDOWN:
diff --git a/kernel/power/power.h b/kernel/power/power.h
index cd6a3493cc0d..6748de23e83c 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -1,7 +1,7 @@
#include <linux/suspend.h>
#include <linux/utsname.h>
-/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but
+/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but
we probably do not take enough locks for switching consoles, etc,
so bad things might happen.
*/
@@ -9,6 +9,9 @@
#define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1)
#endif
+#define MAX_PBES ((PAGE_SIZE - sizeof(struct new_utsname) \
+ - 4 - 3*sizeof(unsigned long) - sizeof(int) \
+ - sizeof(void *)) / sizeof(swp_entry_t))
struct swsusp_info {
struct new_utsname uts;
@@ -18,7 +21,7 @@ struct swsusp_info {
unsigned long image_pages;
unsigned long pagedir_pages;
suspend_pagedir_t * suspend_pagedir;
- swp_entry_t pagedir[768];
+ swp_entry_t pagedir[MAX_PBES];
} __attribute__((aligned(PAGE_SIZE)));
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index d967e875ee82..10bc5ec496d7 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -363,7 +363,7 @@ static void lock_swapdevices(void)
}
/**
- * write_swap_page - Write one page to a fresh swap location.
+ * write_page - Write one page to a fresh swap location.
* @addr: Address we're writing.
* @loc: Place to store the entry we used.
*
@@ -402,15 +402,14 @@ static int write_page(unsigned long addr, swp_entry_t * loc)
static void data_free(void)
{
swp_entry_t entry;
- int i;
+ struct pbe * p;
- for (i = 0; i < nr_copy_pages; i++) {
- entry = (pagedir_nosave + i)->swap_address;
+ for_each_pbe(p, pagedir_nosave) {
+ entry = p->swap_address;
if (entry.val)
swap_free(entry);
else
break;
- (pagedir_nosave + i)->swap_address = (swp_entry_t){0};
}
}
@@ -863,6 +862,9 @@ static int alloc_image_pages(void)
return 0;
}
+/* Free pages we allocated for suspend. Suspend pages are alocated
+ * before atomic copy, so we need to free them after resume.
+ */
void swsusp_free(void)
{
BUG_ON(PageNosave(virt_to_page(pagedir_save)));
@@ -918,6 +920,7 @@ static int swsusp_alloc(void)
pagedir_nosave = NULL;
nr_copy_pages = calc_nr(nr_copy_pages);
+ nr_copy_pages_check = nr_copy_pages;
pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
@@ -928,6 +931,10 @@ static int swsusp_alloc(void)
if (!enough_swap())
return -ENOSPC;
+ if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
+ !!(nr_copy_pages % PBES_PER_PAGE))
+ return -ENOSPC;
+
if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
return -ENOMEM;
@@ -940,7 +947,6 @@ static int swsusp_alloc(void)
return error;
}
- nr_copy_pages_check = nr_copy_pages;
return 0;
}
@@ -1089,7 +1095,7 @@ static inline void eat_page(void *page)
*eaten_memory = c;
}
-static unsigned long get_usable_page(unsigned gfp_mask)
+unsigned long get_usable_page(gfp_t gfp_mask)
{
unsigned long m;
@@ -1103,7 +1109,7 @@ static unsigned long get_usable_page(unsigned gfp_mask)
return m;
}
-static void free_eaten_memory(void)
+void free_eaten_memory(void)
{
unsigned long m;
void **c;
@@ -1213,8 +1219,9 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
free_pagedir(pblist);
free_eaten_memory();
pblist = NULL;
- }
- else
+ /* Is this even worth handling? It should never ever happen, and we
+ have just lost user's state, anyway... */
+ } else
printk("swsusp: Relocated %d pages\n", rel);
return pblist;
@@ -1434,9 +1441,9 @@ static int read_pagedir(struct pbe *pblist)
}
if (error)
- free_page((unsigned long)pblist);
-
- BUG_ON(i != swsusp_info.pagedir_pages);
+ free_pagedir(pblist);
+ else
+ BUG_ON(i != swsusp_info.pagedir_pages);
return error;
}
@@ -1474,11 +1481,12 @@ static int read_suspend_image(void)
/* Allocate memory for the image and read the data from swap */
error = check_pagedir(pagedir_nosave);
- free_eaten_memory();
+
if (!error)
error = data_read(pagedir_nosave);
if (error) { /* We fail cleanly */
+ free_eaten_memory();
for_each_pbe (p, pagedir_nosave)
if (p->address) {
free_page(p->address);
diff --git a/kernel/printk.c b/kernel/printk.c
index a967605bc2e3..4b8f0f9230a4 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -488,6 +488,11 @@ static int __init printk_time_setup(char *str)
__setup("time", printk_time_setup);
+__attribute__((weak)) unsigned long long printk_clock(void)
+{
+ return sched_clock();
+}
+
/*
* This is printk. It can be called from any context. We want it to work.
*
@@ -565,7 +570,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
loglev_char = default_message_loglevel
+ '0';
}
- t = sched_clock();
+ t = printk_clock();
nanosec_rem = do_div(t, 1000000000);
tlen = sprintf(tbuf,
"<%c>[%5lu.%06lu] ",
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index f436993bd590..2559d4b8f23f 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. */
@@ -70,7 +71,20 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
/* Fake initialization required by compiler */
static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
-static int maxbatch = 10;
+static int maxbatch = 10000;
+
+#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.
@@ -95,6 +109,10 @@ void fastcall call_rcu(struct rcu_head *head,
rdp = &__get_cpu_var(rcu_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
+
+ if (unlikely(++rdp->count > 10000))
+ set_need_resched();
+
local_irq_restore(flags);
}
@@ -126,6 +144,12 @@ void fastcall call_rcu_bh(struct rcu_head *head,
rdp = &__get_cpu_var(rcu_bh_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
+ rdp->count++;
+/*
+ * Should we directly call rcu_do_batch() here ?
+ * if (unlikely(rdp->count > 10000))
+ * rcu_do_batch(rdp);
+ */
local_irq_restore(flags);
}
@@ -143,6 +167,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
next = rdp->donelist = list->next;
list->func(list);
list = next;
+ rdp->count--;
if (++count >= maxbatch)
break;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 18b95520a2e2..1e5cafdf4e27 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -294,6 +294,10 @@ static inline void prepare_lock_switch(runqueue_t *rq, task_t *next)
static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
{
+#ifdef CONFIG_DEBUG_SPINLOCK
+ /* this is a valid case when another task releases the spinlock */
+ rq->lock.owner = current;
+#endif
spin_unlock_irq(&rq->lock);
}
@@ -875,7 +879,7 @@ static int migrate_task(task_t *p, int dest_cpu, migration_req_t *req)
* smp_call_function() if an IPI is sent by the same process we are
* waiting to become inactive.
*/
-void wait_task_inactive(task_t * p)
+void wait_task_inactive(task_t *p)
{
unsigned long flags;
runqueue_t *rq;
@@ -966,8 +970,11 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
int local_group;
int i;
+ /* Skip over this group if it has no CPUs allowed */
+ if (!cpus_intersects(group->cpumask, p->cpus_allowed))
+ goto nextgroup;
+
local_group = cpu_isset(this_cpu, group->cpumask);
- /* XXX: put a cpus allowed check */
/* Tally up the load of all CPUs in the group */
avg_load = 0;
@@ -992,6 +999,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
min_load = avg_load;
idlest = group;
}
+nextgroup:
group = group->next;
} while (group != sd->groups);
@@ -1003,13 +1011,18 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
/*
* find_idlest_queue - find the idlest runqueue among the cpus in group.
*/
-static int find_idlest_cpu(struct sched_group *group, int this_cpu)
+static int
+find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
{
+ cpumask_t tmp;
unsigned long load, min_load = ULONG_MAX;
int idlest = -1;
int i;
- for_each_cpu_mask(i, group->cpumask) {
+ /* Traverse only the allowed CPUs */
+ cpus_and(tmp, group->cpumask, p->cpus_allowed);
+
+ for_each_cpu_mask(i, tmp) {
load = source_load(i, 0);
if (load < min_load || (load == min_load && i == this_cpu)) {
@@ -1052,7 +1065,7 @@ static int sched_balance_self(int cpu, int flag)
if (!group)
goto nextlevel;
- new_cpu = find_idlest_cpu(group, cpu);
+ new_cpu = find_idlest_cpu(group, t, cpu);
if (new_cpu == -1 || new_cpu == cpu)
goto nextlevel;
@@ -1127,7 +1140,7 @@ static inline int wake_idle(int cpu, task_t *p)
*
* returns failure only if the task is already active.
*/
-static int try_to_wake_up(task_t * p, unsigned int state, int sync)
+static int try_to_wake_up(task_t *p, unsigned int state, int sync)
{
int cpu, this_cpu, success = 0;
unsigned long flags;
@@ -1252,6 +1265,16 @@ out_activate:
}
/*
+ * Tasks that have marked their sleep as noninteractive get
+ * woken up without updating their sleep average. (i.e. their
+ * sleep is handled in a priority-neutral manner, no priority
+ * boost and no penalty.)
+ */
+ if (old_state & TASK_NONINTERACTIVE)
+ __activate_task(p, rq);
+ else
+ activate_task(p, rq, cpu == this_cpu);
+ /*
* Sync wakeups (i.e. those types of wakeups where the waker
* has indicated that it will leave the CPU in short order)
* don't trigger a preemption, if the woken up task will run on
@@ -1259,7 +1282,6 @@ out_activate:
* the waker guarantees that the freshly woken up task is going
* to be considered on this CPU.)
*/
- activate_task(p, rq, cpu == this_cpu);
if (!sync || cpu != this_cpu) {
if (TASK_PREEMPTS_CURR(p, rq))
resched_task(rq->curr);
@@ -1274,7 +1296,7 @@ out:
return success;
}
-int fastcall wake_up_process(task_t * p)
+int fastcall wake_up_process(task_t *p)
{
return try_to_wake_up(p, TASK_STOPPED | TASK_TRACED |
TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
@@ -1353,7 +1375,7 @@ void fastcall sched_fork(task_t *p, int clone_flags)
* that must be done for every newly created context, then puts the task
* on the runqueue and wakes it.
*/
-void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
+void fastcall wake_up_new_task(task_t *p, unsigned long clone_flags)
{
unsigned long flags;
int this_cpu, cpu;
@@ -1436,7 +1458,7 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
* artificially, because any timeslice recovered here
* was given away by the parent in the first place.)
*/
-void fastcall sched_exit(task_t * p)
+void fastcall sched_exit(task_t *p)
{
unsigned long flags;
runqueue_t *rq;
@@ -1753,7 +1775,8 @@ void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
*/
static inline
int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
- struct sched_domain *sd, enum idle_type idle, int *all_pinned)
+ struct sched_domain *sd, enum idle_type idle,
+ int *all_pinned)
{
/*
* We do not migrate tasks that are:
@@ -1883,10 +1906,11 @@ out:
*/
static struct sched_group *
find_busiest_group(struct sched_domain *sd, int this_cpu,
- unsigned long *imbalance, enum idle_type idle)
+ unsigned long *imbalance, enum idle_type idle, int *sd_idle)
{
struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
unsigned long max_load, avg_load, total_load, this_load, total_pwr;
+ unsigned long max_pull;
int load_idx;
max_load = this_load = total_load = total_pwr = 0;
@@ -1908,6 +1932,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
avg_load = 0;
for_each_cpu_mask(i, group->cpumask) {
+ if (*sd_idle && !idle_cpu(i))
+ *sd_idle = 0;
+
/* Bias balancing toward cpus of our domain */
if (local_group)
load = target_load(i, load_idx);
@@ -1933,7 +1960,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
group = group->next;
} while (group != sd->groups);
- if (!busiest || this_load >= max_load)
+ if (!busiest || this_load >= max_load || max_load <= SCHED_LOAD_SCALE)
goto out_balanced;
avg_load = (SCHED_LOAD_SCALE * total_load) / total_pwr;
@@ -1953,8 +1980,12 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
* by pulling tasks to us. Be careful of negative numbers as they'll
* appear as very large values with unsigned longs.
*/
+
+ /* Don't want to pull so many tasks that a group would go idle */
+ max_pull = min(max_load - avg_load, max_load - SCHED_LOAD_SCALE);
+
/* How much load to actually move to equalise the imbalance */
- *imbalance = min((max_load - avg_load) * busiest->cpu_power,
+ *imbalance = min(max_pull * busiest->cpu_power,
(avg_load - this_load) * this->cpu_power)
/ SCHED_LOAD_SCALE;
@@ -2051,11 +2082,14 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
unsigned long imbalance;
int nr_moved, all_pinned = 0;
int active_balance = 0;
+ int sd_idle = 0;
+
+ if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER)
+ sd_idle = 1;
- spin_lock(&this_rq->lock);
schedstat_inc(sd, lb_cnt[idle]);
- group = find_busiest_group(sd, this_cpu, &imbalance, idle);
+ group = find_busiest_group(sd, this_cpu, &imbalance, idle, &sd_idle);
if (!group) {
schedstat_inc(sd, lb_nobusyg[idle]);
goto out_balanced;
@@ -2079,19 +2113,16 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
* still unbalanced. nr_moved simply stays zero, so it is
* correctly treated as an imbalance.
*/
- double_lock_balance(this_rq, busiest);
+ double_rq_lock(this_rq, busiest);
nr_moved = move_tasks(this_rq, this_cpu, busiest,
- imbalance, sd, idle,
- &all_pinned);
- spin_unlock(&busiest->lock);
+ imbalance, sd, idle, &all_pinned);
+ double_rq_unlock(this_rq, busiest);
/* All tasks on this runqueue were pinned by CPU affinity */
if (unlikely(all_pinned))
goto out_balanced;
}
- spin_unlock(&this_rq->lock);
-
if (!nr_moved) {
schedstat_inc(sd, lb_failed[idle]);
sd->nr_balance_failed++;
@@ -2099,6 +2130,16 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) {
spin_lock(&busiest->lock);
+
+ /* don't kick the migration_thread, if the curr
+ * task on busiest cpu can't be moved to this_cpu
+ */
+ if (!cpu_isset(this_cpu, busiest->curr->cpus_allowed)) {
+ spin_unlock(&busiest->lock);
+ all_pinned = 1;
+ goto out_one_pinned;
+ }
+
if (!busiest->active_balance) {
busiest->active_balance = 1;
busiest->push_cpu = this_cpu;
@@ -2131,19 +2172,23 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
sd->balance_interval *= 2;
}
+ if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+ return -1;
return nr_moved;
out_balanced:
- spin_unlock(&this_rq->lock);
-
schedstat_inc(sd, lb_balanced[idle]);
sd->nr_balance_failed = 0;
+
+out_one_pinned:
/* tune up the balancing interval */
if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) ||
(sd->balance_interval < sd->max_interval))
sd->balance_interval *= 2;
+ if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+ return -1;
return 0;
}
@@ -2161,9 +2206,13 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq,
runqueue_t *busiest = NULL;
unsigned long imbalance;
int nr_moved = 0;
+ int sd_idle = 0;
+
+ if (sd->flags & SD_SHARE_CPUPOWER)
+ sd_idle = 1;
schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
- group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE);
+ group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE, &sd_idle);
if (!group) {
schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]);
goto out_balanced;
@@ -2177,22 +2226,30 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq,
BUG_ON(busiest == this_rq);
- /* Attempt to move tasks */
- double_lock_balance(this_rq, busiest);
-
schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance);
- nr_moved = move_tasks(this_rq, this_cpu, busiest,
+
+ nr_moved = 0;
+ if (busiest->nr_running > 1) {
+ /* Attempt to move tasks */
+ double_lock_balance(this_rq, busiest);
+ nr_moved = move_tasks(this_rq, this_cpu, busiest,
imbalance, sd, NEWLY_IDLE, NULL);
- if (!nr_moved)
+ spin_unlock(&busiest->lock);
+ }
+
+ if (!nr_moved) {
schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
- else
+ if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+ return -1;
+ } else
sd->nr_balance_failed = 0;
- spin_unlock(&busiest->lock);
return nr_moved;
out_balanced:
schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
+ if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+ return -1;
sd->nr_balance_failed = 0;
return 0;
}
@@ -2317,7 +2374,11 @@ static void rebalance_tick(int this_cpu, runqueue_t *this_rq,
if (j - sd->last_balance >= interval) {
if (load_balance(this_cpu, this_rq, sd, idle)) {
- /* We've pulled tasks over so no longer idle */
+ /*
+ * We've pulled tasks over so either we're no
+ * longer idle, or one of our SMT siblings is
+ * not idle.
+ */
idle = NOT_IDLE;
}
sd->last_balance += interval;
@@ -2576,6 +2637,13 @@ out:
}
#ifdef CONFIG_SCHED_SMT
+static inline void wakeup_busy_runqueue(runqueue_t *rq)
+{
+ /* If an SMT runqueue is sleeping due to priority reasons wake it up */
+ if (rq->curr == rq->idle && rq->nr_running)
+ resched_task(rq->idle);
+}
+
static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
{
struct sched_domain *tmp, *sd = NULL;
@@ -2609,12 +2677,7 @@ static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
for_each_cpu_mask(i, sibling_map) {
runqueue_t *smt_rq = cpu_rq(i);
- /*
- * If an SMT sibling task is sleeping due to priority
- * reasons wake it up now.
- */
- if (smt_rq->curr == smt_rq->idle && smt_rq->nr_running)
- resched_task(smt_rq->idle);
+ wakeup_busy_runqueue(smt_rq);
}
for_each_cpu_mask(i, sibling_map)
@@ -2625,6 +2688,16 @@ static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
*/
}
+/*
+ * number of 'lost' timeslices this task wont be able to fully
+ * utilize, if another task runs on a sibling. This models the
+ * slowdown effect of other tasks running on siblings:
+ */
+static inline unsigned long smt_slice(task_t *p, struct sched_domain *sd)
+{
+ return p->time_slice * (100 - sd->per_cpu_gain) / 100;
+}
+
static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
{
struct sched_domain *tmp, *sd = NULL;
@@ -2668,6 +2741,10 @@ static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
runqueue_t *smt_rq = cpu_rq(i);
task_t *smt_curr = smt_rq->curr;
+ /* Kernel threads do not participate in dependent sleeping */
+ if (!p->mm || !smt_curr->mm || rt_task(p))
+ goto check_smt_task;
+
/*
* If a user task with lower static priority than the
* running task on the SMT sibling is trying to schedule,
@@ -2676,21 +2753,45 @@ static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
* task from using an unfair proportion of the
* physical cpu's resources. -ck
*/
- if (((smt_curr->time_slice * (100 - sd->per_cpu_gain) / 100) >
- task_timeslice(p) || rt_task(smt_curr)) &&
- p->mm && smt_curr->mm && !rt_task(p))
- ret = 1;
+ if (rt_task(smt_curr)) {
+ /*
+ * With real time tasks we run non-rt tasks only
+ * per_cpu_gain% of the time.
+ */
+ if ((jiffies % DEF_TIMESLICE) >
+ (sd->per_cpu_gain * DEF_TIMESLICE / 100))
+ ret = 1;
+ } else
+ if (smt_curr->static_prio < p->static_prio &&
+ !TASK_PREEMPTS_CURR(p, smt_rq) &&
+ smt_slice(smt_curr, sd) > task_timeslice(p))
+ ret = 1;
+
+check_smt_task:
+ if ((!smt_curr->mm && smt_curr != smt_rq->idle) ||
+ rt_task(smt_curr))
+ continue;
+ if (!p->mm) {
+ wakeup_busy_runqueue(smt_rq);
+ continue;
+ }
/*
- * Reschedule a lower priority task on the SMT sibling,
- * or wake it up if it has been put to sleep for priority
- * reasons.
+ * Reschedule a lower priority task on the SMT sibling for
+ * it to be put to sleep, or wake it up if it has been put to
+ * sleep for priority reasons to see if it should run now.
*/
- if ((((p->time_slice * (100 - sd->per_cpu_gain) / 100) >
- task_timeslice(smt_curr) || rt_task(p)) &&
- smt_curr->mm && p->mm && !rt_task(smt_curr)) ||
- (smt_curr == smt_rq->idle && smt_rq->nr_running))
- resched_task(smt_curr);
+ if (rt_task(p)) {
+ if ((jiffies % DEF_TIMESLICE) >
+ (sd->per_cpu_gain * DEF_TIMESLICE / 100))
+ resched_task(smt_curr);
+ } else {
+ if (TASK_PREEMPTS_CURR(p, smt_rq) &&
+ smt_slice(p, sd) > task_timeslice(smt_curr))
+ resched_task(smt_curr);
+ else
+ wakeup_busy_runqueue(smt_rq);
+ }
}
out_unlock:
for_each_cpu_mask(i, sibling_map)
@@ -2888,6 +2989,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));
@@ -3015,7 +3117,8 @@ need_resched:
#endif /* CONFIG_PREEMPT */
-int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, void *key)
+int default_wake_function(wait_queue_t *curr, unsigned mode, int sync,
+ void *key)
{
task_t *p = curr->private;
return try_to_wake_up(p, mode, sync);
@@ -3057,7 +3160,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
* @key: is directly passed to the wakeup function
*/
void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,
- int nr_exclusive, void *key)
+ int nr_exclusive, void *key)
{
unsigned long flags;
@@ -3089,7 +3192,8 @@ void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode)
*
* On UP it can prevent extra preemption.
*/
-void fastcall __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
+void fastcall
+__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
{
unsigned long flags;
int sync = 1;
@@ -3280,7 +3384,8 @@ void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q)
EXPORT_SYMBOL(interruptible_sleep_on);
-long fastcall __sched interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
+long fastcall __sched
+interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
{
SLEEP_ON_VAR
@@ -3499,7 +3604,8 @@ static void __setscheduler(struct task_struct *p, int policy, int prio)
* @policy: new policy.
* @param: structure containing the new RT priority.
*/
-int sched_setscheduler(struct task_struct *p, int policy, struct sched_param *param)
+int sched_setscheduler(struct task_struct *p, int policy,
+ struct sched_param *param)
{
int retval;
int oldprio, oldpolicy = -1;
@@ -3519,7 +3625,7 @@ recheck:
* 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
*/
if (param->sched_priority < 0 ||
- (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
+ (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
(!p->mm && param->sched_priority > MAX_RT_PRIO-1))
return -EINVAL;
if ((policy == SCHED_NORMAL) != (param->sched_priority == 0))
@@ -3582,7 +3688,8 @@ recheck:
}
EXPORT_SYMBOL_GPL(sched_setscheduler);
-static int do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
+static int
+do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
{
int retval;
struct sched_param lparam;
@@ -3772,6 +3879,7 @@ EXPORT_SYMBOL(cpu_present_map);
#ifndef CONFIG_SMP
cpumask_t cpu_online_map = CPU_MASK_ALL;
+EXPORT_SYMBOL_GPL(cpu_online_map);
cpumask_t cpu_possible_map = CPU_MASK_ALL;
#endif
@@ -3849,7 +3957,7 @@ asmlinkage long sys_sched_yield(void)
if (rt_task(current))
target = rq->active;
- if (current->array->nr_active == 1) {
+ if (array->nr_active == 1) {
schedstat_inc(rq, yld_act_empty);
if (!rq->expired->nr_active)
schedstat_inc(rq, yld_both_empty);
@@ -3913,7 +4021,7 @@ EXPORT_SYMBOL(cond_resched);
* operations here to prevent schedule() from being called twice (once via
* spin_unlock(), once by hand).
*/
-int cond_resched_lock(spinlock_t * lock)
+int cond_resched_lock(spinlock_t *lock)
{
int ret = 0;
@@ -4096,7 +4204,7 @@ static inline struct task_struct *younger_sibling(struct task_struct *p)
return list_entry(p->sibling.next,struct task_struct,sibling);
}
-static void show_task(task_t * p)
+static void show_task(task_t *p)
{
task_t *relative;
unsigned state;
@@ -4122,7 +4230,7 @@ static void show_task(task_t * p)
#endif
#ifdef CONFIG_DEBUG_STACK_USAGE
{
- unsigned long * n = (unsigned long *) (p->thread_info+1);
+ unsigned long *n = (unsigned long *) (p->thread_info+1);
while (!*n)
n++;
free = (unsigned long) n - (unsigned long)(p->thread_info+1);
@@ -4331,7 +4439,7 @@ out:
* thread migration by bumping thread off CPU then 'pushing' onto
* another runqueue.
*/
-static int migration_thread(void * data)
+static int migration_thread(void *data)
{
runqueue_t *rq;
int cpu = (long)data;
@@ -5495,3 +5603,47 @@ void normalize_rt_tasks(void)
}
#endif /* CONFIG_MAGIC_SYSRQ */
+
+#ifdef CONFIG_IA64
+/*
+ * These functions are only useful for the IA64 MCA handling.
+ *
+ * They can only be called when the whole system has been
+ * stopped - every CPU needs to be quiescent, and no scheduling
+ * activity can take place. Using them for anything else would
+ * be a serious bug, and as a result, they aren't even visible
+ * under any other configuration.
+ */
+
+/**
+ * curr_task - return the current task for a given cpu.
+ * @cpu: the processor in question.
+ *
+ * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
+ */
+task_t *curr_task(int cpu)
+{
+ return cpu_curr(cpu);
+}
+
+/**
+ * set_curr_task - set the current task for a given cpu.
+ * @cpu: the processor in question.
+ * @p: the task pointer to set.
+ *
+ * Description: This function must only be used when non-maskable interrupts
+ * are serviced on a separate stack. It allows the architecture to switch the
+ * notion of the current task on a cpu in a non-blocking manner. This function
+ * must be called with all CPU's synchronized, and interrupts disabled, the
+ * and caller must save the original value of the current task (see
+ * curr_task() above) and restore that value before reenabling interrupts and
+ * re-starting the system.
+ *
+ * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
+ */
+void set_curr_task(int cpu, task_t *p)
+{
+ cpu_curr(cpu) = p;
+}
+
+#endif
diff --git a/kernel/signal.c b/kernel/signal.c
index 4980a073237f..f2b96b08fb44 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -262,7 +262,7 @@ next_signal(struct sigpending *pending, sigset_t *mask)
return sig;
}
-static struct sigqueue *__sigqueue_alloc(struct task_struct *t, unsigned int __nocast flags,
+static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
int override_rlimit)
{
struct sigqueue *q = NULL;
@@ -397,20 +397,8 @@ void __exit_signal(struct task_struct *tsk)
flush_sigqueue(&tsk->pending);
if (sig) {
/*
- * We are cleaning up the signal_struct here. We delayed
- * calling exit_itimers until after flush_sigqueue, just in
- * case our thread-local pending queue contained a queued
- * timer signal that would have been cleared in
- * exit_itimers. When that called sigqueue_free, it would
- * attempt to re-take the tasklist_lock and deadlock. This
- * can never happen if we ensure that all queues the
- * timer's signal might be queued on have been flushed
- * first. The shared_pending queue, and our own pending
- * queue are the only queues the timer could be on, since
- * there are no other threads left in the group and timer
- * signals are constrained to threads inside the group.
+ * We are cleaning up the signal_struct here.
*/
- exit_itimers(sig);
exit_thread_group_keys(sig);
kmem_cache_free(signal_cachep, sig);
}
@@ -578,7 +566,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
* is to alert stop-signal processing code when another
* processor has come along and cleared the flag.
*/
- tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
+ if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT))
+ tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
}
if ( signr &&
((info->si_code & __SI_MASK) == __SI_TIMER) &&
@@ -936,34 +925,31 @@ force_sig_specific(int sig, struct task_struct *t)
* as soon as they're available, so putting the signal on the shared queue
* will be equivalent to sending it to one such thread.
*/
-#define wants_signal(sig, p, mask) \
- (!sigismember(&(p)->blocked, sig) \
- && !((p)->state & mask) \
- && !((p)->flags & PF_EXITING) \
- && (task_curr(p) || !signal_pending(p)))
-
+static inline int wants_signal(int sig, struct task_struct *p)
+{
+ if (sigismember(&p->blocked, sig))
+ return 0;
+ if (p->flags & PF_EXITING)
+ return 0;
+ if (sig == SIGKILL)
+ return 1;
+ if (p->state & (TASK_STOPPED | TASK_TRACED))
+ return 0;
+ return task_curr(p) || !signal_pending(p);
+}
static void
__group_complete_signal(int sig, struct task_struct *p)
{
- unsigned int mask;
struct task_struct *t;
/*
- * Don't bother traced and stopped tasks (but
- * SIGKILL will punch through that).
- */
- mask = TASK_STOPPED | TASK_TRACED;
- if (sig == SIGKILL)
- mask = 0;
-
- /*
* Now find a thread we can wake up to take the signal off the queue.
*
* If the main thread wants the signal, it gets first crack.
* Probably the least surprising to the average bear.
*/
- if (wants_signal(sig, p, mask))
+ if (wants_signal(sig, p))
t = p;
else if (thread_group_empty(p))
/*
@@ -981,7 +967,7 @@ __group_complete_signal(int sig, struct task_struct *p)
t = p->signal->curr_target = p;
BUG_ON(t->tgid != p->tgid);
- while (!wants_signal(sig, t, mask)) {
+ while (!wants_signal(sig, t)) {
t = next_thread(t);
if (t == p->signal->curr_target)
/*
@@ -1195,6 +1181,40 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
return error;
}
+/* like kill_proc_info(), but doesn't use uid/euid of "current" */
+int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+ uid_t uid, uid_t euid)
+{
+ int ret = -EINVAL;
+ struct task_struct *p;
+
+ if (!valid_signal(sig))
+ return ret;
+
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ if (!p) {
+ ret = -ESRCH;
+ goto out_unlock;
+ }
+ if ((!info || ((unsigned long)info != 1 &&
+ (unsigned long)info != 2 && SI_FROMUSER(info)))
+ && (euid != p->suid) && (euid != p->uid)
+ && (uid != p->suid) && (uid != p->uid)) {
+ ret = -EPERM;
+ goto out_unlock;
+ }
+ if (sig && p->sighand) {
+ unsigned long flags;
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ ret = __group_send_sig_info(sig, info, p);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+out_unlock:
+ read_unlock(&tasklist_lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
/*
* kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1766,7 +1786,8 @@ do_signal_stop(int signr)
* stop is always done with the siglock held,
* so this check has no races.
*/
- if (t->state < TASK_STOPPED) {
+ if (!t->exit_state &&
+ !(t->state & (TASK_STOPPED|TASK_TRACED))) {
stop_count++;
signal_wake_up(t, 0);
}
@@ -2221,8 +2242,7 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese,
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- current->state = TASK_INTERRUPTIBLE;
- timeout = schedule_timeout(timeout);
+ timeout = schedule_timeout_interruptible(timeout);
try_to_freeze();
spin_lock_irq(&current->sighand->siglock);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b4ab6af1dea8..f766b2fc48be 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -84,7 +84,7 @@ asmlinkage void __do_softirq(void)
cpu = smp_processor_id();
restart:
/* Reset the pending bitmask before enabling irqs */
- local_softirq_pending() = 0;
+ set_softirq_pending(0);
local_irq_enable();
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index 0c3f9d8bbe17..0375fcd5921d 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -3,7 +3,10 @@
*
* Author: Zwane Mwaikambo <zwane@fsmlabs.com>
*
- * Copyright (2004) Ingo Molnar
+ * Copyright (2004, 2005) Ingo Molnar
+ *
+ * This file contains the spinlock/rwlock implementations for the
+ * SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them)
*/
#include <linux/config.h>
@@ -17,12 +20,12 @@
* Generic declaration of the raw read_trylock() function,
* architectures are supposed to optimize this:
*/
-int __lockfunc generic_raw_read_trylock(rwlock_t *lock)
+int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock)
{
- _raw_read_lock(lock);
+ __raw_read_lock(lock);
return 1;
}
-EXPORT_SYMBOL(generic_raw_read_trylock);
+EXPORT_SYMBOL(generic__raw_read_trylock);
int __lockfunc _spin_trylock(spinlock_t *lock)
{
@@ -57,7 +60,7 @@ int __lockfunc _write_trylock(rwlock_t *lock)
}
EXPORT_SYMBOL(_write_trylock);
-#ifndef CONFIG_PREEMPT
+#if !defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
void __lockfunc _read_lock(rwlock_t *lock)
{
@@ -72,7 +75,7 @@ unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
local_irq_save(flags);
preempt_disable();
- _raw_spin_lock_flags(lock, flags);
+ _raw_spin_lock_flags(lock, &flags);
return flags;
}
EXPORT_SYMBOL(_spin_lock_irqsave);
diff --git a/kernel/sys.c b/kernel/sys.c
index c80412be2302..2fa1ed18123c 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -361,17 +361,35 @@ out_unlock:
return retval;
}
+/**
+ * emergency_restart - reboot the system
+ *
+ * Without shutting down any hardware or taking any locks
+ * reboot the system. This is called when we know we are in
+ * trouble so this is our best effort to reboot. This is
+ * safe to call in interrupt context.
+ */
void emergency_restart(void)
{
machine_emergency_restart();
}
EXPORT_SYMBOL_GPL(emergency_restart);
-void kernel_restart(char *cmd)
+/**
+ * kernel_restart - reboot the system
+ *
+ * Shutdown everything and perform a clean reboot.
+ * This is not safe to call in interrupt context.
+ */
+void kernel_restart_prepare(char *cmd)
{
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
system_state = SYSTEM_RESTART;
device_shutdown();
+}
+void kernel_restart(char *cmd)
+{
+ kernel_restart_prepare(cmd);
if (!cmd) {
printk(KERN_EMERG "Restarting system.\n");
} else {
@@ -382,6 +400,12 @@ void kernel_restart(char *cmd)
}
EXPORT_SYMBOL_GPL(kernel_restart);
+/**
+ * kernel_kexec - reboot the system
+ *
+ * Move into place and start executing a preloaded standalone
+ * executable. If nothing was preloaded return an error.
+ */
void kernel_kexec(void)
{
#ifdef CONFIG_KEXEC
@@ -390,9 +414,7 @@ void kernel_kexec(void)
if (!image) {
return;
}
- notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
- system_state = SYSTEM_RESTART;
- device_shutdown();
+ kernel_restart_prepare(NULL);
printk(KERN_EMERG "Starting new kernel\n");
machine_shutdown();
machine_kexec(image);
@@ -400,21 +422,39 @@ void kernel_kexec(void)
}
EXPORT_SYMBOL_GPL(kernel_kexec);
-void kernel_halt(void)
+/**
+ * kernel_halt - halt the system
+ *
+ * Shutdown everything and perform a clean system halt.
+ */
+void kernel_halt_prepare(void)
{
notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
system_state = SYSTEM_HALT;
device_shutdown();
+}
+void kernel_halt(void)
+{
+ kernel_halt_prepare();
printk(KERN_EMERG "System halted.\n");
machine_halt();
}
EXPORT_SYMBOL_GPL(kernel_halt);
-void kernel_power_off(void)
+/**
+ * kernel_power_off - power_off the system
+ *
+ * Shutdown everything and perform a clean system power_off.
+ */
+void kernel_power_off_prepare(void)
{
notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
system_state = SYSTEM_POWER_OFF;
device_shutdown();
+}
+void kernel_power_off(void)
+{
+ kernel_power_off_prepare();
printk(KERN_EMERG "Power down.\n");
machine_power_off();
}
@@ -1728,8 +1768,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
error = put_user(current->pdeath_signal, (int __user *)arg2);
break;
case PR_GET_DUMPABLE:
- if (current->mm->dumpable)
- error = 1;
+ error = current->mm->dumpable;
break;
case PR_SET_DUMPABLE:
if (arg2 < 0 || arg2 > 2) {
diff --git a/kernel/time.c b/kernel/time.c
index dd5ae1162a8f..40c2410ac99a 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -570,6 +570,7 @@ void getnstimeofday(struct timespec *tv)
tv->tv_sec = x.tv_sec;
tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
}
+EXPORT_SYMBOL_GPL(getnstimeofday);
#endif
#if (BITS_PER_LONG < 64)
diff --git a/kernel/timer.c b/kernel/timer.c
index 13e2b513be01..3ba10fa35b60 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1151,9 +1151,26 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
out:
return timeout < 0 ? 0 : timeout;
}
-
EXPORT_SYMBOL(schedule_timeout);
+/*
+ * We can use __set_current_state() here because schedule_timeout() calls
+ * schedule() unconditionally.
+ */
+signed long __sched schedule_timeout_interruptible(signed long timeout)
+{
+ __set_current_state(TASK_INTERRUPTIBLE);
+ return schedule_timeout(timeout);
+}
+EXPORT_SYMBOL(schedule_timeout_interruptible);
+
+signed long __sched schedule_timeout_uninterruptible(signed long timeout)
+{
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ return schedule_timeout(timeout);
+}
+EXPORT_SYMBOL(schedule_timeout_uninterruptible);
+
/* Thread ID - the internal kernel "pid" */
asmlinkage long sys_gettid(void)
{
@@ -1170,8 +1187,7 @@ static long __sched nanosleep_restart(struct restart_block *restart)
if (!time_after(expire, now))
return 0;
- current->state = TASK_INTERRUPTIBLE;
- expire = schedule_timeout(expire - now);
+ expire = schedule_timeout_interruptible(expire - now);
ret = 0;
if (expire) {
@@ -1199,8 +1215,7 @@ asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __us
return -EINVAL;
expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
- current->state = TASK_INTERRUPTIBLE;
- expire = schedule_timeout(expire);
+ expire = schedule_timeout_interruptible(expire);
ret = 0;
if (expire) {
@@ -1598,10 +1613,8 @@ void msleep(unsigned int msecs)
{
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
- while (timeout) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- }
+ while (timeout)
+ timeout = schedule_timeout_uninterruptible(timeout);
}
EXPORT_SYMBOL(msleep);
@@ -1614,10 +1627,8 @@ unsigned long msleep_interruptible(unsigned int msecs)
{
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
- while (timeout && !signal_pending(current)) {
- set_current_state(TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- }
+ while (timeout && !signal_pending(current))
+ timeout = schedule_timeout_interruptible(timeout);
return jiffies_to_msecs(timeout);
}
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644
index 000000000000..3bef1ea94c99
--- /dev/null
+++ b/lib/.gitignore
@@ -0,0 +1,6 @@
+#
+# Generated files
+#
+gen_crc32table
+crc32table.h
+
diff --git a/lib/Kconfig b/lib/Kconfig
index e43197efeb9c..3de93357f5ab 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -12,6 +12,14 @@ config CRC_CCITT
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/Kconfig.debug b/lib/Kconfig.debug
index 3754c9a8f5c8..016e89a44ac8 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -170,11 +170,11 @@ config DEBUG_FS
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
- depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV || UML)
+ depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
default y if DEBUG_INFO && UML
help
If you say Y here the resulting kernel image will be slightly larger
- and slower, but it will give very useful debugging information.
- If you don't debug the kernel, you can say N, but we may not be able
- to solve problems without frame pointers.
+ and slower, but it might give very useful debugging information
+ on some architectures or you use external debuggers.
+ If you don't debug the kernel, you can say N.
diff --git a/lib/Makefile b/lib/Makefile
index 3e2bd0df23bb..44a46750690a 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -16,6 +16,7 @@ CFLAGS_kobject.o += -DDEBUG
CFLAGS_kobject_uevent.o += -DDEBUG
endif
+obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o
@@ -23,11 +24,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 000000000000..011fe573c666
--- /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/lib/dec_and_lock.c b/lib/dec_and_lock.c
index 6658d81e1836..305a9663aee3 100644
--- a/lib/dec_and_lock.c
+++ b/lib/dec_and_lock.c
@@ -1,7 +1,41 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
+#include <asm/system.h>
+#ifdef __HAVE_ARCH_CMPXCHG
+/*
+ * This is an implementation of the notion of "decrement a
+ * reference count, and return locked if it decremented to zero".
+ *
+ * This implementation can be used on any architecture that
+ * has a cmpxchg, and where atomic->value is an int holding
+ * the value of the atomic (i.e. the high bits aren't used
+ * for a lock or anything like that).
+ */
+int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+{
+ int counter;
+ int newcount;
+
+ for (;;) {
+ counter = atomic_read(atomic);
+ newcount = counter - 1;
+ if (!newcount)
+ break; /* do it the slow way */
+
+ newcount = cmpxchg(&atomic->counter, counter, newcount);
+ if (newcount == counter)
+ return 0;
+ }
+
+ spin_lock(lock);
+ if (atomic_dec_and_test(atomic))
+ return 1;
+ spin_unlock(lock);
+ return 0;
+}
+#else
/*
* This is an architecture-neutral, but slow,
* implementation of the notion of "decrement
@@ -25,8 +59,6 @@
* this is trivially done efficiently using a load-locked
* store-conditional approach, for example.
*/
-
-#ifndef ATOMIC_DEC_AND_LOCK
int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
{
spin_lock(lock);
@@ -35,6 +67,6 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
spin_unlock(lock);
return 0;
}
+#endif
EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif
diff --git a/lib/idr.c b/lib/idr.c
index 6415d053e2bf..6414b2fb482d 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -72,7 +72,7 @@ static void free_layer(struct idr *idp, struct idr_layer *p)
* If the system is REALLY out of memory this function returns 0,
* otherwise 1.
*/
-int idr_pre_get(struct idr *idp, unsigned gfp_mask)
+int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
{
while (idp->id_free_cnt < IDR_FREE_MAX) {
struct idr_layer *new;
@@ -346,6 +346,19 @@ void idr_remove(struct idr *idp, int id)
EXPORT_SYMBOL(idr_remove);
/**
+ * idr_destroy - release all cached layers within an idr tree
+ * idp: idr handle
+ */
+void idr_destroy(struct idr *idp)
+{
+ while (idp->id_free_cnt) {
+ struct idr_layer *p = alloc_layer(idp);
+ kmem_cache_free(idr_layer_cache, p);
+ }
+}
+EXPORT_SYMBOL(idr_destroy);
+
+/**
* idr_find - return pointer for given id
* @idp: idr handle
* @id: lookup key
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index bd2bc5d887b8..cb5490ec00f2 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -177,8 +177,7 @@ static inline void __lock_kernel(void)
static inline void __unlock_kernel(void)
{
- _raw_spin_unlock(&kernel_flag);
- preempt_enable();
+ spin_unlock(&kernel_flag);
}
/*
diff --git a/lib/kobject.c b/lib/kobject.c
index dd0917dd9fa9..253d3004ace9 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -100,7 +100,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
* @kobj: kobject in question, with which to build the path
* @gfp_mask: the allocation type used to allocate the path
*/
-char *kobject_get_path(struct kobject *kobj, int gfp_mask)
+char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
{
char *path;
int len;
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 04ca4429ddfa..7ef6f6a17aa6 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -62,7 +62,7 @@ static struct sock *uevent_sock;
* @gfp_mask:
*/
static int send_uevent(const char *signal, const char *obj,
- char **envp, int gfp_mask)
+ char **envp, gfp_t gfp_mask)
{
struct sk_buff *skb;
char *pos;
@@ -98,7 +98,7 @@ static int send_uevent(const char *signal, const char *obj,
}
static int do_kobject_uevent(struct kobject *kobj, enum kobject_action action,
- struct attribute *attr, int gfp_mask)
+ struct attribute *attr, gfp_t gfp_mask)
{
char *path;
char *attrpath;
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index b972dd29289d..d1c057e71b68 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -110,7 +110,7 @@ radix_tree_node_free(struct radix_tree_node *node)
* success, return zero, with preemption disabled. On error, return -ENOMEM
* with preemption not disabled.
*/
-int radix_tree_preload(int gfp_mask)
+int radix_tree_preload(gfp_t gfp_mask)
{
struct radix_tree_preload *rtp;
struct radix_tree_node *node;
diff --git a/lib/sort.c b/lib/sort.c
index b73dbb0e7c83..ddc4d35df289 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -6,15 +6,16 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/sort.h>
-void u32_swap(void *a, void *b, int size)
+static void u32_swap(void *a, void *b, int size)
{
u32 t = *(u32 *)a;
*(u32 *)a = *(u32 *)b;
*(u32 *)b = t;
}
-void generic_swap(void *a, void *b, int size)
+static void generic_swap(void *a, void *b, int size)
{
char t;
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
new file mode 100644
index 000000000000..906ad101eab3
--- /dev/null
+++ b/lib/spinlock_debug.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2005, Red Hat, Inc., Ingo Molnar
+ * Released under the General Public License (GPL).
+ *
+ * This file contains the spinlock/rwlock implementations for
+ * DEBUG_SPINLOCK.
+ */
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+static void spin_bug(spinlock_t *lock, const char *msg)
+{
+ static long print_once = 1;
+ struct task_struct *owner = NULL;
+
+ if (xchg(&print_once, 0)) {
+ if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
+ owner = lock->owner;
+ printk("BUG: spinlock %s on CPU#%d, %s/%d\n",
+ msg, smp_processor_id(), current->comm, current->pid);
+ printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n",
+ lock, lock->magic,
+ owner ? owner->comm : "<none>",
+ owner ? owner->pid : -1,
+ lock->owner_cpu);
+ dump_stack();
+#ifdef CONFIG_SMP
+ /*
+ * We cannot continue on SMP:
+ */
+// panic("bad locking");
+#endif
+ }
+}
+
+#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
+
+static inline void debug_spin_lock_before(spinlock_t *lock)
+{
+ SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
+ SPIN_BUG_ON(lock->owner == current, lock, "recursion");
+ SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
+ lock, "cpu recursion");
+}
+
+static inline void debug_spin_lock_after(spinlock_t *lock)
+{
+ lock->owner_cpu = raw_smp_processor_id();
+ lock->owner = current;
+}
+
+static inline void debug_spin_unlock(spinlock_t *lock)
+{
+ SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
+ SPIN_BUG_ON(!spin_is_locked(lock), lock, "already unlocked");
+ SPIN_BUG_ON(lock->owner != current, lock, "wrong owner");
+ SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
+ lock, "wrong CPU");
+ lock->owner = SPINLOCK_OWNER_INIT;
+ lock->owner_cpu = -1;
+}
+
+static void __spin_lock_debug(spinlock_t *lock)
+{
+ int print_once = 1;
+ u64 i;
+
+ for (;;) {
+ for (i = 0; i < loops_per_jiffy * HZ; i++) {
+ cpu_relax();
+ if (__raw_spin_trylock(&lock->raw_lock))
+ return;
+ }
+ /* lockup suspected: */
+ if (print_once) {
+ print_once = 0;
+ printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n",
+ smp_processor_id(), current->comm, current->pid,
+ lock);
+ dump_stack();
+ }
+ }
+}
+
+void _raw_spin_lock(spinlock_t *lock)
+{
+ debug_spin_lock_before(lock);
+ if (unlikely(!__raw_spin_trylock(&lock->raw_lock)))
+ __spin_lock_debug(lock);
+ debug_spin_lock_after(lock);
+}
+
+int _raw_spin_trylock(spinlock_t *lock)
+{
+ int ret = __raw_spin_trylock(&lock->raw_lock);
+
+ if (ret)
+ debug_spin_lock_after(lock);
+#ifndef CONFIG_SMP
+ /*
+ * Must not happen on UP:
+ */
+ SPIN_BUG_ON(!ret, lock, "trylock failure on UP");
+#endif
+ return ret;
+}
+
+void _raw_spin_unlock(spinlock_t *lock)
+{
+ debug_spin_unlock(lock);
+ __raw_spin_unlock(&lock->raw_lock);
+}
+
+static void rwlock_bug(rwlock_t *lock, const char *msg)
+{
+ static long print_once = 1;
+
+ if (xchg(&print_once, 0)) {
+ printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg,
+ smp_processor_id(), current->comm, current->pid, lock);
+ dump_stack();
+#ifdef CONFIG_SMP
+ /*
+ * We cannot continue on SMP:
+ */
+ panic("bad locking");
+#endif
+ }
+}
+
+#define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg)
+
+static void __read_lock_debug(rwlock_t *lock)
+{
+ int print_once = 1;
+ u64 i;
+
+ for (;;) {
+ for (i = 0; i < loops_per_jiffy * HZ; i++) {
+ cpu_relax();
+ if (__raw_read_trylock(&lock->raw_lock))
+ return;
+ }
+ /* lockup suspected: */
+ if (print_once) {
+ print_once = 0;
+ printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n",
+ smp_processor_id(), current->comm, current->pid,
+ lock);
+ dump_stack();
+ }
+ }
+}
+
+void _raw_read_lock(rwlock_t *lock)
+{
+ RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
+ if (unlikely(!__raw_read_trylock(&lock->raw_lock)))
+ __read_lock_debug(lock);
+}
+
+int _raw_read_trylock(rwlock_t *lock)
+{
+ int ret = __raw_read_trylock(&lock->raw_lock);
+
+#ifndef CONFIG_SMP
+ /*
+ * Must not happen on UP:
+ */
+ RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP");
+#endif
+ return ret;
+}
+
+void _raw_read_unlock(rwlock_t *lock)
+{
+ RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
+ __raw_read_unlock(&lock->raw_lock);
+}
+
+static inline void debug_write_lock_before(rwlock_t *lock)
+{
+ RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
+ RWLOCK_BUG_ON(lock->owner == current, lock, "recursion");
+ RWLOCK_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
+ lock, "cpu recursion");
+}
+
+static inline void debug_write_lock_after(rwlock_t *lock)
+{
+ lock->owner_cpu = raw_smp_processor_id();
+ lock->owner = current;
+}
+
+static inline void debug_write_unlock(rwlock_t *lock)
+{
+ RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
+ RWLOCK_BUG_ON(lock->owner != current, lock, "wrong owner");
+ RWLOCK_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
+ lock, "wrong CPU");
+ lock->owner = SPINLOCK_OWNER_INIT;
+ lock->owner_cpu = -1;
+}
+
+static void __write_lock_debug(rwlock_t *lock)
+{
+ int print_once = 1;
+ u64 i;
+
+ for (;;) {
+ for (i = 0; i < loops_per_jiffy * HZ; i++) {
+ cpu_relax();
+ if (__raw_write_trylock(&lock->raw_lock))
+ return;
+ }
+ /* lockup suspected: */
+ if (print_once) {
+ print_once = 0;
+ printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n",
+ smp_processor_id(), current->comm, current->pid,
+ lock);
+ dump_stack();
+ }
+ }
+}
+
+void _raw_write_lock(rwlock_t *lock)
+{
+ debug_write_lock_before(lock);
+ if (unlikely(!__raw_write_trylock(&lock->raw_lock)))
+ __write_lock_debug(lock);
+ debug_write_lock_after(lock);
+}
+
+int _raw_write_trylock(rwlock_t *lock)
+{
+ int ret = __raw_write_trylock(&lock->raw_lock);
+
+ if (ret)
+ debug_write_lock_after(lock);
+#ifndef CONFIG_SMP
+ /*
+ * Must not happen on UP:
+ */
+ RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP");
+#endif
+ return ret;
+}
+
+void _raw_write_unlock(rwlock_t *lock)
+{
+ debug_write_unlock(lock);
+ __raw_write_unlock(&lock->raw_lock);
+}
diff --git a/lib/textsearch.c b/lib/textsearch.c
index 1e934c196f0f..6f3093efbd7b 100644
--- a/lib/textsearch.c
+++ b/lib/textsearch.c
@@ -254,7 +254,7 @@ unsigned int textsearch_find_continuous(struct ts_config *conf,
* parameters or a ERR_PTR().
*/
struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
- unsigned int len, int gfp_mask, int flags)
+ unsigned int len, gfp_t gfp_mask, int flags)
{
int err = -ENOENT;
struct ts_config *conf;
diff --git a/lib/ts_bm.c b/lib/ts_bm.c
index 2cc79112ecc3..8a8b3a16133e 100644
--- a/lib/ts_bm.c
+++ b/lib/ts_bm.c
@@ -127,7 +127,7 @@ static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern,
}
static struct ts_config *bm_init(const void *pattern, unsigned int len,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct ts_config *conf;
struct ts_bm *bm;
diff --git a/lib/ts_fsm.c b/lib/ts_fsm.c
index d27c0a072940..ca3211206eef 100644
--- a/lib/ts_fsm.c
+++ b/lib/ts_fsm.c
@@ -258,7 +258,7 @@ found_match:
}
static struct ts_config *fsm_init(const void *pattern, unsigned int len,
- int gfp_mask)
+ gfp_t gfp_mask)
{
int i, err = -EINVAL;
struct ts_config *conf;
diff --git a/lib/ts_kmp.c b/lib/ts_kmp.c
index 73266b975585..7fd45451b44a 100644
--- a/lib/ts_kmp.c
+++ b/lib/ts_kmp.c
@@ -87,7 +87,7 @@ static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len,
}
static struct ts_config *kmp_init(const void *pattern, unsigned int len,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct ts_config *conf;
struct ts_kmp *kmp;
diff --git a/mm/Kconfig b/mm/Kconfig
index 4e9937ac3529..391ffc54d136 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -29,7 +29,7 @@ config FLATMEM_MANUAL
If unsure, choose this option (Flat Memory) over any other.
config DISCONTIGMEM_MANUAL
- bool "Discontigious Memory"
+ bool "Discontiguous Memory"
depends on ARCH_DISCONTIGMEM_ENABLE
help
This option provides enhanced support for discontiguous
@@ -52,7 +52,7 @@ config SPARSEMEM_MANUAL
memory hotplug systems. This is normal.
For many other systems, this will be an alternative to
- "Discontigious Memory". This option provides some potential
+ "Discontiguous Memory". This option provides some potential
performance benefits, along with decreased code complexity,
but it is newer, and more experimental.
diff --git a/mm/bootmem.c b/mm/bootmem.c
index c1330cc19783..a58699b6579e 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -154,10 +154,10 @@ static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,
*/
static void * __init
__alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
- unsigned long align, unsigned long goal)
+ unsigned long align, unsigned long goal, unsigned long limit)
{
unsigned long offset, remaining_size, areasize, preferred;
- unsigned long i, start = 0, incr, eidx;
+ unsigned long i, start = 0, incr, eidx, end_pfn = bdata->node_low_pfn;
void *ret;
if(!size) {
@@ -166,7 +166,14 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
}
BUG_ON(align & (align-1));
- eidx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
+ if (limit && bdata->node_boot_start >= limit)
+ return NULL;
+
+ limit >>=PAGE_SHIFT;
+ if (limit && end_pfn > limit)
+ end_pfn = limit;
+
+ eidx = end_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
offset = 0;
if (align &&
(bdata->node_boot_start & (align - 1UL)) != 0)
@@ -178,11 +185,12 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
* first, then we try to allocate lower pages.
*/
if (goal && (goal >= bdata->node_boot_start) &&
- ((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) {
+ ((goal >> PAGE_SHIFT) < end_pfn)) {
preferred = goal - bdata->node_boot_start;
if (bdata->last_success >= preferred)
- preferred = bdata->last_success;
+ if (!limit || (limit && limit > bdata->last_success))
+ preferred = bdata->last_success;
} else
preferred = 0;
@@ -382,14 +390,15 @@ unsigned long __init free_all_bootmem (void)
return(free_all_bootmem_core(NODE_DATA(0)));
}
-void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
+void * __init __alloc_bootmem_limit (unsigned long size, unsigned long align, unsigned long goal,
+ unsigned long limit)
{
pg_data_t *pgdat = pgdat_list;
void *ptr;
for_each_pgdat(pgdat)
if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
- align, goal)))
+ align, goal, limit)))
return(ptr);
/*
@@ -400,14 +409,16 @@ void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned
return NULL;
}
-void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal)
+
+void * __init __alloc_bootmem_node_limit (pg_data_t *pgdat, unsigned long size, unsigned long align,
+ unsigned long goal, unsigned long limit)
{
void *ptr;
- ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal);
+ ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal, limit);
if (ptr)
return (ptr);
- return __alloc_bootmem(size, align, goal);
+ return __alloc_bootmem_limit(size, align, goal, limit);
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 88611928e71f..1c31b2fd2ca5 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -37,6 +37,10 @@
#include <asm/uaccess.h>
#include <asm/mman.h>
+static ssize_t
+generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs);
+
/*
* Shared mappings implemented 30.11.1994. It's not fully working yet,
* though.
@@ -301,8 +305,9 @@ EXPORT_SYMBOL(sync_page_range);
* as it forces O_SYNC writers to different parts of the same file
* to be serialised right until io completion.
*/
-int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
- loff_t pos, size_t count)
+static int sync_page_range_nolock(struct inode *inode,
+ struct address_space *mapping,
+ loff_t pos, size_t count)
{
pgoff_t start = pos >> PAGE_CACHE_SHIFT;
pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
@@ -317,7 +322,6 @@ int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
ret = wait_on_page_writeback_range(mapping, start, end);
return ret;
}
-EXPORT_SYMBOL(sync_page_range_nolock);
/**
* filemap_fdatawait - walk the list of under-writeback pages of the given
@@ -373,7 +377,7 @@ int filemap_write_and_wait_range(struct address_space *mapping,
* This function does not add the page to the LRU. The caller must do that.
*/
int add_to_page_cache(struct page *page, struct address_space *mapping,
- pgoff_t offset, int gfp_mask)
+ pgoff_t offset, gfp_t gfp_mask)
{
int error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
@@ -397,7 +401,7 @@ int add_to_page_cache(struct page *page, struct address_space *mapping,
EXPORT_SYMBOL(add_to_page_cache);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
- pgoff_t offset, int gfp_mask)
+ pgoff_t offset, gfp_t gfp_mask)
{
int ret = add_to_page_cache(page, mapping, offset, gfp_mask);
if (ret == 0)
@@ -587,7 +591,7 @@ EXPORT_SYMBOL(find_lock_page);
* memory exhaustion.
*/
struct page *find_or_create_page(struct address_space *mapping,
- unsigned long index, unsigned int gfp_mask)
+ unsigned long index, gfp_t gfp_mask)
{
struct page *page, *cached_page = NULL;
int err;
@@ -679,7 +683,7 @@ struct page *
grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
{
struct page *page = find_get_page(mapping, index);
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
if (page) {
if (!TestSetPageLocked(page))
@@ -2008,7 +2012,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
}
EXPORT_SYMBOL(generic_file_buffered_write);
-ssize_t
+static ssize_t
__generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos)
{
@@ -2108,7 +2112,7 @@ generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
return ret;
}
-ssize_t
+static ssize_t
__generic_file_write_nolock(struct file *file, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos)
{
@@ -2229,7 +2233,7 @@ EXPORT_SYMBOL(generic_file_writev);
* Called under i_sem for writes to S_ISREG files. Returns -EIO if something
* went wrong during pagecache shootdown.
*/
-ssize_t
+static ssize_t
generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
loff_t offset, unsigned long nr_segs)
{
@@ -2264,4 +2268,3 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
}
return retval;
}
-EXPORT_SYMBOL_GPL(generic_file_direct_IO);
diff --git a/mm/fremap.c b/mm/fremap.c
index 3235fb77c133..ab23a0673c35 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -89,6 +89,9 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (!page->mapping || page->index >= size)
goto err_unlock;
+ err = -ENOMEM;
+ if (page_mapcount(page) > INT_MAX/2)
+ goto err_unlock;
zap_pte(mm, vma, addr, pte);
diff --git a/mm/highmem.c b/mm/highmem.c
index 400911599468..ce2e7e8bbfa7 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -30,11 +30,9 @@
static mempool_t *page_pool, *isa_page_pool;
-static void *page_pool_alloc(unsigned int __nocast gfp_mask, void *data)
+static void *page_pool_alloc_isa(gfp_t gfp_mask, void *data)
{
- unsigned int gfp = gfp_mask | (unsigned int) (long) data;
-
- return alloc_page(gfp);
+ return alloc_page(gfp_mask | GFP_DMA);
}
static void page_pool_free(void *page, void *data)
@@ -51,6 +49,12 @@ static void page_pool_free(void *page, void *data)
* n means that there are (n-1) current users of it.
*/
#ifdef CONFIG_HIGHMEM
+
+static void *page_pool_alloc(gfp_t gfp_mask, void *data)
+{
+ return alloc_page(gfp_mask);
+}
+
static int pkmap_count[LAST_PKMAP];
static unsigned int last_pkmap_nr;
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
@@ -267,7 +271,7 @@ int init_emergency_isa_pool(void)
if (isa_page_pool)
return 0;
- isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc, page_pool_free, (void *) __GFP_DMA);
+ isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc_isa, page_pool_free, NULL);
if (!isa_page_pool)
BUG();
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 901ac523a1c3..61d380678030 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -274,21 +274,22 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
{
pte_t *src_pte, *dst_pte, entry;
struct page *ptepage;
- unsigned long addr = vma->vm_start;
- unsigned long end = vma->vm_end;
+ unsigned long addr;
- while (addr < end) {
+ for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
dst_pte = huge_pte_alloc(dst, addr);
if (!dst_pte)
goto nomem;
+ spin_lock(&src->page_table_lock);
src_pte = huge_pte_offset(src, addr);
- BUG_ON(!src_pte || pte_none(*src_pte)); /* prefaulted */
- entry = *src_pte;
- ptepage = pte_page(entry);
- get_page(ptepage);
- add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
- set_huge_pte_at(dst, addr, dst_pte, entry);
- addr += HPAGE_SIZE;
+ if (src_pte && !pte_none(*src_pte)) {
+ entry = *src_pte;
+ ptepage = pte_page(entry);
+ get_page(ptepage);
+ add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
+ set_huge_pte_at(dst, addr, dst_pte, entry);
+ }
+ spin_unlock(&src->page_table_lock);
}
return 0;
@@ -323,8 +324,8 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
page = pte_page(pte);
put_page(page);
+ add_mm_counter(mm, rss, - (HPAGE_SIZE / PAGE_SIZE));
}
- add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
flush_tlb_range(vma, start, end);
}
@@ -393,6 +394,28 @@ out:
return ret;
}
+/*
+ * On ia64 at least, it is possible to receive a hugetlb fault from a
+ * stale zero entry left in the TLB from earlier hardware prefetching.
+ * Low-level arch code should already have flushed the stale entry as
+ * part of its fault handling, but we do need to accept this minor fault
+ * and return successfully. Whereas the "normal" case is that this is
+ * an access to a hugetlb page which has been truncated off since mmap.
+ */
+int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, int write_access)
+{
+ int ret = VM_FAULT_SIGBUS;
+ pte_t *pte;
+
+ spin_lock(&mm->page_table_lock);
+ pte = huge_pte_offset(mm, address);
+ if (pte && !pte_none(*pte))
+ ret = VM_FAULT_MINOR;
+ spin_unlock(&mm->page_table_lock);
+ return ret;
+}
+
int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
struct page **pages, struct vm_area_struct **vmas,
unsigned long *position, int *length, int i)
@@ -403,6 +426,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
BUG_ON(!is_vm_hugetlb_page(vma));
vpfn = vaddr/PAGE_SIZE;
+ spin_lock(&mm->page_table_lock);
while (vaddr < vma->vm_end && remainder) {
if (pages) {
@@ -415,8 +439,13 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
* indexing below to work. */
pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
- /* hugetlb should be locked, and hence, prefaulted */
- WARN_ON(!pte || pte_none(*pte));
+ /* the hugetlb file might have been truncated */
+ if (!pte || pte_none(*pte)) {
+ remainder = 0;
+ if (!i)
+ i = -EFAULT;
+ break;
+ }
page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
@@ -434,7 +463,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
--remainder;
++i;
}
-
+ spin_unlock(&mm->page_table_lock);
*length = remainder;
*position = vaddr;
diff --git a/mm/madvise.c b/mm/madvise.c
index 4454936f87d1..20e075d1c64c 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -83,6 +83,9 @@ static long madvise_willneed(struct vm_area_struct * vma,
{
struct file *file = vma->vm_file;
+ if (!file)
+ return -EBADF;
+
if (file->f_mapping->a_ops->get_xip_page) {
/* no bad return value, but ignore advice */
return 0;
@@ -141,11 +144,7 @@ static long
madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
unsigned long start, unsigned long end, int behavior)
{
- struct file *filp = vma->vm_file;
- long error = -EBADF;
-
- if (!filp)
- goto out;
+ long error;
switch (behavior) {
case MADV_NORMAL:
@@ -166,8 +165,6 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
error = -EINVAL;
break;
}
-
-out:
return error;
}
diff --git a/mm/memory.c b/mm/memory.c
index 788a62810340..1db40e935e55 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2045,8 +2045,8 @@ int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
inc_page_state(pgfault);
- if (is_vm_hugetlb_page(vma))
- return VM_FAULT_SIGBUS; /* mapping truncation does this. */
+ if (unlikely(is_vm_hugetlb_page(vma)))
+ return hugetlb_fault(mm, vma, address, write_access);
/*
* We need the page table lock to synchronize with kswapd
@@ -2225,7 +2225,7 @@ void update_mem_hiwater(struct task_struct *tsk)
#if !defined(__HAVE_ARCH_GATE_AREA)
#if defined(AT_SYSINFO_EHDR)
-struct vm_area_struct gate_vma;
+static struct vm_area_struct gate_vma;
static int __init gate_vma_init(void)
{
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 13492d66b7c8..1d5c64df1653 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,
};
@@ -333,8 +333,13 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
if (prev && prev->vm_end < vma->vm_start)
return ERR_PTR(-EFAULT);
if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) {
+ unsigned long endvma = vma->vm_end;
+ if (endvma > end)
+ endvma = end;
+ if (vma->vm_start > start)
+ start = vma->vm_start;
err = check_pgd_range(vma->vm_mm,
- vma->vm_start, vma->vm_end, nodes);
+ start, endvma, nodes);
if (err) {
first = ERR_PTR(err);
break;
@@ -682,7 +687,7 @@ get_vma_policy(struct task_struct *task, struct vm_area_struct *vma, unsigned lo
}
/* Return a zonelist representing a mempolicy */
-static struct zonelist *zonelist_policy(unsigned int __nocast gfp, struct mempolicy *policy)
+static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
{
int nd;
@@ -695,7 +700,7 @@ static struct zonelist *zonelist_policy(unsigned int __nocast gfp, struct mempol
case MPOL_BIND:
/* Lower zones don't get a policy applied */
/* Careful: current->mems_allowed might have moved */
- if ((gfp & GFP_ZONEMASK) >= policy_zone)
+ if (gfp_zone(gfp) >= policy_zone)
if (cpuset_zonelist_valid_mems_allowed(policy->v.zonelist))
return policy->v.zonelist;
/*FALL THROUGH*/
@@ -707,7 +712,7 @@ static struct zonelist *zonelist_policy(unsigned int __nocast gfp, struct mempol
nd = 0;
BUG();
}
- return NODE_DATA(nd)->node_zonelists + (gfp & GFP_ZONEMASK);
+ return NODE_DATA(nd)->node_zonelists + gfp_zone(gfp);
}
/* Do dynamic interleaving for a process */
@@ -746,13 +751,13 @@ static unsigned offset_il_node(struct mempolicy *pol,
/* Allocate a page in interleaved policy.
Own path because it needs to do special accounting. */
-static struct page *alloc_page_interleave(unsigned int __nocast gfp, unsigned order, unsigned nid)
+static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, unsigned nid)
{
struct zonelist *zl;
struct page *page;
BUG_ON(!node_online(nid));
- zl = NODE_DATA(nid)->node_zonelists + (gfp & GFP_ZONEMASK);
+ zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp);
page = __alloc_pages(gfp, order, zl);
if (page && page_zone(page) == zl->zones[0]) {
zone_pcp(zl->zones[0],get_cpu())->interleave_hit++;
@@ -784,7 +789,7 @@ static struct page *alloc_page_interleave(unsigned int __nocast gfp, unsigned or
* Should be called with the mm_sem of the vma hold.
*/
struct page *
-alloc_page_vma(unsigned int __nocast gfp, struct vm_area_struct *vma, unsigned long addr)
+alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
{
struct mempolicy *pol = get_vma_policy(current, vma, addr);
@@ -827,7 +832,7 @@ alloc_page_vma(unsigned int __nocast gfp, struct vm_area_struct *vma, unsigned l
* 1) it's ok to take cpuset_sem (can WAIT), and
* 2) allocating for current task (not interrupt).
*/
-struct page *alloc_pages_current(unsigned int __nocast gfp, unsigned order)
+struct page *alloc_pages_current(gfp_t gfp, unsigned order)
{
struct mempolicy *pol = current->mempolicy;
diff --git a/mm/mempool.c b/mm/mempool.c
index 65f2957b8d51..1a99b80480d3 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -112,7 +112,7 @@ EXPORT_SYMBOL(mempool_create_node);
* while this function is running. mempool_alloc() & mempool_free()
* might be called (eg. from IRQ contexts) while this function executes.
*/
-int mempool_resize(mempool_t *pool, int new_min_nr, unsigned int __nocast gfp_mask)
+int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask)
{
void *element;
void **new_elements;
@@ -200,12 +200,12 @@ EXPORT_SYMBOL(mempool_destroy);
* *never* fails when called from process contexts. (it might
* fail if called from an IRQ context.)
*/
-void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask)
+void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask)
{
void *element;
unsigned long flags;
wait_queue_t wait;
- unsigned int gfp_temp;
+ gfp_t gfp_temp;
might_sleep_if(gfp_mask & __GFP_WAIT);
@@ -276,7 +276,7 @@ EXPORT_SYMBOL(mempool_free);
/*
* A commonly used alloc and free fn.
*/
-void *mempool_alloc_slab(unsigned int __nocast gfp_mask, void *pool_data)
+void *mempool_alloc_slab(gfp_t gfp_mask, void *pool_data)
{
kmem_cache_t *mem = (kmem_cache_t *) pool_data;
return kmem_cache_alloc(mem, gfp_mask);
diff --git a/mm/mmap.c b/mm/mmap.c
index 12334aecf8ad..fa11d91242e8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1640,7 +1640,7 @@ static void unmap_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
/*
* Get rid of page table information in the indicated region.
*
- * Called with the page table lock held.
+ * Called with the mm semaphore held.
*/
static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
@@ -1993,6 +1993,9 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
__vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent);
if (__vma && __vma->vm_start < vma->vm_end)
return -ENOMEM;
+ if ((vma->vm_flags & VM_ACCOUNT) &&
+ security_vm_enough_memory(vma_pages(vma)))
+ return -ENOMEM;
vma_link(mm, vma, prev, rb_link, rb_parent);
return 0;
}
diff --git a/mm/mprotect.c b/mm/mprotect.c
index e9fbd013ad9a..57577f63b305 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -248,7 +248,8 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot)
newflags = vm_flags | (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
- if ((newflags & ~(newflags >> 4)) & 0xf) {
+ /* newflags >> 4 shift VM_MAY% in place of VM_% */
+ if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) {
error = -EACCES;
goto out;
}
diff --git a/mm/mremap.c b/mm/mremap.c
index a32fed454bd7..f343fc73a8bd 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -141,10 +141,10 @@ move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
if (dst) {
pte_t pte;
pte = ptep_clear_flush(vma, old_addr, src);
+
/* ZERO_PAGE can be dependant on virtual addr */
- if (pfn_valid(pte_pfn(pte)) &&
- pte_page(pte) == ZERO_PAGE(old_addr))
- pte = pte_wrprotect(mk_pte(ZERO_PAGE(new_addr), new_vma->vm_page_prot));
+ pte = move_pte(pte, new_vma->vm_page_prot,
+ old_addr, new_addr);
set_pte_at(mm, new_addr, dst, pte);
} else
error = -ENOMEM;
diff --git a/mm/nommu.c b/mm/nommu.c
index fd4e8df0f02d..0ef241ae3763 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -57,6 +57,11 @@ DECLARE_RWSEM(nommu_vma_sem);
struct vm_operations_struct generic_file_vm_ops = {
};
+EXPORT_SYMBOL(vmalloc);
+EXPORT_SYMBOL(vfree);
+EXPORT_SYMBOL(vmalloc_to_page);
+EXPORT_SYMBOL(vmalloc_32);
+
/*
* Handle all mappings that got truncated by a "truncate()"
* system call.
@@ -142,6 +147,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
return(i);
}
+EXPORT_SYMBOL(get_user_pages);
+
DEFINE_RWLOCK(vmlist_lock);
struct vm_struct *vmlist;
@@ -150,8 +157,7 @@ void vfree(void *addr)
kfree(addr);
}
-void *__vmalloc(unsigned long size, unsigned int __nocast gfp_mask,
- pgprot_t prot)
+void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
{
/*
* kmalloc doesn't like __GFP_HIGHMEM for some reason
@@ -852,7 +858,7 @@ unsigned long do_mmap_pgoff(struct file *file,
error_getting_vma:
up_write(&nommu_vma_sem);
kfree(vml);
- printk("Allocation of vml for %lu byte allocation from process %d failed\n",
+ printk("Allocation of vma for %lu byte allocation from process %d failed\n",
len, current->pid);
show_free_areas();
return -ENOMEM;
@@ -909,7 +915,7 @@ int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
for (parent = &mm->context.vmlist; *parent; parent = &(*parent)->next)
if ((*parent)->vma->vm_start == addr &&
- (*parent)->vma->vm_end == end)
+ ((len == 0) || ((*parent)->vma->vm_end == end)))
goto found;
printk("munmap of non-mmaped memory by process %d (%s): %p\n",
@@ -1054,7 +1060,8 @@ struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long to, unsigned long size, pgprot_t prot)
{
- return -EPERM;
+ vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
+ return 0;
}
void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
@@ -1073,9 +1080,10 @@ void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
void update_mem_hiwater(struct task_struct *tsk)
{
- unsigned long rss = get_mm_counter(tsk->mm, rss);
+ unsigned long rss;
if (likely(tsk->mm)) {
+ rss = get_mm_counter(tsk->mm, rss);
if (tsk->mm->hiwater_rss < rss)
tsk->mm->hiwater_rss = rss;
if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 5ec8da12cfd9..d348b9035955 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -263,7 +263,7 @@ static struct mm_struct *oom_kill_process(struct task_struct *p)
* OR try to be smart about which process to kill. Note that we
* don't have to be perfect here, we just have to be good.
*/
-void out_of_memory(unsigned int __nocast gfp_mask, int order)
+void out_of_memory(gfp_t gfp_mask, int order)
{
struct mm_struct *mm = NULL;
task_t * p;
@@ -300,6 +300,5 @@ retry:
* Give "p" a good chance of killing itself before we
* retry to allocate memory.
*/
- __set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a6329fa8f862..0166ea15c9ee 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -368,10 +368,8 @@ int wakeup_pdflush(long nr_pages)
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/page_alloc.c b/mm/page_alloc.c
index 3974fd81d27c..94c864eac9c4 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -22,6 +22,7 @@
#include <linux/pagemap.h>
#include <linux/bootmem.h>
#include <linux/compiler.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/pagevec.h>
@@ -117,7 +118,7 @@ static void bad_page(const char *function, struct page *page)
set_page_count(page, 0);
reset_page_mapcount(page);
page->mapping = NULL;
- tainted |= TAINT_BAD_PAGE;
+ add_taint(TAINT_BAD_PAGE);
}
#ifndef CONFIG_HUGETLB_PAGE
@@ -335,7 +336,7 @@ static inline void free_pages_check(const char *function, struct page *page)
/*
* Frees a list of pages.
* Assumes all pages on list are in same zone, and of same order.
- * count is the number of pages to free, or 0 for all on the list.
+ * count is the number of pages to free.
*
* If the zone was previously in an "all pages pinned" state then look to
* see if this freeing clears that state.
@@ -670,7 +671,7 @@ void fastcall free_cold_page(struct page *page)
free_hot_cold_page(page, 1);
}
-static inline void prep_zero_page(struct page *page, int order, unsigned int __nocast gfp_flags)
+static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
{
int i;
@@ -685,7 +686,7 @@ static inline void prep_zero_page(struct page *page, int order, unsigned int __n
* or two.
*/
static struct page *
-buffered_rmqueue(struct zone *zone, int order, unsigned int __nocast gfp_flags)
+buffered_rmqueue(struct zone *zone, int order, gfp_t gfp_flags)
{
unsigned long flags;
struct page *page = NULL;
@@ -733,7 +734,7 @@ buffered_rmqueue(struct zone *zone, int order, unsigned int __nocast gfp_flags)
* of the allocation.
*/
int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
- int classzone_idx, int can_try_harder, int gfp_high)
+ int classzone_idx, int can_try_harder, gfp_t gfp_high)
{
/* free_pages my go negative - that's OK */
long min = mark, free_pages = z->free_pages - (1 << order) + 1;
@@ -760,7 +761,7 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
}
static inline int
-should_reclaim_zone(struct zone *z, unsigned int gfp_mask)
+should_reclaim_zone(struct zone *z, gfp_t gfp_mask)
{
if (!z->reclaim_pages)
return 0;
@@ -773,10 +774,10 @@ should_reclaim_zone(struct zone *z, unsigned int gfp_mask)
* This is the 'heart' of the zoned buddy allocator.
*/
struct page * fastcall
-__alloc_pages(unsigned int __nocast gfp_mask, unsigned int order,
+__alloc_pages(gfp_t gfp_mask, unsigned int order,
struct zonelist *zonelist)
{
- const int wait = gfp_mask & __GFP_WAIT;
+ const gfp_t wait = gfp_mask & __GFP_WAIT;
struct zone **zones, *z;
struct page *page;
struct reclaim_state reclaim_state;
@@ -976,7 +977,7 @@ EXPORT_SYMBOL(__alloc_pages);
/*
* Common helper functions.
*/
-fastcall unsigned long __get_free_pages(unsigned int __nocast gfp_mask, unsigned int order)
+fastcall unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
{
struct page * page;
page = alloc_pages(gfp_mask, order);
@@ -987,7 +988,7 @@ fastcall unsigned long __get_free_pages(unsigned int __nocast gfp_mask, unsigned
EXPORT_SYMBOL(__get_free_pages);
-fastcall unsigned long get_zeroed_page(unsigned int __nocast gfp_mask)
+fastcall unsigned long get_zeroed_page(gfp_t gfp_mask)
{
struct page * page;
@@ -995,7 +996,7 @@ fastcall unsigned long get_zeroed_page(unsigned int __nocast gfp_mask)
* get_zeroed_page() returns a 32-bit address, which cannot represent
* a highmem page
*/
- BUG_ON(gfp_mask & __GFP_HIGHMEM);
+ BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);
page = alloc_pages(gfp_mask | __GFP_ZERO, 0);
if (page)
@@ -1088,7 +1089,7 @@ static unsigned int nr_free_zone_pages(int offset)
*/
unsigned int nr_free_buffer_pages(void)
{
- return nr_free_zone_pages(GFP_USER & GFP_ZONEMASK);
+ return nr_free_zone_pages(gfp_zone(GFP_USER));
}
/*
@@ -1096,7 +1097,7 @@ unsigned int nr_free_buffer_pages(void)
*/
unsigned int nr_free_pagecache_pages(void)
{
- return nr_free_zone_pages(GFP_HIGHUSER & GFP_ZONEMASK);
+ return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER));
}
#ifdef CONFIG_HIGHMEM
@@ -1427,6 +1428,16 @@ static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zoneli
return j;
}
+static inline int highest_zone(int zone_bits)
+{
+ int res = ZONE_NORMAL;
+ if (zone_bits & (__force int)__GFP_HIGHMEM)
+ res = ZONE_HIGHMEM;
+ if (zone_bits & (__force int)__GFP_DMA)
+ res = ZONE_DMA;
+ return res;
+}
+
#ifdef CONFIG_NUMA
#define MAX_NODE_LOAD (num_online_nodes())
static int __initdata node_load[MAX_NUMNODES];
@@ -1523,11 +1534,7 @@ static void __init build_zonelists(pg_data_t *pgdat)
zonelist = pgdat->node_zonelists + i;
for (j = 0; zonelist->zones[j] != NULL; j++);
- k = ZONE_NORMAL;
- if (i & __GFP_HIGHMEM)
- k = ZONE_HIGHMEM;
- if (i & __GFP_DMA)
- k = ZONE_DMA;
+ k = highest_zone(i);
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
zonelist->zones[j] = NULL;
@@ -1548,12 +1555,7 @@ static void __init build_zonelists(pg_data_t *pgdat)
zonelist = pgdat->node_zonelists + i;
j = 0;
- k = ZONE_NORMAL;
- if (i & __GFP_HIGHMEM)
- k = ZONE_HIGHMEM;
- if (i & __GFP_DMA)
- k = ZONE_DMA;
-
+ k = highest_zone(i);
j = build_zonelists_node(pgdat, zonelist, j, k);
/*
* Now we build the zonelist so that it contains the zones
@@ -1749,6 +1751,8 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
{
struct per_cpu_pages *pcp;
+ memset(p, 0, sizeof(*p));
+
pcp = &p->pcp[0]; /* hot */
pcp->count = 0;
pcp->low = 2 * batch;
diff --git a/mm/page_io.c b/mm/page_io.c
index 2e605a19ce57..330e00d6db00 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -19,7 +19,7 @@
#include <linux/writeback.h>
#include <asm/pgtable.h>
-static struct bio *get_swap_bio(unsigned int __nocast gfp_flags, pgoff_t index,
+static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index,
struct page *page, bio_end_io_t end_io)
{
struct bio *bio;
diff --git a/mm/shmem.c b/mm/shmem.c
index db2c9e8d9909..55e04a0734c1 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -85,7 +85,7 @@ enum sgp_type {
static int shmem_getpage(struct inode *inode, unsigned long idx,
struct page **pagep, enum sgp_type sgp, int *type);
-static inline struct page *shmem_dir_alloc(unsigned int gfp_mask)
+static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
{
/*
* The above definition of ENTRIES_PER_PAGE, and the use of
@@ -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);
@@ -897,7 +898,7 @@ struct page *shmem_swapin(struct shmem_inode_info *info, swp_entry_t entry,
}
static struct page *
-shmem_alloc_page(unsigned long gfp, struct shmem_inode_info *info,
+shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
unsigned long idx)
{
struct vm_area_struct pvma;
@@ -920,8 +921,7 @@ shmem_swapin(struct shmem_inode_info *info,swp_entry_t entry,unsigned long idx)
}
static inline struct page *
-shmem_alloc_page(unsigned int __nocast gfp,struct shmem_inode_info *info,
- unsigned long idx)
+shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx)
{
return alloc_page(gfp | __GFP_ZERO);
}
@@ -1607,6 +1607,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 +1625,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 +1754,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 d7c4443991fe..d30423f167a2 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,84 @@ 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) \
- }
-#define list3_data(cachep) \
- (&(cachep)->lists)
+/*
+ * 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 must 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 __always_inline int index_of(const size_t size)
+{
+ if (__builtin_constant_p(size)) {
+ int i = 0;
-/* NUMA: per-node */
-#define list3_data_ptr(cachep, ptr) \
- list3_data(cachep)
+#define CACHE(x) \
+ if (size <=x) \
+ return i; \
+ else \
+ i++;
+#include "linux/kmalloc_sizes.h"
+#undef CACHE
+ {
+ extern void __bad_size(void);
+ __bad_size();
+ }
+ } else
+ BUG();
+ 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;
+}
+
+#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 +373,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 */
@@ -320,7 +386,7 @@ struct kmem_cache_s {
unsigned int gfporder;
/* force GFP flags, e.g. GFP_DMA */
- unsigned int gfpflags;
+ gfp_t gfpflags;
size_t colour; /* cache colouring range */
unsigned int colour_off; /* colour offset */
@@ -349,6 +415,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 +451,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 +470,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 +603,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 +626,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,28 +633,24 @@ EXPORT_SYMBOL(slab_reclaim_pages);
*/
static enum {
NONE,
- PARTIAL,
+ PARTIAL_AC,
+ PARTIAL_L3,
FULL
} g_cpucache_up;
static DEFINE_PER_CPU(struct work_struct, reap_work);
-static void free_block(kmem_cache_t* cachep, void** objpp, int len);
+static void free_block(kmem_cache_t* cachep, void** objpp, int len, int node);
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)
{
return cachep->array[smp_processor_id()];
}
-static inline kmem_cache_t *__find_general_cachep(size_t size,
- unsigned int __nocast gfpflags)
+static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags)
{
struct cache_sizes *csizep = malloc_sizes;
@@ -595,7 +659,7 @@ static inline kmem_cache_t *__find_general_cachep(size_t size,
* kmem_cache_create(), or __kmalloc(), before
* the generic caches are initialized.
*/
- BUG_ON(csizep->cs_cachep == NULL);
+ BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL);
#endif
while (size > csizep->cs_size)
csizep++;
@@ -610,8 +674,7 @@ static inline kmem_cache_t *__find_general_cachep(size_t size,
return csizep->cs_cachep;
}
-kmem_cache_t *kmem_find_general_cachep(size_t size,
- unsigned int __nocast gfpflags)
+kmem_cache_t *kmem_find_general_cachep(size_t size, gfp_t gfpflags)
{
return __find_general_cachep(size, gfpflags);
}
@@ -676,48 +739,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, node);
+ 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;
+ }
- nc = alloc_arraycache(cpu, cachep->limit, cachep->batchcount);
+ 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);
+ }
+
+ /* 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 +907,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, node);
+
+ if (!cpus_empty(mask)) {
+ spin_unlock(&l3->list_lock);
+ goto unlock_cache;
+ }
+
+ if (l3->shared) {
+ free_block(cachep, l3->shared->entry,
+ l3->shared->avail, node);
+ 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 +967,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 +994,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 +1009,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 +1035,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 +1053,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 +1098,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 +1154,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 +1168,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;
}
@@ -902,7 +1183,7 @@ __initcall(cpucache_init);
* did not request dmaable memory, we might get it, but that
* would be relatively rare and ignorable.
*/
-static void *kmem_getpages(kmem_cache_t *cachep, unsigned int __nocast flags, int nodeid)
+static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid)
{
struct page *page;
void *addr;
@@ -1167,6 +1448,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 +1615,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,13 +1717,9 @@ 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);
+ cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u);
cachep->ctor = ctor;
cachep->dtor = dtor;
cachep->name = name;
@@ -1444,11 +1735,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 +1779,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 +1837,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,68 +1875,92 @@ 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)
{
kmem_cache_t *cachep = (kmem_cache_t*)arg;
struct array_cache *ac;
+ int node = numa_node_id();
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[node]->list_lock);
+ free_block(cachep, ac->entry, ac->avail, node);
+ spin_unlock(&cachep->nodelists[node]->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, gfp_t 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)
@@ -1762,7 +2117,7 @@ static void cache_init_objs(kmem_cache_t *cachep,
slabp->free = 0;
}
-static void kmem_flagcheck(kmem_cache_t *cachep, unsigned int flags)
+static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags)
{
if (flags & SLAB_DMA) {
if (!(cachep->gfpflags & GFP_DMA))
@@ -1792,13 +2147,14 @@ static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp)
* Grow (by 1) the number of slabs within a cache. This is called by
* kmem_cache_alloc() when there are no active objs left in a cache.
*/
-static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nodeid)
+static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
{
struct slab *slabp;
void *objp;
size_t offset;
- unsigned int local_flags;
+ gfp_t 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++;
@@ -1995,7 +2354,7 @@ bad:
#define check_slabp(x,y) do { } while(0)
#endif
-static void *cache_alloc_refill(kmem_cache_t *cachep, unsigned int __nocast flags)
+static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
{
int batchcount;
struct kmem_list3 *l3;
@@ -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,11 +2450,11 @@ alloc_done:
goto retry;
}
ac->touched = 1;
- return ac_entry(ac)[--ac->avail];
+ return ac->entry[--ac->avail];
}
static inline void
-cache_alloc_debugcheck_before(kmem_cache_t *cachep, unsigned int __nocast flags)
+cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags)
{
might_sleep_if(flags & __GFP_WAIT);
#if DEBUG
@@ -2103,7 +2465,7 @@ cache_alloc_debugcheck_before(kmem_cache_t *cachep, unsigned int __nocast flags)
#if DEBUG
static void *
cache_alloc_debugcheck_after(kmem_cache_t *cachep,
- unsigned int __nocast flags, void *objp, void *caller)
+ gfp_t flags, void *objp, void *caller)
{
if (!objp)
return objp;
@@ -2146,25 +2508,33 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep,
#define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
#endif
-
-static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
+static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
{
- unsigned long save_flags;
void* objp;
struct array_cache *ac;
- cache_alloc_debugcheck_before(cachep, flags);
-
- local_irq_save(save_flags);
+ check_irq_off();
ac = ac_data(cachep);
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);
}
+ return objp;
+}
+
+static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+{
+ unsigned long save_flags;
+ void* objp;
+
+ cache_alloc_debugcheck_before(cachep, flags);
+
+ local_irq_save(save_flags);
+ objp = ____cache_alloc(cachep, flags);
local_irq_restore(save_flags);
objp = cache_alloc_debugcheck_after(cachep, flags, objp,
__builtin_return_address(0));
@@ -2172,19 +2542,84 @@ 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 free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
+static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
{
- int i;
+ 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);
+ }
- check_spinlock_acquired(cachep);
+ spin_unlock(&l3->list_lock);
+ goto done;
- /* NUMA: move add into loop */
- cachep->lists.free_objects += nr_objects;
+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 node)
+{
+ int i;
+ struct kmem_list3 *l3;
for (i = 0; i < nr_objects; i++) {
void *objp = objpp[i];
@@ -2192,13 +2627,17 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
unsigned int objnr;
slabp = GET_PAGE_SLAB(virt_to_page(objp));
+ l3 = cachep->nodelists[node];
list_del(&slabp->list);
objnr = (objp - slabp->s_mem) / cachep->objsize;
+ check_spinlock_acquired_node(cachep, node);
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 +2645,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 +2669,39 @@ 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;
+ int node = numa_node_id();
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[node];
+ 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, node);
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 +2713,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 +2734,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, nodeid);
+ 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;
}
}
@@ -2311,7 +2785,7 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp)
* Allocate an object from this cache. The flags are only relevant
* if the cache has no available objects.
*/
-void *kmem_cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
+void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags)
{
return __cache_alloc(cachep, flags);
}
@@ -2369,85 +2843,37 @@ 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)
+void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
{
- int loop;
- void *objp;
- struct slab *slabp;
- kmem_bufctl_t next;
+ unsigned long save_flags;
+ void *ptr;
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);
-
- if (page_to_nid(virt_to_page(slabp->s_mem)) == nodeid ||
- loop > 2)
- goto got_slabp;
- }
- spin_unlock_irq(&cachep->spinlock);
+ 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);
+ cache_alloc_debugcheck_before(cachep, flags);
+ local_irq_save(save_flags);
+ if (nodeid == numa_node_id())
+ ptr = ____cache_alloc(cachep, flags);
else
- list_add(&slabp->list, &cachep->lists.slabs_partial);
-
- list3_data(cachep)->free_objects--;
- spin_unlock_irq(&cachep->spinlock);
+ 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);
-void *kmalloc_node(size_t size, unsigned int __nocast flags, int node)
+void *kmalloc_node(size_t size, gfp_t flags, int node)
{
kmem_cache_t *cachep;
@@ -2480,7 +2906,7 @@ EXPORT_SYMBOL(kmalloc_node);
* platforms. For example, on i386, it means that the memory must come
* from the first 16MB.
*/
-void *__kmalloc(size_t size, unsigned int __nocast flags)
+void *__kmalloc(size_t size, gfp_t flags)
{
kmem_cache_t *cachep;
@@ -2513,11 +2939,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;
@@ -2562,7 +2995,7 @@ EXPORT_SYMBOL(kmem_cache_free);
* @size: how many bytes of memory are required.
* @flags: the type of memory to allocate.
*/
-void *kzalloc(size_t size, unsigned int __nocast flags)
+void *kzalloc(size_t size, gfp_t flags)
{
void *ret = kmalloc(size, flags);
if (ret)
@@ -2575,6 +3008,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 +3042,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 +3064,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, node);
+
+ 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 +3134,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 +3144,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, cpu_to_node(i));
+ 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 +3238,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 +3250,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, node);
ac->avail -= tofree;
- memmove(&ac_entry(ac)[0], &ac_entry(ac)[tofree],
+ memmove(ac->entry, &(ac->entry[tofree]),
sizeof(void*)*ac->avail);
}
}
@@ -2789,6 +3271,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 +3292,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 +3330,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 +3370,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 +3405,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 +3463,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 +3474,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 +3559,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;
}
@@ -3097,7 +3601,7 @@ unsigned int ksize(const void *objp)
* @s: the string to duplicate
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
*/
-char *kstrdup(const char *s, unsigned int __nocast gfp)
+char *kstrdup(const char *s, gfp_t gfp)
{
size_t len;
char *buf;
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 029e56eb5e77..132164f7d0a7 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -67,8 +67,8 @@ void show_swap_cache_info(void)
* __add_to_swap_cache resembles add_to_page_cache on swapper_space,
* but sets SwapCache flag and private instead of mapping and index.
*/
-static int __add_to_swap_cache(struct page *page,
- swp_entry_t entry, int gfp_mask)
+static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
+ gfp_t gfp_mask)
{
int error;
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 4b6e8bf986bc..1dcaeda039f4 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1153,8 +1153,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
p->highest_bit = 0; /* cuts scans short */
while (p->flags >= SWP_SCANNING) {
spin_unlock(&swap_lock);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock(&swap_lock);
}
@@ -1382,6 +1381,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
error = bd_claim(bdev, sys_swapon);
if (error < 0) {
bdev = NULL;
+ error = -EINVAL;
goto bad_swap;
}
p->old_block_size = block_size(bdev);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 67b358e57ef6..1150229b6366 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)
{
@@ -394,7 +395,7 @@ void *vmap(struct page **pages, unsigned int count,
EXPORT_SYMBOL(vmap);
-void *__vmalloc_area(struct vm_struct *area, unsigned int __nocast gfp_mask, pgprot_t prot)
+void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
{
struct page **pages;
unsigned int nr_pages, array_size, i;
@@ -445,7 +446,7 @@ fail:
* allocator with @gfp_mask flags. Map them into contiguous
* kernel virtual space, using a pagetable protection of @prot.
*/
-void *__vmalloc(unsigned long size, unsigned int __nocast gfp_mask, pgprot_t prot)
+void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
{
struct vm_struct *area;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index a740778f688d..843c87d1e61f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -70,7 +70,7 @@ struct scan_control {
unsigned int priority;
/* This context's GFP mask */
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
int may_writepage;
@@ -186,7 +186,7 @@ EXPORT_SYMBOL(remove_shrinker);
*
* Returns the number of slab objects which we shrunk.
*/
-static int shrink_slab(unsigned long scanned, unsigned int gfp_mask,
+static int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
unsigned long lru_pages)
{
struct shrinker *shrinker;
@@ -511,10 +511,11 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
* PageDirty _after_ making sure that the page is freeable and
* not in use by anybody. (pagecache + us == 2)
*/
- if (page_count(page) != 2 || PageDirty(page)) {
- write_unlock_irq(&mapping->tree_lock);
- goto keep_locked;
- }
+ if (unlikely(page_count(page) != 2))
+ goto cannot_free;
+ smp_rmb();
+ if (unlikely(PageDirty(page)))
+ goto cannot_free;
#ifdef CONFIG_SWAP
if (PageSwapCache(page)) {
@@ -538,6 +539,10 @@ free_it:
__pagevec_release_nonlru(&freed_pvec);
continue;
+cannot_free:
+ write_unlock_irq(&mapping->tree_lock);
+ goto keep_locked;
+
activate_locked:
SetPageActive(page);
pgactivate++;
@@ -921,7 +926,7 @@ shrink_caches(struct zone **zones, struct scan_control *sc)
* holds filesystem locks which prevent writeout this might not work, and the
* allocation attempt will fail.
*/
-int try_to_free_pages(struct zone **zones, unsigned int gfp_mask)
+int try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
{
int priority;
int ret = 0;
@@ -1258,9 +1263,9 @@ void wakeup_kswapd(struct zone *zone, int order)
pgdat->kswapd_max_order = order;
if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
return;
- if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
+ if (!waitqueue_active(&pgdat->kswapd_wait))
return;
- wake_up_interruptible(&zone->zone_pgdat->kswapd_wait);
+ wake_up_interruptible(&pgdat->kswapd_wait);
}
#ifdef CONFIG_PM
@@ -1333,7 +1338,7 @@ module_init(kswapd_init)
/*
* Try to free up some pages from this zone through reclaim.
*/
-int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order)
+int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
{
struct scan_control sc;
int nr_pages = 1 << order;
diff --git a/net/802/p8022.c b/net/802/p8022.c
index b24817c63ca8..2530f35241cd 100644
--- a/net/802/p8022.c
+++ b/net/802/p8022.c
@@ -56,7 +56,7 @@ struct datalink_proto *register_8022_client(unsigned char type,
void unregister_8022_client(struct datalink_proto *proto)
{
- llc_sap_close(proto->sap);
+ llc_sap_put(proto->sap);
kfree(proto);
}
diff --git a/net/802/psnap.c b/net/802/psnap.c
index ab80b1fab53c..4d638944d933 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -106,7 +106,7 @@ module_init(snap_init);
static void __exit snap_exit(void)
{
- llc_sap_close(snap_sap);
+ llc_sap_put(snap_sap);
}
module_exit(snap_exit);
diff --git a/net/802/tr.c b/net/802/tr.c
index 1bb7dc1b85cd..afd8385c0c9c 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -238,7 +238,7 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev)
return trllc->ethertype;
}
- return ntohs(ETH_P_802_2);
+ return ntohs(ETH_P_TR_802_2);
}
/*
@@ -340,9 +340,10 @@ static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
unsigned int hash, rii_p = 0;
unsigned long flags;
struct rif_cache *entry;
-
+ unsigned char saddr0;
spin_lock_irqsave(&rif_lock, flags);
+ saddr0 = trh->saddr[0];
/*
* Firstly see if the entry exists
@@ -395,7 +396,6 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK);
memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short));
entry->local_ring = 0;
- trh->saddr[0]|=TR_RII; /* put the routing indicator back for tcpdump */
}
else
{
@@ -422,6 +422,7 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
}
entry->last_used=jiffies;
}
+ trh->saddr[0]=saddr0; /* put the routing indicator back for tcpdump */
spin_unlock_irqrestore(&rif_lock, flags);
}
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 145f5cde96cf..b74864889670 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -120,7 +120,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
unsigned short vid;
struct net_device_stats *stats;
unsigned short vlan_TCI;
- unsigned short proto;
+ __be16 proto;
/* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
vlan_TCI = ntohs(vhdr->h_vlan_TCI);
diff --git a/net/Kconfig b/net/Kconfig
index 2bdd5623fdd5..60f6f321bd76 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -140,6 +140,7 @@ config BRIDGE_NETFILTER
If unsure, say N.
+source "net/netfilter/Kconfig"
source "net/ipv4/netfilter/Kconfig"
source "net/ipv6/netfilter/Kconfig"
source "net/decnet/netfilter/Kconfig"
@@ -206,8 +207,6 @@ config NET_PKTGEN
To compile this code as a module, choose M here: the
module will be called pktgen.
-source "net/netfilter/Kconfig"
-
endmenu
endmenu
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 1d31b3a3f1e5..7982656b9c83 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -100,8 +100,7 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,
continue;
if (to->sat_addr.s_net == ATADDR_ANYNET &&
- to->sat_addr.s_node == ATADDR_BCAST &&
- at->src_net == atif->address.s_net)
+ to->sat_addr.s_node == ATADDR_BCAST)
goto found;
if (to->sat_addr.s_net == at->src_net &&
@@ -1443,8 +1442,10 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
else
atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode);
- /* Not ours, so we route the packet via the correct AppleTalk iface */
if (!atif) {
+ /* Not ours, so we route the packet via the correct
+ * AppleTalk iface
+ */
atalk_route_packet(skb, dev, ddp, &ddphv, origlen);
goto out;
}
@@ -1592,9 +1593,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) {
rt = atrtr_find(&usat->sat_addr);
- if (!rt)
- return -ENETUNREACH;
-
dev = rt->dev;
} else {
struct atalk_addr at_hint;
@@ -1603,11 +1601,12 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
at_hint.s_net = at->src_net;
rt = atrtr_find(&at_hint);
- if (!rt)
- return -ENETUNREACH;
-
dev = rt->dev;
}
+ if (!rt)
+ return -ENETUNREACH;
+
+ dev = rt->dev;
SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n",
sk, size, dev->name);
@@ -1677,6 +1676,20 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
/* loop back */
skb_orphan(skb);
+ if (ddp->deh_dnode == ATADDR_BCAST) {
+ struct atalk_addr at_lo;
+
+ at_lo.s_node = 0;
+ at_lo.s_net = 0;
+
+ rt = atrtr_find(&at_lo);
+ if (!rt) {
+ kfree_skb(skb);
+ return -ENETUNREACH;
+ }
+ dev = rt->dev;
+ skb->dev = dev;
+ }
ddp_dl->request(ddp_dl, skb, dev->dev_addr);
} else {
SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
diff --git a/net/atm/addr.c b/net/atm/addr.c
index 1c8867f7f54a..3060fd0ba4b9 100644
--- a/net/atm/addr.c
+++ b/net/atm/addr.c
@@ -44,29 +44,43 @@ static void notify_sigd(struct atm_dev *dev)
sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL);
}
-void atm_reset_addr(struct atm_dev *dev)
+void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t atype)
{
unsigned long flags;
struct atm_dev_addr *this, *p;
+ struct list_head *head;
spin_lock_irqsave(&dev->lock, flags);
- list_for_each_entry_safe(this, p, &dev->local, entry)
- kfree(this);
+ if (atype == ATM_ADDR_LECS)
+ head = &dev->lecs;
+ else
+ head = &dev->local;
+ list_for_each_entry_safe(this, p, head, entry) {
+ list_del(&this->entry);
+ kfree(this);
+ }
spin_unlock_irqrestore(&dev->lock, flags);
- notify_sigd(dev);
+ if (head == &dev->local)
+ notify_sigd(dev);
}
-int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
+int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+ enum atm_addr_type_t atype)
{
unsigned long flags;
struct atm_dev_addr *this;
+ struct list_head *head;
int error;
error = check_addr(addr);
if (error)
return error;
spin_lock_irqsave(&dev->lock, flags);
- list_for_each_entry(this, &dev->local, entry) {
+ if (atype == ATM_ADDR_LECS)
+ head = &dev->lecs;
+ else
+ head = &dev->local;
+ list_for_each_entry(this, head, entry) {
if (identical(&this->addr, addr)) {
spin_unlock_irqrestore(&dev->lock, flags);
return -EEXIST;
@@ -78,28 +92,36 @@ int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
return -ENOMEM;
}
this->addr = *addr;
- list_add(&this->entry, &dev->local);
+ list_add(&this->entry, head);
spin_unlock_irqrestore(&dev->lock, flags);
- notify_sigd(dev);
+ if (head == &dev->local)
+ notify_sigd(dev);
return 0;
}
-int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
+int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+ enum atm_addr_type_t atype)
{
unsigned long flags;
struct atm_dev_addr *this;
+ struct list_head *head;
int error;
error = check_addr(addr);
if (error)
return error;
spin_lock_irqsave(&dev->lock, flags);
- list_for_each_entry(this, &dev->local, entry) {
+ if (atype == ATM_ADDR_LECS)
+ head = &dev->lecs;
+ else
+ head = &dev->local;
+ list_for_each_entry(this, head, entry) {
if (identical(&this->addr, addr)) {
list_del(&this->entry);
spin_unlock_irqrestore(&dev->lock, flags);
kfree(this);
- notify_sigd(dev);
+ if (head == &dev->local)
+ notify_sigd(dev);
return 0;
}
}
@@ -108,22 +130,27 @@ int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
}
int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf,
- size_t size)
+ size_t size, enum atm_addr_type_t atype)
{
unsigned long flags;
struct atm_dev_addr *this;
+ struct list_head *head;
int total = 0, error;
struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
spin_lock_irqsave(&dev->lock, flags);
- list_for_each_entry(this, &dev->local, entry)
+ if (atype == ATM_ADDR_LECS)
+ head = &dev->lecs;
+ else
+ head = &dev->local;
+ list_for_each_entry(this, head, entry)
total += sizeof(struct sockaddr_atmsvc);
tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
if (!tmp_buf) {
spin_unlock_irqrestore(&dev->lock, flags);
return -ENOMEM;
}
- list_for_each_entry(this, &dev->local, entry)
+ list_for_each_entry(this, head, entry)
memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc));
spin_unlock_irqrestore(&dev->lock, flags);
error = total > size ? -E2BIG : total;
diff --git a/net/atm/addr.h b/net/atm/addr.h
index 3099d21feeaa..f39433ad45da 100644
--- a/net/atm/addr.h
+++ b/net/atm/addr.h
@@ -9,10 +9,12 @@
#include <linux/atm.h>
#include <linux/atmdev.h>
-
-void atm_reset_addr(struct atm_dev *dev);
-int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,size_t size);
+void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t type);
+int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+ enum atm_addr_type_t type);
+int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+ enum atm_addr_type_t type);
+int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user *buf,
+ size_t size, enum atm_addr_type_t type);
#endif
diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c
index b2113c3454ae..223c7ad5bd0f 100644
--- a/net/atm/atm_misc.c
+++ b/net/atm/atm_misc.c
@@ -25,7 +25,7 @@ int atm_charge(struct atm_vcc *vcc,int truesize)
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
- int gfp_flags)
+ gfp_t gfp_flags)
{
struct sock *sk = sk_atm(vcc);
int guess = atm_guess_pdu2truesize(pdu_size);
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 289956c4dd3e..72f3f7b8de80 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -220,7 +220,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* netif_stop_queue(dev); */
dev_kfree_skb(skb);
read_unlock(&devs_lock);
- return -EUNATCH;
+ return 0;
}
if (!br2684_xmit_vcc(skb, brdev, brvcc)) {
/*
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 28dab55a4387..4f54c9a5e84a 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -310,7 +310,7 @@ static int clip_constructor(struct neighbour *neigh)
if (neigh->type != RTN_UNICAST) return -EINVAL;
rcu_read_lock();
- in_dev = rcu_dereference(__in_dev_get(dev));
+ in_dev = __in_dev_get_rcu(dev);
if (!in_dev) {
rcu_read_unlock();
return -EINVAL;
diff --git a/net/atm/common.c b/net/atm/common.c
index e93e838069e8..63feea49fb13 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -46,7 +46,7 @@ static void __vcc_insert_socket(struct sock *sk)
struct atm_vcc *vcc = atm_sk(sk);
struct hlist_head *head = &vcc_hash[vcc->vci &
(VCC_HTABLE_SIZE - 1)];
- sk->sk_hashent = vcc->vci & (VCC_HTABLE_SIZE - 1);
+ sk->sk_hash = vcc->vci & (VCC_HTABLE_SIZE - 1);
sk_add_node(sk, head);
}
@@ -178,8 +178,6 @@ static void vcc_destroy_socket(struct sock *sk)
if (vcc->push)
vcc->push(vcc, NULL); /* atmarpd has no push */
- vcc_remove_socket(sk); /* no more receive */
-
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
atm_return(vcc,skb->truesize);
kfree_skb(skb);
@@ -188,6 +186,8 @@ static void vcc_destroy_socket(struct sock *sk)
module_put(vcc->dev->ops->owner);
atm_dev_put(vcc->dev);
}
+
+ vcc_remove_socket(sk);
}
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index d89056ec44d4..a150198b05a3 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -105,17 +105,35 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (!error)
sock->state = SS_CONNECTED;
goto done;
- default:
+ case ATM_SETBACKEND:
+ case ATM_NEWBACKENDIF:
+ {
+ atm_backend_t backend;
+ error = get_user(backend, (atm_backend_t __user *) argp);
+ if (error)
+ goto done;
+ switch (backend) {
+ case ATM_BACKEND_PPP:
+ request_module("pppoatm");
+ break;
+ case ATM_BACKEND_BR2684:
+ request_module("br2684");
+ break;
+ }
+ }
+ break;
+ case ATMMPC_CTRL:
+ case ATMMPC_DATA:
+ request_module("mpoa");
+ break;
+ case ATMARPD_CTRL:
+ request_module("clip");
+ break;
+ case ATMLEC_CTRL:
+ request_module("lec");
break;
}
- if (cmd == ATMMPC_CTRL || cmd == ATMMPC_DATA)
- request_module("mpoa");
- if (cmd == ATMARPD_CTRL)
- request_module("clip");
- if (cmd == ATMLEC_CTRL)
- request_module("lec");
-
error = -ENOIOCTLCMD;
down(&ioctl_mutex);
diff --git a/net/atm/lec.c b/net/atm/lec.c
index a0752487026d..ad840b9afba8 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -686,9 +686,19 @@ static unsigned char lec_ctrl_magic[] = {
0x01,
0x01 };
+#define LEC_DATA_DIRECT_8023 2
+#define LEC_DATA_DIRECT_8025 3
+
+static int lec_is_data_direct(struct atm_vcc *vcc)
+{
+ return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
+ (vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
+}
+
static void
lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
{
+ unsigned long flags;
struct net_device *dev = (struct net_device *)vcc->proto_data;
struct lec_priv *priv = (struct lec_priv *)dev->priv;
@@ -728,7 +738,8 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, skb->len);
} else { /* Data frame, queue to protocol handlers */
- unsigned char *dst;
+ struct lec_arp_table *entry;
+ unsigned char *src, *dst;
atm_return(vcc,skb->truesize);
if (*(uint16_t *)skb->data == htons(priv->lecid) ||
@@ -741,10 +752,30 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
return;
}
#ifdef CONFIG_TR
- if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
+ if (priv->is_trdev)
+ dst = ((struct lecdatahdr_8025 *) skb->data)->h_dest;
else
#endif
- dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
+ dst = ((struct lecdatahdr_8023 *) skb->data)->h_dest;
+
+ /* If this is a Data Direct VCC, and the VCC does not match
+ * the LE_ARP cache entry, delete the LE_ARP cache entry.
+ */
+ spin_lock_irqsave(&priv->lec_arp_lock, flags);
+ if (lec_is_data_direct(vcc)) {
+#ifdef CONFIG_TR
+ if (priv->is_trdev)
+ src = ((struct lecdatahdr_8025 *) skb->data)->h_source;
+ else
+#endif
+ src = ((struct lecdatahdr_8023 *) skb->data)->h_source;
+ entry = lec_arp_find(priv, src);
+ if (entry && entry->vcc != vcc) {
+ lec_arp_remove(priv, entry);
+ kfree(entry);
+ }
+ }
+ spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */
!priv->is_proxy && /* Proxy wants all the packets */
@@ -1990,6 +2021,12 @@ lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find,
found = entry->vcc;
goto out;
}
+ /* If the LE_ARP cache entry is still pending, reset count to 0
+ * so another LE_ARP request can be made for this frame.
+ */
+ if (entry->status == ESI_ARP_PENDING) {
+ entry->no_tries = 0;
+ }
/* Data direct VC not yet set up, check to see if the unknown
frame count is greater than the limit. If the limit has
not been reached, allow the caller to send packet to
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 17a81ebe7e6e..526d9531411f 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -105,7 +105,7 @@ extern void mpc_proc_clean(void);
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/atm/resources.c b/net/atm/resources.c
index a57a9268bd24..415d2615d475 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -40,6 +40,7 @@ static struct atm_dev *__alloc_atm_dev(const char *type)
dev->link_rate = ATM_OC3_PCR;
spin_lock_init(&dev->lock);
INIT_LIST_HEAD(&dev->local);
+ INIT_LIST_HEAD(&dev->lecs);
return dev;
}
@@ -320,10 +321,12 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
error = -EPERM;
goto done;
}
- atm_reset_addr(dev);
+ atm_reset_addr(dev, ATM_ADDR_LOCAL);
break;
case ATM_ADDADDR:
case ATM_DELADDR:
+ case ATM_ADDLECSADDR:
+ case ATM_DELLECSADDR:
if (!capable(CAP_NET_ADMIN)) {
error = -EPERM;
goto done;
@@ -335,14 +338,21 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
error = -EFAULT;
goto done;
}
- if (cmd == ATM_ADDADDR)
- error = atm_add_addr(dev, &addr);
+ if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
+ error = atm_add_addr(dev, &addr,
+ (cmd == ATM_ADDADDR ?
+ ATM_ADDR_LOCAL : ATM_ADDR_LECS));
else
- error = atm_del_addr(dev, &addr);
+ error = atm_del_addr(dev, &addr,
+ (cmd == ATM_DELADDR ?
+ ATM_ADDR_LOCAL : ATM_ADDR_LECS));
goto done;
}
case ATM_GETADDR:
- error = atm_get_addr(dev, buf, len);
+ case ATM_GETLECSADDR:
+ error = atm_get_addr(dev, buf, len,
+ (cmd == ATM_GETADDR ?
+ ATM_ADDR_LOCAL : ATM_ADDR_LECS));
if (error < 0)
goto done;
size = error;
diff --git a/net/atm/signaling.c b/net/atm/signaling.c
index f7c449ac1800..e7211a7f382c 100644
--- a/net/atm/signaling.c
+++ b/net/atm/signaling.c
@@ -217,8 +217,9 @@ void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type,
static void purge_vcc(struct atm_vcc *vcc)
{
if (sk_atm(vcc)->sk_family == PF_ATMSVC &&
- !test_bit(ATM_VF_META,&vcc->flags)) {
- set_bit(ATM_VF_RELEASED,&vcc->flags);
+ !test_bit(ATM_VF_META, &vcc->flags)) {
+ set_bit(ATM_VF_RELEASED, &vcc->flags);
+ clear_bit(ATM_VF_REGIS, &vcc->flags);
vcc_release_async(vcc, -EUNATCH);
}
}
@@ -243,8 +244,7 @@ static void sigd_close(struct atm_vcc *vcc)
sk_for_each(s, node, head) {
struct atm_vcc *vcc = atm_sk(s);
- if (vcc->dev)
- purge_vcc(vcc);
+ purge_vcc(vcc);
}
}
read_unlock(&vcc_sklist_lock);
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 08e46052a3e4..d7b266136bf6 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -302,6 +302,7 @@ static int svc_listen(struct socket *sock,int backlog)
error = -EINVAL;
goto out;
}
+ vcc_insert_socket(sk);
set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index ed705ddad56b..8e37e71e34ff 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1695,16 +1695,12 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
/* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
- res = put_user(amount, (int __user *)argp);
+ res = put_user(amount, (int __user *) argp);
break;
}
case SIOCGSTAMP:
- if (sk != NULL) {
- res = sock_get_timestamp(sk, argp);
- break;
- }
- res = -EINVAL;
+ res = sock_get_timestamp(sk, argp);
break;
case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */
@@ -1951,24 +1947,24 @@ static struct net_proto_family ax25_family_ops = {
};
static struct proto_ops ax25_proto_ops = {
- .family = PF_AX25,
- .owner = THIS_MODULE,
- .release = ax25_release,
- .bind = ax25_bind,
- .connect = ax25_connect,
- .socketpair = sock_no_socketpair,
- .accept = ax25_accept,
- .getname = ax25_getname,
- .poll = datagram_poll,
- .ioctl = ax25_ioctl,
- .listen = ax25_listen,
- .shutdown = ax25_shutdown,
- .setsockopt = ax25_setsockopt,
- .getsockopt = ax25_getsockopt,
- .sendmsg = ax25_sendmsg,
- .recvmsg = ax25_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = sock_no_sendpage,
+ .family = PF_AX25,
+ .owner = THIS_MODULE,
+ .release = ax25_release,
+ .bind = ax25_bind,
+ .connect = ax25_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = ax25_accept,
+ .getname = ax25_getname,
+ .poll = datagram_poll,
+ .ioctl = ax25_ioctl,
+ .listen = ax25_listen,
+ .shutdown = ax25_shutdown,
+ .setsockopt = ax25_setsockopt,
+ .getsockopt = ax25_getsockopt,
+ .sendmsg = ax25_sendmsg,
+ .recvmsg = ax25_recvmsg,
+ .mmap = sock_no_mmap,
+ .sendpage = sock_no_sendpage,
};
/*
@@ -1984,7 +1980,7 @@ static struct notifier_block ax25_dev_notifier = {
.notifier_call =ax25_device_event,
};
-EXPORT_SYMBOL(ax25_encapsulate);
+EXPORT_SYMBOL(ax25_hard_header);
EXPORT_SYMBOL(ax25_rebuild_header);
EXPORT_SYMBOL(ax25_findbyuid);
EXPORT_SYMBOL(ax25_find_cb);
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index dca179daf415..0164a155b8c4 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -67,37 +67,34 @@ char *ax2asc(char *buf, ax25_address *a)
/*
* 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/ax25/ax25_in.c b/net/ax25/ax25_in.c
index 810c9c76c2e0..73cfc3411c46 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -123,7 +123,7 @@ int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
}
skb_pull(skb, 1); /* Remove PID */
- skb->h.raw = skb->data;
+ skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
skb->dev = ax25->ax25_dev->dev;
skb->pkt_type = PACKET_HOST;
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index bba0173e2d65..d643dac3eccc 100644
--- a/net/ax25/ax25_ip.c
+++ b/net/ax25/ax25_ip.c
@@ -47,7 +47,7 @@
#ifdef CONFIG_INET
-int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
+int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
{
unsigned char *buff;
@@ -88,7 +88,7 @@ int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short
*buff++ = AX25_P_ARP;
break;
default:
- printk(KERN_ERR "AX.25: ax25_encapsulate - wrong protocol type 0x%2.2x\n", type);
+ printk(KERN_ERR "AX.25: ax25_hard_header - wrong protocol type 0x%2.2x\n", type);
*buff++ = 0;
break;
}
@@ -209,7 +209,7 @@ put:
#else /* INET */
-int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
+int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
{
return -AX25_HEADER_LEN;
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d6da0939216d..b61b4e8e36fd 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -558,6 +558,35 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
hci_dev_unlock(hdev);
}
+/* Extended Inquiry Result */
+static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct inquiry_data data;
+ struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
+ int num_rsp = *((__u8 *) skb->data);
+
+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+ if (!num_rsp)
+ return;
+
+ hci_dev_lock(hdev);
+
+ for (; num_rsp; num_rsp--) {
+ bacpy(&data.bdaddr, &info->bdaddr);
+ data.pscan_rep_mode = info->pscan_rep_mode;
+ data.pscan_period_mode = info->pscan_period_mode;
+ data.pscan_mode = 0x00;
+ memcpy(data.dev_class, info->dev_class, 3);
+ data.clock_offset = info->clock_offset;
+ data.rssi = info->rssi;
+ info++;
+ hci_inquiry_cache_update(hdev, &data);
+ }
+
+ hci_dev_unlock(hdev);
+}
+
/* Connect Request */
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
@@ -940,6 +969,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_inquiry_result_with_rssi_evt(hdev, skb);
break;
+ case HCI_EV_EXTENDED_INQUIRY_RESULT:
+ hci_extended_inquiry_result_evt(hdev, skb);
+ break;
+
case HCI_EV_CONN_REQUEST:
hci_conn_request_evt(hdev, skb);
break;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index d3d6bc547212..59b2dd36baa7 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -372,7 +372,7 @@ static struct proto l2cap_proto = {
.obj_size = sizeof(struct l2cap_pinfo)
};
-static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, unsigned int __nocast prio)
+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio)
{
struct sock *sk;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 173f46e8cdae..35adce6482b6 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -229,7 +229,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
d->rx_credits = RFCOMM_DEFAULT_CREDITS;
}
-struct rfcomm_dlc *rfcomm_dlc_alloc(unsigned int __nocast prio)
+struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
{
struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
if (!d)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 90e19eb6d3cc..a2b30f0aedb7 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -284,7 +284,7 @@ static struct proto rfcomm_proto = {
.obj_size = sizeof(struct rfcomm_pinfo)
};
-static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, unsigned int __nocast prio)
+static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio)
{
struct rfcomm_dlc *d;
struct sock *sk;
@@ -363,6 +363,11 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
goto done;
}
+ if (sk->sk_type != SOCK_STREAM) {
+ err = -EINVAL;
+ goto done;
+ }
+
write_lock_bh(&rfcomm_sk_list.lock);
if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
@@ -393,13 +398,17 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
return -EINVAL;
- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
- return -EBADFD;
+ lock_sock(sk);
- if (sk->sk_type != SOCK_STREAM)
- return -EINVAL;
+ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
+ err = -EBADFD;
+ goto done;
+ }
- lock_sock(sk);
+ if (sk->sk_type != SOCK_STREAM) {
+ err = -EINVAL;
+ goto done;
+ }
sk->sk_state = BT_CONNECT;
bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
@@ -410,6 +419,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
+done:
release_sock(sk);
return err;
}
@@ -428,6 +438,11 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
goto done;
}
+ if (sk->sk_type != SOCK_STREAM) {
+ err = -EINVAL;
+ goto done;
+ }
+
if (!rfcomm_pi(sk)->channel) {
bdaddr_t *src = &bt_sk(sk)->src;
u8 channel;
@@ -472,6 +487,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
goto done;
}
+ if (sk->sk_type != SOCK_STREAM) {
+ err = -EINVAL;
+ goto done;
+ }
+
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
BT_DBG("sk %p timeo %ld", sk, timeo);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 1bca860a6109..158a9c46d863 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -286,7 +286,7 @@ static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *de
skb->destructor = rfcomm_wfree;
}
-static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, unsigned int __nocast priority)
+static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
{
if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
struct sk_buff *skb = alloc_skb(size, priority);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index ce7ab7dfa0b2..997e42df115c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -418,7 +418,7 @@ static struct proto sco_proto = {
.obj_size = sizeof(struct sco_pinfo)
};
-static struct sock *sco_sock_alloc(struct socket *sock, int proto, unsigned int __nocast prio)
+static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio)
{
struct sock *sk;
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 069253f830c1..2d24fb400e0c 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -31,7 +31,8 @@ static inline int should_deliver(const struct net_bridge_port *p,
int br_dev_queue_push_xmit(struct sk_buff *skb)
{
- if (skb->len > skb->dev->mtu)
+ /* drop mtu oversized packets except tso */
+ if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
kfree_skb(skb);
else {
#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 91bb895375f4..defcf6a8607c 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -79,7 +79,6 @@ static void destroy_nbp(struct net_bridge_port *p)
{
struct net_device *dev = p->dev;
- dev->br_port = NULL;
p->br = NULL;
p->dev = NULL;
dev_put(dev);
@@ -100,6 +99,7 @@ static void del_nbp(struct net_bridge_port *p)
struct net_bridge *br = p->br;
struct net_device *dev = p->dev;
+ dev->br_port = NULL;
dev_set_promiscuity(dev, -1);
spin_lock_bh(&br->lock);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 2d52fee63a8c..d8e36b775125 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -214,9 +214,11 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
.tos = RT_TOS(iph->tos)} }, .proto = 0};
if (!ip_route_output_key(&rt, &fl)) {
- /* Bridged-and-DNAT'ed traffic doesn't
- * require ip_forwarding. */
- if (((struct dst_entry *)rt)->dev == dev) {
+ /* - Bridged-and-DNAT'ed traffic doesn't
+ * require ip_forwarding.
+ * - Deal with redirected traffic. */
+ if (((struct dst_entry *)rt)->dev == dev ||
+ rt->rt_type == RTN_LOCAL) {
skb->dst = (struct dst_entry *)rt;
goto bridged_dnat;
}
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index c4540144f0f4..f8ffbf6e2333 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/smp.h>
+#include <linux/cpumask.h>
#include <net/sock.h>
/* needed for logical [in,out]-dev filtering */
#include "../br_private.h"
@@ -823,10 +824,11 @@ static int translate_table(struct ebt_replace *repl,
/* this will get free'd in do_replace()/ebt_register_table()
if an error occurs */
newinfo->chainstack = (struct ebt_chainstack **)
- vmalloc(num_possible_cpus() * sizeof(struct ebt_chainstack));
+ vmalloc((highest_possible_processor_id()+1)
+ * sizeof(struct ebt_chainstack));
if (!newinfo->chainstack)
return -ENOMEM;
- for (i = 0; i < num_possible_cpus(); i++) {
+ for_each_cpu(i) {
newinfo->chainstack[i] =
vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
if (!newinfo->chainstack[i]) {
@@ -895,9 +897,12 @@ static void get_counters(struct ebt_counter *oldcounters,
/* counters of cpu 0 */
memcpy(counters, oldcounters,
- sizeof(struct ebt_counter) * nentries);
+ sizeof(struct ebt_counter) * nentries);
+
/* add other counters to those of cpu 0 */
- for (cpu = 1; cpu < num_possible_cpus(); cpu++) {
+ for_each_cpu(cpu) {
+ if (cpu == 0)
+ continue;
counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
for (i = 0; i < nentries; i++) {
counters[i].pcnt += counter_base[i].pcnt;
@@ -929,7 +934,8 @@ static int do_replace(void __user *user, unsigned int len)
BUGPRINT("Entries_size never zero\n");
return -EINVAL;
}
- countersize = COUNTER_OFFSET(tmp.nentries) * num_possible_cpus();
+ countersize = COUNTER_OFFSET(tmp.nentries) *
+ (highest_possible_processor_id()+1);
newinfo = (struct ebt_table_info *)
vmalloc(sizeof(struct ebt_table_info) + countersize);
if (!newinfo)
@@ -1022,7 +1028,7 @@ static int do_replace(void __user *user, unsigned int len)
vfree(table->entries);
if (table->chainstack) {
- for (i = 0; i < num_possible_cpus(); i++)
+ for_each_cpu(i)
vfree(table->chainstack[i]);
vfree(table->chainstack);
}
@@ -1040,7 +1046,7 @@ free_counterstmp:
vfree(counterstmp);
/* can be initialized in translate_table() */
if (newinfo->chainstack) {
- for (i = 0; i < num_possible_cpus(); i++)
+ for_each_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
@@ -1132,7 +1138,8 @@ int ebt_register_table(struct ebt_table *table)
return -EINVAL;
}
- countersize = COUNTER_OFFSET(table->table->nentries) * num_possible_cpus();
+ countersize = COUNTER_OFFSET(table->table->nentries) *
+ (highest_possible_processor_id()+1);
newinfo = (struct ebt_table_info *)
vmalloc(sizeof(struct ebt_table_info) + countersize);
ret = -ENOMEM;
@@ -1186,7 +1193,7 @@ free_unlock:
up(&ebt_mutex);
free_chainstack:
if (newinfo->chainstack) {
- for (i = 0; i < num_possible_cpus(); i++)
+ for_each_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
@@ -1209,7 +1216,7 @@ void ebt_unregister_table(struct ebt_table *table)
up(&ebt_mutex);
vfree(table->private->entries);
if (table->private->chainstack) {
- for (i = 0; i < num_possible_cpus(); i++)
+ for_each_cpu(i)
vfree(table->private->chainstack[i]);
vfree(table->private->chainstack);
}
diff --git a/net/compat.c b/net/compat.c
index d99ab9695893..e593dace2fdb 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -135,13 +135,14 @@ static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *ms
* thus placement) of cmsg headers and length are different for
* 32-bit apps. -DaveM
*/
-int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
+int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
unsigned char *stackbuf, int stackbuf_size)
{
struct compat_cmsghdr __user *ucmsg;
struct cmsghdr *kcmsg, *kcmsg_base;
compat_size_t ucmlen;
__kernel_size_t kcmlen, tmp;
+ int err = -EFAULT;
kcmlen = 0;
kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
@@ -156,6 +157,7 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
CMSG_ALIGN(sizeof(struct cmsghdr)));
+ tmp = CMSG_ALIGN(tmp);
kcmlen += tmp;
ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
}
@@ -167,30 +169,34 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
* until we have successfully copied over all of the data
* from the user.
*/
- if(kcmlen > stackbuf_size)
- kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
- if(kcmsg == NULL)
+ if (kcmlen > stackbuf_size)
+ kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
+ if (kcmsg == NULL)
return -ENOBUFS;
/* Now copy them over neatly. */
memset(kcmsg, 0, kcmlen);
ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
while(ucmsg != NULL) {
- __get_user(ucmlen, &ucmsg->cmsg_len);
+ if (__get_user(ucmlen, &ucmsg->cmsg_len))
+ goto Efault;
+ if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
+ goto Einval;
tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
CMSG_ALIGN(sizeof(struct cmsghdr)));
+ if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
+ goto Einval;
kcmsg->cmsg_len = tmp;
- __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
- __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
-
- /* Copy over the data. */
- if(copy_from_user(CMSG_DATA(kcmsg),
- CMSG_COMPAT_DATA(ucmsg),
- (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg)))))
- goto out_free_efault;
+ tmp = CMSG_ALIGN(tmp);
+ if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
+ __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
+ copy_from_user(CMSG_DATA(kcmsg),
+ CMSG_COMPAT_DATA(ucmsg),
+ (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg)))))
+ goto Efault;
/* Advance. */
- kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
+ kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
}
@@ -199,10 +205,12 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
kmsg->msg_controllen = kcmlen;
return 0;
-out_free_efault:
- if(kcmsg_base != (struct cmsghdr *)stackbuf)
- kfree(kcmsg_base);
- return -EFAULT;
+Einval:
+ err = -EINVAL;
+Efault:
+ if (kcmsg_base != (struct cmsghdr *)stackbuf)
+ sock_kfree_s(sk, kcmsg_base, kcmlen);
+ return err;
}
int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
diff --git a/net/core/datagram.c b/net/core/datagram.c
index da9bf71421a7..81987df536eb 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -211,74 +211,45 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
struct iovec *to, int len)
{
- int start = skb_headlen(skb);
- int i, copy = start - offset;
-
- /* Copy header. */
- if (copy > 0) {
- if (copy > len)
- copy = len;
- if (memcpy_toiovec(to, skb->data + offset, copy))
- goto fault;
- if ((len -= copy) == 0)
- return 0;
- offset += copy;
- }
+ int i, err, fraglen, end = 0;
+ struct sk_buff *next = skb_shinfo(skb)->frag_list;
+next_skb:
+ fraglen = skb_headlen(skb);
+ i = -1;
- /* Copy paged appendix. Hmm... why does this look so complicated? */
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- int end;
-
- BUG_TRAP(start <= offset + len);
+ while (1) {
+ int start = end;
- end = start + skb_shinfo(skb)->frags[i].size;
- if ((copy = end - offset) > 0) {
- int err;
- u8 *vaddr;
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- struct page *page = frag->page;
+ if ((end += fraglen) > offset) {
+ int copy = end - offset, o = offset - start;
if (copy > len)
copy = len;
- vaddr = kmap(page);
- err = memcpy_toiovec(to, vaddr + frag->page_offset +
- offset - start, copy);
- kunmap(page);
+ if (i == -1)
+ err = memcpy_toiovec(to, skb->data + o, copy);
+ else {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ struct page *page = frag->page;
+ void *p = kmap(page) + frag->page_offset + o;
+ err = memcpy_toiovec(to, p, copy);
+ kunmap(page);
+ }
if (err)
goto fault;
if (!(len -= copy))
return 0;
offset += copy;
}
- start = end;
+ if (++i >= skb_shinfo(skb)->nr_frags)
+ break;
+ fraglen = skb_shinfo(skb)->frags[i].size;
}
-
- if (skb_shinfo(skb)->frag_list) {
- struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
- for (; list; list = list->next) {
- int end;
-
- BUG_TRAP(start <= offset + len);
-
- end = start + list->len;
- if ((copy = end - offset) > 0) {
- if (copy > len)
- copy = len;
- if (skb_copy_datagram_iovec(list,
- offset - start,
- to, copy))
- goto fault;
- if ((len -= copy) == 0)
- return 0;
- offset += copy;
- }
- start = end;
- }
+ if (next) {
+ skb = next;
+ BUG_ON(skb_shinfo(skb)->frag_list);
+ next = skb->next;
+ goto next_skb;
}
- if (!len)
- return 0;
-
fault:
return -EFAULT;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index c01511e3d0c1..a44eeef24edf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -574,6 +574,8 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
return dev;
}
+EXPORT_SYMBOL(dev_getbyhwaddr);
+
struct net_device *dev_getfirstbyhwtype(unsigned short type)
{
struct net_device *dev;
@@ -1130,7 +1132,7 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
#endif
/* Keep head the same: replace data */
-int __skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp_mask)
+int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
{
unsigned int size;
u8 *data;
@@ -1257,6 +1259,8 @@ int dev_queue_xmit(struct sk_buff *skb)
if (skb_checksum_help(skb, 0))
goto out_kfree_skb;
+ spin_lock_prefetch(&dev->queue_lock);
+
/* Disable soft irqs for various locks below. Also
* stops preemption for RCU.
*/
diff --git a/net/core/dst.c b/net/core/dst.c
index 334790da9f16..470c05bc4cb2 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -39,8 +39,7 @@ static unsigned long dst_gc_timer_inc = DST_GC_MAX;
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/neighbour.c b/net/core/neighbour.c
index 39fc55edf691..e68700f950a5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -61,7 +61,9 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
static struct neigh_table *neigh_tables;
+#ifdef CONFIG_PROC_FS
static struct file_operations neigh_stat_seq_fops;
+#endif
/*
Neighbour hash table buckets are protected with rwlock tbl->lock.
@@ -173,39 +175,10 @@ static void pneigh_queue_purge(struct sk_buff_head *list)
}
}
-void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev)
-{
- int i;
-
- write_lock_bh(&tbl->lock);
-
- for (i=0; i <= tbl->hash_mask; i++) {
- struct neighbour *n, **np;
-
- np = &tbl->hash_buckets[i];
- while ((n = *np) != NULL) {
- if (dev && n->dev != dev) {
- np = &n->next;
- continue;
- }
- *np = n->next;
- write_lock_bh(&n->lock);
- n->dead = 1;
- neigh_del_timer(n);
- write_unlock_bh(&n->lock);
- neigh_release(n);
- }
- }
-
- write_unlock_bh(&tbl->lock);
-}
-
-int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
+static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
{
int i;
- write_lock_bh(&tbl->lock);
-
for (i = 0; i <= tbl->hash_mask; i++) {
struct neighbour *n, **np = &tbl->hash_buckets[i];
@@ -241,7 +214,19 @@ int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
neigh_release(n);
}
}
+}
+
+void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev)
+{
+ write_lock_bh(&tbl->lock);
+ neigh_flush_dev(tbl, dev);
+ write_unlock_bh(&tbl->lock);
+}
+int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
+{
+ write_lock_bh(&tbl->lock);
+ neigh_flush_dev(tbl, dev);
pneigh_ifdown(tbl, dev);
write_unlock_bh(&tbl->lock);
@@ -725,6 +710,14 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
p->ucast_probes + p->app_probes + p->mcast_probes);
}
+static inline void neigh_add_timer(struct neighbour *n, unsigned long when)
+{
+ if (unlikely(mod_timer(&n->timer, when))) {
+ printk("NEIGH: BUG, double timer add, state is %x\n",
+ n->nud_state);
+ dump_stack();
+ }
+}
/* Called when a timer expires for a neighbour entry. */
@@ -806,11 +799,10 @@ static void neigh_timer_handler(unsigned long arg)
}
if (neigh->nud_state & NUD_IN_TIMER) {
- neigh_hold(neigh);
if (time_before(next, jiffies + HZ/2))
next = jiffies + HZ/2;
- neigh->timer.expires = next;
- add_timer(&neigh->timer);
+ if (!mod_timer(&neigh->timer, next))
+ neigh_hold(neigh);
}
if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
struct sk_buff *skb = skb_peek(&neigh->arp_queue);
@@ -852,8 +844,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
atomic_set(&neigh->probes, neigh->parms->ucast_probes);
neigh->nud_state = NUD_INCOMPLETE;
neigh_hold(neigh);
- neigh->timer.expires = now + 1;
- add_timer(&neigh->timer);
+ neigh_add_timer(neigh, now + 1);
} else {
neigh->nud_state = NUD_FAILED;
write_unlock_bh(&neigh->lock);
@@ -866,8 +857,8 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
neigh_hold(neigh);
neigh->nud_state = NUD_DELAY;
- neigh->timer.expires = jiffies + neigh->parms->delay_probe_time;
- add_timer(&neigh->timer);
+ neigh_add_timer(neigh,
+ jiffies + neigh->parms->delay_probe_time);
}
if (neigh->nud_state == NUD_INCOMPLETE) {
@@ -1013,10 +1004,10 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
neigh_del_timer(neigh);
if (new & NUD_IN_TIMER) {
neigh_hold(neigh);
- neigh->timer.expires = jiffies +
+ neigh_add_timer(neigh, (jiffies +
((new & NUD_REACHABLE) ?
- neigh->parms->reachable_time : 0);
- add_timer(&neigh->timer);
+ neigh->parms->reachable_time :
+ 0)));
}
neigh->nud_state = new;
}
@@ -1634,12 +1625,9 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
memset(&ndst, 0, sizeof(ndst));
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ for_each_cpu(cpu) {
struct neigh_statistics *st;
- if (!cpu_possible(cpu))
- continue;
-
st = per_cpu_ptr(tbl->stats, cpu);
ndst.ndts_allocs += st->allocs;
ndst.ndts_destroys += st->destroys;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a1a9a7abff50..802fe11efad0 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;
@@ -703,7 +703,7 @@ int netpoll_setup(struct netpoll *np)
if (!np->local_ip) {
rcu_read_lock();
- in_dev = __in_dev_get(ndev);
+ in_dev = __in_dev_get_rcu(ndev);
if (!in_dev || !in_dev->ifa_list) {
rcu_read_unlock();
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 8eb083b6041a..7fc3e9e28c34 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -75,7 +75,7 @@
* By design there should only be *one* "controlling" process. In practice
* multiple write accesses gives unpredictable result. Understood by "write"
* to /proc gives result code thats should be read be the "writer".
- * For pratical use this should be no problem.
+ * For practical use this should be no problem.
*
* Note when adding devices to a specific CPU there good idea to also assign
* /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU.
@@ -96,7 +96,7 @@
* New xmit() return, do_div and misc clean up by Stephen Hemminger
* <shemminger@osdl.org> 040923
*
- * Rany Dunlap fixed u64 printk compiler waring
+ * Randy Dunlap fixed u64 printk compiler waring
*
* Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org>
* New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
@@ -137,6 +137,7 @@
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/wait.h>
#include <net/checksum.h>
#include <net/ipv6.h>
@@ -151,7 +152,7 @@
#include <asm/timex.h>
-#define VERSION "pktgen v2.62: Packet Generator for packet performance testing.\n"
+#define VERSION "pktgen v2.63: Packet Generator for packet performance testing.\n"
/* #define PG_DEBUG(a) a */
#define PG_DEBUG(a)
@@ -177,8 +178,8 @@
#define T_REMDEV (1<<3) /* Remove all devs */
/* Locks */
-#define thread_lock() spin_lock(&_thread_lock)
-#define thread_unlock() spin_unlock(&_thread_lock)
+#define thread_lock() down(&pktgen_sem)
+#define thread_unlock() up(&pktgen_sem)
/* If lock -- can be removed after some work */
#define if_lock(t) spin_lock(&(t->if_lock));
@@ -187,6 +188,8 @@
/* Used to help with determining the pkts on receive */
#define PKTGEN_MAGIC 0xbe9be955
#define PG_PROC_DIR "pktgen"
+#define PGCTRL "pgctrl"
+static struct proc_dir_entry *pg_proc_dir = NULL;
#define MAX_CFLOWS 65536
@@ -202,11 +205,8 @@ struct pktgen_dev {
* Try to keep frequent/infrequent used vars. separated.
*/
- char ifname[32];
- struct proc_dir_entry *proc_ent;
+ char ifname[IFNAMSIZ];
char result[512];
- /* proc file names */
- char fname[80];
struct pktgen_thread* pg_thread; /* the owner */
struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
@@ -244,7 +244,7 @@ struct pktgen_dev {
__u32 seq_num;
int clone_skb; /* Use multiple SKBs during packet gen. If this number
- * is greater than 1, then that many coppies of the same
+ * is greater than 1, then that many copies of the same
* packet will be sent before a new packet is allocated.
* For instance, if you want to send 1024 identical packets
* before creating a new packet, set clone_skb to 1024.
@@ -330,8 +330,6 @@ struct pktgen_thread {
struct pktgen_dev *if_list; /* All device here */
struct pktgen_thread* next;
char name[32];
- char fname[128]; /* name of proc file */
- struct proc_dir_entry *proc_ent;
char result[512];
u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
@@ -396,7 +394,7 @@ static inline s64 divremdi3(s64 x, s64 y, int type)
/* End of hacks to deal with 64-bit math on x86 */
-/** Convert to miliseconds */
+/** Convert to milliseconds */
static inline __u64 tv_to_ms(const struct timeval* tv)
{
__u64 ms = tv->tv_usec / 1000;
@@ -425,7 +423,7 @@ static inline __u64 pg_div64(__u64 n, __u64 base)
{
__u64 tmp = n;
/*
- * How do we know if the architectrure we are running on
+ * How do we know if the architecture we are running on
* supports division with 64 bit base?
*
*/
@@ -473,16 +471,6 @@ static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b)
static char version[] __initdata = VERSION;
-static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos);
-static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos);
-static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
-
-static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
-static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
-static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
-static int create_proc_dir(void);
-static int remove_proc_dir(void);
-
static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
static struct pktgen_thread* pktgen_find_thread(const char* name);
@@ -503,83 +491,41 @@ 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 DECLARE_MUTEX(pktgen_sem);
static struct pktgen_thread *pktgen_threads = NULL;
-static char module_fname[128];
-static struct proc_dir_entry *module_proc_ent = NULL;
-
static struct notifier_block pktgen_notifier_block = {
.notifier_call = pktgen_device_event,
};
-static struct file_operations pktgen_fops = {
- .read = proc_pgctrl_read,
- .write = proc_pgctrl_write,
- /* .ioctl = pktgen_ioctl, later maybe */
-};
-
/*
* /proc handling functions
*
*/
-static struct proc_dir_entry *pg_proc_dir = NULL;
-static int proc_pgctrl_read_eof=0;
-
-static ssize_t proc_pgctrl_read(struct file* file, char __user * buf,
- size_t count, loff_t *ppos)
+static int pgctrl_show(struct seq_file *seq, void *v)
{
- char data[200];
- int len = 0;
-
- if(proc_pgctrl_read_eof) {
- proc_pgctrl_read_eof=0;
- len = 0;
- goto out;
- }
-
- sprintf(data, "%s", VERSION);
-
- len = strlen(data);
-
- if(len > count) {
- len =-EFAULT;
- goto out;
- }
-
- if (copy_to_user(buf, data, len)) {
- len =-EFAULT;
- goto out;
- }
-
- *ppos += len;
- proc_pgctrl_read_eof=1; /* EOF next call */
-
- out:
- return len;
+ seq_puts(seq, VERSION);
+ return 0;
}
-static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
- size_t count, loff_t *ppos)
+static ssize_t pgctrl_write(struct file* file,const char __user * buf,
+ size_t count, loff_t *ppos)
{
- char *data = NULL;
int err = 0;
+ char data[128];
if (!capable(CAP_NET_ADMIN)){
err = -EPERM;
goto out;
}
- data = (void*)vmalloc ((unsigned int)count);
+ if (count > sizeof(data))
+ count = sizeof(data);
- if(!data) {
- err = -ENOMEM;
- goto out;
- }
if (copy_from_user(data, buf, count)) {
- err =-EFAULT;
- goto out_free;
+ err = -EFAULT;
+ goto out;
}
data[count-1] = 0; /* Make string */
@@ -594,31 +540,40 @@ static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
err = count;
- out_free:
- vfree (data);
out:
return err;
}
-static int proc_if_read(char *buf , char **start, off_t offset,
- int len, int *eof, void *data)
+static int pgctrl_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pgctrl_show, PDE(inode)->data);
+}
+
+static struct file_operations pktgen_fops = {
+ .owner = THIS_MODULE,
+ .open = pgctrl_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = pgctrl_write,
+ .release = single_release,
+};
+
+static int pktgen_if_show(struct seq_file *seq, void *v)
{
- char *p;
int i;
- struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+ struct pktgen_dev *pkt_dev = seq->private;
__u64 sa;
__u64 stopped;
__u64 now = getCurUs();
- p = buf;
- p += sprintf(p, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
- (unsigned long long) pkt_dev->count,
- pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
+ seq_printf(seq, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
+ (unsigned long long) pkt_dev->count,
+ pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
- p += sprintf(p, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
- pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
+ seq_printf(seq, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
+ pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
- p += sprintf(p, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
+ seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
if(pkt_dev->flags & F_IPV6) {
@@ -626,19 +581,19 @@ static int proc_if_read(char *buf , char **start, off_t offset,
fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
- p += sprintf(p, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
+ seq_printf(seq, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
- p += sprintf(p, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
+ seq_printf(seq, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
}
else
- p += sprintf(p, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
- pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
+ seq_printf(seq," dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
+ pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
- p += sprintf(p, " src_mac: ");
+ seq_puts(seq, " src_mac: ");
if ((pkt_dev->src_mac[0] == 0) &&
(pkt_dev->src_mac[1] == 0) &&
@@ -648,89 +603,89 @@ static int proc_if_read(char *buf , char **start, off_t offset,
(pkt_dev->src_mac[5] == 0))
for (i = 0; i < 6; i++)
- p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
+ seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
else
for (i = 0; i < 6; i++)
- p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
+ seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
- p += sprintf(p, "dst_mac: ");
+ seq_printf(seq, "dst_mac: ");
for (i = 0; i < 6; i++)
- p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
+ seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
- p += sprintf(p, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
- pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
- pkt_dev->udp_dst_max);
+ seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
+ pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
+ pkt_dev->udp_dst_max);
- p += sprintf(p, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
- pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
+ seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
+ pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
if (pkt_dev->flags & F_IPV6)
- p += sprintf(p, "IPV6 ");
+ seq_printf(seq, "IPV6 ");
if (pkt_dev->flags & F_IPSRC_RND)
- p += sprintf(p, "IPSRC_RND ");
+ seq_printf(seq, "IPSRC_RND ");
if (pkt_dev->flags & F_IPDST_RND)
- p += sprintf(p, "IPDST_RND ");
+ seq_printf(seq, "IPDST_RND ");
if (pkt_dev->flags & F_TXSIZE_RND)
- p += sprintf(p, "TXSIZE_RND ");
+ seq_printf(seq, "TXSIZE_RND ");
if (pkt_dev->flags & F_UDPSRC_RND)
- p += sprintf(p, "UDPSRC_RND ");
+ seq_printf(seq, "UDPSRC_RND ");
if (pkt_dev->flags & F_UDPDST_RND)
- p += sprintf(p, "UDPDST_RND ");
+ seq_printf(seq, "UDPDST_RND ");
if (pkt_dev->flags & F_MACSRC_RND)
- p += sprintf(p, "MACSRC_RND ");
+ seq_printf(seq, "MACSRC_RND ");
if (pkt_dev->flags & F_MACDST_RND)
- p += sprintf(p, "MACDST_RND ");
+ seq_printf(seq, "MACDST_RND ");
- p += sprintf(p, "\n");
+ seq_puts(seq, "\n");
sa = pkt_dev->started_at;
stopped = pkt_dev->stopped_at;
if (pkt_dev->running)
stopped = now; /* not really stopped, more like last-running-at */
- p += sprintf(p, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
- (unsigned long long) pkt_dev->sofar,
- (unsigned long long) pkt_dev->errors,
- (unsigned long long) sa,
- (unsigned long long) stopped,
- (unsigned long long) pkt_dev->idle_acc);
+ seq_printf(seq, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
+ (unsigned long long) pkt_dev->sofar,
+ (unsigned long long) pkt_dev->errors,
+ (unsigned long long) sa,
+ (unsigned long long) stopped,
+ (unsigned long long) pkt_dev->idle_acc);
- p += sprintf(p, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
- pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset);
+ seq_printf(seq, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
+ pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset,
+ pkt_dev->cur_src_mac_offset);
if(pkt_dev->flags & F_IPV6) {
char b1[128], b2[128];
fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
- p += sprintf(p, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
+ seq_printf(seq, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
}
else
- p += sprintf(p, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
- pkt_dev->cur_saddr, pkt_dev->cur_daddr);
+ seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
+ pkt_dev->cur_saddr, pkt_dev->cur_daddr);
- p += sprintf(p, " cur_udp_dst: %d cur_udp_src: %d\n",
- pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
+ seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
+ pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
- p += sprintf(p, " flows: %u\n", pkt_dev->nflows);
+ seq_printf(seq, " flows: %u\n", pkt_dev->nflows);
if (pkt_dev->result[0])
- p += sprintf(p, "Result: %s\n", pkt_dev->result);
+ seq_printf(seq, "Result: %s\n", pkt_dev->result);
else
- p += sprintf(p, "Result: Idle\n");
- *eof = 1;
+ seq_printf(seq, "Result: Idle\n");
- return p - buf;
+ return 0;
}
@@ -802,13 +757,14 @@ done_str:
return i;
}
-static int proc_if_write(struct file *file, const char __user *user_buffer,
- unsigned long count, void *data)
+static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer,
+ size_t count, loff_t *offset)
{
+ struct seq_file *seq = (struct seq_file *) file->private_data;
+ struct pktgen_dev *pkt_dev = seq->private;
int i = 0, max, len;
char name[16], valstr[32];
unsigned long value = 0;
- struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
char* pg_result = NULL;
int tmp = 0;
char buf[128];
@@ -849,7 +805,8 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
if (copy_from_user(tb, user_buffer, count))
return -EFAULT;
tb[count] = 0;
- printk("pktgen: %s,%lu buffer -:%s:-\n", name, count, tb);
+ printk("pktgen: %s,%lu buffer -:%s:-\n", name,
+ (unsigned long) count, tb);
}
if (!strcmp(name, "min_pkt_size")) {
@@ -1335,92 +1292,98 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
return -EINVAL;
}
-static int proc_thread_read(char *buf , char **start, off_t offset,
- int len, int *eof, void *data)
+static int pktgen_if_open(struct inode *inode, struct file *file)
{
- char *p;
- struct pktgen_thread *t = (struct pktgen_thread*)(data);
- struct pktgen_dev *pkt_dev = NULL;
+ return single_open(file, pktgen_if_show, PDE(inode)->data);
+}
+static struct file_operations pktgen_if_fops = {
+ .owner = THIS_MODULE,
+ .open = pktgen_if_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = pktgen_if_write,
+ .release = single_release,
+};
- if (!t) {
- printk("pktgen: ERROR: could not find thread in proc_thread_read\n");
- return -EINVAL;
- }
+static int pktgen_thread_show(struct seq_file *seq, void *v)
+{
+ struct pktgen_thread *t = seq->private;
+ struct pktgen_dev *pkt_dev = NULL;
- p = buf;
- p += sprintf(p, "Name: %s max_before_softirq: %d\n",
+ BUG_ON(!t);
+
+ seq_printf(seq, "Name: %s max_before_softirq: %d\n",
t->name, t->max_before_softirq);
- p += sprintf(p, "Running: ");
+ seq_printf(seq, "Running: ");
if_lock(t);
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
if(pkt_dev->running)
- p += sprintf(p, "%s ", pkt_dev->ifname);
+ seq_printf(seq, "%s ", pkt_dev->ifname);
- p += sprintf(p, "\nStopped: ");
+ seq_printf(seq, "\nStopped: ");
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
if(!pkt_dev->running)
- p += sprintf(p, "%s ", pkt_dev->ifname);
+ seq_printf(seq, "%s ", pkt_dev->ifname);
if (t->result[0])
- p += sprintf(p, "\nResult: %s\n", t->result);
+ seq_printf(seq, "\nResult: %s\n", t->result);
else
- p += sprintf(p, "\nResult: NA\n");
-
- *eof = 1;
+ seq_printf(seq, "\nResult: NA\n");
if_unlock(t);
- return p - buf;
+ return 0;
}
-static int proc_thread_write(struct file *file, const char __user *user_buffer,
- unsigned long count, void *data)
+static ssize_t pktgen_thread_write(struct file *file,
+ const char __user *user_buffer,
+ size_t count, loff_t *offset)
{
+ struct seq_file *seq = (struct seq_file *) file->private_data;
+ struct pktgen_thread *t = seq->private;
int i = 0, max, len, ret;
char name[40];
- struct pktgen_thread *t;
char *pg_result;
unsigned long value = 0;
-
+
if (count < 1) {
// sprintf(pg_result, "Wrong command format");
return -EINVAL;
}
-
+
max = count - i;
len = count_trail_chars(&user_buffer[i], max);
- if (len < 0)
- return len;
-
+ if (len < 0)
+ return len;
+
i += len;
-
+
/* Read variable name */
len = strn_len(&user_buffer[i], sizeof(name) - 1);
- if (len < 0)
- return len;
+ if (len < 0)
+ return len;
memset(name, 0, sizeof(name));
if (copy_from_user(name, &user_buffer[i], len))
return -EFAULT;
i += len;
-
+
max = count -i;
len = count_trail_chars(&user_buffer[i], max);
- if (len < 0)
- return len;
-
+ if (len < 0)
+ return len;
+
i += len;
- if (debug)
- printk("pktgen: t=%s, count=%lu\n", name, count);
-
+ if (debug)
+ printk("pktgen: t=%s, count=%lu\n", name,
+ (unsigned long) count);
- t = (struct pktgen_thread*)(data);
if(!t) {
printk("pktgen: ERROR: No thread\n");
ret = -EINVAL;
@@ -1452,8 +1415,7 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer,
thread_lock();
t->control |= T_REMDEV;
thread_unlock();
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/8); /* Propagate thread->control */
+ schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */
ret = count;
sprintf(pg_result, "OK: rem_device_all");
goto out;
@@ -1475,32 +1437,19 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer,
return ret;
}
-static int create_proc_dir(void)
+static int pktgen_thread_open(struct inode *inode, struct file *file)
{
- int len;
- /* does proc_dir already exists */
- len = strlen(PG_PROC_DIR);
-
- for (pg_proc_dir = proc_net->subdir; pg_proc_dir; pg_proc_dir=pg_proc_dir->next) {
- if ((pg_proc_dir->namelen == len) &&
- (! memcmp(pg_proc_dir->name, PG_PROC_DIR, len)))
- break;
- }
-
- if (!pg_proc_dir)
- pg_proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net);
-
- if (!pg_proc_dir)
- return -ENODEV;
-
- return 0;
+ return single_open(file, pktgen_thread_show, PDE(inode)->data);
}
-static int remove_proc_dir(void)
-{
- remove_proc_entry(PG_PROC_DIR, proc_net);
- return 0;
-}
+static struct file_operations pktgen_thread_fops = {
+ .owner = THIS_MODULE,
+ .open = pktgen_thread_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = pktgen_thread_write,
+ .release = single_release,
+};
/* Think find or remove for NN */
static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove)
@@ -1679,13 +1628,12 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
struct in_device *in_dev;
rcu_read_lock();
- in_dev = __in_dev_get(pkt_dev->odev);
+ in_dev = __in_dev_get_rcu(pkt_dev->odev);
if (in_dev) {
if (in_dev->ifa_list) {
pkt_dev->saddr_min = in_dev->ifa_list->ifa_address;
pkt_dev->saddr_max = pkt_dev->saddr_min;
}
- __in_dev_put(in_dev);
}
rcu_read_unlock();
}
@@ -1715,11 +1663,10 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
start = now = getCurUs();
printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
while (now < spin_until_us) {
- /* TODO: optimise sleeping behavior */
- if (spin_until_us - now > (1000000/HZ)+1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- } else if (spin_until_us - now > 100) {
+ /* TODO: optimize sleeping behavior */
+ if (spin_until_us - now > jiffies_to_usecs(1)+1)
+ schedule_timeout_interruptible(1);
+ else if (spin_until_us - now > 100) {
do_softirq();
if (!pkt_dev->running)
return;
@@ -2375,7 +2322,7 @@ static void pktgen_stop_all_threads_ifs(void)
pktgen_stop(t);
t = t->next;
}
- thread_unlock();
+ thread_unlock();
}
static int thread_is_running(struct pktgen_thread *t )
@@ -2449,8 +2396,7 @@ static void pktgen_run_all_threads(void)
}
thread_unlock();
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/8); /* Propagate thread->control */
+ schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */
pktgen_wait_all_threads_run();
}
@@ -2567,10 +2513,9 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
struct pktgen_thread *tmp = pktgen_threads;
- if (strlen(t->fname))
- remove_proc_entry(t->fname, NULL);
+ remove_proc_entry(t->name, pg_proc_dir);
- thread_lock();
+ thread_lock();
if (tmp == t)
pktgen_threads = tmp->next;
@@ -2840,7 +2785,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* i
if_lock(t);
for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
- if (strcmp(pkt_dev->ifname, ifname) == 0) {
+ if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
break;
}
}
@@ -2879,74 +2824,70 @@ static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev
static int pktgen_add_device(struct pktgen_thread *t, const char* ifname)
{
struct pktgen_dev *pkt_dev;
+ struct proc_dir_entry *pe;
/* We don't allow a device to be on several threads */
- if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) {
-
- pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
- if (!pkt_dev)
- return -ENOMEM;
+ pkt_dev = __pktgen_NN_threads(ifname, FIND);
+ if (pkt_dev) {
+ printk("pktgen: ERROR: interface already used.\n");
+ return -EBUSY;
+ }
- memset(pkt_dev, 0, sizeof(struct pktgen_dev));
+ pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
+ if (!pkt_dev)
+ return -ENOMEM;
- pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
- if (pkt_dev->flows == NULL) {
- kfree(pkt_dev);
- return -ENOMEM;
- }
- memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
-
- pkt_dev->min_pkt_size = ETH_ZLEN;
- pkt_dev->max_pkt_size = ETH_ZLEN;
- pkt_dev->nfrags = 0;
- pkt_dev->clone_skb = pg_clone_skb_d;
- pkt_dev->delay_us = pg_delay_d / 1000;
- pkt_dev->delay_ns = pg_delay_d % 1000;
- pkt_dev->count = pg_count_d;
- pkt_dev->sofar = 0;
- pkt_dev->udp_src_min = 9; /* sink port */
- pkt_dev->udp_src_max = 9;
- pkt_dev->udp_dst_min = 9;
- pkt_dev->udp_dst_max = 9;
-
- strncpy(pkt_dev->ifname, ifname, 31);
- sprintf(pkt_dev->fname, "net/%s/%s", PG_PROC_DIR, ifname);
-
- if (! pktgen_setup_dev(pkt_dev)) {
- printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
- if (pkt_dev->flows)
- vfree(pkt_dev->flows);
- kfree(pkt_dev);
- return -ENODEV;
- }
+ pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
+ if (pkt_dev->flows == NULL) {
+ kfree(pkt_dev);
+ return -ENOMEM;
+ }
+ memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
- pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL);
- if (!pkt_dev->proc_ent) {
- printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname);
- if (pkt_dev->flows)
- vfree(pkt_dev->flows);
- kfree(pkt_dev);
- return -EINVAL;
- }
- pkt_dev->proc_ent->read_proc = proc_if_read;
- pkt_dev->proc_ent->write_proc = proc_if_write;
- pkt_dev->proc_ent->data = (void*)(pkt_dev);
- pkt_dev->proc_ent->owner = THIS_MODULE;
+ pkt_dev->min_pkt_size = ETH_ZLEN;
+ pkt_dev->max_pkt_size = ETH_ZLEN;
+ pkt_dev->nfrags = 0;
+ pkt_dev->clone_skb = pg_clone_skb_d;
+ pkt_dev->delay_us = pg_delay_d / 1000;
+ pkt_dev->delay_ns = pg_delay_d % 1000;
+ pkt_dev->count = pg_count_d;
+ pkt_dev->sofar = 0;
+ pkt_dev->udp_src_min = 9; /* sink port */
+ pkt_dev->udp_src_max = 9;
+ pkt_dev->udp_dst_min = 9;
+ pkt_dev->udp_dst_max = 9;
+
+ strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
+
+ if (! pktgen_setup_dev(pkt_dev)) {
+ printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
+ if (pkt_dev->flows)
+ vfree(pkt_dev->flows);
+ kfree(pkt_dev);
+ return -ENODEV;
+ }
+
+ pe = create_proc_entry(ifname, 0600, pg_proc_dir);
+ if (!pe) {
+ printk("pktgen: cannot create %s/%s procfs entry.\n",
+ PG_PROC_DIR, ifname);
+ if (pkt_dev->flows)
+ vfree(pkt_dev->flows);
+ kfree(pkt_dev);
+ return -EINVAL;
+ }
+ pe->proc_fops = &pktgen_if_fops;
+ pe->data = pkt_dev;
- return add_dev_to_thread(t, pkt_dev);
- }
- else {
- printk("pktgen: ERROR: interface already used.\n");
- return -EBUSY;
- }
+ return add_dev_to_thread(t, pkt_dev);
}
static struct pktgen_thread *pktgen_find_thread(const char* name)
{
struct pktgen_thread *t = NULL;
- thread_lock();
+ thread_lock();
t = pktgen_threads;
while (t) {
@@ -2962,6 +2903,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name)
static int pktgen_create_thread(const char* name, int cpu)
{
struct pktgen_thread *t = NULL;
+ struct proc_dir_entry *pe;
if (strlen(name) > 31) {
printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n");
@@ -2973,28 +2915,26 @@ static int pktgen_create_thread(const char* name, int cpu)
return -EINVAL;
}
- t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL));
+ t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
if (!t) {
printk("pktgen: ERROR: out of memory, can't create new thread.\n");
return -ENOMEM;
}
- memset(t, 0, sizeof(struct pktgen_thread));
strcpy(t->name, name);
spin_lock_init(&t->if_lock);
t->cpu = cpu;
- sprintf(t->fname, "net/%s/%s", PG_PROC_DIR, t->name);
- t->proc_ent = create_proc_entry(t->fname, 0600, NULL);
- if (!t->proc_ent) {
- printk("pktgen: cannot create %s procfs entry.\n", t->fname);
+ pe = create_proc_entry(t->name, 0600, pg_proc_dir);
+ if (!pe) {
+ printk("pktgen: cannot create %s/%s procfs entry.\n",
+ PG_PROC_DIR, t->name);
kfree(t);
return -EINVAL;
}
- t->proc_ent->read_proc = proc_thread_read;
- t->proc_ent->write_proc = proc_thread_write;
- t->proc_ent->data = (void*)(t);
- t->proc_ent->owner = THIS_MODULE;
+
+ pe->proc_fops = &pktgen_thread_fops;
+ pe->data = t;
t->next = pktgen_threads;
pktgen_threads = t;
@@ -3049,8 +2989,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
/* Clean up proc file system */
- if (strlen(pkt_dev->fname))
- remove_proc_entry(pkt_dev->fname, NULL);
+ remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
if (pkt_dev->flows)
vfree(pkt_dev->flows);
@@ -3061,31 +3000,31 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
static int __init pg_init(void)
{
int cpu;
- printk(version);
+ struct proc_dir_entry *pe;
- module_fname[0] = 0;
+ printk(version);
- create_proc_dir();
+ pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
+ if (!pg_proc_dir)
+ return -ENODEV;
+ pg_proc_dir->owner = THIS_MODULE;
- sprintf(module_fname, "net/%s/pgctrl", PG_PROC_DIR);
- module_proc_ent = create_proc_entry(module_fname, 0600, NULL);
- if (!module_proc_ent) {
- printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
+ pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
+ if (pe == NULL) {
+ printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL);
+ proc_net_remove(PG_PROC_DIR);
return -EINVAL;
}
- module_proc_ent->proc_fops = &pktgen_fops;
- module_proc_ent->data = NULL;
+ pe->proc_fops = &pktgen_fops;
+ pe->data = NULL;
/* Register us to receive netdevice events */
register_netdevice_notifier(&pktgen_notifier_block);
- for (cpu = 0; cpu < NR_CPUS ; cpu++) {
+ for_each_online_cpu(cpu) {
char buf[30];
- if (!cpu_online(cpu))
- continue;
-
sprintf(buf, "kpktgend_%i", cpu);
pktgen_create_thread(buf, cpu);
}
@@ -3110,10 +3049,8 @@ static void __exit pg_cleanup(void)
unregister_netdevice_notifier(&pktgen_notifier_block);
/* Clean up proc file system */
-
- remove_proc_entry(module_fname, NULL);
-
- remove_proc_dir();
+ remove_proc_entry(PGCTRL, pg_proc_dir);
+ proc_net_remove(PG_PROC_DIR);
}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f80a28785610..ef9d46b91eb9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -71,8 +71,6 @@
static kmem_cache_t *skbuff_head_cache __read_mostly;
static kmem_cache_t *skbuff_fclone_cache __read_mostly;
-struct timeval __read_mostly skb_tv_base;
-
/*
* Keep out-of-line to prevent kernel bloat.
* __builtin_return_address is not used because it is not always
@@ -124,6 +122,8 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
* __alloc_skb - allocate a network buffer
* @size: size to allocate
* @gfp_mask: allocation mask
+ * @fclone: allocate from fclone cache instead of head cache
+ * and allocate a cloned (child) skb
*
* Allocate a new &sk_buff. The returned buffer has no headroom and a
* tail room of size bytes. The object has a reference count of one.
@@ -132,7 +132,7 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
* Buffers may only be allocated from interrupts using a @gfp_mask of
* %GFP_ATOMIC.
*/
-struct sk_buff *__alloc_skb(unsigned int size, unsigned int __nocast gfp_mask,
+struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
int fclone)
{
struct sk_buff *skb;
@@ -200,7 +200,7 @@ nodata:
*/
struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
unsigned int size,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
struct sk_buff *skb;
u8 *data;
@@ -363,7 +363,7 @@ void __kfree_skb(struct sk_buff *skb)
* %GFP_ATOMIC.
*/
-struct sk_buff *skb_clone(struct sk_buff *skb, unsigned int __nocast gfp_mask)
+struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
{
struct sk_buff *n;
@@ -412,6 +412,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, unsigned int __nocast gfp_mask)
C(nfct);
nf_conntrack_get(skb->nfct);
C(nfctinfo);
+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+ C(ipvs_property);
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
C(nf_bridge);
nf_bridge_get(skb->nf_bridge);
@@ -469,6 +472,9 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nfct = old->nfct;
nf_conntrack_get(old->nfct);
new->nfctinfo = old->nfctinfo;
+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+ new->ipvs_property = old->ipvs_property;
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
new->nf_bridge = old->nf_bridge;
nf_bridge_get(old->nf_bridge);
@@ -502,7 +508,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
* header is going to be modified. Use pskb_copy() instead.
*/
-struct sk_buff *skb_copy(const struct sk_buff *skb, unsigned int __nocast gfp_mask)
+struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
{
int headerlen = skb->data - skb->head;
/*
@@ -541,7 +547,7 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, unsigned int __nocast gfp_ma
* The returned buffer has a reference count of 1.
*/
-struct sk_buff *pskb_copy(struct sk_buff *skb, unsigned int __nocast gfp_mask)
+struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
{
/*
* Allocate the copy buffer
@@ -600,7 +606,7 @@ out:
*/
int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
int i;
u8 *data;
@@ -691,7 +697,7 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
*/
struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
int newheadroom, int newtailroom,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
/*
* Allocate the copy buffer
@@ -1708,8 +1714,6 @@ void __init skb_init(void)
NULL, NULL);
if (!skbuff_fclone_cache)
panic("cannot create skbuff cache");
-
- do_gettimeofday(&skb_tv_base);
}
EXPORT_SYMBOL(___pskb_trim);
@@ -1743,4 +1747,3 @@ EXPORT_SYMBOL(skb_prepare_seq_read);
EXPORT_SYMBOL(skb_seq_read);
EXPORT_SYMBOL(skb_abort_seq_read);
EXPORT_SYMBOL(skb_find_text);
-EXPORT_SYMBOL(skb_tv_base);
diff --git a/net/core/sock.c b/net/core/sock.c
index ac63b56e23b2..9602ceb3bac9 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -637,7 +637,7 @@ lenout:
* @prot: struct proto associated with this new sock instance
* @zero_it: if we should zero the newly allocated sock
*/
-struct sock *sk_alloc(int family, unsigned int __nocast priority,
+struct sock *sk_alloc(int family, gfp_t priority,
struct proto *prot, int zero_it)
{
struct sock *sk = NULL;
@@ -660,16 +660,20 @@ struct sock *sk_alloc(int family, unsigned int __nocast priority,
sock_lock_init(sk);
}
- if (security_sk_alloc(sk, family, priority)) {
- if (slab != NULL)
- kmem_cache_free(slab, sk);
- else
- kfree(sk);
- sk = NULL;
- } else
- __module_get(prot->owner);
+ if (security_sk_alloc(sk, family, priority))
+ goto out_free;
+
+ if (!try_module_get(prot->owner))
+ goto out_free;
}
return sk;
+
+out_free:
+ if (slab != NULL)
+ kmem_cache_free(slab, sk);
+ else
+ kfree(sk);
+ return NULL;
}
void sk_free(struct sock *sk)
@@ -700,7 +704,7 @@ void sk_free(struct sock *sk)
module_put(owner);
}
-struct sock *sk_clone(const struct sock *sk, const unsigned int __nocast priority)
+struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
{
struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
@@ -841,7 +845,7 @@ unsigned long sock_i_ino(struct sock *sk)
* Allocate a skb from the socket's send buffer.
*/
struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
- unsigned int __nocast priority)
+ gfp_t priority)
{
if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) {
struct sk_buff * skb = alloc_skb(size, priority);
@@ -857,7 +861,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
* Allocate a skb from the socket's receive buffer.
*/
struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force,
- unsigned int __nocast priority)
+ gfp_t priority)
{
if (force || atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf) {
struct sk_buff *skb = alloc_skb(size, priority);
@@ -872,7 +876,7 @@ struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force,
/*
* Allocate a memory block from the socket's option memory buffer.
*/
-void *sock_kmalloc(struct sock *sk, int size, unsigned int __nocast priority)
+void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
{
if ((unsigned)size <= sysctl_optmem_max &&
atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) {
@@ -936,7 +940,7 @@ static struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
int noblock, int *errcode)
{
struct sk_buff *skb;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
long timeo;
int err;
diff --git a/net/core/wireless.c b/net/core/wireless.c
index d17f1583ea3e..271ddb35b0b2 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -455,10 +455,15 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
/* Old location, field to be removed in next WE */
if(dev->get_wireless_stats) {
- printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n",
- dev->name);
+ static int printed_message;
+
+ if (!printed_message++)
+ printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n",
+ dev->name);
+
return dev->get_wireless_stats(dev);
}
+
/* Not found */
return (struct iw_statistics *) NULL;
}
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index fb97bb042455..344a8da153fc 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -3,6 +3,8 @@ obj-$(CONFIG_IP_DCCP) += dccp.o
dccp-y := ccid.o input.o ipv4.o minisocks.o options.o output.o proto.o \
timer.o
+dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o
+
obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
dccp_diag-y := diag.o
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
new file mode 100644
index 000000000000..c9a62cca22fc
--- /dev/null
+++ b/net/dccp/ackvec.c
@@ -0,0 +1,419 @@
+/*
+ * net/dccp/ackvec.c
+ *
+ * An implementation of the DCCP protocol
+ * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.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; version 2 of the License;
+ */
+
+#include "ackvec.h"
+#include "dccp.h"
+
+#include <linux/dccp.h>
+#include <linux/skbuff.h>
+
+#include <net/sock.h>
+
+int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+ struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
+ int len = av->dccpav_vec_len + 2;
+ struct timeval now;
+ u32 elapsed_time;
+ unsigned char *to, *from;
+
+ dccp_timestamp(sk, &now);
+ elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10;
+
+ if (elapsed_time != 0)
+ dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
+
+ if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
+ return -1;
+
+ /*
+ * XXX: now we have just one ack vector sent record, so
+ * we have to wait for it to be cleared.
+ *
+ * Of course this is not acceptable, but this is just for
+ * basic testing now.
+ */
+ if (av->dccpav_ack_seqno != DCCP_MAX_SEQNO + 1)
+ return -1;
+
+ DCCP_SKB_CB(skb)->dccpd_opt_len += len;
+
+ to = skb_push(skb, len);
+ *to++ = DCCPO_ACK_VECTOR_0;
+ *to++ = len;
+
+ len = av->dccpav_vec_len;
+ from = av->dccpav_buf + av->dccpav_buf_head;
+
+ /* Check if buf_head wraps */
+ if (av->dccpav_buf_head + len > av->dccpav_vec_len) {
+ const u32 tailsize = (av->dccpav_vec_len - av->dccpav_buf_head);
+
+ memcpy(to, from, tailsize);
+ to += tailsize;
+ len -= tailsize;
+ from = av->dccpav_buf;
+ }
+
+ memcpy(to, from, len);
+ /*
+ * From draft-ietf-dccp-spec-11.txt:
+ *
+ * For each acknowledgement it sends, the HC-Receiver will add an
+ * acknowledgement record. ack_seqno will equal the HC-Receiver
+ * sequence number it used for the ack packet; ack_ptr will equal
+ * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
+ * equal buf_nonce.
+ *
+ * This implemention uses just one ack record for now.
+ */
+ av->dccpav_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
+ av->dccpav_ack_ptr = av->dccpav_buf_head;
+ av->dccpav_ack_ackno = av->dccpav_buf_ackno;
+ av->dccpav_ack_nonce = av->dccpav_buf_nonce;
+ av->dccpav_sent_len = av->dccpav_vec_len;
+
+ dccp_pr_debug("%sACK Vector 0, len=%d, ack_seqno=%llu, "
+ "ack_ackno=%llu\n",
+ debug_prefix, av->dccpav_sent_len,
+ (unsigned long long)av->dccpav_ack_seqno,
+ (unsigned long long)av->dccpav_ack_ackno);
+ return -1;
+}
+
+struct dccp_ackvec *dccp_ackvec_alloc(const unsigned int len,
+ const gfp_t priority)
+{
+ struct dccp_ackvec *av = kmalloc(sizeof(*av) + len, priority);
+
+ if (av != NULL) {
+ av->dccpav_buf_len = len;
+ av->dccpav_buf_head =
+ av->dccpav_buf_tail = av->dccpav_buf_len - 1;
+ av->dccpav_buf_ackno =
+ av->dccpav_ack_ackno = av->dccpav_ack_seqno = ~0LLU;
+ av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0;
+ av->dccpav_ack_ptr = 0;
+ av->dccpav_time.tv_sec = 0;
+ av->dccpav_time.tv_usec = 0;
+ av->dccpav_sent_len = av->dccpav_vec_len = 0;
+ }
+
+ return av;
+}
+
+void dccp_ackvec_free(struct dccp_ackvec *av)
+{
+ kfree(av);
+}
+
+static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
+ const unsigned int index)
+{
+ return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK;
+}
+
+static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
+ const unsigned int index)
+{
+ return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK;
+}
+
+/*
+ * If several packets are missing, the HC-Receiver may prefer to enter multiple
+ * bytes with run length 0, rather than a single byte with a larger run length;
+ * this simplifies table updates if one of the missing packets arrives.
+ */
+static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
+ const unsigned int packets,
+ const unsigned char state)
+{
+ unsigned int gap;
+ signed long new_head;
+
+ if (av->dccpav_vec_len + packets > av->dccpav_buf_len)
+ return -ENOBUFS;
+
+ gap = packets - 1;
+ new_head = av->dccpav_buf_head - packets;
+
+ if (new_head < 0) {
+ if (gap > 0) {
+ memset(av->dccpav_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED,
+ gap + new_head + 1);
+ gap = -new_head;
+ }
+ new_head += av->dccpav_buf_len;
+ }
+
+ av->dccpav_buf_head = new_head;
+
+ if (gap > 0)
+ memset(av->dccpav_buf + av->dccpav_buf_head + 1,
+ DCCP_ACKVEC_STATE_NOT_RECEIVED, gap);
+
+ av->dccpav_buf[av->dccpav_buf_head] = state;
+ av->dccpav_vec_len += packets;
+ return 0;
+}
+
+/*
+ * Implements the draft-ietf-dccp-spec-11.txt Appendix A
+ */
+int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
+ const u64 ackno, const u8 state)
+{
+ /*
+ * Check at the right places if the buffer is full, if it is, tell the
+ * caller to start dropping packets till the HC-Sender acks our ACK
+ * vectors, when we will free up space in dccpav_buf.
+ *
+ * We may well decide to do buffer compression, etc, but for now lets
+ * just drop.
+ *
+ * From Appendix A:
+ *
+ * Of course, the circular buffer may overflow, either when the
+ * HC-Sender is sending data at a very high rate, when the
+ * HC-Receiver's acknowledgements are not reaching the HC-Sender,
+ * or when the HC-Sender is forgetting to acknowledge those acks
+ * (so the HC-Receiver is unable to clean up old state). In this
+ * case, the HC-Receiver should either compress the buffer (by
+ * increasing run lengths when possible), transfer its state to
+ * a larger buffer, or, as a last resort, drop all received
+ * packets, without processing them whatsoever, until its buffer
+ * shrinks again.
+ */
+
+ /* See if this is the first ackno being inserted */
+ if (av->dccpav_vec_len == 0) {
+ av->dccpav_buf[av->dccpav_buf_head] = state;
+ av->dccpav_vec_len = 1;
+ } else if (after48(ackno, av->dccpav_buf_ackno)) {
+ const u64 delta = dccp_delta_seqno(av->dccpav_buf_ackno,
+ ackno);
+
+ /*
+ * Look if the state of this packet is the same as the
+ * previous ackno and if so if we can bump the head len.
+ */
+ if (delta == 1 &&
+ dccp_ackvec_state(av, av->dccpav_buf_head) == state &&
+ (dccp_ackvec_len(av, av->dccpav_buf_head) <
+ DCCP_ACKVEC_LEN_MASK))
+ av->dccpav_buf[av->dccpav_buf_head]++;
+ else if (dccp_ackvec_set_buf_head_state(av, delta, state))
+ return -ENOBUFS;
+ } else {
+ /*
+ * A.1.2. Old Packets
+ *
+ * When a packet with Sequence Number S arrives, and
+ * S <= buf_ackno, the HC-Receiver will scan the table
+ * for the byte corresponding to S. (Indexing structures
+ * could reduce the complexity of this scan.)
+ */
+ u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
+ unsigned int index = av->dccpav_buf_head;
+
+ while (1) {
+ const u8 len = dccp_ackvec_len(av, index);
+ const u8 state = dccp_ackvec_state(av, index);
+ /*
+ * valid packets not yet in dccpav_buf have a reserved
+ * entry, with a len equal to 0.
+ */
+ if (state == DCCP_ACKVEC_STATE_NOT_RECEIVED &&
+ len == 0 && delta == 0) { /* Found our
+ reserved seat! */
+ dccp_pr_debug("Found %llu reserved seat!\n",
+ (unsigned long long)ackno);
+ av->dccpav_buf[index] = state;
+ goto out;
+ }
+ /* len == 0 means one packet */
+ if (delta < len + 1)
+ goto out_duplicate;
+
+ delta -= len + 1;
+ if (++index == av->dccpav_buf_len)
+ index = 0;
+ }
+ }
+
+ av->dccpav_buf_ackno = ackno;
+ dccp_timestamp(sk, &av->dccpav_time);
+out:
+ dccp_pr_debug("");
+ return 0;
+
+out_duplicate:
+ /* Duplicate packet */
+ dccp_pr_debug("Received a dup or already considered lost "
+ "packet: %llu\n", (unsigned long long)ackno);
+ return -EILSEQ;
+}
+
+#ifdef CONFIG_IP_DCCP_DEBUG
+void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
+{
+ if (!dccp_debug)
+ return;
+
+ printk("ACK vector len=%d, ackno=%llu |", len,
+ (unsigned long long)ackno);
+
+ while (len--) {
+ const u8 state = (*vector & DCCP_ACKVEC_STATE_MASK) >> 6;
+ const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
+
+ printk("%d,%d|", state, rl);
+ ++vector;
+ }
+
+ printk("\n");
+}
+
+void dccp_ackvec_print(const struct dccp_ackvec *av)
+{
+ dccp_ackvector_print(av->dccpav_buf_ackno,
+ av->dccpav_buf + av->dccpav_buf_head,
+ av->dccpav_vec_len);
+}
+#endif
+
+static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av)
+{
+ /*
+ * As we're keeping track of the ack vector size (dccpav_vec_len) and
+ * the sent ack vector size (dccpav_sent_len) we don't need
+ * dccpav_buf_tail at all, but keep this code here as in the future
+ * we'll implement a vector of ack records, as suggested in
+ * draft-ietf-dccp-spec-11.txt Appendix A. -acme
+ */
+#if 0
+ av->dccpav_buf_tail = av->dccpav_ack_ptr + 1;
+ if (av->dccpav_buf_tail >= av->dccpav_vec_len)
+ av->dccpav_buf_tail -= av->dccpav_vec_len;
+#endif
+ av->dccpav_vec_len -= av->dccpav_sent_len;
+}
+
+void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
+ const u64 ackno)
+{
+ /* Check if we actually sent an ACK vector */
+ if (av->dccpav_ack_seqno == DCCP_MAX_SEQNO + 1)
+ return;
+
+ if (ackno == av->dccpav_ack_seqno) {
+#ifdef CONFIG_IP_DCCP_DEBUG
+ struct dccp_sock *dp = dccp_sk(sk);
+ const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
+ "CLIENT rx ack: " : "server rx ack: ";
+#endif
+ dccp_pr_debug("%sACK packet 0, len=%d, ack_seqno=%llu, "
+ "ack_ackno=%llu, ACKED!\n",
+ debug_prefix, 1,
+ (unsigned long long)av->dccpav_ack_seqno,
+ (unsigned long long)av->dccpav_ack_ackno);
+ dccp_ackvec_trow_away_ack_record(av);
+ av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1;
+ }
+}
+
+static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
+ struct sock *sk, u64 ackno,
+ const unsigned char len,
+ const unsigned char *vector)
+{
+ unsigned char i;
+
+ /* Check if we actually sent an ACK vector */
+ if (av->dccpav_ack_seqno == DCCP_MAX_SEQNO + 1)
+ return;
+ /*
+ * We're in the receiver half connection, so if the received an ACK
+ * vector ackno (e.g. 50) before dccpav_ack_seqno (e.g. 52), we're
+ * not interested.
+ *
+ * Extra explanation with example:
+ *
+ * if we received an ACK vector with ackno 50, it can only be acking
+ * 50, 49, 48, etc, not 52 (the seqno for the ACK vector we sent).
+ */
+ /* dccp_pr_debug("is %llu < %llu? ", ackno, av->dccpav_ack_seqno); */
+ if (before48(ackno, av->dccpav_ack_seqno)) {
+ /* dccp_pr_debug_cat("yes\n"); */
+ return;
+ }
+ /* dccp_pr_debug_cat("no\n"); */
+
+ i = len;
+ while (i--) {
+ const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
+ u64 ackno_end_rl;
+
+ dccp_set_seqno(&ackno_end_rl, ackno - rl);
+
+ /*
+ * dccp_pr_debug("is %llu <= %llu <= %llu? ", ackno_end_rl,
+ * av->dccpav_ack_seqno, ackno);
+ */
+ if (between48(av->dccpav_ack_seqno, ackno_end_rl, ackno)) {
+ const u8 state = (*vector &
+ DCCP_ACKVEC_STATE_MASK) >> 6;
+ /* dccp_pr_debug_cat("yes\n"); */
+
+ if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) {
+#ifdef CONFIG_IP_DCCP_DEBUG
+ struct dccp_sock *dp = dccp_sk(sk);
+ const char *debug_prefix =
+ dp->dccps_role == DCCP_ROLE_CLIENT ?
+ "CLIENT rx ack: " : "server rx ack: ";
+#endif
+ dccp_pr_debug("%sACK vector 0, len=%d, "
+ "ack_seqno=%llu, ack_ackno=%llu, "
+ "ACKED!\n",
+ debug_prefix, len,
+ (unsigned long long)
+ av->dccpav_ack_seqno,
+ (unsigned long long)
+ av->dccpav_ack_ackno);
+ dccp_ackvec_trow_away_ack_record(av);
+ }
+ /*
+ * If dccpav_ack_seqno was not received, no problem
+ * we'll send another ACK vector.
+ */
+ av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1;
+ break;
+ }
+ /* dccp_pr_debug_cat("no\n"); */
+
+ dccp_set_seqno(&ackno, ackno_end_rl - 1);
+ ++vector;
+ }
+}
+
+int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
+ const u8 opt, const u8 *value, const u8 len)
+{
+ if (len > DCCP_MAX_ACKVEC_LEN)
+ return -1;
+
+ /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */
+ dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk,
+ DCCP_SKB_CB(skb)->dccpd_ack_seq,
+ len, value);
+ return 0;
+}
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
new file mode 100644
index 000000000000..d0fd6c60c574
--- /dev/null
+++ b/net/dccp/ackvec.h
@@ -0,0 +1,133 @@
+#ifndef _ACKVEC_H
+#define _ACKVEC_H
+/*
+ * net/dccp/ackvec.h
+ *
+ * An implementation of the DCCP protocol
+ * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.com>
+ *
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+/* Read about the ECN nonce to see why it is 253 */
+#define DCCP_MAX_ACKVEC_LEN 253
+
+#define DCCP_ACKVEC_STATE_RECEIVED 0
+#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6)
+#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6)
+
+#define DCCP_ACKVEC_STATE_MASK 0xC0 /* 11000000 */
+#define DCCP_ACKVEC_LEN_MASK 0x3F /* 00111111 */
+
+/** struct dccp_ackvec - ack vector
+ *
+ * This data structure is the one defined in the DCCP draft
+ * Appendix A.
+ *
+ * @dccpav_buf_head - circular buffer head
+ * @dccpav_buf_tail - circular buffer tail
+ * @dccpav_buf_ackno - ack # of the most recent packet acknowledgeable in the
+ * buffer (i.e. %dccpav_buf_head)
+ * @dccpav_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
+ * by the buffer with State 0
+ *
+ * Additionally, the HC-Receiver must keep some information about the
+ * Ack Vectors it has recently sent. For each packet sent carrying an
+ * Ack Vector, it remembers four variables:
+ *
+ * @dccpav_ack_seqno - the Sequence Number used for the packet
+ * (HC-Receiver seqno)
+ * @dccpav_ack_ptr - the value of buf_head at the time of acknowledgement.
+ * @dccpav_ack_ackno - the Acknowledgement Number used for the packet
+ * (HC-Sender seqno)
+ * @dccpav_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
+ *
+ * @dccpav_buf_len - circular buffer length
+ * @dccpav_time - the time in usecs
+ * @dccpav_buf - circular buffer of acknowledgeable packets
+ */
+struct dccp_ackvec {
+ unsigned int dccpav_buf_head;
+ unsigned int dccpav_buf_tail;
+ u64 dccpav_buf_ackno;
+ u64 dccpav_ack_seqno;
+ u64 dccpav_ack_ackno;
+ unsigned int dccpav_ack_ptr;
+ unsigned int dccpav_sent_len;
+ unsigned int dccpav_vec_len;
+ unsigned int dccpav_buf_len;
+ struct timeval dccpav_time;
+ u8 dccpav_buf_nonce;
+ u8 dccpav_ack_nonce;
+ u8 dccpav_buf[0];
+};
+
+struct sock;
+struct sk_buff;
+
+#ifdef CONFIG_IP_DCCP_ACKVEC
+extern struct dccp_ackvec *dccp_ackvec_alloc(unsigned int len,
+ const gfp_t priority);
+extern void dccp_ackvec_free(struct dccp_ackvec *av);
+
+extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
+ const u64 ackno, const u8 state);
+
+extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
+ struct sock *sk, const u64 ackno);
+extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
+ const u8 opt, const u8 *value, const u8 len);
+
+extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb);
+
+static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
+{
+ return av->dccpav_sent_len != av->dccpav_vec_len;
+}
+#else /* CONFIG_IP_DCCP_ACKVEC */
+static inline struct dccp_ackvec *dccp_ackvec_alloc(unsigned int len,
+ const gfp_t priority)
+{
+ return NULL;
+}
+
+static inline void dccp_ackvec_free(struct dccp_ackvec *av)
+{
+}
+
+static inline int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
+ const u64 ackno, const u8 state)
+{
+ return -1;
+}
+
+static inline void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
+ struct sock *sk, const u64 ackno)
+{
+}
+
+static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
+ const u8 opt, const u8 *value, const u8 len)
+{
+ return -1;
+}
+
+static inline int dccp_insert_option_ackvec(const struct sock *sk,
+ const struct sk_buff *skb)
+{
+ return -1;
+}
+
+static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
+{
+ return 0;
+}
+#endif /* CONFIG_IP_DCCP_ACKVEC */
+#endif /* _ACKVEC_H */
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 962f1e9e2f7e..c37eeeaf5c6e 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -14,6 +14,7 @@
*/
#include <net/sock.h>
+#include <linux/compiler.h>
#include <linux/dccp.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -54,6 +55,14 @@ struct ccid {
struct tcp_info *info);
void (*ccid_hc_tx_get_info)(struct sock *sk,
struct tcp_info *info);
+ int (*ccid_hc_rx_getsockopt)(struct sock *sk,
+ const int optname, int len,
+ u32 __user *optval,
+ int __user *optlen);
+ int (*ccid_hc_tx_getsockopt)(struct sock *sk,
+ const int optname, int len,
+ u32 __user *optval,
+ int __user *optlen);
};
extern int ccid_register(struct ccid *ccid);
@@ -101,14 +110,14 @@ static inline int ccid_hc_tx_init(struct ccid *ccid, struct sock *sk)
static inline void ccid_hc_rx_exit(struct ccid *ccid, struct sock *sk)
{
- if (ccid->ccid_hc_rx_exit != NULL &&
+ if (ccid != NULL && ccid->ccid_hc_rx_exit != NULL &&
dccp_sk(sk)->dccps_hc_rx_ccid_private != NULL)
ccid->ccid_hc_rx_exit(sk);
}
static inline void ccid_hc_tx_exit(struct ccid *ccid, struct sock *sk)
{
- if (ccid->ccid_hc_tx_exit != NULL &&
+ if (ccid != NULL && ccid->ccid_hc_tx_exit != NULL &&
dccp_sk(sk)->dccps_hc_tx_ccid_private != NULL)
ccid->ccid_hc_tx_exit(sk);
}
@@ -177,4 +186,26 @@ static inline void ccid_hc_tx_get_info(struct ccid *ccid, struct sock *sk,
if (ccid->ccid_hc_tx_get_info != NULL)
ccid->ccid_hc_tx_get_info(sk, info);
}
+
+static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
+ const int optname, int len,
+ u32 __user *optval, int __user *optlen)
+{
+ int rc = -ENOPROTOOPT;
+ if (ccid->ccid_hc_rx_getsockopt != NULL)
+ rc = ccid->ccid_hc_rx_getsockopt(sk, optname, len,
+ optval, optlen);
+ return rc;
+}
+
+static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk,
+ const int optname, int len,
+ u32 __user *optval, int __user *optlen)
+{
+ int rc = -ENOPROTOOPT;
+ if (ccid->ccid_hc_tx_getsockopt != NULL)
+ rc = ccid->ccid_hc_tx_getsockopt(sk, optname, len,
+ optval, optlen);
+ return rc;
+}
#endif /* _CCID_H */
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 7bf3b3a91e97..aa68e0ab274d 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;
@@ -68,13 +78,11 @@ static struct dccp_li_hist *ccid3_li_hist;
static int ccid3_init(struct sock *sk)
{
- ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
return 0;
}
static void ccid3_exit(struct sock *sk)
{
- ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
}
/* TFRC sender states */
@@ -102,8 +110,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 +151,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 +165,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 +180,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,20 +279,20 @@ 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;
int rc = -ENOTCONN;
- /* Check if pure ACK or Terminating*/
+ BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
+ /* Check if pure ACK or Terminating*/
/*
* XXX: We only call this function for DATA and DATAACK, on, these
* packets can have zero length, but why the comment about "pure ACK"?
*/
- if (hctx == NULL || len == 0 ||
- hctx->ccid3hctx_state == TFRC_SSTATE_TERM)
+ if (unlikely(len == 0))
goto out;
/* See if last packet allocated was not sent */
@@ -297,23 +302,20 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
SLAB_ATOMIC);
rc = -ENOBUFS;
- if (new_packet == NULL) {
- ccid3_pr_debug("%s, sk=%p, not enough mem to add "
- "to history, send refused\n",
- dccp_role(sk), sk);
+ if (unlikely(new_packet == NULL)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough "
+ "mem to add to history, send refused\n",
+ __FUNCTION__, dccp_role(sk), sk);
goto out;
}
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:
- ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n",
- dccp_role(sk), sk, dp->dccps_gss);
-
hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk;
sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
@@ -321,7 +323,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
hctx->ccid3hctx_last_win_count = 0;
hctx->ccid3hctx_t_last_win_count = now;
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
- hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT;
+ hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
/* Set nominal send time for initial packet */
hctx->ccid3hctx_t_nom = now;
@@ -334,7 +336,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
case TFRC_SSTATE_FBACK:
delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
hctx->ccid3hctx_delta);
- ccid3_pr_debug("send_packet delay=%ld\n", delay);
delay /= -1000;
/* divide by -1000 is to convert to ms and get sign right */
rc = delay > 0 ? delay : 0;
@@ -348,29 +349,25 @@ 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);
-
- if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
- ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n",
- dccp_role(sk), sk);
- return;
- }
+ BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
/* check if we have sent a data packet */
if (len > 0) {
@@ -378,14 +375,14 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
struct dccp_tx_hist_entry *packet;
packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
- if (packet == NULL) {
- printk(KERN_CRIT "%s: packet doesn't exists in "
- "history!\n", __FUNCTION__);
+ if (unlikely(packet == NULL)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't "
+ "exists in history!\n", __FUNCTION__);
return;
}
- if (packet->dccphtx_sent) {
- printk(KERN_CRIT "%s: no unsent packet in history!\n",
- __FUNCTION__);
+ if (unlikely(packet->dccphtx_sent)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
+ "history!\n", __FUNCTION__);
return;
}
packet->dccphtx_tstamp = now;
@@ -445,24 +442,18 @@ 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;
u32 x_recv;
u32 r_sample;
- if (hctx == NULL)
- return;
-
- if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
- ccid3_pr_debug("%s, sk=%p, received a packet when "
- "terminating!\n", dccp_role(sk), sk);
- return;
- }
+ BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
/* we are only interested in ACKs */
if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
@@ -471,7 +462,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;
@@ -486,19 +477,24 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
/* get t_recvdata from history */
packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
DCCP_SKB_CB(skb)->dccpd_ack_seq);
- if (packet == NULL) {
- ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't "
- "exist in history!\n",
- dccp_role(sk), sk,
- DCCP_SKB_CB(skb)->dccpd_ack_seq,
- dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
+ if (unlikely(packet == NULL)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno "
+ "%llu(%s) does't exist in history!\n",
+ __FUNCTION__, dccp_role(sk), sk,
+ (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
+ dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
return;
}
/* 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,11 +587,11 @@ 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;
+ const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
+
+ BUG_ON(hctx == NULL);
- if (hctx == NULL || !(sk->sk_state == DCCP_OPEN ||
- sk->sk_state == DCCP_PARTOPEN))
+ if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
return;
DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
@@ -606,12 +602,11 @@ 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)
- return 0;
+ BUG_ON(hctx == NULL);
opt_recv = &hctx->ccid3hctx_options_received;
@@ -625,10 +620,10 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
switch (option) {
case TFRC_OPT_LOSS_EVENT_RATE:
- if (len != 4) {
- ccid3_pr_debug("%s, sk=%p, invalid len for "
- "TFRC_OPT_LOSS_EVENT_RATE\n",
- dccp_role(sk), sk);
+ if (unlikely(len != 4)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
+ "len for TFRC_OPT_LOSS_EVENT_RATE\n",
+ __FUNCTION__, dccp_role(sk), sk);
rc = -EINVAL;
} else {
opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
@@ -646,10 +641,10 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
opt_recv->ccid3or_loss_intervals_len);
break;
case TFRC_OPT_RECEIVE_RATE:
- if (len != 4) {
- ccid3_pr_debug("%s, sk=%p, invalid len for "
- "TFRC_OPT_RECEIVE_RATE\n",
- dccp_role(sk), sk);
+ if (unlikely(len != 4)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
+ "len for TFRC_OPT_RECEIVE_RATE\n",
+ __FUNCTION__, dccp_role(sk), sk);
rc = -EINVAL;
} else {
opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
@@ -668,13 +663,11 @@ static int ccid3_hc_tx_init(struct sock *sk)
struct dccp_sock *dp = dccp_sk(sk);
struct ccid3_hc_tx_sock *hctx;
- 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,9 +689,8 @@ 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);
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
@@ -738,8 +730,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 +742,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 +758,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:
@@ -782,10 +770,10 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
}
packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
- if (packet == NULL) {
- printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n",
- __FUNCTION__, dccp_role(sk), sk);
- dump_stack();
+ if (unlikely(packet == NULL)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet "
+ "in history!\n",
+ __FUNCTION__, dccp_role(sk), sk);
return;
}
@@ -801,17 +789,18 @@ 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);
+ const 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))
+ BUG_ON(hcrx == NULL);
+
+ if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
return;
DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
@@ -837,8 +826,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, };
@@ -869,17 +857,17 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
}
}
- if (step == 0) {
- printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no "
- "data packets!\n",
- __FUNCTION__, dccp_role(sk), sk);
+ if (unlikely(step == 0)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history "
+ "contains no data packets!\n",
+ __FUNCTION__, dccp_role(sk), sk);
return ~0;
}
- if (interval == 0) {
- ccid3_pr_debug("%s, sk=%p, Could not find a win_count "
- "interval > 0. Defaulting to 1\n",
- dccp_role(sk), sk);
+ if (unlikely(interval == 0)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a "
+ "win_count interval > 0. Defaulting to 1\n",
+ __FUNCTION__, dccp_role(sk), sk);
interval = 1;
}
found:
@@ -889,10 +877,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 +898,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)) {
@@ -924,14 +910,14 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
if (li_tail == NULL)
return;
li_tail->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
- }
- /* FIXME: find end of interval */
+ } else
+ LIMIT_NETDEBUG(KERN_WARNING "%s: FIXME: find end of "
+ "interval\n", __FUNCTION__);
}
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,22 +928,19 @@ 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)
- return;
-
- BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
+ BUG_ON(hcrx == NULL ||
+ !(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 +950,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,
@@ -978,19 +975,16 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
break;
case DCCP_PKT_DATA:
break;
- default:
- ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n",
- dccp_role(sk), sk,
- dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
+ default: /* We're not interested in other packet types, move along */
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 "
- "to history (consider it lost)!",
- dccp_role(sk), sk);
+ if (unlikely(packet == NULL)) {
+ LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to "
+ "add rx packet to history, consider it lost!\n",
+ __FUNCTION__, dccp_role(sk), sk);
return;
}
@@ -1017,7 +1011,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 +1050,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,23 +1066,18 @@ 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);
-
- if (hcrx == NULL)
- return;
+ BUG_ON(hcrx == NULL);
ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
@@ -1104,12 +1093,14 @@ 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)
+ /* Listen socks doesn't have a private CCID block */
+ if (sk->sk_state == DCCP_LISTEN)
return;
+ BUG_ON(hcrx == NULL);
+
info->tcpi_ca_state = hcrx->ccid3hcrx_state;
info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt;
@@ -1117,16 +1108,72 @@ 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)
+ /* Listen socks doesn't have a private CCID block */
+ if (sk->sk_state == DCCP_LISTEN)
return;
+ BUG_ON(hctx == NULL);
+
info->tcpi_rto = hctx->ccid3hctx_t_rto;
info->tcpi_rtt = hctx->ccid3hctx_rtt;
}
+static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
+ u32 __user *optval, int __user *optlen)
+{
+ const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
+ const void *val;
+
+ /* Listen socks doesn't have a private CCID block */
+ if (sk->sk_state == DCCP_LISTEN)
+ return -EINVAL;
+
+ switch (optname) {
+ case DCCP_SOCKOPT_CCID_RX_INFO:
+ if (len < sizeof(hcrx->ccid3hcrx_tfrc))
+ return -EINVAL;
+ len = sizeof(hcrx->ccid3hcrx_tfrc);
+ val = &hcrx->ccid3hcrx_tfrc;
+ break;
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ if (put_user(len, optlen) || copy_to_user(optval, val, len))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
+ u32 __user *optval, int __user *optlen)
+{
+ const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
+ const void *val;
+
+ /* Listen socks doesn't have a private CCID block */
+ if (sk->sk_state == DCCP_LISTEN)
+ return -EINVAL;
+
+ switch (optname) {
+ case DCCP_SOCKOPT_CCID_TX_INFO:
+ if (len < sizeof(hctx->ccid3hctx_tfrc))
+ return -EINVAL;
+ len = sizeof(hctx->ccid3hctx_tfrc);
+ val = &hctx->ccid3hctx_tfrc;
+ break;
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ if (put_user(len, optlen) || copy_to_user(optval, val, len))
+ return -EFAULT;
+
+ return 0;
+}
+
static struct ccid ccid3 = {
.ccid_id = 3,
.ccid_name = "ccid3",
@@ -1146,6 +1193,8 @@ static struct ccid ccid3 = {
.ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv,
.ccid_hc_rx_get_info = ccid3_hc_rx_get_info,
.ccid_hc_tx_get_info = ccid3_hc_tx_get_info,
+ .ccid_hc_rx_getsockopt = ccid3_hc_rx_getsockopt,
+ .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt,
};
module_param(ccid3_debug, int, 0444);
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index ee8cbace6630..0bde4583d091 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -40,6 +40,7 @@
#include <linux/list.h>
#include <linux/time.h>
#include <linux/types.h>
+#include <linux/tfrc.h>
#define TFRC_MIN_PACKET_SIZE 16
#define TFRC_STD_PACKET_SIZE 256
@@ -48,6 +49,8 @@
/* Two seconds as per CCID3 spec */
#define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC)
+#define TFRC_INITIAL_IPI (USEC_PER_SEC / 4)
+
/* In usecs - half the scheduling granularity as per RFC3448 4.6 */
#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))
@@ -91,12 +94,15 @@ struct ccid3_options_received {
* @ccid3hctx_hist - Packet history
*/
struct ccid3_hc_tx_sock {
- u32 ccid3hctx_x;
- u32 ccid3hctx_x_recv;
- u32 ccid3hctx_x_calc;
+ struct tfrc_tx_info ccid3hctx_tfrc;
+#define ccid3hctx_x ccid3hctx_tfrc.tfrctx_x
+#define ccid3hctx_x_recv ccid3hctx_tfrc.tfrctx_x_recv
+#define ccid3hctx_x_calc ccid3hctx_tfrc.tfrctx_x_calc
+#define ccid3hctx_rtt ccid3hctx_tfrc.tfrctx_rtt
+#define ccid3hctx_p ccid3hctx_tfrc.tfrctx_p
+#define ccid3hctx_t_rto ccid3hctx_tfrc.tfrctx_rto
+#define ccid3hctx_t_ipi ccid3hctx_tfrc.tfrctx_ipi
u16 ccid3hctx_s;
- u32 ccid3hctx_rtt;
- u32 ccid3hctx_p;
u8 ccid3hctx_state;
u8 ccid3hctx_last_win_count;
u8 ccid3hctx_idle;
@@ -104,19 +110,19 @@ struct ccid3_hc_tx_sock {
struct timer_list ccid3hctx_no_feedback_timer;
struct timeval ccid3hctx_t_ld;
struct timeval ccid3hctx_t_nom;
- u32 ccid3hctx_t_rto;
- u32 ccid3hctx_t_ipi;
u32 ccid3hctx_delta;
struct list_head ccid3hctx_hist;
struct ccid3_options_received ccid3hctx_options_received;
};
struct ccid3_hc_rx_sock {
+ struct tfrc_rx_info ccid3hcrx_tfrc;
+#define ccid3hcrx_x_recv ccid3hcrx_tfrc.tfrcrx_x_recv
+#define ccid3hcrx_rtt ccid3hcrx_tfrc.tfrcrx_rtt
+#define ccid3hcrx_p ccid3hcrx_tfrc.tfrcrx_p
u64 ccid3hcrx_seqno_last_counter:48,
ccid3hcrx_state:8,
ccid3hcrx_last_counter:4;
- unsigned long ccid3hcrx_rtt;
- u32 ccid3hcrx_p;
u32 ccid3hcrx_bytes_recv;
struct timeval ccid3hcrx_tstamp_last_feedback;
struct timeval ccid3hcrx_tstamp_last_ack;
@@ -125,13 +131,16 @@ struct ccid3_hc_rx_sock {
u16 ccid3hcrx_s;
u32 ccid3hcrx_pinv;
u32 ccid3hcrx_elapsed_time;
- 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/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index 13ad47ba1420..417d9d82df3e 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -36,7 +36,7 @@ struct dccp_li_hist_entry {
static inline struct dccp_li_hist_entry *
dccp_li_hist_entry_new(struct dccp_li_hist *hist,
- const unsigned int __nocast prio)
+ const gfp_t prio)
{
return kmem_cache_alloc(hist->dccplih_slab, prio);
}
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index fb90a91aa93d..122e96737ff6 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -86,7 +86,7 @@ extern struct dccp_rx_hist_entry *
static inline struct dccp_tx_hist_entry *
dccp_tx_hist_entry_new(struct dccp_tx_hist *hist,
- const unsigned int __nocast prio)
+ const gfp_t prio)
{
struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab,
prio);
@@ -134,9 +134,10 @@ 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)
+ const gfp_t prio)
{
struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
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 33456c0d5937..5871c027f9dc 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -17,6 +17,7 @@
#include <net/snmp.h>
#include <net/sock.h>
#include <net/tcp.h>
+#include "ackvec.h"
#ifdef CONFIG_IP_DCCP_DEBUG
extern int dccp_debug;
@@ -258,13 +259,12 @@ extern int dccp_v4_send_reset(struct sock *sk,
extern void dccp_send_close(struct sock *sk, const int active);
struct dccp_skb_cb {
- __u8 dccpd_type;
- __u8 dccpd_reset_code;
- __u8 dccpd_service;
- __u8 dccpd_ccval;
+ __u8 dccpd_type:4;
+ __u8 dccpd_ccval:4;
+ __u8 dccpd_reset_code;
+ __u16 dccpd_opt_len;
__u64 dccpd_seq;
__u64 dccpd_ack_seq;
- int dccpd_opt_len;
};
#define DCCP_SKB_CB(__skb) ((struct dccp_skb_cb *)&((__skb)->cb[0]))
@@ -359,6 +359,17 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq)
(dp->dccps_gss -
dp->dccps_options.dccpo_sequence_window + 1));
}
+
+static inline int dccp_ack_pending(const struct sock *sk)
+{
+ const struct dccp_sock *dp = dccp_sk(sk);
+ return dp->dccps_timestamp_echo != 0 ||
+#ifdef CONFIG_IP_DCCP_ACKVEC
+ (dp->dccps_options.dccpo_send_ack_vector &&
+ dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
+#endif
+ inet_csk_ack_scheduled(sk);
+}
extern void dccp_insert_options(struct sock *sk, struct sk_buff *skb);
extern void dccp_insert_option_elapsed_time(struct sock *sk,
@@ -372,63 +383,7 @@ extern void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
extern struct socket *dccp_ctl_socket;
-#define DCCP_ACKPKTS_STATE_RECEIVED 0
-#define DCCP_ACKPKTS_STATE_ECN_MARKED (1 << 6)
-#define DCCP_ACKPKTS_STATE_NOT_RECEIVED (3 << 6)
-
-#define DCCP_ACKPKTS_STATE_MASK 0xC0 /* 11000000 */
-#define DCCP_ACKPKTS_LEN_MASK 0x3F /* 00111111 */
-
-/** struct dccp_ackpkts - acknowledgeable packets
- *
- * This data structure is the one defined in the DCCP draft
- * Appendix A.
- *
- * @dccpap_buf_head - circular buffer head
- * @dccpap_buf_tail - circular buffer tail
- * @dccpap_buf_ackno - ack # of the most recent packet acknowledgeable in the
- * buffer (i.e. %dccpap_buf_head)
- * @dccpap_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
- * by the buffer with State 0
- *
- * Additionally, the HC-Receiver must keep some information about the
- * Ack Vectors it has recently sent. For each packet sent carrying an
- * Ack Vector, it remembers four variables:
- *
- * @dccpap_ack_seqno - the Sequence Number used for the packet
- * (HC-Receiver seqno)
- * @dccpap_ack_ptr - the value of buf_head at the time of acknowledgement.
- * @dccpap_ack_ackno - the Acknowledgement Number used for the packet
- * (HC-Sender seqno)
- * @dccpap_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
- *
- * @dccpap_buf_len - circular buffer length
- * @dccpap_time - the time in usecs
- * @dccpap_buf - circular buffer of acknowledgeable packets
- */
-struct dccp_ackpkts {
- unsigned int dccpap_buf_head;
- unsigned int dccpap_buf_tail;
- u64 dccpap_buf_ackno;
- u64 dccpap_ack_seqno;
- u64 dccpap_ack_ackno;
- unsigned int dccpap_ack_ptr;
- unsigned int dccpap_buf_vector_len;
- unsigned int dccpap_ack_vector_len;
- unsigned int dccpap_buf_len;
- struct timeval dccpap_time;
- u8 dccpap_buf_nonce;
- u8 dccpap_ack_nonce;
- u8 dccpap_buf[0];
-};
-
-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 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)
{
@@ -468,26 +423,4 @@ 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);
-extern void dccp_ackpkts_print(const struct dccp_ackpkts *ap);
-#else
-static inline void dccp_ackvector_print(const u64 ackno,
- const unsigned char *vector,
- int len) { }
-static inline void dccp_ackpkts_print(const struct dccp_ackpkts *ap) { }
-#endif
-
#endif /* _DCCP_H */
diff --git a/net/dccp/input.c b/net/dccp/input.c
index ef29cef1dafe..3454d5941900 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -16,6 +16,7 @@
#include <net/sock.h>
+#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"
@@ -50,7 +51,8 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
return;
}
- dccp_set_state(sk, DCCP_CLOSING);
+ if (sk->sk_state != DCCP_CLOSING)
+ dccp_set_state(sk, DCCP_CLOSING);
dccp_send_close(sk, 0);
}
@@ -59,8 +61,8 @@ static inline void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
struct dccp_sock *dp = dccp_sk(sk);
if (dp->dccps_options.dccpo_send_ack_vector)
- dccp_ackpkts_check_rcv_ackno(dp->dccps_hc_rx_ackpkts, sk,
- DCCP_SKB_CB(skb)->dccpd_ack_seq);
+ dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk,
+ DCCP_SKB_CB(skb)->dccpd_ack_seq);
}
static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
@@ -163,37 +165,11 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
dccp_event_ack_recv(sk, skb);
- /*
- * FIXME: check ECN to see if we should use
- * DCCP_ACKPKTS_STATE_ECN_MARKED
- */
- 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,
- DCCP_SKB_CB(skb)->dccpd_seq,
- DCCP_ACKPKTS_STATE_RECEIVED)) {
- LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable "
- "packets buffer full!\n");
- ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
- inet_csk_schedule_ack(sk);
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
- TCP_DELACK_MIN,
- DCCP_RTO_MAX);
- goto discard;
- }
-
- /*
- * FIXME: this activation is probably wrong, have to study more
- * TCP delack machinery and how it fits into DCCP draft, but
- * for now it kinda "works" 8)
- */
- if (!inet_csk_ack_scheduled(sk)) {
- inet_csk_schedule_ack(sk);
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, 5 * HZ,
- DCCP_RTO_MAX);
- }
- }
+ if (dp->dccps_options.dccpo_send_ack_vector &&
+ dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+ DCCP_SKB_CB(skb)->dccpd_seq,
+ DCCP_ACKVEC_STATE_RECEIVED))
+ goto discard;
ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
@@ -383,9 +359,9 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
}
out_invalid_packet:
- return 1; /* dccp_v4_do_rcv will send a reset, but...
- FIXME: the reset code should be
- DCCP_RESET_CODE_PACKET_ERROR */
+ /* dccp_v4_do_rcv will send a reset */
+ DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
+ return 1;
}
static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
@@ -399,6 +375,9 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
case DCCP_PKT_RESET:
inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
break;
+ case DCCP_PKT_DATA:
+ if (sk->sk_state == DCCP_RESPOND)
+ break;
case DCCP_PKT_DATAACK:
case DCCP_PKT_ACK:
/*
@@ -417,7 +396,8 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
dccp_sk(sk)->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq;
dccp_set_state(sk, DCCP_OPEN);
- if (dh->dccph_type == DCCP_PKT_DATAACK) {
+ if (dh->dccph_type == DCCP_PKT_DATAACK ||
+ dh->dccph_type == DCCP_PKT_DATA) {
dccp_rcv_established(sk, skb, dh, len);
queued = 1; /* packet was queued
(by dccp_rcv_established) */
@@ -432,6 +412,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
struct dccp_hdr *dh, unsigned len)
{
struct dccp_sock *dp = dccp_sk(sk);
+ struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
const int old_state = sk->sk_state;
int queued = 0;
@@ -472,7 +453,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (dh->dccph_type == DCCP_PKT_RESET)
goto discard;
- /* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/
+ /* Caller (dccp_v4_do_rcv) will send Reset */
+ dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
return 1;
}
@@ -486,36 +468,17 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (dccp_parse_options(sk, skb))
goto discard;
- if (DCCP_SKB_CB(skb)->dccpd_ack_seq !=
- DCCP_PKT_WITHOUT_ACK_SEQ)
+ if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
dccp_event_ack_recv(sk, skb);
ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
- /*
- * FIXME: check ECN to see if we should use
- * DCCP_ACKPKTS_STATE_ECN_MARKED
- */
- if (dp->dccps_options.dccpo_send_ack_vector) {
- if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts,
- DCCP_SKB_CB(skb)->dccpd_seq,
- DCCP_ACKPKTS_STATE_RECEIVED))
- goto discard;
- /*
- * FIXME: this activation is probably wrong, have to
- * study more TCP delack machinery and how it fits into
- * DCCP draft, but for now it kinda "works" 8)
- */
- if ((dp->dccps_hc_rx_ackpkts->dccpap_ack_seqno ==
- DCCP_MAX_SEQNO + 1) &&
- !inet_csk_ack_scheduled(sk)) {
- inet_csk_schedule_ack(sk);
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
- TCP_DELACK_MIN,
- DCCP_RTO_MAX);
- }
- }
+ if (dp->dccps_options.dccpo_send_ack_vector &&
+ dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+ DCCP_SKB_CB(skb)->dccpd_seq,
+ DCCP_ACKVEC_STATE_RECEIVED))
+ goto discard;
}
/*
@@ -550,8 +513,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
dh->dccph_type == DCCP_PKT_REQUEST) ||
(sk->sk_state == DCCP_RESPOND &&
dh->dccph_type == DCCP_PKT_DATA)) {
- dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
- DCCP_PKT_SYNC);
+ dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
goto discard;
} else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
dccp_rcv_closereq(sk, skb);
@@ -561,8 +523,14 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
return 0;
}
+ if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) {
+ dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK);
+ goto discard;
+ }
+
switch (sk->sk_state) {
case DCCP_CLOSED:
+ dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
return 1;
case DCCP_REQUESTING:
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3fc75dbee4b8..6298cf58ff9e 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -23,6 +23,7 @@
#include <net/tcp_states.h>
#include <net/xfrm.h>
+#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"
@@ -61,27 +62,27 @@ static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
const int dif = sk->sk_bound_dev_if;
INET_ADDR_COOKIE(acookie, saddr, daddr)
const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
- const int hash = inet_ehashfn(daddr, lport, saddr, inet->dport,
- dccp_hashinfo.ehash_size);
- struct inet_ehash_bucket *head = &dccp_hashinfo.ehash[hash];
+ unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(&dccp_hashinfo, hash);
const struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ prefetch(head->chain.first);
write_lock(&head->lock);
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &(head + dccp_hashinfo.ehash_size)->chain) {
tw = inet_twsk(sk2);
- if (INET_TW_MATCH(sk2, acookie, saddr, daddr, ports, dif))
+ if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
goto not_unique;
}
tw = NULL;
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET_MATCH(sk2, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
goto not_unique;
}
@@ -89,7 +90,7 @@ static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
* in hash table socket with a funny identity. */
inet->num = lport;
inet->sport = htons(lport);
- sk->sk_hashent = hash;
+ sk->sk_hash = hash;
BUG_TRAP(sk_unhashed(sk));
__sk_add_node(sk, &head->chain);
sock_prot_inc_use(sk->sk_prot);
@@ -246,6 +247,9 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
dp->dccps_role = DCCP_ROLE_CLIENT;
+ if (dccp_service_not_initialized(sk))
+ return -EPROTO;
+
if (addr_len < sizeof(struct sockaddr_in))
return -EINVAL;
@@ -459,6 +463,7 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
if (skb != NULL) {
const struct inet_request_sock *ireq = inet_rsk(req);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
ireq->rmt_addr,
ireq->opt);
@@ -641,16 +646,13 @@ int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
skb = dccp_make_reset(sk, sk->sk_dst_cache, code);
if (skb != NULL) {
- const struct dccp_sock *dp = dccp_sk(sk);
const struct inet_sock *inet = inet_sk(sk);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
err = ip_build_and_send_pkt(skb, sk,
inet->saddr, inet->daddr, NULL);
if (err == NET_XMIT_CN)
err = 0;
-
- ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
- ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
}
return err;
@@ -665,6 +667,16 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
dccp_hdr(skb)->dccph_sport);
}
+static inline int dccp_bad_service_code(const struct sock *sk,
+ const __u32 service)
+{
+ const struct dccp_sock *dp = dccp_sk(sk);
+
+ if (dp->dccps_service == service)
+ return 0;
+ return !dccp_list_has_service(dp->dccps_service_list, service);
+}
+
int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct inet_request_sock *ireq;
@@ -673,13 +685,22 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
struct dccp_request_sock *dreq;
const __u32 saddr = skb->nh.iph->saddr;
const __u32 daddr = skb->nh.iph->daddr;
+ const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
+ struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+ __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
struct dst_entry *dst = NULL;
/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
if (((struct rtable *)skb->dst)->rt_flags &
- (RTCF_BROADCAST | RTCF_MULTICAST))
+ (RTCF_BROADCAST | RTCF_MULTICAST)) {
+ reset_code = DCCP_RESET_CODE_NO_CONNECTION;
goto drop;
+ }
+ if (dccp_bad_service_code(sk, service)) {
+ reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
+ goto drop;
+ }
/*
* TW buckets are converted to open requests without
* limitations, they conserve resources and peer is
@@ -722,9 +743,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
* dccp_create_openreq_child.
*/
dreq = dccp_rsk(req);
- dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq;
- dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
- dreq->dreq_service = dccp_hdr_request(skb)->dccph_req_service;
+ dreq->dreq_isr = dcb->dccpd_seq;
+ dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
+ dreq->dreq_service = service;
if (dccp_v4_send_response(sk, req, dst))
goto drop_and_free;
@@ -739,6 +760,7 @@ drop_and_free:
__reqsk_free(req);
drop:
DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+ dcb->dccpd_reset_code = reset_code;
return -1;
}
@@ -1009,7 +1031,6 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
return 0;
reset:
- DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
dccp_v4_ctl_send_reset(skb);
discard:
kfree_skb(skb);
@@ -1094,45 +1115,7 @@ int dccp_v4_rcv(struct sk_buff *skb)
goto discard_it;
dh = dccp_hdr(skb);
-#if 0
- /*
- * Use something like this to simulate some DATA/DATAACK loss to test
- * dccp_ackpkts_add, you'll get something like this on a session that
- * sends 10 DATA/DATAACK packets:
- *
- * ackpkts_print: 281473596467422 |0,0|3,0|0,0|3,0|0,0|3,0|0,0|3,0|0,1|
- *
- * 0, 0 means: DCCP_ACKPKTS_STATE_RECEIVED, RLE == just this packet
- * 0, 1 means: DCCP_ACKPKTS_STATE_RECEIVED, RLE == two adjacent packets
- * with the same state
- * 3, 0 means: DCCP_ACKPKTS_STATE_NOT_RECEIVED, RLE == just this packet
- *
- * So...
- *
- * 281473596467422 was received
- * 281473596467421 was not received
- * 281473596467420 was received
- * 281473596467419 was not received
- * 281473596467418 was received
- * 281473596467417 was not received
- * 281473596467416 was received
- * 281473596467415 was not received
- * 281473596467414 was received
- * 281473596467413 was received (this one was the 3way handshake
- * RESPONSE)
- *
- */
- if (dh->dccph_type == DCCP_PKT_DATA ||
- dh->dccph_type == DCCP_PKT_DATAACK) {
- static int discard = 0;
- if (discard) {
- discard = 0;
- goto discard_it;
- }
- discard = 1;
- }
-#endif
DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb);
DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
@@ -1243,13 +1226,12 @@ 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 =
- dccp_ackpkts_alloc(DCCP_MAX_ACK_VECTOR_LEN,
- GFP_KERNEL);
-
- if (dp->dccps_hc_rx_ackpkts == NULL)
+ dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(DCCP_MAX_ACKVEC_LEN,
+ GFP_KERNEL);
+ if (dp->dccps_hc_rx_ackvec == NULL)
return -ENOMEM;
}
@@ -1261,16 +1243,18 @@ static int dccp_v4_init_sock(struct sock *sk)
* setsockopt(CCIDs-I-want/accept). -acme
*/
if (likely(!dccp_ctl_socket_init)) {
- dp->dccps_hc_rx_ccid = ccid_init(dp->dccps_options.dccpo_ccid,
+ dp->dccps_hc_rx_ccid = ccid_init(dp->dccps_options.dccpo_rx_ccid,
sk);
- dp->dccps_hc_tx_ccid = ccid_init(dp->dccps_options.dccpo_ccid,
+ dp->dccps_hc_tx_ccid = ccid_init(dp->dccps_options.dccpo_tx_ccid,
sk);
if (dp->dccps_hc_rx_ccid == NULL ||
dp->dccps_hc_tx_ccid == NULL) {
ccid_exit(dp->dccps_hc_rx_ccid, sk);
ccid_exit(dp->dccps_hc_tx_ccid, sk);
- dccp_ackpkts_free(dp->dccps_hc_rx_ackpkts);
- dp->dccps_hc_rx_ackpkts = NULL;
+ if (dp->dccps_options.dccpo_send_ack_vector) {
+ dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
+ dp->dccps_hc_rx_ackvec = NULL;
+ }
dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
return -ENOMEM;
}
@@ -1283,6 +1267,7 @@ static int dccp_v4_init_sock(struct sock *sk)
sk->sk_write_space = dccp_write_space;
dp->dccps_mss_cache = 536;
dp->dccps_role = DCCP_ROLE_UNDEFINED;
+ dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
return 0;
}
@@ -1304,10 +1289,17 @@ static int dccp_v4_destroy_sock(struct sock *sk)
if (inet_csk(sk)->icsk_bind_hash != NULL)
inet_put_port(&dccp_hashinfo, sk);
+ if (dp->dccps_service_list != NULL) {
+ kfree(dp->dccps_service_list);
+ dp->dccps_service_list = NULL;
+ }
+
ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
- dccp_ackpkts_free(dp->dccps_hc_rx_ackpkts);
- dp->dccps_hc_rx_ackpkts = NULL;
+ if (dp->dccps_options.dccpo_send_ack_vector) {
+ dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
+ dp->dccps_hc_rx_ackvec = NULL;
+ }
ccid_exit(dp->dccps_hc_rx_ccid, sk);
ccid_exit(dp->dccps_hc_tx_ccid, sk);
dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index ce5dff4ac22e..1393461898bb 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -19,6 +19,7 @@
#include <net/xfrm.h>
#include <net/inet_timewait_sock.h>
+#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"
@@ -93,21 +94,24 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
struct inet_connection_sock *newicsk = inet_csk(sk);
struct dccp_sock *newdp = dccp_sk(newsk);
- newdp->dccps_hc_rx_ackpkts = NULL;
- newdp->dccps_role = DCCP_ROLE_SERVER;
- newicsk->icsk_rto = DCCP_TIMEOUT_INIT;
+ newdp->dccps_role = DCCP_ROLE_SERVER;
+ newdp->dccps_hc_rx_ackvec = NULL;
+ newdp->dccps_service_list = NULL;
+ newdp->dccps_service = dreq->dreq_service;
+ newicsk->icsk_rto = DCCP_TIMEOUT_INIT;
+ do_gettimeofday(&newdp->dccps_epoch);
if (newdp->dccps_options.dccpo_send_ack_vector) {
- newdp->dccps_hc_rx_ackpkts =
- dccp_ackpkts_alloc(DCCP_MAX_ACK_VECTOR_LEN,
- GFP_ATOMIC);
+ newdp->dccps_hc_rx_ackvec =
+ dccp_ackvec_alloc(DCCP_MAX_ACKVEC_LEN,
+ GFP_ATOMIC);
/*
* XXX: We're using the same CCIDs set on the parent,
* i.e. sk_clone copied the master sock and left the
* CCID pointers for this child, that is why we do the
* __ccid_get calls.
*/
- if (unlikely(newdp->dccps_hc_rx_ackpkts == NULL))
+ if (unlikely(newdp->dccps_hc_rx_ackvec == NULL))
goto out_free;
}
@@ -115,7 +119,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
newsk) != 0 ||
ccid_hc_tx_init(newdp->dccps_hc_tx_ccid,
newsk) != 0)) {
- dccp_ackpkts_free(newdp->dccps_hc_rx_ackpkts);
+ dccp_ackvec_free(newdp->dccps_hc_rx_ackvec);
ccid_hc_rx_exit(newdp->dccps_hc_rx_ccid, newsk);
ccid_hc_tx_exit(newdp->dccps_hc_tx_ccid, newsk);
out_free:
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 382c5894acb2..0a76426c9aea 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -18,19 +18,15 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
+#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"
-static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
- struct sock *sk,
- const u64 ackno,
- const unsigned char len,
- const unsigned char *vector);
-
/* stores the default values for new connection. may be changed with sysctl */
static const struct dccp_options dccpo_default_values = {
.dccpo_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW,
- .dccpo_ccid = DCCPF_INITIAL_CCID,
+ .dccpo_rx_ccid = DCCPF_INITIAL_CCID,
+ .dccpo_tx_ccid = DCCPF_INITIAL_CCID,
.dccpo_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR,
.dccpo_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT,
};
@@ -72,6 +68,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));
@@ -112,25 +109,13 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
opt_recv->dccpor_ndp);
break;
case DCCPO_ACK_VECTOR_0:
- if (len > DCCP_MAX_ACK_VECTOR_LEN)
- goto out_invalid_option;
-
+ case DCCPO_ACK_VECTOR_1:
if (pkt_type == DCCP_PKT_DATA)
continue;
- opt_recv->dccpor_ack_vector_len = len;
- opt_recv->dccpor_ack_vector_idx = value - options;
-
- dccp_pr_debug("%sACK vector 0, len=%d, ack_ackno=%llu\n",
- debug_prefix, len,
- (unsigned long long)
- DCCP_SKB_CB(skb)->dccpd_ack_seq);
- dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq,
- value, len);
- dccp_ackpkts_check_rcv_ackvector(dp->dccps_hc_rx_ackpkts,
- sk,
- DCCP_SKB_CB(skb)->dccpd_ack_seq,
- len, value);
+ if (dp->dccps_options.dccpo_send_ack_vector &&
+ dccp_ackvec_parse(sk, skb, opt, value, len))
+ goto out_invalid_option;
break;
case DCCPO_TIMESTAMP:
if (len != 4)
@@ -139,7 +124,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 +144,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 +165,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:
@@ -350,89 +336,29 @@ void dccp_insert_option_elapsed_time(struct sock *sk,
EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
-static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
+void dccp_timestamp(const struct sock *sk, struct timeval *tv)
{
- struct dccp_sock *dp = dccp_sk(sk);
-#ifdef CONFIG_IP_DCCP_DEBUG
- const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
- "CLIENT TX opt: " : "server TX opt: ";
-#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;
- unsigned char *to, *from;
+ const struct dccp_sock *dp = dccp_sk(sk);
- if (elapsed_time != 0)
- dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
+ do_gettimeofday(tv);
+ tv->tv_sec -= dp->dccps_epoch.tv_sec;
+ tv->tv_usec -= dp->dccps_epoch.tv_usec;
- if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
- LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to "
- "insert ACK Vector!\n");
- return;
- }
-
- /*
- * XXX: now we have just one ack vector sent record, so
- * we have to wait for it to be cleared.
- *
- * Of course this is not acceptable, but this is just for
- * basic testing now.
- */
- if (ap->dccpap_ack_seqno != DCCP_MAX_SEQNO + 1)
- return;
-
- DCCP_SKB_CB(skb)->dccpd_opt_len += len;
-
- to = skb_push(skb, len);
- *to++ = DCCPO_ACK_VECTOR_0;
- *to++ = len;
-
- len = ap->dccpap_buf_vector_len;
- from = ap->dccpap_buf + ap->dccpap_buf_head;
-
- /* Check if buf_head wraps */
- if (ap->dccpap_buf_head + len > ap->dccpap_buf_len) {
- const unsigned int tailsize = (ap->dccpap_buf_len -
- ap->dccpap_buf_head);
-
- memcpy(to, from, tailsize);
- to += tailsize;
- len -= tailsize;
- from = ap->dccpap_buf;
+ while (tv->tv_usec < 0) {
+ tv->tv_sec--;
+ tv->tv_usec += USEC_PER_SEC;
}
-
- memcpy(to, from, len);
- /*
- * From draft-ietf-dccp-spec-11.txt:
- *
- * For each acknowledgement it sends, the HC-Receiver will add an
- * acknowledgement record. ack_seqno will equal the HC-Receiver
- * sequence number it used for the ack packet; ack_ptr will equal
- * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
- * equal buf_nonce.
- *
- * This implemention uses just one ack record for now.
- */
- ap->dccpap_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
- ap->dccpap_ack_ptr = ap->dccpap_buf_head;
- ap->dccpap_ack_ackno = ap->dccpap_buf_ackno;
- ap->dccpap_ack_nonce = ap->dccpap_buf_nonce;
- ap->dccpap_ack_vector_len = ap->dccpap_buf_vector_len;
-
- dccp_pr_debug("%sACK Vector 0, len=%d, ack_seqno=%llu, "
- "ack_ackno=%llu\n",
- debug_prefix, ap->dccpap_ack_vector_len,
- (unsigned long long) ap->dccpap_ack_seqno,
- (unsigned long long) ap->dccpap_ack_ackno);
}
+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 +376,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");
@@ -502,16 +432,20 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
if (!dccp_packet_without_ack(skb)) {
if (dp->dccps_options.dccpo_send_ack_vector &&
- (dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno !=
- DCCP_MAX_SEQNO + 1))
- dccp_insert_option_ack_vector(sk, skb);
-
+ dccp_ackvec_pending(dp->dccps_hc_rx_ackvec))
+ dccp_insert_option_ackvec(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 */
@@ -526,330 +460,3 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
}
}
}
-
-struct dccp_ackpkts *dccp_ackpkts_alloc(const unsigned int len,
- const unsigned int __nocast priority)
-{
- struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority);
-
- if (ap != NULL) {
-#ifdef CONFIG_IP_DCCP_DEBUG
- memset(ap->dccpap_buf, 0xFF, len);
-#endif
- ap->dccpap_buf_len = len;
- ap->dccpap_buf_head =
- ap->dccpap_buf_tail =
- ap->dccpap_buf_len - 1;
- ap->dccpap_buf_ackno =
- ap->dccpap_ack_ackno =
- ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
- ap->dccpap_buf_nonce = ap->dccpap_buf_nonce = 0;
- ap->dccpap_ack_ptr = 0;
- ap->dccpap_time.tv_sec = 0;
- ap->dccpap_time.tv_usec = 0;
- ap->dccpap_buf_vector_len = ap->dccpap_ack_vector_len = 0;
- }
-
- return ap;
-}
-
-void dccp_ackpkts_free(struct dccp_ackpkts *ap)
-{
- if (ap != NULL) {
-#ifdef CONFIG_IP_DCCP_DEBUG
- memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len);
-#endif
- kfree(ap);
- }
-}
-
-static inline u8 dccp_ackpkts_state(const struct dccp_ackpkts *ap,
- const unsigned int index)
-{
- return ap->dccpap_buf[index] & DCCP_ACKPKTS_STATE_MASK;
-}
-
-static inline u8 dccp_ackpkts_len(const struct dccp_ackpkts *ap,
- const unsigned int index)
-{
- return ap->dccpap_buf[index] & DCCP_ACKPKTS_LEN_MASK;
-}
-
-/*
- * If several packets are missing, the HC-Receiver may prefer to enter multiple
- * bytes with run length 0, rather than a single byte with a larger run length;
- * this simplifies table updates if one of the missing packets arrives.
- */
-static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap,
- const unsigned int packets,
- const unsigned char state)
-{
- unsigned int gap;
- signed long new_head;
-
- if (ap->dccpap_buf_vector_len + packets > ap->dccpap_buf_len)
- return -ENOBUFS;
-
- gap = packets - 1;
- new_head = ap->dccpap_buf_head - packets;
-
- if (new_head < 0) {
- if (gap > 0) {
- memset(ap->dccpap_buf, DCCP_ACKPKTS_STATE_NOT_RECEIVED,
- gap + new_head + 1);
- gap = -new_head;
- }
- new_head += ap->dccpap_buf_len;
- }
-
- ap->dccpap_buf_head = new_head;
-
- if (gap > 0)
- memset(ap->dccpap_buf + ap->dccpap_buf_head + 1,
- DCCP_ACKPKTS_STATE_NOT_RECEIVED, gap);
-
- ap->dccpap_buf[ap->dccpap_buf_head] = state;
- ap->dccpap_buf_vector_len += packets;
- return 0;
-}
-
-/*
- * Implements the draft-ietf-dccp-spec-11.txt Appendix A
- */
-int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
-{
- /*
- * Check at the right places if the buffer is full, if it is, tell the
- * caller to start dropping packets till the HC-Sender acks our ACK
- * vectors, when we will free up space in dccpap_buf.
- *
- * We may well decide to do buffer compression, etc, but for now lets
- * just drop.
- *
- * From Appendix A:
- *
- * Of course, the circular buffer may overflow, either when the
- * HC-Sender is sending data at a very high rate, when the
- * HC-Receiver's acknowledgements are not reaching the HC-Sender,
- * or when the HC-Sender is forgetting to acknowledge those acks
- * (so the HC-Receiver is unable to clean up old state). In this
- * case, the HC-Receiver should either compress the buffer (by
- * increasing run lengths when possible), transfer its state to
- * a larger buffer, or, as a last resort, drop all received
- * packets, without processing them whatsoever, until its buffer
- * shrinks again.
- */
-
- /* See if this is the first ackno being inserted */
- if (ap->dccpap_buf_vector_len == 0) {
- ap->dccpap_buf[ap->dccpap_buf_head] = state;
- ap->dccpap_buf_vector_len = 1;
- } else if (after48(ackno, ap->dccpap_buf_ackno)) {
- const u64 delta = dccp_delta_seqno(ap->dccpap_buf_ackno,
- ackno);
-
- /*
- * Look if the state of this packet is the same as the
- * previous ackno and if so if we can bump the head len.
- */
- if (delta == 1 &&
- dccp_ackpkts_state(ap, ap->dccpap_buf_head) == state &&
- (dccp_ackpkts_len(ap, ap->dccpap_buf_head) <
- DCCP_ACKPKTS_LEN_MASK))
- ap->dccpap_buf[ap->dccpap_buf_head]++;
- else if (dccp_ackpkts_set_buf_head_state(ap, delta, state))
- return -ENOBUFS;
- } else {
- /*
- * A.1.2. Old Packets
- *
- * When a packet with Sequence Number S arrives, and
- * S <= buf_ackno, the HC-Receiver will scan the table
- * for the byte corresponding to S. (Indexing structures
- * could reduce the complexity of this scan.)
- */
- u64 delta = dccp_delta_seqno(ackno, ap->dccpap_buf_ackno);
- unsigned int index = ap->dccpap_buf_head;
-
- while (1) {
- const u8 len = dccp_ackpkts_len(ap, index);
- const u8 state = dccp_ackpkts_state(ap, index);
- /*
- * valid packets not yet in dccpap_buf have a reserved
- * entry, with a len equal to 0.
- */
- if (state == DCCP_ACKPKTS_STATE_NOT_RECEIVED &&
- len == 0 && delta == 0) { /* Found our
- reserved seat! */
- dccp_pr_debug("Found %llu reserved seat!\n",
- (unsigned long long) ackno);
- ap->dccpap_buf[index] = state;
- goto out;
- }
- /* len == 0 means one packet */
- if (delta < len + 1)
- goto out_duplicate;
-
- delta -= len + 1;
- if (++index == ap->dccpap_buf_len)
- index = 0;
- }
- }
-
- ap->dccpap_buf_ackno = ackno;
- do_gettimeofday(&ap->dccpap_time);
-out:
- dccp_pr_debug("");
- dccp_ackpkts_print(ap);
- return 0;
-
-out_duplicate:
- /* Duplicate packet */
- dccp_pr_debug("Received a dup or already considered lost "
- "packet: %llu\n", (unsigned long long) ackno);
- return -EILSEQ;
-}
-
-#ifdef CONFIG_IP_DCCP_DEBUG
-void dccp_ackvector_print(const u64 ackno, const unsigned char *vector,
- int len)
-{
- if (!dccp_debug)
- return;
-
- printk("ACK vector len=%d, ackno=%llu |", len,
- (unsigned long long) ackno);
-
- while (len--) {
- const u8 state = (*vector & DCCP_ACKPKTS_STATE_MASK) >> 6;
- const u8 rl = (*vector & DCCP_ACKPKTS_LEN_MASK);
-
- printk("%d,%d|", state, rl);
- ++vector;
- }
-
- printk("\n");
-}
-
-void dccp_ackpkts_print(const struct dccp_ackpkts *ap)
-{
- dccp_ackvector_print(ap->dccpap_buf_ackno,
- ap->dccpap_buf + ap->dccpap_buf_head,
- ap->dccpap_buf_vector_len);
-}
-#endif
-
-static void dccp_ackpkts_trow_away_ack_record(struct dccp_ackpkts *ap)
-{
- /*
- * As we're keeping track of the ack vector size
- * (dccpap_buf_vector_len) and the sent ack vector size
- * (dccpap_ack_vector_len) we don't need dccpap_buf_tail at all, but
- * keep this code here as in the future we'll implement a vector of
- * ack records, as suggested in draft-ietf-dccp-spec-11.txt
- * Appendix A. -acme
- */
-#if 0
- ap->dccpap_buf_tail = ap->dccpap_ack_ptr + 1;
- if (ap->dccpap_buf_tail >= ap->dccpap_buf_len)
- ap->dccpap_buf_tail -= ap->dccpap_buf_len;
-#endif
- ap->dccpap_buf_vector_len -= ap->dccpap_ack_vector_len;
-}
-
-void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, struct sock *sk,
- u64 ackno)
-{
- /* Check if we actually sent an ACK vector */
- if (ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1)
- return;
-
- if (ackno == ap->dccpap_ack_seqno) {
-#ifdef CONFIG_IP_DCCP_DEBUG
- struct dccp_sock *dp = dccp_sk(sk);
- const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
- "CLIENT rx ack: " : "server rx ack: ";
-#endif
- dccp_pr_debug("%sACK packet 0, len=%d, ack_seqno=%llu, "
- "ack_ackno=%llu, ACKED!\n",
- debug_prefix, 1,
- (unsigned long long) ap->dccpap_ack_seqno,
- (unsigned long long) ap->dccpap_ack_ackno);
- dccp_ackpkts_trow_away_ack_record(ap);
- ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
- }
-}
-
-static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
- struct sock *sk, u64 ackno,
- const unsigned char len,
- const unsigned char *vector)
-{
- unsigned char i;
-
- /* Check if we actually sent an ACK vector */
- if (ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1)
- return;
- /*
- * We're in the receiver half connection, so if the received an ACK
- * vector ackno (e.g. 50) before dccpap_ack_seqno (e.g. 52), we're
- * not interested.
- *
- * Extra explanation with example:
- *
- * if we received an ACK vector with ackno 50, it can only be acking
- * 50, 49, 48, etc, not 52 (the seqno for the ACK vector we sent).
- */
- /* dccp_pr_debug("is %llu < %llu? ", ackno, ap->dccpap_ack_seqno); */
- if (before48(ackno, ap->dccpap_ack_seqno)) {
- /* dccp_pr_debug_cat("yes\n"); */
- return;
- }
- /* dccp_pr_debug_cat("no\n"); */
-
- i = len;
- while (i--) {
- const u8 rl = (*vector & DCCP_ACKPKTS_LEN_MASK);
- u64 ackno_end_rl;
-
- dccp_set_seqno(&ackno_end_rl, ackno - rl);
-
- /*
- * dccp_pr_debug("is %llu <= %llu <= %llu? ", ackno_end_rl,
- * ap->dccpap_ack_seqno, ackno);
- */
- if (between48(ap->dccpap_ack_seqno, ackno_end_rl, ackno)) {
- const u8 state = (*vector &
- DCCP_ACKPKTS_STATE_MASK) >> 6;
- /* dccp_pr_debug_cat("yes\n"); */
-
- if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) {
-#ifdef CONFIG_IP_DCCP_DEBUG
- struct dccp_sock *dp = dccp_sk(sk);
- const char *debug_prefix =
- dp->dccps_role == DCCP_ROLE_CLIENT ?
- "CLIENT rx ack: " : "server rx ack: ";
-#endif
- dccp_pr_debug("%sACK vector 0, len=%d, "
- "ack_seqno=%llu, ack_ackno=%llu, "
- "ACKED!\n",
- debug_prefix, len,
- (unsigned long long)
- ap->dccpap_ack_seqno,
- (unsigned long long)
- ap->dccpap_ack_ackno);
- dccp_ackpkts_trow_away_ack_record(ap);
- }
- /*
- * If dccpap_ack_seqno was not received, no problem
- * we'll send another ACK vector.
- */
- ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
- break;
- }
- /* dccp_pr_debug_cat("no\n"); */
-
- dccp_set_seqno(&ackno, ackno_end_rl - 1);
- ++vector;
- }
-}
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 28de157a4326..d59f86f7ceab 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -16,6 +16,7 @@
#include <net/sock.h>
+#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"
@@ -61,10 +62,8 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
skb->h.raw = skb_push(skb, dccp_header_size);
dh = dccp_hdr(skb);
- /*
- * Data packets are not cloned as they are never retransmitted
- */
- if (skb_cloned(skb))
+
+ if (!skb->sk)
skb_set_owner_w(skb, sk);
/* Build DCCP header and checksum it. */
@@ -85,7 +84,7 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
switch (dcb->dccpd_type) {
case DCCP_PKT_REQUEST:
dccp_hdr_request(skb)->dccph_req_service =
- dcb->dccpd_service;
+ dp->dccps_service;
break;
case DCCP_PKT_RESET:
dccp_hdr_reset(skb)->dccph_reset_code =
@@ -101,6 +100,7 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
err = ip_queue_xmit(skb, 0);
if (err <= 0)
return err;
@@ -225,7 +225,6 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
err = dccp_wait_for_ccid(sk, skb, timeo);
if (err == 0) {
- const struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
const int len = skb->len;
@@ -236,22 +235,15 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
inet_csk(sk)->icsk_rto,
DCCP_RTO_MAX);
dcb->dccpd_type = DCCP_PKT_DATAACK;
- /*
- * FIXME: we really should have a
- * dccps_ack_pending or use icsk.
- */
- } else if (inet_csk_ack_scheduled(sk) ||
- dp->dccps_timestamp_echo != 0 ||
- (dp->dccps_options.dccpo_send_ack_vector &&
- ap->dccpap_buf_ackno != DCCP_MAX_SEQNO + 1 &&
- ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1))
+ } else if (dccp_ack_pending(sk))
dcb->dccpd_type = DCCP_PKT_DATAACK;
else
dcb->dccpd_type = DCCP_PKT_DATA;
err = dccp_transmit_skb(sk, skb);
ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
- }
+ } else
+ kfree_skb(skb);
return err;
}
@@ -270,6 +262,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
struct request_sock *req)
{
struct dccp_hdr *dh;
+ struct dccp_request_sock *dreq;
const int dccp_header_size = sizeof(struct dccp_hdr) +
sizeof(struct dccp_hdr_ext) +
sizeof(struct dccp_hdr_response);
@@ -285,8 +278,9 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
skb->dst = dst_clone(dst);
skb->csum = 0;
+ dreq = dccp_rsk(req);
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
- DCCP_SKB_CB(skb)->dccpd_seq = dccp_rsk(req)->dreq_iss;
+ DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss;
dccp_insert_options(sk, skb);
skb->h.raw = skb_push(skb, dccp_header_size);
@@ -300,8 +294,9 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
dh->dccph_type = DCCP_PKT_RESPONSE;
dh->dccph_x = 1;
- dccp_hdr_set_seq(dh, dccp_rsk(req)->dreq_iss);
- dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dccp_rsk(req)->dreq_isr);
+ dccp_hdr_set_seq(dh, dreq->dreq_iss);
+ dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
+ dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
dh->dccph_checksum = dccp_v4_checksum(skb, inet_rsk(req)->loc_addr,
inet_rsk(req)->rmt_addr);
@@ -397,9 +392,6 @@ int dccp_connect(struct sock *sk)
skb_reserve(skb, MAX_DCCP_HEADER);
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
- /* FIXME: set service to something meaningful, coming
- * from userspace*/
- DCCP_SKB_CB(skb)->dccpd_service = 0;
skb->csum = 0;
skb_set_owner_w(skb, sk);
@@ -503,7 +495,7 @@ void dccp_send_close(struct sock *sk, const int active)
{
struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
- const unsigned int prio = active ? GFP_KERNEL : GFP_ATOMIC;
+ const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;
skb = alloc_skb(sk->sk_prot->max_header, prio);
if (skb == NULL)
@@ -522,7 +514,4 @@ void dccp_send_close(struct sock *sk, const int active)
dccp_transmit_skb(sk, skb_clone(skb, prio));
} else
dccp_transmit_skb(sk, skb);
-
- ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
- ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 18a0e69c9dc7..a021c3422f67 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -94,7 +94,15 @@ EXPORT_SYMBOL_GPL(dccp_state_name);
static inline int dccp_listen_start(struct sock *sk)
{
- dccp_sk(sk)->dccps_role = DCCP_ROLE_LISTEN;
+ struct dccp_sock *dp = dccp_sk(sk);
+
+ dp->dccps_role = DCCP_ROLE_LISTEN;
+ /*
+ * Apps need to use setsockopt(DCCP_SOCKOPT_SERVICE)
+ * before calling listen()
+ */
+ if (dccp_service_not_initialized(sk))
+ return -EPROTO;
return inet_csk_listen_start(sk, TCP_SYNQ_HSIZE);
}
@@ -202,6 +210,42 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
return -ENOIOCTLCMD;
}
+static int dccp_setsockopt_service(struct sock *sk, const u32 service,
+ char __user *optval, int optlen)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+ struct dccp_service_list *sl = NULL;
+
+ if (service == DCCP_SERVICE_INVALID_VALUE ||
+ optlen > DCCP_SERVICE_LIST_MAX_LEN * sizeof(u32))
+ return -EINVAL;
+
+ if (optlen > sizeof(service)) {
+ sl = kmalloc(optlen, GFP_KERNEL);
+ if (sl == NULL)
+ return -ENOMEM;
+
+ sl->dccpsl_nr = optlen / sizeof(u32) - 1;
+ if (copy_from_user(sl->dccpsl_list,
+ optval + sizeof(service),
+ optlen - sizeof(service)) ||
+ dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
+ kfree(sl);
+ return -EFAULT;
+ }
+ }
+
+ lock_sock(sk);
+ dp->dccps_service = service;
+
+ if (dp->dccps_service_list != NULL)
+ kfree(dp->dccps_service_list);
+
+ dp->dccps_service_list = sl;
+ release_sock(sk);
+ return 0;
+}
+
int dccp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen)
{
@@ -218,8 +262,10 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
if (get_user(val, (int __user *)optval))
return -EFAULT;
- lock_sock(sk);
+ if (optname == DCCP_SOCKOPT_SERVICE)
+ return dccp_setsockopt_service(sk, val, optval, optlen);
+ lock_sock(sk);
dp = dccp_sk(sk);
err = 0;
@@ -236,6 +282,37 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
return err;
}
+static int dccp_getsockopt_service(struct sock *sk, int len,
+ u32 __user *optval,
+ int __user *optlen)
+{
+ const struct dccp_sock *dp = dccp_sk(sk);
+ const struct dccp_service_list *sl;
+ int err = -ENOENT, slen = 0, total_len = sizeof(u32);
+
+ lock_sock(sk);
+ if (dccp_service_not_initialized(sk))
+ goto out;
+
+ if ((sl = dp->dccps_service_list) != NULL) {
+ slen = sl->dccpsl_nr * sizeof(u32);
+ total_len += slen;
+ }
+
+ err = -EINVAL;
+ if (total_len > len)
+ goto out;
+
+ err = 0;
+ if (put_user(total_len, optlen) ||
+ put_user(dp->dccps_service, optval) ||
+ (sl != NULL && copy_to_user(optval + 1, sl->dccpsl_list, slen)))
+ err = -EFAULT;
+out:
+ release_sock(sk);
+ return err;
+}
+
int dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -248,8 +325,7 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- len = min_t(unsigned int, len, sizeof(int));
- if (len < 0)
+ if (len < sizeof(int))
return -EINVAL;
dp = dccp_sk(sk);
@@ -257,7 +333,17 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
switch (optname) {
case DCCP_SOCKOPT_PACKET_SIZE:
val = dp->dccps_packet_size;
+ len = sizeof(dp->dccps_packet_size);
break;
+ case DCCP_SOCKOPT_SERVICE:
+ return dccp_getsockopt_service(sk, len,
+ (u32 __user *)optval, optlen);
+ case 128 ... 191:
+ return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
+ len, (u32 __user *)optval, optlen);
+ case 192 ... 255:
+ return ccid_hc_tx_getsockopt(dp->dccps_hc_tx_ccid, sk, optname,
+ len, (u32 __user *)optval, optlen);
default:
return -ENOPROTOOPT;
}
@@ -316,8 +402,6 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
* This bug was _quickly_ found & fixed by just looking at an OSTRA
* generated callgraph 8) -acme
*/
- if (rc != 0)
- goto out_discard;
out_release:
release_sock(sk);
return rc ? : len;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 348f36b529f7..3f25cadccddd 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -452,7 +452,7 @@ static struct proto dn_proto = {
.obj_size = sizeof(struct dn_sock),
};
-static struct sock *dn_alloc_sock(struct socket *sock, int gfp)
+static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp)
{
struct dn_scp *scp;
struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1);
@@ -719,22 +719,9 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (saddr->sdn_flags & ~SDF_WILD)
return -EINVAL;
-#if 1
if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
(saddr->sdn_flags & SDF_WILD)))
return -EACCES;
-#else
- /*
- * Maybe put the default actions in the default security ops for
- * dn_prot_sock ? Would be nice if the capable call would go there
- * too.
- */
- if (security_dn_prot_sock(saddr) &&
- !capable(CAP_NET_BIND_SERVICE) ||
- saddr->sdn_objnum || (saddr->sdn_flags & SDF_WILD))
- return -EACCES;
-#endif
-
if (!(saddr->sdn_flags & SDF_WILD)) {
if (dn_ntohs(saddr->sdn_nodeaddrl)) {
@@ -804,7 +791,7 @@ static int dn_auto_bind(struct socket *sock)
return rv;
}
-static int dn_confirm_accept(struct sock *sk, long *timeo, int allocation)
+static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
{
struct dn_scp *scp = DN_SK(sk);
DEFINE_WAIT(wait);
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index 53633d352868..c96c767b1f74 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -117,7 +117,7 @@ try_again:
* The eventual aim is for each socket to have a cached header size
* for its outgoing packets, and to set hdr from this when sk != NULL.
*/
-struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri)
+struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri)
{
struct sk_buff *skb;
int hdr = 64;
@@ -210,7 +210,8 @@ static void dn_nsp_rtt(struct sock *sk, long rtt)
*
* Returns: The number of times the packet has been sent previously
*/
-static inline unsigned dn_nsp_clone_and_send(struct sk_buff *skb, int gfp)
+static inline unsigned dn_nsp_clone_and_send(struct sk_buff *skb,
+ gfp_t gfp)
{
struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct sk_buff *skb2;
@@ -350,7 +351,8 @@ static unsigned short *dn_nsp_mk_data_header(struct sock *sk, struct sk_buff *sk
return ptr;
}
-void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oth)
+void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb,
+ gfp_t gfp, int oth)
{
struct dn_scp *scp = DN_SK(sk);
struct dn_skb_cb *cb = DN_SKB_CB(skb);
@@ -517,7 +519,7 @@ static int dn_nsp_retrans_conn_conf(struct sock *sk)
return 0;
}
-void dn_send_conn_conf(struct sock *sk, int gfp)
+void dn_send_conn_conf(struct sock *sk, gfp_t gfp)
{
struct dn_scp *scp = DN_SK(sk);
struct sk_buff *skb = NULL;
@@ -549,7 +551,8 @@ void dn_send_conn_conf(struct sock *sk, int gfp)
static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
- unsigned short reason, int gfp, struct dst_entry *dst,
+ unsigned short reason, gfp_t gfp,
+ struct dst_entry *dst,
int ddl, unsigned char *dd, __u16 rem, __u16 loc)
{
struct sk_buff *skb = NULL;
@@ -591,7 +594,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg,
- unsigned short reason, int gfp)
+ unsigned short reason, gfp_t gfp)
{
struct dn_scp *scp = DN_SK(sk);
int ddl = 0;
@@ -612,7 +615,7 @@ void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg,
{
struct dn_skb_cb *cb = DN_SKB_CB(skb);
int ddl = 0;
- int gfp = GFP_ATOMIC;
+ gfp_t gfp = GFP_ATOMIC;
dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl,
NULL, cb->src_port, cb->dst_port);
@@ -624,7 +627,7 @@ void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval)
struct dn_scp *scp = DN_SK(sk);
struct sk_buff *skb;
unsigned char *ptr;
- int gfp = GFP_ATOMIC;
+ gfp_t gfp = GFP_ATOMIC;
if ((skb = dn_alloc_skb(sk, DN_MAX_NSP_DATA_HEADER + 2, gfp)) == NULL)
return;
@@ -659,7 +662,7 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
unsigned char menuver;
struct dn_skb_cb *cb;
unsigned char type = 1;
- int allocation = (msgflg == NSP_CI) ? sk->sk_allocation : GFP_ATOMIC;
+ gfp_t allocation = (msgflg == NSP_CI) ? sk->sk_allocation : GFP_ATOMIC;
struct sk_buff *skb = dn_alloc_skb(sk, 200, allocation);
if (!skb)
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2c915f305be3..3407f190afe8 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -117,8 +117,7 @@ static struct dn_rt_hash_bucket *dn_rt_hash_table;
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/econet/af_econet.c b/net/econet/af_econet.c
index 4a62093eb343..34fdac51df96 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -406,7 +406,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
unsigned long network = 0;
rcu_read_lock();
- idev = __in_dev_get(dev);
+ idev = __in_dev_get_rcu(dev);
if (idev) {
if (idev->ifa_list)
network = ntohl(idev->ifa_list->ifa_address) &
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 87a052a9a84f..68a5ca866442 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -146,6 +146,19 @@ int eth_rebuild_header(struct sk_buff *skb)
return 0;
}
+static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b)
+{
+ const unsigned short *dest = (unsigned short *) __a;
+ const unsigned short *devaddr = (unsigned short *) __b;
+ unsigned int res;
+
+ BUILD_BUG_ON(ETH_ALEN != 6);
+ res = ((dest[0] ^ devaddr[0]) |
+ (dest[1] ^ devaddr[1]) |
+ (dest[2] ^ devaddr[2])) != 0;
+
+ return res;
+}
/*
* Determine the packet's protocol ID. The rule here is that we
@@ -158,16 +171,15 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
struct ethhdr *eth;
unsigned char *rawp;
- skb->mac.raw=skb->data;
+ skb->mac.raw = skb->data;
skb_pull(skb,ETH_HLEN);
eth = eth_hdr(skb);
- if(*eth->h_dest&1)
- {
- if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
- skb->pkt_type=PACKET_BROADCAST;
+ if (*eth->h_dest&1) {
+ if (!compare_eth_addr(eth->h_dest, dev->broadcast))
+ skb->pkt_type = PACKET_BROADCAST;
else
- skb->pkt_type=PACKET_MULTICAST;
+ skb->pkt_type = PACKET_MULTICAST;
}
/*
@@ -178,10 +190,9 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
* seems to set IFF_PROMISC.
*/
- else if(1 /*dev->flags&IFF_PROMISC*/)
- {
- if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
- skb->pkt_type=PACKET_OTHERHOST;
+ else if(1 /*dev->flags&IFF_PROMISC*/) {
+ if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr)))
+ skb->pkt_type = PACKET_OTHERHOST;
}
if (ntohs(eth->h_proto) >= 1536)
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index 58ed4319e693..91b16fbf91f0 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -1,6 +1,5 @@
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/ieee80211/Makefile b/net/ieee80211/Makefile
index a6ccac5baea8..f988417121da 100644
--- a/net/ieee80211/Makefile
+++ b/net/ieee80211/Makefile
@@ -7,5 +7,6 @@ ieee80211-objs := \
ieee80211_module.o \
ieee80211_tx.o \
ieee80211_rx.o \
- ieee80211_wx.o
+ ieee80211_wx.o \
+ ieee80211_geo.o
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 61a9d92e455b..f3b6aa3be638 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -41,6 +41,12 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ieee->lock, flags);
+
+ if (list_empty(&ieee->crypt_deinit_list))
+ goto unlock;
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
@@ -57,6 +63,18 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
}
kfree(entry);
}
+ unlock:
+ spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+/* After this, crypt_deinit_list won't accept new members */
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ ieee->crypt_quiesced = 1;
+ spin_unlock_irqrestore(&ieee->lock, flags);
}
void ieee80211_crypt_deinit_handler(unsigned long data)
@@ -64,16 +82,16 @@ void ieee80211_crypt_deinit_handler(unsigned long data)
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
unsigned long flags;
- spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
- if (!list_empty(&ieee->crypt_deinit_list)) {
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
"deletion list\n", ieee->dev->name);
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
-
}
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
@@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
* locking. */
spin_lock_irqsave(&ieee->lock, flags);
- list_add(&tmp->list, &ieee->crypt_deinit_list);
- if (!timer_pending(&ieee->crypt_deinit_timer)) {
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
+ if (!ieee->crypt_quiesced) {
+ list_add(&tmp->list, &ieee->crypt_deinit_list);
+ if (!timer_pending(&ieee->crypt_deinit_timer)) {
+ ieee->crypt_deinit_timer.expires = jiffies + HZ;
+ add_timer(&ieee->crypt_deinit_timer);
+ }
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
@@ -191,18 +211,18 @@ static void ieee80211_crypt_null_deinit(void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- .name = "NULL",
- .init = ieee80211_crypt_null_init,
- .deinit = ieee80211_crypt_null_deinit,
- .encrypt_mpdu = NULL,
- .decrypt_mpdu = NULL,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = NULL,
- .get_key = NULL,
- .extra_prefix_len = 0,
- .extra_postfix_len = 0,
- .owner = THIS_MODULE,
+ .name = "NULL",
+ .init = ieee80211_crypt_null_init,
+ .deinit = ieee80211_crypt_null_deinit,
+ .encrypt_mpdu = NULL,
+ .decrypt_mpdu = NULL,
+ .encrypt_msdu = NULL,
+ .decrypt_msdu = NULL,
+ .set_key = NULL,
+ .get_key = NULL,
+ .extra_mpdu_prefix_len = 0,
+ .extra_mpdu_postfix_len = 0,
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_init(void)
@@ -249,6 +269,7 @@ static void __exit ieee80211_crypto_deinit(void)
EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
+EXPORT_SYMBOL(ieee80211_crypt_quiescing);
EXPORT_SYMBOL(ieee80211_register_crypto_ops);
EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 8fc13f45971e..05a853c13012 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -119,7 +119,7 @@ static inline void xor_block(u8 * b, u8 * a, size_t len)
}
static void ccmp_init_blocks(struct crypto_tfm *tfm,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
{
u8 *pos, qc = 0;
@@ -191,26 +191,18 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
}
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
- int data_len, i, blocks, last, len;
- u8 *pos, *mic;
- struct ieee80211_hdr *hdr;
- u8 *b0 = key->tx_b0;
- u8 *b = key->tx_b;
- u8 *e = key->tx_e;
- u8 *s0 = key->tx_s0;
+ int i;
+ u8 *pos;
- if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
+ if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
return -1;
- data_len = skb->len - hdr_len;
pos = skb_push(skb, CCMP_HDR_LEN);
memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
pos += hdr_len;
- mic = skb_put(skb, CCMP_MIC_LEN);
i = CCMP_PN_LEN - 1;
while (i >= 0) {
@@ -229,7 +221,31 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
*pos++ = key->tx_pn[1];
*pos++ = key->tx_pn[0];
- hdr = (struct ieee80211_hdr *)skb->data;
+ return CCMP_HDR_LEN;
+}
+
+static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+ struct ieee80211_ccmp_data *key = priv;
+ int data_len, i, blocks, last, len;
+ u8 *pos, *mic;
+ struct ieee80211_hdr_4addr *hdr;
+ u8 *b0 = key->tx_b0;
+ u8 *b = key->tx_b;
+ u8 *e = key->tx_e;
+ u8 *s0 = key->tx_s0;
+
+ if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
+ return -1;
+
+ data_len = skb->len - hdr_len;
+ len = ieee80211_ccmp_hdr(skb, hdr_len, priv);
+ if (len < 0)
+ return -1;
+
+ pos = skb->data + hdr_len + CCMP_HDR_LEN;
+ mic = skb_put(skb, CCMP_MIC_LEN);
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
@@ -258,7 +274,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
u8 keyidx, *pos;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u8 *b0 = key->rx_b0;
u8 *b = key->rx_b;
u8 *a = key->rx_a;
@@ -272,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return -1;
}
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
@@ -426,19 +442,20 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- .name = "CCMP",
- .init = ieee80211_ccmp_init,
- .deinit = ieee80211_ccmp_deinit,
- .encrypt_mpdu = ieee80211_ccmp_encrypt,
- .decrypt_mpdu = ieee80211_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = ieee80211_ccmp_set_key,
- .get_key = ieee80211_ccmp_get_key,
- .print_stats = ieee80211_ccmp_print_stats,
- .extra_prefix_len = CCMP_HDR_LEN,
- .extra_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
+ .name = "CCMP",
+ .init = ieee80211_ccmp_init,
+ .deinit = ieee80211_ccmp_deinit,
+ .build_iv = ieee80211_ccmp_hdr,
+ .encrypt_mpdu = ieee80211_ccmp_encrypt,
+ .decrypt_mpdu = ieee80211_ccmp_decrypt,
+ .encrypt_msdu = NULL,
+ .decrypt_msdu = NULL,
+ .set_key = ieee80211_ccmp_set_key,
+ .get_key = ieee80211_ccmp_get_key,
+ .print_stats = ieee80211_ccmp_print_stats,
+ .extra_mpdu_prefix_len = CCMP_HDR_LEN,
+ .extra_mpdu_postfix_len = CCMP_MIC_LEN,
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_ccmp_init(void)
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index d4f9164be1a1..2e34f29b7956 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -59,8 +59,24 @@ struct ieee80211_tkip_data {
/* scratch buffers for virt_to_page() (crypto API) */
u8 rx_hdr[16], tx_hdr[16];
+
+ unsigned long flags;
};
+static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
+{
+ struct ieee80211_tkip_data *_priv = priv;
+ unsigned long old_flags = _priv->flags;
+ _priv->flags = flags;
+ return old_flags;
+}
+
+static unsigned long ieee80211_tkip_get_flags(void *priv)
+{
+ struct ieee80211_tkip_data *_priv = priv;
+ return _priv->flags;
+}
+
static void *ieee80211_tkip_init(int key_idx)
{
struct ieee80211_tkip_data *priv;
@@ -69,6 +85,7 @@ static void *ieee80211_tkip_init(int key_idx)
if (priv == NULL)
goto fail;
memset(priv, 0, sizeof(*priv));
+
priv->key_idx = key_idx;
priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
@@ -255,25 +272,27 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
#endif
}
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
int len;
- u8 rc4key[16], *pos, *icv;
- struct ieee80211_hdr *hdr;
+ u8 *rc4key, *pos, *icv;
+ struct ieee80211_hdr_4addr *hdr;
u32 crc;
- struct scatterlist sg;
- if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
+
+ if (skb_headroom(skb) < 8 || skb->len < hdr_len)
+ return NULL;
- hdr = (struct ieee80211_hdr *)skb->data;
if (!tkey->tx_phase1_done) {
tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
tkey->tx_iv32);
tkey->tx_phase1_done = 1;
}
+ rc4key = kmalloc(16, GFP_ATOMIC);
+ if (!rc4key)
+ return NULL;
tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
len = skb->len - hdr_len;
@@ -282,9 +301,9 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos += hdr_len;
icv = skb_put(skb, 4);
- *pos++ = rc4key[0];
- *pos++ = rc4key[1];
- *pos++ = rc4key[2];
+ *pos++ = *rc4key;
+ *pos++ = *(rc4key + 1);
+ *pos++ = *(rc4key + 2);
*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
*pos++ = tkey->tx_iv32 & 0xff;
*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
@@ -297,6 +316,38 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[2] = crc >> 16;
icv[3] = crc >> 24;
+ return rc4key;
+}
+
+static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+ struct ieee80211_tkip_data *tkey = priv;
+ int len;
+ const u8 *rc4key;
+ u8 *pos;
+ struct scatterlist sg;
+
+ if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
+ if (net_ratelimit()) {
+ struct ieee80211_hdr_4addr *hdr =
+ (struct ieee80211_hdr_4addr *)skb->data;
+ printk(KERN_DEBUG "TKIP countermeasures: dropped "
+ "TX packet to " MAC_FMT "\n",
+ MAC_ARG(hdr->addr1));
+ }
+ return -1;
+ }
+
+ if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
+ return -1;
+
+ len = skb->len - hdr_len;
+ pos = skb->data + hdr_len;
+
+ rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
+ if (!rc4key)
+ return -1;
+
crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
@@ -319,16 +370,26 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
u8 keyidx, *pos;
u32 iv32;
u16 iv16;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u8 icv[4];
u32 crc;
struct scatterlist sg;
int plen;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
+
+ if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
+ if (net_ratelimit()) {
+ printk(KERN_DEBUG "TKIP countermeasures: dropped "
+ "received packet from " MAC_FMT "\n",
+ MAC_ARG(hdr->addr2));
+ }
+ return -1;
+ }
+
if (skb->len < hdr_len + 8 + 4)
return -1;
- hdr = (struct ieee80211_hdr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
@@ -441,9 +502,9 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
{
- struct ieee80211_hdr *hdr11;
+ struct ieee80211_hdr_4addr *hdr11;
- hdr11 = (struct ieee80211_hdr *)skb->data;
+ hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
switch (le16_to_cpu(hdr11->frame_ctl) &
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
case IEEE80211_FCTL_TODS:
@@ -490,9 +551,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
return 0;
}
-#if WIRELESS_EXT >= 18
static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr, int keyidx)
+ struct ieee80211_hdr_4addr *hdr,
+ int keyidx)
{
union iwreq_data wrqu;
struct iw_michaelmicfailure ev;
@@ -510,28 +571,6 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
wrqu.data.length = sizeof(ev);
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}
-#elif WIRELESS_EXT >= 15
-static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr, int keyidx)
-{
- union iwreq_data wrqu;
- char buf[128];
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
- MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
- MAC_ARG(hdr->addr2));
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = strlen(buf);
- wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
-}
-#else /* WIRELESS_EXT >= 15 */
-static inline void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr,
- int keyidx)
-{
-}
-#endif /* WIRELESS_EXT >= 15 */
static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv)
@@ -547,8 +586,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
return -1;
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr *hdr;
- hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_hdr_4addr *hdr;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
"MSDU from " MAC_FMT " keyidx=%d\n",
skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
@@ -654,19 +693,22 @@ static char *ieee80211_tkip_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- .name = "TKIP",
- .init = ieee80211_tkip_init,
- .deinit = ieee80211_tkip_deinit,
- .encrypt_mpdu = ieee80211_tkip_encrypt,
- .decrypt_mpdu = ieee80211_tkip_decrypt,
- .encrypt_msdu = ieee80211_michael_mic_add,
- .decrypt_msdu = ieee80211_michael_mic_verify,
- .set_key = ieee80211_tkip_set_key,
- .get_key = ieee80211_tkip_get_key,
- .print_stats = ieee80211_tkip_print_stats,
- .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_postfix_len = 8 + 4, /* MIC + ICV */
- .owner = THIS_MODULE,
+ .name = "TKIP",
+ .init = ieee80211_tkip_init,
+ .deinit = ieee80211_tkip_deinit,
+ .encrypt_mpdu = ieee80211_tkip_encrypt,
+ .decrypt_mpdu = ieee80211_tkip_decrypt,
+ .encrypt_msdu = ieee80211_michael_mic_add,
+ .decrypt_msdu = ieee80211_michael_mic_verify,
+ .set_key = ieee80211_tkip_set_key,
+ .get_key = ieee80211_tkip_get_key,
+ .print_stats = ieee80211_tkip_print_stats,
+ .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
+ .extra_mpdu_postfix_len = 4, /* ICV */
+ .extra_msdu_postfix_len = 8, /* MIC */
+ .get_flags = ieee80211_tkip_get_flags,
+ .set_flags = ieee80211_tkip_set_flags,
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_tkip_init(void)
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index b4d2514a0902..7c08ed2f2628 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -229,19 +229,19 @@ static char *prism2_wep_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- .name = "WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_prefix_len = 4, /* IV */
- .extra_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
+ .name = "WEP",
+ .init = prism2_wep_init,
+ .deinit = prism2_wep_deinit,
+ .encrypt_mpdu = prism2_wep_encrypt,
+ .decrypt_mpdu = prism2_wep_decrypt,
+ .encrypt_msdu = NULL,
+ .decrypt_msdu = NULL,
+ .set_key = prism2_wep_set_key,
+ .get_key = prism2_wep_get_key,
+ .print_stats = prism2_wep_print_stats,
+ .extra_mpdu_prefix_len = 4, /* IV */
+ .extra_mpdu_postfix_len = 4, /* ICV */
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_wep_init(void)
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
new file mode 100644
index 000000000000..c4b54ef8f6d5
--- /dev/null
+++ b/net/ieee80211/ieee80211_geo.c
@@ -0,0 +1,141 @@
+/******************************************************************************
+
+ Copyright(c) 2005 Intel Corporation. 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
+ published by the Free Software Foundation.
+
+ 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.
+
+ The full GNU General Public License is included in this distribution in the
+ file called LICENSE.
+
+ Contact Information:
+ James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+******************************************************************************/
+#include <linux/compiler.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+
+#include <net/ieee80211.h>
+
+int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ /* NOTE: If G mode is currently supported but
+ * this is a B only channel, we don't see it
+ * as valid. */
+ if ((ieee->geo.bg[i].channel == channel) &&
+ (!(ieee->mode & IEEE_G) ||
+ !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
+ return IEEE80211_24GHZ_BAND;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].channel == channel)
+ return IEEE80211_52GHZ_BAND;
+
+ return 0;
+}
+
+int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ if (ieee->geo.bg[i].channel == channel)
+ return i;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].channel == channel)
+ return i;
+
+ return -1;
+}
+
+u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ freq /= 100000;
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ if (ieee->geo.bg[i].freq == freq)
+ return ieee->geo.bg[i].channel;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].freq == freq)
+ return ieee->geo.a[i].channel;
+
+ return 0;
+}
+
+int ieee80211_set_geo(struct ieee80211_device *ieee,
+ const struct ieee80211_geo *geo)
+{
+ memcpy(ieee->geo.name, geo->name, 3);
+ ieee->geo.name[3] = '\0';
+ ieee->geo.bg_channels = geo->bg_channels;
+ ieee->geo.a_channels = geo->a_channels;
+ memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
+ sizeof(struct ieee80211_channel));
+ memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
+ sizeof(struct ieee80211_channel));
+ return 0;
+}
+
+const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
+{
+ return &ieee->geo;
+}
+
+EXPORT_SYMBOL(ieee80211_is_valid_channel);
+EXPORT_SYMBOL(ieee80211_freq_to_channel);
+EXPORT_SYMBOL(ieee80211_channel_to_index);
+EXPORT_SYMBOL(ieee80211_set_geo);
+EXPORT_SYMBOL(ieee80211_get_geo);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 03a47343ddc7..f66d792cd204 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(c) 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
@@ -53,12 +53,15 @@
#include <net/ieee80211.h>
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR
- ("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
+#define DRV_DESCRIPTION "802.11 data/management/control stack"
+#define DRV_NAME "ieee80211"
+#define DRV_VERSION IEEE80211_VERSION
+#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
-#define DRV_NAME "ieee80211"
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_LICENSE("GPL");
static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
{
@@ -126,26 +129,34 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
/* Default fragmentation threshold is maximum payload size */
ieee->fts = DEFAULT_FTS;
+ ieee->rts = DEFAULT_FTS;
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
ieee->open_wep = 1;
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee->host_encrypt = 1;
ieee->host_decrypt = 1;
+ ieee->host_mc_decrypt = 1;
+
+ /* Host fragementation in Open mode. Default is enabled.
+ * Note: host fragmentation is always enabled if host encryption
+ * is enabled. For cards can do hardware encryption, they must do
+ * hardware fragmentation as well. So we don't need a variable
+ * like host_enc_frag. */
+ ieee->host_open_frag = 1;
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
init_timer(&ieee->crypt_deinit_timer);
ieee->crypt_deinit_timer.data = (unsigned long)ieee;
ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
+ ieee->crypt_quiesced = 0;
spin_lock_init(&ieee->lock);
ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
ieee->drop_unencrypted = 0;
ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
return dev;
@@ -161,6 +172,7 @@ void free_ieee80211(struct net_device *dev)
int i;
+ ieee80211_crypt_quiescing(ieee);
del_timer_sync(&ieee->crypt_deinit_timer);
ieee80211_crypt_deinit_entries(ieee, 1);
@@ -195,42 +207,30 @@ static int show_debug_level(char *page, char **start, off_t offset,
static int store_debug_level(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
- char buf[] = "0x00000000";
- char *p = (char *)buf;
+ char buf[] = "0x00000000\n";
+ unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
unsigned long val;
- if (count > sizeof(buf) - 1)
- count = sizeof(buf) - 1;
-
- if (copy_from_user(buf, buffer, count))
+ if (copy_from_user(buf, buffer, len))
return count;
- buf[count] = 0;
- /*
- * what a FPOS... What, sscanf(buf, "%i", &val) would be too
- * scary?
- */
- if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
- p++;
- if (p[0] == 'x' || p[0] == 'X')
- p++;
- val = simple_strtoul(p, &p, 16);
- } else
- val = simple_strtoul(p, &p, 10);
- if (p == buf)
+ buf[len] = 0;
+ if (sscanf(buf, "%li", &val) != 1)
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else
ieee80211_debug_level = val;
- return strlen(buf);
+ return strnlen(buf, len);
}
+#endif /* CONFIG_IEEE80211_DEBUG */
static int __init ieee80211_init(void)
{
+#ifdef CONFIG_IEEE80211_DEBUG
struct proc_dir_entry *e;
ieee80211_debug_level = debug;
- ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
+ ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
if (ieee80211_proc == NULL) {
IEEE80211_ERROR("Unable to create " DRV_NAME
" proc directory\n");
@@ -246,26 +246,33 @@ static int __init ieee80211_init(void)
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
+#endif /* CONFIG_IEEE80211_DEBUG */
+
+ printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
+ printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
return 0;
}
static void __exit ieee80211_exit(void)
{
+#ifdef CONFIG_IEEE80211_DEBUG
if (ieee80211_proc) {
remove_proc_entry("debug_level", ieee80211_proc);
remove_proc_entry(DRV_NAME, proc_net);
ieee80211_proc = NULL;
}
+#endif /* CONFIG_IEEE80211_DEBUG */
}
+#ifdef CONFIG_IEEE80211_DEBUG
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
+#endif /* CONFIG_IEEE80211_DEBUG */
module_exit(ieee80211_exit);
module_init(ieee80211_init);
-#endif
const char *escape_essid(const char *essid, u8 essid_len)
{
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index f7dcd854139e..ce694cf5c160 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -5,7 +5,7 @@
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, Intel Corporation
+ * Copyright (c) 2004-2005, Intel Corporation
*
* 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
@@ -87,7 +87,7 @@ static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
@@ -101,7 +101,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr) +
+ sizeof(struct ieee80211_hdr_4addr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */ );
@@ -138,7 +138,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
/* Called only as a tasklet (software IRQ) */
static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
u16 sc;
unsigned int seq;
@@ -176,7 +176,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee->dev->name);
return 0;
/*
- hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
+ hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
skb->data);*/
}
@@ -232,13 +232,13 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
{
struct net_device *dev = ieee->dev;
u16 fc, ethertype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_3addr *)skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* check that the frame is unicast frame to us */
@@ -271,26 +271,15 @@ static inline int
ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_3addr *)skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(hdr->addr2));
- }
- return -1;
- }
-#endif
-
atomic_inc(&crypt->refcnt);
res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
atomic_dec(&crypt->refcnt);
@@ -314,13 +303,13 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
struct sk_buff *skb, int keyidx,
struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_3addr *)skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
atomic_inc(&crypt->refcnt);
@@ -343,7 +332,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats)
{
struct net_device *dev = ieee->dev;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device_stats *stats;
@@ -363,7 +352,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt = NULL;
int keyidx = 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
stats = &ieee->stats;
if (skb->len < 10) {
@@ -378,35 +367,51 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
frag = WLAN_GET_SEQ_FRAG(sc);
hdrlen = ieee80211_get_hdrlen(fc);
-#ifdef NOT_YET
-#if WIRELESS_EXT > 15
/* Put this code here so that we avoid duplicating it in all
* Rx paths. - Jean II */
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
/* If spy monitoring on */
- if (iface->spy_data.spy_number > 0) {
+ if (ieee->spy_data.spy_number > 0) {
struct iw_quality wstats;
- wstats.level = rx_stats->signal;
- wstats.noise = rx_stats->noise;
- wstats.updated = 6; /* No qual value */
+
+ wstats.updated = 0;
+ if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
+ wstats.level = rx_stats->rssi;
+ wstats.updated |= IW_QUAL_LEVEL_UPDATED;
+ } else
+ wstats.updated |= IW_QUAL_LEVEL_INVALID;
+
+ if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
+ wstats.noise = rx_stats->noise;
+ wstats.updated |= IW_QUAL_NOISE_UPDATED;
+ } else
+ wstats.updated |= IW_QUAL_NOISE_INVALID;
+
+ if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
+ wstats.qual = rx_stats->signal;
+ wstats.updated |= IW_QUAL_QUAL_UPDATED;
+ } else
+ wstats.updated |= IW_QUAL_QUAL_INVALID;
+
/* Update spy records */
- wireless_spy_update(dev, hdr->addr2, &wstats);
+ wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
}
#endif /* IW_WIRELESS_SPY */
-#endif /* WIRELESS_EXT > 15 */
+
+#ifdef NOT_YET
hostap_update_rx_stats(local->ap, hdr, rx_stats);
#endif
-#if WIRELESS_EXT > 15
if (ieee->iw_mode == IW_MODE_MONITOR) {
ieee80211_monitor_rx(ieee, skb, rx_stats);
stats->rx_packets++;
stats->rx_bytes += skb->len;
return 1;
}
-#endif
- if (ieee->host_decrypt) {
+ if ((is_multicast_ether_addr(hdr->addr1) ||
+ is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
+ ieee->host_decrypt) {
int idx = 0;
if (skb->len >= hdrlen + 3)
idx = skb->data[hdrlen + 3] >> 6;
@@ -531,6 +536,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* Nullfunc frames may have PS-bit set, so they must be passed to
* hostap_handle_sta_rx() before being dropped here. */
+
+ stype &= ~IEEE80211_STYPE_QOS_DATA;
+
if (stype != IEEE80211_STYPE_DATA &&
stype != IEEE80211_STYPE_DATA_CFACK &&
stype != IEEE80211_STYPE_DATA_CFPOLL &&
@@ -549,7 +557,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
(keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
// PR: FIXME: hostap has additional conditions in the "if" below:
@@ -603,7 +611,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
ieee80211_frag_cache_invalidate(ieee, hdr);
}
@@ -613,7 +621,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
if ( /*ieee->ieee802_1x && */
ieee80211_is_eapol_frame(ieee, skb)) {
@@ -755,69 +763,179 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
-static inline int ieee80211_is_ofdm_rate(u8 rate)
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+/*
+* Make ther structure we read from the beacon packet has
+* the right values
+*/
+static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+ *info_element, int sub_type)
{
- switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
- case IEEE80211_OFDM_RATE_6MB:
- case IEEE80211_OFDM_RATE_9MB:
- case IEEE80211_OFDM_RATE_12MB:
- case IEEE80211_OFDM_RATE_18MB:
- case IEEE80211_OFDM_RATE_24MB:
- case IEEE80211_OFDM_RATE_36MB:
- case IEEE80211_OFDM_RATE_48MB:
- case IEEE80211_OFDM_RATE_54MB:
- return 1;
- }
+
+ if (info_element->qui_subtype != sub_type)
+ return -1;
+ if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
+ return -1;
+ if (info_element->qui_type != QOS_OUI_TYPE)
+ return -1;
+ if (info_element->version != QOS_VERSION_1)
+ return -1;
+
return 0;
}
-static inline int ieee80211_network_init(struct ieee80211_device *ieee,
- struct ieee80211_probe_response
- *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
+/*
+ * Parse a QoS parameter element
+ */
+static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
+ *element_param, struct ieee80211_info_element
+ *info_element)
{
-#ifdef CONFIG_IEEE80211_DEBUG
- char rates_str[64];
- char *p;
-#endif
- struct ieee80211_info_element *info_element;
- u16 left;
- u8 i;
+ int ret = 0;
+ u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
- /* Pull out fixed field data */
- memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- network->capability = beacon->capability;
- network->last_scanned = jiffies;
- network->time_stamp[0] = beacon->time_stamp[0];
- network->time_stamp[1] = beacon->time_stamp[1];
- network->beacon_interval = beacon->beacon_interval;
- /* Where to pull this? beacon->listen_interval; */
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->flags = 0;
- network->atim_window = 0;
+ if ((info_element == NULL) || (element_param == NULL))
+ return -1;
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
+ if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
+ memcpy(element_param->info_element.qui, info_element->data,
+ info_element->len);
+ element_param->info_element.elementID = info_element->id;
+ element_param->info_element.length = info_element->len;
} else
- network->flags |= NETWORK_HAS_CCK;
+ ret = -1;
+ if (ret == 0)
+ ret = ieee80211_verify_qos_info(&element_param->info_element,
+ QOS_OUI_PARAM_SUB_TYPE);
+ return ret;
+}
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
+/*
+ * Parse a QoS information element
+ */
+static int ieee80211_read_qos_info_element(struct
+ ieee80211_qos_information_element
+ *element_info, struct ieee80211_info_element
+ *info_element)
+{
+ int ret = 0;
+ u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+
+ if (element_info == NULL)
+ return -1;
+ if (info_element == NULL)
+ return -1;
+
+ if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
+ memcpy(element_info->qui, info_element->data,
+ info_element->len);
+ element_info->elementID = info_element->id;
+ element_info->length = info_element->len;
+ } else
+ ret = -1;
+
+ if (ret == 0)
+ ret = ieee80211_verify_qos_info(element_info,
+ QOS_OUI_INFO_SUB_TYPE);
+ return ret;
+}
+
+/*
+ * Write QoS parameters from the ac parameters.
+ */
+static int ieee80211_qos_convert_ac_to_parameters(struct
+ ieee80211_qos_parameter_info
+ *param_elm, struct
+ ieee80211_qos_parameters
+ *qos_param)
+{
+ int rc = 0;
+ int i;
+ struct ieee80211_qos_ac_parameter *ac_params;
+ u32 txop;
+ u8 cw_min;
+ u8 cw_max;
+
+ for (i = 0; i < QOS_QUEUE_NUM; i++) {
+ ac_params = &(param_elm->ac_params_record[i]);
+
+ qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
+ qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
+
+ cw_min = ac_params->ecw_min_max & 0x0F;
+ qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
+
+ cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
+ qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
+
+ qos_param->flag[i] =
+ (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
+
+ txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
+ qos_param->tx_op_limit[i] = (u16) txop;
+ }
+ return rc;
+}
+
+/*
+ * we have a generic data element which it may contain QoS information or
+ * parameters element. check the information element length to decide
+ * which type to read
+ */
+static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+ *info_element,
+ struct ieee80211_network *network)
+{
+ int rc = 0;
+ struct ieee80211_qos_parameters *qos_param = NULL;
+ struct ieee80211_qos_information_element qos_info_element;
+
+ rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+
+ if (rc == 0) {
+ network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
+ network->flags |= NETWORK_HAS_QOS_INFORMATION;
+ } else {
+ struct ieee80211_qos_parameter_info param_element;
+
+ rc = ieee80211_read_qos_param_element(&param_element,
+ info_element);
+ if (rc == 0) {
+ qos_param = &(network->qos_data.parameters);
+ ieee80211_qos_convert_ac_to_parameters(&param_element,
+ qos_param);
+ network->flags |= NETWORK_HAS_QOS_PARAMETERS;
+ network->qos_data.param_count =
+ param_element.info_element.ac_info & 0x0F;
+ }
+ }
+
+ if (rc == 0) {
+ IEEE80211_DEBUG_QOS("QoS is supported\n");
+ network->qos_data.supported = 1;
+ }
+ return rc;
+}
+
+static int ieee80211_parse_info_param(struct ieee80211_info_element
+ *info_element, u16 length,
+ struct ieee80211_network *network)
+{
+ u8 i;
+#ifdef CONFIG_IEEE80211_DEBUG
+ char rates_str[64];
+ char *p;
+#endif
- info_element = &beacon->info_element;
- left = stats->len - ((void *)info_element - (void *)beacon);
- while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) +
- info_element->len > left) {
- IEEE80211_DEBUG_SCAN
- ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
- info_element->len +
- sizeof(struct ieee80211_info_element), left);
+ while (length >= sizeof(*info_element)) {
+ if (sizeof(*info_element) + info_element->len > length) {
+ IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+ "info_element->len + 2 > left : "
+ "info_element->len+2=%zd left=%d, id=%d.\n",
+ info_element->len +
+ sizeof(*info_element),
+ length, info_element->id);
return 1;
}
@@ -837,7 +955,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
network->ssid, network->ssid_len);
break;
@@ -845,15 +963,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
#ifdef CONFIG_IEEE80211_DEBUG
p = rates_str;
#endif
- network->rates_len =
- min(info_element->len, MAX_RATES_LENGTH);
+ network->rates_len = min(info_element->len,
+ MAX_RATES_LENGTH);
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p,
- sizeof(rates_str) - (p -
- rates_str),
- "%02X ", network->rates[i]);
+ p += snprintf(p, sizeof(rates_str) -
+ (p - rates_str), "%02X ",
+ network->rates[i]);
#endif
if (ieee80211_is_ofdm_rate
(info_element->data[i])) {
@@ -865,7 +982,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
}
}
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
rates_str, network->rates_len);
break;
@@ -873,15 +990,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
#ifdef CONFIG_IEEE80211_DEBUG
p = rates_str;
#endif
- network->rates_ex_len =
- min(info_element->len, MAX_RATES_EX_LENGTH);
+ network->rates_ex_len = min(info_element->len,
+ MAX_RATES_EX_LENGTH);
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p,
- sizeof(rates_str) - (p -
- rates_str),
- "%02X ", network->rates[i]);
+ p += snprintf(p, sizeof(rates_str) -
+ (p - rates_str), "%02X ",
+ network->rates[i]);
#endif
if (ieee80211_is_ofdm_rate
(info_element->data[i])) {
@@ -893,40 +1009,51 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
}
}
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
rates_str, network->rates_ex_len);
break;
case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
info_element->data[0]);
- if (stats->freq == IEEE80211_24GHZ_BAND)
- network->channel = info_element->data[0];
+ network->channel = info_element->data[0];
break;
case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
break;
case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
break;
case MFIE_TYPE_TIM:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
+ break;
+
+ case MFIE_TYPE_ERP_INFO:
+ network->erp_value = info_element->data[0];
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
+ network->erp_value);
break;
case MFIE_TYPE_IBSS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
+ network->atim_window = info_element->data[0];
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+ network->atim_window);
break;
case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
break;
case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
info_element->len);
+ if (!ieee80211_parse_qos_info_param_IE(info_element,
+ network))
+ break;
+
if (info_element->len >= 4 &&
info_element->data[0] == 0x00 &&
info_element->data[1] == 0x50 &&
@@ -940,7 +1067,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
break;
case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
info_element->len);
network->rsn_ie_len = min(info_element->len + 2,
MAX_WPA_IE_LEN);
@@ -948,18 +1075,127 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
network->rsn_ie_len);
break;
+ case MFIE_TYPE_QOS_PARAMETER:
+ printk(KERN_ERR
+ "QoS Error need to parse QOS_PARAMETER IE\n");
+ break;
+
default:
- IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
+ IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
info_element->id);
break;
}
- left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
- info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
+ length -= sizeof(*info_element) + info_element->len;
+ info_element =
+ (struct ieee80211_info_element *)&info_element->
+ data[info_element->len];
+ }
+
+ return 0;
+}
+
+static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
+ *frame, struct ieee80211_rx_stats *stats)
+{
+ struct ieee80211_network network_resp;
+ struct ieee80211_network *network = &network_resp;
+ struct net_device *dev = ieee->dev;
+
+ network->flags = 0;
+ network->qos_data.active = 0;
+ network->qos_data.supported = 0;
+ network->qos_data.param_count = 0;
+ network->qos_data.old_param_count = 0;
+
+ //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
+ network->atim_window = le16_to_cpu(frame->aid);
+ network->listen_interval = le16_to_cpu(frame->status);
+ memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
+ network->capability = le16_to_cpu(frame->capability);
+ network->last_scanned = jiffies;
+ network->rates_len = network->rates_ex_len = 0;
+ network->last_associate = 0;
+ network->ssid_len = 0;
+ network->erp_value =
+ (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
+
+ if (stats->freq == IEEE80211_52GHZ_BAND) {
+ /* for A band (No DS info) */
+ network->channel = stats->received_channel;
+ } else
+ network->flags |= NETWORK_HAS_CCK;
+
+ network->wpa_ie_len = 0;
+ network->rsn_ie_len = 0;
+
+ if (ieee80211_parse_info_param
+ (frame->info_element, stats->len - sizeof(*frame), network))
+ return 1;
+
+ network->mode = 0;
+ if (stats->freq == IEEE80211_52GHZ_BAND)
+ network->mode = IEEE_A;
+ else {
+ if (network->flags & NETWORK_HAS_OFDM)
+ network->mode |= IEEE_G;
+ if (network->flags & NETWORK_HAS_CCK)
+ network->mode |= IEEE_B;
}
+ if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
+ network->flags |= NETWORK_EMPTY_ESSID;
+
+ memcpy(&network->stats, stats, sizeof(network->stats));
+
+ if (ieee->handle_assoc_response != NULL)
+ ieee->handle_assoc_response(dev, frame, network);
+
+ return 0;
+}
+
+/***************************************************/
+
+static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
+ *beacon,
+ struct ieee80211_network *network,
+ struct ieee80211_rx_stats *stats)
+{
+ network->qos_data.active = 0;
+ network->qos_data.supported = 0;
+ network->qos_data.param_count = 0;
+ network->qos_data.old_param_count = 0;
+
+ /* Pull out fixed field data */
+ memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+ network->capability = le16_to_cpu(beacon->capability);
+ network->last_scanned = jiffies;
+ network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
+ network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
+ network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
+ /* Where to pull this? beacon->listen_interval; */
+ network->listen_interval = 0x0A;
+ network->rates_len = network->rates_ex_len = 0;
+ network->last_associate = 0;
+ network->ssid_len = 0;
+ network->flags = 0;
+ network->atim_window = 0;
+ network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
+ 0x3 : 0x0;
+
+ if (stats->freq == IEEE80211_52GHZ_BAND) {
+ /* for A band (No DS info) */
+ network->channel = stats->received_channel;
+ } else
+ network->flags |= NETWORK_HAS_CCK;
+
+ network->wpa_ie_len = 0;
+ network->rsn_ie_len = 0;
+
+ if (ieee80211_parse_info_param
+ (beacon->info_element, stats->len - sizeof(*beacon), network))
+ return 1;
+
network->mode = 0;
if (stats->freq == IEEE80211_52GHZ_BAND)
network->mode = IEEE_A;
@@ -1002,6 +1238,9 @@ static inline int is_same_network(struct ieee80211_network *src,
static inline void update_network(struct ieee80211_network *dst,
struct ieee80211_network *src)
{
+ int qos_active;
+ u8 old_param;
+
memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
dst->capability = src->capability;
memcpy(dst->rates, src->rates, src->rates_len);
@@ -1017,6 +1256,7 @@ static inline void update_network(struct ieee80211_network *dst,
dst->beacon_interval = src->beacon_interval;
dst->listen_interval = src->listen_interval;
dst->atim_window = src->atim_window;
+ dst->erp_value = src->erp_value;
memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
dst->wpa_ie_len = src->wpa_ie_len;
@@ -1024,22 +1264,48 @@ static inline void update_network(struct ieee80211_network *dst,
dst->rsn_ie_len = src->rsn_ie_len;
dst->last_scanned = jiffies;
+ qos_active = src->qos_data.active;
+ old_param = dst->qos_data.old_param_count;
+ if (dst->flags & NETWORK_HAS_QOS_MASK)
+ memcpy(&dst->qos_data, &src->qos_data,
+ sizeof(struct ieee80211_qos_data));
+ else {
+ dst->qos_data.supported = src->qos_data.supported;
+ dst->qos_data.param_count = src->qos_data.param_count;
+ }
+
+ if (dst->qos_data.supported == 1) {
+ if (dst->ssid_len)
+ IEEE80211_DEBUG_QOS
+ ("QoS the network %s is QoS supported\n",
+ dst->ssid);
+ else
+ IEEE80211_DEBUG_QOS
+ ("QoS the network is QoS supported\n");
+ }
+ dst->qos_data.active = qos_active;
+ dst->qos_data.old_param_count = old_param;
+
/* dst->last_associate is not overwritten */
}
+static inline int is_beacon(int fc)
+{
+ return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
+}
+
static inline void ieee80211_process_probe_response(struct ieee80211_device
- *ieee,
- struct
+ *ieee, struct
ieee80211_probe_response
- *beacon,
- struct ieee80211_rx_stats
+ *beacon, struct ieee80211_rx_stats
*stats)
{
+ struct net_device *dev = ieee->dev;
struct ieee80211_network network;
struct ieee80211_network *target;
struct ieee80211_network *oldest = NULL;
#ifdef CONFIG_IEEE80211_DEBUG
- struct ieee80211_info_element *info_element = &beacon->info_element;
+ struct ieee80211_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
@@ -1070,10 +1336,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
escape_essid(info_element->data,
info_element->len),
MAC_ARG(beacon->header.addr3),
- WLAN_FC_GET_STYPE(beacon->header.
- frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
+ is_beacon(le16_to_cpu
+ (beacon->header.
+ frame_ctl)) ?
+ "BEACON" : "PROBE RESPONSE");
return;
}
@@ -1122,10 +1388,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
escape_essid(network.ssid,
network.ssid_len),
MAC_ARG(network.bssid),
- WLAN_FC_GET_STYPE(beacon->header.
- frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
+ is_beacon(le16_to_cpu
+ (beacon->header.
+ frame_ctl)) ?
+ "BEACON" : "PROBE RESPONSE");
#endif
memcpy(target, &network, sizeof(*target));
list_add_tail(&target->list, &ieee->network_list);
@@ -1134,34 +1400,60 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
escape_essid(target->ssid,
target->ssid_len),
MAC_ARG(target->bssid),
- WLAN_FC_GET_STYPE(beacon->header.
- frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
+ is_beacon(le16_to_cpu
+ (beacon->header.
+ frame_ctl)) ?
+ "BEACON" : "PROBE RESPONSE");
update_network(target, &network);
}
spin_unlock_irqrestore(&ieee->lock, flags);
+
+ if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
+ if (ieee->handle_beacon != NULL)
+ ieee->handle_beacon(dev, beacon, &network);
+ } else {
+ if (ieee->handle_probe_response != NULL)
+ ieee->handle_probe_response(dev, beacon, &network);
+ }
}
void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr *header,
+ struct ieee80211_hdr_4addr *header,
struct ieee80211_rx_stats *stats)
{
- switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+ switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
case IEEE80211_STYPE_ASSOC_RESP:
IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+ ieee80211_handle_assoc_resp(ieee,
+ (struct ieee80211_assoc_response *)
+ header, stats);
break;
case IEEE80211_STYPE_REASSOC_RESP:
IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+ break;
+
+ case IEEE80211_STYPE_PROBE_REQ:
+ IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+
+ if (ieee->handle_probe_request != NULL)
+ ieee->handle_probe_request(ieee->dev,
+ (struct
+ ieee80211_probe_request *)
+ header, stats);
break;
case IEEE80211_STYPE_PROBE_RESP:
IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
IEEE80211_DEBUG_SCAN("Probe response\n");
ieee80211_process_probe_response(ieee,
(struct
@@ -1171,20 +1463,46 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
case IEEE80211_STYPE_BEACON:
IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
IEEE80211_DEBUG_SCAN("Beacon\n");
ieee80211_process_probe_response(ieee,
(struct
ieee80211_probe_response *)
header, stats);
break;
+ case IEEE80211_STYPE_AUTH:
+ IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+
+ if (ieee->handle_auth != NULL)
+ ieee->handle_auth(ieee->dev,
+ (struct ieee80211_auth *)header);
+ break;
+
+ case IEEE80211_STYPE_DISASSOC:
+ if (ieee->handle_disassoc != NULL)
+ ieee->handle_disassoc(ieee->dev,
+ (struct ieee80211_disassoc *)
+ header);
+ break;
+
+ case IEEE80211_STYPE_DEAUTH:
+ printk("DEAUTH from AP\n");
+ if (ieee->handle_deauth != NULL)
+ ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *)
+ header);
+ break;
default:
IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
IEEE80211_WARNING("%s: Unknown management packet: %d\n",
ieee->dev->name,
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
break;
}
}
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index c9aaff3fea1e..95ccbadbf55b 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2003 - 2005 Intel Corporation. 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
@@ -128,7 +128,7 @@ payload of each frame is reduced to 492 bytes.
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
+static inline int ieee80211_copy_snap(u8 * data, u16 h_proto)
{
struct ieee80211_snap_hdr *snap;
u8 *oui;
@@ -157,31 +157,14 @@ static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
int res;
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- struct ieee80211_hdr *header;
-
- if (ieee->tkip_countermeasures &&
- crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct ieee80211_hdr *)frag->data;
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(header->addr1));
- }
+ if (crypt == NULL)
return -1;
- }
-#endif
+
/* To encrypt, frame format is:
* IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
-
- // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
- /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- * call both MSDU and MPDU encryption functions from here. */
atomic_inc(&crypt->refcnt);
res = 0;
- if (crypt->ops->encrypt_msdu)
- res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- if (res == 0 && crypt->ops->encrypt_mpdu)
+ if (crypt->ops && crypt->ops->encrypt_mpdu)
res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
atomic_dec(&crypt->refcnt);
@@ -207,7 +190,7 @@ void ieee80211_txb_free(struct ieee80211_txb *txb)
}
static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- int gfp_mask)
+ int headroom, gfp_t gfp_mask)
{
struct ieee80211_txb *txb;
int i;
@@ -221,11 +204,13 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
txb->frag_size = txb_size;
for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = dev_alloc_skb(txb_size);
+ txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
+ gfp_mask);
if (unlikely(!txb->fragments[i])) {
i--;
break;
}
+ skb_reserve(txb->fragments[i], headroom);
}
if (unlikely(i != nr_frags)) {
while (i >= 0)
@@ -236,25 +221,31 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
return txb;
}
-/* SKBs are added to the ieee->tx_queue. */
+/* Incoming skb is converted to a txb which consists of
+ * a block of 802.11 fragment packets (stored as skbs) */
int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ieee80211_device *ieee = netdev_priv(dev);
struct ieee80211_txb *txb = NULL;
- struct ieee80211_hdr *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
+ struct ieee80211_hdr_3addr *frag_hdr;
+ int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
+ rts_required;
unsigned long flags;
struct net_device_stats *stats = &ieee->stats;
- int ether_type, encrypt;
+ int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
int bytes, fc, hdr_len;
struct sk_buff *skb_frag;
- struct ieee80211_hdr header = { /* Ensure zero initialized */
+ struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */
.duration_id = 0,
.seq_ctl = 0
};
u8 dest[ETH_ALEN], src[ETH_ALEN];
-
struct ieee80211_crypt_data *crypt;
+ int priority = skb->priority;
+ int snapped = 0;
+
+ if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
+ return NETDEV_TX_BUSY;
spin_lock_irqsave(&ieee->lock, flags);
@@ -276,7 +267,11 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
crypt = ieee->crypt[ieee->tx_keyidx];
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- ieee->host_encrypt && crypt && crypt->ops;
+ ieee->sec.encrypt;
+
+ host_encrypt = ieee->host_encrypt && encrypt && crypt;
+ host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
+ host_build_iv = ieee->host_build_iv && encrypt && crypt;
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -285,8 +280,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
}
/* Save source and destination addresses */
- memcpy(&dest, skb->data, ETH_ALEN);
- memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
+ memcpy(dest, skb->data, ETH_ALEN);
+ memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);
/* Advance the SKB to the start of the payload */
skb_pull(skb, sizeof(struct ethhdr));
@@ -294,7 +289,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
/* Determine total amount of storage required for TXB packets */
bytes = skb->len + SNAP_SIZE + sizeof(u16);
- if (encrypt)
+ if (host_encrypt)
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
IEEE80211_FCTL_PROTECTED;
else
@@ -302,70 +297,144 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
if (ieee->iw_mode == IW_MODE_INFRA) {
fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA,
- Addr3 = DA */
- memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
- memcpy(&header.addr2, &src, ETH_ALEN);
- memcpy(&header.addr3, &dest, ETH_ALEN);
+ /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
+ memcpy(header.addr1, ieee->bssid, ETH_ALEN);
+ memcpy(header.addr2, src, ETH_ALEN);
+ memcpy(header.addr3, dest, ETH_ALEN);
} else if (ieee->iw_mode == IW_MODE_ADHOC) {
- /* not From/To DS: Addr1 = DA, Addr2 = SA,
- Addr3 = BSSID */
- memcpy(&header.addr1, dest, ETH_ALEN);
- memcpy(&header.addr2, src, ETH_ALEN);
- memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
+ /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
+ memcpy(header.addr1, dest, ETH_ALEN);
+ memcpy(header.addr2, src, ETH_ALEN);
+ memcpy(header.addr3, ieee->bssid, ETH_ALEN);
}
header.frame_ctl = cpu_to_le16(fc);
hdr_len = IEEE80211_3ADDR_LEN;
- /* Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented) */
- if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
- frag_size = MAX_FRAG_THRESHOLD;
- else
- frag_size = ieee->fts;
+ /* Encrypt msdu first on the whole data packet. */
+ if ((host_encrypt || host_encrypt_msdu) &&
+ crypt && crypt->ops && crypt->ops->encrypt_msdu) {
+ int res = 0;
+ int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
+ crypt->ops->extra_msdu_postfix_len;
+ struct sk_buff *skb_new = dev_alloc_skb(len);
+
+ if (unlikely(!skb_new))
+ goto failed;
+
+ skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
+ memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
+ snapped = 1;
+ ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
+ ether_type);
+ memcpy(skb_put(skb_new, skb->len), skb->data, skb->len);
+ res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
+ if (res < 0) {
+ IEEE80211_ERROR("msdu encryption failed\n");
+ dev_kfree_skb_any(skb_new);
+ goto failed;
+ }
+ dev_kfree_skb_any(skb);
+ skb = skb_new;
+ bytes += crypt->ops->extra_msdu_prefix_len +
+ crypt->ops->extra_msdu_postfix_len;
+ skb_pull(skb, hdr_len);
+ }
- /* Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account for
- * it when determining the amount of payload space. */
- bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- bytes_per_frag -= IEEE80211_FCS_LEN;
-
- /* Each fragment may need to have room for encryptiong pre/postfix */
- if (encrypt)
- bytes_per_frag -= crypt->ops->extra_prefix_len +
- crypt->ops->extra_postfix_len;
-
- /* Number of fragments is the total bytes_per_frag /
- * payload_per_fragment */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
+ if (host_encrypt || ieee->host_open_frag) {
+ /* Determine fragmentation size based on destination (multicast
+ * and broadcast are not fragmented) */
+ if (is_multicast_ether_addr(dest) ||
+ is_broadcast_ether_addr(dest))
+ frag_size = MAX_FRAG_THRESHOLD;
+ else
+ frag_size = ieee->fts;
+
+ /* Determine amount of payload per fragment. Regardless of if
+ * this stack is providing the full 802.11 header, one will
+ * eventually be affixed to this fragment -- so we must account
+ * for it when determining the amount of payload space. */
+ bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
+ if (ieee->config &
+ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ bytes_per_frag -= IEEE80211_FCS_LEN;
+
+ /* Each fragment may need to have room for encryptiong
+ * pre/postfix */
+ if (host_encrypt)
+ bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
+ crypt->ops->extra_mpdu_postfix_len;
+
+ /* Number of fragments is the total
+ * bytes_per_frag / payload_per_fragment */
+ nr_frags = bytes / bytes_per_frag;
+ bytes_last_frag = bytes % bytes_per_frag;
+ if (bytes_last_frag)
+ nr_frags++;
+ else
+ bytes_last_frag = bytes_per_frag;
+ } else {
+ nr_frags = 1;
+ bytes_per_frag = bytes_last_frag = bytes;
+ frag_size = bytes + IEEE80211_3ADDR_LEN;
+ }
+
+ rts_required = (frag_size > ieee->rts
+ && ieee->config & CFG_IEEE80211_RTS);
+ if (rts_required)
nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
/* When we allocate the TXB we allocate enough space for the reserve
* and full fragment bytes (bytes_per_frag doesn't include prefix,
* postfix, header, FCS, etc.) */
- txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
+ txb = ieee80211_alloc_txb(nr_frags, frag_size,
+ ieee->tx_headroom, GFP_ATOMIC);
if (unlikely(!txb)) {
printk(KERN_WARNING "%s: Could not allocate TXB\n",
ieee->dev->name);
goto failed;
}
txb->encrypted = encrypt;
- txb->payload_size = bytes;
+ if (host_encrypt)
+ txb->payload_size = frag_size * (nr_frags - 1) +
+ bytes_last_frag;
+ else
+ txb->payload_size = bytes;
+
+ if (rts_required) {
+ skb_frag = txb->fragments[0];
+ frag_hdr =
+ (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+
+ /*
+ * Set header frame_ctl to the RTS.
+ */
+ header.frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+ memcpy(frag_hdr, &header, hdr_len);
- for (i = 0; i < nr_frags; i++) {
+ /*
+ * Restore header frame_ctl to the original data setting.
+ */
+ header.frame_ctl = cpu_to_le16(fc);
+
+ if (ieee->config &
+ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ skb_put(skb_frag, 4);
+
+ txb->rts_included = 1;
+ i = 1;
+ } else
+ i = 0;
+
+ for (; i < nr_frags; i++) {
skb_frag = txb->fragments[i];
- if (encrypt)
- skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
+ if (host_encrypt || host_build_iv)
+ skb_reserve(skb_frag,
+ crypt->ops->extra_mpdu_prefix_len);
- frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
+ frag_hdr =
+ (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
memcpy(frag_hdr, &header, hdr_len);
/* If this is not the last fragment, then add the MOREFRAGS
@@ -379,11 +448,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
bytes = bytes_last_frag;
}
- /* Put a SNAP header on the first fragment */
- if (i == 0) {
- ieee80211_put_snap(skb_put
- (skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
+ if (i == 0 && !snapped) {
+ ieee80211_copy_snap(skb_put
+ (skb_frag, SNAP_SIZE + sizeof(u16)),
+ ether_type);
bytes -= SNAP_SIZE + sizeof(u16);
}
@@ -394,8 +462,19 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
/* Encryption routine will move the header forward in order
* to insert the IV between the header and the payload */
- if (encrypt)
+ if (host_encrypt)
ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+ else if (host_build_iv) {
+ struct ieee80211_crypt_data *crypt;
+
+ crypt = ieee->crypt[ieee->tx_keyidx];
+ atomic_inc(&crypt->refcnt);
+ if (crypt->ops->build_iv)
+ crypt->ops->build_iv(skb_frag, hdr_len,
+ crypt->priv);
+ atomic_dec(&crypt->refcnt);
+ }
+
if (ieee->config &
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
skb_put(skb_frag, 4);
@@ -407,11 +486,20 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb_any(skb);
if (txb) {
- if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
+ int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
+ if (ret == 0) {
stats->tx_packets++;
stats->tx_bytes += txb->payload_size;
return 0;
}
+
+ if (ret == NETDEV_TX_BUSY) {
+ printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
+ "driver should report queue full via "
+ "ieee_device->is_queue_full.\n",
+ ieee->dev->name);
+ }
+
ieee80211_txb_free(txb);
}
@@ -422,7 +510,72 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
stats->tx_errors++;
return 1;
+}
+
+/* Incoming 802.11 strucure is converted to a TXB
+ * a block of 802.11 fragment packets (stored as skbs) */
+int ieee80211_tx_frame(struct ieee80211_device *ieee,
+ struct ieee80211_hdr *frame, int len)
+{
+ struct ieee80211_txb *txb = NULL;
+ unsigned long flags;
+ struct net_device_stats *stats = &ieee->stats;
+ struct sk_buff *skb_frag;
+ int priority = -1;
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ /* If there is no driver handler to take the TXB, dont' bother
+ * creating it... */
+ if (!ieee->hard_start_xmit) {
+ printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
+ goto success;
+ }
+
+ if (unlikely(len < 24)) {
+ printk(KERN_WARNING "%s: skb too small (%d).\n",
+ ieee->dev->name, len);
+ goto success;
+ }
+
+ /* When we allocate the TXB we allocate enough space for the reserve
+ * and full fragment bytes (bytes_per_frag doesn't include prefix,
+ * postfix, header, FCS, etc.) */
+ txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC);
+ if (unlikely(!txb)) {
+ printk(KERN_WARNING "%s: Could not allocate TXB\n",
+ ieee->dev->name);
+ goto failed;
+ }
+ txb->encrypted = 0;
+ txb->payload_size = len;
+
+ skb_frag = txb->fragments[0];
+
+ memcpy(skb_put(skb_frag, len), frame, len);
+
+ if (ieee->config &
+ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ skb_put(skb_frag, 4);
+
+ success:
+ spin_unlock_irqrestore(&ieee->lock, flags);
+
+ if (txb) {
+ if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
+ stats->tx_packets++;
+ stats->tx_bytes += txb->payload_size;
+ return 0;
+ }
+ ieee80211_txb_free(txb);
+ }
+ return 0;
+
+ failed:
+ spin_unlock_irqrestore(&ieee->lock, flags);
+ stats->tx_errors++;
+ return 1;
}
+EXPORT_SYMBOL(ieee80211_tx_frame);
EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 94882f39b072..1ce7af9bec35 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
@@ -32,6 +32,7 @@
#include <linux/kmod.h>
#include <linux/module.h>
+#include <linux/jiffies.h>
#include <net/ieee80211.h>
#include <linux/wireless.h>
@@ -140,18 +141,41 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
start = iwe_stream_add_point(start, stop, &iwe, custom);
/* Add quality statistics */
- /* TODO: Fix these values... */
iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = network->stats.signal;
- iwe.u.qual.level = network->stats.rssi;
- iwe.u.qual.noise = network->stats.noise;
- iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
- if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
+ IW_QUAL_NOISE_UPDATED;
+
+ if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
+ iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
+ IW_QUAL_LEVEL_INVALID;
+ iwe.u.qual.qual = 0;
+ iwe.u.qual.level = 0;
+ } else {
+ iwe.u.qual.level = network->stats.rssi;
+ if (ieee->perfect_rssi == ieee->worst_rssi)
+ iwe.u.qual.qual = 100;
+ else
+ iwe.u.qual.qual =
+ (100 *
+ (ieee->perfect_rssi - ieee->worst_rssi) *
+ (ieee->perfect_rssi - ieee->worst_rssi) -
+ (ieee->perfect_rssi - network->stats.rssi) *
+ (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
+ 62 * (ieee->perfect_rssi - network->stats.rssi))) /
+ ((ieee->perfect_rssi - ieee->worst_rssi) *
+ (ieee->perfect_rssi - ieee->worst_rssi));
+ if (iwe.u.qual.qual > 100)
+ iwe.u.qual.qual = 100;
+ else if (iwe.u.qual.qual < 1)
+ iwe.u.qual.qual = 0;
+ }
+
+ if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
+ iwe.u.qual.noise = 0;
+ } else {
+ iwe.u.qual.noise = network->stats.noise;
+ }
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
@@ -162,7 +186,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom);
- if (ieee->wpa_enabled && network->wpa_ie_len) {
+ if (network->wpa_ie_len) {
char buf[MAX_WPA_IE_LEN * 2 + 30];
u8 *p = buf;
@@ -177,7 +201,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
start = iwe_stream_add_point(start, stop, &iwe, buf);
}
- if (ieee->wpa_enabled && network->rsn_ie_len) {
+ if (network->rsn_ie_len) {
char buf[MAX_WPA_IE_LEN * 2 + 30];
u8 *p = buf;
@@ -197,8 +221,8 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = IWEVCUSTOM;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago",
- (jiffies - network->last_scanned) / (HZ / 100));
+ " Last beacon: %dms ago",
+ jiffies_to_msecs(jiffies - network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom);
@@ -228,13 +252,13 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
ev = ipw2100_translate_scan(ieee, ev, stop, network);
else
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
+ MAC_FMT ")' due to age (%dms).\n",
escape_essid(network->ssid,
network->ssid_len),
MAC_ARG(network->bssid),
- (jiffies -
- network->last_scanned) / (HZ /
- 100));
+ jiffies_to_msecs(jiffies -
+ network->
+ last_scanned));
}
spin_unlock_irqrestore(&ieee->lock, flags);
@@ -258,6 +282,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
};
int i, key, key_provided, len;
struct ieee80211_crypt_data **crypt;
+ int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
IEEE80211_DEBUG_WX("SET_ENCODE\n");
@@ -298,15 +323,17 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
if (i == WEP_KEYS) {
sec.enabled = 0;
+ sec.encrypt = 0;
sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
+ sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
}
goto done;
}
sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
+ sec.encrypt = 1;
+ sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
if (*crypt != NULL && (*crypt)->ops != NULL &&
strcmp((*crypt)->ops->name, "WEP") != 0) {
@@ -315,7 +342,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
ieee80211_crypt_delayed_deinit(ieee, crypt);
}
- if (*crypt == NULL) {
+ if (*crypt == NULL && host_crypto) {
struct ieee80211_crypt_data *new_crypt;
/* take WEP into use */
@@ -355,49 +382,56 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
key, escape_essid(sec.keys[key], len),
erq->length, len);
sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
+ if (*crypt)
+ (*crypt)->ops->set_key(sec.keys[key], len, NULL,
+ (*crypt)->priv);
sec.flags |= (1 << key);
/* This ensures a key will be activated if no key is
* explicitely set */
if (key == sec.active_key)
sec.flags |= SEC_ACTIVE_KEY;
+
} else {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
- key);
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
+ if (host_crypto) {
+ len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
+ NULL, (*crypt)->priv);
+ if (len == 0) {
+ /* Set a default key of all 0 */
+ IEEE80211_DEBUG_WX("Setting key %d to all "
+ "zero.\n", key);
+ memset(sec.keys[key], 0, 13);
+ (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
+ (*crypt)->priv);
+ sec.key_sizes[key] = 13;
+ sec.flags |= (1 << key);
+ }
}
-
/* No key data - just set the default TX key index */
if (key_provided) {
- IEEE80211_DEBUG_WX
- ("Setting key %d to default Tx key.\n", key);
+ IEEE80211_DEBUG_WX("Setting key %d to default Tx "
+ "key.\n", key);
ieee->tx_keyidx = key;
sec.active_key = key;
sec.flags |= SEC_ACTIVE_KEY;
}
}
-
- done:
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
+ if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
+ ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
+ sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
+ WLAN_AUTH_SHARED_KEY;
+ sec.flags |= SEC_AUTH_MODE;
+ IEEE80211_DEBUG_WX("Auth: %s\n",
+ sec.auth_mode == WLAN_AUTH_OPEN ?
+ "OPEN" : "SHARED KEY");
+ }
/* For now we just support WEP, so only set that security level...
* TODO: When WPA is added this is one place that needs to change */
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
+ sec.encode_alg[key] = SEC_ALG_WEP;
+ done:
if (ieee->set_security)
ieee->set_security(dev, &sec);
@@ -422,6 +456,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
struct iw_point *erq = &(wrqu->encoding);
int len, key;
struct ieee80211_crypt_data *crypt;
+ struct ieee80211_security *sec = &ieee->sec;
IEEE80211_DEBUG_WX("GET_ENCODE\n");
@@ -436,23 +471,16 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
crypt = ieee->crypt[key];
erq->flags = key + 1;
- if (crypt == NULL || crypt->ops == NULL) {
+ if (!sec->enabled) {
erq->length = 0;
erq->flags |= IW_ENCODE_DISABLED;
return 0;
}
- if (strcmp(crypt->ops->name, "WEP") != 0) {
- /* only WEP is supported with wireless extensions, so just
- * report that encryption is used */
- erq->length = 0;
- erq->flags |= IW_ENCODE_ENABLED;
- return 0;
- }
+ len = sec->key_sizes[key];
+ memcpy(keybuf, sec->keys[key], len);
- len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
erq->length = (len >= 0 ? len : 0);
-
erq->flags |= IW_ENCODE_ENABLED;
if (ieee->open_wep)
@@ -463,6 +491,240 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
return 0;
}
+int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct net_device *dev = ieee->dev;
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int i, idx, ret = 0;
+ int group_key = 0;
+ const char *alg, *module;
+ struct ieee80211_crypto_ops *ops;
+ struct ieee80211_crypt_data **crypt;
+
+ struct ieee80211_security sec = {
+ .flags = 0,
+ };
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if (idx < 1 || idx > WEP_KEYS)
+ return -EINVAL;
+ idx--;
+ } else
+ idx = ieee->tx_keyidx;
+
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ crypt = &ieee->crypt[idx];
+ group_key = 1;
+ } else {
+ if (idx != 0)
+ return -EINVAL;
+ if (ieee->iw_mode == IW_MODE_INFRA)
+ crypt = &ieee->crypt[idx];
+ else
+ return -EINVAL;
+ }
+
+ sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
+ if ((encoding->flags & IW_ENCODE_DISABLED) ||
+ ext->alg == IW_ENCODE_ALG_NONE) {
+ if (*crypt)
+ ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+ for (i = 0; i < WEP_KEYS; i++)
+ if (ieee->crypt[i] != NULL)
+ break;
+
+ if (i == WEP_KEYS) {
+ sec.enabled = 0;
+ sec.encrypt = 0;
+ sec.level = SEC_LEVEL_0;
+ sec.flags |= SEC_LEVEL;
+ }
+ goto done;
+ }
+
+ sec.enabled = 1;
+ sec.encrypt = 1;
+
+ if (group_key ? !ieee->host_mc_decrypt :
+ !(ieee->host_encrypt || ieee->host_decrypt ||
+ ieee->host_encrypt_msdu))
+ goto skip_host_crypt;
+
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_WEP:
+ alg = "WEP";
+ module = "ieee80211_crypt_wep";
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ alg = "TKIP";
+ module = "ieee80211_crypt_tkip";
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ alg = "CCMP";
+ module = "ieee80211_crypt_ccmp";
+ break;
+ default:
+ IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+ dev->name, ext->alg);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ops = ieee80211_get_crypto_ops(alg);
+ if (ops == NULL) {
+ request_module(module);
+ ops = ieee80211_get_crypto_ops(alg);
+ }
+ if (ops == NULL) {
+ IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+ dev->name, ext->alg);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (*crypt == NULL || (*crypt)->ops != ops) {
+ struct ieee80211_crypt_data *new_crypt;
+
+ ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+ new_crypt = (struct ieee80211_crypt_data *)
+ kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+ if (new_crypt == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+ new_crypt->ops = ops;
+ if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ new_crypt->priv = new_crypt->ops->init(idx);
+ if (new_crypt->priv == NULL) {
+ kfree(new_crypt);
+ ret = -EINVAL;
+ goto done;
+ }
+ *crypt = new_crypt;
+ }
+
+ if (ext->key_len > 0 && (*crypt)->ops->set_key &&
+ (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
+ (*crypt)->priv) < 0) {
+ IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ skip_host_crypt:
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ ieee->tx_keyidx = idx;
+ sec.active_key = idx;
+ sec.flags |= SEC_ACTIVE_KEY;
+ }
+
+ if (ext->alg != IW_ENCODE_ALG_NONE) {
+ memcpy(sec.keys[idx], ext->key, ext->key_len);
+ sec.key_sizes[idx] = ext->key_len;
+ sec.flags |= (1 << idx);
+ if (ext->alg == IW_ENCODE_ALG_WEP) {
+ sec.encode_alg[idx] = SEC_ALG_WEP;
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_1;
+ } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
+ sec.encode_alg[idx] = SEC_ALG_TKIP;
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_2;
+ } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
+ sec.encode_alg[idx] = SEC_ALG_CCMP;
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_3;
+ }
+ /* Don't set sec level for group keys. */
+ if (group_key)
+ sec.flags &= ~SEC_LEVEL;
+ }
+ done:
+ if (ieee->set_security)
+ ieee->set_security(ieee->dev, &sec);
+
+ /*
+ * Do not reset port if card is in Managed mode since resetting will
+ * generate new IEEE 802.11 authentication which may end up in looping
+ * with IEEE 802.1X. If your hardware requires a reset after WEP
+ * configuration (for example... Prism2), implement the reset_port in
+ * the callbacks structures used to initialize the 802.11 stack.
+ */
+ if (ieee->reset_on_keychange &&
+ ieee->iw_mode != IW_MODE_INFRA &&
+ ieee->reset_port && ieee->reset_port(dev)) {
+ IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ struct ieee80211_security *sec = &ieee->sec;
+ int idx, max_key_len;
+
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ return -EINVAL;
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if (idx < 1 || idx > WEP_KEYS)
+ return -EINVAL;
+ idx--;
+ } else
+ idx = ieee->tx_keyidx;
+
+ if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
+ return -EINVAL;
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ if (!sec->enabled) {
+ ext->alg = IW_ENCODE_ALG_NONE;
+ ext->key_len = 0;
+ encoding->flags |= IW_ENCODE_DISABLED;
+ } else {
+ if (sec->encode_alg[idx] == SEC_ALG_WEP)
+ ext->alg = IW_ENCODE_ALG_WEP;
+ else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
+ ext->alg = IW_ENCODE_ALG_CCMP;
+ else
+ return -EINVAL;
+
+ ext->key_len = sec->key_sizes[idx];
+ memcpy(ext->key, sec->keys[idx], ext->key_len);
+ encoding->flags |= IW_ENCODE_ENABLED;
+ if (ext->key_len &&
+ (ext->alg == IW_ENCODE_ALG_TKIP ||
+ ext->alg == IW_ENCODE_ALG_CCMP))
+ ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
+EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
+
EXPORT_SYMBOL(ieee80211_wx_get_scan);
EXPORT_SYMBOL(ieee80211_wx_set_encode);
EXPORT_SYMBOL(ieee80211_wx_get_encode);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index bf147f8db399..a9d84f93442c 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1248,11 +1248,6 @@ module_init(inet_init);
/* ------------------------------------------------------------------------ */
#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/arp.c b/net/ipv4/arp.c
index 8bf312bdea13..b425748f02d7 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -241,7 +241,7 @@ static int arp_constructor(struct neighbour *neigh)
neigh->type = inet_addr_type(addr);
rcu_read_lock();
- in_dev = rcu_dereference(__in_dev_get(dev));
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev == NULL) {
rcu_read_unlock();
return -EINVAL;
@@ -697,12 +697,6 @@ void arp_send(int type, int ptype, u32 dest_ip,
arp_xmit(skb);
}
-static void parp_redo(struct sk_buff *skb)
-{
- nf_reset(skb);
- arp_rcv(skb, skb->dev, NULL, skb->dev);
-}
-
/*
* Process an arp request.
*/
@@ -922,6 +916,11 @@ out:
return 0;
}
+static void parp_redo(struct sk_buff *skb)
+{
+ arp_process(skb);
+}
+
/*
* Receive an arp request from the device layer.
@@ -990,8 +989,8 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev)
ipv4_devconf.proxy_arp = 1;
return 0;
}
- if (__in_dev_get(dev)) {
- __in_dev_get(dev)->cnf.proxy_arp = 1;
+ if (__in_dev_get_rtnl(dev)) {
+ __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1;
return 0;
}
return -ENXIO;
@@ -1096,8 +1095,8 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev)
ipv4_devconf.proxy_arp = 0;
return 0;
}
- if (__in_dev_get(dev)) {
- __in_dev_get(dev)->cnf.proxy_arp = 0;
+ if (__in_dev_get_rtnl(dev)) {
+ __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0;
return 0;
}
return -ENXIO;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index ba2895ae8151..4ec4b2ca6ab1 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -351,7 +351,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa)
static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
{
- struct in_device *in_dev = __in_dev_get(dev);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
ASSERT_RTNL();
@@ -449,7 +449,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
goto out;
rc = -ENOBUFS;
- if ((in_dev = __in_dev_get(dev)) == NULL) {
+ if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
in_dev = inetdev_init(dev);
if (!in_dev)
goto out;
@@ -584,7 +584,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
if (colon)
*colon = ':';
- if ((in_dev = __in_dev_get(dev)) != NULL) {
+ if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
if (tryaddrmatch) {
/* Matthias Andree */
/* compare label and address (4.4BSD style) */
@@ -715,6 +715,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
break;
ret = 0;
if (ifa->ifa_mask != sin->sin_addr.s_addr) {
+ u32 old_mask = ifa->ifa_mask;
inet_del_ifa(in_dev, ifap, 0);
ifa->ifa_mask = sin->sin_addr.s_addr;
ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
@@ -728,7 +729,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
if ((dev->flags & IFF_BROADCAST) &&
(ifa->ifa_prefixlen < 31) &&
(ifa->ifa_broadcast ==
- (ifa->ifa_local|~ifa->ifa_mask))) {
+ (ifa->ifa_local|~old_mask))) {
ifa->ifa_broadcast = (ifa->ifa_local |
~sin->sin_addr.s_addr);
}
@@ -748,7 +749,7 @@ rarok:
static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
{
- struct in_device *in_dev = __in_dev_get(dev);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
struct in_ifaddr *ifa;
struct ifreq ifr;
int done = 0;
@@ -791,7 +792,7 @@ u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope)
struct in_device *in_dev;
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = __in_dev_get_rcu(dev);
if (!in_dev)
goto no_in_dev;
@@ -818,7 +819,7 @@ no_in_dev:
read_lock(&dev_base_lock);
rcu_read_lock();
for (dev = dev_base; dev; dev = dev->next) {
- if ((in_dev = __in_dev_get(dev)) == NULL)
+ if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
continue;
for_primary_ifa(in_dev) {
@@ -887,7 +888,7 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop
if (dev) {
rcu_read_lock();
- if ((in_dev = __in_dev_get(dev)))
+ if ((in_dev = __in_dev_get_rcu(dev)))
addr = confirm_addr_indev(in_dev, dst, local, scope);
rcu_read_unlock();
@@ -897,7 +898,7 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop
read_lock(&dev_base_lock);
rcu_read_lock();
for (dev = dev_base; dev; dev = dev->next) {
- if ((in_dev = __in_dev_get(dev))) {
+ if ((in_dev = __in_dev_get_rcu(dev))) {
addr = confirm_addr_indev(in_dev, dst, local, scope);
if (addr)
break;
@@ -957,7 +958,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
- struct in_device *in_dev = __in_dev_get(dev);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
ASSERT_RTNL();
@@ -1078,7 +1079,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
if (idx > s_idx)
s_ip_idx = 0;
rcu_read_lock();
- if ((in_dev = __in_dev_get(dev)) == NULL) {
+ if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
rcu_read_unlock();
continue;
}
@@ -1149,7 +1150,7 @@ void inet_forward_change(void)
for (dev = dev_base; dev; dev = dev->next) {
struct in_device *in_dev;
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev)
in_dev->cnf.forwarding = on;
rcu_read_unlock();
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 1b5a09d1b90b..1b18ce66e7b7 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -5,6 +5,7 @@
#include <net/esp.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
+#include <linux/kernel.h>
#include <linux/pfkeyv2.h>
#include <linux/random.h>
#include <net/icmp.h>
@@ -42,10 +43,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
esp = x->data;
alen = esp->auth.icv_trunc_len;
tfm = esp->conf.tfm;
- blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3;
- clen = (clen + 2 + blksize-1)&~(blksize-1);
+ blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4);
+ clen = ALIGN(clen + 2, blksize);
if (esp->conf.padlen)
- clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
+ clen = ALIGN(clen, esp->conf.padlen);
if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
goto error;
@@ -143,7 +144,7 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc
struct ip_esp_hdr *esph;
struct esp_data *esp = x->data;
struct sk_buff *trailer;
- int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+ int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
int alen = esp->auth.icv_trunc_len;
int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
int nfrags;
@@ -304,16 +305,16 @@ static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap,
static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
{
struct esp_data *esp = x->data;
- u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+ u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
if (x->props.mode) {
- mtu = (mtu + 2 + blksize-1)&~(blksize-1);
+ mtu = ALIGN(mtu + 2, blksize);
} else {
/* The worst case. */
- mtu += 2 + blksize;
+ mtu = ALIGN(mtu + 2, 4) + blksize - 4;
}
if (esp->conf.padlen)
- mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1);
+ mtu = ALIGN(mtu, esp->conf.padlen);
return mtu + x->props.header_len + esp->auth.icv_trunc_len;
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 4e1379f71269..e61bc7177eb1 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -173,7 +173,7 @@ int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
no_addr = rpf = 0;
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
no_addr = in_dev->ifa_list == NULL;
rpf = IN_DEV_RPFILTER(in_dev);
@@ -607,7 +607,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
- struct in_device *in_dev = __in_dev_get(dev);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
if (event == NETDEV_UNREGISTER) {
fib_disable_ip(dev, 2);
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index d41219e8037c..186f20c4a45e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1087,7 +1087,7 @@ fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
rta->rta_oif = &dev->ifindex;
if (colon) {
struct in_ifaddr *ifa;
- struct in_device *in_dev = __in_dev_get(dev);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
if (!in_dev)
return -ENODEV;
*colon = ':';
@@ -1268,7 +1268,7 @@ int fib_sync_up(struct net_device *dev)
}
if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
continue;
- if (nh->nh_dev != dev || __in_dev_get(dev) == NULL)
+ if (nh->nh_dev != dev || !__in_dev_get_rtnl(dev))
continue;
alive++;
spin_lock_bh(&fib_multipath_lock);
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index b2dea4e5da77..66247f38b371 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.404"
#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;
@@ -225,7 +224,7 @@ static inline int tkey_mismatch(t_key a, int offset, t_key b)
Consider a node 'n' and its parent 'tp'.
If n is a leaf, every bit in its key is significant. Its presence is
- necessitaded by path compression, since during a tree traversal (when
+ necessitated by path compression, since during a tree traversal (when
searching for a leaf - unless we are doing an insertion) we will completely
ignore all skipped bits we encounter. Thus we need to verify, at the end of
a potentially successful search, that we have indeed been walking the
@@ -287,6 +286,8 @@ static inline void check_tnode(const struct tnode *tn)
static int halve_threshold = 25;
static int inflate_threshold = 50;
+static int halve_threshold_root = 15;
+static int inflate_threshold_root = 25;
static void __alias_free_mem(struct rcu_head *head)
@@ -450,6 +451,8 @@ static struct node *resize(struct trie *t, struct tnode *tn)
int i;
int err = 0;
struct tnode *old_tn;
+ int inflate_threshold_use;
+ int halve_threshold_use;
if (!tn)
return NULL;
@@ -542,10 +545,17 @@ static struct node *resize(struct trie *t, struct tnode *tn)
check_tnode(tn);
+ /* Keep root node larger */
+
+ if(!tn->parent)
+ inflate_threshold_use = inflate_threshold_root;
+ else
+ inflate_threshold_use = inflate_threshold;
+
err = 0;
while ((tn->full_children > 0 &&
50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
- inflate_threshold * tnode_child_length(tn))) {
+ inflate_threshold_use * tnode_child_length(tn))) {
old_tn = tn;
tn = inflate(t, tn);
@@ -565,10 +575,18 @@ static struct node *resize(struct trie *t, struct tnode *tn)
* node is above threshold.
*/
+
+ /* Keep root node larger */
+
+ if(!tn->parent)
+ halve_threshold_use = halve_threshold_root;
+ else
+ halve_threshold_use = halve_threshold;
+
err = 0;
while (tn->bits > 1 &&
100 * (tnode_child_length(tn) - tn->empty_children) <
- halve_threshold * tnode_child_length(tn)) {
+ halve_threshold_use * tnode_child_length(tn)) {
old_tn = tn;
tn = halve(t, tn);
@@ -837,11 +855,12 @@ static void trie_init(struct trie *t)
#endif
}
-/* readside most use rcu_read_lock currently dump routines
+/* readside must use rcu_read_lock currently dump routines
via get_fa_head and dump */
-static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
+static struct leaf_info *find_leaf_info(struct leaf *l, int plen)
{
+ struct hlist_head *head = &l->list;
struct hlist_node *node;
struct leaf_info *li;
@@ -854,7 +873,7 @@ static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
static inline struct list_head * get_fa_head(struct leaf *l, int plen)
{
- struct leaf_info *li = find_leaf_info(&l->list, plen);
+ struct leaf_info *li = find_leaf_info(l, plen);
if (!li)
return NULL;
@@ -1086,7 +1105,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
}
if (tp && tp->pos + tp->bits > 32)
- printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
+ printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
tp, tp->pos, tp->bits, key, plen);
/* Rebalance the trie */
@@ -1249,7 +1268,7 @@ err:
}
-/* should be clalled with rcu_read_lock */
+/* should be called with rcu_read_lock */
static inline int check_leaf(struct trie *t, struct leaf *l,
t_key key, int *plen, const struct flowi *flp,
struct fib_result *res)
@@ -1591,7 +1610,7 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);
l = fib_find_node(t, key);
- li = find_leaf_info(&l->list, plen);
+ li = find_leaf_info(l, plen);
list_del_rcu(&fa->fa_list);
@@ -1715,7 +1734,6 @@ static int fn_trie_flush(struct fib_table *tb)
t->revision++;
- rcu_read_lock();
for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
found += trie_flush_leaf(t, l);
@@ -1723,7 +1741,6 @@ static int fn_trie_flush(struct fib_table *tb)
trie_leaf_remove(t, ll->key);
ll = l;
}
- rcu_read_unlock();
if (ll && hlist_empty(&ll->list))
trie_leaf_remove(t, ll->key);
@@ -1834,16 +1851,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
i++;
continue;
}
- if (fa->fa_info->fib_nh == NULL) {
- printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
- i++;
- continue;
- }
- if (fa->fa_info == NULL) {
- printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
- i++;
- continue;
- }
+ BUG_ON(!fa->fa_info);
if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
@@ -1966,563 +1974,531 @@ struct fib_table * __init fib_hash_init(int id)
trie_main = t;
if (id == RT_TABLE_LOCAL)
- printk("IPv4 FIB: Using LC-trie version %s\n", VERSION);
+ printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
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);
-
- if (!n) {
- seq_printf(seq, "------ trie is empty\n");
+ struct node *n = rcu_dereference(t->trie);
- rcu_read_unlock();
- return;
- }
-
- printnode_seq(seq, indent, n, pend, cindex, 0);
-
- if (!IS_TNODE(n)) {
- rcu_read_unlock();
- return;
+ if (n && IS_TNODE(n)) {
+ iter->tnode = (struct tnode *) n;
+ iter->trie = t;
+ iter->index = 0;
+ iter->depth = 1;
+ return n;
}
+ return NULL;
+}
- 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");
+ }
+ seq_indent(seq, iter->depth-1);
+ seq_printf(seq, " +-- %d.%d.%d.%d/%d %d %d %d\n",
+ NIPQUAD(prf), tn->pos, tn->bits, tn->full_children,
+ tn->empty_children);
+
+ } 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, 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);
+
+ if (!s)
+ goto out;
- rc = seq_open(file, &fib_triestat_seq_ops);
+ 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)
+static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
{
- if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops))
- return -ENOMEM;
- return 0;
-}
-
-void __init fib_stat_proc_exit(void)
-{
- 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, 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 = 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/icmp.c b/net/ipv4/icmp.c
index 24eb56ae1b5a..175e093ec564 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -188,7 +188,7 @@ struct icmp_err icmp_err_convert[] = {
/* Control parameters for ECHO replies. */
int sysctl_icmp_echo_ignore_all;
-int sysctl_icmp_echo_ignore_broadcasts;
+int sysctl_icmp_echo_ignore_broadcasts = 1;
/* Control parameter - ignore bogus broadcast responses? */
int sysctl_icmp_ignore_bogus_error_responses;
@@ -1108,12 +1108,9 @@ void __init icmp_init(struct net_proto_family *ops)
struct inet_sock *inet;
int i;
- for (i = 0; i < NR_CPUS; i++) {
+ for_each_cpu(i) {
int err;
- if (!cpu_possible(i))
- continue;
-
err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
&per_cpu(__icmp_socket, i));
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 44607f4767b8..8b6d3939e1e6 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1323,7 +1323,7 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
}
if (dev) {
imr->imr_ifindex = dev->ifindex;
- idev = __in_dev_get(dev);
+ idev = __in_dev_get_rtnl(dev);
}
return idev;
}
@@ -1603,7 +1603,7 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
}
pmc->sources = NULL;
pmc->sfmode = MCAST_EXCLUDE;
- pmc->sfcount[MCAST_EXCLUDE] = 0;
+ pmc->sfcount[MCAST_INCLUDE] = 0;
pmc->sfcount[MCAST_EXCLUDE] = 1;
}
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index fe3c6d3d0c91..94468a76c5b4 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -494,7 +494,7 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_prune);
struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
- const unsigned int __nocast priority)
+ const gfp_t priority)
{
struct sock *newsk = sk_clone(sk, priority);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 4d1502a49852..a010e9a68811 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -20,7 +20,7 @@ void __inet_twsk_kill(struct inet_timewait_sock *tw, struct inet_hashinfo *hashi
struct inet_bind_hashbucket *bhead;
struct inet_bind_bucket *tb;
/* Unlink from established hashes. */
- struct inet_ehash_bucket *ehead = &hashinfo->ehash[tw->tw_hashent];
+ struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, tw->tw_hash);
write_lock(&ehead->lock);
if (hlist_unhashed(&tw->tw_node)) {
@@ -60,7 +60,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
{
const struct inet_sock *inet = inet_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
- struct inet_ehash_bucket *ehead = &hashinfo->ehash[sk->sk_hashent];
+ struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, sk->sk_hash);
struct inet_bind_hashbucket *bhead;
/* Step 1: Put TW into bind hash. Original socket stays there too.
Note, that any socket with inet->num != 0 MUST be bound in
@@ -106,11 +106,12 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
tw->tw_dport = inet->dport;
tw->tw_family = sk->sk_family;
tw->tw_reuse = sk->sk_reuse;
- tw->tw_hashent = sk->sk_hashent;
+ tw->tw_hash = sk->sk_hash;
tw->tw_ipv6only = 0;
tw->tw_prot = sk->sk_prot_creator;
atomic_set(&tw->tw_refcnt, 1);
inet_twsk_dead_node_init(tw);
+ __module_get(tw->tw_prot->owner);
}
return tw;
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index f84ba9c96551..2fc3fd38924f 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -100,8 +100,7 @@ DEFINE_SPINLOCK(inet_peer_unused_lock);
#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/ip_gre.c b/net/ipv4/ip_gre.c
index f0d5740d7e22..896ce3f8f53a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1104,10 +1104,10 @@ static int ipgre_open(struct net_device *dev)
return -EADDRNOTAVAIL;
dev = rt->u.dst.dev;
ip_rt_put(rt);
- if (__in_dev_get(dev) == NULL)
+ if (__in_dev_get_rtnl(dev) == NULL)
return -EADDRNOTAVAIL;
t->mlink = dev->ifindex;
- ip_mc_inc_group(__in_dev_get(dev), t->parms.iph.daddr);
+ ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
}
return 0;
}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3f1a263e1249..87e350069abb 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -391,6 +391,9 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->nfct = from->nfct;
nf_conntrack_get(to->nfct);
to->nfctinfo = from->nfctinfo;
+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+ to->ipvs_property = from->ipvs_property;
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(to->nf_bridge);
to->nf_bridge = from->nf_bridge;
@@ -1020,10 +1023,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
int alloclen;
skb_prev = skb;
- if (skb_prev)
- fraggap = skb_prev->len - maxfraglen;
- else
- fraggap = 0;
+ fraggap = skb_prev->len - maxfraglen;
alloclen = fragheaderlen + hh_len + fraggap + 15;
skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation);
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 953129d392d2..e8674baaa8d9 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1103,10 +1103,8 @@ static int __init ic_dynamic(void)
#endif
jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);
- while (time_before(jiffies, jiff) && !ic_got_reply) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while (time_before(jiffies, jiff) && !ic_got_reply)
+ schedule_timeout_uninterruptible(1);
#ifdef IPCONFIG_DHCP
/* DHCP isn't done until we get a DHCPACK. */
if ((ic_got_reply & IC_BOOTP)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 9dbf5909f3a6..302b7eb507c9 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -149,7 +149,7 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
if (err == 0 && (dev = __dev_get_by_name(p.name)) != NULL) {
dev->flags |= IFF_MULTICAST;
- in_dev = __in_dev_get(dev);
+ in_dev = __in_dev_get_rtnl(dev);
if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL)
goto failure;
in_dev->cnf.rp_filter = 0;
@@ -278,7 +278,7 @@ static int vif_delete(int vifi)
dev_set_allmulti(dev, -1);
- if ((in_dev = __in_dev_get(dev)) != NULL) {
+ if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
in_dev->cnf.mc_forwarding--;
ip_rt_multicast_event(in_dev);
}
@@ -421,7 +421,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
return -EINVAL;
}
- if ((in_dev = __in_dev_get(dev)) == NULL)
+ if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
return -EADDRNOTAVAIL;
in_dev->cnf.mc_forwarding++;
dev_set_allmulti(dev, +1);
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 6e092dadb388..fc6f95aaa969 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -604,7 +604,7 @@ static struct file_operations ip_vs_app_fops = {
/*
* Replace a segment of data with a new segment
*/
-int ip_vs_skb_replace(struct sk_buff *skb, int pri,
+int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri,
char *o_buf, int o_len, char *n_buf, int n_len)
{
struct iphdr *iph;
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index e11952ea17af..f828fa2eb7de 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -196,6 +196,7 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
if (s_addr==cp->caddr && s_port==cp->cport &&
d_port==cp->vport && d_addr==cp->vaddr &&
+ ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
protocol==cp->protocol) {
/* HIT */
atomic_inc(&cp->refcnt);
@@ -227,6 +228,40 @@ struct ip_vs_conn *ip_vs_conn_in_get
return cp;
}
+/* Get reference to connection template */
+struct ip_vs_conn *ip_vs_ct_in_get
+(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+{
+ unsigned hash;
+ struct ip_vs_conn *cp;
+
+ hash = ip_vs_conn_hashkey(protocol, s_addr, s_port);
+
+ ct_read_lock(hash);
+
+ list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+ if (s_addr==cp->caddr && s_port==cp->cport &&
+ d_port==cp->vport && d_addr==cp->vaddr &&
+ cp->flags & IP_VS_CONN_F_TEMPLATE &&
+ protocol==cp->protocol) {
+ /* HIT */
+ atomic_inc(&cp->refcnt);
+ goto out;
+ }
+ }
+ cp = NULL;
+
+ out:
+ ct_read_unlock(hash);
+
+ IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+ ip_vs_proto_name(protocol),
+ NIPQUAD(s_addr), ntohs(s_port),
+ NIPQUAD(d_addr), ntohs(d_port),
+ cp?"hit":"not hit");
+
+ return cp;
+}
/*
* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab.
@@ -367,7 +402,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
atomic_read(&dest->refcnt));
/* Update the connection counters */
- if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) {
+ if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) {
/* It is a normal connection, so increase the inactive
connection counter because it is in TCP SYNRECV
state (inactive) or other protocol inacive state */
@@ -406,7 +441,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
atomic_read(&dest->refcnt));
/* Update the connection counters */
- if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) {
+ if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) {
/* It is a normal connection, so decrease the inactconns
or activeconns counter */
if (cp->flags & IP_VS_CONN_F_INACTIVE) {
@@ -467,7 +502,7 @@ int ip_vs_check_template(struct ip_vs_conn *ct)
/*
* Invalidate the connection template
*/
- if (ct->cport) {
+ if (ct->vport != 65535) {
if (ip_vs_conn_unhash(ct)) {
ct->dport = 65535;
ct->vport = 65535;
@@ -776,7 +811,7 @@ void ip_vs_random_dropentry(void)
ct_write_lock_bh(hash);
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
- if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT))
+ if (cp->flags & IP_VS_CONN_F_TEMPLATE)
/* connection template */
continue;
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 3ac7eeca04ac..981cc3244ef2 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -243,10 +243,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
if (ports[1] == svc->port) {
/* Check if a template already exists */
if (svc->port != FTPPORT)
- ct = ip_vs_conn_in_get(iph->protocol, snet, 0,
+ ct = ip_vs_ct_in_get(iph->protocol, snet, 0,
iph->daddr, ports[1]);
else
- ct = ip_vs_conn_in_get(iph->protocol, snet, 0,
+ ct = ip_vs_ct_in_get(iph->protocol, snet, 0,
iph->daddr, 0);
if (!ct || !ip_vs_check_template(ct)) {
@@ -272,14 +272,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
iph->daddr,
ports[1],
dest->addr, dest->port,
- 0,
+ IP_VS_CONN_F_TEMPLATE,
dest);
else
ct = ip_vs_conn_new(iph->protocol,
snet, 0,
iph->daddr, 0,
dest->addr, 0,
- 0,
+ IP_VS_CONN_F_TEMPLATE,
dest);
if (ct == NULL)
return NULL;
@@ -298,10 +298,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* port zero template: <protocol,caddr,0,vaddr,0,daddr,0>
*/
if (svc->fwmark)
- ct = ip_vs_conn_in_get(IPPROTO_IP, snet, 0,
+ ct = ip_vs_ct_in_get(IPPROTO_IP, snet, 0,
htonl(svc->fwmark), 0);
else
- ct = ip_vs_conn_in_get(iph->protocol, snet, 0,
+ ct = ip_vs_ct_in_get(iph->protocol, snet, 0,
iph->daddr, 0);
if (!ct || !ip_vs_check_template(ct)) {
@@ -326,14 +326,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
snet, 0,
htonl(svc->fwmark), 0,
dest->addr, 0,
- 0,
+ IP_VS_CONN_F_TEMPLATE,
dest);
else
ct = ip_vs_conn_new(iph->protocol,
snet, 0,
iph->daddr, 0,
dest->addr, 0,
- 0,
+ IP_VS_CONN_F_TEMPLATE,
dest);
if (ct == NULL)
return NULL;
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 574d1f509b46..2e5ced3d8062 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -297,16 +297,24 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
p = (char *)buffer + sizeof(struct ip_vs_sync_mesg);
for (i=0; i<m->nr_conns; i++) {
+ unsigned flags;
+
s = (struct ip_vs_sync_conn *)p;
- cp = ip_vs_conn_in_get(s->protocol,
- s->caddr, s->cport,
- s->vaddr, s->vport);
+ flags = ntohs(s->flags);
+ if (!(flags & IP_VS_CONN_F_TEMPLATE))
+ cp = ip_vs_conn_in_get(s->protocol,
+ s->caddr, s->cport,
+ s->vaddr, s->vport);
+ else
+ cp = ip_vs_ct_in_get(s->protocol,
+ s->caddr, s->cport,
+ s->vaddr, s->vport);
if (!cp) {
cp = ip_vs_conn_new(s->protocol,
s->caddr, s->cport,
s->vaddr, s->vport,
s->daddr, s->dport,
- ntohs(s->flags), NULL);
+ flags, NULL);
if (!cp) {
IP_VS_ERR("ip_vs_conn_new failed\n");
return;
@@ -315,11 +323,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
} else if (!cp->dest) {
/* it is an entry created by the synchronization */
cp->state = ntohs(s->state);
- cp->flags = ntohs(s->flags) | IP_VS_CONN_F_HASHED;
+ cp->flags = flags | IP_VS_CONN_F_HASHED;
} /* Note that we don't touch its state and flags
if it is a normal entry. */
- if (ntohs(s->flags) & IP_VS_CONN_F_SEQ_MASK) {
+ if (flags & IP_VS_CONN_F_SEQ_MASK) {
opt = (struct ip_vs_sync_conn_options *)&s[1];
memcpy(&cp->in_seq, opt, sizeof(*opt));
p += FULL_CONN_SIZE;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 30aa8e2ee214..7d917e4ce1d9 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -51,6 +51,14 @@ config IP_NF_CONNTRACK_EVENTS
IF unsure, say `N'.
+config IP_NF_CONNTRACK_NETLINK
+ tristate 'Connection tracking netlink interface'
+ depends on IP_NF_CONNTRACK && NETFILTER_NETLINK
+ depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
+ help
+ This option enables support for a netlink-based userspace interface
+
+
config IP_NF_CT_PROTO_SCTP
tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
depends on IP_NF_CONNTRACK && EXPERIMENTAL
@@ -129,6 +137,23 @@ config IP_NF_AMANDA
To compile it as a module, choose M here. If unsure, say Y.
+config IP_NF_PPTP
+ tristate 'PPTP protocol support'
+ depends on IP_NF_CONNTRACK
+ help
+ This module adds support for PPTP (Point to Point Tunnelling
+ Protocol, RFC2637) connection tracking and NAT.
+
+ If you are running PPTP sessions over a stateful firewall or NAT
+ box, you may want to enable this feature.
+
+ Please note that not all PPTP modes of operation are supported yet.
+ For more info, read top of the file
+ net/ipv4/netfilter/ip_conntrack_pptp.c
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
+
config IP_NF_QUEUE
tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
help
@@ -474,9 +499,14 @@ config IP_NF_TARGET_LOG
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_ULOG
- tristate "ULOG target support"
+ tristate "ULOG target support (OBSOLETE)"
depends on IP_NF_IPTABLES
---help---
+
+ This option enables the old IPv4-only "ipt_ULOG" implementation
+ which has been obsoleted by the new "nfnetlink_log" code (see
+ CONFIG_NETFILTER_NETLINK_LOG).
+
This option adds a `ULOG' target, which allows you to create rules in
any iptables table. The packet is passed to a userspace logging
daemon using netlink multicast sockets; unlike the LOG target
@@ -513,6 +543,17 @@ config IP_NF_TARGET_TCPMSS
To compile it as a module, choose M here. If unsure, say N.
+config IP_NF_TARGET_NFQUEUE
+ tristate "NFQUEUE Target Support"
+ depends on IP_NF_IPTABLES
+ help
+ This Target replaced the old obsolete QUEUE target.
+
+ As opposed to QUEUE, it supports 65535 different queues,
+ not just one.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# NAT + specific targets
config IP_NF_NAT
tristate "Full NAT"
@@ -613,6 +654,12 @@ config IP_NF_NAT_AMANDA
default IP_NF_NAT if IP_NF_AMANDA=y
default m if IP_NF_AMANDA=m
+config IP_NF_NAT_PPTP
+ tristate
+ depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
+ default IP_NF_NAT if IP_NF_PPTP=y
+ default m if IP_NF_PPTP=m
+
# mangle + specific targets
config IP_NF_MANGLE
tristate "Packet mangling"
@@ -774,11 +821,5 @@ config IP_NF_ARP_MANGLE
Allows altering the ARP packet payload: source and destination
hardware and network addresses.
-config IP_NF_CONNTRACK_NETLINK
- tristate 'Connection tracking netlink interface'
- depends on IP_NF_CONNTRACK && NETFILTER_NETLINK
- help
- This option enables support for a netlink-based userspace interface
-
endmenu
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 1ba0db746817..dab4b58dd31e 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -4,7 +4,11 @@
# objects for the standalone - connection tracking / NAT
ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
-iptable_nat-objs := ip_nat_standalone.o ip_nat_rule.o ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
+ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
+iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
+
+ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
+ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
# connection tracking
obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
@@ -17,6 +21,7 @@ obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
# connection tracking helpers
+obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
@@ -24,6 +29,7 @@ obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
# NAT helpers
+obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
@@ -35,7 +41,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
# the three instances of ip_tables
obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
-obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
+obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o ip_nat.o
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
# matches
@@ -87,6 +93,7 @@ obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
+obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o
# generic ARP tables
obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
@@ -96,4 +103,3 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
-obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += ipt_NFQUEUE.o
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index fa1634256680..a7969286e6e7 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -716,8 +716,10 @@ static int translate_table(const char *name,
}
/* And one copy for every other CPU */
- for (i = 1; i < num_possible_cpus(); i++) {
- memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
+ for_each_cpu(i) {
+ if (i == 0)
+ continue;
+ memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
newinfo->entries,
SMP_ALIGN(newinfo->size));
}
@@ -767,7 +769,7 @@ static void get_counters(const struct arpt_table_info *t,
unsigned int cpu;
unsigned int i;
- for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+ for_each_cpu(cpu) {
i = 0;
ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
t->size,
@@ -885,7 +887,8 @@ static int do_replace(void __user *user, unsigned int len)
return -ENOMEM;
newinfo = vmalloc(sizeof(struct arpt_table_info)
- + SMP_ALIGN(tmp.size) * num_possible_cpus());
+ + SMP_ALIGN(tmp.size) *
+ (highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;
@@ -1158,7 +1161,8 @@ int arpt_register_table(struct arpt_table *table,
= { 0, 0, 0, { 0 }, { 0 }, { } };
newinfo = vmalloc(sizeof(struct arpt_table_info)
- + SMP_ALIGN(repl->size) * num_possible_cpus());
+ + SMP_ALIGN(repl->size) *
+ (highest_possible_processor_id()+1));
if (!newinfo) {
ret = -ENOMEM;
return ret;
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index dc20881004bc..fa3f914117ec 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -65,7 +65,7 @@ static int help(struct sk_buff **pskb,
/* increase the UDP timeout of the master connection as replies from
* Amanda clients to the server can be quite delayed */
- ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ);
+ ip_ct_refresh(ct, *pskb, master_timeout * HZ);
/* No data? */
dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 19cba16e6e1e..422ab68ee7fb 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -50,7 +50,7 @@
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/listhelp.h>
-#define IP_CONNTRACK_VERSION "2.3"
+#define IP_CONNTRACK_VERSION "2.4"
#if 0
#define DEBUGP printk
@@ -148,16 +148,20 @@ DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
static int ip_conntrack_hash_rnd_initted;
static unsigned int ip_conntrack_hash_rnd;
-static u_int32_t
-hash_conntrack(const struct ip_conntrack_tuple *tuple)
+static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
+ unsigned int size, unsigned int rnd)
{
-#if 0
- dump_tuple(tuple);
-#endif
return (jhash_3words(tuple->src.ip,
(tuple->dst.ip ^ tuple->dst.protonum),
(tuple->src.u.all | (tuple->dst.u.all << 16)),
- ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
+ rnd) % size);
+}
+
+static u_int32_t
+hash_conntrack(const struct ip_conntrack_tuple *tuple)
+{
+ return __hash_conntrack(tuple, ip_conntrack_htable_size,
+ ip_conntrack_hash_rnd);
}
int
@@ -233,7 +237,7 @@ __ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple)
/* Just find a expectation corresponding to a tuple. */
struct ip_conntrack_expect *
-ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple)
+ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple)
{
struct ip_conntrack_expect *i;
@@ -1112,42 +1116,49 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
synchronize_net();
}
-static inline void ct_add_counters(struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- const struct sk_buff *skb)
-{
-#ifdef CONFIG_IP_NF_CT_ACCT
- if (skb) {
- ct->counters[CTINFO2DIR(ctinfo)].packets++;
- ct->counters[CTINFO2DIR(ctinfo)].bytes +=
- ntohs(skb->nh.iph->tot_len);
- }
-#endif
-}
-
-/* Refresh conntrack for this many jiffies and do accounting (if skb != NULL) */
-void ip_ct_refresh_acct(struct ip_conntrack *ct,
+/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
+void __ip_ct_refresh_acct(struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
const struct sk_buff *skb,
- unsigned long extra_jiffies)
+ unsigned long extra_jiffies,
+ int do_acct)
{
+ int event = 0;
+
IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
+ IP_NF_ASSERT(skb);
+
+ write_lock_bh(&ip_conntrack_lock);
/* If not in hash table, timer will not be active yet */
if (!is_confirmed(ct)) {
ct->timeout.expires = extra_jiffies;
- ct_add_counters(ct, ctinfo, skb);
+ event = IPCT_REFRESH;
} else {
- write_lock_bh(&ip_conntrack_lock);
/* Need del_timer for race avoidance (may already be dying). */
if (del_timer(&ct->timeout)) {
ct->timeout.expires = jiffies + extra_jiffies;
add_timer(&ct->timeout);
- ip_conntrack_event_cache(IPCT_REFRESH, skb);
+ event = IPCT_REFRESH;
}
- ct_add_counters(ct, ctinfo, skb);
- write_unlock_bh(&ip_conntrack_lock);
}
+
+#ifdef CONFIG_IP_NF_CT_ACCT
+ if (do_acct) {
+ ct->counters[CTINFO2DIR(ctinfo)].packets++;
+ ct->counters[CTINFO2DIR(ctinfo)].bytes +=
+ ntohs(skb->nh.iph->tot_len);
+ if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
+ || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
+ event |= IPCT_COUNTER_FILLING;
+ }
+#endif
+
+ write_unlock_bh(&ip_conntrack_lock);
+
+ /* must be unlocked when calling event cache */
+ if (event)
+ ip_conntrack_event_cache(event, skb);
}
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
@@ -1334,14 +1345,13 @@ static int kill_all(struct ip_conntrack *i, void *data)
return 1;
}
-static void free_conntrack_hash(void)
+static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
{
- if (ip_conntrack_vmalloc)
- vfree(ip_conntrack_hash);
+ if (vmalloced)
+ vfree(hash);
else
- free_pages((unsigned long)ip_conntrack_hash,
- get_order(sizeof(struct list_head)
- * ip_conntrack_htable_size));
+ free_pages((unsigned long)hash,
+ get_order(sizeof(struct list_head) * size));
}
void ip_conntrack_flush()
@@ -1371,12 +1381,83 @@ void ip_conntrack_cleanup(void)
ip_conntrack_flush();
kmem_cache_destroy(ip_conntrack_cachep);
kmem_cache_destroy(ip_conntrack_expect_cachep);
- free_conntrack_hash();
+ free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
+ ip_conntrack_htable_size);
nf_unregister_sockopt(&so_getorigdst);
}
-static int hashsize;
-module_param(hashsize, int, 0400);
+static struct list_head *alloc_hashtable(int size, int *vmalloced)
+{
+ struct list_head *hash;
+ unsigned int i;
+
+ *vmalloced = 0;
+ hash = (void*)__get_free_pages(GFP_KERNEL,
+ get_order(sizeof(struct list_head)
+ * size));
+ if (!hash) {
+ *vmalloced = 1;
+ printk(KERN_WARNING"ip_conntrack: falling back to vmalloc.\n");
+ hash = vmalloc(sizeof(struct list_head) * size);
+ }
+
+ if (hash)
+ for (i = 0; i < size; i++)
+ INIT_LIST_HEAD(&hash[i]);
+
+ return hash;
+}
+
+int set_hashsize(const char *val, struct kernel_param *kp)
+{
+ int i, bucket, hashsize, vmalloced;
+ int old_vmalloced, old_size;
+ int rnd;
+ struct list_head *hash, *old_hash;
+ struct ip_conntrack_tuple_hash *h;
+
+ /* On boot, we can set this without any fancy locking. */
+ if (!ip_conntrack_htable_size)
+ return param_set_int(val, kp);
+
+ hashsize = simple_strtol(val, NULL, 0);
+ if (!hashsize)
+ return -EINVAL;
+
+ hash = alloc_hashtable(hashsize, &vmalloced);
+ if (!hash)
+ return -ENOMEM;
+
+ /* We have to rehash for the new table anyway, so we also can
+ * use a new random seed */
+ get_random_bytes(&rnd, 4);
+
+ write_lock_bh(&ip_conntrack_lock);
+ for (i = 0; i < ip_conntrack_htable_size; i++) {
+ while (!list_empty(&ip_conntrack_hash[i])) {
+ h = list_entry(ip_conntrack_hash[i].next,
+ struct ip_conntrack_tuple_hash, list);
+ list_del(&h->list);
+ bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
+ list_add_tail(&h->list, &hash[bucket]);
+ }
+ }
+ old_size = ip_conntrack_htable_size;
+ old_vmalloced = ip_conntrack_vmalloc;
+ old_hash = ip_conntrack_hash;
+
+ ip_conntrack_htable_size = hashsize;
+ ip_conntrack_vmalloc = vmalloced;
+ ip_conntrack_hash = hash;
+ ip_conntrack_hash_rnd = rnd;
+ write_unlock_bh(&ip_conntrack_lock);
+
+ free_conntrack_hash(old_hash, old_vmalloced, old_size);
+ return 0;
+}
+
+module_param_call(hashsize, set_hashsize, param_get_uint,
+ &ip_conntrack_htable_size, 0600);
int __init ip_conntrack_init(void)
{
@@ -1385,9 +1466,7 @@ int __init ip_conntrack_init(void)
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
* machine has 256 buckets. >= 1GB machines have 8192 buckets. */
- if (hashsize) {
- ip_conntrack_htable_size = hashsize;
- } else {
+ if (!ip_conntrack_htable_size) {
ip_conntrack_htable_size
= (((num_physpages << PAGE_SHIFT) / 16384)
/ sizeof(struct list_head));
@@ -1409,20 +1488,8 @@ int __init ip_conntrack_init(void)
return ret;
}
- /* AK: the hash table is twice as big than needed because it
- uses list_head. it would be much nicer to caches to use a
- single pointer list head here. */
- ip_conntrack_vmalloc = 0;
- ip_conntrack_hash
- =(void*)__get_free_pages(GFP_KERNEL,
- get_order(sizeof(struct list_head)
- *ip_conntrack_htable_size));
- if (!ip_conntrack_hash) {
- ip_conntrack_vmalloc = 1;
- printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n");
- ip_conntrack_hash = vmalloc(sizeof(struct list_head)
- * ip_conntrack_htable_size);
- }
+ ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size,
+ &ip_conntrack_vmalloc);
if (!ip_conntrack_hash) {
printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
goto err_unreg_sockopt;
@@ -1454,9 +1521,6 @@ int __init ip_conntrack_init(void)
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
write_unlock_bh(&ip_conntrack_lock);
- for (i = 0; i < ip_conntrack_htable_size; i++)
- INIT_LIST_HEAD(&ip_conntrack_hash[i]);
-
/* For use by ipt_REJECT */
ip_ct_attach = ip_conntrack_attach;
@@ -1471,7 +1535,8 @@ int __init ip_conntrack_init(void)
err_free_conntrack_slab:
kmem_cache_destroy(ip_conntrack_cachep);
err_free_hash:
- free_conntrack_hash();
+ free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
+ ip_conntrack_htable_size);
err_unreg_sockopt:
nf_unregister_sockopt(&so_getorigdst);
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 1b79ec36085f..d77d6b3f5f80 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -29,9 +29,9 @@ static char *ftp_buffer;
static DEFINE_SPINLOCK(ip_ftp_lock);
#define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static short ports[MAX_PORTS];
static int ports_c;
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, short, &ports_c, 0400);
static int loose;
module_param(loose, int, 0600);
@@ -450,7 +450,7 @@ out_update_nl:
}
static struct ip_conntrack_helper ftp[MAX_PORTS];
-static char ftp_names[MAX_PORTS][10];
+static char ftp_names[MAX_PORTS][sizeof("ftp-65535")];
/* Not __exit: called from init() */
static void fini(void)
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
new file mode 100644
index 000000000000..926a6684643d
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -0,0 +1,806 @@
+/*
+ * ip_conntrack_pptp.c - Version 3.0
+ *
+ * Connection tracking support for PPTP (Point to Point Tunneling Protocol).
+ * PPTP is a a protocol for creating virtual private networks.
+ * It is a specification defined by Microsoft and some vendors
+ * working with Microsoft. PPTP is built on top of a modified
+ * version of the Internet Generic Routing Encapsulation Protocol.
+ * GRE is defined in RFC 1701 and RFC 1702. Documentation of
+ * PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ * Limitations:
+ * - We blindly assume that control connections are always
+ * established in PNS->PAC direction. This is a violation
+ * of RFFC2673
+ * - We can only support one single call within each session
+ *
+ * TODO:
+ * - testing of incoming PPTP calls
+ *
+ * Changes:
+ * 2002-02-05 - Version 1.3
+ * - Call ip_conntrack_unexpect_related() from
+ * pptp_destroy_siblings() to destroy expectations in case
+ * CALL_DISCONNECT_NOTIFY or tcp fin packet was seen
+ * (Philip Craig <philipc@snapgear.com>)
+ * - Add Version information at module loadtime
+ * 2002-02-10 - Version 1.6
+ * - move to C99 style initializers
+ * - remove second expectation if first arrives
+ * 2004-10-22 - Version 2.0
+ * - merge Mandrake's 2.6.x port with recent 2.6.x API changes
+ * - fix lots of linear skb assumptions from Mandrake's port
+ * 2005-06-10 - Version 2.1
+ * - use ip_conntrack_expect_free() instead of kfree() on the
+ * expect's (which are from the slab for quite some time)
+ * 2005-06-10 - Version 3.0
+ * - port helper to post-2.6.11 API changes,
+ * funded by Oxcoda NetBox Blue (http://www.netboxblue.com/)
+ * 2005-07-30 - Version 3.1
+ * - port helper to 2.6.13 API changes
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
+
+#define IP_CT_PPTP_VERSION "3.1"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");
+
+static DEFINE_SPINLOCK(ip_pptp_lock);
+
+int
+(*ip_nat_pptp_hook_outbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+int
+(*ip_nat_pptp_hook_inbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+int
+(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *expect_orig,
+ struct ip_conntrack_expect *expect_reply);
+
+void
+(*ip_nat_pptp_hook_expectfn)(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp);
+
+#if 0
+/* PptpControlMessageType names */
+const char *pptp_msg_name[] = {
+ "UNKNOWN_MESSAGE",
+ "START_SESSION_REQUEST",
+ "START_SESSION_REPLY",
+ "STOP_SESSION_REQUEST",
+ "STOP_SESSION_REPLY",
+ "ECHO_REQUEST",
+ "ECHO_REPLY",
+ "OUT_CALL_REQUEST",
+ "OUT_CALL_REPLY",
+ "IN_CALL_REQUEST",
+ "IN_CALL_REPLY",
+ "IN_CALL_CONNECT",
+ "CALL_CLEAR_REQUEST",
+ "CALL_DISCONNECT_NOTIFY",
+ "WAN_ERROR_NOTIFY",
+ "SET_LINK_INFO"
+};
+EXPORT_SYMBOL(pptp_msg_name);
+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#define SECS *HZ
+#define MINS * 60 SECS
+#define HOURS * 60 MINS
+
+#define PPTP_GRE_TIMEOUT (10 MINS)
+#define PPTP_GRE_STREAM_TIMEOUT (5 HOURS)
+
+static void pptp_expectfn(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp)
+{
+ DEBUGP("increasing timeouts\n");
+
+ /* increase timeout of GRE data channel conntrack entry */
+ ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
+ ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;
+
+ /* Can you see how rusty this code is, compared with the pre-2.6.11
+ * one? That's what happened to my shiny newnat of 2002 ;( -HW */
+
+ if (!ip_nat_pptp_hook_expectfn) {
+ struct ip_conntrack_tuple inv_t;
+ struct ip_conntrack_expect *exp_other;
+
+ /* obviously this tuple inversion only works until you do NAT */
+ invert_tuplepr(&inv_t, &exp->tuple);
+ DEBUGP("trying to unexpect other dir: ");
+ DUMP_TUPLE(&inv_t);
+
+ exp_other = ip_conntrack_expect_find(&inv_t);
+ if (exp_other) {
+ /* delete other expectation. */
+ DEBUGP("found\n");
+ ip_conntrack_unexpect_related(exp_other);
+ ip_conntrack_expect_put(exp_other);
+ } else {
+ DEBUGP("not found\n");
+ }
+ } else {
+ /* we need more than simple inversion */
+ ip_nat_pptp_hook_expectfn(ct, exp);
+ }
+}
+
+static int destroy_sibling_or_exp(const struct ip_conntrack_tuple *t)
+{
+ struct ip_conntrack_tuple_hash *h;
+ struct ip_conntrack_expect *exp;
+
+ DEBUGP("trying to timeout ct or exp for tuple ");
+ DUMP_TUPLE(t);
+
+ h = ip_conntrack_find_get(t, NULL);
+ if (h) {
+ struct ip_conntrack *sibling = tuplehash_to_ctrack(h);
+ DEBUGP("setting timeout of conntrack %p to 0\n", sibling);
+ sibling->proto.gre.timeout = 0;
+ sibling->proto.gre.stream_timeout = 0;
+ if (del_timer(&sibling->timeout))
+ sibling->timeout.function((unsigned long)sibling);
+ ip_conntrack_put(sibling);
+ return 1;
+ } else {
+ exp = ip_conntrack_expect_find(t);
+ if (exp) {
+ DEBUGP("unexpect_related of expect %p\n", exp);
+ ip_conntrack_unexpect_related(exp);
+ ip_conntrack_expect_put(exp);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/* timeout GRE data connections */
+static void pptp_destroy_siblings(struct ip_conntrack *ct)
+{
+ struct ip_conntrack_tuple t;
+
+ /* Since ct->sibling_list has literally rusted away in 2.6.11,
+ * we now need another way to find out about our sibling
+ * contrack and expects... -HW */
+
+ /* try original (pns->pac) tuple */
+ memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t));
+ t.dst.protonum = IPPROTO_GRE;
+ t.src.u.gre.key = htons(ct->help.ct_pptp_info.pns_call_id);
+ t.dst.u.gre.key = htons(ct->help.ct_pptp_info.pac_call_id);
+
+ if (!destroy_sibling_or_exp(&t))
+ DEBUGP("failed to timeout original pns->pac ct/exp\n");
+
+ /* try reply (pac->pns) tuple */
+ memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));
+ t.dst.protonum = IPPROTO_GRE;
+ t.src.u.gre.key = htons(ct->help.ct_pptp_info.pac_call_id);
+ t.dst.u.gre.key = htons(ct->help.ct_pptp_info.pns_call_id);
+
+ if (!destroy_sibling_or_exp(&t))
+ DEBUGP("failed to timeout reply pac->pns ct/exp\n");
+}
+
+/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
+static inline int
+exp_gre(struct ip_conntrack *master,
+ u_int32_t seq,
+ __be16 callid,
+ __be16 peer_callid)
+{
+ struct ip_conntrack_tuple inv_tuple;
+ struct ip_conntrack_tuple exp_tuples[] = {
+ /* tuple in original direction, PNS->PAC */
+ { .src = { .ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip,
+ .u = { .gre = { .key = peer_callid } }
+ },
+ .dst = { .ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip,
+ .u = { .gre = { .key = callid } },
+ .protonum = IPPROTO_GRE
+ },
+ },
+ /* tuple in reply direction, PAC->PNS */
+ { .src = { .ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip,
+ .u = { .gre = { .key = callid } }
+ },
+ .dst = { .ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip,
+ .u = { .gre = { .key = peer_callid } },
+ .protonum = IPPROTO_GRE
+ },
+ }
+ };
+ struct ip_conntrack_expect *exp_orig, *exp_reply;
+ int ret = 1;
+
+ exp_orig = ip_conntrack_expect_alloc(master);
+ if (exp_orig == NULL)
+ goto out;
+
+ exp_reply = ip_conntrack_expect_alloc(master);
+ if (exp_reply == NULL)
+ goto out_put_orig;
+
+ memcpy(&exp_orig->tuple, &exp_tuples[0], sizeof(exp_orig->tuple));
+
+ exp_orig->mask.src.ip = 0xffffffff;
+ exp_orig->mask.src.u.all = 0;
+ exp_orig->mask.dst.u.all = 0;
+ exp_orig->mask.dst.u.gre.key = htons(0xffff);
+ exp_orig->mask.dst.ip = 0xffffffff;
+ exp_orig->mask.dst.protonum = 0xff;
+
+ exp_orig->master = master;
+ exp_orig->expectfn = pptp_expectfn;
+ exp_orig->flags = 0;
+
+ exp_orig->dir = IP_CT_DIR_ORIGINAL;
+
+ /* both expectations are identical apart from tuple */
+ memcpy(exp_reply, exp_orig, sizeof(*exp_reply));
+ memcpy(&exp_reply->tuple, &exp_tuples[1], sizeof(exp_reply->tuple));
+
+ exp_reply->dir = !exp_orig->dir;
+
+ if (ip_nat_pptp_hook_exp_gre)
+ ret = ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);
+ else {
+
+ DEBUGP("calling expect_related PNS->PAC");
+ DUMP_TUPLE(&exp_orig->tuple);
+
+ if (ip_conntrack_expect_related(exp_orig) != 0) {
+ DEBUGP("cannot expect_related()\n");
+ goto out_put_both;
+ }
+
+ DEBUGP("calling expect_related PAC->PNS");
+ DUMP_TUPLE(&exp_reply->tuple);
+
+ if (ip_conntrack_expect_related(exp_reply) != 0) {
+ DEBUGP("cannot expect_related()\n");
+ goto out_unexpect_orig;
+ }
+
+ /* Add GRE keymap entries */
+ if (ip_ct_gre_keymap_add(master, &exp_reply->tuple, 0) != 0) {
+ DEBUGP("cannot keymap_add() exp\n");
+ goto out_unexpect_both;
+ }
+
+ invert_tuplepr(&inv_tuple, &exp_reply->tuple);
+ if (ip_ct_gre_keymap_add(master, &inv_tuple, 1) != 0) {
+ ip_ct_gre_keymap_destroy(master);
+ DEBUGP("cannot keymap_add() exp_inv\n");
+ goto out_unexpect_both;
+ }
+ ret = 0;
+ }
+
+out_put_both:
+ ip_conntrack_expect_put(exp_reply);
+out_put_orig:
+ ip_conntrack_expect_put(exp_orig);
+out:
+ return ret;
+
+out_unexpect_both:
+ ip_conntrack_unexpect_related(exp_reply);
+out_unexpect_orig:
+ ip_conntrack_unexpect_related(exp_orig);
+ goto out_put_both;
+}
+
+static inline int
+pptp_inbound_pkt(struct sk_buff **pskb,
+ struct tcphdr *tcph,
+ unsigned int nexthdr_off,
+ unsigned int datalen,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo)
+{
+ struct PptpControlHeader _ctlh, *ctlh;
+ unsigned int reqlen;
+ union pptp_ctrl_union _pptpReq, *pptpReq;
+ struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
+ u_int16_t msg;
+ __be16 *cid, *pcid;
+ u_int32_t seq;
+
+ ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh);
+ if (!ctlh) {
+ DEBUGP("error during skb_header_pointer\n");
+ return NF_ACCEPT;
+ }
+ nexthdr_off += sizeof(_ctlh);
+ datalen -= sizeof(_ctlh);
+
+ reqlen = datalen;
+ if (reqlen > sizeof(*pptpReq))
+ reqlen = sizeof(*pptpReq);
+ pptpReq = skb_header_pointer(*pskb, nexthdr_off, reqlen, &_pptpReq);
+ if (!pptpReq) {
+ DEBUGP("error during skb_header_pointer\n");
+ return NF_ACCEPT;
+ }
+
+ msg = ntohs(ctlh->messageType);
+ DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
+
+ switch (msg) {
+ case PPTP_START_SESSION_REPLY:
+ if (reqlen < sizeof(_pptpReq.srep)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* server confirms new control session */
+ if (info->sstate < PPTP_SESSION_REQUESTED) {
+ DEBUGP("%s without START_SESS_REQUEST\n",
+ pptp_msg_name[msg]);
+ break;
+ }
+ if (pptpReq->srep.resultCode == PPTP_START_OK)
+ info->sstate = PPTP_SESSION_CONFIRMED;
+ else
+ info->sstate = PPTP_SESSION_ERROR;
+ break;
+
+ case PPTP_STOP_SESSION_REPLY:
+ if (reqlen < sizeof(_pptpReq.strep)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* server confirms end of control session */
+ if (info->sstate > PPTP_SESSION_STOPREQ) {
+ DEBUGP("%s without STOP_SESS_REQUEST\n",
+ pptp_msg_name[msg]);
+ break;
+ }
+ if (pptpReq->strep.resultCode == PPTP_STOP_OK)
+ info->sstate = PPTP_SESSION_NONE;
+ else
+ info->sstate = PPTP_SESSION_ERROR;
+ break;
+
+ case PPTP_OUT_CALL_REPLY:
+ if (reqlen < sizeof(_pptpReq.ocack)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* server accepted call, we now expect GRE frames */
+ if (info->sstate != PPTP_SESSION_CONFIRMED) {
+ DEBUGP("%s but no session\n", pptp_msg_name[msg]);
+ break;
+ }
+ if (info->cstate != PPTP_CALL_OUT_REQ &&
+ info->cstate != PPTP_CALL_OUT_CONF) {
+ DEBUGP("%s without OUTCALL_REQ\n", pptp_msg_name[msg]);
+ break;
+ }
+ if (pptpReq->ocack.resultCode != PPTP_OUTCALL_CONNECT) {
+ info->cstate = PPTP_CALL_NONE;
+ break;
+ }
+
+ cid = &pptpReq->ocack.callID;
+ pcid = &pptpReq->ocack.peersCallID;
+
+ info->pac_call_id = ntohs(*cid);
+
+ if (htons(info->pns_call_id) != *pcid) {
+ DEBUGP("%s for unknown callid %u\n",
+ pptp_msg_name[msg], ntohs(*pcid));
+ break;
+ }
+
+ DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
+ ntohs(*cid), ntohs(*pcid));
+
+ info->cstate = PPTP_CALL_OUT_CONF;
+
+ seq = ntohl(tcph->seq) + sizeof(struct pptp_pkt_hdr)
+ + sizeof(struct PptpControlHeader)
+ + ((void *)pcid - (void *)pptpReq);
+
+ if (exp_gre(ct, seq, *cid, *pcid) != 0)
+ printk("ip_conntrack_pptp: error during exp_gre\n");
+ break;
+
+ case PPTP_IN_CALL_REQUEST:
+ if (reqlen < sizeof(_pptpReq.icack)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* server tells us about incoming call request */
+ if (info->sstate != PPTP_SESSION_CONFIRMED) {
+ DEBUGP("%s but no session\n", pptp_msg_name[msg]);
+ break;
+ }
+ pcid = &pptpReq->icack.peersCallID;
+ DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(*pcid));
+ info->cstate = PPTP_CALL_IN_REQ;
+ info->pac_call_id = ntohs(*pcid);
+ break;
+
+ case PPTP_IN_CALL_CONNECT:
+ if (reqlen < sizeof(_pptpReq.iccon)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* server tells us about incoming call established */
+ if (info->sstate != PPTP_SESSION_CONFIRMED) {
+ DEBUGP("%s but no session\n", pptp_msg_name[msg]);
+ break;
+ }
+ if (info->sstate != PPTP_CALL_IN_REP
+ && info->sstate != PPTP_CALL_IN_CONF) {
+ DEBUGP("%s but never sent IN_CALL_REPLY\n",
+ pptp_msg_name[msg]);
+ break;
+ }
+
+ pcid = &pptpReq->iccon.peersCallID;
+ cid = &info->pac_call_id;
+
+ if (info->pns_call_id != ntohs(*pcid)) {
+ DEBUGP("%s for unknown CallID %u\n",
+ pptp_msg_name[msg], ntohs(*pcid));
+ break;
+ }
+
+ DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(*pcid));
+ info->cstate = PPTP_CALL_IN_CONF;
+
+ /* we expect a GRE connection from PAC to PNS */
+ seq = ntohl(tcph->seq) + sizeof(struct pptp_pkt_hdr)
+ + sizeof(struct PptpControlHeader)
+ + ((void *)pcid - (void *)pptpReq);
+
+ if (exp_gre(ct, seq, *cid, *pcid) != 0)
+ printk("ip_conntrack_pptp: error during exp_gre\n");
+
+ break;
+
+ case PPTP_CALL_DISCONNECT_NOTIFY:
+ if (reqlen < sizeof(_pptpReq.disc)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* server confirms disconnect */
+ cid = &pptpReq->disc.callID;
+ DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(*cid));
+ info->cstate = PPTP_CALL_NONE;
+
+ /* untrack this call id, unexpect GRE packets */
+ pptp_destroy_siblings(ct);
+ break;
+
+ case PPTP_WAN_ERROR_NOTIFY:
+ break;
+
+ case PPTP_ECHO_REQUEST:
+ case PPTP_ECHO_REPLY:
+ /* I don't have to explain these ;) */
+ break;
+ default:
+ DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)
+ ? pptp_msg_name[msg]:pptp_msg_name[0], msg);
+ break;
+ }
+
+
+ if (ip_nat_pptp_hook_inbound)
+ return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh,
+ pptpReq);
+
+ return NF_ACCEPT;
+
+}
+
+static inline int
+pptp_outbound_pkt(struct sk_buff **pskb,
+ struct tcphdr *tcph,
+ unsigned int nexthdr_off,
+ unsigned int datalen,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo)
+{
+ struct PptpControlHeader _ctlh, *ctlh;
+ unsigned int reqlen;
+ union pptp_ctrl_union _pptpReq, *pptpReq;
+ struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
+ u_int16_t msg;
+ __be16 *cid, *pcid;
+
+ ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh);
+ if (!ctlh)
+ return NF_ACCEPT;
+ nexthdr_off += sizeof(_ctlh);
+ datalen -= sizeof(_ctlh);
+
+ reqlen = datalen;
+ if (reqlen > sizeof(*pptpReq))
+ reqlen = sizeof(*pptpReq);
+ pptpReq = skb_header_pointer(*pskb, nexthdr_off, reqlen, &_pptpReq);
+ if (!pptpReq)
+ return NF_ACCEPT;
+
+ msg = ntohs(ctlh->messageType);
+ DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
+
+ switch (msg) {
+ case PPTP_START_SESSION_REQUEST:
+ /* client requests for new control session */
+ if (info->sstate != PPTP_SESSION_NONE) {
+ DEBUGP("%s but we already have one",
+ pptp_msg_name[msg]);
+ }
+ info->sstate = PPTP_SESSION_REQUESTED;
+ break;
+ case PPTP_STOP_SESSION_REQUEST:
+ /* client requests end of control session */
+ info->sstate = PPTP_SESSION_STOPREQ;
+ break;
+
+ case PPTP_OUT_CALL_REQUEST:
+ if (reqlen < sizeof(_pptpReq.ocreq)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ /* FIXME: break; */
+ }
+
+ /* client initiating connection to server */
+ if (info->sstate != PPTP_SESSION_CONFIRMED) {
+ DEBUGP("%s but no session\n",
+ pptp_msg_name[msg]);
+ break;
+ }
+ info->cstate = PPTP_CALL_OUT_REQ;
+ /* track PNS call id */
+ cid = &pptpReq->ocreq.callID;
+ DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(*cid));
+ info->pns_call_id = ntohs(*cid);
+ break;
+ case PPTP_IN_CALL_REPLY:
+ if (reqlen < sizeof(_pptpReq.icack)) {
+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
+ break;
+ }
+
+ /* client answers incoming call */
+ if (info->cstate != PPTP_CALL_IN_REQ
+ && info->cstate != PPTP_CALL_IN_REP) {
+ DEBUGP("%s without incall_req\n",
+ pptp_msg_name[msg]);
+ break;
+ }
+ if (pptpReq->icack.resultCode != PPTP_INCALL_ACCEPT) {
+ info->cstate = PPTP_CALL_NONE;
+ break;
+ }
+ pcid = &pptpReq->icack.peersCallID;
+ if (info->pac_call_id != ntohs(*pcid)) {
+ DEBUGP("%s for unknown call %u\n",
+ pptp_msg_name[msg], ntohs(*pcid));
+ break;
+ }
+ DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(*pcid));
+ /* part two of the three-way handshake */
+ info->cstate = PPTP_CALL_IN_REP;
+ info->pns_call_id = ntohs(pptpReq->icack.callID);
+ break;
+
+ case PPTP_CALL_CLEAR_REQUEST:
+ /* client requests hangup of call */
+ if (info->sstate != PPTP_SESSION_CONFIRMED) {
+ DEBUGP("CLEAR_CALL but no session\n");
+ break;
+ }
+ /* FUTURE: iterate over all calls and check if
+ * call ID is valid. We don't do this without newnat,
+ * because we only know about last call */
+ info->cstate = PPTP_CALL_CLEAR_REQ;
+ break;
+ case PPTP_SET_LINK_INFO:
+ break;
+ case PPTP_ECHO_REQUEST:
+ case PPTP_ECHO_REPLY:
+ /* I don't have to explain these ;) */
+ break;
+ default:
+ DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)?
+ pptp_msg_name[msg]:pptp_msg_name[0], msg);
+ /* unknown: no need to create GRE masq table entry */
+ break;
+ }
+
+ if (ip_nat_pptp_hook_outbound)
+ return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh,
+ pptpReq);
+
+ return NF_ACCEPT;
+}
+
+
+/* track caller id inside control connection, call expect_related */
+static int
+conntrack_pptp_help(struct sk_buff **pskb,
+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+
+{
+ struct pptp_pkt_hdr _pptph, *pptph;
+ struct tcphdr _tcph, *tcph;
+ u_int32_t tcplen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
+ u_int32_t datalen;
+ int dir = CTINFO2DIR(ctinfo);
+ struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
+ unsigned int nexthdr_off;
+
+ int oldsstate, oldcstate;
+ int ret;
+
+ /* don't do any tracking before tcp handshake complete */
+ if (ctinfo != IP_CT_ESTABLISHED
+ && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
+ DEBUGP("ctinfo = %u, skipping\n", ctinfo);
+ return NF_ACCEPT;
+ }
+
+ nexthdr_off = (*pskb)->nh.iph->ihl*4;
+ tcph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_tcph), &_tcph);
+ BUG_ON(!tcph);
+ nexthdr_off += tcph->doff * 4;
+ datalen = tcplen - tcph->doff * 4;
+
+ if (tcph->fin || tcph->rst) {
+ DEBUGP("RST/FIN received, timeouting GRE\n");
+ /* can't do this after real newnat */
+ info->cstate = PPTP_CALL_NONE;
+
+ /* untrack this call id, unexpect GRE packets */
+ pptp_destroy_siblings(ct);
+ }
+
+ pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
+ if (!pptph) {
+ DEBUGP("no full PPTP header, can't track\n");
+ return NF_ACCEPT;
+ }
+ nexthdr_off += sizeof(_pptph);
+ datalen -= sizeof(_pptph);
+
+ /* if it's not a control message we can't do anything with it */
+ if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
+ ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
+ DEBUGP("not a control packet\n");
+ return NF_ACCEPT;
+ }
+
+ oldsstate = info->sstate;
+ oldcstate = info->cstate;
+
+ spin_lock_bh(&ip_pptp_lock);
+
+ /* FIXME: We just blindly assume that the control connection is always
+ * established from PNS->PAC. However, RFC makes no guarantee */
+ if (dir == IP_CT_DIR_ORIGINAL)
+ /* client -> server (PNS -> PAC) */
+ ret = pptp_outbound_pkt(pskb, tcph, nexthdr_off, datalen, ct,
+ ctinfo);
+ else
+ /* server -> client (PAC -> PNS) */
+ ret = pptp_inbound_pkt(pskb, tcph, nexthdr_off, datalen, ct,
+ ctinfo);
+ DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
+ oldsstate, info->sstate, oldcstate, info->cstate);
+ spin_unlock_bh(&ip_pptp_lock);
+
+ return ret;
+}
+
+/* control protocol helper */
+static struct ip_conntrack_helper pptp = {
+ .list = { NULL, NULL },
+ .name = "pptp",
+ .me = THIS_MODULE,
+ .max_expected = 2,
+ .timeout = 5 * 60,
+ .tuple = { .src = { .ip = 0,
+ .u = { .tcp = { .port =
+ __constant_htons(PPTP_CONTROL_PORT) } }
+ },
+ .dst = { .ip = 0,
+ .u = { .all = 0 },
+ .protonum = IPPROTO_TCP
+ }
+ },
+ .mask = { .src = { .ip = 0,
+ .u = { .tcp = { .port = __constant_htons(0xffff) } }
+ },
+ .dst = { .ip = 0,
+ .u = { .all = 0 },
+ .protonum = 0xff
+ }
+ },
+ .help = conntrack_pptp_help
+};
+
+extern void __exit ip_ct_proto_gre_fini(void);
+extern int __init ip_ct_proto_gre_init(void);
+
+/* ip_conntrack_pptp initialization */
+static int __init init(void)
+{
+ int retcode;
+
+ retcode = ip_ct_proto_gre_init();
+ if (retcode < 0)
+ return retcode;
+
+ DEBUGP(" registering helper\n");
+ if ((retcode = ip_conntrack_helper_register(&pptp))) {
+ printk(KERN_ERR "Unable to register conntrack application "
+ "helper for pptp: %d\n", retcode);
+ ip_ct_proto_gre_fini();
+ return retcode;
+ }
+
+ printk("ip_conntrack_pptp version %s loaded\n", IP_CT_PPTP_VERSION);
+ return 0;
+}
+
+static void __exit fini(void)
+{
+ ip_conntrack_helper_unregister(&pptp);
+ ip_ct_proto_gre_fini();
+ printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION);
+}
+
+module_init(init);
+module_exit(fini);
+
+EXPORT_SYMBOL(ip_nat_pptp_hook_outbound);
+EXPORT_SYMBOL(ip_nat_pptp_hook_inbound);
+EXPORT_SYMBOL(ip_nat_pptp_hook_exp_gre);
+EXPORT_SYMBOL(ip_nat_pptp_hook_expectfn);
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index d7a8a98c05e1..15457415a4f3 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -34,7 +34,7 @@
#include <linux/moduleparam.h>
#define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static short ports[MAX_PORTS];
static int ports_c;
static int max_dcc_channels = 8;
static unsigned int dcc_timeout = 300;
@@ -52,7 +52,7 @@ EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
MODULE_LICENSE("GPL");
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, short, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
module_param(max_dcc_channels, int, 0400);
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
@@ -240,7 +240,7 @@ static int help(struct sk_buff **pskb,
}
static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
-static char irc_names[MAX_PORTS][10];
+static char irc_names[MAX_PORTS][sizeof("irc-65535")];
static void fini(void);
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 2b5cf9c51309..186646eb249f 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -23,7 +23,6 @@
#include <linux/inetdevice.h>
#include <linux/in.h>
#include <linux/ip.h>
-#include <linux/udp.h>
#include <net/route.h>
#include <linux/netfilter.h>
@@ -31,6 +30,8 @@
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#define NMBD_PORT 137
+
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
MODULE_LICENSE("GPL");
@@ -44,7 +45,6 @@ static int help(struct sk_buff **pskb,
{
struct ip_conntrack_expect *exp;
struct iphdr *iph = (*pskb)->nh.iph;
- struct udphdr _uh, *uh;
struct rtable *rt = (struct rtable *)(*pskb)->dst;
struct in_device *in_dev;
u_int32_t mask = 0;
@@ -58,7 +58,7 @@ static int help(struct sk_buff **pskb,
goto out;
rcu_read_lock();
- in_dev = __in_dev_get(rt->u.dst.dev);
+ in_dev = __in_dev_get_rcu(rt->u.dst.dev);
if (in_dev != NULL) {
for_primary_ifa(in_dev) {
if (ifa->ifa_broadcast == iph->daddr) {
@@ -72,20 +72,15 @@ static int help(struct sk_buff **pskb,
if (mask == 0)
goto out;
- uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh);
- BUG_ON(uh == NULL);
-
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL)
goto out;
- memset(&exp->tuple, 0, sizeof(exp->tuple));
- exp->tuple.src.ip = iph->daddr & mask;
- exp->tuple.dst.ip = iph->saddr;
- exp->tuple.dst.u.udp.port = uh->source;
- exp->tuple.dst.protonum = IPPROTO_UDP;
- memset(&exp->mask, 0, sizeof(exp->mask));
+ exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ exp->tuple.src.u.udp.port = ntohs(NMBD_PORT);
+
exp->mask.src.ip = mask;
+ exp->mask.src.u.udp.port = 0xFFFF;
exp->mask.dst.ip = 0xFFFFFFFF;
exp->mask.dst.u.udp.port = 0xFFFF;
exp->mask.dst.protonum = 0xFF;
@@ -96,7 +91,7 @@ static int help(struct sk_buff **pskb,
ip_conntrack_expect_related(exp);
ip_conntrack_expect_put(exp);
- ip_ct_refresh_acct(ct, ctinfo, NULL, timeout * HZ);
+ ip_ct_refresh(ct, *pskb, timeout * HZ);
out:
return NF_ACCEPT;
}
@@ -104,12 +99,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(NMBD_PORT),
+ }
+ }
+ },
+ .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/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 15aef3564742..166e6069f121 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -177,11 +177,11 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
struct nfattr *nest_count = NFA_NEST(skb, type);
u_int64_t tmp;
- tmp = cpu_to_be64(ct->counters[dir].packets);
- NFA_PUT(skb, CTA_COUNTERS_PACKETS, sizeof(u_int64_t), &tmp);
+ tmp = htonl(ct->counters[dir].packets);
+ NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
- tmp = cpu_to_be64(ct->counters[dir].bytes);
- NFA_PUT(skb, CTA_COUNTERS_BYTES, sizeof(u_int64_t), &tmp);
+ tmp = htonl(ct->counters[dir].bytes);
+ NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
NFA_NEST_END(skb, nest_count);
@@ -833,7 +833,8 @@ out:
static inline int
ctnetlink_change_status(struct ip_conntrack *ct, struct nfattr *cda[])
{
- unsigned long d, status = *(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]);
+ unsigned long d;
+ unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
d = ct->status ^ status;
if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
@@ -948,6 +949,31 @@ ctnetlink_change_timeout(struct ip_conntrack *ct, struct nfattr *cda[])
return 0;
}
+static inline int
+ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
+{
+ struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
+ struct ip_conntrack_protocol *proto;
+ u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
+ int err = 0;
+
+ if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0)
+ goto nfattr_failure;
+
+ proto = ip_conntrack_proto_find_get(npt);
+ if (!proto)
+ return -EINVAL;
+
+ if (proto->from_nfattr)
+ err = proto->from_nfattr(tb, ct);
+ ip_conntrack_proto_put(proto);
+
+ return err;
+
+nfattr_failure:
+ return -ENOMEM;
+}
+
static int
ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
{
@@ -973,6 +999,12 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
return err;
}
+ if (cda[CTA_PROTOINFO-1]) {
+ err = ctnetlink_change_protoinfo(ct, cda);
+ if (err < 0)
+ return err;
+ }
+
DEBUGP("all done\n");
return 0;
}
@@ -1002,6 +1034,12 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
if (err < 0)
goto err;
+ if (cda[CTA_PROTOINFO-1]) {
+ err = ctnetlink_change_protoinfo(ct, cda);
+ if (err < 0)
+ return err;
+ }
+
ct->helper = ip_conntrack_helper_find_get(rtuple);
add_timer(&ct->timeout);
@@ -1270,7 +1308,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
if (err < 0)
return err;
- exp = ip_conntrack_expect_find_get(&tuple);
+ exp = ip_conntrack_expect_find(&tuple);
if (!exp)
return -ENOENT;
@@ -1318,7 +1356,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
return err;
/* bump usage count to 2 */
- exp = ip_conntrack_expect_find_get(&tuple);
+ exp = ip_conntrack_expect_find(&tuple);
if (!exp)
return -ENOENT;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
new file mode 100644
index 000000000000..744abb9d377a
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
@@ -0,0 +1,328 @@
+/*
+ * ip_conntrack_proto_gre.c - Version 3.0
+ *
+ * Connection tracking protocol helper module for GRE.
+ *
+ * GRE is a generic encapsulation protocol, which is generally not very
+ * suited for NAT, as it has no protocol-specific part as port numbers.
+ *
+ * It has an optional key field, which may help us distinguishing two
+ * connections between the same two hosts.
+ *
+ * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
+ *
+ * PPTP is built on top of a modified version of GRE, and has a mandatory
+ * field called "CallID", which serves us for the same purpose as the key
+ * field in plain GRE.
+ *
+ * Documentation about PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/list.h>
+
+static DEFINE_RWLOCK(ip_ct_gre_lock);
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
+
+#include <linux/netfilter_ipv4/listhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
+
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE");
+
+/* shamelessly stolen from ip_conntrack_proto_udp.c */
+#define GRE_TIMEOUT (30*HZ)
+#define GRE_STREAM_TIMEOUT (180*HZ)
+
+#if 0
+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
+#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x\n", \
+ NIPQUAD((x)->src.ip), ntohs((x)->src.u.gre.key), \
+ NIPQUAD((x)->dst.ip), ntohs((x)->dst.u.gre.key))
+#else
+#define DEBUGP(x, args...)
+#define DUMP_TUPLE_GRE(x)
+#endif
+
+/* GRE KEYMAP HANDLING FUNCTIONS */
+static LIST_HEAD(gre_keymap_list);
+
+static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km,
+ const struct ip_conntrack_tuple *t)
+{
+ return ((km->tuple.src.ip == t->src.ip) &&
+ (km->tuple.dst.ip == t->dst.ip) &&
+ (km->tuple.dst.protonum == t->dst.protonum) &&
+ (km->tuple.dst.u.all == t->dst.u.all));
+}
+
+/* look up the source key for a given tuple */
+static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t)
+{
+ struct ip_ct_gre_keymap *km;
+ u_int32_t key = 0;
+
+ read_lock_bh(&ip_ct_gre_lock);
+ km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
+ struct ip_ct_gre_keymap *, t);
+ if (km)
+ key = km->tuple.src.u.gre.key;
+ read_unlock_bh(&ip_ct_gre_lock);
+
+ DEBUGP("lookup src key 0x%x up key for ", key);
+ DUMP_TUPLE_GRE(t);
+
+ return key;
+}
+
+/* add a single keymap entry, associate with specified master ct */
+int
+ip_ct_gre_keymap_add(struct ip_conntrack *ct,
+ struct ip_conntrack_tuple *t, int reply)
+{
+ struct ip_ct_gre_keymap **exist_km, *km, *old;
+
+ if (!ct->helper || strcmp(ct->helper->name, "pptp")) {
+ DEBUGP("refusing to add GRE keymap to non-pptp session\n");
+ return -1;
+ }
+
+ if (!reply)
+ exist_km = &ct->help.ct_pptp_info.keymap_orig;
+ else
+ exist_km = &ct->help.ct_pptp_info.keymap_reply;
+
+ if (*exist_km) {
+ /* check whether it's a retransmission */
+ old = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
+ struct ip_ct_gre_keymap *, t);
+ if (old == *exist_km) {
+ DEBUGP("retransmission\n");
+ return 0;
+ }
+
+ DEBUGP("trying to override keymap_%s for ct %p\n",
+ reply? "reply":"orig", ct);
+ return -EEXIST;
+ }
+
+ km = kmalloc(sizeof(*km), GFP_ATOMIC);
+ if (!km)
+ return -ENOMEM;
+
+ memcpy(&km->tuple, t, sizeof(*t));
+ *exist_km = km;
+
+ DEBUGP("adding new entry %p: ", km);
+ DUMP_TUPLE_GRE(&km->tuple);
+
+ write_lock_bh(&ip_ct_gre_lock);
+ list_append(&gre_keymap_list, km);
+ write_unlock_bh(&ip_ct_gre_lock);
+
+ return 0;
+}
+
+/* destroy the keymap entries associated with specified master ct */
+void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct)
+{
+ DEBUGP("entering for ct %p\n", ct);
+
+ if (!ct->helper || strcmp(ct->helper->name, "pptp")) {
+ DEBUGP("refusing to destroy GRE keymap to non-pptp session\n");
+ return;
+ }
+
+ write_lock_bh(&ip_ct_gre_lock);
+ if (ct->help.ct_pptp_info.keymap_orig) {
+ DEBUGP("removing %p from list\n",
+ ct->help.ct_pptp_info.keymap_orig);
+ list_del(&ct->help.ct_pptp_info.keymap_orig->list);
+ kfree(ct->help.ct_pptp_info.keymap_orig);
+ ct->help.ct_pptp_info.keymap_orig = NULL;
+ }
+ if (ct->help.ct_pptp_info.keymap_reply) {
+ DEBUGP("removing %p from list\n",
+ ct->help.ct_pptp_info.keymap_reply);
+ list_del(&ct->help.ct_pptp_info.keymap_reply->list);
+ kfree(ct->help.ct_pptp_info.keymap_reply);
+ ct->help.ct_pptp_info.keymap_reply = NULL;
+ }
+ write_unlock_bh(&ip_ct_gre_lock);
+}
+
+
+/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
+
+/* invert gre part of tuple */
+static int gre_invert_tuple(struct ip_conntrack_tuple *tuple,
+ const struct ip_conntrack_tuple *orig)
+{
+ tuple->dst.u.gre.key = orig->src.u.gre.key;
+ tuple->src.u.gre.key = orig->dst.u.gre.key;
+
+ return 1;
+}
+
+/* gre hdr info to tuple */
+static int gre_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct ip_conntrack_tuple *tuple)
+{
+ struct gre_hdr_pptp _pgrehdr, *pgrehdr;
+ u_int32_t srckey;
+ struct gre_hdr _grehdr, *grehdr;
+
+ /* first only delinearize old RFC1701 GRE header */
+ grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
+ if (!grehdr || grehdr->version != GRE_VERSION_PPTP) {
+ /* try to behave like "ip_conntrack_proto_generic" */
+ tuple->src.u.all = 0;
+ tuple->dst.u.all = 0;
+ return 1;
+ }
+
+ /* PPTP header is variable length, only need up to the call_id field */
+ pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);
+ if (!pgrehdr)
+ return 1;
+
+ if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
+ DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
+ return 0;
+ }
+
+ tuple->dst.u.gre.key = pgrehdr->call_id;
+ srckey = gre_keymap_lookup(tuple);
+ tuple->src.u.gre.key = srckey;
+
+ return 1;
+}
+
+/* print gre part of tuple */
+static int gre_print_tuple(struct seq_file *s,
+ const struct ip_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "srckey=0x%x dstkey=0x%x ",
+ ntohs(tuple->src.u.gre.key),
+ ntohs(tuple->dst.u.gre.key));
+}
+
+/* print private data for conntrack */
+static int gre_print_conntrack(struct seq_file *s,
+ const struct ip_conntrack *ct)
+{
+ return seq_printf(s, "timeout=%u, stream_timeout=%u ",
+ (ct->proto.gre.timeout / HZ),
+ (ct->proto.gre.stream_timeout / HZ));
+}
+
+/* Returns verdict for packet, and may modify conntrack */
+static int gre_packet(struct ip_conntrack *ct,
+ const struct sk_buff *skb,
+ enum ip_conntrack_info conntrackinfo)
+{
+ /* If we've seen traffic both ways, this is a GRE connection.
+ * Extend timeout. */
+ if (ct->status & IPS_SEEN_REPLY) {
+ ip_ct_refresh_acct(ct, conntrackinfo, skb,
+ ct->proto.gre.stream_timeout);
+ /* Also, more likely to be important, and not a probe. */
+ set_bit(IPS_ASSURED_BIT, &ct->status);
+ ip_conntrack_event_cache(IPCT_STATUS, skb);
+ } else
+ ip_ct_refresh_acct(ct, conntrackinfo, skb,
+ ct->proto.gre.timeout);
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int gre_new(struct ip_conntrack *ct,
+ const struct sk_buff *skb)
+{
+ DEBUGP(": ");
+ DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+
+ /* initialize to sane value. Ideally a conntrack helper
+ * (e.g. in case of pptp) is increasing them */
+ ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
+ ct->proto.gre.timeout = GRE_TIMEOUT;
+
+ return 1;
+}
+
+/* Called when a conntrack entry has already been removed from the hashes
+ * and is about to be deleted from memory */
+static void gre_destroy(struct ip_conntrack *ct)
+{
+ struct ip_conntrack *master = ct->master;
+ DEBUGP(" entering\n");
+
+ if (!master)
+ DEBUGP("no master !?!\n");
+ else
+ ip_ct_gre_keymap_destroy(master);
+}
+
+/* protocol helper struct */
+static struct ip_conntrack_protocol gre = {
+ .proto = IPPROTO_GRE,
+ .name = "gre",
+ .pkt_to_tuple = gre_pkt_to_tuple,
+ .invert_tuple = gre_invert_tuple,
+ .print_tuple = gre_print_tuple,
+ .print_conntrack = gre_print_conntrack,
+ .packet = gre_packet,
+ .new = gre_new,
+ .destroy = gre_destroy,
+ .me = THIS_MODULE,
+#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+ defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+ .tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
+ .nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
+#endif
+};
+
+/* ip_conntrack_proto_gre initialization */
+int __init ip_ct_proto_gre_init(void)
+{
+ return ip_conntrack_protocol_register(&gre);
+}
+
+void __exit ip_ct_proto_gre_fini(void)
+{
+ struct list_head *pos, *n;
+
+ /* delete all keymap entries */
+ write_lock_bh(&ip_ct_gre_lock);
+ list_for_each_safe(pos, n, &gre_keymap_list) {
+ DEBUGP("deleting keymap %p at module unload time\n", pos);
+ list_del(pos);
+ kfree(pos);
+ }
+ write_unlock_bh(&ip_ct_gre_lock);
+
+ ip_conntrack_protocol_unregister(&gre);
+}
+
+EXPORT_SYMBOL(ip_ct_gre_keymap_add);
+EXPORT_SYMBOL(ip_ct_gre_keymap_destroy);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 838d1d69b36e..98f0015dd255 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -296,8 +296,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
struct ip_conntrack_tuple *tuple)
{
if (!tb[CTA_PROTO_ICMP_TYPE-1]
- || !tb[CTA_PROTO_ICMP_CODE-1]
- || !tb[CTA_PROTO_ICMP_ID-1])
+ || !tb[CTA_PROTO_ICMP_CODE-1])
return -1;
tuple->dst.u.icmp.type =
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index a875f35e576d..59a4a0111dd3 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -416,6 +416,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
&& newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
DEBUGP("Setting assured bit\n");
set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ ip_conntrack_event_cache(IPCT_STATUS, skb);
}
return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 1985abc59d24..d6701cafbcc2 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -341,17 +341,43 @@ static int tcp_print_conntrack(struct seq_file *s,
static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
const struct ip_conntrack *ct)
{
+ struct nfattr *nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
+
read_lock_bh(&tcp_lock);
NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
&ct->proto.tcp.state);
read_unlock_bh(&tcp_lock);
+ NFA_NEST_END(skb, nest_parms);
+
return 0;
nfattr_failure:
read_unlock_bh(&tcp_lock);
return -1;
}
+
+static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
+{
+ struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
+ struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
+
+ if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0)
+ goto nfattr_failure;
+
+ if (!tb[CTA_PROTOINFO_TCP_STATE-1])
+ return -EINVAL;
+
+ write_lock_bh(&tcp_lock);
+ ct->proto.tcp.state =
+ *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
+ write_unlock_bh(&tcp_lock);
+
+ return 0;
+
+nfattr_failure:
+ return -1;
+}
#endif
static unsigned int get_conntrack_index(const struct tcphdr *tcph)
@@ -1014,7 +1040,8 @@ static int tcp_packet(struct ip_conntrack *conntrack,
/* Set ASSURED if we see see valid ack in ESTABLISHED
after SYN_RECV or a valid answer for a picked up
connection. */
- set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ ip_conntrack_event_cache(IPCT_STATUS, skb);
}
ip_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
@@ -1122,6 +1149,7 @@ struct ip_conntrack_protocol ip_conntrack_protocol_tcp =
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
.to_nfattr = tcp_to_nfattr,
+ .from_nfattr = nfattr_to_tcp,
.tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
.nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
#endif
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index ae3e3e655db5..dd476b191f4b 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -989,15 +989,15 @@ EXPORT_SYMBOL(need_ip_conntrack);
EXPORT_SYMBOL(ip_conntrack_helper_register);
EXPORT_SYMBOL(ip_conntrack_helper_unregister);
EXPORT_SYMBOL(ip_ct_iterate_cleanup);
-EXPORT_SYMBOL(ip_ct_refresh_acct);
+EXPORT_SYMBOL(__ip_ct_refresh_acct);
EXPORT_SYMBOL(ip_conntrack_expect_alloc);
EXPORT_SYMBOL(ip_conntrack_expect_put);
-EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
+EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
+EXPORT_SYMBOL_GPL(ip_conntrack_expect_find);
EXPORT_SYMBOL(ip_conntrack_expect_related);
EXPORT_SYMBOL(ip_conntrack_unexpect_related);
EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
-EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
EXPORT_SYMBOL_GPL(ip_ct_unlink_expect);
EXPORT_SYMBOL(ip_conntrack_tuple_taken);
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index d2b590533452..a78736b8525d 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -26,9 +26,9 @@ MODULE_DESCRIPTION("tftp connection tracking helper");
MODULE_LICENSE("GPL");
#define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static short ports[MAX_PORTS];
static int ports_c;
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, short, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of tftp servers");
#if 0
@@ -100,7 +100,7 @@ static int tftp_help(struct sk_buff **pskb,
}
static struct ip_conntrack_helper tftp[MAX_PORTS];
-static char tftp_names[MAX_PORTS][10];
+static char tftp_names[MAX_PORTS][sizeof("tftp-65535")];
static void fini(void)
{
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 1adedb743f60..c5e3abd24672 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -74,12 +74,14 @@ ip_nat_proto_find_get(u_int8_t protonum)
return p;
}
+EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
void
ip_nat_proto_put(struct ip_nat_protocol *p)
{
module_put(p->me);
}
+EXPORT_SYMBOL_GPL(ip_nat_proto_put);
/* We keep an extra hash for each conntrack, for fast searching. */
static inline unsigned int
@@ -111,6 +113,7 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
oldcheck^0xFFFF));
}
+EXPORT_SYMBOL(ip_nat_cheat_check);
/* Is this tuple already taken? (not by us) */
int
@@ -127,6 +130,7 @@ ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
invert_tuplepr(&reply, tuple);
return ip_conntrack_tuple_taken(&reply, ignored_conntrack);
}
+EXPORT_SYMBOL(ip_nat_used_tuple);
/* If we source map this tuple so reply looks like reply_tuple, will
* that meet the constraints of range. */
@@ -347,6 +351,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
return NF_ACCEPT;
}
+EXPORT_SYMBOL(ip_nat_setup_info);
/* Returns true if succeeded. */
static int
@@ -387,10 +392,10 @@ manip_pkt(u_int16_t proto,
}
/* Do packet manipulations according to ip_nat_setup_info. */
-unsigned int nat_packet(struct ip_conntrack *ct,
- enum ip_conntrack_info ctinfo,
- unsigned int hooknum,
- struct sk_buff **pskb)
+unsigned int ip_nat_packet(struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ unsigned int hooknum,
+ struct sk_buff **pskb)
{
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned long statusbit;
@@ -417,12 +422,13 @@ unsigned int nat_packet(struct ip_conntrack *ct,
}
return NF_ACCEPT;
}
+EXPORT_SYMBOL_GPL(ip_nat_packet);
/* Dir is direction ICMP is coming from (opposite to packet it contains) */
-int icmp_reply_translation(struct sk_buff **pskb,
- struct ip_conntrack *ct,
- enum ip_nat_manip_type manip,
- enum ip_conntrack_dir dir)
+int ip_nat_icmp_reply_translation(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_nat_manip_type manip,
+ enum ip_conntrack_dir dir)
{
struct {
struct icmphdr icmp;
@@ -509,6 +515,7 @@ int icmp_reply_translation(struct sk_buff **pskb,
return 1;
}
+EXPORT_SYMBOL_GPL(ip_nat_icmp_reply_translation);
/* Protocol registration. */
int ip_nat_protocol_register(struct ip_nat_protocol *proto)
@@ -525,6 +532,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
write_unlock_bh(&ip_nat_lock);
return ret;
}
+EXPORT_SYMBOL(ip_nat_protocol_register);
/* Noone stores the protocol anywhere; simply delete it. */
void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
@@ -536,6 +544,7 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
/* Someone could be still looking at the proto in a bh. */
synchronize_net();
}
+EXPORT_SYMBOL(ip_nat_protocol_unregister);
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
@@ -578,9 +587,11 @@ ip_nat_port_nfattr_to_range(struct nfattr *tb[], struct ip_nat_range *range)
return ret;
}
+EXPORT_SYMBOL_GPL(ip_nat_port_nfattr_to_range);
+EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr);
#endif
-int __init ip_nat_init(void)
+static int __init ip_nat_init(void)
{
size_t i;
@@ -622,10 +633,14 @@ static int clean_nat(struct ip_conntrack *i, void *data)
return 0;
}
-/* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */
-void ip_nat_cleanup(void)
+static void __exit ip_nat_cleanup(void)
{
ip_ct_iterate_cleanup(&clean_nat, NULL);
ip_conntrack_destroyed = NULL;
vfree(bysource);
}
+
+MODULE_LICENSE("GPL");
+
+module_init(ip_nat_init);
+module_exit(ip_nat_cleanup);
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index d2dd5d313556..5d506e0564d5 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -199,6 +199,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
}
return 1;
}
+EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
/* Generic function for mangling variable-length address changes inside
* NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
@@ -256,6 +257,7 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
return 1;
}
+EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
/* Adjust one found SACK option including checksum correction */
static void
@@ -399,6 +401,7 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
return 1;
}
+EXPORT_SYMBOL(ip_nat_seq_adjust);
/* Setup NAT on this expected conntrack so it follows master. */
/* If we fail to get a free NAT slot, we'll get dropped on confirm */
@@ -425,3 +428,4 @@ void ip_nat_follow_master(struct ip_conntrack *ct,
/* hook doesn't matter, but it has to do destination manip */
ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
}
+EXPORT_SYMBOL(ip_nat_follow_master);
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
new file mode 100644
index 000000000000..3cdd0684d30d
--- /dev/null
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -0,0 +1,401 @@
+/*
+ * ip_nat_pptp.c - Version 3.0
+ *
+ * NAT support for PPTP (Point to Point Tunneling Protocol).
+ * PPTP is a a protocol for creating virtual private networks.
+ * It is a specification defined by Microsoft and some vendors
+ * working with Microsoft. PPTP is built on top of a modified
+ * version of the Internet Generic Routing Encapsulation Protocol.
+ * GRE is defined in RFC 1701 and RFC 1702. Documentation of
+ * PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ * TODO: - NAT to a unique tuple, not to TCP source port
+ * (needs netfilter tuple reservation)
+ *
+ * Changes:
+ * 2002-02-10 - Version 1.3
+ * - Use ip_nat_mangle_tcp_packet() because of cloned skb's
+ * in local connections (Philip Craig <philipc@snapgear.com>)
+ * - add checks for magicCookie and pptp version
+ * - make argument list of pptp_{out,in}bound_packet() shorter
+ * - move to C99 style initializers
+ * - print version number at module loadtime
+ * 2003-09-22 - Version 1.5
+ * - use SNATed tcp sourceport as callid, since we get called before
+ * TCP header is mangled (Philip Craig <philipc@snapgear.com>)
+ * 2004-10-22 - Version 2.0
+ * - kernel 2.6.x version
+ * 2005-06-10 - Version 3.0
+ * - kernel >= 2.6.11 version,
+ * funded by Oxcoda NetBox Blue (http://www.netboxblue.com/)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_pptp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
+
+#define IP_NAT_PPTP_VERSION "3.0"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
+
+
+#if 0
+extern const char *pptp_msg_name[];
+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
+ __FUNCTION__, ## args)
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static void pptp_nat_expected(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp)
+{
+ struct ip_conntrack *master = ct->master;
+ struct ip_conntrack_expect *other_exp;
+ struct ip_conntrack_tuple t;
+ struct ip_ct_pptp_master *ct_pptp_info;
+ struct ip_nat_pptp *nat_pptp_info;
+
+ ct_pptp_info = &master->help.ct_pptp_info;
+ nat_pptp_info = &master->nat.help.nat_pptp_info;
+
+ /* And here goes the grand finale of corrosion... */
+
+ if (exp->dir == IP_CT_DIR_ORIGINAL) {
+ DEBUGP("we are PNS->PAC\n");
+ /* therefore, build tuple for PAC->PNS */
+ t.src.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+ t.src.u.gre.key = htons(master->help.ct_pptp_info.pac_call_id);
+ t.dst.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+ t.dst.u.gre.key = htons(master->help.ct_pptp_info.pns_call_id);
+ t.dst.protonum = IPPROTO_GRE;
+ } else {
+ DEBUGP("we are PAC->PNS\n");
+ /* build tuple for PNS->PAC */
+ t.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+ t.src.u.gre.key =
+ htons(master->nat.help.nat_pptp_info.pns_call_id);
+ t.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+ t.dst.u.gre.key =
+ htons(master->nat.help.nat_pptp_info.pac_call_id);
+ t.dst.protonum = IPPROTO_GRE;
+ }
+
+ DEBUGP("trying to unexpect other dir: ");
+ DUMP_TUPLE(&t);
+ other_exp = ip_conntrack_expect_find(&t);
+ if (other_exp) {
+ ip_conntrack_unexpect_related(other_exp);
+ ip_conntrack_expect_put(other_exp);
+ DEBUGP("success\n");
+ } else {
+ DEBUGP("not found!\n");
+ }
+
+ ip_nat_follow_master(ct, exp);
+}
+
+/* outbound packets == from PNS to PAC */
+static int
+pptp_outbound_pkt(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq)
+
+{
+ struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
+ struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
+
+ u_int16_t msg, *cid = NULL, new_callid;
+
+ new_callid = htons(ct_pptp_info->pns_call_id);
+
+ switch (msg = ntohs(ctlh->messageType)) {
+ case PPTP_OUT_CALL_REQUEST:
+ cid = &pptpReq->ocreq.callID;
+ /* FIXME: ideally we would want to reserve a call ID
+ * here. current netfilter NAT core is not able to do
+ * this :( For now we use TCP source port. This breaks
+ * multiple calls within one control session */
+
+ /* save original call ID in nat_info */
+ nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id;
+
+ /* don't use tcph->source since we are at a DSTmanip
+ * hook (e.g. PREROUTING) and pkt is not mangled yet */
+ new_callid = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port;
+
+ /* save new call ID in ct info */
+ ct_pptp_info->pns_call_id = ntohs(new_callid);
+ break;
+ case PPTP_IN_CALL_REPLY:
+ cid = &pptpReq->icreq.callID;
+ break;
+ case PPTP_CALL_CLEAR_REQUEST:
+ cid = &pptpReq->clrreq.callID;
+ break;
+ default:
+ DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
+ (msg <= PPTP_MSG_MAX)?
+ pptp_msg_name[msg]:pptp_msg_name[0]);
+ /* fall through */
+
+ case PPTP_SET_LINK_INFO:
+ /* only need to NAT in case PAC is behind NAT box */
+ case PPTP_START_SESSION_REQUEST:
+ case PPTP_START_SESSION_REPLY:
+ case PPTP_STOP_SESSION_REQUEST:
+ case PPTP_STOP_SESSION_REPLY:
+ case PPTP_ECHO_REQUEST:
+ case PPTP_ECHO_REPLY:
+ /* no need to alter packet */
+ return NF_ACCEPT;
+ }
+
+ /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass
+ * down to here */
+
+ IP_NF_ASSERT(cid);
+
+ DEBUGP("altering call id from 0x%04x to 0x%04x\n",
+ ntohs(*cid), ntohs(new_callid));
+
+ /* mangle packet */
+ if (ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
+ sizeof(new_callid),
+ (char *)&new_callid,
+ sizeof(new_callid)) == 0)
+ return NF_DROP;
+
+ return NF_ACCEPT;
+}
+
+static int
+pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
+ struct ip_conntrack_expect *expect_reply)
+{
+ struct ip_ct_pptp_master *ct_pptp_info =
+ &expect_orig->master->help.ct_pptp_info;
+ struct ip_nat_pptp *nat_pptp_info =
+ &expect_orig->master->nat.help.nat_pptp_info;
+
+ struct ip_conntrack *ct = expect_orig->master;
+
+ struct ip_conntrack_tuple inv_t;
+ struct ip_conntrack_tuple *orig_t, *reply_t;
+
+ /* save original PAC call ID in nat_info */
+ nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;
+
+ /* alter expectation */
+ orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+
+ /* alter expectation for PNS->PAC direction */
+ invert_tuplepr(&inv_t, &expect_orig->tuple);
+ expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
+ expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
+ expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
+ inv_t.src.ip = reply_t->src.ip;
+ inv_t.dst.ip = reply_t->dst.ip;
+ inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
+ inv_t.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
+
+ if (!ip_conntrack_expect_related(expect_orig)) {
+ DEBUGP("successfully registered expect\n");
+ } else {
+ DEBUGP("can't expect_related(expect_orig)\n");
+ return 1;
+ }
+
+ /* alter expectation for PAC->PNS direction */
+ invert_tuplepr(&inv_t, &expect_reply->tuple);
+ expect_reply->saved_proto.gre.key = htons(nat_pptp_info->pns_call_id);
+ expect_reply->tuple.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
+ expect_reply->tuple.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
+ inv_t.src.ip = orig_t->src.ip;
+ inv_t.dst.ip = orig_t->dst.ip;
+ inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
+ inv_t.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
+
+ if (!ip_conntrack_expect_related(expect_reply)) {
+ DEBUGP("successfully registered expect\n");
+ } else {
+ DEBUGP("can't expect_related(expect_reply)\n");
+ ip_conntrack_unexpect_related(expect_orig);
+ return 1;
+ }
+
+ if (ip_ct_gre_keymap_add(ct, &expect_reply->tuple, 0) < 0) {
+ DEBUGP("can't register original keymap\n");
+ ip_conntrack_unexpect_related(expect_orig);
+ ip_conntrack_unexpect_related(expect_reply);
+ return 1;
+ }
+
+ if (ip_ct_gre_keymap_add(ct, &inv_t, 1) < 0) {
+ DEBUGP("can't register reply keymap\n");
+ ip_conntrack_unexpect_related(expect_orig);
+ ip_conntrack_unexpect_related(expect_reply);
+ ip_ct_gre_keymap_destroy(ct);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* inbound packets == from PAC to PNS */
+static int
+pptp_inbound_pkt(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq)
+{
+ struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
+ u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL;
+
+ int ret = NF_ACCEPT, rv;
+
+ new_pcid = htons(nat_pptp_info->pns_call_id);
+
+ switch (msg = ntohs(ctlh->messageType)) {
+ case PPTP_OUT_CALL_REPLY:
+ pcid = &pptpReq->ocack.peersCallID;
+ cid = &pptpReq->ocack.callID;
+ break;
+ case PPTP_IN_CALL_CONNECT:
+ pcid = &pptpReq->iccon.peersCallID;
+ break;
+ case PPTP_IN_CALL_REQUEST:
+ /* only need to nat in case PAC is behind NAT box */
+ break;
+ case PPTP_WAN_ERROR_NOTIFY:
+ pcid = &pptpReq->wanerr.peersCallID;
+ break;
+ case PPTP_CALL_DISCONNECT_NOTIFY:
+ pcid = &pptpReq->disc.callID;
+ break;
+ case PPTP_SET_LINK_INFO:
+ pcid = &pptpReq->setlink.peersCallID;
+ break;
+
+ default:
+ DEBUGP("unknown inbound packet %s\n", (msg <= PPTP_MSG_MAX)?
+ pptp_msg_name[msg]:pptp_msg_name[0]);
+ /* fall through */
+
+ case PPTP_START_SESSION_REQUEST:
+ case PPTP_START_SESSION_REPLY:
+ case PPTP_STOP_SESSION_REQUEST:
+ case PPTP_STOP_SESSION_REPLY:
+ case PPTP_ECHO_REQUEST:
+ case PPTP_ECHO_REPLY:
+ /* no need to alter packet */
+ return NF_ACCEPT;
+ }
+
+ /* only OUT_CALL_REPLY, IN_CALL_CONNECT, IN_CALL_REQUEST,
+ * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */
+
+ /* mangle packet */
+ IP_NF_ASSERT(pcid);
+ DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
+ ntohs(*pcid), ntohs(new_pcid));
+
+ rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ (void *)pcid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
+ sizeof(new_pcid), (char *)&new_pcid,
+ sizeof(new_pcid));
+ if (rv != NF_ACCEPT)
+ return rv;
+
+ if (new_cid) {
+ IP_NF_ASSERT(cid);
+ DEBUGP("altering call id from 0x%04x to 0x%04x\n",
+ ntohs(*cid), ntohs(new_cid));
+ rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
+ sizeof(new_cid),
+ (char *)&new_cid,
+ sizeof(new_cid));
+ if (rv != NF_ACCEPT)
+ return rv;
+ }
+
+ /* check for earlier return value of 'switch' above */
+ if (ret != NF_ACCEPT)
+ return ret;
+
+ /* great, at least we don't need to resize packets */
+ return NF_ACCEPT;
+}
+
+
+extern int __init ip_nat_proto_gre_init(void);
+extern void __exit ip_nat_proto_gre_fini(void);
+
+static int __init init(void)
+{
+ int ret;
+
+ DEBUGP("%s: registering NAT helper\n", __FILE__);
+
+ ret = ip_nat_proto_gre_init();
+ if (ret < 0)
+ return ret;
+
+ BUG_ON(ip_nat_pptp_hook_outbound);
+ ip_nat_pptp_hook_outbound = &pptp_outbound_pkt;
+
+ BUG_ON(ip_nat_pptp_hook_inbound);
+ ip_nat_pptp_hook_inbound = &pptp_inbound_pkt;
+
+ BUG_ON(ip_nat_pptp_hook_exp_gre);
+ ip_nat_pptp_hook_exp_gre = &pptp_exp_gre;
+
+ BUG_ON(ip_nat_pptp_hook_expectfn);
+ ip_nat_pptp_hook_expectfn = &pptp_nat_expected;
+
+ printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION);
+ return 0;
+}
+
+static void __exit fini(void)
+{
+ DEBUGP("cleanup_module\n" );
+
+ ip_nat_pptp_hook_expectfn = NULL;
+ ip_nat_pptp_hook_exp_gre = NULL;
+ ip_nat_pptp_hook_inbound = NULL;
+ ip_nat_pptp_hook_outbound = NULL;
+
+ ip_nat_proto_gre_fini();
+ /* Make sure noone calls it, meanwhile */
+ synchronize_net();
+
+ printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c
new file mode 100644
index 000000000000..7c1285401672
--- /dev/null
+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c
@@ -0,0 +1,214 @@
+/*
+ * ip_nat_proto_gre.c - Version 2.0
+ *
+ * NAT protocol helper module for GRE.
+ *
+ * GRE is a generic encapsulation protocol, which is generally not very
+ * suited for NAT, as it has no protocol-specific part as port numbers.
+ *
+ * It has an optional key field, which may help us distinguishing two
+ * connections between the same two hosts.
+ *
+ * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
+ *
+ * PPTP is built on top of a modified version of GRE, and has a mandatory
+ * field called "CallID", which serves us for the same purpose as the key
+ * field in plain GRE.
+ *
+ * Documentation about PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_nat_protocol.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
+
+#if 0
+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
+ __FUNCTION__, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
+/* is key in given range between min and max */
+static int
+gre_in_range(const struct ip_conntrack_tuple *tuple,
+ enum ip_nat_manip_type maniptype,
+ const union ip_conntrack_manip_proto *min,
+ const union ip_conntrack_manip_proto *max)
+{
+ u_int32_t key;
+
+ if (maniptype == IP_NAT_MANIP_SRC)
+ key = tuple->src.u.gre.key;
+ else
+ key = tuple->dst.u.gre.key;
+
+ return ntohl(key) >= ntohl(min->gre.key)
+ && ntohl(key) <= ntohl(max->gre.key);
+}
+
+/* generate unique tuple ... */
+static int
+gre_unique_tuple(struct ip_conntrack_tuple *tuple,
+ const struct ip_nat_range *range,
+ enum ip_nat_manip_type maniptype,
+ const struct ip_conntrack *conntrack)
+{
+ static u_int16_t key;
+ u_int16_t *keyptr;
+ unsigned int min, i, range_size;
+
+ if (maniptype == IP_NAT_MANIP_SRC)
+ keyptr = &tuple->src.u.gre.key;
+ else
+ keyptr = &tuple->dst.u.gre.key;
+
+ if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
+ DEBUGP("%p: NATing GRE PPTP\n", conntrack);
+ min = 1;
+ range_size = 0xffff;
+ } else {
+ min = ntohl(range->min.gre.key);
+ range_size = ntohl(range->max.gre.key) - min + 1;
+ }
+
+ DEBUGP("min = %u, range_size = %u\n", min, range_size);
+
+ for (i = 0; i < range_size; i++, key++) {
+ *keyptr = htonl(min + key % range_size);
+ if (!ip_nat_used_tuple(tuple, conntrack))
+ return 1;
+ }
+
+ DEBUGP("%p: no NAT mapping\n", conntrack);
+
+ return 0;
+}
+
+/* manipulate a GRE packet according to maniptype */
+static int
+gre_manip_pkt(struct sk_buff **pskb,
+ unsigned int iphdroff,
+ const struct ip_conntrack_tuple *tuple,
+ enum ip_nat_manip_type maniptype)
+{
+ struct gre_hdr *greh;
+ struct gre_hdr_pptp *pgreh;
+ struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
+ unsigned int hdroff = iphdroff + iph->ihl*4;
+
+ /* pgreh includes two optional 32bit fields which are not required
+ * to be there. That's where the magic '8' comes from */
+ if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh)-8))
+ return 0;
+
+ greh = (void *)(*pskb)->data + hdroff;
+ pgreh = (struct gre_hdr_pptp *) greh;
+
+ /* we only have destination manip of a packet, since 'source key'
+ * is not present in the packet itself */
+ if (maniptype == IP_NAT_MANIP_DST) {
+ /* key manipulation is always dest */
+ switch (greh->version) {
+ case 0:
+ if (!greh->key) {
+ DEBUGP("can't nat GRE w/o key\n");
+ break;
+ }
+ if (greh->csum) {
+ /* FIXME: Never tested this code... */
+ *(gre_csum(greh)) =
+ ip_nat_cheat_check(~*(gre_key(greh)),
+ tuple->dst.u.gre.key,
+ *(gre_csum(greh)));
+ }
+ *(gre_key(greh)) = tuple->dst.u.gre.key;
+ break;
+ case GRE_VERSION_PPTP:
+ DEBUGP("call_id -> 0x%04x\n",
+ ntohl(tuple->dst.u.gre.key));
+ pgreh->call_id = htons(ntohl(tuple->dst.u.gre.key));
+ break;
+ default:
+ DEBUGP("can't nat unknown GRE version\n");
+ return 0;
+ break;
+ }
+ }
+ return 1;
+}
+
+/* print out a nat tuple */
+static unsigned int
+gre_print(char *buffer,
+ const struct ip_conntrack_tuple *match,
+ const struct ip_conntrack_tuple *mask)
+{
+ unsigned int len = 0;
+
+ if (mask->src.u.gre.key)
+ len += sprintf(buffer + len, "srckey=0x%x ",
+ ntohl(match->src.u.gre.key));
+
+ if (mask->dst.u.gre.key)
+ len += sprintf(buffer + len, "dstkey=0x%x ",
+ ntohl(match->src.u.gre.key));
+
+ return len;
+}
+
+/* print a range of keys */
+static unsigned int
+gre_print_range(char *buffer, const struct ip_nat_range *range)
+{
+ if (range->min.gre.key != 0
+ || range->max.gre.key != 0xFFFF) {
+ if (range->min.gre.key == range->max.gre.key)
+ return sprintf(buffer, "key 0x%x ",
+ ntohl(range->min.gre.key));
+ else
+ return sprintf(buffer, "keys 0x%u-0x%u ",
+ ntohl(range->min.gre.key),
+ ntohl(range->max.gre.key));
+ } else
+ return 0;
+}
+
+/* nat helper struct */
+static struct ip_nat_protocol gre = {
+ .name = "GRE",
+ .protonum = IPPROTO_GRE,
+ .manip_pkt = gre_manip_pkt,
+ .in_range = gre_in_range,
+ .unique_tuple = gre_unique_tuple,
+ .print = gre_print,
+ .print_range = gre_print_range,
+#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+ defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+ .range_to_nfattr = ip_nat_port_range_to_nfattr,
+ .nfattr_to_range = ip_nat_port_nfattr_to_range,
+#endif
+};
+
+int __init ip_nat_proto_gre_init(void)
+{
+ return ip_nat_protocol_register(&gre);
+}
+
+void __exit ip_nat_proto_gre_fini(void)
+{
+ ip_nat_protocol_unregister(&gre);
+}
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 0ff368b131f6..30cd4e18c129 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -108,8 +108,8 @@ ip_nat_fn(unsigned int hooknum,
case IP_CT_RELATED:
case IP_CT_RELATED+IP_CT_IS_REPLY:
if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
- if (!icmp_reply_translation(pskb, ct, maniptype,
- CTINFO2DIR(ctinfo)))
+ if (!ip_nat_icmp_reply_translation(pskb, ct, maniptype,
+ CTINFO2DIR(ctinfo)))
return NF_DROP;
else
return NF_ACCEPT;
@@ -152,7 +152,7 @@ ip_nat_fn(unsigned int hooknum,
}
IP_NF_ASSERT(info);
- return nat_packet(ct, ctinfo, hooknum, pskb);
+ return ip_nat_packet(ct, ctinfo, hooknum, pskb);
}
static unsigned int
@@ -325,15 +325,10 @@ static int init_or_cleanup(int init)
printk("ip_nat_init: can't setup rules.\n");
goto cleanup_nothing;
}
- ret = ip_nat_init();
- if (ret < 0) {
- printk("ip_nat_init: can't setup rules.\n");
- goto cleanup_rule_init;
- }
ret = nf_register_hook(&ip_nat_in_ops);
if (ret < 0) {
printk("ip_nat_init: can't register in hook.\n");
- goto cleanup_nat;
+ goto cleanup_rule_init;
}
ret = nf_register_hook(&ip_nat_out_ops);
if (ret < 0) {
@@ -374,8 +369,6 @@ static int init_or_cleanup(int init)
nf_unregister_hook(&ip_nat_out_ops);
cleanup_inops:
nf_unregister_hook(&ip_nat_in_ops);
- cleanup_nat:
- ip_nat_cleanup();
cleanup_rule_init:
ip_nat_rule_cleanup();
cleanup_nothing:
@@ -395,14 +388,4 @@ static void __exit fini(void)
module_init(init);
module_exit(fini);
-EXPORT_SYMBOL(ip_nat_setup_info);
-EXPORT_SYMBOL(ip_nat_protocol_register);
-EXPORT_SYMBOL(ip_nat_protocol_unregister);
-EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
-EXPORT_SYMBOL_GPL(ip_nat_proto_put);
-EXPORT_SYMBOL(ip_nat_cheat_check);
-EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
-EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
-EXPORT_SYMBOL(ip_nat_used_tuple);
-EXPORT_SYMBOL(ip_nat_follow_master);
MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index d54f14d926f6..36339eb39e17 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -240,8 +240,8 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
pmsg->packet_id = (unsigned long )entry;
pmsg->data_len = data_len;
- pmsg->timestamp_sec = skb_tv_base.tv_sec + entry->skb->tstamp.off_sec;
- pmsg->timestamp_usec = skb_tv_base.tv_usec + entry->skb->tstamp.off_usec;
+ pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
+ pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
pmsg->mark = entry->skb->nfmark;
pmsg->hook = entry->info->hook;
pmsg->hw_protocol = entry->skb->protocol;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index eef99a1b5de6..75c27e92f6ab 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -27,6 +27,7 @@
#include <asm/semaphore.h>
#include <linux/proc_fs.h>
#include <linux/err.h>
+#include <linux/cpumask.h>
#include <linux/netfilter_ipv4/ip_tables.h>
@@ -921,8 +922,10 @@ translate_table(const char *name,
}
/* And one copy for every other CPU */
- for (i = 1; i < num_possible_cpus(); i++) {
- memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
+ for_each_cpu(i) {
+ if (i == 0)
+ continue;
+ memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
newinfo->entries,
SMP_ALIGN(newinfo->size));
}
@@ -943,7 +946,7 @@ replace_table(struct ipt_table *table,
struct ipt_entry *table_base;
unsigned int i;
- for (i = 0; i < num_possible_cpus(); i++) {
+ for_each_cpu(i) {
table_base =
(void *)newinfo->entries
+ TABLE_OFFSET(newinfo, i);
@@ -990,7 +993,7 @@ get_counters(const struct ipt_table_info *t,
unsigned int cpu;
unsigned int i;
- for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+ for_each_cpu(cpu) {
i = 0;
IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
t->size,
@@ -1128,7 +1131,8 @@ do_replace(void __user *user, unsigned int len)
return -ENOMEM;
newinfo = vmalloc(sizeof(struct ipt_table_info)
- + SMP_ALIGN(tmp.size) * num_possible_cpus());
+ + SMP_ALIGN(tmp.size) *
+ (highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;
@@ -1458,7 +1462,8 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
= { 0, 0, 0, { 0 }, { 0 }, { } };
newinfo = vmalloc(sizeof(struct ipt_table_info)
- + SMP_ALIGN(repl->size) * num_possible_cpus());
+ + SMP_ALIGN(repl->size) *
+ (highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 7d38913754b1..9bcb398fbc1f 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -13,6 +13,7 @@
#include <linux/config.h>
#include <linux/proc_fs.h>
#include <linux/jhash.h>
+#include <linux/bitops.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -30,7 +31,7 @@
#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
-#define CLUSTERIP_VERSION "0.7"
+#define CLUSTERIP_VERSION "0.8"
#define DEBUG_CLUSTERIP
@@ -49,13 +50,14 @@ MODULE_DESCRIPTION("iptables target for CLUSTERIP");
struct clusterip_config {
struct list_head list; /* list of all configs */
atomic_t refcount; /* reference count */
+ atomic_t entries; /* number of entries/rules
+ * referencing us */
u_int32_t clusterip; /* the IP address */
u_int8_t clustermac[ETH_ALEN]; /* the MAC address */
struct net_device *dev; /* device */
u_int16_t num_total_nodes; /* total number of nodes */
- u_int16_t num_local_nodes; /* number of local nodes */
- u_int16_t local_nodes[CLUSTERIP_MAX_NODES]; /* node number array */
+ unsigned long local_nodes; /* node number array */
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *pde; /* proc dir entry */
@@ -66,8 +68,7 @@ struct clusterip_config {
static LIST_HEAD(clusterip_configs);
-/* clusterip_lock protects the clusterip_configs list _AND_ the configurable
- * data within all structurses (num_local_nodes, local_nodes[]) */
+/* clusterip_lock protects the clusterip_configs list */
static DEFINE_RWLOCK(clusterip_lock);
#ifdef CONFIG_PROC_FS
@@ -76,23 +77,48 @@ static struct proc_dir_entry *clusterip_procdir;
#endif
static inline void
-clusterip_config_get(struct clusterip_config *c) {
+clusterip_config_get(struct clusterip_config *c)
+{
atomic_inc(&c->refcount);
}
static inline void
-clusterip_config_put(struct clusterip_config *c) {
- if (atomic_dec_and_test(&c->refcount)) {
+clusterip_config_put(struct clusterip_config *c)
+{
+ if (atomic_dec_and_test(&c->refcount))
+ kfree(c);
+}
+
+/* increase the count of entries(rules) using/referencing this config */
+static inline void
+clusterip_config_entry_get(struct clusterip_config *c)
+{
+ atomic_inc(&c->entries);
+}
+
+/* decrease the count of entries using/referencing this config. If last
+ * entry(rule) is removed, remove the config from lists, but don't free it
+ * yet, since proc-files could still be holding references */
+static inline void
+clusterip_config_entry_put(struct clusterip_config *c)
+{
+ if (atomic_dec_and_test(&c->entries)) {
write_lock_bh(&clusterip_lock);
list_del(&c->list);
write_unlock_bh(&clusterip_lock);
+
dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0);
dev_put(c->dev);
- kfree(c);
+
+ /* In case anyone still accesses the file, the open/close
+ * functions are also incrementing the refcount on their own,
+ * so it's safe to remove the entry even if it's in use. */
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry(c->pde->name, c->pde->parent);
+#endif
}
}
-
static struct clusterip_config *
__clusterip_config_find(u_int32_t clusterip)
{
@@ -111,7 +137,7 @@ __clusterip_config_find(u_int32_t clusterip)
}
static inline struct clusterip_config *
-clusterip_config_find_get(u_int32_t clusterip)
+clusterip_config_find_get(u_int32_t clusterip, int entry)
{
struct clusterip_config *c;
@@ -122,11 +148,24 @@ clusterip_config_find_get(u_int32_t clusterip)
return NULL;
}
atomic_inc(&c->refcount);
+ if (entry)
+ atomic_inc(&c->entries);
read_unlock_bh(&clusterip_lock);
return c;
}
+static void
+clusterip_config_init_nodelist(struct clusterip_config *c,
+ const struct ipt_clusterip_tgt_info *i)
+{
+ int n;
+
+ for (n = 0; n < i->num_local_nodes; n++) {
+ set_bit(i->local_nodes[n] - 1, &c->local_nodes);
+ }
+}
+
static struct clusterip_config *
clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
struct net_device *dev)
@@ -143,11 +182,11 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
c->clusterip = ip;
memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
c->num_total_nodes = i->num_total_nodes;
- c->num_local_nodes = i->num_local_nodes;
- memcpy(&c->local_nodes, &i->local_nodes, sizeof(c->local_nodes));
+ clusterip_config_init_nodelist(c, i);
c->hash_mode = i->hash_mode;
c->hash_initval = i->hash_initval;
atomic_set(&c->refcount, 1);
+ atomic_set(&c->entries, 1);
#ifdef CONFIG_PROC_FS
/* create proc dir entry */
@@ -171,53 +210,28 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
static int
clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum)
{
- int i;
-
- write_lock_bh(&clusterip_lock);
- if (c->num_local_nodes >= CLUSTERIP_MAX_NODES
- || nodenum > CLUSTERIP_MAX_NODES) {
- write_unlock_bh(&clusterip_lock);
+ if (nodenum == 0 ||
+ nodenum > c->num_total_nodes)
return 1;
- }
-
- /* check if we alrady have this number in our array */
- for (i = 0; i < c->num_local_nodes; i++) {
- if (c->local_nodes[i] == nodenum) {
- write_unlock_bh(&clusterip_lock);
- return 1;
- }
- }
- c->local_nodes[c->num_local_nodes++] = nodenum;
+ /* check if we already have this number in our bitfield */
+ if (test_and_set_bit(nodenum - 1, &c->local_nodes))
+ return 1;
- write_unlock_bh(&clusterip_lock);
return 0;
}
static int
clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
{
- int i;
-
- write_lock_bh(&clusterip_lock);
-
- if (c->num_local_nodes <= 1 || nodenum > CLUSTERIP_MAX_NODES) {
- write_unlock_bh(&clusterip_lock);
+ if (nodenum == 0 ||
+ nodenum > c->num_total_nodes)
return 1;
- }
- for (i = 0; i < c->num_local_nodes; i++) {
- if (c->local_nodes[i] == nodenum) {
- int size = sizeof(u_int16_t)*(c->num_local_nodes-(i+1));
- memmove(&c->local_nodes[i], &c->local_nodes[i+1], size);
- c->num_local_nodes--;
- write_unlock_bh(&clusterip_lock);
- return 0;
- }
- }
+ if (test_and_clear_bit(nodenum - 1, &c->local_nodes))
+ return 0;
- write_unlock_bh(&clusterip_lock);
return 1;
}
@@ -285,25 +299,7 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
static inline int
clusterip_responsible(struct clusterip_config *config, u_int32_t hash)
{
- int i;
-
- read_lock_bh(&clusterip_lock);
-
- if (config->num_local_nodes == 0) {
- read_unlock_bh(&clusterip_lock);
- return 0;
- }
-
- for (i = 0; i < config->num_local_nodes; i++) {
- if (config->local_nodes[i] == hash) {
- read_unlock_bh(&clusterip_lock);
- return 1;
- }
- }
-
- read_unlock_bh(&clusterip_lock);
-
- return 0;
+ return test_bit(hash - 1, &config->local_nodes);
}
/***********************************************************************
@@ -415,8 +411,26 @@ checkentry(const char *tablename,
/* FIXME: further sanity checks */
- config = clusterip_config_find_get(e->ip.dst.s_addr);
- if (!config) {
+ config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
+ if (config) {
+ if (cipinfo->config != NULL) {
+ /* Case A: This is an entry that gets reloaded, since
+ * it still has a cipinfo->config pointer. Simply
+ * increase the entry refcount and return */
+ if (cipinfo->config != config) {
+ printk(KERN_ERR "CLUSTERIP: Reloaded entry "
+ "has invalid config pointer!\n");
+ return 0;
+ }
+ clusterip_config_entry_get(cipinfo->config);
+ } else {
+ /* Case B: This is a new rule referring to an existing
+ * clusterip config. */
+ cipinfo->config = config;
+ clusterip_config_entry_get(cipinfo->config);
+ }
+ } else {
+ /* Case C: This is a completely new clusterip config */
if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr));
return 0;
@@ -443,10 +457,9 @@ checkentry(const char *tablename,
}
dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0);
}
+ cipinfo->config = config;
}
- cipinfo->config = config;
-
return 1;
}
@@ -455,13 +468,10 @@ static void destroy(void *matchinfo, unsigned int matchinfosize)
{
struct ipt_clusterip_tgt_info *cipinfo = matchinfo;
- /* we first remove the proc entry and then drop the reference
- * count. In case anyone still accesses the file, the open/close
- * functions are also incrementing the refcount on their own */
-#ifdef CONFIG_PROC_FS
- remove_proc_entry(cipinfo->config->pde->name,
- cipinfo->config->pde->parent);
-#endif
+ /* if no more entries are referencing the config, remove it
+ * from the list and destroy the proc entry */
+ clusterip_config_entry_put(cipinfo->config);
+
clusterip_config_put(cipinfo->config);
}
@@ -533,7 +543,7 @@ arp_mangle(unsigned int hook,
/* if there is no clusterip configuration for the arp reply's
* source ip, we don't want to mangle it */
- c = clusterip_config_find_get(payload->src_ip);
+ c = clusterip_config_find_get(payload->src_ip, 0);
if (!c)
return NF_ACCEPT;
@@ -574,56 +584,69 @@ static struct nf_hook_ops cip_arp_ops = {
#ifdef CONFIG_PROC_FS
+struct clusterip_seq_position {
+ unsigned int pos; /* position */
+ unsigned int weight; /* number of bits set == size */
+ unsigned int bit; /* current bit */
+ unsigned long val; /* current value */
+};
+
static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
{
struct proc_dir_entry *pde = s->private;
struct clusterip_config *c = pde->data;
- unsigned int *nodeidx;
-
- read_lock_bh(&clusterip_lock);
- if (*pos >= c->num_local_nodes)
+ unsigned int weight;
+ u_int32_t local_nodes;
+ struct clusterip_seq_position *idx;
+
+ /* FIXME: possible race */
+ local_nodes = c->local_nodes;
+ weight = hweight32(local_nodes);
+ if (*pos >= weight)
return NULL;
- nodeidx = kmalloc(sizeof(unsigned int), GFP_KERNEL);
- if (!nodeidx)
+ idx = kmalloc(sizeof(struct clusterip_seq_position), GFP_KERNEL);
+ if (!idx)
return ERR_PTR(-ENOMEM);
- *nodeidx = *pos;
- return nodeidx;
+ idx->pos = *pos;
+ idx->weight = weight;
+ idx->bit = ffs(local_nodes);
+ idx->val = local_nodes;
+ clear_bit(idx->bit - 1, &idx->val);
+
+ return idx;
}
static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
- struct proc_dir_entry *pde = s->private;
- struct clusterip_config *c = pde->data;
- unsigned int *nodeidx = (unsigned int *)v;
+ struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v;
- *pos = ++(*nodeidx);
- if (*pos >= c->num_local_nodes) {
+ *pos = ++idx->pos;
+ if (*pos >= idx->weight) {
kfree(v);
return NULL;
}
- return nodeidx;
+ idx->bit = ffs(idx->val);
+ clear_bit(idx->bit - 1, &idx->val);
+ return idx;
}
static void clusterip_seq_stop(struct seq_file *s, void *v)
{
kfree(v);
-
- read_unlock_bh(&clusterip_lock);
}
static int clusterip_seq_show(struct seq_file *s, void *v)
{
- struct proc_dir_entry *pde = s->private;
- struct clusterip_config *c = pde->data;
- unsigned int *nodeidx = (unsigned int *)v;
+ struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v;
- if (*nodeidx != 0)
+ if (idx->pos != 0)
seq_putc(s, ',');
- seq_printf(s, "%u", c->local_nodes[*nodeidx]);
- if (*nodeidx == c->num_local_nodes-1)
+ seq_printf(s, "%u", idx->bit);
+
+ if (idx->pos == idx->weight - 1)
seq_putc(s, '\n');
return 0;
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 2f3e181c8e97..275a174c6fe6 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -90,6 +90,12 @@ masquerade_target(struct sk_buff **pskb,
IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
|| ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
+ /* Source address is 0.0.0.0 - locally generated packet that is
+ * probably not supposed to be masqueraded.
+ */
+ if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == 0)
+ return NF_ACCEPT;
+
mr = targinfo;
rt = (struct rtable *)(*pskb)->dst;
newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index d2e13447678e..5245bfd33d52 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -88,14 +88,18 @@ redirect_target(struct sk_buff **pskb,
newdst = htonl(0x7F000001);
else {
struct in_device *indev;
+ struct in_ifaddr *ifa;
- /* Device might not have an associated in_device. */
- indev = (struct in_device *)(*pskb)->dev->ip_ptr;
- if (indev == NULL || indev->ifa_list == NULL)
- return NF_DROP;
+ newdst = 0;
+
+ rcu_read_lock();
+ indev = __in_dev_get_rcu((*pskb)->dev);
+ if (indev && (ifa = indev->ifa_list))
+ newdst = ifa->ifa_local;
+ rcu_read_unlock();
- /* Grab first address on interface. */
- newdst = indev->ifa_list->ifa_local;
+ if (!newdst)
+ return NF_DROP;
}
/* Transfer from original range. */
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f115a84a4ac6..f057025a719e 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -92,10 +92,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
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_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index e2c14f3cb2fc..2883ccd8a91d 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -225,8 +225,8 @@ static void ipt_ulog_packet(unsigned int hooknum,
/* copy hook, prefix, timestamp, payload, etc. */
pm->data_len = copy_len;
- pm->timestamp_sec = skb_tv_base.tv_sec + skb->tstamp.off_sec;
- pm->timestamp_usec = skb_tv_base.tv_usec + skb->tstamp.off_usec;
+ pm->timestamp_sec = skb->tstamp.off_sec;
+ pm->timestamp_usec = skb->tstamp.off_usec;
pm->mark = skb->nfmark;
pm->hook = hooknum;
if (prefix != NULL)
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index c1889f88262b..0cee2862ed85 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -11,6 +11,7 @@
#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/proc.c b/net/ipv4/proc.c
index f7943ba1f43c..a65e508fbd40 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -90,9 +90,7 @@ fold_field(void *mib[], int offt)
unsigned long res = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 304bb0a1d4f0..4b0d7e4d6269 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -361,7 +361,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
if (type && code) {
get_user(fl->fl_icmp_type, type);
- __get_user(fl->fl_icmp_code, code);
+ get_user(fl->fl_icmp_code, code);
probed = 1;
}
break;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c0b14e3beec..381dd6a6aebb 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);
@@ -2131,7 +2128,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
struct in_device *in_dev;
rcu_read_lock();
- if ((in_dev = __in_dev_get(dev)) != NULL) {
+ if ((in_dev = __in_dev_get_rcu(dev)) != NULL) {
int our = ip_check_mc(in_dev, daddr, saddr,
skb->nh.iph->protocol);
if (our
@@ -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,
@@ -2444,7 +2443,9 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
err = -ENODEV;
if (dev_out == NULL)
goto out;
- if (__in_dev_get(dev_out) == NULL) {
+
+ /* RACE: Check return value of inet_select_addr instead. */
+ if (__in_dev_get_rtnl(dev_out) == NULL) {
dev_put(dev_out);
goto out; /* Wrong error code */
}
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index b940346de4e7..6d80e063c187 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -136,7 +136,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
else if (cwnd < ca->last_max_cwnd + max_increment*(BICTCP_B-1))
/* slow start */
ca->cnt = (cwnd * (BICTCP_B-1))
- / cwnd-ca->last_max_cwnd;
+ / (cwnd - ca->last_max_cwnd);
else
/* linear increase */
ca->cnt = cwnd / max_increment;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 29222b964951..3e98b57578dc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -355,8 +355,6 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
app_win -= icsk->icsk_ack.rcv_mss;
app_win = max(app_win, 2U*tp->advmss);
- if (!ofo_win)
- tp->window_clamp = min(tp->window_clamp, app_win);
tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
}
}
@@ -979,14 +977,19 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if (!before(TCP_SKB_CB(skb)->seq, end_seq))
break;
+ in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
+ !before(end_seq, TCP_SKB_CB(skb)->end_seq);
+
pcount = tcp_skb_pcount(skb);
- if (pcount > 1 &&
- (after(start_seq, TCP_SKB_CB(skb)->seq) ||
- before(end_seq, TCP_SKB_CB(skb)->end_seq))) {
+ if (pcount > 1 && !in_sack &&
+ after(TCP_SKB_CB(skb)->end_seq, start_seq)) {
unsigned int pkt_len;
- if (after(start_seq, TCP_SKB_CB(skb)->seq))
+ in_sack = !after(start_seq,
+ TCP_SKB_CB(skb)->seq);
+
+ if (!in_sack)
pkt_len = (start_seq -
TCP_SKB_CB(skb)->seq);
else
@@ -999,9 +1002,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
fack_count += pcount;
- in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
- !before(end_seq, TCP_SKB_CB(skb)->end_seq);
-
sacked = TCP_SKB_CB(skb)->sacked;
/* Account D-SACK for retransmitted packet. */
@@ -2239,6 +2239,7 @@ static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp,
/* Note, it is the only place, where
* fast path is recovered for sending TCP.
*/
+ tp->pred_flags = 0;
tcp_fast_path_check(sk, tp);
if (nwin > tp->max_window) {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 13dfb391cdf1..c85819d8474b 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -130,19 +130,20 @@ static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
int dif = sk->sk_bound_dev_if;
INET_ADDR_COOKIE(acookie, saddr, daddr)
const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
- const int hash = inet_ehashfn(daddr, lport, saddr, inet->dport, tcp_hashinfo.ehash_size);
- struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash];
+ unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ prefetch(head->chain.first);
write_lock(&head->lock);
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
tw = inet_twsk(sk2);
- if (INET_TW_MATCH(sk2, acookie, saddr, daddr, ports, dif)) {
+ if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
struct tcp_sock *tp = tcp_sk(sk);
@@ -179,7 +180,7 @@ static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET_MATCH(sk2, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
goto not_unique;
}
@@ -188,7 +189,7 @@ unique:
* in hash table socket with a funny identity. */
inet->num = lport;
inet->sport = htons(lport);
- sk->sk_hashent = hash;
+ sk->sk_hash = hash;
BUG_TRAP(sk_unhashed(sk));
__sk_add_node(sk, &head->chain);
sock_prot_inc_use(sk->sk_prot);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index a88db28b0af7..b1a63b2c6b4a 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -384,7 +384,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
newtp->frto_counter = 0;
newtp->frto_highmark = 0;
- newicsk->icsk_ca_ops = &tcp_reno;
+ newicsk->icsk_ca_ops = &tcp_init_congestion_ops;
tcp_set_ca_state(newsk, TCP_CA_Open);
tcp_init_xmit_timers(newsk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 6094db5e11be..b907456a79f4 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -190,7 +190,7 @@ void tcp_select_initial_window(int __space, __u32 mss,
}
/* Set initial window to value enough for senders,
- * following RFC1414. Senders, not following this RFC,
+ * following RFC2414. Senders, not following this RFC,
* will be satisfied with 2.
*/
if (mss > (1<<*rcv_wscale)) {
@@ -435,6 +435,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
int nsize, old_factor;
u16 flags;
+ BUG_ON(len > skb->len);
nsize = skb_headlen(skb) - len;
if (nsize < 0)
nsize = 0;
@@ -459,9 +460,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
flags = TCP_SKB_CB(skb)->flags;
TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
TCP_SKB_CB(buff)->flags = flags;
- TCP_SKB_CB(buff)->sacked =
- (TCP_SKB_CB(skb)->sacked &
- (TCPCB_LOST | TCPCB_EVER_RETRANS | TCPCB_AT_TAIL));
+ TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked;
TCP_SKB_CB(skb)->sacked &= ~TCPCB_AT_TAIL;
if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_HW) {
@@ -485,11 +484,6 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
buff->tstamp = skb->tstamp;
- if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
- tp->lost_out -= tcp_skb_pcount(skb);
- tp->left_out -= tcp_skb_pcount(skb);
- }
-
old_factor = tcp_skb_pcount(skb);
/* Fix up tso_factor for both original and new SKB. */
@@ -499,16 +493,31 @@ 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);
tp->packets_out -= diff;
+
+ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)
+ tp->sacked_out -= diff;
+ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
+ tp->retrans_out -= diff;
+
if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
tp->lost_out -= diff;
tp->left_out -= diff;
}
+
if (diff > 0) {
+ /* Adjust Reno SACK estimate. */
+ if (!tp->rx_opt.sack_ok) {
+ tp->sacked_out -= diff;
+ if ((int)tp->sacked_out < 0)
+ tp->sacked_out = 0;
+ tcp_sync_left_out(tp);
+ }
+
tp->fackets_out -= diff;
if ((int)tp->fackets_out < 0)
tp->fackets_out = 0;
@@ -1600,7 +1609,7 @@ void tcp_send_fin(struct sock *sk)
* was unread data in the receive queue. This behavior is recommended
* by draft-ietf-tcpimpl-prob-03.txt section 3.10. -DaveM
*/
-void tcp_send_active_reset(struct sock *sk, unsigned int __nocast priority)
+void tcp_send_active_reset(struct sock *sk, gfp_t priority)
{
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e5beca7de86c..e0bd1013cb0d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1141,7 +1141,7 @@ int udp_rcv(struct sk_buff *skb)
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 6d6fb74f3b52..a970b4727ce8 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);
@@ -1807,7 +1806,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
}
for (dev = dev_base; dev != NULL; dev = dev->next) {
- struct in_device * in_dev = __in_dev_get(dev);
+ struct in_device * in_dev = __in_dev_get_rtnl(dev);
if (in_dev && (dev->flags & IFF_UP)) {
struct in_ifaddr * ifa;
@@ -3521,6 +3520,8 @@ int __init addrconf_init(void)
if (err)
return err;
+ ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+
register_netdevice_notifier(&ipv6_dev_notf);
#ifdef CONFIG_IPV6_PRIVACY
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 01468fab3d3d..cc518405b3e1 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -175,10 +175,8 @@ ipv4_connected:
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/esp6.c b/net/ipv6/esp6.c
index 9b27460f0cc7..40d9a1935ab5 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -31,6 +31,7 @@
#include <net/esp.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
+#include <linux/kernel.h>
#include <linux/pfkeyv2.h>
#include <linux/random.h>
#include <net/icmp.h>
@@ -66,10 +67,10 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
alen = esp->auth.icv_trunc_len;
tfm = esp->conf.tfm;
- blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3;
- clen = (clen + 2 + blksize-1)&~(blksize-1);
+ blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4);
+ clen = ALIGN(clen + 2, blksize);
if (esp->conf.padlen)
- clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
+ clen = ALIGN(clen, esp->conf.padlen);
if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {
goto error;
@@ -133,7 +134,7 @@ static int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, stru
struct ipv6_esp_hdr *esph;
struct esp_data *esp = x->data;
struct sk_buff *trailer;
- int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+ int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
int alen = esp->auth.icv_trunc_len;
int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen;
@@ -235,16 +236,17 @@ out_nofree:
static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
{
struct esp_data *esp = x->data;
- u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+ u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
if (x->props.mode) {
- mtu = (mtu + 2 + blksize-1)&~(blksize-1);
+ mtu = ALIGN(mtu + 2, blksize);
} else {
/* The worst case. */
- mtu += 2 + blksize;
+ u32 padsize = ((blksize - 1) & 7) + 1;
+ mtu = ALIGN(mtu + 2, padsize) + blksize - padsize;
}
if (esp->conf.padlen)
- mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1);
+ mtu = ALIGN(mtu, esp->conf.padlen);
return mtu + x->props.header_len + esp->auth.icv_full_len;
}
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 5be6da2584ee..922549581abc 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;
@@ -404,8 +406,7 @@ ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
memcpy(opt->srcrt, hdr, sizeof(*hdr));
irthdr = (struct rt0_hdr*)opt->srcrt;
- /* Obsolete field, MBZ, when originated by us */
- irthdr->bitmap = 0;
+ irthdr->reserved = 0;
opt->srcrt->segments_left = n;
for (i=0; i<n; i++)
memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
@@ -459,11 +460,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 +539,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 +578,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 fa8f1bb0aa52..23e540365a14 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();
@@ -692,10 +700,7 @@ int __init icmpv6_init(struct net_proto_family *ops)
struct sock *sk;
int err, i, j;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
-
+ for_each_cpu(i) {
err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
&per_cpu(__icmpv6_socket, i));
if (err < 0) {
@@ -741,9 +746,7 @@ void icmpv6_cleanup(void)
{
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
sock_release(per_cpu(__icmpv6_socket, i));
}
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 16af874c9e8f..4fcc5a7acf6e 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -92,7 +92,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
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 b6c73da5ff35..bbbe80cdaf72 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;
@@ -479,7 +483,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
goto done;
}
fl1 = sfl->fl;
- atomic_inc(&fl->users);
+ atomic_inc(&fl1->users);
break;
}
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 01ef94f7c7f1..563b442ffab8 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;
@@ -659,7 +666,7 @@ slow_path:
*/
fh->nexthdr = nexthdr;
fh->reserved = 0;
- if (frag_id) {
+ if (!frag_id) {
ipv6_select_ident(skb, fh);
frag_id = fh->identification;
} else
@@ -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 09613729404c..cf94372d1af3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -673,11 +673,12 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
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 76466af8331e..8567873d0dd8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -210,39 +210,139 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
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/mcast.c b/net/ipv6/mcast.c
index 29fed6e58d0a..39a96c768102 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1393,7 +1393,7 @@ static void mld_sendpack(struct sk_buff *skb)
static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel)
{
- return sizeof(struct mld2_grec) + 4*mld_scount(pmc,type,gdel,sdel);
+ return sizeof(struct mld2_grec) + 16 * mld_scount(pmc,type,gdel,sdel);
}
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc,
@@ -1968,7 +1968,7 @@ static void ip6_mc_clear_src(struct ifmcaddr6 *pmc)
}
pmc->mca_sources = NULL;
pmc->mca_sfmode = MCAST_EXCLUDE;
- pmc->mca_sfcount[MCAST_EXCLUDE] = 0;
+ pmc->mca_sfcount[MCAST_INCLUDE] = 0;
pmc->mca_sfcount[MCAST_EXCLUDE] = 1;
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a7eae30f4554..305d9ee6d7db 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;
@@ -1458,7 +1450,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
static void pndisc_redo(struct sk_buff *skb)
{
- ndisc_rcv(skb);
+ ndisc_recv_ns(skb);
kfree_skb(skb);
}
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 216fbe1ac65c..bb7ccfe33f23 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -209,6 +209,17 @@ config IP6_NF_TARGET_REJECT
To compile it as a module, choose M here. If unsure, say N.
+config IP6_NF_TARGET_NFQUEUE
+ tristate "NFQUEUE Target Support"
+ depends on IP_NF_IPTABLES
+ help
+ This Target replaced the old obsolete QUEUE target.
+
+ As opposed to QUEUE, it supports 65535 different queues,
+ not just one.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
# dep_tristate ' REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index bd9a16a5cbba..2b2c370e8b1c 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -21,9 +21,9 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
+obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o
obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
-obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += ip6t_NFQUEUE.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index aa11cf366efa..5027bbe6415e 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -238,8 +238,8 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
pmsg->packet_id = (unsigned long )entry;
pmsg->data_len = data_len;
- pmsg->timestamp_sec = skb_tv_base.tv_sec + entry->skb->tstamp.off_sec;
- pmsg->timestamp_usec = skb_tv_base.tv_usec + entry->skb->tstamp.off_usec;
+ pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
+ pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
pmsg->mark = entry->skb->nfmark;
pmsg->hook = entry->info->hook;
pmsg->hw_protocol = entry->skb->protocol;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 1cb8adb2787f..21deec25a12b 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -28,6 +28,7 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/proc_fs.h>
+#include <linux/cpumask.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
@@ -950,8 +951,10 @@ translate_table(const char *name,
}
/* And one copy for every other CPU */
- for (i = 1; i < num_possible_cpus(); i++) {
- memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
+ for_each_cpu(i) {
+ if (i == 0)
+ continue;
+ memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
newinfo->entries,
SMP_ALIGN(newinfo->size));
}
@@ -972,7 +975,7 @@ replace_table(struct ip6t_table *table,
struct ip6t_entry *table_base;
unsigned int i;
- for (i = 0; i < num_possible_cpus(); i++) {
+ for_each_cpu(i) {
table_base =
(void *)newinfo->entries
+ TABLE_OFFSET(newinfo, i);
@@ -1019,7 +1022,7 @@ get_counters(const struct ip6t_table_info *t,
unsigned int cpu;
unsigned int i;
- for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+ for_each_cpu(cpu) {
i = 0;
IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
t->size,
@@ -1153,7 +1156,8 @@ do_replace(void __user *user, unsigned int len)
return -ENOMEM;
newinfo = vmalloc(sizeof(struct ip6t_table_info)
- + SMP_ALIGN(tmp.size) * num_possible_cpus());
+ + SMP_ALIGN(tmp.size) *
+ (highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;
@@ -1467,7 +1471,8 @@ int ip6t_register_table(struct ip6t_table *table,
= { 0, 0, 0, { 0 }, { 0 }, { } };
newinfo = vmalloc(sizeof(struct ip6t_table_info)
- + SMP_ALIGN(repl->size) * num_possible_cpus());
+ + SMP_ALIGN(repl->size) *
+ (highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;
@@ -1955,6 +1960,57 @@ static void __exit fini(void)
#endif
}
+/*
+ * find specified header up to transport protocol header.
+ * If found target header, the offset to the header is set to *offset
+ * and return 0. otherwise, return -1.
+ *
+ * Notes: - non-1st Fragment Header isn't skipped.
+ * - ESP header isn't skipped.
+ * - The target header may be trancated.
+ */
+int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target)
+{
+ unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data;
+ u8 nexthdr = skb->nh.ipv6h->nexthdr;
+ unsigned int len = skb->len - start;
+
+ while (nexthdr != target) {
+ struct ipv6_opt_hdr _hdr, *hp;
+ unsigned int hdrlen;
+
+ if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE)
+ return -1;
+ hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return -1;
+ if (nexthdr == NEXTHDR_FRAGMENT) {
+ unsigned short _frag_off, *fp;
+ fp = skb_header_pointer(skb,
+ start+offsetof(struct frag_hdr,
+ frag_off),
+ sizeof(_frag_off),
+ &_frag_off);
+ if (fp == NULL)
+ return -1;
+
+ if (ntohs(*fp) & ~0x7)
+ return -1;
+ hdrlen = 8;
+ } else if (nexthdr == NEXTHDR_AUTH)
+ hdrlen = (hp->hdrlen + 2) << 2;
+ else
+ hdrlen = ipv6_optlen(hp);
+
+ nexthdr = hp->nexthdr;
+ len -= hdrlen;
+ start += hdrlen;
+ }
+
+ *offset = start;
+ return 0;
+}
+
EXPORT_SYMBOL(ip6t_register_table);
EXPORT_SYMBOL(ip6t_unregister_table);
EXPORT_SYMBOL(ip6t_do_table);
@@ -1963,6 +2019,7 @@ EXPORT_SYMBOL(ip6t_unregister_match);
EXPORT_SYMBOL(ip6t_register_target);
EXPORT_SYMBOL(ip6t_unregister_target);
EXPORT_SYMBOL(ip6t_ext_hdr);
+EXPORT_SYMBOL(ipv6_find_hdr);
module_init(init);
module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 14316c3ebde4..b03e87adca93 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -100,11 +100,8 @@ static void send_reset(struct sk_buff *oldskb)
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_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index d5b94f142bba..dde37793d20b 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -48,92 +48,21 @@ match(const struct sk_buff *skb,
unsigned int protoff,
int *hotdrop)
{
- struct ip_auth_hdr *ah = NULL, _ah;
+ struct ip_auth_hdr *ah, _ah;
const struct ip6t_ah *ahinfo = matchinfo;
- unsigned int temp;
- int len;
- u8 nexthdr;
unsigned int ptr;
unsigned int hdrlen = 0;
- /*DEBUGP("IPv6 AH entered\n");*/
- /* if (opt->auth == 0) return 0;
- * It does not filled on output */
-
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
-
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
-
- DEBUGP("ipv6_ah header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE)
- break;
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP)
- break;
-
- hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
- BUG_ON(hp == NULL);
-
- /* Calculate the header length */
- if (nexthdr == NEXTHDR_FRAGMENT)
- hdrlen = 8;
- else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* AH -> evaluate */
- if (nexthdr == NEXTHDR_AUTH) {
- temp |= MASK_AH;
- break;
- }
-
-
- /* set the flag */
- switch (nexthdr) {
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_ah match: unknown nextheader %u\n",nexthdr);
- return 0;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if (ptr > skb->len) {
- DEBUGP("ipv6_ah: new pointer too large! \n");
- break;
- }
- }
-
- /* AH header not found */
- if (temp != MASK_AH)
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH) < 0)
return 0;
- if (len < sizeof(struct ip_auth_hdr)){
+ ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
+ if (ah == NULL) {
*hotdrop = 1;
return 0;
}
- ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
- BUG_ON(ah == NULL);
+ hdrlen = (ah->hdrlen + 2) << 2;
DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
DEBUGP("RES %04X ", ah->reserved);
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
index 540925e4a7a8..c450a635e54b 100644
--- a/net/ipv6/netfilter/ip6t_dst.c
+++ b/net/ipv6/netfilter/ip6t_dst.c
@@ -63,8 +63,6 @@ match(const struct sk_buff *skb,
struct ipv6_opt_hdr _optsh, *oh;
const struct ip6t_opts *optinfo = matchinfo;
unsigned int temp;
- unsigned int len;
- u8 nexthdr;
unsigned int ptr;
unsigned int hdrlen = 0;
unsigned int ret = 0;
@@ -72,97 +70,25 @@ match(const struct sk_buff *skb,
u8 _optlen, *lp = NULL;
unsigned int optlen;
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
-
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
-
- DEBUGP("ipv6_opts header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < (int)sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE) {
- break;
- }
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP) {
- break;
- }
-
- hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
- BUG_ON(hp == NULL);
-
- /* Calculate the header length */
- if (nexthdr == NEXTHDR_FRAGMENT) {
- hdrlen = 8;
- } else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* OPTS -> evaluate */
#if HOPBYHOP
- if (nexthdr == NEXTHDR_HOP) {
- temp |= MASK_HOPOPTS;
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0)
#else
- if (nexthdr == NEXTHDR_DEST) {
- temp |= MASK_DSTOPTS;
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0)
#endif
- break;
- }
-
+ return 0;
- /* set the flag */
- switch (nexthdr){
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_opts match: unknown nextheader %u\n",nexthdr);
- return 0;
- break;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if ( ptr > skb->len ) {
- DEBUGP("ipv6_opts: new pointer is too large! \n");
- break;
- }
- }
-
- /* OPTIONS header not found */
-#if HOPBYHOP
- if ( temp != MASK_HOPOPTS ) return 0;
-#else
- if ( temp != MASK_DSTOPTS ) return 0;
-#endif
-
- if (len < (int)sizeof(struct ipv6_opt_hdr)){
+ oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
+ if (oh == NULL){
*hotdrop = 1;
return 0;
}
- if (len < hdrlen){
+ hdrlen = ipv6_optlen(oh);
+ if (skb->len - ptr < hdrlen){
/* Packet smaller than it's length field */
return 0;
}
- oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
- BUG_ON(oh == NULL);
-
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
DEBUGP("len %02X %04X %02X ",
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
index e39dd236fd8e..24bc0cde43a1 100644
--- a/net/ipv6/netfilter/ip6t_esp.c
+++ b/net/ipv6/netfilter/ip6t_esp.c
@@ -48,87 +48,22 @@ match(const struct sk_buff *skb,
unsigned int protoff,
int *hotdrop)
{
- struct ip_esp_hdr _esp, *eh = NULL;
+ struct ip_esp_hdr _esp, *eh;
const struct ip6t_esp *espinfo = matchinfo;
- unsigned int temp;
- int len;
- u8 nexthdr;
unsigned int ptr;
/* Make sure this isn't an evil packet */
/*DEBUGP("ipv6_esp entered \n");*/
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
-
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
- int hdrlen;
-
- DEBUGP("ipv6_esp header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE)
- break;
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP) {
- temp |= MASK_ESP;
- break;
- }
-
- hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
- BUG_ON(hp == NULL);
-
- /* Calculate the header length */
- if (nexthdr == NEXTHDR_FRAGMENT)
- hdrlen = 8;
- else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* set the flag */
- switch (nexthdr) {
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_esp match: unknown nextheader %u\n",nexthdr);
- return 0;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if (ptr > skb->len) {
- DEBUGP("ipv6_esp: new pointer too large! \n");
- break;
- }
- }
-
- /* ESP header not found */
- if (temp != MASK_ESP)
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP) < 0)
return 0;
- if (len < sizeof(struct ip_esp_hdr)) {
+ eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp);
+ if (eh == NULL) {
*hotdrop = 1;
return 0;
}
- eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp);
- BUG_ON(eh == NULL);
-
DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(eh->spi), ntohl(eh->spi));
return (eh != NULL)
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 4bfa30a9bc80..085d5f8eea29 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -48,90 +48,18 @@ match(const struct sk_buff *skb,
unsigned int protoff,
int *hotdrop)
{
- struct frag_hdr _frag, *fh = NULL;
+ struct frag_hdr _frag, *fh;
const struct ip6t_frag *fraginfo = matchinfo;
- unsigned int temp;
- int len;
- u8 nexthdr;
unsigned int ptr;
- unsigned int hdrlen = 0;
-
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
-
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
-
- DEBUGP("ipv6_frag header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < (int)sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE) {
- break;
- }
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP) {
- break;
- }
-
- hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
- BUG_ON(hp == NULL);
-
- /* Calculate the header length */
- if (nexthdr == NEXTHDR_FRAGMENT) {
- hdrlen = 8;
- } else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* FRAG -> evaluate */
- if (nexthdr == NEXTHDR_FRAGMENT) {
- temp |= MASK_FRAGMENT;
- break;
- }
-
-
- /* set the flag */
- switch (nexthdr){
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_frag match: unknown nextheader %u\n",nexthdr);
- return 0;
- break;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if ( ptr > skb->len ) {
- DEBUGP("ipv6_frag: new pointer too large! \n");
- break;
- }
- }
-
- /* FRAG header not found */
- if ( temp != MASK_FRAGMENT ) return 0;
-
- if (len < sizeof(struct frag_hdr)){
- *hotdrop = 1;
- return 0;
- }
- fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
- BUG_ON(fh == NULL);
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT) < 0)
+ return 0;
+
+ fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
+ if (fh == NULL){
+ *hotdrop = 1;
+ return 0;
+ }
DEBUGP("INFO %04X ", fh->frag_off);
DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 27f3650d127e..1d09485111d0 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -63,8 +63,6 @@ match(const struct sk_buff *skb,
struct ipv6_opt_hdr _optsh, *oh;
const struct ip6t_opts *optinfo = matchinfo;
unsigned int temp;
- unsigned int len;
- u8 nexthdr;
unsigned int ptr;
unsigned int hdrlen = 0;
unsigned int ret = 0;
@@ -72,97 +70,25 @@ match(const struct sk_buff *skb,
u8 _optlen, *lp = NULL;
unsigned int optlen;
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
-
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
-
- DEBUGP("ipv6_opts header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < (int)sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE) {
- break;
- }
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP) {
- break;
- }
-
- hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
- BUG_ON(hp == NULL);
-
- /* Calculate the header length */
- if (nexthdr == NEXTHDR_FRAGMENT) {
- hdrlen = 8;
- } else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* OPTS -> evaluate */
#if HOPBYHOP
- if (nexthdr == NEXTHDR_HOP) {
- temp |= MASK_HOPOPTS;
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0)
#else
- if (nexthdr == NEXTHDR_DEST) {
- temp |= MASK_DSTOPTS;
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0)
#endif
- break;
- }
-
+ return 0;
- /* set the flag */
- switch (nexthdr){
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_opts match: unknown nextheader %u\n",nexthdr);
- return 0;
- break;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if ( ptr > skb->len ) {
- DEBUGP("ipv6_opts: new pointer is too large! \n");
- break;
- }
- }
-
- /* OPTIONS header not found */
-#if HOPBYHOP
- if ( temp != MASK_HOPOPTS ) return 0;
-#else
- if ( temp != MASK_DSTOPTS ) return 0;
-#endif
-
- if (len < (int)sizeof(struct ipv6_opt_hdr)){
+ oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
+ if (oh == NULL){
*hotdrop = 1;
return 0;
}
- if (len < hdrlen){
+ hdrlen = ipv6_optlen(oh);
+ if (skb->len - ptr < hdrlen){
/* Packet smaller than it's length field */
return 0;
}
- oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
- BUG_ON(oh == NULL);
-
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
DEBUGP("len %02X %04X %02X ",
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 9b91decbfddb..4de4cdad4b7d 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -11,6 +11,7 @@
#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/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index a9526b773d28..beb2fd5cebbb 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -50,98 +50,29 @@ match(const struct sk_buff *skb,
unsigned int protoff,
int *hotdrop)
{
- struct ipv6_rt_hdr _route, *rh = NULL;
+ struct ipv6_rt_hdr _route, *rh;
const struct ip6t_rt *rtinfo = matchinfo;
unsigned int temp;
- unsigned int len;
- u8 nexthdr;
unsigned int ptr;
unsigned int hdrlen = 0;
unsigned int ret = 0;
struct in6_addr *ap, _addr;
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING) < 0)
+ return 0;
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
-
- DEBUGP("ipv6_rt header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < (int)sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE) {
- break;
- }
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP) {
- break;
- }
-
- hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
- BUG_ON(hp == NULL);
-
- /* Calculate the header length */
- if (nexthdr == NEXTHDR_FRAGMENT) {
- hdrlen = 8;
- } else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* ROUTING -> evaluate */
- if (nexthdr == NEXTHDR_ROUTING) {
- temp |= MASK_ROUTING;
- break;
- }
-
-
- /* set the flag */
- switch (nexthdr){
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_rt match: unknown nextheader %u\n",nexthdr);
- return 0;
- break;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if ( ptr > skb->len ) {
- DEBUGP("ipv6_rt: new pointer is too large! \n");
- break;
- }
- }
-
- /* ROUTING header not found */
- if ( temp != MASK_ROUTING ) return 0;
-
- if (len < (int)sizeof(struct ipv6_rt_hdr)){
+ rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
+ if (rh == NULL){
*hotdrop = 1;
return 0;
}
- if (len < hdrlen){
+ hdrlen = ipv6_optlen(rh);
+ if (skb->len - ptr < hdrlen){
/* Pcket smaller than its length field */
return 0;
}
- rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
- BUG_ON(rh == NULL);
-
DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
DEBUGP("TYPE %04X ", rh->type);
DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
@@ -161,8 +92,8 @@ match(const struct sk_buff *skb,
((rtinfo->hdrlen == hdrlen) ^
!!(rtinfo->invflags & IP6T_RT_INV_LEN))));
DEBUGP("res %02X %02X %02X ",
- (rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)rh)->bitmap,
- !((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)rh)->bitmap)));
+ (rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)rh)->reserved,
+ !((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)rh)->reserved)));
ret = (rh != NULL)
&&
@@ -179,12 +110,12 @@ match(const struct sk_buff *skb,
!!(rtinfo->invflags & IP6T_RT_INV_TYP)));
if (ret && (rtinfo->flags & IP6T_RT_RES)) {
- u_int32_t *bp, _bitmap;
- bp = skb_header_pointer(skb,
- ptr + offsetof(struct rt0_hdr, bitmap),
- sizeof(_bitmap), &_bitmap);
+ u_int32_t *rp, _reserved;
+ rp = skb_header_pointer(skb,
+ ptr + offsetof(struct rt0_hdr, reserved),
+ sizeof(_reserved), &_reserved);
- ret = (*bp == 0);
+ ret = (*rp == 0);
}
DEBUGP("#%d ",rtinfo->addrnr);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 334a5967831e..50a13e75d70e 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -140,9 +140,7 @@ fold_field(void *mib[], int offt)
unsigned long res = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ed3a76b30fd9..a1265a320b11 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -627,7 +627,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
if (type && code) {
get_user(fl->fl_icmp_type, type);
- __get_user(fl->fl_icmp_code, code);
+ get_user(fl->fl_icmp_code, code);
probed = 1;
}
break;
@@ -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 9d9e04344c77..e4fe9ee484dd 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -479,12 +479,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
/* 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 794734f1d230..d693cb988b78 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -209,9 +209,11 @@ static __inline__ void __tcp_v6_hash(struct sock *sk)
lock = &tcp_hashinfo.lhash_lock;
inet_listen_wlock(&tcp_hashinfo);
} else {
- sk->sk_hashent = inet6_sk_ehashfn(sk, tcp_hashinfo.ehash_size);
- list = &tcp_hashinfo.ehash[sk->sk_hashent].chain;
- lock = &tcp_hashinfo.ehash[sk->sk_hashent].lock;
+ unsigned int hash;
+ sk->sk_hash = hash = inet6_sk_ehashfn(sk);
+ hash &= (tcp_hashinfo.ehash_size - 1);
+ list = &tcp_hashinfo.ehash[hash].chain;
+ lock = &tcp_hashinfo.ehash[hash].lock;
write_lock(lock);
}
@@ -322,13 +324,13 @@ static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
const struct in6_addr *saddr = &np->daddr;
const int dif = sk->sk_bound_dev_if;
const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
- const int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport,
- tcp_hashinfo.ehash_size);
- struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash];
+ unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ prefetch(head->chain.first);
write_lock(&head->lock);
/* Check TIME-WAIT sockets first. */
@@ -365,14 +367,14 @@ static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET6_MATCH(sk2, saddr, daddr, ports, dif))
+ if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
goto not_unique;
}
unique:
BUG_TRAP(sk_unhashed(sk));
__sk_add_node(sk, &head->chain);
- sk->sk_hashent = hash;
+ sk->sk_hash = hash;
sock_prot_inc_use(sk->sk_prot);
write_unlock(&head->lock);
@@ -632,10 +634,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 +849,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 +888,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 +914,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 +999,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 +1064,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 +1184,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 +1282,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 +1538,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 +1728,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 +1780,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 390d750449ce..bf9519341fd3 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -99,7 +99,7 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum)
next:;
}
result = best;
- for(;; result += UDP_HTABLE_SIZE) {
+ for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) {
if (result > sysctl_local_port_range[1])
result = sysctl_local_port_range[0]
+ ((result - sysctl_local_port_range[0]) &
@@ -107,6 +107,8 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum)
if (!udp_lport_inuse(result))
break;
}
+ if (i >= (1 << 16) / UDP_HTABLE_SIZE)
+ goto fail;
gotit:
udp_port_rover = snum = result;
} else {
@@ -405,9 +407,8 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
continue;
if (!ipv6_addr_any(&np->rcv_saddr)) {
- if (ipv6_addr_equal(&np->rcv_saddr, loc_addr))
- return s;
- continue;
+ if (!ipv6_addr_equal(&np->rcv_saddr, loc_addr))
+ continue;
}
if(!inet6_mc_check(s, loc_addr, rmt_addr))
continue;
@@ -483,7 +484,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,8 +638,10 @@ 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;
+ int connected = 0;
/* destination address check */
if (sin6) {
@@ -748,6 +751,7 @@ do_udp_sendmsg:
fl->fl_ip_dport = inet->dport;
daddr = &np->daddr;
fl->fl6_flowlabel = np->flow_label;
+ connected = 1;
}
if (!fl->oif)
@@ -758,7 +762,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;
@@ -770,11 +774,11 @@ do_udp_sendmsg:
}
if (!(opt->opt_nflen|opt->opt_flen))
opt = NULL;
+ connected = 0;
}
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);
@@ -788,10 +792,13 @@ do_udp_sendmsg:
ipv6_addr_copy(&final, &fl->fl6_dst);
ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
final_p = &final;
+ connected = 0;
}
- if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst))
+ if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) {
fl->oif = np->mcast_oif;
+ connected = 0;
+ }
err = ip6_dst_lookup(sk, &dst, fl);
if (err)
@@ -799,10 +806,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 +820,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,18 +845,25 @@ 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)
err = udp_v6_push_pending_frames(sk, up);
- if (dst)
- ip6_dst_store(sk, dst,
- ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ?
- &np->daddr : NULL);
+ if (dst) {
+ if (connected) {
+ ip6_dst_store(sk, dst,
+ ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ?
+ &np->daddr : NULL);
+ } else {
+ dst_release(dst);
+ }
+ }
+
if (err > 0)
err = np->recverr ? net_xmit_errno(err) : 0;
release_sock(sk);
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 5d1e61168eb7..6f20b4206e08 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -567,10 +567,8 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
self->tty = NULL;
if (self->blocked_open) {
- if (self->close_delay) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(self->close_delay);
- }
+ if (self->close_delay)
+ schedule_timeout_interruptible(self->close_delay);
wake_up_interruptible(&self->open_wait);
}
@@ -863,8 +861,7 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
spin_lock_irqsave(&self->spinlock, flags);
while (self->tx_skb && self->tx_skb->len) {
spin_unlock_irqrestore(&self->spinlock, flags);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(poll_time);
+ schedule_timeout_interruptible(poll_time);
spin_lock_irqsave(&self->spinlock, flags);
if (signal_pending(current))
break;
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 071cd2cefd8a..953e255d2bc8 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -310,7 +310,7 @@ void irlan_eth_send_gratuitous_arp(struct net_device *dev)
#ifdef CONFIG_INET
IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev == NULL)
goto out;
if (in_dev->ifa_list)
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 6602d901f8b1..8aff254cb418 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -38,7 +38,7 @@
#include <net/irda/parameters.h>
#include <net/irda/irttp.h>
-static struct irttp_cb *irttp = NULL;
+static struct irttp_cb *irttp;
static void __irttp_close_tsap(struct tsap_cb *self);
@@ -86,12 +86,9 @@ static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 };
*/
int __init irttp_init(void)
{
- /* Initialize the irttp structure. */
- if (irttp == NULL) {
- irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL);
- if (irttp == NULL)
- return -ENOMEM;
- }
+ irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL);
+ if (irttp == NULL)
+ return -ENOMEM;
memset(irttp, 0, sizeof(struct irttp_cb));
irttp->magic = TTP_MAGIC;
@@ -100,6 +97,7 @@ int __init irttp_init(void)
if (!irttp->tsaps) {
IRDA_ERROR("%s: can't allocate IrTTP hashbin!\n",
__FUNCTION__);
+ kfree(irttp);
return -ENOMEM;
}
@@ -115,7 +113,6 @@ int __init irttp_init(void)
void __exit irttp_cleanup(void)
{
/* Check for main structure */
- IRDA_ASSERT(irttp != NULL, return;);
IRDA_ASSERT(irttp->magic == TTP_MAGIC, return;);
/*
@@ -382,7 +379,6 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
struct lsap_cb *lsap;
notify_t ttp_notify;
- IRDA_ASSERT(irttp != NULL, return NULL;);
IRDA_ASSERT(irttp->magic == TTP_MAGIC, return NULL;);
/* The IrLMP spec (IrLMP 1.1 p10) says that we have the right to
@@ -1880,8 +1876,6 @@ static int irttp_seq_open(struct inode *inode, struct file *file)
struct seq_file *seq;
int rc = -ENOMEM;
struct irttp_iter_state *s;
-
- IRDA_ASSERT(irttp != NULL, return -EINVAL;);
s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 4879743b945a..39031684b65c 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -185,7 +185,7 @@ static int pfkey_release(struct socket *sock)
}
static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
- int allocation, struct sock *sk)
+ gfp_t allocation, struct sock *sk)
{
int err = -ENOBUFS;
@@ -217,7 +217,7 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
#define BROADCAST_ONE 1
#define BROADCAST_REGISTERED 2
#define BROADCAST_PROMISC_ONLY 4
-static int pfkey_broadcast(struct sk_buff *skb, int allocation,
+static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
int broadcast_flags, struct sock *one_sk)
{
struct sock *sk;
@@ -1416,7 +1416,8 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
return 0;
}
-static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, int allocation)
+static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig,
+ gfp_t allocation)
{
struct sk_buff *skb;
struct sadb_msg *hdr;
@@ -2153,6 +2154,7 @@ out:
static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
{
+ unsigned int dir;
int err;
struct sadb_x_policy *pol;
struct xfrm_policy *xp;
@@ -2161,7 +2163,11 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL)
return -EINVAL;
- xp = xfrm_policy_byid(0, pol->sadb_x_policy_id,
+ dir = xfrm_policy_id2dir(pol->sadb_x_policy_id);
+ if (dir >= XFRM_POLICY_MAX)
+ return -EINVAL;
+
+ xp = xfrm_policy_byid(dir, pol->sadb_x_policy_id,
hdr->sadb_msg_type == SADB_X_SPDDELETE2);
if (xp == NULL)
return -ENOENT;
@@ -2173,9 +2179,9 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
c.data.byid = 1;
c.event = XFRM_MSG_DELPOLICY;
- km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
+ km_policy_notify(xp, dir, &c);
} else {
- err = key_pol_get_resp(sk, xp, hdr, pol->sadb_x_policy_dir-1);
+ err = key_pol_get_resp(sk, xp, hdr, dir);
}
xfrm_pol_put(xp);
diff --git a/net/llc/Makefile b/net/llc/Makefile
index 5ebd4ed2bd42..4e260cff3c5d 100644
--- a/net/llc/Makefile
+++ b/net/llc/Makefile
@@ -22,3 +22,4 @@ llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
llc2-$(CONFIG_PROC_FS) += llc_proc.o
+llc2-$(CONFIG_SYSCTL) += sysctl_net_llc.o
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 66f55e514b56..59d02cbbeb9e 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -21,6 +21,7 @@
* See the GNU General Public License for more details.
*/
#include <linux/config.h>
+#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/rtnetlink.h>
@@ -37,10 +38,9 @@ static u16 llc_ui_sap_link_no_max[256];
static struct sockaddr_llc llc_ui_addrnull;
static struct proto_ops llc_ui_ops;
-static int llc_ui_wait_for_conn(struct sock *sk, int timeout);
-static int llc_ui_wait_for_disc(struct sock *sk, int timeout);
-static int llc_ui_wait_for_data(struct sock *sk, int timeout);
-static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout);
+static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
+static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
+static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
#if 0
#define dprintk(args...) printk(KERN_DEBUG args)
@@ -116,12 +116,12 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
struct llc_sock* llc = llc_sk(sk);
int rc = 0;
- if (llc_data_accept_state(llc->state) || llc->p_flag) {
- int timeout = sock_sndtimeo(sk, noblock);
+ if (unlikely(llc_data_accept_state(llc->state) || llc->p_flag)) {
+ long timeout = sock_sndtimeo(sk, noblock);
rc = llc_ui_wait_for_busy_core(sk, timeout);
}
- if (!rc)
+ if (unlikely(!rc))
rc = llc_build_and_send_pkt(sk, skb);
return rc;
}
@@ -155,7 +155,7 @@ static int llc_ui_create(struct socket *sock, int protocol)
struct sock *sk;
int rc = -ESOCKTNOSUPPORT;
- if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) {
+ if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
rc = -ENOMEM;
sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
if (sk) {
@@ -177,7 +177,7 @@ static int llc_ui_release(struct socket *sock)
struct sock *sk = sock->sk;
struct llc_sock *llc;
- if (!sk)
+ if (unlikely(sk == NULL))
goto out;
sock_hold(sk);
lock_sock(sk);
@@ -189,10 +189,6 @@ static int llc_ui_release(struct socket *sock)
if (!sock_flag(sk, SOCK_ZAPPED))
llc_sap_remove_socket(llc->sap, sk);
release_sock(sk);
- if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
- llc_release_sockets(llc->sap);
- llc_sap_close(llc->sap);
- }
if (llc->dev)
dev_put(llc->dev);
sock_put(sk);
@@ -221,6 +217,7 @@ static int llc_ui_autoport(void)
llc_ui_sap_last_autoport = i + 2;
goto out;
}
+ llc_sap_put(sap);
}
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
tries++;
@@ -231,20 +228,13 @@ out:
}
/**
- * llc_ui_autobind - Bind a socket to a specific address.
- * @sk: Socket to bind an address to.
- * @addr: Address the user wants the socket bound to.
+ * llc_ui_autobind - automatically bind a socket to a sap
+ * @sock: socket to bind
+ * @addr: address to connect to
+ *
+ * Used by llc_ui_connect and llc_ui_sendmsg when the user hasn't
+ * specifically used llc_ui_bind to bind to an specific address/sap
*
- * Bind a socket to a specific address. For llc a user is able to bind to
- * a specific sap only or mac + sap. If the user only specifies a sap and
- * a null dmac (all zeros) the user is attempting to bind to an entire
- * sap. This will stop anyone else on the local system from using that
- * sap. If someone else has a mac + sap open the bind to null + sap will
- * fail.
- * If the user desires to bind to a specific mac + sap, it is possible to
- * have multiple sap connections via multiple macs.
- * Bind and autobind for that matter must enforce the correct sap usage
- * otherwise all hell will break loose.
* Returns: 0 upon success, negative otherwise.
*/
static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
@@ -285,11 +275,7 @@ out:
* @addrlen: Length of the uaddr structure.
*
* Bind a socket to a specific address. For llc a user is able to bind to
- * a specific sap only or mac + sap. If the user only specifies a sap and
- * a null dmac (all zeros) the user is attempting to bind to an entire
- * sap. This will stop anyone else on the local system from using that
- * sap. If someone else has a mac + sap open the bind to null + sap will
- * fail.
+ * a specific sap only or mac + sap.
* If the user desires to bind to a specific mac + sap, it is possible to
* have multiple sap connections via multiple macs.
* Bind and autobind for that matter must enforce the correct sap usage
@@ -305,10 +291,16 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
int rc = -EINVAL;
dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
- if (!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))
+ if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)))
goto out;
rc = -EAFNOSUPPORT;
- if (addr->sllc_family != AF_LLC)
+ if (unlikely(addr->sllc_family != AF_LLC))
+ goto out;
+ rc = -ENODEV;
+ rtnl_lock();
+ llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac);
+ rtnl_unlock();
+ if (!llc->dev)
goto out;
if (!addr->sllc_sap) {
rc = -EUSERS;
@@ -322,6 +314,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
rc = -EBUSY; /* some other network layer is using the sap */
if (!sap)
goto out;
+ llc_sap_hold(sap);
} else {
struct llc_addr laddr, daddr;
struct sock *ask;
@@ -338,7 +331,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
ask = llc_lookup_established(sap, &daddr, &laddr);
if (ask) {
sock_put(ask);
- goto out;
+ goto out_put;
}
}
llc->laddr.lsap = addr->sllc_sap;
@@ -348,6 +341,8 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
llc_sap_add_socket(sap, sk);
sock_reset_flag(sk, SOCK_ZAPPED);
rc = 0;
+out_put:
+ llc_sap_put(sap);
out:
return rc;
}
@@ -369,7 +364,7 @@ static int llc_ui_shutdown(struct socket *sock, int how)
int rc = -ENOTCONN;
lock_sock(sk);
- if (sk->sk_state != TCP_ESTABLISHED)
+ if (unlikely(sk->sk_state != TCP_ESTABLISHED))
goto out;
rc = -EINVAL;
if (how != 2)
@@ -404,14 +399,18 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk);
struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
- struct net_device *dev;
int rc = -EINVAL;
lock_sock(sk);
- if (addrlen != sizeof(*addr))
+ if (unlikely(addrlen != sizeof(*addr)))
goto out;
rc = -EAFNOSUPPORT;
- if (addr->sllc_family != AF_LLC)
+ if (unlikely(addr->sllc_family != AF_LLC))
+ goto out;
+ if (unlikely(sk->sk_type != SOCK_STREAM))
+ goto out;
+ rc = -EALREADY;
+ if (unlikely(sock->state == SS_CONNECTING))
goto out;
/* bind connection to sap if user hasn't done it. */
if (sock_flag(sk, SOCK_ZAPPED)) {
@@ -419,19 +418,13 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
rc = llc_ui_autobind(sock, addr);
if (rc)
goto out;
- llc->daddr.lsap = addr->sllc_sap;
- memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
}
- dev = llc->dev;
- if (sk->sk_type != SOCK_STREAM)
- goto out;
- rc = -EALREADY;
- if (sock->state == SS_CONNECTING)
- goto out;
+ llc->daddr.lsap = addr->sllc_sap;
+ memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
sock->state = SS_CONNECTING;
sk->sk_state = TCP_SYN_SENT;
llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap);
- rc = llc_establish_connection(sk, dev->dev_addr,
+ rc = llc_establish_connection(sk, llc->dev->dev_addr,
addr->sllc_mac, addr->sllc_sap);
if (rc) {
dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
@@ -439,12 +432,30 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
sk->sk_state = TCP_CLOSE;
goto out;
}
- rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo);
- if (rc)
- dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc);
+
+ if (sk->sk_state == TCP_SYN_SENT) {
+ const long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+
+ if (!timeo || !llc_ui_wait_for_conn(sk, timeo))
+ goto out;
+
+ rc = sock_intr_errno(timeo);
+ if (signal_pending(current))
+ goto out;
+ }
+
+ if (sk->sk_state == TCP_CLOSE)
+ goto sock_error;
+
+ sock->state = SS_CONNECTED;
+ rc = 0;
out:
release_sock(sk);
return rc;
+sock_error:
+ rc = sock_error(sk) ? : -ECONNABORTED;
+ sock->state = SS_UNCONNECTED;
+ goto out;
}
/**
@@ -461,10 +472,10 @@ static int llc_ui_listen(struct socket *sock, int backlog)
int rc = -EINVAL;
lock_sock(sk);
- if (sock->state != SS_UNCONNECTED)
+ if (unlikely(sock->state != SS_UNCONNECTED))
goto out;
rc = -EOPNOTSUPP;
- if (sk->sk_type != SOCK_STREAM)
+ if (unlikely(sk->sk_type != SOCK_STREAM))
goto out;
rc = -EAGAIN;
if (sock_flag(sk, SOCK_ZAPPED))
@@ -483,20 +494,14 @@ out:
return rc;
}
-static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
+static int llc_ui_wait_for_disc(struct sock *sk, long timeout)
{
- DECLARE_WAITQUEUE(wait, current);
- int rc;
+ DEFINE_WAIT(wait);
+ int rc = 0;
- add_wait_queue_exclusive(sk->sk_sleep, &wait);
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- rc = 0;
- if (sk->sk_state != TCP_CLOSE) {
- release_sock(sk);
- timeout = schedule_timeout(timeout);
- lock_sock(sk);
- } else
+ while (1) {
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+ if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE))
break;
rc = -ERESTARTSYS;
if (signal_pending(current))
@@ -504,65 +509,40 @@ static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
rc = -EAGAIN;
if (!timeout)
break;
+ rc = 0;
}
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk->sk_sleep, &wait);
+ finish_wait(sk->sk_sleep, &wait);
return rc;
}
-static int llc_ui_wait_for_conn(struct sock *sk, int timeout)
+static int llc_ui_wait_for_conn(struct sock *sk, long timeout)
{
- DECLARE_WAITQUEUE(wait, current);
- int rc;
+ DEFINE_WAIT(wait);
- add_wait_queue_exclusive(sk->sk_sleep, &wait);
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- rc = -EAGAIN;
- if (sk->sk_state == TCP_CLOSE)
- break;
- rc = 0;
- if (sk->sk_state != TCP_ESTABLISHED) {
- release_sock(sk);
- timeout = schedule_timeout(timeout);
- lock_sock(sk);
- } else
+ while (1) {
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+ if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT))
break;
- rc = -ERESTARTSYS;
- if (signal_pending(current))
- break;
- rc = -EAGAIN;
- if (!timeout)
+ if (signal_pending(current) || !timeout)
break;
}
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk->sk_sleep, &wait);
- return rc;
+ finish_wait(sk->sk_sleep, &wait);
+ return timeout;
}
-static int llc_ui_wait_for_data(struct sock *sk, int timeout)
+static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
{
- DECLARE_WAITQUEUE(wait, current);
- int rc = 0;
+ DEFINE_WAIT(wait);
+ struct llc_sock *llc = llc_sk(sk);
+ int rc;
- add_wait_queue_exclusive(sk->sk_sleep, &wait);
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- break;
- /*
- * Well, if we have backlog, try to process it now.
- */
- if (sk->sk_backlog.tail) {
- release_sock(sk);
- lock_sock(sk);
- }
+ while (1) {
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
rc = 0;
- if (skb_queue_empty(&sk->sk_receive_queue)) {
- release_sock(sk);
- timeout = schedule_timeout(timeout);
- lock_sock(sk);
- } else
+ if (sk_wait_event(sk, &timeout,
+ (sk->sk_shutdown & RCV_SHUTDOWN) ||
+ (!llc_data_accept_state(llc->state) &&
+ !llc->p_flag)))
break;
rc = -ERESTARTSYS;
if (signal_pending(current))
@@ -571,40 +551,35 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout)
if (!timeout)
break;
}
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk->sk_sleep, &wait);
+ finish_wait(sk->sk_sleep, &wait);
return rc;
}
-static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
+static int llc_wait_data(struct sock *sk, long timeo)
{
- DECLARE_WAITQUEUE(wait, current);
- struct llc_sock *llc = llc_sk(sk);
int rc;
- add_wait_queue_exclusive(sk->sk_sleep, &wait);
- for (;;) {
- dprintk("%s: looping...\n", __FUNCTION__);
- __set_current_state(TASK_INTERRUPTIBLE);
- rc = -ENOTCONN;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
+ while (1) {
+ /*
+ * POSIX 1003.1g mandates this order.
+ */
+ if (sk->sk_err) {
+ rc = sock_error(sk);
break;
+ }
rc = 0;
- if (llc_data_accept_state(llc->state) || llc->p_flag) {
- release_sock(sk);
- timeout = schedule_timeout(timeout);
- lock_sock(sk);
- } else
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
break;
- rc = -ERESTARTSYS;
+ rc = -EAGAIN;
+ if (!timeo)
+ break;
+ rc = sock_intr_errno(timeo);
if (signal_pending(current))
break;
- rc = -EAGAIN;
- if (!timeout)
+ rc = 0;
+ if (sk_wait_data(sk, &timeo))
break;
}
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk->sk_sleep, &wait);
return rc;
}
@@ -627,15 +602,18 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
dprintk("%s: accepting on %02X\n", __FUNCTION__,
llc_sk(sk)->laddr.lsap);
lock_sock(sk);
- if (sk->sk_type != SOCK_STREAM)
+ if (unlikely(sk->sk_type != SOCK_STREAM))
goto out;
rc = -EINVAL;
- if (sock->state != SS_UNCONNECTED || sk->sk_state != TCP_LISTEN)
+ if (unlikely(sock->state != SS_UNCONNECTED ||
+ sk->sk_state != TCP_LISTEN))
goto out;
/* wait for a connection to arrive. */
- rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
- if (rc)
- goto out;
+ if (skb_queue_empty(&sk->sk_receive_queue)) {
+ rc = llc_wait_data(sk, sk->sk_rcvtimeo);
+ if (rc)
+ goto out;
+ }
dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
llc_sk(sk)->laddr.lsap);
skb = skb_dequeue(&sk->sk_receive_queue);
@@ -657,7 +635,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
/* put original socket back into a clean listen state. */
sk->sk_state = TCP_LISTEN;
sk->sk_ack_backlog--;
- skb->sk = NULL;
dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
frees:
@@ -671,56 +648,167 @@ out:
* llc_ui_recvmsg - copy received data to the socket user.
* @sock: Socket to copy data from.
* @msg: Various user space related information.
- * @size: Size of user buffer.
+ * @len: Size of user buffer.
* @flags: User specified flags.
*
* Copy received data to the socket user.
* Returns non-negative upon success, negative otherwise.
*/
static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t size, int flags)
+ struct msghdr *msg, size_t len, int flags)
{
- struct sock *sk = sock->sk;
struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
- struct sk_buff *skb;
+ const int nonblock = flags & MSG_DONTWAIT;
+ struct sk_buff *skb = NULL;
+ struct sock *sk = sock->sk;
+ struct llc_sock *llc = llc_sk(sk);
size_t copied = 0;
- int rc = -ENOMEM, timeout;
- int noblock = flags & MSG_DONTWAIT;
+ u32 peek_seq = 0;
+ u32 *seq;
+ unsigned long used;
+ int target; /* Read at least this many bytes */
+ long timeo;
- dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
- llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
lock_sock(sk);
- timeout = sock_rcvtimeo(sk, noblock);
- rc = llc_ui_wait_for_data(sk, timeout);
- if (rc) {
- dprintk("%s: llc_ui_wait_for_data failed recv "
- "in %02X from %02X\n", __FUNCTION__,
- llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
+ copied = -ENOTCONN;
+ if (sk->sk_state == TCP_LISTEN)
goto out;
- }
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (!skb) /* shutdown */
- goto out;
- copied = skb->len;
- if (copied > size)
- copied = size;
- rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- if (rc)
- goto dgram_free;
- if (skb->len > copied) {
- skb_pull(skb, copied);
- skb_queue_head(&sk->sk_receive_queue, skb);
- }
- if (uaddr)
- memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
- msg->msg_namelen = sizeof(*uaddr);
- if (!skb->next) {
-dgram_free:
- kfree_skb(skb);
- }
+
+ timeo = sock_rcvtimeo(sk, nonblock);
+
+ seq = &llc->copied_seq;
+ if (flags & MSG_PEEK) {
+ peek_seq = llc->copied_seq;
+ seq = &peek_seq;
+ }
+
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
+ copied = 0;
+
+ do {
+ u32 offset;
+
+ /*
+ * We need to check signals first, to get correct SIGURG
+ * handling. FIXME: Need to check this doesn't impact 1003.1g
+ * and move it down to the bottom of the loop
+ */
+ if (signal_pending(current)) {
+ if (copied)
+ break;
+ copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
+ break;
+ }
+
+ /* Next get a buffer. */
+
+ skb = skb_peek(&sk->sk_receive_queue);
+ if (skb) {
+ offset = *seq;
+ goto found_ok_skb;
+ }
+ /* Well, if we have backlog, try to process it now yet. */
+
+ if (copied >= target && !sk->sk_backlog.tail)
+ break;
+
+ if (copied) {
+ if (sk->sk_err ||
+ sk->sk_state == TCP_CLOSE ||
+ (sk->sk_shutdown & RCV_SHUTDOWN) ||
+ !timeo ||
+ (flags & MSG_PEEK))
+ break;
+ } else {
+ if (sock_flag(sk, SOCK_DONE))
+ break;
+
+ if (sk->sk_err) {
+ copied = sock_error(sk);
+ break;
+ }
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ break;
+
+ if (sk->sk_state == TCP_CLOSE) {
+ if (!sock_flag(sk, SOCK_DONE)) {
+ /*
+ * This occurs when user tries to read
+ * from never connected socket.
+ */
+ copied = -ENOTCONN;
+ break;
+ }
+ break;
+ }
+ if (!timeo) {
+ copied = -EAGAIN;
+ break;
+ }
+ }
+
+ if (copied >= target) { /* Do not sleep, just process backlog. */
+ release_sock(sk);
+ lock_sock(sk);
+ } else
+ sk_wait_data(sk, &timeo);
+
+ if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) {
+ if (net_ratelimit())
+ printk(KERN_DEBUG "LLC(%s:%d): Application "
+ "bug, race in MSG_PEEK.\n",
+ current->comm, current->pid);
+ peek_seq = llc->copied_seq;
+ }
+ continue;
+ found_ok_skb:
+ /* Ok so how much can we use? */
+ used = skb->len - offset;
+ if (len < used)
+ used = len;
+
+ if (!(flags & MSG_TRUNC)) {
+ int rc = skb_copy_datagram_iovec(skb, offset,
+ msg->msg_iov, used);
+ if (rc) {
+ /* Exception. Bailout! */
+ if (!copied)
+ copied = -EFAULT;
+ break;
+ }
+ }
+
+ *seq += used;
+ copied += used;
+ len -= used;
+
+ if (used + offset < skb->len)
+ continue;
+
+ if (!(flags & MSG_PEEK)) {
+ sk_eat_skb(sk, skb);
+ *seq = 0;
+ }
+ } while (len > 0);
+
+ /*
+ * According to UNIX98, msg_name/msg_namelen are ignored
+ * on connected socket. -ANK
+ * But... af_llc still doesn't have separate sets of methods for
+ * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will
+ * eventually fix this tho :-) -acme
+ */
+ if (sk->sk_type == SOCK_DGRAM)
+ goto copy_uaddr;
out:
release_sock(sk);
- return rc ? : copied;
+ return copied;
+copy_uaddr:
+ if (uaddr != NULL && skb != NULL) {
+ memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
+ msg->msg_namelen = sizeof(*uaddr);
+ }
+ goto out;
}
/**
@@ -740,7 +828,6 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
int flags = msg->msg_flags;
int noblock = flags & MSG_DONTWAIT;
- struct net_device *dev;
struct sk_buff *skb;
size_t size = 0;
int rc = -EINVAL, copied = 0, hdrlen;
@@ -763,19 +850,17 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
if (rc)
goto release;
}
- dev = llc->dev;
- hdrlen = dev->hard_header_len + llc_ui_header_len(sk, addr);
+ hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr);
size = hdrlen + len;
- if (size > dev->mtu)
- size = dev->mtu;
+ if (size > llc->dev->mtu)
+ size = llc->dev->mtu;
copied = size - hdrlen;
release_sock(sk);
skb = sock_alloc_send_skb(sk, size, noblock, &rc);
lock_sock(sk);
if (!skb)
goto release;
- skb->sk = sk;
- skb->dev = dev;
+ skb->dev = llc->dev;
skb->protocol = llc_proto_type(addr->sllc_arphrd);
skb_reserve(skb, hdrlen);
rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
@@ -800,15 +885,13 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
goto out;
rc = llc_ui_send_data(sk, skb, noblock);
- if (rc)
- dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc);
out:
- if (rc)
+ if (rc) {
kfree_skb(skb);
release:
- if (rc)
dprintk("%s: failed sending from %02X to %02X: %d\n",
__FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
+ }
release_sock(sk);
return rc ? : copied;
}
@@ -895,7 +978,7 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
int rc = -EINVAL, opt;
lock_sock(sk);
- if (level != SOL_LLC || optlen != sizeof(int))
+ if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
goto out;
rc = get_user(opt, (int __user *)optval);
if (rc)
@@ -915,22 +998,22 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
case LLC_OPT_ACK_TMR_EXP:
if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
goto out;
- llc->ack_timer.expire = opt;
+ llc->ack_timer.expire = opt * HZ;
break;
case LLC_OPT_P_TMR_EXP:
if (opt > LLC_OPT_MAX_P_TMR_EXP)
goto out;
- llc->pf_cycle_timer.expire = opt;
+ llc->pf_cycle_timer.expire = opt * HZ;
break;
case LLC_OPT_REJ_TMR_EXP:
if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
goto out;
- llc->rej_sent_timer.expire = opt;
+ llc->rej_sent_timer.expire = opt * HZ;
break;
case LLC_OPT_BUSY_TMR_EXP:
if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
goto out;
- llc->busy_state_timer.expire = opt;
+ llc->busy_state_timer.expire = opt * HZ;
break;
case LLC_OPT_TX_WIN:
if (opt > LLC_OPT_MAX_WIN)
@@ -970,7 +1053,7 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
int val = 0, len = 0, rc = -EINVAL;
lock_sock(sk);
- if (level != SOL_LLC)
+ if (unlikely(level != SOL_LLC))
goto out;
rc = get_user(len, optlen);
if (rc)
@@ -980,17 +1063,17 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
goto out;
switch (optname) {
case LLC_OPT_RETRY:
- val = llc->n2; break;
+ val = llc->n2; break;
case LLC_OPT_SIZE:
- val = llc->n1; break;
+ val = llc->n1; break;
case LLC_OPT_ACK_TMR_EXP:
- val = llc->ack_timer.expire; break;
+ val = llc->ack_timer.expire / HZ; break;
case LLC_OPT_P_TMR_EXP:
- val = llc->pf_cycle_timer.expire; break;
+ val = llc->pf_cycle_timer.expire / HZ; break;
case LLC_OPT_REJ_TMR_EXP:
- val = llc->rej_sent_timer.expire; break;
+ val = llc->rej_sent_timer.expire / HZ; break;
case LLC_OPT_BUSY_TMR_EXP:
- val = llc->busy_state_timer.expire; break;
+ val = llc->busy_state_timer.expire / HZ; break;
case LLC_OPT_TX_WIN:
val = llc->k; break;
case LLC_OPT_RX_WIN:
@@ -1034,8 +1117,12 @@ static struct proto_ops llc_ui_ops = {
.sendpage = sock_no_sendpage,
};
-extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
-extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
+static char llc_proc_err_msg[] __initdata =
+ KERN_CRIT "LLC: Unable to register the proc_fs entries\n";
+static char llc_sysctl_err_msg[] __initdata =
+ KERN_CRIT "LLC: Unable to register the sysctl entries\n";
+static char llc_sock_err_msg[] __initdata =
+ KERN_CRIT "LLC: Unable to register the network family\n";
static int __init llc2_init(void)
{
@@ -1048,13 +1135,28 @@ static int __init llc2_init(void)
llc_station_init();
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
rc = llc_proc_init();
- if (rc != 0)
+ if (rc != 0) {
+ printk(llc_proc_err_msg);
goto out_unregister_llc_proto;
- sock_register(&llc_ui_family_ops);
+ }
+ rc = llc_sysctl_init();
+ if (rc) {
+ printk(llc_sysctl_err_msg);
+ goto out_proc;
+ }
+ rc = sock_register(&llc_ui_family_ops);
+ if (rc) {
+ printk(llc_sock_err_msg);
+ goto out_sysctl;
+ }
llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
out:
return rc;
+out_sysctl:
+ llc_sysctl_exit();
+out_proc:
+ llc_proc_exit();
out_unregister_llc_proto:
proto_unregister(&llc_proto);
goto out;
@@ -1067,6 +1169,7 @@ static void __exit llc2_exit(void)
llc_remove_pack(LLC_DEST_CONN);
sock_unregister(PF_LLC);
llc_proc_exit();
+ llc_sysctl_exit();
proto_unregister(&llc_proto);
}
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index b218be4c10ec..b0bcfb1f12dd 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -60,23 +60,10 @@ int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
{
- int rc = -ENOTCONN;
- u8 dsap;
- struct llc_sap *sap;
-
- llc_pdu_decode_dsap(skb, &dsap);
- sap = llc_sap_find(dsap);
- if (sap) {
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- struct llc_sock *llc = llc_sk(sk);
+ struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- llc_pdu_decode_sa(skb, llc->daddr.mac);
- llc_pdu_decode_da(skb, llc->laddr.mac);
- llc->dev = skb->dev;
- ev->ind_prim = LLC_CONN_PRIM;
- rc = 0;
- }
- return rc;
+ ev->ind_prim = LLC_CONN_PRIM;
+ return 0;
}
int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
@@ -120,10 +107,8 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
} else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
reason = LLC_DISC_REASON_ACK_TMR_EXP;
- else {
- reason = 0;
+ else
rc = -EINVAL;
- }
if (!rc) {
ev->reason = reason;
ev->ind_prim = LLC_DISC_PRIM;
@@ -160,9 +145,6 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
reason = LLC_RESET_REASON_REMOTE;
rc = 0;
- } else {
- reason = 0;
- rc = 1;
}
break;
case LLC_CONN_EV_TYPE_ACK_TMR:
@@ -172,8 +154,7 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
if (llc->retry_count > llc->n2) {
reason = LLC_RESET_REASON_LOCAL;
rc = 0;
- } else
- rc = 1;
+ }
break;
}
if (!rc) {
@@ -217,18 +198,17 @@ int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_disc_cmd(nskb, 1);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
llc_conn_ac_set_p_flag_1(sk, skb);
@@ -243,20 +223,19 @@ free:
int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit;
- nskb->dev = llc->dev;
llc_pdu_decode_pf_bit(skb, &f_bit);
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_dm_rsp(nskb, f_bit);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -270,19 +249,17 @@ free:
int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- u8 f_bit = 1;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_dm_rsp(nskb, f_bit);
+ llc_pdu_init_as_dm_rsp(nskb, 1);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -306,17 +283,16 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
llc_pdu_decode_pf_bit(skb, &f_bit);
else
f_bit = 0;
- nskb = llc_alloc_frame();
+ nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
llc->vR, INCORRECT);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -330,21 +306,19 @@ free:
int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- u8 f_bit = 0;
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+ llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS,
llc->vR, INCORRECT);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -360,21 +334,20 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
u8 f_bit;
int rc = -ENOBUFS;
struct sk_buff *nskb;
+ struct llc_sock *llc = llc_sk(sk);
llc_pdu_decode_pf_bit(skb, &f_bit);
- nskb = llc_alloc_frame();
+ nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
llc->vR, INCORRECT);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -395,7 +368,7 @@ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
- if (!rc) {
+ if (likely(!rc)) {
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, skb);
}
@@ -412,7 +385,7 @@ static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
- if (!rc) {
+ if (likely(!rc)) {
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, skb);
}
@@ -429,7 +402,7 @@ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
- if (!rc) {
+ if (likely(!rc)) {
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, skb);
}
@@ -451,18 +424,17 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
u8 nr;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (!rc)
+ if (likely(!rc))
llc_conn_send_pdu(sk, nskb);
else
kfree_skb(skb);
@@ -487,18 +459,17 @@ int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -512,19 +483,17 @@ free:
int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- u8 f_bit = 1;
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
+ llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -538,19 +507,17 @@ free:
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- u8 f_bit = 0;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
+ llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -564,18 +531,17 @@ free:
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -589,19 +555,17 @@ free:
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- u8 f_bit = 1;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+ llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -615,19 +579,17 @@ free:
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- u8 f_bit = 0;
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+ llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -645,7 +607,7 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
if (!llc->remote_busy_flag) {
llc->remote_busy_flag = 1;
mod_timer(&llc->busy_state_timer.timer,
- jiffies + llc->busy_state_timer.expire * HZ);
+ jiffies + llc->busy_state_timer.expire);
}
return 0;
}
@@ -653,18 +615,17 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -678,18 +639,17 @@ free:
int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -703,19 +663,18 @@ free:
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 1;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -729,19 +688,17 @@ free:
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- u8 f_bit = 1;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
- llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+ llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -755,18 +712,17 @@ free:
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -780,18 +736,17 @@ free:
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -815,8 +770,8 @@ void llc_conn_set_p_flag(struct sock *sk, u8 value)
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -824,12 +779,11 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
if (llc->dev->flags & IFF_LOOPBACK)
dmac = llc->dev->dev_addr;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_sabme_cmd(nskb, 1);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
llc_conn_set_p_flag(sk, 1);
@@ -845,11 +799,11 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
{
u8 f_bit;
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
llc_pdu_decode_pf_bit(skb, &f_bit);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
nskb->dev = llc->dev;
@@ -857,7 +811,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_ua_rsp(nskb, f_bit);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -886,7 +840,7 @@ int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
llc_conn_set_p_flag(sk, 1);
mod_timer(&llc->pf_cycle_timer.timer,
- jiffies + llc->pf_cycle_timer.expire * HZ);
+ jiffies + llc->pf_cycle_timer.expire);
return 0;
}
@@ -957,7 +911,7 @@ static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
- if (!rc) {
+ if (likely(!rc)) {
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, skb);
}
@@ -1001,18 +955,17 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
struct sk_buff *skb)
{
int rc = -ENOBUFS;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct llc_sock *llc = llc_sk(sk);
+ struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
if (nskb) {
- struct llc_sock *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
- nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_conn_send_pdu(sk, nskb);
}
@@ -1165,7 +1118,7 @@ int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
{
struct llc_sock *llc = llc_sk(sk);
- mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ);
+ mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire);
return 0;
}
@@ -1174,7 +1127,7 @@ int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
struct llc_sock *llc = llc_sk(sk);
mod_timer(&llc->rej_sent_timer.timer,
- jiffies + llc->rej_sent_timer.expire * HZ);
+ jiffies + llc->rej_sent_timer.expire);
return 0;
}
@@ -1185,7 +1138,7 @@ int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
if (!timer_pending(&llc->ack_timer.timer))
mod_timer(&llc->ack_timer.timer,
- jiffies + llc->ack_timer.expire * HZ);
+ jiffies + llc->ack_timer.expire);
return 0;
}
@@ -1233,7 +1186,7 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
}
if (unacked)
mod_timer(&llc->ack_timer.timer,
- jiffies + llc->ack_timer.expire * HZ);
+ jiffies + llc->ack_timer.expire);
} else if (llc->failed_data_req) {
u8 f_bit;
@@ -1354,13 +1307,13 @@ int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
return 0;
}
-int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
+static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
return 0;
}
-void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
+static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type)
{
struct sock *sk = (struct sock *)timeout_data;
struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
@@ -1369,59 +1322,31 @@ void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- skb->sk = sk;
- ev->type = LLC_CONN_EV_TYPE_P_TMR;
+ skb_set_owner_r(skb, sk);
+ ev->type = type;
llc_process_tmr_ev(sk, skb);
}
bh_unlock_sock(sk);
}
-void llc_conn_busy_tmr_cb(unsigned long timeout_data)
+void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
{
- struct sock *sk = (struct sock *)timeout_data;
- struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
-
- bh_lock_sock(sk);
- if (skb) {
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
+}
- skb->sk = sk;
- ev->type = LLC_CONN_EV_TYPE_BUSY_TMR;
- llc_process_tmr_ev(sk, skb);
- }
- bh_unlock_sock(sk);
+void llc_conn_busy_tmr_cb(unsigned long timeout_data)
+{
+ llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
}
void llc_conn_ack_tmr_cb(unsigned long timeout_data)
{
- struct sock* sk = (struct sock *)timeout_data;
- struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
-
- bh_lock_sock(sk);
- if (skb) {
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
- skb->sk = sk;
- ev->type = LLC_CONN_EV_TYPE_ACK_TMR;
- llc_process_tmr_ev(sk, skb);
- }
- bh_unlock_sock(sk);
+ llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
}
void llc_conn_rej_tmr_cb(unsigned long timeout_data)
{
- struct sock *sk = (struct sock *)timeout_data;
- struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
-
- bh_lock_sock(sk);
- if (skb) {
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
- skb->sk = sk;
- ev->type = LLC_CONN_EV_TYPE_REJ_TMR;
- llc_process_tmr_ev(sk, skb);
- }
- bh_unlock_sock(sk);
+ llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
}
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
diff --git a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
index d5bdb53a348f..c5deda246614 100644
--- a/net/llc/llc_c_ev.c
+++ b/net/llc/llc_c_ev.c
@@ -37,6 +37,7 @@
#include <net/llc_conn.h>
#include <net/llc_sap.h>
#include <net/sock.h>
+#include <net/llc_c_ac.h>
#include <net/llc_c_ev.h>
#include <net/llc_pdu.h>
@@ -46,8 +47,6 @@
#define dprintk(args...)
#endif
-extern u16 llc_circular_between(u8 a, u8 b, u8 c);
-
/**
* llc_util_ns_inside_rx_window - check if sequence number is in rx window
* @ns: sequence number of received pdu.
@@ -99,7 +98,7 @@ out:
int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->prim == LLC_CONN_PRIM &&
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
@@ -107,7 +106,7 @@ int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->prim == LLC_DATA_PRIM &&
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
@@ -115,7 +114,7 @@ int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->prim == LLC_DISC_PRIM &&
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
@@ -123,7 +122,7 @@ int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->prim == LLC_RESET_PRIM &&
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
@@ -131,7 +130,7 @@ int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
@@ -139,7 +138,7 @@ int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
@@ -152,7 +151,7 @@ int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
@@ -160,7 +159,7 @@ int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
@@ -168,7 +167,7 @@ int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
@@ -176,7 +175,7 @@ int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return llc_conn_space(sk, skb) &&
LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
@@ -186,7 +185,7 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return llc_conn_space(sk, skb) &&
LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
@@ -197,9 +196,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
LLC_I_PF_IS_0(pdu) && ns != vr &&
@@ -209,9 +208,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
LLC_I_PF_IS_1(pdu) && ns != vr &&
@@ -221,10 +220,11 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
- u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+ const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
+ const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+ ns != vr &&
llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
if (!rc)
dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
@@ -234,7 +234,7 @@ int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return llc_conn_space(sk, skb) &&
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
@@ -244,7 +244,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
LLC_I_PF_IS_1(pdu) &&
@@ -253,7 +253,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return llc_conn_space(sk, skb) &&
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
@@ -263,9 +263,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
LLC_I_PF_IS_0(pdu) && ns != vr &&
@@ -275,9 +275,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
LLC_I_PF_IS_1(pdu) && ns != vr &&
@@ -287,9 +287,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
!llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
@@ -298,10 +298,11 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vr = llc_sk(sk)->vR;
- u8 ns = LLC_I_GET_NS(pdu);
- u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vr = llc_sk(sk)->vR;
+ const u8 ns = LLC_I_GET_NS(pdu);
+ const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+ ns != vr &&
llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
if (!rc)
dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
@@ -311,7 +312,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_0(pdu) &&
@@ -320,7 +321,7 @@ int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_1(pdu) &&
@@ -329,7 +330,7 @@ int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_0(pdu) &&
@@ -338,7 +339,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_1(pdu) &&
@@ -347,7 +348,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
@@ -355,7 +356,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_0(pdu) &&
@@ -364,7 +365,7 @@ int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_1(pdu) &&
@@ -373,7 +374,7 @@ int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_0(pdu) &&
@@ -382,7 +383,7 @@ int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_1(pdu) &&
@@ -391,7 +392,7 @@ int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_0(pdu) &&
@@ -400,7 +401,7 @@ int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
LLC_S_PF_IS_1(pdu) &&
@@ -409,7 +410,7 @@ int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return llc_conn_space(sk, skb) &&
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
@@ -419,7 +420,7 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return llc_conn_space(sk, skb) &&
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
@@ -429,7 +430,7 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
@@ -446,7 +447,7 @@ int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if (LLC_PDU_IS_CMD(pdu)) {
if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
@@ -461,7 +462,7 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
if (LLC_PDU_IS_CMD(pdu)) {
if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
@@ -477,32 +478,10 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
return rc;
}
-int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
-{
- u16 rc = 1;
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-
- if (LLC_PDU_IS_RSP(pdu)) {
- if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
- if (LLC_I_PF_IS_1(pdu))
- rc = 0;
- } else if (LLC_PDU_TYPE_IS_U(pdu))
- switch (LLC_U_PDU_RSP(pdu)) {
- case LLC_2_PDU_RSP_UA:
- case LLC_2_PDU_RSP_DM:
- case LLC_2_PDU_RSP_FRMR:
- if (LLC_U_PF_IS_1(pdu))
- rc = 0;
- break;
- }
- }
- return rc;
-}
-
int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+ const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
if (LLC_PDU_IS_RSP(pdu)) {
if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
@@ -524,9 +503,9 @@ int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
struct sk_buff *skb)
{
u16 rc = 1;
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vs = llc_sk(sk)->vS;
- u8 nr = LLC_I_GET_NR(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vs = llc_sk(sk)->vS;
+ const u8 nr = LLC_I_GET_NR(pdu);
if (LLC_PDU_IS_CMD(pdu) &&
(LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
@@ -542,9 +521,9 @@ int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
struct sk_buff *skb)
{
u16 rc = 1;
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
- u8 vs = llc_sk(sk)->vS;
- u8 nr = LLC_I_GET_NR(pdu);
+ const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ const u8 vs = llc_sk(sk)->vS;
+ const u8 nr = LLC_I_GET_NR(pdu);
if (LLC_PDU_IS_RSP(pdu) &&
(LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
@@ -563,28 +542,28 @@ int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type != LLC_CONN_EV_TYPE_P_TMR;
}
int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
}
int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
}
int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
}
@@ -596,7 +575,7 @@ int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 4c644bc70eae..c761c15da421 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -40,6 +40,11 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
/* Offset table on connection states transition diagram */
static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
+int sysctl_llc2_ack_timeout = LLC2_ACK_TIME * HZ;
+int sysctl_llc2_p_timeout = LLC2_P_TIME * HZ;
+int sysctl_llc2_rej_timeout = LLC2_REJ_TIME * HZ;
+int sysctl_llc2_busy_timeout = LLC2_BUSY_TIME * HZ;
+
/**
* llc_conn_state_process - sends event to connection state machine
* @sk: connection
@@ -53,7 +58,7 @@ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
{
int rc;
- struct llc_sock *llc = llc_sk(sk);
+ struct llc_sock *llc = llc_sk(skb->sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
/*
@@ -63,13 +68,16 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
*/
skb_get(skb);
ev->ind_prim = ev->cfm_prim = 0;
- rc = llc_conn_service(sk, skb); /* sending event to state machine */
- if (rc) {
+ /*
+ * Send event to state machine
+ */
+ rc = llc_conn_service(skb->sk, skb);
+ if (unlikely(rc != 0)) {
printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__);
goto out_kfree_skb;
}
- if (!ev->ind_prim && !ev->cfm_prim) {
+ if (unlikely(!ev->ind_prim && !ev->cfm_prim)) {
/* indicate or confirm not required */
/* XXX this is not very pretty, perhaps we should store
* XXX indicate/confirm-needed state in the llc_conn_state_ev
@@ -80,13 +88,13 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
goto out_skb_put;
}
- if (ev->ind_prim && ev->cfm_prim) /* Paranoia */
+ if (unlikely(ev->ind_prim && ev->cfm_prim)) /* Paranoia */
skb_get(skb);
switch (ev->ind_prim) {
case LLC_DATA_PRIM:
- llc_save_primitive(skb, LLC_DATA_PRIM);
- if (sock_queue_rcv_skb(sk, skb)) {
+ llc_save_primitive(sk, skb, LLC_DATA_PRIM);
+ if (unlikely(sock_queue_rcv_skb(sk, skb))) {
/*
* shouldn't happen
*/
@@ -95,13 +103,14 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
kfree_skb(skb);
}
break;
- case LLC_CONN_PRIM: {
- struct sock *parent = skb->sk;
-
- skb->sk = sk;
- skb_queue_tail(&parent->sk_receive_queue, skb);
- sk->sk_state_change(parent);
- }
+ case LLC_CONN_PRIM:
+ /*
+ * Can't be sock_queue_rcv_skb, because we have to leave the
+ * skb->sk pointing to the newly created struct sock in
+ * llc_conn_handler. -acme
+ */
+ skb_queue_tail(&sk->sk_receive_queue, skb);
+ sk->sk_state_change(sk);
break;
case LLC_DISC_PRIM:
sock_hold(sk);
@@ -111,8 +120,8 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
sk->sk_socket->state = SS_UNCONNECTED;
sk->sk_state = TCP_CLOSE;
if (!sock_flag(sk, SOCK_DEAD)) {
- sk->sk_state_change(sk);
sock_set_flag(sk, SOCK_DEAD);
+ sk->sk_state_change(sk);
}
}
kfree_skb(skb);
@@ -465,7 +474,7 @@ static int llc_exec_conn_trans_actions(struct sock *sk,
}
/**
- * llc_lookup_established - Finds connection for the remote/local sap/mac
+ * __llc_lookup_established - Finds connection for the remote/local sap/mac
* @sap: SAP
* @daddr: address of remote LLC (MAC + SAP)
* @laddr: address of local LLC (MAC + SAP)
@@ -473,14 +482,16 @@ static int llc_exec_conn_trans_actions(struct sock *sk,
* Search connection list of the SAP and finds connection using the remote
* mac, remote sap, local mac, and local sap. Returns pointer for
* connection found, %NULL otherwise.
+ * Caller has to make sure local_bh is disabled.
*/
-struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
- struct llc_addr *laddr)
+static struct sock *__llc_lookup_established(struct llc_sap *sap,
+ struct llc_addr *daddr,
+ struct llc_addr *laddr)
{
struct sock *rc;
struct hlist_node *node;
- read_lock_bh(&sap->sk_list.lock);
+ read_lock(&sap->sk_list.lock);
sk_for_each(rc, node, &sap->sk_list.list) {
struct llc_sock *llc = llc_sk(rc);
@@ -494,10 +505,22 @@ struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
}
rc = NULL;
found:
- read_unlock_bh(&sap->sk_list.lock);
+ read_unlock(&sap->sk_list.lock);
return rc;
}
+struct sock *llc_lookup_established(struct llc_sap *sap,
+ struct llc_addr *daddr,
+ struct llc_addr *laddr)
+{
+ struct sock *sk;
+
+ local_bh_disable();
+ sk = __llc_lookup_established(sap, daddr, laddr);
+ local_bh_enable();
+ return sk;
+}
+
/**
* llc_lookup_listener - Finds listener for local MAC + SAP
* @sap: SAP
@@ -506,6 +529,7 @@ found:
* Search connection list of the SAP and finds connection listening on
* local mac, and local sap. Returns pointer for parent socket found,
* %NULL otherwise.
+ * Caller has to make sure local_bh is disabled.
*/
static struct sock *llc_lookup_listener(struct llc_sap *sap,
struct llc_addr *laddr)
@@ -513,7 +537,7 @@ static struct sock *llc_lookup_listener(struct llc_sap *sap,
struct sock *rc;
struct hlist_node *node;
- read_lock_bh(&sap->sk_list.lock);
+ read_lock(&sap->sk_list.lock);
sk_for_each(rc, node, &sap->sk_list.list) {
struct llc_sock *llc = llc_sk(rc);
@@ -527,10 +551,19 @@ static struct sock *llc_lookup_listener(struct llc_sap *sap,
}
rc = NULL;
found:
- read_unlock_bh(&sap->sk_list.lock);
+ read_unlock(&sap->sk_list.lock);
return rc;
}
+static struct sock *__llc_lookup(struct llc_sap *sap,
+ struct llc_addr *daddr,
+ struct llc_addr *laddr)
+{
+ struct sock *sk = __llc_lookup_established(sap, daddr, laddr);
+
+ return sk ? : llc_lookup_listener(sap, laddr);
+}
+
/**
* llc_data_accept_state - designates if in this state data can be sent.
* @state: state of connection.
@@ -544,14 +577,14 @@ u8 llc_data_accept_state(u8 state)
}
/**
- * find_next_offset - finds offset for next category of transitions
+ * llc_find_next_offset - finds offset for next category of transitions
* @state: state table.
* @offset: start offset.
*
* Finds offset of next category of transitions in transition table.
* Returns the start index of next category.
*/
-static u16 find_next_offset(struct llc_conn_state *state, u16 offset)
+static u16 __init llc_find_next_offset(struct llc_conn_state *state, u16 offset)
{
u16 cnt = 0;
struct llc_conn_state_trans **next_trans;
@@ -578,8 +611,8 @@ void __init llc_build_offset_table(void)
next_offset = 0;
for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) {
llc_offset_table[state][ev_type] = next_offset;
- next_offset += find_next_offset(curr_state,
- next_offset) + 1;
+ next_offset += llc_find_next_offset(curr_state,
+ next_offset) + 1;
}
}
}
@@ -623,6 +656,7 @@ static int llc_find_offset(int state, int ev_type)
*/
void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
{
+ llc_sap_hold(sap);
write_lock_bh(&sap->sk_list.lock);
llc_sk(sk)->sap = sap;
sk_add_node(sk, &sap->sk_list.list);
@@ -642,6 +676,7 @@ void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
write_lock_bh(&sap->sk_list.lock);
sk_del_node_init(sk);
write_unlock_bh(&sap->sk_list.lock);
+ llc_sap_put(sap);
}
/**
@@ -654,15 +689,34 @@ void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- struct llc_sock *llc = llc_sk(sk);
- if (!llc->dev)
- llc->dev = skb->dev;
ev->type = LLC_CONN_EV_TYPE_PDU;
ev->reason = 0;
return llc_conn_state_process(sk, skb);
}
+static struct sock *llc_create_incoming_sock(struct sock *sk,
+ struct net_device *dev,
+ struct llc_addr *saddr,
+ struct llc_addr *daddr)
+{
+ struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC,
+ sk->sk_prot);
+ struct llc_sock *newllc, *llc = llc_sk(sk);
+
+ if (!newsk)
+ goto out;
+ newllc = llc_sk(newsk);
+ memcpy(&newllc->laddr, daddr, sizeof(newllc->laddr));
+ memcpy(&newllc->daddr, saddr, sizeof(newllc->daddr));
+ newllc->dev = dev;
+ dev_hold(dev);
+ llc_sap_add_socket(llc->sap, newsk);
+ llc_sap_hold(llc->sap);
+out:
+ return newsk;
+}
+
void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_addr saddr, daddr;
@@ -673,35 +727,35 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
llc_pdu_decode_da(skb, daddr.mac);
llc_pdu_decode_dsap(skb, &daddr.lsap);
- sk = llc_lookup_established(sap, &saddr, &daddr);
- if (!sk) {
+ sk = __llc_lookup(sap, &saddr, &daddr);
+ if (!sk)
+ goto drop;
+
+ bh_lock_sock(sk);
+ /*
+ * This has to be done here and not at the upper layer ->accept
+ * method because of the way the PROCOM state machine works:
+ * it needs to set several state variables (see, for instance,
+ * llc_adm_actions_2 in net/llc/llc_c_st.c) and send a packet to
+ * the originator of the new connection, and this state has to be
+ * in the newly created struct sock private area. -acme
+ */
+ if (unlikely(sk->sk_state == TCP_LISTEN)) {
+ struct sock *newsk = llc_create_incoming_sock(sk, skb->dev,
+ &saddr, &daddr);
+ if (!newsk)
+ goto drop_unlock;
+ skb_set_owner_r(skb, newsk);
+ } else {
/*
- * Didn't find an active connection; verify if there
- * is a listening socket for this llc addr
+ * Can't be skb_set_owner_r, this will be done at the
+ * llc_conn_state_process function, later on, when we will use
+ * skb_queue_rcv_skb to send it to upper layers, this is
+ * another trick required to cope with how the PROCOM state
+ * machine works. -acme
*/
- struct llc_sock *llc;
- struct sock *parent = llc_lookup_listener(sap, &daddr);
-
- if (!parent) {
- dprintk("llc_lookup_listener failed!\n");
- goto drop;
- }
-
- sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC, parent->sk_prot);
- if (!sk) {
- sock_put(parent);
- goto drop;
- }
- llc = llc_sk(sk);
- memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
- memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
- llc_sap_add_socket(sap, sk);
- sock_hold(sk);
- sock_put(parent);
- skb->sk = parent;
- } else
skb->sk = sk;
- bh_lock_sock(sk);
+ }
if (!sock_owned_by_user(sk))
llc_conn_rcv(sk, skb);
else {
@@ -709,11 +763,16 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
llc_set_backlog_type(skb, LLC_PACKET);
sk_add_backlog(sk, skb);
}
+out:
bh_unlock_sock(sk);
sock_put(sk);
return;
drop:
kfree_skb(skb);
+ return;
+drop_unlock:
+ kfree_skb(skb);
+ goto out;
}
#undef LLC_REFCNT_DEBUG
@@ -722,32 +781,6 @@ static atomic_t llc_sock_nr;
#endif
/**
- * llc_release_sockets - releases all sockets in a sap
- * @sap: sap to release its sockets
- *
- * Releases all connections of a sap. Returns 0 if all actions complete
- * successfully, nonzero otherwise
- */
-int llc_release_sockets(struct llc_sap *sap)
-{
- int rc = 0;
- struct sock *sk;
- struct hlist_node *node;
-
- write_lock_bh(&sap->sk_list.lock);
-
- sk_for_each(sk, node, &sap->sk_list.list) {
- llc_sk(sk)->state = LLC_CONN_STATE_TEMP;
-
- if (llc_send_disc(sk))
- rc = 1;
- }
-
- write_unlock_bh(&sap->sk_list.lock);
- return rc;
-}
-
-/**
* llc_backlog_rcv - Processes rx frames and expired timers.
* @sk: LLC sock (p8022 connection)
* @skb: queued rx frame or event
@@ -762,14 +795,14 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
int rc = 0;
struct llc_sock *llc = llc_sk(sk);
- if (llc_backlog_type(skb) == LLC_PACKET) {
- if (llc->state > 1) /* not closed */
+ if (likely(llc_backlog_type(skb) == LLC_PACKET)) {
+ if (likely(llc->state > 1)) /* not closed */
rc = llc_conn_rcv(sk, skb);
else
goto out_kfree_skb;
} else if (llc_backlog_type(skb) == LLC_EVENT) {
/* timer expiration event */
- if (llc->state > 1) /* not closed */
+ if (likely(llc->state > 1)) /* not closed */
rc = llc_conn_state_process(sk, skb);
else
goto out_kfree_skb;
@@ -799,22 +832,22 @@ static void llc_sk_init(struct sock* sk)
llc->dec_step = llc->connect_step = 1;
init_timer(&llc->ack_timer.timer);
- llc->ack_timer.expire = LLC_ACK_TIME;
+ llc->ack_timer.expire = sysctl_llc2_ack_timeout;
llc->ack_timer.timer.data = (unsigned long)sk;
llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
init_timer(&llc->pf_cycle_timer.timer);
- llc->pf_cycle_timer.expire = LLC_P_TIME;
+ llc->pf_cycle_timer.expire = sysctl_llc2_p_timeout;
llc->pf_cycle_timer.timer.data = (unsigned long)sk;
llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
init_timer(&llc->rej_sent_timer.timer);
- llc->rej_sent_timer.expire = LLC_REJ_TIME;
+ llc->rej_sent_timer.expire = sysctl_llc2_rej_timeout;
llc->rej_sent_timer.timer.data = (unsigned long)sk;
llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
init_timer(&llc->busy_state_timer.timer);
- llc->busy_state_timer.expire = LLC_BUSY_TIME;
+ llc->busy_state_timer.expire = sysctl_llc2_busy_timeout;
llc->busy_state_timer.timer.data = (unsigned long)sk;
llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
@@ -834,7 +867,7 @@ static void llc_sk_init(struct sock* sk)
* Allocates a LLC sock and initializes it. Returns the new LLC sock
* or %NULL if there's no memory available for one
*/
-struct sock *llc_sk_alloc(int family, int priority, struct proto *prot)
+struct sock *llc_sk_alloc(int family, gfp_t priority, struct proto *prot)
{
struct sock *sk = sk_alloc(family, priority, prot, 1);
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
index 9727455bf0e7..ab0fcd32fd84 100644
--- a/net/llc/llc_core.c
+++ b/net/llc/llc_core.c
@@ -40,6 +40,7 @@ static struct llc_sap *llc_sap_alloc(void)
sap->state = LLC_SAP_STATE_ACTIVE;
memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
rwlock_init(&sap->sk_list.lock);
+ atomic_set(&sap->refcnt, 1);
}
return sap;
}
@@ -52,9 +53,7 @@ static struct llc_sap *llc_sap_alloc(void)
*/
static void llc_add_sap(struct llc_sap *sap)
{
- write_lock_bh(&llc_sap_list_lock);
list_add_tail(&sap->node, &llc_sap_list);
- write_unlock_bh(&llc_sap_list_lock);
}
/**
@@ -70,11 +69,25 @@ static void llc_del_sap(struct llc_sap *sap)
write_unlock_bh(&llc_sap_list_lock);
}
+static struct llc_sap *__llc_sap_find(unsigned char sap_value)
+{
+ struct llc_sap* sap;
+
+ list_for_each_entry(sap, &llc_sap_list, node)
+ if (sap->laddr.lsap == sap_value)
+ goto out;
+ sap = NULL;
+out:
+ return sap;
+}
+
/**
* llc_sap_find - searchs a SAP in station
* @sap_value: sap to be found
*
* Searchs for a sap in the sap list of the LLC's station upon the sap ID.
+ * If the sap is found it will be refcounted and the user will have to do
+ * a llc_sap_put after use.
* Returns the sap or %NULL if not found.
*/
struct llc_sap *llc_sap_find(unsigned char sap_value)
@@ -82,11 +95,9 @@ struct llc_sap *llc_sap_find(unsigned char sap_value)
struct llc_sap* sap;
read_lock_bh(&llc_sap_list_lock);
- list_for_each_entry(sap, &llc_sap_list, node)
- if (sap->laddr.lsap == sap_value)
- goto out;
- sap = NULL;
-out:
+ sap = __llc_sap_find(sap_value);
+ if (sap)
+ llc_sap_hold(sap);
read_unlock_bh(&llc_sap_list_lock);
return sap;
}
@@ -106,19 +117,20 @@ struct llc_sap *llc_sap_open(unsigned char lsap,
struct packet_type *pt,
struct net_device *orig_dev))
{
- struct llc_sap *sap = llc_sap_find(lsap);
+ struct llc_sap *sap = NULL;
- if (sap) { /* SAP already exists */
- sap = NULL;
+ write_lock_bh(&llc_sap_list_lock);
+ if (__llc_sap_find(lsap)) /* SAP already exists */
goto out;
- }
sap = llc_sap_alloc();
if (!sap)
goto out;
sap->laddr.lsap = lsap;
sap->rcv_func = func;
+ llc_sap_hold(sap);
llc_add_sap(sap);
out:
+ write_unlock_bh(&llc_sap_list_lock);
return sap;
}
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index 0f84f66018e4..ba90f7f0801a 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -47,14 +47,11 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
int rc = -ECONNABORTED;
struct llc_sock *llc = llc_sk(sk);
- if (llc->state == LLC_CONN_STATE_ADM)
+ if (unlikely(llc->state == LLC_CONN_STATE_ADM))
goto out;
rc = -EBUSY;
- if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */
- llc->failed_data_req = 1;
- goto out;
- }
- if (llc->p_flag) {
+ if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
+ llc->p_flag)) {
llc->failed_data_req = 1;
goto out;
}
@@ -110,6 +107,7 @@ int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->prim = LLC_CONN_PRIM;
ev->prim_type = LLC_PRIM_TYPE_REQ;
+ skb_set_owner_w(skb, sk);
rc = llc_conn_state_process(sk, skb);
}
out_put:
@@ -144,6 +142,7 @@ int llc_send_disc(struct sock *sk)
skb = alloc_skb(0, GFP_ATOMIC);
if (!skb)
goto out;
+ skb_set_owner_w(skb, sk);
sk->sk_state = TCP_CLOSING;
ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_PRIM;
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index 13b46240b7a1..8f3addf0724c 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -99,15 +99,19 @@ out:
static inline int llc_fixup_skb(struct sk_buff *skb)
{
u8 llc_len = 2;
- struct llc_pdu_sn *pdu;
+ struct llc_pdu_un *pdu;
- if (!pskb_may_pull(skb, sizeof(*pdu)))
+ if (unlikely(!pskb_may_pull(skb, sizeof(*pdu))))
return 0;
- pdu = (struct llc_pdu_sn *)skb->data;
+ pdu = (struct llc_pdu_un *)skb->data;
if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
llc_len = 1;
llc_len += 2;
+
+ if (unlikely(!pskb_may_pull(skb, llc_len)))
+ return 0;
+
skb->h.raw += llc_len;
skb_pull(skb, llc_len);
if (skb->protocol == htons(ETH_P_802_2)) {
@@ -166,17 +170,22 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
*/
if (sap->rcv_func) {
sap->rcv_func(skb, dev, pt, orig_dev);
- goto out;
+ goto out_put;
}
dest = llc_pdu_type(skb);
if (unlikely(!dest || !llc_type_handlers[dest - 1]))
- goto drop;
+ goto drop_put;
llc_type_handlers[dest - 1](sap, skb);
+out_put:
+ llc_sap_put(sap);
out:
return 0;
drop:
kfree_skb(skb);
goto out;
+drop_put:
+ kfree_skb(skb);
+ goto out_put;
handle_station:
if (!llc_station_handler)
goto drop;
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c
index ab5784cf163e..b4d55b6abb67 100644
--- a/net/llc/llc_output.c
+++ b/net/llc/llc_output.c
@@ -98,7 +98,7 @@ int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
dsap, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
- if (!rc)
+ if (likely(!rc))
rc = dev_queue_xmit(skb);
return rc;
}
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
index 36e8db3fa1a2..bd531cb235a7 100644
--- a/net/llc/llc_proc.c
+++ b/net/llc/llc_proc.c
@@ -134,7 +134,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)
llc_ui_format_mac(seq, llc->daddr.mac);
seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
atomic_read(&sk->sk_wmem_alloc),
- atomic_read(&sk->sk_rmem_alloc),
+ atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq,
sk->sk_state,
sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1,
llc->link);
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
index ed8ba7de6122..bb3580fb8cfe 100644
--- a/net/llc/llc_s_ac.c
+++ b/net/llc/llc_s_ac.c
@@ -58,7 +58,7 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
ev->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
- if (!rc)
+ if (likely(!rc))
rc = dev_queue_xmit(skb);
return rc;
}
@@ -81,7 +81,7 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
ev->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
- if (!rc)
+ if (likely(!rc))
rc = dev_queue_xmit(skb);
return rc;
}
@@ -103,15 +103,14 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap);
- nskb = llc_alloc_frame();
+ nskb = llc_alloc_frame(NULL, skb->dev);
if (!nskb)
goto out;
- nskb->dev = skb->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
LLC_PDU_RSP);
llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
- if (!rc)
+ if (likely(!rc))
rc = dev_queue_xmit(nskb);
out:
return rc;
@@ -135,7 +134,7 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
ev->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_test_cmd(skb);
rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
- if (!rc)
+ if (likely(!rc))
rc = dev_queue_xmit(skb);
return rc;
}
@@ -149,15 +148,14 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap);
- nskb = llc_alloc_frame();
+ nskb = llc_alloc_frame(NULL, skb->dev);
if (!nskb)
goto out;
- nskb->dev = skb->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
LLC_PDU_RSP);
llc_pdu_init_as_test_rsp(nskb, skb);
rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
- if (!rc)
+ if (likely(!rc))
rc = dev_queue_xmit(nskb);
out:
return rc;
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 34228ef14985..4029ceee9b91 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -26,11 +26,12 @@
/**
* llc_alloc_frame - allocates sk_buff for frame
+ * @dev: network device this skb will be sent over
*
* Allocates an sk_buff for frame and initializes sk_buff fields.
* Returns allocated skb or %NULL when out of memory.
*/
-struct sk_buff *llc_alloc_frame(void)
+struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev)
{
struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
@@ -38,18 +39,23 @@ struct sk_buff *llc_alloc_frame(void)
skb_reserve(skb, 50);
skb->nh.raw = skb->h.raw = skb->data;
skb->protocol = htons(ETH_P_802_2);
- skb->dev = dev_base->next;
+ skb->dev = dev;
skb->mac.raw = skb->head;
+ if (sk != NULL)
+ skb_set_owner_w(skb, sk);
}
return skb;
}
-void llc_save_primitive(struct sk_buff* skb, u8 prim)
+void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
{
- struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
+ struct sockaddr_llc *addr;
+ if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */
+ return;
/* save primitive for use by the user. */
- addr->sllc_family = skb->sk->sk_family;
+ addr = llc_ui_skb_cb(skb);
+ addr->sllc_family = sk->sk_family;
addr->sllc_arphrd = skb->dev->type;
addr->sllc_test = prim == LLC_TEST_PRIM;
addr->sllc_xid = prim == LLC_XID_PRIM;
@@ -189,7 +195,7 @@ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
if (skb->sk->sk_state == TCP_LISTEN)
kfree_skb(skb);
else {
- llc_save_primitive(skb, ev->prim);
+ llc_save_primitive(skb->sk, skb, ev->prim);
/* queue skb to the user. */
if (sock_queue_rcv_skb(skb->sk, skb))
@@ -308,7 +314,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
sk = llc_lookup_dgram(sap, &laddr);
if (sk) {
- skb->sk = sk;
+ skb_set_owner_r(skb, sk);
llc_sap_rcv(sap, skb);
sock_put(sk);
} else
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c
index 8fe48a24bad5..f37dbf8ef126 100644
--- a/net/llc/llc_station.c
+++ b/net/llc/llc_station.c
@@ -50,6 +50,10 @@ struct llc_station {
struct sk_buff_head mac_pdu_q;
};
+#define LLC_STATION_ACK_TIME (3 * HZ)
+
+int sysctl_llc_station_ack_timeout = LLC_STATION_ACK_TIME;
+
/* Types of events (possible values in 'ev->type') */
#define LLC_STATION_EV_TYPE_SIMPLE 1
#define LLC_STATION_EV_TYPE_CONDITION 2
@@ -218,7 +222,8 @@ static void llc_station_send_pdu(struct sk_buff *skb)
static int llc_station_ac_start_ack_timer(struct sk_buff *skb)
{
- mod_timer(&llc_main_station.ack_timer, jiffies + LLC_ACK_TIME * HZ);
+ mod_timer(&llc_main_station.ack_timer,
+ jiffies + sysctl_llc_station_ack_timeout);
return 0;
}
@@ -249,14 +254,14 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
{
int rc = 1;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
if (!nskb)
goto out;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_station_send_pdu(nskb);
out:
@@ -270,18 +275,17 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
{
u8 mac_da[ETH_ALEN], dsap;
int rc = 1;
- struct sk_buff* nskb = llc_alloc_frame();
+ struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev);
if (!nskb)
goto out;
rc = 0;
- nskb->dev = skb->dev;
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_ssap(skb, &dsap);
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_station_send_pdu(nskb);
out:
@@ -295,18 +299,17 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
{
u8 mac_da[ETH_ALEN], dsap;
int rc = 1;
- struct sk_buff *nskb = llc_alloc_frame();
+ struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
if (!nskb)
goto out;
rc = 0;
- nskb->dev = skb->dev;
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_ssap(skb, &dsap);
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
llc_pdu_init_as_test_rsp(nskb, skb);
rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
- if (rc)
+ if (unlikely(rc))
goto free;
llc_station_send_pdu(nskb);
out:
@@ -689,7 +692,8 @@ int __init llc_station_init(void)
init_timer(&llc_main_station.ack_timer);
llc_main_station.ack_timer.data = (unsigned long)&llc_main_station;
llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
-
+ llc_main_station.ack_timer.expires = jiffies +
+ sysctl_llc_station_ack_timeout;
skb = alloc_skb(0, GFP_ATOMIC);
if (!skb)
goto out;
@@ -697,7 +701,6 @@ int __init llc_station_init(void)
llc_set_station_handler(llc_station_rcv);
ev = llc_station_ev(skb);
memset(ev, 0, sizeof(*ev));
- llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
llc_main_station.maximum_retry = 1;
llc_main_station.state = LLC_STATION_STATE_DOWN;
ev->type = LLC_STATION_EV_TYPE_SIMPLE;
diff --git a/net/llc/sysctl_net_llc.c b/net/llc/sysctl_net_llc.c
new file mode 100644
index 000000000000..d1eaddb13633
--- /dev/null
+++ b/net/llc/sysctl_net_llc.c
@@ -0,0 +1,131 @@
+/*
+ * sysctl_net_llc.c: sysctl interface to LLC net subsystem.
+ *
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <net/llc.h>
+
+#ifndef CONFIG_SYSCTL
+#error This file should not be compiled without CONFIG_SYSCTL defined
+#endif
+
+static struct ctl_table llc2_timeout_table[] = {
+ {
+ .ctl_name = NET_LLC2_ACK_TIMEOUT,
+ .procname = "ack",
+ .data = &sysctl_llc2_ack_timeout,
+ .maxlen = sizeof(long),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ .strategy = &sysctl_jiffies,
+ },
+ {
+ .ctl_name = NET_LLC2_BUSY_TIMEOUT,
+ .procname = "busy",
+ .data = &sysctl_llc2_busy_timeout,
+ .maxlen = sizeof(long),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ .strategy = &sysctl_jiffies,
+ },
+ {
+ .ctl_name = NET_LLC2_P_TIMEOUT,
+ .procname = "p",
+ .data = &sysctl_llc2_p_timeout,
+ .maxlen = sizeof(long),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ .strategy = &sysctl_jiffies,
+ },
+ {
+ .ctl_name = NET_LLC2_REJ_TIMEOUT,
+ .procname = "rej",
+ .data = &sysctl_llc2_rej_timeout,
+ .maxlen = sizeof(long),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ .strategy = &sysctl_jiffies,
+ },
+ { 0 },
+};
+
+static struct ctl_table llc_station_table[] = {
+ {
+ .ctl_name = NET_LLC_STATION_ACK_TIMEOUT,
+ .procname = "ack_timeout",
+ .data = &sysctl_llc_station_ack_timeout,
+ .maxlen = sizeof(long),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ .strategy = &sysctl_jiffies,
+ },
+ { 0 },
+};
+
+static struct ctl_table llc2_dir_timeout_table[] = {
+ {
+ .ctl_name = NET_LLC2,
+ .procname = "timeout",
+ .mode = 0555,
+ .child = llc2_timeout_table,
+ },
+ { 0 },
+};
+
+static struct ctl_table llc_table[] = {
+ {
+ .ctl_name = NET_LLC2,
+ .procname = "llc2",
+ .mode = 0555,
+ .child = llc2_dir_timeout_table,
+ },
+ {
+ .ctl_name = NET_LLC_STATION,
+ .procname = "station",
+ .mode = 0555,
+ .child = llc_station_table,
+ },
+ { 0 },
+};
+
+static struct ctl_table llc_dir_table[] = {
+ {
+ .ctl_name = NET_LLC,
+ .procname = "llc",
+ .mode = 0555,
+ .child = llc_table,
+ },
+ { 0 },
+};
+
+static struct ctl_table llc_root_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = llc_dir_table,
+ },
+ { 0 },
+};
+
+static struct ctl_table_header *llc_table_header;
+
+int __init llc_sysctl_init(void)
+{
+ llc_table_header = register_sysctl_table(llc_root_table, 1);
+
+ return llc_table_header ? 0 : -ENOMEM;
+}
+
+void llc_sysctl_exit(void)
+{
+ if (llc_table_header) {
+ unregister_sysctl_table(llc_table_header);
+ llc_table_header = NULL;
+ }
+}
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 49a3900e3d32..4bc27a6334c1 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -133,7 +133,7 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
memset(tb, 0, sizeof(struct nfattr *) * maxattr);
while (NFA_OK(nfa, len)) {
- unsigned flavor = nfa->nfa_type;
+ unsigned flavor = NFA_TYPE(nfa);
if (flavor && flavor <= maxattr)
tb[flavor-1] = nfa;
nfa = NFA_NEXT(nfa, len);
@@ -177,7 +177,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
while (NFA_OK(attr, attrlen)) {
- unsigned flavor = attr->nfa_type;
+ unsigned flavor = NFA_TYPE(attr);
if (flavor) {
if (flavor > attr_count)
return -EINVAL;
@@ -195,7 +195,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
{
- int allocation = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ gfp_t allocation = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
int err = 0;
NETLINK_CB(skb).dst_group = group;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index ff5601ceedcb..efcd10f996ba 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -494,8 +494,8 @@ __build_packet_message(struct nfulnl_instance *inst,
if (skb->tstamp.off_sec) {
struct nfulnl_msg_packet_timestamp ts;
- ts.sec = cpu_to_be64(skb_tv_base.tv_sec + skb->tstamp.off_sec);
- ts.usec = cpu_to_be64(skb_tv_base.tv_usec + skb->tstamp.off_usec);
+ ts.sec = cpu_to_be64(skb->tstamp.off_sec);
+ ts.usec = cpu_to_be64(skb->tstamp.off_usec);
NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index f81fe8c52e99..eaa44c49567b 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -492,8 +492,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
if (entry->skb->tstamp.off_sec) {
struct nfqnl_msg_packet_timestamp ts;
- ts.sec = cpu_to_be64(skb_tv_base.tv_sec + entry->skb->tstamp.off_sec);
- ts.usec = cpu_to_be64(skb_tv_base.tv_usec + entry->skb->tstamp.off_usec);
+ ts.sec = cpu_to_be64(entry->skb->tstamp.off_sec);
+ ts.usec = cpu_to_be64(entry->skb->tstamp.off_usec);
NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index a64e1d5ce3ca..5ca283537bc6 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -740,11 +740,8 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
{
- struct netlink_sock *nlk;
int len = skb->len;
- nlk = nlk_sk(sk);
-
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, len);
sock_put(sk);
@@ -758,7 +755,7 @@ void netlink_detachskb(struct sock *sk, struct sk_buff *skb)
}
static inline struct sk_buff *netlink_trim(struct sk_buff *skb,
- unsigned int __nocast allocation)
+ gfp_t allocation)
{
int delta;
@@ -827,7 +824,7 @@ struct netlink_broadcast_data {
int failure;
int congested;
int delivered;
- unsigned int allocation;
+ gfp_t allocation;
struct sk_buff *skb, *skb2;
};
@@ -880,7 +877,7 @@ out:
}
int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
- u32 group, unsigned int __nocast allocation)
+ u32 group, gfp_t allocation)
{
struct netlink_broadcast_data info;
struct hlist_node *node;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index f4578c759ffc..e5d82d711cae 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -56,6 +56,7 @@ int sysctl_netrom_transport_requested_window_size = NR_DEFAULT_WINDOW;
int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE;
int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING;
int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS;
+int sysctl_netrom_reset_circuit = NR_DEFAULT_RESET;
static unsigned short circuit = 0x101;
@@ -908,17 +909,17 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
if (frametype != NR_CONNREQ) {
/*
* Here it would be nice to be able to send a reset but
- * NET/ROM doesn't have one. The following hack would
- * have been a way to extend the protocol but apparently
- * it kills BPQ boxes... :-(
+ * NET/ROM doesn't have one. We've tried to extend the protocol
+ * by sending NR_CONNACK | NR_CHOKE_FLAGS replies but that
+ * apparently kills BPQ boxes... :-(
+ * So now we try to follow the established behaviour of
+ * G8PZT's Xrouter which is sending packets with command type 7
+ * as an extension of the protocol.
*/
-#if 0
- /*
- * Never reply to a CONNACK/CHOKE.
- */
- if (frametype != NR_CONNACK || flags != NR_CHOKE_FLAG)
- nr_transmit_refusal(skb, 1);
-#endif
+ if (sysctl_netrom_reset_circuit &&
+ (frametype != NR_RESET || flags != 0))
+ nr_transmit_reset(skb, 1);
+
return 0;
}
@@ -1187,9 +1188,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
case SIOCGSTAMP:
- ret = -EINVAL;
- if (sk != NULL)
- ret = sock_get_timestamp(sk, argp);
+ ret = sock_get_timestamp(sk, argp);
release_sock(sk);
return ret;
@@ -1393,8 +1392,7 @@ static int __init nr_proto_init(void)
struct net_device *dev;
sprintf(name, "nr%d", i);
- dev = alloc_netdev(sizeof(struct net_device_stats), name,
- nr_setup);
+ dev = alloc_netdev(sizeof(struct nr_private), name, nr_setup);
if (!dev) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n");
goto fail;
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 263da4c26494..509afddae569 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -47,7 +47,7 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
struct net_device_stats *stats = netdev_priv(dev);
if (!netif_running(dev)) {
- stats->rx_errors++;
+ stats->rx_dropped++;
return 0;
}
@@ -58,7 +58,7 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
/* Spoof incoming device */
skb->dev = dev;
- skb->h.raw = skb->data;
+ skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
skb->pkt_type = PACKET_HOST;
@@ -71,15 +71,10 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
static int nr_rebuild_header(struct sk_buff *skb)
{
- struct net_device *dev = skb->dev;
- struct net_device_stats *stats = netdev_priv(dev);
- struct sk_buff *skbn;
unsigned char *bp = skb->data;
- int len;
- if (arp_find(bp + 7, skb)) {
+ if (arp_find(bp + 7, skb))
return 1;
- }
bp[6] &= ~AX25_CBIT;
bp[6] &= ~AX25_EBIT;
@@ -90,27 +85,7 @@ static int nr_rebuild_header(struct sk_buff *skb)
bp[6] |= AX25_EBIT;
bp[6] |= AX25_SSSID_SPARE;
- if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
- kfree_skb(skb);
- return 1;
- }
-
- if (skb->sk != NULL)
- skb_set_owner_w(skbn, skb->sk);
-
- kfree_skb(skb);
-
- len = skbn->len;
-
- if (!nr_route_frame(skbn, NULL)) {
- kfree_skb(skbn);
- stats->tx_errors++;
- }
-
- stats->tx_packets++;
- stats->tx_bytes += len;
-
- return 1;
+ return 0;
}
#else
@@ -185,15 +160,27 @@ static int nr_close(struct net_device *dev)
static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct net_device_stats *stats = netdev_priv(dev);
- dev_kfree_skb(skb);
- stats->tx_errors++;
+ struct nr_private *nr = netdev_priv(dev);
+ struct net_device_stats *stats = &nr->stats;
+ unsigned int len = skb->len;
+
+ if (!nr_route_frame(skb, NULL)) {
+ kfree_skb(skb);
+ stats->tx_errors++;
+ return 0;
+ }
+
+ stats->tx_packets++;
+ stats->tx_bytes += len;
+
return 0;
}
static struct net_device_stats *nr_get_stats(struct net_device *dev)
{
- return netdev_priv(dev);
+ struct nr_private *nr = netdev_priv(dev);
+
+ return &nr->stats;
}
void nr_setup(struct net_device *dev)
@@ -208,12 +195,11 @@ void nr_setup(struct net_device *dev)
dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
dev->addr_len = AX25_ADDR_LEN;
dev->type = ARPHRD_NETROM;
- dev->tx_queue_len = 40;
dev->rebuild_header = nr_rebuild_header;
dev->set_mac_address = nr_set_mac_address;
/* New-style flags. */
- dev->flags = 0;
+ dev->flags = IFF_NOARP;
dev->get_stats = nr_get_stats;
}
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index 64b81a796907..004e8599b8fe 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -98,6 +98,11 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
nr_disconnect(sk, ECONNREFUSED);
break;
+ case NR_RESET:
+ if (sysctl_netrom_reset_circuit);
+ nr_disconnect(sk, ECONNRESET);
+ break;
+
default:
break;
}
@@ -124,6 +129,11 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
nr_disconnect(sk, 0);
break;
+ case NR_RESET:
+ if (sysctl_netrom_reset_circuit);
+ nr_disconnect(sk, ECONNRESET);
+ break;
+
default:
break;
}
@@ -254,6 +264,11 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
}
break;
+ case NR_RESET:
+ if (sysctl_netrom_reset_circuit);
+ nr_disconnect(sk, ECONNRESET);
+ break;
+
default:
break;
}
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
index 165b2abce110..e856ae1b360a 100644
--- a/net/netrom/nr_loopback.c
+++ b/net/netrom/nr_loopback.c
@@ -17,7 +17,7 @@
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/netrom/nr_subr.c b/net/netrom/nr_subr.c
index 587bed2674bf..bcb9946b4f56 100644
--- a/net/netrom/nr_subr.c
+++ b/net/netrom/nr_subr.c
@@ -210,10 +210,9 @@ void nr_write_internal(struct sock *sk, int frametype)
}
/*
- * This routine is called when a Connect Acknowledge with the Choke Flag
- * set is needed to refuse a connection.
+ * This routine is called to send an error reply.
*/
-void nr_transmit_refusal(struct sk_buff *skb, int mine)
+void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
{
struct sk_buff *skbn;
unsigned char *dptr;
@@ -254,7 +253,7 @@ void nr_transmit_refusal(struct sk_buff *skb, int mine)
*dptr++ = 0;
}
- *dptr++ = NR_CONNACK | NR_CHOKE_FLAG;
+ *dptr++ = cmdflags;
*dptr++ = 0;
if (!nr_route_frame(skbn, NULL))
diff --git a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c
index c9ed50382ea7..6bb8dda849dc 100644
--- a/net/netrom/sysctl_net_netrom.c
+++ b/net/netrom/sysctl_net_netrom.c
@@ -30,6 +30,7 @@ static int min_idle[] = {0 * HZ};
static int max_idle[] = {65535 * HZ};
static int min_route[] = {0}, max_route[] = {1};
static int min_fails[] = {1}, max_fails[] = {10};
+static int min_reset[] = {0}, max_reset[] = {1};
static struct ctl_table_header *nr_table_header;
@@ -155,6 +156,17 @@ static ctl_table nr_table[] = {
.extra1 = &min_fails,
.extra2 = &max_fails
},
+ {
+ .ctl_name = NET_NETROM_RESET,
+ .procname = "reset",
+ .data = &sysctl_netrom_reset_circuit,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &min_reset,
+ .extra2 = &max_reset
+ },
{ .ctl_name = 0 }
};
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 8690f171c1ef..499ae3df4a44 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -36,6 +36,11 @@
* Michal Ostrowski : Module initialization cleanup.
* Ulises Alonso : Frame number limit removal and
* packet_set_ring memory leak.
+ * Eric Biederman : Allow for > 8 byte hardware addresses.
+ * The convention is that longer addresses
+ * will simply extend the hardware address
+ * byte arrays at the end of sockaddr_ll
+ * and packet_mreq.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -161,7 +166,17 @@ struct packet_mclist
int count;
unsigned short type;
unsigned short alen;
- unsigned char addr[8];
+ unsigned char addr[MAX_ADDR_LEN];
+};
+/* identical to struct packet_mreq except it has
+ * a longer address field.
+ */
+struct packet_mreq_max
+{
+ int mr_ifindex;
+ unsigned short mr_type;
+ unsigned short mr_alen;
+ unsigned char mr_address[MAX_ADDR_LEN];
};
#endif
#ifdef CONFIG_PACKET_MMAP
@@ -639,8 +654,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
__net_timestamp(skb);
sock_enable_timestamp(sk);
}
- h->tp_sec = skb_tv_base.tv_sec + skb->tstamp.off_sec;
- h->tp_usec = skb_tv_base.tv_usec + skb->tstamp.off_usec;
+ h->tp_sec = skb->tstamp.off_sec;
+ h->tp_usec = skb->tstamp.off_usec;
sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
sll->sll_halen = 0;
@@ -716,6 +731,8 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
err = -EINVAL;
if (msg->msg_namelen < sizeof(struct sockaddr_ll))
goto out;
+ if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
+ goto out;
ifindex = saddr->sll_ifindex;
proto = saddr->sll_protocol;
addr = saddr->sll_addr;
@@ -1045,6 +1062,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sk_buff *skb;
int copied, err;
+ struct sockaddr_ll *sll;
err = -EINVAL;
if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
@@ -1057,16 +1075,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
#endif
/*
- * If the address length field is there to be filled in, we fill
- * it in now.
- */
-
- if (sock->type == SOCK_PACKET)
- msg->msg_namelen = sizeof(struct sockaddr_pkt);
- else
- msg->msg_namelen = sizeof(struct sockaddr_ll);
-
- /*
* Call the generic datagram receiver. This handles all sorts
* of horrible races and re-entrancy so we can forget about it
* in the protocol layers.
@@ -1087,6 +1095,17 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
goto out;
/*
+ * If the address length field is there to be filled in, we fill
+ * it in now.
+ */
+
+ sll = (struct sockaddr_ll*)skb->cb;
+ if (sock->type == SOCK_PACKET)
+ msg->msg_namelen = sizeof(struct sockaddr_pkt);
+ else
+ msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
+
+ /*
* You lose any data beyond the buffer you gave. If it worries a
* user program they can ask the device for its MTU anyway.
*/
@@ -1166,7 +1185,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */
sll->sll_halen = 0;
}
- *uaddr_len = sizeof(*sll);
+ *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
return 0;
}
@@ -1199,7 +1218,7 @@ static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, i
}
}
-static int packet_mc_add(struct sock *sk, struct packet_mreq *mreq)
+static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
{
struct packet_sock *po = pkt_sk(sk);
struct packet_mclist *ml, *i;
@@ -1249,7 +1268,7 @@ done:
return err;
}
-static int packet_mc_drop(struct sock *sk, struct packet_mreq *mreq)
+static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
{
struct packet_mclist *ml, **mlp;
@@ -1315,11 +1334,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
case PACKET_ADD_MEMBERSHIP:
case PACKET_DROP_MEMBERSHIP:
{
- struct packet_mreq mreq;
- if (optlen<sizeof(mreq))
+ struct packet_mreq_max mreq;
+ int len = optlen;
+ memset(&mreq, 0, sizeof(mreq));
+ if (len < sizeof(struct packet_mreq))
return -EINVAL;
- if (copy_from_user(&mreq,optval,sizeof(mreq)))
+ if (len > sizeof(mreq))
+ len = sizeof(mreq);
+ if (copy_from_user(&mreq,optval,len))
return -EFAULT;
+ if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
+ return -EINVAL;
if (optname == PACKET_ADD_MEMBERSHIP)
ret = packet_mc_add(sk, &mreq);
else
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 3077878ed4f0..829fdbc4400b 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1243,7 +1243,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- return put_user(amount, (unsigned int __user *)argp);
+ return put_user(amount, (unsigned int __user *) argp);
}
case TIOCINQ: {
@@ -1252,13 +1252,11 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
/* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
- return put_user(amount, (unsigned int __user *)argp);
+ return put_user(amount, (unsigned int __user *) argp);
}
case SIOCGSTAMP:
- if (sk != NULL)
- return sock_get_timestamp(sk, (struct timeval __user *)argp);
- return -EINVAL;
+ return sock_get_timestamp(sk, (struct timeval __user *) argp);
case SIOCGIFADDR:
case SIOCSIFADDR:
@@ -1474,22 +1472,25 @@ static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62
static int __init rose_proto_init(void)
{
int i;
- int rc = proto_register(&rose_proto, 0);
+ int rc;
+
+ if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) {
+ printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n");
+ rc = -EINVAL;
+ goto out;
+ }
+ rc = proto_register(&rose_proto, 0);
if (rc != 0)
goto out;
rose_callsign = null_ax25_address;
- if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) {
- printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n");
- return -1;
- }
-
dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL);
if (dev_rose == NULL) {
printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n");
- return -1;
+ rc = -ENOMEM;
+ goto out_proto_unregister;
}
memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device*));
@@ -1502,10 +1503,12 @@ static int __init rose_proto_init(void)
name, rose_setup);
if (!dev) {
printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n");
+ rc = -ENOMEM;
goto fail;
}
- if (register_netdev(dev)) {
- printk(KERN_ERR "ROSE: netdevice regeistration failed\n");
+ rc = register_netdev(dev);
+ if (rc) {
+ printk(KERN_ERR "ROSE: netdevice registration failed\n");
free_netdev(dev);
goto fail;
}
@@ -1538,8 +1541,9 @@ fail:
free_netdev(dev_rose[i]);
}
kfree(dev_rose);
+out_proto_unregister:
proto_unregister(&rose_proto);
- return -ENOMEM;
+ goto out;
}
module_init(rose_proto_init);
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index a8ed9a1d09f9..d297af737d10 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -149,6 +149,6 @@ void rose_setup(struct net_device *dev)
dev->set_mac_address = rose_set_mac_address;
/* New-style flags. */
- dev->flags = 0;
+ dev->flags = IFF_NOARP;
dev->get_stats = rose_get_stats;
}
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index e556d92c0bc4..b18fe5043019 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -727,7 +727,7 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
}
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
return -EINVAL;
- if (rose_route.ndigis > 8) /* No more than 8 digipeats */
+ if (rose_route.ndigis > AX25_MAX_DIGIS)
return -EINVAL;
err = rose_add_node(&rose_route, dev);
dev_put(dev);
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 02891ce2db37..36a77944622b 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -337,13 +337,13 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
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/rxrpc/call.c b/net/rxrpc/call.c
index 5cfd4cadee42..c4aeb7d40266 100644
--- a/net/rxrpc/call.c
+++ b/net/rxrpc/call.c
@@ -1923,7 +1923,7 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
size_t sioc,
struct kvec *siov,
u8 rxhdr_flags,
- int alloc_flags,
+ gfp_t alloc_flags,
int dup_data,
size_t *size_sent)
{
diff --git a/net/rxrpc/connection.c b/net/rxrpc/connection.c
index 61463c74f8cc..2ba14a75dbbe 100644
--- a/net/rxrpc/connection.c
+++ b/net/rxrpc/connection.c
@@ -522,7 +522,7 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
uint8_t type,
int dcount,
struct kvec diov[],
- int alloc_flags,
+ gfp_t alloc_flags,
struct rxrpc_message **_msg)
{
struct rxrpc_message *msg;
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 45d3bc0812c8..81510da31792 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -72,9 +72,11 @@ config NET_SCH_CLK_GETTIMEOFDAY
Choose this if you need a high resolution clock source but can't use
the CPU's cycle counter.
+# don't allow on SMP x86 because they can have unsynchronized TSCs.
+# gettimeofday is a good alternative
config NET_SCH_CLK_CPU
bool "CPU cycle counter"
- depends on X86_TSC || X86_64 || ALPHA || SPARC64 || PPC64 || IA64
+ depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64
help
Say Y here if you want to use the CPU's cycle counter as clock source.
This is a cheap and high resolution clock source, but on some
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 00eae5f9a01a..cf68a59fdc5a 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -393,10 +393,10 @@ META_COLLECTOR(int_sk_route_caps)
dst->value = skb->sk->sk_route_caps;
}
-META_COLLECTOR(int_sk_hashent)
+META_COLLECTOR(int_sk_hash)
{
SKIP_NONLOCAL(skb);
- dst->value = skb->sk->sk_hashent;
+ dst->value = skb->sk->sk_hash;
}
META_COLLECTOR(int_sk_lingertime)
@@ -515,7 +515,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
[META_ID(SK_FORWARD_ALLOCS)] = META_FUNC(int_sk_fwd_alloc),
[META_ID(SK_ALLOCS)] = META_FUNC(int_sk_alloc),
[META_ID(SK_ROUTE_CAPS)] = META_FUNC(int_sk_route_caps),
- [META_ID(SK_HASHENT)] = META_FUNC(int_sk_hashent),
+ [META_ID(SK_HASH)] = META_FUNC(int_sk_hash),
[META_ID(SK_LINGERTIME)] = META_FUNC(int_sk_lingertime),
[META_ID(SK_ACK_BACKLOG)] = META_FUNC(int_sk_ack_bl),
[META_ID(SK_MAX_ACK_BACKLOG)] = META_FUNC(int_sk_max_ack_bl),
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 737681cb9a92..31570b9a6e9a 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1194,7 +1194,7 @@ EXPORT_SYMBOL(psched_time_base);
* 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/sctp/associola.c b/net/sctp/associola.c
index 5b24ae0650d3..12b0f582a66b 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -71,7 +71,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
const struct sctp_endpoint *ep,
const struct sock *sk,
sctp_scope_t scope,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_sock *sp;
int i;
@@ -273,7 +273,7 @@ fail_init:
struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
const struct sock *sk,
sctp_scope_t scope,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_association *asoc;
@@ -479,7 +479,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
/* Add a transport address to an association. */
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
const union sctp_addr *addr,
- const unsigned int __nocast gfp,
+ const gfp_t gfp,
const int peer_state)
{
struct sctp_transport *peer;
@@ -1231,7 +1231,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len)
* local endpoint and the remote peer.
*/
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
sctp_scope_t scope;
int flags;
@@ -1254,7 +1254,7 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
/* Build the association's bind address list from the cookie. */
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
struct sctp_cookie *cookie,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length);
int var_size3 = cookie->raw_addr_list_len;
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index f71549710f2e..2b962627f631 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -53,7 +53,7 @@
/* Forward declarations for internal helpers. */
static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *,
- sctp_scope_t scope, unsigned int __nocast gfp,
+ sctp_scope_t scope, gfp_t gfp,
int flags);
static void sctp_bind_addr_clean(struct sctp_bind_addr *);
@@ -64,7 +64,7 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *);
*/
int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src,
- sctp_scope_t scope, unsigned int __nocast gfp,
+ sctp_scope_t scope, gfp_t gfp,
int flags)
{
struct sctp_sockaddr_entry *addr;
@@ -146,7 +146,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp)
/* Add an address to the bind address list in the SCTP_bind_addr structure. */
int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_sockaddr_entry *addr;
@@ -200,7 +200,7 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
*/
union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
int *addrs_len,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
union sctp_params addrparms;
union sctp_params retval;
@@ -252,7 +252,7 @@ end_raw:
* address parameters).
*/
int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
- int addrs_len, __u16 port, unsigned int __nocast gfp)
+ int addrs_len, __u16 port, gfp_t gfp)
{
union sctp_addr_param *rawaddr;
struct sctp_paramhdr *param;
@@ -350,7 +350,7 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
/* Copy out addresses from the global local address list. */
static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
union sctp_addr *addr,
- sctp_scope_t scope, unsigned int __nocast gfp,
+ sctp_scope_t scope, gfp_t gfp,
int flags)
{
int error = 0;
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 61da2937e641..83ef411772f4 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -62,7 +62,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
}
/* Allocate and initialize datamsg. */
-SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(unsigned int __nocast gfp)
+SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp)
{
struct sctp_datamsg *msg;
msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index e22ccd655965..96984f7a2d69 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -68,7 +68,7 @@ static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep);
*/
static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
struct sock *sk,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_sock *sp = sctp_sk(sk);
memset(ep, 0, sizeof(struct sctp_endpoint));
@@ -138,8 +138,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* Create a sctp_endpoint with all that boring stuff initialized.
* Returns NULL if there isn't enough memory.
*/
-struct sctp_endpoint *sctp_endpoint_new(struct sock *sk,
- unsigned int __nocast gfp)
+struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, gfp_t gfp)
{
struct sctp_endpoint *ep;
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index b74f7772b576..6e4dc28874d7 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -69,9 +69,7 @@ fold_field(void *mib[], int nr)
unsigned long res = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
res +=
*((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
sizeof (unsigned long) * nr));
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index e7025be77691..26de4d3e1bd9 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -147,7 +147,7 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist,
struct sctp_sockaddr_entry *addr;
rcu_read_lock();
- if ((in_dev = __in_dev_get(dev)) == NULL) {
+ if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
rcu_read_unlock();
return;
}
@@ -219,7 +219,7 @@ static void sctp_free_local_addr_list(void)
/* Copy the local addresses which are valid for 'scope' into 'bp'. */
int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
- unsigned int __nocast gfp, int copy_flags)
+ gfp_t gfp, int copy_flags)
{
struct sctp_sockaddr_entry *addr;
int error = 0;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 3868a8d70cc0..10e82ec2ebd3 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -78,7 +78,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
static int sctp_process_param(struct sctp_association *asoc,
union sctp_params param,
const union sctp_addr *peer_addr,
- unsigned int __nocast gfp);
+ gfp_t gfp);
/* What was the inbound interface for this chunk? */
int sctp_chunk_iif(const struct sctp_chunk *chunk)
@@ -174,7 +174,7 @@ void sctp_init_cause(struct sctp_chunk *chunk, __u16 cause_code,
*/
struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
const struct sctp_bind_addr *bp,
- unsigned int __nocast gfp, int vparam_len)
+ gfp_t gfp, int vparam_len)
{
sctp_inithdr_t init;
union sctp_params addrs;
@@ -261,7 +261,7 @@ nodata:
struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
- unsigned int __nocast gfp, int unkparam_len)
+ gfp_t gfp, int unkparam_len)
{
sctp_inithdr_t initack;
struct sctp_chunk *retval;
@@ -1234,7 +1234,7 @@ void sctp_chunk_assign_tsn(struct sctp_chunk *chunk)
/* Create a CLOSED association to use with an incoming packet. */
struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_association *asoc;
struct sk_buff *skb;
@@ -1349,7 +1349,7 @@ nodata:
struct sctp_association *sctp_unpack_cookie(
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
- struct sctp_chunk *chunk, unsigned int __nocast gfp,
+ struct sctp_chunk *chunk, gfp_t gfp,
int *error, struct sctp_chunk **errp)
{
struct sctp_association *retval = NULL;
@@ -1814,7 +1814,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
*/
int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
const union sctp_addr *peer_addr,
- sctp_init_chunk_t *peer_init, unsigned int __nocast gfp)
+ sctp_init_chunk_t *peer_init, gfp_t gfp)
{
union sctp_params param;
struct sctp_transport *transport;
@@ -1985,7 +1985,7 @@ nomem:
static int sctp_process_param(struct sctp_association *asoc,
union sctp_params param,
const union sctp_addr *peer_addr,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
union sctp_addr addr;
int i;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 39c970b5b198..f84173ea8ec1 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -63,7 +63,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
void *event_arg,
sctp_disposition_t status,
sctp_cmd_seq_t *commands,
- unsigned int __nocast gfp);
+ gfp_t gfp);
static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
sctp_state_t state,
struct sctp_endpoint *ep,
@@ -71,7 +71,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
void *event_arg,
sctp_disposition_t status,
sctp_cmd_seq_t *commands,
- unsigned int __nocast gfp);
+ gfp_t gfp);
/********************************************************************
* Helper functions
@@ -498,7 +498,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_init_chunk_t *peer_init,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
int error;
@@ -853,7 +853,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
struct sctp_endpoint *ep,
struct sctp_association *asoc,
void *event_arg,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
sctp_cmd_seq_t commands;
const sctp_sm_table_entry_t *state_fn;
@@ -898,7 +898,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
void *event_arg,
sctp_disposition_t status,
sctp_cmd_seq_t *commands,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
int error;
@@ -986,7 +986,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
void *event_arg,
sctp_disposition_t status,
sctp_cmd_seq_t *commands,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
int error = 0;
int force;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 86073df418f5..505c7de10c50 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2414,6 +2414,17 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
chunk->subh.shutdown_hdr = sdh;
+ /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
+ * When a peer sends a SHUTDOWN, SCTP delivers this notification to
+ * inform the application that it should cease sending data.
+ */
+ ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);
+ if (!ev) {
+ disposition = SCTP_DISPOSITION_NOMEM;
+ goto out;
+ }
+ sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
+
/* Upon the reception of the SHUTDOWN, the peer endpoint shall
* - enter the SHUTDOWN-RECEIVED state,
* - stop accepting new data from its SCTP user
@@ -2439,17 +2450,6 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
SCTP_U32(chunk->subh.shutdown_hdr->cum_tsn_ack));
- /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
- * When a peer sends a SHUTDOWN, SCTP delivers this notification to
- * inform the application that it should cease sending data.
- */
- ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);
- if (!ev) {
- disposition = SCTP_DISPOSITION_NOMEM;
- goto out;
- }
- sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
-
out:
return disposition;
}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 91ec8c936913..02e068d3450d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3159,8 +3159,9 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval
return 0;
}
-static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
- char __user *optval, int __user *optlen)
+static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len,
+ char __user *optval,
+ int __user *optlen)
{
sctp_assoc_t id;
struct sctp_association *asoc;
@@ -3185,23 +3186,28 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
return cnt;
}
-static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
- char __user *optval, int __user *optlen)
+/*
+ * Old API for getting list of peer addresses. Does not work for 32-bit
+ * programs running on a 64-bit kernel
+ */
+static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len,
+ char __user *optval,
+ int __user *optlen)
{
struct sctp_association *asoc;
struct list_head *pos;
int cnt = 0;
- struct sctp_getaddrs getaddrs;
+ struct sctp_getaddrs_old getaddrs;
struct sctp_transport *from;
void __user *to;
union sctp_addr temp;
struct sctp_sock *sp = sctp_sk(sk);
int addrlen;
- if (len != sizeof(struct sctp_getaddrs))
+ if (len != sizeof(struct sctp_getaddrs_old))
return -EINVAL;
- if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+ if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old)))
return -EFAULT;
if (getaddrs.addr_num <= 0) return -EINVAL;
@@ -3225,15 +3231,69 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
if (cnt >= getaddrs.addr_num) break;
}
getaddrs.addr_num = cnt;
- if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
+ if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+ char __user *optval, int __user *optlen)
+{
+ struct sctp_association *asoc;
+ struct list_head *pos;
+ int cnt = 0;
+ struct sctp_getaddrs getaddrs;
+ struct sctp_transport *from;
+ void __user *to;
+ union sctp_addr temp;
+ struct sctp_sock *sp = sctp_sk(sk);
+ int addrlen;
+ size_t space_left;
+ int bytes_copied;
+
+ if (len < sizeof(struct sctp_getaddrs))
+ return -EINVAL;
+
+ if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+ return -EFAULT;
+
+ /* For UDP-style sockets, id specifies the association to query. */
+ asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
+ if (!asoc)
+ return -EINVAL;
+
+ to = optval + offsetof(struct sctp_getaddrs,addrs);
+ space_left = len - sizeof(struct sctp_getaddrs) -
+ offsetof(struct sctp_getaddrs,addrs);
+
+ list_for_each(pos, &asoc->peer.transport_addr_list) {
+ from = list_entry(pos, struct sctp_transport, transports);
+ memcpy(&temp, &from->ipaddr, sizeof(temp));
+ sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+ addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+ if(space_left < addrlen)
+ return -ENOMEM;
+ temp.v4.sin_port = htons(temp.v4.sin_port);
+ if (copy_to_user(to, &temp, addrlen))
+ return -EFAULT;
+ to += addrlen;
+ cnt++;
+ space_left -= addrlen;
+ }
+
+ if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num))
+ return -EFAULT;
+ bytes_copied = ((char __user *)to) - optval;
+ if (put_user(bytes_copied, optlen))
return -EFAULT;
return 0;
}
-static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
- char __user *optval,
- int __user *optlen)
+static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
+ char __user *optval,
+ int __user *optlen)
{
sctp_assoc_t id;
struct sctp_bind_addr *bp;
@@ -3306,8 +3366,8 @@ done:
/* Helper function that copies local addresses to user and returns the number
* of addresses copied.
*/
-static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, int max_addrs,
- void __user *to)
+static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs,
+ void __user *to)
{
struct list_head *pos;
struct sctp_sockaddr_entry *addr;
@@ -3341,14 +3401,54 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, int max_addrs,
return cnt;
}
-static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
- char __user *optval, int __user *optlen)
+static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
+ void * __user *to, size_t space_left)
+{
+ struct list_head *pos;
+ struct sctp_sockaddr_entry *addr;
+ unsigned long flags;
+ union sctp_addr temp;
+ int cnt = 0;
+ int addrlen;
+
+ sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+ list_for_each(pos, &sctp_local_addr_list) {
+ addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ if ((PF_INET == sk->sk_family) &&
+ (AF_INET6 == addr->a.sa.sa_family))
+ continue;
+ memcpy(&temp, &addr->a, sizeof(temp));
+ sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+ &temp);
+ addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+ if(space_left<addrlen)
+ return -ENOMEM;
+ temp.v4.sin_port = htons(port);
+ if (copy_to_user(*to, &temp, addrlen)) {
+ sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+ flags);
+ return -EFAULT;
+ }
+ *to += addrlen;
+ cnt ++;
+ space_left -= addrlen;
+ }
+ sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
+
+ return cnt;
+}
+
+/* Old API for getting list of local addresses. Does not work for 32-bit
+ * programs running on a 64-bit kernel
+ */
+static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
+ char __user *optval, int __user *optlen)
{
struct sctp_bind_addr *bp;
struct sctp_association *asoc;
struct list_head *pos;
int cnt = 0;
- struct sctp_getaddrs getaddrs;
+ struct sctp_getaddrs_old getaddrs;
struct sctp_sockaddr_entry *addr;
void __user *to;
union sctp_addr temp;
@@ -3357,10 +3457,10 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
rwlock_t *addr_lock;
int err = 0;
- if (len != sizeof(struct sctp_getaddrs))
+ if (len != sizeof(struct sctp_getaddrs_old))
return -EINVAL;
- if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+ if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old)))
return -EFAULT;
if (getaddrs.addr_num <= 0) return -EINVAL;
@@ -3392,8 +3492,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
addr = list_entry(bp->address_list.next,
struct sctp_sockaddr_entry, list);
if (sctp_is_any(&addr->a)) {
- cnt = sctp_copy_laddrs_to_user(sk, bp->port,
- getaddrs.addr_num, to);
+ cnt = sctp_copy_laddrs_to_user_old(sk, bp->port,
+ getaddrs.addr_num,
+ to);
if (cnt < 0) {
err = cnt;
goto unlock;
@@ -3419,7 +3520,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
copy_getaddrs:
getaddrs.addr_num = cnt;
- if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
+ if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old)))
err = -EFAULT;
unlock:
@@ -3427,6 +3528,99 @@ unlock:
return err;
}
+static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+ char __user *optval, int __user *optlen)
+{
+ struct sctp_bind_addr *bp;
+ struct sctp_association *asoc;
+ struct list_head *pos;
+ int cnt = 0;
+ struct sctp_getaddrs getaddrs;
+ struct sctp_sockaddr_entry *addr;
+ void __user *to;
+ union sctp_addr temp;
+ struct sctp_sock *sp = sctp_sk(sk);
+ int addrlen;
+ rwlock_t *addr_lock;
+ int err = 0;
+ size_t space_left;
+ int bytes_copied;
+
+ if (len <= sizeof(struct sctp_getaddrs))
+ return -EINVAL;
+
+ if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+ return -EFAULT;
+
+ /*
+ * For UDP-style sockets, id specifies the association to query.
+ * If the id field is set to the value '0' then the locally bound
+ * addresses are returned without regard to any particular
+ * association.
+ */
+ if (0 == getaddrs.assoc_id) {
+ bp = &sctp_sk(sk)->ep->base.bind_addr;
+ addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
+ } else {
+ asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
+ if (!asoc)
+ return -EINVAL;
+ bp = &asoc->base.bind_addr;
+ addr_lock = &asoc->base.addr_lock;
+ }
+
+ to = optval + offsetof(struct sctp_getaddrs,addrs);
+ space_left = len - sizeof(struct sctp_getaddrs) -
+ offsetof(struct sctp_getaddrs,addrs);
+
+ sctp_read_lock(addr_lock);
+
+ /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
+ * addresses from the global local address list.
+ */
+ if (sctp_list_single_entry(&bp->address_list)) {
+ addr = list_entry(bp->address_list.next,
+ struct sctp_sockaddr_entry, list);
+ if (sctp_is_any(&addr->a)) {
+ cnt = sctp_copy_laddrs_to_user(sk, bp->port,
+ &to, space_left);
+ if (cnt < 0) {
+ err = cnt;
+ goto unlock;
+ }
+ goto copy_getaddrs;
+ }
+ }
+
+ list_for_each(pos, &bp->address_list) {
+ addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ memcpy(&temp, &addr->a, sizeof(temp));
+ sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+ addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+ if(space_left < addrlen)
+ return -ENOMEM; /*fixme: right error?*/
+ temp.v4.sin_port = htons(temp.v4.sin_port);
+ if (copy_to_user(to, &temp, addrlen)) {
+ err = -EFAULT;
+ goto unlock;
+ }
+ to += addrlen;
+ cnt ++;
+ space_left -= addrlen;
+ }
+
+copy_getaddrs:
+ if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num))
+ return -EFAULT;
+ bytes_copied = ((char __user *)to) - optval;
+ if (put_user(bytes_copied, optlen))
+ return -EFAULT;
+
+unlock:
+ sctp_read_unlock(addr_lock);
+ return err;
+}
+
/* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
*
* Requests that the local SCTP stack use the enclosed peer address as
@@ -3807,12 +4001,20 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
case SCTP_INITMSG:
retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
break;
- case SCTP_GET_PEER_ADDRS_NUM:
- retval = sctp_getsockopt_peer_addrs_num(sk, len, optval,
+ case SCTP_GET_PEER_ADDRS_NUM_OLD:
+ retval = sctp_getsockopt_peer_addrs_num_old(sk, len, optval,
+ optlen);
+ break;
+ case SCTP_GET_LOCAL_ADDRS_NUM_OLD:
+ retval = sctp_getsockopt_local_addrs_num_old(sk, len, optval,
+ optlen);
+ break;
+ case SCTP_GET_PEER_ADDRS_OLD:
+ retval = sctp_getsockopt_peer_addrs_old(sk, len, optval,
optlen);
break;
- case SCTP_GET_LOCAL_ADDRS_NUM:
- retval = sctp_getsockopt_local_addrs_num(sk, len, optval,
+ case SCTP_GET_LOCAL_ADDRS_OLD:
+ retval = sctp_getsockopt_local_addrs_old(sk, len, optval,
optlen);
break;
case SCTP_GET_PEER_ADDRS:
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
index 25037daf3fa0..cbe2513d2822 100644
--- a/net/sctp/ssnmap.c
+++ b/net/sctp/ssnmap.c
@@ -58,7 +58,7 @@ static inline size_t sctp_ssnmap_size(__u16 in, __u16 out)
* Allocate room to store at least 'len' contiguous TSNs.
*/
struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_ssnmap *retval;
int size;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index d2f04ebe5081..6bc27200e6ca 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -57,7 +57,7 @@
/* Initialize a new transport from provided memory. */
static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
const union sctp_addr *addr,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
/* Copy in the address. */
peer->ipaddr = *addr;
@@ -122,7 +122,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
/* Allocate and initialize a new transport. */
struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_transport *transport;
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 0abd5101107c..057e7fac3af0 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -74,7 +74,7 @@ SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
/* Create a new sctp_ulpevent. */
SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sk_buff *skb;
@@ -136,7 +136,7 @@ static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
const struct sctp_association *asoc,
__u16 flags, __u16 state, __u16 error, __u16 outbound,
- __u16 inbound, unsigned int __nocast gfp)
+ __u16 inbound, gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_assoc_change *sac;
@@ -237,7 +237,7 @@ fail:
struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
const struct sctp_association *asoc,
const struct sockaddr_storage *aaddr,
- int flags, int state, int error, unsigned int __nocast gfp)
+ int flags, int state, int error, gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_paddr_change *spc;
@@ -350,7 +350,7 @@ fail:
*/
struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
const struct sctp_association *asoc, struct sctp_chunk *chunk,
- __u16 flags, unsigned int __nocast gfp)
+ __u16 flags, gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_remote_error *sre;
@@ -448,7 +448,7 @@ fail:
*/
struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
const struct sctp_association *asoc, struct sctp_chunk *chunk,
- __u16 flags, __u32 error, unsigned int __nocast gfp)
+ __u16 flags, __u32 error, gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_send_failed *ssf;
@@ -557,7 +557,7 @@ fail:
*/
struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
const struct sctp_association *asoc,
- __u16 flags, unsigned int __nocast gfp)
+ __u16 flags, gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_shutdown_event *sse;
@@ -620,7 +620,7 @@ fail:
* 5.3.1.6 SCTP_ADAPTION_INDICATION
*/
struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
- const struct sctp_association *asoc, unsigned int __nocast gfp)
+ const struct sctp_association *asoc, gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_adaption_event *sai;
@@ -657,7 +657,7 @@ fail:
*/
struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
struct sctp_chunk *chunk,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_ulpevent *event = NULL;
struct sk_buff *skb;
@@ -719,7 +719,7 @@ fail:
*/
struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
const struct sctp_association *asoc, __u32 indication,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_pdapi_event *pd;
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index ec2c857eae7f..2080b2d28c98 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -100,7 +100,7 @@ void sctp_ulpq_free(struct sctp_ulpq *ulpq)
/* Process an incoming DATA chunk. */
int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sk_buff_head temp;
sctp_data_chunk_t *hdr;
@@ -792,7 +792,7 @@ static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed)
/* Partial deliver the first message as there is pressure on rwnd. */
void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
struct sctp_chunk *chunk,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_ulpevent *event;
struct sctp_association *asoc;
@@ -816,7 +816,7 @@ void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
/* Renege some packets to make room for an incoming chunk. */
void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
- unsigned int __nocast gfp)
+ gfp_t gfp)
{
struct sctp_association *asoc;
__u16 needed, freed;
@@ -855,7 +855,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
/* Notify the application if an association is aborted and in
* partial delivery mode. Send up any pending received messages.
*/
-void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, unsigned int __nocast gfp)
+void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
{
struct sctp_ulpevent *ev = NULL;
struct sock *sk;
diff --git a/net/socket.c b/net/socket.c
index e1bd5d84d7bf..3145103cdf54 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1145,8 +1145,11 @@ static int __sock_create(int family, int type, int protocol, struct socket **res
if (!try_module_get(net_families[family]->owner))
goto out_release;
- if ((err = net_families[family]->create(sock, protocol)) < 0)
+ if ((err = net_families[family]->create(sock, protocol)) < 0) {
+ sock->ops = NULL;
goto out_module_put;
+ }
+
/*
* Now to bump the refcnt of the [loadable] module that owns this
* socket at sock_release time we decrement its refcnt.
@@ -1360,16 +1363,16 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
newsock->type = sock->type;
newsock->ops = sock->ops;
- err = security_socket_accept(sock, newsock);
- if (err)
- goto out_release;
-
/*
* We don't need try_module_get here, as the listening socket (sock)
* has the protocol module (sock->ops->owner) held.
*/
__module_get(newsock->ops->owner);
+ err = security_socket_accept(sock, newsock);
+ if (err)
+ goto out_release;
+
err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0)
goto out_release;
@@ -1700,7 +1703,9 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
struct socket *sock;
char address[MAX_SOCK_ADDR];
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
- unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */
+ unsigned char ctl[sizeof(struct cmsghdr) + 20]
+ __attribute__ ((aligned (sizeof(__kernel_size_t))));
+ /* 20 is size of ipv6_pktinfo */
unsigned char *ctl_buf = ctl;
struct msghdr msg_sys;
int err, ctl_len, iov_size, total_len;
@@ -1745,10 +1750,11 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
goto out_freeiov;
ctl_len = msg_sys.msg_controllen;
if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
- err = cmsghdr_from_user_compat_to_kern(&msg_sys, ctl, sizeof(ctl));
+ err = cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl, sizeof(ctl));
if (err)
goto out_freeiov;
ctl_buf = msg_sys.msg_control;
+ ctl_len = msg_sys.msg_controllen;
} else if (ctl_len) {
if (ctl_len > sizeof(ctl))
{
@@ -1861,7 +1867,8 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
if (err < 0)
goto out_freeiov;
}
- err = __put_user(msg_sys.msg_flags, COMPAT_FLAGS(msg));
+ err = __put_user((msg_sys.msg_flags & ~MSG_CMSG_COMPAT),
+ COMPAT_FLAGS(msg));
if (err)
goto out_freeiov;
if (MSG_CMSG_COMPAT & flags)
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index 46a2ce00a29b..cdcab9ca4c60 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -6,7 +6,7 @@
obj-$(CONFIG_SUNRPC) += sunrpc.o
obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
-sunrpc-y := clnt.o xprt.o sched.o \
+sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
auth.o auth_null.o auth_unix.o \
svc.o svcsock.o svcauth.o svcauth_unix.o \
pmap_clnt.o timer.o xdr.o \
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 505e2d4b3d62..a415d99c394d 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
-#include <linux/socket.h>
#include <linux/sunrpc/clnt.h>
#include <linux/spinlock.h>
diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile
index fe1b874084bc..f3431a7e33da 100644
--- a/net/sunrpc/auth_gss/Makefile
+++ b/net/sunrpc/auth_gss/Makefile
@@ -10,7 +10,7 @@ auth_rpcgss-objs := auth_gss.o gss_generic_token.o \
obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
- gss_krb5_seqnum.o
+ gss_krb5_seqnum.o gss_krb5_wrap.o
obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 2f7b867161d2..f44f46f1d8e0 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -42,9 +42,8 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/in.h>
#include <linux/sched.h>
+#include <linux/pagemap.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/auth_gss.h>
@@ -846,10 +845,8 @@ gss_marshal(struct rpc_task *task, u32 *p)
/* We compute the checksum for the verifier over the xdr-encoded bytes
* starting with the xid and ending at the end of the credential: */
- iov.iov_base = req->rq_snd_buf.head[0].iov_base;
- if (task->tk_client->cl_xprt->stream)
- /* See clnt.c:call_header() */
- iov.iov_base += 4;
+ iov.iov_base = xprt_skip_transport_header(task->tk_xprt,
+ req->rq_snd_buf.head[0].iov_base);
iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
xdr_buf_from_iov(&iov, &verf_buf);
@@ -857,9 +854,7 @@ gss_marshal(struct rpc_task *task, u32 *p)
*p++ = htonl(RPC_AUTH_GSS);
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx->gc_gss_ctx,
- GSS_C_QOP_DEFAULT,
- &verf_buf, &mic);
+ maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
} else if (maj_stat != 0) {
@@ -890,10 +885,8 @@ static u32 *
gss_validate(struct rpc_task *task, u32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
- struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
- gc_base);
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
- u32 seq, qop_state;
+ u32 seq;
struct kvec iov;
struct xdr_buf verf_buf;
struct xdr_netobj mic;
@@ -914,23 +907,14 @@ gss_validate(struct rpc_task *task, u32 *p)
mic.data = (u8 *)p;
mic.len = len;
- maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic, &qop_state);
+ maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
if (maj_stat)
goto out_bad;
- switch (gss_cred->gc_service) {
- case RPC_GSS_SVC_NONE:
- /* verifier data, flavor, length: */
- task->tk_auth->au_rslack = XDR_QUADLEN(len) + 2;
- break;
- case RPC_GSS_SVC_INTEGRITY:
- /* verifier data, flavor, length, length, sequence number: */
- task->tk_auth->au_rslack = XDR_QUADLEN(len) + 4;
- break;
- case RPC_GSS_SVC_PRIVACY:
- goto out_bad;
- }
+ /* We leave it to unwrap to calculate au_rslack. For now we just
+ * calculate the length of the verifier: */
+ task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2;
gss_put_ctx(ctx);
dprintk("RPC: %4u GSS gss_validate: gss_verify_mic succeeded.\n",
task->tk_pid);
@@ -975,8 +959,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
p = iov->iov_base + iov->iov_len;
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx->gc_gss_ctx,
- GSS_C_QOP_DEFAULT, &integ_buf, &mic);
+ maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
status = -EIO; /* XXX? */
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
@@ -990,6 +973,113 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
return 0;
}
+static void
+priv_release_snd_buf(struct rpc_rqst *rqstp)
+{
+ int i;
+
+ for (i=0; i < rqstp->rq_enc_pages_num; i++)
+ __free_page(rqstp->rq_enc_pages[i]);
+ kfree(rqstp->rq_enc_pages);
+}
+
+static int
+alloc_enc_pages(struct rpc_rqst *rqstp)
+{
+ struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
+ int first, last, i;
+
+ if (snd_buf->page_len == 0) {
+ rqstp->rq_enc_pages_num = 0;
+ return 0;
+ }
+
+ first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
+ last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
+ rqstp->rq_enc_pages_num = last - first + 1 + 1;
+ rqstp->rq_enc_pages
+ = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
+ GFP_NOFS);
+ if (!rqstp->rq_enc_pages)
+ goto out;
+ for (i=0; i < rqstp->rq_enc_pages_num; i++) {
+ rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
+ if (rqstp->rq_enc_pages[i] == NULL)
+ goto out_free;
+ }
+ rqstp->rq_release_snd_buf = priv_release_snd_buf;
+ return 0;
+out_free:
+ for (i--; i >= 0; i--) {
+ __free_page(rqstp->rq_enc_pages[i]);
+ }
+out:
+ return -EAGAIN;
+}
+
+static inline int
+gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+ kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
+{
+ struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
+ u32 offset;
+ u32 maj_stat;
+ int status;
+ u32 *opaque_len;
+ struct page **inpages;
+ int first;
+ int pad;
+ struct kvec *iov;
+ char *tmp;
+
+ opaque_len = p++;
+ offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
+ *p++ = htonl(rqstp->rq_seqno);
+
+ status = encode(rqstp, p, obj);
+ if (status)
+ return status;
+
+ status = alloc_enc_pages(rqstp);
+ if (status)
+ return status;
+ first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
+ inpages = snd_buf->pages + first;
+ snd_buf->pages = rqstp->rq_enc_pages;
+ snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
+ /* Give the tail its own page, in case we need extra space in the
+ * head when wrapping: */
+ if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
+ tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
+ memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
+ snd_buf->tail[0].iov_base = tmp;
+ }
+ maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
+ /* RPC_SLACK_SPACE should prevent this ever happening: */
+ BUG_ON(snd_buf->len > snd_buf->buflen);
+ status = -EIO;
+ /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
+ * done anyway, so it's safe to put the request on the wire: */
+ if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ else if (maj_stat)
+ return status;
+
+ *opaque_len = htonl(snd_buf->len - offset);
+ /* guess whether we're in the head or the tail: */
+ if (snd_buf->page_len || snd_buf->tail[0].iov_len)
+ iov = snd_buf->tail;
+ else
+ iov = snd_buf->head;
+ p = iov->iov_base + iov->iov_len;
+ pad = 3 - ((snd_buf->len - offset - 1) & 3);
+ memset(p, 0, pad);
+ iov->iov_len += pad;
+ snd_buf->len += pad;
+
+ return 0;
+}
+
static int
gss_wrap_req(struct rpc_task *task,
kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
@@ -1017,6 +1107,8 @@ gss_wrap_req(struct rpc_task *task,
rqstp, p, obj);
break;
case RPC_GSS_SVC_PRIVACY:
+ status = gss_wrap_req_priv(cred, ctx, encode,
+ rqstp, p, obj);
break;
}
out:
@@ -1054,8 +1146,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
return status;
- maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf,
- &mic, NULL);
+ maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
if (maj_stat != GSS_S_COMPLETE)
@@ -1063,6 +1154,35 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
return 0;
}
+static inline int
+gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+ struct rpc_rqst *rqstp, u32 **p)
+{
+ struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
+ u32 offset;
+ u32 opaque_len;
+ u32 maj_stat;
+ int status = -EIO;
+
+ opaque_len = ntohl(*(*p)++);
+ offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
+ if (offset + opaque_len > rcv_buf->len)
+ return status;
+ /* remove padding: */
+ rcv_buf->len = offset + opaque_len;
+
+ maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
+ if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ if (maj_stat != GSS_S_COMPLETE)
+ return status;
+ if (ntohl(*(*p)++) != rqstp->rq_seqno)
+ return status;
+
+ return 0;
+}
+
+
static int
gss_unwrap_resp(struct rpc_task *task,
kxdrproc_t decode, void *rqstp, u32 *p, void *obj)
@@ -1071,6 +1191,9 @@ gss_unwrap_resp(struct rpc_task *task,
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
gc_base);
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
+ u32 *savedp = p;
+ struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
+ int savedlen = head->iov_len;
int status = -EIO;
if (ctx->gc_proc != RPC_GSS_PROC_DATA)
@@ -1084,8 +1207,14 @@ gss_unwrap_resp(struct rpc_task *task,
goto out;
break;
case RPC_GSS_SVC_PRIVACY:
+ status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
+ if (status)
+ goto out;
break;
}
+ /* take into account extra slack for integrity and privacy cases: */
+ task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
+ + (savedlen - head->iov_len);
out_decode:
status = decode(rqstp, p, obj);
out:
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index ee6ae74cd1b2..3f3d5437f02d 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -139,17 +139,91 @@ buf_to_sg(struct scatterlist *sg, char *ptr, int len) {
sg->length = len;
}
+static int
+process_xdr_buf(struct xdr_buf *buf, int offset, int len,
+ int (*actor)(struct scatterlist *, void *), void *data)
+{
+ int i, page_len, thislen, page_offset, ret = 0;
+ struct scatterlist sg[1];
+
+ if (offset >= buf->head[0].iov_len) {
+ offset -= buf->head[0].iov_len;
+ } else {
+ thislen = buf->head[0].iov_len - offset;
+ if (thislen > len)
+ thislen = len;
+ buf_to_sg(sg, buf->head[0].iov_base + offset, thislen);
+ ret = actor(sg, data);
+ if (ret)
+ goto out;
+ offset = 0;
+ len -= thislen;
+ }
+ if (len == 0)
+ goto out;
+
+ if (offset >= buf->page_len) {
+ offset -= buf->page_len;
+ } else {
+ page_len = buf->page_len - offset;
+ if (page_len > len)
+ page_len = len;
+ len -= page_len;
+ page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1);
+ i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT;
+ thislen = PAGE_CACHE_SIZE - page_offset;
+ do {
+ if (thislen > page_len)
+ thislen = page_len;
+ sg->page = buf->pages[i];
+ sg->offset = page_offset;
+ sg->length = thislen;
+ ret = actor(sg, data);
+ if (ret)
+ goto out;
+ page_len -= thislen;
+ i++;
+ page_offset = 0;
+ thislen = PAGE_CACHE_SIZE;
+ } while (page_len != 0);
+ offset = 0;
+ }
+ if (len == 0)
+ goto out;
+
+ if (offset < buf->tail[0].iov_len) {
+ thislen = buf->tail[0].iov_len - offset;
+ if (thislen > len)
+ thislen = len;
+ buf_to_sg(sg, buf->tail[0].iov_base + offset, thislen);
+ ret = actor(sg, data);
+ len -= thislen;
+ }
+ if (len != 0)
+ ret = -EINVAL;
+out:
+ return ret;
+}
+
+static int
+checksummer(struct scatterlist *sg, void *data)
+{
+ struct crypto_tfm *tfm = (struct crypto_tfm *)data;
+
+ crypto_digest_update(tfm, sg, 1);
+
+ return 0;
+}
+
/* checksum the plaintext data and hdrlen bytes of the token header */
s32
make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
- struct xdr_netobj *cksum)
+ int body_offset, struct xdr_netobj *cksum)
{
char *cksumname;
struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */
struct scatterlist sg[1];
u32 code = GSS_S_FAILURE;
- int len, thislen, offset;
- int i;
switch (cksumtype) {
case CKSUMTYPE_RSA_MD5:
@@ -169,33 +243,8 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
crypto_digest_init(tfm);
buf_to_sg(sg, header, hdrlen);
crypto_digest_update(tfm, sg, 1);
- if (body->head[0].iov_len) {
- buf_to_sg(sg, body->head[0].iov_base, body->head[0].iov_len);
- crypto_digest_update(tfm, sg, 1);
- }
-
- len = body->page_len;
- if (len != 0) {
- offset = body->page_base & (PAGE_CACHE_SIZE - 1);
- i = body->page_base >> PAGE_CACHE_SHIFT;
- thislen = PAGE_CACHE_SIZE - offset;
- do {
- if (thislen > len)
- thislen = len;
- sg->page = body->pages[i];
- sg->offset = offset;
- sg->length = thislen;
- crypto_digest_update(tfm, sg, 1);
- len -= thislen;
- i++;
- offset = 0;
- thislen = PAGE_CACHE_SIZE;
- } while(len != 0);
- }
- if (body->tail[0].iov_len) {
- buf_to_sg(sg, body->tail[0].iov_base, body->tail[0].iov_len);
- crypto_digest_update(tfm, sg, 1);
- }
+ process_xdr_buf(body, body_offset, body->len - body_offset,
+ checksummer, tfm);
crypto_digest_final(tfm, cksum->data);
code = 0;
out:
@@ -204,3 +253,154 @@ out:
}
EXPORT_SYMBOL(make_checksum);
+
+struct encryptor_desc {
+ u8 iv[8]; /* XXX hard-coded blocksize */
+ struct crypto_tfm *tfm;
+ int pos;
+ struct xdr_buf *outbuf;
+ struct page **pages;
+ struct scatterlist infrags[4];
+ struct scatterlist outfrags[4];
+ int fragno;
+ int fraglen;
+};
+
+static int
+encryptor(struct scatterlist *sg, void *data)
+{
+ struct encryptor_desc *desc = data;
+ struct xdr_buf *outbuf = desc->outbuf;
+ struct page *in_page;
+ int thislen = desc->fraglen + sg->length;
+ int fraglen, ret;
+ int page_pos;
+
+ /* Worst case is 4 fragments: head, end of page 1, start
+ * of page 2, tail. Anything more is a bug. */
+ BUG_ON(desc->fragno > 3);
+ desc->infrags[desc->fragno] = *sg;
+ desc->outfrags[desc->fragno] = *sg;
+
+ page_pos = desc->pos - outbuf->head[0].iov_len;
+ if (page_pos >= 0 && page_pos < outbuf->page_len) {
+ /* pages are not in place: */
+ int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
+ in_page = desc->pages[i];
+ } else {
+ in_page = sg->page;
+ }
+ desc->infrags[desc->fragno].page = in_page;
+ desc->fragno++;
+ desc->fraglen += sg->length;
+ desc->pos += sg->length;
+
+ fraglen = thislen & 7; /* XXX hardcoded blocksize */
+ thislen -= fraglen;
+
+ if (thislen == 0)
+ return 0;
+
+ ret = crypto_cipher_encrypt_iv(desc->tfm, desc->outfrags, desc->infrags,
+ thislen, desc->iv);
+ if (ret)
+ return ret;
+ if (fraglen) {
+ desc->outfrags[0].page = sg->page;
+ desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
+ desc->outfrags[0].length = fraglen;
+ desc->infrags[0] = desc->outfrags[0];
+ desc->infrags[0].page = in_page;
+ desc->fragno = 1;
+ desc->fraglen = fraglen;
+ } else {
+ desc->fragno = 0;
+ desc->fraglen = 0;
+ }
+ return 0;
+}
+
+int
+gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset,
+ struct page **pages)
+{
+ int ret;
+ struct encryptor_desc desc;
+
+ BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);
+
+ memset(desc.iv, 0, sizeof(desc.iv));
+ desc.tfm = tfm;
+ desc.pos = offset;
+ desc.outbuf = buf;
+ desc.pages = pages;
+ desc.fragno = 0;
+ desc.fraglen = 0;
+
+ ret = process_xdr_buf(buf, offset, buf->len - offset, encryptor, &desc);
+ return ret;
+}
+
+EXPORT_SYMBOL(gss_encrypt_xdr_buf);
+
+struct decryptor_desc {
+ u8 iv[8]; /* XXX hard-coded blocksize */
+ struct crypto_tfm *tfm;
+ struct scatterlist frags[4];
+ int fragno;
+ int fraglen;
+};
+
+static int
+decryptor(struct scatterlist *sg, void *data)
+{
+ struct decryptor_desc *desc = data;
+ int thislen = desc->fraglen + sg->length;
+ int fraglen, ret;
+
+ /* Worst case is 4 fragments: head, end of page 1, start
+ * of page 2, tail. Anything more is a bug. */
+ BUG_ON(desc->fragno > 3);
+ desc->frags[desc->fragno] = *sg;
+ desc->fragno++;
+ desc->fraglen += sg->length;
+
+ fraglen = thislen & 7; /* XXX hardcoded blocksize */
+ thislen -= fraglen;
+
+ if (thislen == 0)
+ return 0;
+
+ ret = crypto_cipher_decrypt_iv(desc->tfm, desc->frags, desc->frags,
+ thislen, desc->iv);
+ if (ret)
+ return ret;
+ if (fraglen) {
+ desc->frags[0].page = sg->page;
+ desc->frags[0].offset = sg->offset + sg->length - fraglen;
+ desc->frags[0].length = fraglen;
+ desc->fragno = 1;
+ desc->fraglen = fraglen;
+ } else {
+ desc->fragno = 0;
+ desc->fraglen = 0;
+ }
+ return 0;
+}
+
+int
+gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset)
+{
+ struct decryptor_desc desc;
+
+ /* XXXJBF: */
+ BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);
+
+ memset(desc.iv, 0, sizeof(desc.iv));
+ desc.tfm = tfm;
+ desc.fragno = 0;
+ desc.fraglen = 0;
+ return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc);
+}
+
+EXPORT_SYMBOL(gss_decrypt_xdr_buf);
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 606a8a82cafb..5f1f806a0b11 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -39,7 +39,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/sunrpc/auth.h>
-#include <linux/in.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/sunrpc/xdr.h>
#include <linux/crypto.h>
@@ -191,43 +190,12 @@ gss_delete_sec_context_kerberos(void *internal_ctx) {
kfree(kctx);
}
-static u32
-gss_verify_mic_kerberos(struct gss_ctx *ctx,
- struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate) {
- u32 maj_stat = 0;
- int qop_state;
- struct krb5_ctx *kctx = ctx->internal_ctx_id;
-
- maj_stat = krb5_read_token(kctx, mic_token, message, &qop_state,
- KG_TOK_MIC_MSG);
- if (!maj_stat && qop_state)
- *qstate = qop_state;
-
- dprintk("RPC: gss_verify_mic_kerberos returning %d\n", maj_stat);
- return maj_stat;
-}
-
-static u32
-gss_get_mic_kerberos(struct gss_ctx *ctx,
- u32 qop,
- struct xdr_buf *message,
- struct xdr_netobj *mic_token) {
- u32 err = 0;
- struct krb5_ctx *kctx = ctx->internal_ctx_id;
-
- err = krb5_make_token(kctx, qop, message, mic_token, KG_TOK_MIC_MSG);
-
- dprintk("RPC: gss_get_mic_kerberos returning %d\n",err);
-
- return err;
-}
-
static struct gss_api_ops gss_kerberos_ops = {
.gss_import_sec_context = gss_import_sec_context_kerberos,
.gss_get_mic = gss_get_mic_kerberos,
.gss_verify_mic = gss_verify_mic_kerberos,
+ .gss_wrap = gss_wrap_kerberos,
+ .gss_unwrap = gss_unwrap_kerberos,
.gss_delete_sec_context = gss_delete_sec_context_kerberos,
};
@@ -242,6 +210,11 @@ static struct pf_desc gss_kerberos_pfs[] = {
.service = RPC_GSS_SVC_INTEGRITY,
.name = "krb5i",
},
+ [2] = {
+ .pseudoflavor = RPC_AUTH_GSS_KRB5P,
+ .service = RPC_GSS_SVC_PRIVACY,
+ .name = "krb5p",
+ },
};
static struct gss_api_mech gss_kerberos_mech = {
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index afeeb8715a77..13f8ae979454 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -70,22 +70,13 @@
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
-static inline int
-gss_krb5_padding(int blocksize, int length) {
- /* Most of the code is block-size independent but in practice we
- * use only 8: */
- BUG_ON(blocksize != 8);
- return 8 - (length & 7);
-}
-
u32
-krb5_make_token(struct krb5_ctx *ctx, int qop_req,
- struct xdr_buf *text, struct xdr_netobj *token,
- int toktype)
+gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
+ struct xdr_netobj *token)
{
+ struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
s32 checksum_type;
struct xdr_netobj md5cksum = {.len = 0, .data = NULL};
- int blocksize = 0, tmsglen;
unsigned char *ptr, *krb5_hdr, *msg_start;
s32 now;
@@ -93,9 +84,6 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
now = get_seconds();
- if (qop_req != 0)
- goto out_err;
-
switch (ctx->signalg) {
case SGN_ALG_DES_MAC_MD5:
checksum_type = CKSUMTYPE_RSA_MD5;
@@ -111,21 +99,13 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
goto out_err;
}
- if (toktype == KG_TOK_WRAP_MSG) {
- blocksize = crypto_tfm_alg_blocksize(ctx->enc);
- tmsglen = blocksize + text->len
- + gss_krb5_padding(blocksize, blocksize + text->len);
- } else {
- tmsglen = 0;
- }
-
- token->len = g_token_size(&ctx->mech_used, 22 + tmsglen);
+ token->len = g_token_size(&ctx->mech_used, 22);
ptr = token->data;
- g_make_token_header(&ctx->mech_used, 22 + tmsglen, &ptr);
+ g_make_token_header(&ctx->mech_used, 22, &ptr);
- *ptr++ = (unsigned char) ((toktype>>8)&0xff);
- *ptr++ = (unsigned char) (toktype&0xff);
+ *ptr++ = (unsigned char) ((KG_TOK_MIC_MSG>>8)&0xff);
+ *ptr++ = (unsigned char) (KG_TOK_MIC_MSG&0xff);
/* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
krb5_hdr = ptr - 2;
@@ -133,17 +113,9 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
*(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
memset(krb5_hdr + 4, 0xff, 4);
- if (toktype == KG_TOK_WRAP_MSG)
- *(u16 *)(krb5_hdr + 4) = htons(ctx->sealalg);
- if (toktype == KG_TOK_WRAP_MSG) {
- /* XXX removing support for now */
- goto out_err;
- } else { /* Sign only. */
- if (make_checksum(checksum_type, krb5_hdr, 8, text,
- &md5cksum))
+ if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum))
goto out_err;
- }
switch (ctx->signalg) {
case SGN_ALG_DES_MAC_MD5:
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 8767fc53183d..2030475d98ed 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -68,21 +68,14 @@
#endif
-/* message_buffer is an input if toktype is MIC and an output if it is WRAP:
- * If toktype is MIC: read_token is a mic token, and message_buffer is the
- * data that the mic was supposedly taken over.
- * If toktype is WRAP: read_token is a wrap token, and message_buffer is used
- * to return the decrypted data.
- */
+/* read_token is a mic token, and message_buffer is the data that the mic was
+ * supposedly taken over. */
-/* XXX will need to change prototype and/or just split into a separate function
- * when we add privacy (because read_token will be in pages too). */
u32
-krb5_read_token(struct krb5_ctx *ctx,
- struct xdr_netobj *read_token,
- struct xdr_buf *message_buffer,
- int *qop_state, int toktype)
+gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
+ struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
{
+ struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
int signalg;
int sealalg;
s32 checksum_type;
@@ -100,16 +93,12 @@ krb5_read_token(struct krb5_ctx *ctx,
read_token->len))
goto out;
- if ((*ptr++ != ((toktype>>8)&0xff)) || (*ptr++ != (toktype&0xff)))
+ if ((*ptr++ != ((KG_TOK_MIC_MSG>>8)&0xff)) ||
+ (*ptr++ != ( KG_TOK_MIC_MSG &0xff)) )
goto out;
/* XXX sanity-check bodysize?? */
- if (toktype == KG_TOK_WRAP_MSG) {
- /* XXX gone */
- goto out;
- }
-
/* get the sign and seal algorithms */
signalg = ptr[0] + (ptr[1] << 8);
@@ -120,14 +109,7 @@ krb5_read_token(struct krb5_ctx *ctx,
if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
goto out;
- if (((toktype != KG_TOK_WRAP_MSG) && (sealalg != 0xffff)) ||
- ((toktype == KG_TOK_WRAP_MSG) && (sealalg == 0xffff)))
- goto out;
-
- /* in the current spec, there is only one valid seal algorithm per
- key type, so a simple comparison is ok */
-
- if ((toktype == KG_TOK_WRAP_MSG) && !(sealalg == ctx->sealalg))
+ if (sealalg != 0xffff)
goto out;
/* there are several mappings of seal algorithms to sign algorithms,
@@ -154,7 +136,7 @@ krb5_read_token(struct krb5_ctx *ctx,
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
ret = make_checksum(checksum_type, ptr - 2, 8,
- message_buffer, &md5cksum);
+ message_buffer, 0, &md5cksum);
if (ret)
goto out;
@@ -175,9 +157,6 @@ krb5_read_token(struct krb5_ctx *ctx,
/* it got through unscathed. Make sure the context is unexpired */
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
now = get_seconds();
ret = GSS_S_CONTEXT_EXPIRED;
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
new file mode 100644
index 000000000000..af777cf9f251
--- /dev/null
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -0,0 +1,363 @@
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/random.h>
+#include <linux/pagemap.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+static inline int
+gss_krb5_padding(int blocksize, int length)
+{
+ /* Most of the code is block-size independent but currently we
+ * use only 8: */
+ BUG_ON(blocksize != 8);
+ return 8 - (length & 7);
+}
+
+static inline void
+gss_krb5_add_padding(struct xdr_buf *buf, int offset, int blocksize)
+{
+ int padding = gss_krb5_padding(blocksize, buf->len - offset);
+ char *p;
+ struct kvec *iov;
+
+ if (buf->page_len || buf->tail[0].iov_len)
+ iov = &buf->tail[0];
+ else
+ iov = &buf->head[0];
+ p = iov->iov_base + iov->iov_len;
+ iov->iov_len += padding;
+ buf->len += padding;
+ memset(p, padding, padding);
+}
+
+static inline int
+gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
+{
+ u8 *ptr;
+ u8 pad;
+ int len = buf->len;
+
+ if (len <= buf->head[0].iov_len) {
+ pad = *(u8 *)(buf->head[0].iov_base + len - 1);
+ if (pad > buf->head[0].iov_len)
+ return -EINVAL;
+ buf->head[0].iov_len -= pad;
+ goto out;
+ } else
+ len -= buf->head[0].iov_len;
+ if (len <= buf->page_len) {
+ int last = (buf->page_base + len - 1)
+ >>PAGE_CACHE_SHIFT;
+ int offset = (buf->page_base + len - 1)
+ & (PAGE_CACHE_SIZE - 1);
+ ptr = kmap_atomic(buf->pages[last], KM_SKB_SUNRPC_DATA);
+ pad = *(ptr + offset);
+ kunmap_atomic(ptr, KM_SKB_SUNRPC_DATA);
+ goto out;
+ } else
+ len -= buf->page_len;
+ BUG_ON(len > buf->tail[0].iov_len);
+ pad = *(u8 *)(buf->tail[0].iov_base + len - 1);
+out:
+ /* XXX: NOTE: we do not adjust the page lengths--they represent
+ * a range of data in the real filesystem page cache, and we need
+ * to know that range so the xdr code can properly place read data.
+ * However adjusting the head length, as we do above, is harmless.
+ * In the case of a request that fits into a single page, the server
+ * also uses length and head length together to determine the original
+ * start of the request to copy the request for deferal; so it's
+ * easier on the server if we adjust head and tail length in tandem.
+ * It's not really a problem that we don't fool with the page and
+ * tail lengths, though--at worst badly formed xdr might lead the
+ * server to attempt to parse the padding.
+ * XXX: Document all these weird requirements for gss mechanism
+ * wrap/unwrap functions. */
+ if (pad > blocksize)
+ return -EINVAL;
+ if (buf->len > pad)
+ buf->len -= pad;
+ else
+ return -EINVAL;
+ return 0;
+}
+
+static inline void
+make_confounder(char *p, int blocksize)
+{
+ static u64 i = 0;
+ u64 *q = (u64 *)p;
+
+ /* rfc1964 claims this should be "random". But all that's really
+ * necessary is that it be unique. And not even that is necessary in
+ * our case since our "gssapi" implementation exists only to support
+ * rpcsec_gss, so we know that the only buffers we will ever encrypt
+ * already begin with a unique sequence number. Just to hedge my bets
+ * I'll make a half-hearted attempt at something unique, but ensuring
+ * uniqueness would mean worrying about atomicity and rollover, and I
+ * don't care enough. */
+
+ BUG_ON(blocksize != 8);
+ *q = i++;
+}
+
+/* Assumptions: the head and tail of inbuf are ours to play with.
+ * The pages, however, may be real pages in the page cache and we replace
+ * them with scratch pages from **pages before writing to them. */
+/* XXX: obviously the above should be documentation of wrap interface,
+ * and shouldn't be in this kerberos-specific file. */
+
+/* XXX factor out common code with seal/unseal. */
+
+u32
+gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
+ struct xdr_buf *buf, struct page **pages)
+{
+ struct krb5_ctx *kctx = ctx->internal_ctx_id;
+ s32 checksum_type;
+ struct xdr_netobj md5cksum = {.len = 0, .data = NULL};
+ int blocksize = 0, plainlen;
+ unsigned char *ptr, *krb5_hdr, *msg_start;
+ s32 now;
+ int headlen;
+ struct page **tmp_pages;
+
+ dprintk("RPC: gss_wrap_kerberos\n");
+
+ now = get_seconds();
+
+ switch (kctx->signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ default:
+ dprintk("RPC: gss_krb5_seal: kctx->signalg %d not"
+ " supported\n", kctx->signalg);
+ goto out_err;
+ }
+ if (kctx->sealalg != SEAL_ALG_NONE && kctx->sealalg != SEAL_ALG_DES) {
+ dprintk("RPC: gss_krb5_seal: kctx->sealalg %d not supported\n",
+ kctx->sealalg);
+ goto out_err;
+ }
+
+ blocksize = crypto_tfm_alg_blocksize(kctx->enc);
+ gss_krb5_add_padding(buf, offset, blocksize);
+ BUG_ON((buf->len - offset) % blocksize);
+ plainlen = blocksize + buf->len - offset;
+
+ headlen = g_token_size(&kctx->mech_used, 22 + plainlen) -
+ (buf->len - offset);
+
+ ptr = buf->head[0].iov_base + offset;
+ /* shift data to make room for header. */
+ /* XXX Would be cleverer to encrypt while copying. */
+ /* XXX bounds checking, slack, etc. */
+ memmove(ptr + headlen, ptr, buf->head[0].iov_len - offset);
+ buf->head[0].iov_len += headlen;
+ buf->len += headlen;
+ BUG_ON((buf->len - offset - headlen) % blocksize);
+
+ g_make_token_header(&kctx->mech_used, 22 + plainlen, &ptr);
+
+
+ *ptr++ = (unsigned char) ((KG_TOK_WRAP_MSG>>8)&0xff);
+ *ptr++ = (unsigned char) (KG_TOK_WRAP_MSG&0xff);
+
+ /* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
+ krb5_hdr = ptr - 2;
+ msg_start = krb5_hdr + 24;
+ /* XXXJBF: */ BUG_ON(buf->head[0].iov_base + offset + headlen != msg_start + blocksize);
+
+ *(u16 *)(krb5_hdr + 2) = htons(kctx->signalg);
+ memset(krb5_hdr + 4, 0xff, 4);
+ *(u16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
+
+ make_confounder(msg_start, blocksize);
+
+ /* XXXJBF: UGH!: */
+ tmp_pages = buf->pages;
+ buf->pages = pages;
+ if (make_checksum(checksum_type, krb5_hdr, 8, buf,
+ offset + headlen - blocksize, &md5cksum))
+ goto out_err;
+ buf->pages = tmp_pages;
+
+ switch (kctx->signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
+ md5cksum.data, md5cksum.len))
+ goto out_err;
+ memcpy(krb5_hdr + 16,
+ md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
+ KRB5_CKSUM_LENGTH);
+
+ dprintk("RPC: make_seal_token: cksum data: \n");
+ print_hexl((u32 *) (krb5_hdr + 16), KRB5_CKSUM_LENGTH, 0);
+ break;
+ default:
+ BUG();
+ }
+
+ kfree(md5cksum.data);
+
+ /* XXX would probably be more efficient to compute checksum
+ * and encrypt at the same time: */
+ if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff,
+ kctx->seq_send, krb5_hdr + 16, krb5_hdr + 8)))
+ goto out_err;
+
+ if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
+ pages))
+ goto out_err;
+
+ kctx->seq_send++;
+
+ return ((kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
+out_err:
+ if (md5cksum.data) kfree(md5cksum.data);
+ return GSS_S_FAILURE;
+}
+
+u32
+gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
+{
+ struct krb5_ctx *kctx = ctx->internal_ctx_id;
+ int signalg;
+ int sealalg;
+ s32 checksum_type;
+ struct xdr_netobj md5cksum = {.len = 0, .data = NULL};
+ s32 now;
+ int direction;
+ s32 seqnum;
+ unsigned char *ptr;
+ int bodysize;
+ u32 ret = GSS_S_DEFECTIVE_TOKEN;
+ void *data_start, *orig_start;
+ int data_len;
+ int blocksize;
+
+ dprintk("RPC: gss_unwrap_kerberos\n");
+
+ ptr = (u8 *)buf->head[0].iov_base + offset;
+ if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr,
+ buf->len - offset))
+ goto out;
+
+ if ((*ptr++ != ((KG_TOK_WRAP_MSG>>8)&0xff)) ||
+ (*ptr++ != (KG_TOK_WRAP_MSG &0xff)) )
+ goto out;
+
+ /* XXX sanity-check bodysize?? */
+
+ /* get the sign and seal algorithms */
+
+ signalg = ptr[0] + (ptr[1] << 8);
+ sealalg = ptr[2] + (ptr[3] << 8);
+
+ /* Sanity checks */
+
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
+ goto out;
+
+ if (sealalg == 0xffff)
+ goto out;
+
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
+
+ if (sealalg != kctx->sealalg)
+ goto out;
+
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
+
+ if ((kctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (kctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (kctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
+ goto out;
+
+ if (gss_decrypt_xdr_buf(kctx->enc, buf,
+ ptr + 22 - (unsigned char *)buf->head[0].iov_base))
+ goto out;
+
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ default:
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ goto out;
+ }
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ ret = make_checksum(checksum_type, ptr - 2, 8, buf,
+ ptr + 22 - (unsigned char *)buf->head[0].iov_base, &md5cksum);
+ if (ret)
+ goto out;
+
+ ret = krb5_encrypt(kctx->seq, NULL, md5cksum.data,
+ md5cksum.data, md5cksum.len);
+ if (ret)
+ goto out;
+
+ if (memcmp(md5cksum.data + 8, ptr + 14, 8)) {
+ ret = GSS_S_BAD_SIG;
+ goto out;
+ }
+ break;
+ default:
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ goto out;
+ }
+
+ /* it got through unscathed. Make sure the context is unexpired */
+
+ now = get_seconds();
+
+ ret = GSS_S_CONTEXT_EXPIRED;
+ if (now > kctx->endtime)
+ goto out;
+
+ /* do sequencing checks */
+
+ ret = GSS_S_BAD_SIG;
+ if ((ret = krb5_get_seq_num(kctx->seq, ptr + 14, ptr + 6, &direction,
+ &seqnum)))
+ goto out;
+
+ if ((kctx->initiate && direction != 0xff) ||
+ (!kctx->initiate && direction != 0))
+ goto out;
+
+ /* Copy the data back to the right position. XXX: Would probably be
+ * better to copy and encrypt at the same time. */
+
+ blocksize = crypto_tfm_alg_blocksize(kctx->enc);
+ data_start = ptr + 22 + blocksize;
+ orig_start = buf->head[0].iov_base + offset;
+ data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
+ memmove(orig_start, data_start, data_len);
+ buf->head[0].iov_len -= (data_start - orig_start);
+ buf->len -= (data_start - orig_start);
+
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ if (gss_krb5_remove_padding(buf, blocksize))
+ goto out;
+
+ ret = GSS_S_COMPLETE;
+out:
+ if (md5cksum.data) kfree(md5cksum.data);
+ return ret;
+}
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 9dfb68377d69..b048bf672da2 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -35,7 +35,6 @@
#include <linux/types.h>
#include <linux/slab.h>
-#include <linux/socket.h>
#include <linux/module.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_asn1.h>
@@ -251,13 +250,11 @@ gss_import_sec_context(const void *input_token, size_t bufsize,
u32
gss_get_mic(struct gss_ctx *context_handle,
- u32 qop,
struct xdr_buf *message,
struct xdr_netobj *mic_token)
{
return context_handle->mech_type->gm_ops
->gss_get_mic(context_handle,
- qop,
message,
mic_token);
}
@@ -267,16 +264,34 @@ gss_get_mic(struct gss_ctx *context_handle,
u32
gss_verify_mic(struct gss_ctx *context_handle,
struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate)
+ struct xdr_netobj *mic_token)
{
return context_handle->mech_type->gm_ops
->gss_verify_mic(context_handle,
message,
- mic_token,
- qstate);
+ mic_token);
}
+u32
+gss_wrap(struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *buf,
+ struct page **inpages)
+{
+ return ctx_id->mech_type->gm_ops
+ ->gss_wrap(ctx_id, offset, buf, inpages);
+}
+
+u32
+gss_unwrap(struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *buf)
+{
+ return ctx_id->mech_type->gm_ops
+ ->gss_unwrap(ctx_id, offset, buf);
+}
+
+
/* gss_delete_sec_context: free all resources associated with context_handle.
* Note this differs from the RFC 2744-specified prototype in that we don't
* bother returning an output token, since it would never be used anyway. */
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 6c97d61baa9b..39b3edc14694 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -224,18 +224,13 @@ gss_delete_sec_context_spkm3(void *internal_ctx) {
static u32
gss_verify_mic_spkm3(struct gss_ctx *ctx,
struct xdr_buf *signbuf,
- struct xdr_netobj *checksum,
- u32 *qstate) {
+ struct xdr_netobj *checksum)
+{
u32 maj_stat = 0;
- int qop_state = 0;
struct spkm3_ctx *sctx = ctx->internal_ctx_id;
dprintk("RPC: gss_verify_mic_spkm3 calling spkm3_read_token\n");
- maj_stat = spkm3_read_token(sctx, checksum, signbuf, &qop_state,
- SPKM_MIC_TOK);
-
- if (!maj_stat && qop_state)
- *qstate = qop_state;
+ maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);
dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat);
return maj_stat;
@@ -243,15 +238,15 @@ gss_verify_mic_spkm3(struct gss_ctx *ctx,
static u32
gss_get_mic_spkm3(struct gss_ctx *ctx,
- u32 qop,
struct xdr_buf *message_buffer,
- struct xdr_netobj *message_token) {
+ struct xdr_netobj *message_token)
+{
u32 err = 0;
struct spkm3_ctx *sctx = ctx->internal_ctx_id;
dprintk("RPC: gss_get_mic_spkm3\n");
- err = spkm3_make_token(sctx, qop, message_buffer,
+ err = spkm3_make_token(sctx, message_buffer,
message_token, SPKM_MIC_TOK);
return err;
}
@@ -264,8 +259,8 @@ static struct gss_api_ops gss_spkm3_ops = {
};
static struct pf_desc gss_spkm3_pfs[] = {
- {RPC_AUTH_GSS_SPKM, 0, RPC_GSS_SVC_NONE, "spkm3"},
- {RPC_AUTH_GSS_SPKMI, 0, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
+ {RPC_AUTH_GSS_SPKM, RPC_GSS_SVC_NONE, "spkm3"},
+ {RPC_AUTH_GSS_SPKMI, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
};
static struct gss_api_mech gss_spkm3_mech = {
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index 25339868d462..148201e929d0 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -51,7 +51,7 @@
*/
u32
-spkm3_make_token(struct spkm3_ctx *ctx, int qop_req,
+spkm3_make_token(struct spkm3_ctx *ctx,
struct xdr_buf * text, struct xdr_netobj * token,
int toktype)
{
@@ -68,8 +68,6 @@ spkm3_make_token(struct spkm3_ctx *ctx, int qop_req,
dprintk("RPC: spkm3_make_token\n");
now = jiffies;
- if (qop_req != 0)
- goto out_err;
if (ctx->ctx_id.len != 16) {
dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n",
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
index 65ce81bf0bc4..c3c0d9586103 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
@@ -52,7 +52,7 @@ u32
spkm3_read_token(struct spkm3_ctx *ctx,
struct xdr_netobj *read_token, /* checksum */
struct xdr_buf *message_buffer, /* signbuf */
- int *qop_state, int toktype)
+ int toktype)
{
s32 code;
struct xdr_netobj wire_cksum = {.len =0, .data = NULL};
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index e3308195374e..e4ada15ed856 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -566,8 +566,7 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
if (rqstp->rq_deferred) /* skip verification of revisited request */
return SVC_OK;
- if (gss_verify_mic(ctx_id, &rpchdr, &checksum, NULL)
- != GSS_S_COMPLETE) {
+ if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) {
*authp = rpcsec_gsserr_credproblem;
return SVC_DENIED;
}
@@ -604,7 +603,7 @@ gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
xdr_buf_from_iov(&iov, &verf_data);
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx_id, 0, &verf_data, &mic);
+ maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
if (maj_stat != GSS_S_COMPLETE)
return -1;
*p++ = htonl(mic.len);
@@ -710,7 +709,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
goto out;
if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
goto out;
- maj_stat = gss_verify_mic(ctx, &integ_buf, &mic, NULL);
+ maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
if (maj_stat != GSS_S_COMPLETE)
goto out;
if (ntohl(svc_getu32(&buf->head[0])) != seq)
@@ -1012,7 +1011,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
resv = &resbuf->tail[0];
}
mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
- if (gss_get_mic(gsd->rsci->mechctx, 0, &integ_buf, &mic))
+ if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
goto out_err;
svc_putu32(resv, htonl(mic.len));
memset(mic.data + mic.len, 0,
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 9b72d3abf823..f56767aaa927 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -7,9 +7,7 @@
*/
#include <linux/types.h>
-#include <linux/socket.h>
#include <linux/module.h>
-#include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sched.h>
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 4ff297a9b15b..890fb5ea0dcb 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -9,8 +9,6 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/module.h>
-#include <linux/socket.h>
-#include <linux/in.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f17e6153b688..702ede309b06 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1,5 +1,5 @@
/*
- * linux/net/sunrpc/rpcclnt.c
+ * linux/net/sunrpc/clnt.c
*
* This file contains the high-level RPC interface.
* It is modeled as a finite state machine to support both synchronous
@@ -27,7 +27,6 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h>
@@ -53,6 +52,7 @@ static void call_allocate(struct rpc_task *task);
static void call_encode(struct rpc_task *task);
static void call_decode(struct rpc_task *task);
static void call_bind(struct rpc_task *task);
+static void call_bind_status(struct rpc_task *task);
static void call_transmit(struct rpc_task *task);
static void call_status(struct rpc_task *task);
static void call_refresh(struct rpc_task *task);
@@ -517,15 +517,8 @@ void
rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize)
{
struct rpc_xprt *xprt = clnt->cl_xprt;
-
- xprt->sndsize = 0;
- if (sndsize)
- xprt->sndsize = sndsize + RPC_SLACK_SPACE;
- xprt->rcvsize = 0;
- if (rcvsize)
- xprt->rcvsize = rcvsize + RPC_SLACK_SPACE;
- if (xprt_connected(xprt))
- xprt_sock_setbufsize(xprt);
+ if (xprt->ops->set_buffer_size)
+ xprt->ops->set_buffer_size(xprt, sndsize, rcvsize);
}
/*
@@ -685,13 +678,11 @@ call_allocate(struct rpc_task *task)
static void
call_encode(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
struct xdr_buf *sndbuf = &req->rq_snd_buf;
struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
unsigned int bufsiz;
kxdrproc_t encode;
- int status;
u32 *p;
dprintk("RPC: %4d call_encode (status %d)\n",
@@ -719,11 +710,15 @@ call_encode(struct rpc_task *task)
rpc_exit(task, -EIO);
return;
}
- if (encode && (status = rpcauth_wrap_req(task, encode, req, p,
- task->tk_msg.rpc_argp)) < 0) {
- printk(KERN_WARNING "%s: can't encode arguments: %d\n",
- clnt->cl_protname, -status);
- rpc_exit(task, status);
+ if (encode == NULL)
+ return;
+
+ task->tk_status = rpcauth_wrap_req(task, encode, req, p,
+ task->tk_msg.rpc_argp);
+ if (task->tk_status == -ENOMEM) {
+ /* XXX: Is this sane? */
+ rpc_delay(task, 3*HZ);
+ task->tk_status = -EAGAIN;
}
}
@@ -734,43 +729,95 @@ static void
call_bind(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
- struct rpc_xprt *xprt = clnt->cl_xprt;
-
- dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid,
- xprt, (xprt_connected(xprt) ? "is" : "is not"));
- task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_connect;
+ dprintk("RPC: %4d call_bind (status %d)\n",
+ task->tk_pid, task->tk_status);
+ task->tk_action = call_connect;
if (!clnt->cl_port) {
- task->tk_action = call_connect;
- task->tk_timeout = RPC_CONNECT_TIMEOUT;
+ task->tk_action = call_bind_status;
+ task->tk_timeout = task->tk_xprt->bind_timeout;
rpc_getport(task, clnt);
}
}
/*
- * 4a. Connect to the RPC server (TCP case)
+ * 4a. Sort out bind result
+ */
+static void
+call_bind_status(struct rpc_task *task)
+{
+ int status = -EACCES;
+
+ if (task->tk_status >= 0) {
+ dprintk("RPC: %4d call_bind_status (status %d)\n",
+ task->tk_pid, task->tk_status);
+ task->tk_status = 0;
+ task->tk_action = call_connect;
+ return;
+ }
+
+ switch (task->tk_status) {
+ case -EACCES:
+ dprintk("RPC: %4d remote rpcbind: RPC program/version unavailable\n",
+ task->tk_pid);
+ rpc_delay(task, 3*HZ);
+ goto retry_bind;
+ case -ETIMEDOUT:
+ dprintk("RPC: %4d rpcbind request timed out\n",
+ task->tk_pid);
+ if (RPC_IS_SOFT(task)) {
+ status = -EIO;
+ break;
+ }
+ goto retry_bind;
+ case -EPFNOSUPPORT:
+ dprintk("RPC: %4d remote rpcbind service unavailable\n",
+ task->tk_pid);
+ break;
+ case -EPROTONOSUPPORT:
+ dprintk("RPC: %4d remote rpcbind version 2 unavailable\n",
+ task->tk_pid);
+ break;
+ default:
+ dprintk("RPC: %4d unrecognized rpcbind error (%d)\n",
+ task->tk_pid, -task->tk_status);
+ status = -EIO;
+ break;
+ }
+
+ rpc_exit(task, status);
+ return;
+
+retry_bind:
+ task->tk_status = 0;
+ task->tk_action = call_bind;
+ return;
+}
+
+/*
+ * 4b. Connect to the RPC server
*/
static void
call_connect(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
+ struct rpc_xprt *xprt = task->tk_xprt;
- dprintk("RPC: %4d call_connect status %d\n",
- task->tk_pid, task->tk_status);
+ dprintk("RPC: %4d call_connect xprt %p %s connected\n",
+ task->tk_pid, xprt,
+ (xprt_connected(xprt) ? "is" : "is not"));
- if (xprt_connected(clnt->cl_xprt)) {
- task->tk_action = call_transmit;
- return;
+ task->tk_action = call_transmit;
+ if (!xprt_connected(xprt)) {
+ task->tk_action = call_connect_status;
+ if (task->tk_status < 0)
+ return;
+ xprt_connect(task);
}
- task->tk_action = call_connect_status;
- if (task->tk_status < 0)
- return;
- xprt_connect(task);
}
/*
- * 4b. Sort out connect result
+ * 4c. Sort out connect result
*/
static void
call_connect_status(struct rpc_task *task)
@@ -778,6 +825,9 @@ call_connect_status(struct rpc_task *task)
struct rpc_clnt *clnt = task->tk_client;
int status = task->tk_status;
+ dprintk("RPC: %5u call_connect_status (status %d)\n",
+ task->tk_pid, task->tk_status);
+
task->tk_status = 0;
if (status >= 0) {
clnt->cl_stats->netreconn++;
@@ -785,17 +835,19 @@ call_connect_status(struct rpc_task *task)
return;
}
- /* Something failed: we may have to rebind */
+ /* Something failed: remote service port may have changed */
if (clnt->cl_autobind)
clnt->cl_port = 0;
+
switch (status) {
case -ENOTCONN:
case -ETIMEDOUT:
case -EAGAIN:
- task->tk_action = (clnt->cl_port == 0) ? call_bind : call_connect;
+ task->tk_action = call_bind;
break;
default:
rpc_exit(task, -EIO);
+ break;
}
}
@@ -815,10 +867,12 @@ call_transmit(struct rpc_task *task)
if (task->tk_status != 0)
return;
/* Encode here so that rpcsec_gss can use correct sequence number. */
- if (!task->tk_rqstp->rq_bytes_sent)
+ if (task->tk_rqstp->rq_bytes_sent == 0) {
call_encode(task);
- if (task->tk_status < 0)
- return;
+ /* Did the encode result in an error condition? */
+ if (task->tk_status != 0)
+ goto out_nosend;
+ }
xprt_transmit(task);
if (task->tk_status < 0)
return;
@@ -826,6 +880,10 @@ call_transmit(struct rpc_task *task)
task->tk_action = NULL;
rpc_wake_up_task(task);
}
+ return;
+out_nosend:
+ /* release socket write lock before attempting to handle error */
+ xprt_abort_transmit(task);
}
/*
@@ -1020,13 +1078,12 @@ static u32 *
call_header(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
- struct rpc_xprt *xprt = clnt->cl_xprt;
struct rpc_rqst *req = task->tk_rqstp;
u32 *p = req->rq_svec[0].iov_base;
/* FIXME: check buffer size? */
- if (xprt->stream)
- *p++ = 0; /* fill in later */
+
+ p = xprt_skip_transport_header(task->tk_xprt, p);
*p++ = req->rq_xid; /* XID */
*p++ = htonl(RPC_CALL); /* CALL */
*p++ = htonl(RPC_VERSION); /* RPC version */
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index 4e81f2766923..a398575f94b8 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -26,7 +26,7 @@
#define PMAP_GETPORT 3
static struct rpc_procinfo pmap_procedures[];
-static struct rpc_clnt * pmap_create(char *, struct sockaddr_in *, int);
+static struct rpc_clnt * pmap_create(char *, struct sockaddr_in *, int, int);
static void pmap_getport_done(struct rpc_task *);
static struct rpc_program pmap_program;
static DEFINE_SPINLOCK(pmap_lock);
@@ -65,7 +65,7 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
map->pm_binding = 1;
spin_unlock(&pmap_lock);
- pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot);
+ pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot, 0);
if (IS_ERR(pmap_clnt)) {
task->tk_status = PTR_ERR(pmap_clnt);
goto bailout;
@@ -112,7 +112,7 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
- pmap_clnt = pmap_create(hostname, sin, prot);
+ pmap_clnt = pmap_create(hostname, sin, prot, 0);
if (IS_ERR(pmap_clnt))
return PTR_ERR(pmap_clnt);
@@ -171,7 +171,7 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP);
+ pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1);
if (IS_ERR(pmap_clnt)) {
error = PTR_ERR(pmap_clnt);
dprintk("RPC: couldn't create pmap client. Error = %d\n", error);
@@ -198,7 +198,7 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
}
static struct rpc_clnt *
-pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
+pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged)
{
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
@@ -208,6 +208,8 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
if (IS_ERR(xprt))
return (struct rpc_clnt *)xprt;
xprt->addr.sin_port = htons(RPC_PMAP_PORT);
+ if (!privileged)
+ xprt->resvport = 0;
/* printk("pmap: create clnt\n"); */
clnt = rpc_new_client(xprt, hostname,
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index ded6c63f11ec..4f188d0a5d11 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -76,25 +76,35 @@ int
rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
{
struct rpc_inode *rpci = RPC_I(inode);
- int res = 0;
+ int res = -EPIPE;
down(&inode->i_sem);
+ if (rpci->ops == NULL)
+ goto out;
if (rpci->nreaders) {
list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len;
+ res = 0;
} else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
if (list_empty(&rpci->pipe))
schedule_delayed_work(&rpci->queue_timeout,
RPC_UPCALL_TIMEOUT);
list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len;
- } else
- res = -EPIPE;
+ res = 0;
+ }
+out:
up(&inode->i_sem);
wake_up(&rpci->waitq);
return res;
}
+static inline void
+rpc_inode_setowner(struct inode *inode, void *private)
+{
+ RPC_I(inode)->private = private;
+}
+
static void
rpc_close_pipes(struct inode *inode)
{
@@ -111,15 +121,10 @@ rpc_close_pipes(struct inode *inode)
rpci->ops->release_pipe(inode);
rpci->ops = NULL;
}
+ rpc_inode_setowner(inode, NULL);
up(&inode->i_sem);
}
-static inline void
-rpc_inode_setowner(struct inode *inode, void *private)
-{
- RPC_I(inode)->private = private;
-}
-
static struct inode *
rpc_alloc_inode(struct super_block *sb)
{
@@ -501,7 +506,6 @@ repeat:
dentry = dvec[--n];
if (dentry->d_inode) {
rpc_close_pipes(dentry->d_inode);
- rpc_inode_setowner(dentry->d_inode, NULL);
simple_unlink(dir, dentry);
}
dput(dentry);
@@ -576,10 +580,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
int error;
shrink_dcache_parent(dentry);
- if (dentry->d_inode) {
+ if (dentry->d_inode)
rpc_close_pipes(dentry->d_inode);
- rpc_inode_setowner(dentry->d_inode, NULL);
- }
if ((error = simple_rmdir(dir, dentry)) != 0)
return error;
if (!error) {
@@ -732,7 +734,6 @@ rpc_unlink(char *path)
d_drop(dentry);
if (dentry->d_inode) {
rpc_close_pipes(dentry->d_inode);
- rpc_inode_setowner(dentry->d_inode, NULL);
error = simple_unlink(dir, dentry);
}
dput(dentry);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index f3104035e35d..54e60a657500 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -719,7 +719,7 @@ static void rpc_async_schedule(void *arg)
void *
rpc_malloc(struct rpc_task *task, size_t size)
{
- int gfp;
+ gfp_t gfp;
if (task->tk_flags & RPC_TASK_SWAPPER)
gfp = GFP_ATOMIC;
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
new file mode 100644
index 000000000000..8f97e90f36c8
--- /dev/null
+++ b/net/sunrpc/socklib.c
@@ -0,0 +1,175 @@
+/*
+ * linux/net/sunrpc/socklib.c
+ *
+ * Common socket helper routines for RPC client and server
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/udp.h>
+#include <linux/sunrpc/xdr.h>
+
+
+/**
+ * skb_read_bits - copy some data bits from skb to internal buffer
+ * @desc: sk_buff copy helper
+ * @to: copy destination
+ * @len: number of bytes to copy
+ *
+ * Possibly called several times to iterate over an sk_buff and copy
+ * data out of it.
+ */
+static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
+{
+ if (len > desc->count)
+ len = desc->count;
+ if (skb_copy_bits(desc->skb, desc->offset, to, len))
+ return 0;
+ desc->count -= len;
+ desc->offset += len;
+ return len;
+}
+
+/**
+ * skb_read_and_csum_bits - copy and checksum from skb to buffer
+ * @desc: sk_buff copy helper
+ * @to: copy destination
+ * @len: number of bytes to copy
+ *
+ * Same as skb_read_bits, but calculate a checksum at the same time.
+ */
+static size_t skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
+{
+ unsigned int csum2, pos;
+
+ if (len > desc->count)
+ len = desc->count;
+ pos = desc->offset;
+ csum2 = skb_copy_and_csum_bits(desc->skb, pos, to, len, 0);
+ desc->csum = csum_block_add(desc->csum, csum2, pos);
+ desc->count -= len;
+ desc->offset += len;
+ return len;
+}
+
+/**
+ * xdr_partial_copy_from_skb - copy data out of an skb
+ * @xdr: target XDR buffer
+ * @base: starting offset
+ * @desc: sk_buff copy helper
+ * @copy_actor: virtual method for copying data
+ *
+ */
+ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, skb_reader_t *desc, skb_read_actor_t copy_actor)
+{
+ struct page **ppage = xdr->pages;
+ unsigned int len, pglen = xdr->page_len;
+ ssize_t copied = 0;
+ int ret;
+
+ len = xdr->head[0].iov_len;
+ if (base < len) {
+ len -= base;
+ ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
+ copied += ret;
+ if (ret != len || !desc->count)
+ goto out;
+ base = 0;
+ } else
+ base -= len;
+
+ if (unlikely(pglen == 0))
+ goto copy_tail;
+ if (unlikely(base >= pglen)) {
+ base -= pglen;
+ goto copy_tail;
+ }
+ if (base || xdr->page_base) {
+ pglen -= base;
+ base += xdr->page_base;
+ ppage += base >> PAGE_CACHE_SHIFT;
+ base &= ~PAGE_CACHE_MASK;
+ }
+ do {
+ char *kaddr;
+
+ /* ACL likes to be lazy in allocating pages - ACLs
+ * are small by default but can get huge. */
+ if (unlikely(*ppage == NULL)) {
+ *ppage = alloc_page(GFP_ATOMIC);
+ if (unlikely(*ppage == NULL)) {
+ if (copied == 0)
+ copied = -ENOMEM;
+ goto out;
+ }
+ }
+
+ len = PAGE_CACHE_SIZE;
+ kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
+ if (base) {
+ len -= base;
+ if (pglen < len)
+ len = pglen;
+ ret = copy_actor(desc, kaddr + base, len);
+ base = 0;
+ } else {
+ if (pglen < len)
+ len = pglen;
+ ret = copy_actor(desc, kaddr, len);
+ }
+ flush_dcache_page(*ppage);
+ kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
+ copied += ret;
+ if (ret != len || !desc->count)
+ goto out;
+ ppage++;
+ } while ((pglen -= len) != 0);
+copy_tail:
+ len = xdr->tail[0].iov_len;
+ if (base < len)
+ copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
+out:
+ return copied;
+}
+
+/**
+ * csum_partial_copy_to_xdr - checksum and copy data
+ * @xdr: target XDR buffer
+ * @skb: source skb
+ *
+ * We have set things up such that we perform the checksum of the UDP
+ * packet in parallel with the copies into the RPC client iovec. -DaveM
+ */
+int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
+{
+ skb_reader_t desc;
+
+ desc.skb = skb;
+ desc.offset = sizeof(struct udphdr);
+ desc.count = skb->len - desc.offset;
+
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+ goto no_checksum;
+
+ desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
+ if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
+ return -1;
+ if (desc.offset != skb->len) {
+ unsigned int csum2;
+ csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
+ desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
+ }
+ if (desc.count)
+ return -1;
+ if ((unsigned short)csum_fold(desc.csum))
+ return -1;
+ return 0;
+no_checksum:
+ if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
+ return -1;
+ if (desc.count)
+ return -1;
+ return 0;
+}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index ed48ff022d35..2387e7b823ff 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/socket.h>
#include <linux/sched.h>
#include <linux/uio.h>
#include <linux/unistd.h>
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 05fe2e735538..f16e7cdd6150 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -512,15 +512,14 @@ svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv)
static void
svc_udp_data_ready(struct sock *sk, int count)
{
- struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data);
+ struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data;
- if (!svsk)
- goto out;
- dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
- svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags));
- set_bit(SK_DATA, &svsk->sk_flags);
- svc_sock_enqueue(svsk);
- out:
+ if (svsk) {
+ dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
+ svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags));
+ set_bit(SK_DATA, &svsk->sk_flags);
+ svc_sock_enqueue(svsk);
+ }
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible(sk->sk_sleep);
}
@@ -540,7 +539,7 @@ svc_write_space(struct sock *sk)
}
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) {
- printk(KERN_WARNING "RPC svc_write_space: some sleeping on %p\n",
+ dprintk("RPC svc_write_space: someone sleeping on %p\n",
svsk);
wake_up_interruptible(sk->sk_sleep);
}
@@ -549,9 +548,6 @@ svc_write_space(struct sock *sk)
/*
* Receive a datagram from a UDP socket.
*/
-extern int
-csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb);
-
static int
svc_udp_recvfrom(struct svc_rqst *rqstp)
{
@@ -588,7 +584,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
struct timeval tv;
tv.tv_sec = xtime.tv_sec;
- tv.tv_usec = xtime.tv_nsec * 1000;
+ tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
skb_set_timestamp(skb, &tv);
/* Don't enable netstamp, sunrpc doesn't
need that much accuracy */
@@ -692,31 +688,29 @@ svc_udp_init(struct svc_sock *svsk)
static void
svc_tcp_listen_data_ready(struct sock *sk, int count_unused)
{
- struct svc_sock *svsk;
+ struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data;
dprintk("svc: socket %p TCP (listen) state change %d\n",
- sk, sk->sk_state);
+ sk, sk->sk_state);
- if (sk->sk_state != TCP_LISTEN) {
- /*
- * This callback may called twice when a new connection
- * is established as a child socket inherits everything
- * from a parent LISTEN socket.
- * 1) data_ready method of the parent socket will be called
- * when one of child sockets become ESTABLISHED.
- * 2) data_ready method of the child socket may be called
- * when it receives data before the socket is accepted.
- * In case of 2, we should ignore it silently.
- */
- goto out;
- }
- if (!(svsk = (struct svc_sock *) sk->sk_user_data)) {
- printk("svc: socket %p: no user data\n", sk);
- goto out;
+ /*
+ * This callback may called twice when a new connection
+ * is established as a child socket inherits everything
+ * from a parent LISTEN socket.
+ * 1) data_ready method of the parent socket will be called
+ * when one of child sockets become ESTABLISHED.
+ * 2) data_ready method of the child socket may be called
+ * when it receives data before the socket is accepted.
+ * In case of 2, we should ignore it silently.
+ */
+ if (sk->sk_state == TCP_LISTEN) {
+ if (svsk) {
+ set_bit(SK_CONN, &svsk->sk_flags);
+ svc_sock_enqueue(svsk);
+ } else
+ printk("svc: socket %p: no user data\n", sk);
}
- set_bit(SK_CONN, &svsk->sk_flags);
- svc_sock_enqueue(svsk);
- out:
+
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible_all(sk->sk_sleep);
}
@@ -727,18 +721,17 @@ svc_tcp_listen_data_ready(struct sock *sk, int count_unused)
static void
svc_tcp_state_change(struct sock *sk)
{
- struct svc_sock *svsk;
+ struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data;
dprintk("svc: socket %p TCP (connected) state change %d (svsk %p)\n",
- sk, sk->sk_state, sk->sk_user_data);
+ sk, sk->sk_state, sk->sk_user_data);
- if (!(svsk = (struct svc_sock *) sk->sk_user_data)) {
+ if (!svsk)
printk("svc: socket %p: no user data\n", sk);
- goto out;
+ else {
+ set_bit(SK_CLOSE, &svsk->sk_flags);
+ svc_sock_enqueue(svsk);
}
- set_bit(SK_CLOSE, &svsk->sk_flags);
- svc_sock_enqueue(svsk);
- out:
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible_all(sk->sk_sleep);
}
@@ -746,15 +739,14 @@ svc_tcp_state_change(struct sock *sk)
static void
svc_tcp_data_ready(struct sock *sk, int count)
{
- struct svc_sock * svsk;
+ struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data;
dprintk("svc: socket %p TCP data ready (svsk %p)\n",
- sk, sk->sk_user_data);
- if (!(svsk = (struct svc_sock *)(sk->sk_user_data)))
- goto out;
- set_bit(SK_DATA, &svsk->sk_flags);
- svc_sock_enqueue(svsk);
- out:
+ sk, sk->sk_user_data);
+ if (svsk) {
+ set_bit(SK_DATA, &svsk->sk_flags);
+ svc_sock_enqueue(svsk);
+ }
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible(sk->sk_sleep);
}
@@ -1170,8 +1162,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
while (rqstp->rq_arghi < pages) {
struct page *p = alloc_page(GFP_KERNEL);
if (!p) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ/2);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(500));
continue;
}
rqstp->rq_argpages[rqstp->rq_arghi++] = p;
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 1b9616a12e24..d0c9f460e411 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -119,8 +119,18 @@ done:
return 0;
}
+unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
+unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE;
+unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
+EXPORT_SYMBOL(xprt_min_resvport);
+unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
+EXPORT_SYMBOL(xprt_max_resvport);
+
+
static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
+static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
+static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
static ctl_table debug_table[] = {
{
@@ -177,6 +187,28 @@ static ctl_table debug_table[] = {
.extra1 = &min_slot_table_size,
.extra2 = &max_slot_table_size
},
+ {
+ .ctl_name = CTL_MIN_RESVPORT,
+ .procname = "min_resvport",
+ .data = &xprt_min_resvport,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &xprt_min_resvport_limit,
+ .extra2 = &xprt_max_resvport_limit
+ },
+ {
+ .ctl_name = CTL_MAX_RESVPORT,
+ .procname = "max_resvport",
+ .data = &xprt_max_resvport,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &xprt_min_resvport_limit,
+ .extra2 = &xprt_max_resvport_limit
+ },
{ .ctl_name = 0 }
};
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index fde16f40a581..32df43372ee9 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -6,15 +6,12 @@
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/module.h>
#include <linux/types.h>
-#include <linux/socket.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/net.h>
-#include <net/sock.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>
@@ -176,178 +173,6 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
xdr->buflen += len;
}
-ssize_t
-xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
- skb_reader_t *desc,
- skb_read_actor_t copy_actor)
-{
- struct page **ppage = xdr->pages;
- unsigned int len, pglen = xdr->page_len;
- ssize_t copied = 0;
- int ret;
-
- len = xdr->head[0].iov_len;
- if (base < len) {
- len -= base;
- ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
- copied += ret;
- if (ret != len || !desc->count)
- goto out;
- base = 0;
- } else
- base -= len;
-
- if (pglen == 0)
- goto copy_tail;
- if (base >= pglen) {
- base -= pglen;
- goto copy_tail;
- }
- if (base || xdr->page_base) {
- pglen -= base;
- base += xdr->page_base;
- ppage += base >> PAGE_CACHE_SHIFT;
- base &= ~PAGE_CACHE_MASK;
- }
- do {
- char *kaddr;
-
- /* ACL likes to be lazy in allocating pages - ACLs
- * are small by default but can get huge. */
- if (unlikely(*ppage == NULL)) {
- *ppage = alloc_page(GFP_ATOMIC);
- if (unlikely(*ppage == NULL)) {
- if (copied == 0)
- copied = -ENOMEM;
- goto out;
- }
- }
-
- len = PAGE_CACHE_SIZE;
- kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
- if (base) {
- len -= base;
- if (pglen < len)
- len = pglen;
- ret = copy_actor(desc, kaddr + base, len);
- base = 0;
- } else {
- if (pglen < len)
- len = pglen;
- ret = copy_actor(desc, kaddr, len);
- }
- flush_dcache_page(*ppage);
- kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
- copied += ret;
- if (ret != len || !desc->count)
- goto out;
- ppage++;
- } while ((pglen -= len) != 0);
-copy_tail:
- len = xdr->tail[0].iov_len;
- if (base < len)
- copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
-out:
- return copied;
-}
-
-
-int
-xdr_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
- struct xdr_buf *xdr, unsigned int base, int msgflags)
-{
- struct page **ppage = xdr->pages;
- unsigned int len, pglen = xdr->page_len;
- int err, ret = 0;
- ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
-
- len = xdr->head[0].iov_len;
- if (base < len || (addr != NULL && base == 0)) {
- struct kvec iov = {
- .iov_base = xdr->head[0].iov_base + base,
- .iov_len = len - base,
- };
- struct msghdr msg = {
- .msg_name = addr,
- .msg_namelen = addrlen,
- .msg_flags = msgflags,
- };
- if (xdr->len > len)
- msg.msg_flags |= MSG_MORE;
-
- if (iov.iov_len != 0)
- err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
- else
- err = kernel_sendmsg(sock, &msg, NULL, 0, 0);
- if (ret == 0)
- ret = err;
- else if (err > 0)
- ret += err;
- if (err != iov.iov_len)
- goto out;
- base = 0;
- } else
- base -= len;
-
- if (pglen == 0)
- goto copy_tail;
- if (base >= pglen) {
- base -= pglen;
- goto copy_tail;
- }
- if (base || xdr->page_base) {
- pglen -= base;
- base += xdr->page_base;
- ppage += base >> PAGE_CACHE_SHIFT;
- base &= ~PAGE_CACHE_MASK;
- }
-
- sendpage = sock->ops->sendpage ? : sock_no_sendpage;
- do {
- int flags = msgflags;
-
- len = PAGE_CACHE_SIZE;
- if (base)
- len -= base;
- if (pglen < len)
- len = pglen;
-
- if (pglen != len || xdr->tail[0].iov_len != 0)
- flags |= MSG_MORE;
-
- /* Hmm... We might be dealing with highmem pages */
- if (PageHighMem(*ppage))
- sendpage = sock_no_sendpage;
- err = sendpage(sock, *ppage, base, len, flags);
- if (ret == 0)
- ret = err;
- else if (err > 0)
- ret += err;
- if (err != len)
- goto out;
- base = 0;
- ppage++;
- } while ((pglen -= len) != 0);
-copy_tail:
- len = xdr->tail[0].iov_len;
- if (base < len) {
- struct kvec iov = {
- .iov_base = xdr->tail[0].iov_base + base,
- .iov_len = len - base,
- };
- struct msghdr msg = {
- .msg_flags = msgflags,
- };
- err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
- if (ret == 0)
- ret = err;
- else if (err > 0)
- ret += err;
- }
-out:
- return ret;
-}
-
/*
* Helper routines for doing 'memmove' like operations on a struct xdr_buf
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 3c654e06b084..6dda3860351f 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -10,12 +10,12 @@
* one is available. Otherwise, it sleeps on the backlog queue
* (xprt_reserve).
* - Next, the caller puts together the RPC message, stuffs it into
- * the request struct, and calls xprt_call().
- * - xprt_call transmits the message and installs the caller on the
- * socket's wait list. At the same time, it installs a timer that
+ * the request struct, and calls xprt_transmit().
+ * - xprt_transmit sends the message and installs the caller on the
+ * transport's wait list. At the same time, it installs a timer that
* is run after the packet's timeout has expired.
* - When a packet arrives, the data_ready handler walks the list of
- * pending requests for that socket. If a matching XID is found, the
+ * pending requests for that transport. If a matching XID is found, the
* caller is woken up, and the timer removed.
* - When no reply arrives within the timeout interval, the timer is
* fired by the kernel and runs xprt_timer(). It either adjusts the
@@ -33,36 +33,17 @@
*
* Copyright (C) 1995-1997, Olaf Kirch <okir@monad.swb.de>
*
- * TCP callback races fixes (C) 1998 Red Hat Software <alan@redhat.com>
- * TCP send fixes (C) 1998 Red Hat Software <alan@redhat.com>
- * TCP NFS related read + write fixes
- * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie>
- *
- * Rewrite of larges part of the code in order to stabilize TCP stuff.
- * Fix behaviour when socket buffer is full.
- * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no>
+ * Transport switch API copyright (C) 2005, Chuck Lever <cel@netapp.com>
*/
+#include <linux/module.h>
+
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/capability.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/net.h>
-#include <linux/mm.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/file.h>
+#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/random.h>
-#include <net/sock.h>
-#include <net/checksum.h>
-#include <net/udp.h>
-#include <net/tcp.h>
+#include <linux/sunrpc/clnt.h>
/*
* Local variables
@@ -73,81 +54,90 @@
# define RPCDBG_FACILITY RPCDBG_XPRT
#endif
-#define XPRT_MAX_BACKOFF (8)
-#define XPRT_IDLE_TIMEOUT (5*60*HZ)
-#define XPRT_MAX_RESVPORT (800)
-
/*
* Local functions
*/
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
static inline void do_xprt_reserve(struct rpc_task *);
-static void xprt_disconnect(struct rpc_xprt *);
static void xprt_connect_status(struct rpc_task *task);
-static struct rpc_xprt * xprt_setup(int proto, struct sockaddr_in *ap,
- struct rpc_timeout *to);
-static struct socket *xprt_create_socket(struct rpc_xprt *, int, int);
-static void xprt_bind_socket(struct rpc_xprt *, struct socket *);
static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
-static int xprt_clear_backlog(struct rpc_xprt *xprt);
-
-#ifdef RPC_DEBUG_DATA
/*
- * Print the buffer contents (first 128 bytes only--just enough for
- * diropres return).
+ * The transport code maintains an estimate on the maximum number of out-
+ * standing RPC requests, using a smoothed version of the congestion
+ * avoidance implemented in 44BSD. This is basically the Van Jacobson
+ * congestion algorithm: If a retransmit occurs, the congestion window is
+ * halved; otherwise, it is incremented by 1/cwnd when
+ *
+ * - a reply is received and
+ * - a full number of requests are outstanding and
+ * - the congestion window hasn't been updated recently.
*/
-static void
-xprt_pktdump(char *msg, u32 *packet, unsigned int count)
-{
- u8 *buf = (u8 *) packet;
- int j;
-
- dprintk("RPC: %s\n", msg);
- for (j = 0; j < count && j < 128; j += 4) {
- if (!(j & 31)) {
- if (j)
- dprintk("\n");
- dprintk("0x%04x ", j);
- }
- dprintk("%02x%02x%02x%02x ",
- buf[j], buf[j+1], buf[j+2], buf[j+3]);
- }
- dprintk("\n");
-}
-#else
-static inline void
-xprt_pktdump(char *msg, u32 *packet, unsigned int count)
-{
- /* NOP */
-}
-#endif
+#define RPC_CWNDSHIFT (8U)
+#define RPC_CWNDSCALE (1U << RPC_CWNDSHIFT)
+#define RPC_INITCWND RPC_CWNDSCALE
+#define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT)
-/*
- * Look up RPC transport given an INET socket
+#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
+
+/**
+ * xprt_reserve_xprt - serialize write access to transports
+ * @task: task that is requesting access to the transport
+ *
+ * This prevents mixing the payload of separate requests, and prevents
+ * transport connects from colliding with writes. No congestion control
+ * is provided.
*/
-static inline struct rpc_xprt *
-xprt_from_sock(struct sock *sk)
+int xprt_reserve_xprt(struct rpc_task *task)
{
- return (struct rpc_xprt *) sk->sk_user_data;
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_rqst *req = task->tk_rqstp;
+
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
+ if (task == xprt->snd_task)
+ return 1;
+ if (task == NULL)
+ return 0;
+ goto out_sleep;
+ }
+ xprt->snd_task = task;
+ if (req) {
+ req->rq_bytes_sent = 0;
+ req->rq_ntrans++;
+ }
+ return 1;
+
+out_sleep:
+ dprintk("RPC: %4d failed to lock transport %p\n",
+ task->tk_pid, xprt);
+ task->tk_timeout = 0;
+ task->tk_status = -EAGAIN;
+ if (req && req->rq_ntrans)
+ rpc_sleep_on(&xprt->resend, task, NULL, NULL);
+ else
+ rpc_sleep_on(&xprt->sending, task, NULL, NULL);
+ return 0;
}
/*
- * Serialize write access to sockets, in order to prevent different
- * requests from interfering with each other.
- * Also prevents TCP socket connects from colliding with writes.
+ * xprt_reserve_xprt_cong - serialize write access to transports
+ * @task: task that is requesting access to the transport
+ *
+ * Same as xprt_reserve_xprt, but Van Jacobson congestion control is
+ * integrated into the decision of whether a request is allowed to be
+ * woken up and given access to the transport.
*/
-static int
-__xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+int xprt_reserve_xprt_cong(struct rpc_task *task)
{
+ struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req = task->tk_rqstp;
- if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) {
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
if (task == xprt->snd_task)
return 1;
goto out_sleep;
}
- if (xprt->nocong || __xprt_get_cong(xprt, task)) {
+ if (__xprt_get_cong(xprt, task)) {
xprt->snd_task = task;
if (req) {
req->rq_bytes_sent = 0;
@@ -156,10 +146,10 @@ __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
return 1;
}
smp_mb__before_clear_bit();
- clear_bit(XPRT_LOCKED, &xprt->sockstate);
+ clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
out_sleep:
- dprintk("RPC: %4d failed to lock socket %p\n", task->tk_pid, xprt);
+ dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt);
task->tk_timeout = 0;
task->tk_status = -EAGAIN;
if (req && req->rq_ntrans)
@@ -169,26 +159,52 @@ out_sleep:
return 0;
}
-static inline int
-xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
int retval;
- spin_lock_bh(&xprt->sock_lock);
- retval = __xprt_lock_write(xprt, task);
- spin_unlock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
+ retval = xprt->ops->reserve_xprt(task);
+ spin_unlock_bh(&xprt->transport_lock);
return retval;
}
+static void __xprt_lock_write_next(struct rpc_xprt *xprt)
+{
+ struct rpc_task *task;
+ struct rpc_rqst *req;
-static void
-__xprt_lock_write_next(struct rpc_xprt *xprt)
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
+ return;
+
+ task = rpc_wake_up_next(&xprt->resend);
+ if (!task) {
+ task = rpc_wake_up_next(&xprt->sending);
+ if (!task)
+ goto out_unlock;
+ }
+
+ req = task->tk_rqstp;
+ xprt->snd_task = task;
+ if (req) {
+ req->rq_bytes_sent = 0;
+ req->rq_ntrans++;
+ }
+ return;
+
+out_unlock:
+ smp_mb__before_clear_bit();
+ clear_bit(XPRT_LOCKED, &xprt->state);
+ smp_mb__after_clear_bit();
+}
+
+static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
{
struct rpc_task *task;
- if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate))
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
return;
- if (!xprt->nocong && RPCXPRT_CONGESTED(xprt))
+ if (RPCXPRT_CONGESTED(xprt))
goto out_unlock;
task = rpc_wake_up_next(&xprt->resend);
if (!task) {
@@ -196,7 +212,7 @@ __xprt_lock_write_next(struct rpc_xprt *xprt)
if (!task)
goto out_unlock;
}
- if (xprt->nocong || __xprt_get_cong(xprt, task)) {
+ if (__xprt_get_cong(xprt, task)) {
struct rpc_rqst *req = task->tk_rqstp;
xprt->snd_task = task;
if (req) {
@@ -207,87 +223,52 @@ __xprt_lock_write_next(struct rpc_xprt *xprt)
}
out_unlock:
smp_mb__before_clear_bit();
- clear_bit(XPRT_LOCKED, &xprt->sockstate);
+ clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
}
-/*
- * Releases the socket for use by other requests.
+/**
+ * xprt_release_xprt - allow other requests to use a transport
+ * @xprt: transport with other tasks potentially waiting
+ * @task: task that is releasing access to the transport
+ *
+ * Note that "task" can be NULL. No congestion control is provided.
*/
-static void
-__xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
+void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
{
if (xprt->snd_task == task) {
xprt->snd_task = NULL;
smp_mb__before_clear_bit();
- clear_bit(XPRT_LOCKED, &xprt->sockstate);
+ clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
__xprt_lock_write_next(xprt);
}
}
-static inline void
-xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
-{
- spin_lock_bh(&xprt->sock_lock);
- __xprt_release_write(xprt, task);
- spin_unlock_bh(&xprt->sock_lock);
-}
-
-/*
- * Write data to socket.
+/**
+ * xprt_release_xprt_cong - allow other requests to use a transport
+ * @xprt: transport with other tasks potentially waiting
+ * @task: task that is releasing access to the transport
+ *
+ * Note that "task" can be NULL. Another task is awoken to use the
+ * transport if the transport's congestion window allows it.
*/
-static inline int
-xprt_sendmsg(struct rpc_xprt *xprt, struct rpc_rqst *req)
+void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
{
- struct socket *sock = xprt->sock;
- struct xdr_buf *xdr = &req->rq_snd_buf;
- struct sockaddr *addr = NULL;
- int addrlen = 0;
- unsigned int skip;
- int result;
-
- if (!sock)
- return -ENOTCONN;
-
- xprt_pktdump("packet data:",
- req->rq_svec->iov_base,
- req->rq_svec->iov_len);
-
- /* For UDP, we need to provide an address */
- if (!xprt->stream) {
- addr = (struct sockaddr *) &xprt->addr;
- addrlen = sizeof(xprt->addr);
+ if (xprt->snd_task == task) {
+ xprt->snd_task = NULL;
+ smp_mb__before_clear_bit();
+ clear_bit(XPRT_LOCKED, &xprt->state);
+ smp_mb__after_clear_bit();
+ __xprt_lock_write_next_cong(xprt);
}
- /* Dont repeat bytes */
- skip = req->rq_bytes_sent;
-
- clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
- result = xdr_sendpages(sock, addr, addrlen, xdr, skip, MSG_DONTWAIT);
-
- dprintk("RPC: xprt_sendmsg(%d) = %d\n", xdr->len - skip, result);
-
- if (result >= 0)
- return result;
+}
- switch (result) {
- case -ECONNREFUSED:
- /* When the server has died, an ICMP port unreachable message
- * prompts ECONNREFUSED.
- */
- case -EAGAIN:
- break;
- case -ECONNRESET:
- case -ENOTCONN:
- case -EPIPE:
- /* connection broken */
- if (xprt->stream)
- result = -ENOTCONN;
- break;
- default:
- printk(KERN_NOTICE "RPC: sendmsg returned error %d\n", -result);
- }
- return result;
+static inline void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
+{
+ spin_lock_bh(&xprt->transport_lock);
+ xprt->ops->release_xprt(xprt, task);
+ spin_unlock_bh(&xprt->transport_lock);
}
/*
@@ -321,26 +302,40 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
return;
req->rq_cong = 0;
xprt->cong -= RPC_CWNDSCALE;
- __xprt_lock_write_next(xprt);
+ __xprt_lock_write_next_cong(xprt);
}
-/*
- * Adjust RPC congestion window
+/**
+ * xprt_release_rqst_cong - housekeeping when request is complete
+ * @task: RPC request that recently completed
+ *
+ * Useful for transports that require congestion control.
+ */
+void xprt_release_rqst_cong(struct rpc_task *task)
+{
+ __xprt_put_cong(task->tk_xprt, task->tk_rqstp);
+}
+
+/**
+ * xprt_adjust_cwnd - adjust transport congestion window
+ * @task: recently completed RPC request used to adjust window
+ * @result: result code of completed RPC request
+ *
* We use a time-smoothed congestion estimator to avoid heavy oscillation.
*/
-static void
-xprt_adjust_cwnd(struct rpc_xprt *xprt, int result)
+void xprt_adjust_cwnd(struct rpc_task *task, int result)
{
- unsigned long cwnd;
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = task->tk_xprt;
+ unsigned long cwnd = xprt->cwnd;
- cwnd = xprt->cwnd;
if (result >= 0 && cwnd <= xprt->cong) {
/* The (cwnd >> 1) term makes sure
* the result gets rounded properly. */
cwnd += (RPC_CWNDSCALE * RPC_CWNDSCALE + (cwnd >> 1)) / cwnd;
if (cwnd > RPC_MAXCWND(xprt))
cwnd = RPC_MAXCWND(xprt);
- __xprt_lock_write_next(xprt);
+ __xprt_lock_write_next_cong(xprt);
} else if (result == -ETIMEDOUT) {
cwnd >>= 1;
if (cwnd < RPC_CWNDSCALE)
@@ -349,11 +344,89 @@ xprt_adjust_cwnd(struct rpc_xprt *xprt, int result)
dprintk("RPC: cong %ld, cwnd was %ld, now %ld\n",
xprt->cong, xprt->cwnd, cwnd);
xprt->cwnd = cwnd;
+ __xprt_put_cong(xprt, req);
+}
+
+/**
+ * xprt_wake_pending_tasks - wake all tasks on a transport's pending queue
+ * @xprt: transport with waiting tasks
+ * @status: result code to plant in each task before waking it
+ *
+ */
+void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status)
+{
+ if (status < 0)
+ rpc_wake_up_status(&xprt->pending, status);
+ else
+ rpc_wake_up(&xprt->pending);
+}
+
+/**
+ * xprt_wait_for_buffer_space - wait for transport output buffer to clear
+ * @task: task to be put to sleep
+ *
+ */
+void xprt_wait_for_buffer_space(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+
+ task->tk_timeout = req->rq_timeout;
+ rpc_sleep_on(&xprt->pending, task, NULL, NULL);
+}
+
+/**
+ * xprt_write_space - wake the task waiting for transport output buffer space
+ * @xprt: transport with waiting tasks
+ *
+ * Can be called in a soft IRQ context, so xprt_write_space never sleeps.
+ */
+void xprt_write_space(struct rpc_xprt *xprt)
+{
+ if (unlikely(xprt->shutdown))
+ return;
+
+ spin_lock_bh(&xprt->transport_lock);
+ if (xprt->snd_task) {
+ dprintk("RPC: write space: waking waiting task on xprt %p\n",
+ xprt);
+ rpc_wake_up_task(xprt->snd_task);
+ }
+ spin_unlock_bh(&xprt->transport_lock);
+}
+
+/**
+ * xprt_set_retrans_timeout_def - set a request's retransmit timeout
+ * @task: task whose timeout is to be set
+ *
+ * Set a request's retransmit timeout based on the transport's
+ * default timeout parameters. Used by transports that don't adjust
+ * the retransmit timeout based on round-trip time estimation.
+ */
+void xprt_set_retrans_timeout_def(struct rpc_task *task)
+{
+ task->tk_timeout = task->tk_rqstp->rq_timeout;
}
/*
- * Reset the major timeout value
+ * xprt_set_retrans_timeout_rtt - set a request's retransmit timeout
+ * @task: task whose timeout is to be set
+ *
+ * Set a request's retransmit timeout using the RTT estimator.
*/
+void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
+{
+ int timer = task->tk_msg.rpc_proc->p_timer;
+ struct rpc_rtt *rtt = task->tk_client->cl_rtt;
+ struct rpc_rqst *req = task->tk_rqstp;
+ unsigned long max_timeout = req->rq_xprt->timeout.to_maxval;
+
+ task->tk_timeout = rpc_calc_rto(rtt, timer);
+ task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries;
+ if (task->tk_timeout > max_timeout || task->tk_timeout == 0)
+ task->tk_timeout = max_timeout;
+}
+
static void xprt_reset_majortimeo(struct rpc_rqst *req)
{
struct rpc_timeout *to = &req->rq_xprt->timeout;
@@ -368,8 +441,10 @@ static void xprt_reset_majortimeo(struct rpc_rqst *req)
req->rq_majortimeo += jiffies;
}
-/*
- * Adjust timeout values etc for next retransmit
+/**
+ * xprt_adjust_timeout - adjust timeout values for next retransmit
+ * @req: RPC request containing parameters to use for the adjustment
+ *
*/
int xprt_adjust_timeout(struct rpc_rqst *req)
{
@@ -391,9 +466,9 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
req->rq_retries = 0;
xprt_reset_majortimeo(req);
/* Reset the RTT counters == "slow start" */
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval);
- spin_unlock_bh(&xprt->sock_lock);
+ spin_unlock_bh(&xprt->transport_lock);
pprintk("RPC: %lu timeout\n", jiffies);
status = -ETIMEDOUT;
}
@@ -405,133 +480,52 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
return status;
}
-/*
- * Close down a transport socket
- */
-static void
-xprt_close(struct rpc_xprt *xprt)
-{
- struct socket *sock = xprt->sock;
- struct sock *sk = xprt->inet;
-
- if (!sk)
- return;
-
- write_lock_bh(&sk->sk_callback_lock);
- xprt->inet = NULL;
- xprt->sock = NULL;
-
- sk->sk_user_data = NULL;
- sk->sk_data_ready = xprt->old_data_ready;
- sk->sk_state_change = xprt->old_state_change;
- sk->sk_write_space = xprt->old_write_space;
- write_unlock_bh(&sk->sk_callback_lock);
-
- sk->sk_no_check = 0;
-
- sock_release(sock);
-}
-
-static void
-xprt_socket_autoclose(void *args)
+static void xprt_autoclose(void *args)
{
struct rpc_xprt *xprt = (struct rpc_xprt *)args;
xprt_disconnect(xprt);
- xprt_close(xprt);
+ xprt->ops->close(xprt);
xprt_release_write(xprt, NULL);
}
-/*
- * Mark a transport as disconnected
+/**
+ * xprt_disconnect - mark a transport as disconnected
+ * @xprt: transport to flag for disconnect
+ *
*/
-static void
-xprt_disconnect(struct rpc_xprt *xprt)
+void xprt_disconnect(struct rpc_xprt *xprt)
{
dprintk("RPC: disconnected transport %p\n", xprt);
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
xprt_clear_connected(xprt);
- rpc_wake_up_status(&xprt->pending, -ENOTCONN);
- spin_unlock_bh(&xprt->sock_lock);
+ xprt_wake_pending_tasks(xprt, -ENOTCONN);
+ spin_unlock_bh(&xprt->transport_lock);
}
-/*
- * Used to allow disconnection when we've been idle
- */
static void
xprt_init_autodisconnect(unsigned long data)
{
struct rpc_xprt *xprt = (struct rpc_xprt *)data;
- spin_lock(&xprt->sock_lock);
+ spin_lock(&xprt->transport_lock);
if (!list_empty(&xprt->recv) || xprt->shutdown)
goto out_abort;
- if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate))
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
goto out_abort;
- spin_unlock(&xprt->sock_lock);
- /* Let keventd close the socket */
- if (test_bit(XPRT_CONNECTING, &xprt->sockstate) != 0)
+ spin_unlock(&xprt->transport_lock);
+ if (xprt_connecting(xprt))
xprt_release_write(xprt, NULL);
else
schedule_work(&xprt->task_cleanup);
return;
out_abort:
- spin_unlock(&xprt->sock_lock);
-}
-
-static void xprt_socket_connect(void *args)
-{
- struct rpc_xprt *xprt = (struct rpc_xprt *)args;
- struct socket *sock = xprt->sock;
- int status = -EIO;
-
- if (xprt->shutdown || xprt->addr.sin_port == 0)
- goto out;
-
- /*
- * Start by resetting any existing state
- */
- xprt_close(xprt);
- sock = xprt_create_socket(xprt, xprt->prot, xprt->resvport);
- if (sock == NULL) {
- /* couldn't create socket or bind to reserved port;
- * this is likely a permanent error, so cause an abort */
- goto out;
- }
- xprt_bind_socket(xprt, sock);
- xprt_sock_setbufsize(xprt);
-
- status = 0;
- if (!xprt->stream)
- goto out;
-
- /*
- * Tell the socket layer to start connecting...
- */
- status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
- sizeof(xprt->addr), O_NONBLOCK);
- dprintk("RPC: %p connect status %d connected %d sock state %d\n",
- xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
- if (status < 0) {
- switch (status) {
- case -EINPROGRESS:
- case -EALREADY:
- goto out_clear;
- }
- }
-out:
- if (status < 0)
- rpc_wake_up_status(&xprt->pending, status);
- else
- rpc_wake_up(&xprt->pending);
-out_clear:
- smp_mb__before_clear_bit();
- clear_bit(XPRT_CONNECTING, &xprt->sockstate);
- smp_mb__after_clear_bit();
+ spin_unlock(&xprt->transport_lock);
}
-/*
- * Attempt to connect a TCP socket.
+/**
+ * xprt_connect - schedule a transport connect operation
+ * @task: RPC task that is requesting the connect
*
*/
void xprt_connect(struct rpc_task *task)
@@ -552,37 +546,19 @@ void xprt_connect(struct rpc_task *task)
if (!xprt_lock_write(xprt, task))
return;
if (xprt_connected(xprt))
- goto out_write;
+ xprt_release_write(xprt, task);
+ else {
+ if (task->tk_rqstp)
+ task->tk_rqstp->rq_bytes_sent = 0;
- if (task->tk_rqstp)
- task->tk_rqstp->rq_bytes_sent = 0;
-
- task->tk_timeout = RPC_CONNECT_TIMEOUT;
- rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
- if (!test_and_set_bit(XPRT_CONNECTING, &xprt->sockstate)) {
- /* Note: if we are here due to a dropped connection
- * we delay reconnecting by RPC_REESTABLISH_TIMEOUT/HZ
- * seconds
- */
- if (xprt->sock != NULL)
- schedule_delayed_work(&xprt->sock_connect,
- RPC_REESTABLISH_TIMEOUT);
- else {
- schedule_work(&xprt->sock_connect);
- if (!RPC_IS_ASYNC(task))
- flush_scheduled_work();
- }
+ task->tk_timeout = xprt->connect_timeout;
+ rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
+ xprt->ops->connect(task);
}
return;
- out_write:
- xprt_release_write(xprt, task);
}
-/*
- * We arrive here when awoken from waiting on connection establishment.
- */
-static void
-xprt_connect_status(struct rpc_task *task)
+static void xprt_connect_status(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
@@ -592,31 +568,42 @@ xprt_connect_status(struct rpc_task *task)
return;
}
- /* if soft mounted, just cause this RPC to fail */
- if (RPC_IS_SOFT(task))
- task->tk_status = -EIO;
-
switch (task->tk_status) {
case -ECONNREFUSED:
case -ECONNRESET:
+ dprintk("RPC: %4d xprt_connect_status: server %s refused connection\n",
+ task->tk_pid, task->tk_client->cl_server);
+ break;
case -ENOTCONN:
- return;
+ dprintk("RPC: %4d xprt_connect_status: connection broken\n",
+ task->tk_pid);
+ break;
case -ETIMEDOUT:
- dprintk("RPC: %4d xprt_connect_status: timed out\n",
+ dprintk("RPC: %4d xprt_connect_status: connect attempt timed out\n",
task->tk_pid);
break;
default:
- printk(KERN_ERR "RPC: error %d connecting to server %s\n",
- -task->tk_status, task->tk_client->cl_server);
+ dprintk("RPC: %4d xprt_connect_status: error %d connecting to server %s\n",
+ task->tk_pid, -task->tk_status, task->tk_client->cl_server);
+ xprt_release_write(xprt, task);
+ task->tk_status = -EIO;
+ return;
+ }
+
+ /* if soft mounted, just cause this RPC to fail */
+ if (RPC_IS_SOFT(task)) {
+ xprt_release_write(xprt, task);
+ task->tk_status = -EIO;
}
- xprt_release_write(xprt, task);
}
-/*
- * Look up the RPC request corresponding to a reply, and then lock it.
+/**
+ * xprt_lookup_rqst - find an RPC request corresponding to an XID
+ * @xprt: transport on which the original request was transmitted
+ * @xid: RPC XID of incoming reply
+ *
*/
-static inline struct rpc_rqst *
-xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
+struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
{
struct list_head *pos;
struct rpc_rqst *req = NULL;
@@ -631,556 +618,68 @@ xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
return req;
}
-/*
- * Complete reply received.
- * The TCP code relies on us to remove the request from xprt->pending.
- */
-static void
-xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
-{
- struct rpc_task *task = req->rq_task;
- struct rpc_clnt *clnt = task->tk_client;
-
- /* Adjust congestion window */
- if (!xprt->nocong) {
- unsigned timer = task->tk_msg.rpc_proc->p_timer;
- xprt_adjust_cwnd(xprt, copied);
- __xprt_put_cong(xprt, req);
- if (timer) {
- if (req->rq_ntrans == 1)
- rpc_update_rtt(clnt->cl_rtt, timer,
- (long)jiffies - req->rq_xtime);
- rpc_set_timeo(clnt->cl_rtt, timer, req->rq_ntrans - 1);
- }
- }
-
-#ifdef RPC_PROFILE
- /* Profile only reads for now */
- if (copied > 1024) {
- static unsigned long nextstat;
- static unsigned long pkt_rtt, pkt_len, pkt_cnt;
-
- pkt_cnt++;
- pkt_len += req->rq_slen + copied;
- pkt_rtt += jiffies - req->rq_xtime;
- if (time_before(nextstat, jiffies)) {
- printk("RPC: %lu %ld cwnd\n", jiffies, xprt->cwnd);
- printk("RPC: %ld %ld %ld %ld stat\n",
- jiffies, pkt_cnt, pkt_len, pkt_rtt);
- pkt_rtt = pkt_len = pkt_cnt = 0;
- nextstat = jiffies + 5 * HZ;
- }
- }
-#endif
-
- dprintk("RPC: %4d has input (%d bytes)\n", task->tk_pid, copied);
- list_del_init(&req->rq_list);
- req->rq_received = req->rq_private_buf.len = copied;
-
- /* ... and wake up the process. */
- rpc_wake_up_task(task);
- return;
-}
-
-static size_t
-skb_read_bits(skb_reader_t *desc, void *to, size_t len)
-{
- if (len > desc->count)
- len = desc->count;
- if (skb_copy_bits(desc->skb, desc->offset, to, len))
- return 0;
- desc->count -= len;
- desc->offset += len;
- return len;
-}
-
-static size_t
-skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
-{
- unsigned int csum2, pos;
-
- if (len > desc->count)
- len = desc->count;
- pos = desc->offset;
- csum2 = skb_copy_and_csum_bits(desc->skb, pos, to, len, 0);
- desc->csum = csum_block_add(desc->csum, csum2, pos);
- desc->count -= len;
- desc->offset += len;
- return len;
-}
-
-/*
- * We have set things up such that we perform the checksum of the UDP
- * packet in parallel with the copies into the RPC client iovec. -DaveM
- */
-int
-csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
-{
- skb_reader_t desc;
-
- desc.skb = skb;
- desc.offset = sizeof(struct udphdr);
- desc.count = skb->len - desc.offset;
-
- if (skb->ip_summed == CHECKSUM_UNNECESSARY)
- goto no_checksum;
-
- desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
- if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
- return -1;
- if (desc.offset != skb->len) {
- unsigned int csum2;
- csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
- desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
- }
- if (desc.count)
- return -1;
- if ((unsigned short)csum_fold(desc.csum))
- return -1;
- return 0;
-no_checksum:
- if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
- return -1;
- if (desc.count)
- return -1;
- return 0;
-}
-
-/*
- * Input handler for RPC replies. Called from a bottom half and hence
- * atomic.
- */
-static void
-udp_data_ready(struct sock *sk, int len)
-{
- struct rpc_task *task;
- struct rpc_xprt *xprt;
- struct rpc_rqst *rovr;
- struct sk_buff *skb;
- int err, repsize, copied;
- u32 _xid, *xp;
-
- read_lock(&sk->sk_callback_lock);
- dprintk("RPC: udp_data_ready...\n");
- if (!(xprt = xprt_from_sock(sk))) {
- printk("RPC: udp_data_ready request not found!\n");
- goto out;
- }
-
- dprintk("RPC: udp_data_ready client %p\n", xprt);
-
- if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
- goto out;
-
- if (xprt->shutdown)
- goto dropit;
-
- repsize = skb->len - sizeof(struct udphdr);
- if (repsize < 4) {
- printk("RPC: impossible RPC reply size %d!\n", repsize);
- goto dropit;
- }
-
- /* Copy the XID from the skb... */
- xp = skb_header_pointer(skb, sizeof(struct udphdr),
- sizeof(_xid), &_xid);
- if (xp == NULL)
- goto dropit;
-
- /* Look up and lock the request corresponding to the given XID */
- spin_lock(&xprt->sock_lock);
- rovr = xprt_lookup_rqst(xprt, *xp);
- if (!rovr)
- goto out_unlock;
- task = rovr->rq_task;
-
- dprintk("RPC: %4d received reply\n", task->tk_pid);
-
- if ((copied = rovr->rq_private_buf.buflen) > repsize)
- copied = repsize;
-
- /* Suck it into the iovec, verify checksum if not done by hw. */
- if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
- goto out_unlock;
-
- /* Something worked... */
- dst_confirm(skb->dst);
-
- xprt_complete_rqst(xprt, rovr, copied);
-
- out_unlock:
- spin_unlock(&xprt->sock_lock);
- dropit:
- skb_free_datagram(sk, skb);
- out:
- read_unlock(&sk->sk_callback_lock);
-}
-
-/*
- * Copy from an skb into memory and shrink the skb.
- */
-static inline size_t
-tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
-{
- if (len > desc->count)
- len = desc->count;
- if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
- dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
- len, desc->count);
- return 0;
- }
- desc->offset += len;
- desc->count -= len;
- dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
- len, desc->count);
- return len;
-}
-
-/*
- * TCP read fragment marker
- */
-static inline void
-tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- size_t len, used;
- char *p;
-
- p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
- len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
- used = tcp_copy_data(desc, p, len);
- xprt->tcp_offset += used;
- if (used != len)
- return;
- xprt->tcp_reclen = ntohl(xprt->tcp_recm);
- if (xprt->tcp_reclen & 0x80000000)
- xprt->tcp_flags |= XPRT_LAST_FRAG;
- else
- xprt->tcp_flags &= ~XPRT_LAST_FRAG;
- xprt->tcp_reclen &= 0x7fffffff;
- xprt->tcp_flags &= ~XPRT_COPY_RECM;
- xprt->tcp_offset = 0;
- /* Sanity check of the record length */
- if (xprt->tcp_reclen < 4) {
- printk(KERN_ERR "RPC: Invalid TCP record fragment length\n");
- xprt_disconnect(xprt);
- }
- dprintk("RPC: reading TCP record fragment of length %d\n",
- xprt->tcp_reclen);
-}
-
-static void
-tcp_check_recm(struct rpc_xprt *xprt)
-{
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
- if (xprt->tcp_offset == xprt->tcp_reclen) {
- xprt->tcp_flags |= XPRT_COPY_RECM;
- xprt->tcp_offset = 0;
- if (xprt->tcp_flags & XPRT_LAST_FRAG) {
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- xprt->tcp_flags |= XPRT_COPY_XID;
- xprt->tcp_copied = 0;
- }
- }
-}
-
-/*
- * TCP read xid
- */
-static inline void
-tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- size_t len, used;
- char *p;
-
- len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
- dprintk("RPC: reading XID (%Zu bytes)\n", len);
- p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
- used = tcp_copy_data(desc, p, len);
- xprt->tcp_offset += used;
- if (used != len)
- return;
- xprt->tcp_flags &= ~XPRT_COPY_XID;
- xprt->tcp_flags |= XPRT_COPY_DATA;
- xprt->tcp_copied = 4;
- dprintk("RPC: reading reply for XID %08x\n",
- ntohl(xprt->tcp_xid));
- tcp_check_recm(xprt);
-}
-
-/*
- * TCP read and complete request
- */
-static inline void
-tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- struct rpc_rqst *req;
- struct xdr_buf *rcvbuf;
- size_t len;
- ssize_t r;
-
- /* Find and lock the request corresponding to this xid */
- spin_lock(&xprt->sock_lock);
- req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
- if (!req) {
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- dprintk("RPC: XID %08x request not found!\n",
- ntohl(xprt->tcp_xid));
- spin_unlock(&xprt->sock_lock);
- return;
- }
-
- rcvbuf = &req->rq_private_buf;
- len = desc->count;
- if (len > xprt->tcp_reclen - xprt->tcp_offset) {
- skb_reader_t my_desc;
-
- len = xprt->tcp_reclen - xprt->tcp_offset;
- memcpy(&my_desc, desc, sizeof(my_desc));
- my_desc.count = len;
- r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
- &my_desc, tcp_copy_data);
- desc->count -= r;
- desc->offset += r;
- } else
- r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
- desc, tcp_copy_data);
-
- if (r > 0) {
- xprt->tcp_copied += r;
- xprt->tcp_offset += r;
- }
- if (r != len) {
- /* Error when copying to the receive buffer,
- * usually because we weren't able to allocate
- * additional buffer pages. All we can do now
- * is turn off XPRT_COPY_DATA, so the request
- * will not receive any additional updates,
- * and time out.
- * Any remaining data from this record will
- * be discarded.
- */
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- dprintk("RPC: XID %08x truncated request\n",
- ntohl(xprt->tcp_xid));
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
- goto out;
- }
-
- dprintk("RPC: XID %08x read %Zd bytes\n",
- ntohl(xprt->tcp_xid), r);
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
-
- if (xprt->tcp_copied == req->rq_private_buf.buflen)
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- else if (xprt->tcp_offset == xprt->tcp_reclen) {
- if (xprt->tcp_flags & XPRT_LAST_FRAG)
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- }
-
-out:
- if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
- dprintk("RPC: %4d received reply complete\n",
- req->rq_task->tk_pid);
- xprt_complete_rqst(xprt, req, xprt->tcp_copied);
- }
- spin_unlock(&xprt->sock_lock);
- tcp_check_recm(xprt);
-}
-
-/*
- * TCP discard extra bytes from a short read
- */
-static inline void
-tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- size_t len;
-
- len = xprt->tcp_reclen - xprt->tcp_offset;
- if (len > desc->count)
- len = desc->count;
- desc->count -= len;
- desc->offset += len;
- xprt->tcp_offset += len;
- dprintk("RPC: discarded %Zu bytes\n", len);
- tcp_check_recm(xprt);
-}
-
-/*
- * TCP record receive routine
- * We first have to grab the record marker, then the XID, then the data.
+/**
+ * xprt_update_rtt - update an RPC client's RTT state after receiving a reply
+ * @task: RPC request that recently completed
+ *
*/
-static int
-tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
- unsigned int offset, size_t len)
-{
- struct rpc_xprt *xprt = rd_desc->arg.data;
- skb_reader_t desc = {
- .skb = skb,
- .offset = offset,
- .count = len,
- .csum = 0
- };
-
- dprintk("RPC: tcp_data_recv\n");
- do {
- /* Read in a new fragment marker if necessary */
- /* Can we ever really expect to get completely empty fragments? */
- if (xprt->tcp_flags & XPRT_COPY_RECM) {
- tcp_read_fraghdr(xprt, &desc);
- continue;
- }
- /* Read in the xid if necessary */
- if (xprt->tcp_flags & XPRT_COPY_XID) {
- tcp_read_xid(xprt, &desc);
- continue;
- }
- /* Read in the request data */
- if (xprt->tcp_flags & XPRT_COPY_DATA) {
- tcp_read_request(xprt, &desc);
- continue;
- }
- /* Skip over any trailing bytes on short reads */
- tcp_read_discard(xprt, &desc);
- } while (desc.count);
- dprintk("RPC: tcp_data_recv done\n");
- return len - desc.count;
-}
-
-static void tcp_data_ready(struct sock *sk, int bytes)
+void xprt_update_rtt(struct rpc_task *task)
{
- struct rpc_xprt *xprt;
- read_descriptor_t rd_desc;
-
- read_lock(&sk->sk_callback_lock);
- dprintk("RPC: tcp_data_ready...\n");
- if (!(xprt = xprt_from_sock(sk))) {
- printk("RPC: tcp_data_ready socket info not found!\n");
- goto out;
- }
- if (xprt->shutdown)
- goto out;
-
- /* We use rd_desc to pass struct xprt to tcp_data_recv */
- rd_desc.arg.data = xprt;
- rd_desc.count = 65536;
- tcp_read_sock(sk, &rd_desc, tcp_data_recv);
-out:
- read_unlock(&sk->sk_callback_lock);
-}
-
-static void
-tcp_state_change(struct sock *sk)
-{
- struct rpc_xprt *xprt;
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_rtt *rtt = task->tk_client->cl_rtt;
+ unsigned timer = task->tk_msg.rpc_proc->p_timer;
- read_lock(&sk->sk_callback_lock);
- if (!(xprt = xprt_from_sock(sk)))
- goto out;
- dprintk("RPC: tcp_state_change client %p...\n", xprt);
- dprintk("RPC: state %x conn %d dead %d zapped %d\n",
- sk->sk_state, xprt_connected(xprt),
- sock_flag(sk, SOCK_DEAD),
- sock_flag(sk, SOCK_ZAPPED));
-
- switch (sk->sk_state) {
- case TCP_ESTABLISHED:
- spin_lock_bh(&xprt->sock_lock);
- if (!xprt_test_and_set_connected(xprt)) {
- /* Reset TCP record info */
- xprt->tcp_offset = 0;
- xprt->tcp_reclen = 0;
- xprt->tcp_copied = 0;
- xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
- rpc_wake_up(&xprt->pending);
- }
- spin_unlock_bh(&xprt->sock_lock);
- break;
- case TCP_SYN_SENT:
- case TCP_SYN_RECV:
- break;
- default:
- xprt_disconnect(xprt);
- break;
+ if (timer) {
+ if (req->rq_ntrans == 1)
+ rpc_update_rtt(rtt, timer,
+ (long)jiffies - req->rq_xtime);
+ rpc_set_timeo(rtt, timer, req->rq_ntrans - 1);
}
- out:
- read_unlock(&sk->sk_callback_lock);
}
-/*
- * Called when more output buffer space is available for this socket.
- * We try not to wake our writers until they can make "significant"
- * progress, otherwise we'll waste resources thrashing sock_sendmsg
- * with a bunch of small requests.
+/**
+ * xprt_complete_rqst - called when reply processing is complete
+ * @task: RPC request that recently completed
+ * @copied: actual number of bytes received from the transport
+ *
+ * Caller holds transport lock.
*/
-static void
-xprt_write_space(struct sock *sk)
+void xprt_complete_rqst(struct rpc_task *task, int copied)
{
- struct rpc_xprt *xprt;
- struct socket *sock;
-
- read_lock(&sk->sk_callback_lock);
- if (!(xprt = xprt_from_sock(sk)) || !(sock = sk->sk_socket))
- goto out;
- if (xprt->shutdown)
- goto out;
-
- /* Wait until we have enough socket memory */
- if (xprt->stream) {
- /* from net/core/stream.c:sk_stream_write_space */
- if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
- goto out;
- } else {
- /* from net/core/sock.c:sock_def_write_space */
- if (!sock_writeable(sk))
- goto out;
- }
+ struct rpc_rqst *req = task->tk_rqstp;
- if (!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))
- goto out;
+ dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
+ task->tk_pid, ntohl(req->rq_xid), copied);
- spin_lock_bh(&xprt->sock_lock);
- if (xprt->snd_task)
- rpc_wake_up_task(xprt->snd_task);
- spin_unlock_bh(&xprt->sock_lock);
-out:
- read_unlock(&sk->sk_callback_lock);
+ list_del_init(&req->rq_list);
+ req->rq_received = req->rq_private_buf.len = copied;
+ rpc_wake_up_task(task);
}
-/*
- * RPC receive timeout handler.
- */
-static void
-xprt_timer(struct rpc_task *task)
+static void xprt_timer(struct rpc_task *task)
{
- struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
- spin_lock(&xprt->sock_lock);
- if (req->rq_received)
- goto out;
-
- xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT);
- __xprt_put_cong(xprt, req);
+ dprintk("RPC: %4d xprt_timer\n", task->tk_pid);
- dprintk("RPC: %4d xprt_timer (%s request)\n",
- task->tk_pid, req ? "pending" : "backlogged");
-
- task->tk_status = -ETIMEDOUT;
-out:
+ spin_lock(&xprt->transport_lock);
+ if (!req->rq_received) {
+ if (xprt->ops->timer)
+ xprt->ops->timer(task);
+ task->tk_status = -ETIMEDOUT;
+ }
task->tk_timeout = 0;
rpc_wake_up_task(task);
- spin_unlock(&xprt->sock_lock);
+ spin_unlock(&xprt->transport_lock);
}
-/*
- * Place the actual RPC call.
- * We have to copy the iovec because sendmsg fiddles with its contents.
+/**
+ * xprt_prepare_transmit - reserve the transport before sending a request
+ * @task: RPC task about to send a request
+ *
*/
-int
-xprt_prepare_transmit(struct rpc_task *task)
+int xprt_prepare_transmit(struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
@@ -1191,12 +690,12 @@ xprt_prepare_transmit(struct rpc_task *task)
if (xprt->shutdown)
return -EIO;
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
if (req->rq_received && !req->rq_bytes_sent) {
err = req->rq_received;
goto out_unlock;
}
- if (!__xprt_lock_write(xprt, task)) {
+ if (!xprt->ops->reserve_xprt(task)) {
err = -EAGAIN;
goto out_unlock;
}
@@ -1206,39 +705,42 @@ xprt_prepare_transmit(struct rpc_task *task)
goto out_unlock;
}
out_unlock:
- spin_unlock_bh(&xprt->sock_lock);
+ spin_unlock_bh(&xprt->transport_lock);
return err;
}
void
-xprt_transmit(struct rpc_task *task)
+xprt_abort_transmit(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+
+ xprt_release_write(xprt, task);
+}
+
+/**
+ * xprt_transmit - send an RPC request on a transport
+ * @task: controlling RPC task
+ *
+ * We have to copy the iovec because sendmsg fiddles with its contents.
+ */
+void xprt_transmit(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
- int status, retry = 0;
-
+ int status;
dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
- /* set up everything as needed. */
- /* Write the record marker */
- if (xprt->stream) {
- u32 *marker = req->rq_svec[0].iov_base;
-
- *marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
- }
-
smp_rmb();
if (!req->rq_received) {
if (list_empty(&req->rq_list)) {
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
/* Update the softirq receive buffer */
memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
sizeof(req->rq_private_buf));
/* Add request to the receive list */
list_add_tail(&req->rq_list, &xprt->recv);
- spin_unlock_bh(&xprt->sock_lock);
+ spin_unlock_bh(&xprt->transport_lock);
xprt_reset_majortimeo(req);
/* Turn off autodisconnect */
del_singleshot_timer_sync(&xprt->timer);
@@ -1246,40 +748,19 @@ xprt_transmit(struct rpc_task *task)
} else if (!req->rq_bytes_sent)
return;
- /* Continue transmitting the packet/record. We must be careful
- * to cope with writespace callbacks arriving _after_ we have
- * called xprt_sendmsg().
- */
- while (1) {
- req->rq_xtime = jiffies;
- status = xprt_sendmsg(xprt, req);
-
- if (status < 0)
- break;
-
- if (xprt->stream) {
- req->rq_bytes_sent += status;
-
- /* If we've sent the entire packet, immediately
- * reset the count of bytes sent. */
- if (req->rq_bytes_sent >= req->rq_slen) {
- req->rq_bytes_sent = 0;
- goto out_receive;
- }
- } else {
- if (status >= req->rq_slen)
- goto out_receive;
- status = -EAGAIN;
- break;
- }
-
- dprintk("RPC: %4d xmit incomplete (%d left of %d)\n",
- task->tk_pid, req->rq_slen - req->rq_bytes_sent,
- req->rq_slen);
-
- status = -EAGAIN;
- if (retry++ > 50)
- break;
+ status = xprt->ops->send_request(task);
+ if (status == 0) {
+ dprintk("RPC: %4d xmit complete\n", task->tk_pid);
+ spin_lock_bh(&xprt->transport_lock);
+ xprt->ops->set_retrans_timeout(task);
+ /* Don't race with disconnect */
+ if (!xprt_connected(xprt))
+ task->tk_status = -ENOTCONN;
+ else if (!req->rq_received)
+ rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
+ xprt->ops->release_xprt(xprt, task);
+ spin_unlock_bh(&xprt->transport_lock);
+ return;
}
/* Note: at this point, task->tk_sleeping has not yet been set,
@@ -1289,60 +770,19 @@ xprt_transmit(struct rpc_task *task)
task->tk_status = status;
switch (status) {
- case -EAGAIN:
- if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
- /* Protect against races with xprt_write_space */
- spin_lock_bh(&xprt->sock_lock);
- /* Don't race with disconnect */
- if (!xprt_connected(xprt))
- task->tk_status = -ENOTCONN;
- else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) {
- task->tk_timeout = req->rq_timeout;
- rpc_sleep_on(&xprt->pending, task, NULL, NULL);
- }
- spin_unlock_bh(&xprt->sock_lock);
- return;
- }
- /* Keep holding the socket if it is blocked */
- rpc_delay(task, HZ>>4);
- return;
case -ECONNREFUSED:
- task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
+ case -EAGAIN:
case -ENOTCONN:
return;
default:
- if (xprt->stream)
- xprt_disconnect(xprt);
+ break;
}
xprt_release_write(xprt, task);
return;
- out_receive:
- dprintk("RPC: %4d xmit complete\n", task->tk_pid);
- /* Set the task's receive timeout value */
- spin_lock_bh(&xprt->sock_lock);
- if (!xprt->nocong) {
- int timer = task->tk_msg.rpc_proc->p_timer;
- task->tk_timeout = rpc_calc_rto(clnt->cl_rtt, timer);
- task->tk_timeout <<= rpc_ntimeo(clnt->cl_rtt, timer) + req->rq_retries;
- if (task->tk_timeout > xprt->timeout.to_maxval || task->tk_timeout == 0)
- task->tk_timeout = xprt->timeout.to_maxval;
- } else
- task->tk_timeout = req->rq_timeout;
- /* Don't race with disconnect */
- if (!xprt_connected(xprt))
- task->tk_status = -ENOTCONN;
- else if (!req->rq_received)
- rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
- __xprt_release_write(xprt, task);
- spin_unlock_bh(&xprt->sock_lock);
}
-/*
- * Reserve an RPC call slot.
- */
-static inline void
-do_xprt_reserve(struct rpc_task *task)
+static inline void do_xprt_reserve(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
@@ -1362,22 +802,25 @@ do_xprt_reserve(struct rpc_task *task)
rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
}
-void
-xprt_reserve(struct rpc_task *task)
+/**
+ * xprt_reserve - allocate an RPC request slot
+ * @task: RPC task requesting a slot allocation
+ *
+ * If no more slots are available, place the task on the transport's
+ * backlog queue.
+ */
+void xprt_reserve(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
task->tk_status = -EIO;
if (!xprt->shutdown) {
- spin_lock(&xprt->xprt_lock);
+ spin_lock(&xprt->reserve_lock);
do_xprt_reserve(task);
- spin_unlock(&xprt->xprt_lock);
+ spin_unlock(&xprt->reserve_lock);
}
}
-/*
- * Allocate a 'unique' XID
- */
static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
{
return xprt->xid++;
@@ -1388,11 +831,7 @@ static inline void xprt_init_xid(struct rpc_xprt *xprt)
get_random_bytes(&xprt->xid, sizeof(xprt->xid));
}
-/*
- * Initialize RPC request
- */
-static void
-xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
+static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
{
struct rpc_rqst *req = task->tk_rqstp;
@@ -1400,128 +839,104 @@ xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
req->rq_task = task;
req->rq_xprt = xprt;
req->rq_xid = xprt_alloc_xid(xprt);
+ req->rq_release_snd_buf = NULL;
dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
req, ntohl(req->rq_xid));
}
-/*
- * Release an RPC call slot
+/**
+ * xprt_release - release an RPC request slot
+ * @task: task which is finished with the slot
+ *
*/
-void
-xprt_release(struct rpc_task *task)
+void xprt_release(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req;
if (!(req = task->tk_rqstp))
return;
- spin_lock_bh(&xprt->sock_lock);
- __xprt_release_write(xprt, task);
- __xprt_put_cong(xprt, req);
+ spin_lock_bh(&xprt->transport_lock);
+ xprt->ops->release_xprt(xprt, task);
+ if (xprt->ops->release_request)
+ xprt->ops->release_request(task);
if (!list_empty(&req->rq_list))
list_del(&req->rq_list);
xprt->last_used = jiffies;
if (list_empty(&xprt->recv) && !xprt->shutdown)
- mod_timer(&xprt->timer, xprt->last_used + XPRT_IDLE_TIMEOUT);
- spin_unlock_bh(&xprt->sock_lock);
+ mod_timer(&xprt->timer,
+ xprt->last_used + xprt->idle_timeout);
+ spin_unlock_bh(&xprt->transport_lock);
task->tk_rqstp = NULL;
+ if (req->rq_release_snd_buf)
+ req->rq_release_snd_buf(req);
memset(req, 0, sizeof(*req)); /* mark unused */
dprintk("RPC: %4d release request %p\n", task->tk_pid, req);
- spin_lock(&xprt->xprt_lock);
+ spin_lock(&xprt->reserve_lock);
list_add(&req->rq_list, &xprt->free);
- xprt_clear_backlog(xprt);
- spin_unlock(&xprt->xprt_lock);
-}
-
-/*
- * Set default timeout parameters
- */
-static void
-xprt_default_timeout(struct rpc_timeout *to, int proto)
-{
- if (proto == IPPROTO_UDP)
- xprt_set_timeout(to, 5, 5 * HZ);
- else
- xprt_set_timeout(to, 5, 60 * HZ);
+ rpc_wake_up_next(&xprt->backlog);
+ spin_unlock(&xprt->reserve_lock);
}
-/*
- * Set constant timeout
+/**
+ * xprt_set_timeout - set constant RPC timeout
+ * @to: RPC timeout parameters to set up
+ * @retr: number of retries
+ * @incr: amount of increase after each retry
+ *
*/
-void
-xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
+void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
{
to->to_initval =
to->to_increment = incr;
- to->to_maxval = incr * retr;
+ to->to_maxval = to->to_initval + (incr * retr);
to->to_retries = retr;
to->to_exponential = 0;
}
-unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
-unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE;
-
-/*
- * Initialize an RPC client
- */
-static struct rpc_xprt *
-xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
+static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
{
+ int result;
struct rpc_xprt *xprt;
- unsigned int entries;
- size_t slot_table_size;
struct rpc_rqst *req;
- dprintk("RPC: setting up %s transport...\n",
- proto == IPPROTO_UDP? "UDP" : "TCP");
-
- entries = (proto == IPPROTO_TCP)?
- xprt_tcp_slot_table_entries : xprt_udp_slot_table_entries;
-
if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL)
return ERR_PTR(-ENOMEM);
memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */
- xprt->max_reqs = entries;
- slot_table_size = entries * sizeof(xprt->slot[0]);
- xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
- if (xprt->slot == NULL) {
- kfree(xprt);
- return ERR_PTR(-ENOMEM);
- }
- memset(xprt->slot, 0, slot_table_size);
xprt->addr = *ap;
- xprt->prot = proto;
- xprt->stream = (proto == IPPROTO_TCP)? 1 : 0;
- if (xprt->stream) {
- xprt->cwnd = RPC_MAXCWND(xprt);
- xprt->nocong = 1;
- xprt->max_payload = (1U << 31) - 1;
- } else {
- xprt->cwnd = RPC_INITCWND;
- xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
+
+ switch (proto) {
+ case IPPROTO_UDP:
+ result = xs_setup_udp(xprt, to);
+ break;
+ case IPPROTO_TCP:
+ result = xs_setup_tcp(xprt, to);
+ break;
+ default:
+ printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
+ proto);
+ result = -EIO;
+ break;
+ }
+ if (result) {
+ kfree(xprt);
+ return ERR_PTR(result);
}
- spin_lock_init(&xprt->sock_lock);
- spin_lock_init(&xprt->xprt_lock);
- init_waitqueue_head(&xprt->cong_wait);
+
+ spin_lock_init(&xprt->transport_lock);
+ spin_lock_init(&xprt->reserve_lock);
INIT_LIST_HEAD(&xprt->free);
INIT_LIST_HEAD(&xprt->recv);
- INIT_WORK(&xprt->sock_connect, xprt_socket_connect, xprt);
- INIT_WORK(&xprt->task_cleanup, xprt_socket_autoclose, xprt);
+ INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt);
init_timer(&xprt->timer);
xprt->timer.function = xprt_init_autodisconnect;
xprt->timer.data = (unsigned long) xprt;
xprt->last_used = jiffies;
- xprt->port = XPRT_MAX_RESVPORT;
-
- /* Set timeout parameters */
- if (to) {
- xprt->timeout = *to;
- } else
- xprt_default_timeout(&xprt->timeout, xprt->prot);
+ xprt->cwnd = RPC_INITCWND;
rpc_init_wait_queue(&xprt->pending, "xprt_pending");
rpc_init_wait_queue(&xprt->sending, "xprt_sending");
@@ -1529,139 +944,25 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog");
/* initialize free list */
- for (req = &xprt->slot[entries-1]; req >= &xprt->slot[0]; req--)
+ for (req = &xprt->slot[xprt->max_reqs-1]; req >= &xprt->slot[0]; req--)
list_add(&req->rq_list, &xprt->free);
xprt_init_xid(xprt);
- /* Check whether we want to use a reserved port */
- xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
-
dprintk("RPC: created transport %p with %u slots\n", xprt,
xprt->max_reqs);
return xprt;
}
-/*
- * Bind to a reserved port
- */
-static inline int xprt_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
-{
- struct sockaddr_in myaddr = {
- .sin_family = AF_INET,
- };
- int err, port;
-
- /* Were we already bound to a given port? Try to reuse it */
- port = xprt->port;
- do {
- myaddr.sin_port = htons(port);
- err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
- sizeof(myaddr));
- if (err == 0) {
- xprt->port = port;
- return 0;
- }
- if (--port == 0)
- port = XPRT_MAX_RESVPORT;
- } while (err == -EADDRINUSE && port != xprt->port);
-
- printk("RPC: Can't bind to reserved port (%d).\n", -err);
- return err;
-}
-
-static void
-xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock)
-{
- struct sock *sk = sock->sk;
-
- if (xprt->inet)
- return;
-
- write_lock_bh(&sk->sk_callback_lock);
- sk->sk_user_data = xprt;
- xprt->old_data_ready = sk->sk_data_ready;
- xprt->old_state_change = sk->sk_state_change;
- xprt->old_write_space = sk->sk_write_space;
- if (xprt->prot == IPPROTO_UDP) {
- sk->sk_data_ready = udp_data_ready;
- sk->sk_no_check = UDP_CSUM_NORCV;
- xprt_set_connected(xprt);
- } else {
- tcp_sk(sk)->nonagle = 1; /* disable Nagle's algorithm */
- sk->sk_data_ready = tcp_data_ready;
- sk->sk_state_change = tcp_state_change;
- xprt_clear_connected(xprt);
- }
- sk->sk_write_space = xprt_write_space;
-
- /* Reset to new socket */
- xprt->sock = sock;
- xprt->inet = sk;
- write_unlock_bh(&sk->sk_callback_lock);
-
- return;
-}
-
-/*
- * Set socket buffer length
- */
-void
-xprt_sock_setbufsize(struct rpc_xprt *xprt)
-{
- struct sock *sk = xprt->inet;
-
- if (xprt->stream)
- return;
- if (xprt->rcvsize) {
- sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
- sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs * 2;
- }
- if (xprt->sndsize) {
- sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
- sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
- sk->sk_write_space(sk);
- }
-}
-
-/*
- * Datastream sockets are created here, but xprt_connect will create
- * and connect stream sockets.
- */
-static struct socket * xprt_create_socket(struct rpc_xprt *xprt, int proto, int resvport)
-{
- struct socket *sock;
- int type, err;
-
- dprintk("RPC: xprt_create_socket(%s %d)\n",
- (proto == IPPROTO_UDP)? "udp" : "tcp", proto);
-
- type = (proto == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
-
- if ((err = sock_create_kern(PF_INET, type, proto, &sock)) < 0) {
- printk("RPC: can't create socket (%d).\n", -err);
- return NULL;
- }
-
- /* If the caller has the capability, bind to a reserved port */
- if (resvport && xprt_bindresvport(xprt, sock) < 0) {
- printk("RPC: can't bind to reserved port.\n");
- goto failed;
- }
-
- return sock;
-
-failed:
- sock_release(sock);
- return NULL;
-}
-
-/*
- * Create an RPC client transport given the protocol and peer address.
+/**
+ * xprt_create_proto - create an RPC client transport
+ * @proto: requested transport protocol
+ * @sap: remote peer's address
+ * @to: timeout parameters for new transport
+ *
*/
-struct rpc_xprt *
-xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
+struct rpc_xprt *xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
{
struct rpc_xprt *xprt;
@@ -1673,46 +974,26 @@ xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
return xprt;
}
-/*
- * Prepare for transport shutdown.
- */
-static void
-xprt_shutdown(struct rpc_xprt *xprt)
+static void xprt_shutdown(struct rpc_xprt *xprt)
{
xprt->shutdown = 1;
rpc_wake_up(&xprt->sending);
rpc_wake_up(&xprt->resend);
- rpc_wake_up(&xprt->pending);
+ xprt_wake_pending_tasks(xprt, -EIO);
rpc_wake_up(&xprt->backlog);
- wake_up(&xprt->cong_wait);
del_timer_sync(&xprt->timer);
-
- /* synchronously wait for connect worker to finish */
- cancel_delayed_work(&xprt->sock_connect);
- flush_scheduled_work();
}
-/*
- * Clear the xprt backlog queue
- */
-static int
-xprt_clear_backlog(struct rpc_xprt *xprt) {
- rpc_wake_up_next(&xprt->backlog);
- wake_up(&xprt->cong_wait);
- return 1;
-}
-
-/*
- * Destroy an RPC transport, killing off all requests.
+/**
+ * xprt_destroy - destroy an RPC transport, killing off all requests.
+ * @xprt: transport to destroy
+ *
*/
-int
-xprt_destroy(struct rpc_xprt *xprt)
+int xprt_destroy(struct rpc_xprt *xprt)
{
dprintk("RPC: destroying transport %p\n", xprt);
xprt_shutdown(xprt);
- xprt_disconnect(xprt);
- xprt_close(xprt);
- kfree(xprt->slot);
+ xprt->ops->destroy(xprt);
kfree(xprt);
return 0;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
new file mode 100644
index 000000000000..2e1529217e65
--- /dev/null
+++ b/net/sunrpc/xprtsock.c
@@ -0,0 +1,1252 @@
+/*
+ * linux/net/sunrpc/xprtsock.c
+ *
+ * Client-side transport implementation for sockets.
+ *
+ * TCP callback races fixes (C) 1998 Red Hat Software <alan@redhat.com>
+ * TCP send fixes (C) 1998 Red Hat Software <alan@redhat.com>
+ * TCP NFS related read + write fixes
+ * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie>
+ *
+ * Rewrite of larges part of the code in order to stabilize TCP stuff.
+ * Fix behaviour when socket buffer is full.
+ * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no>
+ *
+ * IP socket transport implementation, (C) 2005 Chuck Lever <cel@netapp.com>
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/pagemap.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/mm.h>
+#include <linux/udp.h>
+#include <linux/tcp.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/file.h>
+
+#include <net/sock.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+
+/*
+ * How many times to try sending a request on a socket before waiting
+ * for the socket buffer to clear.
+ */
+#define XS_SENDMSG_RETRY (10U)
+
+/*
+ * Time out for an RPC UDP socket connect. UDP socket connects are
+ * synchronous, but we set a timeout anyway in case of resource
+ * exhaustion on the local host.
+ */
+#define XS_UDP_CONN_TO (5U * HZ)
+
+/*
+ * Wait duration for an RPC TCP connection to be established. Solaris
+ * NFS over TCP uses 60 seconds, for example, which is in line with how
+ * long a server takes to reboot.
+ */
+#define XS_TCP_CONN_TO (60U * HZ)
+
+/*
+ * Wait duration for a reply from the RPC portmapper.
+ */
+#define XS_BIND_TO (60U * HZ)
+
+/*
+ * Delay if a UDP socket connect error occurs. This is most likely some
+ * kind of resource problem on the local host.
+ */
+#define XS_UDP_REEST_TO (2U * HZ)
+
+/*
+ * The reestablish timeout allows clients to delay for a bit before attempting
+ * to reconnect to a server that just dropped our connection.
+ *
+ * We implement an exponential backoff when trying to reestablish a TCP
+ * transport connection with the server. Some servers like to drop a TCP
+ * connection when they are overworked, so we start with a short timeout and
+ * increase over time if the server is down or not responding.
+ */
+#define XS_TCP_INIT_REEST_TO (3U * HZ)
+#define XS_TCP_MAX_REEST_TO (5U * 60 * HZ)
+
+/*
+ * TCP idle timeout; client drops the transport socket if it is idle
+ * for this long. Note that we also timeout UDP sockets to prevent
+ * holding port numbers when there is no RPC traffic.
+ */
+#define XS_IDLE_DISC_TO (5U * 60 * HZ)
+
+#ifdef RPC_DEBUG
+# undef RPC_DEBUG_DATA
+# define RPCDBG_FACILITY RPCDBG_TRANS
+#endif
+
+#ifdef RPC_DEBUG_DATA
+static void xs_pktdump(char *msg, u32 *packet, unsigned int count)
+{
+ u8 *buf = (u8 *) packet;
+ int j;
+
+ dprintk("RPC: %s\n", msg);
+ for (j = 0; j < count && j < 128; j += 4) {
+ if (!(j & 31)) {
+ if (j)
+ dprintk("\n");
+ dprintk("0x%04x ", j);
+ }
+ dprintk("%02x%02x%02x%02x ",
+ buf[j], buf[j+1], buf[j+2], buf[j+3]);
+ }
+ dprintk("\n");
+}
+#else
+static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
+{
+ /* NOP */
+}
+#endif
+
+#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)
+
+static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len)
+{
+ struct kvec iov = {
+ .iov_base = xdr->head[0].iov_base + base,
+ .iov_len = len - base,
+ };
+ struct msghdr msg = {
+ .msg_name = addr,
+ .msg_namelen = addrlen,
+ .msg_flags = XS_SENDMSG_FLAGS,
+ };
+
+ if (xdr->len > len)
+ msg.msg_flags |= MSG_MORE;
+
+ if (likely(iov.iov_len))
+ return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+ return kernel_sendmsg(sock, &msg, NULL, 0, 0);
+}
+
+static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int base, unsigned int len)
+{
+ struct kvec iov = {
+ .iov_base = xdr->tail[0].iov_base + base,
+ .iov_len = len - base,
+ };
+ struct msghdr msg = {
+ .msg_flags = XS_SENDMSG_FLAGS,
+ };
+
+ return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+}
+
+/**
+ * xs_sendpages - write pages directly to a socket
+ * @sock: socket to send on
+ * @addr: UDP only -- address of destination
+ * @addrlen: UDP only -- length of destination address
+ * @xdr: buffer containing this request
+ * @base: starting position in the buffer
+ *
+ */
+static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
+{
+ struct page **ppage = xdr->pages;
+ unsigned int len, pglen = xdr->page_len;
+ int err, ret = 0;
+ ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
+
+ if (unlikely(!sock))
+ return -ENOTCONN;
+
+ clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+
+ len = xdr->head[0].iov_len;
+ if (base < len || (addr != NULL && base == 0)) {
+ err = xs_send_head(sock, addr, addrlen, xdr, base, len);
+ if (ret == 0)
+ ret = err;
+ else if (err > 0)
+ ret += err;
+ if (err != (len - base))
+ goto out;
+ base = 0;
+ } else
+ base -= len;
+
+ if (unlikely(pglen == 0))
+ goto copy_tail;
+ if (unlikely(base >= pglen)) {
+ base -= pglen;
+ goto copy_tail;
+ }
+ if (base || xdr->page_base) {
+ pglen -= base;
+ base += xdr->page_base;
+ ppage += base >> PAGE_CACHE_SHIFT;
+ base &= ~PAGE_CACHE_MASK;
+ }
+
+ sendpage = sock->ops->sendpage ? : sock_no_sendpage;
+ do {
+ int flags = XS_SENDMSG_FLAGS;
+
+ len = PAGE_CACHE_SIZE;
+ if (base)
+ len -= base;
+ if (pglen < len)
+ len = pglen;
+
+ if (pglen != len || xdr->tail[0].iov_len != 0)
+ flags |= MSG_MORE;
+
+ /* Hmm... We might be dealing with highmem pages */
+ if (PageHighMem(*ppage))
+ sendpage = sock_no_sendpage;
+ err = sendpage(sock, *ppage, base, len, flags);
+ if (ret == 0)
+ ret = err;
+ else if (err > 0)
+ ret += err;
+ if (err != len)
+ goto out;
+ base = 0;
+ ppage++;
+ } while ((pglen -= len) != 0);
+copy_tail:
+ len = xdr->tail[0].iov_len;
+ if (base < len) {
+ err = xs_send_tail(sock, xdr, base, len);
+ if (ret == 0)
+ ret = err;
+ else if (err > 0)
+ ret += err;
+ }
+out:
+ return ret;
+}
+
+/**
+ * xs_nospace - place task on wait queue if transmit was incomplete
+ * @task: task to put to sleep
+ *
+ */
+static void xs_nospace(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+
+ dprintk("RPC: %4d xmit incomplete (%u left of %u)\n",
+ task->tk_pid, req->rq_slen - req->rq_bytes_sent,
+ req->rq_slen);
+
+ if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
+ /* Protect against races with write_space */
+ spin_lock_bh(&xprt->transport_lock);
+
+ /* Don't race with disconnect */
+ if (!xprt_connected(xprt))
+ task->tk_status = -ENOTCONN;
+ else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags))
+ xprt_wait_for_buffer_space(task);
+
+ spin_unlock_bh(&xprt->transport_lock);
+ } else
+ /* Keep holding the socket if it is blocked */
+ rpc_delay(task, HZ>>4);
+}
+
+/**
+ * xs_udp_send_request - write an RPC request to a UDP socket
+ * @task: address of RPC task that manages the state of an RPC request
+ *
+ * Return values:
+ * 0: The request has been sent
+ * EAGAIN: The socket was blocked, please call again later to
+ * complete the request
+ * ENOTCONN: Caller needs to invoke connect logic then call again
+ * other: Some other error occured, the request was not sent
+ */
+static int xs_udp_send_request(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+ struct xdr_buf *xdr = &req->rq_snd_buf;
+ int status;
+
+ xs_pktdump("packet data:",
+ req->rq_svec->iov_base,
+ req->rq_svec->iov_len);
+
+ req->rq_xtime = jiffies;
+ status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr,
+ sizeof(xprt->addr), xdr, req->rq_bytes_sent);
+
+ dprintk("RPC: xs_udp_send_request(%u) = %d\n",
+ xdr->len - req->rq_bytes_sent, status);
+
+ if (likely(status >= (int) req->rq_slen))
+ return 0;
+
+ /* Still some bytes left; set up for a retry later. */
+ if (status > 0)
+ status = -EAGAIN;
+
+ switch (status) {
+ case -ENETUNREACH:
+ case -EPIPE:
+ case -ECONNREFUSED:
+ /* When the server has died, an ICMP port unreachable message
+ * prompts ECONNREFUSED. */
+ break;
+ case -EAGAIN:
+ xs_nospace(task);
+ break;
+ default:
+ dprintk("RPC: sendmsg returned unrecognized error %d\n",
+ -status);
+ break;
+ }
+
+ return status;
+}
+
+static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf)
+{
+ u32 reclen = buf->len - sizeof(rpc_fraghdr);
+ rpc_fraghdr *base = buf->head[0].iov_base;
+ *base = htonl(RPC_LAST_STREAM_FRAGMENT | reclen);
+}
+
+/**
+ * xs_tcp_send_request - write an RPC request to a TCP socket
+ * @task: address of RPC task that manages the state of an RPC request
+ *
+ * Return values:
+ * 0: The request has been sent
+ * EAGAIN: The socket was blocked, please call again later to
+ * complete the request
+ * ENOTCONN: Caller needs to invoke connect logic then call again
+ * other: Some other error occured, the request was not sent
+ *
+ * XXX: In the case of soft timeouts, should we eventually give up
+ * if sendmsg is not able to make progress?
+ */
+static int xs_tcp_send_request(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+ struct xdr_buf *xdr = &req->rq_snd_buf;
+ int status, retry = 0;
+
+ xs_encode_tcp_record_marker(&req->rq_snd_buf);
+
+ xs_pktdump("packet data:",
+ req->rq_svec->iov_base,
+ req->rq_svec->iov_len);
+
+ /* Continue transmitting the packet/record. We must be careful
+ * to cope with writespace callbacks arriving _after_ we have
+ * called sendmsg(). */
+ while (1) {
+ req->rq_xtime = jiffies;
+ status = xs_sendpages(xprt->sock, NULL, 0, xdr,
+ req->rq_bytes_sent);
+
+ dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
+ xdr->len - req->rq_bytes_sent, status);
+
+ if (unlikely(status < 0))
+ break;
+
+ /* If we've sent the entire packet, immediately
+ * reset the count of bytes sent. */
+ req->rq_bytes_sent += status;
+ if (likely(req->rq_bytes_sent >= req->rq_slen)) {
+ req->rq_bytes_sent = 0;
+ return 0;
+ }
+
+ status = -EAGAIN;
+ if (retry++ > XS_SENDMSG_RETRY)
+ break;
+ }
+
+ switch (status) {
+ case -EAGAIN:
+ xs_nospace(task);
+ break;
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ENOTCONN:
+ case -EPIPE:
+ status = -ENOTCONN;
+ break;
+ default:
+ dprintk("RPC: sendmsg returned unrecognized error %d\n",
+ -status);
+ xprt_disconnect(xprt);
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * xs_close - close a socket
+ * @xprt: transport
+ *
+ * This is used when all requests are complete; ie, no DRC state remains
+ * on the server we want to save.
+ */
+static void xs_close(struct rpc_xprt *xprt)
+{
+ struct socket *sock = xprt->sock;
+ struct sock *sk = xprt->inet;
+
+ if (!sk)
+ return;
+
+ dprintk("RPC: xs_close xprt %p\n", xprt);
+
+ write_lock_bh(&sk->sk_callback_lock);
+ xprt->inet = NULL;
+ xprt->sock = NULL;
+
+ sk->sk_user_data = NULL;
+ sk->sk_data_ready = xprt->old_data_ready;
+ sk->sk_state_change = xprt->old_state_change;
+ sk->sk_write_space = xprt->old_write_space;
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ sk->sk_no_check = 0;
+
+ sock_release(sock);
+}
+
+/**
+ * xs_destroy - prepare to shutdown a transport
+ * @xprt: doomed transport
+ *
+ */
+static void xs_destroy(struct rpc_xprt *xprt)
+{
+ dprintk("RPC: xs_destroy xprt %p\n", xprt);
+
+ cancel_delayed_work(&xprt->connect_worker);
+ flush_scheduled_work();
+
+ xprt_disconnect(xprt);
+ xs_close(xprt);
+ kfree(xprt->slot);
+}
+
+static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
+{
+ return (struct rpc_xprt *) sk->sk_user_data;
+}
+
+/**
+ * xs_udp_data_ready - "data ready" callback for UDP sockets
+ * @sk: socket with data to read
+ * @len: how much data to read
+ *
+ */
+static void xs_udp_data_ready(struct sock *sk, int len)
+{
+ struct rpc_task *task;
+ struct rpc_xprt *xprt;
+ struct rpc_rqst *rovr;
+ struct sk_buff *skb;
+ int err, repsize, copied;
+ u32 _xid, *xp;
+
+ read_lock(&sk->sk_callback_lock);
+ dprintk("RPC: xs_udp_data_ready...\n");
+ if (!(xprt = xprt_from_sock(sk)))
+ goto out;
+
+ if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
+ goto out;
+
+ if (xprt->shutdown)
+ goto dropit;
+
+ repsize = skb->len - sizeof(struct udphdr);
+ if (repsize < 4) {
+ dprintk("RPC: impossible RPC reply size %d!\n", repsize);
+ goto dropit;
+ }
+
+ /* Copy the XID from the skb... */
+ xp = skb_header_pointer(skb, sizeof(struct udphdr),
+ sizeof(_xid), &_xid);
+ if (xp == NULL)
+ goto dropit;
+
+ /* Look up and lock the request corresponding to the given XID */
+ spin_lock(&xprt->transport_lock);
+ rovr = xprt_lookup_rqst(xprt, *xp);
+ if (!rovr)
+ goto out_unlock;
+ task = rovr->rq_task;
+
+ if ((copied = rovr->rq_private_buf.buflen) > repsize)
+ copied = repsize;
+
+ /* Suck it into the iovec, verify checksum if not done by hw. */
+ if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
+ goto out_unlock;
+
+ /* Something worked... */
+ dst_confirm(skb->dst);
+
+ xprt_adjust_cwnd(task, copied);
+ xprt_update_rtt(task);
+ xprt_complete_rqst(task, copied);
+
+ out_unlock:
+ spin_unlock(&xprt->transport_lock);
+ dropit:
+ skb_free_datagram(sk, skb);
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+static inline size_t xs_tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
+{
+ if (len > desc->count)
+ len = desc->count;
+ if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
+ dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
+ len, desc->count);
+ return 0;
+ }
+ desc->offset += len;
+ desc->count -= len;
+ dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
+ len, desc->count);
+ return len;
+}
+
+static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ size_t len, used;
+ char *p;
+
+ p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
+ len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+ used = xs_tcp_copy_data(desc, p, len);
+ xprt->tcp_offset += used;
+ if (used != len)
+ return;
+
+ xprt->tcp_reclen = ntohl(xprt->tcp_recm);
+ if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
+ xprt->tcp_flags |= XPRT_LAST_FRAG;
+ else
+ xprt->tcp_flags &= ~XPRT_LAST_FRAG;
+ xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
+
+ xprt->tcp_flags &= ~XPRT_COPY_RECM;
+ xprt->tcp_offset = 0;
+
+ /* Sanity check of the record length */
+ if (unlikely(xprt->tcp_reclen < 4)) {
+ dprintk("RPC: invalid TCP record fragment length\n");
+ xprt_disconnect(xprt);
+ return;
+ }
+ dprintk("RPC: reading TCP record fragment of length %d\n",
+ xprt->tcp_reclen);
+}
+
+static void xs_tcp_check_recm(struct rpc_xprt *xprt)
+{
+ dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
+ xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
+ if (xprt->tcp_offset == xprt->tcp_reclen) {
+ xprt->tcp_flags |= XPRT_COPY_RECM;
+ xprt->tcp_offset = 0;
+ if (xprt->tcp_flags & XPRT_LAST_FRAG) {
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ xprt->tcp_flags |= XPRT_COPY_XID;
+ xprt->tcp_copied = 0;
+ }
+ }
+}
+
+static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ size_t len, used;
+ char *p;
+
+ len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
+ dprintk("RPC: reading XID (%Zu bytes)\n", len);
+ p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
+ used = xs_tcp_copy_data(desc, p, len);
+ xprt->tcp_offset += used;
+ if (used != len)
+ return;
+ xprt->tcp_flags &= ~XPRT_COPY_XID;
+ xprt->tcp_flags |= XPRT_COPY_DATA;
+ xprt->tcp_copied = 4;
+ dprintk("RPC: reading reply for XID %08x\n",
+ ntohl(xprt->tcp_xid));
+ xs_tcp_check_recm(xprt);
+}
+
+static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ struct rpc_rqst *req;
+ struct xdr_buf *rcvbuf;
+ size_t len;
+ ssize_t r;
+
+ /* Find and lock the request corresponding to this xid */
+ spin_lock(&xprt->transport_lock);
+ req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
+ if (!req) {
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ dprintk("RPC: XID %08x request not found!\n",
+ ntohl(xprt->tcp_xid));
+ spin_unlock(&xprt->transport_lock);
+ return;
+ }
+
+ rcvbuf = &req->rq_private_buf;
+ len = desc->count;
+ if (len > xprt->tcp_reclen - xprt->tcp_offset) {
+ skb_reader_t my_desc;
+
+ len = xprt->tcp_reclen - xprt->tcp_offset;
+ memcpy(&my_desc, desc, sizeof(my_desc));
+ my_desc.count = len;
+ r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+ &my_desc, xs_tcp_copy_data);
+ desc->count -= r;
+ desc->offset += r;
+ } else
+ r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+ desc, xs_tcp_copy_data);
+
+ if (r > 0) {
+ xprt->tcp_copied += r;
+ xprt->tcp_offset += r;
+ }
+ if (r != len) {
+ /* Error when copying to the receive buffer,
+ * usually because we weren't able to allocate
+ * additional buffer pages. All we can do now
+ * is turn off XPRT_COPY_DATA, so the request
+ * will not receive any additional updates,
+ * and time out.
+ * Any remaining data from this record will
+ * be discarded.
+ */
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ dprintk("RPC: XID %08x truncated request\n",
+ ntohl(xprt->tcp_xid));
+ dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+ xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+ goto out;
+ }
+
+ dprintk("RPC: XID %08x read %Zd bytes\n",
+ ntohl(xprt->tcp_xid), r);
+ dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+ xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+
+ if (xprt->tcp_copied == req->rq_private_buf.buflen)
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ else if (xprt->tcp_offset == xprt->tcp_reclen) {
+ if (xprt->tcp_flags & XPRT_LAST_FRAG)
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ }
+
+out:
+ if (!(xprt->tcp_flags & XPRT_COPY_DATA))
+ xprt_complete_rqst(req->rq_task, xprt->tcp_copied);
+ spin_unlock(&xprt->transport_lock);
+ xs_tcp_check_recm(xprt);
+}
+
+static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ size_t len;
+
+ len = xprt->tcp_reclen - xprt->tcp_offset;
+ if (len > desc->count)
+ len = desc->count;
+ desc->count -= len;
+ desc->offset += len;
+ xprt->tcp_offset += len;
+ dprintk("RPC: discarded %Zu bytes\n", len);
+ xs_tcp_check_recm(xprt);
+}
+
+static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
+{
+ struct rpc_xprt *xprt = rd_desc->arg.data;
+ skb_reader_t desc = {
+ .skb = skb,
+ .offset = offset,
+ .count = len,
+ .csum = 0
+ };
+
+ dprintk("RPC: xs_tcp_data_recv started\n");
+ do {
+ /* Read in a new fragment marker if necessary */
+ /* Can we ever really expect to get completely empty fragments? */
+ if (xprt->tcp_flags & XPRT_COPY_RECM) {
+ xs_tcp_read_fraghdr(xprt, &desc);
+ continue;
+ }
+ /* Read in the xid if necessary */
+ if (xprt->tcp_flags & XPRT_COPY_XID) {
+ xs_tcp_read_xid(xprt, &desc);
+ continue;
+ }
+ /* Read in the request data */
+ if (xprt->tcp_flags & XPRT_COPY_DATA) {
+ xs_tcp_read_request(xprt, &desc);
+ continue;
+ }
+ /* Skip over any trailing bytes on short reads */
+ xs_tcp_read_discard(xprt, &desc);
+ } while (desc.count);
+ dprintk("RPC: xs_tcp_data_recv done\n");
+ return len - desc.count;
+}
+
+/**
+ * xs_tcp_data_ready - "data ready" callback for TCP sockets
+ * @sk: socket with data to read
+ * @bytes: how much data to read
+ *
+ */
+static void xs_tcp_data_ready(struct sock *sk, int bytes)
+{
+ struct rpc_xprt *xprt;
+ read_descriptor_t rd_desc;
+
+ read_lock(&sk->sk_callback_lock);
+ dprintk("RPC: xs_tcp_data_ready...\n");
+ if (!(xprt = xprt_from_sock(sk)))
+ goto out;
+ if (xprt->shutdown)
+ goto out;
+
+ /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
+ rd_desc.arg.data = xprt;
+ rd_desc.count = 65536;
+ tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
+out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+/**
+ * xs_tcp_state_change - callback to handle TCP socket state changes
+ * @sk: socket whose state has changed
+ *
+ */
+static void xs_tcp_state_change(struct sock *sk)
+{
+ struct rpc_xprt *xprt;
+
+ read_lock(&sk->sk_callback_lock);
+ if (!(xprt = xprt_from_sock(sk)))
+ goto out;
+ dprintk("RPC: xs_tcp_state_change client %p...\n", xprt);
+ dprintk("RPC: state %x conn %d dead %d zapped %d\n",
+ sk->sk_state, xprt_connected(xprt),
+ sock_flag(sk, SOCK_DEAD),
+ sock_flag(sk, SOCK_ZAPPED));
+
+ switch (sk->sk_state) {
+ case TCP_ESTABLISHED:
+ spin_lock_bh(&xprt->transport_lock);
+ if (!xprt_test_and_set_connected(xprt)) {
+ /* Reset TCP record info */
+ xprt->tcp_offset = 0;
+ xprt->tcp_reclen = 0;
+ xprt->tcp_copied = 0;
+ xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
+ xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+ xprt_wake_pending_tasks(xprt, 0);
+ }
+ spin_unlock_bh(&xprt->transport_lock);
+ break;
+ case TCP_SYN_SENT:
+ case TCP_SYN_RECV:
+ break;
+ default:
+ xprt_disconnect(xprt);
+ break;
+ }
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+/**
+ * xs_udp_write_space - callback invoked when socket buffer space
+ * becomes available
+ * @sk: socket whose state has changed
+ *
+ * Called when more output buffer space is available for this socket.
+ * We try not to wake our writers until they can make "significant"
+ * progress, otherwise we'll waste resources thrashing kernel_sendmsg
+ * with a bunch of small requests.
+ */
+static void xs_udp_write_space(struct sock *sk)
+{
+ read_lock(&sk->sk_callback_lock);
+
+ /* from net/core/sock.c:sock_def_write_space */
+ if (sock_writeable(sk)) {
+ struct socket *sock;
+ struct rpc_xprt *xprt;
+
+ if (unlikely(!(sock = sk->sk_socket)))
+ goto out;
+ if (unlikely(!(xprt = xprt_from_sock(sk))))
+ goto out;
+ if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
+ goto out;
+
+ xprt_write_space(xprt);
+ }
+
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+/**
+ * xs_tcp_write_space - callback invoked when socket buffer space
+ * becomes available
+ * @sk: socket whose state has changed
+ *
+ * Called when more output buffer space is available for this socket.
+ * We try not to wake our writers until they can make "significant"
+ * progress, otherwise we'll waste resources thrashing kernel_sendmsg
+ * with a bunch of small requests.
+ */
+static void xs_tcp_write_space(struct sock *sk)
+{
+ read_lock(&sk->sk_callback_lock);
+
+ /* from net/core/stream.c:sk_stream_write_space */
+ if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
+ struct socket *sock;
+ struct rpc_xprt *xprt;
+
+ if (unlikely(!(sock = sk->sk_socket)))
+ goto out;
+ if (unlikely(!(xprt = xprt_from_sock(sk))))
+ goto out;
+ if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
+ goto out;
+
+ xprt_write_space(xprt);
+ }
+
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
+{
+ struct sock *sk = xprt->inet;
+
+ if (xprt->rcvsize) {
+ sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
+ sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs * 2;
+ }
+ if (xprt->sndsize) {
+ sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+ sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
+ sk->sk_write_space(sk);
+ }
+}
+
+/**
+ * xs_udp_set_buffer_size - set send and receive limits
+ * @xprt: generic transport
+ * @sndsize: requested size of send buffer, in bytes
+ * @rcvsize: requested size of receive buffer, in bytes
+ *
+ * Set socket send and receive buffer size limits.
+ */
+static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize)
+{
+ xprt->sndsize = 0;
+ if (sndsize)
+ xprt->sndsize = sndsize + 1024;
+ xprt->rcvsize = 0;
+ if (rcvsize)
+ xprt->rcvsize = rcvsize + 1024;
+
+ xs_udp_do_set_buffer_size(xprt);
+}
+
+/**
+ * xs_udp_timer - called when a retransmit timeout occurs on a UDP transport
+ * @task: task that timed out
+ *
+ * Adjust the congestion window after a retransmit timeout has occurred.
+ */
+static void xs_udp_timer(struct rpc_task *task)
+{
+ xprt_adjust_cwnd(task, -ETIMEDOUT);
+}
+
+static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
+{
+ struct sockaddr_in myaddr = {
+ .sin_family = AF_INET,
+ };
+ int err;
+ unsigned short port = xprt->port;
+
+ do {
+ myaddr.sin_port = htons(port);
+ err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
+ sizeof(myaddr));
+ if (err == 0) {
+ xprt->port = port;
+ dprintk("RPC: xs_bindresvport bound to port %u\n",
+ port);
+ return 0;
+ }
+ if (port <= xprt_min_resvport)
+ port = xprt_max_resvport;
+ else
+ port--;
+ } while (err == -EADDRINUSE && port != xprt->port);
+
+ dprintk("RPC: can't bind to reserved port (%d).\n", -err);
+ return err;
+}
+
+/**
+ * xs_udp_connect_worker - set up a UDP socket
+ * @args: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_udp_connect_worker(void *args)
+{
+ struct rpc_xprt *xprt = (struct rpc_xprt *) args;
+ struct socket *sock = xprt->sock;
+ int err, status = -EIO;
+
+ if (xprt->shutdown || xprt->addr.sin_port == 0)
+ goto out;
+
+ dprintk("RPC: xs_udp_connect_worker for xprt %p\n", xprt);
+
+ /* Start by resetting any existing state */
+ xs_close(xprt);
+
+ if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
+ dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
+ goto out;
+ }
+
+ if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
+ sock_release(sock);
+ goto out;
+ }
+
+ if (!xprt->inet) {
+ struct sock *sk = sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ sk->sk_user_data = xprt;
+ xprt->old_data_ready = sk->sk_data_ready;
+ xprt->old_state_change = sk->sk_state_change;
+ xprt->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = xs_udp_data_ready;
+ sk->sk_write_space = xs_udp_write_space;
+ sk->sk_no_check = UDP_CSUM_NORCV;
+
+ xprt_set_connected(xprt);
+
+ /* Reset to new socket */
+ xprt->sock = sock;
+ xprt->inet = sk;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+ xs_udp_do_set_buffer_size(xprt);
+ status = 0;
+out:
+ xprt_wake_pending_tasks(xprt, status);
+ xprt_clear_connecting(xprt);
+}
+
+/*
+ * We need to preserve the port number so the reply cache on the server can
+ * find our cached RPC replies when we get around to reconnecting.
+ */
+static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
+{
+ int result;
+ struct socket *sock = xprt->sock;
+ struct sockaddr any;
+
+ dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt);
+
+ /*
+ * Disconnect the transport socket by doing a connect operation
+ * with AF_UNSPEC. This should return immediately...
+ */
+ memset(&any, 0, sizeof(any));
+ any.sa_family = AF_UNSPEC;
+ result = sock->ops->connect(sock, &any, sizeof(any), 0);
+ if (result)
+ dprintk("RPC: AF_UNSPEC connect return code %d\n",
+ result);
+}
+
+/**
+ * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
+ * @args: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_tcp_connect_worker(void *args)
+{
+ struct rpc_xprt *xprt = (struct rpc_xprt *)args;
+ struct socket *sock = xprt->sock;
+ int err, status = -EIO;
+
+ if (xprt->shutdown || xprt->addr.sin_port == 0)
+ goto out;
+
+ dprintk("RPC: xs_tcp_connect_worker for xprt %p\n", xprt);
+
+ if (!xprt->sock) {
+ /* start from scratch */
+ if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
+ dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
+ goto out;
+ }
+
+ if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
+ sock_release(sock);
+ goto out;
+ }
+ } else
+ /* "close" the socket, preserving the local port */
+ xs_tcp_reuse_connection(xprt);
+
+ if (!xprt->inet) {
+ struct sock *sk = sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ sk->sk_user_data = xprt;
+ xprt->old_data_ready = sk->sk_data_ready;
+ xprt->old_state_change = sk->sk_state_change;
+ xprt->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = xs_tcp_data_ready;
+ sk->sk_state_change = xs_tcp_state_change;
+ sk->sk_write_space = xs_tcp_write_space;
+
+ /* socket options */
+ sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
+ sock_reset_flag(sk, SOCK_LINGER);
+ tcp_sk(sk)->linger2 = 0;
+ tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
+
+ xprt_clear_connected(xprt);
+
+ /* Reset to new socket */
+ xprt->sock = sock;
+ xprt->inet = sk;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+
+ /* Tell the socket layer to start connecting... */
+ status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
+ sizeof(xprt->addr), O_NONBLOCK);
+ dprintk("RPC: %p connect status %d connected %d sock state %d\n",
+ xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
+ if (status < 0) {
+ switch (status) {
+ case -EINPROGRESS:
+ case -EALREADY:
+ goto out_clear;
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ /* retry with existing socket, after a delay */
+ break;
+ default:
+ /* get rid of existing socket, and retry */
+ xs_close(xprt);
+ break;
+ }
+ }
+out:
+ xprt_wake_pending_tasks(xprt, status);
+out_clear:
+ xprt_clear_connecting(xprt);
+}
+
+/**
+ * xs_connect - connect a socket to a remote endpoint
+ * @task: address of RPC task that manages state of connect request
+ *
+ * TCP: If the remote end dropped the connection, delay reconnecting.
+ *
+ * UDP socket connects are synchronous, but we use a work queue anyway
+ * to guarantee that even unprivileged user processes can set up a
+ * socket on a privileged port.
+ *
+ * If a UDP socket connect fails, the delay behavior here prevents
+ * retry floods (hard mounts).
+ */
+static void xs_connect(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+
+ if (xprt_test_and_set_connecting(xprt))
+ return;
+
+ if (xprt->sock != NULL) {
+ dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
+ xprt, xprt->reestablish_timeout / HZ);
+ schedule_delayed_work(&xprt->connect_worker,
+ xprt->reestablish_timeout);
+ xprt->reestablish_timeout <<= 1;
+ if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
+ xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
+ } else {
+ dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
+ schedule_work(&xprt->connect_worker);
+
+ /* flush_scheduled_work can sleep... */
+ if (!RPC_IS_ASYNC(task))
+ flush_scheduled_work();
+ }
+}
+
+static struct rpc_xprt_ops xs_udp_ops = {
+ .set_buffer_size = xs_udp_set_buffer_size,
+ .reserve_xprt = xprt_reserve_xprt_cong,
+ .release_xprt = xprt_release_xprt_cong,
+ .connect = xs_connect,
+ .send_request = xs_udp_send_request,
+ .set_retrans_timeout = xprt_set_retrans_timeout_rtt,
+ .timer = xs_udp_timer,
+ .release_request = xprt_release_rqst_cong,
+ .close = xs_close,
+ .destroy = xs_destroy,
+};
+
+static struct rpc_xprt_ops xs_tcp_ops = {
+ .reserve_xprt = xprt_reserve_xprt,
+ .release_xprt = xprt_release_xprt,
+ .connect = xs_connect,
+ .send_request = xs_tcp_send_request,
+ .set_retrans_timeout = xprt_set_retrans_timeout_def,
+ .close = xs_close,
+ .destroy = xs_destroy,
+};
+
+/**
+ * xs_setup_udp - Set up transport to use a UDP socket
+ * @xprt: transport to set up
+ * @to: timeout parameters
+ *
+ */
+int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
+{
+ size_t slot_table_size;
+
+ dprintk("RPC: setting up udp-ipv4 transport...\n");
+
+ xprt->max_reqs = xprt_udp_slot_table_entries;
+ slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
+ xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+ if (xprt->slot == NULL)
+ return -ENOMEM;
+ memset(xprt->slot, 0, slot_table_size);
+
+ xprt->prot = IPPROTO_UDP;
+ xprt->port = xprt_max_resvport;
+ xprt->tsh_size = 0;
+ xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
+ /* XXX: header size can vary due to auth type, IPv6, etc. */
+ xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
+
+ INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt);
+ xprt->bind_timeout = XS_BIND_TO;
+ xprt->connect_timeout = XS_UDP_CONN_TO;
+ xprt->reestablish_timeout = XS_UDP_REEST_TO;
+ xprt->idle_timeout = XS_IDLE_DISC_TO;
+
+ xprt->ops = &xs_udp_ops;
+
+ if (to)
+ xprt->timeout = *to;
+ else
+ xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
+
+ return 0;
+}
+
+/**
+ * xs_setup_tcp - Set up transport to use a TCP socket
+ * @xprt: transport to set up
+ * @to: timeout parameters
+ *
+ */
+int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
+{
+ size_t slot_table_size;
+
+ dprintk("RPC: setting up tcp-ipv4 transport...\n");
+
+ xprt->max_reqs = xprt_tcp_slot_table_entries;
+ slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
+ xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+ if (xprt->slot == NULL)
+ return -ENOMEM;
+ memset(xprt->slot, 0, slot_table_size);
+
+ xprt->prot = IPPROTO_TCP;
+ xprt->port = xprt_max_resvport;
+ xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
+ xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
+ xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
+
+ INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt);
+ xprt->bind_timeout = XS_BIND_TO;
+ xprt->connect_timeout = XS_TCP_CONN_TO;
+ xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+ xprt->idle_timeout = XS_IDLE_DISC_TO;
+
+ xprt->ops = &xs_tcp_ops;
+
+ if (to)
+ xprt->timeout = *to;
+ else
+ xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);
+
+ return 0;
+}
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index c5241fcbb966..55538f6b60ff 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -16,6 +16,8 @@
#include <linux/mm.h>
#include <linux/sysctl.h>
+#include <net/sock.h>
+
#ifdef CONFIG_INET
#include <net/ip.h>
#endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 83c8135e1764..0db9e57013fd 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -163,7 +163,7 @@ static void xfrm_policy_timer(unsigned long data)
if (xp->dead)
goto out;
- dir = xp->index & 7;
+ dir = xfrm_policy_id2dir(xp->index);
if (xp->lft.hard_add_expires_seconds) {
long tmo = xp->lft.hard_add_expires_seconds +
@@ -225,7 +225,7 @@ expired:
* SPD calls.
*/
-struct xfrm_policy *xfrm_policy_alloc(int gfp)
+struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
{
struct xfrm_policy *policy;
@@ -417,7 +417,7 @@ struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
struct xfrm_policy *pol, **p;
write_lock_bh(&xfrm_policy_lock);
- for (p = &xfrm_policy_list[id & 7]; (pol=*p)!=NULL; p = &pol->next) {
+ for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
if (pol->index == id) {
xfrm_pol_hold(pol);
if (delete)
@@ -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)
@@ -1192,46 +1192,6 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
EXPORT_SYMBOL(xfrm_bundle_ok);
-/* Well... that's _TASK_. We need to scan through transformation
- * list and figure out what mss tcp should generate in order to
- * final datagram fit to mtu. Mama mia... :-)
- *
- * Apparently, some easy way exists, but we used to choose the most
- * bizarre ones. :-) So, raising Kalashnikov... tra-ta-ta.
- *
- * Consider this function as something like dark humour. :-)
- */
-static int xfrm_get_mss(struct dst_entry *dst, u32 mtu)
-{
- int res = mtu - dst->header_len;
-
- for (;;) {
- struct dst_entry *d = dst;
- int m = res;
-
- do {
- struct xfrm_state *x = d->xfrm;
- if (x) {
- spin_lock_bh(&x->lock);
- if (x->km.state == XFRM_STATE_VALID &&
- x->type && x->type->get_max_size)
- m = x->type->get_max_size(d->xfrm, m);
- else
- m += x->props.header_len;
- spin_unlock_bh(&x->lock);
- }
- } while ((d = d->child) != NULL);
-
- if (m <= mtu)
- break;
- res -= (m - mtu);
- if (res < 88)
- return mtu;
- }
-
- return res + dst->header_len;
-}
-
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{
int err = 0;
@@ -1252,8 +1212,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
dst_ops->negative_advice = xfrm_negative_advice;
if (likely(dst_ops->link_failure == NULL))
dst_ops->link_failure = xfrm_link_failure;
- if (likely(dst_ops->get_mss == NULL))
- dst_ops->get_mss = xfrm_get_mss;
if (likely(afinfo->garbage_collect == NULL))
afinfo->garbage_collect = __xfrm_garbage_collect;
xfrm_policy_afinfo[afinfo->family] = afinfo;
@@ -1281,7 +1239,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
dst_ops->check = NULL;
dst_ops->negative_advice = NULL;
dst_ops->link_failure = NULL;
- dst_ops->get_mss = NULL;
afinfo->garbage_collect = NULL;
}
}
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9d206c282cf1..8b9a4747417d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1026,6 +1026,12 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
}
EXPORT_SYMBOL(xfrm_state_delete_tunnel);
+/*
+ * This function is NOT optimal. For example, with ESP it will give an
+ * MTU that's usually two bytes short of being optimal. However, it will
+ * usually give an answer that's a multiple of 4 provided the input is
+ * also a multiple of 4.
+ */
int xfrm_state_mtu(struct xfrm_state *x, int mtu)
{
int res = mtu;
diff --git a/scripts/.gitignore b/scripts/.gitignore
new file mode 100644
index 000000000000..b46d68bb9e17
--- /dev/null
+++ b/scripts/.gitignore
@@ -0,0 +1,4 @@
+conmakehash
+kallsyms
+pnmtologo
+
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 9087273abf91..db3c708e546b 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -49,6 +49,9 @@ build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
cmd = @$(if $($(quiet)cmd_$(1)),\
echo ' $(subst ','\'',$($(quiet)cmd_$(1)))' &&) $(cmd_$(1))
+# Add $(obj)/ for paths that is not absolute
+objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))
+
###
# if_changed - execute command if any prerequisite is newer than
# target, or command line has changed
diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore
new file mode 100644
index 000000000000..7304e19782c7
--- /dev/null
+++ b/scripts/basic/.gitignore
@@ -0,0 +1,3 @@
+fixdep
+split-include
+docproc
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
new file mode 100644
index 000000000000..2dac3442e0ac
--- /dev/null
+++ b/scripts/kconfig/.gitignore
@@ -0,0 +1,16 @@
+#
+# Generated files
+#
+config*
+lex.*.c
+*.tab.c
+*.tab.h
+
+#
+# configuration programs
+#
+conf
+mconf
+qconf
+gconf
+kxgettext
diff --git a/scripts/mod/.gitignore b/scripts/mod/.gitignore
new file mode 100644
index 000000000000..e9b7abe7b95b
--- /dev/null
+++ b/scripts/mod/.gitignore
@@ -0,0 +1,4 @@
+elfconfig.h
+mk_elfconfig
+modpost
+
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index d8ee38aede26..f2ee673329a7 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -295,11 +295,13 @@ static int do_pcmcia_entry(const char *filename,
{
unsigned int i;
+ id->match_flags = TO_NATIVE(id->match_flags);
id->manf_id = TO_NATIVE(id->manf_id);
id->card_id = TO_NATIVE(id->card_id);
id->func_id = TO_NATIVE(id->func_id);
id->function = TO_NATIVE(id->function);
id->device_no = TO_NATIVE(id->device_no);
+
for (i=0; i<4; i++) {
id->prod_id_hash[i] = TO_NATIVE(id->prod_id_hash[i]);
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 09ffca54b373..3bed09e625c0 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -370,6 +370,12 @@ handle_modversions(struct module *mod, struct elf_info *info,
/* Ignore register directives. */
if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
break;
+ if (symname[0] == '.') {
+ char *munged = strdup(symname);
+ munged[0] = '_';
+ munged[1] = toupper(munged[1]);
+ symname = munged;
+ }
}
#endif
diff --git a/scripts/reference_discarded.pl b/scripts/reference_discarded.pl
index f04f62736851..c2d54148a91f 100644
--- a/scripts/reference_discarded.pl
+++ b/scripts/reference_discarded.pl
@@ -91,12 +91,7 @@ foreach $object (keys(%object)) {
$from !~ /\.exit\.data$/ &&
$from !~ /\.altinstructions$/ &&
$from !~ /\.pdr$/ &&
- $from !~ /\.debug_info$/ &&
- $from !~ /\.debug_aranges$/ &&
- $from !~ /\.debug_ranges$/ &&
- $from !~ /\.debug_line$/ &&
- $from !~ /\.debug_frame$/ &&
- $from !~ /\.debug_loc$/ &&
+ $from !~ /\.debug_.*$/ &&
$from !~ /\.exitcall\.exit$/ &&
$from !~ /\.eh_frame$/ &&
$from !~ /\.stab$/)) {
diff --git a/security/Kconfig b/security/Kconfig
index dcf04a09185d..64d3f1e9ca85 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -35,6 +35,7 @@ config KEYS_DEBUG_PROC_KEYS
config SECURITY
bool "Enable different security models"
+ depends on SYSFS
help
This allows you to choose different security modules to be
configured into your kernel.
diff --git a/security/Makefile b/security/Makefile
index 197cc2f3f1ec..8cbbf2f36709 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -11,7 +11,7 @@ obj-y += commoncap.o
endif
# Object file lists
-obj-$(CONFIG_SECURITY) += security.o dummy.o
+obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
diff --git a/security/dummy.c b/security/dummy.c
index 6ff887586479..3d34f3de7e82 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;
@@ -801,7 +768,7 @@ static int dummy_socket_getpeersec(struct socket *sock, char __user *optval,
return -ENOPROTOOPT;
}
-static inline int dummy_sk_alloc_security (struct sock *sk, int family, int priority)
+static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t priority)
{
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/inode.c b/security/inode.c
new file mode 100644
index 000000000000..a5964502ae30
--- /dev/null
+++ b/security/inode.c
@@ -0,0 +1,347 @@
+/*
+ * inode.c - securityfs
+ *
+ * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * 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.
+ *
+ * Based on fs/debugfs/inode.c which had the following copyright notice:
+ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2004 IBM Inc.
+ */
+
+/* #define DEBUG */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+
+#define SECURITYFS_MAGIC 0x73636673
+
+static struct vfsmount *mount;
+static int mount_count;
+
+/*
+ * TODO:
+ * I think I can get rid of these default_file_ops, but not quite sure...
+ */
+static ssize_t default_read_file(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return 0;
+}
+
+static ssize_t default_write_file(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return count;
+}
+
+static int default_open(struct inode *inode, struct file *file)
+{
+ if (inode->u.generic_ip)
+ file->private_data = inode->u.generic_ip;
+
+ return 0;
+}
+
+static struct file_operations default_file_ops = {
+ .read = default_read_file,
+ .write = default_write_file,
+ .open = default_open,
+};
+
+static struct inode *get_inode(struct super_block *sb, int mode, dev_t dev)
+{
+ struct inode *inode = new_inode(sb);
+
+ if (inode) {
+ inode->i_mode = mode;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ switch (mode & S_IFMT) {
+ default:
+ init_special_inode(inode, mode, dev);
+ break;
+ case S_IFREG:
+ inode->i_fop = &default_file_ops;
+ break;
+ case S_IFDIR:
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+
+ /* directory inodes start off with i_nlink == 2 (for "." entry) */
+ inode->i_nlink++;
+ break;
+ }
+ }
+ return inode;
+}
+
+/* SMP-safe */
+static int mknod(struct inode *dir, struct dentry *dentry,
+ int mode, dev_t dev)
+{
+ struct inode *inode;
+ int error = -EPERM;
+
+ if (dentry->d_inode)
+ return -EEXIST;
+
+ inode = get_inode(dir->i_sb, mode, dev);
+ if (inode) {
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ error = 0;
+ }
+ return error;
+}
+
+static int mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ int res;
+
+ mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ res = mknod(dir, dentry, mode, 0);
+ if (!res)
+ dir->i_nlink++;
+ return res;
+}
+
+static int create(struct inode *dir, struct dentry *dentry, int mode)
+{
+ mode = (mode & S_IALLUGO) | S_IFREG;
+ return mknod(dir, dentry, mode, 0);
+}
+
+static inline int positive(struct dentry *dentry)
+{
+ return dentry->d_inode && !d_unhashed(dentry);
+}
+
+static int fill_super(struct super_block *sb, void *data, int silent)
+{
+ static struct tree_descr files[] = {{""}};
+
+ return simple_fill_super(sb, SECURITYFS_MAGIC, files);
+}
+
+static struct super_block *get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+ void *data)
+{
+ return get_sb_single(fs_type, flags, data, fill_super);
+}
+
+static struct file_system_type fs_type = {
+ .owner = THIS_MODULE,
+ .name = "securityfs",
+ .get_sb = get_sb,
+ .kill_sb = kill_litter_super,
+};
+
+static int create_by_name(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct dentry **dentry)
+{
+ int error = 0;
+
+ *dentry = NULL;
+
+ /* If the parent is not specified, we create it in the root.
+ * We need the root dentry to do this, which is in the super
+ * block. A pointer to that is in the struct vfsmount that we
+ * have around.
+ */
+ if (!parent ) {
+ if (mount && mount->mnt_sb) {
+ parent = mount->mnt_sb->s_root;
+ }
+ }
+ if (!parent) {
+ pr_debug("securityfs: Ah! can not find a parent!\n");
+ return -EFAULT;
+ }
+
+ down(&parent->d_inode->i_sem);
+ *dentry = lookup_one_len(name, parent, strlen(name));
+ if (!IS_ERR(dentry)) {
+ if ((mode & S_IFMT) == S_IFDIR)
+ error = mkdir(parent->d_inode, *dentry, mode);
+ else
+ error = create(parent->d_inode, *dentry, mode);
+ } else
+ error = PTR_ERR(dentry);
+ up(&parent->d_inode->i_sem);
+
+ return error;
+}
+
+/**
+ * securityfs_create_file - create a file in the securityfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the securityfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.u.generic_ip pointer will point to this value on
+ * the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ * this file.
+ *
+ * This is the basic "create a file" function for securityfs. It allows for a
+ * wide range of flexibility in createing a file, or a directory (if you
+ * want to create a directory, the securityfs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the securityfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If securityfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *securityfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent, void *data,
+ struct file_operations *fops)
+{
+ struct dentry *dentry = NULL;
+ int error;
+
+ pr_debug("securityfs: creating file '%s'\n",name);
+
+ error = simple_pin_fs("securityfs", &mount, &mount_count);
+ if (error) {
+ dentry = ERR_PTR(error);
+ goto exit;
+ }
+
+ error = create_by_name(name, mode, parent, &dentry);
+ if (error) {
+ dentry = ERR_PTR(error);
+ simple_release_fs(&mount, &mount_count);
+ goto exit;
+ }
+
+ if (dentry->d_inode) {
+ if (fops)
+ dentry->d_inode->i_fop = fops;
+ if (data)
+ dentry->d_inode->u.generic_ip = data;
+ }
+exit:
+ return dentry;
+}
+EXPORT_SYMBOL_GPL(securityfs_create_file);
+
+/**
+ * securityfs_create_dir - create a directory in the securityfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the directory to
+ * create.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * directory will be created in the root of the securityfs filesystem.
+ *
+ * This function creates a directory in securityfs with the given name.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the securityfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If securityfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
+{
+ return securityfs_create_file(name,
+ S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+ parent, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(securityfs_create_dir);
+
+/**
+ * securityfs_remove - removes a file or directory from the securityfs filesystem
+ *
+ * @dentry: a pointer to a the dentry of the file or directory to be
+ * removed.
+ *
+ * This function removes a file or directory in securityfs that was previously
+ * created with a call to another securityfs function (like
+ * securityfs_create_file() or variants thereof.)
+ *
+ * This function is required to be called in order for the file to be
+ * removed, no automatic cleanup of files will happen when a module is
+ * removed, you are responsible here.
+ */
+void securityfs_remove(struct dentry *dentry)
+{
+ struct dentry *parent;
+
+ if (!dentry)
+ return;
+
+ parent = dentry->d_parent;
+ if (!parent || !parent->d_inode)
+ return;
+
+ down(&parent->d_inode->i_sem);
+ if (positive(dentry)) {
+ if (dentry->d_inode) {
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ simple_rmdir(parent->d_inode, dentry);
+ else
+ simple_unlink(parent->d_inode, dentry);
+ dput(dentry);
+ }
+ }
+ up(&parent->d_inode->i_sem);
+ simple_release_fs(&mount, &mount_count);
+}
+EXPORT_SYMBOL_GPL(securityfs_remove);
+
+static decl_subsys(security, NULL, NULL);
+
+static int __init securityfs_init(void)
+{
+ int retval;
+
+ kset_set_kset_s(&security_subsys, kernel_subsys);
+ retval = subsystem_register(&security_subsys);
+ if (retval)
+ return retval;
+
+ retval = register_filesystem(&fs_type);
+ if (retval)
+ subsystem_unregister(&security_subsys);
+ return retval;
+}
+
+static void __exit securityfs_exit(void)
+{
+ simple_release_fs(&mount, &mount_count);
+ unregister_filesystem(&fs_type);
+ subsystem_unregister(&security_subsys);
+}
+
+core_initcall(securityfs_init);
+module_exit(securityfs_exit);
+MODULE_LICENSE("GPL");
+
diff --git a/security/keys/Makefile b/security/keys/Makefile
index c392d750b208..5145adfb6a05 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -6,6 +6,7 @@ obj-y := \
key.o \
keyring.o \
keyctl.o \
+ permission.o \
process_keys.o \
request_key.o \
request_key_auth.o \
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 46c8602661c9..db99ed434f3a 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -71,26 +71,26 @@ extern void keyring_publish_name(struct key *keyring);
extern int __key_link(struct key *keyring, struct key *key);
-extern struct key *__keyring_search_one(struct key *keyring,
- const struct key_type *type,
- const char *description,
- key_perm_t perm);
+extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
+ const struct key_type *type,
+ const char *description,
+ key_perm_t perm);
extern struct key *keyring_search_instkey(struct key *keyring,
key_serial_t target_id);
typedef int (*key_match_func_t)(const struct key *, const void *);
-extern struct key *keyring_search_aux(struct key *keyring,
- struct task_struct *tsk,
- struct key_type *type,
- const void *description,
- key_match_func_t match);
+extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
+ struct task_struct *tsk,
+ struct key_type *type,
+ const void *description,
+ key_match_func_t match);
-extern struct key *search_process_keyrings(struct key_type *type,
- const void *description,
- key_match_func_t match,
- struct task_struct *tsk);
+extern key_ref_t search_process_keyrings(struct key_type *type,
+ const void *description,
+ key_match_func_t match,
+ struct task_struct *tsk);
extern struct key *find_keyring_by_name(const char *name, key_serial_t bound);
diff --git a/security/keys/key.c b/security/keys/key.c
index fb89f9844465..2182be9e9309 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -693,14 +693,15 @@ void key_type_put(struct key_type *ktype)
* - the key has an incremented refcount
* - we need to put the key if we get an error
*/
-static inline struct key *__key_update(struct key *key, const void *payload,
- size_t plen)
+static inline key_ref_t __key_update(key_ref_t key_ref,
+ const void *payload, size_t plen)
{
+ struct key *key = key_ref_to_ptr(key_ref);
int ret;
/* need write permission on the key to update it */
ret = -EACCES;
- if (!key_permission(key, KEY_WRITE))
+ if (!key_permission(key_ref, KEY_WRITE))
goto error;
ret = -EEXIST;
@@ -719,12 +720,12 @@ static inline struct key *__key_update(struct key *key, const void *payload,
if (ret < 0)
goto error;
- out:
- return key;
+out:
+ return key_ref;
- error:
+error:
key_put(key);
- key = ERR_PTR(ret);
+ key_ref = ERR_PTR(ret);
goto out;
} /* end __key_update() */
@@ -734,52 +735,56 @@ static inline struct key *__key_update(struct key *key, const void *payload,
* search the specified keyring for a key of the same description; if one is
* found, update it, otherwise add a new one
*/
-struct key *key_create_or_update(struct key *keyring,
- const char *type,
- const char *description,
- const void *payload,
- size_t plen,
- int not_in_quota)
+key_ref_t key_create_or_update(key_ref_t keyring_ref,
+ const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ int not_in_quota)
{
struct key_type *ktype;
- struct key *key = NULL;
+ struct key *keyring, *key = NULL;
key_perm_t perm;
+ key_ref_t key_ref;
int ret;
- key_check(keyring);
-
/* look up the key type to see if it's one of the registered kernel
* types */
ktype = key_type_lookup(type);
if (IS_ERR(ktype)) {
- key = ERR_PTR(-ENODEV);
+ key_ref = ERR_PTR(-ENODEV);
goto error;
}
- ret = -EINVAL;
+ key_ref = ERR_PTR(-EINVAL);
if (!ktype->match || !ktype->instantiate)
goto error_2;
+ keyring = key_ref_to_ptr(keyring_ref);
+
+ key_check(keyring);
+
+ down_write(&keyring->sem);
+
+ /* if we're going to allocate a new key, we're going to have
+ * to modify the keyring */
+ key_ref = ERR_PTR(-EACCES);
+ if (!key_permission(keyring_ref, KEY_WRITE))
+ goto error_3;
+
/* search for an existing key of the same type and description in the
* destination keyring
*/
- down_write(&keyring->sem);
-
- key = __keyring_search_one(keyring, ktype, description, 0);
- if (!IS_ERR(key))
+ key_ref = __keyring_search_one(keyring_ref, ktype, description, 0);
+ if (!IS_ERR(key_ref))
goto found_matching_key;
- /* if we're going to allocate a new key, we're going to have to modify
- * the keyring */
- ret = -EACCES;
- if (!key_permission(keyring, KEY_WRITE))
- goto error_3;
-
/* decide on the permissions we want */
- perm = KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
+ perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
+ perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
if (ktype->read)
- perm |= KEY_USR_READ;
+ perm |= KEY_POS_READ | KEY_USR_READ;
if (ktype == &key_type_keyring || ktype->update)
perm |= KEY_USR_WRITE;
@@ -788,7 +793,7 @@ struct key *key_create_or_update(struct key *keyring,
key = key_alloc(ktype, description, current->fsuid, current->fsgid,
perm, not_in_quota);
if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = ERR_PTR(PTR_ERR(key));
goto error_3;
}
@@ -796,15 +801,18 @@ struct key *key_create_or_update(struct key *keyring,
ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
if (ret < 0) {
key_put(key);
- key = ERR_PTR(ret);
+ key_ref = ERR_PTR(ret);
+ goto error_3;
}
+ key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
+
error_3:
up_write(&keyring->sem);
error_2:
key_type_put(ktype);
error:
- return key;
+ return key_ref;
found_matching_key:
/* we found a matching key, so we're going to try to update it
@@ -813,7 +821,7 @@ struct key *key_create_or_update(struct key *keyring,
up_write(&keyring->sem);
key_type_put(ktype);
- key = __key_update(key, payload, plen);
+ key_ref = __key_update(key_ref, payload, plen);
goto error;
} /* end key_create_or_update() */
@@ -824,15 +832,16 @@ EXPORT_SYMBOL(key_create_or_update);
/*
* update a key
*/
-int key_update(struct key *key, const void *payload, size_t plen)
+int key_update(key_ref_t key_ref, const void *payload, size_t plen)
{
+ struct key *key = key_ref_to_ptr(key_ref);
int ret;
key_check(key);
/* the key must be writable */
ret = -EACCES;
- if (!key_permission(key, KEY_WRITE))
+ if (!key_permission(key_ref, KEY_WRITE))
goto error;
/* attempt to update it if supported */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index a6516a64b297..4c670ee6acf9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -34,7 +34,7 @@ asmlinkage long sys_add_key(const char __user *_type,
size_t plen,
key_serial_t ringid)
{
- struct key *keyring, *key;
+ key_ref_t keyring_ref, key_ref;
char type[32], *description;
void *payload;
long dlen, ret;
@@ -86,25 +86,25 @@ asmlinkage long sys_add_key(const char __user *_type,
}
/* find the target keyring (which must be writable) */
- keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error3;
}
/* create or update the requested key and add it to the target
* keyring */
- key = key_create_or_update(keyring, type, description,
- payload, plen, 0);
- if (!IS_ERR(key)) {
- ret = key->serial;
- key_put(key);
+ key_ref = key_create_or_update(keyring_ref, type, description,
+ payload, plen, 0);
+ if (!IS_ERR(key_ref)) {
+ ret = key_ref_to_ptr(key_ref)->serial;
+ key_ref_put(key_ref);
}
else {
- ret = PTR_ERR(key);
+ ret = PTR_ERR(key_ref);
}
- key_put(keyring);
+ key_ref_put(keyring_ref);
error3:
kfree(payload);
error2:
@@ -131,7 +131,8 @@ asmlinkage long sys_request_key(const char __user *_type,
key_serial_t destringid)
{
struct key_type *ktype;
- struct key *key, *dest;
+ struct key *key;
+ key_ref_t dest_ref;
char type[32], *description, *callout_info;
long dlen, ret;
@@ -187,11 +188,11 @@ asmlinkage long sys_request_key(const char __user *_type,
}
/* get the destination keyring if specified */
- dest = NULL;
+ dest_ref = NULL;
if (destringid) {
- dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
- if (IS_ERR(dest)) {
- ret = PTR_ERR(dest);
+ dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
+ if (IS_ERR(dest_ref)) {
+ ret = PTR_ERR(dest_ref);
goto error3;
}
}
@@ -204,7 +205,8 @@ asmlinkage long sys_request_key(const char __user *_type,
}
/* do the search */
- key = request_key_and_link(ktype, description, callout_info, dest);
+ key = request_key_and_link(ktype, description, callout_info,
+ key_ref_to_ptr(dest_ref));
if (IS_ERR(key)) {
ret = PTR_ERR(key);
goto error5;
@@ -216,7 +218,7 @@ asmlinkage long sys_request_key(const char __user *_type,
error5:
key_type_put(ktype);
error4:
- key_put(dest);
+ key_ref_put(dest_ref);
error3:
kfree(callout_info);
error2:
@@ -234,17 +236,17 @@ asmlinkage long sys_request_key(const char __user *_type,
*/
long keyctl_get_keyring_ID(key_serial_t id, int create)
{
- struct key *key;
+ key_ref_t key_ref;
long ret;
- key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error;
}
- ret = key->serial;
- key_put(key);
+ ret = key_ref_to_ptr(key_ref)->serial;
+ key_ref_put(key_ref);
error:
return ret;
@@ -302,7 +304,7 @@ long keyctl_update_key(key_serial_t id,
const void __user *_payload,
size_t plen)
{
- struct key *key;
+ key_ref_t key_ref;
void *payload;
long ret;
@@ -324,16 +326,16 @@ long keyctl_update_key(key_serial_t id,
}
/* find the target key (which must be writable) */
- key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error2;
}
/* update the key */
- ret = key_update(key, payload, plen);
+ ret = key_update(key_ref, payload, plen);
- key_put(key);
+ key_ref_put(key_ref);
error2:
kfree(payload);
error:
@@ -349,19 +351,19 @@ long keyctl_update_key(key_serial_t id,
*/
long keyctl_revoke_key(key_serial_t id)
{
- struct key *key;
+ key_ref_t key_ref;
long ret;
- key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error;
}
- key_revoke(key);
+ key_revoke(key_ref_to_ptr(key_ref));
ret = 0;
- key_put(key);
+ key_ref_put(key_ref);
error:
return ret;
@@ -375,18 +377,18 @@ long keyctl_revoke_key(key_serial_t id)
*/
long keyctl_keyring_clear(key_serial_t ringid)
{
- struct key *keyring;
+ key_ref_t keyring_ref;
long ret;
- keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error;
}
- ret = keyring_clear(keyring);
+ ret = keyring_clear(key_ref_to_ptr(keyring_ref));
- key_put(keyring);
+ key_ref_put(keyring_ref);
error:
return ret;
@@ -401,26 +403,26 @@ long keyctl_keyring_clear(key_serial_t ringid)
*/
long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
{
- struct key *keyring, *key;
+ key_ref_t keyring_ref, key_ref;
long ret;
- keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error;
}
- key = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error2;
}
- ret = key_link(keyring, key);
+ ret = key_link(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
- key_put(key);
+ key_ref_put(key_ref);
error2:
- key_put(keyring);
+ key_ref_put(keyring_ref);
error:
return ret;
@@ -435,26 +437,26 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
*/
long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
{
- struct key *keyring, *key;
+ key_ref_t keyring_ref, key_ref;
long ret;
- keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error;
}
- key = lookup_user_key(NULL, id, 0, 0, 0);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, 0, 0, 0);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error2;
}
- ret = key_unlink(keyring, key);
+ ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
- key_put(key);
+ key_ref_put(key_ref);
error2:
- key_put(keyring);
+ key_ref_put(keyring_ref);
error:
return ret;
@@ -476,24 +478,26 @@ long keyctl_describe_key(key_serial_t keyid,
size_t buflen)
{
struct key *key, *instkey;
+ key_ref_t key_ref;
char *tmpbuf;
long ret;
- key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
- if (IS_ERR(key)) {
+ key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
+ if (IS_ERR(key_ref)) {
/* viewing a key under construction is permitted if we have the
* authorisation token handy */
- if (PTR_ERR(key) == -EACCES) {
+ if (PTR_ERR(key_ref) == -EACCES) {
instkey = key_get_instantiation_authkey(keyid);
if (!IS_ERR(instkey)) {
key_put(instkey);
- key = lookup_user_key(NULL, keyid, 0, 1, 0);
- if (!IS_ERR(key))
+ key_ref = lookup_user_key(NULL, keyid,
+ 0, 1, 0);
+ if (!IS_ERR(key_ref))
goto okay;
}
}
- ret = PTR_ERR(key);
+ ret = PTR_ERR(key_ref);
goto error;
}
@@ -504,13 +508,16 @@ okay:
if (!tmpbuf)
goto error2;
+ key = key_ref_to_ptr(key_ref);
+
ret = snprintf(tmpbuf, PAGE_SIZE - 1,
- "%s;%d;%d;%06x;%s",
- key->type->name,
- key->uid,
- key->gid,
- key->perm,
- key->description ? key->description :""
+ "%s;%d;%d;%08x;%s",
+ key_ref_to_ptr(key_ref)->type->name,
+ key_ref_to_ptr(key_ref)->uid,
+ key_ref_to_ptr(key_ref)->gid,
+ key_ref_to_ptr(key_ref)->perm,
+ key_ref_to_ptr(key_ref)->description ?
+ key_ref_to_ptr(key_ref)->description : ""
);
/* include a NUL char at the end of the data */
@@ -530,7 +537,7 @@ okay:
kfree(tmpbuf);
error2:
- key_put(key);
+ key_ref_put(key_ref);
error:
return ret;
@@ -552,7 +559,7 @@ long keyctl_keyring_search(key_serial_t ringid,
key_serial_t destringid)
{
struct key_type *ktype;
- struct key *keyring, *key, *dest;
+ key_ref_t keyring_ref, key_ref, dest_ref;
char type[32], *description;
long dlen, ret;
@@ -581,18 +588,18 @@ long keyctl_keyring_search(key_serial_t ringid,
goto error2;
/* get the keyring at which to begin the search */
- keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error2;
}
/* get the destination keyring if specified */
- dest = NULL;
+ dest_ref = NULL;
if (destringid) {
- dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
- if (IS_ERR(dest)) {
- ret = PTR_ERR(dest);
+ dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
+ if (IS_ERR(dest_ref)) {
+ ret = PTR_ERR(dest_ref);
goto error3;
}
}
@@ -605,9 +612,9 @@ long keyctl_keyring_search(key_serial_t ringid,
}
/* do the search */
- key = keyring_search(keyring, ktype, description);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = keyring_search(keyring_ref, ktype, description);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
/* treat lack or presence of a negative key the same */
if (ret == -EAGAIN)
@@ -616,26 +623,26 @@ long keyctl_keyring_search(key_serial_t ringid,
}
/* link the resulting key to the destination keyring if we can */
- if (dest) {
+ if (dest_ref) {
ret = -EACCES;
- if (!key_permission(key, KEY_LINK))
+ if (!key_permission(key_ref, KEY_LINK))
goto error6;
- ret = key_link(dest, key);
+ ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
if (ret < 0)
goto error6;
}
- ret = key->serial;
+ ret = key_ref_to_ptr(key_ref)->serial;
error6:
- key_put(key);
+ key_ref_put(key_ref);
error5:
key_type_put(ktype);
error4:
- key_put(dest);
+ key_ref_put(dest_ref);
error3:
- key_put(keyring);
+ key_ref_put(keyring_ref);
error2:
kfree(description);
error:
@@ -645,16 +652,6 @@ long keyctl_keyring_search(key_serial_t ringid,
/*****************************************************************************/
/*
- * see if the key we're looking at is the target key
- */
-static int keyctl_read_key_same(const struct key *key, const void *target)
-{
- return key == target;
-
-} /* end keyctl_read_key_same() */
-
-/*****************************************************************************/
-/*
* read a user key's payload
* - the keyring must be readable or the key must be searchable from the
* process's keyrings
@@ -665,38 +662,33 @@ static int keyctl_read_key_same(const struct key *key, const void *target)
*/
long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
{
- struct key *key, *skey;
+ struct key *key;
+ key_ref_t key_ref;
long ret;
/* find the key first */
- key = lookup_user_key(NULL, keyid, 0, 0, 0);
- if (!IS_ERR(key)) {
- /* see if we can read it directly */
- if (key_permission(key, KEY_READ))
- goto can_read_key;
-
- /* we can't; see if it's searchable from this process's
- * keyrings
- * - we automatically take account of the fact that it may be
- * dangling off an instantiation key
- */
- skey = search_process_keyrings(key->type, key,
- keyctl_read_key_same, current);
- if (!IS_ERR(skey))
- goto can_read_key2;
-
- ret = PTR_ERR(skey);
- if (ret == -EAGAIN)
- ret = -EACCES;
- goto error2;
+ key_ref = lookup_user_key(NULL, keyid, 0, 0, 0);
+ if (IS_ERR(key_ref)) {
+ ret = -ENOKEY;
+ goto error;
}
- ret = -ENOKEY;
- goto error;
+ key = key_ref_to_ptr(key_ref);
+
+ /* see if we can read it directly */
+ if (key_permission(key_ref, KEY_READ))
+ goto can_read_key;
+
+ /* we can't; see if it's searchable from this process's keyrings
+ * - we automatically take account of the fact that it may be
+ * dangling off an instantiation key
+ */
+ if (!is_key_possessed(key_ref)) {
+ ret = -EACCES;
+ goto error2;
+ }
/* the key is probably readable - now try to read it */
- can_read_key2:
- key_put(skey);
can_read_key:
ret = key_validate(key);
if (ret == 0) {
@@ -727,18 +719,21 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
{
struct key *key;
+ key_ref_t key_ref;
long ret;
ret = 0;
if (uid == (uid_t) -1 && gid == (gid_t) -1)
goto error;
- key = lookup_user_key(NULL, id, 1, 1, 0);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error;
}
+ key = key_ref_to_ptr(key_ref);
+
/* make the changes with the locks held to prevent chown/chown races */
ret = -EACCES;
down_write(&key->sem);
@@ -784,18 +779,21 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
{
struct key *key;
+ key_ref_t key_ref;
long ret;
ret = -EINVAL;
- if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
+ if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
goto error;
- key = lookup_user_key(NULL, id, 1, 1, 0);
- if (IS_ERR(key)) {
- ret = PTR_ERR(key);
+ key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
goto error;
}
+ key = key_ref_to_ptr(key_ref);
+
/* make the changes with the locks held to prevent chown/chmod races */
ret = -EACCES;
down_write(&key->sem);
@@ -824,7 +822,8 @@ long keyctl_instantiate_key(key_serial_t id,
key_serial_t ringid)
{
struct request_key_auth *rka;
- struct key *instkey, *keyring;
+ struct key *instkey;
+ key_ref_t keyring_ref;
void *payload;
long ret;
@@ -857,21 +856,21 @@ long keyctl_instantiate_key(key_serial_t id,
/* find the destination keyring amongst those belonging to the
* requesting task */
- keyring = NULL;
+ keyring_ref = NULL;
if (ringid) {
- keyring = lookup_user_key(rka->context, ringid, 1, 0,
- KEY_WRITE);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(rka->context, ringid, 1, 0,
+ KEY_WRITE);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error3;
}
}
/* instantiate the key and link it into a keyring */
ret = key_instantiate_and_link(rka->target_key, payload, plen,
- keyring, instkey);
+ key_ref_to_ptr(keyring_ref), instkey);
- key_put(keyring);
+ key_ref_put(keyring_ref);
error3:
key_put(instkey);
error2:
@@ -889,7 +888,8 @@ long keyctl_instantiate_key(key_serial_t id,
long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
{
struct request_key_auth *rka;
- struct key *instkey, *keyring;
+ struct key *instkey;
+ key_ref_t keyring_ref;
long ret;
/* find the instantiation authorisation key */
@@ -903,19 +903,20 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
/* find the destination keyring if present (which must also be
* writable) */
- keyring = NULL;
+ keyring_ref = NULL;
if (ringid) {
- keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
+ keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+ if (IS_ERR(keyring_ref)) {
+ ret = PTR_ERR(keyring_ref);
goto error2;
}
}
/* instantiate the key and link it into a keyring */
- ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey);
+ ret = key_negate_and_link(rka->target_key, timeout,
+ key_ref_to_ptr(keyring_ref), instkey);
- key_put(keyring);
+ key_ref_put(keyring_ref);
error2:
key_put(instkey);
error:
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 9c208c756df8..0639396dd441 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -309,7 +309,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
int ret;
keyring = key_alloc(&key_type_keyring, description,
- uid, gid, KEY_USR_ALL, not_in_quota);
+ uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
if (!IS_ERR(keyring)) {
ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -333,12 +333,13 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
* - we rely on RCU to prevent the keyring lists from disappearing on us
* - we return -EAGAIN if we didn't find any matching key
* - we return -ENOKEY if we only found negative matching keys
+ * - we propagate the possession attribute from the keyring ref to the key ref
*/
-struct key *keyring_search_aux(struct key *keyring,
- struct task_struct *context,
- struct key_type *type,
- const void *description,
- key_match_func_t match)
+key_ref_t keyring_search_aux(key_ref_t keyring_ref,
+ struct task_struct *context,
+ struct key_type *type,
+ const void *description,
+ key_match_func_t match)
{
struct {
struct keyring_list *keylist;
@@ -347,29 +348,33 @@ struct key *keyring_search_aux(struct key *keyring,
struct keyring_list *keylist;
struct timespec now;
- struct key *key;
+ unsigned long possessed;
+ struct key *keyring, *key;
+ key_ref_t key_ref;
long err;
int sp, kix;
+ keyring = key_ref_to_ptr(keyring_ref);
+ possessed = is_key_possessed(keyring_ref);
key_check(keyring);
- rcu_read_lock();
-
/* top keyring must have search permission to begin the search */
- key = ERR_PTR(-EACCES);
- if (!key_task_permission(keyring, context, KEY_SEARCH))
+ key_ref = ERR_PTR(-EACCES);
+ if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
goto error;
- key = ERR_PTR(-ENOTDIR);
+ key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
goto error;
+ rcu_read_lock();
+
now = current_kernel_time();
err = -EAGAIN;
sp = 0;
/* start processing a new keyring */
- descend:
+descend:
if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
goto not_this_keyring;
@@ -397,7 +402,8 @@ struct key *keyring_search_aux(struct key *keyring,
continue;
/* key must have search permissions */
- if (!key_task_permission(key, context, KEY_SEARCH))
+ if (!key_task_permission(make_key_ref(key, possessed),
+ context, KEY_SEARCH))
continue;
/* we set a different error code if we find a negative key */
@@ -411,7 +417,7 @@ struct key *keyring_search_aux(struct key *keyring,
/* search through the keyrings nested in this one */
kix = 0;
- ascend:
+ascend:
for (; kix < keylist->nkeys; kix++) {
key = keylist->keys[kix];
if (key->type != &key_type_keyring)
@@ -423,7 +429,8 @@ struct key *keyring_search_aux(struct key *keyring,
if (sp >= KEYRING_SEARCH_MAX_DEPTH)
continue;
- if (!key_task_permission(key, context, KEY_SEARCH))
+ if (!key_task_permission(make_key_ref(key, possessed),
+ context, KEY_SEARCH))
continue;
/* stack the current position */
@@ -438,7 +445,7 @@ struct key *keyring_search_aux(struct key *keyring,
/* the keyring we're looking at was disqualified or didn't contain a
* matching key */
- not_this_keyring:
+not_this_keyring:
if (sp > 0) {
/* resume the processing of a keyring higher up in the tree */
sp--;
@@ -447,16 +454,18 @@ struct key *keyring_search_aux(struct key *keyring,
goto ascend;
}
- key = ERR_PTR(err);
- goto error;
+ key_ref = ERR_PTR(err);
+ goto error_2;
/* we found a viable match */
- found:
+found:
atomic_inc(&key->usage);
key_check(key);
- error:
+ key_ref = make_key_ref(key, possessed);
+error_2:
rcu_read_unlock();
- return key;
+error:
+ return key_ref;
} /* end keyring_search_aux() */
@@ -469,9 +478,9 @@ struct key *keyring_search_aux(struct key *keyring,
* - we return -EAGAIN if we didn't find any matching key
* - we return -ENOKEY if we only found negative matching keys
*/
-struct key *keyring_search(struct key *keyring,
- struct key_type *type,
- const char *description)
+key_ref_t keyring_search(key_ref_t keyring,
+ struct key_type *type,
+ const char *description)
{
if (!type->match)
return ERR_PTR(-ENOKEY);
@@ -488,15 +497,19 @@ EXPORT_SYMBOL(keyring_search);
* search the given keyring only (no recursion)
* - keyring must be locked by caller
*/
-struct key *__keyring_search_one(struct key *keyring,
- const struct key_type *ktype,
- const char *description,
- key_perm_t perm)
+key_ref_t __keyring_search_one(key_ref_t keyring_ref,
+ const struct key_type *ktype,
+ const char *description,
+ key_perm_t perm)
{
struct keyring_list *klist;
- struct key *key;
+ unsigned long possessed;
+ struct key *keyring, *key;
int loop;
+ keyring = key_ref_to_ptr(keyring_ref);
+ possessed = is_key_possessed(keyring_ref);
+
rcu_read_lock();
klist = rcu_dereference(keyring->payload.subscriptions);
@@ -507,21 +520,21 @@ struct key *__keyring_search_one(struct key *keyring,
if (key->type == ktype &&
(!key->type->match ||
key->type->match(key, description)) &&
- key_permission(key, perm) &&
+ key_permission(make_key_ref(key, possessed),
+ perm) &&
!test_bit(KEY_FLAG_REVOKED, &key->flags)
)
goto found;
}
}
- key = ERR_PTR(-ENOKEY);
- goto error;
+ rcu_read_unlock();
+ return ERR_PTR(-ENOKEY);
found:
atomic_inc(&key->usage);
- error:
rcu_read_unlock();
- return key;
+ return make_key_ref(key, possessed);
} /* end __keyring_search_one() */
@@ -603,7 +616,8 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
if (strcmp(keyring->description, name) != 0)
continue;
- if (!key_permission(keyring, KEY_SEARCH))
+ if (!key_permission(make_key_ref(keyring, 0),
+ KEY_SEARCH))
continue;
/* found a potential candidate, but we still need to
diff --git a/security/keys/permission.c b/security/keys/permission.c
new file mode 100644
index 000000000000..03db073ba45c
--- /dev/null
+++ b/security/keys/permission.c
@@ -0,0 +1,70 @@
+/* permission.c: key permission determination
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.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.
+ */
+
+#include <linux/module.h>
+#include "internal.h"
+
+/*****************************************************************************/
+/*
+ * check to see whether permission is granted to use a key in the desired way,
+ * but permit the security modules to override
+ */
+int key_task_permission(const key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ struct key *key;
+ key_perm_t kperm;
+ int ret;
+
+ key = key_ref_to_ptr(key_ref);
+
+ /* use the second 8-bits of permissions for keys the caller owns */
+ if (key->uid == context->fsuid) {
+ kperm = key->perm >> 16;
+ goto use_these_perms;
+ }
+
+ /* use the third 8-bits of permissions for keys the caller has a group
+ * membership in common with */
+ if (key->gid != -1 && key->perm & KEY_GRP_ALL) {
+ if (key->gid == context->fsgid) {
+ kperm = key->perm >> 8;
+ goto use_these_perms;
+ }
+
+ task_lock(context);
+ ret = groups_search(context->group_info, key->gid);
+ task_unlock(context);
+
+ if (ret) {
+ kperm = key->perm >> 8;
+ goto use_these_perms;
+ }
+ }
+
+ /* otherwise use the least-significant 8-bits */
+ kperm = key->perm;
+
+use_these_perms:
+ /* use the top 8-bits of permissions for keys the caller possesses
+ * - possessor permissions are additive with other permissions
+ */
+ if (is_key_possessed(key_ref))
+ kperm |= key->perm >> 24;
+
+ kperm = kperm & perm & KEY_ALL;
+
+ return kperm == perm;
+
+} /* end key_task_permission() */
+
+EXPORT_SYMBOL(key_task_permission);
diff --git a/security/keys/proc.c b/security/keys/proc.c
index c55cf1fd0826..12b750e51fbf 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -167,7 +167,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
#define showflag(KEY, LETTER, FLAG) \
(test_bit(FLAG, &(KEY)->flags) ? LETTER : '-')
- seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ",
+ seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
key->serial,
showflag(key, 'I', KEY_FLAG_INSTANTIATED),
showflag(key, 'R', KEY_FLAG_REVOKED),
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index c089f78fb94e..d42d2158ce13 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -39,7 +39,7 @@ struct key root_user_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
- .perm = KEY_USR_ALL,
+ .perm = KEY_POS_ALL | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid.0",
#ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@ struct key root_session_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
- .perm = KEY_USR_ALL,
+ .perm = KEY_POS_ALL | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid_ses.0",
#ifdef KEY_DEBUGGING
@@ -98,7 +98,7 @@ int alloc_uid_keyring(struct user_struct *user)
user->session_keyring = session_keyring;
ret = 0;
- error:
+error:
return ret;
} /* end alloc_uid_keyring() */
@@ -156,7 +156,7 @@ int install_thread_keyring(struct task_struct *tsk)
ret = 0;
key_put(old);
- error:
+error:
return ret;
} /* end install_thread_keyring() */
@@ -193,7 +193,7 @@ int install_process_keyring(struct task_struct *tsk)
}
ret = 0;
- error:
+error:
return ret;
} /* end install_process_keyring() */
@@ -236,7 +236,7 @@ static int install_session_keyring(struct task_struct *tsk,
/* we're using RCU on the pointer */
synchronize_rcu();
key_put(old);
- error:
+error:
return ret;
} /* end install_session_keyring() */
@@ -376,13 +376,13 @@ void key_fsgid_changed(struct task_struct *tsk)
* - we return -EAGAIN if we didn't find any matching key
* - we return -ENOKEY if we found only negative matching keys
*/
-struct key *search_process_keyrings(struct key_type *type,
- const void *description,
- key_match_func_t match,
- struct task_struct *context)
+key_ref_t search_process_keyrings(struct key_type *type,
+ const void *description,
+ key_match_func_t match,
+ struct task_struct *context)
{
struct request_key_auth *rka;
- struct key *key, *ret, *err, *instkey;
+ key_ref_t key_ref, ret, err, instkey_ref;
/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
* searchable, but we failed to find a key or we found a negative key;
@@ -391,46 +391,48 @@ struct key *search_process_keyrings(struct key_type *type,
*
* in terms of priority: success > -ENOKEY > -EAGAIN > other error
*/
- key = NULL;
+ key_ref = NULL;
ret = NULL;
err = ERR_PTR(-EAGAIN);
/* search the thread keyring first */
if (context->thread_keyring) {
- key = keyring_search_aux(context->thread_keyring,
- context, type, description, match);
- if (!IS_ERR(key))
+ key_ref = keyring_search_aux(
+ make_key_ref(context->thread_keyring, 1),
+ context, type, description, match);
+ if (!IS_ERR(key_ref))
goto found;
- switch (PTR_ERR(key)) {
+ switch (PTR_ERR(key_ref)) {
case -EAGAIN: /* no key */
if (ret)
break;
case -ENOKEY: /* negative key */
- ret = key;
+ ret = key_ref;
break;
default:
- err = key;
+ err = key_ref;
break;
}
}
/* search the process keyring second */
if (context->signal->process_keyring) {
- key = keyring_search_aux(context->signal->process_keyring,
- context, type, description, match);
- if (!IS_ERR(key))
+ key_ref = keyring_search_aux(
+ make_key_ref(context->signal->process_keyring, 1),
+ context, type, description, match);
+ if (!IS_ERR(key_ref))
goto found;
- switch (PTR_ERR(key)) {
+ switch (PTR_ERR(key_ref)) {
case -EAGAIN: /* no key */
if (ret)
break;
case -ENOKEY: /* negative key */
- ret = key;
+ ret = key_ref;
break;
default:
- err = key;
+ err = key_ref;
break;
}
}
@@ -438,23 +440,25 @@ struct key *search_process_keyrings(struct key_type *type,
/* search the session keyring */
if (context->signal->session_keyring) {
rcu_read_lock();
- key = keyring_search_aux(
- rcu_dereference(context->signal->session_keyring),
+ key_ref = keyring_search_aux(
+ make_key_ref(rcu_dereference(
+ context->signal->session_keyring),
+ 1),
context, type, description, match);
rcu_read_unlock();
- if (!IS_ERR(key))
+ if (!IS_ERR(key_ref))
goto found;
- switch (PTR_ERR(key)) {
+ switch (PTR_ERR(key_ref)) {
case -EAGAIN: /* no key */
if (ret)
break;
case -ENOKEY: /* negative key */
- ret = key;
+ ret = key_ref;
break;
default:
- err = key;
+ err = key_ref;
break;
}
@@ -465,51 +469,54 @@ struct key *search_process_keyrings(struct key_type *type,
goto no_key;
rcu_read_lock();
- instkey = __keyring_search_one(
- rcu_dereference(context->signal->session_keyring),
+ instkey_ref = __keyring_search_one(
+ make_key_ref(rcu_dereference(
+ context->signal->session_keyring),
+ 1),
&key_type_request_key_auth, NULL, 0);
rcu_read_unlock();
- if (IS_ERR(instkey))
+ if (IS_ERR(instkey_ref))
goto no_key;
- rka = instkey->payload.data;
+ rka = key_ref_to_ptr(instkey_ref)->payload.data;
- key = search_process_keyrings(type, description, match,
- rka->context);
- key_put(instkey);
+ key_ref = search_process_keyrings(type, description, match,
+ rka->context);
+ key_ref_put(instkey_ref);
- if (!IS_ERR(key))
+ if (!IS_ERR(key_ref))
goto found;
- switch (PTR_ERR(key)) {
+ switch (PTR_ERR(key_ref)) {
case -EAGAIN: /* no key */
if (ret)
break;
case -ENOKEY: /* negative key */
- ret = key;
+ ret = key_ref;
break;
default:
- err = key;
+ err = key_ref;
break;
}
}
/* or search the user-session keyring */
else {
- key = keyring_search_aux(context->user->session_keyring,
- context, type, description, match);
- if (!IS_ERR(key))
+ key_ref = keyring_search_aux(
+ make_key_ref(context->user->session_keyring, 1),
+ context, type, description, match);
+ if (!IS_ERR(key_ref))
goto found;
- switch (PTR_ERR(key)) {
+ switch (PTR_ERR(key_ref)) {
case -EAGAIN: /* no key */
if (ret)
break;
case -ENOKEY: /* negative key */
- ret = key;
+ ret = key_ref;
break;
default:
- err = key;
+ err = key_ref;
break;
}
}
@@ -517,29 +524,40 @@ struct key *search_process_keyrings(struct key_type *type,
no_key:
/* no key - decide on the error we're going to go for */
- key = ret ? ret : err;
+ key_ref = ret ? ret : err;
found:
- return key;
+ return key_ref;
} /* end search_process_keyrings() */
/*****************************************************************************/
/*
+ * see if the key we're looking at is the target key
+ */
+static int lookup_user_key_possessed(const struct key *key, const void *target)
+{
+ return key == target;
+
+} /* end lookup_user_key_possessed() */
+
+/*****************************************************************************/
+/*
* lookup a key given a key ID from userspace with a given permissions mask
* - don't create special keyrings unless so requested
* - partially constructed keys aren't found unless requested
*/
-struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
- int create, int partial, key_perm_t perm)
+key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
+ int create, int partial, key_perm_t perm)
{
+ key_ref_t key_ref, skey_ref;
struct key *key;
int ret;
if (!context)
context = current;
- key = ERR_PTR(-ENOKEY);
+ key_ref = ERR_PTR(-ENOKEY);
switch (id) {
case KEY_SPEC_THREAD_KEYRING:
@@ -556,6 +574,7 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
key = context->thread_keyring;
atomic_inc(&key->usage);
+ key_ref = make_key_ref(key, 1);
break;
case KEY_SPEC_PROCESS_KEYRING:
@@ -572,6 +591,7 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
key = context->signal->process_keyring;
atomic_inc(&key->usage);
+ key_ref = make_key_ref(key, 1);
break;
case KEY_SPEC_SESSION_KEYRING:
@@ -579,7 +599,7 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
/* always install a session keyring upon access if one
* doesn't exist yet */
ret = install_session_keyring(
- context, context->user->session_keyring);
+ context, context->user->session_keyring);
if (ret < 0)
goto error;
}
@@ -588,16 +608,19 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
key = rcu_dereference(context->signal->session_keyring);
atomic_inc(&key->usage);
rcu_read_unlock();
+ key_ref = make_key_ref(key, 1);
break;
case KEY_SPEC_USER_KEYRING:
key = context->user->uid_keyring;
atomic_inc(&key->usage);
+ key_ref = make_key_ref(key, 1);
break;
case KEY_SPEC_USER_SESSION_KEYRING:
key = context->user->session_keyring;
atomic_inc(&key->usage);
+ key_ref = make_key_ref(key, 1);
break;
case KEY_SPEC_GROUP_KEYRING:
@@ -606,13 +629,28 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
goto error;
default:
- key = ERR_PTR(-EINVAL);
+ key_ref = ERR_PTR(-EINVAL);
if (id < 1)
goto error;
key = key_lookup(id);
- if (IS_ERR(key))
+ if (IS_ERR(key)) {
+ key_ref = ERR_PTR(PTR_ERR(key));
goto error;
+ }
+
+ key_ref = make_key_ref(key, 0);
+
+ /* check to see if we possess the key */
+ skey_ref = search_process_keyrings(key->type, key,
+ lookup_user_key_possessed,
+ current);
+
+ if (!IS_ERR(skey_ref)) {
+ key_put(key);
+ key_ref = skey_ref;
+ }
+
break;
}
@@ -630,15 +668,15 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
/* check the permissions */
ret = -EACCES;
- if (!key_task_permission(key, context, perm))
+ if (!key_task_permission(key_ref, context, perm))
goto invalid_key;
- error:
- return key;
+error:
+ return key_ref;
- invalid_key:
- key_put(key);
- key = ERR_PTR(ret);
+invalid_key:
+ key_ref_put(key_ref);
+ key_ref = ERR_PTR(ret);
goto error;
} /* end lookup_user_key() */
@@ -694,9 +732,9 @@ long join_session_keyring(const char *name)
ret = keyring->serial;
key_put(keyring);
- error2:
+error2:
up(&key_session_sem);
- error:
+error:
return ret;
} /* end join_session_keyring() */
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 90c1506d007c..5cc4bba70db6 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -7,6 +7,8 @@
* 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.
+ *
+ * See Documentation/keys-request-key.txt
*/
#include <linux/module.h>
@@ -129,7 +131,7 @@ static struct key *__request_key_construction(struct key_type *type,
/* create a key and add it to the queue */
key = key_alloc(type, description,
- current->fsuid, current->fsgid, KEY_USR_ALL, 0);
+ current->fsuid, current->fsgid, KEY_POS_ALL, 0);
if (IS_ERR(key))
goto alloc_failed;
@@ -365,14 +367,24 @@ struct key *request_key_and_link(struct key_type *type,
{
struct key_user *user;
struct key *key;
+ key_ref_t key_ref;
kenter("%s,%s,%s,%p",
type->name, description, callout_info, dest_keyring);
/* search all the process keyrings for a key */
- key = search_process_keyrings(type, description, type->match, current);
+ key_ref = search_process_keyrings(type, description, type->match,
+ current);
+
+ kdebug("search 1: %p", key_ref);
- if (PTR_ERR(key) == -EAGAIN) {
+ if (!IS_ERR(key_ref)) {
+ key = key_ref_to_ptr(key_ref);
+ }
+ else if (PTR_ERR(key_ref) != -EAGAIN) {
+ key = ERR_PTR(PTR_ERR(key_ref));
+ }
+ else {
/* the search failed, but the keyrings were searchable, so we
* should consult userspace if we can */
key = ERR_PTR(-ENOKEY);
@@ -384,7 +396,7 @@ struct key *request_key_and_link(struct key_type *type,
if (!user)
goto nomem;
- do {
+ for (;;) {
if (signal_pending(current))
goto interrupted;
@@ -397,10 +409,22 @@ struct key *request_key_and_link(struct key_type *type,
/* someone else made the key we want, so we need to
* search again as it might now be available to us */
- key = search_process_keyrings(type, description,
- type->match, current);
+ key_ref = search_process_keyrings(type, description,
+ type->match,
+ current);
+
+ kdebug("search 2: %p", key_ref);
- } while (PTR_ERR(key) == -EAGAIN);
+ if (!IS_ERR(key_ref)) {
+ key = key_ref_to_ptr(key_ref);
+ break;
+ }
+
+ if (PTR_ERR(key_ref) != -EAGAIN) {
+ key = ERR_PTR(PTR_ERR(key_ref));
+ break;
+ }
+ }
key_user_put(user);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index f22264632229..a8e4069d48cb 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -7,6 +7,8 @@
* 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.
+ *
+ * See Documentation/keys-request-key.txt
*/
#include <linux/module.h>
@@ -96,6 +98,7 @@ static void request_key_auth_destroy(struct key *key)
kenter("{%d}", key->serial);
key_put(rka->target_key);
+ kfree(rka);
} /* end request_key_auth_destroy() */
@@ -126,7 +129,7 @@ struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
rkakey = key_alloc(&key_type_request_key_auth, desc,
current->fsuid, current->fsgid,
- KEY_USR_VIEW, 1);
+ KEY_POS_VIEW | KEY_USR_VIEW, 1);
if (IS_ERR(rkakey)) {
key_put(keyring);
kleave("= %ld", PTR_ERR(rkakey));
diff --git a/security/seclvl.c b/security/seclvl.c
index 96b1f2122f67..1caac0164643 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -119,69 +119,6 @@ MODULE_PARM_DESC(hideHash, "When set to 0, reading seclvl/passwd from sysfs "
} while (0)
/**
- * kobject stuff
- */
-
-struct subsystem seclvl_subsys;
-
-struct seclvl_obj {
- char *name;
- struct list_head slot_list;
- struct kobject kobj;
-};
-
-/**
- * There is a seclvl_attribute struct for each file in sysfs.
- *
- * In our case, we have one of these structs for "passwd" and another
- * for "seclvl".
- */
-struct seclvl_attribute {
- struct attribute attr;
- ssize_t(*show) (struct seclvl_obj *, char *);
- ssize_t(*store) (struct seclvl_obj *, const char *, size_t);
-};
-
-/**
- * When this function is called, one of the files in sysfs is being
- * written to. attribute->store is a function pointer to whatever the
- * struct seclvl_attribute store function pointer points to. It is
- * unique for "passwd" and "seclvl".
- */
-static ssize_t
-seclvl_attr_store(struct kobject *kobj,
- struct attribute *attr, const char *buf, size_t len)
-{
- struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
- struct seclvl_attribute *attribute =
- container_of(attr, struct seclvl_attribute, attr);
- return attribute->store ? attribute->store(obj, buf, len) : -EIO;
-}
-
-static ssize_t
-seclvl_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
-{
- struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
- struct seclvl_attribute *attribute =
- container_of(attr, struct seclvl_attribute, attr);
- return attribute->show ? attribute->show(obj, buf) : -EIO;
-}
-
-/**
- * Callback function pointers for show and store
- */
-static struct sysfs_ops seclvlfs_sysfs_ops = {
- .show = seclvl_attr_show,
- .store = seclvl_attr_store,
-};
-
-static struct kobj_type seclvl_ktype = {
- .sysfs_ops = &seclvlfs_sysfs_ops
-};
-
-decl_subsys(seclvl, &seclvl_ktype, NULL);
-
-/**
* The actual security level. Ranges between -1 and 2 inclusive.
*/
static int seclvl;
@@ -213,97 +150,44 @@ static int seclvl_sanity(int reqlvl)
}
/**
- * Called whenever the user reads the sysfs handle to this kernel
- * object
- */
-static ssize_t seclvl_read_file(struct seclvl_obj *obj, char *buff)
-{
- return snprintf(buff, PAGE_SIZE, "%d\n", seclvl);
-}
-
-/**
* security level advancement rules:
* Valid levels are -1 through 2, inclusive.
* From -1, stuck. [ in case compiled into kernel ]
* From 0 or above, can only increment.
*/
-static int do_seclvl_advance(int newlvl)
+static void do_seclvl_advance(void *data, u64 val)
{
- if (newlvl <= seclvl) {
- seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
- "[%d]\n", newlvl);
- return -EINVAL;
- }
+ int ret;
+ int newlvl = (int)val;
+
+ ret = seclvl_sanity(newlvl);
+ if (ret)
+ return;
+
if (newlvl > 2) {
seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
"[%d]\n", newlvl);
- return -EINVAL;
+ return;
}
if (seclvl == -1) {
seclvl_printk(1, KERN_WARNING, "Not allowed to advance to "
"seclvl [%d]\n", seclvl);
- return -EPERM;
+ return;
}
- seclvl = newlvl;
- return 0;
+ seclvl = newlvl; /* would it be more "correct" to set *data? */
+ return;
}
-/**
- * Called whenever the user writes to the sysfs handle to this kernel
- * object (seclvl/seclvl). It expects a single-digit number.
- */
-static ssize_t
-seclvl_write_file(struct seclvl_obj *obj, const char *buff, size_t count)
+static u64 seclvl_int_get(void *data)
{
- unsigned long val;
- if (count > 2 || (count == 2 && buff[1] != '\n')) {
- seclvl_printk(1, KERN_WARNING, "Invalid value passed to "
- "seclvl: [%s]\n", buff);
- return -EINVAL;
- }
- val = buff[0] - 48;
- if (seclvl_sanity(val)) {
- seclvl_printk(1, KERN_WARNING, "Illegal secure level "
- "requested: [%d]\n", (int)val);
- return -EPERM;
- }
- if (do_seclvl_advance(val)) {
- seclvl_printk(0, KERN_ERR, "Failure advancing security level "
- "to %lu\n", val);
- }
- return count;
+ return *(int *)data;
}
-/* Generate sysfs_attr_seclvl */
-static struct seclvl_attribute sysfs_attr_seclvl =
-__ATTR(seclvl, (S_IFREG | S_IRUGO | S_IWUSR), seclvl_read_file,
- seclvl_write_file);
+DEFINE_SIMPLE_ATTRIBUTE(seclvl_file_ops, seclvl_int_get, do_seclvl_advance, "%lld\n");
static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
/**
- * Called whenever the user reads the sysfs passwd handle.
- */
-static ssize_t seclvl_read_passwd(struct seclvl_obj *obj, char *buff)
-{
- /* So just how good *is* your password? :-) */
- char tmp[3];
- int i = 0;
- buff[0] = '\0';
- if (hideHash) {
- /* Security through obscurity */
- return 0;
- }
- while (i < SHA1_DIGEST_SIZE) {
- snprintf(tmp, 3, "%02x", hashedPassword[i]);
- strncat(buff, tmp, 2);
- i++;
- }
- strcat(buff, "\n");
- return ((SHA1_DIGEST_SIZE * 2) + 1);
-}
-
-/**
* Converts a block of plaintext of into its SHA1 hashed value.
*
* It would be nice if crypto had a wrapper to do this for us linear
@@ -347,12 +231,15 @@ plaintext_to_sha1(unsigned char *hash, const char *plaintext, int len)
* object. It hashes the password and compares the hashed results.
*/
static ssize_t
-seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
+passwd_write_file(struct file * file, const char __user * buf,
+ size_t count, loff_t *ppos)
{
int i;
unsigned char tmp[SHA1_DIGEST_SIZE];
+ char *page;
int rc;
int len;
+
if (!*passwd && !*sha1_passwd) {
seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
"seclvl module, but neither a plain text "
@@ -363,32 +250,45 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
"maintainer about this event.\n");
return -EINVAL;
}
- len = strlen(buff);
+
+ if (count < 0 || count >= PAGE_SIZE)
+ return -EINVAL;
+ if (*ppos != 0)
+ return -EINVAL;
+ page = (char *)get_zeroed_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+ len = -EFAULT;
+ if (copy_from_user(page, buf, count))
+ goto out;
+
+ len = strlen(page);
/* ``echo "secret" > seclvl/passwd'' includes a newline */
- if (buff[len - 1] == '\n') {
+ if (page[len - 1] == '\n')
len--;
- }
/* Hash the password, then compare the hashed values */
- if ((rc = plaintext_to_sha1(tmp, buff, len))) {
+ if ((rc = plaintext_to_sha1(tmp, page, len))) {
seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
"[%d]\n", rc);
return rc;
}
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
- if (hashedPassword[i] != tmp[i]) {
+ if (hashedPassword[i] != tmp[i])
return -EPERM;
- }
}
seclvl_printk(0, KERN_INFO,
"Password accepted; seclvl reduced to 0.\n");
seclvl = 0;
- return count;
+ len = count;
+
+out:
+ free_page((unsigned long)page);
+ return len;
}
-/* Generate sysfs_attr_passwd */
-static struct seclvl_attribute sysfs_attr_passwd =
-__ATTR(passwd, (S_IFREG | S_IRUGO | S_IWUSR), seclvl_read_passwd,
- seclvl_write_passwd);
+static struct file_operations passwd_file_ops = {
+ .write = passwd_write_file,
+};
/**
* Explicitely disallow ptrace'ing the init process.
@@ -579,9 +479,8 @@ static void seclvl_file_free_security(struct file *filp)
*/
static int seclvl_umount(struct vfsmount *mnt, int flags)
{
- if (current->pid == 1) {
+ if (current->pid == 1)
return 0;
- }
if (seclvl == 2) {
seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure "
"level %d\n", seclvl);
@@ -647,22 +546,34 @@ static int processPassword(void)
}
/**
- * Sysfs registrations
+ * securityfs registrations
*/
-static int doSysfsRegistrations(void)
+struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
+
+static int seclvlfs_register(void)
{
- int rc = 0;
- if ((rc = subsystem_register(&seclvl_subsys))) {
- seclvl_printk(0, KERN_WARNING,
- "Error [%d] registering seclvl subsystem\n", rc);
- return rc;
- }
- sysfs_create_file(&seclvl_subsys.kset.kobj, &sysfs_attr_seclvl.attr);
+ dir_ino = securityfs_create_dir("seclvl", NULL);
+ if (!dir_ino)
+ return -EFAULT;
+
+ seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
+ dir_ino, &seclvl, &seclvl_file_ops);
+ if (!seclvl_ino)
+ goto out_deldir;
if (*passwd || *sha1_passwd) {
- sysfs_create_file(&seclvl_subsys.kset.kobj,
- &sysfs_attr_passwd.attr);
+ passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
+ dir_ino, NULL, &passwd_file_ops);
+ if (!passwd_ino)
+ goto out_delf;
}
return 0;
+
+out_deldir:
+ securityfs_remove(dir_ino);
+out_delf:
+ securityfs_remove(seclvl_ino);
+
+ return -EFAULT;
}
/**
@@ -677,8 +588,6 @@ static int __init seclvl_init(void)
rc = -EINVAL;
goto exit;
}
- sysfs_attr_seclvl.attr.owner = THIS_MODULE;
- sysfs_attr_passwd.attr.owner = THIS_MODULE;
if (initlvl < -1 || initlvl > 2) {
seclvl_printk(0, KERN_ERR, "Error: bad initial securelevel "
"[%d].\n", initlvl);
@@ -706,7 +615,7 @@ static int __init seclvl_init(void)
} /* if primary module registered */
secondary = 1;
} /* if we registered ourselves with the security framework */
- if ((rc = doSysfsRegistrations())) {
+ if ((rc = seclvlfs_register())) {
seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
goto exit;
}
@@ -724,12 +633,10 @@ static int __init seclvl_init(void)
*/
static void __exit seclvl_exit(void)
{
- sysfs_remove_file(&seclvl_subsys.kset.kobj, &sysfs_attr_seclvl.attr);
- if (*passwd || *sha1_passwd) {
- sysfs_remove_file(&seclvl_subsys.kset.kobj,
- &sysfs_attr_passwd.attr);
- }
- subsystem_unregister(&seclvl_subsys);
+ securityfs_remove(seclvl_ino);
+ if (*passwd || *sha1_passwd)
+ securityfs_remove(passwd_ino);
+ securityfs_remove(dir_ino);
if (secondary == 1) {
mod_unreg_security(MY_NAME, &seclvl_ops);
} else if (unregister_security(&seclvl_ops)) {
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index cf6020f85403..12e4fb72bf0f 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -242,7 +242,7 @@ void __init avc_init(void)
avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
0, SLAB_PANIC, NULL, NULL);
- audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
+ audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
}
int avc_get_hash_stats(char *page)
@@ -550,7 +550,7 @@ void avc_audit(u32 ssid, u32 tsid,
return;
}
- ab = audit_log_start(current->audit_context, AUDIT_AVC);
+ ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8641f8894b4c..447a1e0f48cb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -262,7 +262,7 @@ static void superblock_free_security(struct super_block *sb)
}
#ifdef CONFIG_SECURITY_NETWORK
-static int sk_alloc_security(struct sock *sk, int family, int priority)
+static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
struct sk_security_struct *ssec;
@@ -630,6 +630,16 @@ static inline u16 inode_mode_to_security_class(umode_t mode)
return SECCLASS_FILE;
}
+static inline int default_protocol_stream(int protocol)
+{
+ return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
+}
+
+static inline int default_protocol_dgram(int protocol)
+{
+ return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
+}
+
static inline u16 socket_type_to_security_class(int family, int type, int protocol)
{
switch (family) {
@@ -646,10 +656,16 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
case PF_INET6:
switch (type) {
case SOCK_STREAM:
- return SECCLASS_TCP_SOCKET;
+ if (default_protocol_stream(protocol))
+ return SECCLASS_TCP_SOCKET;
+ else
+ return SECCLASS_RAWIP_SOCKET;
case SOCK_DGRAM:
- return SECCLASS_UDP_SOCKET;
- case SOCK_RAW:
+ if (default_protocol_dgram(protocol))
+ return SECCLASS_UDP_SOCKET;
+ else
+ return SECCLASS_RAWIP_SOCKET;
+ default:
return SECCLASS_RAWIP_SOCKET;
}
break;
@@ -1265,85 +1281,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 +1610,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 +1644,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 +1668,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 +1957,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 +2027,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 +2042,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 +2063,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);
@@ -3023,6 +2986,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
/*
* If PF_INET or PF_INET6, check name_bind permission for the port.
+ * Multiple address binding for SCTP is not supported yet: we just
+ * check the first address now.
*/
family = sock->sk->sk_family;
if (family == PF_INET || family == PF_INET6) {
@@ -3067,12 +3032,12 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
goto out;
}
- switch(sk->sk_protocol) {
- case IPPROTO_TCP:
+ switch(isec->sclass) {
+ case SECCLASS_TCP_SOCKET:
node_perm = TCP_SOCKET__NODE_BIND;
break;
- case IPPROTO_UDP:
+ case SECCLASS_UDP_SOCKET:
node_perm = UDP_SOCKET__NODE_BIND;
break;
@@ -3415,7 +3380,7 @@ out:
return err;
}
-static int selinux_sk_alloc_security(struct sock *sk, int family, int priority)
+static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
return sk_alloc_security(sk, family, priority);
}
@@ -3442,7 +3407,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
if (err) {
if (err == -EINVAL) {
- audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+ audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
"SELinux: unrecognized netlink message"
" type=%hu for sclass=%hu\n",
nlh->nlmsg_type, isec->sclass);
@@ -4298,20 +4263,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/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 8eb140dd2e4b..a45cc971e735 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -879,7 +879,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
if (sscanf(page, "%d", &new_value) != 1)
goto out;
- if (new_value) {
+ if (new_value && bool_pending_values) {
security_set_bools(bool_num, bool_pending_values);
}
@@ -952,6 +952,7 @@ static int sel_make_bools(void)
/* remove any existing files */
kfree(bool_pending_values);
+ bool_pending_values = NULL;
sel_remove_bools(dir);
@@ -1002,6 +1003,7 @@ out:
}
return ret;
err:
+ kfree(values);
d_genocide(dir);
ret = -ENOMEM;
goto out;
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 0a758323a9cf..8e6262d12aa9 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -650,8 +650,10 @@ void policydb_destroy(struct policydb *p)
}
if (lrt) kfree(lrt);
- for (i = 0; i < p->p_types.nprim; i++)
- ebitmap_destroy(&p->type_attr_map[i]);
+ if (p->type_attr_map) {
+ for (i = 0; i < p->p_types.nprim; i++)
+ ebitmap_destroy(&p->type_attr_map[i]);
+ }
kfree(p->type_attr_map);
return;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 92b89dc99bcd..aecdded55e74 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -381,7 +381,7 @@ static int security_validtrans_handle_fail(struct context *ocontext,
goto out;
if (context_struct_to_string(tcontext, &t, &tlen) < 0)
goto out;
- audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+ audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
"security_validate_transition: denied for"
" oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -787,7 +787,7 @@ static int compute_sid_handle_invalid_context(
goto out;
if (context_struct_to_string(newcontext, &n, &nlen) < 0)
goto out;
- audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+ audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
"security_compute_sid: invalid context %s"
" for scontext=%s"
" tcontext=%s"
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 2e4a5e0d16db..0864a7ce414d 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -7,6 +7,7 @@ config SND_SA11XX_UDA1341
tristate "SA11xx UDA1341TS driver (iPaq H3600)"
depends on ARCH_SA1100 && SND && L3
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here if you have a Compaq iPaq H3x00 handheld computer
and want to use its Philips UDA 1341 audio chip.
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 98877030d579..559ead6367da 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -20,6 +20,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <sound/driver.h>
@@ -650,7 +651,7 @@ static int aaci_do_resume(snd_card_t *card, unsigned int state)
return 0;
}
-static int aaci_suspend(struct amba_device *dev, u32 state)
+static int aaci_suspend(struct amba_device *dev, pm_message_t state)
{
snd_card_t *card = amba_get_drvdata(dev);
return card ? aaci_do_suspend(card) : 0;
@@ -900,6 +901,8 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
if (ret)
goto out;
+ snd_card_set_dev(aaci->card, &dev->dev);
+
ret = snd_card_register(aaci->card);
if (ret == 0) {
dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname,
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 29450befb5da..38b20efc9c0b 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -245,7 +245,7 @@ static pxa2xx_pcm_client_t pxa2xx_ac97_pcm_client = {
#ifdef CONFIG_PM
-static int pxa2xx_ac97_do_suspend(snd_card_t *card, unsigned int state)
+static int pxa2xx_ac97_do_suspend(snd_card_t *card, pm_message_t state)
{
if (card->power_state != SNDRV_CTL_POWER_D3cold) {
pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 174bc032d1ad..6ee912259cc5 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -21,7 +21,7 @@
* merged HAL layer (patches from Brian)
*/
-/* $Id: sa11xx-uda1341.c,v 1.21 2005/01/28 19:34:04 tiwai Exp $ */
+/* $Id: sa11xx-uda1341.c,v 1.23 2005/09/09 13:22:34 tiwai Exp $ */
/***************************************************************************************************
*
@@ -918,7 +918,7 @@ static int __init sa11xx_uda1341_init(void)
if (card == NULL)
return -ENOMEM;
- sa11xx_uda1341 = kcalloc(1, sizeof(*sa11xx_uda1341), GFP_KERNEL);
+ sa11xx_uda1341 = kzalloc(sizeof(*sa11xx_uda1341), GFP_KERNEL);
if (sa11xx_uda1341 == NULL)
return -ENOMEM;
spin_lock_init(&chip->s[0].dma_lock);
@@ -946,6 +946,9 @@ static int __init sa11xx_uda1341_init(void)
strcpy(card->shortname, "H3600 UDA1341TS");
sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS");
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto nodev;
+
if ((err = snd_card_register(card)) == 0) {
printk( KERN_INFO "iPAQ audio support initialized\n" );
return 0;
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index d1e800b9866d..48cf45cfd0b7 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -99,6 +99,18 @@ config SND_RTCTIMER
To compile this driver as a module, choose M here: the module
will be called snd-rtctimer.
+config SND_SEQ_RTCTIMER_DEFAULT
+ bool "Use RTC as default sequencer timer"
+ depends on SND_RTCTIMER && SND_SEQUENCER
+ default y
+ help
+ Say Y here to use the RTC timer as the default sequencer
+ timer. This is strongly recommended because it ensures
+ precise MIDI timing even when the system timer runs at less
+ than 1000 Hz.
+
+ If in doubt, say Y.
+
config SND_VERBOSE_PRINTK
bool "Verbose printk"
depends on SND
@@ -128,6 +140,6 @@ config SND_DEBUG_DETECT
Say Y here to enable extra-verbose log messages printed when
detecting devices.
-config SND_GENERIC_PM
+config SND_GENERIC_DRIVER
bool
depends on SND
diff --git a/sound/core/control.c b/sound/core/control.c
index 227f3cf02771..736edf358e05 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -69,7 +69,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
err = -EFAULT;
goto __error2;
}
- ctl = kcalloc(1, sizeof(*ctl), GFP_KERNEL);
+ ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
if (ctl == NULL) {
err = -ENOMEM;
goto __error;
@@ -162,7 +162,7 @@ void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id)
goto _found;
}
}
- ev = kcalloc(1, sizeof(*ev), GFP_ATOMIC);
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (ev) {
ev->id = *id;
ev->mask = mask;
@@ -195,7 +195,7 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access)
snd_runtime_check(control != NULL, return NULL);
snd_runtime_check(control->count > 0, return NULL);
- kctl = kcalloc(1, sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
+ kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
if (kctl == NULL)
return NULL;
*kctl = *control;
@@ -521,7 +521,7 @@ static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
{
snd_ctl_card_info_t *info;
- info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (! info)
return -ENOMEM;
down_read(&snd_ioctl_rwsem);
@@ -929,7 +929,7 @@ static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *info, int
return -EINVAL;
}
private_size *= info->count;
- ue = kcalloc(1, sizeof(struct user_element) + private_size, GFP_KERNEL);
+ ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
if (ue == NULL)
return -ENOMEM;
ue->info = *info;
@@ -1185,7 +1185,7 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *
{
snd_kctl_ioctl_t *pn;
- pn = kcalloc(1, sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
+ pn = kzalloc(sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
if (pn == NULL)
return -ENOMEM;
pn->fioctl = fcn;
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 7fdabea4bfc8..207c7de5129c 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -92,7 +92,7 @@ static int snd_ctl_elem_info_compat(snd_ctl_file_t *ctl, struct sndrv_ctl_elem_i
struct sndrv_ctl_elem_info *data;
int err;
- data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (! data)
return -ENOMEM;
@@ -271,7 +271,7 @@ static int snd_ctl_elem_read_user_compat(snd_card_t *card,
struct sndrv_ctl_elem_value *data;
int err, type, count;
- data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -291,7 +291,7 @@ static int snd_ctl_elem_write_user_compat(snd_ctl_file_t *file,
struct sndrv_ctl_elem_value *data;
int err, type, count;
- data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -313,7 +313,7 @@ static int snd_ctl_elem_add_compat(snd_ctl_file_t *file,
struct sndrv_ctl_elem_info *data;
int err;
- data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (! data)
return -ENOMEM;
diff --git a/sound/core/device.c b/sound/core/device.c
index ca00ad7740c9..1f509f56e60c 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -49,7 +49,7 @@ int snd_device_new(snd_card_t *card, snd_device_type_t type,
snd_assert(card != NULL, return -ENXIO);
snd_assert(device_data != NULL, return -ENXIO);
snd_assert(ops != NULL, return -ENXIO);
- dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL)
return -ENOMEM;
dev->card = card;
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 997dd41c584e..9383f1294fb5 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -359,7 +359,7 @@ int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep
snd_assert(rhwdep != NULL, return -EINVAL);
*rhwdep = NULL;
snd_assert(card != NULL, return -ENXIO);
- hwdep = kcalloc(1, sizeof(*hwdep), GFP_KERNEL);
+ hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
if (hwdep == NULL)
return -ENOMEM;
hwdep->card = card;
diff --git a/sound/core/info.c b/sound/core/info.c
index 7f8bdf7b0058..37024d68a26e 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -295,7 +295,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
goto __error;
}
}
- data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) {
err = -ENOMEM;
goto __error;
@@ -304,7 +304,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT:
if (mode == O_RDONLY || mode == O_RDWR) {
- buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (buffer == NULL) {
kfree(data);
err = -ENOMEM;
@@ -323,7 +323,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
data->rbuffer = buffer;
}
if (mode == O_WRONLY || mode == O_RDWR) {
- buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (buffer == NULL) {
if (mode == O_RDWR) {
vfree(data->rbuffer->buffer);
@@ -752,7 +752,7 @@ char *snd_info_get_str(char *dest, char *src, int len)
static snd_info_entry_t *snd_info_create_entry(const char *name)
{
snd_info_entry_t *entry;
- entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL)
return NULL;
entry->name = kstrdup(name, GFP_KERNEL);
diff --git a/sound/core/init.c b/sound/core/init.c
index d72f58f450ce..c72a79115cca 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -72,7 +72,7 @@ snd_card_t *snd_card_new(int idx, const char *xid,
if (extra_size < 0)
extra_size = 0;
- card = kcalloc(1, sizeof(*card) + extra_size, GFP_KERNEL);
+ card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
if (card == NULL)
return NULL;
if (xid) {
@@ -226,8 +226,10 @@ int snd_card_disconnect(snd_card_t * card)
return 0;
}
-#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
-static void snd_generic_device_unregister(struct snd_generic_device *dev);
+#ifdef CONFIG_SND_GENERIC_DRIVER
+static void snd_generic_device_unregister(snd_card_t *card);
+#else
+#define snd_generic_device_unregister(x) /*NOP*/
#endif
/**
@@ -253,14 +255,7 @@ int snd_card_free(snd_card_t * card)
#ifdef CONFIG_PM
wake_up(&card->power_sleep);
-#ifdef CONFIG_SND_GENERIC_PM
- if (card->pm_dev) {
- snd_generic_device_unregister(card->pm_dev);
- card->pm_dev = NULL;
- }
-#endif
#endif
-
/* wait, until all devices are ready for the free operation */
wait_event(card->shutdown_sleep, card->files == NULL);
@@ -288,6 +283,7 @@ int snd_card_free(snd_card_t * card)
snd_printk(KERN_WARNING "unable to free card info\n");
/* Not fatal error */
}
+ snd_generic_device_unregister(card);
while (card->s_f_ops) {
s_f_ops = card->s_f_ops;
card->s_f_ops = s_f_ops->next;
@@ -665,6 +661,96 @@ int snd_card_file_remove(snd_card_t *card, struct file *file)
return 0;
}
+#ifdef CONFIG_SND_GENERIC_DRIVER
+/*
+ * generic device without a proper bus using platform_device
+ * (e.g. ISA)
+ */
+struct snd_generic_device {
+ struct platform_device pdev;
+ snd_card_t *card;
+};
+
+#define get_snd_generic_card(dev) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
+
+#define SND_GENERIC_NAME "snd_generic"
+
+#ifdef CONFIG_PM
+static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
+static int snd_generic_resume(struct device *dev, u32 level);
+#endif
+
+/* initialized in sound.c */
+struct device_driver snd_generic_driver = {
+ .name = SND_GENERIC_NAME,
+ .bus = &platform_bus_type,
+#ifdef CONFIG_PM
+ .suspend = snd_generic_suspend,
+ .resume = snd_generic_resume,
+#endif
+};
+
+void snd_generic_device_release(struct device *dev)
+{
+}
+
+static int snd_generic_device_register(snd_card_t *card)
+{
+ struct snd_generic_device *dev;
+ int err;
+
+ if (card->generic_dev)
+ return 0; /* already registered */
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (! dev) {
+ snd_printk(KERN_ERR "can't allocate generic_device\n");
+ return -ENOMEM;
+ }
+
+ dev->pdev.name = SND_GENERIC_NAME;
+ dev->pdev.id = card->number;
+ dev->pdev.dev.release = snd_generic_device_release;
+ dev->card = card;
+ if ((err = platform_device_register(&dev->pdev)) < 0) {
+ kfree(dev);
+ return err;
+ }
+ card->generic_dev = dev;
+ return 0;
+}
+
+static void snd_generic_device_unregister(snd_card_t *card)
+{
+ struct snd_generic_device *dev = card->generic_dev;
+ if (dev) {
+ platform_device_unregister(&dev->pdev);
+ kfree(dev);
+ card->generic_dev = NULL;
+ }
+}
+
+/**
+ * snd_card_set_generic_dev - assign the generic device to the card
+ * @card: soundcard structure
+ *
+ * Assigns a generic device to the card. This function is provided as the
+ * last resort, for devices without any proper bus. Thus this won't override
+ * the device already assigned to the card.
+ *
+ * Returns zero if successful, or a negative error code.
+ */
+int snd_card_set_generic_dev(snd_card_t *card)
+{
+ int err;
+ if ((err = snd_generic_device_register(card)) < 0)
+ return err;
+ if (! card->dev)
+ snd_card_set_dev(card, &card->generic_dev->pdev.dev);
+ return 0;
+}
+#endif /* CONFIG_SND_GENERIC_DRIVER */
+
#ifdef CONFIG_PM
/**
* snd_power_wait - wait until the power-state is changed.
@@ -730,75 +816,7 @@ int snd_card_set_pm_callback(snd_card_t *card,
return 0;
}
-#ifdef CONFIG_SND_GENERIC_PM
-/*
- * use platform_device for generic power-management without a proper bus
- * (e.g. ISA)
- */
-struct snd_generic_device {
- struct platform_device pdev;
- snd_card_t *card;
-};
-
-#define get_snd_generic_card(dev) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
-
-#define SND_GENERIC_NAME "snd_generic_pm"
-
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
-static int snd_generic_resume(struct device *dev, u32 level);
-
-static struct device_driver snd_generic_driver = {
- .name = SND_GENERIC_NAME,
- .bus = &platform_bus_type,
- .suspend = snd_generic_suspend,
- .resume = snd_generic_resume,
-};
-
-static int generic_driver_registered;
-
-static void generic_driver_unregister(void)
-{
- if (generic_driver_registered) {
- generic_driver_registered--;
- if (! generic_driver_registered)
- driver_unregister(&snd_generic_driver);
- }
-}
-
-static struct snd_generic_device *snd_generic_device_register(snd_card_t *card)
-{
- struct snd_generic_device *dev;
-
- if (! generic_driver_registered) {
- if (driver_register(&snd_generic_driver) < 0)
- return NULL;
- }
- generic_driver_registered++;
-
- dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
- if (! dev) {
- generic_driver_unregister();
- return NULL;
- }
-
- dev->pdev.name = SND_GENERIC_NAME;
- dev->pdev.id = card->number;
- dev->card = card;
- if (platform_device_register(&dev->pdev) < 0) {
- kfree(dev);
- generic_driver_unregister();
- return NULL;
- }
- return dev;
-}
-
-static void snd_generic_device_unregister(struct snd_generic_device *dev)
-{
- platform_device_unregister(&dev->pdev);
- kfree(dev);
- generic_driver_unregister();
-}
-
+#ifdef CONFIG_SND_GENERIC_DRIVER
/* suspend/resume callbacks for snd_generic platform device */
static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
{
@@ -810,7 +828,8 @@ static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level
card = get_snd_generic_card(dev);
if (card->power_state == SNDRV_CTL_POWER_D3hot)
return 0;
- card->pm_suspend(card, PMSG_SUSPEND);
+ if (card->pm_suspend)
+ card->pm_suspend(card, PMSG_SUSPEND);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
return 0;
}
@@ -825,7 +844,8 @@ static int snd_generic_resume(struct device *dev, u32 level)
card = get_snd_generic_card(dev);
if (card->power_state == SNDRV_CTL_POWER_D0)
return 0;
- card->pm_resume(card);
+ if (card->pm_suspend)
+ card->pm_resume(card);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
@@ -846,13 +866,12 @@ int snd_card_set_generic_pm_callback(snd_card_t *card,
int (*resume)(snd_card_t *),
void *private_data)
{
- card->pm_dev = snd_generic_device_register(card);
- if (! card->pm_dev)
- return -ENOMEM;
- snd_card_set_pm_callback(card, suspend, resume, private_data);
- return 0;
+ int err;
+ if ((err = snd_generic_device_register(card)) < 0)
+ return err;
+ return snd_card_set_pm_callback(card, suspend, resume, private_data);
}
-#endif /* CONFIG_SND_GENERIC_PM */
+#endif /* CONFIG_SND_GENERIC_DRIVER */
#ifdef CONFIG_PCI
int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 39a54a415528..129abab5ce98 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -106,7 +106,7 @@ struct snd_mem_list {
static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle,
- unsigned int __nocast flags)
+ gfp_t flags)
{
void *ret;
u64 dma_mask, coherent_dma_mask;
@@ -190,7 +190,7 @@ static void unmark_pages(struct page *page, int order)
*
* Returns the pointer of the buffer, or NULL if no enoguh memory.
*/
-void *snd_malloc_pages(size_t size, unsigned int gfp_flags)
+void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
{
int pg;
void *res;
@@ -235,7 +235,7 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
{
int pg;
void *res;
- unsigned int gfp_flags;
+ gfp_t gfp_flags;
snd_assert(size > 0, return NULL);
snd_assert(dma != NULL, return NULL);
@@ -590,7 +590,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
alloced = 0;
pci = NULL;
- while ((pci = pci_find_device(vendor, device, pci)) != NULL) {
+ while ((pci = pci_get_device(vendor, device, pci)) != NULL) {
if (mask > 0 && mask < 0xffffffff) {
if (pci_set_dma_mask(pci, mask) < 0 ||
pci_set_consistent_dma_mask(pci, mask) < 0) {
@@ -604,6 +604,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
size, &dmab) < 0) {
printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
+ pci_dev_put(pci);
return (int)count;
}
snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 291b4769bde3..7d8e2eebba51 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -89,7 +89,7 @@ void snd_memory_done(void)
}
}
-static void *__snd_kmalloc(size_t size, unsigned int __nocast flags, void *caller)
+static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller)
{
unsigned long cpu_flags;
struct snd_alloc_track *t;
@@ -111,12 +111,12 @@ static void *__snd_kmalloc(size_t size, unsigned int __nocast flags, void *calle
}
#define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0));
-void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags)
+void *snd_hidden_kmalloc(size_t size, gfp_t flags)
{
return _snd_kmalloc(size, flags);
}
-void *snd_hidden_kzalloc(size_t size, unsigned int __nocast flags)
+void *snd_hidden_kzalloc(size_t size, gfp_t flags)
{
void *ret = _snd_kmalloc(size, flags);
if (ret)
@@ -125,7 +125,7 @@ void *snd_hidden_kzalloc(size_t size, unsigned int __nocast flags)
}
EXPORT_SYMBOL(snd_hidden_kzalloc);
-void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags)
+void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags)
{
void *ret = NULL;
if (n != 0 && size > INT_MAX / n)
@@ -190,7 +190,7 @@ void snd_hidden_vfree(void *obj)
snd_wrapper_vfree(obj);
}
-char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags)
+char *snd_hidden_kstrdup(const char *s, gfp_t flags)
{
int len;
char *buf;
@@ -249,7 +249,7 @@ int __exit snd_memory_info_done(void)
int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)
{
#if defined(__i386__) || defined(CONFIG_SPARC32)
- return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
+ return copy_to_user(dst, (const void __force*)src, count) ? -EFAULT : 0;
#else
char buf[256];
while (count) {
@@ -280,7 +280,7 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size
int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)
{
#if defined(__i386__) || defined(CONFIG_SPARC32)
- return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
+ return copy_from_user((void __force *)dst, src, count) ? -EFAULT : 0;
#else
char buf[256];
while (count) {
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 98fc0766f885..69e1059112d1 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -53,7 +53,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
err = snd_card_file_add(card, file);
if (err < 0)
return err;
- fmixer = kcalloc(1, sizeof(*fmixer), GFP_KERNEL);
+ fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL);
if (fmixer == NULL) {
snd_card_file_remove(card, file);
return -ENOMEM;
@@ -517,8 +517,8 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer,
up_read(&card->controls_rwsem);
return;
}
- uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -551,8 +551,8 @@ static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
up_read(&card->controls_rwsem);
return;
}
- uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -612,8 +612,8 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer,
down_read(&card->controls_rwsem);
if ((kctl = snd_ctl_find_numid(card, numid)) == NULL)
return;
- uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -649,8 +649,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
up_read(&fmixer->card->controls_rwsem);
return;
}
- uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -768,8 +768,8 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
snd_ctl_elem_value_t *uctl;
int err, idx;
- uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) {
err = -ENOMEM;
goto __unlock;
@@ -813,8 +813,8 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
int err;
unsigned int idx;
- uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) {
err = -ENOMEM;
goto __unlock;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index a13bd7bb4c9f..842c28b2ed55 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -850,7 +850,9 @@ static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __u
return xfer > 0 ? xfer : -EAGAIN;
}
} else {
- tmp = snd_pcm_oss_write2(substream, (const char *)buf, runtime->oss.period_bytes, 0);
+ tmp = snd_pcm_oss_write2(substream,
+ (const char __force *)buf,
+ runtime->oss.period_bytes, 0);
if (tmp <= 0)
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
runtime->oss.bytes += tmp;
@@ -926,7 +928,8 @@ static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char __user *bu
xfer += tmp;
runtime->oss.buffer_used -= tmp;
} else {
- tmp = snd_pcm_oss_read2(substream, (char *)buf, runtime->oss.period_bytes, 0);
+ tmp = snd_pcm_oss_read2(substream, (char __force *)buf,
+ runtime->oss.period_bytes, 0);
if (tmp <= 0)
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
runtime->oss.bytes += tmp;
@@ -1540,7 +1543,11 @@ static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, str
} else {
delay = snd_pcm_oss_bytes(substream, delay);
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
+ snd_pcm_oss_setup_t *setup = substream->oss.setup;
+ if (setup && setup->buggyptr)
+ info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
+ else
+ info.blocks = (delay + fixup) / runtime->oss.period_bytes;
info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
} else {
delay += fixup;
@@ -1733,7 +1740,7 @@ static int snd_pcm_oss_open_file(struct file *file,
snd_assert(rpcm_oss_file != NULL, return -EINVAL);
*rpcm_oss_file = NULL;
- pcm_oss_file = kcalloc(1, sizeof(*pcm_oss_file), GFP_KERNEL);
+ pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
if (pcm_oss_file == NULL)
return -ENOMEM;
@@ -2347,6 +2354,8 @@ static void snd_pcm_oss_proc_write(snd_info_entry_t *entry,
template.partialfrag = 1;
} else if (!strcmp(str, "no-silence")) {
template.nosilence = 1;
+ } else if (!strcmp(str, "buggy-ptr")) {
+ template.buggyptr = 1;
}
} while (*str);
if (setup == NULL) {
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 6430410c6c04..fc23373c000d 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -171,7 +171,7 @@ int snd_pcm_plugin_build(snd_pcm_plug_t *plug,
snd_assert(plug != NULL, return -ENXIO);
snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO);
- plugin = kcalloc(1, sizeof(*plugin) + extra, GFP_KERNEL);
+ plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
if (plugin == NULL)
return -ENOMEM;
plugin->name = name;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 9f4c9209b271..1be470e942ef 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -597,7 +597,7 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
}
prev = NULL;
for (idx = 0, prev = NULL; idx < substream_count; idx++) {
- substream = kcalloc(1, sizeof(*substream), GFP_KERNEL);
+ substream = kzalloc(sizeof(*substream), GFP_KERNEL);
if (substream == NULL)
return -ENOMEM;
substream->pcm = pcm;
@@ -657,7 +657,7 @@ int snd_pcm_new(snd_card_t * card, char *id, int device,
snd_assert(rpcm != NULL, return -EINVAL);
*rpcm = NULL;
snd_assert(card != NULL, return -ENXIO);
- pcm = kcalloc(1, sizeof(*pcm), GFP_KERNEL);
+ pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
if (pcm == NULL)
return -ENOMEM;
pcm->card = card;
@@ -795,7 +795,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
if (substream == NULL)
return -EAGAIN;
- runtime = kcalloc(1, sizeof(*runtime), GFP_KERNEL);
+ runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
if (runtime == NULL)
return -ENOMEM;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0082914a7e33..0503980c23d9 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -524,6 +524,9 @@ void snd_interval_mul(const snd_interval_t *a, const snd_interval_t *b, snd_inte
/**
* snd_interval_div - refine the interval value with division
+ * @a: dividend
+ * @b: divisor
+ * @c: quotient
*
* c = a / b
*
@@ -555,7 +558,11 @@ void snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_inte
/**
* snd_interval_muldivk - refine the interval value
- *
+ * @a: dividend 1
+ * @b: dividend 2
+ * @k: divisor (as integer)
+ * @c: result
+ *
* c = a * b / k
*
* Returns non-zero if the value is changed, zero if not changed.
@@ -582,6 +589,10 @@ void snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b,
/**
* snd_interval_mulkdiv - refine the interval value
+ * @a: dividend 1
+ * @k: dividend 2 (as integer)
+ * @b: divisor
+ * @c: result
*
* c = a * k / b
*
@@ -618,6 +629,11 @@ void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k,
/**
* snd_interval_ratnum - refine the interval value
+ * @i: interval to refine
+ * @rats_count: number of ratnum_t
+ * @rats: ratnum_t array
+ * @nump: pointer to store the resultant numerator
+ * @denp: pointer to store the resultant denominator
*
* Returns non-zero if the value is changed, zero if not changed.
*/
@@ -715,6 +731,11 @@ int snd_interval_ratnum(snd_interval_t *i,
/**
* snd_interval_ratden - refine the interval value
+ * @i: interval to refine
+ * @rats_count: number of ratden_t
+ * @rats: ratden_t array
+ * @nump: pointer to store the resultant numerator
+ * @denp: pointer to store the resultant denominator
*
* Returns non-zero if the value is changed, zero if not changed.
*/
@@ -936,6 +957,11 @@ int snd_pcm_hw_rule_add(snd_pcm_runtime_t *runtime, unsigned int cond,
/**
* snd_pcm_hw_constraint_mask
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the mask
+ * @mask: the bitmap mask
+ *
+ * Apply the constraint of the given bitmap mask to a mask parameter.
*/
int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
u_int32_t mask)
@@ -951,6 +977,11 @@ int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t va
/**
* snd_pcm_hw_constraint_mask64
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the mask
+ * @mask: the 64bit bitmap mask
+ *
+ * Apply the constraint of the given bitmap mask to a mask parameter.
*/
int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
u_int64_t mask)
@@ -967,6 +998,10 @@ int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t
/**
* snd_pcm_hw_constraint_integer
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the integer constraint
+ *
+ * Apply the constraint of integer to an interval parameter.
*/
int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var)
{
@@ -976,6 +1011,12 @@ int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t
/**
* snd_pcm_hw_constraint_minmax
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the range
+ * @min: the minimal value
+ * @max: the maximal value
+ *
+ * Apply the min/max range constraint to an interval parameter.
*/
int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
unsigned int min, unsigned int max)
@@ -999,6 +1040,12 @@ static int snd_pcm_hw_rule_list(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_constraint_list
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the list constraint
+ * @l: list
+ *
+ * Apply the list of constraints to an interval parameter.
*/
int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime,
unsigned int cond,
@@ -1027,6 +1074,10 @@ static int snd_pcm_hw_rule_ratnums(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_constraint_ratnums
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the ratnums constraint
+ * @r: ratnums_t constriants
*/
int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime,
unsigned int cond,
@@ -1054,6 +1105,10 @@ static int snd_pcm_hw_rule_ratdens(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_constraint_ratdens
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the ratdens constraint
+ * @r: ratdens_t constriants
*/
int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime,
unsigned int cond,
@@ -1079,6 +1134,10 @@ static int snd_pcm_hw_rule_msbits(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_constraint_msbits
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @width: sample bits width
+ * @msbits: msbits width
*/
int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime,
unsigned int cond,
@@ -1101,6 +1160,10 @@ static int snd_pcm_hw_rule_step(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_constraint_step
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the step constraint
+ * @step: step size
*/
int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime,
unsigned int cond,
@@ -1126,6 +1189,9 @@ static int snd_pcm_hw_rule_pow2(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *
/**
* snd_pcm_hw_constraint_pow2
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the power-of-2 constraint
*/
int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime,
unsigned int cond,
@@ -1162,7 +1228,7 @@ static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params,
}
#if 0
-/**
+/*
* snd_pcm_hw_param_any
*/
int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
@@ -1185,7 +1251,7 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
}
#if 0
-/**
+/*
* snd_pcm_hw_params_any
*
* Fill PARAMS with full configuration space boundaries
@@ -1199,6 +1265,9 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
/**
* snd_pcm_hw_param_value
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Return the value for field PAR if it's fixed in configuration space
* defined by PARAMS. Return -EINVAL otherwise
@@ -1228,6 +1297,9 @@ static int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_value_min
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Return the minimum value for field PAR.
*/
@@ -1251,6 +1323,9 @@ unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_value_max
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Return the maximum value for field PAR.
*/
@@ -1302,7 +1377,7 @@ int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params,
}
#if 0
-/**
+/*
* snd_pcm_hw_param_setinteger
*
* Inside configuration space defined by PARAMS remove from PAR all
@@ -1347,6 +1422,10 @@ static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_first
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Inside configuration space defined by PARAMS remove from PAR all
* values > minimum. Reduce configuration space accordingly.
@@ -1388,6 +1467,10 @@ static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_last
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Inside configuration space defined by PARAMS remove from PAR all
* values < maximum. Reduce configuration space accordingly.
@@ -1439,6 +1522,11 @@ int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_min
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: minimal value
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Inside configuration space defined by PARAMS remove from PAR all
* values < VAL. Reduce configuration space accordingly.
@@ -1494,6 +1582,11 @@ static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_max
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: maximal value
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Inside configuration space defined by PARAMS remove from PAR all
* values >= VAL + 1. Reduce configuration space accordingly.
@@ -1565,6 +1658,11 @@ int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_set
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: value to set
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Inside configuration space defined by PARAMS remove from PAR all
* values != VAL. Reduce configuration space accordingly.
@@ -1599,6 +1697,10 @@ static int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_mask
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: mask to apply
*
* Inside configuration space defined by PARAMS remove from PAR all values
* not contained in MASK. Reduce configuration space accordingly.
@@ -1671,6 +1773,11 @@ static int boundary_nearer(int min, int mindir,
/**
* snd_pcm_hw_param_near
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @best: value to set
+ * @dir: pointer to the direction (-1,0,1) or NULL
*
* Inside configuration space defined by PARAMS set PAR to the available value
* nearest to VAL. Reduce configuration space accordingly.
@@ -1747,6 +1854,8 @@ int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
/**
* snd_pcm_hw_param_choose
+ * @pcm: PCM instance
+ * @params: the hw_params instance
*
* Choose one configuration from configuration space defined by PARAMS
* The configuration chosen is that obtained fixing in this order:
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 9a174fb96565..b3f5344f60be 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -244,7 +244,7 @@ int snd_pcm_lib_preallocate_pages(snd_pcm_substream_t *substream,
/**
* snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
- * @substream: the pcm substream instance
+ * @pcm: the pcm instance
* @type: DMA type (SNDRV_DMA_TYPE_*)
* @data: DMA type dependant data
* @size: the requested pre-allocation size in bytes
@@ -321,7 +321,7 @@ int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size)
if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
dmab = &substream->dma_buffer; /* use the pre-allocated buffer */
} else {
- dmab = kcalloc(1, sizeof(*dmab), GFP_KERNEL);
+ dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
if (! dmab)
return -ENOMEM;
dmab->dev = substream->dma_buffer.dev;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 03c17159dd8e..67abebabf83e 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -859,6 +859,7 @@ static struct action_ops snd_pcm_action_start = {
/**
* snd_pcm_start
+ * @substream: the PCM substream instance
*
* Start all linked streams.
*/
@@ -908,6 +909,8 @@ static struct action_ops snd_pcm_action_stop = {
/**
* snd_pcm_stop
+ * @substream: the PCM substream instance
+ * @state: PCM state after stopping the stream
*
* Try to stop all running streams in the substream group.
* The state of each stream is changed to the given value after that unconditionally.
@@ -919,6 +922,7 @@ int snd_pcm_stop(snd_pcm_substream_t *substream, int state)
/**
* snd_pcm_drain_done
+ * @substream: the PCM substream
*
* Stop the DMA only when the given stream is playback.
* The state is changed to SETUP.
@@ -1040,6 +1044,7 @@ static struct action_ops snd_pcm_action_suspend = {
/**
* snd_pcm_suspend
+ * @substream: the PCM substream
*
* Trigger SUSPEND to all linked streams.
* After this call, all streams are changed to SUSPENDED state.
@@ -1057,6 +1062,7 @@ int snd_pcm_suspend(snd_pcm_substream_t *substream)
/**
* snd_pcm_suspend_all
+ * @pcm: the PCM instance
*
* Trigger SUSPEND to all substreams in the given pcm.
* After this call, all streams are changed to SUSPENDED state.
@@ -1272,6 +1278,9 @@ static struct action_ops snd_pcm_action_prepare = {
/**
* snd_pcm_prepare
+ * @substream: the PCM substream instance
+ *
+ * Prepare the PCM substream to be triggerable.
*/
int snd_pcm_prepare(snd_pcm_substream_t *substream)
{
@@ -1992,7 +2001,7 @@ static int snd_pcm_open_file(struct file *file,
snd_assert(rpcm_file != NULL, return -EINVAL);
*rpcm_file = NULL;
- pcm_file = kcalloc(1, sizeof(*pcm_file), GFP_KERNEL);
+ pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
if (pcm_file == NULL) {
return -ENOMEM;
}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index edba4118271c..7c20eafecb8a 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -101,7 +101,7 @@ static int snd_rawmidi_runtime_create(snd_rawmidi_substream_t * substream)
{
snd_rawmidi_runtime_t *runtime;
- if ((runtime = kcalloc(1, sizeof(*runtime), GFP_KERNEL)) == NULL)
+ if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
return -ENOMEM;
spin_lock_init(&runtime->lock);
init_waitqueue_head(&runtime->sleep);
@@ -984,7 +984,9 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
spin_lock_irq(&runtime->lock);
}
spin_unlock_irq(&runtime->lock);
- count1 = snd_rawmidi_kernel_read1(substream, (unsigned char *)buf, count, 0);
+ count1 = snd_rawmidi_kernel_read1(substream,
+ (unsigned char __force *)buf,
+ count, 0);
if (count1 < 0)
return result > 0 ? result : count1;
result += count1;
@@ -1107,7 +1109,7 @@ int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count)
/**
* snd_rawmidi_transmit - copy from the buffer to the device
* @substream: the rawmidi substream
- * @buf: the buffer pointer
+ * @buffer: the buffer pointer
* @count: the data size to transfer
*
* Copies data from the buffer to the device and advances the pointer.
@@ -1213,7 +1215,9 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size
spin_lock_irq(&runtime->lock);
}
spin_unlock_irq(&runtime->lock);
- count1 = snd_rawmidi_kernel_write1(substream, (unsigned char *)buf, count, 0);
+ count1 = snd_rawmidi_kernel_write1(substream,
+ (unsigned char __force *)buf,
+ count, 0);
if (count1 < 0)
return result > 0 ? result : count1;
result += count1;
@@ -1370,7 +1374,7 @@ static int snd_rawmidi_alloc_substreams(snd_rawmidi_t *rmidi,
INIT_LIST_HEAD(&stream->substreams);
for (idx = 0; idx < count; idx++) {
- substream = kcalloc(1, sizeof(*substream), GFP_KERNEL);
+ substream = kzalloc(sizeof(*substream), GFP_KERNEL);
if (substream == NULL)
return -ENOMEM;
substream->stream = direction;
@@ -1413,7 +1417,7 @@ int snd_rawmidi_new(snd_card_t * card, char *id, int device,
snd_assert(rrawmidi != NULL, return -EINVAL);
*rrawmidi = NULL;
snd_assert(card != NULL, return -ENXIO);
- rmidi = kcalloc(1, sizeof(*rmidi), GFP_KERNEL);
+ rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
if (rmidi == NULL)
return -ENOMEM;
rmidi->card = card;
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
index 32e91c6b25fe..0e4df8826eed 100644
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -51,7 +51,7 @@ static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
gf1_wave_t *wp, *prev;
gf1_xwave_t xp;
int err;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
unsigned int real_size;
gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
@@ -61,7 +61,7 @@ static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
return -EFAULT;
*data += sizeof(xp);
*len -= sizeof(xp);
- wp = kcalloc(1, sizeof(*wp), gfp_mask);
+ wp = kzalloc(sizeof(*wp), gfp_mask);
if (wp == NULL)
return -ENOMEM;
wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
@@ -144,7 +144,8 @@ static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr,
snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
gf1_instrument_t *ip;
gf1_xinstrument_t ix;
- int err, gfp_mask;
+ int err;
+ gfp_t gfp_mask;
if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
return -EINVAL;
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
index 2622b8679ca7..7c19fbbc5d0f 100644
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -58,7 +58,7 @@ static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype,
iwffff_xenv_t *ex,
char __user **data,
long *len,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
__u32 stype;
iwffff_env_record_t *rp, *rp_last;
@@ -92,7 +92,7 @@ static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype,
points_size = (le16_to_cpu(rx.nattack) + le16_to_cpu(rx.nrelease)) * 2 * sizeof(__u16);
if (points_size > *len)
return -EINVAL;
- rp = kcalloc(1, sizeof(*rp) + points_size, gfp_mask);
+ rp = kzalloc(sizeof(*rp) + points_size, gfp_mask);
if (rp == NULL)
return -ENOMEM;
rp->nattack = le16_to_cpu(rx.nattack);
@@ -129,7 +129,7 @@ static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops,
iwffff_wave_t *wp, *prev;
iwffff_xwave_t xp;
int err;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
unsigned int real_size;
gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
@@ -139,7 +139,7 @@ static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops,
return -EFAULT;
*data += sizeof(xp);
*len -= sizeof(xp);
- wp = kcalloc(1, sizeof(*wp), gfp_mask);
+ wp = kzalloc(sizeof(*wp), gfp_mask);
if (wp == NULL)
return -ENOMEM;
wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
@@ -236,7 +236,7 @@ static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr,
iwffff_layer_t *lp, *prev_lp;
iwffff_xlayer_t lx;
int err;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
return -EINVAL;
@@ -273,7 +273,7 @@ static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr,
snd_seq_iwffff_instr_free(ops, ip, atomic);
return -EINVAL;
}
- lp = kcalloc(1, sizeof(*lp), gfp_mask);
+ lp = kzalloc(sizeof(*lp), gfp_mask);
if (lp == NULL) {
snd_seq_iwffff_instr_free(ops, ip, atomic);
return -ENOMEM;
diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
index 6183d2151034..17ab94e76073 100644
--- a/sound/core/seq/instr/ainstr_simple.c
+++ b/sound/core/seq/instr/ainstr_simple.c
@@ -57,7 +57,8 @@ static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
simple_instrument_t *ip;
simple_xinstrument_t ix;
- int err, gfp_mask;
+ int err;
+ gfp_t gfp_mask;
unsigned int real_size;
if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index bac4b4f1a94e..1ab1cf8158c8 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -193,7 +193,7 @@ snd_seq_oss_open(struct file *file, int level)
int i, rc;
seq_oss_devinfo_t *dp;
- if ((dp = kcalloc(1, sizeof(*dp), GFP_KERNEL)) == NULL) {
+ if ((dp = kzalloc(sizeof(*dp), GFP_KERNEL)) == NULL) {
snd_printk(KERN_ERR "can't malloc device info\n");
return -ENOMEM;
}
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 9aece6c65dbc..f0e95c8f2eef 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -76,8 +76,8 @@ snd_seq_oss_midi_lookup_ports(int client)
snd_seq_client_info_t *clinfo;
snd_seq_port_info_t *pinfo;
- clinfo = kcalloc(1, sizeof(*clinfo), GFP_KERNEL);
- pinfo = kcalloc(1, sizeof(*pinfo), GFP_KERNEL);
+ clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL);
+ pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
if (! clinfo || ! pinfo) {
kfree(clinfo);
kfree(pinfo);
@@ -172,7 +172,7 @@ snd_seq_oss_midi_check_new_port(snd_seq_port_info_t *pinfo)
/*
* allocate midi info record
*/
- if ((mdev = kcalloc(1, sizeof(*mdev), GFP_KERNEL)) == NULL) {
+ if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) {
snd_printk(KERN_ERR "can't malloc midi info\n");
return -ENOMEM;
}
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index 0a6f2a64f692..55571e15cd38 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -46,7 +46,7 @@ snd_seq_oss_readq_new(seq_oss_devinfo_t *dp, int maxlen)
{
seq_oss_readq_t *q;
- if ((q = kcalloc(1, sizeof(*q), GFP_KERNEL)) == NULL) {
+ if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) {
snd_printk(KERN_ERR "can't malloc read queue\n");
return NULL;
}
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 1a7736cbf3a4..8257fce2ca1b 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -103,7 +103,7 @@ snd_seq_oss_synth_register(snd_seq_device_t *dev)
snd_seq_oss_reg_t *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
unsigned long flags;
- if ((rec = kcalloc(1, sizeof(*rec), GFP_KERNEL)) == NULL) {
+ if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
snd_printk(KERN_ERR "can't malloc synth info\n");
return -ENOMEM;
}
@@ -499,7 +499,7 @@ snd_seq_oss_synth_sysex(seq_oss_devinfo_t *dp, int dev, unsigned char *buf, snd_
sysex = dp->synths[dev].sysex;
if (sysex == NULL) {
- sysex = kcalloc(1, sizeof(*sysex), GFP_KERNEL);
+ sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
if (sysex == NULL)
return -ENOMEM;
dp->synths[dev].sysex = sysex;
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index 42ca9493fa60..64d594b3170f 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -46,7 +46,7 @@ snd_seq_oss_timer_new(seq_oss_devinfo_t *dp)
{
seq_oss_timer_t *rec;
- rec = kcalloc(1, sizeof(*rec), GFP_KERNEL);
+ rec = kzalloc(sizeof(*rec), GFP_KERNEL);
if (rec == NULL)
return NULL;
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 87f85f7ee814..b20378024547 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -38,7 +38,7 @@ snd_seq_oss_writeq_new(seq_oss_devinfo_t *dp, int maxlen)
seq_oss_writeq_t *q;
snd_seq_client_pool_t pool;
- if ((q = kcalloc(1, sizeof(*q), GFP_KERNEL)) == NULL)
+ if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL)
return NULL;
q->dp = dp;
q->maxlen = maxlen;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 7449d2a62629..24644150f24b 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -43,7 +43,13 @@ int seq_client_load[64] = {[0 ... 63] = -1};
int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
int seq_default_timer_card = -1;
-int seq_default_timer_device = SNDRV_TIMER_GLOBAL_SYSTEM;
+int seq_default_timer_device =
+#ifdef CONFIG_SND_SEQ_RTCTIMER_DEFAULT
+ SNDRV_TIMER_GLOBAL_RTC
+#else
+ SNDRV_TIMER_GLOBAL_SYSTEM
+#endif
+ ;
int seq_default_timer_subdevice = 0;
int seq_default_timer_resolution = 0; /* Hz */
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index d8f76afd284b..a886db94b1fa 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -203,7 +203,7 @@ static client_t *seq_create_client1(int client_index, int poolsize)
client_t *client;
/* init client data */
- client = kcalloc(1, sizeof(*client), GFP_KERNEL);
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
if (client == NULL)
return NULL;
client->pool = snd_seq_pool_new(poolsize);
@@ -413,7 +413,9 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, l
}
count -= sizeof(snd_seq_event_t);
buf += sizeof(snd_seq_event_t);
- err = snd_seq_expand_var_event(&cell->event, count, (char *)buf, 0, sizeof(snd_seq_event_t));
+ err = snd_seq_expand_var_event(&cell->event, count,
+ (char __force *)buf, 0,
+ sizeof(snd_seq_event_t));
if (err < 0)
break;
result += err;
@@ -1009,7 +1011,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, size_t c
}
/* set user space pointer */
event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR;
- event.data.ext.ptr = (char*)buf + sizeof(snd_seq_event_t);
+ event.data.ext.ptr = (char __force *)buf
+ + sizeof(snd_seq_event_t);
len += extlen; /* increment data length */
} else {
#ifdef CONFIG_COMPAT
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 4d80f39612e8..252b52731003 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -200,7 +200,7 @@ int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
if (ops == NULL)
return -ENOMEM;
- dev = kcalloc(1, sizeof(*dev)*2 + argsize, GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev)*2 + argsize, GFP_KERNEL);
if (dev == NULL) {
unlock_driver(ops);
return -ENOMEM;
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index ea945a5d2a0b..5dd0e6a19e50 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -153,7 +153,7 @@ create_port(int idx, int type)
snd_seq_port_callback_t pcb;
snd_seq_dummy_port_t *rec;
- if ((rec = kcalloc(1, sizeof(*rec), GFP_KERNEL)) == NULL)
+ if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL)
return NULL;
rec->client = my_client;
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 3b7647ca7ad9..4767cfdc361f 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -33,7 +33,7 @@ fifo_t *snd_seq_fifo_new(int poolsize)
{
fifo_t *f;
- f = kcalloc(1, sizeof(*f), GFP_KERNEL);
+ f = kzalloc(sizeof(*f), GFP_KERNEL);
if (f == NULL) {
snd_printd("malloc failed for snd_seq_fifo_new() \n");
return NULL;
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 5b40ea2ba8f4..019d43a462d7 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -53,7 +53,7 @@ static snd_seq_kinstr_t *snd_seq_instr_new(int add_len, int atomic)
{
snd_seq_kinstr_t *instr;
- instr = kcalloc(1, sizeof(snd_seq_kinstr_t) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
+ instr = kzalloc(sizeof(snd_seq_kinstr_t) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
if (instr == NULL)
return NULL;
instr->add_len = add_len;
@@ -77,7 +77,7 @@ snd_seq_kinstr_list_t *snd_seq_instr_list_new(void)
{
snd_seq_kinstr_list_t *list;
- list = kcalloc(1, sizeof(snd_seq_kinstr_list_t), GFP_KERNEL);
+ list = kzalloc(sizeof(snd_seq_kinstr_list_t), GFP_KERNEL);
if (list == NULL)
return NULL;
spin_lock_init(&list->lock);
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 03acb2d519ba..d4d7d326c4b1 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -452,7 +452,7 @@ pool_t *snd_seq_pool_new(int poolsize)
pool_t *pool;
/* create pool block */
- pool = kcalloc(1, sizeof(*pool), GFP_KERNEL);
+ pool = kzalloc(sizeof(*pool), GFP_KERNEL);
if (pool == NULL) {
snd_printd("seq: malloc failed for pool\n");
return NULL;
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 4374829ea770..b4674ae3bc30 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -322,7 +322,7 @@ snd_seq_midisynth_register_port(snd_seq_device_t *dev)
client = synths[card->number];
if (client == NULL) {
newclient = 1;
- client = kcalloc(1, sizeof(*client), GFP_KERNEL);
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
if (client == NULL) {
up(&register_mutex);
kfree(info);
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
index 603b63716db6..2dc1aecfb426 100644
--- a/sound/core/seq/seq_midi_event.c
+++ b/sound/core/seq/seq_midi_event.c
@@ -118,7 +118,7 @@ int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev)
snd_midi_event_t *dev;
*rdev = NULL;
- dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL)
return -ENOMEM;
if (bufsize > 0) {
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index b976951fc100..57ec31df0d15 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -141,7 +141,7 @@ client_port_t *snd_seq_create_port(client_t *client, int port)
}
/* create a new port */
- new_port = kcalloc(1, sizeof(*new_port), GFP_KERNEL);
+ new_port = kzalloc(sizeof(*new_port), GFP_KERNEL);
if (! new_port) {
snd_printd("malloc failed for registering client port\n");
return NULL; /* failure, out of memory */
@@ -488,7 +488,7 @@ int snd_seq_port_connect(client_t *connector,
unsigned long flags;
int exclusive;
- subs = kcalloc(1, sizeof(*subs), GFP_KERNEL);
+ subs = kzalloc(sizeof(*subs), GFP_KERNEL);
if (! subs)
return -ENOMEM;
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index a519732ed833..cd641bca9945 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -59,7 +59,7 @@ prioq_t *snd_seq_prioq_new(void)
{
prioq_t *f;
- f = kcalloc(1, sizeof(*f), GFP_KERNEL);
+ f = kzalloc(sizeof(*f), GFP_KERNEL);
if (f == NULL) {
snd_printd("oops: malloc failed for snd_seq_prioq_new()\n");
return NULL;
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 98de2e711fde..5f5c3cb37cbf 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -111,7 +111,7 @@ static queue_t *queue_new(int owner, int locked)
{
queue_t *q;
- q = kcalloc(1, sizeof(*q), GFP_KERNEL);
+ q = kzalloc(sizeof(*q), GFP_KERNEL);
if (q == NULL) {
snd_printd("malloc failed for snd_seq_queue_new()\n");
return NULL;
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index e8f0a6683d50..0d9eff85ab88 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -126,8 +126,8 @@ int __init snd_seq_system_client_init(void)
snd_seq_client_info_t *inf;
snd_seq_port_info_t *port;
- inf = kcalloc(1, sizeof(*inf), GFP_KERNEL);
- port = kcalloc(1, sizeof(*port), GFP_KERNEL);
+ inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
if (! inf || ! port) {
kfree(inf);
kfree(port);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index a7f76fc95280..b57a3c07ff6f 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -60,7 +60,7 @@ seq_timer_t *snd_seq_timer_new(void)
{
seq_timer_t *tmr;
- tmr = kcalloc(1, sizeof(*tmr), GFP_KERNEL);
+ tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
if (tmr == NULL) {
snd_printd("malloc failed for snd_seq_timer_new() \n");
return NULL;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index a66484b5cf0e..e4f512aa7426 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -205,7 +205,7 @@ static int snd_virmidi_input_open(snd_rawmidi_substream_t * substream)
snd_virmidi_t *vmidi;
unsigned long flags;
- vmidi = kcalloc(1, sizeof(*vmidi), GFP_KERNEL);
+ vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
if (vmidi == NULL)
return -ENOMEM;
vmidi->substream = substream;
@@ -233,7 +233,7 @@ static int snd_virmidi_output_open(snd_rawmidi_substream_t * substream)
snd_rawmidi_runtime_t *runtime = substream->runtime;
snd_virmidi_t *vmidi;
- vmidi = kcalloc(1, sizeof(*vmidi), GFP_KERNEL);
+ vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
if (vmidi == NULL)
return -ENOMEM;
vmidi->substream = substream;
@@ -508,7 +508,7 @@ int snd_virmidi_new(snd_card_t *card, int device, snd_rawmidi_t **rrmidi)
&rmidi)) < 0)
return err;
strcpy(rmidi->name, rmidi->id);
- rdev = kcalloc(1, sizeof(*rdev), GFP_KERNEL);
+ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
if (rdev == NULL) {
snd_device_free(card, rmidi);
return -ENOMEM;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 3271e9245490..9e76bddb2c0b 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -328,6 +328,10 @@ int __exit snd_minor_info_done(void)
* INIT PART
*/
+#ifdef CONFIG_SND_GENERIC_DRIVER
+extern struct device_driver snd_generic_driver;
+#endif
+
static int __init alsa_sound_init(void)
{
short controlnum;
@@ -354,6 +358,9 @@ static int __init alsa_sound_init(void)
return -ENOMEM;
}
snd_info_minor_register();
+#ifdef CONFIG_SND_GENERIC_DRIVER
+ driver_register(&snd_generic_driver);
+#endif
for (controlnum = 0; controlnum < cards_limit; controlnum++)
devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
#ifndef MODULE
@@ -369,6 +376,9 @@ static void __exit alsa_sound_exit(void)
for (controlnum = 0; controlnum < cards_limit; controlnum++)
devfs_remove("snd/controlC%d", controlnum);
+#ifdef CONFIG_SND_GENERIC_DRIVER
+ driver_unregister(&snd_generic_driver);
+#endif
snd_info_minor_unregister();
snd_info_done();
snd_memory_done();
@@ -416,10 +426,13 @@ EXPORT_SYMBOL(snd_card_register);
EXPORT_SYMBOL(snd_component_add);
EXPORT_SYMBOL(snd_card_file_add);
EXPORT_SYMBOL(snd_card_file_remove);
+#ifdef CONFIG_SND_GENERIC_DRIVER
+EXPORT_SYMBOL(snd_card_set_generic_dev);
+#endif
#ifdef CONFIG_PM
EXPORT_SYMBOL(snd_power_wait);
EXPORT_SYMBOL(snd_card_set_pm_callback);
-#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
+#ifdef CONFIG_SND_GENERIC_DRIVER
EXPORT_SYMBOL(snd_card_set_generic_pm_callback);
#endif
#ifdef CONFIG_PCI
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 4104f6e292e9..22b104624084 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -98,7 +98,7 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left);
static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer)
{
snd_timer_instance_t *timeri;
- timeri = kcalloc(1, sizeof(*timeri), GFP_KERNEL);
+ timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
if (timeri == NULL)
return NULL;
timeri->owner = kstrdup(owner, GFP_KERNEL);
@@ -764,7 +764,7 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t *
snd_assert(tid != NULL, return -EINVAL);
snd_assert(rtimer != NULL, return -EINVAL);
*rtimer = NULL;
- timer = kcalloc(1, sizeof(*timer), GFP_KERNEL);
+ timer = kzalloc(sizeof(*timer), GFP_KERNEL);
if (timer == NULL)
return -ENOMEM;
timer->tmr_class = tid->dev_class;
@@ -1017,7 +1017,7 @@ static int snd_timer_register_system(void)
return err;
strcpy(timer->name, "system timer");
timer->hw = snd_timer_system;
- priv = kcalloc(1, sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (priv == NULL) {
snd_timer_free(timer);
return -ENOMEM;
@@ -1202,7 +1202,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
{
snd_timer_user_t *tu;
- tu = kcalloc(1, sizeof(*tu), GFP_KERNEL);
+ tu = kzalloc(sizeof(*tu), GFP_KERNEL);
if (tu == NULL)
return -ENOMEM;
spin_lock_init(&tu->qlock);
@@ -1513,7 +1513,7 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info
t = tu->timeri->timer;
snd_assert(t != NULL, return -ENXIO);
- info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (! info)
return -ENOMEM;
info->card = t->card ? t->card->number : -1;
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c
index 508e6d67ee19..296b716f1376 100644
--- a/sound/core/wrappers.c
+++ b/sound/core/wrappers.c
@@ -27,7 +27,7 @@
#include <linux/fs.h>
#ifdef CONFIG_SND_DEBUG_MEMORY
-void *snd_wrapper_kmalloc(size_t size, unsigned int __nocast flags)
+void *snd_wrapper_kmalloc(size_t size, gfp_t flags)
{
return kmalloc(size, flags);
}
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 3b2bee19e2c0..efcb4eb2d1a0 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -29,6 +29,7 @@ config SND_DUMMY
tristate "Dummy (/dev/null) soundcard"
depends on SND
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include the dummy driver. This driver does
nothing, but emulates various mixer controls and PCM devices.
@@ -44,6 +45,7 @@ config SND_VIRMIDI
depends on SND_SEQUENCER
select SND_TIMER
select SND_RAWMIDI
+ select SND_GENERIC_DRIVER
help
Say Y here to include the virtual MIDI driver. This driver
allows to connect applications using raw MIDI devices to
@@ -59,6 +61,7 @@ config SND_MTPAV
depends on SND
select SND_TIMER
select SND_RAWMIDI
+ select SND_GENERIC_DRIVER
help
To use a MOTU MidiTimePiece AV multiport MIDI adapter
connected to the parallel port, say Y here and make sure that
@@ -72,6 +75,7 @@ config SND_SERIAL_U16550
depends on SND
select SND_TIMER
select SND_RAWMIDI
+ select SND_GENERIC_DRIVER
help
To include support for MIDI serial port interfaces, say Y here
and read <file:Documentation/sound/alsa/serial-u16550.txt>.
@@ -88,6 +92,7 @@ config SND_MPU401
tristate "Generic MPU-401 UART driver"
depends on SND
select SND_MPU401_UART
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for MIDI ports compatible with
the Roland MPU-401 interface in UART mode.
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index a61640cf7ae7..64ef7f62851d 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -337,7 +337,7 @@ static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream)
snd_card_dummy_pcm_t *dpcm;
int err;
- dpcm = kcalloc(1, sizeof(*dpcm), GFP_KERNEL);
+ dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
if (dpcm == NULL)
return -ENOMEM;
init_timer(&dpcm->timer);
@@ -368,7 +368,7 @@ static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream)
snd_card_dummy_pcm_t *dpcm;
int err;
- dpcm = kcalloc(1, sizeof(*dpcm), GFP_KERNEL);
+ dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
if (dpcm == NULL)
return -ENOMEM;
init_timer(&dpcm->timer);
@@ -600,6 +600,10 @@ static int __init snd_card_dummy_probe(int dev)
strcpy(card->driver, "Dummy");
strcpy(card->shortname, "Dummy");
sprintf(card->longname, "Dummy %i", dev + 1);
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto __nodev;
+
if ((err = snd_card_register(card)) == 0) {
snd_dummy_cards[dev] = card;
return 0;
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index cb36ecb78697..54e2ff9b5ca1 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -77,20 +77,26 @@ static int snd_mpu401_create(int dev, snd_card_t **rcard)
strcat(card->longname, "polled");
}
- if (snd_mpu401_uart_new(card, 0,
- MPU401_HW_MPU401,
- port[dev], 0,
- irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
+ if ((err = snd_mpu401_uart_new(card, 0,
+ MPU401_HW_MPU401,
+ port[dev], 0,
+ irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL)) < 0) {
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
- snd_card_free(card);
- return -ENODEV;
- }
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ goto _err;
}
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
*rcard = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __devinit snd_mpu401_probe(int dev)
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 0f83c5241b6b..fe3f921ffbe3 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -463,7 +463,7 @@ int snd_mpu401_uart_new(snd_card_t * card, int device,
*rrawmidi = NULL;
if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0)
return err;
- mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL);
+ mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
if (mpu == NULL) {
snd_device_free(card, rmidi);
return -ENOMEM;
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 1280a57c49eb..3a25c89d2983 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -688,7 +688,7 @@ static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard)
static mtpav_t *new_mtpav(void)
{
- mtpav_t *ncrd = kcalloc(1, sizeof(*ncrd), GFP_KERNEL);
+ mtpav_t *ncrd = kzalloc(sizeof(*ncrd), GFP_KERNEL);
if (ncrd != NULL) {
spin_lock_init(&ncrd->spinlock);
@@ -757,6 +757,9 @@ static int __init alsa_card_mtpav_init(void)
if (err < 0)
goto __error;
+ if ((err = snd_card_set_generic_dev(mtp_card->card)) < 0)
+ goto __error;
+
err = snd_card_register(mtp_card->card); // don't snd_card_register until AFTER all cards reources done!
//printk("snd_card_register returned %d\n", err);
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index c313e5205cb8..1f84d78260de 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -354,7 +354,7 @@ int snd_opl3_new(snd_card_t *card,
int err;
*ropl3 = NULL;
- opl3 = kcalloc(1, sizeof(*opl3), GFP_KERNEL);
+ opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
if (opl3 == NULL)
return -ENOMEM;
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index 33da334ae981..21a2b409d6d3 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -241,7 +241,7 @@ static int snd_opl3_load_patch_seq_oss(snd_seq_oss_arg_t *arg, int format,
}
size = sizeof(*put) + sizeof(fm_xinstrument_t);
- put = kcalloc(1, size, GFP_KERNEL);
+ put = kzalloc(size, GFP_KERNEL);
if (put == NULL)
return -ENOMEM;
/* build header */
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 8261464dade8..380c2c704c54 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -204,7 +204,7 @@ int snd_opl4_create(snd_card_t *card,
if (ropl4)
*ropl4 = NULL;
- opl4 = kcalloc(1, sizeof(*opl4), GFP_KERNEL);
+ opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL);
if (!opl4)
return -ENOMEM;
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 986df35fb829..416172ea1f47 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -779,7 +779,7 @@ static int __init snd_uart16550_create(snd_card_t * card,
int err;
- if ((uart = kcalloc(1, sizeof(*uart), GFP_KERNEL)) == NULL)
+ if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL)
return -ENOMEM;
uart->adaptor = adaptor;
uart->card = card;
@@ -928,15 +928,11 @@ static int __init snd_serial_probe(int dev)
base[dev],
adaptor[dev],
droponfull[dev],
- &uart)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &uart)) < 0)
+ goto _err;
- if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0)
+ goto _err;
sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d",
card->shortname,
@@ -949,12 +945,18 @@ static int __init snd_serial_probe(int dev)
adaptor_names[uart->adaptor],
uart->drop_on_full);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
snd_serial_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init alsa_card_serial_init(void)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 5937711e9505..af12185ab8a2 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -116,6 +116,10 @@ static int __init snd_card_virmidi_probe(int dev)
strcpy(card->driver, "VirMIDI");
strcpy(card->shortname, "VirMIDI");
sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto __nodev;
+
if ((err = snd_card_register(card)) == 0) {
snd_virmidi_cards[dev] = card;
return 0;
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index c6fa5afa3e9a..4697b1d75cbb 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -782,7 +782,7 @@ vx_core_t *snd_vx_create(snd_card_t *card, struct snd_vx_hardware *hw,
snd_assert(card && hw && ops, return NULL);
- chip = kcalloc(1, sizeof(*chip) + extra_size, GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
if (! chip) {
snd_printk(KERN_ERR "vx_core: no memory\n");
return NULL;
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index d4becf44e247..c2312d912fc7 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -473,7 +473,7 @@ static int vx_alloc_pipe(vx_core_t *chip, int capture,
return err;
/* initialize the pipe record */
- pipe = kcalloc(1, sizeof(*pipe), GFP_KERNEL);
+ pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
if (! pipe) {
/* release the pipe */
vx_init_rmh(&rmh, CMD_FREE_PIPE);
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index a3fda859dd15..a21f7d541f86 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -200,7 +200,7 @@ int snd_cs8427_create(snd_i2c_bus_t *bus,
if ((err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7), &device)) < 0)
return err;
- chip = device->private_data = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
snd_i2c_device_free(device);
return -ENOMEM;
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index e8fa7e1a68e8..e4e505b9d88b 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -81,7 +81,7 @@ int snd_i2c_bus_create(snd_card_t *card, const char *name, snd_i2c_bus_t *master
};
*ri2c = NULL;
- bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (bus == NULL)
return -ENOMEM;
init_MUTEX(&bus->lock_mutex);
@@ -108,7 +108,7 @@ int snd_i2c_device_create(snd_i2c_bus_t *bus, const char *name, unsigned char ad
*rdevice = NULL;
snd_assert(bus != NULL, return -EINVAL);
- device = kcalloc(1, sizeof(*device), GFP_KERNEL);
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
if (device == NULL)
return -ENOMEM;
device->addr = addr;
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index e13122f3fc50..103a7dcd0dde 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -17,7 +17,7 @@
* 2002-05-12 Tomas Kasparek another code cleanup
*/
-/* $Id: uda1341.c,v 1.15 2005/01/03 12:05:20 tiwai Exp $ */
+/* $Id: uda1341.c,v 1.16 2005/09/09 13:22:34 tiwai Exp $ */
#include <sound/driver.h>
#include <linux/module.h>
@@ -670,7 +670,7 @@ int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt)
snd_assert(card != NULL, return -EINVAL);
- uda1341 = kcalloc(1, sizeof(*uda1341), GFP_KERNEL);
+ uda1341 = kzalloc(sizeof(*uda1341), GFP_KERNEL);
if (uda1341 == NULL)
return -ENOMEM;
@@ -707,7 +707,7 @@ static int uda1341_attach(struct l3_client *clnt)
{
struct uda1341 *uda;
- uda = kcalloc(1, sizeof(*uda), 0, GFP_KERNEL);
+ uda = kzalloc(sizeof(*uda), 0, GFP_KERNEL);
if (!uda)
return -ENOMEM;
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 5adde308a00f..af5eadcddd92 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -92,7 +92,7 @@ int snd_ak4114_create(snd_card_t *card,
.dev_free = snd_ak4114_dev_free,
};
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->lock);
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index 0419c4336a55..d51b51dd86d6 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -83,7 +83,7 @@ int snd_ak4117_create(snd_card_t *card, ak4117_read_t *read, ak4117_write_t *wri
.dev_free = snd_ak4117_dev_free,
};
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->lock);
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index 2da8d7f157f4..fd65da654267 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -281,7 +281,7 @@ int snd_tea6330t_update_mixer(snd_card_t * card,
u8 default_treble, default_bass;
unsigned char bytes[7];
- tea = kcalloc(1, sizeof(*tea), GFP_KERNEL);
+ tea = kzalloc(sizeof(*tea), GFP_KERNEL);
if (tea == NULL)
return -ENOMEM;
if ((err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device)) < 0) {
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 5c3948311528..5d6c300ac0d5 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -6,12 +6,12 @@ menu "ISA devices"
config SND_AD1848_LIB
tristate
select SND_PCM
- select SND_GENERIC_PM
+ select SND_GENERIC_DRIVER
config SND_CS4231_LIB
tristate
select SND_PCM
- select SND_GENERIC_PM
+ select SND_GENERIC_DRIVER
config SND_AD1816A
tristate "Analog Devices SoundPort AD1816A"
@@ -97,6 +97,7 @@ config SND_ES1688
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for ESS AudioDrive ES688 or
ES1688 chips.
@@ -110,7 +111,7 @@ config SND_ES18XX
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
- select SND_GENERIC_PM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for ESS AudioDrive ES18xx chips.
@@ -126,6 +127,7 @@ config SND_GUSCLASSIC
select SND_RAWMIDI
select SND_PCM
select SND_GUS_SYNTH
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for Gravis UltraSound Classic
soundcards.
@@ -140,6 +142,7 @@ config SND_GUSEXTREME
select SND_MPU401_UART
select SND_PCM
select SND_GUS_SYNTH
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for Gravis UltraSound Extreme
soundcards.
@@ -153,6 +156,7 @@ config SND_GUSMAX
select SND_RAWMIDI
select SND_CS4231_LIB
select SND_GUS_SYNTH
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for Gravis UltraSound MAX
soundcards.
@@ -166,7 +170,7 @@ config SND_INTERWAVE
select SND_RAWMIDI
select SND_CS4231_LIB
select SND_GUS_SYNTH
- select ISAPNP
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for AMD InterWave based
soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
@@ -181,7 +185,7 @@ config SND_INTERWAVE_STB
select SND_RAWMIDI
select SND_CS4231_LIB
select SND_GUS_SYNTH
- select ISAPNP
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for AMD InterWave based
soundcards with a TEA6330T bass and treble regulator
@@ -224,6 +228,7 @@ config SND_OPTI93X
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for soundcards based on Opti
82C93x chips.
@@ -237,6 +242,7 @@ config SND_SB8
select SND_OPL3_LIB
select SND_RAWMIDI
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for Creative Sound Blaster 1.0/
2.0/Pro (8-bit) or 100% compatible soundcards.
@@ -250,6 +256,7 @@ config SND_SB16
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for Sound Blaster 16 soundcards
(including the Plug and Play version).
@@ -263,6 +270,7 @@ config SND_SBAWE
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for Sound Blaster AWE soundcards
(including the Plug and Play version).
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index ae860360ecf9..27a9dcfbba00 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -591,7 +591,7 @@ int snd_ad1816a_create(snd_card_t *card,
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->irq = -1;
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 8c399340cd72..3ebcc482b07a 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -91,35 +91,36 @@ static int __init snd_card_ad1848_probe(int dev)
irq[dev],
dma1[dev],
thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &chip)) < 0)
+ goto _err;
+
+ if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
+ goto _err;
+
+ if ((err = snd_ad1848_mixer(chip)) < 0)
+ goto _err;
- if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_ad1848_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
strcpy(card->driver, "AD1848");
strcpy(card->shortname, pcm->name);
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
pcm->name, chip->port, irq[dev], dma1[dev]);
- if (thinkpad[dev]) {
+ if (thinkpad[dev])
strcat(card->longname, " [Thinkpad]");
- }
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
snd_ad1848_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init alsa_card_ad1848_init(void)
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index bc642dc94547..303861cd03cd 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -890,7 +890,7 @@ int snd_ad1848_create(snd_card_t * card,
int err;
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 1fce8b9f37cf..5252206ea388 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -438,33 +438,37 @@ static int __devinit snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
/*
*/
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev) isapnp[dev]
+#else
+#define is_isapnp_selected(dev) 0
+#endif
+
+#define PFX "cmi8330: "
+
static int __devinit snd_cmi8330_probe(int dev,
struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
snd_card_t *card;
struct snd_cmi8330 *acard;
- unsigned long flags;
int i, err;
-#ifdef CONFIG_PNP
- if (!isapnp[dev]) {
-#endif
+ if (! is_isapnp_selected(dev)) {
if (wssport[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify wssport\n");
+ snd_printk(KERN_ERR PFX "specify wssport\n");
return -EINVAL;
}
if (sbport[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify sbport\n");
+ snd_printk(KERN_ERR PFX "specify sbport\n");
return -EINVAL;
}
-#ifdef CONFIG_PNP
}
-#endif
+
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_cmi8330));
if (card == NULL) {
- snd_printk("could not get a new card\n");
+ snd_printk(KERN_ERR PFX "could not get a new card\n");
return -ENOMEM;
}
acard = (struct snd_cmi8330 *)card->private_data;
@@ -473,9 +477,8 @@ static int __devinit snd_cmi8330_probe(int dev,
#ifdef CONFIG_PNP
if (isapnp[dev]) {
if ((err = snd_cmi8330_pnp(dev, acard, pcard, pid)) < 0) {
- snd_printk("PnP detection failed\n");
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR PFX "PnP detection failed\n");
+ goto _err;
}
snd_card_set_dev(card, &pcard->card->dev);
}
@@ -487,14 +490,13 @@ static int __devinit snd_cmi8330_probe(int dev,
wssdma[dev],
AD1848_HW_DETECT,
&acard->wss)) < 0) {
- snd_printk("(AD1848) device busy??\n");
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
+ goto _err;
}
if (acard->wss->hardware != AD1848_HW_CMI8330) {
- snd_printk("(AD1848) not found during probe\n");
- snd_card_free(card);
- return -ENODEV;
+ snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n");
+ err = -ENODEV;
+ goto _err;
}
if ((err = snd_sbdsp_create(card, sbport[dev],
@@ -503,32 +505,26 @@ static int __devinit snd_cmi8330_probe(int dev,
sbdma8[dev],
sbdma16[dev],
SB_HW_AUTO, &acard->sb)) < 0) {
- snd_printk("(SB16) device busy??\n");
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR PFX "(SB16) device busy??\n");
+ goto _err;
}
if (acard->sb->hardware != SB_HW_16) {
- snd_printk("(SB16) not found during probe\n");
- snd_card_free(card);
- return -ENODEV;
+ snd_printk(KERN_ERR PFX "(SB16) not found during probe\n");
+ goto _err;
}
- spin_lock_irqsave(&acard->wss->reg_lock, flags);
snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */
for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]);
- spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
- snd_printk("failed to create mixers\n");
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR PFX "failed to create mixers\n");
+ goto _err;
}
if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
- snd_printk("failed to create pcms\n");
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR PFX "failed to create pcms\n");
+ goto _err;
}
strcpy(card->driver, "CMI8330/C3D");
@@ -539,16 +535,21 @@ static int __devinit snd_cmi8330_probe(int dev,
wssirq[dev],
wssdma[dev]);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
if (pcard)
pnp_set_card_drvdata(pcard, card);
else
snd_cmi8330_legacy[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
#ifdef CONFIG_PNP
@@ -594,10 +595,8 @@ static int __init alsa_card_cmi8330_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
continue;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
+ if (is_isapnp_selected(dev))
continue;
-#endif
if (snd_cmi8330_probe(dev, NULL, NULL) >= 0)
cards++;
}
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index 7640837659ea..9be5416bcb92 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -76,15 +76,15 @@ static int __init snd_card_cs4231_probe(int dev)
int err;
if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify port\n");
+ snd_printk(KERN_ERR "specify port\n");
return -EINVAL;
}
if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk("specify irq\n");
+ snd_printk(KERN_ERR "specify irq\n");
return -EINVAL;
}
if (dma1[dev] == SNDRV_AUTO_DMA) {
- snd_printk("specify dma1\n");
+ snd_printk(KERN_ERR "specify dma1\n");
return -EINVAL;
}
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -96,15 +96,11 @@ static int __init snd_card_cs4231_probe(int dev)
dma1[dev],
dma2[dev],
CS4231_HW_DETECT,
- 0, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ 0, &chip)) < 0)
+ goto _err;
- if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
+ goto _err;
strcpy(card->driver, "CS4231");
strcpy(card->shortname, pcm->name);
@@ -113,14 +109,10 @@ static int __init snd_card_cs4231_probe(int dev)
if (dma2[dev] >= 0)
sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
- if ((err = snd_cs4231_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_cs4231_mixer(chip)) < 0)
+ goto _err;
+ if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
+ goto _err;
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
@@ -130,14 +122,20 @@ static int __init snd_card_cs4231_probe(int dev)
mpu_irq[dev],
mpu_irq[dev] >= 0 ? SA_INTERRUPT : 0,
NULL) < 0)
- printk(KERN_ERR "cs4231: MPU401 not detected\n");
- }
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ printk(KERN_WARNING "cs4231: MPU401 not detected\n");
}
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
snd_cs4231_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init alsa_card_cs4231_init(void)
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 3199941edd9b..32318258cd8e 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1480,7 +1480,7 @@ static int snd_cs4231_new(snd_card_t * card,
cs4231_t *chip;
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->hardware = hardware;
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 39f4eff44f5c..d28315dc72f7 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -387,6 +387,12 @@ static void snd_card_cs4236_free(snd_card_t *card)
}
}
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev) isapnp[dev]
+#else
+#define is_isapnp_selected(dev) 0
+#endif
+
static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
@@ -397,20 +403,16 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
opl3_t *opl3;
int err;
-#ifdef CONFIG_PNP
- if (!isapnp[dev]) {
-#endif
+ if (! is_isapnp_selected(dev)) {
if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify port\n");
+ snd_printk(KERN_ERR "specify port\n");
return -EINVAL;
}
if (cport[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify cport\n");
+ snd_printk(KERN_ERR "specify cport\n");
return -EINVAL;
}
-#ifdef CONFIG_PNP
}
-#endif
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_cs4236));
if (card == NULL)
@@ -421,8 +423,7 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
if (isapnp[dev]) {
if ((err = snd_card_cs4236_pnp(dev, acard, pcard, pid))<0) {
printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n");
- snd_card_free(card);
- return -ENXIO;
+ goto _err;
}
snd_card_set_dev(card, &pcard->card->dev);
}
@@ -430,8 +431,8 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT)
if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) {
printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
- snd_card_free(card);
- return -ENOMEM;
+ err = -EBUSY;
+ goto _err;
}
#ifdef CS4232
@@ -443,18 +444,14 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
dma2[dev],
CS4231_HW_DETECT,
0,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &chip)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_mixer(chip)) < 0)
+ goto _err;
#else /* CS4236 */
if ((err = snd_cs4236_create(card,
@@ -465,18 +462,14 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
dma2[dev],
CS4231_HW_DETECT,
0,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4236_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &chip)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4236_mixer(chip)) < 0)
+ goto _err;
#endif
strcpy(card->driver, pcm->name);
strcpy(card->shortname, pcm->name);
@@ -488,21 +481,17 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
if (dma2[dev] >= 0)
sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
- if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
+ goto _err;
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
if (snd_opl3_create(card,
fm_port[dev], fm_port[dev] + 2,
OPL3_HW_OPL3_CS, 0, &opl3) < 0) {
- printk(KERN_ERR IDENT ": OPL3 not detected\n");
+ printk(KERN_WARNING IDENT ": OPL3 not detected\n");
} else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+ goto _err;
}
}
@@ -513,17 +502,23 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
mpu_port[dev], 0,
mpu_irq[dev],
mpu_irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0)
- printk(KERN_ERR IDENT ": MPU401 not detected\n");
- }
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ printk(KERN_WARNING IDENT ": MPU401 not detected\n");
}
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
if (pcard)
pnp_set_card_drvdata(pcard, card);
else
snd_cs4236_legacy[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
#ifdef CONFIG_PNP
@@ -569,10 +564,8 @@ static int __init alsa_card_cs423x_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
continue;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
+ if (is_isapnp_selected(dev))
continue;
-#endif
if (snd_card_cs423x_probe(dev, NULL, NULL) >= 0)
cards++;
}
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index c5eaec087b46..26a7d335ed8e 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -70,6 +70,7 @@ MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
static snd_card_t *snd_audiodrive_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+#define PFX "es1688: "
static int __init snd_audiodrive_probe(int dev)
{
@@ -89,47 +90,41 @@ static int __init snd_audiodrive_probe(int dev)
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free IRQ\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
}
}
xmpu_irq = mpu_irq[dev];
xdma = dma8[dev];
if (xdma == SNDRV_AUTO_DMA) {
if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
+ err = -EBUSY;
+ goto _err;
}
}
if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
xirq, xmpu_irq, xdma,
- ES1688_HW_AUTO, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_es1688_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ ES1688_HW_AUTO, &chip)) < 0)
+ goto _err;
+
+ if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
+ goto _err;
+
+ if ((err = snd_es1688_mixer(chip)) < 0)
+ goto _err;
strcpy(card->driver, "ES1688");
strcpy(card->shortname, pcm->name);
sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);
if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
- printk(KERN_ERR "es1688: opl3 not detected at 0x%lx\n", chip->port);
+ printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
} else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+ goto _err;
}
if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
@@ -137,18 +132,22 @@ static int __init snd_audiodrive_probe(int dev)
chip->mpu_port, 0,
xmpu_irq,
SA_INTERRUPT,
- NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- }
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ NULL)) < 0)
+ goto _err;
}
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
snd_audiodrive_cards[dev] = card;
return 0;
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init snd_audiodrive_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 17f68d07d9b2..aac898765c02 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -649,7 +649,7 @@ int snd_es1688_create(snd_card_t * card,
int err;
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->irq = -1;
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 1d832b2adb7c..d0ea19f42703 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1686,7 +1686,7 @@ static int __devinit snd_es18xx_new_device(snd_card_t * card,
int err;
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
@@ -1988,6 +1988,12 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard,
}
#endif /* CONFIG_PNP */
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev) isapnp[dev]
+#else
+#define is_isapnp_selected(dev) 0
+#endif
+
static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
@@ -1996,7 +2002,6 @@ static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
int xirq, xdma1, xdma2;
snd_card_t *card;
struct snd_audiodrive *acard;
- snd_rawmidi_t *rmidi = NULL;
es18xx_t *chip;
opl3_t *opl3;
int err;
@@ -2019,25 +2024,25 @@ static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free IRQ\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma1 = dma1[dev];
if (xdma1 == SNDRV_AUTO_DMA) {
if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA1\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma2 = dma2[dev];
if (xdma2 == SNDRV_AUTO_DMA) {
if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA2\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+ err = -EBUSY;
+ goto _err;
}
}
@@ -2046,10 +2051,8 @@ static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
mpu_port[dev],
fm_port[dev],
xirq, xdma1, xdma2,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &chip)) < 0)
+ goto _err;
sprintf(card->driver, "ES%x", chip->version);
sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version);
@@ -2064,23 +2067,18 @@ static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
chip->port,
xirq, xdma1);
- if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_es18xx_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0)
+ goto _err;
+
+ if ((err = snd_es18xx_mixer(chip)) < 0)
+ goto _err;
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) {
- snd_printk(KERN_ERR PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
+ snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
} else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+ goto _err;
}
}
@@ -2088,25 +2086,28 @@ static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
chip->mpu_port, 0,
xirq, 0,
- &rmidi)) < 0) {
- snd_card_free(card);
- return err;
- }
- chip->rmidi = rmidi;
+ &chip->rmidi)) < 0)
+ goto _err;
}
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
/* Power Management */
snd_card_set_isa_pm_callback(card, snd_es18xx_suspend, snd_es18xx_resume, chip);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
if (pcard)
pnp_set_card_drvdata(pcard, card);
else
snd_audiodrive_legacy[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __devinit snd_audiodrive_probe_legacy_port(unsigned long xport)
@@ -2117,10 +2118,8 @@ static int __devinit snd_audiodrive_probe_legacy_port(unsigned long xport)
for ( ; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
continue;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
+ if (is_isapnp_selected(dev))
continue;
-#endif
port[dev] = xport;
res = snd_audiodrive_probe(dev, NULL, NULL);
if (res < 0)
@@ -2177,10 +2176,8 @@ static int __init alsa_card_es18xx_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
continue;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
+ if (is_isapnp_selected(dev))
continue;
-#endif
if (snd_audiodrive_probe(dev, NULL, NULL) >= 0)
cards++;
}
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index a636d9ce3502..8f2872f8e8f6 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -157,7 +157,7 @@ int snd_gus_create(snd_card_t * card,
};
*rgus = NULL;
- gus = kcalloc(1, sizeof(*gus), GFP_KERNEL);
+ gus = kzalloc(sizeof(*gus), GFP_KERNEL);
if (gus == NULL)
return -ENOMEM;
gus->gf1.irq = -1;
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 886763f12132..7f96ac237f3c 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -98,7 +98,7 @@ int snd_gf1_mem_proc_init(snd_gus_card_t * gus)
for (idx = 0; idx < 4; idx++) {
if (gus->gf1.mem_alloc.banks_8[idx].size > 0) {
- priv = kcalloc(1, sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
priv->gus = gus;
@@ -115,7 +115,7 @@ int snd_gf1_mem_proc_init(snd_gus_card_t * gus)
}
for (idx = 0; idx < 4; idx++) {
if (gus->gf1.rom_present & (1 << idx)) {
- priv = kcalloc(1, sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
priv->rom = 1;
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index b75066ab46fc..beb01365dc46 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -666,7 +666,7 @@ static int snd_gf1_pcm_playback_open(snd_pcm_substream_t *substream)
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- pcmp = kcalloc(1, sizeof(*pcmp), GFP_KERNEL);
+ pcmp = kzalloc(sizeof(*pcmp), GFP_KERNEL);
if (pcmp == NULL)
return -ENOMEM;
pcmp->gus = gus;
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index a99fa5040b46..39cef38835ca 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -72,40 +72,24 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
static snd_card_t *snd_gusclassic_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+#define PFX "gusclassic: "
static int __init snd_gusclassic_detect(snd_gus_card_t * gus)
{
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- unsigned char d;
+ unsigned char d;
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+ snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
-#endif
+ }
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- unsigned char d;
-
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
-#endif
-
+ }
return 0;
}
@@ -137,25 +121,25 @@ static int __init snd_gusclassic_probe(int dev)
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free IRQ\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma1 = dma1[dev];
if (xdma1 == SNDRV_AUTO_DMA) {
if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA1\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma2 = dma2[dev];
if (xdma2 == SNDRV_AUTO_DMA) {
if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA2\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+ err = -EBUSY;
+ goto _err;
}
}
@@ -164,47 +148,48 @@ static int __init snd_gusclassic_probe(int dev)
port[dev],
xirq, xdma1, xdma2,
0, channels[dev], pcm_channels[dev],
- 0, &gus)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_gusclassic_detect(gus)) < 0) {
- snd_card_free(card);
- return err;
- }
+ 0, &gus)) < 0)
+ goto _err;
+
+ if ((err = snd_gusclassic_detect(gus)) < 0)
+ goto _err;
+
snd_gusclassic_init(dev, gus);
- if ((err = snd_gus_initialize(gus)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_gus_initialize(gus)) < 0)
+ goto _err;
+
if (gus->max_flag || gus->ess_flag) {
- snd_printdd("GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
- snd_card_free(card);
- return -ENODEV;
- }
- if ((err = snd_gf1_new_mixer(gus)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
+ err = -ENODEV;
+ goto _err;
}
+
+ if ((err = snd_gf1_new_mixer(gus)) < 0)
+ goto _err;
+
+ if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0)
+ goto _err;
+
if (!gus->ace_flag) {
- if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+ goto _err;
}
sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
if (dma2 >= 0)
sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
snd_gusclassic_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init snd_gusclassic_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index bc6fecb18dcf..d2e7cb1df537 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -87,6 +87,7 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
static snd_card_t *snd_gusextreme_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+#define PFX "gusextreme: "
static int __init snd_gusextreme_detect(int dev,
snd_card_t * card,
@@ -94,6 +95,7 @@ static int __init snd_gusextreme_detect(int dev,
es1688_t *es1688)
{
unsigned long flags;
+ unsigned char d;
/*
* This is main stuff - enable access to GF1 chip...
@@ -123,36 +125,17 @@ static int __init snd_gusextreme_detect(int dev,
udelay(100);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- unsigned char d;
-
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -EIO;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -EIO;
-#endif
+ }
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- unsigned char d;
-
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -EIO;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -EIO;
-#endif
-
+ }
return 0;
}
@@ -205,7 +188,7 @@ static int __init snd_gusextreme_probe(int dev)
xgf1_irq = gf1_irq[dev];
if (xgf1_irq == SNDRV_AUTO_IRQ) {
if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
- snd_printk("unable to find a free IRQ for GF1\n");
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
err = -EBUSY;
goto out;
}
@@ -213,7 +196,7 @@ static int __init snd_gusextreme_probe(int dev)
xess_irq = irq[dev];
if (xess_irq == SNDRV_AUTO_IRQ) {
if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
- snd_printk("unable to find a free IRQ for ES1688\n");
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
err = -EBUSY;
goto out;
}
@@ -226,7 +209,7 @@ static int __init snd_gusextreme_probe(int dev)
xgf1_dma = dma1[dev];
if (xgf1_dma == SNDRV_AUTO_DMA) {
if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
- snd_printk("unable to find a free DMA for GF1\n");
+ snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
err = -EBUSY;
goto out;
}
@@ -234,7 +217,7 @@ static int __init snd_gusextreme_probe(int dev)
xess_dma = dma8[dev];
if (xess_dma == SNDRV_AUTO_DMA) {
if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
- snd_printk("unable to find a free DMA for ES1688\n");
+ snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
err = -EBUSY;
goto out;
}
@@ -264,7 +247,7 @@ static int __init snd_gusextreme_probe(int dev)
goto out;
if (!gus->ess_flag) {
- snd_printdd("GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
+ snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
err = -ENODEV;
goto out;
}
@@ -287,7 +270,7 @@ static int __init snd_gusextreme_probe(int dev)
if (snd_opl3_create(card, es1688->port, es1688->port + 2,
OPL3_HW_OPL3, 0, &opl3) < 0) {
- printk(KERN_ERR "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
+ printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
} else {
if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
goto out;
@@ -303,6 +286,10 @@ static int __init snd_gusextreme_probe(int dev)
sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto out;
+
if ((err = snd_card_register(card)) < 0)
goto out;
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 400ff34710fb..0bb44b519340 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -82,39 +82,25 @@ struct snd_gusmax {
static snd_card_t *snd_gusmax_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+#define PFX "gusmax: "
static int __init snd_gusmax_detect(snd_gus_card_t * gus)
{
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- unsigned char d;
+ unsigned char d;
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+ snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
-#endif
+ }
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- unsigned char d;
-
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
-#endif
+ }
+
return 0;
}
@@ -239,25 +225,25 @@ static int __init snd_gusmax_probe(int dev)
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free IRQ\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma1 = dma1[dev];
if (xdma1 == SNDRV_AUTO_DMA) {
if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA1\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma2 = dma2[dev];
if (xdma2 == SNDRV_AUTO_DMA) {
if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA2\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+ err = -EBUSY;
+ goto _err;
}
}
@@ -266,31 +252,28 @@ static int __init snd_gusmax_probe(int dev)
-xirq, xdma1, xdma2,
0, channels[dev],
pcm_channels[dev],
- 0, &gus)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_gusmax_detect(gus)) < 0) {
- snd_card_free(card);
- return err;
- }
+ 0, &gus)) < 0)
+ goto _err;
+
+ if ((err = snd_gusmax_detect(gus)) < 0)
+ goto _err;
+
maxcard->gus_status_reg = gus->gf1.reg_irqstat;
maxcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
snd_gusmax_init(dev, card, gus);
- if ((err = snd_gus_initialize(gus)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_gus_initialize(gus)) < 0)
+ goto _err;
+
if (!gus->max_flag) {
- printk(KERN_ERR "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
- snd_card_free(card);
- return -ENODEV;
+ snd_printk(KERN_ERR PFX "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
+ err = -ENODEV;
+ goto _err;
}
if (request_irq(xirq, snd_gusmax_interrupt, SA_INTERRUPT, "GUS MAX", (void *)maxcard)) {
- snd_card_free(card);
- printk(KERN_ERR "gusmax: unable to grab IRQ %d\n", xirq);
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
+ err = -EBUSY;
+ goto _err;
}
maxcard->irq = xirq;
@@ -301,50 +284,46 @@ static int __init snd_gusmax_probe(int dev)
CS4231_HWSHARE_IRQ |
CS4231_HWSHARE_DMA1 |
CS4231_HWSHARE_DMA2,
- &cs4231)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_mixer(cs4231)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &cs4231)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_mixer(cs4231)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0)
+ goto _err;
+
if (pcm_channels[dev] > 0) {
- if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- }
- if ((err = snd_gusmax_mixer(cs4231)) < 0) {
- snd_card_free(card);
- return err;
+ if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+ goto _err;
}
+ if ((err = snd_gusmax_mixer(cs4231)) < 0)
+ goto _err;
- if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+ goto _err;
sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1);
if (xdma2 >= 0)
sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
maxcard->gus = gus;
maxcard->cs4231 = cs4231;
snd_gusmax_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init snd_gusmax_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 46e867daba6a..358cba9d738f 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -73,6 +73,12 @@ static int midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
static int effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+#ifdef SNDRV_STB
+#define PFX "interwave-stb: "
+#else
+#define PFX "interwave: "
+#endif
+
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for InterWave soundcard.");
module_param_array(id, charp, NULL, 0444);
@@ -249,38 +255,20 @@ static int __devinit snd_interwave_detect(struct snd_interwave *iwcard,
{
unsigned long flags;
unsigned char rev1, rev2;
+ int d;
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- int d;
-
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
-#endif
+ }
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
- {
- int d;
-
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- }
-#else
- if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
-#endif
-
+ }
spin_lock_irqsave(&gus->reg_lock, flags);
rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
@@ -686,35 +674,33 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
card->private_free = snd_interwave_free;
#ifdef CONFIG_PNP
if (isapnp[dev]) {
- if (snd_interwave_pnp(dev, iwcard, pcard, pid)) {
- snd_card_free(card);
- return -ENODEV;
- }
+ if ((err = snd_interwave_pnp(dev, iwcard, pcard, pid)) < 0)
+ goto _err;
snd_card_set_dev(card, &pcard->card->dev);
}
#endif
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free IRQ\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma1 = dma1[dev];
if (xdma1 == SNDRV_AUTO_DMA) {
if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA1\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma2 = dma2[dev];
if (xdma2 == SNDRV_AUTO_DMA) {
if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA2\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+ err = -EBUSY;
+ goto _err;
}
}
@@ -722,32 +708,28 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
port[dev],
-xirq, xdma1, xdma2,
0, 32,
- pcm_channels[dev], effect[dev], &gus)) < 0) {
- snd_card_free(card);
- return err;
- }
+ pcm_channels[dev], effect[dev], &gus)) < 0)
+ goto _err;
+
if ((err = snd_interwave_detect(iwcard, gus, dev
#ifdef SNDRV_STB
, &i2c_bus
#endif
- )) < 0) {
- snd_card_free(card);
- return err;
- }
+ )) < 0)
+ goto _err;
+
iwcard->gus_status_reg = gus->gf1.reg_irqstat;
iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
snd_interwave_init(dev, gus);
snd_interwave_detect_memory(gus);
- if ((err = snd_gus_initialize(gus)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_gus_initialize(gus)) < 0)
+ goto _err;
if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, "InterWave", (void *)iwcard)) {
- snd_card_free(card);
- snd_printk("unable to grab IRQ %d\n", xirq);
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
+ err = -EBUSY;
+ goto _err;
}
iwcard->irq = xirq;
@@ -758,34 +740,28 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
CS4231_HWSHARE_IRQ |
CS4231_HWSHARE_DMA1 |
CS4231_HWSHARE_DMA2,
- &cs4231)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &cs4231)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0)
+ goto _err;
+
sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
strcat(pcm->name, " (codec)");
- if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4231_mixer(cs4231)) < 0) {
- snd_card_free(card);
- return err;
- }
+
+ if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0)
+ goto _err;
+
+ if ((err = snd_cs4231_mixer(cs4231)) < 0)
+ goto _err;
+
if (pcm_channels[dev] > 0) {
- if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- }
- if ((err = snd_interwave_mixer(cs4231)) < 0) {
- snd_card_free(card);
- return err;
+ if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+ goto _err;
}
+ if ((err = snd_interwave_mixer(cs4231)) < 0)
+ goto _err;
+
#ifdef SNDRV_STB
{
snd_ctl_elem_id_t id1, id2;
@@ -795,28 +771,20 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
strcpy(id1.name, "Master Playback Switch");
strcpy(id2.name, id1.name);
id2.index = 1;
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ goto _err;
strcpy(id1.name, "Master Playback Volume");
strcpy(id2.name, id1.name);
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ goto _err;
+ if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)
+ goto _err;
}
#endif
gus->uart_enable = midi[dev];
- if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+ goto _err;
#ifndef SNDRV_STB
str = "AMD InterWave";
@@ -835,10 +803,11 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
if (xdma2 >= 0)
sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
iwcard->cs4231 = cs4231;
iwcard->gus = gus;
@@ -847,6 +816,10 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
else
snd_interwave_legacy[dev++] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __devinit snd_interwave_probe_legacy_port(unsigned long xport)
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 75bd6eca63e7..4ba268f251e3 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -143,6 +143,8 @@ struct snd_opl3sa2 {
static snd_card_t *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+#define PFX "opl3sa2: "
+
#ifdef CONFIG_PNP
static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = {
@@ -231,7 +233,7 @@ static int __init snd_opl3sa2_detect(opl3sa2_t *chip)
card = chip->card;
port = chip->port;
if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) {
- snd_printk(KERN_ERR "opl3sa2: can't grab port 0x%lx\n", port);
+ snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
return -EBUSY;
}
// snd_printk("REG 0A = 0x%x\n", snd_opl3sa2_read(chip, 0x0a));
@@ -668,6 +670,12 @@ static int snd_opl3sa2_dev_free(snd_device_t *device)
return snd_opl3sa2_free(chip);
}
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev) isapnp[dev]
+#else
+#define is_isapnp_selected(dev) 0
+#endif
+
static int __devinit snd_opl3sa2_probe(int dev,
struct pnp_dev *pdev,
struct pnp_card_link *pcard,
@@ -683,34 +691,31 @@ static int __devinit snd_opl3sa2_probe(int dev,
};
int err;
-#ifdef CONFIG_PNP
- if (!isapnp[dev]) {
-#endif
+ if (! is_isapnp_selected(dev)) {
if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify port\n");
+ snd_printk(KERN_ERR PFX "specify port\n");
return -EINVAL;
}
if (wss_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify wss_port\n");
+ snd_printk(KERN_ERR PFX "specify wss_port\n");
return -EINVAL;
}
if (fm_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify fm_port\n");
+ snd_printk(KERN_ERR PFX "specify fm_port\n");
return -EINVAL;
}
if (midi_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify midi_port\n");
+ snd_printk(KERN_ERR PFX "specify midi_port\n");
return -EINVAL;
}
-#ifdef CONFIG_PNP
}
-#endif
+
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
strcpy(card->driver, "OPL3SA2");
strcpy(card->shortname, "Yamaha OPL3-SA2");
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
err = -ENOMEM;
goto __error;
@@ -742,7 +747,7 @@ static int __devinit snd_opl3sa2_probe(int dev,
if ((err = snd_opl3sa2_detect(chip)) < 0)
goto __error;
if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", (void *)chip)) {
- snd_printk(KERN_ERR "opl3sa2: can't grab IRQ %d\n", xirq);
+ snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
err = -ENODEV;
goto __error;
}
@@ -795,6 +800,9 @@ static int __devinit snd_opl3sa2_probe(int dev,
if (dma2 >= 0)
sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto __error;
+
if ((err = snd_card_register(card)) < 0)
goto __error;
@@ -852,8 +860,10 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *card,
int res;
for ( ; dev < SNDRV_CARDS; dev++) {
- if (!enable[dev] || !isapnp[dev])
- continue;
+ if (!enable[dev])
+ continue;
+ if (is_isapnp_selected(dev))
+ continue;
res = snd_opl3sa2_probe(dev, NULL, card, id);
if (res < 0)
return res;
@@ -904,6 +914,7 @@ static int __init alsa_card_opl3sa2_init(void)
#endif
#ifdef CONFIG_PNP
pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+ pnp_unregister_driver(&opl3sa2_pnp_driver);
#endif
return -ENODEV;
}
@@ -917,6 +928,7 @@ static void __exit alsa_card_opl3sa2_exit(void)
#ifdef CONFIG_PNP
/* PnP cards first */
pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+ pnp_unregister_driver(&opl3sa2_pnp_driver);
#endif
for (idx = 0; idx < SNDRV_CARDS; idx++)
snd_card_free(snd_opl3sa2_legacy[idx]);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 411a702d85ba..73573cb1db6a 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1038,8 +1038,7 @@ static int snd_opti93x_capture_prepare(snd_pcm_substream_t *substream)
chip->c_dma_size = size;
snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF,
- OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO,
- (unsigned char)~(OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO));
+ OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO, 0);
snd_dma_program(chip->dma2, runtime->dma_addr, size,
DMA_MODE_READ | DMA_AUTOINIT);
@@ -1274,7 +1273,7 @@ static int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
opti93x_t *codec;
*rcodec = NULL;
- codec = kcalloc(1, sizeof(*codec), GFP_KERNEL);
+ codec = kzalloc(sizeof(*codec), GFP_KERNEL);
if (codec == NULL)
return -ENOMEM;
codec->irq = -1;
@@ -1895,8 +1894,8 @@ static void snd_card_opti9xx_free(snd_card_t *card)
}
}
-static int __devinit snd_card_opti9xx_probe(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
+static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
+ const struct pnp_card_device_id *pid)
{
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
static long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
@@ -1966,6 +1965,10 @@ static int __devinit snd_card_opti9xx_probe(struct pnp_card_link *pcard,
snd_card_free(card);
return error;
}
+ if ((error = snd_card_set_generic_dev(card)) < 0) {
+ snd_card_free(card);
+ return error;
+ }
#ifdef CONFIG_PNP
}
#endif /* CONFIG_PNP */
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 028af4066595..5375705c054b 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -1097,7 +1097,7 @@ snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_d
if (seq_ports <= 0)
return 0;
- hw = kcalloc(1, sizeof(*hw), GFP_KERNEL);
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (hw == NULL)
return -ENOMEM;
spin_lock_init(&hw->reg_lock);
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index db5eb8b55058..0209790dc4b5 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -233,7 +233,7 @@ static int emu8k_pcm_open(snd_pcm_substream_t *subs)
emu8k_pcm_t *rec;
snd_pcm_runtime_t *runtime = subs->runtime;
- rec = kcalloc(1, sizeof(*rec), GFP_KERNEL);
+ rec = kzalloc(sizeof(*rec), GFP_KERNEL);
if (! rec)
return -ENOMEM;
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 60e2c53c49fc..7888783d68f5 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -351,6 +351,12 @@ static void snd_sb16_free(snd_card_t *card)
}
}
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev) isapnp[dev]
+#else
+#define is_isapnp_selected(dev) 0
+#endif
+
static int __init snd_sb16_probe(int dev,
struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
@@ -378,10 +384,8 @@ static int __init snd_sb16_probe(int dev,
card->private_free = snd_sb16_free;
#ifdef CONFIG_PNP
if (isapnp[dev]) {
- if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid))) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid)))
+ goto _err;
snd_card_set_dev(card, &pcard->card->dev);
}
#endif
@@ -389,41 +393,37 @@ static int __init snd_sb16_probe(int dev,
xirq = irq[dev];
xdma8 = dma8[dev];
xdma16 = dma16[dev];
-#ifdef CONFIG_PNP
- if (!isapnp[dev]) {
-#endif
- if (xirq == SNDRV_AUTO_IRQ) {
- if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- return -EBUSY;
+ if (! is_isapnp_selected(dev)) {
+ if (xirq == SNDRV_AUTO_IRQ) {
+ if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
+ }
}
- }
- if (xdma8 == SNDRV_AUTO_DMA) {
- if ((xdma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
- return -EBUSY;
+ if (xdma8 == SNDRV_AUTO_DMA) {
+ if ((xdma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
+ snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
+ err = -EBUSY;
+ goto _err;
+ }
}
- }
- if (xdma16 == SNDRV_AUTO_DMA) {
- if ((xdma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
- return -EBUSY;
+ if (xdma16 == SNDRV_AUTO_DMA) {
+ if ((xdma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
+ snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
+ err = -EBUSY;
+ goto _err;
+ }
}
- }
- /* non-PnP FM port address is hardwired with base port address */
- fm_port[dev] = port[dev];
- /* block the 0x388 port to avoid PnP conflicts */
- acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
+ /* non-PnP FM port address is hardwired with base port address */
+ fm_port[dev] = port[dev];
+ /* block the 0x388 port to avoid PnP conflicts */
+ acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
#ifdef SNDRV_SBAWE_EMU8000
- /* non-PnP AWE port address is hardwired with base port address */
- awe_port[dev] = port[dev] + 0x400;
+ /* non-PnP AWE port address is hardwired with base port address */
+ awe_port[dev] = port[dev] + 0x400;
#endif
-#ifdef CONFIG_PNP
}
-#endif
if ((err = snd_sbdsp_create(card,
port[dev],
@@ -432,28 +432,20 @@ static int __init snd_sb16_probe(int dev,
xdma8,
xdma16,
SB_HW_AUTO,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &chip)) < 0)
+ goto _err;
+
if (chip->hardware != SB_HW_16) {
- snd_card_free(card);
- snd_printdd("SB 16 chip was not detected at 0x%lx\n", port[dev]);
- return -ENODEV;
+ snd_printk(KERN_ERR PFX "SB 16 chip was not detected at 0x%lx\n", port[dev]);
+ err = -ENODEV;
+ goto _err;
}
chip->mpu_port = mpu_port[dev];
-#ifdef CONFIG_PNP
- if (!isapnp[dev] && (err = snd_sb16dsp_configure(chip)) < 0) {
-#else
- if ((err = snd_sb16dsp_configure(chip)) < 0) {
-#endif
- snd_card_free(card);
- return -ENXIO;
- }
- if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return -ENXIO;
- }
+ if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0)
+ goto _err;
+
+ if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0)
+ goto _err;
strcpy(card->driver,
#ifdef SNDRV_SBAWE_EMU8000
@@ -474,10 +466,8 @@ static int __init snd_sb16_probe(int dev,
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
chip->mpu_port, 0,
- xirq, 0, &chip->rmidi)) < 0) {
- snd_card_free(card);
- return -ENXIO;
- }
+ xirq, 0, &chip->rmidi)) < 0)
+ goto _err;
chip->rmidi_callback = snd_mpu401_uart_interrupt;
}
@@ -499,17 +489,13 @@ static int __init snd_sb16_probe(int dev,
#else
int seqdev = 1;
#endif
- if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0) {
- snd_card_free(card);
- return -ENXIO;
- }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0)
+ goto _err;
}
}
- if ((err = snd_sbmixer_new(chip)) < 0) {
- snd_card_free(card);
- return -ENXIO;
- }
+ if ((err = snd_sbmixer_new(chip)) < 0)
+ goto _err;
#ifdef CONFIG_SND_SB16_CSP
/* CSP chip on SB16ASP/AWE32 */
@@ -525,11 +511,11 @@ static int __init snd_sb16_probe(int dev,
#endif
#ifdef SNDRV_SBAWE_EMU8000
if (awe_port[dev] > 0) {
- if (snd_emu8000_new(card, 1, awe_port[dev],
- seq_ports[dev], NULL) < 0) {
+ if ((err = snd_emu8000_new(card, 1, awe_port[dev],
+ seq_ports[dev], NULL)) < 0) {
snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]);
- snd_card_free(card);
- return -ENXIO;
+
+ goto _err;
}
}
#endif
@@ -541,15 +527,21 @@ static int __init snd_sb16_probe(int dev,
(mic_agc[dev] ? 0x00 : 0x01));
spin_unlock_irqrestore(&chip->mixer_lock, flags);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
if (pcard)
pnp_set_card_drvdata(pcard, card);
else
snd_sb16_legacy[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init snd_sb16_probe_legacy_port(unsigned long xport)
@@ -560,10 +552,8 @@ static int __init snd_sb16_probe_legacy_port(unsigned long xport)
for ( ; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
continue;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
+ if (is_isapnp_selected(dev))
continue;
-#endif
port[dev] = xport;
res = snd_sb16_probe(dev, NULL, NULL);
if (res < 0)
@@ -621,10 +611,8 @@ static int __init alsa_card_sb16_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
continue;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
+ if (is_isapnp_selected(dev))
continue;
-#endif
if (!snd_sb16_probe(dev, NULL, NULL)) {
cards++;
continue;
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index b62920eead3d..7192d4c758e6 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -42,8 +42,6 @@ MODULE_LICENSE("GPL");
#else
#define CSP_HDR_VALUE(a,b,c,d) ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24))
#endif
-#define LE_SHORT(v) le16_to_cpu(v)
-#define LE_INT(v) le32_to_cpu(v)
#define RIFF_HEADER CSP_HDR_VALUE('R', 'I', 'F', 'F')
#define CSP__HEADER CSP_HDR_VALUE('C', 'S', 'P', ' ')
@@ -56,20 +54,20 @@ MODULE_LICENSE("GPL");
/*
* RIFF data format
*/
-typedef struct riff_header {
+struct riff_header {
__u32 name;
__u32 len;
-} riff_header_t;
+};
-typedef struct desc_header {
- riff_header_t info;
+struct desc_header {
+ struct riff_header info;
__u16 func_nr;
__u16 VOC_type;
__u16 flags_play_rec;
__u16 flags_16bit_8bit;
__u16 flags_stereo_mono;
__u16 flags_rates;
-} desc_header_t;
+};
/*
* prototypes
@@ -124,7 +122,7 @@ int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep)
if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0)
return err;
- if ((p = kcalloc(1, sizeof(*p), GFP_KERNEL)) == NULL) {
+ if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
snd_device_free(chip->card, hw);
return -ENOMEM;
}
@@ -302,9 +300,9 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
unsigned char __user *data_end;
unsigned short func_nr = 0;
- riff_header_t file_h, item_h, code_h;
+ struct riff_header file_h, item_h, code_h;
__u32 item_type;
- desc_header_t funcdesc_h;
+ struct desc_header funcdesc_h;
unsigned long flags;
int err;
@@ -316,12 +314,12 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
if (copy_from_user(&file_h, data_ptr, sizeof(file_h)))
return -EFAULT;
if ((file_h.name != RIFF_HEADER) ||
- (LE_INT(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) {
+ (le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) {
snd_printd("%s: Invalid RIFF header\n", __FUNCTION__);
return -EINVAL;
}
data_ptr += sizeof(file_h);
- data_end = data_ptr + LE_INT(file_h.len);
+ data_end = data_ptr + le32_to_cpu(file_h.len);
if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
return -EFAULT;
@@ -331,7 +329,7 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
}
data_ptr += sizeof (item_type);
- for (; data_ptr < data_end; data_ptr += LE_INT(item_h.len)) {
+ for (; data_ptr < data_end; data_ptr += le32_to_cpu(item_h.len)) {
if (copy_from_user(&item_h, data_ptr, sizeof(item_h)))
return -EFAULT;
data_ptr += sizeof(item_h);
@@ -344,7 +342,7 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
case FUNC_HEADER:
if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h)))
return -EFAULT;
- func_nr = LE_SHORT(funcdesc_h.func_nr);
+ func_nr = le16_to_cpu(funcdesc_h.func_nr);
break;
case CODE_HEADER:
if (func_nr != info.func_req)
@@ -370,11 +368,11 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
if (code_h.name != INIT_HEADER)
break;
data_ptr += sizeof(code_h);
- err = snd_sb_csp_load_user(p, data_ptr, LE_INT(code_h.len),
+ err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len),
SNDRV_SB_CSP_LOAD_INITBLOCK);
if (err)
return err;
- data_ptr += LE_INT(code_h.len);
+ data_ptr += le32_to_cpu(code_h.len);
}
/* main microcode block */
if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
@@ -386,17 +384,17 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
}
data_ptr += sizeof(code_h);
err = snd_sb_csp_load_user(p, data_ptr,
- LE_INT(code_h.len), 0);
+ le32_to_cpu(code_h.len), 0);
if (err)
return err;
/* fill in codec header */
strlcpy(p->codec_name, info.codec_name, sizeof(p->codec_name));
p->func_nr = func_nr;
- p->mode = LE_SHORT(funcdesc_h.flags_play_rec);
- switch (LE_SHORT(funcdesc_h.VOC_type)) {
+ p->mode = le16_to_cpu(funcdesc_h.flags_play_rec);
+ switch (le16_to_cpu(funcdesc_h.VOC_type)) {
case 0x0001: /* QSound decoder */
- if (LE_SHORT(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) {
+ if (le16_to_cpu(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) {
if (snd_sb_qsound_build(p) == 0)
/* set QSound flag and clear all other mode flags */
p->mode = SNDRV_SB_CSP_MODE_QSOUND;
@@ -426,12 +424,12 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user
p->mode = 0;
snd_printd("%s: Unsupported CSP codec type: 0x%04x\n",
__FUNCTION__,
- LE_SHORT(funcdesc_h.VOC_type));
+ le16_to_cpu(funcdesc_h.VOC_type));
return -EINVAL;
}
- p->acc_channels = LE_SHORT(funcdesc_h.flags_stereo_mono);
- p->acc_width = LE_SHORT(funcdesc_h.flags_16bit_8bit);
- p->acc_rates = LE_SHORT(funcdesc_h.flags_rates);
+ p->acc_channels = le16_to_cpu(funcdesc_h.flags_stereo_mono);
+ p->acc_width = le16_to_cpu(funcdesc_h.flags_16bit_8bit);
+ p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates);
/* Decouple CSP from IRQ and DMAREQ lines */
spin_lock_irqsave(&p->chip->reg_lock, flags);
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index e2cbc4202b3d..c41ac25e85ca 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -107,54 +107,47 @@ static int __init snd_sb8_probe(int dev)
dma8[dev],
-1,
SB_HW_AUTO,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ &chip)) < 0)
+ goto _err;
+
if (chip->hardware >= SB_HW_16) {
- snd_card_free(card);
if (chip->hardware == SB_HW_ALS100)
- snd_printdd("ALS100 chip detected at 0x%lx, try snd-als100 module\n",
+ snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n",
port[dev]);
else
- snd_printdd("SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
- port[dev]);
- return -ENODEV;
+ snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
+ port[dev]);
+ err = -ENODEV;
+ goto _err;
}
- if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_sbmixer_new(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0)
+ goto _err;
+
+ if ((err = snd_sbmixer_new(chip)) < 0)
+ goto _err;
+
if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
if ((err = snd_opl3_create(card, chip->port + 8, 0,
OPL3_HW_AUTO, 1,
&opl3)) < 0) {
- snd_printk(KERN_ERR "sb8: no OPL device at 0x%lx\n", chip->port + 8);
+ snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8);
}
} else {
if ((err = snd_opl3_create(card, chip->port, chip->port + 2,
OPL3_HW_AUTO, 1,
&opl3)) < 0) {
- snd_printk(KERN_ERR "sb8: no OPL device at 0x%lx-0x%lx\n",
+ snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n",
chip->port, chip->port + 2);
}
}
if (err >= 0) {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+ goto _err;
}
- if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0)
+ goto _err;
strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
strcpy(card->shortname, chip->name);
@@ -162,12 +155,19 @@ static int __init snd_sb8_probe(int dev)
chip->name,
chip->port,
irq[dev], dma8[dev]);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
snd_sb8_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init snd_card_sb8_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 5b6bde213ea0..f0f205ae425f 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -221,7 +221,7 @@ int snd_sbdsp_create(snd_card_t *card,
snd_assert(r_chip != NULL, return -EINVAL);
*r_chip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index 17f585b0ddc1..52f2294da62b 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -67,6 +67,8 @@ MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
static snd_card_t *snd_sgalaxy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+#define PFX "sgalaxy: "
+
/*
*/
@@ -135,7 +137,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
}
#if 0
- snd_printdd("sgalaxy - setting up IRQ/DMA for WSS\n");
+ snd_printdd(PFX "setting up IRQ/DMA for WSS\n");
#endif
/* initialize IRQ for WSS codec */
@@ -160,7 +162,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
{
#if 0
- snd_printdd("sgalaxy - switching to WSS mode\n");
+ snd_printdd(PFX "switching to WSS mode\n");
#endif
/* switch to WSS mode */
@@ -223,11 +225,11 @@ static int __init snd_sgalaxy_probe(int dev)
ad1848_t *chip;
if (sbport[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify SB port\n");
+ snd_printk(KERN_ERR PFX "specify SB port\n");
return -EINVAL;
}
if (wssport[dev] == SNDRV_AUTO_PORT) {
- snd_printk("specify WSS port\n");
+ snd_printk(KERN_ERR PFX "specify WSS port\n");
return -EINVAL;
}
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -237,46 +239,39 @@ static int __init snd_sgalaxy_probe(int dev)
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free IRQ\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto _err;
}
}
xdma1 = dma1[dev];
if (xdma1 == SNDRV_AUTO_DMA) {
if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_card_free(card);
- snd_printk("unable to find a free DMA\n");
- return -EBUSY;
+ snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
+ err = -EBUSY;
+ goto _err;
}
}
- if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0)
+ goto _err;
if ((err = snd_ad1848_create(card, wssport[dev] + 4,
xirq, xdma1,
- AD1848_HW_DETECT, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
+ AD1848_HW_DETECT, &chip)) < 0)
+ goto _err;
if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) {
- snd_printdd("sgalaxy - error creating new ad1848 PCM device\n");
- snd_card_free(card);
- return err;
+ snd_printdd(PFX "error creating new ad1848 PCM device\n");
+ goto _err;
}
if ((err = snd_ad1848_mixer(chip)) < 0) {
- snd_printdd("sgalaxy - error creating new ad1848 mixer\n");
- snd_card_free(card);
- return err;
+ snd_printdd(PFX "error creating new ad1848 mixer\n");
+ goto _err;
}
- if (snd_sgalaxy_mixer(chip) < 0) {
- snd_printdd("sgalaxy - the mixer rewrite failed\n");
- snd_card_free(card);
- return err;
+ if ((err = snd_sgalaxy_mixer(chip)) < 0) {
+ snd_printdd(PFX "the mixer rewrite failed\n");
+ goto _err;
}
strcpy(card->driver, "Sound Galaxy");
@@ -284,12 +279,18 @@ static int __init snd_sgalaxy_probe(int dev)
sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
wssport[dev], xirq, xdma1);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
+
snd_sgalaxy_cards[dev] = card;
return 0;
+
+ _err:
+ snd_card_free(card);
+ return err;
}
static int __init alsa_card_sgalaxy_init(void)
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 3959ed694eec..9f6b58c79209 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -1262,11 +1262,6 @@ static int __devinit create_sscape(const struct params *params, snd_card_t **rca
*/
sscape_write(sscape, GA_INTENA_REG, 0x80);
- if ((err = snd_card_register(card)) < 0) {
- printk(KERN_ERR "sscape: Failed to register sound card\n");
- goto _release_card;
- }
-
/*
* Initialize mixer
*/
@@ -1396,6 +1391,13 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
if (ret < 0)
return ret;
snd_card_set_dev(card, &pcard->card->dev);
+
+ if ((ret = snd_card_register(card)) < 0) {
+ printk(KERN_ERR "sscape: Failed to register sound card\n");
+ snd_card_free(card);
+ return ret;
+ }
+
pnp_set_card_drvdata(pcard, card);
++sscape_cards;
++idx;
@@ -1460,6 +1462,16 @@ static int __init sscape_manual_probe(struct params *params)
if (ret < 0)
return ret;
+ if ((ret = snd_card_set_generic_dev(card)) < 0) {
+ snd_card_free(card);
+ return ret;
+ }
+ if ((ret = snd_card_register(card)) < 0) {
+ printk(KERN_ERR "sscape: Failed to register sound card\n");
+ snd_card_free(card);
+ return ret;
+ }
+
sscape_card[sscape_cards] = card;
params++;
sscape_cards++;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 79b022070ba3..0a572e0a47e6 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -622,6 +622,11 @@ snd_wavefront_probe (int dev, struct pnp_card_link *pcard,
ics2115_port[dev],
ics2115_irq[dev]);
+ if ((err = snd_card_set_generic_dev(card)) < 0) {
+ snd_card_free(card);
+ return err;
+ }
+
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
return err;
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig
index 531f8ba96a71..2433b7727404 100644
--- a/sound/mips/Kconfig
+++ b/sound/mips/Kconfig
@@ -8,6 +8,7 @@ config SND_AU1X00
depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND
select SND_PCM
select SND_AC97_CODEC
+ select SND_GENERIC_DRIVER
help
ALSA Sound driver for the Au1x00's AC97 port.
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index c20522b02134..3f9684f1d1d2 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -667,6 +667,11 @@ au1000_init(void)
strcpy(au1000->card->shortname, "Au1000-AC97");
sprintf(au1000->card->longname, "AMD Au1000--AC97 ALSA Driver");
+ if ((err = snd_card_set_generic_dev(au1000->card)) < 0) {
+ snd_card_free(au1000->card);
+ return err;
+ }
+
if ((err = snd_card_register(au1000->card)) < 0) {
snd_card_free(au1000->card);
return err;
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c
index 4491733c9e4e..2c2ae2ee01ac 100644
--- a/sound/oss/au1000.c
+++ b/sound/oss/au1000.c
@@ -1295,7 +1295,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long size;
int ret = 0;
- dbg(__FUNCTION__);
+ dbg("%s", __FUNCTION__);
lock_kernel();
down(&s->sem);
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 9a2f50f0b184..222014cafc1a 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -116,7 +116,7 @@ typedef struct {
const char *name;
const char *name2;
struct module *owner;
- void *(*dma_alloc)(unsigned int, int);
+ void *(*dma_alloc)(unsigned int, gfp_t);
void (*dma_free)(void *, unsigned int);
int (*irqinit)(void);
#ifdef MODULE
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 8daaf87664ba..59eb53f89318 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -114,7 +114,7 @@ static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
/*** Low level stuff *********************************************************/
-static void *AtaAlloc(unsigned int size, int flags);
+static void *AtaAlloc(unsigned int size, gfp_t flags);
static void AtaFree(void *, unsigned int size);
static int AtaIrqInit(void);
#ifdef MODULE
@@ -810,7 +810,7 @@ static TRANS transFalconExpanding = {
* Atari (TT/Falcon)
*/
-static void *AtaAlloc(unsigned int size, int flags)
+static void *AtaAlloc(unsigned int size, gfp_t flags)
{
return atari_stram_alloc(size, "dmasound");
}
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 2ceb46f1d40f..b2bf8bac842d 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -271,7 +271,7 @@ int expand_read_bal; /* Balance factor for expanding reads (not volume!) */
/*** Low level stuff *********************************************************/
-static void *PMacAlloc(unsigned int size, int flags);
+static void *PMacAlloc(unsigned int size, gfp_t flags);
static void PMacFree(void *ptr, unsigned int size);
static int PMacIrqInit(void);
#ifdef MODULE
@@ -614,7 +614,7 @@ tas_init_frame_rates(unsigned int *prop, unsigned int l)
/*
* PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
*/
-static void *PMacAlloc(unsigned int size, int flags)
+static void *PMacAlloc(unsigned int size, gfp_t flags)
{
return kmalloc(size, flags);
}
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 558db5311e06..d59f60b26410 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -69,7 +69,7 @@ static int write_sq_block_size_half, write_sq_block_size_quarter;
/*** Low level stuff *********************************************************/
-static void *AmiAlloc(unsigned int size, int flags);
+static void *AmiAlloc(unsigned int size, gfp_t flags);
static void AmiFree(void *obj, unsigned int size);
static int AmiIrqInit(void);
#ifdef MODULE
@@ -317,7 +317,7 @@ static inline void StopDMA(void)
enable_heartbeat();
}
-static void *AmiAlloc(unsigned int size, int flags)
+static void *AmiAlloc(unsigned int size, gfp_t flags)
{
return amiga_chip_alloc((long)size, "dmasound [Paula]");
}
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 92c25a0174db..1ddaa6284b08 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -36,7 +36,7 @@ static int expand_data; /* Data for expanding */
/*** Low level stuff *********************************************************/
-static void *Q40Alloc(unsigned int size, int flags);
+static void *Q40Alloc(unsigned int size, gfp_t flags);
static void Q40Free(void *, unsigned int);
static int Q40IrqInit(void);
#ifdef MODULE
@@ -358,7 +358,7 @@ static TRANS transQ40Compressing = {
/*** Low level stuff *********************************************************/
-static void *Q40Alloc(unsigned int size, int flags)
+static void *Q40Alloc(unsigned int size, gfp_t flags)
{
return kmalloc(size, flags); /* change to vmalloc */
}
diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c
index 58f879fda975..26e5944b6ba8 100644
--- a/sound/oss/ite8172.c
+++ b/sound/oss/ite8172.c
@@ -1859,7 +1859,7 @@ static int it8172_release(struct inode *inode, struct file *file)
struct it8172_state *s = (struct it8172_state *)file->private_data;
#ifdef IT8172_VERBOSE_DEBUG
- dbg(__FUNCTION__);
+ dbg("%s", __FUNCTION__);
#endif
lock_kernel();
if (file->f_mode & FMODE_WRITE)
diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c
index b2676fa34630..6982556ded56 100644
--- a/sound/oss/midibuf.c
+++ b/sound/oss/midibuf.c
@@ -50,7 +50,7 @@ static struct midi_parms parms[MAX_MIDI_DEV];
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/skeleton.c b/sound/oss/skeleton.c
deleted file mode 100644
index 8fea783dd0cb..000000000000
--- a/sound/oss/skeleton.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * PCI sound skeleton example
- *
- * (c) 1998 Red Hat Software
- *
- * This software may be used and distributed according to the
- * terms of the GNU General Public License, incorporated herein by
- * reference.
- *
- * This example is designed to be built in the linux/drivers/sound
- * directory as part of a kernel build. The example is modular only
- * drop me a note once you have a working modular driver and want
- * to integrate it with the main code.
- * -- Alan <alan@redhat.com>
- *
- * This is a first draft. Please report any errors, corrections or
- * improvements to me.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-
-#include <asm/io.h>
-
-#include "sound_config.h"
-
-/*
- * Define our PCI vendor ID here
- */
-
-#ifndef PCI_VENDOR_MYIDENT
-#define PCI_VENDOR_MYIDENT 0x125D
-
-/*
- * PCI identity for the card.
- */
-
-#define PCI_DEVICE_ID_MYIDENT_MYCARD1 0x1969
-#endif
-
-#define CARD_NAME "ExampleWave 3D Pro Ultra ThingyWotsit"
-
-#define MAX_CARDS 8
-
-/*
- * Each address_info object holds the information about one of
- * our card resources. In this case the MSS emulation of our
- * ficticious card. Its used to manage and attach things.
- */
-
-static struct address_info mss_data[MAX_CARDS];
-static int cards;
-
-/*
- * Install the actual card. This is an example
- */
-
-static int mycard_install(struct pci_dev *pcidev)
-{
- int iobase;
- int mssbase;
- int mpubase;
- u8 x;
- u16 w;
- u32 v;
- int i;
- int dma;
-
- /*
- * Our imaginary code has its I/O on PCI address 0, a
- * MSS on PCI address 1 and an MPU on address 2
- *
- * For the example we will only initialise the MSS
- */
-
- iobase = pci_resource_start(pcidev, 0);
- mssbase = pci_resource_start(pcidev, 1);
- mpubase = pci_resource_start(pcidev, 2);
-
- /*
- * Reset the board
- */
-
- /*
- * Wait for completion. udelay() waits in microseconds
- */
-
- udelay(100);
-
- /*
- * Ok card ready. Begin setup proper. You might for example
- * load the firmware here
- */
-
- dma = card_specific_magic(ioaddr);
-
- /*
- * Turn on legacy mode (example), There are also byte and
- * dword (32bit) PCI configuration function calls
- */
-
- pci_read_config_word(pcidev, 0x40, &w);
- w&=~(1<<15); /* legacy decode on */
- w|=(1<<14); /* Reserved write as 1 in this case */
- w|=(1<<3)|(1<<1)|(1<<0); /* SB on , FM on, MPU on */
- pci_write_config_word(pcidev, 0x40, w);
-
- /*
- * Let the user know we found his toy.
- */
-
- printk(KERN_INFO "Programmed "CARD_NAME" at 0x%X to legacy mode.\n",
- iobase);
-
- /*
- * Now set it up the description of the card
- */
-
- mss_data[cards].io_base = mssbase;
- mss_data[cards].irq = pcidev->irq;
- mss_data[cards].dma = dma;
-
- /*
- * Check there is an MSS present
- */
-
- if(ad1848_detect(mssbase, NULL, mss_data[cards].osp)==0)
- return 0;
-
- /*
- * Initialize it
- */
-
- mss_data[cards].slots[3] = ad1848_init("MyCard MSS 16bit",
- mssbase,
- mss_data[cards].irq,
- mss_data[cards].dma,
- mss_data[cards].dma,
- 0,
- 0,
- THIS_MODULE);
-
- cards++;
- return 1;
-}
-
-
-/*
- * This loop walks the PCI configuration database and finds where
- * the sound cards are.
- */
-
-int init_mycard(void)
-{
- struct pci_dev *pcidev=NULL;
- int count=0;
-
- while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL)
- {
- if (pci_enable_device(pcidev))
- continue;
- count+=mycard_install(pcidev);
- if(count)
- return 0;
- if(count==MAX_CARDS)
- break;
- }
-
- if(count==0)
- return -ENODEV;
- return 0;
-}
-
-/*
- * This function is called when the user or kernel loads the
- * module into memory.
- */
-
-
-int init_module(void)
-{
- if(init_mycard()<0)
- {
- printk(KERN_ERR "No "CARD_NAME" cards found.\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-/*
- * This is called when it is removed. It will only be removed
- * when its use count is 0.
- */
-
-void cleanup_module(void)
-{
- for(i=0;i< cards; i++)
- {
- /*
- * Free attached resources
- */
-
- ad1848_unload(mss_data[i].io_base,
- mss_data[i].irq,
- mss_data[i].dma,
- mss_data[i].dma,
- 0);
- /*
- * And disconnect the device from the kernel
- */
- sound_unload_audiodevice(mss_data[i].slots[3]);
- }
-}
-
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index a686be936aff..95fa81e26de2 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -681,8 +681,7 @@ static void do_sequencer_timer(unsigned long dummy)
}
-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 6afe29b763b7..c9d04518b172 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -28,8 +28,7 @@ static unsigned long prev_event_time;
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 be00cf128651..74ae75f9e2dc 100644
--- a/sound/oss/uart6850.c
+++ b/sound/oss/uart6850.c
@@ -78,8 +78,7 @@ static void (*midi_input_intr) (int dev, unsigned char data);
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/parisc/harmony.c b/sound/parisc/harmony.c
index d7a8f9f5896f..f560dd8cdb90 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -880,6 +880,8 @@ snd_harmony_create(snd_card_t *card,
goto free_and_ret;
}
+ snd_card_set_dev(card, &padev->dev);
+
*rchip = h;
return 0;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1e458919cce6..a5d593c66f9f 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -316,6 +316,18 @@ config SND_YMFPCI
To compile this driver as a module, choose M here: the module
will be called snd-ymfpci.
+config SND_AD1889
+ tristate "Analog Devices AD1889"
+ depends on SND
+ select SND_AC97_CODEC
+ help
+ Say Y here to include support for the integrated AC97 sound
+ device found in particular on the Hewlett-Packard [BCJ]-xxx0
+ class PA-RISC workstations, using the AD1819 codec.
+
+ To compile this as a module, choose M here: the module
+ will be called snd-ad1889.
+
config SND_ALS4000
tristate "Avance Logic ALS4000"
depends on SND && ISA_DMA_API
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index b40575c3349a..42fabfcfc2a9 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -3,6 +3,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
#
+snd-ad1889-objs := ad1889.o
snd-als4000-objs := als4000.o
snd-atiixp-objs := atiixp.o
snd-atiixp-modem-objs := atiixp_modem.o
@@ -25,6 +26,7 @@ snd-via82xx-objs := via82xx.o
snd-via82xx-modem-objs := via82xx_modem.o
# Toplevel Module Dependency
+obj-$(CONFIG_SND_AD1889) += snd-ad1889.o
obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o
obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c
index 227f8b9f67ce..becbc420ba41 100644
--- a/sound/pci/ac97/ac97_bus.c
+++ b/sound/pci/ac97/ac97_bus.c
@@ -17,25 +17,21 @@
#include <linux/string.h>
/*
- * Codec families have names seperated by commas, so we search for an
- * individual codec name within the family string.
+ * Let drivers decide whether they want to support given codec from their
+ * probe method. Drivers have direct access to the ac97_t structure and may
+ * decide based on the id field amongst other things.
*/
static int ac97_bus_match(struct device *dev, struct device_driver *drv)
{
- return (strstr(dev->bus_id, drv->name) != NULL);
+ return 1;
}
static int ac97_bus_suspend(struct device *dev, pm_message_t state)
{
int ret = 0;
- if (dev->driver && dev->driver->suspend) {
- ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE);
- if (ret == 0)
- ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
- if (ret == 0)
- ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
- }
+ if (dev->driver && dev->driver->suspend)
+ ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
return ret;
}
@@ -43,13 +39,8 @@ static int ac97_bus_resume(struct device *dev)
{
int ret = 0;
- if (dev->driver && dev->driver->resume) {
+ if (dev->driver && dev->driver->resume)
ret = dev->driver->resume(dev, RESUME_POWER_ON);
- if (ret == 0)
- ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
- if (ret == 0)
- ret = dev->driver->resume(dev, RESUME_ENABLE);
- }
return ret;
}
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 5501f4440c92..41fc290149ed 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -112,6 +112,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
+{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
@@ -1556,7 +1557,7 @@ static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97)
/* build modem switches */
for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++)
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_modem_switches[idx], ac97))) < 0)
+ if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ac97_controls_modem_switches[idx], ac97))) < 0)
return err;
/* build chip specific controls */
@@ -1796,7 +1797,7 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops,
snd_assert(card != NULL, return -EINVAL);
snd_assert(rbus != NULL, return -EINVAL);
- bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (bus == NULL)
return -ENOMEM;
bus->card = card;
@@ -1827,7 +1828,6 @@ static int snd_ac97_dev_register(snd_device_t *device)
ac97->dev.bus = &ac97_bus_type;
ac97->dev.parent = ac97->bus->card->dev;
- ac97->dev.platform_data = ac97;
ac97->dev.release = ac97_device_release;
snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "card%d-%d", ac97->bus->card->number, ac97->num);
if ((err = device_register(&ac97->dev)) < 0) {
@@ -1905,7 +1905,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
}
card = bus->card;
- ac97 = kcalloc(1, sizeof(*ac97), GFP_KERNEL);
+ ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
if (ac97 == NULL)
return -ENOMEM;
ac97->private_data = template->private_data;
diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
index dadf387ad0b8..6d73514dc49e 100644
--- a/sound/pci/ac97/ac97_id.h
+++ b/sound/pci/ac97/ac97_id.h
@@ -52,6 +52,7 @@
#define AC97_ID_ALC650F 0x414c4723
#define AC97_ID_ALC655 0x414c4760
#define AC97_ID_ALC658 0x414c4780
+#define AC97_ID_ALC658D 0x414c4781
#define AC97_ID_ALC850 0x414c4790
#define AC97_ID_YMF753 0x594d4803
#define AC97_ID_VT1616 0x49434551
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index b584172c1104..0238cc65d32a 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2134,7 +2134,13 @@ int patch_alc655(ac97_t * ac97)
{
unsigned int val;
- ac97->spec.dev_flags = (ac97->id == 0x414c4780); /* ALC658 */
+ if (ac97->id == AC97_ID_ALC658) {
+ ac97->spec.dev_flags = 1; /* ALC658 */
+ if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) {
+ ac97->id = AC97_ID_ALC658D;
+ ac97->spec.dev_flags = 2;
+ }
+ }
ac97->build_ops = &patch_alc655_ops;
@@ -2143,10 +2149,15 @@ int patch_alc655(ac97_t * ac97)
/* adjust default values */
val = snd_ac97_read(ac97, 0x7a); /* misc control */
- if (ac97->id == 0x414c4780) /* ALC658 */
+ if (ac97->spec.dev_flags) /* ALC658 */
val &= ~(1 << 1); /* Pin 47 is spdif input pin */
- else /* ALC655 */
- val |= (1 << 1); /* Pin 47 is spdif input pin */
+ else { /* ALC655 */
+ if (ac97->subsystem_vendor == 0x1462 &&
+ ac97->subsystem_device == 0x0131) /* MSI S270 laptop */
+ val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
+ else
+ val |= (1 << 1); /* Pin 47 is spdif input pin */
+ }
val &= ~(1 << 12); /* vref enable */
snd_ac97_write_cache(ac97, 0x7a, val);
/* set default: spdif-in enabled,
@@ -2159,6 +2170,11 @@ int patch_alc655(ac97_t * ac97)
/* full DAC volume */
snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
+
+ /* update undocumented bit... */
+ if (ac97->id == AC97_ID_ALC658D)
+ snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
+
return 0;
}
@@ -2736,7 +2752,11 @@ AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
static int patch_si3036_specific(ac97_t * ac97)
{
- return patch_build_controls(ac97, snd_ac97_controls_si3036, ARRAY_SIZE(snd_ac97_controls_si3036));
+ int idx, err;
+ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++)
+ if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97))) < 0)
+ return err;
+ return 0;
}
static struct snd_ac97_build_ops patch_si3036_ops = {
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index f9ce0fd2f52f..4032c5748370 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -357,7 +357,7 @@ int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531)
snd_assert(rak4531 != NULL, return -EINVAL);
*rak4531 = NULL;
snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL);
- ak4531 = kcalloc(1, sizeof(*ak4531), GFP_KERNEL);
+ ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL);
if (ak4531 == NULL)
return -ENOMEM;
*ak4531 = *_ak4531;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
new file mode 100644
index 000000000000..d7d99a25c5e5
--- /dev/null
+++ b/sound/pci/ad1889.c
@@ -0,0 +1,1090 @@
+/* Analog Devices 1889 audio driver
+ *
+ * This is a driver for the AD1889 PCI audio chipset found
+ * on the HP PA-RISC [BCJ]-xxx0 workstations.
+ *
+ * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org>
+ * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org>
+ * Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * TODO:
+ * Do we need to take care of CCS register?
+ * Maybe we could use finer grained locking (separate locks for pb/cap)?
+ * Wishlist:
+ * Control Interface (mixer) support
+ * Better AC97 support (VSR...)?
+ * PM support
+ * MIDI support
+ * Game Port support
+ * SG DMA support (this will need *alot* of work)
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+#include <linux/delay.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/ac97_codec.h>
+
+#include <asm/io.h>
+
+#include "ad1889.h"
+#include "ac97/ac97_id.h"
+
+#define AD1889_DRVVER "$Revision: 1.3 $"
+
+MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
+MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard.");
+
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard.");
+
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable AD1889 soundcard.");
+
+static char *ac97_quirk[SNDRV_CARDS];
+module_param_array(ac97_quirk, charp, NULL, 0444);
+MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
+
+#define DEVNAME "ad1889"
+#define PFX DEVNAME ": "
+
+/* let's use the global sound debug interfaces */
+#define ad1889_debug(fmt, arg...) snd_printd(KERN_DEBUG fmt, ## arg)
+
+/* keep track of some hw registers */
+struct ad1889_register_state {
+ u16 reg; /* reg setup */
+ u32 addr; /* dma base address */
+ unsigned long size; /* DMA buffer size */
+};
+
+struct snd_ad1889 {
+ snd_card_t *card;
+ struct pci_dev *pci;
+
+ int irq;
+ unsigned long bar;
+ void __iomem *iobase;
+
+ ac97_t *ac97;
+ ac97_bus_t *ac97_bus;
+ snd_pcm_t *pcm;
+ snd_info_entry_t *proc;
+
+ snd_pcm_substream_t *psubs;
+ snd_pcm_substream_t *csubs;
+
+ /* playback register state */
+ struct ad1889_register_state wave;
+ struct ad1889_register_state ramc;
+
+ spinlock_t lock;
+};
+
+static inline u16
+ad1889_readw(struct snd_ad1889 *chip, unsigned reg)
+{
+ return readw(chip->iobase + reg);
+}
+
+static inline void
+ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val)
+{
+ writew(val, chip->iobase + reg);
+}
+
+static inline u32
+ad1889_readl(struct snd_ad1889 *chip, unsigned reg)
+{
+ return readl(chip->iobase + reg);
+}
+
+static inline void
+ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
+{
+ writel(val, chip->iobase + reg);
+}
+
+static inline void
+ad1889_unmute(struct snd_ad1889 *chip)
+{
+ u16 st;
+ st = ad1889_readw(chip, AD_DS_WADA) &
+ ~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM);
+ ad1889_writew(chip, AD_DS_WADA, st);
+ ad1889_readw(chip, AD_DS_WADA);
+}
+
+static inline void
+ad1889_mute(struct snd_ad1889 *chip)
+{
+ u16 st;
+ st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM;
+ ad1889_writew(chip, AD_DS_WADA, st);
+ ad1889_readw(chip, AD_DS_WADA);
+}
+
+static inline void
+ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address)
+{
+ ad1889_writel(chip, AD_DMA_ADCBA, address);
+ ad1889_writel(chip, AD_DMA_ADCCA, address);
+}
+
+static inline void
+ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count)
+{
+ ad1889_writel(chip, AD_DMA_ADCBC, count);
+ ad1889_writel(chip, AD_DMA_ADCCC, count);
+}
+
+static inline void
+ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count)
+{
+ ad1889_writel(chip, AD_DMA_ADCIB, count);
+ ad1889_writel(chip, AD_DMA_ADCIC, count);
+}
+
+static inline void
+ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address)
+{
+ ad1889_writel(chip, AD_DMA_WAVBA, address);
+ ad1889_writel(chip, AD_DMA_WAVCA, address);
+}
+
+static inline void
+ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count)
+{
+ ad1889_writel(chip, AD_DMA_WAVBC, count);
+ ad1889_writel(chip, AD_DMA_WAVCC, count);
+}
+
+static inline void
+ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count)
+{
+ ad1889_writel(chip, AD_DMA_WAVIB, count);
+ ad1889_writel(chip, AD_DMA_WAVIC, count);
+}
+
+static void
+ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel)
+{
+ u16 reg;
+
+ if (channel & AD_CHAN_WAV) {
+ /* Disable wave channel */
+ reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN;
+ ad1889_writew(chip, AD_DS_WSMC, reg);
+ chip->wave.reg = reg;
+
+ /* disable IRQs */
+ reg = ad1889_readw(chip, AD_DMA_WAV);
+ reg &= AD_DMA_IM_DIS;
+ reg &= ~AD_DMA_LOOP;
+ ad1889_writew(chip, AD_DMA_WAV, reg);
+
+ /* clear IRQ and address counters and pointers */
+ ad1889_load_wave_buffer_address(chip, 0x0);
+ ad1889_load_wave_buffer_count(chip, 0x0);
+ ad1889_load_wave_interrupt_count(chip, 0x0);
+
+ /* flush */
+ ad1889_readw(chip, AD_DMA_WAV);
+ }
+
+ if (channel & AD_CHAN_ADC) {
+ /* Disable ADC channel */
+ reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN;
+ ad1889_writew(chip, AD_DS_RAMC, reg);
+ chip->ramc.reg = reg;
+
+ reg = ad1889_readw(chip, AD_DMA_ADC);
+ reg &= AD_DMA_IM_DIS;
+ reg &= ~AD_DMA_LOOP;
+ ad1889_writew(chip, AD_DMA_ADC, reg);
+
+ ad1889_load_adc_buffer_address(chip, 0x0);
+ ad1889_load_adc_buffer_count(chip, 0x0);
+ ad1889_load_adc_interrupt_count(chip, 0x0);
+
+ /* flush */
+ ad1889_readw(chip, AD_DMA_ADC);
+ }
+}
+
+static inline u16
+snd_ad1889_ac97_read(ac97_t *ac97, unsigned short reg)
+{
+ struct snd_ad1889 *chip = ac97->private_data;
+ return ad1889_readw(chip, AD_AC97_BASE + reg);
+}
+
+static inline void
+snd_ad1889_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+{
+ struct snd_ad1889 *chip = ac97->private_data;
+ ad1889_writew(chip, AD_AC97_BASE + reg, val);
+}
+
+static int
+snd_ad1889_ac97_ready(struct snd_ad1889 *chip)
+{
+ int retry = 400; /* average needs 352 msec */
+
+ while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY)
+ && --retry)
+ mdelay(1);
+ if (!retry) {
+ snd_printk(KERN_ERR PFX "[%s] Link is not ready.\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ ad1889_debug("[%s] ready after %d ms\n", __FUNCTION__, 400 - retry);
+
+ return 0;
+}
+
+static int
+snd_ad1889_hw_params(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *hw_params)
+{
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+}
+
+static int
+snd_ad1889_hw_free(snd_pcm_substream_t *substream)
+{
+ return snd_pcm_lib_free_pages(substream);
+}
+
+static snd_pcm_hardware_t snd_ad1889_playback_hw = {
+ .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000, /* docs say 7000, but we're lazy */
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = BUFFER_BYTES_MAX,
+ .period_bytes_min = PERIOD_BYTES_MIN,
+ .period_bytes_max = PERIOD_BYTES_MAX,
+ .periods_min = PERIODS_MIN,
+ .periods_max = PERIODS_MAX,
+ /*.fifo_size = 0,*/
+};
+
+static snd_pcm_hardware_t snd_ad1889_capture_hw = {
+ .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000, /* docs say we could to VSR, but we're lazy */
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = BUFFER_BYTES_MAX,
+ .period_bytes_min = PERIOD_BYTES_MIN,
+ .period_bytes_max = PERIOD_BYTES_MAX,
+ .periods_min = PERIODS_MIN,
+ .periods_max = PERIODS_MAX,
+ /*.fifo_size = 0,*/
+};
+
+static int
+snd_ad1889_playback_open(snd_pcm_substream_t *ss)
+{
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+ snd_pcm_runtime_t *rt = ss->runtime;
+
+ chip->psubs = ss;
+ rt->hw = snd_ad1889_playback_hw;
+
+ return 0;
+}
+
+static int
+snd_ad1889_capture_open(snd_pcm_substream_t *ss)
+{
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+ snd_pcm_runtime_t *rt = ss->runtime;
+
+ chip->csubs = ss;
+ rt->hw = snd_ad1889_capture_hw;
+
+ return 0;
+}
+
+static int
+snd_ad1889_playback_close(snd_pcm_substream_t *ss)
+{
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+ chip->psubs = NULL;
+ return 0;
+}
+
+static int
+snd_ad1889_capture_close(snd_pcm_substream_t *ss)
+{
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+ chip->csubs = NULL;
+ return 0;
+}
+
+static int
+snd_ad1889_playback_prepare(snd_pcm_substream_t *ss)
+{
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+ snd_pcm_runtime_t *rt = ss->runtime;
+ unsigned int size = snd_pcm_lib_buffer_bytes(ss);
+ unsigned int count = snd_pcm_lib_period_bytes(ss);
+ u16 reg;
+
+ ad1889_channel_reset(chip, AD_CHAN_WAV);
+
+ reg = ad1889_readw(chip, AD_DS_WSMC);
+
+ /* Mask out 16-bit / Stereo */
+ reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST);
+
+ if (snd_pcm_format_width(rt->format) == 16)
+ reg |= AD_DS_WSMC_WA16;
+
+ if (rt->channels > 1)
+ reg |= AD_DS_WSMC_WAST;
+
+ /* let's make sure we don't clobber ourselves */
+ spin_lock_irq(&chip->lock);
+
+ chip->wave.size = size;
+ chip->wave.reg = reg;
+ chip->wave.addr = rt->dma_addr;
+
+ ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg);
+
+ /* Set sample rates on the codec */
+ ad1889_writew(chip, AD_DS_WAS, rt->rate);
+
+ /* Set up DMA */
+ ad1889_load_wave_buffer_address(chip, chip->wave.addr);
+ ad1889_load_wave_buffer_count(chip, size);
+ ad1889_load_wave_interrupt_count(chip, count);
+
+ /* writes flush */
+ ad1889_readw(chip, AD_DS_WSMC);
+
+ spin_unlock_irq(&chip->lock);
+
+ ad1889_debug("prepare playback: addr = 0x%x, count = %u, "
+ "size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr,
+ count, size, reg, rt->rate);
+ return 0;
+}
+
+static int
+snd_ad1889_capture_prepare(snd_pcm_substream_t *ss)
+{
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+ snd_pcm_runtime_t *rt = ss->runtime;
+ unsigned int size = snd_pcm_lib_buffer_bytes(ss);
+ unsigned int count = snd_pcm_lib_period_bytes(ss);
+ u16 reg;
+
+ ad1889_channel_reset(chip, AD_CHAN_ADC);
+
+ reg = ad1889_readw(chip, AD_DS_RAMC);
+
+ /* Mask out 16-bit / Stereo */
+ reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST);
+
+ if (snd_pcm_format_width(rt->format) == 16)
+ reg |= AD_DS_RAMC_AD16;
+
+ if (rt->channels > 1)
+ reg |= AD_DS_RAMC_ADST;
+
+ /* let's make sure we don't clobber ourselves */
+ spin_lock_irq(&chip->lock);
+
+ chip->ramc.size = size;
+ chip->ramc.reg = reg;
+ chip->ramc.addr = rt->dma_addr;
+
+ ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg);
+
+ /* Set up DMA */
+ ad1889_load_adc_buffer_address(chip, chip->ramc.addr);
+ ad1889_load_adc_buffer_count(chip, size);
+ ad1889_load_adc_interrupt_count(chip, count);
+
+ /* writes flush */
+ ad1889_readw(chip, AD_DS_RAMC);
+
+ spin_unlock_irq(&chip->lock);
+
+ ad1889_debug("prepare capture: addr = 0x%x, count = %u, "
+ "size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr,
+ count, size, reg, rt->rate);
+ return 0;
+}
+
+/* this is called in atomic context with IRQ disabled.
+ Must be as fast as possible and not sleep.
+ DMA should be *triggered* by this call.
+ The WSMC "WAEN" bit triggers DMA Wave On/Off */
+static int
+snd_ad1889_playback_trigger(snd_pcm_substream_t *ss, int cmd)
+{
+ u16 wsmc;
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+ wsmc = ad1889_readw(chip, AD_DS_WSMC);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ /* enable DMA loop & interrupts */
+ ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
+ wsmc |= AD_DS_WSMC_WAEN;
+ /* 1 to clear CHSS bit */
+ ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
+ ad1889_unmute(chip);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ ad1889_mute(chip);
+ wsmc &= ~AD_DS_WSMC_WAEN;
+ break;
+ default:
+ snd_BUG();
+ return -EINVAL;
+ }
+
+ chip->wave.reg = wsmc;
+ ad1889_writew(chip, AD_DS_WSMC, wsmc);
+ ad1889_readw(chip, AD_DS_WSMC); /* flush */
+
+ /* reset the chip when STOP - will disable IRQs */
+ if (cmd == SNDRV_PCM_TRIGGER_STOP)
+ ad1889_channel_reset(chip, AD_CHAN_WAV);
+
+ return 0;
+}
+
+/* this is called in atomic context with IRQ disabled.
+ Must be as fast as possible and not sleep.
+ DMA should be *triggered* by this call.
+ The RAMC "ADEN" bit triggers DMA ADC On/Off */
+static int
+snd_ad1889_capture_trigger(snd_pcm_substream_t *ss, int cmd)
+{
+ u16 ramc;
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+ ramc = ad1889_readw(chip, AD_DS_RAMC);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ /* enable DMA loop & interrupts */
+ ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT);
+ ramc |= AD_DS_RAMC_ADEN;
+ /* 1 to clear CHSS bit */
+ ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ ramc &= ~AD_DS_RAMC_ADEN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ chip->ramc.reg = ramc;
+ ad1889_writew(chip, AD_DS_RAMC, ramc);
+ ad1889_readw(chip, AD_DS_RAMC); /* flush */
+
+ /* reset the chip when STOP - will disable IRQs */
+ if (cmd == SNDRV_PCM_TRIGGER_STOP)
+ ad1889_channel_reset(chip, AD_CHAN_ADC);
+
+ return 0;
+}
+
+/* Called in atomic context with IRQ disabled */
+static snd_pcm_uframes_t
+snd_ad1889_playback_pointer(snd_pcm_substream_t *ss)
+{
+ size_t ptr = 0;
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+ if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN)))
+ return 0;
+
+ ptr = ad1889_readl(chip, AD_DMA_WAVCA);
+ ptr -= chip->wave.addr;
+
+ snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0);
+
+ return bytes_to_frames(ss->runtime, ptr);
+}
+
+/* Called in atomic context with IRQ disabled */
+static snd_pcm_uframes_t
+snd_ad1889_capture_pointer(snd_pcm_substream_t *ss)
+{
+ size_t ptr = 0;
+ struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+ if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN)))
+ return 0;
+
+ ptr = ad1889_readl(chip, AD_DMA_ADCCA);
+ ptr -= chip->ramc.addr;
+
+ snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0);
+
+ return bytes_to_frames(ss->runtime, ptr);
+}
+
+static snd_pcm_ops_t snd_ad1889_playback_ops = {
+ .open = snd_ad1889_playback_open,
+ .close = snd_ad1889_playback_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_ad1889_hw_params,
+ .hw_free = snd_ad1889_hw_free,
+ .prepare = snd_ad1889_playback_prepare,
+ .trigger = snd_ad1889_playback_trigger,
+ .pointer = snd_ad1889_playback_pointer,
+};
+
+static snd_pcm_ops_t snd_ad1889_capture_ops = {
+ .open = snd_ad1889_capture_open,
+ .close = snd_ad1889_capture_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_ad1889_hw_params,
+ .hw_free = snd_ad1889_hw_free,
+ .prepare = snd_ad1889_capture_prepare,
+ .trigger = snd_ad1889_capture_trigger,
+ .pointer = snd_ad1889_capture_pointer,
+};
+
+static irqreturn_t
+snd_ad1889_interrupt(int irq,
+ void *dev_id,
+ struct pt_regs *regs)
+{
+ unsigned long st;
+ struct snd_ad1889 *chip = dev_id;
+
+ st = ad1889_readl(chip, AD_DMA_DISR);
+
+ /* clear ISR */
+ ad1889_writel(chip, AD_DMA_DISR, st);
+
+ st &= AD_INTR_MASK;
+
+ if (unlikely(!st))
+ return IRQ_NONE;
+
+ if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI))
+ ad1889_debug("Unexpected master or target abort interrupt!\n");
+
+ if ((st & AD_DMA_DISR_WAVI) && chip->psubs)
+ snd_pcm_period_elapsed(chip->psubs);
+ if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
+ snd_pcm_period_elapsed(chip->csubs);
+
+ return IRQ_HANDLED;
+}
+
+static void
+snd_ad1889_pcm_free(snd_pcm_t *pcm)
+{
+ struct snd_ad1889 *chip = pcm->private_data;
+ chip->pcm = NULL;
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int __devinit
+snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, snd_pcm_t **rpcm)
+{
+ int err;
+ snd_pcm_t *pcm;
+
+ if (rpcm)
+ *rpcm = NULL;
+
+ err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm);
+ if (err < 0)
+ return err;
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_ad1889_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_ad1889_capture_ops);
+
+ pcm->private_data = chip;
+ pcm->private_free = snd_ad1889_pcm_free;
+ pcm->info_flags = 0;
+ strcpy(pcm->name, chip->card->shortname);
+
+ chip->pcm = pcm;
+ chip->psubs = NULL;
+ chip->csubs = NULL;
+
+ err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->pci),
+ BUFFER_BYTES_MAX / 2,
+ BUFFER_BYTES_MAX);
+
+ if (err < 0) {
+ snd_printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
+ return err;
+ }
+
+ if (rpcm)
+ *rpcm = pcm;
+
+ return 0;
+}
+
+static void
+snd_ad1889_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+{
+ struct snd_ad1889 *chip = entry->private_data;
+ u16 reg;
+ int tmp;
+
+ reg = ad1889_readw(chip, AD_DS_WSMC);
+ snd_iprintf(buffer, "Wave output: %s\n",
+ (reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled");
+ snd_iprintf(buffer, "Wave Channels: %s\n",
+ (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+ snd_iprintf(buffer, "Wave Quality: %d-bit linear\n",
+ (reg & AD_DS_WSMC_WA16) ? 16 : 8);
+
+ /* WARQ is at offset 12 */
+ tmp = (reg & AD_DS_WSMC_WARQ) ?
+ (((reg & AD_DS_WSMC_WARQ >> 12) & 0x01) ? 12 : 18) : 4;
+ tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
+
+ snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp,
+ (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+
+
+ snd_iprintf(buffer, "Synthesis output: %s\n",
+ reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled");
+
+ /* SYRQ is at offset 4 */
+ tmp = (reg & AD_DS_WSMC_SYRQ) ?
+ (((reg & AD_DS_WSMC_SYRQ >> 4) & 0x01) ? 12 : 18) : 4;
+ tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
+
+ snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp,
+ (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+
+ reg = ad1889_readw(chip, AD_DS_RAMC);
+ snd_iprintf(buffer, "ADC input: %s\n",
+ (reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled");
+ snd_iprintf(buffer, "ADC Channels: %s\n",
+ (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
+ snd_iprintf(buffer, "ADC Quality: %d-bit linear\n",
+ (reg & AD_DS_RAMC_AD16) ? 16 : 8);
+
+ /* ACRQ is at offset 4 */
+ tmp = (reg & AD_DS_RAMC_ACRQ) ?
+ (((reg & AD_DS_RAMC_ACRQ >> 4) & 0x01) ? 12 : 18) : 4;
+ tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
+
+ snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp,
+ (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
+
+ snd_iprintf(buffer, "Resampler input: %s\n",
+ reg & AD_DS_RAMC_REEN ? "enabled" : "disabled");
+
+ /* RERQ is at offset 12 */
+ tmp = (reg & AD_DS_RAMC_RERQ) ?
+ (((reg & AD_DS_RAMC_RERQ >> 12) & 0x01) ? 12 : 18) : 4;
+ tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
+
+ snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp,
+ (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+
+
+ /* doc says LSB represents -1.5dB, but the max value (-94.5dB)
+ suggests that LSB is -3dB, which is more coherent with the logarithmic
+ nature of the dB scale */
+ reg = ad1889_readw(chip, AD_DS_WADA);
+ snd_iprintf(buffer, "Left: %s, -%d dB\n",
+ (reg & AD_DS_WADA_LWAM) ? "mute" : "unmute",
+ ((reg & AD_DS_WADA_LWAA) >> 8) * 3);
+ reg = ad1889_readw(chip, AD_DS_WADA);
+ snd_iprintf(buffer, "Right: %s, -%d dB\n",
+ (reg & AD_DS_WADA_RWAM) ? "mute" : "unmute",
+ ((reg & AD_DS_WADA_RWAA) >> 8) * 3);
+
+ reg = ad1889_readw(chip, AD_DS_WAS);
+ snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg);
+ reg = ad1889_readw(chip, AD_DS_RES);
+ snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg);
+}
+
+static void __devinit
+snd_ad1889_proc_init(struct snd_ad1889 *chip)
+{
+ snd_info_entry_t *entry;
+
+ if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
+ snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read);
+}
+
+static struct ac97_quirk ac97_quirks[] = {
+ {
+ .subvendor = 0x11d4, /* AD */
+ .subdevice = 0x1889, /* AD1889 */
+ .codec_id = AC97_ID_AD1819,
+ .name = "AD1889",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ { } /* terminator */
+};
+
+static void __devinit
+snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
+{
+ u16 reg;
+
+ reg = ad1889_readw(chip, AD_AC97_ACIC);
+ reg |= AD_AC97_ACIC_ACRD; /* Reset Disable */
+ ad1889_writew(chip, AD_AC97_ACIC, reg);
+ ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */
+ udelay(10);
+ /* Interface Enable */
+ reg |= AD_AC97_ACIC_ACIE;
+ ad1889_writew(chip, AD_AC97_ACIC, reg);
+
+ snd_ad1889_ac97_ready(chip);
+
+ /* Audio Stream Output | Variable Sample Rate Mode */
+ reg = ad1889_readw(chip, AD_AC97_ACIC);
+ reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM;
+ ad1889_writew(chip, AD_AC97_ACIC, reg);
+ ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */
+
+}
+
+static void
+snd_ad1889_ac97_bus_free(ac97_bus_t *bus)
+{
+ struct snd_ad1889 *chip = bus->private_data;
+ chip->ac97_bus = NULL;
+}
+
+static void
+snd_ad1889_ac97_free(ac97_t *ac97)
+{
+ struct snd_ad1889 *chip = ac97->private_data;
+ chip->ac97 = NULL;
+}
+
+static int __devinit
+snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
+{
+ int err;
+ ac97_template_t ac97;
+ static ac97_bus_ops_t ops = {
+ .write = snd_ad1889_ac97_write,
+ .read = snd_ad1889_ac97_read,
+ };
+
+ /* doing that here, it works. */
+ snd_ad1889_ac97_xinit(chip);
+
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
+ return err;
+
+ chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free;
+
+ memset(&ac97, 0, sizeof(ac97));
+ ac97.private_data = chip;
+ ac97.private_free = snd_ad1889_ac97_free;
+ ac97.pci = chip->pci;
+
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+ if (err < 0)
+ return err;
+
+ snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
+
+ return 0;
+}
+
+static int
+snd_ad1889_free(struct snd_ad1889 *chip)
+{
+ if (chip->irq < 0)
+ goto skip_hw;
+
+ spin_lock_irq(&chip->lock);
+
+ ad1889_mute(chip);
+
+ /* Turn off interrupt on count and zero DMA registers */
+ ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC);
+
+ /* clear DISR. If we don't, we'd better jump off the Eiffel Tower */
+ ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
+ ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */
+
+ spin_unlock_irq(&chip->lock);
+
+ synchronize_irq(chip->irq);
+
+ if (chip->irq >= 0)
+ free_irq(chip->irq, (void*)chip);
+
+skip_hw:
+ if (chip->iobase)
+ iounmap(chip->iobase);
+
+ pci_release_regions(chip->pci);
+ pci_disable_device(chip->pci);
+
+ kfree(chip);
+ return 0;
+}
+
+static inline int
+snd_ad1889_dev_free(snd_device_t *device)
+{
+ struct snd_ad1889 *chip = device->device_data;
+ return snd_ad1889_free(chip);
+}
+
+static int __devinit
+snd_ad1889_init(struct snd_ad1889 *chip)
+{
+ ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
+ ad1889_readw(chip, AD_DS_CCS); /* flush posted write */
+
+ mdelay(10);
+
+ /* enable Master and Target abort interrupts */
+ ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);
+
+ return 0;
+}
+
+static int __devinit
+snd_ad1889_create(snd_card_t *card,
+ struct pci_dev *pci,
+ struct snd_ad1889 **rchip)
+{
+ int err;
+
+ struct snd_ad1889 *chip;
+ static snd_device_ops_t ops = {
+ .dev_free = snd_ad1889_dev_free,
+ };
+
+ *rchip = NULL;
+
+ if ((err = pci_enable_device(pci)) < 0)
+ return err;
+
+ /* check PCI availability (32bit DMA) */
+ if (pci_set_dma_mask(pci, 0xffffffff) < 0 ||
+ pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) {
+ printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n");
+ pci_disable_device(pci);
+ return -ENXIO;
+ }
+
+ /* allocate chip specific data with zero-filled memory */
+ if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
+ pci_disable_device(pci);
+ return -ENOMEM;
+ }
+
+ chip->card = card;
+ card->private_data = chip;
+ chip->pci = pci;
+ chip->irq = -1;
+
+ /* (1) PCI resource allocation */
+ if ((err = pci_request_regions(pci, card->driver)) < 0)
+ goto free_and_ret;
+
+ chip->bar = pci_resource_start(pci, 0);
+ chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0));
+ if (chip->iobase == NULL) {
+ printk(KERN_ERR PFX "unable to reserve region.\n");
+ err = -EBUSY;
+ goto free_and_ret;
+ }
+
+ pci_set_master(pci);
+
+ spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
+
+ if (request_irq(pci->irq, snd_ad1889_interrupt,
+ SA_INTERRUPT|SA_SHIRQ, card->driver, (void*)chip)) {
+ printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
+ snd_ad1889_free(chip);
+ return -EBUSY;
+ }
+
+ chip->irq = pci->irq;
+ synchronize_irq(chip->irq);
+
+ /* (2) initialization of the chip hardware */
+ if ((err = snd_ad1889_init(chip)) < 0) {
+ snd_ad1889_free(chip);
+ return err;
+ }
+
+ if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ snd_ad1889_free(chip);
+ return err;
+ }
+
+ snd_card_set_dev(card, &pci->dev);
+
+ *rchip = chip;
+
+ return 0;
+
+free_and_ret:
+ if (chip)
+ kfree(chip);
+ pci_disable_device(pci);
+
+ return err;
+}
+
+static int __devinit
+snd_ad1889_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ int err;
+ static int devno;
+ snd_card_t *card;
+ struct snd_ad1889 *chip;
+
+ /* (1) */
+ if (devno >= SNDRV_CARDS)
+ return -ENODEV;
+ if (!enable[devno]) {
+ devno++;
+ return -ENOENT;
+ }
+
+ /* (2) */
+ card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0);
+ /* XXX REVISIT: we can probably allocate chip in this call */
+ if (card == NULL)
+ return -ENOMEM;
+
+ strcpy(card->driver, "AD1889");
+ strcpy(card->shortname, "Analog Devices AD1889");
+
+ /* (3) */
+ err = snd_ad1889_create(card, pci, &chip);
+ if (err < 0)
+ goto free_and_ret;
+
+ /* (4) */
+ sprintf(card->longname, "%s at 0x%lx irq %i",
+ card->shortname, chip->bar, chip->irq);
+
+ /* (5) */
+ /* register AC97 mixer */
+ err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]);
+ if (err < 0)
+ goto free_and_ret;
+
+ err = snd_ad1889_pcm_init(chip, 0, NULL);
+ if (err < 0)
+ goto free_and_ret;
+
+ /* register proc interface */
+ snd_ad1889_proc_init(chip);
+
+ /* (6) */
+ err = snd_card_register(card);
+ if (err < 0)
+ goto free_and_ret;
+
+ /* (7) */
+ pci_set_drvdata(pci, card);
+
+ devno++;
+ return 0;
+
+free_and_ret:
+ snd_card_free(card);
+ return err;
+}
+
+static void __devexit
+snd_ad1889_remove(struct pci_dev *pci)
+{
+ snd_card_free(pci_get_drvdata(pci));
+ pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_device_id snd_ad1889_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
+
+static struct pci_driver ad1889_pci = {
+ .name = "AD1889 Audio",
+ .owner = THIS_MODULE,
+ .id_table = snd_ad1889_ids,
+ .probe = snd_ad1889_probe,
+ .remove = __devexit_p(snd_ad1889_remove),
+};
+
+static int __init
+alsa_ad1889_init(void)
+{
+ return pci_register_driver(&ad1889_pci);
+}
+
+static void __exit
+alsa_ad1889_fini(void)
+{
+ pci_unregister_driver(&ad1889_pci);
+}
+
+module_init(alsa_ad1889_init);
+module_exit(alsa_ad1889_fini);
diff --git a/sound/pci/ad1889.h b/sound/pci/ad1889.h
new file mode 100644
index 000000000000..5e6dad5341a1
--- /dev/null
+++ b/sound/pci/ad1889.h
@@ -0,0 +1,189 @@
+/* Analog Devices 1889 audio driver
+ * Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org>
+ */
+
+#ifndef __AD1889_H__
+#define __AD1889_H__
+
+#define AD_DS_WSMC 0x00 /* wave/synthesis channel mixer control */
+#define AD_DS_WSMC_SYEN 0x0004 /* synthesis channel enable */
+#define AD_DS_WSMC_SYRQ 0x0030 /* synth. fifo request point */
+#define AD_DS_WSMC_WA16 0x0100 /* wave channel 16bit select */
+#define AD_DS_WSMC_WAST 0x0200 /* wave channel stereo select */
+#define AD_DS_WSMC_WAEN 0x0400 /* wave channel enable */
+#define AD_DS_WSMC_WARQ 0x3000 /* wave fifo request point */
+
+#define AD_DS_RAMC 0x02 /* resampler/ADC channel mixer control */
+#define AD_DS_RAMC_AD16 0x0001 /* ADC channel 16bit select */
+#define AD_DS_RAMC_ADST 0x0002 /* ADC channel stereo select */
+#define AD_DS_RAMC_ADEN 0x0004 /* ADC channel enable */
+#define AD_DS_RAMC_ACRQ 0x0030 /* ADC fifo request point */
+#define AD_DS_RAMC_REEN 0x0400 /* resampler channel enable */
+#define AD_DS_RAMC_RERQ 0x3000 /* res. fifo request point */
+
+#define AD_DS_WADA 0x04 /* wave channel mix attenuation */
+#define AD_DS_WADA_RWAM 0x0080 /* right wave mute */
+#define AD_DS_WADA_RWAA 0x001f /* right wave attenuation */
+#define AD_DS_WADA_LWAM 0x8000 /* left wave mute */
+#define AD_DS_WADA_LWAA 0x3e00 /* left wave attenuation */
+
+#define AD_DS_SYDA 0x06 /* synthesis channel mix attenuation */
+#define AD_DS_SYDA_RSYM 0x0080 /* right synthesis mute */
+#define AD_DS_SYDA_RSYA 0x001f /* right synthesis attenuation */
+#define AD_DS_SYDA_LSYM 0x8000 /* left synthesis mute */
+#define AD_DS_SYDA_LSYA 0x3e00 /* left synthesis attenuation */
+
+#define AD_DS_WAS 0x08 /* wave channel sample rate */
+#define AD_DS_WAS_WAS 0xffff /* sample rate mask */
+
+#define AD_DS_RES 0x0a /* resampler channel sample rate */
+#define AD_DS_RES_RES 0xffff /* sample rate mask */
+
+#define AD_DS_CCS 0x0c /* chip control/status */
+#define AD_DS_CCS_ADO 0x0001 /* ADC channel overflow */
+#define AD_DS_CCS_REO 0x0002 /* resampler channel overflow */
+#define AD_DS_CCS_SYU 0x0004 /* synthesis channel underflow */
+#define AD_DS_CCS_WAU 0x0008 /* wave channel underflow */
+/* bits 4 -> 7, 9, 11 -> 14 reserved */
+#define AD_DS_CCS_XTD 0x0100 /* xtd delay control (4096 clock cycles) */
+#define AD_DS_CCS_PDALL 0x0400 /* power */
+#define AD_DS_CCS_CLKEN 0x8000 /* clock */
+
+#define AD_DMA_RESBA 0x40 /* RES base address */
+#define AD_DMA_RESCA 0x44 /* RES current address */
+#define AD_DMA_RESBC 0x48 /* RES base count */
+#define AD_DMA_RESCC 0x4c /* RES current count */
+
+#define AD_DMA_ADCBA 0x50 /* ADC base address */
+#define AD_DMA_ADCCA 0x54 /* ADC current address */
+#define AD_DMA_ADCBC 0x58 /* ADC base count */
+#define AD_DMA_ADCCC 0x5c /* ADC current count */
+
+#define AD_DMA_SYNBA 0x60 /* synth base address */
+#define AD_DMA_SYNCA 0x64 /* synth current address */
+#define AD_DMA_SYNBC 0x68 /* synth base count */
+#define AD_DMA_SYNCC 0x6c /* synth current count */
+
+#define AD_DMA_WAVBA 0x70 /* wave base address */
+#define AD_DMA_WAVCA 0x74 /* wave current address */
+#define AD_DMA_WAVBC 0x78 /* wave base count */
+#define AD_DMA_WAVCC 0x7c /* wave current count */
+
+#define AD_DMA_RESIC 0x80 /* RES dma interrupt current byte count */
+#define AD_DMA_RESIB 0x84 /* RES dma interrupt base byte count */
+
+#define AD_DMA_ADCIC 0x88 /* ADC dma interrupt current byte count */
+#define AD_DMA_ADCIB 0x8c /* ADC dma interrupt base byte count */
+
+#define AD_DMA_SYNIC 0x90 /* synth dma interrupt current byte count */
+#define AD_DMA_SYNIB 0x94 /* synth dma interrupt base byte count */
+
+#define AD_DMA_WAVIC 0x98 /* wave dma interrupt current byte count */
+#define AD_DMA_WAVIB 0x9c /* wave dma interrupt base byte count */
+
+#define AD_DMA_ICC 0xffffff /* current byte count mask */
+#define AD_DMA_IBC 0xffffff /* base byte count mask */
+/* bits 24 -> 31 reserved */
+
+/* 4 bytes pad */
+#define AD_DMA_ADC 0xa8 /* ADC dma control and status */
+#define AD_DMA_SYNTH 0xb0 /* Synth dma control and status */
+#define AD_DMA_WAV 0xb8 /* wave dma control and status */
+#define AD_DMA_RES 0xa0 /* Resample dma control and status */
+
+#define AD_DMA_SGDE 0x0001 /* SGD mode enable */
+#define AD_DMA_LOOP 0x0002 /* loop enable */
+#define AD_DMA_IM 0x000c /* interrupt mode mask */
+#define AD_DMA_IM_DIS (~AD_DMA_IM) /* disable */
+#define AD_DMA_IM_CNT 0x0004 /* interrupt on count */
+#define AD_DMA_IM_SGD 0x0008 /* interrupt on SGD flag */
+#define AD_DMA_IM_EOL 0x000c /* interrupt on End of Linked List */
+#define AD_DMA_SGDS 0x0030 /* SGD status */
+#define AD_DMA_SFLG 0x0040 /* SGD flag */
+#define AD_DMA_EOL 0x0080 /* SGD end of list */
+/* bits 8 -> 15 reserved */
+
+#define AD_DMA_DISR 0xc0 /* dma interrupt status */
+#define AD_DMA_DISR_RESI 0x000001 /* resampler channel interrupt */
+#define AD_DMA_DISR_ADCI 0x000002 /* ADC channel interrupt */
+#define AD_DMA_DISR_SYNI 0x000004 /* synthesis channel interrupt */
+#define AD_DMA_DISR_WAVI 0x000008 /* wave channel interrupt */
+/* bits 4, 5 reserved */
+#define AD_DMA_DISR_SEPS 0x000040 /* serial eeprom status */
+/* bits 7 -> 13 reserved */
+#define AD_DMA_DISR_PMAI 0x004000 /* pci master abort interrupt */
+#define AD_DMA_DISR_PTAI 0x008000 /* pci target abort interrupt */
+#define AD_DMA_DISR_PTAE 0x010000 /* pci target abort interrupt enable */
+#define AD_DMA_DISR_PMAE 0x020000 /* pci master abort interrupt enable */
+/* bits 19 -> 31 reserved */
+
+/* interrupt mask */
+#define AD_INTR_MASK (AD_DMA_DISR_RESI|AD_DMA_DISR_ADCI| \
+ AD_DMA_DISR_WAVI|AD_DMA_DISR_SYNI| \
+ AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI)
+
+#define AD_DMA_CHSS 0xc4 /* dma channel stop status */
+#define AD_DMA_CHSS_RESS 0x000001 /* resampler channel stopped */
+#define AD_DMA_CHSS_ADCS 0x000002 /* ADC channel stopped */
+#define AD_DMA_CHSS_SYNS 0x000004 /* synthesis channel stopped */
+#define AD_DMA_CHSS_WAVS 0x000008 /* wave channel stopped */
+
+#define AD_GPIO_IPC 0xc8 /* gpio port control */
+#define AD_GPIO_OP 0xca /* gpio output port status */
+#define AD_GPIO_IP 0xcc /* gpio input port status */
+
+#define AD_AC97_BASE 0x100 /* ac97 base register */
+
+#define AD_AC97_RESET 0x100 /* reset */
+
+#define AD_AC97_PWR_CTL 0x126 /* == AC97_POWERDOWN */
+#define AD_AC97_PWR_ADC 0x0001 /* ADC ready status */
+#define AD_AC97_PWR_DAC 0x0002 /* DAC ready status */
+#define AD_AC97_PWR_PR0 0x0100 /* PR0 (ADC) powerdown */
+#define AD_AC97_PWR_PR1 0x0200 /* PR1 (DAC) powerdown */
+
+#define AD_MISC_CTL 0x176 /* misc control */
+#define AD_MISC_CTL_DACZ 0x8000 /* set for zero fill, unset for repeat */
+#define AD_MISC_CTL_ARSR 0x0001 /* set for SR1, unset for SR0 */
+#define AD_MISC_CTL_ALSR 0x0100
+#define AD_MISC_CTL_DLSR 0x0400
+#define AD_MISC_CTL_DRSR 0x0004
+
+#define AD_AC97_SR0 0x178 /* sample rate 0, 0xbb80 == 48K */
+#define AD_AC97_SR0_48K 0xbb80 /* 48KHz */
+#define AD_AC97_SR1 0x17a /* sample rate 1 */
+
+#define AD_AC97_ACIC 0x180 /* ac97 codec interface control */
+#define AD_AC97_ACIC_ACIE 0x0001 /* analog codec interface enable */
+#define AD_AC97_ACIC_ACRD 0x0002 /* analog codec reset disable */
+#define AD_AC97_ACIC_ASOE 0x0004 /* audio stream output enable */
+#define AD_AC97_ACIC_VSRM 0x0008 /* variable sample rate mode */
+#define AD_AC97_ACIC_FSDH 0x0100 /* force SDATA_OUT high */
+#define AD_AC97_ACIC_FSYH 0x0200 /* force sync high */
+#define AD_AC97_ACIC_ACRDY 0x8000 /* analog codec ready status */
+/* bits 10 -> 14 reserved */
+
+
+#define AD_DS_MEMSIZE 512
+#define AD_OPL_MEMSIZE 16
+#define AD_MIDI_MEMSIZE 16
+
+#define AD_WAV_STATE 0
+#define AD_ADC_STATE 1
+#define AD_MAX_STATES 2
+
+#define AD_CHAN_WAV 0x0001
+#define AD_CHAN_ADC 0x0002
+#define AD_CHAN_RES 0x0004
+#define AD_CHAN_SYN 0x0008
+
+
+/* The chip would support 4 GB buffers and 16 MB periods,
+ * but let's not overdo it ... */
+#define BUFFER_BYTES_MAX (256 * 1024)
+#define PERIOD_BYTES_MIN 32
+#define PERIOD_BYTES_MAX (BUFFER_BYTES_MAX / 2)
+#define PERIODS_MIN 2
+#define PERIODS_MAX (BUFFER_BYTES_MAX / PERIOD_BYTES_MIN)
+
+#endif /* __AD1889_H__ */
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 4943299cf137..f35b558c29b2 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -78,15 +78,7 @@ MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
* Constants definition
*/
-#ifndef PCI_VENDOR_ID_ALI
-#define PCI_VENDOR_ID_ALI 0x10b9
-#endif
-
-#ifndef PCI_DEVICE_ID_ALI_5451
-#define PCI_DEVICE_ID_ALI_5451 0x5451
-#endif
-
-#define DEVICE_ID_ALI5451 ((PCI_VENDOR_ID_ALI<<16)|PCI_DEVICE_ID_ALI_5451)
+#define DEVICE_ID_ALI5451 ((PCI_VENDOR_ID_AL<<16)|PCI_DEVICE_ID_AL_M5451)
#define ALI_CHANNELS 32
@@ -326,13 +318,12 @@ static void ali_read_regs(ali_t *codec, int channel)
static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
{
unsigned int dwVal;
- struct pci_dev *pci_dev = NULL;
+ struct pci_dev *pci_dev;
int i,j;
-
- pci_dev = pci_find_device(vendor, deviceid, pci_dev);
- if (pci_dev == NULL)
- return ;
+ pci_dev = pci_get_device(vendor, deviceid, NULL);
+ if (pci_dev == NULL)
+ return ;
printk("\nM%x PCI CFG\n", deviceid);
printk(" ");
@@ -349,6 +340,7 @@ static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
}
printk("\n");
}
+ pci_dev_put(pci_dev);
}
static void ali_read_ac97regs(ali_t *codec, int secondary)
{
@@ -2001,8 +1993,10 @@ static int __devinit snd_ali_mixer(ali_t * codec)
if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
snd_printk("ali mixer %d creating error.\n", i);
if(i == 0)
- return err;
- }
+ return err;
+ codec->num_of_codecs = 1;
+ break;
+ }
}
if (codec->spdif_support) {
@@ -2116,6 +2110,8 @@ static int snd_ali_free(ali_t * codec)
#ifdef CONFIG_PM
kfree(codec->image);
#endif
+ pci_dev_put(codec->pci_m1533);
+ pci_dev_put(codec->pci_m7101);
kfree(codec);
return 0;
}
@@ -2305,7 +2301,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
codec->chregs.data.ainten = 0x00;
/* M1533: southbridge */
- pci_dev = pci_find_device(0x10b9, 0x1533, NULL);
+ pci_dev = pci_get_device(0x10b9, 0x1533, NULL);
codec->pci_m1533 = pci_dev;
if (! codec->pci_m1533) {
snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
@@ -2313,7 +2309,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
return -ENODEV;
}
/* M7101: power management */
- pci_dev = pci_find_device(0x10b9, 0x7101, NULL);
+ pci_dev = pci_get_device(0x10b9, 0x7101, NULL);
codec->pci_m7101 = pci_dev;
if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
@@ -2417,6 +2413,7 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ALI 5451",
+ .owner = THIS_MODULE,
.id_table = snd_ali_ids,
.probe = snd_ali_probe,
.remove = __devexit_p(snd_ali_remove),
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index ca28b229c704..196ec1c61bb4 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -770,6 +770,7 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ALS4000",
+ .owner = THIS_MODULE,
.id_table = snd_als4000_ids,
.probe = snd_card_als4000_probe,
.remove = __devexit_p(snd_card_als4000_remove),
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 188df085b7ee..241eacf1e652 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1453,6 +1453,7 @@ static int snd_atiixp_resume(snd_card_t *card)
atiixp_dma_t *dma = &chip->dmas[i];
if (dma->substream && dma->suspended) {
dma->ops->enable_dma(chip, 1);
+ dma->substream->ops->prepare(dma->substream);
writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
chip->remap_addr + dma->ops->llp_offset);
writel(dma->saved_curptr, chip->remap_addr + dma->ops->dt_cur);
@@ -1530,7 +1531,7 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1644,6 +1645,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ATI IXP AC97 controller",
+ .owner = THIS_MODULE,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 8d2002951bd7..c1a239a4dac6 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -405,7 +405,7 @@ static int snd_atiixp_acquire_codec(atiixp_t *chip)
while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) {
if (! timeout--) {
- snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n");
+ snd_printk(KERN_WARNING "atiixp-modem: codec acquire timeout\n");
return -EBUSY;
}
udelay(1);
@@ -436,7 +436,7 @@ static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec
} while (--timeout);
/* time out may happen during reset */
if (reg < 0x7c)
- snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg);
+ snd_printk(KERN_WARNING "atiixp-modem: codec read timeout (reg %x)\n", reg);
return 0xffff;
}
@@ -498,7 +498,7 @@ static int snd_atiixp_aclink_reset(atiixp_t *chip)
do_delay();
atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
if (--timeout) {
- snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
+ snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n");
break;
}
}
@@ -552,7 +552,7 @@ static int snd_atiixp_codec_detect(atiixp_t *chip)
atiixp_write(chip, IER, 0); /* disable irqs */
if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) {
- snd_printk(KERN_ERR "atiixp: no codec detected!\n");
+ snd_printk(KERN_ERR "atiixp-modem: no codec detected!\n");
return -ENXIO;
}
return 0;
@@ -635,7 +635,7 @@ static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma)
{
if (! dma->substream || ! dma->running)
return;
- snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type);
+ snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type);
snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
}
@@ -1081,14 +1081,14 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
ac97.scaps = AC97_SCAP_SKIP_AUDIO;
if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
chip->ac97[i] = NULL; /* to be sure */
- snd_printdd("atiixp: codec %d not available for modem\n", i);
+ snd_printdd("atiixp-modem: codec %d not available for modem\n", i);
continue;
}
codec_count++;
}
if (! codec_count) {
- snd_printk(KERN_ERR "atiixp: no codec available\n");
+ snd_printk(KERN_ERR "atiixp-modem: no codec available\n");
return -ENODEV;
}
@@ -1159,7 +1159,7 @@ static void __devinit snd_atiixp_proc_init(atiixp_t *chip)
{
snd_info_entry_t *entry;
- if (! snd_card_proc_new(chip->card, "atiixp", &entry))
+ if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry))
snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read);
}
@@ -1208,7 +1208,7 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1318,6 +1318,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ATI IXP MC97 controller",
+ .owner = THIS_MODULE,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index f6236c63aaaa..04b695d6fd48 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -79,19 +79,21 @@ static void vortex_fix_agp_bridge(struct pci_dev *via)
static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
{
- struct pci_dev *via;
+ struct pci_dev *via = NULL;
/* autodetect if workarounds are required */
if (fix == 255) {
/* VIA KT133 */
- via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL);
+ via = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8365_1, NULL);
/* VIA Apollo */
if (via == NULL) {
- via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL);
- }
- /* AMD Irongate */
- if (via == NULL) {
- via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
+ via = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C598_1, NULL);
+ /* AMD Irongate */
+ if (via == NULL)
+ via = pci_get_device(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
}
if (via) {
printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n");
@@ -101,13 +103,17 @@ static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
} else {
if (fix & 0x1)
vortex_fix_latency(vortex);
- if ((fix & 0x2) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL)))
+ if ((fix & 0x2) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8365_1, NULL)))
vortex_fix_agp_bridge(via);
- if ((fix & 0x4) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL)))
+ if ((fix & 0x4) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C598_1, NULL)))
vortex_fix_agp_bridge(via);
- if ((fix & 0x8) && (via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
+ if ((fix & 0x8) && (via = pci_get_device(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
vortex_fix_agp_bridge(via);
}
+ pci_dev_put(via);
}
// component-destructor
@@ -150,7 +156,7 @@ snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
}
pci_set_dma_mask(pci, VORTEX_DMA_MASK);
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
@@ -367,6 +373,7 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
// pci_driver definition
static struct pci_driver driver = {
.name = CARD_NAME_SHORT,
+ .owner = THIS_MODULE,
.id_table = snd_vortex_ids,
.probe = snd_vortex_probe,
.remove = __devexit_p(snd_vortex_remove),
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 72bba7b2d983..d5261bdec583 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1345,7 +1345,7 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1511,6 +1511,7 @@ static void __devexit snd_azf3328_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "AZF3328",
+ .owner = THIS_MODULE,
.id_table = snd_azf3328_ids,
.probe = snd_azf3328_probe,
.remove = __devexit_p(snd_azf3328_remove),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index c5557eaf3e2e..2236c958aec0 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -59,16 +59,6 @@ module_param(load_all, bool, 0444);
MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
-#ifndef PCI_VENDOR_ID_BROOKTREE
-#define PCI_VENDOR_ID_BROOKTREE 0x109e
-#endif
-#ifndef PCI_DEVICE_ID_BROOKTREE_878
-#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
-#endif
-#ifndef PCI_DEVICE_ID_BROOKTREE_879
-#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
-#endif
-
/* register offsets */
#define REG_INT_STAT 0x100 /* interrupt status */
#define REG_INT_MASK 0x104 /* interrupt mask */
@@ -720,7 +710,7 @@ static int __devinit snd_bt87x_create(snd_card_t *card,
if (err < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
@@ -911,6 +901,7 @@ static struct pci_device_id snd_bt87x_default_ids[] = {
static struct pci_driver driver = {
.name = "Bt87x",
+ .owner = THIS_MODULE,
.id_table = snd_bt87x_ids,
.probe = snd_bt87x_probe,
.remove = __devexit_p(snd_bt87x_remove),
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 7e27bfc37439..ba07960921d8 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -352,7 +352,7 @@ static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream,
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
@@ -419,7 +419,7 @@ static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, i
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL) {
snd_printk("open_capture_channel: failed epcm alloc\n");
return -ENOMEM;
@@ -1144,7 +1144,7 @@ static int __devinit snd_ca0106_create(snd_card_t *card,
return -ENXIO;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1390,6 +1390,7 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
// pci_driver definition
static struct pci_driver driver = {
.name = "CA0106",
+ .owner = THIS_MODULE,
.id_table = snd_ca0106_ids,
.probe = snd_ca0106_probe,
.remove = __devexit_p(snd_ca0106_remove),
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index b6b8882ce704..c10e4a54301b 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -482,7 +482,7 @@ static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol,
static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Front Volume",
+ .name = "Analog Front Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_analog_front,
.put = snd_ca0106_volume_put_analog_front
@@ -490,7 +490,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Center/LFE Volume",
+ .name = "Analog Center/LFE Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_analog_center_lfe,
.put = snd_ca0106_volume_put_analog_center_lfe
@@ -498,7 +498,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Side Volume",
+ .name = "Analog Side Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_analog_unknown,
.put = snd_ca0106_volume_put_analog_unknown
@@ -506,7 +506,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Rear Volume",
+ .name = "Analog Rear Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_analog_rear,
.put = snd_ca0106_volume_put_analog_rear
@@ -514,7 +514,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Front Volume",
+ .name = "SPDIF Front Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_spdif_front,
.put = snd_ca0106_volume_put_spdif_front
@@ -522,7 +522,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Center/LFE Volume",
+ .name = "SPDIF Center/LFE Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_spdif_center_lfe,
.put = snd_ca0106_volume_put_spdif_center_lfe
@@ -530,7 +530,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Unknown Volume",
+ .name = "SPDIF Unknown Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_spdif_unknown,
.put = snd_ca0106_volume_put_spdif_unknown
@@ -538,7 +538,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Rear Volume",
+ .name = "SPDIF Rear Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_spdif_rear,
.put = snd_ca0106_volume_put_spdif_rear
@@ -547,7 +547,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
static snd_kcontrol_new_t snd_ca0106_volume_control_feedback =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CAPTURE feedback into PLAYBACK",
+ .name = "CAPTURE feedback Playback Volume",
.info = snd_ca0106_volume_info,
.get = snd_ca0106_volume_get_feedback,
.put = snd_ca0106_volume_put_feedback
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index b098b51099c2..1eb3315d136d 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -79,13 +79,6 @@ module_param_array(joystick_port, int, NULL, 0444);
MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
-#endif
-
/*
* CM8x38 registers definition
*/
@@ -348,25 +341,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
/*
- * pci ids
- */
-#ifndef PCI_VENDOR_ID_CMEDIA
-#define PCI_VENDOR_ID_CMEDIA 0x13F6
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
-#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
-#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
-#endif
-
-/*
* channels for playback / capture
*/
#define CM_CH_PLAY 0
@@ -2801,7 +2775,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
if ((err = pci_enable_device(pci)) < 0)
return err;
- cm = kcalloc(1, sizeof(*cm), GFP_KERNEL);
+ cm = kzalloc(sizeof(*cm), GFP_KERNEL);
if (cm == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -3063,6 +3037,7 @@ static void __devexit snd_cmipci_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "C-Media PCI",
+ .owner = THIS_MODULE,
.id_table = snd_cmipci_ids,
.probe = snd_cmipci_probe,
.remove = __devexit_p(snd_cmipci_remove),
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index c7a370d4f923..dc87e0144b5a 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -57,17 +57,6 @@ module_param_array(dual_codec, bool, NULL, 0444);
MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled).");
/*
- *
- */
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS 0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4281
-#define PCI_DEVICE_ID_CIRRUS_4281 0x6005
-#endif
-
-/*
* Direct registers
*/
@@ -1394,7 +1383,7 @@ static int __devinit snd_cs4281_create(snd_card_t * card,
*rchip = NULL;
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2119,6 +2108,7 @@ static int cs4281_resume(snd_card_t *card)
static struct pci_driver driver = {
.name = "CS4281",
+ .owner = THIS_MODULE,
.id_table = snd_cs4281_ids,
.probe = snd_cs4281_probe,
.remove = __devexit_p(snd_cs4281_remove),
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index b9fff4ee6f9d..32b4f8465cef 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -163,6 +163,7 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Sound Fusion CS46xx",
+ .owner = THIS_MODULE,
.id_table = snd_cs46xx_ids,
.probe = snd_card_cs46xx_probe,
.remove = __devexit_p(snd_card_cs46xx_remove),
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 4b052158ee33..6e3855b8b33d 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1304,7 +1304,7 @@ static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pc
cs46xx_pcm_t * cpcm;
snd_pcm_runtime_t *runtime = substream->runtime;
- cpcm = kcalloc(1, sizeof(*cpcm), GFP_KERNEL);
+ cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
if (cpcm == NULL)
return -ENOMEM;
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
@@ -3525,17 +3525,6 @@ static void amp_voyetra_4294(cs46xx_t *chip, int change)
/*
- * piix4 pci ids
- */
-#ifndef PCI_VENDOR_ID_INTEL
-#define PCI_VENDOR_ID_INTEL 0x8086
-#endif /* PCI_VENDOR_ID_INTEL */
-
-#ifndef PCI_DEVICE_ID_INTEL_82371AB_3
-#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#endif /* PCI_DEVICE_ID_INTEL_82371AB_3 */
-
-/*
* Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
* whenever we need to beat on the chip.
*
@@ -3548,7 +3537,7 @@ static void clkrun_hack(cs46xx_t *chip, int change)
{
u16 control, nval;
- if (chip->acpi_dev == NULL)
+ if (!chip->acpi_port)
return;
chip->amplifier += change;
@@ -3571,15 +3560,20 @@ static void clkrun_hack(cs46xx_t *chip, int change)
*/
static void clkrun_init(cs46xx_t *chip)
{
+ struct pci_dev *pdev;
u8 pp;
- chip->acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
- if (chip->acpi_dev == NULL)
+ chip->acpi_port = 0;
+
+ pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+ if (pdev == NULL)
return; /* Not a thinkpad thats for sure */
/* Find the control port */
- pci_read_config_byte(chip->acpi_dev, 0x41, &pp);
+ pci_read_config_byte(pdev, 0x41, &pp);
chip->acpi_port = pp << 8;
+ pci_dev_put(pdev);
}
@@ -3780,7 +3774,7 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index fc377c4b666c..b0e00f0a7c2f 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -223,6 +223,7 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "EMU10K1_Audigy",
+ .owner = THIS_MODULE,
.id_table = snd_emu10k1_ids,
.probe = snd_card_emu10k1_probe,
.remove = __devexit_p(snd_card_emu10k1_remove),
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index e69d5b739e80..e9cd8e054f25 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -754,12 +754,14 @@ static emu_chip_details_t emu_chip_details[] = {
.emu10k1_chip = 1,
.ac97_chip = 1,
.sblive51 = 1} ,
- /* Tested by alsa bugtrack user "hus" 12th Sept 2005 */
+ /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
- .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]",
+ .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]",
.id = "Live",
.emu10k1_chip = 1,
- .ac97_chip = 1,
+ .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
+ * share the same IDs!
+ */
.sblive51 = 1} ,
{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
.driver = "EMU10K1", .name = "SBLive! Value [CT4850]",
@@ -865,7 +867,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
+ emu = kzalloc(sizeof(*emu), GFP_KERNEL);
if (emu == NULL) {
pci_disable_device(pci);
return -ENOMEM;
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 52c7826df440..ad15755a63c3 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -395,7 +395,7 @@ static int snd_emu10k1x_playback_open(snd_pcm_substream_t *substream)
if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
return err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
epcm->emu = chip;
@@ -571,7 +571,7 @@ static int snd_emu10k1x_pcm_open_capture(snd_pcm_substream_t *substream)
if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
return err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
@@ -920,7 +920,7 @@ static int __devinit snd_emu10k1x_create(snd_card_t *card,
return -ENXIO;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1615,6 +1615,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
// pci_driver definition
static struct pci_driver driver = {
.name = "EMU10K1X",
+ .owner = THIS_MODULE,
.id_table = snd_emu10k1x_ids,
.probe = snd_emu10k1x_probe,
.remove = __devexit_p(snd_emu10k1x_remove),
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 637c555cfdb1..646b5d972e6f 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -470,7 +470,7 @@ static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr
{
u_int32_t *code;
snd_assert(*ptr < 512, return);
- code = (u_int32_t *)icode->code + (*ptr) * 2;
+ code = (u_int32_t __force *)icode->code + (*ptr) * 2;
set_bit(*ptr, icode->code_valid);
code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
@@ -485,7 +485,7 @@ static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned i
{
u_int32_t *code;
snd_assert(*ptr < 1024, return);
- code = (u_int32_t *)icode->code + (*ptr) * 2;
+ code = (u_int32_t __force *)icode->code + (*ptr) * 2;
set_bit(*ptr, icode->code_valid);
code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
@@ -1036,13 +1036,13 @@ static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
spin_lock_init(&emu->fx8010.irq_lock);
INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
- if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
+ if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
(icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
(controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
err = -ENOMEM;
goto __err;
}
- gpr_map = (u32 *)icode->gpr_map;
+ gpr_map = (u32 __force *)icode->gpr_map;
icode->tram_data_map = icode->gpr_map + 512;
icode->tram_addr_map = icode->tram_data_map + 256;
@@ -1431,7 +1431,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
__err:
kfree(controls);
if (icode != NULL) {
- kfree((void *)icode->gpr_map);
+ kfree((void __force *)icode->gpr_map);
kfree(icode);
}
return err;
@@ -1503,15 +1503,15 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
spin_lock_init(&emu->fx8010.irq_lock);
INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
- if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
+ if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
return -ENOMEM;
if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
(controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
- (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
+ (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
err = -ENOMEM;
goto __err;
}
- gpr_map = (u32 *)icode->gpr_map;
+ gpr_map = (u32 __force *)icode->gpr_map;
icode->tram_data_map = icode->gpr_map + 256;
icode->tram_addr_map = icode->tram_data_map + 160;
@@ -2032,7 +2032,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
kfree(ipcm);
kfree(controls);
if (icode != NULL) {
- kfree((void *)icode->gpr_map);
+ kfree((void __force *)icode->gpr_map);
kfree(icode);
}
return err;
@@ -2217,7 +2217,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
kfree(ipcm);
return res;
case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
- ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
+ ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
if (ipcm == NULL)
return -ENOMEM;
if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index d71a72e84bcc..7cc831ccd0cb 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -810,8 +810,14 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu,
ac97.private_data = emu;
ac97.private_free = snd_emu10k1_mixer_free_ac97;
ac97.scaps = AC97_SCAP_NO_SPDIF;
- if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
- return err;
+ if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) {
+ if (emu->card_capabilities->ac97_chip == 1)
+ return err;
+ snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n");
+ snd_printd(KERN_INFO" Proceeding without ac97 mixers...\n");
+ snd_device_free(emu->card, pbus);
+ goto no_ac97; /* FIXME: get rid of ugly gotos.. */
+ }
if (emu->audigy) {
/* set master volume to 0 dB */
snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
@@ -836,6 +842,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu,
for (; *c; c++)
remove_ctl(card, *c);
} else {
+ no_ac97:
if (emu->card_capabilities->ecard)
strcpy(emu->card->mixername, "EMU APS");
else if (emu->audigy)
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 9c35f6dde1b5..66ba27afe962 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1016,7 +1016,7 @@ static int snd_emu10k1_efx_playback_open(snd_pcm_substream_t * substream)
snd_pcm_runtime_t *runtime = substream->runtime;
int i;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
epcm->emu = emu;
@@ -1049,7 +1049,7 @@ static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream)
snd_pcm_runtime_t *runtime = substream->runtime;
int i, err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
epcm->emu = emu;
@@ -1094,7 +1094,7 @@ static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream)
snd_pcm_runtime_t *runtime = substream->runtime;
emu10k1_pcm_t *epcm;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
epcm->emu = emu;
@@ -1130,7 +1130,7 @@ static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream)
emu10k1_pcm_t *epcm;
snd_pcm_runtime_t *runtime = substream->runtime;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
epcm->emu = emu;
@@ -1170,7 +1170,7 @@ static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream)
int nefx = emu->audigy ? 64 : 32;
int idx;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
return -ENOMEM;
epcm->emu = emu;
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index a1691330d3b6..d59c7f345ad6 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -178,7 +178,7 @@ static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, in
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
//snd_printk("epcm kcalloc: %p\n", epcm);
if (epcm == NULL)
@@ -214,7 +214,7 @@ static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+ epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
//snd_printk("epcm kcalloc: %p\n", epcm);
if (epcm == NULL)
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index f06b95f41a1d..bef9a59f46d7 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -100,13 +100,6 @@ MODULE_PARM_DESC(joystick, "Enable joystick.");
#endif
#endif /* SUPPORT_JOYSTICK */
-#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
-#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
-#endif
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-#endif
-
/* ES1371 chip ID */
/* This is a little confusing because all ES1371 compatible chips have the
same DEVICE_ID, the only thing differentiating them is the REV_ID field.
@@ -1950,7 +1943,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
*rensoniq = NULL;
if ((err = pci_enable_device(pci)) < 0)
return err;
- ensoniq = kcalloc(1, sizeof(*ensoniq), GFP_KERNEL);
+ ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
if (ensoniq == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2394,6 +2387,7 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = DRIVER_NAME,
+ .owner = THIS_MODULE,
.id_table = snd_audiopci_ids,
.probe = snd_audiopci_probe,
.remove = __devexit_p(snd_audiopci_remove),
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index b492777bc30f..17fa80c23870 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -76,13 +76,6 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES1938},"
#define SUPPORT_JOYSTICK 1
#endif
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS 0x125d
-#endif
-#ifndef PCI_DEVICE_ID_ESS_ES1938
-#define PCI_DEVICE_ID_ESS_ES1938 0x1969
-#endif
-
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
@@ -1501,7 +1494,7 @@ static int __devinit snd_es1938_create(snd_card_t * card,
return -ENXIO;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1753,6 +1746,7 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ESS ES1938 (Solo-1)",
+ .owner = THIS_MODULE,
.id_table = snd_es1938_ids,
.probe = snd_es1938_probe,
.remove = __devexit_p(snd_es1938_remove),
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 9d7a28783930..ecdcada90ca2 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -160,25 +160,6 @@ MODULE_PARM_DESC(joystick, "Enable joystick.");
#endif
-/* PCI Dev ID's */
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS 0x125D
-#endif
-
-#define PCI_VENDOR_ID_ESS_OLD 0x1285 /* Platform Tech, the people the ESS
- was bought form */
-
-#ifndef PCI_DEVICE_ID_ESS_M2E
-#define PCI_DEVICE_ID_ESS_M2E 0x1978
-#endif
-#ifndef PCI_DEVICE_ID_ESS_M2
-#define PCI_DEVICE_ID_ESS_M2 0x1968
-#endif
-#ifndef PCI_DEVICE_ID_ESS_M1
-#define PCI_DEVICE_ID_ESS_M1 0x0100
-#endif
-
#define NR_APUS 64
#define NR_APU_REGS 16
@@ -1596,7 +1577,7 @@ static int snd_es1968_playback_open(snd_pcm_substream_t *substream)
if (apu1 < 0)
return apu1;
- es = kcalloc(1, sizeof(*es), GFP_KERNEL);
+ es = kzalloc(sizeof(*es), GFP_KERNEL);
if (!es) {
snd_es1968_free_apu_pair(chip, apu1);
return -ENOMEM;
@@ -1641,7 +1622,7 @@ static int snd_es1968_capture_open(snd_pcm_substream_t *substream)
return apu2;
}
- es = kcalloc(1, sizeof(*es), GFP_KERNEL);
+ es = kzalloc(sizeof(*es), GFP_KERNEL);
if (!es) {
snd_es1968_free_apu_pair(chip, apu1);
snd_es1968_free_apu_pair(chip, apu2);
@@ -2588,7 +2569,7 @@ static int __devinit snd_es1968_create(snd_card_t * card,
return -ENXIO;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (! chip) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2782,6 +2763,7 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ES1968 (ESS Maestro)",
+ .owner = THIS_MODULE,
.id_table = snd_es1968_ids,
.probe = snd_es1968_probe,
.remove = __devexit_p(snd_es1968_remove),
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 36b2f62e8573..e5cfa2a0c246 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1263,7 +1263,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
*rchip = NULL;
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1462,6 +1462,7 @@ static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "FM801",
+ .owner = THIS_MODULE,
.id_table = snd_fm801_ids,
.probe = snd_card_fm801_probe,
.remove = __devexit_p(snd_card_fm801_remove),
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 20f7762f7144..3815403ed095 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -288,7 +288,7 @@ static int init_unsol_queue(struct hda_bus *bus)
{
struct hda_bus_unsolicited *unsol;
- unsol = kcalloc(1, sizeof(*unsol), GFP_KERNEL);
+ unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
if (! unsol) {
snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
return -ENOMEM;
@@ -358,7 +358,7 @@ int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
if (busp)
*busp = NULL;
- bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (bus == NULL) {
snd_printk(KERN_ERR "can't allocate struct hda_bus\n");
return -ENOMEM;
@@ -493,7 +493,7 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
return -EBUSY;
}
- codec = kcalloc(1, sizeof(*codec), GFP_KERNEL);
+ codec = kzalloc(sizeof(*codec), GFP_KERNEL);
if (codec == NULL) {
snd_printk(KERN_ERR "can't allocate struct hda_codec\n");
return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 63a29a8a2860..bb53bcf76742 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -505,6 +505,7 @@ struct hda_pcm_stream {
struct hda_pcm {
char *name;
struct hda_pcm_stream stream[2];
+ unsigned int is_modem; /* modem codec? */
};
/* codec information */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1229227af5b5..d0eb9f2250aa 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -98,7 +98,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
struct hda_gnode *node;
int nconns;
- node = kcalloc(1, sizeof(*node), GFP_KERNEL);
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
if (node == NULL)
return -ENOMEM;
node->nid = nid;
@@ -881,12 +881,10 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec)
struct hda_gspec *spec;
int err;
- if(!codec->afg) {
- snd_printdd("hda_generic: no generic modem yet\n");
- return -ENODEV;
- }
+ if(!codec->afg)
+ return 0;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL) {
printk(KERN_ERR "hda_generic: can't allocate spec\n");
return -ENOMEM;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 15107df1f490..6fe696e53ea6 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -62,7 +62,7 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
module_param_array(model, charp, NULL, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
module_param_array(position_fix, int, NULL, 0444);
-MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF).");
+MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
@@ -164,7 +164,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
/* max buffer size - no h/w limit, you can increase as you like */
#define AZX_MAX_BUF_SIZE (1024*1024*1024)
/* max number of PCM devics per card */
-#define AZX_MAX_PCMS 8
+#define AZX_MAX_AUDIO_PCMS 6
+#define AZX_MAX_MODEM_PCMS 2
+#define AZX_MAX_PCMS (AZX_MAX_AUDIO_PCMS + AZX_MAX_MODEM_PCMS)
/* RIRB int mask: overrun[2], response[0] */
#define RIRB_INT_RESPONSE 0x01
@@ -211,9 +213,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
/* position fix mode */
enum {
- POS_FIX_FIFO,
+ POS_FIX_AUTO,
POS_FIX_NONE,
- POS_FIX_POSBUF
+ POS_FIX_POSBUF,
+ POS_FIX_FIFO,
};
/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -243,6 +246,7 @@ struct snd_azx_dev {
unsigned int fragsize; /* size of each period in bytes */
unsigned int frags; /* number for period in the play buffer */
unsigned int fifo_size; /* FIFO size */
+ unsigned int last_pos; /* last updated period position */
void __iomem *sd_addr; /* stream descriptor pointer */
@@ -256,6 +260,7 @@ struct snd_azx_dev {
unsigned int opened: 1;
unsigned int running: 1;
+ unsigned int period_updating: 1;
};
/* CORB/RIRB */
@@ -724,11 +729,9 @@ static void azx_init_chip(azx_t *chip)
/* initialize the codec command I/O */
azx_init_cmd_io(chip);
- if (chip->position_fix == POS_FIX_POSBUF) {
- /* program the position buffer */
- azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
- azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
- }
+ /* program the position buffer */
+ azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
+ azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
/* For ATI SB450 azalia HD audio, we need to enable snoop */
if (chip->driver_type == AZX_DRIVER_ATI) {
@@ -763,9 +766,11 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs)
if (status & azx_dev->sd_int_sta_mask) {
azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
if (azx_dev->substream && azx_dev->running) {
+ azx_dev->period_updating = 1;
spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(azx_dev->substream);
spin_lock(&chip->reg_lock);
+ azx_dev->period_updating = 0;
}
}
}
@@ -866,11 +871,9 @@ static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev)
/* upper BDL address */
azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr));
- if (chip->position_fix == POS_FIX_POSBUF) {
- /* enable the position buffer */
- if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
- azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
- }
+ /* enable the position buffer */
+ if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
+ azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
/* set the interrupt enable bits in the descriptor control register */
azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
@@ -1078,6 +1081,7 @@ static int azx_pcm_prepare(snd_pcm_substream_t *substream)
azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
else
azx_dev->fifo_size = 0;
+ azx_dev->last_pos = 0;
return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag,
azx_dev->format_val, substream);
@@ -1133,6 +1137,31 @@ static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
pos = azx_sd_readl(azx_dev, SD_LPIB);
if (chip->position_fix == POS_FIX_FIFO)
pos += azx_dev->fifo_size;
+#if 0 /* disabled temprarily, auto-correction doesn't work well... */
+ else if (chip->position_fix == POS_FIX_AUTO && azx_dev->period_updating) {
+ /* check the validity of DMA position */
+ unsigned int diff = 0;
+ azx_dev->last_pos += azx_dev->fragsize;
+ if (azx_dev->last_pos > pos)
+ diff = azx_dev->last_pos - pos;
+ if (azx_dev->last_pos >= azx_dev->bufsize) {
+ if (pos < azx_dev->fragsize)
+ diff = 0;
+ azx_dev->last_pos = 0;
+ }
+ if (diff > 0 && diff <= azx_dev->fifo_size)
+ pos += azx_dev->fifo_size;
+ else {
+ snd_printdd(KERN_INFO "hda_intel: DMA position fix %d, switching to posbuf\n", diff);
+ chip->position_fix = POS_FIX_POSBUF;
+ pos = *azx_dev->posbuf;
+ }
+ azx_dev->period_updating = 0;
+ }
+#else
+ else if (chip->position_fix == POS_FIX_AUTO)
+ pos += azx_dev->fifo_size;
+#endif
}
if (pos >= azx_dev->bufsize)
pos = 0;
@@ -1203,12 +1232,33 @@ static int __devinit azx_pcm_create(azx_t *chip)
if ((err = snd_hda_build_pcms(chip->bus)) < 0)
return err;
+ /* create audio PCMs */
pcm_dev = 0;
list_for_each(p, &chip->bus->codec_list) {
codec = list_entry(p, struct hda_codec, list);
for (c = 0; c < codec->num_pcms; c++) {
+ if (codec->pcm_info[c].is_modem)
+ continue; /* create later */
+ if (pcm_dev >= AZX_MAX_AUDIO_PCMS) {
+ snd_printk(KERN_ERR SFX "Too many audio PCMs\n");
+ return -EINVAL;
+ }
+ err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
+ if (err < 0)
+ return err;
+ pcm_dev++;
+ }
+ }
+
+ /* create modem PCMs */
+ pcm_dev = AZX_MAX_AUDIO_PCMS;
+ list_for_each(p, &chip->bus->codec_list) {
+ codec = list_entry(p, struct hda_codec, list);
+ for (c = 0; c < codec->num_pcms; c++) {
+ if (! codec->pcm_info[c].is_modem)
+ continue; /* already created */
if (pcm_dev >= AZX_MAX_PCMS) {
- snd_printk(KERN_ERR SFX "Too many PCMs\n");
+ snd_printk(KERN_ERR SFX "Too many modem PCMs\n");
return -EINVAL;
}
err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
@@ -1244,8 +1294,7 @@ static int __devinit azx_init_stream(azx_t *chip)
azx_dev_t *azx_dev = &chip->azx_dev[i];
azx_dev->bdl = (u32 *)(chip->bdl.area + off);
azx_dev->bdl_addr = chip->bdl.addr + off;
- if (chip->position_fix == POS_FIX_POSBUF)
- azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
+ azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
/* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
/* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
@@ -1358,7 +1407,7 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (NULL == chip) {
snd_printk(KERN_ERR SFX "cannot allocate chip\n");
@@ -1437,13 +1486,11 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
goto errout;
}
- if (chip->position_fix == POS_FIX_POSBUF) {
- /* allocate memory for the position buffer */
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- chip->num_streams * 8, &chip->posbuf)) < 0) {
- snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
- goto errout;
- }
+ /* allocate memory for the position buffer */
+ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+ chip->num_streams * 8, &chip->posbuf)) < 0) {
+ snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
+ goto errout;
}
/* allocate CORB/RIRB */
if ((err = azx_alloc_cmd_io(chip)) < 0)
@@ -1561,6 +1608,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
/* pci_driver definition */
static struct pci_driver driver = {
.name = "HDA Intel",
+ .owner = THIS_MODULE,
.id_table = azx_ids,
.probe = azx_probe,
.remove = __devexit_p(azx_remove),
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index de1217bd8e68..08f6a6efc5e6 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -207,6 +207,8 @@ static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id);
snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id);
snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
+ if (! codec->afg)
+ return;
snd_iprintf(buffer, "Default PCM: ");
print_pcm_caps(buffer, codec, codec->afg);
snd_iprintf(buffer, "Default Amp-In caps: ");
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index bceb83a42a38..da6874d3988c 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -465,7 +465,7 @@ static int patch_ad1986a(struct hda_codec *codec)
{
struct ad198x_spec *spec;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -623,7 +623,7 @@ static int patch_ad1983(struct hda_codec *codec)
{
struct ad198x_spec *spec;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -764,7 +764,7 @@ static int patch_ad1981(struct hda_codec *codec)
{
struct ad198x_spec *spec;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 07fb4f5a54b3..523c362ec44d 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -667,7 +667,7 @@ static int patch_cmi9880(struct hda_codec *codec)
{
struct cmi_spec *spec;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index eeb900ab79af..7327deb6df9f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1385,8 +1385,8 @@ static snd_kcontrol_new_t alc880_test_mixer[] = {
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- ALC_BIND_MUTE("CLFE Playback Volume", 0x0e, 2, HDA_INPUT),
- ALC_BIND_MUTE("Side Playback Volume", 0x0f, 2, HDA_INPUT),
+ ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
+ ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
PIN_CTL_TEST("Front Pin Mode", 0x14),
PIN_CTL_TEST("Surround Pin Mode", 0x15),
PIN_CTL_TEST("CLFE Pin Mode", 0x16),
@@ -1409,18 +1409,6 @@ static snd_kcontrol_new_t alc880_test_mixer[] = {
HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .count = 2,
- .info = alc_mux_enum_info,
- .get = alc_mux_enum_get,
- .put = alc_mux_enum_put,
- },
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Channel Mode",
@@ -1526,6 +1514,7 @@ static struct hda_board_config alc880_cfg_tbl[] = {
/* Back 3 jack, front 2 jack (Internal add Aux-In) */
{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST },
+ { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
@@ -1581,6 +1570,7 @@ static struct hda_board_config alc880_cfg_tbl[] = {
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
@@ -2093,7 +2083,7 @@ static int patch_alc880(struct hda_codec *codec)
int board_config;
int i, err;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -2241,7 +2231,7 @@ static snd_kcontrol_new_t alc260_base_mixer[] = {
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
+ ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
{
@@ -2268,7 +2258,7 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = {
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
+ ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
{
@@ -2365,7 +2355,7 @@ static int patch_alc260(struct hda_codec *codec)
struct alc_spec *spec;
int board_config;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -2499,7 +2489,7 @@ static snd_kcontrol_new_t alc882_base_mixer[] = {
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_OUTPUT),
+ ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -2615,7 +2605,7 @@ static int patch_alc882(struct hda_codec *codec)
{
struct alc_spec *spec;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index b0270d1b64ce..d014b7bb70df 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -214,6 +214,7 @@ static int si3054_build_pcms(struct hda_codec *codec)
info->name = "Si3054 Modem";
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
+ info->is_modem = 1;
return 0;
}
@@ -282,7 +283,7 @@ static struct hda_codec_ops si3054_patch_ops = {
static int patch_si3054(struct hda_codec *codec)
{
- struct si3054_spec *spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ struct si3054_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
codec->spec = spec;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9d503da7320d..33a8adaea768 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -919,7 +919,7 @@ static int patch_stac9200(struct hda_codec *codec)
struct sigmatel_spec *spec;
int err;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -957,7 +957,7 @@ static int patch_stac922x(struct hda_codec *codec)
struct sigmatel_spec *spec;
int err;
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 4405d96cbedf..2e0a31613ee6 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1796,7 +1796,7 @@ static int __devinit aureon_init(ice1712_t *ice)
}
/* to remeber the register values of CS8415 */
- ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+ ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
if (! ice->akm)
return -ENOMEM;
ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index b97f50d10ba3..a6d98013c331 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -100,12 +100,6 @@ MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec r
module_param_array(model, charp, NULL, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
-#ifndef PCI_VENDOR_ID_ICE
-#define PCI_VENDOR_ID_ICE 0x1412
-#endif
-#ifndef PCI_DEVICE_ID_ICE_1712
-#define PCI_DEVICE_ID_ICE_1712 0x1712
-#endif
static struct pci_device_id snd_ice1712_ids[] = {
{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */
@@ -2535,7 +2529,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
return -ENXIO;
}
- ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
+ ice = kzalloc(sizeof(*ice), GFP_KERNEL);
if (ice == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2741,6 +2735,7 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ICE1712",
+ .owner = THIS_MODULE,
.id_table = snd_ice1712_ids,
.probe = snd_ice1712_probe,
.remove = __devexit_p(snd_ice1712_remove),
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c7af5e5fee13..c3ce8f93740b 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -83,12 +83,6 @@ MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard.");
module_param_array(model, charp, NULL, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
-#ifndef PCI_VENDOR_ID_ICE
-#define PCI_VENDOR_ID_ICE 0x1412
-#endif
-#ifndef PCI_DEVICE_ID_VT1724
-#define PCI_DEVICE_ID_VT1724 0x1724
-#endif
/* Both VT1720 and VT1724 have the same PCI IDs */
static struct pci_device_id snd_vt1724_ids[] = {
@@ -2130,7 +2124,7 @@ static int __devinit snd_vt1724_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
+ ice = kzalloc(sizeof(*ice), GFP_KERNEL);
if (ice == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2321,6 +2315,7 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ICE1724",
+ .owner = THIS_MODULE,
.id_table = snd_vt1724_ids,
.probe = snd_vt1724_probe,
.remove = __devexit_p(snd_vt1724_remove),
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 3fb297b969cd..2437876a44e4 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -182,7 +182,7 @@ static int __devinit juli_init(ice1712_t *ice)
ice->num_total_dacs = 2;
ice->num_total_adcs = 2;
- ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+ ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
if (! ak)
return -ENOMEM;
ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 5bf734b04fa0..dcf1e8ca3f66 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -122,7 +122,7 @@ static int __devinit phase22_init(ice1712_t *ice)
}
// Initialize analog chips
- ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+ ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
if (! ak)
return -ENOMEM;
ice->akm_codecs = 1;
@@ -386,7 +386,7 @@ static int __devinit phase28_init(ice1712_t *ice)
ice->num_total_adcs = 2;
// Initialize analog chips
- ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+ ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
if (!ak)
return -ENOMEM;
ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 25f827d8fbd9..a5f852b1f575 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -781,7 +781,7 @@ static int __devinit pontis_init(ice1712_t *ice)
ice->num_total_adcs = 2;
/* to remeber the register values */
- ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+ ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
if (! ice->akm)
return -ENOMEM;
ice->akm_codecs = 1;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 7b548416dcef..1a96198a17ae 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -69,6 +69,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
static char *ac97_quirk[SNDRV_CARDS];
+static int buggy_semaphore[SNDRV_CARDS];
static int buggy_irq[SNDRV_CARDS];
static int xbox[SNDRV_CARDS];
@@ -86,6 +87,8 @@ module_param_array(ac97_clock, int, NULL, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
module_param_array(ac97_quirk, charp, NULL, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
+module_param_array(buggy_semaphore, bool, NULL, 0444);
+MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
module_param_array(buggy_irq, bool, NULL, 0444);
MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
module_param_array(xbox, bool, NULL, 0444);
@@ -94,62 +97,6 @@ MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 c
/*
* Direct registers
*/
-
-#ifndef PCI_DEVICE_ID_INTEL_82801
-#define PCI_DEVICE_ID_INTEL_82801 0x2415
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82901
-#define PCI_DEVICE_ID_INTEL_82901 0x2425
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82801BA
-#define PCI_DEVICE_ID_INTEL_82801BA 0x2445
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_440MX
-#define PCI_DEVICE_ID_INTEL_440MX 0x7195
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH3
-#define PCI_DEVICE_ID_INTEL_ICH3 0x2485
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH4
-#define PCI_DEVICE_ID_INTEL_ICH4 0x24c5
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH5
-#define PCI_DEVICE_ID_INTEL_ICH5 0x24d5
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ESB_5
-#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH6_18
-#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH7_20
-#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ESB2_14
-#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698
-#endif
-#ifndef PCI_DEVICE_ID_SI_7012
-#define PCI_DEVICE_ID_SI_7012 0x7012
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO 0x01b1
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_CK804_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_CK8_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea
-#endif
-
enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
#define ICHREG(x) ICH_REG_##x
@@ -423,6 +370,7 @@ struct _snd_intel8x0 {
unsigned fix_nocache: 1; /* workaround for 440MX */
unsigned buggy_irq: 1; /* workaround for buggy mobos */
unsigned xbox: 1; /* workaround for Xbox AC'97 detection */
+ unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */
int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
unsigned int sdm_saved; /* SDM reg value */
@@ -577,6 +525,9 @@ static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
return -EIO;
+ if (chip->buggy_semaphore)
+ return 0; /* just ignore ... */
+
/* Anyone holding a semaphore for 1 msec should be shot... */
time = 100;
do {
@@ -1759,6 +1710,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.type = AC97_TUNE_ALC_JACK
},
{
+ .subvendor = 0x1014,
+ .subdevice = 0x0267,
+ .name = "IBM NetVista A30p", /* AD1981B */
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
.subvendor = 0x1028,
.subdevice = 0x00d8,
.name = "Dell Precision 530", /* AD1885 */
@@ -2599,6 +2556,7 @@ struct ich_reg_info {
static int __devinit snd_intel8x0_create(snd_card_t * card,
struct pci_dev *pci,
unsigned long device_type,
+ int buggy_sem,
intel8x0_t ** r_intel8x0)
{
intel8x0_t *chip;
@@ -2646,7 +2604,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2656,6 +2614,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
+ chip->buggy_semaphore = buggy_sem;
if (pci->vendor == PCI_VENDOR_ID_INTEL &&
pci->device == PCI_DEVICE_ID_INTEL_440MX)
@@ -2795,19 +2754,19 @@ static struct shortname_table {
unsigned int id;
const char *s;
} shortnames[] __devinitdata = {
- { PCI_DEVICE_ID_INTEL_82801, "Intel 82801AA-ICH" },
- { PCI_DEVICE_ID_INTEL_82901, "Intel 82901AB-ICH0" },
- { PCI_DEVICE_ID_INTEL_82801BA, "Intel 82801BA-ICH2" },
+ { PCI_DEVICE_ID_INTEL_82801AA_5, "Intel 82801AA-ICH" },
+ { PCI_DEVICE_ID_INTEL_82801AB_5, "Intel 82901AB-ICH0" },
+ { PCI_DEVICE_ID_INTEL_82801BA_4, "Intel 82801BA-ICH2" },
{ PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" },
- { PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" },
- { PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
- { PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
+ { PCI_DEVICE_ID_INTEL_82801CA_5, "Intel 82801CA-ICH3" },
+ { PCI_DEVICE_ID_INTEL_82801DB_5, "Intel 82801DB-ICH4" },
+ { PCI_DEVICE_ID_INTEL_82801EB_5, "Intel ICH5" },
{ PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
{ PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" },
{ PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
{ PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" },
{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
- { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
+ { PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, "NVidia nForce" },
{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
{ PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" },
{ PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" },
@@ -2860,7 +2819,8 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
}
}
- if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) {
+ if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
+ buggy_semaphore[dev], &chip)) < 0) {
snd_card_free(card);
return err;
}
@@ -2904,6 +2864,7 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Intel ICH",
+ .owner = THIS_MODULE,
.id_table = snd_intel8x0_ids,
.probe = snd_intel8x0_probe,
.remove = __devexit_p(snd_intel8x0_remove),
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index bb758c77d211..9e2060d56c24 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -73,51 +73,6 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
/*
* Direct registers
*/
-
-#ifndef PCI_DEVICE_ID_INTEL_82801_6
-#define PCI_DEVICE_ID_INTEL_82801_6 0x2416
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82901_6
-#define PCI_DEVICE_ID_INTEL_82901_6 0x2426
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82801BA_6
-#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2446
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_440MX_6
-#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH3_6
-#define PCI_DEVICE_ID_INTEL_ICH3_6 0x2486
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH4_6
-#define PCI_DEVICE_ID_INTEL_ICH4_6 0x24c6
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH5_6
-#define PCI_DEVICE_ID_INTEL_ICH5_6 0x24d6
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH6_6
-#define PCI_DEVICE_ID_INTEL_ICH6_6 0x266d
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH7_6
-#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27dd
-#endif
-#ifndef PCI_DEVICE_ID_SI_7013
-#define PCI_DEVICE_ID_SI_7013 0x7013
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP_MODEM 0x01c1
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9
-#endif
-
-
enum { DEVICE_INTEL, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
#define ICHREG(x) ICH_REG_##x
@@ -1158,7 +1113,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1283,18 +1238,18 @@ static struct shortname_table {
unsigned int id;
const char *s;
} shortnames[] __devinitdata = {
- { PCI_DEVICE_ID_INTEL_82801_6, "Intel 82801AA-ICH" },
- { PCI_DEVICE_ID_INTEL_82901_6, "Intel 82901AB-ICH0" },
+ { PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" },
+ { PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" },
{ PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
{ PCI_DEVICE_ID_INTEL_440MX_6, "Intel 440MX" },
- { PCI_DEVICE_ID_INTEL_ICH3_6, "Intel 82801CA-ICH3" },
- { PCI_DEVICE_ID_INTEL_ICH4_6, "Intel 82801DB-ICH4" },
- { PCI_DEVICE_ID_INTEL_ICH5_6, "Intel ICH5" },
- { PCI_DEVICE_ID_INTEL_ICH6_6, "Intel ICH6" },
- { PCI_DEVICE_ID_INTEL_ICH7_6, "Intel ICH7" },
+ { PCI_DEVICE_ID_INTEL_82801CA_6, "Intel 82801CA-ICH3" },
+ { PCI_DEVICE_ID_INTEL_82801DB_6, "Intel 82801DB-ICH4" },
+ { PCI_DEVICE_ID_INTEL_82801EB_6, "Intel ICH5" },
+ { PCI_DEVICE_ID_INTEL_ICH6_17, "Intel ICH6" },
+ { PCI_DEVICE_ID_INTEL_ICH7_19, "Intel ICH7" },
{ 0x7446, "AMD AMD768" },
{ PCI_DEVICE_ID_SI_7013, "SiS SI7013" },
- { PCI_DEVICE_ID_NVIDIA_MCP_MODEM, "NVidia nForce" },
+ { PCI_DEVICE_ID_NVIDIA_MCP1_MODEM, "NVidia nForce" },
{ PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
{ PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
{ PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
@@ -1371,6 +1326,7 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Intel ICH Modem",
+ .owner = THIS_MODULE,
.id_table = snd_intel8x0m_ids,
.probe = snd_intel8x0m_probe,
.remove = __devexit_p(snd_intel8x0m_remove),
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index d2aa9c82d41e..5561fd4091e8 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -442,7 +442,7 @@ static char* stateName[] = {
"Setup for play",
"Playing",
"Monitor mode on",
- "Calibrating"
+ "Calibrating",
"Invalid"
};
@@ -2220,7 +2220,7 @@ static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci,
if ((err = pci_enable_device(pci)) < 0)
return err;
- korg1212 = kcalloc(1, sizeof(*korg1212), GFP_KERNEL);
+ korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL);
if (korg1212 == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2534,6 +2534,7 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "korg1212",
+ .owner = THIS_MODULE,
.id_table = snd_korg1212_ids,
.probe = snd_korg1212_probe,
.remove = __devexit_p(snd_korg1212_remove),
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 39b5e7db1543..2693b6f731f3 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -872,35 +872,6 @@ struct snd_m3 {
/*
* pci ids
*/
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS 0x125D
-#endif
-#ifndef PCI_DEVICE_ID_ESS_ALLEGRO_1
-#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988
-#endif
-#ifndef PCI_DEVICE_ID_ESS_ALLEGRO
-#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989
-#endif
-#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2LE
-#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990
-#endif
-#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2
-#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3
-#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_1
-#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_HW
-#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_2
-#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b
-#endif
-
static struct pci_device_id snd_m3_ids[] = {
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
@@ -2689,7 +2660,7 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
return -ENXIO;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -2890,6 +2861,7 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Maestro3",
+ .owner = THIS_MODULE,
.id_table = snd_m3_ids,
.probe = snd_m3_probe,
.remove = __devexit_p(snd_m3_remove),
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 6c868d913634..1a62c7f6c52b 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1004,7 +1004,7 @@ static int __devinit snd_mixart_create(mixart_mgr_t *mgr, snd_card_t *card, int
.dev_free = snd_mixart_chip_dev_free,
};
- mgr->chip[idx] = chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (! chip) {
snd_printk(KERN_ERR "cannot allocate chip\n");
return -ENOMEM;
@@ -1292,7 +1292,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
/*
*/
- mgr = kcalloc(1, sizeof(*mgr), GFP_KERNEL);
+ mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
if (! mgr) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1424,6 +1424,7 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Digigram miXart",
+ .owner = THIS_MODULE,
.id_table = snd_mixart_ids,
.probe = snd_mixart_probe,
.remove = __devexit_p(snd_mixart_remove),
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 2bbeb10ff7c4..5c55a3b1d121 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -259,21 +259,6 @@ struct snd_nm256 {
/*
* PCI ids
*/
-
-#ifndef PCI_VENDOR_ID_NEOMAGIC
-#define PCI_VENDOR_ID_NEOMEGIC 0x10c8
-#endif
-#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO
-#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
-#endif
-#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO
-#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
-#endif
-#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO
-#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
-#endif
-
-
static struct pci_device_id snd_nm256_ids[] = {
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -840,7 +825,7 @@ static void snd_nm256_setup_stream(nm256_t *chip, nm256_stream_t *s,
runtime->hw = *hw_ptr;
runtime->hw.buffer_bytes_max = s->bufsize;
runtime->hw.period_bytes_max = s->bufsize / 2;
- runtime->dma_area = (void*) s->bufptr;
+ runtime->dma_area = (void __force *) s->bufptr;
runtime->dma_addr = s->bufptr_addr;
runtime->dma_bytes = s->bufsize;
runtime->private_data = s;
@@ -1404,7 +1389,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1683,6 +1668,7 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "NeoMagic 256",
+ .owner = THIS_MODULE,
.id_table = snd_nm256_ids,
.probe = snd_nm256_probe,
.remove = __devexit_p(snd_nm256_remove),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 456be39e8e4a..cd313af6ebcf 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -192,20 +192,6 @@ MODULE_SUPPORTED_DEVICE("{{RME,Digi32}," "{RME,Digi32/8}," "{RME,Digi32 PRO}}");
#define RME32_PRO_REVISION_WITH_8414 150
-/* PCI vendor/device ID's */
-#ifndef PCI_VENDOR_ID_XILINX_RME
-# define PCI_VENDOR_ID_XILINX_RME 0xea60
-#endif
-#ifndef PCI_DEVICE_ID_DIGI32
-# define PCI_DEVICE_ID_DIGI32 0x9896
-#endif
-#ifndef PCI_DEVICE_ID_DIGI32_PRO
-# define PCI_DEVICE_ID_DIGI32_PRO 0x9897
-#endif
-#ifndef PCI_DEVICE_ID_DIGI32_8
-# define PCI_DEVICE_ID_DIGI32_8 0x9898
-#endif
-
typedef struct snd_rme32 {
spinlock_t lock;
int irq;
@@ -242,11 +228,11 @@ typedef struct snd_rme32 {
} rme32_t;
static struct pci_device_id snd_rme32_ids[] = {
- {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32,
+ {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
- {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_8,
+ {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
- {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_PRO,
+ {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{0,}
};
@@ -254,7 +240,7 @@ static struct pci_device_id snd_rme32_ids[] = {
MODULE_DEVICE_TABLE(pci, snd_rme32_ids);
#define RME32_ISWORKING(rme32) ((rme32)->wcreg & RME32_WCR_START)
-#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414)
+#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414)
static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream);
@@ -541,21 +527,21 @@ static int snd_rme32_playback_setrate(rme32_t * rme32, int rate)
RME32_WCR_FREQ_1;
break;
case 64000:
- if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO)
+ if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO)
return -EINVAL;
rme32->wcreg |= RME32_WCR_DS_BM;
rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
~RME32_WCR_FREQ_1;
break;
case 88200:
- if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO)
+ if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO)
return -EINVAL;
rme32->wcreg |= RME32_WCR_DS_BM;
rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) &
~RME32_WCR_FREQ_0;
break;
case 96000:
- if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO)
+ if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO)
return -EINVAL;
rme32->wcreg |= RME32_WCR_DS_BM;
rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
@@ -692,7 +678,8 @@ snd_rme32_playback_hw_params(snd_pcm_substream_t * substream,
if (err < 0)
return err;
} else {
- runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER);
+ runtime->dma_area = (void __force *)(rme32->iobase +
+ RME32_IO_DATA_BUFFER);
runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
runtime->dma_bytes = RME32_BUFFER_SIZE;
}
@@ -746,7 +733,8 @@ snd_rme32_capture_hw_params(snd_pcm_substream_t * substream,
if (err < 0)
return err;
} else {
- runtime->dma_area = (void *)rme32->iobase + RME32_IO_DATA_BUFFER;
+ runtime->dma_area = (void __force *)rme32->iobase +
+ RME32_IO_DATA_BUFFER;
runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
runtime->dma_bytes = RME32_BUFFER_SIZE;
}
@@ -893,7 +881,7 @@ static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream)
runtime->hw = snd_rme32_spdif_fd_info;
else
runtime->hw = snd_rme32_spdif_info;
- if (rme32->pci->device == PCI_DEVICE_ID_DIGI32_PRO) {
+ if (rme32->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO) {
runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
runtime->hw.rate_max = 96000;
}
@@ -1420,8 +1408,8 @@ static int __devinit snd_rme32_create(rme32_t * rme32)
}
/* set up ALSA pcm device for ADAT */
- if ((pci->device == PCI_DEVICE_ID_DIGI32) ||
- (pci->device == PCI_DEVICE_ID_DIGI32_PRO)) {
+ if ((pci->device == PCI_DEVICE_ID_RME_DIGI32) ||
+ (pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO)) {
/* ADAT is not available on DIGI32 and DIGI32 Pro */
rme32->adat_pcm = NULL;
}
@@ -1651,11 +1639,11 @@ snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
switch (rme32->pci->device) {
- case PCI_DEVICE_ID_DIGI32:
- case PCI_DEVICE_ID_DIGI32_8:
+ case PCI_DEVICE_ID_RME_DIGI32:
+ case PCI_DEVICE_ID_RME_DIGI32_8:
uinfo->value.enumerated.items = 3;
break;
- case PCI_DEVICE_ID_DIGI32_PRO:
+ case PCI_DEVICE_ID_RME_DIGI32_PRO:
uinfo->value.enumerated.items = 4;
break;
default:
@@ -1682,11 +1670,11 @@ snd_rme32_get_inputtype_control(snd_kcontrol_t * kcontrol,
ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32);
switch (rme32->pci->device) {
- case PCI_DEVICE_ID_DIGI32:
- case PCI_DEVICE_ID_DIGI32_8:
+ case PCI_DEVICE_ID_RME_DIGI32:
+ case PCI_DEVICE_ID_RME_DIGI32_8:
items = 3;
break;
- case PCI_DEVICE_ID_DIGI32_PRO:
+ case PCI_DEVICE_ID_RME_DIGI32_PRO:
items = 4;
break;
default:
@@ -1709,11 +1697,11 @@ snd_rme32_put_inputtype_control(snd_kcontrol_t * kcontrol,
int change, items = 3;
switch (rme32->pci->device) {
- case PCI_DEVICE_ID_DIGI32:
- case PCI_DEVICE_ID_DIGI32_8:
+ case PCI_DEVICE_ID_RME_DIGI32:
+ case PCI_DEVICE_ID_RME_DIGI32_8:
items = 3;
break;
- case PCI_DEVICE_ID_DIGI32_PRO:
+ case PCI_DEVICE_ID_RME_DIGI32_PRO:
items = 4;
break;
default:
@@ -1994,13 +1982,13 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
strcpy(card->driver, "Digi32");
switch (rme32->pci->device) {
- case PCI_DEVICE_ID_DIGI32:
+ case PCI_DEVICE_ID_RME_DIGI32:
strcpy(card->shortname, "RME Digi32");
break;
- case PCI_DEVICE_ID_DIGI32_8:
+ case PCI_DEVICE_ID_RME_DIGI32_8:
strcpy(card->shortname, "RME Digi32/8");
break;
- case PCI_DEVICE_ID_DIGI32_PRO:
+ case PCI_DEVICE_ID_RME_DIGI32_PRO:
strcpy(card->shortname, "RME Digi32 PRO");
break;
}
@@ -2024,6 +2012,7 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Digi32",
+ .owner = THIS_MODULE,
.id_table = snd_rme32_ids,
.probe = snd_rme32_probe,
.remove = __devexit_p(snd_rme32_remove),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9645e9004a48..c495cae78dbf 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -200,25 +200,6 @@ MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
#define RME96_AD1852_VOL_BITS 14
#define RME96_AD1855_VOL_BITS 10
-/*
- * PCI vendor/device ids, could in the future be defined in <linux/pci.h>,
- * therefore #ifndef is used.
- */
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96
-#define PCI_DEVICE_ID_DIGI96 0x3fc0
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96_8
-#define PCI_DEVICE_ID_DIGI96_8 0x3fc1
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96_8_PRO
-#define PCI_DEVICE_ID_DIGI96_8_PRO 0x3fc2
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST
-#define PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST 0x3fc3
-#endif
typedef struct snd_rme96 {
spinlock_t lock;
@@ -252,13 +233,13 @@ typedef struct snd_rme96 {
} rme96_t;
static struct pci_device_id snd_rme96_ids[] = {
- { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96,
+ { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8,
+ { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PRO,
+ { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST,
+ { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ 0, }
};
@@ -267,12 +248,12 @@ MODULE_DEVICE_TABLE(pci, snd_rme96_ids);
#define RME96_ISPLAYING(rme96) ((rme96)->wcreg & RME96_WCR_START)
#define RME96_ISRECORDING(rme96) ((rme96)->wcreg & RME96_WCR_START_2)
-#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST)
-#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO || \
- (rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST)
+#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST)
+#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO || \
+ (rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST)
#define RME96_DAC_IS_1852(rme96) (RME96_HAS_ANALOG_OUT(rme96) && (rme96)->rev >= 4)
-#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \
- ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO && (rme96)->rev == 2))
+#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \
+ ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO && (rme96)->rev == 2))
#define RME96_185X_MAX_OUT(rme96) ((1 << (RME96_DAC_IS_1852(rme96) ? RME96_AD1852_VOL_BITS : RME96_AD1855_VOL_BITS)) - 1)
static int
@@ -849,9 +830,9 @@ snd_rme96_setinputtype(rme96_t *rme96,
RME96_WCR_INP_1;
break;
case RME96_INPUT_XLR:
- if ((rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST &&
- rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PRO) ||
- (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST &&
+ if ((rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST &&
+ rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PRO) ||
+ (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST &&
rme96->rev > 4))
{
/* Only Digi96/8 PRO and Digi96/8 PAD supports XLR */
@@ -985,7 +966,8 @@ snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
snd_pcm_runtime_t *runtime = substream->runtime;
int err, rate, dummy;
- runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER);
+ runtime->dma_area = (void __force *)(rme96->iobase +
+ RME96_IO_PLAY_BUFFER);
runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
runtime->dma_bytes = RME96_BUFFER_SIZE;
@@ -1037,7 +1019,8 @@ snd_rme96_capture_hw_params(snd_pcm_substream_t *substream,
snd_pcm_runtime_t *runtime = substream->runtime;
int err, isadat, rate;
- runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER);
+ runtime->dma_area = (void __force *)(rme96->iobase +
+ RME96_IO_REC_BUFFER);
runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
runtime->dma_bytes = RME96_BUFFER_SIZE;
@@ -1615,7 +1598,7 @@ snd_rme96_create(rme96_t *rme96)
rme96->spdif_pcm->info_flags = 0;
/* set up ALSA pcm device for ADAT */
- if (pci->device == PCI_DEVICE_ID_DIGI96) {
+ if (pci->device == PCI_DEVICE_ID_RME_DIGI96) {
/* ADAT is not available on the base model */
rme96->adat_pcm = NULL;
} else {
@@ -1875,14 +1858,14 @@ snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
switch (rme96->pci->device) {
- case PCI_DEVICE_ID_DIGI96:
- case PCI_DEVICE_ID_DIGI96_8:
+ case PCI_DEVICE_ID_RME_DIGI96:
+ case PCI_DEVICE_ID_RME_DIGI96_8:
uinfo->value.enumerated.items = 3;
break;
- case PCI_DEVICE_ID_DIGI96_8_PRO:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
uinfo->value.enumerated.items = 4;
break;
- case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
if (rme96->rev > 4) {
/* PST */
uinfo->value.enumerated.items = 4;
@@ -1912,14 +1895,14 @@ snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);
switch (rme96->pci->device) {
- case PCI_DEVICE_ID_DIGI96:
- case PCI_DEVICE_ID_DIGI96_8:
+ case PCI_DEVICE_ID_RME_DIGI96:
+ case PCI_DEVICE_ID_RME_DIGI96_8:
items = 3;
break;
- case PCI_DEVICE_ID_DIGI96_8_PRO:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
items = 4;
break;
- case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
if (rme96->rev > 4) {
/* for handling PST case, (INPUT_ANALOG is moved to INPUT_XLR */
if (ucontrol->value.enumerated.item[0] == RME96_INPUT_ANALOG) {
@@ -1949,14 +1932,14 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
int change, items = 3;
switch (rme96->pci->device) {
- case PCI_DEVICE_ID_DIGI96:
- case PCI_DEVICE_ID_DIGI96_8:
+ case PCI_DEVICE_ID_RME_DIGI96:
+ case PCI_DEVICE_ID_RME_DIGI96_8:
items = 3;
break;
- case PCI_DEVICE_ID_DIGI96_8_PRO:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
items = 4;
break;
- case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
if (rme96->rev > 4) {
items = 4;
} else {
@@ -1970,7 +1953,7 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
val = ucontrol->value.enumerated.item[0] % items;
/* special case for PST */
- if (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && rme96->rev > 4) {
+ if (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4) {
if (val == RME96_INPUT_XLR) {
val = RME96_INPUT_ANALOG;
}
@@ -2392,16 +2375,16 @@ snd_rme96_probe(struct pci_dev *pci,
strcpy(card->driver, "Digi96");
switch (rme96->pci->device) {
- case PCI_DEVICE_ID_DIGI96:
+ case PCI_DEVICE_ID_RME_DIGI96:
strcpy(card->shortname, "RME Digi96");
break;
- case PCI_DEVICE_ID_DIGI96_8:
+ case PCI_DEVICE_ID_RME_DIGI96_8:
strcpy(card->shortname, "RME Digi96/8");
break;
- case PCI_DEVICE_ID_DIGI96_8_PRO:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
strcpy(card->shortname, "RME Digi96/8 PRO");
break;
- case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
+ case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
pci_read_config_byte(rme96->pci, 8, &val);
if (val < 5) {
strcpy(card->shortname, "RME Digi96/8 PAD");
@@ -2430,6 +2413,7 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Digi96",
+ .owner = THIS_MODULE,
.id_table = snd_rme96_ids,
.probe = snd_rme96_probe,
.remove = __devexit_p(snd_rme96_remove),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 6694866089b5..52525eb198c7 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -370,13 +370,6 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
#define UNITY_GAIN 32768
#define MINUS_INFINITY_GAIN 0
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
-#endif
-
/* the size of a substream (1 mono data stream) */
#define HDSP_CHANNEL_BUFFER_SAMPLES (16*1024)
@@ -4899,6 +4892,7 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
}
if (!(hdsp->state & HDSP_InitializationComplete)) {
+ strcpy(card->shortname, "Hammerfall DSP");
sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
hdsp->port, hdsp->irq);
@@ -5222,6 +5216,7 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Hammerfall DSP",
+ .owner = THIS_MODULE,
.id_table = snd_hdsp_ids,
.probe = snd_hdsp_probe,
.remove = __devexit_p(snd_hdsp_remove),
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 5d786d113b25..fc3f3283ff37 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -301,18 +301,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define UNITY_GAIN 32768 /* = 65536/2 */
#define MINUS_INFINITY_GAIN 0
-/* PCI info */
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
-#endif
-
-
/* Number of channels for different Speed Modes */
#define MADI_SS_CHANNELS 64
#define MADI_DS_CHANNELS 32
@@ -3652,6 +3640,7 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Hammerfall DSP MADI",
+ .owner = THIS_MODULE,
.id_table = snd_hdspm_ids,
.probe = snd_hdspm_probe,
.remove = __devexit_p(snd_hdspm_remove),
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 8ee4d6fd6ea7..b600f45e1834 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -120,13 +120,6 @@ MODULE_SUPPORTED_DEVICE("{{RME,Hammerfall},"
#define RME9652_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME9652_buf_pos))
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4
-#endif
-
/* amount of io space we remap for register access. i'm not sure we
even need this much, but 1K is nice round number :)
*/
@@ -2661,6 +2654,7 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Digi9652 (Hammerfall)",
+ .owner = THIS_MODULE,
.id_table = snd_rme9652_ids,
.probe = snd_rme9652_probe,
.remove = __devexit_p(snd_rme9652_remove),
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 60ecb2bdb65e..1f6c2bfd43fd 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -50,13 +50,6 @@ MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
#define SUPPORT_JOYSTICK 1
#endif
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3 0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SONICVIBES
-#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
-#endif
-
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
@@ -1257,7 +1250,7 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
return -ENXIO;
}
- sonic = kcalloc(1, sizeof(*sonic), GFP_KERNEL);
+ sonic = kzalloc(sizeof(*sonic), GFP_KERNEL);
if (sonic == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1515,6 +1508,7 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "S3 SonicVibes",
+ .owner = THIS_MODULE,
.id_table = snd_sonic_ids,
.probe = snd_sonic_probe,
.remove = __devexit_p(snd_sonic_remove),
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 940d531575c0..a8ca8e17853f 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -177,6 +177,7 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Trident4DWaveAudio",
+ .owner = THIS_MODULE,
.id_table = snd_trident_ids,
.probe = snd_trident_probe,
.remove = __devexit_p(snd_trident_remove),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index f30d9d947862..777da9a7298b 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2960,7 +2960,7 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
.read = snd_trident_codec_read,
};
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (!uctl)
return -ENOMEM;
@@ -3546,7 +3546,7 @@ int __devinit snd_trident_create(snd_card_t * card,
return -ENXIO;
}
- trident = kcalloc(1, sizeof(*trident), GFP_KERNEL);
+ trident = kzalloc(sizeof(*trident), GFP_KERNEL);
if (trident == NULL) {
pci_disable_device(pci);
return -ENOMEM;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 56c6e52d7264..3c0205b91e10 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -104,14 +104,6 @@ module_param_array(dxs_support, int, NULL, 0444);
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
-/* pci ids */
-#ifndef PCI_DEVICE_ID_VIA_82C686_5
-#define PCI_DEVICE_ID_VIA_82C686_5 0x3058
-#endif
-#ifndef PCI_DEVICE_ID_VIA_8233_5
-#define PCI_DEVICE_ID_VIA_8233_5 0x3059
-#endif
-
/* revision numbers for via686 */
#define VIA_REV_686_A 0x10
#define VIA_REV_686_B 0x11
@@ -1935,11 +1927,12 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
* DXS channels don't work properly with VRA if MC97 is disabled.
*/
struct pci_dev *pci;
- pci = pci_find_device(0x1106, 0x3068, NULL); /* MC97 */
+ pci = pci_get_device(0x1106, 0x3068, NULL); /* MC97 */
if (pci) {
unsigned char data;
pci_read_config_byte(pci, 0x44, &data);
pci_write_config_byte(pci, 0x44, data | 0x40);
+ pci_dev_put(pci);
}
}
@@ -2065,7 +2058,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
+ if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
@@ -2154,11 +2147,13 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
{ .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K },
{ .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
{ .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */
+ { .subvendor = 0x1019, .subdevice = 0xa101, .action = VIA_DXS_SRC },
{ .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */
{ .subvendor = 0x1025, .subdevice = 0x0046, .action = VIA_DXS_SRC }, /* Acer Aspire 1524 WLMi */
{ .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
{ .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
{ .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/
+ { .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */
{ .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */
{ .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
{ .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */
@@ -2350,6 +2345,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "VIA 82xx Audio",
+ .owner = THIS_MODULE,
.id_table = snd_via82xx_ids,
.probe = snd_via82xx_probe,
.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 5872d438a04a..7eac6f6ac737 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1083,7 +1083,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
+ if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
@@ -1207,6 +1207,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "VIA 82xx Modem",
+ .owner = THIS_MODULE,
.id_table = snd_via82xx_modem_ids,
.probe = snd_via82xx_probe,
.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index dca6bd2c7580..2a7ad9dec021 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -252,6 +252,7 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Digigram VX222",
+ .owner = THIS_MODULE,
.id_table = snd_vx222_ids,
.probe = snd_vx222_probe,
.remove = __devexit_p(snd_vx222_remove),
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 5b5b624b47d0..2e69abe51aa9 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -352,6 +352,7 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Yamaha DS-XG PCI",
+ .owner = THIS_MODULE,
.id_table = snd_ymfpci_ids,
.probe = snd_card_ymfpci_probe,
.remove = __devexit_p(snd_card_ymfpci_remove),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 054836412dc4..27fa523639ae 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -839,7 +839,7 @@ static int snd_ymfpci_playback_open_1(snd_pcm_substream_t * substream)
snd_pcm_runtime_t *runtime = substream->runtime;
ymfpci_pcm_t *ypcm;
- ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL);
+ ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
if (ypcm == NULL)
return -ENOMEM;
ypcm->chip = chip;
@@ -957,7 +957,7 @@ static int snd_ymfpci_capture_open(snd_pcm_substream_t * substream,
snd_pcm_runtime_t *runtime = substream->runtime;
ymfpci_pcm_t *ypcm;
- ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL);
+ ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
if (ypcm == NULL)
return -ENOMEM;
ypcm->chip = chip;
@@ -2270,7 +2270,7 @@ int __devinit snd_ymfpci_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index a2132e3763dd..0208c54896b3 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -151,7 +151,7 @@ pdacf_t *snd_pdacf_create(snd_card_t *card)
{
pdacf_t *chip;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return NULL;
chip->card = card;
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index 75213bf4d567..206b9333f91f 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -13,11 +13,24 @@ config SND_POWERMAC
tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
depends on SND && I2C && INPUT && PPC_PMAC
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for the integrated sound device.
To compile this driver as a module, choose M here: the module
will be called snd-powermac.
-endmenu
+config SND_POWERMAC_AUTO_DRC
+ bool "Toggle DRC automatically at headphone/line plug-in"
+ depends on SND_POWERMAC
+ default y
+ help
+ Say Y here to enable the automatic toggle of DRC (dynamic
+ range compression) on Tumbler/Snapper.
+ If this feature is enabled, DRC is turned off when the
+ headphone/line jack is plugged, and turned on when unplugged.
+ Note that you can turn on/off DRC manually even without this
+ option.
+
+endmenu
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index c89e82eb06a6..392b2abd9f13 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -988,6 +988,8 @@ static int __init snd_pmac_detect(pmac_t *chip)
case 0x33:
case 0x29:
case 0x24:
+ case 0x50:
+ case 0x5c:
chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
chip->model = PMAC_SNAPPER;
chip->can_byte_swap = 0; /* FIXME: check this */
@@ -1159,7 +1161,7 @@ int __init snd_pmac_new(snd_card_t *card, pmac_t **chip_return)
snd_runtime_check(chip_return, return -EINVAL);
*chip_return = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->card = card;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 231f6432ea6d..a6d8cbf4064f 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -131,6 +131,9 @@ static int __init snd_pmac_probe(void)
if (enable_beep)
snd_pmac_attach_beep(chip);
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto __error;
+
if ((err = snd_card_register(card)) < 0)
goto __error;
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index b94437c024b1..65384afcfc3f 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -948,7 +948,6 @@ static void device_change_handler(void *self)
msleep(10);
check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify,
chip->speaker_sw_ctl);
- mix->drc_enable = 0;
} else {
/* unmute speaker, mute others */
check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify,
@@ -960,20 +959,21 @@ static void device_change_handler(void *self)
if (mix->line_mute.addr != 0)
check_mute(chip, &mix->line_mute, 1, mix->auto_mute_notify,
chip->lineout_sw_ctl);
- mix->drc_enable = 1;
}
- if (mix->auto_mute_notify) {
+ if (mix->auto_mute_notify)
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->hp_detect_ctl->id);
+
+#ifdef CONFIG_SND_POWERMAC_AUTO_DRC
+ mix->drc_enable = ! (headphone || lineout);
+ if (mix->auto_mute_notify)
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->drc_sw_ctl->id);
- }
-
- /* first set the DRC so the speaker do not explode -ReneR */
if (chip->model == PMAC_TUMBLER)
tumbler_set_drc(mix);
else
snapper_set_drc(mix);
+#endif
/* reset the master volume so the correct amplification is applied */
tumbler_set_master_volume(mix);
@@ -1370,6 +1370,17 @@ int __init snd_pmac_tumbler_init(pmac_t *chip)
if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
return err;
+ /* set initial DRC range to 60% */
+ if (chip->model == PMAC_TUMBLER)
+ mix->drc_range = (TAS3001_DRC_MAX * 6) / 10;
+ else
+ mix->drc_range = (TAS3004_DRC_MAX * 6) / 10;
+ mix->drc_enable = 1; /* will be changed later if AUTO_DRC is set */
+ if (chip->model == PMAC_TUMBLER)
+ tumbler_set_drc(mix);
+ else
+ snapper_set_drc(mix);
+
#ifdef CONFIG_PM
chip->suspend = tumbler_suspend;
chip->resume = tumbler_resume;
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig
index 25a8a558ef92..09ab138646a6 100644
--- a/sound/sparc/Kconfig
+++ b/sound/sparc/Kconfig
@@ -7,6 +7,7 @@ config SND_SUN_AMD7930
tristate "Sun AMD7930"
depends on SBUS && SND
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for AMD7930 sound device on Sun.
@@ -17,6 +18,7 @@ config SND_SUN_CS4231
tristate "Sun CS4231"
depends on SND
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for CS4231 sound device on Sun.
@@ -27,6 +29,7 @@ config SND_SUN_DBRI
tristate "Sun DBRI"
depends on SND && SBUS
select SND_PCM
+ select SND_GENERIC_DRIVER
help
Say Y here to include support for DBRI sound device on Sun.
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index bd8a850e93ea..46d504ba7e03 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -967,7 +967,7 @@ static int __init snd_amd7930_create(snd_card_t *card,
int err;
*ramd = NULL;
- amd = kcalloc(1, sizeof(*amd), GFP_KERNEL);
+ amd = kzalloc(sizeof(*amd), GFP_KERNEL);
if (amd == NULL)
return -ENOMEM;
@@ -1088,6 +1088,9 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
if ((err = snd_amd7930_mixer(amd)) < 0)
goto out_err;
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto out_err;
+
if ((err = snd_card_register(card)) < 0)
goto out_err;
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 36f9fe4d7bea..f4361c518e46 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -173,7 +173,7 @@ static cs4231_t *cs4231_list;
#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
-/* definitions for codec irq status */
+/* definitions for codec irq status - CS4231_IRQ_STATUS */
#define CS4231_PLAYBACK_IRQ 0x10
#define CS4231_RECORD_IRQ 0x20
@@ -402,7 +402,7 @@ static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ snd_printdd("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif
if (chip->calibrate_mute) {
chip->image[reg] &= mask;
@@ -425,6 +425,10 @@ static void snd_cs4231_dout(cs4231_t *chip, unsigned char reg, unsigned char val
timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
timeout--)
udelay(100);
+#ifdef CONFIG_SND_DEBUG
+ if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
+ snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+#endif
__cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
__cs4231_writeb(chip, value, CS4231P(chip, REG));
mb();
@@ -440,15 +444,12 @@ static void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char valu
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif
__cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
__cs4231_writeb(chip, value, CS4231P(chip, REG));
chip->image[reg] = value;
mb();
-#if 0
- printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
-#endif
}
static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
@@ -462,61 +463,14 @@ static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
+ snd_printdd("in: auto calibration time out - reg = 0x%x\n", reg);
#endif
__cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
mb();
ret = __cs4231_readb(chip, CS4231P(chip, REG));
-#if 0
- printk("codec in - reg 0x%x = 0x%x\n", chip->mce_bit | reg, ret);
-#endif
return ret;
}
-#if 0
-
-static void snd_cs4231_debug(cs4231_t *chip)
-{
- printk("CS4231 REGS: INDEX = 0x%02x ",
- __cs4231_readb(chip, CS4231P(chip, REGSEL)));
- printk(" STATUS = 0x%02x\n",
- __cs4231_readb(chip, CS4231P(chip, STATUS)));
- printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00));
- printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10));
- printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01));
- printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11));
- printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02));
- printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12));
- printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03));
- printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13));
- printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04));
- printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14));
- printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05));
- printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15));
- printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06));
- printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16));
- printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07));
- printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17));
- printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08));
- printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18));
- printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09));
- printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19));
- printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a));
- printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a));
- printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b));
- printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b));
- printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c));
- printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c));
- printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d));
- printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d));
- printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e));
- printk(" 0x1e: rec upr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e));
- printk(" 0x0f: ply lwr count = 0x%02x ", snd_cs4231_in(chip, 0x0f));
- printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f));
-}
-
-#endif
-
/*
* CS4231 detection / MCE routines
*/
@@ -528,11 +482,12 @@ static void snd_cs4231_busy_wait(cs4231_t *chip)
/* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
for (timeout = 5; timeout > 0; timeout--)
__cs4231_readb(chip, CS4231P(chip, REGSEL));
+
/* end of cleanup sequence */
- for (timeout = 250;
+ for (timeout = 500;
timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
timeout--)
- udelay(100);
+ udelay(1000);
}
static void snd_cs4231_mce_up(cs4231_t *chip)
@@ -545,12 +500,12 @@ static void snd_cs4231_mce_up(cs4231_t *chip)
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printk("mce_up - auto calibration time out (0)\n");
+ snd_printdd("mce_up - auto calibration time out (0)\n");
#endif
chip->mce_bit |= CS4231_MCE;
timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
if (timeout == 0x80)
- snd_printk("mce_up [%p]: serious init problem - codec still busy\n", chip->port);
+ snd_printdd("mce_up [%p]: serious init problem - codec still busy\n", chip->port);
if (!(timeout & CS4231_MCE))
__cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
spin_unlock_irqrestore(&chip->lock, flags);
@@ -563,18 +518,15 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_busy_wait(chip);
-#if 0
- printk("(1) timeout = %i\n", timeout);
-#endif
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printk("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL));
+ snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL));
#endif
chip->mce_bit &= ~CS4231_MCE;
timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
__cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
if (timeout == 0x80)
- snd_printk("mce_down [%p]: serious init problem - codec still busy\n", chip->port);
+ snd_printdd("mce_down [%p]: serious init problem - codec still busy\n", chip->port);
if ((timeout & CS4231_MCE) == 0) {
spin_unlock_irqrestore(&chip->lock, flags);
return;
@@ -590,9 +542,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_unlock_irqrestore(&chip->lock, flags);
return;
}
-#if 0
- printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
-#endif
+
/* in 10ms increments, check condition, up to 250ms */
timeout = 25;
while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
@@ -604,9 +554,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
msleep(10);
spin_lock_irqsave(&chip->lock, flags);
}
-#if 0
- printk("(3) jiffies = %li\n", jiffies);
-#endif
+
/* in 10ms increments, check condition, up to 100ms */
timeout = 10;
while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) {
@@ -619,28 +567,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_lock_irqsave(&chip->lock, flags);
}
spin_unlock_irqrestore(&chip->lock, flags);
-#if 0
- printk("(4) jiffies = %li\n", jiffies);
- snd_printk("mce_down - exit = 0x%x\n", __cs4231_readb(chip, CS4231P(chip, REGSEL)));
-#endif
-}
-
-#if 0 /* Unused for now... */
-static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size)
-{
- switch (format & 0xe0) {
- case CS4231_LINEAR_16:
- case CS4231_LINEAR_16_BIG:
- size >>= 1;
- break;
- case CS4231_ADPCM_16:
- return size >> 2;
- }
- if (format & CS4231_STEREO)
- size >>= 1;
- return size;
}
-#endif
#ifdef EBUS_SUPPORT
static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent)
@@ -648,25 +575,50 @@ static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substre
snd_pcm_runtime_t *runtime = substream->runtime;
while (1) {
- unsigned int dma_size = snd_pcm_lib_period_bytes(substream);
- unsigned int offset = dma_size * (*periods_sent);
+ unsigned int period_size = snd_pcm_lib_period_bytes(substream);
+ unsigned int offset = period_size * (*periods_sent);
- if (dma_size >= (1 << 24))
+ if (period_size >= (1 << 24))
BUG();
- if (ebus_dma_request(p, runtime->dma_addr + offset, dma_size))
+ if (ebus_dma_request(p, runtime->dma_addr + offset, period_size))
return;
-#if 0
- printk("ebus_advance: Sent period %u (size[%x] offset[%x])\n",
- (*periods_sent), dma_size, offset);
-#endif
(*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
}
}
#endif
-static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on)
+#ifdef SBUS_SUPPORT
+static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent)
{
+ cs4231_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
+
+ unsigned int period_size = snd_pcm_lib_period_bytes(substream);
+ unsigned int offset = period_size * (*periods_sent % runtime->periods);
+
+ if (runtime->period_size > 0xffff + 1)
+ BUG();
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA);
+ sbus_writel(period_size, chip->port + APCPNC);
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA);
+ sbus_writel(period_size, chip->port + APCCNC);
+ break;
+ }
+
+ (*periods_sent) = (*periods_sent + 1) % runtime->periods;
+}
+#endif
+
+static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on)
+{
+ cs4231_t *chip = snd_pcm_substream_chip(substream);
+
#ifdef EBUS_SUPPORT
if (chip->flags & CS4231_FLAG_EBUS) {
if (what & CS4231_PLAYBACK_ENABLE) {
@@ -694,6 +646,60 @@ static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on)
} else {
#endif
#ifdef SBUS_SUPPORT
+ u32 csr = sbus_readl(chip->port + APCCSR);
+ /* I don't know why, but on sbus the period counter must
+ * only start counting after the first period is sent.
+ * Therefore this dummy thing.
+ */
+ unsigned int dummy = 0;
+
+ switch (what) {
+ case CS4231_PLAYBACK_ENABLE:
+ if (on) {
+ csr &= ~APC_XINT_PLAY;
+ sbus_writel(csr, chip->port + APCCSR);
+
+ csr &= ~APC_PPAUSE;
+ sbus_writel(csr, chip->port + APCCSR);
+
+ snd_cs4231_sbus_advance_dma(substream, &dummy);
+
+ csr |= APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
+ APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL |
+ APC_XINT_PENA | APC_PDMA_READY;
+ sbus_writel(csr, chip->port + APCCSR);
+ } else {
+ csr |= APC_PPAUSE;
+ sbus_writel(csr, chip->port + APCCSR);
+
+ csr &= ~APC_PDMA_READY;
+ sbus_writel(csr, chip->port + APCCSR);
+ }
+ break;
+ case CS4231_RECORD_ENABLE:
+ if (on) {
+ csr &= ~APC_XINT_CAPT;
+ sbus_writel(csr, chip->port + APCCSR);
+
+ csr &= ~APC_CPAUSE;
+ sbus_writel(csr, chip->port + APCCSR);
+
+ snd_cs4231_sbus_advance_dma(substream, &dummy);
+
+ csr |= APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
+ APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL |
+ APC_CDMA_READY;
+
+ sbus_writel(csr, chip->port + APCCSR);
+ } else {
+ csr |= APC_CPAUSE;
+ sbus_writel(csr, chip->port + APCCSR);
+
+ csr &= ~APC_CDMA_READY;
+ sbus_writel(csr, chip->port + APCCSR);
+ }
+ break;
+ }
#endif
#ifdef EBUS_SUPPORT
}
@@ -725,25 +731,12 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
}
}
-#if 0
- printk("TRIGGER: what[%x] on(%d)\n",
- what, (cmd == SNDRV_PCM_TRIGGER_START));
-#endif
-
spin_lock_irqsave(&chip->lock, flags);
if (cmd == SNDRV_PCM_TRIGGER_START) {
- cs4231_dma_trigger(chip, what, 1);
+ cs4231_dma_trigger(substream, what, 1);
chip->image[CS4231_IFACE_CTRL] |= what;
- if (what & CS4231_PLAYBACK_ENABLE) {
- snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, 0xff);
- snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, 0xff);
- }
- if (what & CS4231_RECORD_ENABLE) {
- snd_cs4231_out(chip, CS4231_REC_LWR_CNT, 0xff);
- snd_cs4231_out(chip, CS4231_REC_UPR_CNT, 0xff);
- }
} else {
- cs4231_dma_trigger(chip, what, 0);
+ cs4231_dma_trigger(substream, what, 0);
chip->image[CS4231_IFACE_CTRL] &= ~what;
}
snd_cs4231_out(chip, CS4231_IFACE_CTRL,
@@ -755,9 +748,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
result = -EINVAL;
break;
}
-#if 0
- snd_cs4231_debug(chip);
-#endif
+
return result;
}
@@ -790,9 +781,6 @@ static unsigned char snd_cs4231_get_format(cs4231_t *chip, int format, int chann
}
if (channels > 1)
rformat |= CS4231_STEREO;
-#if 0
- snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
-#endif
return rformat;
}
@@ -944,7 +932,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printk("init: (1)\n");
+ snd_printdd("init: (1)\n");
#endif
snd_cs4231_mce_up(chip);
spin_lock_irqsave(&chip->lock, flags);
@@ -957,7 +945,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printk("init: (2)\n");
+ snd_printdd("init: (2)\n");
#endif
snd_cs4231_mce_up(chip);
@@ -967,7 +955,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
+ snd_printdd("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
#endif
spin_lock_irqsave(&chip->lock, flags);
@@ -981,7 +969,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printk("init: (4)\n");
+ snd_printdd("init: (4)\n");
#endif
snd_cs4231_mce_up(chip);
@@ -991,7 +979,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printk("init: (5)\n");
+ snd_printdd("init: (5)\n");
#endif
}
@@ -1022,6 +1010,7 @@ static int snd_cs4231_open(cs4231_t *chip, unsigned int mode)
CS4231_RECORD_IRQ |
CS4231_TIMER_IRQ);
snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
+
spin_unlock_irqrestore(&chip->lock, flags);
chip->mode = mode;
@@ -1136,11 +1125,21 @@ static int snd_cs4231_playback_hw_free(snd_pcm_substream_t *substream)
static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
+
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
CS4231_PLAYBACK_PIO);
+
+ if (runtime->period_size > 0xffff + 1)
+ BUG();
+
+ snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
+ snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
+ chip->p_periods_sent = 0;
+
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -1172,12 +1171,16 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream)
static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
CS4231_RECORD_PIO);
+ snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
+ snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
+
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -1196,53 +1199,61 @@ static void snd_cs4231_overrange(cs4231_t *chip)
chip->capture_substream->runtime->overrange++;
}
-static void snd_cs4231_generic_interrupt(cs4231_t *chip)
+static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip)
{
unsigned long flags;
unsigned char status;
+ /*This is IRQ is not raised by the cs4231*/
+ if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
+ return IRQ_NONE;
+
status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
- if (!status)
- return;
if (status & CS4231_TIMER_IRQ) {
if (chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
}
- if (status & CS4231_PLAYBACK_IRQ)
- snd_pcm_period_elapsed(chip->playback_substream);
- if (status & CS4231_RECORD_IRQ) {
+
+ if (status & CS4231_RECORD_IRQ)
snd_cs4231_overrange(chip);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
/* ACK the CS4231 interrupt. */
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
spin_unlock_irqrestore(&chip->lock, flags);
+
+ return 0;
}
#ifdef SBUS_SUPPORT
static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
cs4231_t *chip = dev_id;
- u32 csr;
-
- csr = sbus_readl(chip->port + APCCSR);
- if (!(csr & (APC_INT_PENDING |
- APC_PLAY_INT |
- APC_CAPT_INT |
- APC_GENL_INT |
- APC_XINT_PEMP |
- APC_XINT_CEMP)))
- return IRQ_NONE;
/* ACK the APC interrupt. */
+ u32 csr = sbus_readl(chip->port + APCCSR);
+
sbus_writel(csr, chip->port + APCCSR);
- snd_cs4231_generic_interrupt(chip);
+ if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) &&
+ (csr & APC_PLAY_INT) &&
+ (csr & APC_XINT_PNVA) &&
+ !(csr & APC_XINT_EMPT)) {
+ snd_cs4231_sbus_advance_dma(chip->playback_substream,
+ &chip->p_periods_sent);
+ snd_pcm_period_elapsed(chip->playback_substream);
+ }
- return IRQ_HANDLED;
+ if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) &&
+ (csr & APC_CAPT_INT) &&
+ (csr & APC_XINT_CNVA)) {
+ snd_cs4231_sbus_advance_dma(chip->capture_substream,
+ &chip->c_periods_sent);
+ snd_pcm_period_elapsed(chip->capture_substream);
+ }
+
+ return snd_cs4231_generic_interrupt(chip);
}
#endif
@@ -1290,7 +1301,8 @@ static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substr
#ifdef EBUS_SUPPORT
}
#endif
- ptr += (period_bytes - residue);
+ ptr += period_bytes - residue;
+
return bytes_to_frames(substream->runtime, ptr);
}
@@ -1314,7 +1326,7 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substr
#ifdef EBUS_SUPPORT
}
#endif
- ptr += (period_bytes - residue);
+ ptr += period_bytes - residue;
return bytes_to_frames(substream->runtime, ptr);
}
@@ -1328,9 +1340,6 @@ static int snd_cs4231_probe(cs4231_t *chip)
int i, id, vers;
unsigned char *ptr;
-#if 0
- snd_cs4231_debug(chip);
-#endif
id = vers = 0;
for (i = 0; i < 50; i++) {
mb();
@@ -1915,6 +1924,9 @@ static int cs4231_attach_finish(snd_card_t *card, cs4231_t *chip)
if ((err = snd_cs4231_timer(chip)) < 0)
goto out_err;
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto out_err;
+
if ((err = snd_card_register(card)) < 0)
goto out_err;
@@ -1966,7 +1978,7 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
int err;
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
@@ -1982,13 +1994,13 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
chip->port = sbus_ioremap(&sdev->resource[0], 0,
chip->regs_size, "cs4231");
if (!chip->port) {
- snd_printk("cs4231-%d: Unable to map chip registers.\n", dev);
+ snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
return -EIO;
}
if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
SA_SHIRQ, "cs4231", chip)) {
- snd_printk("cs4231-%d: Unable to grab SBUS IRQ %s\n",
+ snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n",
dev,
__irq_itoa(sdev->irqs[0]));
snd_cs4231_sbus_free(chip);
@@ -2080,7 +2092,7 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
int err;
*rchip = NULL;
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
@@ -2110,29 +2122,29 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10);
if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) {
snd_cs4231_ebus_free(chip);
- snd_printk("cs4231-%d: Unable to map chip registers.\n", dev);
+ snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
return -EIO;
}
if (ebus_dma_register(&chip->eb2c)) {
snd_cs4231_ebus_free(chip);
- snd_printk("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
+ snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
return -EBUSY;
}
if (ebus_dma_irq_enable(&chip->eb2c, 1)) {
snd_cs4231_ebus_free(chip);
- snd_printk("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
+ snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
return -EBUSY;
}
if (ebus_dma_register(&chip->eb2p)) {
snd_cs4231_ebus_free(chip);
- snd_printk("cs4231-%d: Unable to register EBUS play DMA\n", dev);
+ snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev);
return -EBUSY;
}
if (ebus_dma_irq_enable(&chip->eb2p, 1)) {
snd_cs4231_ebus_free(chip);
- snd_printk("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
+ snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
return -EBUSY;
}
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 941c7b1e7ebb..b5c4c15ae7f0 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -1,6 +1,6 @@
/*
* Driver for DBRI sound chip found on Sparcs.
- * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net)
+ * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net)
*
* Based entirely upon drivers/sbus/audio/dbri.c which is:
* Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
@@ -43,6 +43,12 @@
* audio devices. But the SUN HW group decided against it, at least on my
* LX the speakerbox connector has at least 1 pin missing and 1 wrongly
* connected.
+ *
+ * I've tried to stick to the following function naming conventions:
+ * snd_* ALSA stuff
+ * cs4215_* CS4215 codec specfic stuff
+ * dbri_* DBRI high-level stuff
+ * other DBRI low-level stuff
*/
#include <sound/driver.h>
@@ -87,7 +93,7 @@ MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
#define D_DESC (1<<5)
static int dbri_debug = 0;
-module_param(dbri_debug, int, 0444);
+module_param(dbri_debug, int, 0644);
MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
#ifdef DBRI_DEBUG
@@ -320,7 +326,8 @@ typedef struct snd_dbri {
void __iomem *regs; /* dbri HW regs */
int dbri_version; /* 'e' and up is OK */
int dbri_irqp; /* intr queue pointer */
- int wait_seen;
+ int wait_send; /* sequence of command buffers send */
+ int wait_ackd; /* sequence of command buffers acknowledged */
struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */
struct dbri_desc descs[DBRI_NO_DESCS];
@@ -625,16 +632,13 @@ static __u32 reverse_bytes(__u32 b, int len)
Commands are sent to the DBRI by building a list of them in memory,
then writing the address of the first list item to DBRI register 8.
-The list is terminated with a WAIT command, which can generate a
-CPU interrupt if required.
+The list is terminated with a WAIT command, which generates a
+CPU interrupt to signal completion.
Since the DBRI can run in parallel with the CPU, several means of
-synchronization present themselves. The original scheme (Rudolf's)
-was to set a flag when we "cmdlock"ed the DBRI, clear the flag when
-an interrupt signaled completion, and wait on a wait_queue if a routine
-attempted to cmdlock while the flag was set. The problems arose when
-we tried to cmdlock from inside an interrupt handler, which might
-cause scheduling in an interrupt (if we waited), etc, etc
+synchronization present themselves. The method implemented here is close
+to the original scheme (Rudolf's), and uses 2 counters (wait_send and
+wait_ackd) to synchronize the command buffer between the CPU and the DBRI.
A more sophisticated scheme might involve a circular command buffer
or an array of command buffers. A routine could fill one with
@@ -642,70 +646,75 @@ commands and link it onto a list. When a interrupt signaled
completion of the current command buffer, look on the list for
the next one.
-I've decided to implement something much simpler - after each command,
-the CPU waits for the DBRI to finish the command by polling the P bit
-in DBRI register 0. I've tried to implement this in such a way
-that might make implementing a more sophisticated scheme easier.
-
Every time a routine wants to write commands to the DBRI, it must
first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd
-in return. After the commands have been writen, dbri_cmdsend() is
-called with the final pointer value.
+in return. dbri_cmdlock() will block if the previous commands have not
+been completed yet. After this the commands can be written to the buffer,
+and dbri_cmdsend() is called with the final pointer value to send them
+to the DBRI.
*/
+static void dbri_process_interrupt_buffer(snd_dbri_t * dbri);
+
enum dbri_lock_t { NoGetLock, GetLock };
+#define MAXLOOPS 10
static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get)
{
+ int maxloops = MAXLOOPS;
+
#ifndef SMP
if ((get == GetLock) && spin_is_locked(&dbri->lock)) {
printk(KERN_ERR "DBRI: cmdlock called while in spinlock.");
}
#endif
+ /* Delay if previous commands are still being processed */
+ while ((--maxloops) > 0 && (dbri->wait_send != dbri->wait_ackd)) {
+ msleep_interruptible(1);
+ /* If dbri_cmdlock() got called from inside the
+ * interrupt handler, this will do the processing.
+ */
+ dbri_process_interrupt_buffer(dbri);
+ }
+ if (maxloops == 0) {
+ printk(KERN_ERR "DBRI: Chip never completed command buffer %d\n",
+ dbri->wait_send);
+ } else {
+ dprintk(D_CMD, "Chip completed command buffer (%d)\n",
+ MAXLOOPS - maxloops - 1);
+ }
+
/*if (get == GetLock) spin_lock(&dbri->lock); */
return &dbri->dma->cmd[0];
}
-static void dbri_process_interrupt_buffer(snd_dbri_t *);
-
static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd)
{
- int MAXLOOPS = 1000000;
- int maxloops = MAXLOOPS;
volatile s32 *ptr;
+ u32 reg;
for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) {
dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
}
if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) {
- printk("DBRI: Command buffer overflow! (bug in driver)\n");
+ printk(KERN_ERR "DBRI: Command buffer overflow! (bug in driver)\n");
/* Ignore the last part. */
cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3];
}
+ dbri->wait_send++;
+ dbri->wait_send &= 0xffff; /* restrict it to a 16 bit counter. */
*(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
- dbri->wait_seen = 0;
+ *(cmd++) = DBRI_CMD(D_WAIT, 1, dbri->wait_send);
+
+ /* Set command pointer and signal it is valid. */
sbus_writel(dbri->dma_dvma, dbri->regs + REG8);
- while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P))
- barrier();
- if (maxloops == 0) {
- printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
- dprintk(D_CMD, "DBRI: Chip never completed command buffer\n");
- } else {
- while ((--maxloops) > 0 && (!dbri->wait_seen))
- dbri_process_interrupt_buffer(dbri);
- if (maxloops == 0) {
- printk(KERN_ERR "DBRI: Chip never acked WAIT\n");
- dprintk(D_CMD, "DBRI: Chip never acked WAIT\n");
- } else {
- dprintk(D_CMD, "Chip completed command "
- "buffer (%d)\n", MAXLOOPS - maxloops);
- }
- }
+ reg = sbus_readl(dbri->regs + REG0);
+ reg |= D_P;
+ sbus_writel(reg, dbri->regs + REG0);
/*spin_unlock(&dbri->lock); */
}
@@ -757,10 +766,11 @@ static void dbri_initialize(snd_dbri_t * dbri)
for (n = 0; n < DBRI_NO_PIPES; n++)
dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
- /* We should query the openprom to see what burst sizes this
- * SBus supports. For now, just disable all SBus bursts */
+ /* A brute approach - DBRI falls back to working burst size by itself
+ * On SS20 D_S does not work, so do not try so high. */
tmp = sbus_readl(dbri->regs + REG0);
- tmp &= ~(D_G | D_S | D_E);
+ tmp |= D_G | D_E;
+ tmp &= ~D_S;
sbus_writel(tmp, dbri->regs + REG0);
/*
@@ -805,13 +815,13 @@ static void reset_pipe(snd_dbri_t * dbri, int pipe)
volatile int *cmd;
if (pipe < 0 || pipe > 31) {
- printk("DBRI: reset_pipe called with illegal pipe number\n");
+ printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n");
return;
}
sdp = dbri->pipes[pipe].sdp;
if (sdp == 0) {
- printk("DBRI: reset_pipe called on uninitialized pipe\n");
+ printk(KERN_ERR "DBRI: reset_pipe called on uninitialized pipe\n");
return;
}
@@ -834,12 +844,12 @@ static void reset_pipe(snd_dbri_t * dbri, int pipe)
static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp)
{
if (pipe < 0 || pipe > 31) {
- printk("DBRI: setup_pipe called with illegal pipe number\n");
+ printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n");
return;
}
if ((sdp & 0xf800) != sdp) {
- printk("DBRI: setup_pipe called with strange SDP value\n");
+ printk(KERN_ERR "DBRI: setup_pipe called with strange SDP value\n");
/* sdp &= 0xf800; */
}
@@ -872,13 +882,13 @@ static void link_time_slot(snd_dbri_t * dbri, int pipe,
int nextpipe;
if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) {
- printk
- ("DBRI: link_time_slot called with illegal pipe number\n");
+ printk(KERN_ERR
+ "DBRI: link_time_slot called with illegal pipe number\n");
return;
}
if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) {
- printk("DBRI: link_time_slot called on uninitialized pipe\n");
+ printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n");
return;
}
@@ -960,8 +970,8 @@ static void unlink_time_slot(snd_dbri_t * dbri, int pipe,
int val;
if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) {
- printk
- ("DBRI: unlink_time_slot called with illegal pipe number\n");
+ printk(KERN_ERR
+ "DBRI: unlink_time_slot called with illegal pipe number\n");
return;
}
@@ -1001,22 +1011,22 @@ static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data)
volatile s32 *cmd;
if (pipe < 16 || pipe > 31) {
- printk("DBRI: xmit_fixed: Illegal pipe number\n");
+ printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
return;
}
if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
- printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe);
return;
}
if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
- printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
return;
}
if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
- printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", pipe);
return;
}
@@ -1036,17 +1046,17 @@ static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data)
static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr)
{
if (pipe < 16 || pipe > 31) {
- printk("DBRI: recv_fixed called with illegal pipe number\n");
+ printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n");
return;
}
if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
- printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: recv_fixed called on non-fixed pipe %d\n", pipe);
return;
}
if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
- printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: recv_fixed called on transmit pipe %d\n", pipe);
return;
}
@@ -1075,12 +1085,12 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period)
int last_desc = -1;
if (info->pipe < 0 || info->pipe > 15) {
- printk("DBRI: setup_descs: Illegal pipe number\n");
+ printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n");
return -2;
}
if (dbri->pipes[info->pipe].sdp == 0) {
- printk("DBRI: setup_descs: Uninitialized pipe %d\n",
+ printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n",
info->pipe);
return -2;
}
@@ -1090,20 +1100,20 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period)
if (streamno == DBRI_PLAY) {
if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
- printk("DBRI: setup_descs: Called on receive pipe %d\n",
+ printk(KERN_ERR "DBRI: setup_descs: Called on receive pipe %d\n",
info->pipe);
return -2;
}
} else {
if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
- printk
- ("DBRI: setup_descs: Called on transmit pipe %d\n",
+ printk(KERN_ERR
+ "DBRI: setup_descs: Called on transmit pipe %d\n",
info->pipe);
return -2;
}
/* Should be able to queue multiple buffers to receive on a pipe */
if (pipe_active(dbri, info->pipe)) {
- printk("DBRI: recv_on_pipe: Called on active pipe %d\n",
+ printk(KERN_ERR "DBRI: recv_on_pipe: Called on active pipe %d\n",
info->pipe);
return -2;
}
@@ -1120,7 +1130,7 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period)
break;
}
if (desc == DBRI_NO_DESCS) {
- printk("DBRI: setup_descs: No descriptors\n");
+ printk(KERN_ERR "DBRI: setup_descs: No descriptors\n");
return -1;
}
@@ -1165,7 +1175,7 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period)
}
if (first_desc == -1 || last_desc == -1) {
- printk("DBRI: setup_descs: Not enough descriptors available\n");
+ printk(KERN_ERR "DBRI: setup_descs: Not enough descriptors available\n");
return -1;
}
@@ -1270,7 +1280,7 @@ static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave,
int divisor = 12288 / clockrate;
if (divisor > 255 || divisor * clockrate != 12288)
- printk("DBRI: illegal bits_per_frame in setup_chi\n");
+ printk(KERN_ERR "DBRI: illegal bits_per_frame in setup_chi\n");
*(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
| D_CHI_BPF(bits_per_frame));
@@ -1474,7 +1484,6 @@ static int cs4215_setctrl(snd_dbri_t * dbri)
/* Temporarily mute outputs, and wait 1/8000 sec (125 us)
* to make sure this takes. This avoids clicking noises.
*/
-
cs4215_setdata(dbri, 1);
udelay(125);
@@ -1530,8 +1539,8 @@ static int cs4215_setctrl(snd_dbri_t * dbri)
tmp |= D_C; /* Enable CHI */
sbus_writel(tmp, dbri->regs + REG0);
- for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) {
- udelay(125);
+ for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) {
+ msleep_interruptible(1);
}
if (i == 0) {
dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
@@ -1678,8 +1687,8 @@ buffer and calls dbri_process_one_interrupt() for each interrupt word.
Complicated interrupts are handled by dedicated functions (which
appear first in this file). Any pending interrupts can be serviced by
calling dbri_process_interrupt_buffer(), which works even if the CPU's
-interrupts are disabled. This function is used by dbri_cmdsend()
-to make sure we're synced up with the chip after each command sequence,
+interrupts are disabled. This function is used by dbri_cmdlock()
+to make sure we're synced up with the chip before each command sequence,
even if we're running cli'ed.
*/
@@ -1765,11 +1774,13 @@ DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
* Called by main interrupt handler when DBRI signals transmission complete
* on a pipe (interrupt triggered by the B bit in a transmit descriptor).
*
- * Walks through the pipe's list of transmit buffer descriptors, releasing
- * each one's DMA buffer (if present), flagging the descriptor available,
- * and signaling its callback routine (if present), before proceeding
- * to the next one. Stops when the first descriptor is found without
+ * Walks through the pipe's list of transmit buffer descriptors and marks
+ * them as available. Stops when the first descriptor is found without
* TBC (Transmit Buffer Complete) set, or we've run through them all.
+ *
+ * The DMA buffers are not released, but re-used. Since the transmit buffer
+ * descriptors are not clobbered, they can be re-submitted as is. This is
+ * done by the xmit_descs() tasklet above since that could take longer.
*/
static void transmission_complete_intr(snd_dbri_t * dbri, int pipe)
@@ -1885,7 +1896,11 @@ static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x)
}
if (channel == D_INTR_CMD && command == D_WAIT) {
- dbri->wait_seen++;
+ dbri->wait_ackd = val;
+ if (dbri->wait_send != val) {
+ printk(KERN_ERR "Processing wait command %d when %d was send.\n",
+ val, dbri->wait_send);
+ }
return;
}
@@ -1994,8 +2009,7 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id,
* The only one I've seen is MRR, which will be triggered
* if you let a transmit pipe underrun, then try to CDP it.
*
- * If these things persist, we should probably reset
- * and re-init the chip.
+ * If these things persist, we reset the chip.
*/
if ((++errcnt) % 10 == 0) {
dprintk(D_INT, "Interrupt errors exceeded.\n");
@@ -2094,7 +2108,7 @@ static int snd_dbri_hw_params(snd_pcm_substream_t * substream,
if ((ret = snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params))) < 0) {
- snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret);
+ printk(KERN_ERR "malloc_pages failed with %d\n", ret);
return ret;
}
@@ -2455,8 +2469,7 @@ static int __init snd_dbri_mixer(snd_dbri_t * dbri)
for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) {
if ((err = snd_ctl_add(card,
- snd_ctl_new1(&dbri_controls[idx],
- dbri))) < 0)
+ snd_ctl_new1(&dbri_controls[idx], dbri))) < 0)
return err;
}
@@ -2490,8 +2503,6 @@ static void dbri_debug_read(snd_info_entry_t * entry,
int pipe;
snd_iprintf(buffer, "debug=%d\n", dbri_debug);
- snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n",
- dbri->chi_in_pipe, dbri->chi_out_pipe);
for (pipe = 0; pipe < 32; pipe++) {
if (pipe_active(dbri, pipe)) {
struct dbri_pipe *pptr = &dbri->pipes[pipe];
@@ -2506,18 +2517,6 @@ static void dbri_debug_read(snd_info_entry_t * entry,
}
}
}
-
-static void dbri_debug_write(snd_info_entry_t * entry,
- snd_info_buffer_t * buffer)
-{
- char line[80];
- int i;
-
- if (snd_info_get_line(buffer, line, 80) == 0) {
- sscanf(line, "%d\n", &i);
- dbri_debug = i & 0x3f;
- }
-}
#endif
void snd_dbri_proc(snd_dbri_t * dbri)
@@ -2531,9 +2530,7 @@ void snd_dbri_proc(snd_dbri_t * dbri)
#ifdef DBRI_DEBUG
err = snd_card_proc_new(dbri->card, "debug", &entry);
snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read);
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */
- entry->c.text.write_size = 256;
- entry->c.text.write = dbri_debug_write;
+ entry->mode = S_IFREG | S_IRUGO; /* Readable only. */
#endif
}
@@ -2637,7 +2634,11 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
return -ENOENT;
}
- prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
+ err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
+ if (err < 0) {
+ printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", dev);
+ return -ENODEV;
+ }
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof(snd_dbri_t));
@@ -2657,26 +2658,20 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
}
dbri = (snd_dbri_t *) card->private_data;
- if ((err = snd_dbri_pcm(dbri)) < 0) {
- snd_dbri_free(dbri);
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_dbri_pcm(dbri)) < 0)
+ goto _err;
- if ((err = snd_dbri_mixer(dbri)) < 0) {
- snd_dbri_free(dbri);
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_dbri_mixer(dbri)) < 0)
+ goto _err;
/* /proc file handling */
snd_dbri_proc(dbri);
- if ((err = snd_card_register(card)) < 0) {
- snd_dbri_free(dbri);
- snd_card_free(card);
- return err;
- }
+ if ((err = snd_card_set_generic_dev(card)) < 0)
+ goto _err;
+
+ if ((err = snd_card_register(card)) < 0)
+ goto _err;
printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
dev, dbri->regs,
@@ -2684,6 +2679,11 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
dev++;
return 0;
+
+ _err:
+ snd_dbri_free(dbri);
+ snd_card_free(card);
+ return err;
}
/* Probe for the dbri chip and then attach the driver. */
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index 60d0b2c66698..9e2b4c0c8a8a 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -40,7 +40,7 @@ int snd_emux_new(snd_emux_t **remu)
snd_emux_t *emu;
*remu = NULL;
- emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
+ emu = kzalloc(sizeof(*emu), GFP_KERNEL);
if (emu == NULL)
return -ENOMEM;
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index e41b28d9bf52..8ccd33f4aa57 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -146,7 +146,7 @@ snd_emux_create_port(snd_emux_t *emu, char *name,
int i, type, cap;
/* Allocate structures for this channel */
- if ((p = kcalloc(1, sizeof(*p), GFP_KERNEL)) == NULL) {
+ if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
snd_printk("no memory\n");
return NULL;
}
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 901a7db05bde..d0925ea50838 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -266,7 +266,7 @@ newsf(snd_sf_list_t *sflist, int type, char *name)
}
/* not found -- create a new one */
- sf = kcalloc(1, sizeof(*sf), GFP_KERNEL);
+ sf = kzalloc(sizeof(*sf), GFP_KERNEL);
if (sf == NULL)
return NULL;
sf->id = sflist->fonts_size;
@@ -346,7 +346,7 @@ sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
{
snd_sf_zone_t *zp;
- if ((zp = kcalloc(1, sizeof(*zp), GFP_KERNEL)) == NULL)
+ if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
return NULL;
zp->next = sf->zones;
sf->zones = zp;
@@ -377,7 +377,7 @@ sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
{
snd_sf_sample_t *sp;
- if ((sp = kcalloc(1, sizeof(*sp), GFP_KERNEL)) == NULL)
+ if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
return NULL;
sp->next = sf->samples;
@@ -1362,7 +1362,7 @@ snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr)
{
snd_sf_list_t *sflist;
- if ((sflist = kcalloc(1, sizeof(*sflist), GFP_KERNEL)) == NULL)
+ if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
return NULL;
init_MUTEX(&sflist->presets_mutex);
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c
index 8b131a11e549..5f75bf31bc36 100644
--- a/sound/synth/util_mem.c
+++ b/sound/synth/util_mem.c
@@ -38,7 +38,7 @@ snd_util_memhdr_new(int memsize)
{
snd_util_memhdr_t *hdr;
- hdr = kcalloc(1, sizeof(*hdr), GFP_KERNEL);
+ hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
if (hdr == NULL)
return NULL;
hdr->size = memsize;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 5aa5fe651a8a..2ead878bcb8f 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);
}
}
@@ -1441,24 +1439,28 @@ static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream)
static snd_pcm_hardware_t snd_usb_playback =
{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .buffer_bytes_max = (256*1024),
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .buffer_bytes_max = 1024 * 1024,
.period_bytes_min = 64,
- .period_bytes_max = (128*1024),
+ .period_bytes_max = 512 * 1024,
.periods_min = 2,
.periods_max = 1024,
};
static snd_pcm_hardware_t snd_usb_capture =
{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .buffer_bytes_max = (256*1024),
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .buffer_bytes_max = 1024 * 1024,
.period_bytes_min = 64,
- .period_bytes_max = (128*1024),
+ .period_bytes_max = 512 * 1024,
.periods_min = 2,
.periods_max = 1024,
};
@@ -3134,7 +3136,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
return -ENOMEM;
}
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (! chip) {
snd_card_free(card);
return -ENOMEM;
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 93dedde3c428..f1a2e2c2e02f 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -163,7 +163,7 @@ static const uint8_t snd_usbmidi_cin_length[] = {
/*
* Submits the URB, with error handling.
*/
-static int snd_usbmidi_submit_urb(struct urb* urb, int flags)
+static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags)
{
int err = usb_submit_urb(urb, flags);
if (err < 0 && err != -ENODEV)
@@ -841,7 +841,7 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi,
int length;
rep->in = NULL;
- ep = kcalloc(1, sizeof(*ep), GFP_KERNEL);
+ ep = kzalloc(sizeof(*ep), GFP_KERNEL);
if (!ep)
return -ENOMEM;
ep->umidi = umidi;
@@ -913,7 +913,7 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi,
void* buffer;
rep->out = NULL;
- ep = kcalloc(1, sizeof(*ep), GFP_KERNEL);
+ ep = kzalloc(sizeof(*ep), GFP_KERNEL);
if (!ep)
return -ENOMEM;
ep->umidi = umidi;
@@ -1537,7 +1537,7 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip,
int out_ports, in_ports;
int i, err;
- umidi = kcalloc(1, sizeof(*umidi), GFP_KERNEL);
+ umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
if (!umidi)
return -ENOMEM;
umidi->chip = chip;
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index fa7056f5caaf..c3c08c9cb46e 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -824,7 +824,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
if (check_ignored_ctl(state, unitid, control))
return;
- cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+ cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
return;
@@ -997,7 +997,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
if (check_ignored_ctl(state, unitid, 0))
return;
- cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+ cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval)
return;
@@ -1244,7 +1244,7 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char
continue;
if (check_ignored_ctl(state, unitid, valinfo->control))
continue;
- cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+ cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
return -ENOMEM;
@@ -1430,7 +1430,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned
if (check_ignored_ctl(state, unitid, 0))
return 0;
- cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+ cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
return -ENOMEM;
@@ -1945,7 +1945,7 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
strcpy(chip->card->mixername, "USB Mixer");
- mixer = kcalloc(1, sizeof(*mixer), GFP_KERNEL);
+ mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
if (!mixer)
return -ENOMEM;
mixer->chip = chip;
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index f05500b05ec0..c1264434e50a 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -238,6 +238,16 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
.selector_map = audigy2nx_selectors,
},
{
+ /* Hercules DJ Console (Windows Edition) */
+ .id = USB_ID(0x06f8, 0xb000),
+ .ignore_ctl_error = 1,
+ },
+ {
+ /* Hercules DJ Console (Macintosh Edition) */
+ .id = USB_ID(0x06f8, 0xd002),
+ .ignore_ctl_error = 1,
+ },
+ {
.id = USB_ID(0x08bb, 0x2702),
.map = linex_map,
.ignore_ctl_error = 1,
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index f74e652a1e51..948759da6563 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -117,6 +117,10 @@ YAMAHA_DEVICE(0x103a, NULL),
YAMAHA_DEVICE(0x103b, NULL),
YAMAHA_DEVICE(0x103c, NULL),
YAMAHA_DEVICE(0x103d, NULL),
+YAMAHA_DEVICE(0x103e, NULL),
+YAMAHA_DEVICE(0x103f, NULL),
+YAMAHA_DEVICE(0x1040, NULL),
+YAMAHA_DEVICE(0x1041, NULL),
YAMAHA_DEVICE(0x2000, "DGP-7"),
YAMAHA_DEVICE(0x2001, "DGP-5"),
YAMAHA_DEVICE(0x2002, NULL),
@@ -1010,6 +1014,40 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Roland",
+ /* RD-700SX, RD-300SX */
+ .ifnum = 0,
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .out_cables = 0x0003,
+ .in_cables = 0x0003
+ }
+ }
+},
+
+/* Guillemot devices */
+{
+ /*
+ * This is for the "Windows Edition" where the external MIDI ports are
+ * the only MIDI ports; the control data is reported through HID
+ * interfaces. The "Macintosh Edition" has ID 0xd002 and uses standard
+ * compliant USB MIDI ports for external MIDI and controls.
+ */
+ USB_DEVICE_VENDOR_SPEC(0x06f8, 0xb000),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Hercules",
+ .product_name = "DJ Console (WE)",
+ .ifnum = 4,
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
+ }
+ }
+},
/* Midiman/M-Audio devices */
{
@@ -1339,10 +1377,20 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
+/* TerraTec devices */
+{
+ USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "TerraTec",
+ .product_name = "PHASE 26",
+ .ifnum = 3,
+ .type = QUIRK_MIDI_STANDARD_INTERFACE
+ }
+},
{
USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0013),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
- .vendor_name = "Terratec",
+ .vendor_name = "TerraTec",
.product_name = "PHASE 26",
.ifnum = 3,
.type = QUIRK_MIDI_STANDARD_INTERFACE
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 62dfd28b3b07..0f09e0de52dd 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -957,7 +957,7 @@ static int usX2Y_audio_stream_new(snd_card_t *card, int playback_endpoint, int c
for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
- usX2Y_substream[i] = kcalloc(1, sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
+ usX2Y_substream[i] = kzalloc(sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
if (NULL == usX2Y_substream[i]) {
snd_printk(KERN_ERR "cannot malloc\n");
return -ENOMEM;
diff --git a/usr/.gitignore b/usr/.gitignore
new file mode 100644
index 000000000000..be186a82e8d0
--- /dev/null
+++ b/usr/.gitignore
@@ -0,0 +1,7 @@
+#
+# Generated files
+#
+gen_init_cpio
+initramfs_data.cpio
+initramfs_data.cpio.gz
+initramfs_list